• Home
  • Raw
  • Download

Lines Matching +full:enable +full:- +full:ssc

2  * Driver for AT73C213 16-bit stereo DAC connected to Atmel SSC
4 * Copyright (C) 2006-2007 Atmel Norway
17 #include <linux/dma-mapping.h>
30 #include <linux/atmel-ssc.h>
44 0x00, /* 00 - CTRL */
45 0x05, /* 01 - LLIG */
46 0x05, /* 02 - RLIG */
47 0x08, /* 03 - LPMG */
48 0x08, /* 04 - RPMG */
49 0x00, /* 05 - LLOG */
50 0x00, /* 06 - RLOG */
51 0x22, /* 07 - OLC */
52 0x09, /* 08 - MC */
53 0x00, /* 09 - CSFC */
54 0x00, /* 0A - MISC */
55 0x00, /* 0B - */
56 0x00, /* 0C - PRECH */
57 0x05, /* 0D - AUXG */
58 0x00, /* 0E - */
59 0x00, /* 0F - */
60 0x00, /* 10 - RST */
61 0x00, /* 11 - PA_CTRL */
72 struct ssc_device *ssc; member
78 /* Protect SSC registers against concurrent access. */
84 #define get_chip(card) ((struct snd_at73c213 *)card->private_data)
98 chip->spi_wbuffer[0] = reg; in snd_at73c213_write_reg()
99 chip->spi_wbuffer[1] = val; in snd_at73c213_write_reg()
101 msg_xfer.tx_buf = chip->spi_wbuffer; in snd_at73c213_write_reg()
102 msg_xfer.rx_buf = chip->spi_rbuffer; in snd_at73c213_write_reg()
105 retval = spi_sync(chip->spi, &msg); in snd_at73c213_write_reg()
108 chip->reg_image[reg] = val; in snd_at73c213_write_reg()
118 .rate_min = 8000, /* Replaced by chip->bitrate later. */
119 .rate_max = 50000, /* Replaced by chip->bitrate later. */
122 .buffer_bytes_max = 64 * 1024 - 1,
124 .period_bytes_max = 64 * 1024 - 1,
134 unsigned long ssc_rate = clk_get_rate(chip->ssc->clk); in snd_at73c213_set_bitrate()
149 /* SSC clock / (bitrate * stereo * 16-bit). */ in snd_at73c213_set_bitrate()
153 max_tries = (ssc_div_max - ssc_div_min) / 2; in snd_at73c213_set_bitrate()
162 ssc_div -= 2; in snd_at73c213_set_bitrate()
164 return -ENXIO; in snd_at73c213_set_bitrate()
169 /* SSC clock / (ssc divider * 16-bit * stereo). */ in snd_at73c213_set_bitrate()
171 return -ENXIO; in snd_at73c213_set_bitrate()
176 status = clk_round_rate(chip->board->dac_clk, dac_rate_new); in snd_at73c213_set_bitrate()
185 } while (--max_tries); in snd_at73c213_set_bitrate()
188 return -ENXIO; in snd_at73c213_set_bitrate()
191 status = clk_set_rate(chip->board->dac_clk, status); in snd_at73c213_set_bitrate()
195 /* Set divider in SSC device. */ in snd_at73c213_set_bitrate()
196 ssc_writel(chip->ssc->regs, CMR, ssc_div/2); in snd_at73c213_set_bitrate()
198 /* SSC clock / (ssc divider * 16-bit * stereo). */ in snd_at73c213_set_bitrate()
199 chip->bitrate = ssc_rate / (ssc_div * 16 * 2); in snd_at73c213_set_bitrate()
201 dev_info(&chip->spi->dev, in snd_at73c213_set_bitrate()
203 chip->bitrate, ssc_div); in snd_at73c213_set_bitrate()
211 struct snd_pcm_runtime *runtime = substream->runtime; in snd_at73c213_pcm_open()
219 snd_at73c213_playback_hw.rate_min = chip->bitrate; in snd_at73c213_pcm_open()
220 snd_at73c213_playback_hw.rate_max = chip->bitrate; in snd_at73c213_pcm_open()
221 runtime->hw = snd_at73c213_playback_hw; in snd_at73c213_pcm_open()
222 chip->substream = substream; in snd_at73c213_pcm_open()
224 clk_enable(chip->ssc->clk); in snd_at73c213_pcm_open()
232 chip->substream = NULL; in snd_at73c213_pcm_close()
233 clk_disable(chip->ssc->clk); in snd_at73c213_pcm_close()
244 val = ssc_readl(chip->ssc->regs, TFMR); in snd_at73c213_pcm_hw_params()
245 val = SSC_BFINS(TFMR_DATNB, channels - 1, val); in snd_at73c213_pcm_hw_params()
246 ssc_writel(chip->ssc->regs, TFMR, val); in snd_at73c213_pcm_hw_params()
260 struct snd_pcm_runtime *runtime = substream->runtime; in snd_at73c213_pcm_prepare()
263 block_size = frames_to_bytes(runtime, runtime->period_size); in snd_at73c213_pcm_prepare()
265 chip->period = 0; in snd_at73c213_pcm_prepare()
267 ssc_writel(chip->ssc->regs, PDC_TPR, in snd_at73c213_pcm_prepare()
268 (long)runtime->dma_addr); in snd_at73c213_pcm_prepare()
269 ssc_writel(chip->ssc->regs, PDC_TCR, in snd_at73c213_pcm_prepare()
270 runtime->period_size * runtime->channels); in snd_at73c213_pcm_prepare()
271 ssc_writel(chip->ssc->regs, PDC_TNPR, in snd_at73c213_pcm_prepare()
272 (long)runtime->dma_addr + block_size); in snd_at73c213_pcm_prepare()
273 ssc_writel(chip->ssc->regs, PDC_TNCR, in snd_at73c213_pcm_prepare()
274 runtime->period_size * runtime->channels); in snd_at73c213_pcm_prepare()
285 spin_lock(&chip->lock); in snd_at73c213_pcm_trigger()
289 ssc_writel(chip->ssc->regs, IER, SSC_BIT(IER_ENDTX)); in snd_at73c213_pcm_trigger()
290 ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTEN)); in snd_at73c213_pcm_trigger()
293 ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTDIS)); in snd_at73c213_pcm_trigger()
294 ssc_writel(chip->ssc->regs, IDR, SSC_BIT(IDR_ENDTX)); in snd_at73c213_pcm_trigger()
297 dev_dbg(&chip->spi->dev, "spurious command %x\n", cmd); in snd_at73c213_pcm_trigger()
298 retval = -EINVAL; in snd_at73c213_pcm_trigger()
302 spin_unlock(&chip->lock); in snd_at73c213_pcm_trigger()
311 struct snd_pcm_runtime *runtime = substream->runtime; in snd_at73c213_pcm_pointer()
315 bytes = ssc_readl(chip->ssc->regs, PDC_TPR) in snd_at73c213_pcm_pointer()
316 - (unsigned long)runtime->dma_addr; in snd_at73c213_pcm_pointer()
319 if (pos >= runtime->buffer_size) in snd_at73c213_pcm_pointer()
320 pos -= runtime->buffer_size; in snd_at73c213_pcm_pointer()
341 retval = snd_pcm_new(chip->card, chip->card->shortname, in snd_at73c213_pcm_new()
346 pcm->private_data = chip; in snd_at73c213_pcm_new()
347 pcm->info_flags = SNDRV_PCM_INFO_BLOCK_TRANSFER; in snd_at73c213_pcm_new()
348 strcpy(pcm->name, "at73c213"); in snd_at73c213_pcm_new()
349 chip->pcm = pcm; in snd_at73c213_pcm_new()
353 retval = snd_pcm_lib_preallocate_pages_for_all(chip->pcm, in snd_at73c213_pcm_new()
354 SNDRV_DMA_TYPE_DEV, &chip->ssc->pdev->dev, in snd_at73c213_pcm_new()
363 struct snd_pcm_runtime *runtime = chip->substream->runtime; in snd_at73c213_interrupt()
370 spin_lock(&chip->lock); in snd_at73c213_interrupt()
372 block_size = frames_to_bytes(runtime, runtime->period_size); in snd_at73c213_interrupt()
373 status = ssc_readl(chip->ssc->regs, IMR); in snd_at73c213_interrupt()
376 chip->period++; in snd_at73c213_interrupt()
377 if (chip->period == runtime->periods) in snd_at73c213_interrupt()
378 chip->period = 0; in snd_at73c213_interrupt()
379 next_period = chip->period + 1; in snd_at73c213_interrupt()
380 if (next_period == runtime->periods) in snd_at73c213_interrupt()
385 ssc_writel(chip->ssc->regs, PDC_TNPR, in snd_at73c213_interrupt()
386 (long)runtime->dma_addr + offset); in snd_at73c213_interrupt()
387 ssc_writel(chip->ssc->regs, PDC_TNCR, in snd_at73c213_interrupt()
388 runtime->period_size * runtime->channels); in snd_at73c213_interrupt()
392 ssc_readl(chip->ssc->regs, IMR); in snd_at73c213_interrupt()
393 spin_unlock(&chip->lock); in snd_at73c213_interrupt()
396 snd_pcm_period_elapsed(chip->substream); in snd_at73c213_interrupt()
408 int reg = kcontrol->private_value & 0xff; in snd_at73c213_mono_get()
409 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_mono_get()
410 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_at73c213_mono_get()
411 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_mono_get()
413 mutex_lock(&chip->mixer_lock); in snd_at73c213_mono_get()
415 ucontrol->value.integer.value[0] = in snd_at73c213_mono_get()
416 (chip->reg_image[reg] >> shift) & mask; in snd_at73c213_mono_get()
419 ucontrol->value.integer.value[0] = in snd_at73c213_mono_get()
420 mask - ucontrol->value.integer.value[0]; in snd_at73c213_mono_get()
422 mutex_unlock(&chip->mixer_lock); in snd_at73c213_mono_get()
431 int reg = kcontrol->private_value & 0xff; in snd_at73c213_mono_put()
432 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_mono_put()
433 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_at73c213_mono_put()
434 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_mono_put()
438 val = (ucontrol->value.integer.value[0] & mask); in snd_at73c213_mono_put()
440 val = mask - val; in snd_at73c213_mono_put()
443 mutex_lock(&chip->mixer_lock); in snd_at73c213_mono_put()
445 val = (chip->reg_image[reg] & ~(mask << shift)) | val; in snd_at73c213_mono_put()
446 change = val != chip->reg_image[reg]; in snd_at73c213_mono_put()
449 mutex_unlock(&chip->mixer_lock); in snd_at73c213_mono_put()
460 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_stereo_info()
463 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_at73c213_stereo_info()
465 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_at73c213_stereo_info()
467 uinfo->count = 2; in snd_at73c213_stereo_info()
468 uinfo->value.integer.min = 0; in snd_at73c213_stereo_info()
469 uinfo->value.integer.max = mask; in snd_at73c213_stereo_info()
478 int left_reg = kcontrol->private_value & 0xff; in snd_at73c213_stereo_get()
479 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_stereo_get()
480 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_at73c213_stereo_get()
481 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_at73c213_stereo_get()
482 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_stereo_get()
483 int invert = (kcontrol->private_value >> 22) & 1; in snd_at73c213_stereo_get()
485 mutex_lock(&chip->mixer_lock); in snd_at73c213_stereo_get()
487 ucontrol->value.integer.value[0] = in snd_at73c213_stereo_get()
488 (chip->reg_image[left_reg] >> shift_left) & mask; in snd_at73c213_stereo_get()
489 ucontrol->value.integer.value[1] = in snd_at73c213_stereo_get()
490 (chip->reg_image[right_reg] >> shift_right) & mask; in snd_at73c213_stereo_get()
493 ucontrol->value.integer.value[0] = in snd_at73c213_stereo_get()
494 mask - ucontrol->value.integer.value[0]; in snd_at73c213_stereo_get()
495 ucontrol->value.integer.value[1] = in snd_at73c213_stereo_get()
496 mask - ucontrol->value.integer.value[1]; in snd_at73c213_stereo_get()
499 mutex_unlock(&chip->mixer_lock); in snd_at73c213_stereo_get()
508 int left_reg = kcontrol->private_value & 0xff; in snd_at73c213_stereo_put()
509 int right_reg = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_stereo_put()
510 int shift_left = (kcontrol->private_value >> 16) & 0x07; in snd_at73c213_stereo_put()
511 int shift_right = (kcontrol->private_value >> 19) & 0x07; in snd_at73c213_stereo_put()
512 int mask = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_stereo_put()
513 int invert = (kcontrol->private_value >> 22) & 1; in snd_at73c213_stereo_put()
517 val1 = ucontrol->value.integer.value[0] & mask; in snd_at73c213_stereo_put()
518 val2 = ucontrol->value.integer.value[1] & mask; in snd_at73c213_stereo_put()
520 val1 = mask - val1; in snd_at73c213_stereo_put()
521 val2 = mask - val2; in snd_at73c213_stereo_put()
526 mutex_lock(&chip->mixer_lock); in snd_at73c213_stereo_put()
528 val1 = (chip->reg_image[left_reg] & ~(mask << shift_left)) | val1; in snd_at73c213_stereo_put()
529 val2 = (chip->reg_image[right_reg] & ~(mask << shift_right)) | val2; in snd_at73c213_stereo_put()
530 change = val1 != chip->reg_image[left_reg] in snd_at73c213_stereo_put()
531 || val2 != chip->reg_image[right_reg]; in snd_at73c213_stereo_put()
534 mutex_unlock(&chip->mixer_lock); in snd_at73c213_stereo_put()
539 mutex_unlock(&chip->mixer_lock); in snd_at73c213_stereo_put()
543 mutex_unlock(&chip->mixer_lock); in snd_at73c213_stereo_put()
557 int reg = kcontrol->private_value & 0xff; in snd_at73c213_mono_switch_get()
558 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_mono_switch_get()
559 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_mono_switch_get()
561 mutex_lock(&chip->mixer_lock); in snd_at73c213_mono_switch_get()
563 ucontrol->value.integer.value[0] = in snd_at73c213_mono_switch_get()
564 (chip->reg_image[reg] >> shift) & 0x01; in snd_at73c213_mono_switch_get()
567 ucontrol->value.integer.value[0] = in snd_at73c213_mono_switch_get()
568 0x01 - ucontrol->value.integer.value[0]; in snd_at73c213_mono_switch_get()
570 mutex_unlock(&chip->mixer_lock); in snd_at73c213_mono_switch_get()
579 int reg = kcontrol->private_value & 0xff; in snd_at73c213_mono_switch_put()
580 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_at73c213_mono_switch_put()
581 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_at73c213_mono_switch_put()
582 int invert = (kcontrol->private_value >> 24) & 0xff; in snd_at73c213_mono_switch_put()
586 if (ucontrol->value.integer.value[0]) in snd_at73c213_mono_switch_put()
592 val = mask - val; in snd_at73c213_mono_switch_put()
595 mutex_lock(&chip->mixer_lock); in snd_at73c213_mono_switch_put()
597 val |= (chip->reg_image[reg] & ~(mask << shift)); in snd_at73c213_mono_switch_put()
598 change = val != chip->reg_image[reg]; in snd_at73c213_mono_switch_put()
602 mutex_unlock(&chip->mixer_lock); in snd_at73c213_mono_switch_put()
613 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_at73c213_pa_volume_info()
614 uinfo->count = 1; in snd_at73c213_pa_volume_info()
615 uinfo->value.integer.min = 0; in snd_at73c213_pa_volume_info()
616 uinfo->value.integer.max = ((kcontrol->private_value >> 16) & 0xff) - 1; in snd_at73c213_pa_volume_info()
625 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_at73c213_line_capture_volume_info()
626 uinfo->count = 2; in snd_at73c213_line_capture_volume_info()
628 uinfo->value.integer.min = 14; in snd_at73c213_line_capture_volume_info()
629 uinfo->value.integer.max = 31; in snd_at73c213_line_capture_volume_info()
638 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_at73c213_aux_capture_volume_info()
639 uinfo->count = 1; in snd_at73c213_aux_capture_volume_info()
641 uinfo->value.integer.min = 14; in snd_at73c213_aux_capture_volume_info()
642 uinfo->value.integer.max = 31; in snd_at73c213_aux_capture_volume_info()
720 if (chip == NULL || chip->pcm == NULL) in snd_at73c213_mixer()
721 return -EINVAL; in snd_at73c213_mixer()
723 card = chip->card; in snd_at73c213_mixer()
725 strcpy(card->mixername, chip->pcm->name); in snd_at73c213_mixer()
756 * Periode is 16 bit (16 - 1). in snd_at73c213_ssc_init()
758 ssc_writel(chip->ssc->regs, TCMR, in snd_at73c213_ssc_init()
762 | SSC_BF(TCMR_PERIOD, 16 - 1)); in snd_at73c213_ssc_init()
764 * Data length is 16 bit (16 - 1). in snd_at73c213_ssc_init()
767 * Frame sync length is 16 bit (16 - 1). in snd_at73c213_ssc_init()
770 ssc_writel(chip->ssc->regs, TFMR, in snd_at73c213_ssc_init()
771 SSC_BF(TFMR_DATLEN, 16 - 1) in snd_at73c213_ssc_init()
774 | SSC_BF(TFMR_FSLEN, 16 - 1) in snd_at73c213_ssc_init()
789 /* Enable DAC master clock. */ in snd_at73c213_chip_init()
790 clk_enable(chip->board->dac_clk); in snd_at73c213_chip_init()
861 /* Enable I2S device, i.e. clock output. */ in snd_at73c213_chip_init()
862 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN)); in snd_at73c213_chip_init()
867 clk_disable(chip->board->dac_clk); in snd_at73c213_chip_init()
874 struct snd_at73c213 *chip = device->device_data; in snd_at73c213_dev_free()
876 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); in snd_at73c213_dev_free()
877 if (chip->irq >= 0) { in snd_at73c213_dev_free()
878 free_irq(chip->irq, chip); in snd_at73c213_dev_free()
879 chip->irq = -1; in snd_at73c213_dev_free()
894 irq = chip->ssc->irq; in snd_at73c213_dev_init()
898 spin_lock_init(&chip->lock); in snd_at73c213_dev_init()
899 mutex_init(&chip->mixer_lock); in snd_at73c213_dev_init()
900 chip->card = card; in snd_at73c213_dev_init()
901 chip->irq = -1; in snd_at73c213_dev_init()
903 clk_enable(chip->ssc->clk); in snd_at73c213_dev_init()
907 dev_dbg(&chip->spi->dev, "unable to request irq %d\n", irq); in snd_at73c213_dev_init()
910 chip->irq = irq; in snd_at73c213_dev_init()
912 memcpy(&chip->reg_image, &snd_at73c213_original_image, in snd_at73c213_dev_init()
940 free_irq(chip->irq, chip); in snd_at73c213_dev_init()
941 chip->irq = -1; in snd_at73c213_dev_init()
943 clk_disable(chip->ssc->clk); in snd_at73c213_dev_init()
956 board = spi->dev.platform_data; in snd_at73c213_probe()
958 dev_dbg(&spi->dev, "no platform_data\n"); in snd_at73c213_probe()
959 return -ENXIO; in snd_at73c213_probe()
962 if (!board->dac_clk) { in snd_at73c213_probe()
963 dev_dbg(&spi->dev, "no DAC clk\n"); in snd_at73c213_probe()
964 return -ENXIO; in snd_at73c213_probe()
967 if (IS_ERR(board->dac_clk)) { in snd_at73c213_probe()
968 dev_dbg(&spi->dev, "no DAC clk\n"); in snd_at73c213_probe()
969 return PTR_ERR(board->dac_clk); in snd_at73c213_probe()
973 snprintf(id, sizeof id, "at73c213_%d", board->ssc_id); in snd_at73c213_probe()
974 retval = snd_card_new(&spi->dev, -1, id, THIS_MODULE, in snd_at73c213_probe()
979 chip = card->private_data; in snd_at73c213_probe()
980 chip->spi = spi; in snd_at73c213_probe()
981 chip->board = board; in snd_at73c213_probe()
983 chip->ssc = ssc_request(board->ssc_id); in snd_at73c213_probe()
984 if (IS_ERR(chip->ssc)) { in snd_at73c213_probe()
985 dev_dbg(&spi->dev, "could not get ssc%d device\n", in snd_at73c213_probe()
986 board->ssc_id); in snd_at73c213_probe()
987 retval = PTR_ERR(chip->ssc); in snd_at73c213_probe()
995 strcpy(card->driver, "at73c213"); in snd_at73c213_probe()
996 strcpy(card->shortname, board->shortname); in snd_at73c213_probe()
997 sprintf(card->longname, "%s on irq %d", card->shortname, chip->irq); in snd_at73c213_probe()
1003 dev_set_drvdata(&spi->dev, card); in snd_at73c213_probe()
1008 ssc_free(chip->ssc); in snd_at73c213_probe()
1017 struct snd_card *card = dev_get_drvdata(&spi->dev); in snd_at73c213_remove()
1018 struct snd_at73c213 *chip = card->private_data; in snd_at73c213_remove()
1022 clk_enable(chip->ssc->clk); in snd_at73c213_remove()
1023 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); in snd_at73c213_remove()
1024 clk_disable(chip->ssc->clk); in snd_at73c213_remove()
1051 chip->reg_image[PA_CTRL] | 0x0f); in snd_at73c213_remove()
1076 clk_disable(chip->board->dac_clk); in snd_at73c213_remove()
1078 ssc_free(chip->ssc); in snd_at73c213_remove()
1089 struct snd_at73c213 *chip = card->private_data; in snd_at73c213_suspend()
1091 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); in snd_at73c213_suspend()
1092 clk_disable(chip->ssc->clk); in snd_at73c213_suspend()
1093 clk_disable(chip->board->dac_clk); in snd_at73c213_suspend()
1101 struct snd_at73c213 *chip = card->private_data; in snd_at73c213_resume()
1103 clk_enable(chip->board->dac_clk); in snd_at73c213_resume()
1104 clk_enable(chip->ssc->clk); in snd_at73c213_resume()
1105 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN)); in snd_at73c213_resume()
1129 MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
1130 MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC");