Lines Matching +full:max +full:- +full:bitrate

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for AT73C213 16-bit stereo DAC connected to Atmel SSC
5 * Copyright (C) 2006-2007 Atmel Norway
14 #include <linux/dma-mapping.h>
27 #include <linux/atmel-ssc.h>
41 0x00, /* 00 - CTRL */
42 0x05, /* 01 - LLIG */
43 0x05, /* 02 - RLIG */
44 0x08, /* 03 - LPMG */
45 0x08, /* 04 - RPMG */
46 0x00, /* 05 - LLOG */
47 0x00, /* 06 - RLOG */
48 0x22, /* 07 - OLC */
49 0x09, /* 08 - MC */
50 0x00, /* 09 - CSFC */
51 0x00, /* 0A - MISC */
52 0x00, /* 0B - */
53 0x00, /* 0C - PRECH */
54 0x05, /* 0D - AUXG */
55 0x00, /* 0E - */
56 0x00, /* 0F - */
57 0x00, /* 10 - RST */
58 0x00, /* 11 - PA_CTRL */
68 unsigned long bitrate; member
81 #define get_chip(card) ((struct snd_at73c213 *)card->private_data)
95 chip->spi_wbuffer[0] = reg; in snd_at73c213_write_reg()
96 chip->spi_wbuffer[1] = val; in snd_at73c213_write_reg()
98 msg_xfer.tx_buf = chip->spi_wbuffer; in snd_at73c213_write_reg()
99 msg_xfer.rx_buf = chip->spi_rbuffer; in snd_at73c213_write_reg()
102 retval = spi_sync(chip->spi, &msg); in snd_at73c213_write_reg()
105 chip->reg_image[reg] = val; in snd_at73c213_write_reg()
115 .rate_min = 8000, /* Replaced by chip->bitrate later. */
116 .rate_max = 50000, /* Replaced by chip->bitrate later. */
119 .buffer_bytes_max = 64 * 1024 - 1,
121 .period_bytes_max = 64 * 1024 - 1,
127 * Calculate and set bitrate and divisions.
131 unsigned long ssc_rate = clk_get_rate(chip->ssc->clk); in snd_at73c213_set_bitrate()
146 /* SSC clock / (bitrate * stereo * 16-bit). */ in snd_at73c213_set_bitrate()
150 max_tries = (ssc_div_max - ssc_div_min) / 2; in snd_at73c213_set_bitrate()
159 ssc_div -= 2; in snd_at73c213_set_bitrate()
161 return -ENXIO; in snd_at73c213_set_bitrate()
164 /* Search for a possible bitrate. */ in snd_at73c213_set_bitrate()
166 /* SSC clock / (ssc divider * 16-bit * stereo). */ in snd_at73c213_set_bitrate()
168 return -ENXIO; in snd_at73c213_set_bitrate()
173 status = clk_round_rate(chip->board->dac_clk, dac_rate_new); in snd_at73c213_set_bitrate()
182 } while (--max_tries); in snd_at73c213_set_bitrate()
184 /* Not able to find a valid bitrate. */ in snd_at73c213_set_bitrate()
185 return -ENXIO; in snd_at73c213_set_bitrate()
188 status = clk_set_rate(chip->board->dac_clk, status); in snd_at73c213_set_bitrate()
193 ssc_writel(chip->ssc->regs, CMR, ssc_div/2); in snd_at73c213_set_bitrate()
195 /* SSC clock / (ssc divider * 16-bit * stereo). */ in snd_at73c213_set_bitrate()
196 chip->bitrate = ssc_rate / (ssc_div * 16 * 2); in snd_at73c213_set_bitrate()
198 dev_info(&chip->spi->dev, in snd_at73c213_set_bitrate()
199 "at73c213: supported bitrate is %lu (%lu divider)\n", in snd_at73c213_set_bitrate()
200 chip->bitrate, ssc_div); in snd_at73c213_set_bitrate()
208 struct snd_pcm_runtime *runtime = substream->runtime; in snd_at73c213_pcm_open()
216 snd_at73c213_playback_hw.rate_min = chip->bitrate; in snd_at73c213_pcm_open()
217 snd_at73c213_playback_hw.rate_max = chip->bitrate; in snd_at73c213_pcm_open()
218 runtime->hw = snd_at73c213_playback_hw; in snd_at73c213_pcm_open()
219 chip->substream = substream; in snd_at73c213_pcm_open()
221 clk_enable(chip->ssc->clk); in snd_at73c213_pcm_open()
229 chip->substream = NULL; in snd_at73c213_pcm_close()
230 clk_disable(chip->ssc->clk); in snd_at73c213_pcm_close()
241 val = ssc_readl(chip->ssc->regs, TFMR); in snd_at73c213_pcm_hw_params()
242 val = SSC_BFINS(TFMR_DATNB, channels - 1, val); in snd_at73c213_pcm_hw_params()
243 ssc_writel(chip->ssc->regs, TFMR, val); in snd_at73c213_pcm_hw_params()
251 struct snd_pcm_runtime *runtime = substream->runtime; in snd_at73c213_pcm_prepare()
254 block_size = frames_to_bytes(runtime, runtime->period_size); in snd_at73c213_pcm_prepare()
256 chip->period = 0; in snd_at73c213_pcm_prepare()
258 ssc_writel(chip->ssc->regs, PDC_TPR, in snd_at73c213_pcm_prepare()
259 (long)runtime->dma_addr); in snd_at73c213_pcm_prepare()
260 ssc_writel(chip->ssc->regs, PDC_TCR, in snd_at73c213_pcm_prepare()
261 runtime->period_size * runtime->channels); in snd_at73c213_pcm_prepare()
262 ssc_writel(chip->ssc->regs, PDC_TNPR, in snd_at73c213_pcm_prepare()
263 (long)runtime->dma_addr + block_size); in snd_at73c213_pcm_prepare()
264 ssc_writel(chip->ssc->regs, PDC_TNCR, in snd_at73c213_pcm_prepare()
265 runtime->period_size * runtime->channels); in snd_at73c213_pcm_prepare()
276 spin_lock(&chip->lock); in snd_at73c213_pcm_trigger()
280 ssc_writel(chip->ssc->regs, IER, SSC_BIT(IER_ENDTX)); in snd_at73c213_pcm_trigger()
281 ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTEN)); in snd_at73c213_pcm_trigger()
284 ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTDIS)); in snd_at73c213_pcm_trigger()
285 ssc_writel(chip->ssc->regs, IDR, SSC_BIT(IDR_ENDTX)); in snd_at73c213_pcm_trigger()
288 dev_dbg(&chip->spi->dev, "spurious command %x\n", cmd); in snd_at73c213_pcm_trigger()
289 retval = -EINVAL; in snd_at73c213_pcm_trigger()
293 spin_unlock(&chip->lock); in snd_at73c213_pcm_trigger()
302 struct snd_pcm_runtime *runtime = substream->runtime; in snd_at73c213_pcm_pointer()
306 bytes = ssc_readl(chip->ssc->regs, PDC_TPR) in snd_at73c213_pcm_pointer()
307 - (unsigned long)runtime->dma_addr; in snd_at73c213_pcm_pointer()
310 if (pos >= runtime->buffer_size) in snd_at73c213_pcm_pointer()
311 pos -= runtime->buffer_size; in snd_at73c213_pcm_pointer()
330 retval = snd_pcm_new(chip->card, chip->card->shortname, in snd_at73c213_pcm_new()
335 pcm->private_data = chip; in snd_at73c213_pcm_new()
336 pcm->info_flags = SNDRV_PCM_INFO_BLOCK_TRANSFER; in snd_at73c213_pcm_new()
337 strcpy(pcm->name, "at73c213"); in snd_at73c213_pcm_new()
338 chip->pcm = pcm; in snd_at73c213_pcm_new()
342 snd_pcm_set_managed_buffer_all(chip->pcm, in snd_at73c213_pcm_new()
343 SNDRV_DMA_TYPE_DEV, &chip->ssc->pdev->dev, in snd_at73c213_pcm_new()
352 struct snd_pcm_runtime *runtime = chip->substream->runtime; in snd_at73c213_interrupt()
359 spin_lock(&chip->lock); in snd_at73c213_interrupt()
361 block_size = frames_to_bytes(runtime, runtime->period_size); in snd_at73c213_interrupt()
362 status = ssc_readl(chip->ssc->regs, IMR); in snd_at73c213_interrupt()
365 chip->period++; in snd_at73c213_interrupt()
366 if (chip->period == runtime->periods) in snd_at73c213_interrupt()
367 chip->period = 0; in snd_at73c213_interrupt()
368 next_period = chip->period + 1; in snd_at73c213_interrupt()
369 if (next_period == runtime->periods) in snd_at73c213_interrupt()
374 ssc_writel(chip->ssc->regs, PDC_TNPR, in snd_at73c213_interrupt()
375 (long)runtime->dma_addr + offset); in snd_at73c213_interrupt()
376 ssc_writel(chip->ssc->regs, PDC_TNCR, in snd_at73c213_interrupt()
377 runtime->period_size * runtime->channels); in snd_at73c213_interrupt()
381 ssc_readl(chip->ssc->regs, IMR); in snd_at73c213_interrupt()
382 spin_unlock(&chip->lock); in snd_at73c213_interrupt()
385 snd_pcm_period_elapsed(chip->substream); in snd_at73c213_interrupt()
397 int reg = kcontrol->private_value & 0xff; in snd_at73c213_mono_get()
398 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_mono_get()
399 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_at73c213_mono_get()
400 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_mono_get()
402 mutex_lock(&chip->mixer_lock); in snd_at73c213_mono_get()
404 ucontrol->value.integer.value[0] = in snd_at73c213_mono_get()
405 (chip->reg_image[reg] >> shift) & mask; in snd_at73c213_mono_get()
408 ucontrol->value.integer.value[0] = in snd_at73c213_mono_get()
409 mask - ucontrol->value.integer.value[0]; in snd_at73c213_mono_get()
411 mutex_unlock(&chip->mixer_lock); in snd_at73c213_mono_get()
420 int reg = kcontrol->private_value & 0xff; in snd_at73c213_mono_put()
421 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_mono_put()
422 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_at73c213_mono_put()
423 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_mono_put()
427 val = (ucontrol->value.integer.value[0] & mask); in snd_at73c213_mono_put()
429 val = mask - val; in snd_at73c213_mono_put()
432 mutex_lock(&chip->mixer_lock); in snd_at73c213_mono_put()
434 val = (chip->reg_image[reg] & ~(mask << shift)) | val; in snd_at73c213_mono_put()
435 change = val != chip->reg_image[reg]; in snd_at73c213_mono_put()
438 mutex_unlock(&chip->mixer_lock); in snd_at73c213_mono_put()
449 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_stereo_info()
452 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_at73c213_stereo_info()
454 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_at73c213_stereo_info()
456 uinfo->count = 2; in snd_at73c213_stereo_info()
457 uinfo->value.integer.min = 0; in snd_at73c213_stereo_info()
458 uinfo->value.integer.max = mask; in snd_at73c213_stereo_info()
467 int left_reg = kcontrol->private_value & 0xff; in snd_at73c213_stereo_get()
468 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_stereo_get()
469 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_at73c213_stereo_get()
470 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_at73c213_stereo_get()
471 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_stereo_get()
472 int invert = (kcontrol->private_value >> 22) & 1; in snd_at73c213_stereo_get()
474 mutex_lock(&chip->mixer_lock); in snd_at73c213_stereo_get()
476 ucontrol->value.integer.value[0] = in snd_at73c213_stereo_get()
477 (chip->reg_image[left_reg] >> shift_left) & mask; in snd_at73c213_stereo_get()
478 ucontrol->value.integer.value[1] = in snd_at73c213_stereo_get()
479 (chip->reg_image[right_reg] >> shift_right) & mask; in snd_at73c213_stereo_get()
482 ucontrol->value.integer.value[0] = in snd_at73c213_stereo_get()
483 mask - ucontrol->value.integer.value[0]; in snd_at73c213_stereo_get()
484 ucontrol->value.integer.value[1] = in snd_at73c213_stereo_get()
485 mask - ucontrol->value.integer.value[1]; in snd_at73c213_stereo_get()
488 mutex_unlock(&chip->mixer_lock); in snd_at73c213_stereo_get()
497 int left_reg = kcontrol->private_value & 0xff; in snd_at73c213_stereo_put()
498 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_stereo_put()
499 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_at73c213_stereo_put()
500 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_at73c213_stereo_put()
501 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_stereo_put()
502 int invert = (kcontrol->private_value >> 22) & 1; in snd_at73c213_stereo_put()
506 val1 = ucontrol->value.integer.value[0] & mask; in snd_at73c213_stereo_put()
507 val2 = ucontrol->value.integer.value[1] & mask; in snd_at73c213_stereo_put()
509 val1 = mask - val1; in snd_at73c213_stereo_put()
510 val2 = mask - val2; in snd_at73c213_stereo_put()
515 mutex_lock(&chip->mixer_lock); in snd_at73c213_stereo_put()
517 val1 = (chip->reg_image[left_reg] & ~(mask << shift_left)) | val1; in snd_at73c213_stereo_put()
518 val2 = (chip->reg_image[right_reg] & ~(mask << shift_right)) | val2; in snd_at73c213_stereo_put()
519 change = val1 != chip->reg_image[left_reg] in snd_at73c213_stereo_put()
520 || val2 != chip->reg_image[right_reg]; in snd_at73c213_stereo_put()
523 mutex_unlock(&chip->mixer_lock); in snd_at73c213_stereo_put()
528 mutex_unlock(&chip->mixer_lock); in snd_at73c213_stereo_put()
532 mutex_unlock(&chip->mixer_lock); in snd_at73c213_stereo_put()
546 int reg = kcontrol->private_value & 0xff; in snd_at73c213_mono_switch_get()
547 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_mono_switch_get()
548 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_mono_switch_get()
550 mutex_lock(&chip->mixer_lock); in snd_at73c213_mono_switch_get()
552 ucontrol->value.integer.value[0] = in snd_at73c213_mono_switch_get()
553 (chip->reg_image[reg] >> shift) & 0x01; in snd_at73c213_mono_switch_get()
556 ucontrol->value.integer.value[0] = in snd_at73c213_mono_switch_get()
557 0x01 - ucontrol->value.integer.value[0]; in snd_at73c213_mono_switch_get()
559 mutex_unlock(&chip->mixer_lock); in snd_at73c213_mono_switch_get()
568 int reg = kcontrol->private_value & 0xff; in snd_at73c213_mono_switch_put()
569 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_mono_switch_put()
570 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_at73c213_mono_switch_put()
571 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_mono_switch_put()
575 if (ucontrol->value.integer.value[0]) in snd_at73c213_mono_switch_put()
581 val = mask - val; in snd_at73c213_mono_switch_put()
584 mutex_lock(&chip->mixer_lock); in snd_at73c213_mono_switch_put()
586 val |= (chip->reg_image[reg] & ~(mask << shift)); in snd_at73c213_mono_switch_put()
587 change = val != chip->reg_image[reg]; in snd_at73c213_mono_switch_put()
591 mutex_unlock(&chip->mixer_lock); in snd_at73c213_mono_switch_put()
602 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_at73c213_pa_volume_info()
603 uinfo->count = 1; in snd_at73c213_pa_volume_info()
604 uinfo->value.integer.min = 0; in snd_at73c213_pa_volume_info()
605 uinfo->value.integer.max = ((kcontrol->private_value >> 16) & 0xff) - 1; in snd_at73c213_pa_volume_info()
614 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_at73c213_line_capture_volume_info()
615 uinfo->count = 2; in snd_at73c213_line_capture_volume_info()
617 uinfo->value.integer.min = 14; in snd_at73c213_line_capture_volume_info()
618 uinfo->value.integer.max = 31; in snd_at73c213_line_capture_volume_info()
627 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_at73c213_aux_capture_volume_info()
628 uinfo->count = 1; in snd_at73c213_aux_capture_volume_info()
630 uinfo->value.integer.min = 14; in snd_at73c213_aux_capture_volume_info()
631 uinfo->value.integer.max = 31; in snd_at73c213_aux_capture_volume_info()
709 if (chip == NULL || chip->pcm == NULL) in snd_at73c213_mixer()
710 return -EINVAL; in snd_at73c213_mixer()
712 card = chip->card; in snd_at73c213_mixer()
714 strcpy(card->mixername, chip->pcm->name); in snd_at73c213_mixer()
745 * Periode is 16 bit (16 - 1). in snd_at73c213_ssc_init()
747 ssc_writel(chip->ssc->regs, TCMR, in snd_at73c213_ssc_init()
751 | SSC_BF(TCMR_PERIOD, 16 - 1)); in snd_at73c213_ssc_init()
753 * Data length is 16 bit (16 - 1). in snd_at73c213_ssc_init()
756 * Frame sync length is 16 bit (16 - 1). in snd_at73c213_ssc_init()
759 ssc_writel(chip->ssc->regs, TFMR, in snd_at73c213_ssc_init()
760 SSC_BF(TFMR_DATLEN, 16 - 1) in snd_at73c213_ssc_init()
763 | SSC_BF(TFMR_FSLEN, 16 - 1) in snd_at73c213_ssc_init()
779 clk_enable(chip->board->dac_clk); in snd_at73c213_chip_init()
851 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN)); in snd_at73c213_chip_init()
856 clk_disable(chip->board->dac_clk); in snd_at73c213_chip_init()
863 struct snd_at73c213 *chip = device->device_data; in snd_at73c213_dev_free()
865 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); in snd_at73c213_dev_free()
866 if (chip->irq >= 0) { in snd_at73c213_dev_free()
867 free_irq(chip->irq, chip); in snd_at73c213_dev_free()
868 chip->irq = -1; in snd_at73c213_dev_free()
883 irq = chip->ssc->irq; in snd_at73c213_dev_init()
887 spin_lock_init(&chip->lock); in snd_at73c213_dev_init()
888 mutex_init(&chip->mixer_lock); in snd_at73c213_dev_init()
889 chip->card = card; in snd_at73c213_dev_init()
890 chip->irq = -1; in snd_at73c213_dev_init()
892 clk_enable(chip->ssc->clk); in snd_at73c213_dev_init()
896 dev_dbg(&chip->spi->dev, "unable to request irq %d\n", irq); in snd_at73c213_dev_init()
899 chip->irq = irq; in snd_at73c213_dev_init()
901 memcpy(&chip->reg_image, &snd_at73c213_original_image, in snd_at73c213_dev_init()
929 free_irq(chip->irq, chip); in snd_at73c213_dev_init()
930 chip->irq = -1; in snd_at73c213_dev_init()
932 clk_disable(chip->ssc->clk); in snd_at73c213_dev_init()
945 board = spi->dev.platform_data; in snd_at73c213_probe()
947 dev_dbg(&spi->dev, "no platform_data\n"); in snd_at73c213_probe()
948 return -ENXIO; in snd_at73c213_probe()
951 if (!board->dac_clk) { in snd_at73c213_probe()
952 dev_dbg(&spi->dev, "no DAC clk\n"); in snd_at73c213_probe()
953 return -ENXIO; in snd_at73c213_probe()
956 if (IS_ERR(board->dac_clk)) { in snd_at73c213_probe()
957 dev_dbg(&spi->dev, "no DAC clk\n"); in snd_at73c213_probe()
958 return PTR_ERR(board->dac_clk); in snd_at73c213_probe()
962 snprintf(id, sizeof id, "at73c213_%d", board->ssc_id); in snd_at73c213_probe()
963 retval = snd_card_new(&spi->dev, -1, id, THIS_MODULE, in snd_at73c213_probe()
968 chip = card->private_data; in snd_at73c213_probe()
969 chip->spi = spi; in snd_at73c213_probe()
970 chip->board = board; in snd_at73c213_probe()
972 chip->ssc = ssc_request(board->ssc_id); in snd_at73c213_probe()
973 if (IS_ERR(chip->ssc)) { in snd_at73c213_probe()
974 dev_dbg(&spi->dev, "could not get ssc%d device\n", in snd_at73c213_probe()
975 board->ssc_id); in snd_at73c213_probe()
976 retval = PTR_ERR(chip->ssc); in snd_at73c213_probe()
984 strcpy(card->driver, "at73c213"); in snd_at73c213_probe()
985 strcpy(card->shortname, board->shortname); in snd_at73c213_probe()
986 sprintf(card->longname, "%s on irq %d", card->shortname, chip->irq); in snd_at73c213_probe()
992 dev_set_drvdata(&spi->dev, card); in snd_at73c213_probe()
997 ssc_free(chip->ssc); in snd_at73c213_probe()
1006 struct snd_card *card = dev_get_drvdata(&spi->dev); in snd_at73c213_remove()
1007 struct snd_at73c213 *chip = card->private_data; in snd_at73c213_remove()
1011 clk_enable(chip->ssc->clk); in snd_at73c213_remove()
1012 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); in snd_at73c213_remove()
1013 clk_disable(chip->ssc->clk); in snd_at73c213_remove()
1040 chip->reg_image[PA_CTRL] | 0x0f); in snd_at73c213_remove()
1065 clk_disable(chip->board->dac_clk); in snd_at73c213_remove()
1067 ssc_free(chip->ssc); in snd_at73c213_remove()
1078 struct snd_at73c213 *chip = card->private_data; in snd_at73c213_suspend()
1080 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); in snd_at73c213_suspend()
1081 clk_disable(chip->ssc->clk); in snd_at73c213_suspend()
1082 clk_disable(chip->board->dac_clk); in snd_at73c213_suspend()
1090 struct snd_at73c213 *chip = card->private_data; in snd_at73c213_resume()
1092 clk_enable(chip->board->dac_clk); in snd_at73c213_resume()
1093 clk_enable(chip->ssc->clk); in snd_at73c213_resume()
1094 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN)); in snd_at73c213_resume()
1118 MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");