aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2016-07-26 04:35:31 -0400
committerTakashi Iwai <tiwai@suse.de>2016-07-26 04:35:31 -0400
commit4a6baf1b35891ebc877e91a803877d69b703e086 (patch)
tree3a1368712165fb4fb18741b3496b514b2661b998 /sound
parentcf81d6b583444cb6f5e656f050e43413b236354e (diff)
parente7ca8fcd15049b1e48ae2ef1434a68a51ef0ead5 (diff)
Merge tag 'asoc-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.8 Not really any framework work this time around (though we have seen one of the Analog Devices drivers move more to the clock API which is good to see) but rather a lot of new drivers: - Lots of updates for the Intel drivers, mostly board support and bug fixing, and to the NAU8825 driver. - Work on generalizing bits of simple-card to allow more code sharing with the Renesas rsrc-card (which can't use simple-card due to DPCM). - Removal of the Odroid X2 driver due to replacement with simple-card. - Support for several new Mediatek platforms and associated boards. - New drivers for Allwinner A10, Analog Devices ADAU7002, Broadcom Cygnus, Cirrus Logic CS35L33 and CS53L30, Maxim MAX8960 and MAX98504, Realtek RT5514 and Wolfson WM8758
Diffstat (limited to 'sound')
-rw-r--r--sound/core/compress_offload.c67
-rw-r--r--sound/soc/atmel/Kconfig1
-rw-r--r--sound/soc/atmel/atmel-classd.c5
-rw-r--r--sound/soc/atmel/atmel-pdmic.c5
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c2
-rw-r--r--sound/soc/bcm/Kconfig9
-rw-r--r--sound/soc/bcm/Makefile5
-rw-r--r--sound/soc/bcm/cygnus-pcm.c861
-rw-r--r--sound/soc/bcm/cygnus-ssp.c1529
-rw-r--r--sound/soc/bcm/cygnus-ssp.h139
-rw-r--r--sound/soc/codecs/Kconfig38
-rw-r--r--sound/soc/codecs/Makefile14
-rw-r--r--sound/soc/codecs/adau-utils.c61
-rw-r--r--sound/soc/codecs/adau-utils.h7
-rw-r--r--sound/soc/codecs/adau1373.c38
-rw-r--r--sound/soc/codecs/adau1761-i2c.c2
-rw-r--r--sound/soc/codecs/adau1761-spi.c2
-rw-r--r--sound/soc/codecs/adau1781-i2c.c2
-rw-r--r--sound/soc/codecs/adau1781-spi.c2
-rw-r--r--sound/soc/codecs/adau17x1.c251
-rw-r--r--sound/soc/codecs/adau17x1.h6
-rw-r--r--sound/soc/codecs/adau7002.c80
-rw-r--r--sound/soc/codecs/ak4613.c12
-rw-r--r--sound/soc/codecs/ak4642.c13
-rw-r--r--sound/soc/codecs/arizona.c91
-rw-r--r--sound/soc/codecs/arizona.h22
-rw-r--r--sound/soc/codecs/bt-sco.c52
-rw-r--r--sound/soc/codecs/cs35l33.c1303
-rw-r--r--sound/soc/codecs/cs35l33.h221
-rw-r--r--sound/soc/codecs/cs47l24.c19
-rw-r--r--sound/soc/codecs/cs53l30.c1143
-rw-r--r--sound/soc/codecs/cs53l30.h459
-rw-r--r--sound/soc/codecs/da7219-aad.c103
-rw-r--r--sound/soc/codecs/da7219.c34
-rw-r--r--sound/soc/codecs/hdac_hdmi.c7
-rw-r--r--sound/soc/codecs/hdmi-codec.c15
-rw-r--r--sound/soc/codecs/max98504.c383
-rw-r--r--sound/soc/codecs/max98504.h59
-rw-r--r--sound/soc/codecs/max9860.c753
-rw-r--r--sound/soc/codecs/max9860.h162
-rw-r--r--[-rwxr-xr-x]sound/soc/codecs/max9867.c0
-rw-r--r--[-rwxr-xr-x]sound/soc/codecs/max9867.h0
-rw-r--r--sound/soc/codecs/max9877.h2
-rw-r--r--sound/soc/codecs/nau8825.c1256
-rw-r--r--sound/soc/codecs/nau8825.h127
-rw-r--r--sound/soc/codecs/pcm1681.c2
-rw-r--r--sound/soc/codecs/pcm179x.c2
-rw-r--r--sound/soc/codecs/pcm5102a.c1
-rw-r--r--sound/soc/codecs/rt286.c7
-rw-r--r--sound/soc/codecs/rt5514-spi.c447
-rw-r--r--sound/soc/codecs/rt5514-spi.h38
-rw-r--r--sound/soc/codecs/rt5514.c168
-rw-r--r--sound/soc/codecs/rt5514.h7
-rw-r--r--sound/soc/codecs/rt5645.c24
-rw-r--r--sound/soc/codecs/rt5645.h3
-rw-r--r--sound/soc/codecs/rt5670.c3
-rw-r--r--sound/soc/codecs/sgtl5000.c431
-rw-r--r--sound/soc/codecs/sgtl5000.h2
-rw-r--r--sound/soc/codecs/tas571x.c188
-rw-r--r--sound/soc/codecs/tas571x.h40
-rw-r--r--sound/soc/codecs/tlv320aic31xx.h134
-rw-r--r--sound/soc/codecs/tpa6130a2.c394
-rw-r--r--sound/soc/codecs/tpa6130a2.h14
-rw-r--r--sound/soc/codecs/wm5102.c1
-rw-r--r--sound/soc/codecs/wm5110.c19
-rw-r--r--sound/soc/codecs/wm8731.c5
-rw-r--r--sound/soc/codecs/wm8753.c3
-rw-r--r--sound/soc/codecs/wm8985.c143
-rw-r--r--sound/soc/codecs/wm8985.h38
-rw-r--r--sound/soc/codecs/wm8998.c1
-rw-r--r--sound/soc/codecs/wm_adsp.c34
-rw-r--r--sound/soc/codecs/wm_adsp.h4
-rw-r--r--sound/soc/davinci/davinci-mcasp.c9
-rw-r--r--sound/soc/dwc/Kconfig9
-rw-r--r--sound/soc/dwc/Makefile4
-rw-r--r--sound/soc/dwc/designware_i2s.c231
-rw-r--r--sound/soc/dwc/designware_pcm.c225
-rw-r--r--sound/soc/dwc/local.h128
-rw-r--r--sound/soc/fsl/Kconfig1
-rw-r--r--sound/soc/fsl/fsl_spdif.c2
-rw-r--r--sound/soc/generic/Kconfig4
-rw-r--r--sound/soc/generic/Makefile2
-rw-r--r--sound/soc/generic/simple-card-utils.c97
-rw-r--r--sound/soc/generic/simple-card.c276
-rw-r--r--sound/soc/intel/Kconfig73
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c44
-rw-r--r--sound/soc/intel/boards/Makefile2
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c460
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c118
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c20
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c51
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c51
-rw-r--r--sound/soc/intel/boards/skl_rt286.c9
-rw-r--r--sound/soc/intel/common/Makefile4
-rw-r--r--sound/soc/intel/common/sst-acpi.h4
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h4
-rw-r--r--sound/soc/intel/common/sst-dsp.c69
-rw-r--r--sound/soc/intel/common/sst-dsp.h2
-rw-r--r--sound/soc/intel/common/sst-firmware.c68
-rw-r--r--sound/soc/intel/haswell/sst-haswell-pcm.c1
-rw-r--r--sound/soc/intel/skylake/Makefile2
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c202
-rw-r--r--sound/soc/intel/skylake/skl-messages.c53
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c40
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.h22
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c93
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c260
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h102
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c4
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h18
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c256
-rw-r--r--sound/soc/intel/skylake/skl-sst.c124
-rw-r--r--sound/soc/intel/skylake/skl-topology.c230
-rw-r--r--sound/soc/intel/skylake/skl-topology.h7
-rw-r--r--sound/soc/intel/skylake/skl.c39
-rw-r--r--sound/soc/intel/skylake/skl.h10
-rw-r--r--sound/soc/mediatek/Kconfig38
-rw-r--r--sound/soc/mediatek/Makefile10
-rw-r--r--sound/soc/mediatek/common/Makefile16
-rw-r--r--sound/soc/mediatek/common/mtk-afe-fe-dai.c379
-rw-r--r--sound/soc/mediatek/common/mtk-afe-fe-dai.h45
-rw-r--r--sound/soc/mediatek/common/mtk-afe-platform-driver.c90
-rw-r--r--sound/soc/mediatek/common/mtk-afe-platform-driver.h23
-rw-r--r--sound/soc/mediatek/common/mtk-base-afe.h104
-rw-r--r--sound/soc/mediatek/mt2701/Makefile19
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c464
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h38
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-common.h172
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-pcm.c1656
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-cs42448.c412
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-reg.h186
-rw-r--r--sound/soc/mediatek/mt8173/Makefile7
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-afe-common.h73
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-afe-pcm.c (renamed from sound/soc/mediatek/mtk-afe-pcm.c)925
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-max98090.c (renamed from sound/soc/mediatek/mt8173-max98090.c)2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c (renamed from sound/soc/mediatek/mt8173-rt5650-rt5514.c)2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c (renamed from sound/soc/mediatek/mt8173-rt5650-rt5676.c)4
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650.c (renamed from sound/soc/mediatek/mt8173-rt5650.c)73
-rw-r--r--sound/soc/mediatek/mtk-afe-common.h101
-rw-r--r--sound/soc/omap/Kconfig3
-rw-r--r--sound/soc/omap/omap-mcpdm.c74
-rw-r--r--sound/soc/omap/rx51.c46
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c71
-rw-r--r--sound/soc/rockchip/rockchip_i2s.h11
-rw-r--r--sound/soc/rockchip/rockchip_max98090.c65
-rw-r--r--sound/soc/rockchip/rockchip_spdif.c17
-rw-r--r--sound/soc/samsung/Kconfig8
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/ac97.c3
-rw-r--r--sound/soc/samsung/dma.h9
-rw-r--r--sound/soc/samsung/dmaengine.c31
-rw-r--r--sound/soc/samsung/i2s.c53
-rw-r--r--sound/soc/samsung/odroidx2_max98090.c185
-rw-r--r--sound/soc/samsung/pcm.c3
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c2
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c3
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c3
-rw-r--r--sound/soc/samsung/spdif.c3
-rw-r--r--sound/soc/sh/Kconfig1
-rw-r--r--sound/soc/sh/rcar/adg.c18
-rw-r--r--sound/soc/sh/rcar/gen.c12
-rw-r--r--sound/soc/sh/rcar/rsrc-card.c99
-rw-r--r--sound/soc/soc-compress.c5
-rw-r--r--sound/soc/soc-dapm.c61
-rw-r--r--sound/soc/soc-pcm.c43
-rw-r--r--sound/soc/sti/uniperif_player.c4
-rw-r--r--sound/soc/sunxi/Kconfig9
-rw-r--r--sound/soc/sunxi/Makefile2
-rw-r--r--sound/soc/sunxi/sun4i-i2s.c701
169 files changed, 18406 insertions, 2925 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 9b3334be9df2..2c498488af6c 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -67,6 +67,8 @@ struct snd_compr_file {
67 struct snd_compr_stream stream; 67 struct snd_compr_stream stream;
68}; 68};
69 69
70static void error_delayed_work(struct work_struct *work);
71
70/* 72/*
71 * a note on stream states used: 73 * a note on stream states used:
72 * we use following states in the compressed core 74 * we use following states in the compressed core
@@ -123,6 +125,9 @@ static int snd_compr_open(struct inode *inode, struct file *f)
123 snd_card_unref(compr->card); 125 snd_card_unref(compr->card);
124 return -ENOMEM; 126 return -ENOMEM;
125 } 127 }
128
129 INIT_DELAYED_WORK(&data->stream.error_work, error_delayed_work);
130
126 data->stream.ops = compr->ops; 131 data->stream.ops = compr->ops;
127 data->stream.direction = dirn; 132 data->stream.direction = dirn;
128 data->stream.private_data = compr->private_data; 133 data->stream.private_data = compr->private_data;
@@ -153,6 +158,8 @@ static int snd_compr_free(struct inode *inode, struct file *f)
153 struct snd_compr_file *data = f->private_data; 158 struct snd_compr_file *data = f->private_data;
154 struct snd_compr_runtime *runtime = data->stream.runtime; 159 struct snd_compr_runtime *runtime = data->stream.runtime;
155 160
161 cancel_delayed_work_sync(&data->stream.error_work);
162
156 switch (runtime->state) { 163 switch (runtime->state) {
157 case SNDRV_PCM_STATE_RUNNING: 164 case SNDRV_PCM_STATE_RUNNING:
158 case SNDRV_PCM_STATE_DRAINING: 165 case SNDRV_PCM_STATE_DRAINING:
@@ -237,6 +244,15 @@ snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg)
237 avail = snd_compr_calc_avail(stream, &ioctl_avail); 244 avail = snd_compr_calc_avail(stream, &ioctl_avail);
238 ioctl_avail.avail = avail; 245 ioctl_avail.avail = avail;
239 246
247 switch (stream->runtime->state) {
248 case SNDRV_PCM_STATE_OPEN:
249 return -EBADFD;
250 case SNDRV_PCM_STATE_XRUN:
251 return -EPIPE;
252 default:
253 break;
254 }
255
240 if (copy_to_user((__u64 __user *)arg, 256 if (copy_to_user((__u64 __user *)arg,
241 &ioctl_avail, sizeof(ioctl_avail))) 257 &ioctl_avail, sizeof(ioctl_avail)))
242 return -EFAULT; 258 return -EFAULT;
@@ -346,11 +362,13 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf,
346 switch (stream->runtime->state) { 362 switch (stream->runtime->state) {
347 case SNDRV_PCM_STATE_OPEN: 363 case SNDRV_PCM_STATE_OPEN:
348 case SNDRV_PCM_STATE_PREPARED: 364 case SNDRV_PCM_STATE_PREPARED:
349 case SNDRV_PCM_STATE_XRUN:
350 case SNDRV_PCM_STATE_SUSPENDED: 365 case SNDRV_PCM_STATE_SUSPENDED:
351 case SNDRV_PCM_STATE_DISCONNECTED: 366 case SNDRV_PCM_STATE_DISCONNECTED:
352 retval = -EBADFD; 367 retval = -EBADFD;
353 goto out; 368 goto out;
369 case SNDRV_PCM_STATE_XRUN:
370 retval = -EPIPE;
371 goto out;
354 } 372 }
355 373
356 avail = snd_compr_get_avail(stream); 374 avail = snd_compr_get_avail(stream);
@@ -399,10 +417,16 @@ static unsigned int snd_compr_poll(struct file *f, poll_table *wait)
399 stream = &data->stream; 417 stream = &data->stream;
400 418
401 mutex_lock(&stream->device->lock); 419 mutex_lock(&stream->device->lock);
402 if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) { 420
421 switch (stream->runtime->state) {
422 case SNDRV_PCM_STATE_OPEN:
423 case SNDRV_PCM_STATE_XRUN:
403 retval = snd_compr_get_poll(stream) | POLLERR; 424 retval = snd_compr_get_poll(stream) | POLLERR;
404 goto out; 425 goto out;
426 default:
427 break;
405 } 428 }
429
406 poll_wait(f, &stream->runtime->sleep, wait); 430 poll_wait(f, &stream->runtime->sleep, wait);
407 431
408 avail = snd_compr_get_avail(stream); 432 avail = snd_compr_get_avail(stream);
@@ -697,6 +721,45 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
697 return retval; 721 return retval;
698} 722}
699 723
724static void error_delayed_work(struct work_struct *work)
725{
726 struct snd_compr_stream *stream;
727
728 stream = container_of(work, struct snd_compr_stream, error_work.work);
729
730 mutex_lock(&stream->device->lock);
731
732 stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
733 wake_up(&stream->runtime->sleep);
734
735 mutex_unlock(&stream->device->lock);
736}
737
738/*
739 * snd_compr_stop_error: Report a fatal error on a stream
740 * @stream: pointer to stream
741 * @state: state to transition the stream to
742 *
743 * Stop the stream and set its state.
744 *
745 * Should be called with compressed device lock held.
746 */
747int snd_compr_stop_error(struct snd_compr_stream *stream,
748 snd_pcm_state_t state)
749{
750 if (stream->runtime->state == state)
751 return 0;
752
753 stream->runtime->state = state;
754
755 pr_debug("Changing state to: %d\n", state);
756
757 queue_delayed_work(system_power_efficient_wq, &stream->error_work, 0);
758
759 return 0;
760}
761EXPORT_SYMBOL_GPL(snd_compr_stop_error);
762
700static int snd_compress_wait_for_drain(struct snd_compr_stream *stream) 763static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
701{ 764{
702 int ret; 765 int ret;
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 06e099e802df..22aec9a1e9a4 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -10,6 +10,7 @@ if SND_ATMEL_SOC
10 10
11config SND_ATMEL_SOC_PDC 11config SND_ATMEL_SOC_PDC
12 tristate 12 tristate
13 depends on HAS_DMA
13 default m if SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=m 14 default m if SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=m
14 default y if SND_ATMEL_SOC_SSC_PDC=y || (SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=y) 15 default y if SND_ATMEL_SOC_SSC_PDC=y || (SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=y)
15 16
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index 6107de9c538b..6d9b8b44e2da 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -593,11 +593,6 @@ static int atmel_classd_probe(struct platform_device *pdev)
593 } 593 }
594 594
595 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 595 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
596 if (!res) {
597 dev_err(dev, "no memory resource\n");
598 return -ENXIO;
599 }
600
601 io_base = devm_ioremap_resource(dev, res); 596 io_base = devm_ioremap_resource(dev, res);
602 if (IS_ERR(io_base)) { 597 if (IS_ERR(io_base)) {
603 ret = PTR_ERR(io_base); 598 ret = PTR_ERR(io_base);
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c
index aee4787a0b89..5f56da60c92f 100644
--- a/sound/soc/atmel/atmel-pdmic.c
+++ b/sound/soc/atmel/atmel-pdmic.c
@@ -624,11 +624,6 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
624 } 624 }
625 625
626 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 626 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
627 if (!res) {
628 dev_err(dev, "no memory resource\n");
629 return -ENXIO;
630 }
631
632 io_base = devm_ioremap_resource(dev, res); 627 io_base = devm_ioremap_resource(dev, res);
633 if (IS_ERR(io_base)) { 628 if (IS_ERR(io_base)) {
634 ret = PTR_ERR(io_base); 629 ret = PTR_ERR(io_base);
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 1267e1af0fae..54c09acd3fed 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -321,7 +321,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
321 return ret; 321 return ret;
322 } 322 }
323 323
324 dma_params = &ssc_dma_params[dai->id][dir]; 324 dma_params = &ssc_dma_params[pdev->id][dir];
325 dma_params->ssc = ssc_p->ssc; 325 dma_params->ssc = ssc_p->ssc;
326 dma_params->substream = substream; 326 dma_params->substream = substream;
327 327
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index 6a834e109f1d..d528aaceaad9 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -7,3 +7,12 @@ config SND_BCM2835_SOC_I2S
7 Say Y or M if you want to add support for codecs attached to 7 Say Y or M if you want to add support for codecs attached to
8 the BCM2835 I2S interface. You will also need 8 the BCM2835 I2S interface. You will also need
9 to select the audio interfaces to support below. 9 to select the audio interfaces to support below.
10
11config SND_SOC_CYGNUS
12 tristate "SoC platform audio for Broadcom Cygnus chips"
13 depends on ARCH_BCM_CYGNUS || COMPILE_TEST
14 help
15 Say Y if you want to add support for ASoC audio on Broadcom
16 Cygnus chips (bcm958300, bcm958305, bcm911360)
17
18 If you don't know what to do here, say N. \ No newline at end of file
diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile
index bc816b71e5a4..fc739d007884 100644
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
@@ -3,3 +3,8 @@ snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o
3 3
4obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o 4obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o
5 5
6# CYGNUS Platform Support
7snd-soc-cygnus-objs := cygnus-pcm.o cygnus-ssp.o
8
9obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc-cygnus.o
10
diff --git a/sound/soc/bcm/cygnus-pcm.c b/sound/soc/bcm/cygnus-pcm.c
new file mode 100644
index 000000000000..d616e096462e
--- /dev/null
+++ b/sound/soc/bcm/cygnus-pcm.c
@@ -0,0 +1,861 @@
1/*
2 * Copyright (C) 2014-2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#include <linux/debugfs.h>
14#include <linux/dma-mapping.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/slab.h>
19#include <linux/timer.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/soc-dai.h>
25
26#include "cygnus-ssp.h"
27
28/* Register offset needed for ASoC PCM module */
29
30#define INTH_R5F_STATUS_OFFSET 0x040
31#define INTH_R5F_CLEAR_OFFSET 0x048
32#define INTH_R5F_MASK_SET_OFFSET 0x050
33#define INTH_R5F_MASK_CLEAR_OFFSET 0x054
34
35#define BF_REARM_FREE_MARK_OFFSET 0x344
36#define BF_REARM_FULL_MARK_OFFSET 0x348
37
38/* Ring Buffer Ctrl Regs --- Start */
39/* AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_X_RDADDR_REG_BASE */
40#define SRC_RBUF_0_RDADDR_OFFSET 0x500
41#define SRC_RBUF_1_RDADDR_OFFSET 0x518
42#define SRC_RBUF_2_RDADDR_OFFSET 0x530
43#define SRC_RBUF_3_RDADDR_OFFSET 0x548
44#define SRC_RBUF_4_RDADDR_OFFSET 0x560
45#define SRC_RBUF_5_RDADDR_OFFSET 0x578
46#define SRC_RBUF_6_RDADDR_OFFSET 0x590
47
48/* AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_X_WRADDR_REG_BASE */
49#define SRC_RBUF_0_WRADDR_OFFSET 0x504
50#define SRC_RBUF_1_WRADDR_OFFSET 0x51c
51#define SRC_RBUF_2_WRADDR_OFFSET 0x534
52#define SRC_RBUF_3_WRADDR_OFFSET 0x54c
53#define SRC_RBUF_4_WRADDR_OFFSET 0x564
54#define SRC_RBUF_5_WRADDR_OFFSET 0x57c
55#define SRC_RBUF_6_WRADDR_OFFSET 0x594
56
57/* AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_X_BASEADDR_REG_BASE */
58#define SRC_RBUF_0_BASEADDR_OFFSET 0x508
59#define SRC_RBUF_1_BASEADDR_OFFSET 0x520
60#define SRC_RBUF_2_BASEADDR_OFFSET 0x538
61#define SRC_RBUF_3_BASEADDR_OFFSET 0x550
62#define SRC_RBUF_4_BASEADDR_OFFSET 0x568
63#define SRC_RBUF_5_BASEADDR_OFFSET 0x580
64#define SRC_RBUF_6_BASEADDR_OFFSET 0x598
65
66/* AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_X_ENDADDR_REG_BASE */
67#define SRC_RBUF_0_ENDADDR_OFFSET 0x50c
68#define SRC_RBUF_1_ENDADDR_OFFSET 0x524
69#define SRC_RBUF_2_ENDADDR_OFFSET 0x53c
70#define SRC_RBUF_3_ENDADDR_OFFSET 0x554
71#define SRC_RBUF_4_ENDADDR_OFFSET 0x56c
72#define SRC_RBUF_5_ENDADDR_OFFSET 0x584
73#define SRC_RBUF_6_ENDADDR_OFFSET 0x59c
74
75/* AUD_FMM_BF_CTRL_SOURCECH_RINGBUF_X_FREE_MARK_REG_BASE */
76#define SRC_RBUF_0_FREE_MARK_OFFSET 0x510
77#define SRC_RBUF_1_FREE_MARK_OFFSET 0x528
78#define SRC_RBUF_2_FREE_MARK_OFFSET 0x540
79#define SRC_RBUF_3_FREE_MARK_OFFSET 0x558
80#define SRC_RBUF_4_FREE_MARK_OFFSET 0x570
81#define SRC_RBUF_5_FREE_MARK_OFFSET 0x588
82#define SRC_RBUF_6_FREE_MARK_OFFSET 0x5a0
83
84/* AUD_FMM_BF_CTRL_DESTCH_RINGBUF_X_RDADDR_REG_BASE */
85#define DST_RBUF_0_RDADDR_OFFSET 0x5c0
86#define DST_RBUF_1_RDADDR_OFFSET 0x5d8
87#define DST_RBUF_2_RDADDR_OFFSET 0x5f0
88#define DST_RBUF_3_RDADDR_OFFSET 0x608
89#define DST_RBUF_4_RDADDR_OFFSET 0x620
90#define DST_RBUF_5_RDADDR_OFFSET 0x638
91
92/* AUD_FMM_BF_CTRL_DESTCH_RINGBUF_X_WRADDR_REG_BASE */
93#define DST_RBUF_0_WRADDR_OFFSET 0x5c4
94#define DST_RBUF_1_WRADDR_OFFSET 0x5dc
95#define DST_RBUF_2_WRADDR_OFFSET 0x5f4
96#define DST_RBUF_3_WRADDR_OFFSET 0x60c
97#define DST_RBUF_4_WRADDR_OFFSET 0x624
98#define DST_RBUF_5_WRADDR_OFFSET 0x63c
99
100/* AUD_FMM_BF_CTRL_DESTCH_RINGBUF_X_BASEADDR_REG_BASE */
101#define DST_RBUF_0_BASEADDR_OFFSET 0x5c8
102#define DST_RBUF_1_BASEADDR_OFFSET 0x5e0
103#define DST_RBUF_2_BASEADDR_OFFSET 0x5f8
104#define DST_RBUF_3_BASEADDR_OFFSET 0x610
105#define DST_RBUF_4_BASEADDR_OFFSET 0x628
106#define DST_RBUF_5_BASEADDR_OFFSET 0x640
107
108/* AUD_FMM_BF_CTRL_DESTCH_RINGBUF_X_ENDADDR_REG_BASE */
109#define DST_RBUF_0_ENDADDR_OFFSET 0x5cc
110#define DST_RBUF_1_ENDADDR_OFFSET 0x5e4
111#define DST_RBUF_2_ENDADDR_OFFSET 0x5fc
112#define DST_RBUF_3_ENDADDR_OFFSET 0x614
113#define DST_RBUF_4_ENDADDR_OFFSET 0x62c
114#define DST_RBUF_5_ENDADDR_OFFSET 0x644
115
116/* AUD_FMM_BF_CTRL_DESTCH_RINGBUF_X_FULL_MARK_REG_BASE */
117#define DST_RBUF_0_FULL_MARK_OFFSET 0x5d0
118#define DST_RBUF_1_FULL_MARK_OFFSET 0x5e8
119#define DST_RBUF_2_FULL_MARK_OFFSET 0x600
120#define DST_RBUF_3_FULL_MARK_OFFSET 0x618
121#define DST_RBUF_4_FULL_MARK_OFFSET 0x630
122#define DST_RBUF_5_FULL_MARK_OFFSET 0x648
123/* Ring Buffer Ctrl Regs --- End */
124
125/* Error Status Regs --- Start */
126/* AUD_FMM_BF_ESR_ESRX_STATUS_REG_BASE */
127#define ESR0_STATUS_OFFSET 0x900
128#define ESR1_STATUS_OFFSET 0x918
129#define ESR2_STATUS_OFFSET 0x930
130#define ESR3_STATUS_OFFSET 0x948
131#define ESR4_STATUS_OFFSET 0x960
132
133/* AUD_FMM_BF_ESR_ESRX_STATUS_CLEAR_REG_BASE */
134#define ESR0_STATUS_CLR_OFFSET 0x908
135#define ESR1_STATUS_CLR_OFFSET 0x920
136#define ESR2_STATUS_CLR_OFFSET 0x938
137#define ESR3_STATUS_CLR_OFFSET 0x950
138#define ESR4_STATUS_CLR_OFFSET 0x968
139
140/* AUD_FMM_BF_ESR_ESRX_MASK_REG_BASE */
141#define ESR0_MASK_STATUS_OFFSET 0x90c
142#define ESR1_MASK_STATUS_OFFSET 0x924
143#define ESR2_MASK_STATUS_OFFSET 0x93c
144#define ESR3_MASK_STATUS_OFFSET 0x954
145#define ESR4_MASK_STATUS_OFFSET 0x96c
146
147/* AUD_FMM_BF_ESR_ESRX_MASK_SET_REG_BASE */
148#define ESR0_MASK_SET_OFFSET 0x910
149#define ESR1_MASK_SET_OFFSET 0x928
150#define ESR2_MASK_SET_OFFSET 0x940
151#define ESR3_MASK_SET_OFFSET 0x958
152#define ESR4_MASK_SET_OFFSET 0x970
153
154/* AUD_FMM_BF_ESR_ESRX_MASK_CLEAR_REG_BASE */
155#define ESR0_MASK_CLR_OFFSET 0x914
156#define ESR1_MASK_CLR_OFFSET 0x92c
157#define ESR2_MASK_CLR_OFFSET 0x944
158#define ESR3_MASK_CLR_OFFSET 0x95c
159#define ESR4_MASK_CLR_OFFSET 0x974
160/* Error Status Regs --- End */
161
162#define R5F_ESR0_SHIFT 0 /* esr0 = fifo underflow */
163#define R5F_ESR1_SHIFT 1 /* esr1 = ringbuf underflow */
164#define R5F_ESR2_SHIFT 2 /* esr2 = ringbuf overflow */
165#define R5F_ESR3_SHIFT 3 /* esr3 = freemark */
166#define R5F_ESR4_SHIFT 4 /* esr4 = fullmark */
167
168
169/* Mask for R5F register. Set all relevant interrupt for playback handler */
170#define ANY_PLAYBACK_IRQ (BIT(R5F_ESR0_SHIFT) | \
171 BIT(R5F_ESR1_SHIFT) | \
172 BIT(R5F_ESR3_SHIFT))
173
174/* Mask for R5F register. Set all relevant interrupt for capture handler */
175#define ANY_CAPTURE_IRQ (BIT(R5F_ESR2_SHIFT) | BIT(R5F_ESR4_SHIFT))
176
177/*
178 * PERIOD_BYTES_MIN is the number of bytes to at which the interrupt will tick.
179 * This number should be a multiple of 256. Minimum value is 256
180 */
181#define PERIOD_BYTES_MIN 0x100
182
183static const struct snd_pcm_hardware cygnus_pcm_hw = {
184 .info = SNDRV_PCM_INFO_MMAP |
185 SNDRV_PCM_INFO_MMAP_VALID |
186 SNDRV_PCM_INFO_INTERLEAVED,
187 .formats = SNDRV_PCM_FMTBIT_S16_LE |
188 SNDRV_PCM_FMTBIT_S32_LE,
189
190 /* A period is basically an interrupt */
191 .period_bytes_min = PERIOD_BYTES_MIN,
192 .period_bytes_max = 0x10000,
193
194 /* period_min/max gives range of approx interrupts per buffer */
195 .periods_min = 2,
196 .periods_max = 8,
197
198 /*
199 * maximum buffer size in bytes = period_bytes_max * periods_max
200 * We allocate this amount of data for each enabled channel
201 */
202 .buffer_bytes_max = 4 * 0x8000,
203};
204
205static u64 cygnus_dma_dmamask = DMA_BIT_MASK(32);
206
207static struct cygnus_aio_port *cygnus_dai_get_dma_data(
208 struct snd_pcm_substream *substream)
209{
210 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
211
212 return snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
213}
214
215static void ringbuf_set_initial(void __iomem *audio_io,
216 struct ringbuf_regs *p_rbuf,
217 bool is_playback,
218 u32 start,
219 u32 periodsize,
220 u32 bufsize)
221{
222 u32 initial_rd;
223 u32 initial_wr;
224 u32 end;
225 u32 fmark_val; /* free or full mark */
226
227 p_rbuf->period_bytes = periodsize;
228 p_rbuf->buf_size = bufsize;
229
230 if (is_playback) {
231 /* Set the pointers to indicate full (flip uppermost bit) */
232 initial_rd = start;
233 initial_wr = initial_rd ^ BIT(31);
234 } else {
235 /* Set the pointers to indicate empty */
236 initial_wr = start;
237 initial_rd = initial_wr;
238 }
239
240 end = start + bufsize - 1;
241
242 /*
243 * The interrupt will fire when free/full mark is *exceeded*
244 * The fmark value must be multiple of PERIOD_BYTES_MIN so set fmark
245 * to be PERIOD_BYTES_MIN less than the period size.
246 */
247 fmark_val = periodsize - PERIOD_BYTES_MIN;
248
249 writel(start, audio_io + p_rbuf->baseaddr);
250 writel(end, audio_io + p_rbuf->endaddr);
251 writel(fmark_val, audio_io + p_rbuf->fmark);
252 writel(initial_rd, audio_io + p_rbuf->rdaddr);
253 writel(initial_wr, audio_io + p_rbuf->wraddr);
254}
255
256static int configure_ringbuf_regs(struct snd_pcm_substream *substream)
257{
258 struct cygnus_aio_port *aio;
259 struct ringbuf_regs *p_rbuf;
260 int status = 0;
261
262 aio = cygnus_dai_get_dma_data(substream);
263
264 /* Map the ssp portnum to a set of ring buffers. */
265 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
266 p_rbuf = &aio->play_rb_regs;
267
268 switch (aio->portnum) {
269 case 0:
270 *p_rbuf = RINGBUF_REG_PLAYBACK(0);
271 break;
272 case 1:
273 *p_rbuf = RINGBUF_REG_PLAYBACK(2);
274 break;
275 case 2:
276 *p_rbuf = RINGBUF_REG_PLAYBACK(4);
277 break;
278 case 3: /* SPDIF */
279 *p_rbuf = RINGBUF_REG_PLAYBACK(6);
280 break;
281 default:
282 status = -EINVAL;
283 }
284 } else {
285 p_rbuf = &aio->capture_rb_regs;
286
287 switch (aio->portnum) {
288 case 0:
289 *p_rbuf = RINGBUF_REG_CAPTURE(0);
290 break;
291 case 1:
292 *p_rbuf = RINGBUF_REG_CAPTURE(2);
293 break;
294 case 2:
295 *p_rbuf = RINGBUF_REG_CAPTURE(4);
296 break;
297 default:
298 status = -EINVAL;
299 }
300 }
301
302 return status;
303}
304
305static struct ringbuf_regs *get_ringbuf(struct snd_pcm_substream *substream)
306{
307 struct cygnus_aio_port *aio;
308 struct ringbuf_regs *p_rbuf = NULL;
309
310 aio = cygnus_dai_get_dma_data(substream);
311
312 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
313 p_rbuf = &aio->play_rb_regs;
314 else
315 p_rbuf = &aio->capture_rb_regs;
316
317 return p_rbuf;
318}
319
320static void enable_intr(struct snd_pcm_substream *substream)
321{
322 struct cygnus_aio_port *aio;
323 u32 clear_mask;
324
325 aio = cygnus_dai_get_dma_data(substream);
326
327 /* The port number maps to the bit position to be cleared */
328 clear_mask = BIT(aio->portnum);
329
330 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
331 /* Clear interrupt status before enabling them */
332 writel(clear_mask, aio->cygaud->audio + ESR0_STATUS_CLR_OFFSET);
333 writel(clear_mask, aio->cygaud->audio + ESR1_STATUS_CLR_OFFSET);
334 writel(clear_mask, aio->cygaud->audio + ESR3_STATUS_CLR_OFFSET);
335 /* Unmask the interrupts of the given port*/
336 writel(clear_mask, aio->cygaud->audio + ESR0_MASK_CLR_OFFSET);
337 writel(clear_mask, aio->cygaud->audio + ESR1_MASK_CLR_OFFSET);
338 writel(clear_mask, aio->cygaud->audio + ESR3_MASK_CLR_OFFSET);
339
340 writel(ANY_PLAYBACK_IRQ,
341 aio->cygaud->audio + INTH_R5F_MASK_CLEAR_OFFSET);
342 } else {
343 writel(clear_mask, aio->cygaud->audio + ESR2_STATUS_CLR_OFFSET);
344 writel(clear_mask, aio->cygaud->audio + ESR4_STATUS_CLR_OFFSET);
345 writel(clear_mask, aio->cygaud->audio + ESR2_MASK_CLR_OFFSET);
346 writel(clear_mask, aio->cygaud->audio + ESR4_MASK_CLR_OFFSET);
347
348 writel(ANY_CAPTURE_IRQ,
349 aio->cygaud->audio + INTH_R5F_MASK_CLEAR_OFFSET);
350 }
351
352}
353
354static void disable_intr(struct snd_pcm_substream *substream)
355{
356 struct snd_soc_pcm_runtime *rtd = substream->private_data;
357 struct cygnus_aio_port *aio;
358 u32 set_mask;
359
360 aio = cygnus_dai_get_dma_data(substream);
361
362 dev_dbg(rtd->cpu_dai->dev, "%s on port %d\n", __func__, aio->portnum);
363
364 /* The port number maps to the bit position to be set */
365 set_mask = BIT(aio->portnum);
366
367 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
368 /* Mask the interrupts of the given port*/
369 writel(set_mask, aio->cygaud->audio + ESR0_MASK_SET_OFFSET);
370 writel(set_mask, aio->cygaud->audio + ESR1_MASK_SET_OFFSET);
371 writel(set_mask, aio->cygaud->audio + ESR3_MASK_SET_OFFSET);
372 } else {
373 writel(set_mask, aio->cygaud->audio + ESR2_MASK_SET_OFFSET);
374 writel(set_mask, aio->cygaud->audio + ESR4_MASK_SET_OFFSET);
375 }
376
377}
378
379static int cygnus_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
380{
381 int ret = 0;
382
383 switch (cmd) {
384 case SNDRV_PCM_TRIGGER_START:
385 case SNDRV_PCM_TRIGGER_RESUME:
386 enable_intr(substream);
387 break;
388
389 case SNDRV_PCM_TRIGGER_STOP:
390 case SNDRV_PCM_TRIGGER_SUSPEND:
391 disable_intr(substream);
392 break;
393 default:
394 ret = -EINVAL;
395 }
396
397 return ret;
398}
399
400static void cygnus_pcm_period_elapsed(struct snd_pcm_substream *substream)
401{
402 struct cygnus_aio_port *aio;
403 struct ringbuf_regs *p_rbuf = NULL;
404 u32 regval;
405
406 aio = cygnus_dai_get_dma_data(substream);
407
408 p_rbuf = get_ringbuf(substream);
409
410 /*
411 * If free/full mark interrupt occurs, provide timestamp
412 * to ALSA and update appropriate idx by period_bytes
413 */
414 snd_pcm_period_elapsed(substream);
415
416 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
417 /* Set the ring buffer to full */
418 regval = readl(aio->cygaud->audio + p_rbuf->rdaddr);
419 regval = regval ^ BIT(31);
420 writel(regval, aio->cygaud->audio + p_rbuf->wraddr);
421 } else {
422 /* Set the ring buffer to empty */
423 regval = readl(aio->cygaud->audio + p_rbuf->wraddr);
424 writel(regval, aio->cygaud->audio + p_rbuf->rdaddr);
425 }
426}
427
428/*
429 * ESR0/1/3 status Description
430 * 0x1 I2S0_out port caused interrupt
431 * 0x2 I2S1_out port caused interrupt
432 * 0x4 I2S2_out port caused interrupt
433 * 0x8 SPDIF_out port caused interrupt
434 */
435static void handle_playback_irq(struct cygnus_audio *cygaud)
436{
437 void __iomem *audio_io;
438 u32 port;
439 u32 esr_status0, esr_status1, esr_status3;
440
441 audio_io = cygaud->audio;
442
443 /*
444 * ESR status gets updates with/without interrupts enabled.
445 * So, check the ESR mask, which provides interrupt enable/
446 * disable status and use it to determine which ESR status
447 * should be serviced.
448 */
449 esr_status0 = readl(audio_io + ESR0_STATUS_OFFSET);
450 esr_status0 &= ~readl(audio_io + ESR0_MASK_STATUS_OFFSET);
451 esr_status1 = readl(audio_io + ESR1_STATUS_OFFSET);
452 esr_status1 &= ~readl(audio_io + ESR1_MASK_STATUS_OFFSET);
453 esr_status3 = readl(audio_io + ESR3_STATUS_OFFSET);
454 esr_status3 &= ~readl(audio_io + ESR3_MASK_STATUS_OFFSET);
455
456 for (port = 0; port < CYGNUS_MAX_PLAYBACK_PORTS; port++) {
457 u32 esrmask = BIT(port);
458
459 /*
460 * Ringbuffer or FIFO underflow
461 * If we get this interrupt then, it is also true that we have
462 * not yet responded to the freemark interrupt.
463 * Log a debug message. The freemark handler below will
464 * handle getting everything going again.
465 */
466 if ((esrmask & esr_status1) || (esrmask & esr_status0)) {
467 dev_dbg(cygaud->dev,
468 "Underrun: esr0=0x%x, esr1=0x%x esr3=0x%x\n",
469 esr_status0, esr_status1, esr_status3);
470 }
471
472 /*
473 * Freemark is hit. This is the normal interrupt.
474 * In typical operation the read and write regs will be equal
475 */
476 if (esrmask & esr_status3) {
477 struct snd_pcm_substream *playstr;
478
479 playstr = cygaud->portinfo[port].play_stream;
480 cygnus_pcm_period_elapsed(playstr);
481 }
482 }
483
484 /* Clear ESR interrupt */
485 writel(esr_status0, audio_io + ESR0_STATUS_CLR_OFFSET);
486 writel(esr_status1, audio_io + ESR1_STATUS_CLR_OFFSET);
487 writel(esr_status3, audio_io + ESR3_STATUS_CLR_OFFSET);
488 /* Rearm freemark logic by writing 1 to the correct bit */
489 writel(esr_status3, audio_io + BF_REARM_FREE_MARK_OFFSET);
490}
491
492/*
493 * ESR2/4 status Description
494 * 0x1 I2S0_in port caused interrupt
495 * 0x2 I2S1_in port caused interrupt
496 * 0x4 I2S2_in port caused interrupt
497 */
498static void handle_capture_irq(struct cygnus_audio *cygaud)
499{
500 void __iomem *audio_io;
501 u32 port;
502 u32 esr_status2, esr_status4;
503
504 audio_io = cygaud->audio;
505
506 /*
507 * ESR status gets updates with/without interrupts enabled.
508 * So, check the ESR mask, which provides interrupt enable/
509 * disable status and use it to determine which ESR status
510 * should be serviced.
511 */
512 esr_status2 = readl(audio_io + ESR2_STATUS_OFFSET);
513 esr_status2 &= ~readl(audio_io + ESR2_MASK_STATUS_OFFSET);
514 esr_status4 = readl(audio_io + ESR4_STATUS_OFFSET);
515 esr_status4 &= ~readl(audio_io + ESR4_MASK_STATUS_OFFSET);
516
517 for (port = 0; port < CYGNUS_MAX_CAPTURE_PORTS; port++) {
518 u32 esrmask = BIT(port);
519
520 /*
521 * Ringbuffer or FIFO overflow
522 * If we get this interrupt then, it is also true that we have
523 * not yet responded to the fullmark interrupt.
524 * Log a debug message. The fullmark handler below will
525 * handle getting everything going again.
526 */
527 if (esrmask & esr_status2)
528 dev_dbg(cygaud->dev,
529 "Overflow: esr2=0x%x\n", esr_status2);
530
531 if (esrmask & esr_status4) {
532 struct snd_pcm_substream *capstr;
533
534 capstr = cygaud->portinfo[port].capture_stream;
535 cygnus_pcm_period_elapsed(capstr);
536 }
537 }
538
539 writel(esr_status2, audio_io + ESR2_STATUS_CLR_OFFSET);
540 writel(esr_status4, audio_io + ESR4_STATUS_CLR_OFFSET);
541 /* Rearm fullmark logic by writing 1 to the correct bit */
542 writel(esr_status4, audio_io + BF_REARM_FULL_MARK_OFFSET);
543}
544
545static irqreturn_t cygnus_dma_irq(int irq, void *data)
546{
547 u32 r5_status;
548 struct cygnus_audio *cygaud = data;
549
550 /*
551 * R5 status bits Description
552 * 0 ESR0 (playback FIFO interrupt)
553 * 1 ESR1 (playback rbuf interrupt)
554 * 2 ESR2 (capture rbuf interrupt)
555 * 3 ESR3 (Freemark play. interrupt)
556 * 4 ESR4 (Fullmark capt. interrupt)
557 */
558 r5_status = readl(cygaud->audio + INTH_R5F_STATUS_OFFSET);
559
560 if (!(r5_status & (ANY_PLAYBACK_IRQ | ANY_CAPTURE_IRQ)))
561 return IRQ_NONE;
562
563 /* If playback interrupt happened */
564 if (ANY_PLAYBACK_IRQ & r5_status) {
565 handle_playback_irq(cygaud);
566 writel(ANY_PLAYBACK_IRQ & r5_status,
567 cygaud->audio + INTH_R5F_CLEAR_OFFSET);
568 }
569
570 /* If capture interrupt happened */
571 if (ANY_CAPTURE_IRQ & r5_status) {
572 handle_capture_irq(cygaud);
573 writel(ANY_CAPTURE_IRQ & r5_status,
574 cygaud->audio + INTH_R5F_CLEAR_OFFSET);
575 }
576
577 return IRQ_HANDLED;
578}
579
580static int cygnus_pcm_open(struct snd_pcm_substream *substream)
581{
582 struct snd_soc_pcm_runtime *rtd = substream->private_data;
583 struct snd_pcm_runtime *runtime = substream->runtime;
584 struct cygnus_aio_port *aio;
585 int ret;
586
587 aio = cygnus_dai_get_dma_data(substream);
588 if (!aio)
589 return -ENODEV;
590
591 dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum);
592
593 snd_soc_set_runtime_hwparams(substream, &cygnus_pcm_hw);
594
595 ret = snd_pcm_hw_constraint_step(runtime, 0,
596 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, PERIOD_BYTES_MIN);
597 if (ret < 0)
598 return ret;
599
600 ret = snd_pcm_hw_constraint_step(runtime, 0,
601 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, PERIOD_BYTES_MIN);
602 if (ret < 0)
603 return ret;
604 /*
605 * Keep track of which substream belongs to which port.
606 * This info is needed by snd_pcm_period_elapsed() in irq_handler
607 */
608 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
609 aio->play_stream = substream;
610 else
611 aio->capture_stream = substream;
612
613 return 0;
614}
615
616static int cygnus_pcm_close(struct snd_pcm_substream *substream)
617{
618 struct snd_soc_pcm_runtime *rtd = substream->private_data;
619 struct cygnus_aio_port *aio;
620
621 aio = cygnus_dai_get_dma_data(substream);
622
623 dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum);
624
625 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
626 aio->play_stream = NULL;
627 else
628 aio->capture_stream = NULL;
629
630 if (!aio->play_stream && !aio->capture_stream)
631 dev_dbg(rtd->cpu_dai->dev, "freed port %d\n", aio->portnum);
632
633 return 0;
634}
635
636static int cygnus_pcm_hw_params(struct snd_pcm_substream *substream,
637 struct snd_pcm_hw_params *params)
638{
639 struct snd_soc_pcm_runtime *rtd = substream->private_data;
640 struct snd_pcm_runtime *runtime = substream->runtime;
641 struct cygnus_aio_port *aio;
642 int ret = 0;
643
644 aio = cygnus_dai_get_dma_data(substream);
645 dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum);
646
647 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
648 runtime->dma_bytes = params_buffer_bytes(params);
649
650 return ret;
651}
652
653static int cygnus_pcm_hw_free(struct snd_pcm_substream *substream)
654{
655 struct snd_soc_pcm_runtime *rtd = substream->private_data;
656 struct cygnus_aio_port *aio;
657
658 aio = cygnus_dai_get_dma_data(substream);
659 dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum);
660
661 snd_pcm_set_runtime_buffer(substream, NULL);
662 return 0;
663}
664
665static int cygnus_pcm_prepare(struct snd_pcm_substream *substream)
666{
667 struct snd_soc_pcm_runtime *rtd = substream->private_data;
668 struct snd_pcm_runtime *runtime = substream->runtime;
669 struct cygnus_aio_port *aio;
670 unsigned long bufsize, periodsize;
671 int ret = 0;
672 bool is_play;
673 u32 start;
674 struct ringbuf_regs *p_rbuf = NULL;
675
676 aio = cygnus_dai_get_dma_data(substream);
677 dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum);
678
679 bufsize = snd_pcm_lib_buffer_bytes(substream);
680 periodsize = snd_pcm_lib_period_bytes(substream);
681
682 dev_dbg(rtd->cpu_dai->dev, "%s (buf_size %lu) (period_size %lu)\n",
683 __func__, bufsize, periodsize);
684
685 configure_ringbuf_regs(substream);
686
687 p_rbuf = get_ringbuf(substream);
688
689 start = runtime->dma_addr;
690
691 is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 1 : 0;
692
693 ringbuf_set_initial(aio->cygaud->audio, p_rbuf, is_play, start,
694 periodsize, bufsize);
695
696 return ret;
697}
698
699static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_pcm_substream *substream)
700{
701 struct cygnus_aio_port *aio;
702 unsigned int res = 0, cur = 0, base = 0;
703 struct ringbuf_regs *p_rbuf = NULL;
704
705 aio = cygnus_dai_get_dma_data(substream);
706
707 /*
708 * Get the offset of the current read (for playack) or write
709 * index (for capture). Report this value back to the asoc framework.
710 */
711 p_rbuf = get_ringbuf(substream);
712 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
713 cur = readl(aio->cygaud->audio + p_rbuf->rdaddr);
714 else
715 cur = readl(aio->cygaud->audio + p_rbuf->wraddr);
716
717 base = readl(aio->cygaud->audio + p_rbuf->baseaddr);
718
719 /*
720 * Mask off the MSB of the rdaddr,wraddr and baseaddr
721 * since MSB is not part of the address
722 */
723 res = (cur & 0x7fffffff) - (base & 0x7fffffff);
724
725 return bytes_to_frames(substream->runtime, res);
726}
727
728static int cygnus_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
729{
730 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
731 struct snd_soc_pcm_runtime *rtd = substream->private_data;
732 struct snd_dma_buffer *buf = &substream->dma_buffer;
733 size_t size;
734
735 size = cygnus_pcm_hw.buffer_bytes_max;
736
737 buf->dev.type = SNDRV_DMA_TYPE_DEV;
738 buf->dev.dev = pcm->card->dev;
739 buf->private_data = NULL;
740 buf->area = dma_alloc_coherent(pcm->card->dev, size,
741 &buf->addr, GFP_KERNEL);
742
743 dev_dbg(rtd->cpu_dai->dev, "%s: size 0x%zx @ %pK\n",
744 __func__, size, buf->area);
745
746 if (!buf->area) {
747 dev_err(rtd->cpu_dai->dev, "%s: dma_alloc failed\n", __func__);
748 return -ENOMEM;
749 }
750 buf->bytes = size;
751
752 return 0;
753}
754
755
756static const struct snd_pcm_ops cygnus_pcm_ops = {
757 .open = cygnus_pcm_open,
758 .close = cygnus_pcm_close,
759 .ioctl = snd_pcm_lib_ioctl,
760 .hw_params = cygnus_pcm_hw_params,
761 .hw_free = cygnus_pcm_hw_free,
762 .prepare = cygnus_pcm_prepare,
763 .trigger = cygnus_pcm_trigger,
764 .pointer = cygnus_pcm_pointer,
765};
766
767static void cygnus_dma_free_dma_buffers(struct snd_pcm *pcm)
768{
769 struct snd_pcm_substream *substream;
770 struct snd_dma_buffer *buf;
771
772 substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
773 if (substream) {
774 buf = &substream->dma_buffer;
775 if (buf->area) {
776 dma_free_coherent(pcm->card->dev, buf->bytes,
777 buf->area, buf->addr);
778 buf->area = NULL;
779 }
780 }
781
782 substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
783 if (substream) {
784 buf = &substream->dma_buffer;
785 if (buf->area) {
786 dma_free_coherent(pcm->card->dev, buf->bytes,
787 buf->area, buf->addr);
788 buf->area = NULL;
789 }
790 }
791}
792
793static int cygnus_dma_new(struct snd_soc_pcm_runtime *rtd)
794{
795 struct snd_card *card = rtd->card->snd_card;
796 struct snd_pcm *pcm = rtd->pcm;
797 int ret;
798
799 if (!card->dev->dma_mask)
800 card->dev->dma_mask = &cygnus_dma_dmamask;
801 if (!card->dev->coherent_dma_mask)
802 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
803
804 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
805 ret = cygnus_pcm_preallocate_dma_buffer(pcm,
806 SNDRV_PCM_STREAM_PLAYBACK);
807 if (ret)
808 return ret;
809 }
810
811 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
812 ret = cygnus_pcm_preallocate_dma_buffer(pcm,
813 SNDRV_PCM_STREAM_CAPTURE);
814 if (ret) {
815 cygnus_dma_free_dma_buffers(pcm);
816 return ret;
817 }
818 }
819
820 return 0;
821}
822
823static struct snd_soc_platform_driver cygnus_soc_platform = {
824 .ops = &cygnus_pcm_ops,
825 .pcm_new = cygnus_dma_new,
826 .pcm_free = cygnus_dma_free_dma_buffers,
827};
828
829int cygnus_soc_platform_register(struct device *dev,
830 struct cygnus_audio *cygaud)
831{
832 int rc = 0;
833
834 dev_dbg(dev, "%s Enter\n", __func__);
835
836 rc = devm_request_irq(dev, cygaud->irq_num, cygnus_dma_irq,
837 IRQF_SHARED, "cygnus-audio", cygaud);
838 if (rc) {
839 dev_err(dev, "%s request_irq error %d\n", __func__, rc);
840 return rc;
841 }
842
843 rc = snd_soc_register_platform(dev, &cygnus_soc_platform);
844 if (rc) {
845 dev_err(dev, "%s failed\n", __func__);
846 return rc;
847 }
848
849 return 0;
850}
851
852int cygnus_soc_platform_unregister(struct device *dev)
853{
854 snd_soc_unregister_platform(dev);
855
856 return 0;
857}
858
859MODULE_LICENSE("GPL v2");
860MODULE_AUTHOR("Broadcom");
861MODULE_DESCRIPTION("Cygnus ASoC PCM module");
diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c
new file mode 100644
index 000000000000..e710bb0c5637
--- /dev/null
+++ b/sound/soc/bcm/cygnus-ssp.c
@@ -0,0 +1,1529 @@
1/*
2 * Copyright (C) 2014-2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/of_device.h>
19#include <linux/slab.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/soc-dai.h>
25
26#include "cygnus-ssp.h"
27
28#define DEFAULT_VCO 1354750204
29
30#define CYGNUS_TDM_RATE \
31 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
32 SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 | \
33 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
34 SNDRV_PCM_RATE_48000)
35
36#define CAPTURE_FCI_ID_BASE 0x180
37#define CYGNUS_SSP_TRISTATE_MASK 0x001fff
38#define CYGNUS_PLLCLKSEL_MASK 0xf
39
40/* Used with stream_on field to indicate which streams are active */
41#define PLAYBACK_STREAM_MASK BIT(0)
42#define CAPTURE_STREAM_MASK BIT(1)
43
44#define I2S_STREAM_CFG_MASK 0xff003ff
45#define I2S_CAP_STREAM_CFG_MASK 0xf0
46#define SPDIF_STREAM_CFG_MASK 0x3ff
47#define CH_GRP_STEREO 0x1
48
49/* Begin register offset defines */
50#define AUD_MISC_SEROUT_OE_REG_BASE 0x01c
51#define AUD_MISC_SEROUT_SPDIF_OE 12
52#define AUD_MISC_SEROUT_MCLK_OE 3
53#define AUD_MISC_SEROUT_LRCK_OE 2
54#define AUD_MISC_SEROUT_SCLK_OE 1
55#define AUD_MISC_SEROUT_SDAT_OE 0
56
57/* AUD_FMM_BF_CTRL_xxx regs */
58#define BF_DST_CFG0_OFFSET 0x100
59#define BF_DST_CFG1_OFFSET 0x104
60#define BF_DST_CFG2_OFFSET 0x108
61
62#define BF_DST_CTRL0_OFFSET 0x130
63#define BF_DST_CTRL1_OFFSET 0x134
64#define BF_DST_CTRL2_OFFSET 0x138
65
66#define BF_SRC_CFG0_OFFSET 0x148
67#define BF_SRC_CFG1_OFFSET 0x14c
68#define BF_SRC_CFG2_OFFSET 0x150
69#define BF_SRC_CFG3_OFFSET 0x154
70
71#define BF_SRC_CTRL0_OFFSET 0x1c0
72#define BF_SRC_CTRL1_OFFSET 0x1c4
73#define BF_SRC_CTRL2_OFFSET 0x1c8
74#define BF_SRC_CTRL3_OFFSET 0x1cc
75
76#define BF_SRC_GRP0_OFFSET 0x1fc
77#define BF_SRC_GRP1_OFFSET 0x200
78#define BF_SRC_GRP2_OFFSET 0x204
79#define BF_SRC_GRP3_OFFSET 0x208
80
81#define BF_SRC_GRP_EN_OFFSET 0x320
82#define BF_SRC_GRP_FLOWON_OFFSET 0x324
83#define BF_SRC_GRP_SYNC_DIS_OFFSET 0x328
84
85/* AUD_FMM_IOP_OUT_I2S_xxx regs */
86#define OUT_I2S_0_STREAM_CFG_OFFSET 0xa00
87#define OUT_I2S_0_CFG_OFFSET 0xa04
88#define OUT_I2S_0_MCLK_CFG_OFFSET 0xa0c
89
90#define OUT_I2S_1_STREAM_CFG_OFFSET 0xa40
91#define OUT_I2S_1_CFG_OFFSET 0xa44
92#define OUT_I2S_1_MCLK_CFG_OFFSET 0xa4c
93
94#define OUT_I2S_2_STREAM_CFG_OFFSET 0xa80
95#define OUT_I2S_2_CFG_OFFSET 0xa84
96#define OUT_I2S_2_MCLK_CFG_OFFSET 0xa8c
97
98/* AUD_FMM_IOP_OUT_SPDIF_xxx regs */
99#define SPDIF_STREAM_CFG_OFFSET 0xac0
100#define SPDIF_CTRL_OFFSET 0xac4
101#define SPDIF_FORMAT_CFG_OFFSET 0xad8
102#define SPDIF_MCLK_CFG_OFFSET 0xadc
103
104/* AUD_FMM_IOP_PLL_0_xxx regs */
105#define IOP_PLL_0_MACRO_OFFSET 0xb00
106#define IOP_PLL_0_MDIV_Ch0_OFFSET 0xb14
107#define IOP_PLL_0_MDIV_Ch1_OFFSET 0xb18
108#define IOP_PLL_0_MDIV_Ch2_OFFSET 0xb1c
109
110#define IOP_PLL_0_ACTIVE_MDIV_Ch0_OFFSET 0xb30
111#define IOP_PLL_0_ACTIVE_MDIV_Ch1_OFFSET 0xb34
112#define IOP_PLL_0_ACTIVE_MDIV_Ch2_OFFSET 0xb38
113
114/* AUD_FMM_IOP_xxx regs */
115#define IOP_PLL_0_CONTROL_OFFSET 0xb04
116#define IOP_PLL_0_USER_NDIV_OFFSET 0xb08
117#define IOP_PLL_0_ACTIVE_NDIV_OFFSET 0xb20
118#define IOP_PLL_0_RESET_OFFSET 0xb5c
119
120/* AUD_FMM_IOP_IN_I2S_xxx regs */
121#define IN_I2S_0_STREAM_CFG_OFFSET 0x00
122#define IN_I2S_0_CFG_OFFSET 0x04
123#define IN_I2S_1_STREAM_CFG_OFFSET 0x40
124#define IN_I2S_1_CFG_OFFSET 0x44
125#define IN_I2S_2_STREAM_CFG_OFFSET 0x80
126#define IN_I2S_2_CFG_OFFSET 0x84
127
128/* AUD_FMM_IOP_MISC_xxx regs */
129#define IOP_SW_INIT_LOGIC 0x1c0
130
131/* End register offset defines */
132
133
134/* AUD_FMM_IOP_OUT_I2S_x_MCLK_CFG_0_REG */
135#define I2S_OUT_MCLKRATE_SHIFT 16
136
137/* AUD_FMM_IOP_OUT_I2S_x_MCLK_CFG_REG */
138#define I2S_OUT_PLLCLKSEL_SHIFT 0
139
140/* AUD_FMM_IOP_OUT_I2S_x_STREAM_CFG */
141#define I2S_OUT_STREAM_ENA 31
142#define I2S_OUT_STREAM_CFG_GROUP_ID 20
143#define I2S_OUT_STREAM_CFG_CHANNEL_GROUPING 24
144
145/* AUD_FMM_IOP_IN_I2S_x_CAP */
146#define I2S_IN_STREAM_CFG_CAP_ENA 31
147#define I2S_IN_STREAM_CFG_0_GROUP_ID 4
148
149/* AUD_FMM_IOP_OUT_I2S_x_I2S_CFG_REG */
150#define I2S_OUT_CFGX_CLK_ENA 0
151#define I2S_OUT_CFGX_DATA_ENABLE 1
152#define I2S_OUT_CFGX_DATA_ALIGNMENT 6
153#define I2S_OUT_CFGX_BITS_PER_SLOT 13
154#define I2S_OUT_CFGX_VALID_SLOT 14
155#define I2S_OUT_CFGX_FSYNC_WIDTH 18
156#define I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32 26
157#define I2S_OUT_CFGX_SLAVE_MODE 30
158#define I2S_OUT_CFGX_TDM_MODE 31
159
160/* AUD_FMM_BF_CTRL_SOURCECH_CFGx_REG */
161#define BF_SRC_CFGX_SFIFO_ENA 0
162#define BF_SRC_CFGX_BUFFER_PAIR_ENABLE 1
163#define BF_SRC_CFGX_SAMPLE_CH_MODE 2
164#define BF_SRC_CFGX_SFIFO_SZ_DOUBLE 5
165#define BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY 10
166#define BF_SRC_CFGX_BIT_RES 20
167#define BF_SRC_CFGX_PROCESS_SEQ_ID_VALID 31
168
169/* AUD_FMM_BF_CTRL_DESTCH_CFGx_REG */
170#define BF_DST_CFGX_CAP_ENA 0
171#define BF_DST_CFGX_BUFFER_PAIR_ENABLE 1
172#define BF_DST_CFGX_DFIFO_SZ_DOUBLE 2
173#define BF_DST_CFGX_NOT_PAUSE_WHEN_FULL 11
174#define BF_DST_CFGX_FCI_ID 12
175#define BF_DST_CFGX_CAP_MODE 24
176#define BF_DST_CFGX_PROC_SEQ_ID_VALID 31
177
178/* AUD_FMM_IOP_OUT_SPDIF_xxx */
179#define SPDIF_0_OUT_DITHER_ENA 3
180#define SPDIF_0_OUT_STREAM_ENA 31
181
182/* AUD_FMM_IOP_PLL_0_USER */
183#define IOP_PLL_0_USER_NDIV_FRAC 10
184
185/* AUD_FMM_IOP_PLL_0_ACTIVE */
186#define IOP_PLL_0_ACTIVE_NDIV_FRAC 10
187
188
189#define INIT_SSP_REGS(num) (struct cygnus_ssp_regs){ \
190 .i2s_stream_cfg = OUT_I2S_ ##num## _STREAM_CFG_OFFSET, \
191 .i2s_cap_stream_cfg = IN_I2S_ ##num## _STREAM_CFG_OFFSET, \
192 .i2s_cfg = OUT_I2S_ ##num## _CFG_OFFSET, \
193 .i2s_cap_cfg = IN_I2S_ ##num## _CFG_OFFSET, \
194 .i2s_mclk_cfg = OUT_I2S_ ##num## _MCLK_CFG_OFFSET, \
195 .bf_destch_ctrl = BF_DST_CTRL ##num## _OFFSET, \
196 .bf_destch_cfg = BF_DST_CFG ##num## _OFFSET, \
197 .bf_sourcech_ctrl = BF_SRC_CTRL ##num## _OFFSET, \
198 .bf_sourcech_cfg = BF_SRC_CFG ##num## _OFFSET, \
199 .bf_sourcech_grp = BF_SRC_GRP ##num## _OFFSET \
200}
201
202struct pll_macro_entry {
203 u32 mclk;
204 u32 pll_ch_num;
205};
206
207/*
208 * PLL has 3 output channels (1x, 2x, and 4x). Below are
209 * the common MCLK frequencies used by audio driver
210 */
211static const struct pll_macro_entry pll_predef_mclk[] = {
212 { 4096000, 0},
213 { 8192000, 1},
214 {16384000, 2},
215
216 { 5644800, 0},
217 {11289600, 1},
218 {22579200, 2},
219
220 { 6144000, 0},
221 {12288000, 1},
222 {24576000, 2},
223
224 {12288000, 0},
225 {24576000, 1},
226 {49152000, 2},
227
228 {22579200, 0},
229 {45158400, 1},
230 {90316800, 2},
231
232 {24576000, 0},
233 {49152000, 1},
234 {98304000, 2},
235};
236
237/* List of valid frame sizes for tdm mode */
238static const int ssp_valid_tdm_framesize[] = {32, 64, 128, 256, 512};
239
240/*
241 * Use this relationship to derive the sampling rate (lrclk)
242 * lrclk = (mclk) / ((2*mclk_to_sclk_ratio) * (32 * SCLK))).
243 *
244 * Use mclk and pll_ch from the table above
245 *
246 * Valid SCLK = 0/1/2/4/8/12
247 *
248 * mclk_to_sclk_ratio = number of MCLK per SCLK. Division is twice the
249 * value programmed in this field.
250 * Valid mclk_to_sclk_ratio = 1 through to 15
251 *
252 * eg: To set lrclk = 48khz, set mclk = 12288000, mclk_to_sclk_ratio = 2,
253 * SCLK = 64
254 */
255struct _ssp_clk_coeff {
256 u32 mclk;
257 u32 sclk_rate;
258 u32 rate;
259 u32 mclk_rate;
260};
261
262static const struct _ssp_clk_coeff ssp_clk_coeff[] = {
263 { 4096000, 32, 16000, 4},
264 { 4096000, 32, 32000, 2},
265 { 4096000, 64, 8000, 4},
266 { 4096000, 64, 16000, 2},
267 { 4096000, 64, 32000, 1},
268 { 4096000, 128, 8000, 2},
269 { 4096000, 128, 16000, 1},
270 { 4096000, 256, 8000, 1},
271
272 { 6144000, 32, 16000, 6},
273 { 6144000, 32, 32000, 3},
274 { 6144000, 32, 48000, 2},
275 { 6144000, 32, 96000, 1},
276 { 6144000, 64, 8000, 6},
277 { 6144000, 64, 16000, 3},
278 { 6144000, 64, 48000, 1},
279 { 6144000, 128, 8000, 3},
280
281 { 8192000, 32, 32000, 4},
282 { 8192000, 64, 16000, 4},
283 { 8192000, 64, 32000, 2},
284 { 8192000, 128, 8000, 4},
285 { 8192000, 128, 16000, 2},
286 { 8192000, 128, 32000, 1},
287 { 8192000, 256, 8000, 2},
288 { 8192000, 256, 16000, 1},
289 { 8192000, 512, 8000, 1},
290
291 {12288000, 32, 32000, 6},
292 {12288000, 32, 48000, 4},
293 {12288000, 32, 96000, 2},
294 {12288000, 32, 192000, 1},
295 {12288000, 64, 16000, 6},
296 {12288000, 64, 32000, 3},
297 {12288000, 64, 48000, 2},
298 {12288000, 64, 96000, 1},
299 {12288000, 128, 8000, 6},
300 {12288000, 128, 16000, 3},
301 {12288000, 128, 48000, 1},
302 {12288000, 256, 8000, 3},
303
304 {16384000, 64, 32000, 4},
305 {16384000, 128, 16000, 4},
306 {16384000, 128, 32000, 2},
307 {16384000, 256, 8000, 4},
308 {16384000, 256, 16000, 2},
309 {16384000, 256, 32000, 1},
310 {16384000, 512, 8000, 2},
311 {16384000, 512, 16000, 1},
312
313 {24576000, 32, 96000, 4},
314 {24576000, 32, 192000, 2},
315 {24576000, 64, 32000, 6},
316 {24576000, 64, 48000, 4},
317 {24576000, 64, 96000, 2},
318 {24576000, 64, 192000, 1},
319 {24576000, 128, 16000, 6},
320 {24576000, 128, 32000, 3},
321 {24576000, 128, 48000, 2},
322 {24576000, 256, 8000, 6},
323 {24576000, 256, 16000, 3},
324 {24576000, 256, 48000, 1},
325 {24576000, 512, 8000, 3},
326
327 {49152000, 32, 192000, 4},
328 {49152000, 64, 96000, 4},
329 {49152000, 64, 192000, 2},
330 {49152000, 128, 32000, 6},
331 {49152000, 128, 48000, 4},
332 {49152000, 128, 96000, 2},
333 {49152000, 128, 192000, 1},
334 {49152000, 256, 16000, 6},
335 {49152000, 256, 32000, 3},
336 {49152000, 256, 48000, 2},
337 {49152000, 256, 96000, 1},
338 {49152000, 512, 8000, 6},
339 {49152000, 512, 16000, 3},
340 {49152000, 512, 48000, 1},
341
342 { 5644800, 32, 22050, 4},
343 { 5644800, 32, 44100, 2},
344 { 5644800, 32, 88200, 1},
345 { 5644800, 64, 11025, 4},
346 { 5644800, 64, 22050, 2},
347 { 5644800, 64, 44100, 1},
348
349 {11289600, 32, 44100, 4},
350 {11289600, 32, 88200, 2},
351 {11289600, 32, 176400, 1},
352 {11289600, 64, 22050, 4},
353 {11289600, 64, 44100, 2},
354 {11289600, 64, 88200, 1},
355 {11289600, 128, 11025, 4},
356 {11289600, 128, 22050, 2},
357 {11289600, 128, 44100, 1},
358
359 {22579200, 32, 88200, 4},
360 {22579200, 32, 176400, 2},
361 {22579200, 64, 44100, 4},
362 {22579200, 64, 88200, 2},
363 {22579200, 64, 176400, 1},
364 {22579200, 128, 22050, 4},
365 {22579200, 128, 44100, 2},
366 {22579200, 128, 88200, 1},
367 {22579200, 256, 11025, 4},
368 {22579200, 256, 22050, 2},
369 {22579200, 256, 44100, 1},
370
371 {45158400, 32, 176400, 4},
372 {45158400, 64, 88200, 4},
373 {45158400, 64, 176400, 2},
374 {45158400, 128, 44100, 4},
375 {45158400, 128, 88200, 2},
376 {45158400, 128, 176400, 1},
377 {45158400, 256, 22050, 4},
378 {45158400, 256, 44100, 2},
379 {45158400, 256, 88200, 1},
380 {45158400, 512, 11025, 4},
381 {45158400, 512, 22050, 2},
382 {45158400, 512, 44100, 1},
383};
384
385static struct cygnus_aio_port *cygnus_dai_get_portinfo(struct snd_soc_dai *dai)
386{
387 struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
388
389 return &cygaud->portinfo[dai->id];
390}
391
392static int audio_ssp_init_portregs(struct cygnus_aio_port *aio)
393{
394 u32 value, fci_id;
395 int status = 0;
396
397 switch (aio->port_type) {
398 case PORT_TDM:
399 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
400 value &= ~I2S_STREAM_CFG_MASK;
401
402 /* Set Group ID */
403 writel(aio->portnum,
404 aio->cygaud->audio + aio->regs.bf_sourcech_grp);
405
406 /* Configure the AUD_FMM_IOP_OUT_I2S_x_STREAM_CFG reg */
407 value |= aio->portnum << I2S_OUT_STREAM_CFG_GROUP_ID;
408 value |= aio->portnum; /* FCI ID is the port num */
409 value |= CH_GRP_STEREO << I2S_OUT_STREAM_CFG_CHANNEL_GROUPING;
410 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
411
412 /* Configure the AUD_FMM_BF_CTRL_SOURCECH_CFGX reg */
413 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
414 value &= ~BIT(BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY);
415 value |= BIT(BF_SRC_CFGX_SFIFO_SZ_DOUBLE);
416 value |= BIT(BF_SRC_CFGX_PROCESS_SEQ_ID_VALID);
417 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
418
419 /* Configure the AUD_FMM_IOP_IN_I2S_x_CAP_STREAM_CFG_0 reg */
420 value = readl(aio->cygaud->i2s_in +
421 aio->regs.i2s_cap_stream_cfg);
422 value &= ~I2S_CAP_STREAM_CFG_MASK;
423 value |= aio->portnum << I2S_IN_STREAM_CFG_0_GROUP_ID;
424 writel(value, aio->cygaud->i2s_in +
425 aio->regs.i2s_cap_stream_cfg);
426
427 /* Configure the AUD_FMM_BF_CTRL_DESTCH_CFGX_REG_BASE reg */
428 fci_id = CAPTURE_FCI_ID_BASE + aio->portnum;
429
430 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
431 value |= BIT(BF_DST_CFGX_DFIFO_SZ_DOUBLE);
432 value &= ~BIT(BF_DST_CFGX_NOT_PAUSE_WHEN_FULL);
433 value |= (fci_id << BF_DST_CFGX_FCI_ID);
434 value |= BIT(BF_DST_CFGX_PROC_SEQ_ID_VALID);
435 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
436
437 /* Enable the transmit pin for this port */
438 value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
439 value &= ~BIT((aio->portnum * 4) + AUD_MISC_SEROUT_SDAT_OE);
440 writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
441 break;
442 case PORT_SPDIF:
443 writel(aio->portnum, aio->cygaud->audio + BF_SRC_GRP3_OFFSET);
444
445 value = readl(aio->cygaud->audio + SPDIF_CTRL_OFFSET);
446 value |= BIT(SPDIF_0_OUT_DITHER_ENA);
447 writel(value, aio->cygaud->audio + SPDIF_CTRL_OFFSET);
448
449 /* Enable and set the FCI ID for the SPDIF channel */
450 value = readl(aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET);
451 value &= ~SPDIF_STREAM_CFG_MASK;
452 value |= aio->portnum; /* FCI ID is the port num */
453 value |= BIT(SPDIF_0_OUT_STREAM_ENA);
454 writel(value, aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET);
455
456 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
457 value &= ~BIT(BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY);
458 value |= BIT(BF_SRC_CFGX_SFIFO_SZ_DOUBLE);
459 value |= BIT(BF_SRC_CFGX_PROCESS_SEQ_ID_VALID);
460 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
461
462 /* Enable the spdif output pin */
463 value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
464 value &= ~BIT(AUD_MISC_SEROUT_SPDIF_OE);
465 writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
466 break;
467 default:
468 dev_err(aio->cygaud->dev, "Port not supported\n");
469 status = -EINVAL;
470 }
471
472 return status;
473}
474
475static void audio_ssp_in_enable(struct cygnus_aio_port *aio)
476{
477 u32 value;
478
479 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
480 value |= BIT(BF_DST_CFGX_CAP_ENA);
481 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
482
483 writel(0x1, aio->cygaud->audio + aio->regs.bf_destch_ctrl);
484
485 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
486 value |= BIT(I2S_OUT_CFGX_CLK_ENA);
487 value |= BIT(I2S_OUT_CFGX_DATA_ENABLE);
488 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
489
490 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
491 value |= BIT(I2S_IN_STREAM_CFG_CAP_ENA);
492 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
493
494 aio->streams_on |= CAPTURE_STREAM_MASK;
495}
496
497static void audio_ssp_in_disable(struct cygnus_aio_port *aio)
498{
499 u32 value;
500
501 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
502 value &= ~BIT(I2S_IN_STREAM_CFG_CAP_ENA);
503 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
504
505 aio->streams_on &= ~CAPTURE_STREAM_MASK;
506
507 /* If both playback and capture are off */
508 if (!aio->streams_on) {
509 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
510 value &= ~BIT(I2S_OUT_CFGX_CLK_ENA);
511 value &= ~BIT(I2S_OUT_CFGX_DATA_ENABLE);
512 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
513 }
514
515 writel(0x0, aio->cygaud->audio + aio->regs.bf_destch_ctrl);
516
517 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
518 value &= ~BIT(BF_DST_CFGX_CAP_ENA);
519 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
520}
521
522static int audio_ssp_out_enable(struct cygnus_aio_port *aio)
523{
524 u32 value;
525 int status = 0;
526
527 switch (aio->port_type) {
528 case PORT_TDM:
529 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
530 value |= BIT(I2S_OUT_STREAM_ENA);
531 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
532
533 writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
534
535 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
536 value |= BIT(I2S_OUT_CFGX_CLK_ENA);
537 value |= BIT(I2S_OUT_CFGX_DATA_ENABLE);
538 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
539
540 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
541 value |= BIT(BF_SRC_CFGX_SFIFO_ENA);
542 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
543
544 aio->streams_on |= PLAYBACK_STREAM_MASK;
545 break;
546 case PORT_SPDIF:
547 value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
548 value |= 0x3;
549 writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
550
551 writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
552
553 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
554 value |= BIT(BF_SRC_CFGX_SFIFO_ENA);
555 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
556 break;
557 default:
558 dev_err(aio->cygaud->dev,
559 "Port not supported %d\n", aio->portnum);
560 status = -EINVAL;
561 }
562
563 return status;
564}
565
566static int audio_ssp_out_disable(struct cygnus_aio_port *aio)
567{
568 u32 value;
569 int status = 0;
570
571 switch (aio->port_type) {
572 case PORT_TDM:
573 aio->streams_on &= ~PLAYBACK_STREAM_MASK;
574
575 /* If both playback and capture are off */
576 if (!aio->streams_on) {
577 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
578 value &= ~BIT(I2S_OUT_CFGX_CLK_ENA);
579 value &= ~BIT(I2S_OUT_CFGX_DATA_ENABLE);
580 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
581 }
582
583 /* set group_sync_dis = 1 */
584 value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
585 value |= BIT(aio->portnum);
586 writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
587
588 writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
589
590 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
591 value &= ~BIT(BF_SRC_CFGX_SFIFO_ENA);
592 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
593
594 /* set group_sync_dis = 0 */
595 value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
596 value &= ~BIT(aio->portnum);
597 writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
598
599 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
600 value &= ~BIT(I2S_OUT_STREAM_ENA);
601 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
602
603 /* IOP SW INIT on OUT_I2S_x */
604 value = readl(aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
605 value |= BIT(aio->portnum);
606 writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
607 value &= ~BIT(aio->portnum);
608 writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
609 break;
610 case PORT_SPDIF:
611 value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
612 value &= ~0x3;
613 writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
614 writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
615
616 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
617 value &= ~BIT(BF_SRC_CFGX_SFIFO_ENA);
618 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
619 break;
620 default:
621 dev_err(aio->cygaud->dev,
622 "Port not supported %d\n", aio->portnum);
623 status = -EINVAL;
624 }
625
626 return status;
627}
628
629static int pll_configure_mclk(struct cygnus_audio *cygaud, u32 mclk,
630 struct cygnus_aio_port *aio)
631{
632 int i = 0, error;
633 bool found = false;
634 const struct pll_macro_entry *p_entry;
635 struct clk *ch_clk;
636
637 for (i = 0; i < ARRAY_SIZE(pll_predef_mclk); i++) {
638 p_entry = &pll_predef_mclk[i];
639 if (p_entry->mclk == mclk) {
640 found = true;
641 break;
642 }
643 }
644 if (!found) {
645 dev_err(cygaud->dev,
646 "%s No valid mclk freq (%u) found!\n", __func__, mclk);
647 return -EINVAL;
648 }
649
650 ch_clk = cygaud->audio_clk[p_entry->pll_ch_num];
651
652 if ((aio->clk_trace.cap_en) && (!aio->clk_trace.cap_clk_en)) {
653 error = clk_prepare_enable(ch_clk);
654 if (error) {
655 dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n",
656 __func__, error);
657 return error;
658 }
659 aio->clk_trace.cap_clk_en = true;
660 }
661
662 if ((aio->clk_trace.play_en) && (!aio->clk_trace.play_clk_en)) {
663 error = clk_prepare_enable(ch_clk);
664 if (error) {
665 dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n",
666 __func__, error);
667 return error;
668 }
669 aio->clk_trace.play_clk_en = true;
670 }
671
672 error = clk_set_rate(ch_clk, mclk);
673 if (error) {
674 dev_err(cygaud->dev, "%s Set MCLK rate failed: %d\n",
675 __func__, error);
676 return error;
677 }
678
679 return p_entry->pll_ch_num;
680}
681
682static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio,
683 struct cygnus_audio *cygaud)
684{
685 u32 value, i = 0;
686 u32 mask = 0xf;
687 u32 sclk;
688 bool found = false;
689 const struct _ssp_clk_coeff *p_entry = NULL;
690
691 for (i = 0; i < ARRAY_SIZE(ssp_clk_coeff); i++) {
692 p_entry = &ssp_clk_coeff[i];
693 if ((p_entry->rate == aio->lrclk) &&
694 (p_entry->sclk_rate == aio->bit_per_frame) &&
695 (p_entry->mclk == aio->mclk)) {
696 found = true;
697 break;
698 }
699 }
700 if (!found) {
701 dev_err(aio->cygaud->dev,
702 "No valid match found in ssp_clk_coeff array\n");
703 dev_err(aio->cygaud->dev, "lrclk = %u, bits/frame = %u, mclk = %u\n",
704 aio->lrclk, aio->bit_per_frame, aio->mclk);
705 return -EINVAL;
706 }
707
708 sclk = aio->bit_per_frame;
709 if (sclk == 512)
710 sclk = 0;
711 /* sclks_per_1fs_div = sclk cycles/32 */
712 sclk /= 32;
713 /* Set sclk rate */
714 switch (aio->port_type) {
715 case PORT_TDM:
716 /* Set number of bitclks per frame */
717 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
718 value &= ~(mask << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32);
719 value |= sclk << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32;
720 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
721 dev_dbg(aio->cygaud->dev,
722 "SCLKS_PER_1FS_DIV32 = 0x%x\n", value);
723 break;
724 case PORT_SPDIF:
725 break;
726 default:
727 dev_err(aio->cygaud->dev, "Unknown port type\n");
728 return -EINVAL;
729 }
730
731 /* Set MCLK_RATE ssp port (spdif and ssp are the same) */
732 value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
733 value &= ~(0xf << I2S_OUT_MCLKRATE_SHIFT);
734 value |= (p_entry->mclk_rate << I2S_OUT_MCLKRATE_SHIFT);
735 writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
736
737 dev_dbg(aio->cygaud->dev, "mclk cfg reg = 0x%x\n", value);
738 dev_dbg(aio->cygaud->dev, "bits per frame = %u, mclk = %u Hz, lrclk = %u Hz\n",
739 aio->bit_per_frame, aio->mclk, aio->lrclk);
740 return 0;
741}
742
743static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream,
744 struct snd_pcm_hw_params *params,
745 struct snd_soc_dai *dai)
746{
747 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
748 struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
749 int rate, bitres;
750 u32 value;
751 u32 mask = 0x1f;
752 int ret = 0;
753
754 dev_dbg(aio->cygaud->dev, "%s port = %d\n", __func__, aio->portnum);
755 dev_dbg(aio->cygaud->dev, "params_channels %d\n",
756 params_channels(params));
757 dev_dbg(aio->cygaud->dev, "rate %d\n", params_rate(params));
758 dev_dbg(aio->cygaud->dev, "format %d\n", params_format(params));
759
760 rate = params_rate(params);
761
762 switch (aio->mode) {
763 case CYGNUS_SSPMODE_TDM:
764 if ((rate == 192000) && (params_channels(params) > 4)) {
765 dev_err(aio->cygaud->dev, "Cannot run %d channels at %dHz\n",
766 params_channels(params), rate);
767 return -EINVAL;
768 }
769 break;
770 case CYGNUS_SSPMODE_I2S:
771 aio->bit_per_frame = 64; /* I2S must be 64 bit per frame */
772 break;
773 default:
774 dev_err(aio->cygaud->dev,
775 "%s port running in unknown mode\n", __func__);
776 return -EINVAL;
777 }
778
779 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
780 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
781 value &= ~BIT(BF_SRC_CFGX_BUFFER_PAIR_ENABLE);
782 /* Configure channels as mono or stereo/TDM */
783 if (params_channels(params) == 1)
784 value |= BIT(BF_SRC_CFGX_SAMPLE_CH_MODE);
785 else
786 value &= ~BIT(BF_SRC_CFGX_SAMPLE_CH_MODE);
787 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
788
789 switch (params_format(params)) {
790 case SNDRV_PCM_FORMAT_S8:
791 if (aio->port_type == PORT_SPDIF) {
792 dev_err(aio->cygaud->dev,
793 "SPDIF does not support 8bit format\n");
794 return -EINVAL;
795 }
796 bitres = 8;
797 break;
798
799 case SNDRV_PCM_FORMAT_S16_LE:
800 bitres = 16;
801 break;
802
803 case SNDRV_PCM_FORMAT_S32_LE:
804 /* 32 bit mode is coded as 0 */
805 bitres = 0;
806 break;
807
808 default:
809 return -EINVAL;
810 }
811
812 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
813 value &= ~(mask << BF_SRC_CFGX_BIT_RES);
814 value |= (bitres << BF_SRC_CFGX_BIT_RES);
815 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
816
817 } else {
818
819 switch (params_format(params)) {
820 case SNDRV_PCM_FORMAT_S16_LE:
821 value = readl(aio->cygaud->audio +
822 aio->regs.bf_destch_cfg);
823 value |= BIT(BF_DST_CFGX_CAP_MODE);
824 writel(value, aio->cygaud->audio +
825 aio->regs.bf_destch_cfg);
826 break;
827
828 case SNDRV_PCM_FORMAT_S32_LE:
829 value = readl(aio->cygaud->audio +
830 aio->regs.bf_destch_cfg);
831 value &= ~BIT(BF_DST_CFGX_CAP_MODE);
832 writel(value, aio->cygaud->audio +
833 aio->regs.bf_destch_cfg);
834 break;
835
836 default:
837 return -EINVAL;
838 }
839 }
840
841 aio->lrclk = rate;
842
843 if (!aio->is_slave)
844 ret = cygnus_ssp_set_clocks(aio, cygaud);
845
846 return ret;
847}
848
849/*
850 * This function sets the mclk frequency for pll clock
851 */
852static int cygnus_ssp_set_sysclk(struct snd_soc_dai *dai,
853 int clk_id, unsigned int freq, int dir)
854{
855 int sel;
856 u32 value;
857 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
858 struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
859
860 dev_dbg(aio->cygaud->dev,
861 "%s Enter port = %d\n", __func__, aio->portnum);
862 sel = pll_configure_mclk(cygaud, freq, aio);
863 if (sel < 0) {
864 dev_err(aio->cygaud->dev,
865 "%s Setting mclk failed.\n", __func__);
866 return -EINVAL;
867 }
868
869 aio->mclk = freq;
870
871 dev_dbg(aio->cygaud->dev, "%s Setting MCLKSEL to %d\n", __func__, sel);
872 value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
873 value &= ~(0xf << I2S_OUT_PLLCLKSEL_SHIFT);
874 value |= (sel << I2S_OUT_PLLCLKSEL_SHIFT);
875 writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
876
877 return 0;
878}
879
880static int cygnus_ssp_startup(struct snd_pcm_substream *substream,
881 struct snd_soc_dai *dai)
882{
883 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
884
885 snd_soc_dai_set_dma_data(dai, substream, aio);
886 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
887 aio->clk_trace.play_en = true;
888 else
889 aio->clk_trace.cap_en = true;
890
891 return 0;
892}
893
894static void cygnus_ssp_shutdown(struct snd_pcm_substream *substream,
895 struct snd_soc_dai *dai)
896{
897 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
898
899 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
900 aio->clk_trace.play_en = false;
901 else
902 aio->clk_trace.cap_en = false;
903
904 if (!aio->is_slave) {
905 u32 val;
906
907 val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
908 val &= CYGNUS_PLLCLKSEL_MASK;
909 if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) {
910 dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n",
911 val);
912 return;
913 }
914
915 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
916 if (aio->clk_trace.play_clk_en) {
917 clk_disable_unprepare(aio->cygaud->
918 audio_clk[val]);
919 aio->clk_trace.play_clk_en = false;
920 }
921 } else {
922 if (aio->clk_trace.cap_clk_en) {
923 clk_disable_unprepare(aio->cygaud->
924 audio_clk[val]);
925 aio->clk_trace.cap_clk_en = false;
926 }
927 }
928 }
929}
930
931/*
932 * Bit Update Notes
933 * 31 Yes TDM Mode (1 = TDM, 0 = i2s)
934 * 30 Yes Slave Mode (1 = Slave, 0 = Master)
935 * 29:26 No Sclks per frame
936 * 25:18 Yes FS Width
937 * 17:14 No Valid Slots
938 * 13 No Bits (1 = 16 bits, 0 = 32 bits)
939 * 12:08 No Bits per samp
940 * 07 Yes Justifcation (1 = LSB, 0 = MSB)
941 * 06 Yes Alignment (1 = Delay 1 clk, 0 = no delay
942 * 05 Yes SCLK polarity (1 = Rising, 0 = Falling)
943 * 04 Yes LRCLK Polarity (1 = High for left, 0 = Low for left)
944 * 03:02 Yes Reserved - write as zero
945 * 01 No Data Enable
946 * 00 No CLK Enable
947 */
948#define I2S_OUT_CFG_REG_UPDATE_MASK 0x3C03FF03
949
950/* Input cfg is same as output, but the FS width is not a valid field */
951#define I2S_IN_CFG_REG_UPDATE_MASK (I2S_OUT_CFG_REG_UPDATE_MASK | 0x03FC0000)
952
953int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai, int len)
954{
955 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
956
957 if ((len > 0) && (len < 256)) {
958 aio->fsync_width = len;
959 return 0;
960 } else {
961 return -EINVAL;
962 }
963}
964
965static int cygnus_ssp_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
966{
967 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
968 u32 ssp_curcfg;
969 u32 ssp_newcfg;
970 u32 ssp_outcfg;
971 u32 ssp_incfg;
972 u32 val;
973 u32 mask;
974
975 dev_dbg(aio->cygaud->dev, "%s Enter fmt: %x\n", __func__, fmt);
976
977 if (aio->port_type == PORT_SPDIF)
978 return -EINVAL;
979
980 ssp_newcfg = 0;
981
982 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
983 case SND_SOC_DAIFMT_CBM_CFM:
984 ssp_newcfg |= BIT(I2S_OUT_CFGX_SLAVE_MODE);
985 aio->is_slave = 1;
986 break;
987 case SND_SOC_DAIFMT_CBS_CFS:
988 ssp_newcfg &= ~BIT(I2S_OUT_CFGX_SLAVE_MODE);
989 aio->is_slave = 0;
990 break;
991 default:
992 return -EINVAL;
993 }
994
995 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
996 case SND_SOC_DAIFMT_I2S:
997 ssp_newcfg |= BIT(I2S_OUT_CFGX_DATA_ALIGNMENT);
998 ssp_newcfg |= BIT(I2S_OUT_CFGX_FSYNC_WIDTH);
999 aio->mode = CYGNUS_SSPMODE_I2S;
1000 break;
1001
1002 case SND_SOC_DAIFMT_DSP_A:
1003 case SND_SOC_DAIFMT_DSP_B:
1004 ssp_newcfg |= BIT(I2S_OUT_CFGX_TDM_MODE);
1005
1006 /* DSP_A = data after FS, DSP_B = data during FS */
1007 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A)
1008 ssp_newcfg |= BIT(I2S_OUT_CFGX_DATA_ALIGNMENT);
1009
1010 if ((aio->fsync_width > 0) && (aio->fsync_width < 256))
1011 ssp_newcfg |=
1012 (aio->fsync_width << I2S_OUT_CFGX_FSYNC_WIDTH);
1013 else
1014 ssp_newcfg |= BIT(I2S_OUT_CFGX_FSYNC_WIDTH);
1015
1016 aio->mode = CYGNUS_SSPMODE_TDM;
1017 break;
1018
1019 default:
1020 return -EINVAL;
1021 }
1022
1023 /*
1024 * SSP out cfg.
1025 * Retain bits we do not want to update, then OR in new bits
1026 */
1027 ssp_curcfg = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
1028 ssp_outcfg = (ssp_curcfg & I2S_OUT_CFG_REG_UPDATE_MASK) | ssp_newcfg;
1029 writel(ssp_outcfg, aio->cygaud->audio + aio->regs.i2s_cfg);
1030
1031 /*
1032 * SSP in cfg.
1033 * Retain bits we do not want to update, then OR in new bits
1034 */
1035 ssp_curcfg = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
1036 ssp_incfg = (ssp_curcfg & I2S_IN_CFG_REG_UPDATE_MASK) | ssp_newcfg;
1037 writel(ssp_incfg, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
1038
1039 val = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
1040
1041 /*
1042 * Configure the word clk and bit clk as output or tristate
1043 * Each port has 4 bits for controlling its pins.
1044 * Shift the mask based upon port number.
1045 */
1046 mask = BIT(AUD_MISC_SEROUT_LRCK_OE)
1047 | BIT(AUD_MISC_SEROUT_SCLK_OE)
1048 | BIT(AUD_MISC_SEROUT_MCLK_OE);
1049 mask = mask << (aio->portnum * 4);
1050 if (aio->is_slave)
1051 /* Set bit for tri-state */
1052 val |= mask;
1053 else
1054 /* Clear bit for drive */
1055 val &= ~mask;
1056
1057 dev_dbg(aio->cygaud->dev, "%s Set OE bits 0x%x\n", __func__, val);
1058 writel(val, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
1059
1060 return 0;
1061}
1062
1063static int cygnus_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
1064 struct snd_soc_dai *dai)
1065{
1066 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
1067 struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
1068
1069 dev_dbg(aio->cygaud->dev,
1070 "%s cmd %d at port = %d\n", __func__, cmd, aio->portnum);
1071
1072 switch (cmd) {
1073 case SNDRV_PCM_TRIGGER_START:
1074 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1075 case SNDRV_PCM_TRIGGER_RESUME:
1076 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1077 audio_ssp_out_enable(aio);
1078 else
1079 audio_ssp_in_enable(aio);
1080 cygaud->active_ports++;
1081
1082 break;
1083
1084 case SNDRV_PCM_TRIGGER_STOP:
1085 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1086 case SNDRV_PCM_TRIGGER_SUSPEND:
1087 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1088 audio_ssp_out_disable(aio);
1089 else
1090 audio_ssp_in_disable(aio);
1091 cygaud->active_ports--;
1092 break;
1093
1094 default:
1095 return -EINVAL;
1096 }
1097
1098 return 0;
1099}
1100
1101static int cygnus_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
1102 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
1103{
1104 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
1105 u32 value;
1106 int bits_per_slot = 0; /* default to 32-bits per slot */
1107 int frame_bits;
1108 unsigned int active_slots;
1109 bool found = false;
1110 int i;
1111
1112 if (tx_mask != rx_mask) {
1113 dev_err(aio->cygaud->dev,
1114 "%s tx_mask must equal rx_mask\n", __func__);
1115 return -EINVAL;
1116 }
1117
1118 active_slots = hweight32(tx_mask);
1119
1120 if ((active_slots < 0) || (active_slots > 16))
1121 return -EINVAL;
1122
1123 /* Slot value must be even */
1124 if (active_slots % 2)
1125 return -EINVAL;
1126
1127 /* We encode 16 slots as 0 in the reg */
1128 if (active_slots == 16)
1129 active_slots = 0;
1130
1131 /* Slot Width is either 16 or 32 */
1132 switch (slot_width) {
1133 case 16:
1134 bits_per_slot = 1;
1135 break;
1136 case 32:
1137 bits_per_slot = 0;
1138 break;
1139 default:
1140 bits_per_slot = 0;
1141 dev_warn(aio->cygaud->dev,
1142 "%s Defaulting Slot Width to 32\n", __func__);
1143 }
1144
1145 frame_bits = slots * slot_width;
1146
1147 for (i = 0; i < ARRAY_SIZE(ssp_valid_tdm_framesize); i++) {
1148 if (ssp_valid_tdm_framesize[i] == frame_bits) {
1149 found = true;
1150 break;
1151 }
1152 }
1153
1154 if (!found) {
1155 dev_err(aio->cygaud->dev,
1156 "%s In TDM mode, frame bits INVALID (%d)\n",
1157 __func__, frame_bits);
1158 return -EINVAL;
1159 }
1160
1161 aio->bit_per_frame = frame_bits;
1162
1163 dev_dbg(aio->cygaud->dev, "%s active_slots %u, bits per frame %d\n",
1164 __func__, active_slots, frame_bits);
1165
1166 /* Set capture side of ssp port */
1167 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
1168 value &= ~(0xf << I2S_OUT_CFGX_VALID_SLOT);
1169 value |= (active_slots << I2S_OUT_CFGX_VALID_SLOT);
1170 value &= ~BIT(I2S_OUT_CFGX_BITS_PER_SLOT);
1171 value |= (bits_per_slot << I2S_OUT_CFGX_BITS_PER_SLOT);
1172 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
1173
1174 /* Set playback side of ssp port */
1175 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
1176 value &= ~(0xf << I2S_OUT_CFGX_VALID_SLOT);
1177 value |= (active_slots << I2S_OUT_CFGX_VALID_SLOT);
1178 value &= ~BIT(I2S_OUT_CFGX_BITS_PER_SLOT);
1179 value |= (bits_per_slot << I2S_OUT_CFGX_BITS_PER_SLOT);
1180 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
1181
1182 return 0;
1183}
1184
1185#ifdef CONFIG_PM_SLEEP
1186static int cygnus_ssp_suspend(struct snd_soc_dai *cpu_dai)
1187{
1188 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
1189
1190 if (!aio->is_slave) {
1191 u32 val;
1192
1193 val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
1194 val &= CYGNUS_PLLCLKSEL_MASK;
1195 if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) {
1196 dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n",
1197 val);
1198 return -EINVAL;
1199 }
1200
1201 if (aio->clk_trace.cap_clk_en)
1202 clk_disable_unprepare(aio->cygaud->audio_clk[val]);
1203 if (aio->clk_trace.play_clk_en)
1204 clk_disable_unprepare(aio->cygaud->audio_clk[val]);
1205
1206 aio->pll_clk_num = val;
1207 }
1208
1209 return 0;
1210}
1211
1212static int cygnus_ssp_resume(struct snd_soc_dai *cpu_dai)
1213{
1214 struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
1215 int error;
1216
1217 if (!aio->is_slave) {
1218 if (aio->clk_trace.cap_clk_en) {
1219 error = clk_prepare_enable(aio->cygaud->
1220 audio_clk[aio->pll_clk_num]);
1221 if (error) {
1222 dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n",
1223 __func__);
1224 return -EINVAL;
1225 }
1226 }
1227 if (aio->clk_trace.play_clk_en) {
1228 error = clk_prepare_enable(aio->cygaud->
1229 audio_clk[aio->pll_clk_num]);
1230 if (error) {
1231 if (aio->clk_trace.cap_clk_en)
1232 clk_disable_unprepare(aio->cygaud->
1233 audio_clk[aio->pll_clk_num]);
1234 dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n",
1235 __func__);
1236 return -EINVAL;
1237 }
1238 }
1239 }
1240
1241 return 0;
1242}
1243#else
1244#define cygnus_ssp_suspend NULL
1245#define cygnus_ssp_resume NULL
1246#endif
1247
1248static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = {
1249 .startup = cygnus_ssp_startup,
1250 .shutdown = cygnus_ssp_shutdown,
1251 .trigger = cygnus_ssp_trigger,
1252 .hw_params = cygnus_ssp_hw_params,
1253 .set_fmt = cygnus_ssp_set_fmt,
1254 .set_sysclk = cygnus_ssp_set_sysclk,
1255 .set_tdm_slot = cygnus_set_dai_tdm_slot,
1256};
1257
1258
1259#define INIT_CPU_DAI(num) { \
1260 .name = "cygnus-ssp" #num, \
1261 .playback = { \
1262 .channels_min = 1, \
1263 .channels_max = 16, \
1264 .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | \
1265 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
1266 SNDRV_PCM_RATE_192000, \
1267 .formats = SNDRV_PCM_FMTBIT_S8 | \
1268 SNDRV_PCM_FMTBIT_S16_LE | \
1269 SNDRV_PCM_FMTBIT_S32_LE, \
1270 }, \
1271 .capture = { \
1272 .channels_min = 2, \
1273 .channels_max = 16, \
1274 .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | \
1275 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
1276 SNDRV_PCM_RATE_192000, \
1277 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
1278 SNDRV_PCM_FMTBIT_S32_LE, \
1279 }, \
1280 .ops = &cygnus_ssp_dai_ops, \
1281 .suspend = cygnus_ssp_suspend, \
1282 .resume = cygnus_ssp_resume, \
1283}
1284
1285static const struct snd_soc_dai_driver cygnus_ssp_dai_info[] = {
1286 INIT_CPU_DAI(0),
1287 INIT_CPU_DAI(1),
1288 INIT_CPU_DAI(2),
1289};
1290
1291static struct snd_soc_dai_driver cygnus_spdif_dai_info = {
1292 .name = "cygnus-spdif",
1293 .playback = {
1294 .channels_min = 2,
1295 .channels_max = 2,
1296 .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 |
1297 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
1298 SNDRV_PCM_RATE_192000,
1299 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1300 SNDRV_PCM_FMTBIT_S32_LE,
1301 },
1302 .ops = &cygnus_ssp_dai_ops,
1303 .suspend = cygnus_ssp_suspend,
1304 .resume = cygnus_ssp_resume,
1305};
1306
1307static struct snd_soc_dai_driver cygnus_ssp_dai[CYGNUS_MAX_PORTS];
1308
1309static const struct snd_soc_component_driver cygnus_ssp_component = {
1310 .name = "cygnus-audio",
1311};
1312
1313/*
1314 * Return < 0 if error
1315 * Return 0 if disabled
1316 * Return 1 if enabled and node is parsed successfully
1317 */
1318static int parse_ssp_child_node(struct platform_device *pdev,
1319 struct device_node *dn,
1320 struct cygnus_audio *cygaud,
1321 struct snd_soc_dai_driver *p_dai)
1322{
1323 struct cygnus_aio_port *aio;
1324 struct cygnus_ssp_regs ssp_regs[3];
1325 u32 rawval;
1326 int portnum = -1;
1327 enum cygnus_audio_port_type port_type;
1328
1329 if (of_property_read_u32(dn, "reg", &rawval)) {
1330 dev_err(&pdev->dev, "Missing reg property\n");
1331 return -EINVAL;
1332 }
1333
1334 portnum = rawval;
1335 switch (rawval) {
1336 case 0:
1337 ssp_regs[0] = INIT_SSP_REGS(0);
1338 port_type = PORT_TDM;
1339 break;
1340 case 1:
1341 ssp_regs[1] = INIT_SSP_REGS(1);
1342 port_type = PORT_TDM;
1343 break;
1344 case 2:
1345 ssp_regs[2] = INIT_SSP_REGS(2);
1346 port_type = PORT_TDM;
1347 break;
1348 case 3:
1349 port_type = PORT_SPDIF;
1350 break;
1351 default:
1352 dev_err(&pdev->dev, "Bad value for reg %u\n", rawval);
1353 return -EINVAL;
1354 }
1355
1356 aio = &cygaud->portinfo[portnum];
1357 aio->cygaud = cygaud;
1358 aio->portnum = portnum;
1359 aio->port_type = port_type;
1360 aio->fsync_width = -1;
1361
1362 switch (port_type) {
1363 case PORT_TDM:
1364 aio->regs = ssp_regs[portnum];
1365 *p_dai = cygnus_ssp_dai_info[portnum];
1366 aio->mode = CYGNUS_SSPMODE_UNKNOWN;
1367 break;
1368
1369 case PORT_SPDIF:
1370 aio->regs.bf_sourcech_cfg = BF_SRC_CFG3_OFFSET;
1371 aio->regs.bf_sourcech_ctrl = BF_SRC_CTRL3_OFFSET;
1372 aio->regs.i2s_mclk_cfg = SPDIF_MCLK_CFG_OFFSET;
1373 aio->regs.i2s_stream_cfg = SPDIF_STREAM_CFG_OFFSET;
1374 *p_dai = cygnus_spdif_dai_info;
1375
1376 /* For the purposes of this code SPDIF can be I2S mode */
1377 aio->mode = CYGNUS_SSPMODE_I2S;
1378 break;
1379 default:
1380 dev_err(&pdev->dev, "Bad value for port_type %d\n", port_type);
1381 return -EINVAL;
1382 }
1383
1384 dev_dbg(&pdev->dev, "%s portnum = %d\n", __func__, aio->portnum);
1385 aio->streams_on = 0;
1386 aio->cygaud->dev = &pdev->dev;
1387 aio->clk_trace.play_en = false;
1388 aio->clk_trace.cap_en = false;
1389
1390 audio_ssp_init_portregs(aio);
1391 return 0;
1392}
1393
1394static int audio_clk_init(struct platform_device *pdev,
1395 struct cygnus_audio *cygaud)
1396{
1397 int i;
1398 char clk_name[PROP_LEN_MAX];
1399
1400 for (i = 0; i < ARRAY_SIZE(cygaud->audio_clk); i++) {
1401 snprintf(clk_name, PROP_LEN_MAX, "ch%d_audio", i);
1402
1403 cygaud->audio_clk[i] = devm_clk_get(&pdev->dev, clk_name);
1404 if (IS_ERR(cygaud->audio_clk[i]))
1405 return PTR_ERR(cygaud->audio_clk[i]);
1406 }
1407
1408 return 0;
1409}
1410
1411static int cygnus_ssp_probe(struct platform_device *pdev)
1412{
1413 struct device *dev = &pdev->dev;
1414 struct device_node *child_node;
1415 struct resource *res = pdev->resource;
1416 struct cygnus_audio *cygaud;
1417 int err = -EINVAL;
1418 int node_count;
1419 int active_port_count;
1420
1421 cygaud = devm_kzalloc(dev, sizeof(struct cygnus_audio), GFP_KERNEL);
1422 if (!cygaud)
1423 return -ENOMEM;
1424
1425 dev_set_drvdata(dev, cygaud);
1426
1427 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aud");
1428 cygaud->audio = devm_ioremap_resource(dev, res);
1429 if (IS_ERR(cygaud->audio))
1430 return PTR_ERR(cygaud->audio);
1431
1432 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "i2s_in");
1433 cygaud->i2s_in = devm_ioremap_resource(dev, res);
1434 if (IS_ERR(cygaud->i2s_in))
1435 return PTR_ERR(cygaud->i2s_in);
1436
1437 /* Tri-state all controlable pins until we know that we need them */
1438 writel(CYGNUS_SSP_TRISTATE_MASK,
1439 cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
1440
1441 node_count = of_get_child_count(pdev->dev.of_node);
1442 if ((node_count < 1) || (node_count > CYGNUS_MAX_PORTS)) {
1443 dev_err(dev, "child nodes is %d. Must be between 1 and %d\n",
1444 node_count, CYGNUS_MAX_PORTS);
1445 return -EINVAL;
1446 }
1447
1448 active_port_count = 0;
1449
1450 for_each_available_child_of_node(pdev->dev.of_node, child_node) {
1451 err = parse_ssp_child_node(pdev, child_node, cygaud,
1452 &cygnus_ssp_dai[active_port_count]);
1453
1454 /* negative is err, 0 is active and good, 1 is disabled */
1455 if (err < 0)
1456 return err;
1457 else if (!err) {
1458 dev_dbg(dev, "Activating DAI: %s\n",
1459 cygnus_ssp_dai[active_port_count].name);
1460 active_port_count++;
1461 }
1462 }
1463
1464 cygaud->dev = dev;
1465 cygaud->active_ports = 0;
1466
1467 dev_dbg(dev, "Registering %d DAIs\n", active_port_count);
1468 err = snd_soc_register_component(dev, &cygnus_ssp_component,
1469 cygnus_ssp_dai, active_port_count);
1470 if (err) {
1471 dev_err(dev, "snd_soc_register_dai failed\n");
1472 return err;
1473 }
1474
1475 cygaud->irq_num = platform_get_irq(pdev, 0);
1476 if (cygaud->irq_num <= 0) {
1477 dev_err(dev, "platform_get_irq failed\n");
1478 err = cygaud->irq_num;
1479 goto err_irq;
1480 }
1481
1482 err = audio_clk_init(pdev, cygaud);
1483 if (err) {
1484 dev_err(dev, "audio clock initialization failed\n");
1485 goto err_irq;
1486 }
1487
1488 err = cygnus_soc_platform_register(dev, cygaud);
1489 if (err) {
1490 dev_err(dev, "platform reg error %d\n", err);
1491 goto err_irq;
1492 }
1493
1494 return 0;
1495
1496err_irq:
1497 snd_soc_unregister_component(dev);
1498 return err;
1499}
1500
1501static int cygnus_ssp_remove(struct platform_device *pdev)
1502{
1503 cygnus_soc_platform_unregister(&pdev->dev);
1504 snd_soc_unregister_component(&pdev->dev);
1505
1506 return 0;
1507}
1508
1509static const struct of_device_id cygnus_ssp_of_match[] = {
1510 { .compatible = "brcm,cygnus-audio" },
1511 {},
1512};
1513MODULE_DEVICE_TABLE(of, cygnus_ssp_of_match);
1514
1515static struct platform_driver cygnus_ssp_driver = {
1516 .probe = cygnus_ssp_probe,
1517 .remove = cygnus_ssp_remove,
1518 .driver = {
1519 .name = "cygnus-ssp",
1520 .of_match_table = cygnus_ssp_of_match,
1521 },
1522};
1523
1524module_platform_driver(cygnus_ssp_driver);
1525
1526MODULE_ALIAS("platform:cygnus-ssp");
1527MODULE_LICENSE("GPL v2");
1528MODULE_AUTHOR("Broadcom");
1529MODULE_DESCRIPTION("Cygnus ASoC SSP Interface");
diff --git a/sound/soc/bcm/cygnus-ssp.h b/sound/soc/bcm/cygnus-ssp.h
new file mode 100644
index 000000000000..33dd34305928
--- /dev/null
+++ b/sound/soc/bcm/cygnus-ssp.h
@@ -0,0 +1,139 @@
1/*
2 * Copyright (C) 2014-2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#ifndef __CYGNUS_SSP_H__
14#define __CYGNUS_SSP_H__
15
16#define CYGNUS_TDM_DAI_MAX_SLOTS 16
17
18#define CYGNUS_MAX_PLAYBACK_PORTS 4
19#define CYGNUS_MAX_CAPTURE_PORTS 3
20#define CYGNUS_MAX_I2S_PORTS 3
21#define CYGNUS_MAX_PORTS CYGNUS_MAX_PLAYBACK_PORTS
22#define CYGNUS_AUIDO_MAX_NUM_CLKS 3
23
24#define CYGNUS_SSP_FRAMEBITS_DIV 1
25
26#define CYGNUS_SSPMODE_I2S 0
27#define CYGNUS_SSPMODE_TDM 1
28#define CYGNUS_SSPMODE_UNKNOWN -1
29
30#define CYGNUS_SSP_CLKSRC_PLL 0
31
32/* Max string length of our dt property names */
33#define PROP_LEN_MAX 40
34
35struct ringbuf_regs {
36 unsigned rdaddr;
37 unsigned wraddr;
38 unsigned baseaddr;
39 unsigned endaddr;
40 unsigned fmark; /* freemark for play, fullmark for caputure */
41 unsigned period_bytes;
42 unsigned buf_size;
43};
44
45#define RINGBUF_REG_PLAYBACK(num) ((struct ringbuf_regs) { \
46 .rdaddr = SRC_RBUF_ ##num## _RDADDR_OFFSET, \
47 .wraddr = SRC_RBUF_ ##num## _WRADDR_OFFSET, \
48 .baseaddr = SRC_RBUF_ ##num## _BASEADDR_OFFSET, \
49 .endaddr = SRC_RBUF_ ##num## _ENDADDR_OFFSET, \
50 .fmark = SRC_RBUF_ ##num## _FREE_MARK_OFFSET, \
51 .period_bytes = 0, \
52 .buf_size = 0, \
53})
54
55#define RINGBUF_REG_CAPTURE(num) ((struct ringbuf_regs) { \
56 .rdaddr = DST_RBUF_ ##num## _RDADDR_OFFSET, \
57 .wraddr = DST_RBUF_ ##num## _WRADDR_OFFSET, \
58 .baseaddr = DST_RBUF_ ##num## _BASEADDR_OFFSET, \
59 .endaddr = DST_RBUF_ ##num## _ENDADDR_OFFSET, \
60 .fmark = DST_RBUF_ ##num## _FULL_MARK_OFFSET, \
61 .period_bytes = 0, \
62 .buf_size = 0, \
63})
64
65enum cygnus_audio_port_type {
66 PORT_TDM,
67 PORT_SPDIF,
68};
69
70struct cygnus_ssp_regs {
71 u32 i2s_stream_cfg;
72 u32 i2s_cfg;
73 u32 i2s_cap_stream_cfg;
74 u32 i2s_cap_cfg;
75 u32 i2s_mclk_cfg;
76
77 u32 bf_destch_ctrl;
78 u32 bf_destch_cfg;
79 u32 bf_sourcech_ctrl;
80 u32 bf_sourcech_cfg;
81 u32 bf_sourcech_grp;
82};
83
84struct cygnus_track_clk {
85 bool cap_en;
86 bool play_en;
87 bool cap_clk_en;
88 bool play_clk_en;
89};
90
91struct cygnus_aio_port {
92 int portnum;
93 int mode;
94 bool is_slave;
95 int streams_on; /* will be 0 if both capture and play are off */
96 int fsync_width;
97 int port_type;
98
99 u32 mclk;
100 u32 lrclk;
101 u32 bit_per_frame;
102 u32 pll_clk_num;
103
104 struct cygnus_audio *cygaud;
105 struct cygnus_ssp_regs regs;
106
107 struct ringbuf_regs play_rb_regs;
108 struct ringbuf_regs capture_rb_regs;
109
110 struct snd_pcm_substream *play_stream;
111 struct snd_pcm_substream *capture_stream;
112
113 struct cygnus_track_clk clk_trace;
114};
115
116
117struct cygnus_audio {
118 struct cygnus_aio_port portinfo[CYGNUS_MAX_PORTS];
119
120 int irq_num;
121 void __iomem *audio;
122 struct device *dev;
123 void __iomem *i2s_in;
124
125 struct clk *audio_clk[CYGNUS_AUIDO_MAX_NUM_CLKS];
126 int active_ports;
127 unsigned long vco_rate;
128};
129
130extern int cygnus_ssp_get_mode(struct snd_soc_dai *cpu_dai);
131extern int cygnus_ssp_add_pll_tweak_controls(struct snd_soc_pcm_runtime *rtd);
132extern int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai,
133 int len);
134extern int cygnus_soc_platform_register(struct device *dev,
135 struct cygnus_audio *cygaud);
136extern int cygnus_soc_platform_unregister(struct device *dev);
137extern int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai,
138 int len);
139#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f3fb98f0a995..1cd6ab344d67 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -32,6 +32,7 @@ config SND_SOC_ALL_CODECS
32 select SND_SOC_ADAU1977_SPI if SPI_MASTER 32 select SND_SOC_ADAU1977_SPI if SPI_MASTER
33 select SND_SOC_ADAU1977_I2C if I2C 33 select SND_SOC_ADAU1977_I2C if I2C
34 select SND_SOC_ADAU1701 if I2C 34 select SND_SOC_ADAU1701 if I2C
35 select SND_SOC_ADAU7002
35 select SND_SOC_ADS117X 36 select SND_SOC_ADS117X
36 select SND_SOC_AK4104 if SPI_MASTER 37 select SND_SOC_AK4104 if SPI_MASTER
37 select SND_SOC_AK4535 if I2C 38 select SND_SOC_AK4535 if I2C
@@ -46,6 +47,7 @@ config SND_SOC_ALL_CODECS
46 select SND_SOC_BT_SCO 47 select SND_SOC_BT_SCO
47 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 48 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
48 select SND_SOC_CS35L32 if I2C 49 select SND_SOC_CS35L32 if I2C
50 select SND_SOC_CS35L33 if I2C
49 select SND_SOC_CS42L51_I2C if I2C 51 select SND_SOC_CS42L51_I2C if I2C
50 select SND_SOC_CS42L52 if I2C && INPUT 52 select SND_SOC_CS42L52 if I2C && INPUT
51 select SND_SOC_CS42L56 if I2C && INPUT 53 select SND_SOC_CS42L56 if I2C && INPUT
@@ -57,6 +59,7 @@ config SND_SOC_ALL_CODECS
57 select SND_SOC_CS42XX8_I2C if I2C 59 select SND_SOC_CS42XX8_I2C if I2C
58 select SND_SOC_CS4349 if I2C 60 select SND_SOC_CS4349 if I2C
59 select SND_SOC_CS47L24 if MFD_CS47L24 61 select SND_SOC_CS47L24 if MFD_CS47L24
62 select SND_SOC_CS53L30 if I2C
60 select SND_SOC_CX20442 if TTY 63 select SND_SOC_CX20442 if TTY
61 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI 64 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
62 select SND_SOC_DA7213 if I2C 65 select SND_SOC_DA7213 if I2C
@@ -84,6 +87,7 @@ config SND_SOC_ALL_CODECS
84 select SND_SOC_MAX98925 if I2C 87 select SND_SOC_MAX98925 if I2C
85 select SND_SOC_MAX98926 if I2C 88 select SND_SOC_MAX98926 if I2C
86 select SND_SOC_MAX9850 if I2C 89 select SND_SOC_MAX9850 if I2C
90 select SND_SOC_MAX9860 if I2C
87 select SND_SOC_MAX9768 if I2C 91 select SND_SOC_MAX9768 if I2C
88 select SND_SOC_MAX9877 if I2C 92 select SND_SOC_MAX9877 if I2C
89 select SND_SOC_MC13783 if MFD_MC13XXX 93 select SND_SOC_MC13783 if MFD_MC13XXX
@@ -269,8 +273,12 @@ config SND_SOC_AD1980
269config SND_SOC_AD73311 273config SND_SOC_AD73311
270 tristate 274 tristate
271 275
276config SND_SOC_ADAU_UTILS
277 tristate
278
272config SND_SOC_ADAU1373 279config SND_SOC_ADAU1373
273 tristate 280 tristate
281 select SND_SOC_ADAU_UTILS
274 282
275config SND_SOC_ADAU1701 283config SND_SOC_ADAU1701
276 tristate "Analog Devices ADAU1701 CODEC" 284 tristate "Analog Devices ADAU1701 CODEC"
@@ -280,6 +288,7 @@ config SND_SOC_ADAU1701
280config SND_SOC_ADAU17X1 288config SND_SOC_ADAU17X1
281 tristate 289 tristate
282 select SND_SOC_SIGMADSP_REGMAP 290 select SND_SOC_SIGMADSP_REGMAP
291 select SND_SOC_ADAU_UTILS
283 292
284config SND_SOC_ADAU1761 293config SND_SOC_ADAU1761
285 tristate 294 tristate
@@ -322,6 +331,9 @@ config SND_SOC_ADAU1977_I2C
322 select SND_SOC_ADAU1977 331 select SND_SOC_ADAU1977
323 select REGMAP_I2C 332 select REGMAP_I2C
324 333
334config SND_SOC_ADAU7002
335 tristate "Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter"
336
325config SND_SOC_ADAV80X 337config SND_SOC_ADAV80X
326 tristate 338 tristate
327 339
@@ -371,7 +383,7 @@ config SND_SOC_ALC5632
371 tristate 383 tristate
372 384
373config SND_SOC_BT_SCO 385config SND_SOC_BT_SCO
374 tristate 386 tristate "Dummy BT SCO codec driver"
375 387
376config SND_SOC_CQ0093VC 388config SND_SOC_CQ0093VC
377 tristate 389 tristate
@@ -380,6 +392,10 @@ config SND_SOC_CS35L32
380 tristate "Cirrus Logic CS35L32 CODEC" 392 tristate "Cirrus Logic CS35L32 CODEC"
381 depends on I2C 393 depends on I2C
382 394
395config SND_SOC_CS35L33
396 tristate "Cirrus Logic CS35L33 CODEC"
397 depends on I2C
398
383config SND_SOC_CS42L51 399config SND_SOC_CS42L51
384 tristate 400 tristate
385 401
@@ -450,6 +466,11 @@ config SND_SOC_CS4349
450config SND_SOC_CS47L24 466config SND_SOC_CS47L24
451 tristate 467 tristate
452 468
469# Cirrus Logic Quad-Channel ADC
470config SND_SOC_CS53L30
471 tristate "Cirrus Logic CS53L30 CODEC"
472 depends on I2C
473
453config SND_SOC_CX20442 474config SND_SOC_CX20442
454 tristate 475 tristate
455 depends on TTY 476 depends on TTY
@@ -536,6 +557,10 @@ config SND_SOC_MAX98357A
536config SND_SOC_MAX98371 557config SND_SOC_MAX98371
537 tristate 558 tristate
538 559
560config SND_SOC_MAX98504
561 tristate "Maxim MAX98504 speaker amplifier"
562 depends on I2C
563
539config SND_SOC_MAX9867 564config SND_SOC_MAX9867
540 tristate 565 tristate
541 566
@@ -548,6 +573,11 @@ config SND_SOC_MAX98926
548config SND_SOC_MAX9850 573config SND_SOC_MAX9850
549 tristate 574 tristate
550 575
576config SND_SOC_MAX9860
577 tristate "Maxim MAX9860 Mono Audio Voice Codec"
578 depends on I2C
579 select REGMAP_I2C
580
551config SND_SOC_PCM1681 581config SND_SOC_PCM1681
552 tristate "Texas Instruments PCM1681 CODEC" 582 tristate "Texas Instruments PCM1681 CODEC"
553 depends on I2C 583 depends on I2C
@@ -644,6 +674,9 @@ config SND_SOC_RT298
644config SND_SOC_RT5514 674config SND_SOC_RT5514
645 tristate 675 tristate
646 676
677config SND_SOC_RT5514_SPI
678 tristate
679
647config SND_SOC_RT5616 680config SND_SOC_RT5616
648 tristate "Realtek RT5616 CODEC" 681 tristate "Realtek RT5616 CODEC"
649 depends on I2C 682 depends on I2C
@@ -969,7 +1002,8 @@ config SND_SOC_WM8983
969 tristate 1002 tristate
970 1003
971config SND_SOC_WM8985 1004config SND_SOC_WM8985
972 tristate 1005 tristate "Wolfson Microelectronics WM8985 and WM8758 codec driver"
1006 depends on SND_SOC_I2C_AND_SPI
973 1007
974config SND_SOC_WM8988 1008config SND_SOC_WM8988
975 tristate 1009 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 0f548fd34ca3..58036af2c7d9 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -7,6 +7,7 @@ snd-soc-ad193x-spi-objs := ad193x-spi.o
7snd-soc-ad193x-i2c-objs := ad193x-i2c.o 7snd-soc-ad193x-i2c-objs := ad193x-i2c.o
8snd-soc-ad1980-objs := ad1980.o 8snd-soc-ad1980-objs := ad1980.o
9snd-soc-ad73311-objs := ad73311.o 9snd-soc-ad73311-objs := ad73311.o
10snd-soc-adau-utils-objs := adau-utils.o
10snd-soc-adau1373-objs := adau1373.o 11snd-soc-adau1373-objs := adau1373.o
11snd-soc-adau1701-objs := adau1701.o 12snd-soc-adau1701-objs := adau1701.o
12snd-soc-adau17x1-objs := adau17x1.o 13snd-soc-adau17x1-objs := adau17x1.o
@@ -19,6 +20,7 @@ snd-soc-adau1781-spi-objs := adau1781-spi.o
19snd-soc-adau1977-objs := adau1977.o 20snd-soc-adau1977-objs := adau1977.o
20snd-soc-adau1977-spi-objs := adau1977-spi.o 21snd-soc-adau1977-spi-objs := adau1977-spi.o
21snd-soc-adau1977-i2c-objs := adau1977-i2c.o 22snd-soc-adau1977-i2c-objs := adau1977-i2c.o
23snd-soc-adau7002-objs := adau7002.o
22snd-soc-adav80x-objs := adav80x.o 24snd-soc-adav80x-objs := adav80x.o
23snd-soc-adav801-objs := adav801.o 25snd-soc-adav801-objs := adav801.o
24snd-soc-adav803-objs := adav803.o 26snd-soc-adav803-objs := adav803.o
@@ -35,6 +37,7 @@ snd-soc-arizona-objs := arizona.o
35snd-soc-bt-sco-objs := bt-sco.o 37snd-soc-bt-sco-objs := bt-sco.o
36snd-soc-cq93vc-objs := cq93vc.o 38snd-soc-cq93vc-objs := cq93vc.o
37snd-soc-cs35l32-objs := cs35l32.o 39snd-soc-cs35l32-objs := cs35l32.o
40snd-soc-cs35l33-objs := cs35l33.o
38snd-soc-cs42l51-objs := cs42l51.o 41snd-soc-cs42l51-objs := cs42l51.o
39snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o 42snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
40snd-soc-cs42l52-objs := cs42l52.o 43snd-soc-cs42l52-objs := cs42l52.o
@@ -49,6 +52,7 @@ snd-soc-cs42xx8-objs := cs42xx8.o
49snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o 52snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
50snd-soc-cs4349-objs := cs4349.o 53snd-soc-cs4349-objs := cs4349.o
51snd-soc-cs47l24-objs := cs47l24.o 54snd-soc-cs47l24-objs := cs47l24.o
55snd-soc-cs53l30-objs := cs53l30.o
52snd-soc-cx20442-objs := cx20442.o 56snd-soc-cx20442-objs := cx20442.o
53snd-soc-da7210-objs := da7210.o 57snd-soc-da7210-objs := da7210.o
54snd-soc-da7213-objs := da7213.o 58snd-soc-da7213-objs := da7213.o
@@ -79,6 +83,7 @@ snd-soc-max9867-objs := max9867.o
79snd-soc-max98925-objs := max98925.o 83snd-soc-max98925-objs := max98925.o
80snd-soc-max98926-objs := max98926.o 84snd-soc-max98926-objs := max98926.o
81snd-soc-max9850-objs := max9850.o 85snd-soc-max9850-objs := max9850.o
86snd-soc-max9860-objs := max9860.o
82snd-soc-mc13783-objs := mc13783.o 87snd-soc-mc13783-objs := mc13783.o
83snd-soc-ml26124-objs := ml26124.o 88snd-soc-ml26124-objs := ml26124.o
84snd-soc-nau8825-objs := nau8825.o 89snd-soc-nau8825-objs := nau8825.o
@@ -100,6 +105,7 @@ snd-soc-rl6347a-objs := rl6347a.o
100snd-soc-rt286-objs := rt286.o 105snd-soc-rt286-objs := rt286.o
101snd-soc-rt298-objs := rt298.o 106snd-soc-rt298-objs := rt298.o
102snd-soc-rt5514-objs := rt5514.o 107snd-soc-rt5514-objs := rt5514.o
108snd-soc-rt5514-spi-objs := rt5514-spi.o
103snd-soc-rt5616-objs := rt5616.o 109snd-soc-rt5616-objs := rt5616.o
104snd-soc-rt5631-objs := rt5631.o 110snd-soc-rt5631-objs := rt5631.o
105snd-soc-rt5640-objs := rt5640.o 111snd-soc-rt5640-objs := rt5640.o
@@ -208,6 +214,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
208 214
209# Amp 215# Amp
210snd-soc-max9877-objs := max9877.o 216snd-soc-max9877-objs := max9877.o
217snd-soc-max98504-objs := max98504.o
211snd-soc-tpa6130a2-objs := tpa6130a2.o 218snd-soc-tpa6130a2-objs := tpa6130a2.o
212snd-soc-tas2552-objs := tas2552.o 219snd-soc-tas2552-objs := tas2552.o
213 220
@@ -220,6 +227,7 @@ obj-$(CONFIG_SND_SOC_AD193X_SPI) += snd-soc-ad193x-spi.o
220obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o 227obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o
221obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 228obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
222obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 229obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
230obj-$(CONFIG_SND_SOC_ADAU_UTILS) += snd-soc-adau-utils.o
223obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o 231obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
224obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o 232obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o
225obj-$(CONFIG_SND_SOC_ADAU17X1) += snd-soc-adau17x1.o 233obj-$(CONFIG_SND_SOC_ADAU17X1) += snd-soc-adau17x1.o
@@ -232,6 +240,7 @@ obj-$(CONFIG_SND_SOC_ADAU1781_SPI) += snd-soc-adau1781-spi.o
232obj-$(CONFIG_SND_SOC_ADAU1977) += snd-soc-adau1977.o 240obj-$(CONFIG_SND_SOC_ADAU1977) += snd-soc-adau1977.o
233obj-$(CONFIG_SND_SOC_ADAU1977_SPI) += snd-soc-adau1977-spi.o 241obj-$(CONFIG_SND_SOC_ADAU1977_SPI) += snd-soc-adau1977-spi.o
234obj-$(CONFIG_SND_SOC_ADAU1977_I2C) += snd-soc-adau1977-i2c.o 242obj-$(CONFIG_SND_SOC_ADAU1977_I2C) += snd-soc-adau1977-i2c.o
243obj-$(CONFIG_SND_SOC_ADAU7002) += snd-soc-adau7002.o
235obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o 244obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
236obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o 245obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o
237obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o 246obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o
@@ -250,6 +259,7 @@ obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
250obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o 259obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
251obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 260obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
252obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o 261obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o
262obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o
253obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 263obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
254obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o 264obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
255obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o 265obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
@@ -264,6 +274,7 @@ obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
264obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o 274obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
265obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o 275obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
266obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o 276obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
277obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o
267obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 278obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
268obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 279obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
269obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o 280obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
@@ -293,6 +304,7 @@ obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
293obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o 304obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
294obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o 305obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
295obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 306obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
307obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
296obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 308obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
297obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 309obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
298obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o 310obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
@@ -314,6 +326,7 @@ obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
314obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o 326obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
315obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o 327obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
316obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o 328obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o
329obj-$(CONFIG_SND_SOC_RT5514_SPI) += snd-soc-rt5514-spi.o
317obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o 330obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o
318obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 331obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
319obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 332obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
@@ -419,4 +432,5 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
419 432
420# Amp 433# Amp
421obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 434obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
435obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
422obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 436obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
diff --git a/sound/soc/codecs/adau-utils.c b/sound/soc/codecs/adau-utils.c
new file mode 100644
index 000000000000..19d6a6f41b12
--- /dev/null
+++ b/sound/soc/codecs/adau-utils.c
@@ -0,0 +1,61 @@
1/*
2 * Shared helper functions for devices from the ADAU family
3 *
4 * Copyright 2011-2016 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
10#include <linux/gcd.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13
14#include "adau-utils.h"
15
16int adau_calc_pll_cfg(unsigned int freq_in, unsigned int freq_out,
17 uint8_t regs[5])
18{
19 unsigned int r, n, m, i, j;
20 unsigned int div;
21
22 if (!freq_out) {
23 r = 0;
24 n = 0;
25 m = 0;
26 div = 0;
27 } else {
28 if (freq_out % freq_in != 0) {
29 div = DIV_ROUND_UP(freq_in, 13500000);
30 freq_in /= div;
31 r = freq_out / freq_in;
32 i = freq_out % freq_in;
33 j = gcd(i, freq_in);
34 n = i / j;
35 m = freq_in / j;
36 div--;
37 } else {
38 r = freq_out / freq_in;
39 n = 0;
40 m = 0;
41 div = 0;
42 }
43 if (n > 0xffff || m > 0xffff || div > 3 || r > 8 || r < 2)
44 return -EINVAL;
45 }
46
47 regs[0] = m >> 8;
48 regs[1] = m & 0xff;
49 regs[2] = n >> 8;
50 regs[3] = n & 0xff;
51 regs[4] = (r << 3) | (div << 1);
52 if (m != 0)
53 regs[4] |= 1; /* Fractional mode */
54
55 return 0;
56}
57EXPORT_SYMBOL_GPL(adau_calc_pll_cfg);
58
59MODULE_DESCRIPTION("ASoC ADAU audio CODECs shared helper functions");
60MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
61MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/adau-utils.h b/sound/soc/codecs/adau-utils.h
new file mode 100644
index 000000000000..939b5f37762f
--- /dev/null
+++ b/sound/soc/codecs/adau-utils.h
@@ -0,0 +1,7 @@
1#ifndef SOUND_SOC_CODECS_ADAU_PLL_H
2#define SOUND_SOC_CODECS_ADAU_PLL_H
3
4int adau_calc_pll_cfg(unsigned int freq_in, unsigned int freq_out,
5 uint8_t regs[5]);
6
7#endif
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index fe1353a797b9..1556b360fa15 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -23,6 +23,7 @@
23#include <sound/adau1373.h> 23#include <sound/adau1373.h>
24 24
25#include "adau1373.h" 25#include "adau1373.h"
26#include "adau-utils.h"
26 27
27struct adau1373_dai { 28struct adau1373_dai {
28 unsigned int clk_src; 29 unsigned int clk_src;
@@ -1254,7 +1255,8 @@ static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
1254{ 1255{
1255 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); 1256 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
1256 unsigned int dpll_div = 0; 1257 unsigned int dpll_div = 0;
1257 unsigned int x, r, n, m, i, j, mode; 1258 uint8_t pll_regs[5];
1259 int ret;
1258 1260
1259 switch (pll_id) { 1261 switch (pll_id) {
1260 case ADAU1373_PLL1: 1262 case ADAU1373_PLL1:
@@ -1295,27 +1297,8 @@ static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
1295 dpll_div++; 1297 dpll_div++;
1296 } 1298 }
1297 1299
1298 if (freq_out % freq_in != 0) { 1300 ret = adau_calc_pll_cfg(freq_in, freq_out, pll_regs);
1299 /* fout = fin * (r + (n/m)) / x */ 1301 if (ret)
1300 x = DIV_ROUND_UP(freq_in, 13500000);
1301 freq_in /= x;
1302 r = freq_out / freq_in;
1303 i = freq_out % freq_in;
1304 j = gcd(i, freq_in);
1305 n = i / j;
1306 m = freq_in / j;
1307 x--;
1308 mode = 1;
1309 } else {
1310 /* fout = fin / r */
1311 r = freq_out / freq_in;
1312 n = 0;
1313 m = 0;
1314 x = 0;
1315 mode = 0;
1316 }
1317
1318 if (r < 2 || r > 8 || x > 3 || m > 0xffff || n > 0xffff)
1319 return -EINVAL; 1302 return -EINVAL;
1320 1303
1321 if (dpll_div) { 1304 if (dpll_div) {
@@ -1330,12 +1313,11 @@ static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
1330 1313
1331 regmap_write(adau1373->regmap, ADAU1373_DPLL_CTRL(pll_id), 1314 regmap_write(adau1373->regmap, ADAU1373_DPLL_CTRL(pll_id),
1332 (source << 4) | dpll_div); 1315 (source << 4) | dpll_div);
1333 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff); 1316 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL1(pll_id), pll_regs[0]);
1334 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL2(pll_id), m & 0xff); 1317 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL2(pll_id), pll_regs[1]);
1335 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff); 1318 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL3(pll_id), pll_regs[2]);
1336 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL4(pll_id), n & 0xff); 1319 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL4(pll_id), pll_regs[3]);
1337 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL5(pll_id), 1320 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL5(pll_id), pll_regs[4]);
1338 (r << 3) | (x << 1) | mode);
1339 1321
1340 /* Set sysclk to pll_rate / 4 */ 1322 /* Set sysclk to pll_rate / 4 */
1341 regmap_update_bits(adau1373->regmap, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09); 1323 regmap_update_bits(adau1373->regmap, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09);
diff --git a/sound/soc/codecs/adau1761-i2c.c b/sound/soc/codecs/adau1761-i2c.c
index 8de010f758cd..9e7f257f17f8 100644
--- a/sound/soc/codecs/adau1761-i2c.c
+++ b/sound/soc/codecs/adau1761-i2c.c
@@ -31,7 +31,7 @@ static int adau1761_i2c_probe(struct i2c_client *client,
31 31
32static int adau1761_i2c_remove(struct i2c_client *client) 32static int adau1761_i2c_remove(struct i2c_client *client)
33{ 33{
34 snd_soc_unregister_codec(&client->dev); 34 adau17x1_remove(&client->dev);
35 return 0; 35 return 0;
36} 36}
37 37
diff --git a/sound/soc/codecs/adau1761-spi.c b/sound/soc/codecs/adau1761-spi.c
index d9171245bd9f..a0b214be759a 100644
--- a/sound/soc/codecs/adau1761-spi.c
+++ b/sound/soc/codecs/adau1761-spi.c
@@ -48,7 +48,7 @@ static int adau1761_spi_probe(struct spi_device *spi)
48 48
49static int adau1761_spi_remove(struct spi_device *spi) 49static int adau1761_spi_remove(struct spi_device *spi)
50{ 50{
51 snd_soc_unregister_codec(&spi->dev); 51 adau17x1_remove(&spi->dev);
52 return 0; 52 return 0;
53} 53}
54 54
diff --git a/sound/soc/codecs/adau1781-i2c.c b/sound/soc/codecs/adau1781-i2c.c
index 06cbca84cf02..7b9d1802d159 100644
--- a/sound/soc/codecs/adau1781-i2c.c
+++ b/sound/soc/codecs/adau1781-i2c.c
@@ -31,7 +31,7 @@ static int adau1781_i2c_probe(struct i2c_client *client,
31 31
32static int adau1781_i2c_remove(struct i2c_client *client) 32static int adau1781_i2c_remove(struct i2c_client *client)
33{ 33{
34 snd_soc_unregister_codec(&client->dev); 34 adau17x1_remove(&client->dev);
35 return 0; 35 return 0;
36} 36}
37 37
diff --git a/sound/soc/codecs/adau1781-spi.c b/sound/soc/codecs/adau1781-spi.c
index 3d965a01b99c..9b233544d2e8 100644
--- a/sound/soc/codecs/adau1781-spi.c
+++ b/sound/soc/codecs/adau1781-spi.c
@@ -48,7 +48,7 @@ static int adau1781_spi_probe(struct spi_device *spi)
48 48
49static int adau1781_spi_remove(struct spi_device *spi) 49static int adau1781_spi_remove(struct spi_device *spi)
50{ 50{
51 snd_soc_unregister_codec(&spi->dev); 51 adau17x1_remove(&spi->dev);
52 return 0; 52 return 0;
53} 53}
54 54
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c
index fcf05b254ecd..439aa3ff1f99 100644
--- a/sound/soc/codecs/adau17x1.c
+++ b/sound/soc/codecs/adau17x1.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/clk.h>
12#include <linux/delay.h> 13#include <linux/delay.h>
13#include <linux/slab.h> 14#include <linux/slab.h>
14#include <sound/core.h> 15#include <sound/core.h>
@@ -23,6 +24,7 @@
23 24
24#include "sigmadsp.h" 25#include "sigmadsp.h"
25#include "adau17x1.h" 26#include "adau17x1.h"
27#include "adau-utils.h"
26 28
27static const char * const adau17x1_capture_mixer_boost_text[] = { 29static const char * const adau17x1_capture_mixer_boost_text[] = {
28 "Normal operation", "Boost Level 1", "Boost Level 2", "Boost Level 3", 30 "Normal operation", "Boost Level 1", "Boost Level 2", "Boost Level 3",
@@ -302,6 +304,116 @@ bool adau17x1_has_dsp(struct adau *adau)
302} 304}
303EXPORT_SYMBOL_GPL(adau17x1_has_dsp); 305EXPORT_SYMBOL_GPL(adau17x1_has_dsp);
304 306
307static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
308 int source, unsigned int freq_in, unsigned int freq_out)
309{
310 struct snd_soc_codec *codec = dai->codec;
311 struct adau *adau = snd_soc_codec_get_drvdata(codec);
312 int ret;
313
314 if (freq_in < 8000000 || freq_in > 27000000)
315 return -EINVAL;
316
317 ret = adau_calc_pll_cfg(freq_in, freq_out, adau->pll_regs);
318 if (ret < 0)
319 return ret;
320
321 /* The PLL register is 6 bytes long and can only be written at once. */
322 ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
323 adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
324 if (ret)
325 return ret;
326
327 adau->pll_freq = freq_out;
328
329 return 0;
330}
331
332static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
333 int clk_id, unsigned int freq, int dir)
334{
335 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec);
336 struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
337 bool is_pll;
338 bool was_pll;
339
340 switch (clk_id) {
341 case ADAU17X1_CLK_SRC_MCLK:
342 is_pll = false;
343 break;
344 case ADAU17X1_CLK_SRC_PLL_AUTO:
345 if (!adau->mclk)
346 return -EINVAL;
347 /* Fall-through */
348 case ADAU17X1_CLK_SRC_PLL:
349 is_pll = true;
350 break;
351 default:
352 return -EINVAL;
353 }
354
355 switch (adau->clk_src) {
356 case ADAU17X1_CLK_SRC_MCLK:
357 was_pll = false;
358 break;
359 case ADAU17X1_CLK_SRC_PLL:
360 case ADAU17X1_CLK_SRC_PLL_AUTO:
361 was_pll = true;
362 break;
363 default:
364 return -EINVAL;
365 }
366
367 adau->sysclk = freq;
368
369 if (is_pll != was_pll) {
370 if (is_pll) {
371 snd_soc_dapm_add_routes(dapm,
372 &adau17x1_dapm_pll_route, 1);
373 } else {
374 snd_soc_dapm_del_routes(dapm,
375 &adau17x1_dapm_pll_route, 1);
376 }
377 }
378
379 adau->clk_src = clk_id;
380
381 return 0;
382}
383
384static int adau17x1_auto_pll(struct snd_soc_dai *dai,
385 struct snd_pcm_hw_params *params)
386{
387 struct adau *adau = snd_soc_dai_get_drvdata(dai);
388 unsigned int pll_rate;
389
390 switch (params_rate(params)) {
391 case 48000:
392 case 8000:
393 case 12000:
394 case 16000:
395 case 24000:
396 case 32000:
397 case 96000:
398 pll_rate = 48000 * 1024;
399 break;
400 case 44100:
401 case 7350:
402 case 11025:
403 case 14700:
404 case 22050:
405 case 29400:
406 case 88200:
407 pll_rate = 44100 * 1024;
408 break;
409 default:
410 return -EINVAL;
411 }
412
413 return adau17x1_set_dai_pll(dai, ADAU17X1_PLL, ADAU17X1_PLL_SRC_MCLK,
414 clk_get_rate(adau->mclk), pll_rate);
415}
416
305static int adau17x1_hw_params(struct snd_pcm_substream *substream, 417static int adau17x1_hw_params(struct snd_pcm_substream *substream,
306 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 418 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
307{ 419{
@@ -311,10 +423,19 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream,
311 unsigned int freq; 423 unsigned int freq;
312 int ret; 424 int ret;
313 425
314 if (adau->clk_src == ADAU17X1_CLK_SRC_PLL) 426 switch (adau->clk_src) {
427 case ADAU17X1_CLK_SRC_PLL_AUTO:
428 ret = adau17x1_auto_pll(dai, params);
429 if (ret)
430 return ret;
431 /* Fall-through */
432 case ADAU17X1_CLK_SRC_PLL:
315 freq = adau->pll_freq; 433 freq = adau->pll_freq;
316 else 434 break;
435 default:
317 freq = adau->sysclk; 436 freq = adau->sysclk;
437 break;
438 }
318 439
319 if (freq % params_rate(params) != 0) 440 if (freq % params_rate(params) != 0)
320 return -EINVAL; 441 return -EINVAL;
@@ -386,93 +507,6 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream,
386 ADAU17X1_SERIAL_PORT1_DELAY_MASK, val); 507 ADAU17X1_SERIAL_PORT1_DELAY_MASK, val);
387} 508}
388 509
389static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
390 int source, unsigned int freq_in, unsigned int freq_out)
391{
392 struct snd_soc_codec *codec = dai->codec;
393 struct adau *adau = snd_soc_codec_get_drvdata(codec);
394 unsigned int r, n, m, i, j;
395 unsigned int div;
396 int ret;
397
398 if (freq_in < 8000000 || freq_in > 27000000)
399 return -EINVAL;
400
401 if (!freq_out) {
402 r = 0;
403 n = 0;
404 m = 0;
405 div = 0;
406 } else {
407 if (freq_out % freq_in != 0) {
408 div = DIV_ROUND_UP(freq_in, 13500000);
409 freq_in /= div;
410 r = freq_out / freq_in;
411 i = freq_out % freq_in;
412 j = gcd(i, freq_in);
413 n = i / j;
414 m = freq_in / j;
415 div--;
416 } else {
417 r = freq_out / freq_in;
418 n = 0;
419 m = 0;
420 div = 0;
421 }
422 if (n > 0xffff || m > 0xffff || div > 3 || r > 8 || r < 2)
423 return -EINVAL;
424 }
425
426 adau->pll_regs[0] = m >> 8;
427 adau->pll_regs[1] = m & 0xff;
428 adau->pll_regs[2] = n >> 8;
429 adau->pll_regs[3] = n & 0xff;
430 adau->pll_regs[4] = (r << 3) | (div << 1);
431 if (m != 0)
432 adau->pll_regs[4] |= 1; /* Fractional mode */
433
434 /* The PLL register is 6 bytes long and can only be written at once. */
435 ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
436 adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
437 if (ret)
438 return ret;
439
440 adau->pll_freq = freq_out;
441
442 return 0;
443}
444
445static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
446 int clk_id, unsigned int freq, int dir)
447{
448 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec);
449 struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
450
451 switch (clk_id) {
452 case ADAU17X1_CLK_SRC_MCLK:
453 case ADAU17X1_CLK_SRC_PLL:
454 break;
455 default:
456 return -EINVAL;
457 }
458
459 adau->sysclk = freq;
460
461 if (adau->clk_src != clk_id) {
462 if (clk_id == ADAU17X1_CLK_SRC_PLL) {
463 snd_soc_dapm_add_routes(dapm,
464 &adau17x1_dapm_pll_route, 1);
465 } else {
466 snd_soc_dapm_del_routes(dapm,
467 &adau17x1_dapm_pll_route, 1);
468 }
469 }
470
471 adau->clk_src = clk_id;
472
473 return 0;
474}
475
476static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai, 510static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai,
477 unsigned int fmt) 511 unsigned int fmt)
478{ 512{
@@ -857,6 +891,10 @@ int adau17x1_add_routes(struct snd_soc_codec *codec)
857 ret = snd_soc_dapm_add_routes(dapm, adau17x1_no_dsp_dapm_routes, 891 ret = snd_soc_dapm_add_routes(dapm, adau17x1_no_dsp_dapm_routes,
858 ARRAY_SIZE(adau17x1_no_dsp_dapm_routes)); 892 ARRAY_SIZE(adau17x1_no_dsp_dapm_routes));
859 } 893 }
894
895 if (adau->clk_src != ADAU17X1_CLK_SRC_MCLK)
896 snd_soc_dapm_add_routes(dapm, &adau17x1_dapm_pll_route, 1);
897
860 return ret; 898 return ret;
861} 899}
862EXPORT_SYMBOL_GPL(adau17x1_add_routes); 900EXPORT_SYMBOL_GPL(adau17x1_add_routes);
@@ -879,6 +917,7 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap,
879 const char *firmware_name) 917 const char *firmware_name)
880{ 918{
881 struct adau *adau; 919 struct adau *adau;
920 int ret;
882 921
883 if (IS_ERR(regmap)) 922 if (IS_ERR(regmap))
884 return PTR_ERR(regmap); 923 return PTR_ERR(regmap);
@@ -887,6 +926,30 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap,
887 if (!adau) 926 if (!adau)
888 return -ENOMEM; 927 return -ENOMEM;
889 928
929 adau->mclk = devm_clk_get(dev, "mclk");
930 if (IS_ERR(adau->mclk)) {
931 if (PTR_ERR(adau->mclk) != -ENOENT)
932 return PTR_ERR(adau->mclk);
933 /* Clock is optional (for the driver) */
934 adau->mclk = NULL;
935 } else if (adau->mclk) {
936 adau->clk_src = ADAU17X1_CLK_SRC_PLL_AUTO;
937
938 /*
939 * Any valid PLL output rate will work at this point, use one
940 * that is likely to be chosen later as well. The register will
941 * be written when the PLL is powered up for the first time.
942 */
943 ret = adau_calc_pll_cfg(clk_get_rate(adau->mclk), 48000 * 1024,
944 adau->pll_regs);
945 if (ret < 0)
946 return ret;
947
948 ret = clk_prepare_enable(adau->mclk);
949 if (ret)
950 return ret;
951 }
952
890 adau->regmap = regmap; 953 adau->regmap = regmap;
891 adau->switch_mode = switch_mode; 954 adau->switch_mode = switch_mode;
892 adau->type = type; 955 adau->type = type;
@@ -910,6 +973,16 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap,
910} 973}
911EXPORT_SYMBOL_GPL(adau17x1_probe); 974EXPORT_SYMBOL_GPL(adau17x1_probe);
912 975
976void adau17x1_remove(struct device *dev)
977{
978 struct adau *adau = dev_get_drvdata(dev);
979
980 snd_soc_unregister_codec(dev);
981 if (adau->mclk)
982 clk_disable_unprepare(adau->mclk);
983}
984EXPORT_SYMBOL_GPL(adau17x1_remove);
985
913MODULE_DESCRIPTION("ASoC ADAU1X61/ADAU1X81 common code"); 986MODULE_DESCRIPTION("ASoC ADAU1X61/ADAU1X81 common code");
914MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 987MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
915MODULE_LICENSE("GPL"); 988MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h
index 5ae87a084d97..bf04b7efee40 100644
--- a/sound/soc/codecs/adau17x1.h
+++ b/sound/soc/codecs/adau17x1.h
@@ -22,13 +22,18 @@ enum adau17x1_pll_src {
22}; 22};
23 23
24enum adau17x1_clk_src { 24enum adau17x1_clk_src {
25 /* Automatically configure PLL based on the sample rate */
26 ADAU17X1_CLK_SRC_PLL_AUTO,
25 ADAU17X1_CLK_SRC_MCLK, 27 ADAU17X1_CLK_SRC_MCLK,
26 ADAU17X1_CLK_SRC_PLL, 28 ADAU17X1_CLK_SRC_PLL,
27}; 29};
28 30
31struct clk;
32
29struct adau { 33struct adau {
30 unsigned int sysclk; 34 unsigned int sysclk;
31 unsigned int pll_freq; 35 unsigned int pll_freq;
36 struct clk *mclk;
32 37
33 enum adau17x1_clk_src clk_src; 38 enum adau17x1_clk_src clk_src;
34 enum adau17x1_type type; 39 enum adau17x1_type type;
@@ -52,6 +57,7 @@ int adau17x1_add_routes(struct snd_soc_codec *codec);
52int adau17x1_probe(struct device *dev, struct regmap *regmap, 57int adau17x1_probe(struct device *dev, struct regmap *regmap,
53 enum adau17x1_type type, void (*switch_mode)(struct device *dev), 58 enum adau17x1_type type, void (*switch_mode)(struct device *dev),
54 const char *firmware_name); 59 const char *firmware_name);
60void adau17x1_remove(struct device *dev);
55int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec, 61int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
56 enum adau17x1_micbias_voltage micbias); 62 enum adau17x1_micbias_voltage micbias);
57bool adau17x1_readable_register(struct device *dev, unsigned int reg); 63bool adau17x1_readable_register(struct device *dev, unsigned int reg);
diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c
new file mode 100644
index 000000000000..9df72c6adcca
--- /dev/null
+++ b/sound/soc/codecs/adau7002.c
@@ -0,0 +1,80 @@
1/*
2 * ADAU7002 Stereo PDM-to-I2S/TDM converter driver
3 *
4 * Copyright 2014-2016 Analog Devices
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/of.h>
13#include <linux/platform_device.h>
14
15#include <sound/soc.h>
16
17static const struct snd_soc_dapm_widget adau7002_widgets[] = {
18 SND_SOC_DAPM_INPUT("PDM_DAT"),
19 SND_SOC_DAPM_REGULATOR_SUPPLY("IOVDD", 0, 0),
20};
21
22static const struct snd_soc_dapm_route adau7002_routes[] = {
23 { "Capture", NULL, "PDM_DAT" },
24 { "Capture", NULL, "IOVDD" },
25};
26
27static struct snd_soc_dai_driver adau7002_dai = {
28 .name = "adau7002-hifi",
29 .capture = {
30 .stream_name = "Capture",
31 .channels_min = 2,
32 .channels_max = 2,
33 .rates = SNDRV_PCM_RATE_8000_96000,
34 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |
35 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |
36 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE,
37 .sig_bits = 20,
38 },
39};
40
41static const struct snd_soc_codec_driver adau7002_codec_driver = {
42 .dapm_widgets = adau7002_widgets,
43 .num_dapm_widgets = ARRAY_SIZE(adau7002_widgets),
44 .dapm_routes = adau7002_routes,
45 .num_dapm_routes = ARRAY_SIZE(adau7002_routes),
46};
47
48static int adau7002_probe(struct platform_device *pdev)
49{
50 return snd_soc_register_codec(&pdev->dev, &adau7002_codec_driver,
51 &adau7002_dai, 1);
52}
53
54static int adau7002_remove(struct platform_device *pdev)
55{
56 snd_soc_unregister_codec(&pdev->dev);
57 return 0;
58}
59
60#ifdef CONFIG_OF
61static const struct of_device_id adau7002_dt_ids[] = {
62 { .compatible = "adi,adau7002", },
63 { }
64};
65MODULE_DEVICE_TABLE(of, adau7002_dt_ids);
66#endif
67
68static struct platform_driver adau7002_driver = {
69 .driver = {
70 .name = "adau7002",
71 .of_match_table = of_match_ptr(adau7002_dt_ids),
72 },
73 .probe = adau7002_probe,
74 .remove = adau7002_remove,
75};
76module_platform_driver(adau7002_driver);
77
78MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
79MODULE_DESCRIPTION("ADAU7002 Stereo PDM-to-I2S/TDM Converter driver");
80MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index 5013d2ba0c10..97798d250f08 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -437,15 +437,25 @@ static struct snd_soc_dai_driver ak4613_dai = {
437 .symmetric_rates = 1, 437 .symmetric_rates = 1,
438}; 438};
439 439
440static int ak4613_resume(struct snd_soc_codec *codec) 440static int ak4613_suspend(struct snd_soc_codec *codec)
441{ 441{
442 struct regmap *regmap = dev_get_regmap(codec->dev, NULL); 442 struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
443 443
444 regcache_cache_only(regmap, true);
444 regcache_mark_dirty(regmap); 445 regcache_mark_dirty(regmap);
446 return 0;
447}
448
449static int ak4613_resume(struct snd_soc_codec *codec)
450{
451 struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
452
453 regcache_cache_only(regmap, false);
445 return regcache_sync(regmap); 454 return regcache_sync(regmap);
446} 455}
447 456
448static struct snd_soc_codec_driver soc_codec_dev_ak4613 = { 457static struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
458 .suspend = ak4613_suspend,
449 .resume = ak4613_resume, 459 .resume = ak4613_resume,
450 .set_bias_level = ak4613_set_bias_level, 460 .set_bias_level = ak4613_set_bias_level,
451 .controls = ak4613_snd_controls, 461 .controls = ak4613_snd_controls,
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 4d8b9e49e8d6..cc941d66ec3d 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -523,15 +523,23 @@ static struct snd_soc_dai_driver ak4642_dai = {
523 .symmetric_rates = 1, 523 .symmetric_rates = 1,
524}; 524};
525 525
526static int ak4642_resume(struct snd_soc_codec *codec) 526static int ak4642_suspend(struct snd_soc_codec *codec)
527{ 527{
528 struct regmap *regmap = dev_get_regmap(codec->dev, NULL); 528 struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
529 529
530 regcache_cache_only(regmap, true);
530 regcache_mark_dirty(regmap); 531 regcache_mark_dirty(regmap);
531 regcache_sync(regmap);
532 return 0; 532 return 0;
533} 533}
534 534
535static int ak4642_resume(struct snd_soc_codec *codec)
536{
537 struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
538
539 regcache_cache_only(regmap, false);
540 regcache_sync(regmap);
541 return 0;
542}
535static int ak4642_probe(struct snd_soc_codec *codec) 543static int ak4642_probe(struct snd_soc_codec *codec)
536{ 544{
537 struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec); 545 struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
@@ -544,6 +552,7 @@ static int ak4642_probe(struct snd_soc_codec *codec)
544 552
545static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { 553static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
546 .probe = ak4642_probe, 554 .probe = ak4642_probe,
555 .suspend = ak4642_suspend,
547 .resume = ak4642_resume, 556 .resume = ak4642_resume,
548 .set_bias_level = ak4642_set_bias_level, 557 .set_bias_level = ak4642_set_bias_level,
549 .controls = ak4642_snd_controls, 558 .controls = ak4642_snd_controls,
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 664a8c044ffb..ecfdbfcae366 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -85,30 +85,9 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
85{ 85{
86 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 86 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
87 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 87 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
88 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
89 bool manual_ena = false;
90 int val; 88 int val;
91 89
92 switch (arizona->type) {
93 case WM5102:
94 switch (arizona->rev) {
95 case 0:
96 break;
97 default:
98 manual_ena = true;
99 break;
100 }
101 default:
102 break;
103 }
104
105 switch (event) { 90 switch (event) {
106 case SND_SOC_DAPM_PRE_PMU:
107 if (!priv->spk_ena && manual_ena) {
108 regmap_write_async(arizona->regmap, 0x4f5, 0x25a);
109 priv->spk_ena_pending = true;
110 }
111 break;
112 case SND_SOC_DAPM_POST_PMU: 91 case SND_SOC_DAPM_POST_PMU:
113 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3); 92 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
114 if (val & ARIZONA_SPK_OVERHEAT_STS) { 93 if (val & ARIZONA_SPK_OVERHEAT_STS) {
@@ -120,33 +99,12 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
120 regmap_update_bits_async(arizona->regmap, 99 regmap_update_bits_async(arizona->regmap,
121 ARIZONA_OUTPUT_ENABLES_1, 100 ARIZONA_OUTPUT_ENABLES_1,
122 1 << w->shift, 1 << w->shift); 101 1 << w->shift, 1 << w->shift);
123
124 if (priv->spk_ena_pending) {
125 msleep(75);
126 regmap_write_async(arizona->regmap, 0x4f5, 0xda);
127 priv->spk_ena_pending = false;
128 priv->spk_ena++;
129 }
130 break; 102 break;
131 case SND_SOC_DAPM_PRE_PMD: 103 case SND_SOC_DAPM_PRE_PMD:
132 if (manual_ena) {
133 priv->spk_ena--;
134 if (!priv->spk_ena)
135 regmap_write_async(arizona->regmap,
136 0x4f5, 0x25a);
137 }
138
139 regmap_update_bits_async(arizona->regmap, 104 regmap_update_bits_async(arizona->regmap,
140 ARIZONA_OUTPUT_ENABLES_1, 105 ARIZONA_OUTPUT_ENABLES_1,
141 1 << w->shift, 0); 106 1 << w->shift, 0);
142 break; 107 break;
143 case SND_SOC_DAPM_POST_PMD:
144 if (manual_ena) {
145 if (!priv->spk_ena)
146 regmap_write_async(arizona->regmap,
147 0x4f5, 0x0da);
148 }
149 break;
150 default: 108 default:
151 break; 109 break;
152 } 110 }
@@ -324,6 +282,17 @@ int arizona_init_gpio(struct snd_soc_codec *codec)
324} 282}
325EXPORT_SYMBOL_GPL(arizona_init_gpio); 283EXPORT_SYMBOL_GPL(arizona_init_gpio);
326 284
285int arizona_init_notifiers(struct snd_soc_codec *codec)
286{
287 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
288 struct arizona *arizona = priv->arizona;
289
290 BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
291
292 return 0;
293}
294EXPORT_SYMBOL_GPL(arizona_init_notifiers);
295
327const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 296const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
328 "None", 297 "None",
329 "Tone Generator 1", 298 "Tone Generator 1",
@@ -619,7 +588,7 @@ const struct soc_enum arizona_asrc_rate1 =
619 arizona_rate_text, arizona_rate_val); 588 arizona_rate_text, arizona_rate_val);
620EXPORT_SYMBOL_GPL(arizona_asrc_rate1); 589EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
621 590
622static const char *arizona_vol_ramp_text[] = { 591static const char * const arizona_vol_ramp_text[] = {
623 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", 592 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
624 "15ms/6dB", "30ms/6dB", 593 "15ms/6dB", "30ms/6dB",
625}; 594};
@@ -648,7 +617,7 @@ SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
648 arizona_vol_ramp_text); 617 arizona_vol_ramp_text);
649EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); 618EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
650 619
651static const char *arizona_lhpf_mode_text[] = { 620static const char * const arizona_lhpf_mode_text[] = {
652 "Low-pass", "High-pass" 621 "Low-pass", "High-pass"
653}; 622};
654 623
@@ -676,7 +645,7 @@ SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
676 arizona_lhpf_mode_text); 645 arizona_lhpf_mode_text);
677EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); 646EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
678 647
679static const char *arizona_ng_hold_text[] = { 648static const char * const arizona_ng_hold_text[] = {
680 "30ms", "120ms", "250ms", "500ms", 649 "30ms", "120ms", "250ms", "500ms",
681}; 650};
682 651
@@ -810,6 +779,14 @@ const struct soc_enum arizona_output_anc_src[] = {
810}; 779};
811EXPORT_SYMBOL_GPL(arizona_output_anc_src); 780EXPORT_SYMBOL_GPL(arizona_output_anc_src);
812 781
782const struct snd_kcontrol_new arizona_voice_trigger_switch[] = {
783 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
784 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 1, 1, 0),
785 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 2, 1, 0),
786 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 3, 1, 0),
787};
788EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch);
789
813static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) 790static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
814{ 791{
815 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 792 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
@@ -2573,6 +2550,30 @@ int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2573} 2550}
2574EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put); 2551EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2575 2552
2553int arizona_register_notifier(struct snd_soc_codec *codec,
2554 struct notifier_block *nb,
2555 int (*notify)(struct notifier_block *nb,
2556 unsigned long action, void *data))
2557{
2558 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
2559 struct arizona *arizona = priv->arizona;
2560
2561 nb->notifier_call = notify;
2562
2563 return blocking_notifier_chain_register(&arizona->notifier, nb);
2564}
2565EXPORT_SYMBOL_GPL(arizona_register_notifier);
2566
2567int arizona_unregister_notifier(struct snd_soc_codec *codec,
2568 struct notifier_block *nb)
2569{
2570 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
2571 struct arizona *arizona = priv->arizona;
2572
2573 return blocking_notifier_chain_unregister(&arizona->notifier, nb);
2574}
2575EXPORT_SYMBOL_GPL(arizona_unregister_notifier);
2576
2576MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support"); 2577MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2577MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 2578MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2578MODULE_LICENSE("GPL"); 2579MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index ce0531b8c632..69da1ef3a17c 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -63,6 +63,9 @@
63#define ARIZONA_DVFS_SR1_RQ 0x001 63#define ARIZONA_DVFS_SR1_RQ 0x001
64#define ARIZONA_DVFS_ADSP1_RQ 0x100 64#define ARIZONA_DVFS_ADSP1_RQ 0x100
65 65
66/* Notifier events */
67#define ARIZONA_NOTIFY_VOICE_TRIGGER 0x1
68
66struct arizona; 69struct arizona;
67struct wm_adsp; 70struct wm_adsp;
68 71
@@ -87,14 +90,15 @@ struct arizona_priv {
87 unsigned int out_down_pending; 90 unsigned int out_down_pending;
88 unsigned int out_down_delay; 91 unsigned int out_down_delay;
89 92
90 unsigned int spk_ena:2;
91 unsigned int spk_ena_pending:1;
92
93 unsigned int dvfs_reqs; 93 unsigned int dvfs_reqs;
94 struct mutex dvfs_lock; 94 struct mutex dvfs_lock;
95 bool dvfs_cached; 95 bool dvfs_cached;
96}; 96};
97 97
98struct arizona_voice_trigger_info {
99 int core;
100};
101
98#define ARIZONA_NUM_MIXER_INPUTS 104 102#define ARIZONA_NUM_MIXER_INPUTS 104
99 103
100extern const unsigned int arizona_mixer_tlv[]; 104extern const unsigned int arizona_mixer_tlv[];
@@ -248,6 +252,8 @@ extern const struct soc_enum arizona_anc_input_src[];
248extern const struct soc_enum arizona_anc_ng_enum; 252extern const struct soc_enum arizona_anc_ng_enum;
249extern const struct soc_enum arizona_output_anc_src[]; 253extern const struct soc_enum arizona_output_anc_src[];
250 254
255extern const struct snd_kcontrol_new arizona_voice_trigger_switch[];
256
251extern int arizona_in_ev(struct snd_soc_dapm_widget *w, 257extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
252 struct snd_kcontrol *kcontrol, 258 struct snd_kcontrol *kcontrol,
253 int event); 259 int event);
@@ -306,6 +312,7 @@ extern int arizona_set_fll(struct arizona_fll *fll, int source,
306extern int arizona_init_spk(struct snd_soc_codec *codec); 312extern int arizona_init_spk(struct snd_soc_codec *codec);
307extern int arizona_init_gpio(struct snd_soc_codec *codec); 313extern int arizona_init_gpio(struct snd_soc_codec *codec);
308extern int arizona_init_mono(struct snd_soc_codec *codec); 314extern int arizona_init_mono(struct snd_soc_codec *codec);
315extern int arizona_init_notifiers(struct snd_soc_codec *codec);
309 316
310extern int arizona_free_spk(struct snd_soc_codec *codec); 317extern int arizona_free_spk(struct snd_soc_codec *codec);
311 318
@@ -317,4 +324,13 @@ int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
317extern bool arizona_input_analog(struct snd_soc_codec *codec, int shift); 324extern bool arizona_input_analog(struct snd_soc_codec *codec, int shift);
318 325
319extern const char *arizona_sample_rate_val_to_name(unsigned int rate_val); 326extern const char *arizona_sample_rate_val_to_name(unsigned int rate_val);
327
328extern int arizona_register_notifier(struct snd_soc_codec *codec,
329 struct notifier_block *nb,
330 int (*notify)(struct notifier_block *nb,
331 unsigned long action,
332 void *data));
333extern int arizona_unregister_notifier(struct snd_soc_codec *codec,
334 struct notifier_block *nb);
335
320#endif 336#endif
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index b084ad113e96..2a8d0ee141d4 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -25,22 +25,41 @@ static const struct snd_soc_dapm_route bt_sco_routes[] = {
25 { "TX", NULL, "Playback" }, 25 { "TX", NULL, "Playback" },
26}; 26};
27 27
28static struct snd_soc_dai_driver bt_sco_dai = { 28static struct snd_soc_dai_driver bt_sco_dai[] = {
29 .name = "bt-sco-pcm", 29 {
30 .playback = { 30 .name = "bt-sco-pcm",
31 .stream_name = "Playback", 31 .playback = {
32 .channels_min = 1, 32 .stream_name = "Playback",
33 .channels_max = 1, 33 .channels_min = 1,
34 .rates = SNDRV_PCM_RATE_8000, 34 .channels_max = 1,
35 .formats = SNDRV_PCM_FMTBIT_S16_LE, 35 .rates = SNDRV_PCM_RATE_8000,
36 }, 36 .formats = SNDRV_PCM_FMTBIT_S16_LE,
37 .capture = { 37 },
38 .stream_name = "Capture", 38 .capture = {
39 .channels_min = 1, 39 .stream_name = "Capture",
40 .channels_max = 1, 40 .channels_min = 1,
41 .rates = SNDRV_PCM_RATE_8000, 41 .channels_max = 1,
42 .formats = SNDRV_PCM_FMTBIT_S16_LE, 42 .rates = SNDRV_PCM_RATE_8000,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE,
44 },
43 }, 45 },
46 {
47 .name = "bt-sco-pcm-wb",
48 .playback = {
49 .stream_name = "Playback",
50 .channels_min = 1,
51 .channels_max = 1,
52 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
53 .formats = SNDRV_PCM_FMTBIT_S16_LE,
54 },
55 .capture = {
56 .stream_name = "Capture",
57 .channels_min = 1,
58 .channels_max = 1,
59 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
60 .formats = SNDRV_PCM_FMTBIT_S16_LE,
61 },
62 }
44}; 63};
45 64
46static struct snd_soc_codec_driver soc_codec_dev_bt_sco = { 65static struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
@@ -53,7 +72,7 @@ static struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
53static int bt_sco_probe(struct platform_device *pdev) 72static int bt_sco_probe(struct platform_device *pdev)
54{ 73{
55 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_bt_sco, 74 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_bt_sco,
56 &bt_sco_dai, 1); 75 bt_sco_dai, ARRAY_SIZE(bt_sco_dai));
57} 76}
58 77
59static int bt_sco_remove(struct platform_device *pdev) 78static int bt_sco_remove(struct platform_device *pdev)
@@ -77,6 +96,7 @@ MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
77#if defined(CONFIG_OF) 96#if defined(CONFIG_OF)
78static const struct of_device_id bt_sco_codec_of_match[] = { 97static const struct of_device_id bt_sco_codec_of_match[] = {
79 { .compatible = "delta,dfbmcs320", }, 98 { .compatible = "delta,dfbmcs320", },
99 { .compatible = "linux,bt-sco", },
80 {}, 100 {},
81}; 101};
82MODULE_DEVICE_TABLE(of, bt_sco_codec_of_match); 102MODULE_DEVICE_TABLE(of, bt_sco_codec_of_match);
diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c
new file mode 100644
index 000000000000..6f9c1addcd7f
--- /dev/null
+++ b/sound/soc/codecs/cs35l33.c
@@ -0,0 +1,1303 @@
1/*
2 * cs35l33.c -- CS35L33 ALSA SoC audio driver
3 *
4 * Copyright 2016 Cirrus Logic, Inc.
5 *
6 * Author: Paul Handrigan <paul.handrigan@cirrus.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20#include <linux/workqueue.h>
21#include <linux/platform_device.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <linux/gpio.h>
30#include <linux/gpio/consumer.h>
31#include <sound/cs35l33.h>
32#include <linux/pm_runtime.h>
33#include <linux/regulator/consumer.h>
34#include <linux/regulator/machine.h>
35#include <linux/of_gpio.h>
36#include <linux/of.h>
37#include <linux/of_device.h>
38#include <linux/of_irq.h>
39
40#include "cs35l33.h"
41
42#define CS35L33_BOOT_DELAY 50
43
44struct cs35l33_private {
45 struct snd_soc_codec *codec;
46 struct cs35l33_pdata pdata;
47 struct regmap *regmap;
48 struct gpio_desc *reset_gpio;
49 bool amp_cal;
50 int mclk_int;
51 struct regulator_bulk_data core_supplies[2];
52 int num_core_supplies;
53 bool is_tdm_mode;
54 bool enable_soft_ramp;
55};
56
57static const struct reg_default cs35l33_reg[] = {
58 {CS35L33_PWRCTL1, 0x85},
59 {CS35L33_PWRCTL2, 0xFE},
60 {CS35L33_CLK_CTL, 0x0C},
61 {CS35L33_BST_PEAK_CTL, 0x90},
62 {CS35L33_PROTECT_CTL, 0x55},
63 {CS35L33_BST_CTL1, 0x00},
64 {CS35L33_BST_CTL2, 0x01},
65 {CS35L33_ADSP_CTL, 0x00},
66 {CS35L33_ADC_CTL, 0xC8},
67 {CS35L33_DAC_CTL, 0x14},
68 {CS35L33_DIG_VOL_CTL, 0x00},
69 {CS35L33_CLASSD_CTL, 0x04},
70 {CS35L33_AMP_CTL, 0x90},
71 {CS35L33_INT_MASK_1, 0xFF},
72 {CS35L33_INT_MASK_2, 0xFF},
73 {CS35L33_DIAG_LOCK, 0x00},
74 {CS35L33_DIAG_CTRL_1, 0x40},
75 {CS35L33_DIAG_CTRL_2, 0x00},
76 {CS35L33_HG_MEMLDO_CTL, 0x62},
77 {CS35L33_HG_REL_RATE, 0x03},
78 {CS35L33_LDO_DEL, 0x12},
79 {CS35L33_HG_HEAD, 0x0A},
80 {CS35L33_HG_EN, 0x05},
81 {CS35L33_TX_VMON, 0x00},
82 {CS35L33_TX_IMON, 0x03},
83 {CS35L33_TX_VPMON, 0x02},
84 {CS35L33_TX_VBSTMON, 0x05},
85 {CS35L33_TX_FLAG, 0x06},
86 {CS35L33_TX_EN1, 0x00},
87 {CS35L33_TX_EN2, 0x00},
88 {CS35L33_TX_EN3, 0x00},
89 {CS35L33_TX_EN4, 0x00},
90 {CS35L33_RX_AUD, 0x40},
91 {CS35L33_RX_SPLY, 0x03},
92 {CS35L33_RX_ALIVE, 0x04},
93 {CS35L33_BST_CTL4, 0x63},
94};
95
96static const struct reg_sequence cs35l33_patch[] = {
97 { 0x00, 0x99, 0 },
98 { 0x59, 0x02, 0 },
99 { 0x52, 0x30, 0 },
100 { 0x39, 0x45, 0 },
101 { 0x57, 0x30, 0 },
102 { 0x2C, 0x68, 0 },
103 { 0x00, 0x00, 0 },
104};
105
106static bool cs35l33_volatile_register(struct device *dev, unsigned int reg)
107{
108 switch (reg) {
109 case CS35L33_DEVID_AB:
110 case CS35L33_DEVID_CD:
111 case CS35L33_DEVID_E:
112 case CS35L33_REV_ID:
113 case CS35L33_INT_STATUS_1:
114 case CS35L33_INT_STATUS_2:
115 case CS35L33_HG_STATUS:
116 return true;
117 default:
118 return false;
119 }
120}
121
122static bool cs35l33_writeable_register(struct device *dev, unsigned int reg)
123{
124 switch (reg) {
125 /* these are read only registers */
126 case CS35L33_DEVID_AB:
127 case CS35L33_DEVID_CD:
128 case CS35L33_DEVID_E:
129 case CS35L33_REV_ID:
130 case CS35L33_INT_STATUS_1:
131 case CS35L33_INT_STATUS_2:
132 case CS35L33_HG_STATUS:
133 return false;
134 default:
135 return true;
136 }
137}
138
139static bool cs35l33_readable_register(struct device *dev, unsigned int reg)
140{
141 switch (reg) {
142 case CS35L33_DEVID_AB:
143 case CS35L33_DEVID_CD:
144 case CS35L33_DEVID_E:
145 case CS35L33_REV_ID:
146 case CS35L33_PWRCTL1:
147 case CS35L33_PWRCTL2:
148 case CS35L33_CLK_CTL:
149 case CS35L33_BST_PEAK_CTL:
150 case CS35L33_PROTECT_CTL:
151 case CS35L33_BST_CTL1:
152 case CS35L33_BST_CTL2:
153 case CS35L33_ADSP_CTL:
154 case CS35L33_ADC_CTL:
155 case CS35L33_DAC_CTL:
156 case CS35L33_DIG_VOL_CTL:
157 case CS35L33_CLASSD_CTL:
158 case CS35L33_AMP_CTL:
159 case CS35L33_INT_MASK_1:
160 case CS35L33_INT_MASK_2:
161 case CS35L33_INT_STATUS_1:
162 case CS35L33_INT_STATUS_2:
163 case CS35L33_DIAG_LOCK:
164 case CS35L33_DIAG_CTRL_1:
165 case CS35L33_DIAG_CTRL_2:
166 case CS35L33_HG_MEMLDO_CTL:
167 case CS35L33_HG_REL_RATE:
168 case CS35L33_LDO_DEL:
169 case CS35L33_HG_HEAD:
170 case CS35L33_HG_EN:
171 case CS35L33_TX_VMON:
172 case CS35L33_TX_IMON:
173 case CS35L33_TX_VPMON:
174 case CS35L33_TX_VBSTMON:
175 case CS35L33_TX_FLAG:
176 case CS35L33_TX_EN1:
177 case CS35L33_TX_EN2:
178 case CS35L33_TX_EN3:
179 case CS35L33_TX_EN4:
180 case CS35L33_RX_AUD:
181 case CS35L33_RX_SPLY:
182 case CS35L33_RX_ALIVE:
183 case CS35L33_BST_CTL4:
184 return true;
185 default:
186 return false;
187 }
188}
189
190static DECLARE_TLV_DB_SCALE(classd_ctl_tlv, 900, 100, 0);
191static DECLARE_TLV_DB_SCALE(dac_tlv, -10200, 50, 0);
192
193static const struct snd_kcontrol_new cs35l33_snd_controls[] = {
194
195 SOC_SINGLE_TLV("SPK Amp Volume", CS35L33_AMP_CTL,
196 4, 0x09, 0, classd_ctl_tlv),
197 SOC_SINGLE_SX_TLV("DAC Volume", CS35L33_DIG_VOL_CTL,
198 0, 0x34, 0xE4, dac_tlv),
199};
200
201static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
202 struct snd_kcontrol *kcontrol, int event)
203{
204 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
205 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
206
207 switch (event) {
208 case SND_SOC_DAPM_POST_PMU:
209 if (!priv->amp_cal) {
210 usleep_range(8000, 9000);
211 priv->amp_cal = true;
212 regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
213 CS35L33_AMP_CAL, 0);
214 dev_dbg(codec->dev, "Amp calibration done\n");
215 }
216 dev_dbg(codec->dev, "Amp turned on\n");
217 break;
218 case SND_SOC_DAPM_POST_PMD:
219 dev_dbg(codec->dev, "Amp turned off\n");
220 break;
221 default:
222 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
223 break;
224 }
225
226 return 0;
227}
228
229static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
230 struct snd_kcontrol *kcontrol, int event)
231{
232 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
233 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
234 unsigned int val;
235
236 switch (event) {
237 case SND_SOC_DAPM_PRE_PMU:
238 regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
239 CS35L33_PDN_BST, 0);
240 val = priv->is_tdm_mode ? 0 : CS35L33_PDN_TDM;
241 regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
242 CS35L33_PDN_TDM, val);
243 dev_dbg(codec->dev, "BST turned on\n");
244 break;
245 case SND_SOC_DAPM_POST_PMU:
246 dev_dbg(codec->dev, "SDIN turned on\n");
247 if (!priv->amp_cal) {
248 regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
249 CS35L33_AMP_CAL, CS35L33_AMP_CAL);
250 dev_dbg(codec->dev, "Amp calibration started\n");
251 usleep_range(10000, 11000);
252 }
253 break;
254 case SND_SOC_DAPM_POST_PMD:
255 regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
256 CS35L33_PDN_TDM, CS35L33_PDN_TDM);
257 usleep_range(4000, 4100);
258 regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
259 CS35L33_PDN_BST, CS35L33_PDN_BST);
260 dev_dbg(codec->dev, "BST and SDIN turned off\n");
261 break;
262 default:
263 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
264
265 }
266
267 return 0;
268}
269
270static int cs35l33_sdout_event(struct snd_soc_dapm_widget *w,
271 struct snd_kcontrol *kcontrol, int event)
272{
273 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
274 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
275 unsigned int mask = CS35L33_SDOUT_3ST_I2S | CS35L33_PDN_TDM;
276 unsigned int mask2 = CS35L33_SDOUT_3ST_TDM;
277 unsigned int val, val2;
278
279 switch (event) {
280 case SND_SOC_DAPM_PRE_PMU:
281 if (priv->is_tdm_mode) {
282 /* set sdout_3st_i2s and reset pdn_tdm */
283 val = CS35L33_SDOUT_3ST_I2S;
284 /* reset sdout_3st_tdm */
285 val2 = 0;
286 } else {
287 /* reset sdout_3st_i2s and set pdn_tdm */
288 val = CS35L33_PDN_TDM;
289 /* set sdout_3st_tdm */
290 val2 = CS35L33_SDOUT_3ST_TDM;
291 }
292 dev_dbg(codec->dev, "SDOUT turned on\n");
293 break;
294 case SND_SOC_DAPM_PRE_PMD:
295 val = CS35L33_SDOUT_3ST_I2S | CS35L33_PDN_TDM;
296 val2 = CS35L33_SDOUT_3ST_TDM;
297 dev_dbg(codec->dev, "SDOUT turned off\n");
298 break;
299 default:
300 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
301 return 0;
302 }
303
304 regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
305 mask, val);
306 regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
307 mask2, val2);
308
309 return 0;
310}
311
312static const struct snd_soc_dapm_widget cs35l33_dapm_widgets[] = {
313
314 SND_SOC_DAPM_OUTPUT("SPK"),
315 SND_SOC_DAPM_OUT_DRV_E("SPKDRV", CS35L33_PWRCTL1, 7, 1, NULL, 0,
316 cs35l33_spkrdrv_event,
317 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
318 SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L33_PWRCTL2,
319 2, 1, cs35l33_sdin_event, SND_SOC_DAPM_PRE_PMU |
320 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
321
322 SND_SOC_DAPM_INPUT("MON"),
323
324 SND_SOC_DAPM_ADC("VMON", NULL,
325 CS35L33_PWRCTL2, CS35L33_PDN_VMON_SHIFT, 1),
326 SND_SOC_DAPM_ADC("IMON", NULL,
327 CS35L33_PWRCTL2, CS35L33_PDN_IMON_SHIFT, 1),
328 SND_SOC_DAPM_ADC("VPMON", NULL,
329 CS35L33_PWRCTL2, CS35L33_PDN_VPMON_SHIFT, 1),
330 SND_SOC_DAPM_ADC("VBSTMON", NULL,
331 CS35L33_PWRCTL2, CS35L33_PDN_VBSTMON_SHIFT, 1),
332
333 SND_SOC_DAPM_AIF_OUT_E("SDOUT", NULL, 0, SND_SOC_NOPM, 0, 0,
334 cs35l33_sdout_event, SND_SOC_DAPM_PRE_PMU |
335 SND_SOC_DAPM_PRE_PMD),
336};
337
338static const struct snd_soc_dapm_route cs35l33_audio_map[] = {
339 {"SDIN", NULL, "CS35L33 Playback"},
340 {"SPKDRV", NULL, "SDIN"},
341 {"SPK", NULL, "SPKDRV"},
342
343 {"VMON", NULL, "MON"},
344 {"IMON", NULL, "MON"},
345
346 {"SDOUT", NULL, "VMON"},
347 {"SDOUT", NULL, "IMON"},
348 {"CS35L33 Capture", NULL, "SDOUT"},
349};
350
351static const struct snd_soc_dapm_route cs35l33_vphg_auto_route[] = {
352 {"SPKDRV", NULL, "VPMON"},
353 {"VPMON", NULL, "CS35L33 Playback"},
354};
355
356static const struct snd_soc_dapm_route cs35l33_vp_vbst_mon_route[] = {
357 {"SDOUT", NULL, "VPMON"},
358 {"VPMON", NULL, "MON"},
359 {"SDOUT", NULL, "VBSTMON"},
360 {"VBSTMON", NULL, "MON"},
361};
362
363static int cs35l33_set_bias_level(struct snd_soc_codec *codec,
364 enum snd_soc_bias_level level)
365{
366 unsigned int val;
367 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
368
369 switch (level) {
370 case SND_SOC_BIAS_ON:
371 break;
372 case SND_SOC_BIAS_PREPARE:
373 regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
374 CS35L33_PDN_ALL, 0);
375 regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
376 CS35L33_MCLKDIS, 0);
377 break;
378 case SND_SOC_BIAS_STANDBY:
379 regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
380 CS35L33_PDN_ALL, CS35L33_PDN_ALL);
381 regmap_read(priv->regmap, CS35L33_INT_STATUS_2, &val);
382 usleep_range(1000, 1100);
383 if (val & CS35L33_PDN_DONE)
384 regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
385 CS35L33_MCLKDIS, CS35L33_MCLKDIS);
386 break;
387 case SND_SOC_BIAS_OFF:
388 break;
389 default:
390 return -EINVAL;
391 }
392
393 return 0;
394}
395
396struct cs35l33_mclk_div {
397 int mclk;
398 int srate;
399 u8 adsp_rate;
400 u8 int_fs_ratio;
401};
402
403static const struct cs35l33_mclk_div cs35l33_mclk_coeffs[] = {
404 /* MCLK, Sample Rate, adsp_rate, int_fs_ratio */
405 {5644800, 11025, 0x4, CS35L33_INT_FS_RATE},
406 {5644800, 22050, 0x8, CS35L33_INT_FS_RATE},
407 {5644800, 44100, 0xC, CS35L33_INT_FS_RATE},
408
409 {6000000, 8000, 0x1, 0},
410 {6000000, 11025, 0x2, 0},
411 {6000000, 11029, 0x3, 0},
412 {6000000, 12000, 0x4, 0},
413 {6000000, 16000, 0x5, 0},
414 {6000000, 22050, 0x6, 0},
415 {6000000, 22059, 0x7, 0},
416 {6000000, 24000, 0x8, 0},
417 {6000000, 32000, 0x9, 0},
418 {6000000, 44100, 0xA, 0},
419 {6000000, 44118, 0xB, 0},
420 {6000000, 48000, 0xC, 0},
421
422 {6144000, 8000, 0x1, CS35L33_INT_FS_RATE},
423 {6144000, 12000, 0x4, CS35L33_INT_FS_RATE},
424 {6144000, 16000, 0x5, CS35L33_INT_FS_RATE},
425 {6144000, 24000, 0x8, CS35L33_INT_FS_RATE},
426 {6144000, 32000, 0x9, CS35L33_INT_FS_RATE},
427 {6144000, 48000, 0xC, CS35L33_INT_FS_RATE},
428};
429
430static int cs35l33_get_mclk_coeff(int mclk, int srate)
431{
432 int i;
433
434 for (i = 0; i < ARRAY_SIZE(cs35l33_mclk_coeffs); i++) {
435 if (cs35l33_mclk_coeffs[i].mclk == mclk &&
436 cs35l33_mclk_coeffs[i].srate == srate)
437 return i;
438 }
439 return -EINVAL;
440}
441
442static int cs35l33_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
443{
444 struct snd_soc_codec *codec = codec_dai->codec;
445 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
446
447 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
448 case SND_SOC_DAIFMT_CBM_CFM:
449 regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL,
450 CS35L33_MS_MASK, CS35L33_MS_MASK);
451 dev_dbg(codec->dev, "Audio port in master mode\n");
452 break;
453 case SND_SOC_DAIFMT_CBS_CFS:
454 regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL,
455 CS35L33_MS_MASK, 0);
456 dev_dbg(codec->dev, "Audio port in slave mode\n");
457 break;
458 default:
459 return -EINVAL;
460 }
461
462 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
463 case SND_SOC_DAIFMT_DSP_A:
464 /*
465 * tdm mode in cs35l33 resembles dsp-a mode very
466 * closely, it is dsp-a with fsync shifted left by half bclk
467 */
468 priv->is_tdm_mode = true;
469 dev_dbg(codec->dev, "Audio port in TDM mode\n");
470 break;
471 case SND_SOC_DAIFMT_I2S:
472 priv->is_tdm_mode = false;
473 dev_dbg(codec->dev, "Audio port in I2S mode\n");
474 break;
475 default:
476 return -EINVAL;
477 }
478
479 return 0;
480}
481
482static int cs35l33_pcm_hw_params(struct snd_pcm_substream *substream,
483 struct snd_pcm_hw_params *params,
484 struct snd_soc_dai *dai)
485{
486 struct snd_soc_codec *codec = dai->codec;
487 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
488 int sample_size = params_width(params);
489 int coeff = cs35l33_get_mclk_coeff(priv->mclk_int, params_rate(params));
490
491 if (coeff < 0)
492 return coeff;
493
494 regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
495 CS35L33_ADSP_FS | CS35L33_INT_FS_RATE,
496 cs35l33_mclk_coeffs[coeff].int_fs_ratio
497 | cs35l33_mclk_coeffs[coeff].adsp_rate);
498
499 if (priv->is_tdm_mode) {
500 sample_size = (sample_size / 8) - 1;
501 if (sample_size > 2)
502 sample_size = 2;
503 regmap_update_bits(priv->regmap, CS35L33_RX_AUD,
504 CS35L33_AUDIN_RX_DEPTH,
505 sample_size << CS35L33_AUDIN_RX_DEPTH_SHIFT);
506 }
507
508 dev_dbg(codec->dev, "sample rate=%d, bits per sample=%d\n",
509 params_rate(params), params_width(params));
510
511 return 0;
512}
513
514static const unsigned int cs35l33_src_rates[] = {
515 8000, 11025, 11029, 12000, 16000, 22050,
516 22059, 24000, 32000, 44100, 44118, 48000
517};
518
519static const struct snd_pcm_hw_constraint_list cs35l33_constraints = {
520 .count = ARRAY_SIZE(cs35l33_src_rates),
521 .list = cs35l33_src_rates,
522};
523
524static int cs35l33_pcm_startup(struct snd_pcm_substream *substream,
525 struct snd_soc_dai *dai)
526{
527 snd_pcm_hw_constraint_list(substream->runtime, 0,
528 SNDRV_PCM_HW_PARAM_RATE,
529 &cs35l33_constraints);
530 return 0;
531}
532
533static int cs35l33_set_tristate(struct snd_soc_dai *dai, int tristate)
534{
535 struct snd_soc_codec *codec = dai->codec;
536 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
537
538 if (tristate) {
539 regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
540 CS35L33_SDOUT_3ST_I2S, CS35L33_SDOUT_3ST_I2S);
541 regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
542 CS35L33_SDOUT_3ST_TDM, CS35L33_SDOUT_3ST_TDM);
543 } else {
544 regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
545 CS35L33_SDOUT_3ST_I2S, 0);
546 regmap_update_bits(priv->regmap, CS35L33_CLK_CTL,
547 CS35L33_SDOUT_3ST_TDM, 0);
548 }
549
550 return 0;
551}
552
553static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
554 unsigned int rx_mask, int slots, int slot_width)
555{
556 struct snd_soc_codec *codec = dai->codec;
557 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
558 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
559 unsigned int reg, bit_pos, i;
560 int slot, slot_num;
561
562 if (slot_width != 8)
563 return -EINVAL;
564
565 /* scan rx_mask for aud slot */
566 slot = ffs(rx_mask) - 1;
567 if (slot >= 0) {
568 regmap_update_bits(priv->regmap, CS35L33_RX_AUD,
569 CS35L33_X_LOC, slot);
570 dev_dbg(codec->dev, "Audio starts from slots %d", slot);
571 }
572
573 /*
574 * scan tx_mask: vmon(2 slots); imon (2 slots);
575 * vpmon (1 slot) vbstmon (1 slot)
576 */
577 slot = ffs(tx_mask) - 1;
578 slot_num = 0;
579
580 for (i = 0; i < 2 ; i++) {
581 /* disable vpmon/vbstmon: enable later if set in tx_mask */
582 regmap_update_bits(priv->regmap, CS35L33_TX_VPMON + i,
583 CS35L33_X_STATE | CS35L33_X_LOC, CS35L33_X_STATE
584 | CS35L33_X_LOC);
585 }
586
587 /* disconnect {vp,vbst}_mon routes: eanble later if set in tx_mask*/
588 snd_soc_dapm_del_routes(dapm, cs35l33_vp_vbst_mon_route,
589 ARRAY_SIZE(cs35l33_vp_vbst_mon_route));
590
591 while (slot >= 0) {
592 /* configure VMON_TX_LOC */
593 if (slot_num == 0) {
594 regmap_update_bits(priv->regmap, CS35L33_TX_VMON,
595 CS35L33_X_STATE | CS35L33_X_LOC, slot);
596 dev_dbg(codec->dev, "VMON enabled in slots %d-%d",
597 slot, slot + 1);
598 }
599
600 /* configure IMON_TX_LOC */
601 if (slot_num == 3) {
602 regmap_update_bits(priv->regmap, CS35L33_TX_IMON,
603 CS35L33_X_STATE | CS35L33_X_LOC, slot);
604 dev_dbg(codec->dev, "IMON enabled in slots %d-%d",
605 slot, slot + 1);
606 }
607
608 /* configure VPMON_TX_LOC */
609 if (slot_num == 4) {
610 regmap_update_bits(priv->regmap, CS35L33_TX_VPMON,
611 CS35L33_X_STATE | CS35L33_X_LOC, slot);
612 snd_soc_dapm_add_routes(dapm,
613 &cs35l33_vp_vbst_mon_route[0], 2);
614 dev_dbg(codec->dev, "VPMON enabled in slots %d", slot);
615 }
616
617 /* configure VBSTMON_TX_LOC */
618 if (slot_num == 5) {
619 regmap_update_bits(priv->regmap, CS35L33_TX_VBSTMON,
620 CS35L33_X_STATE | CS35L33_X_LOC, slot);
621 snd_soc_dapm_add_routes(dapm,
622 &cs35l33_vp_vbst_mon_route[2], 2);
623 dev_dbg(codec->dev,
624 "VBSTMON enabled in slots %d", slot);
625 }
626
627 /* Enable the relevant tx slot */
628 reg = CS35L33_TX_EN4 - (slot/8);
629 bit_pos = slot - ((slot / 8) * (8));
630 regmap_update_bits(priv->regmap, reg,
631 1 << bit_pos, 1 << bit_pos);
632
633 tx_mask &= ~(1 << slot);
634 slot = ffs(tx_mask) - 1;
635 slot_num++;
636 }
637
638 return 0;
639}
640
641static int cs35l33_codec_set_sysclk(struct snd_soc_codec *codec,
642 int clk_id, int source, unsigned int freq, int dir)
643{
644 struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
645
646 switch (freq) {
647 case CS35L33_MCLK_5644:
648 case CS35L33_MCLK_6:
649 case CS35L33_MCLK_6144:
650 regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
651 CS35L33_MCLKDIV2, 0);
652 cs35l33->mclk_int = freq;
653 break;
654 case CS35L33_MCLK_11289:
655 case CS35L33_MCLK_12:
656 case CS35L33_MCLK_12288:
657 regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
658 CS35L33_MCLKDIV2, CS35L33_MCLKDIV2);
659 cs35l33->mclk_int = freq/2;
660 break;
661 default:
662 cs35l33->mclk_int = 0;
663 return -EINVAL;
664 }
665
666 dev_dbg(codec->dev, "external mclk freq=%d, internal mclk freq=%d\n",
667 freq, cs35l33->mclk_int);
668
669 return 0;
670}
671
672static const struct snd_soc_dai_ops cs35l33_ops = {
673 .startup = cs35l33_pcm_startup,
674 .set_tristate = cs35l33_set_tristate,
675 .set_fmt = cs35l33_set_dai_fmt,
676 .hw_params = cs35l33_pcm_hw_params,
677 .set_tdm_slot = cs35l33_set_tdm_slot,
678};
679
680static struct snd_soc_dai_driver cs35l33_dai = {
681 .name = "cs35l33-dai",
682 .id = 0,
683 .playback = {
684 .stream_name = "CS35L33 Playback",
685 .channels_min = 1,
686 .channels_max = 1,
687 .rates = CS35L33_RATES,
688 .formats = CS35L33_FORMATS,
689 },
690 .capture = {
691 .stream_name = "CS35L33 Capture",
692 .channels_min = 2,
693 .channels_max = 2,
694 .rates = CS35L33_RATES,
695 .formats = CS35L33_FORMATS,
696 },
697 .ops = &cs35l33_ops,
698 .symmetric_rates = 1,
699};
700
701static int cs35l33_set_hg_data(struct snd_soc_codec *codec,
702 struct cs35l33_pdata *pdata)
703{
704 struct cs35l33_hg *hg_config = &pdata->hg_config;
705 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
706 struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
707
708 if (hg_config->enable_hg_algo) {
709 regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL,
710 CS35L33_MEM_DEPTH_MASK,
711 hg_config->mem_depth << CS35L33_MEM_DEPTH_SHIFT);
712 regmap_write(priv->regmap, CS35L33_HG_REL_RATE,
713 hg_config->release_rate);
714 regmap_update_bits(priv->regmap, CS35L33_HG_HEAD,
715 CS35L33_HD_RM_MASK,
716 hg_config->hd_rm << CS35L33_HD_RM_SHIFT);
717 regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL,
718 CS35L33_LDO_THLD_MASK,
719 hg_config->ldo_thld << CS35L33_LDO_THLD_SHIFT);
720 regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL,
721 CS35L33_LDO_DISABLE_MASK,
722 hg_config->ldo_path_disable <<
723 CS35L33_LDO_DISABLE_SHIFT);
724 regmap_update_bits(priv->regmap, CS35L33_LDO_DEL,
725 CS35L33_LDO_ENTRY_DELAY_MASK,
726 hg_config->ldo_entry_delay <<
727 CS35L33_LDO_ENTRY_DELAY_SHIFT);
728 if (hg_config->vp_hg_auto) {
729 regmap_update_bits(priv->regmap, CS35L33_HG_EN,
730 CS35L33_VP_HG_AUTO_MASK,
731 CS35L33_VP_HG_AUTO_MASK);
732 snd_soc_dapm_add_routes(dapm, cs35l33_vphg_auto_route,
733 ARRAY_SIZE(cs35l33_vphg_auto_route));
734 }
735 regmap_update_bits(priv->regmap, CS35L33_HG_EN,
736 CS35L33_VP_HG_MASK,
737 hg_config->vp_hg << CS35L33_VP_HG_SHIFT);
738 regmap_update_bits(priv->regmap, CS35L33_LDO_DEL,
739 CS35L33_VP_HG_RATE_MASK,
740 hg_config->vp_hg_rate << CS35L33_VP_HG_RATE_SHIFT);
741 regmap_update_bits(priv->regmap, CS35L33_LDO_DEL,
742 CS35L33_VP_HG_VA_MASK,
743 hg_config->vp_hg_va << CS35L33_VP_HG_VA_SHIFT);
744 regmap_update_bits(priv->regmap, CS35L33_HG_EN,
745 CS35L33_CLASS_HG_EN_MASK, CS35L33_CLASS_HG_EN_MASK);
746 }
747 return 0;
748}
749
750static int cs35l33_set_bst_ipk(struct snd_soc_codec *codec, unsigned int bst)
751{
752 struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
753 int ret = 0, steps = 0;
754
755 /* Boost current in uA */
756 if (bst > 3600000 || bst < 1850000) {
757 dev_err(codec->dev, "Invalid boost current %d\n", bst);
758 ret = -EINVAL;
759 goto err;
760 }
761
762 if (bst % 15625) {
763 dev_err(codec->dev, "Current not a multiple of 15625uA (%d)\n",
764 bst);
765 ret = -EINVAL;
766 goto err;
767 }
768
769 while (bst > 1850000) {
770 bst -= 15625;
771 steps++;
772 }
773
774 regmap_write(cs35l33->regmap, CS35L33_BST_PEAK_CTL,
775 steps+0x70);
776
777err:
778 return ret;
779}
780
781static int cs35l33_probe(struct snd_soc_codec *codec)
782{
783 struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
784
785 cs35l33->codec = codec;
786 pm_runtime_get_sync(codec->dev);
787
788 regmap_update_bits(cs35l33->regmap, CS35L33_PROTECT_CTL,
789 CS35L33_ALIVE_WD_DIS, 0x8);
790 regmap_update_bits(cs35l33->regmap, CS35L33_BST_CTL2,
791 CS35L33_ALIVE_WD_DIS2,
792 CS35L33_ALIVE_WD_DIS2);
793
794 /* Set Platform Data */
795 regmap_update_bits(cs35l33->regmap, CS35L33_BST_CTL1,
796 CS35L33_BST_CTL_MASK, cs35l33->pdata.boost_ctl);
797 regmap_update_bits(cs35l33->regmap, CS35L33_CLASSD_CTL,
798 CS35L33_AMP_DRV_SEL_MASK,
799 cs35l33->pdata.amp_drv_sel << CS35L33_AMP_DRV_SEL_SHIFT);
800
801 if (cs35l33->pdata.boost_ipk)
802 cs35l33_set_bst_ipk(codec, cs35l33->pdata.boost_ipk);
803
804 if (cs35l33->enable_soft_ramp) {
805 snd_soc_update_bits(codec, CS35L33_DAC_CTL,
806 CS35L33_DIGSFT, CS35L33_DIGSFT);
807 snd_soc_update_bits(codec, CS35L33_DAC_CTL,
808 CS35L33_DSR_RATE, cs35l33->pdata.ramp_rate);
809 } else {
810 snd_soc_update_bits(codec, CS35L33_DAC_CTL,
811 CS35L33_DIGSFT, 0);
812 }
813
814 /* update IMON scaling rate if different from default of 0x8 */
815 if (cs35l33->pdata.imon_adc_scale != 0x8)
816 snd_soc_update_bits(codec, CS35L33_ADC_CTL,
817 CS35L33_IMON_SCALE, cs35l33->pdata.imon_adc_scale);
818
819 cs35l33_set_hg_data(codec, &(cs35l33->pdata));
820
821 /*
822 * unmask important interrupts that causes the chip to enter
823 * speaker safe mode and hence deserves user attention
824 */
825 regmap_update_bits(cs35l33->regmap, CS35L33_INT_MASK_1,
826 CS35L33_M_OTE | CS35L33_M_OTW | CS35L33_M_AMP_SHORT |
827 CS35L33_M_CAL_ERR, 0);
828
829 pm_runtime_put_sync(codec->dev);
830
831 return 0;
832}
833
834static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = {
835 .probe = cs35l33_probe,
836
837 .set_bias_level = cs35l33_set_bias_level,
838 .set_sysclk = cs35l33_codec_set_sysclk,
839
840 .dapm_widgets = cs35l33_dapm_widgets,
841 .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets),
842 .dapm_routes = cs35l33_audio_map,
843 .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map),
844 .controls = cs35l33_snd_controls,
845 .num_controls = ARRAY_SIZE(cs35l33_snd_controls),
846
847 .idle_bias_off = true,
848};
849
850static const struct regmap_config cs35l33_regmap = {
851 .reg_bits = 8,
852 .val_bits = 8,
853
854 .max_register = CS35L33_MAX_REGISTER,
855 .reg_defaults = cs35l33_reg,
856 .num_reg_defaults = ARRAY_SIZE(cs35l33_reg),
857 .volatile_reg = cs35l33_volatile_register,
858 .readable_reg = cs35l33_readable_register,
859 .writeable_reg = cs35l33_writeable_register,
860 .cache_type = REGCACHE_RBTREE,
861 .use_single_rw = true,
862};
863
864static int __maybe_unused cs35l33_runtime_resume(struct device *dev)
865{
866 struct cs35l33_private *cs35l33 = dev_get_drvdata(dev);
867 int ret;
868
869 dev_dbg(dev, "%s\n", __func__);
870
871 if (cs35l33->reset_gpio)
872 gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
873
874 ret = regulator_bulk_enable(cs35l33->num_core_supplies,
875 cs35l33->core_supplies);
876 if (ret != 0) {
877 dev_err(dev, "Failed to enable core supplies: %d\n", ret);
878 return ret;
879 }
880
881 regcache_cache_only(cs35l33->regmap, false);
882
883 if (cs35l33->reset_gpio)
884 gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);
885
886 msleep(CS35L33_BOOT_DELAY);
887
888 ret = regcache_sync(cs35l33->regmap);
889 if (ret != 0) {
890 dev_err(dev, "Failed to restore register cache\n");
891 goto err;
892 }
893
894 return 0;
895
896err:
897 regcache_cache_only(cs35l33->regmap, true);
898 regulator_bulk_disable(cs35l33->num_core_supplies,
899 cs35l33->core_supplies);
900
901 return ret;
902}
903
904static int __maybe_unused cs35l33_runtime_suspend(struct device *dev)
905{
906 struct cs35l33_private *cs35l33 = dev_get_drvdata(dev);
907
908 dev_dbg(dev, "%s\n", __func__);
909
910 /* redo the calibration in next power up */
911 cs35l33->amp_cal = false;
912
913 regcache_cache_only(cs35l33->regmap, true);
914 regcache_mark_dirty(cs35l33->regmap);
915 regulator_bulk_disable(cs35l33->num_core_supplies,
916 cs35l33->core_supplies);
917
918 return 0;
919}
920
921static const struct dev_pm_ops cs35l33_pm_ops = {
922 SET_RUNTIME_PM_OPS(cs35l33_runtime_suspend,
923 cs35l33_runtime_resume,
924 NULL)
925};
926
927static int cs35l33_get_hg_data(const struct device_node *np,
928 struct cs35l33_pdata *pdata)
929{
930 struct device_node *hg;
931 struct cs35l33_hg *hg_config = &pdata->hg_config;
932 u32 val32;
933
934 hg = of_get_child_by_name(np, "cirrus,hg-algo");
935 hg_config->enable_hg_algo = hg ? true : false;
936
937 if (hg_config->enable_hg_algo) {
938 if (of_property_read_u32(hg, "cirrus,mem-depth", &val32) >= 0)
939 hg_config->mem_depth = val32;
940 if (of_property_read_u32(hg, "cirrus,release-rate",
941 &val32) >= 0)
942 hg_config->release_rate = val32;
943 if (of_property_read_u32(hg, "cirrus,ldo-thld", &val32) >= 0)
944 hg_config->ldo_thld = val32;
945 if (of_property_read_u32(hg, "cirrus,ldo-path-disable",
946 &val32) >= 0)
947 hg_config->ldo_path_disable = val32;
948 if (of_property_read_u32(hg, "cirrus,ldo-entry-delay",
949 &val32) >= 0)
950 hg_config->ldo_entry_delay = val32;
951
952 hg_config->vp_hg_auto = of_property_read_bool(hg,
953 "cirrus,vp-hg-auto");
954
955 if (of_property_read_u32(hg, "cirrus,vp-hg", &val32) >= 0)
956 hg_config->vp_hg = val32;
957 if (of_property_read_u32(hg, "cirrus,vp-hg-rate", &val32) >= 0)
958 hg_config->vp_hg_rate = val32;
959 if (of_property_read_u32(hg, "cirrus,vp-hg-va", &val32) >= 0)
960 hg_config->vp_hg_va = val32;
961 }
962
963 of_node_put(hg);
964
965 return 0;
966}
967
968static irqreturn_t cs35l33_irq_thread(int irq, void *data)
969{
970 struct cs35l33_private *cs35l33 = data;
971 struct snd_soc_codec *codec = cs35l33->codec;
972 unsigned int sticky_val1, sticky_val2, current_val, mask1, mask2;
973
974 regmap_read(cs35l33->regmap, CS35L33_INT_STATUS_2,
975 &sticky_val2);
976 regmap_read(cs35l33->regmap, CS35L33_INT_STATUS_1,
977 &sticky_val1);
978 regmap_read(cs35l33->regmap, CS35L33_INT_MASK_2, &mask2);
979 regmap_read(cs35l33->regmap, CS35L33_INT_MASK_1, &mask1);
980
981 /* Check to see if the unmasked bits are active,
982 * if not then exit.
983 */
984 if (!(sticky_val1 & ~mask1) && !(sticky_val2 & ~mask2))
985 return IRQ_NONE;
986
987 regmap_read(cs35l33->regmap, CS35L33_INT_STATUS_1,
988 &current_val);
989
990 /* handle the interrupts */
991
992 if (sticky_val1 & CS35L33_AMP_SHORT) {
993 dev_crit(codec->dev, "Amp short error\n");
994 if (!(current_val & CS35L33_AMP_SHORT)) {
995 dev_dbg(codec->dev,
996 "Amp short error release\n");
997 regmap_update_bits(cs35l33->regmap,
998 CS35L33_AMP_CTL,
999 CS35L33_AMP_SHORT_RLS, 0);
1000 regmap_update_bits(cs35l33->regmap,
1001 CS35L33_AMP_CTL,
1002 CS35L33_AMP_SHORT_RLS,
1003 CS35L33_AMP_SHORT_RLS);
1004 regmap_update_bits(cs35l33->regmap,
1005 CS35L33_AMP_CTL, CS35L33_AMP_SHORT_RLS,
1006 0);
1007 }
1008 }
1009
1010 if (sticky_val1 & CS35L33_CAL_ERR) {
1011 dev_err(codec->dev, "Cal error\n");
1012
1013 /* redo the calibration in next power up */
1014 cs35l33->amp_cal = false;
1015
1016 if (!(current_val & CS35L33_CAL_ERR)) {
1017 dev_dbg(codec->dev, "Cal error release\n");
1018 regmap_update_bits(cs35l33->regmap,
1019 CS35L33_AMP_CTL, CS35L33_CAL_ERR_RLS,
1020 0);
1021 regmap_update_bits(cs35l33->regmap,
1022 CS35L33_AMP_CTL, CS35L33_CAL_ERR_RLS,
1023 CS35L33_CAL_ERR_RLS);
1024 regmap_update_bits(cs35l33->regmap,
1025 CS35L33_AMP_CTL, CS35L33_CAL_ERR_RLS,
1026 0);
1027 }
1028 }
1029
1030 if (sticky_val1 & CS35L33_OTE) {
1031 dev_crit(codec->dev, "Over temperature error\n");
1032 if (!(current_val & CS35L33_OTE)) {
1033 dev_dbg(codec->dev,
1034 "Over temperature error release\n");
1035 regmap_update_bits(cs35l33->regmap,
1036 CS35L33_AMP_CTL, CS35L33_OTE_RLS, 0);
1037 regmap_update_bits(cs35l33->regmap,
1038 CS35L33_AMP_CTL, CS35L33_OTE_RLS,
1039 CS35L33_OTE_RLS);
1040 regmap_update_bits(cs35l33->regmap,
1041 CS35L33_AMP_CTL, CS35L33_OTE_RLS, 0);
1042 }
1043 }
1044
1045 if (sticky_val1 & CS35L33_OTW) {
1046 dev_err(codec->dev, "Over temperature warning\n");
1047 if (!(current_val & CS35L33_OTW)) {
1048 dev_dbg(codec->dev,
1049 "Over temperature warning release\n");
1050 regmap_update_bits(cs35l33->regmap,
1051 CS35L33_AMP_CTL, CS35L33_OTW_RLS, 0);
1052 regmap_update_bits(cs35l33->regmap,
1053 CS35L33_AMP_CTL, CS35L33_OTW_RLS,
1054 CS35L33_OTW_RLS);
1055 regmap_update_bits(cs35l33->regmap,
1056 CS35L33_AMP_CTL, CS35L33_OTW_RLS, 0);
1057 }
1058 }
1059 if (CS35L33_ALIVE_ERR & sticky_val1)
1060 dev_err(codec->dev, "ERROR: ADSPCLK Interrupt\n");
1061
1062 if (CS35L33_MCLK_ERR & sticky_val1)
1063 dev_err(codec->dev, "ERROR: MCLK Interrupt\n");
1064
1065 if (CS35L33_VMON_OVFL & sticky_val2)
1066 dev_err(codec->dev,
1067 "ERROR: VMON Overflow Interrupt\n");
1068
1069 if (CS35L33_IMON_OVFL & sticky_val2)
1070 dev_err(codec->dev,
1071 "ERROR: IMON Overflow Interrupt\n");
1072
1073 if (CS35L33_VPMON_OVFL & sticky_val2)
1074 dev_err(codec->dev,
1075 "ERROR: VPMON Overflow Interrupt\n");
1076
1077 return IRQ_HANDLED;
1078}
1079
1080static const char * const cs35l33_core_supplies[] = {
1081 "VA",
1082 "VP",
1083};
1084
1085static int cs35l33_of_get_pdata(struct device *dev,
1086 struct cs35l33_private *cs35l33)
1087{
1088 struct device_node *np = dev->of_node;
1089 struct cs35l33_pdata *pdata = &cs35l33->pdata;
1090 u32 val32;
1091
1092 if (!np)
1093 return 0;
1094
1095 if (of_property_read_u32(np, "cirrus,boost-ctl", &val32) >= 0) {
1096 pdata->boost_ctl = val32;
1097 pdata->amp_drv_sel = 1;
1098 }
1099
1100 if (of_property_read_u32(np, "cirrus,ramp-rate", &val32) >= 0) {
1101 pdata->ramp_rate = val32;
1102 cs35l33->enable_soft_ramp = true;
1103 }
1104
1105 if (of_property_read_u32(np, "cirrus,boost-ipk", &val32) >= 0)
1106 pdata->boost_ipk = val32;
1107
1108 if (of_property_read_u32(np, "cirrus,imon-adc-scale", &val32) >= 0) {
1109 if ((val32 == 0x0) || (val32 == 0x7) || (val32 == 0x6))
1110 pdata->imon_adc_scale = val32;
1111 else
1112 /* use default value */
1113 pdata->imon_adc_scale = 0x8;
1114 } else {
1115 /* use default value */
1116 pdata->imon_adc_scale = 0x8;
1117 }
1118
1119 cs35l33_get_hg_data(np, pdata);
1120
1121 return 0;
1122}
1123
1124static int cs35l33_i2c_probe(struct i2c_client *i2c_client,
1125 const struct i2c_device_id *id)
1126{
1127 struct cs35l33_private *cs35l33;
1128 struct cs35l33_pdata *pdata = dev_get_platdata(&i2c_client->dev);
1129 int ret, devid, i;
1130 unsigned int reg;
1131
1132 cs35l33 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l33_private),
1133 GFP_KERNEL);
1134 if (!cs35l33)
1135 return -ENOMEM;
1136
1137 i2c_set_clientdata(i2c_client, cs35l33);
1138 cs35l33->regmap = devm_regmap_init_i2c(i2c_client, &cs35l33_regmap);
1139 if (IS_ERR(cs35l33->regmap)) {
1140 ret = PTR_ERR(cs35l33->regmap);
1141 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1142 return ret;
1143 }
1144
1145 regcache_cache_only(cs35l33->regmap, true);
1146
1147 for (i = 0; i < ARRAY_SIZE(cs35l33_core_supplies); i++)
1148 cs35l33->core_supplies[i].supply
1149 = cs35l33_core_supplies[i];
1150 cs35l33->num_core_supplies = ARRAY_SIZE(cs35l33_core_supplies);
1151
1152 ret = devm_regulator_bulk_get(&i2c_client->dev,
1153 cs35l33->num_core_supplies,
1154 cs35l33->core_supplies);
1155 if (ret != 0) {
1156 dev_err(&i2c_client->dev,
1157 "Failed to request core supplies: %d\n",
1158 ret);
1159 return ret;
1160 }
1161
1162 if (pdata) {
1163 cs35l33->pdata = *pdata;
1164 } else {
1165 cs35l33_of_get_pdata(&i2c_client->dev, cs35l33);
1166 pdata = &cs35l33->pdata;
1167 }
1168
1169 ret = devm_request_threaded_irq(&i2c_client->dev, i2c_client->irq, NULL,
1170 cs35l33_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW,
1171 "cs35l33", cs35l33);
1172 if (ret != 0)
1173 dev_warn(&i2c_client->dev, "Failed to request IRQ: %d\n", ret);
1174
1175 /* We could issue !RST or skip it based on AMP topology */
1176 cs35l33->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
1177 "reset-gpios", GPIOD_OUT_HIGH);
1178 if (IS_ERR(cs35l33->reset_gpio)) {
1179 dev_err(&i2c_client->dev, "%s ERROR: Can't get reset GPIO\n",
1180 __func__);
1181 return PTR_ERR(cs35l33->reset_gpio);
1182 }
1183
1184 ret = regulator_bulk_enable(cs35l33->num_core_supplies,
1185 cs35l33->core_supplies);
1186 if (ret != 0) {
1187 dev_err(&i2c_client->dev,
1188 "Failed to enable core supplies: %d\n",
1189 ret);
1190 return ret;
1191 }
1192
1193 if (cs35l33->reset_gpio)
1194 gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);
1195
1196 msleep(CS35L33_BOOT_DELAY);
1197 regcache_cache_only(cs35l33->regmap, false);
1198
1199 /* initialize codec */
1200 ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_AB, &reg);
1201 devid = (reg & 0xFF) << 12;
1202 ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_CD, &reg);
1203 devid |= (reg & 0xFF) << 4;
1204 ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_E, &reg);
1205 devid |= (reg & 0xF0) >> 4;
1206
1207 if (devid != CS35L33_CHIP_ID) {
1208 dev_err(&i2c_client->dev,
1209 "CS35L33 Device ID (%X). Expected ID %X\n",
1210 devid, CS35L33_CHIP_ID);
1211 goto err_enable;
1212 }
1213
1214 ret = regmap_read(cs35l33->regmap, CS35L33_REV_ID, &reg);
1215 if (ret < 0) {
1216 dev_err(&i2c_client->dev, "Get Revision ID failed\n");
1217 goto err_enable;
1218 }
1219
1220 dev_info(&i2c_client->dev,
1221 "Cirrus Logic CS35L33, Revision: %02X\n", reg & 0xFF);
1222
1223 ret = regmap_register_patch(cs35l33->regmap,
1224 cs35l33_patch, ARRAY_SIZE(cs35l33_patch));
1225 if (ret < 0) {
1226 dev_err(&i2c_client->dev,
1227 "Error in applying regmap patch: %d\n", ret);
1228 goto err_enable;
1229 }
1230
1231 /* disable mclk and tdm */
1232 regmap_update_bits(cs35l33->regmap, CS35L33_CLK_CTL,
1233 CS35L33_MCLKDIS | CS35L33_SDOUT_3ST_TDM,
1234 CS35L33_MCLKDIS | CS35L33_SDOUT_3ST_TDM);
1235
1236 pm_runtime_set_autosuspend_delay(&i2c_client->dev, 100);
1237 pm_runtime_use_autosuspend(&i2c_client->dev);
1238 pm_runtime_set_active(&i2c_client->dev);
1239 pm_runtime_enable(&i2c_client->dev);
1240
1241 ret = snd_soc_register_codec(&i2c_client->dev,
1242 &soc_codec_dev_cs35l33, &cs35l33_dai, 1);
1243 if (ret < 0) {
1244 dev_err(&i2c_client->dev, "%s: Register codec failed\n",
1245 __func__);
1246 goto err_enable;
1247 }
1248
1249 return 0;
1250
1251err_enable:
1252 regulator_bulk_disable(cs35l33->num_core_supplies,
1253 cs35l33->core_supplies);
1254
1255 return ret;
1256}
1257
1258static int cs35l33_i2c_remove(struct i2c_client *client)
1259{
1260 struct cs35l33_private *cs35l33 = i2c_get_clientdata(client);
1261
1262 snd_soc_unregister_codec(&client->dev);
1263
1264 if (cs35l33->reset_gpio)
1265 gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
1266
1267 pm_runtime_disable(&client->dev);
1268 regulator_bulk_disable(cs35l33->num_core_supplies,
1269 cs35l33->core_supplies);
1270
1271 return 0;
1272}
1273
1274static const struct of_device_id cs35l33_of_match[] = {
1275 { .compatible = "cirrus,cs35l33", },
1276 {},
1277};
1278MODULE_DEVICE_TABLE(of, cs35l33_of_match);
1279
1280static const struct i2c_device_id cs35l33_id[] = {
1281 {"cs35l33", 0},
1282 {}
1283};
1284
1285MODULE_DEVICE_TABLE(i2c, cs35l33_id);
1286
1287static struct i2c_driver cs35l33_i2c_driver = {
1288 .driver = {
1289 .name = "cs35l33",
1290 .pm = &cs35l33_pm_ops,
1291 .of_match_table = cs35l33_of_match,
1292
1293 },
1294 .id_table = cs35l33_id,
1295 .probe = cs35l33_i2c_probe,
1296 .remove = cs35l33_i2c_remove,
1297
1298};
1299module_i2c_driver(cs35l33_i2c_driver);
1300
1301MODULE_DESCRIPTION("ASoC CS35L33 driver");
1302MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <paul.handrigan@cirrus.com>");
1303MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l33.h b/sound/soc/codecs/cs35l33.h
new file mode 100644
index 000000000000..c045737d1a5f
--- /dev/null
+++ b/sound/soc/codecs/cs35l33.h
@@ -0,0 +1,221 @@
1/*
2 * cs35l33.h -- CS35L33 ALSA SoC audio driver
3 *
4 * Copyright 2016 Cirrus Logic, Inc.
5 *
6 * Author: Paul Handrigan <paul.handrigan@cirrus.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#ifndef __CS35L33_H__
15#define __CS35L33_H__
16
17#define CS35L33_CHIP_ID 0x00035A33
18#define CS35L33_DEVID_AB 0x01 /* Device ID A & B [RO] */
19#define CS35L33_DEVID_CD 0x02 /* Device ID C & D [RO] */
20#define CS35L33_DEVID_E 0x03 /* Device ID E [RO] */
21#define CS35L33_FAB_ID 0x04 /* Fab ID [RO] */
22#define CS35L33_REV_ID 0x05 /* Revision ID [RO] */
23#define CS35L33_PWRCTL1 0x06 /* Power Ctl 1 */
24#define CS35L33_PWRCTL2 0x07 /* Power Ctl 2 */
25#define CS35L33_CLK_CTL 0x08 /* Clock Ctl */
26#define CS35L33_BST_PEAK_CTL 0x09 /* Max Current for Boost */
27#define CS35L33_PROTECT_CTL 0x0A /* Amp Protection Parameters */
28#define CS35L33_BST_CTL1 0x0B /* Boost Converter CTL1 */
29#define CS35L33_BST_CTL2 0x0C /* Boost Converter CTL2 */
30#define CS35L33_ADSP_CTL 0x0D /* Serial Port Control */
31#define CS35L33_ADC_CTL 0x0E /* ADC Control */
32#define CS35L33_DAC_CTL 0x0F /* DAC Control */
33#define CS35L33_DIG_VOL_CTL 0x10 /* Digital Volume CTL */
34#define CS35L33_CLASSD_CTL 0x11 /* Class D Amp CTL */
35#define CS35L33_AMP_CTL 0x12 /* Amp Gain/Protecton Release CTL */
36#define CS35L33_INT_MASK_1 0x13 /* Interrupt Mask 1 */
37#define CS35L33_INT_MASK_2 0x14 /* Interrupt Mask 2 */
38#define CS35L33_INT_STATUS_1 0x15 /* Interrupt Status 1 [RO] */
39#define CS35L33_INT_STATUS_2 0x16 /* Interrupt Status 2 [RO] */
40#define CS35L33_DIAG_LOCK 0x17 /* Diagnostic Mode Register Lock */
41#define CS35L33_DIAG_CTRL_1 0x18 /* Diagnostic Mode Register Control */
42#define CS35L33_DIAG_CTRL_2 0x19 /* Diagnostic Mode Register Control 2 */
43#define CS35L33_HG_MEMLDO_CTL 0x23 /* H/G Memory/LDO CTL */
44#define CS35L33_HG_REL_RATE 0x24 /* H/G Release Rate */
45#define CS35L33_LDO_DEL 0x25 /* LDO Entry Delay/VPhg Control 1 */
46#define CS35L33_HG_HEAD 0x29 /* H/G Headroom */
47#define CS35L33_HG_EN 0x2A /* H/G Enable/VPhg CNT2 */
48#define CS35L33_TX_VMON 0x2D /* TDM TX Control 1 (VMON) */
49#define CS35L33_TX_IMON 0x2E /* TDM TX Control 2 (IMON) */
50#define CS35L33_TX_VPMON 0x2F /* TDM TX Control 3 (VPMON) */
51#define CS35L33_TX_VBSTMON 0x30 /* TDM TX Control 4 (VBSTMON) */
52#define CS35L33_TX_FLAG 0x31 /* TDM TX Control 5 (FLAG) */
53#define CS35L33_TX_EN1 0x32 /* TDM TX Enable 1 */
54#define CS35L33_TX_EN2 0x33 /* TDM TX Enable 2 */
55#define CS35L33_TX_EN3 0x34 /* TDM TX Enable 3 */
56#define CS35L33_TX_EN4 0x35 /* TDM TX Enable 4 */
57#define CS35L33_RX_AUD 0x36 /* TDM RX Control 1 */
58#define CS35L33_RX_SPLY 0x37 /* TDM RX Control 2 */
59#define CS35L33_RX_ALIVE 0x38 /* TDM RX Control 3 */
60#define CS35L33_BST_CTL4 0x39 /* Boost Converter Control 4 */
61#define CS35L33_HG_STATUS 0x3F /* H/G Status */
62#define CS35L33_MAX_REGISTER 0x59
63
64#define CS35L33_MCLK_5644 5644800
65#define CS35L33_MCLK_6144 6144000
66#define CS35L33_MCLK_6 6000000
67#define CS35L33_MCLK_11289 11289600
68#define CS35L33_MCLK_12 12000000
69#define CS35L33_MCLK_12288 12288000
70
71/* CS35L33_PWRCTL1 */
72#define CS35L33_PDN_AMP (1 << 7)
73#define CS35L33_PDN_BST (1 << 2)
74#define CS35L33_PDN_ALL 1
75
76/* CS35L33_PWRCTL2 */
77#define CS35L33_PDN_VMON_SHIFT 7
78#define CS35L33_PDN_VMON (1 << CS35L33_PDN_VMON_SHIFT)
79#define CS35L33_PDN_IMON_SHIFT 6
80#define CS35L33_PDN_IMON (1 << CS35L33_PDN_IMON_SHIFT)
81#define CS35L33_PDN_VPMON_SHIFT 5
82#define CS35L33_PDN_VPMON (1 << CS35L33_PDN_VPMON_SHIFT)
83#define CS35L33_PDN_VBSTMON_SHIFT 4
84#define CS35L33_PDN_VBSTMON (1 << CS35L33_PDN_VBSTMON_SHIFT)
85#define CS35L33_SDOUT_3ST_I2S_SHIFT 3
86#define CS35L33_SDOUT_3ST_I2S (1 << CS35L33_SDOUT_3ST_I2S_SHIFT)
87#define CS35L33_PDN_SDIN_SHIFT 2
88#define CS35L33_PDN_SDIN (1 << CS35L33_PDN_SDIN_SHIFT)
89#define CS35L33_PDN_TDM_SHIFT 1
90#define CS35L33_PDN_TDM (1 << CS35L33_PDN_TDM_SHIFT)
91
92/* CS35L33_CLK_CTL */
93#define CS35L33_MCLKDIS (1 << 7)
94#define CS35L33_MCLKDIV2 (1 << 6)
95#define CS35L33_SDOUT_3ST_TDM (1 << 5)
96#define CS35L33_INT_FS_RATE (1 << 4)
97#define CS35L33_ADSP_FS 0xF
98
99/* CS35L33_PROTECT_CTL */
100#define CS35L33_ALIVE_WD_DIS (3 << 2)
101
102/* CS35L33_BST_CTL1 */
103#define CS35L33_BST_CTL_SRC (1 << 6)
104#define CS35L33_BST_CTL_SHIFT (1 << 5)
105#define CS35L33_BST_CTL_MASK 0x3F
106
107/* CS35L33_BST_CTL2 */
108#define CS35L33_TDM_WD_SEL (1 << 4)
109#define CS35L33_ALIVE_WD_DIS2 (1 << 3)
110#define CS35L33_VBST_SR_STEP 0x3
111
112/* CS35L33_ADSP_CTL */
113#define CS35L33_ADSP_DRIVE (1 << 7)
114#define CS35L33_MS_MASK (1 << 6)
115#define CS35L33_SDIN_LOC (3 << 4)
116#define CS35L33_ALIVE_RATE 0x3
117
118/* CS35L33_ADC_CTL */
119#define CS35L33_INV_VMON (1 << 7)
120#define CS35L33_INV_IMON (1 << 6)
121#define CS35L33_ADC_NOTCH_DIS (1 << 5)
122#define CS35L33_IMON_SCALE 0xF
123
124/* CS35L33_DAC_CTL */
125#define CS35L33_INV_DAC (1 << 7)
126#define CS35L33_DAC_NOTCH_DIS (1 << 5)
127#define CS35L33_DIGSFT (1 << 4)
128#define CS35L33_DSR_RATE 0xF
129
130/* CS35L33_CLASSD_CTL */
131#define CS35L33_AMP_SD (1 << 6)
132#define CS35L33_AMP_DRV_SEL_SRC (1 << 5)
133#define CS35L33_AMP_DRV_SEL_MASK 0x10
134#define CS35L33_AMP_DRV_SEL_SHIFT 4
135#define CS35L33_AMP_CAL (1 << 3)
136#define CS35L33_GAIN_CHG_ZC_MASK 0x04
137#define CS35L33_GAIN_CHG_ZC_SHIFT 2
138#define CS35L33_CLASS_D_CTL_MASK 0x3F
139
140/* CS35L33_AMP_CTL */
141#define CS35L33_AMP_GAIN 0xF0
142#define CS35L33_CAL_ERR_RLS (1 << 3)
143#define CS35L33_AMP_SHORT_RLS (1 << 2)
144#define CS35L33_OTW_RLS (1 << 1)
145#define CS35L33_OTE_RLS 1
146
147/* CS35L33_INT_MASK_1 */
148#define CS35L33_M_CAL_ERR_SHIFT 6
149#define CS35L33_M_CAL_ERR (1 << CS35L33_M_CAL_ERR_SHIFT)
150#define CS35L33_M_ALIVE_ERR_SHIFT 5
151#define CS35L33_M_ALIVE_ERR (1 << CS35L33_M_ALIVE_ERR_SHIFT)
152#define CS35L33_M_AMP_SHORT_SHIFT 2
153#define CS35L33_M_AMP_SHORT (1 << CS35L33_M_AMP_SHORT_SHIFT)
154#define CS35L33_M_OTW_SHIFT 1
155#define CS35L33_M_OTW (1 << CS35L33_M_OTW_SHIFT)
156#define CS35L33_M_OTE_SHIFT 0
157#define CS35L33_M_OTE (1 << CS35L33_M_OTE_SHIFT)
158
159/* CS35L33_INT_STATUS_1 */
160#define CS35L33_CAL_ERR (1 << 6)
161#define CS35L33_ALIVE_ERR (1 << 5)
162#define CS35L33_ADSPCLK_ERR (1 << 4)
163#define CS35L33_MCLK_ERR (1 << 3)
164#define CS35L33_AMP_SHORT (1 << 2)
165#define CS35L33_OTW (1 << 1)
166#define CS35L33_OTE (1 << 0)
167
168/* CS35L33_INT_STATUS_2 */
169#define CS35L33_VMON_OVFL (1 << 7)
170#define CS35L33_IMON_OVFL (1 << 6)
171#define CS35L33_VPMON_OVFL (1 << 5)
172#define CS35L33_VBSTMON_OVFL (1 << 4)
173#define CS35L33_PDN_DONE 1
174
175/* CS35L33_BST_CTL4 */
176#define CS35L33_BST_RGS 0x70
177#define CS35L33_BST_COEFF3 0xF
178
179/* CS35L33_HG_MEMLDO_CTL */
180#define CS35L33_MEM_DEPTH_SHIFT 5
181#define CS35L33_MEM_DEPTH_MASK (0x3 << CS35L33_MEM_DEPTH_SHIFT)
182#define CS35L33_LDO_THLD_SHIFT 1
183#define CS35L33_LDO_THLD_MASK (0xF << CS35L33_LDO_THLD_SHIFT)
184#define CS35L33_LDO_DISABLE_SHIFT 0
185#define CS35L33_LDO_DISABLE_MASK (0x1 << CS35L33_LDO_DISABLE_SHIFT)
186
187/* CS35L33_LDO_DEL */
188#define CS35L33_VP_HG_VA_SHIFT 5
189#define CS35L33_VP_HG_VA_MASK (0x7 << CS35L33_VP_HG_VA_SHIFT)
190#define CS35L33_LDO_ENTRY_DELAY_SHIFT 2
191#define CS35L33_LDO_ENTRY_DELAY_MASK (0x7 << CS35L33_LDO_ENTRY_DELAY_SHIFT)
192#define CS35L33_VP_HG_RATE_SHIFT 0
193#define CS35L33_VP_HG_RATE_MASK (0x3 << CS35L33_VP_HG_RATE_SHIFT)
194
195/* CS35L33_HG_HEAD */
196#define CS35L33_HD_RM_SHIFT 0
197#define CS35L33_HD_RM_MASK (0x7F << CS35L33_HD_RM_SHIFT)
198
199/* CS35L33_HG_EN */
200#define CS35L33_CLASS_HG_ENA_SHIFT 7
201#define CS35L33_CLASS_HG_EN_MASK (0x1 << CS35L33_CLASS_HG_ENA_SHIFT)
202#define CS35L33_VP_HG_AUTO_SHIFT 6
203#define CS35L33_VP_HG_AUTO_MASK (0x1 << 6)
204#define CS35L33_VP_HG_SHIFT 0
205#define CS35L33_VP_HG_MASK (0x1F << CS35L33_VP_HG_SHIFT)
206
207#define CS35L33_RATES (SNDRV_PCM_RATE_8000_48000)
208#define CS35L33_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
209 SNDRV_PCM_FMTBIT_S24_LE)
210
211/* CS35L33_{RX,TX}_X */
212#define CS35L33_X_STATE_SHIFT 7
213#define CS35L33_X_STATE (1 << CS35L33_X_STATE_SHIFT)
214#define CS35L33_X_LOC_SHIFT 0
215#define CS35L33_X_LOC (0x1F << CS35L33_X_LOC_SHIFT)
216
217/* CS35L33_RX_AUD */
218#define CS35L33_AUDIN_RX_DEPTH_SHIFT 5
219#define CS35L33_AUDIN_RX_DEPTH (0x7 << CS35L33_AUDIN_RX_DEPTH_SHIFT)
220
221#endif
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index 5ec5a682d186..954a4f5d3338 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -359,6 +359,11 @@ SND_SOC_DAPM_INPUT("IN2R"),
359SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"), 359SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
360SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"), 360SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
361 361
362SND_SOC_DAPM_OUTPUT("DSP Voice Trigger"),
363
364SND_SOC_DAPM_SWITCH("DSP3 Voice Trigger", SND_SOC_NOPM, 2, 0,
365 &arizona_voice_trigger_switch[2]),
366
362SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 367SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
363 0, NULL, 0, arizona_in_ev, 368 0, NULL, 0, arizona_in_ev,
364 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 369 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
@@ -899,10 +904,16 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
899 904
900 { "MICSUPP", NULL, "SYSCLK" }, 905 { "MICSUPP", NULL, "SYSCLK" },
901 906
907 { "DRC1 Signal Activity", NULL, "SYSCLK" },
908 { "DRC2 Signal Activity", NULL, "SYSCLK" },
902 { "DRC1 Signal Activity", NULL, "DRC1L" }, 909 { "DRC1 Signal Activity", NULL, "DRC1L" },
903 { "DRC1 Signal Activity", NULL, "DRC1R" }, 910 { "DRC1 Signal Activity", NULL, "DRC1R" },
904 { "DRC2 Signal Activity", NULL, "DRC2L" }, 911 { "DRC2 Signal Activity", NULL, "DRC2L" },
905 { "DRC2 Signal Activity", NULL, "DRC2R" }, 912 { "DRC2 Signal Activity", NULL, "DRC2R" },
913
914 { "DSP Voice Trigger", NULL, "SYSCLK" },
915 { "DSP Voice Trigger", NULL, "DSP3 Voice Trigger" },
916 { "DSP3 Voice Trigger", "Switch", "DSP3" },
906}; 917};
907 918
908static int cs47l24_set_fll(struct snd_soc_codec *codec, int fll_id, int source, 919static int cs47l24_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
@@ -1067,6 +1078,7 @@ static irqreturn_t cs47l24_adsp2_irq(int irq, void *data)
1067{ 1078{
1068 struct cs47l24_priv *priv = data; 1079 struct cs47l24_priv *priv = data;
1069 struct arizona *arizona = priv->core.arizona; 1080 struct arizona *arizona = priv->core.arizona;
1081 struct arizona_voice_trigger_info info;
1070 int serviced = 0; 1082 int serviced = 0;
1071 int i, ret; 1083 int i, ret;
1072 1084
@@ -1074,6 +1086,12 @@ static irqreturn_t cs47l24_adsp2_irq(int irq, void *data)
1074 ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]); 1086 ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]);
1075 if (ret != -ENODEV) 1087 if (ret != -ENODEV)
1076 serviced++; 1088 serviced++;
1089 if (ret == WM_ADSP_COMPR_VOICE_TRIGGER) {
1090 info.core = i;
1091 arizona_call_notifiers(arizona,
1092 ARIZONA_NOTIFY_VOICE_TRIGGER,
1093 &info);
1094 }
1077 } 1095 }
1078 1096
1079 if (!serviced) { 1097 if (!serviced) {
@@ -1096,6 +1114,7 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec)
1096 arizona_init_spk(codec); 1114 arizona_init_spk(codec);
1097 arizona_init_gpio(codec); 1115 arizona_init_gpio(codec);
1098 arizona_init_mono(codec); 1116 arizona_init_mono(codec);
1117 arizona_init_notifiers(codec);
1099 1118
1100 ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, 1119 ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
1101 "ADSP2 Compressed IRQ", cs47l24_adsp2_irq, 1120 "ADSP2 Compressed IRQ", cs47l24_adsp2_irq,
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
new file mode 100644
index 000000000000..2c0d9c430a8c
--- /dev/null
+++ b/sound/soc/codecs/cs53l30.c
@@ -0,0 +1,1143 @@
1/*
2 * cs53l30.c -- CS53l30 ALSA Soc Audio driver
3 *
4 * Copyright 2015 Cirrus Logic, Inc.
5 *
6 * Authors: Paul Handrigan <Paul.Handrigan@cirrus.com>,
7 * Tim Howe <Tim.Howe@cirrus.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/clk.h>
16#include <linux/delay.h>
17#include <linux/i2c.h>
18#include <linux/module.h>
19#include <linux/of_gpio.h>
20#include <linux/gpio/consumer.h>
21#include <linux/regulator/consumer.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/tlv.h>
25
26#include "cs53l30.h"
27
28#define CS53L30_NUM_SUPPLIES 2
29static const char *const cs53l30_supply_names[CS53L30_NUM_SUPPLIES] = {
30 "VA",
31 "VP",
32};
33
34struct cs53l30_private {
35 struct regulator_bulk_data supplies[CS53L30_NUM_SUPPLIES];
36 struct regmap *regmap;
37 struct gpio_desc *reset_gpio;
38 struct gpio_desc *mute_gpio;
39 struct clk *mclk;
40 bool use_sdout2;
41 u32 mclk_rate;
42};
43
44static const struct reg_default cs53l30_reg_defaults[] = {
45 { CS53L30_PWRCTL, CS53L30_PWRCTL_DEFAULT },
46 { CS53L30_MCLKCTL, CS53L30_MCLKCTL_DEFAULT },
47 { CS53L30_INT_SR_CTL, CS53L30_INT_SR_CTL_DEFAULT },
48 { CS53L30_MICBIAS_CTL, CS53L30_MICBIAS_CTL_DEFAULT },
49 { CS53L30_ASPCFG_CTL, CS53L30_ASPCFG_CTL_DEFAULT },
50 { CS53L30_ASP_CTL1, CS53L30_ASP_CTL1_DEFAULT },
51 { CS53L30_ASP_TDMTX_CTL1, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
52 { CS53L30_ASP_TDMTX_CTL2, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
53 { CS53L30_ASP_TDMTX_CTL3, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
54 { CS53L30_ASP_TDMTX_CTL4, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
55 { CS53L30_ASP_TDMTX_EN1, CS53L30_ASP_TDMTX_ENx_DEFAULT },
56 { CS53L30_ASP_TDMTX_EN2, CS53L30_ASP_TDMTX_ENx_DEFAULT },
57 { CS53L30_ASP_TDMTX_EN3, CS53L30_ASP_TDMTX_ENx_DEFAULT },
58 { CS53L30_ASP_TDMTX_EN4, CS53L30_ASP_TDMTX_ENx_DEFAULT },
59 { CS53L30_ASP_TDMTX_EN5, CS53L30_ASP_TDMTX_ENx_DEFAULT },
60 { CS53L30_ASP_TDMTX_EN6, CS53L30_ASP_TDMTX_ENx_DEFAULT },
61 { CS53L30_ASP_CTL2, CS53L30_ASP_CTL2_DEFAULT },
62 { CS53L30_SFT_RAMP, CS53L30_SFT_RMP_DEFAULT },
63 { CS53L30_LRCK_CTL1, CS53L30_LRCK_CTLx_DEFAULT },
64 { CS53L30_LRCK_CTL2, CS53L30_LRCK_CTLx_DEFAULT },
65 { CS53L30_MUTEP_CTL1, CS53L30_MUTEP_CTL1_DEFAULT },
66 { CS53L30_MUTEP_CTL2, CS53L30_MUTEP_CTL2_DEFAULT },
67 { CS53L30_INBIAS_CTL1, CS53L30_INBIAS_CTL1_DEFAULT },
68 { CS53L30_INBIAS_CTL2, CS53L30_INBIAS_CTL2_DEFAULT },
69 { CS53L30_DMIC1_STR_CTL, CS53L30_DMIC1_STR_CTL_DEFAULT },
70 { CS53L30_DMIC2_STR_CTL, CS53L30_DMIC2_STR_CTL_DEFAULT },
71 { CS53L30_ADCDMIC1_CTL1, CS53L30_ADCDMICx_CTL1_DEFAULT },
72 { CS53L30_ADCDMIC1_CTL2, CS53L30_ADCDMIC1_CTL2_DEFAULT },
73 { CS53L30_ADC1_CTL3, CS53L30_ADCx_CTL3_DEFAULT },
74 { CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_CTL_DEFAULT },
75 { CS53L30_ADC1A_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
76 { CS53L30_ADC1B_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
77 { CS53L30_ADC1A_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
78 { CS53L30_ADC1B_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
79 { CS53L30_ADCDMIC2_CTL1, CS53L30_ADCDMICx_CTL1_DEFAULT },
80 { CS53L30_ADCDMIC2_CTL2, CS53L30_ADCDMIC1_CTL2_DEFAULT },
81 { CS53L30_ADC2_CTL3, CS53L30_ADCx_CTL3_DEFAULT },
82 { CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_CTL_DEFAULT },
83 { CS53L30_ADC2A_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
84 { CS53L30_ADC2B_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
85 { CS53L30_ADC2A_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
86 { CS53L30_ADC2B_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
87 { CS53L30_INT_MASK, CS53L30_DEVICE_INT_MASK },
88};
89
90static bool cs53l30_volatile_register(struct device *dev, unsigned int reg)
91{
92 if (reg == CS53L30_IS)
93 return true;
94 else
95 return false;
96}
97
98static bool cs53l30_writeable_register(struct device *dev, unsigned int reg)
99{
100 switch (reg) {
101 case CS53L30_DEVID_AB:
102 case CS53L30_DEVID_CD:
103 case CS53L30_DEVID_E:
104 case CS53L30_REVID:
105 case CS53L30_IS:
106 return false;
107 default:
108 return true;
109 }
110}
111
112static bool cs53l30_readable_register(struct device *dev, unsigned int reg)
113{
114 switch (reg) {
115 case CS53L30_DEVID_AB:
116 case CS53L30_DEVID_CD:
117 case CS53L30_DEVID_E:
118 case CS53L30_REVID:
119 case CS53L30_PWRCTL:
120 case CS53L30_MCLKCTL:
121 case CS53L30_INT_SR_CTL:
122 case CS53L30_MICBIAS_CTL:
123 case CS53L30_ASPCFG_CTL:
124 case CS53L30_ASP_CTL1:
125 case CS53L30_ASP_TDMTX_CTL1:
126 case CS53L30_ASP_TDMTX_CTL2:
127 case CS53L30_ASP_TDMTX_CTL3:
128 case CS53L30_ASP_TDMTX_CTL4:
129 case CS53L30_ASP_TDMTX_EN1:
130 case CS53L30_ASP_TDMTX_EN2:
131 case CS53L30_ASP_TDMTX_EN3:
132 case CS53L30_ASP_TDMTX_EN4:
133 case CS53L30_ASP_TDMTX_EN5:
134 case CS53L30_ASP_TDMTX_EN6:
135 case CS53L30_ASP_CTL2:
136 case CS53L30_SFT_RAMP:
137 case CS53L30_LRCK_CTL1:
138 case CS53L30_LRCK_CTL2:
139 case CS53L30_MUTEP_CTL1:
140 case CS53L30_MUTEP_CTL2:
141 case CS53L30_INBIAS_CTL1:
142 case CS53L30_INBIAS_CTL2:
143 case CS53L30_DMIC1_STR_CTL:
144 case CS53L30_DMIC2_STR_CTL:
145 case CS53L30_ADCDMIC1_CTL1:
146 case CS53L30_ADCDMIC1_CTL2:
147 case CS53L30_ADC1_CTL3:
148 case CS53L30_ADC1_NG_CTL:
149 case CS53L30_ADC1A_AFE_CTL:
150 case CS53L30_ADC1B_AFE_CTL:
151 case CS53L30_ADC1A_DIG_VOL:
152 case CS53L30_ADC1B_DIG_VOL:
153 case CS53L30_ADCDMIC2_CTL1:
154 case CS53L30_ADCDMIC2_CTL2:
155 case CS53L30_ADC2_CTL3:
156 case CS53L30_ADC2_NG_CTL:
157 case CS53L30_ADC2A_AFE_CTL:
158 case CS53L30_ADC2B_AFE_CTL:
159 case CS53L30_ADC2A_DIG_VOL:
160 case CS53L30_ADC2B_DIG_VOL:
161 case CS53L30_INT_MASK:
162 return true;
163 default:
164 return false;
165 }
166}
167
168static DECLARE_TLV_DB_SCALE(adc_boost_tlv, 0, 2000, 0);
169static DECLARE_TLV_DB_SCALE(adc_ng_boost_tlv, 0, 3000, 0);
170static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
171static DECLARE_TLV_DB_SCALE(dig_tlv, -9600, 100, 1);
172static DECLARE_TLV_DB_SCALE(pga_preamp_tlv, 0, 10000, 0);
173
174static const char * const input1_sel_text[] = {
175 "DMIC1 On AB In",
176 "DMIC1 On A In",
177 "DMIC1 On B In",
178 "ADC1 On AB In",
179 "ADC1 On A In",
180 "ADC1 On B In",
181 "DMIC1 Off ADC1 Off",
182};
183
184static unsigned int const input1_sel_values[] = {
185 CS53L30_CH_TYPE,
186 CS53L30_ADCxB_PDN | CS53L30_CH_TYPE,
187 CS53L30_ADCxA_PDN | CS53L30_CH_TYPE,
188 CS53L30_DMICx_PDN,
189 CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN,
190 CS53L30_ADCxA_PDN | CS53L30_DMICx_PDN,
191 CS53L30_ADCxA_PDN | CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN,
192};
193
194static const char * const input2_sel_text[] = {
195 "DMIC2 On AB In",
196 "DMIC2 On A In",
197 "DMIC2 On B In",
198 "ADC2 On AB In",
199 "ADC2 On A In",
200 "ADC2 On B In",
201 "DMIC2 Off ADC2 Off",
202};
203
204static unsigned int const input2_sel_values[] = {
205 0x0,
206 CS53L30_ADCxB_PDN,
207 CS53L30_ADCxA_PDN,
208 CS53L30_DMICx_PDN,
209 CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN,
210 CS53L30_ADCxA_PDN | CS53L30_DMICx_PDN,
211 CS53L30_ADCxA_PDN | CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN,
212};
213
214static const char * const input1_route_sel_text[] = {
215 "ADC1_SEL", "DMIC1_SEL",
216};
217
218static const struct soc_enum input1_route_sel_enum =
219 SOC_ENUM_SINGLE(CS53L30_ADCDMIC1_CTL1, CS53L30_CH_TYPE_SHIFT,
220 ARRAY_SIZE(input1_route_sel_text),
221 input1_route_sel_text);
222
223static SOC_VALUE_ENUM_SINGLE_DECL(input1_sel_enum, CS53L30_ADCDMIC1_CTL1, 0,
224 CS53L30_ADCDMICx_PDN_MASK, input1_sel_text,
225 input1_sel_values);
226
227static const struct snd_kcontrol_new input1_route_sel_mux =
228 SOC_DAPM_ENUM("Input 1 Route", input1_route_sel_enum);
229
230static const char * const input2_route_sel_text[] = {
231 "ADC2_SEL", "DMIC2_SEL",
232};
233
234/* Note: CS53L30_ADCDMIC1_CTL1 CH_TYPE controls inputs 1 and 2 */
235static const struct soc_enum input2_route_sel_enum =
236 SOC_ENUM_SINGLE(CS53L30_ADCDMIC1_CTL1, 0,
237 ARRAY_SIZE(input2_route_sel_text),
238 input2_route_sel_text);
239
240static SOC_VALUE_ENUM_SINGLE_DECL(input2_sel_enum, CS53L30_ADCDMIC2_CTL1, 0,
241 CS53L30_ADCDMICx_PDN_MASK, input2_sel_text,
242 input2_sel_values);
243
244static const struct snd_kcontrol_new input2_route_sel_mux =
245 SOC_DAPM_ENUM("Input 2 Route", input2_route_sel_enum);
246
247/*
248 * TB = 6144*(MCLK(int) scaling factor)/MCLK(internal)
249 * TB - Time base
250 * NOTE: If MCLK_INT_SCALE = 0, then TB=1
251 */
252static const char * const cs53l30_ng_delay_text[] = {
253 "TB*50ms", "TB*100ms", "TB*150ms", "TB*200ms",
254};
255
256static const struct soc_enum adc1_ng_delay_enum =
257 SOC_ENUM_SINGLE(CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_DELAY_SHIFT,
258 ARRAY_SIZE(cs53l30_ng_delay_text),
259 cs53l30_ng_delay_text);
260
261static const struct soc_enum adc2_ng_delay_enum =
262 SOC_ENUM_SINGLE(CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_DELAY_SHIFT,
263 ARRAY_SIZE(cs53l30_ng_delay_text),
264 cs53l30_ng_delay_text);
265
266/* The noise gate threshold selected will depend on NG Boost */
267static const char * const cs53l30_ng_thres_text[] = {
268 "-64dB/-34dB", "-66dB/-36dB", "-70dB/-40dB", "-73dB/-43dB",
269 "-76dB/-46dB", "-82dB/-52dB", "-58dB", "-64dB",
270};
271
272static const struct soc_enum adc1_ng_thres_enum =
273 SOC_ENUM_SINGLE(CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_THRESH_SHIFT,
274 ARRAY_SIZE(cs53l30_ng_thres_text),
275 cs53l30_ng_thres_text);
276
277static const struct soc_enum adc2_ng_thres_enum =
278 SOC_ENUM_SINGLE(CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_THRESH_SHIFT,
279 ARRAY_SIZE(cs53l30_ng_thres_text),
280 cs53l30_ng_thres_text);
281
282/* Corner frequencies are with an Fs of 48kHz. */
283static const char * const hpf_corner_freq_text[] = {
284 "1.86Hz", "120Hz", "235Hz", "466Hz",
285};
286
287static const struct soc_enum adc1_hpf_enum =
288 SOC_ENUM_SINGLE(CS53L30_ADC1_CTL3, CS53L30_ADCx_HPF_CF_SHIFT,
289 ARRAY_SIZE(hpf_corner_freq_text), hpf_corner_freq_text);
290
291static const struct soc_enum adc2_hpf_enum =
292 SOC_ENUM_SINGLE(CS53L30_ADC2_CTL3, CS53L30_ADCx_HPF_CF_SHIFT,
293 ARRAY_SIZE(hpf_corner_freq_text), hpf_corner_freq_text);
294
295static const struct snd_kcontrol_new cs53l30_snd_controls[] = {
296 SOC_SINGLE("Digital Soft-Ramp Switch", CS53L30_SFT_RAMP,
297 CS53L30_DIGSFT_SHIFT, 1, 0),
298 SOC_SINGLE("ADC1 Noise Gate Ganging Switch", CS53L30_ADC1_CTL3,
299 CS53L30_ADCx_NG_ALL_SHIFT, 1, 0),
300 SOC_SINGLE("ADC2 Noise Gate Ganging Switch", CS53L30_ADC2_CTL3,
301 CS53L30_ADCx_NG_ALL_SHIFT, 1, 0),
302 SOC_SINGLE("ADC1A Noise Gate Enable Switch", CS53L30_ADC1_NG_CTL,
303 CS53L30_ADCxA_NG_SHIFT, 1, 0),
304 SOC_SINGLE("ADC1B Noise Gate Enable Switch", CS53L30_ADC1_NG_CTL,
305 CS53L30_ADCxB_NG_SHIFT, 1, 0),
306 SOC_SINGLE("ADC2A Noise Gate Enable Switch", CS53L30_ADC2_NG_CTL,
307 CS53L30_ADCxA_NG_SHIFT, 1, 0),
308 SOC_SINGLE("ADC2B Noise Gate Enable Switch", CS53L30_ADC2_NG_CTL,
309 CS53L30_ADCxB_NG_SHIFT, 1, 0),
310 SOC_SINGLE("ADC1 Notch Filter Switch", CS53L30_ADCDMIC1_CTL2,
311 CS53L30_ADCx_NOTCH_DIS_SHIFT, 1, 1),
312 SOC_SINGLE("ADC2 Notch Filter Switch", CS53L30_ADCDMIC2_CTL2,
313 CS53L30_ADCx_NOTCH_DIS_SHIFT, 1, 1),
314 SOC_SINGLE("ADC1A Invert Switch", CS53L30_ADCDMIC1_CTL2,
315 CS53L30_ADCxA_INV_SHIFT, 1, 0),
316 SOC_SINGLE("ADC1B Invert Switch", CS53L30_ADCDMIC1_CTL2,
317 CS53L30_ADCxB_INV_SHIFT, 1, 0),
318 SOC_SINGLE("ADC2A Invert Switch", CS53L30_ADCDMIC2_CTL2,
319 CS53L30_ADCxA_INV_SHIFT, 1, 0),
320 SOC_SINGLE("ADC2B Invert Switch", CS53L30_ADCDMIC2_CTL2,
321 CS53L30_ADCxB_INV_SHIFT, 1, 0),
322
323 SOC_SINGLE_TLV("ADC1A Digital Boost Volume", CS53L30_ADCDMIC1_CTL2,
324 CS53L30_ADCxA_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv),
325 SOC_SINGLE_TLV("ADC1B Digital Boost Volume", CS53L30_ADCDMIC1_CTL2,
326 CS53L30_ADCxB_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv),
327 SOC_SINGLE_TLV("ADC2A Digital Boost Volume", CS53L30_ADCDMIC2_CTL2,
328 CS53L30_ADCxA_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv),
329 SOC_SINGLE_TLV("ADC2B Digital Boost Volume", CS53L30_ADCDMIC2_CTL2,
330 CS53L30_ADCxB_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv),
331 SOC_SINGLE_TLV("ADC1 NG Boost Volume", CS53L30_ADC1_NG_CTL,
332 CS53L30_ADCx_NG_BOOST_SHIFT, 1, 0, adc_ng_boost_tlv),
333 SOC_SINGLE_TLV("ADC2 NG Boost Volume", CS53L30_ADC2_NG_CTL,
334 CS53L30_ADCx_NG_BOOST_SHIFT, 1, 0, adc_ng_boost_tlv),
335
336 SOC_DOUBLE_R_TLV("ADC1 Preamplifier Volume", CS53L30_ADC1A_AFE_CTL,
337 CS53L30_ADC1B_AFE_CTL, CS53L30_ADCxy_PREAMP_SHIFT,
338 2, 0, pga_preamp_tlv),
339 SOC_DOUBLE_R_TLV("ADC2 Preamplifier Volume", CS53L30_ADC2A_AFE_CTL,
340 CS53L30_ADC2B_AFE_CTL, CS53L30_ADCxy_PREAMP_SHIFT,
341 2, 0, pga_preamp_tlv),
342
343 SOC_ENUM("Input 1 Channel Select", input1_sel_enum),
344 SOC_ENUM("Input 2 Channel Select", input2_sel_enum),
345
346 SOC_ENUM("ADC1 HPF Select", adc1_hpf_enum),
347 SOC_ENUM("ADC2 HPF Select", adc2_hpf_enum),
348 SOC_ENUM("ADC1 NG Threshold", adc1_ng_thres_enum),
349 SOC_ENUM("ADC2 NG Threshold", adc2_ng_thres_enum),
350 SOC_ENUM("ADC1 NG Delay", adc1_ng_delay_enum),
351 SOC_ENUM("ADC2 NG Delay", adc2_ng_delay_enum),
352
353 SOC_SINGLE_SX_TLV("ADC1A PGA Volume",
354 CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
355 SOC_SINGLE_SX_TLV("ADC1B PGA Volume",
356 CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
357 SOC_SINGLE_SX_TLV("ADC2A PGA Volume",
358 CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
359 SOC_SINGLE_SX_TLV("ADC2B PGA Volume",
360 CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x18, pga_tlv),
361
362 SOC_SINGLE_SX_TLV("ADC1A Digital Volume",
363 CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
364 SOC_SINGLE_SX_TLV("ADC1B Digital Volume",
365 CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
366 SOC_SINGLE_SX_TLV("ADC2A Digital Volume",
367 CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
368 SOC_SINGLE_SX_TLV("ADC2B Digital Volume",
369 CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv),
370};
371
372static const struct snd_soc_dapm_widget cs53l30_dapm_widgets[] = {
373 SND_SOC_DAPM_INPUT("IN1_DMIC1"),
374 SND_SOC_DAPM_INPUT("IN2"),
375 SND_SOC_DAPM_INPUT("IN3_DMIC2"),
376 SND_SOC_DAPM_INPUT("IN4"),
377 SND_SOC_DAPM_SUPPLY("MIC1 Bias", CS53L30_MICBIAS_CTL,
378 CS53L30_MIC1_BIAS_PDN_SHIFT, 1, NULL, 0),
379 SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS53L30_MICBIAS_CTL,
380 CS53L30_MIC2_BIAS_PDN_SHIFT, 1, NULL, 0),
381 SND_SOC_DAPM_SUPPLY("MIC3 Bias", CS53L30_MICBIAS_CTL,
382 CS53L30_MIC3_BIAS_PDN_SHIFT, 1, NULL, 0),
383 SND_SOC_DAPM_SUPPLY("MIC4 Bias", CS53L30_MICBIAS_CTL,
384 CS53L30_MIC4_BIAS_PDN_SHIFT, 1, NULL, 0),
385
386 SND_SOC_DAPM_AIF_OUT("ASP_SDOUT1", NULL, 0, CS53L30_ASP_CTL1,
387 CS53L30_ASP_SDOUTx_PDN_SHIFT, 1),
388 SND_SOC_DAPM_AIF_OUT("ASP_SDOUT2", NULL, 0, CS53L30_ASP_CTL2,
389 CS53L30_ASP_SDOUTx_PDN_SHIFT, 1),
390
391 SND_SOC_DAPM_MUX("Input Mux 1", SND_SOC_NOPM, 0, 0,
392 &input1_route_sel_mux),
393 SND_SOC_DAPM_MUX("Input Mux 2", SND_SOC_NOPM, 0, 0,
394 &input2_route_sel_mux),
395
396 SND_SOC_DAPM_ADC("ADC1A", NULL, CS53L30_ADCDMIC1_CTL1,
397 CS53L30_ADCxA_PDN_SHIFT, 1),
398 SND_SOC_DAPM_ADC("ADC1B", NULL, CS53L30_ADCDMIC1_CTL1,
399 CS53L30_ADCxB_PDN_SHIFT, 1),
400 SND_SOC_DAPM_ADC("ADC2A", NULL, CS53L30_ADCDMIC2_CTL1,
401 CS53L30_ADCxA_PDN_SHIFT, 1),
402 SND_SOC_DAPM_ADC("ADC2B", NULL, CS53L30_ADCDMIC2_CTL1,
403 CS53L30_ADCxB_PDN_SHIFT, 1),
404 SND_SOC_DAPM_ADC("DMIC1", NULL, CS53L30_ADCDMIC1_CTL1,
405 CS53L30_DMICx_PDN_SHIFT, 1),
406 SND_SOC_DAPM_ADC("DMIC2", NULL, CS53L30_ADCDMIC2_CTL1,
407 CS53L30_DMICx_PDN_SHIFT, 1),
408};
409
410static const struct snd_soc_dapm_route cs53l30_dapm_routes[] = {
411 /* ADC Input Paths */
412 {"ADC1A", NULL, "IN1_DMIC1"},
413 {"Input Mux 1", "ADC1_SEL", "ADC1A"},
414 {"ADC1B", NULL, "IN2"},
415
416 {"ADC2A", NULL, "IN3_DMIC2"},
417 {"Input Mux 2", "ADC2_SEL", "ADC2A"},
418 {"ADC2B", NULL, "IN4"},
419
420 /* MIC Bias Paths */
421 {"ADC1A", NULL, "MIC1 Bias"},
422 {"ADC1B", NULL, "MIC2 Bias"},
423 {"ADC2A", NULL, "MIC3 Bias"},
424 {"ADC2B", NULL, "MIC4 Bias"},
425
426 /* DMIC Paths */
427 {"DMIC1", NULL, "IN1_DMIC1"},
428 {"Input Mux 1", "DMIC1_SEL", "DMIC1"},
429
430 {"DMIC2", NULL, "IN3_DMIC2"},
431 {"Input Mux 2", "DMIC2_SEL", "DMIC2"},
432};
433
434static const struct snd_soc_dapm_route cs53l30_dapm_routes_sdout1[] = {
435 /* Output Paths when using SDOUT1 only */
436 {"ASP_SDOUT1", NULL, "ADC1A" },
437 {"ASP_SDOUT1", NULL, "Input Mux 1"},
438 {"ASP_SDOUT1", NULL, "ADC1B"},
439
440 {"ASP_SDOUT1", NULL, "ADC2A"},
441 {"ASP_SDOUT1", NULL, "Input Mux 2"},
442 {"ASP_SDOUT1", NULL, "ADC2B"},
443
444 {"Capture", NULL, "ASP_SDOUT1"},
445};
446
447static const struct snd_soc_dapm_route cs53l30_dapm_routes_sdout2[] = {
448 /* Output Paths when using both SDOUT1 and SDOUT2 */
449 {"ASP_SDOUT1", NULL, "ADC1A" },
450 {"ASP_SDOUT1", NULL, "Input Mux 1"},
451 {"ASP_SDOUT1", NULL, "ADC1B"},
452
453 {"ASP_SDOUT2", NULL, "ADC2A"},
454 {"ASP_SDOUT2", NULL, "Input Mux 2"},
455 {"ASP_SDOUT2", NULL, "ADC2B"},
456
457 {"Capture", NULL, "ASP_SDOUT1"},
458 {"Capture", NULL, "ASP_SDOUT2"},
459};
460
461struct cs53l30_mclk_div {
462 u32 mclk_rate;
463 u32 srate;
464 u8 asp_rate;
465 u8 internal_fs_ratio;
466 u8 mclk_int_scale;
467};
468
469static struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = {
470 /* NOTE: Enable MCLK_INT_SCALE to save power. */
471
472 /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */
473 {5644800, 11025, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
474 {5644800, 22050, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
475 {5644800, 44100, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
476
477 {6000000, 8000, 0x1, 0, CS53L30_MCLK_INT_SCALE},
478 {6000000, 11025, 0x2, 0, CS53L30_MCLK_INT_SCALE},
479 {6000000, 12000, 0x4, 0, CS53L30_MCLK_INT_SCALE},
480 {6000000, 16000, 0x5, 0, CS53L30_MCLK_INT_SCALE},
481 {6000000, 22050, 0x6, 0, CS53L30_MCLK_INT_SCALE},
482 {6000000, 24000, 0x8, 0, CS53L30_MCLK_INT_SCALE},
483 {6000000, 32000, 0x9, 0, CS53L30_MCLK_INT_SCALE},
484 {6000000, 44100, 0xA, 0, CS53L30_MCLK_INT_SCALE},
485 {6000000, 48000, 0xC, 0, CS53L30_MCLK_INT_SCALE},
486
487 {6144000, 8000, 0x1, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
488 {6144000, 11025, 0x2, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
489 {6144000, 12000, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
490 {6144000, 16000, 0x5, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
491 {6144000, 22050, 0x6, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
492 {6144000, 24000, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
493 {6144000, 32000, 0x9, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
494 {6144000, 44100, 0xA, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
495 {6144000, 48000, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
496
497 {6400000, 8000, 0x1, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
498 {6400000, 11025, 0x2, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
499 {6400000, 12000, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
500 {6400000, 16000, 0x5, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
501 {6400000, 22050, 0x6, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
502 {6400000, 24000, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
503 {6400000, 32000, 0x9, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
504 {6400000, 44100, 0xA, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
505 {6400000, 48000, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
506};
507
508struct cs53l30_mclkx_div {
509 u32 mclkx;
510 u8 ratio;
511 u8 mclkdiv;
512};
513
514static struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = {
515 {5644800, 1, CS53L30_MCLK_DIV_BY_1},
516 {6000000, 1, CS53L30_MCLK_DIV_BY_1},
517 {6144000, 1, CS53L30_MCLK_DIV_BY_1},
518 {11289600, 2, CS53L30_MCLK_DIV_BY_2},
519 {12288000, 2, CS53L30_MCLK_DIV_BY_2},
520 {12000000, 2, CS53L30_MCLK_DIV_BY_2},
521 {19200000, 3, CS53L30_MCLK_DIV_BY_3},
522};
523
524static int cs53l30_get_mclkx_coeff(int mclkx)
525{
526 int i;
527
528 for (i = 0; i < ARRAY_SIZE(cs53l30_mclkx_coeffs); i++) {
529 if (cs53l30_mclkx_coeffs[i].mclkx == mclkx)
530 return i;
531 }
532
533 return -EINVAL;
534}
535
536static int cs53l30_get_mclk_coeff(int mclk_rate, int srate)
537{
538 int i;
539
540 for (i = 0; i < ARRAY_SIZE(cs53l30_mclk_coeffs); i++) {
541 if (cs53l30_mclk_coeffs[i].mclk_rate == mclk_rate &&
542 cs53l30_mclk_coeffs[i].srate == srate)
543 return i;
544 }
545
546 return -EINVAL;
547}
548
549static int cs53l30_set_sysclk(struct snd_soc_dai *dai,
550 int clk_id, unsigned int freq, int dir)
551{
552 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
553 int mclkx_coeff;
554 u32 mclk_rate;
555
556 /* MCLKX -> MCLK */
557 mclkx_coeff = cs53l30_get_mclkx_coeff(freq);
558 if (mclkx_coeff < 0)
559 return mclkx_coeff;
560
561 mclk_rate = cs53l30_mclkx_coeffs[mclkx_coeff].mclkx /
562 cs53l30_mclkx_coeffs[mclkx_coeff].ratio;
563
564 regmap_update_bits(priv->regmap, CS53L30_MCLKCTL,
565 CS53L30_MCLK_DIV_MASK,
566 cs53l30_mclkx_coeffs[mclkx_coeff].mclkdiv);
567
568 priv->mclk_rate = mclk_rate;
569
570 return 0;
571}
572
573static int cs53l30_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
574{
575 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
576 u8 aspcfg = 0, aspctl1 = 0;
577
578 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
579 case SND_SOC_DAIFMT_CBM_CFM:
580 aspcfg |= CS53L30_ASP_MS;
581 break;
582 case SND_SOC_DAIFMT_CBS_CFS:
583 break;
584 default:
585 return -EINVAL;
586 }
587
588 /* DAI mode */
589 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
590 case SND_SOC_DAIFMT_I2S:
591 /* Set TDM_PDN to turn off TDM mode -- Reset default */
592 aspctl1 |= CS53L30_ASP_TDM_PDN;
593 break;
594 case SND_SOC_DAIFMT_DSP_A:
595 /*
596 * Clear TDM_PDN to turn on TDM mode; Use ASP_SCLK_INV = 0
597 * with SHIFT_LEFT = 1 combination as Figure 4-13 shows in
598 * the CS53L30 datasheet
599 */
600 aspctl1 |= CS53L30_SHIFT_LEFT;
601 break;
602 default:
603 return -EINVAL;
604 }
605
606 /* Check to see if the SCLK is inverted */
607 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
608 case SND_SOC_DAIFMT_IB_NF:
609 case SND_SOC_DAIFMT_IB_IF:
610 aspcfg ^= CS53L30_ASP_SCLK_INV;
611 break;
612 default:
613 break;
614 }
615
616 regmap_update_bits(priv->regmap, CS53L30_ASPCFG_CTL,
617 CS53L30_ASP_MS | CS53L30_ASP_SCLK_INV, aspcfg);
618
619 regmap_update_bits(priv->regmap, CS53L30_ASP_CTL1,
620 CS53L30_ASP_TDM_PDN | CS53L30_SHIFT_LEFT, aspctl1);
621
622 return 0;
623}
624
625static int cs53l30_pcm_hw_params(struct snd_pcm_substream *substream,
626 struct snd_pcm_hw_params *params,
627 struct snd_soc_dai *dai)
628{
629 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
630 int srate = params_rate(params);
631 int mclk_coeff;
632
633 /* MCLK -> srate */
634 mclk_coeff = cs53l30_get_mclk_coeff(priv->mclk_rate, srate);
635 if (mclk_coeff < 0)
636 return -EINVAL;
637
638 regmap_update_bits(priv->regmap, CS53L30_INT_SR_CTL,
639 CS53L30_INTRNL_FS_RATIO_MASK,
640 cs53l30_mclk_coeffs[mclk_coeff].internal_fs_ratio);
641
642 regmap_update_bits(priv->regmap, CS53L30_MCLKCTL,
643 CS53L30_MCLK_INT_SCALE_MASK,
644 cs53l30_mclk_coeffs[mclk_coeff].mclk_int_scale);
645
646 regmap_update_bits(priv->regmap, CS53L30_ASPCFG_CTL,
647 CS53L30_ASP_RATE_MASK,
648 cs53l30_mclk_coeffs[mclk_coeff].asp_rate);
649
650 return 0;
651}
652
653static int cs53l30_set_bias_level(struct snd_soc_codec *codec,
654 enum snd_soc_bias_level level)
655{
656 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
657 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(codec);
658 unsigned int reg;
659 int i, inter_max_check, ret;
660
661 switch (level) {
662 case SND_SOC_BIAS_ON:
663 break;
664 case SND_SOC_BIAS_PREPARE:
665 if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
666 regmap_update_bits(priv->regmap, CS53L30_PWRCTL,
667 CS53L30_PDN_LP_MASK, 0);
668 break;
669 case SND_SOC_BIAS_STANDBY:
670 if (dapm->bias_level == SND_SOC_BIAS_OFF) {
671 ret = clk_prepare_enable(priv->mclk);
672 if (ret) {
673 dev_err(codec->dev,
674 "failed to enable MCLK: %d\n", ret);
675 return ret;
676 }
677 regmap_update_bits(priv->regmap, CS53L30_MCLKCTL,
678 CS53L30_MCLK_DIS_MASK, 0);
679 regmap_update_bits(priv->regmap, CS53L30_PWRCTL,
680 CS53L30_PDN_ULP_MASK, 0);
681 msleep(50);
682 } else {
683 regmap_update_bits(priv->regmap, CS53L30_PWRCTL,
684 CS53L30_PDN_ULP_MASK,
685 CS53L30_PDN_ULP);
686 }
687 break;
688 case SND_SOC_BIAS_OFF:
689 regmap_update_bits(priv->regmap, CS53L30_INT_MASK,
690 CS53L30_PDN_DONE, 0);
691 /*
692 * If digital softramp is set, the amount of time required
693 * for power down increases and depends on the digital
694 * volume setting.
695 */
696
697 /* Set the max possible time if digsft is set */
698 regmap_read(priv->regmap, CS53L30_SFT_RAMP, &reg);
699 if (reg & CS53L30_DIGSFT_MASK)
700 inter_max_check = CS53L30_PDN_POLL_MAX;
701 else
702 inter_max_check = 10;
703
704 regmap_update_bits(priv->regmap, CS53L30_PWRCTL,
705 CS53L30_PDN_ULP_MASK,
706 CS53L30_PDN_ULP);
707 /* PDN_DONE will take a min of 20ms to be set.*/
708 msleep(20);
709 /* Clr status */
710 regmap_read(priv->regmap, CS53L30_IS, &reg);
711 for (i = 0; i < inter_max_check; i++) {
712 if (inter_max_check < 10) {
713 usleep_range(1000, 1100);
714 regmap_read(priv->regmap, CS53L30_IS, &reg);
715 if (reg & CS53L30_PDN_DONE)
716 break;
717 } else {
718 usleep_range(10000, 10100);
719 regmap_read(priv->regmap, CS53L30_IS, &reg);
720 if (reg & CS53L30_PDN_DONE)
721 break;
722 }
723 }
724 /* PDN_DONE is set. We now can disable the MCLK */
725 regmap_update_bits(priv->regmap, CS53L30_INT_MASK,
726 CS53L30_PDN_DONE, CS53L30_PDN_DONE);
727 regmap_update_bits(priv->regmap, CS53L30_MCLKCTL,
728 CS53L30_MCLK_DIS_MASK,
729 CS53L30_MCLK_DIS);
730 clk_disable_unprepare(priv->mclk);
731 break;
732 }
733
734 return 0;
735}
736
737static int cs53l30_set_tristate(struct snd_soc_dai *dai, int tristate)
738{
739 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
740 u8 val = tristate ? CS53L30_ASP_3ST : 0;
741
742 return regmap_update_bits(priv->regmap, CS53L30_ASP_CTL1,
743 CS53L30_ASP_3ST_MASK, val);
744}
745
746static unsigned int const cs53l30_src_rates[] = {
747 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
748};
749
750static struct snd_pcm_hw_constraint_list src_constraints = {
751 .count = ARRAY_SIZE(cs53l30_src_rates),
752 .list = cs53l30_src_rates,
753};
754
755static int cs53l30_pcm_startup(struct snd_pcm_substream *substream,
756 struct snd_soc_dai *dai)
757{
758 snd_pcm_hw_constraint_list(substream->runtime, 0,
759 SNDRV_PCM_HW_PARAM_RATE, &src_constraints);
760
761 return 0;
762}
763
764/*
765 * Note: CS53L30 counts the slot number per byte while ASoC counts the slot
766 * number per slot_width. So there is a difference between the slots of ASoC
767 * and the slots of CS53L30.
768 */
769static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai,
770 unsigned int tx_mask, unsigned int rx_mask,
771 int slots, int slot_width)
772{
773 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
774 unsigned int loc[CS53L30_TDM_SLOT_MAX] = {48, 48, 48, 48};
775 unsigned int slot_next, slot_step;
776 u64 tx_enable = 0;
777 int i;
778
779 if (!rx_mask) {
780 dev_err(dai->dev, "rx masks must not be 0\n");
781 return -EINVAL;
782 }
783
784 /* Assuming slot_width is not supposed to be greater than 64 */
785 if (slots <= 0 || slot_width <= 0 || slot_width > 64) {
786 dev_err(dai->dev, "invalid slot number or slot width\n");
787 return -EINVAL;
788 }
789
790 if (slot_width & 0x7) {
791 dev_err(dai->dev, "slot width must count in byte\n");
792 return -EINVAL;
793 }
794
795 /* How many bytes in each ASoC slot */
796 slot_step = slot_width >> 3;
797
798 for (i = 0; rx_mask && i < CS53L30_TDM_SLOT_MAX; i++) {
799 /* Find the first slot from LSB */
800 slot_next = __ffs(rx_mask);
801 /* Save the slot location by converting to CS53L30 slot */
802 loc[i] = slot_next * slot_step;
803 /* Create the mask of CS53L30 slot */
804 tx_enable |= (u64)((u64)(1 << slot_step) - 1) << (u64)loc[i];
805 /* Clear this slot from rx_mask */
806 rx_mask &= ~(1 << slot_next);
807 }
808
809 /* Error out to avoid slot shift */
810 if (rx_mask && i == CS53L30_TDM_SLOT_MAX) {
811 dev_err(dai->dev, "rx_mask exceeds max slot number: %d\n",
812 CS53L30_TDM_SLOT_MAX);
813 return -EINVAL;
814 }
815
816 /* Validate the last active CS53L30 slot */
817 slot_next = loc[i - 1] + slot_step - 1;
818 if (slot_next > 47) {
819 dev_err(dai->dev, "slot selection out of bounds: %u\n",
820 slot_next);
821 return -EINVAL;
822 }
823
824 for (i = 0; i < CS53L30_TDM_SLOT_MAX && loc[i] != 48; i++) {
825 regmap_update_bits(priv->regmap, CS53L30_ASP_TDMTX_CTL(i),
826 CS53L30_ASP_CHx_TX_LOC_MASK, loc[i]);
827 dev_dbg(dai->dev, "loc[%d]=%x\n", i, loc[i]);
828 }
829
830 for (i = 0; i < CS53L30_ASP_TDMTX_ENx_MAX && tx_enable; i++) {
831 regmap_write(priv->regmap, CS53L30_ASP_TDMTX_ENx(i),
832 tx_enable & 0xff);
833 tx_enable >>= 8;
834 dev_dbg(dai->dev, "en_reg=%x, tx_enable=%llx\n",
835 CS53L30_ASP_TDMTX_ENx(i), tx_enable & 0xff);
836 }
837
838 return 0;
839}
840
841static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
842{
843 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
844
845 if (priv->mute_gpio)
846 gpiod_set_value_cansleep(priv->mute_gpio, mute);
847
848 return 0;
849}
850
851/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */
852#define CS53L30_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
853
854#define CS53L30_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
855 SNDRV_PCM_FMTBIT_S24_LE)
856
857static const struct snd_soc_dai_ops cs53l30_ops = {
858 .startup = cs53l30_pcm_startup,
859 .hw_params = cs53l30_pcm_hw_params,
860 .set_fmt = cs53l30_set_dai_fmt,
861 .set_sysclk = cs53l30_set_sysclk,
862 .set_tristate = cs53l30_set_tristate,
863 .set_tdm_slot = cs53l30_set_dai_tdm_slot,
864 .mute_stream = cs53l30_mute_stream,
865};
866
867static struct snd_soc_dai_driver cs53l30_dai = {
868 .name = "cs53l30",
869 .capture = {
870 .stream_name = "Capture",
871 .channels_min = 1,
872 .channels_max = 4,
873 .rates = CS53L30_RATES,
874 .formats = CS53L30_FORMATS,
875 },
876 .ops = &cs53l30_ops,
877 .symmetric_rates = 1,
878};
879
880static int cs53l30_codec_probe(struct snd_soc_codec *codec)
881{
882 struct cs53l30_private *priv = snd_soc_codec_get_drvdata(codec);
883 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
884
885 if (priv->use_sdout2)
886 snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout2,
887 ARRAY_SIZE(cs53l30_dapm_routes_sdout2));
888 else
889 snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout1,
890 ARRAY_SIZE(cs53l30_dapm_routes_sdout1));
891
892 return 0;
893}
894
895static struct snd_soc_codec_driver cs53l30_driver = {
896 .probe = cs53l30_codec_probe,
897 .set_bias_level = cs53l30_set_bias_level,
898 .idle_bias_off = true,
899
900 .dapm_widgets = cs53l30_dapm_widgets,
901 .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets),
902 .dapm_routes = cs53l30_dapm_routes,
903 .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes),
904
905 .controls = cs53l30_snd_controls,
906 .num_controls = ARRAY_SIZE(cs53l30_snd_controls),
907};
908
909static struct regmap_config cs53l30_regmap = {
910 .reg_bits = 8,
911 .val_bits = 8,
912
913 .max_register = CS53L30_MAX_REGISTER,
914 .reg_defaults = cs53l30_reg_defaults,
915 .num_reg_defaults = ARRAY_SIZE(cs53l30_reg_defaults),
916 .volatile_reg = cs53l30_volatile_register,
917 .writeable_reg = cs53l30_writeable_register,
918 .readable_reg = cs53l30_readable_register,
919 .cache_type = REGCACHE_RBTREE,
920};
921
922static int cs53l30_i2c_probe(struct i2c_client *client,
923 const struct i2c_device_id *id)
924{
925 const struct device_node *np = client->dev.of_node;
926 struct device *dev = &client->dev;
927 struct cs53l30_private *cs53l30;
928 unsigned int devid = 0;
929 unsigned int reg;
930 int ret = 0, i;
931 u8 val;
932
933 cs53l30 = devm_kzalloc(dev, sizeof(*cs53l30), GFP_KERNEL);
934 if (!cs53l30)
935 return -ENOMEM;
936
937 for (i = 0; i < ARRAY_SIZE(cs53l30->supplies); i++)
938 cs53l30->supplies[i].supply = cs53l30_supply_names[i];
939
940 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs53l30->supplies),
941 cs53l30->supplies);
942 if (ret) {
943 dev_err(dev, "failed to get supplies: %d\n", ret);
944 return ret;
945 }
946
947 ret = regulator_bulk_enable(ARRAY_SIZE(cs53l30->supplies),
948 cs53l30->supplies);
949 if (ret) {
950 dev_err(dev, "failed to enable supplies: %d\n", ret);
951 return ret;
952 }
953
954 /* Reset the Device */
955 cs53l30->reset_gpio = devm_gpiod_get_optional(dev, "reset",
956 GPIOD_OUT_LOW);
957 if (IS_ERR(cs53l30->reset_gpio)) {
958 ret = PTR_ERR(cs53l30->reset_gpio);
959 goto error;
960 }
961
962 if (cs53l30->reset_gpio)
963 gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
964
965 i2c_set_clientdata(client, cs53l30);
966
967 cs53l30->mclk_rate = 0;
968
969 cs53l30->regmap = devm_regmap_init_i2c(client, &cs53l30_regmap);
970 if (IS_ERR(cs53l30->regmap)) {
971 ret = PTR_ERR(cs53l30->regmap);
972 dev_err(dev, "regmap_init() failed: %d\n", ret);
973 goto error;
974 }
975
976 /* Initialize codec */
977 ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_AB, &reg);
978 devid = reg << 12;
979
980 ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_CD, &reg);
981 devid |= reg << 4;
982
983 ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_E, &reg);
984 devid |= (reg & 0xF0) >> 4;
985
986 if (devid != CS53L30_DEVID) {
987 ret = -ENODEV;
988 dev_err(dev, "Device ID (%X). Expected %X\n",
989 devid, CS53L30_DEVID);
990 goto error;
991 }
992
993 ret = regmap_read(cs53l30->regmap, CS53L30_REVID, &reg);
994 if (ret < 0) {
995 dev_err(dev, "failed to get Revision ID: %d\n", ret);
996 goto error;
997 }
998
999 /* Check if MCLK provided */
1000 cs53l30->mclk = devm_clk_get(dev, "mclk");
1001 if (IS_ERR(cs53l30->mclk)) {
1002 if (PTR_ERR(cs53l30->mclk) == -EPROBE_DEFER) {
1003 ret = -EPROBE_DEFER;
1004 goto error;
1005 }
1006 /* Otherwise mark the mclk pointer to NULL */
1007 cs53l30->mclk = NULL;
1008 }
1009
1010 /* Fetch the MUTE control */
1011 cs53l30->mute_gpio = devm_gpiod_get_optional(dev, "mute",
1012 GPIOD_OUT_HIGH);
1013 if (IS_ERR(cs53l30->mute_gpio)) {
1014 ret = PTR_ERR(cs53l30->mute_gpio);
1015 goto error;
1016 }
1017
1018 if (cs53l30->mute_gpio) {
1019 /* Enable MUTE controls via MUTE pin */
1020 regmap_write(cs53l30->regmap, CS53L30_MUTEP_CTL1,
1021 CS53L30_MUTEP_CTL1_MUTEALL);
1022 /* Flip the polarity of MUTE pin */
1023 if (gpiod_is_active_low(cs53l30->mute_gpio))
1024 regmap_update_bits(cs53l30->regmap, CS53L30_MUTEP_CTL2,
1025 CS53L30_MUTE_PIN_POLARITY, 0);
1026 }
1027
1028 if (!of_property_read_u8(np, "cirrus,micbias-lvl", &val))
1029 regmap_update_bits(cs53l30->regmap, CS53L30_MICBIAS_CTL,
1030 CS53L30_MIC_BIAS_CTRL_MASK, val);
1031
1032 if (of_property_read_bool(np, "cirrus,use-sdout2"))
1033 cs53l30->use_sdout2 = true;
1034
1035 dev_info(dev, "Cirrus Logic CS53L30, Revision: %02X\n", reg & 0xFF);
1036
1037 ret = snd_soc_register_codec(dev, &cs53l30_driver, &cs53l30_dai, 1);
1038 if (ret) {
1039 dev_err(dev, "failed to register codec: %d\n", ret);
1040 goto error;
1041 }
1042
1043 return 0;
1044
1045error:
1046 regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
1047 cs53l30->supplies);
1048 return ret;
1049}
1050
1051static int cs53l30_i2c_remove(struct i2c_client *client)
1052{
1053 struct cs53l30_private *cs53l30 = i2c_get_clientdata(client);
1054
1055 snd_soc_unregister_codec(&client->dev);
1056
1057 /* Hold down reset */
1058 if (cs53l30->reset_gpio)
1059 gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
1060
1061 regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
1062 cs53l30->supplies);
1063
1064 return 0;
1065}
1066
1067#ifdef CONFIG_PM
1068static int cs53l30_runtime_suspend(struct device *dev)
1069{
1070 struct cs53l30_private *cs53l30 = dev_get_drvdata(dev);
1071
1072 regcache_cache_only(cs53l30->regmap, true);
1073
1074 /* Hold down reset */
1075 if (cs53l30->reset_gpio)
1076 gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
1077
1078 regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
1079 cs53l30->supplies);
1080
1081 return 0;
1082}
1083
1084static int cs53l30_runtime_resume(struct device *dev)
1085{
1086 struct cs53l30_private *cs53l30 = dev_get_drvdata(dev);
1087 int ret;
1088
1089 ret = regulator_bulk_enable(ARRAY_SIZE(cs53l30->supplies),
1090 cs53l30->supplies);
1091 if (ret) {
1092 dev_err(dev, "failed to enable supplies: %d\n", ret);
1093 return ret;
1094 }
1095
1096 if (cs53l30->reset_gpio)
1097 gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
1098
1099 regcache_cache_only(cs53l30->regmap, false);
1100 ret = regcache_sync(cs53l30->regmap);
1101 if (ret) {
1102 dev_err(dev, "failed to synchronize regcache: %d\n", ret);
1103 return ret;
1104 }
1105
1106 return 0;
1107}
1108#endif
1109
1110static const struct dev_pm_ops cs53l30_runtime_pm = {
1111 SET_RUNTIME_PM_OPS(cs53l30_runtime_suspend, cs53l30_runtime_resume,
1112 NULL)
1113};
1114
1115static const struct of_device_id cs53l30_of_match[] = {
1116 { .compatible = "cirrus,cs53l30", },
1117 {},
1118};
1119
1120MODULE_DEVICE_TABLE(of, cs53l30_of_match);
1121
1122static const struct i2c_device_id cs53l30_id[] = {
1123 { "cs53l30", 0 },
1124 {}
1125};
1126
1127MODULE_DEVICE_TABLE(i2c, cs53l30_id);
1128
1129static struct i2c_driver cs53l30_i2c_driver = {
1130 .driver = {
1131 .name = "cs53l30",
1132 .pm = &cs53l30_runtime_pm,
1133 },
1134 .id_table = cs53l30_id,
1135 .probe = cs53l30_i2c_probe,
1136 .remove = cs53l30_i2c_remove,
1137};
1138
1139module_i2c_driver(cs53l30_i2c_driver);
1140
1141MODULE_DESCRIPTION("ASoC CS53L30 driver");
1142MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <Paul.Handrigan@cirrus.com>");
1143MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs53l30.h b/sound/soc/codecs/cs53l30.h
new file mode 100644
index 000000000000..5e39da568749
--- /dev/null
+++ b/sound/soc/codecs/cs53l30.h
@@ -0,0 +1,459 @@
1/*
2 * ALSA SoC CS53L30 codec driver
3 *
4 * Copyright 2015 Cirrus Logic, Inc.
5 *
6 * Author: Paul Handrigan <Paul.Handrigan@cirrus.com>,
7 * Tim Howe <Tim.Howe@cirrus.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#ifndef __CS53L30_H__
16#define __CS53L30_H__
17
18/* I2C Registers */
19#define CS53L30_DEVID_AB 0x01 /* Device ID A & B [RO]. */
20#define CS53L30_DEVID_CD 0x02 /* Device ID C & D [RO]. */
21#define CS53L30_DEVID_E 0x03 /* Device ID E [RO]. */
22#define CS53L30_REVID 0x05 /* Revision ID [RO]. */
23#define CS53L30_PWRCTL 0x06 /* Power Control. */
24#define CS53L30_MCLKCTL 0x07 /* MCLK Control. */
25#define CS53L30_INT_SR_CTL 0x08 /* Internal Sample Rate Control. */
26#define CS53L30_MICBIAS_CTL 0x0A /* Mic Bias Control. */
27#define CS53L30_ASPCFG_CTL 0x0C /* ASP Config Control. */
28#define CS53L30_ASP_CTL1 0x0D /* ASP1 Control. */
29#define CS53L30_ASP_TDMTX_CTL1 0x0E /* ASP1 TDM TX Control 1 */
30#define CS53L30_ASP_TDMTX_CTL2 0x0F /* ASP1 TDM TX Control 2 */
31#define CS53L30_ASP_TDMTX_CTL3 0x10 /* ASP1 TDM TX Control 3 */
32#define CS53L30_ASP_TDMTX_CTL4 0x11 /* ASP1 TDM TX Control 4 */
33#define CS53L30_ASP_TDMTX_EN1 0x12 /* ASP1 TDM TX Enable 1 */
34#define CS53L30_ASP_TDMTX_EN2 0x13 /* ASP1 TDM TX Enable 2 */
35#define CS53L30_ASP_TDMTX_EN3 0x14 /* ASP1 TDM TX Enable 3 */
36#define CS53L30_ASP_TDMTX_EN4 0x15 /* ASP1 TDM TX Enable 4 */
37#define CS53L30_ASP_TDMTX_EN5 0x16 /* ASP1 TDM TX Enable 5 */
38#define CS53L30_ASP_TDMTX_EN6 0x17 /* ASP1 TDM TX Enable 6 */
39#define CS53L30_ASP_CTL2 0x18 /* ASP2 Control. */
40#define CS53L30_SFT_RAMP 0x1A /* Soft Ramp Control. */
41#define CS53L30_LRCK_CTL1 0x1B /* LRCK Control 1. */
42#define CS53L30_LRCK_CTL2 0x1C /* LRCK Control 2. */
43#define CS53L30_MUTEP_CTL1 0x1F /* Mute Pin Control 1. */
44#define CS53L30_MUTEP_CTL2 0x20 /* Mute Pin Control 2. */
45#define CS53L30_INBIAS_CTL1 0x21 /* Input Bias Control 1. */
46#define CS53L30_INBIAS_CTL2 0x22 /* Input Bias Control 2. */
47#define CS53L30_DMIC1_STR_CTL 0x23 /* DMIC1 Stereo Control. */
48#define CS53L30_DMIC2_STR_CTL 0x24 /* DMIC2 Stereo Control. */
49#define CS53L30_ADCDMIC1_CTL1 0x25 /* ADC1/DMIC1 Control 1. */
50#define CS53L30_ADCDMIC1_CTL2 0x26 /* ADC1/DMIC1 Control 2. */
51#define CS53L30_ADC1_CTL3 0x27 /* ADC1 Control 3. */
52#define CS53L30_ADC1_NG_CTL 0x28 /* ADC1 Noise Gate Control. */
53#define CS53L30_ADC1A_AFE_CTL 0x29 /* ADC1A AFE Control. */
54#define CS53L30_ADC1B_AFE_CTL 0x2A /* ADC1B AFE Control. */
55#define CS53L30_ADC1A_DIG_VOL 0x2B /* ADC1A Digital Volume. */
56#define CS53L30_ADC1B_DIG_VOL 0x2C /* ADC1B Digital Volume. */
57#define CS53L30_ADCDMIC2_CTL1 0x2D /* ADC2/DMIC2 Control 1. */
58#define CS53L30_ADCDMIC2_CTL2 0x2E /* ADC2/DMIC2 Control 2. */
59#define CS53L30_ADC2_CTL3 0x2F /* ADC2 Control 3. */
60#define CS53L30_ADC2_NG_CTL 0x30 /* ADC2 Noise Gate Control. */
61#define CS53L30_ADC2A_AFE_CTL 0x31 /* ADC2A AFE Control. */
62#define CS53L30_ADC2B_AFE_CTL 0x32 /* ADC2B AFE Control. */
63#define CS53L30_ADC2A_DIG_VOL 0x33 /* ADC2A Digital Volume. */
64#define CS53L30_ADC2B_DIG_VOL 0x34 /* ADC2B Digital Volume. */
65#define CS53L30_INT_MASK 0x35 /* Interrupt Mask. */
66#define CS53L30_IS 0x36 /* Interrupt Status. */
67#define CS53L30_MAX_REGISTER 0x36
68
69#define CS53L30_TDM_SLOT_MAX 4
70#define CS53L30_ASP_TDMTX_CTL(x) (CS53L30_ASP_TDMTX_CTL1 + (x))
71/* x : index for registers; n : index for slot; 8 slots per register */
72#define CS53L30_ASP_TDMTX_ENx(x) (CS53L30_ASP_TDMTX_EN6 - (x))
73#define CS53L30_ASP_TDMTX_ENn(n) CS53L30_ASP_TDMTX_ENx((n) >> 3)
74#define CS53L30_ASP_TDMTX_ENx_MAX 6
75
76/* Device ID */
77#define CS53L30_DEVID 0x53A30
78
79/* PDN_DONE Poll Maximum
80 * If soft ramp is set it will take much longer to power down
81 * the system.
82 */
83#define CS53L30_PDN_POLL_MAX 90
84
85/* Bitfield Definitions */
86
87/* R6 (0x06) CS53L30_PWRCTL - Power Control */
88#define CS53L30_PDN_ULP_SHIFT 7
89#define CS53L30_PDN_ULP_MASK (1 << CS53L30_PDN_ULP_SHIFT)
90#define CS53L30_PDN_ULP (1 << CS53L30_PDN_ULP_SHIFT)
91#define CS53L30_PDN_LP_SHIFT 6
92#define CS53L30_PDN_LP_MASK (1 << CS53L30_PDN_LP_SHIFT)
93#define CS53L30_PDN_LP (1 << CS53L30_PDN_LP_SHIFT)
94#define CS53L30_DISCHARGE_FILT_SHIFT 5
95#define CS53L30_DISCHARGE_FILT_MASK (1 << CS53L30_DISCHARGE_FILT_SHIFT)
96#define CS53L30_DISCHARGE_FILT (1 << CS53L30_DISCHARGE_FILT_SHIFT)
97#define CS53L30_THMS_PDN_SHIFT 4
98#define CS53L30_THMS_PDN_MASK (1 << CS53L30_THMS_PDN_SHIFT)
99#define CS53L30_THMS_PDN (1 << CS53L30_THMS_PDN_SHIFT)
100
101#define CS53L30_PWRCTL_DEFAULT (CS53L30_THMS_PDN)
102
103/* R7 (0x07) CS53L30_MCLKCTL - MCLK Control */
104#define CS53L30_MCLK_DIS_SHIFT 7
105#define CS53L30_MCLK_DIS_MASK (1 << CS53L30_MCLK_DIS_SHIFT)
106#define CS53L30_MCLK_DIS (1 << CS53L30_MCLK_DIS_SHIFT)
107#define CS53L30_MCLK_INT_SCALE_SHIFT 6
108#define CS53L30_MCLK_INT_SCALE_MASK (1 << CS53L30_MCLK_INT_SCALE_SHIFT)
109#define CS53L30_MCLK_INT_SCALE (1 << CS53L30_MCLK_INT_SCALE_SHIFT)
110#define CS53L30_DMIC_DRIVE_SHIFT 5
111#define CS53L30_DMIC_DRIVE_MASK (1 << CS53L30_DMIC_DRIVE_SHIFT)
112#define CS53L30_DMIC_DRIVE (1 << CS53L30_DMIC_DRIVE_SHIFT)
113#define CS53L30_MCLK_DIV_SHIFT 2
114#define CS53L30_MCLK_DIV_WIDTH 2
115#define CS53L30_MCLK_DIV_MASK (((1 << CS53L30_MCLK_DIV_WIDTH) - 1) << CS53L30_MCLK_DIV_SHIFT)
116#define CS53L30_MCLK_DIV_BY_1 (0x0 << CS53L30_MCLK_DIV_SHIFT)
117#define CS53L30_MCLK_DIV_BY_2 (0x1 << CS53L30_MCLK_DIV_SHIFT)
118#define CS53L30_MCLK_DIV_BY_3 (0x2 << CS53L30_MCLK_DIV_SHIFT)
119#define CS53L30_SYNC_EN_SHIFT 1
120#define CS53L30_SYNC_EN_MASK (1 << CS53L30_SYNC_EN_SHIFT)
121#define CS53L30_SYNC_EN (1 << CS53L30_SYNC_EN_SHIFT)
122
123#define CS53L30_MCLKCTL_DEFAULT (CS53L30_MCLK_DIV_BY_2)
124
125/* R8 (0x08) CS53L30_INT_SR_CTL - Internal Sample Rate Control */
126#define CS53L30_INTRNL_FS_RATIO_SHIFT 4
127#define CS53L30_INTRNL_FS_RATIO_MASK (1 << CS53L30_INTRNL_FS_RATIO_SHIFT)
128#define CS53L30_INTRNL_FS_RATIO (1 << CS53L30_INTRNL_FS_RATIO_SHIFT)
129#define CS53L30_MCLK_19MHZ_EN_SHIFT 0
130#define CS53L30_MCLK_19MHZ_EN_MASK (1 << CS53L30_MCLK_19MHZ_EN_SHIFT)
131#define CS53L30_MCLK_19MHZ_EN (1 << CS53L30_MCLK_19MHZ_EN_SHIFT)
132
133/* 0x6 << 1 is reserved bits */
134#define CS53L30_INT_SR_CTL_DEFAULT (CS53L30_INTRNL_FS_RATIO | 0x6 << 1)
135
136/* R10 (0x0A) CS53L30_MICBIAS_CTL - Mic Bias Control */
137#define CS53L30_MIC4_BIAS_PDN_SHIFT 7
138#define CS53L30_MIC4_BIAS_PDN_MASK (1 << CS53L30_MIC4_BIAS_PDN_SHIFT)
139#define CS53L30_MIC4_BIAS_PDN (1 << CS53L30_MIC4_BIAS_PDN_SHIFT)
140#define CS53L30_MIC3_BIAS_PDN_SHIFT 6
141#define CS53L30_MIC3_BIAS_PDN_MASK (1 << CS53L30_MIC3_BIAS_PDN_SHIFT)
142#define CS53L30_MIC3_BIAS_PDN (1 << CS53L30_MIC3_BIAS_PDN_SHIFT)
143#define CS53L30_MIC2_BIAS_PDN_SHIFT 5
144#define CS53L30_MIC2_BIAS_PDN_MASK (1 << CS53L30_MIC2_BIAS_PDN_SHIFT)
145#define CS53L30_MIC2_BIAS_PDN (1 << CS53L30_MIC2_BIAS_PDN_SHIFT)
146#define CS53L30_MIC1_BIAS_PDN_SHIFT 4
147#define CS53L30_MIC1_BIAS_PDN_MASK (1 << CS53L30_MIC1_BIAS_PDN_SHIFT)
148#define CS53L30_MIC1_BIAS_PDN (1 << CS53L30_MIC1_BIAS_PDN_SHIFT)
149#define CS53L30_MICx_BIAS_PDN (0xf << CS53L30_MIC1_BIAS_PDN_SHIFT)
150#define CS53L30_VP_MIN_SHIFT 2
151#define CS53L30_VP_MIN_MASK (1 << CS53L30_VP_MIN_SHIFT)
152#define CS53L30_VP_MIN (1 << CS53L30_VP_MIN_SHIFT)
153#define CS53L30_MIC_BIAS_CTRL_SHIFT 0
154#define CS53L30_MIC_BIAS_CTRL_WIDTH 2
155#define CS53L30_MIC_BIAS_CTRL_MASK (((1 << CS53L30_MIC_BIAS_CTRL_WIDTH) - 1) << CS53L30_MIC_BIAS_CTRL_SHIFT)
156#define CS53L30_MIC_BIAS_CTRL_HIZ (0 << CS53L30_MIC_BIAS_CTRL_SHIFT)
157#define CS53L30_MIC_BIAS_CTRL_1V8 (1 << CS53L30_MIC_BIAS_CTRL_SHIFT)
158#define CS53L30_MIC_BIAS_CTRL_2V75 (2 << CS53L30_MIC_BIAS_CTRL_SHIFT)
159
160#define CS53L30_MICBIAS_CTL_DEFAULT (CS53L30_MICx_BIAS_PDN | CS53L30_VP_MIN)
161
162/* R12 (0x0C) CS53L30_ASPCFG_CTL - ASP Configuration Control */
163#define CS53L30_ASP_MS_SHIFT 7
164#define CS53L30_ASP_MS_MASK (1 << CS53L30_ASP_MS_SHIFT)
165#define CS53L30_ASP_MS (1 << CS53L30_ASP_MS_SHIFT)
166#define CS53L30_ASP_SCLK_INV_SHIFT 4
167#define CS53L30_ASP_SCLK_INV_MASK (1 << CS53L30_ASP_SCLK_INV_SHIFT)
168#define CS53L30_ASP_SCLK_INV (1 << CS53L30_ASP_SCLK_INV_SHIFT)
169#define CS53L30_ASP_RATE_SHIFT 0
170#define CS53L30_ASP_RATE_WIDTH 4
171#define CS53L30_ASP_RATE_MASK (((1 << CS53L30_ASP_RATE_WIDTH) - 1) << CS53L30_ASP_RATE_SHIFT)
172#define CS53L30_ASP_RATE_48K (0xc << CS53L30_ASP_RATE_SHIFT)
173
174#define CS53L30_ASPCFG_CTL_DEFAULT (CS53L30_ASP_RATE_48K)
175
176/* R13/R24 (0x0D/0x18) CS53L30_ASP_CTL1 & CS53L30_ASP_CTL2 - ASP Control 1~2 */
177#define CS53L30_ASP_TDM_PDN_SHIFT 7
178#define CS53L30_ASP_TDM_PDN_MASK (1 << CS53L30_ASP_TDM_PDN_SHIFT)
179#define CS53L30_ASP_TDM_PDN (1 << CS53L30_ASP_TDM_PDN_SHIFT)
180#define CS53L30_ASP_SDOUTx_PDN_SHIFT 6
181#define CS53L30_ASP_SDOUTx_PDN_MASK (1 << CS53L30_ASP_SDOUTx_PDN_SHIFT)
182#define CS53L30_ASP_SDOUTx_PDN (1 << CS53L30_ASP_SDOUTx_PDN_SHIFT)
183#define CS53L30_ASP_3ST_SHIFT 5
184#define CS53L30_ASP_3ST_MASK (1 << CS53L30_ASP_3ST_SHIFT)
185#define CS53L30_ASP_3ST (1 << CS53L30_ASP_3ST_SHIFT)
186#define CS53L30_SHIFT_LEFT_SHIFT 4
187#define CS53L30_SHIFT_LEFT_MASK (1 << CS53L30_SHIFT_LEFT_SHIFT)
188#define CS53L30_SHIFT_LEFT (1 << CS53L30_SHIFT_LEFT_SHIFT)
189#define CS53L30_ASP_SDOUTx_DRIVE_SHIFT 0
190#define CS53L30_ASP_SDOUTx_DRIVE_MASK (1 << CS53L30_ASP_SDOUTx_DRIVE_SHIFT)
191#define CS53L30_ASP_SDOUTx_DRIVE (1 << CS53L30_ASP_SDOUTx_DRIVE_SHIFT)
192
193#define CS53L30_ASP_CTL1_DEFAULT (CS53L30_ASP_TDM_PDN)
194#define CS53L30_ASP_CTL2_DEFAULT (0)
195
196/* R14 (0x0E) ~ R17 (0x11) CS53L30_ASP_TDMTX_CTLx - ASP TDM TX Control 1~4 */
197#define CS53L30_ASP_CHx_TX_STATE_SHIFT 7
198#define CS53L30_ASP_CHx_TX_STATE_MASK (1 << CS53L30_ASP_CHx_TX_STATE_SHIFT)
199#define CS53L30_ASP_CHx_TX_STATE (1 << CS53L30_ASP_CHx_TX_STATE_SHIFT)
200#define CS53L30_ASP_CHx_TX_LOC_SHIFT 0
201#define CS53L30_ASP_CHx_TX_LOC_WIDTH 6
202#define CS53L30_ASP_CHx_TX_LOC_MASK (((1 << CS53L30_ASP_CHx_TX_LOC_WIDTH) - 1) << CS53L30_ASP_CHx_TX_LOC_SHIFT)
203#define CS53L30_ASP_CHx_TX_LOC_MAX (47 << CS53L30_ASP_CHx_TX_LOC_SHIFT)
204#define CS53L30_ASP_CHx_TX_LOC(x) ((x) << CS53L30_ASP_CHx_TX_LOC_SHIFT)
205
206#define CS53L30_ASP_TDMTX_CTLx_DEFAULT (CS53L30_ASP_CHx_TX_LOC_MAX)
207
208/* R18 (0x12) ~ R23 (0x17) CS53L30_ASP_TDMTX_ENx - ASP TDM TX Enable 1~6 */
209#define CS53L30_ASP_TDMTX_ENx_DEFAULT (0)
210
211/* R26 (0x1A) CS53L30_SFT_RAMP - Soft Ramp Control */
212#define CS53L30_DIGSFT_SHIFT 5
213#define CS53L30_DIGSFT_MASK (1 << CS53L30_DIGSFT_SHIFT)
214#define CS53L30_DIGSFT (1 << CS53L30_DIGSFT_SHIFT)
215
216#define CS53L30_SFT_RMP_DEFAULT (0)
217
218/* R28 (0x1C) CS53L30_LRCK_CTL2 - LRCK Control 2 */
219#define CS53L30_LRCK_50_NPW_SHIFT 3
220#define CS53L30_LRCK_50_NPW_MASK (1 << CS53L30_LRCK_50_NPW_SHIFT)
221#define CS53L30_LRCK_50_NPW (1 << CS53L30_LRCK_50_NPW_SHIFT)
222#define CS53L30_LRCK_TPWH_SHIFT 0
223#define CS53L30_LRCK_TPWH_WIDTH 3
224#define CS53L30_LRCK_TPWH_MASK (((1 << CS53L30_LRCK_TPWH_WIDTH) - 1) << CS53L30_LRCK_TPWH_SHIFT)
225#define CS53L30_LRCK_TPWH(x) (((x) << CS53L30_LRCK_TPWH_SHIFT) & CS53L30_LRCK_TPWH_MASK)
226
227#define CS53L30_LRCK_CTLx_DEFAULT (0)
228
229/* R31 (0x1F) CS53L30_MUTEP_CTL1 - MUTE Pin Control 1 */
230#define CS53L30_MUTE_PDN_ULP_SHIFT 7
231#define CS53L30_MUTE_PDN_ULP_MASK (1 << CS53L30_MUTE_PDN_ULP_SHIFT)
232#define CS53L30_MUTE_PDN_ULP (1 << CS53L30_MUTE_PDN_ULP_SHIFT)
233#define CS53L30_MUTE_PDN_LP_SHIFT 6
234#define CS53L30_MUTE_PDN_LP_MASK (1 << CS53L30_MUTE_PDN_LP_SHIFT)
235#define CS53L30_MUTE_PDN_LP (1 << CS53L30_MUTE_PDN_LP_SHIFT)
236#define CS53L30_MUTE_M4B_PDN_SHIFT 4
237#define CS53L30_MUTE_M4B_PDN_MASK (1 << CS53L30_MUTE_M4B_PDN_SHIFT)
238#define CS53L30_MUTE_M4B_PDN (1 << CS53L30_MUTE_M4B_PDN_SHIFT)
239#define CS53L30_MUTE_M3B_PDN_SHIFT 3
240#define CS53L30_MUTE_M3B_PDN_MASK (1 << CS53L30_MUTE_M3B_PDN_SHIFT)
241#define CS53L30_MUTE_M3B_PDN (1 << CS53L30_MUTE_M3B_PDN_SHIFT)
242#define CS53L30_MUTE_M2B_PDN_SHIFT 2
243#define CS53L30_MUTE_M2B_PDN_MASK (1 << CS53L30_MUTE_M2B_PDN_SHIFT)
244#define CS53L30_MUTE_M2B_PDN (1 << CS53L30_MUTE_M2B_PDN_SHIFT)
245#define CS53L30_MUTE_M1B_PDN_SHIFT 1
246#define CS53L30_MUTE_M1B_PDN_MASK (1 << CS53L30_MUTE_M1B_PDN_SHIFT)
247#define CS53L30_MUTE_M1B_PDN (1 << CS53L30_MUTE_M1B_PDN_SHIFT)
248/* Note: be careful - x starts from 0 */
249#define CS53L30_MUTE_MxB_PDN_SHIFT(x) (CS53L30_MUTE_M1B_PDN_SHIFT + (x))
250#define CS53L30_MUTE_MxB_PDN_MASK(x) (1 << CS53L30_MUTE_MxB_PDN_SHIFT(x))
251#define CS53L30_MUTE_MxB_PDN(x) (1 << CS53L30_MUTE_MxB_PDN_SHIFT(x))
252#define CS53L30_MUTE_MB_ALL_PDN_SHIFT 0
253#define CS53L30_MUTE_MB_ALL_PDN_MASK (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT)
254#define CS53L30_MUTE_MB_ALL_PDN (1 << CS53L30_MUTE_MB_ALL_PDN_SHIFT)
255
256#define CS53L30_MUTEP_CTL1_MUTEALL (0xdf)
257#define CS53L30_MUTEP_CTL1_DEFAULT (0)
258
259/* R32 (0x20) CS53L30_MUTEP_CTL2 - MUTE Pin Control 2 */
260#define CS53L30_MUTE_PIN_POLARITY_SHIFT 7
261#define CS53L30_MUTE_PIN_POLARITY_MASK (1 << CS53L30_MUTE_PIN_POLARITY_SHIFT)
262#define CS53L30_MUTE_PIN_POLARITY (1 << CS53L30_MUTE_PIN_POLARITY_SHIFT)
263#define CS53L30_MUTE_ASP_TDM_PDN_SHIFT 6
264#define CS53L30_MUTE_ASP_TDM_PDN_MASK (1 << CS53L30_MUTE_ASP_TDM_PDN_SHIFT)
265#define CS53L30_MUTE_ASP_TDM_PDN (1 << CS53L30_MUTE_ASP_TDM_PDN_SHIFT)
266#define CS53L30_MUTE_ASP_SDOUT2_PDN_SHIFT 5
267#define CS53L30_MUTE_ASP_SDOUT2_PDN_MASK (1 << CS53L30_MUTE_ASP_SDOUT2_PDN_SHIFT)
268#define CS53L30_MUTE_ASP_SDOUT2_PDN (1 << CS53L30_MUTE_ASP_SDOUT2_PDN_SHIFT)
269#define CS53L30_MUTE_ASP_SDOUT1_PDN_SHIFT 4
270#define CS53L30_MUTE_ASP_SDOUT1_PDN_MASK (1 << CS53L30_MUTE_ASP_SDOUT1_PDN_SHIFT)
271#define CS53L30_MUTE_ASP_SDOUT1_PDN (1 << CS53L30_MUTE_ASP_SDOUT1_PDN_SHIFT)
272/* Note: be careful - x starts from 0 */
273#define CS53L30_MUTE_ASP_SDOUTx_PDN_SHIFT(x) ((x) + CS53L30_MUTE_ASP_SDOUT1_PDN_SHIFT)
274#define CS53L30_MUTE_ASP_SDOUTx_PDN_MASK(x) (1 << CS53L30_MUTE_ASP_SDOUTx_PDN_SHIFT(x))
275#define CS53L30_MUTE_ASP_SDOUTx_PDN (1 << CS53L30_MUTE_ASP_SDOUTx_PDN_SHIFT(x))
276#define CS53L30_MUTE_ADC2B_PDN_SHIFT 3
277#define CS53L30_MUTE_ADC2B_PDN_MASK (1 << CS53L30_MUTE_ADC2B_PDN_SHIFT)
278#define CS53L30_MUTE_ADC2B_PDN (1 << CS53L30_MUTE_ADC2B_PDN_SHIFT)
279#define CS53L30_MUTE_ADC2A_PDN_SHIFT 2
280#define CS53L30_MUTE_ADC2A_PDN_MASK (1 << CS53L30_MUTE_ADC2A_PDN_SHIFT)
281#define CS53L30_MUTE_ADC2A_PDN (1 << CS53L30_MUTE_ADC2A_PDN_SHIFT)
282#define CS53L30_MUTE_ADC1B_PDN_SHIFT 1
283#define CS53L30_MUTE_ADC1B_PDN_MASK (1 << CS53L30_MUTE_ADC1B_PDN_SHIFT)
284#define CS53L30_MUTE_ADC1B_PDN (1 << CS53L30_MUTE_ADC1B_PDN_SHIFT)
285#define CS53L30_MUTE_ADC1A_PDN_SHIFT 0
286#define CS53L30_MUTE_ADC1A_PDN_MASK (1 << CS53L30_MUTE_ADC1A_PDN_SHIFT)
287#define CS53L30_MUTE_ADC1A_PDN (1 << CS53L30_MUTE_ADC1A_PDN_SHIFT)
288
289#define CS53L30_MUTEP_CTL2_DEFAULT (CS53L30_MUTE_PIN_POLARITY)
290
291/* R33 (0x21) CS53L30_INBIAS_CTL1 - Input Bias Control 1 */
292#define CS53L30_IN4M_BIAS_SHIFT 6
293#define CS53L30_IN4M_BIAS_WIDTH 2
294#define CS53L30_IN4M_BIAS_MASK (((1 << CS53L30_IN4M_BIAS_WIDTH) - 1) << CS53L30_IN4M_BIAS_SHIFT)
295#define CS53L30_IN4M_BIAS_OPEN (0 << CS53L30_IN4M_BIAS_SHIFT)
296#define CS53L30_IN4M_BIAS_PULL_DOWN (1 << CS53L30_IN4M_BIAS_SHIFT)
297#define CS53L30_IN4M_BIAS_VCM (2 << CS53L30_IN4M_BIAS_SHIFT)
298#define CS53L30_IN4P_BIAS_SHIFT 4
299#define CS53L30_IN4P_BIAS_WIDTH 2
300#define CS53L30_IN4P_BIAS_MASK (((1 << CS53L30_IN4P_BIAS_WIDTH) - 1) << CS53L30_IN4P_BIAS_SHIFT)
301#define CS53L30_IN4P_BIAS_OPEN (0 << CS53L30_IN4P_BIAS_SHIFT)
302#define CS53L30_IN4P_BIAS_PULL_DOWN (1 << CS53L30_IN4P_BIAS_SHIFT)
303#define CS53L30_IN4P_BIAS_VCM (2 << CS53L30_IN4P_BIAS_SHIFT)
304#define CS53L30_IN3M_BIAS_SHIFT 2
305#define CS53L30_IN3M_BIAS_WIDTH 2
306#define CS53L30_IN3M_BIAS_MASK (((1 << CS53L30_IN3M_BIAS_WIDTH) - 1) << CS53L30_IN4M_BIAS_SHIFT)
307#define CS53L30_IN3M_BIAS_OPEN (0 << CS53L30_IN3M_BIAS_SHIFT)
308#define CS53L30_IN3M_BIAS_PULL_DOWN (1 << CS53L30_IN3M_BIAS_SHIFT)
309#define CS53L30_IN3M_BIAS_VCM (2 << CS53L30_IN3M_BIAS_SHIFT)
310#define CS53L30_IN3P_BIAS_SHIFT 0
311#define CS53L30_IN3P_BIAS_WIDTH 2
312#define CS53L30_IN3P_BIAS_MASK (((1 << CS53L30_IN3P_BIAS_WIDTH) - 1) << CS53L30_IN3P_BIAS_SHIFT)
313#define CS53L30_IN3P_BIAS_OPEN (0 << CS53L30_IN3P_BIAS_SHIFT)
314#define CS53L30_IN3P_BIAS_PULL_DOWN (1 << CS53L30_IN3P_BIAS_SHIFT)
315#define CS53L30_IN3P_BIAS_VCM (2 << CS53L30_IN3P_BIAS_SHIFT)
316
317#define CS53L30_INBIAS_CTL1_DEFAULT (CS53L30_IN4M_BIAS_VCM | CS53L30_IN4P_BIAS_VCM |\
318 CS53L30_IN3M_BIAS_VCM | CS53L30_IN3P_BIAS_VCM)
319
320/* R34 (0x22) CS53L30_INBIAS_CTL2 - Input Bias Control 2 */
321#define CS53L30_IN2M_BIAS_SHIFT 6
322#define CS53L30_IN2M_BIAS_WIDTH 2
323#define CS53L30_IN2M_BIAS_MASK (((1 << CS53L30_IN2M_BIAS_WIDTH) - 1) << CS53L30_IN2M_BIAS_SHIFT)
324#define CS53L30_IN2M_BIAS_OPEN (0 << CS53L30_IN2M_BIAS_SHIFT)
325#define CS53L30_IN2M_BIAS_PULL_DOWN (1 << CS53L30_IN2M_BIAS_SHIFT)
326#define CS53L30_IN2M_BIAS_VCM (2 << CS53L30_IN2M_BIAS_SHIFT)
327#define CS53L30_IN2P_BIAS_SHIFT 4
328#define CS53L30_IN2P_BIAS_WIDTH 2
329#define CS53L30_IN2P_BIAS_MASK (((1 << CS53L30_IN2P_BIAS_WIDTH) - 1) << CS53L30_IN2P_BIAS_SHIFT)
330#define CS53L30_IN2P_BIAS_OPEN (0 << CS53L30_IN2P_BIAS_SHIFT)
331#define CS53L30_IN2P_BIAS_PULL_DOWN (1 << CS53L30_IN2P_BIAS_SHIFT)
332#define CS53L30_IN2P_BIAS_VCM (2 << CS53L30_IN2P_BIAS_SHIFT)
333#define CS53L30_IN1M_BIAS_SHIFT 2
334#define CS53L30_IN1M_BIAS_WIDTH 2
335#define CS53L30_IN1M_BIAS_MASK (((1 << CS53L30_IN1M_BIAS_WIDTH) - 1) << CS53L30_IN1M_BIAS_SHIFT)
336#define CS53L30_IN1M_BIAS_OPEN (0 << CS53L30_IN1M_BIAS_SHIFT)
337#define CS53L30_IN1M_BIAS_PULL_DOWN (1 << CS53L30_IN1M_BIAS_SHIFT)
338#define CS53L30_IN1M_BIAS_VCM (2 << CS53L30_IN1M_BIAS_SHIFT)
339#define CS53L30_IN1P_BIAS_SHIFT 0
340#define CS53L30_IN1P_BIAS_WIDTH 2
341#define CS53L30_IN1P_BIAS_MASK (((1 << CS53L30_IN1P_BIAS_WIDTH) - 1) << CS53L30_IN1P_BIAS_SHIFT)
342#define CS53L30_IN1P_BIAS_OPEN (0 << CS53L30_IN1P_BIAS_SHIFT)
343#define CS53L30_IN1P_BIAS_PULL_DOWN (1 << CS53L30_IN1P_BIAS_SHIFT)
344#define CS53L30_IN1P_BIAS_VCM (2 << CS53L30_IN1P_BIAS_SHIFT)
345
346#define CS53L30_INBIAS_CTL2_DEFAULT (CS53L30_IN2M_BIAS_VCM | CS53L30_IN2P_BIAS_VCM |\
347 CS53L30_IN1M_BIAS_VCM | CS53L30_IN1P_BIAS_VCM)
348
349/* R35 (0x23) & R36 (0x24) CS53L30_DMICx_STR_CTL - DMIC1 & DMIC2 Stereo Control */
350#define CS53L30_DMICx_STEREO_ENB_SHIFT 5
351#define CS53L30_DMICx_STEREO_ENB_MASK (1 << CS53L30_DMICx_STEREO_ENB_SHIFT)
352#define CS53L30_DMICx_STEREO_ENB (1 << CS53L30_DMICx_STEREO_ENB_SHIFT)
353
354/* 0x88 and 0xCC are reserved bits */
355#define CS53L30_DMIC1_STR_CTL_DEFAULT (CS53L30_DMICx_STEREO_ENB | 0x88)
356#define CS53L30_DMIC2_STR_CTL_DEFAULT (CS53L30_DMICx_STEREO_ENB | 0xCC)
357
358/* R37/R45 (0x25/0x2D) CS53L30_ADCDMICx_CTL1 - ADC1/DMIC1 & ADC2/DMIC2 Control 1 */
359#define CS53L30_ADCxB_PDN_SHIFT 7
360#define CS53L30_ADCxB_PDN_MASK (1 << CS53L30_ADCxB_PDN_SHIFT)
361#define CS53L30_ADCxB_PDN (1 << CS53L30_ADCxB_PDN_SHIFT)
362#define CS53L30_ADCxA_PDN_SHIFT 6
363#define CS53L30_ADCxA_PDN_MASK (1 << CS53L30_ADCxA_PDN_SHIFT)
364#define CS53L30_ADCxA_PDN (1 << CS53L30_ADCxA_PDN_SHIFT)
365#define CS53L30_DMICx_PDN_SHIFT 2
366#define CS53L30_DMICx_PDN_MASK (1 << CS53L30_DMICx_PDN_SHIFT)
367#define CS53L30_DMICx_PDN (1 << CS53L30_DMICx_PDN_SHIFT)
368#define CS53L30_DMICx_SCLK_DIV_SHIFT 1
369#define CS53L30_DMICx_SCLK_DIV_MASK (1 << CS53L30_DMICx_SCLK_DIV_SHIFT)
370#define CS53L30_DMICx_SCLK_DIV (1 << CS53L30_DMICx_SCLK_DIV_SHIFT)
371#define CS53L30_CH_TYPE_SHIFT 0
372#define CS53L30_CH_TYPE_MASK (1 << CS53L30_CH_TYPE_SHIFT)
373#define CS53L30_CH_TYPE (1 << CS53L30_CH_TYPE_SHIFT)
374
375#define CS53L30_ADCDMICx_PDN_MASK 0xFF
376#define CS53L30_ADCDMICx_CTL1_DEFAULT (CS53L30_DMICx_PDN)
377
378/* R38/R46 (0x26/0x2E) CS53L30_ADCDMICx_CTL2 - ADC1/DMIC1 & ADC2/DMIC2 Control 2 */
379#define CS53L30_ADCx_NOTCH_DIS_SHIFT 7
380#define CS53L30_ADCx_NOTCH_DIS_MASK (1 << CS53L30_ADCx_NOTCH_DIS_SHIFT)
381#define CS53L30_ADCx_NOTCH_DIS (1 << CS53L30_ADCx_NOTCH_DIS_SHIFT)
382#define CS53L30_ADCxB_INV_SHIFT 5
383#define CS53L30_ADCxB_INV_MASK (1 << CS53L30_ADCxB_INV_SHIFT)
384#define CS53L30_ADCxB_INV (1 << CS53L30_ADCxB_INV_SHIFT)
385#define CS53L30_ADCxA_INV_SHIFT 4
386#define CS53L30_ADCxA_INV_MASK (1 << CS53L30_ADCxA_INV_SHIFT)
387#define CS53L30_ADCxA_INV (1 << CS53L30_ADCxA_INV_SHIFT)
388#define CS53L30_ADCxB_DIG_BOOST_SHIFT 1
389#define CS53L30_ADCxB_DIG_BOOST_MASK (1 << CS53L30_ADCxB_DIG_BOOST_SHIFT)
390#define CS53L30_ADCxB_DIG_BOOST (1 << CS53L30_ADCxB_DIG_BOOST_SHIFT)
391#define CS53L30_ADCxA_DIG_BOOST_SHIFT 0
392#define CS53L30_ADCxA_DIG_BOOST_MASK (1 << CS53L30_ADCxA_DIG_BOOST_SHIFT)
393#define CS53L30_ADCxA_DIG_BOOST (1 << CS53L30_ADCxA_DIG_BOOST_SHIFT)
394
395#define CS53L30_ADCDMIC1_CTL2_DEFAULT (0)
396
397/* R39/R47 (0x27/0x2F) CS53L30_ADCx_CTL3 - ADC1/ADC2 Control 3 */
398#define CS53L30_ADCx_HPF_EN_SHIFT 3
399#define CS53L30_ADCx_HPF_EN_MASK (1 << CS53L30_ADCx_HPF_EN_SHIFT)
400#define CS53L30_ADCx_HPF_EN (1 << CS53L30_ADCx_HPF_EN_SHIFT)
401#define CS53L30_ADCx_HPF_CF_SHIFT 1
402#define CS53L30_ADCx_HPF_CF_WIDTH 2
403#define CS53L30_ADCx_HPF_CF_MASK (((1 << CS53L30_ADCx_HPF_CF_WIDTH) - 1) << CS53L30_ADCx_HPF_CF_SHIFT)
404#define CS53L30_ADCx_HPF_CF_1HZ86 (0 << CS53L30_ADCx_HPF_CF_SHIFT)
405#define CS53L30_ADCx_HPF_CF_120HZ (1 << CS53L30_ADCx_HPF_CF_SHIFT)
406#define CS53L30_ADCx_HPF_CF_235HZ (2 << CS53L30_ADCx_HPF_CF_SHIFT)
407#define CS53L30_ADCx_HPF_CF_466HZ (3 << CS53L30_ADCx_HPF_CF_SHIFT)
408#define CS53L30_ADCx_NG_ALL_SHIFT 0
409#define CS53L30_ADCx_NG_ALL_MASK (1 << CS53L30_ADCx_NG_ALL_SHIFT)
410#define CS53L30_ADCx_NG_ALL (1 << CS53L30_ADCx_NG_ALL_SHIFT)
411
412#define CS53L30_ADCx_CTL3_DEFAULT (CS53L30_ADCx_HPF_EN)
413
414/* R40/R48 (0x28/0x30) CS53L30_ADCx_NG_CTL - ADC1/ADC2 Noise Gate Control */
415#define CS53L30_ADCxB_NG_SHIFT 7
416#define CS53L30_ADCxB_NG_MASK (1 << CS53L30_ADCxB_NG_SHIFT)
417#define CS53L30_ADCxB_NG (1 << CS53L30_ADCxB_NG_SHIFT)
418#define CS53L30_ADCxA_NG_SHIFT 6
419#define CS53L30_ADCxA_NG_MASK (1 << CS53L30_ADCxA_NG_SHIFT)
420#define CS53L30_ADCxA_NG (1 << CS53L30_ADCxA_NG_SHIFT)
421#define CS53L30_ADCx_NG_BOOST_SHIFT 5
422#define CS53L30_ADCx_NG_BOOST_MASK (1 << CS53L30_ADCx_NG_BOOST_SHIFT)
423#define CS53L30_ADCx_NG_BOOST (1 << CS53L30_ADCx_NG_BOOST_SHIFT)
424#define CS53L30_ADCx_NG_THRESH_SHIFT 2
425#define CS53L30_ADCx_NG_THRESH_WIDTH 3
426#define CS53L30_ADCx_NG_THRESH_MASK (((1 << CS53L30_ADCx_NG_THRESH_WIDTH) - 1) << CS53L30_ADCx_NG_THRESH_SHIFT)
427#define CS53L30_ADCx_NG_DELAY_SHIFT 0
428#define CS53L30_ADCx_NG_DELAY_WIDTH 2
429#define CS53L30_ADCx_NG_DELAY_MASK (((1 << CS53L30_ADCx_NG_DELAY_WIDTH) - 1) << CS53L30_ADCx_NG_DELAY_SHIFT)
430
431#define CS53L30_ADCx_NG_CTL_DEFAULT (0)
432
433/* R41/R42/R49/R50 (0x29/0x2A/0x31/0x32) CS53L30_ADCxy_AFE_CTL - ADC1A/1B/2A/2B AFE Control */
434#define CS53L30_ADCxy_PREAMP_SHIFT 6
435#define CS53L30_ADCxy_PREAMP_WIDTH 2
436#define CS53L30_ADCxy_PREAMP_MASK (((1 << CS53L30_ADCxy_PREAMP_WIDTH) - 1) << CS53L30_ADCxy_PREAMP_SHIFT)
437#define CS53L30_ADCxy_PGA_VOL_SHIFT 0
438#define CS53L30_ADCxy_PGA_VOL_WIDTH 6
439#define CS53L30_ADCxy_PGA_VOL_MASK (((1 << CS53L30_ADCxy_PGA_VOL_WIDTH) - 1) << CS53L30_ADCxy_PGA_VOL_SHIFT)
440
441#define CS53L30_ADCxy_AFE_CTL_DEFAULT (0)
442
443/* R43/R44/R51/R52 (0x2B/0x2C/0x33/0x34) CS53L30_ADCxy_DIG_VOL - ADC1A/1B/2A/2B Digital Volume */
444#define CS53L30_ADCxy_VOL_MUTE (0x80)
445
446#define CS53L30_ADCxy_DIG_VOL_DEFAULT (0x0)
447
448/* CS53L30_INT */
449#define CS53L30_PDN_DONE (1 << 7)
450#define CS53L30_THMS_TRIP (1 << 6)
451#define CS53L30_SYNC_DONE (1 << 5)
452#define CS53L30_ADC2B_OVFL (1 << 4)
453#define CS53L30_ADC2A_OVFL (1 << 3)
454#define CS53L30_ADC1B_OVFL (1 << 2)
455#define CS53L30_ADC1A_OVFL (1 << 1)
456#define CS53L30_MUTE_PIN (1 << 0)
457#define CS53L30_DEVICE_INT_MASK 0xFF
458
459#endif /* __CS53L30_H__ */
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c
index 9459593eef13..f0057cd223a4 100644
--- a/sound/soc/codecs/da7219-aad.c
+++ b/sound/soc/codecs/da7219-aad.c
@@ -13,8 +13,8 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/of_device.h> 16#include <linux/i2c.h>
17#include <linux/of_irq.h> 17#include <linux/property.h>
18#include <linux/pm_wakeirq.h> 18#include <linux/pm_wakeirq.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
@@ -382,11 +382,11 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
382} 382}
383 383
384/* 384/*
385 * DT to pdata conversion 385 * DT/ACPI to pdata conversion
386 */ 386 */
387 387
388static enum da7219_aad_micbias_pulse_lvl 388static enum da7219_aad_micbias_pulse_lvl
389 da7219_aad_of_micbias_pulse_lvl(struct snd_soc_codec *codec, u32 val) 389 da7219_aad_fw_micbias_pulse_lvl(struct snd_soc_codec *codec, u32 val)
390{ 390{
391 switch (val) { 391 switch (val) {
392 case 2800: 392 case 2800:
@@ -400,7 +400,7 @@ static enum da7219_aad_micbias_pulse_lvl
400} 400}
401 401
402static enum da7219_aad_btn_cfg 402static enum da7219_aad_btn_cfg
403 da7219_aad_of_btn_cfg(struct snd_soc_codec *codec, u32 val) 403 da7219_aad_fw_btn_cfg(struct snd_soc_codec *codec, u32 val)
404{ 404{
405 switch (val) { 405 switch (val) {
406 case 2: 406 case 2:
@@ -424,7 +424,7 @@ static enum da7219_aad_btn_cfg
424} 424}
425 425
426static enum da7219_aad_mic_det_thr 426static enum da7219_aad_mic_det_thr
427 da7219_aad_of_mic_det_thr(struct snd_soc_codec *codec, u32 val) 427 da7219_aad_fw_mic_det_thr(struct snd_soc_codec *codec, u32 val)
428{ 428{
429 switch (val) { 429 switch (val) {
430 case 200: 430 case 200:
@@ -442,7 +442,7 @@ static enum da7219_aad_mic_det_thr
442} 442}
443 443
444static enum da7219_aad_jack_ins_deb 444static enum da7219_aad_jack_ins_deb
445 da7219_aad_of_jack_ins_deb(struct snd_soc_codec *codec, u32 val) 445 da7219_aad_fw_jack_ins_deb(struct snd_soc_codec *codec, u32 val)
446{ 446{
447 switch (val) { 447 switch (val) {
448 case 5: 448 case 5:
@@ -468,7 +468,7 @@ static enum da7219_aad_jack_ins_deb
468} 468}
469 469
470static enum da7219_aad_jack_det_rate 470static enum da7219_aad_jack_det_rate
471 da7219_aad_of_jack_det_rate(struct snd_soc_codec *codec, const char *str) 471 da7219_aad_fw_jack_det_rate(struct snd_soc_codec *codec, const char *str)
472{ 472{
473 if (!strcmp(str, "32ms_64ms")) { 473 if (!strcmp(str, "32ms_64ms")) {
474 return DA7219_AAD_JACK_DET_RATE_32_64MS; 474 return DA7219_AAD_JACK_DET_RATE_32_64MS;
@@ -485,7 +485,7 @@ static enum da7219_aad_jack_det_rate
485} 485}
486 486
487static enum da7219_aad_jack_rem_deb 487static enum da7219_aad_jack_rem_deb
488 da7219_aad_of_jack_rem_deb(struct snd_soc_codec *codec, u32 val) 488 da7219_aad_fw_jack_rem_deb(struct snd_soc_codec *codec, u32 val)
489{ 489{
490 switch (val) { 490 switch (val) {
491 case 1: 491 case 1:
@@ -503,7 +503,7 @@ static enum da7219_aad_jack_rem_deb
503} 503}
504 504
505static enum da7219_aad_btn_avg 505static enum da7219_aad_btn_avg
506 da7219_aad_of_btn_avg(struct snd_soc_codec *codec, u32 val) 506 da7219_aad_fw_btn_avg(struct snd_soc_codec *codec, u32 val)
507{ 507{
508 switch (val) { 508 switch (val) {
509 case 1: 509 case 1:
@@ -521,7 +521,7 @@ static enum da7219_aad_btn_avg
521} 521}
522 522
523static enum da7219_aad_adc_1bit_rpt 523static enum da7219_aad_adc_1bit_rpt
524 da7219_aad_of_adc_1bit_rpt(struct snd_soc_codec *codec, u32 val) 524 da7219_aad_fw_adc_1bit_rpt(struct snd_soc_codec *codec, u32 val)
525{ 525{
526 switch (val) { 526 switch (val) {
527 case 1: 527 case 1:
@@ -538,97 +538,96 @@ static enum da7219_aad_adc_1bit_rpt
538 } 538 }
539} 539}
540 540
541static struct da7219_aad_pdata *da7219_aad_of_to_pdata(struct snd_soc_codec *codec) 541static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *codec)
542{ 542{
543 struct device_node *np = codec->dev->of_node; 543 struct device *dev = codec->dev;
544 struct device_node *aad_np = of_find_node_by_name(np, "da7219_aad"); 544 struct i2c_client *i2c = to_i2c_client(dev);
545 struct fwnode_handle *aad_np;
545 struct da7219_aad_pdata *aad_pdata; 546 struct da7219_aad_pdata *aad_pdata;
546 const char *of_str; 547 const char *fw_str;
547 u32 of_val32; 548 u32 fw_val32;
548 549
550 aad_np = device_get_named_child_node(dev, "da7219_aad");
549 if (!aad_np) 551 if (!aad_np)
550 return NULL; 552 return NULL;
551 553
552 aad_pdata = devm_kzalloc(codec->dev, sizeof(*aad_pdata), GFP_KERNEL); 554 aad_pdata = devm_kzalloc(codec->dev, sizeof(*aad_pdata), GFP_KERNEL);
553 if (!aad_pdata) 555 if (!aad_pdata)
554 goto out; 556 return NULL;
555 557
556 aad_pdata->irq = irq_of_parse_and_map(np, 0); 558 aad_pdata->irq = i2c->irq;
557 559
558 if (of_property_read_u32(aad_np, "dlg,micbias-pulse-lvl", 560 if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
559 &of_val32) >= 0) 561 &fw_val32) >= 0)
560 aad_pdata->micbias_pulse_lvl = 562 aad_pdata->micbias_pulse_lvl =
561 da7219_aad_of_micbias_pulse_lvl(codec, of_val32); 563 da7219_aad_fw_micbias_pulse_lvl(codec, fw_val32);
562 else 564 else
563 aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF; 565 aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
564 566
565 if (of_property_read_u32(aad_np, "dlg,micbias-pulse-time", 567 if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-time",
566 &of_val32) >= 0) 568 &fw_val32) >= 0)
567 aad_pdata->micbias_pulse_time = of_val32; 569 aad_pdata->micbias_pulse_time = fw_val32;
568 570
569 if (of_property_read_u32(aad_np, "dlg,btn-cfg", &of_val32) >= 0) 571 if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0)
570 aad_pdata->btn_cfg = da7219_aad_of_btn_cfg(codec, of_val32); 572 aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(codec, fw_val32);
571 else 573 else
572 aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS; 574 aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
573 575
574 if (of_property_read_u32(aad_np, "dlg,mic-det-thr", &of_val32) >= 0) 576 if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
575 aad_pdata->mic_det_thr = 577 aad_pdata->mic_det_thr =
576 da7219_aad_of_mic_det_thr(codec, of_val32); 578 da7219_aad_fw_mic_det_thr(codec, fw_val32);
577 else 579 else
578 aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS; 580 aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
579 581
580 if (of_property_read_u32(aad_np, "dlg,jack-ins-deb", &of_val32) >= 0) 582 if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
581 aad_pdata->jack_ins_deb = 583 aad_pdata->jack_ins_deb =
582 da7219_aad_of_jack_ins_deb(codec, of_val32); 584 da7219_aad_fw_jack_ins_deb(codec, fw_val32);
583 else 585 else
584 aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS; 586 aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
585 587
586 if (!of_property_read_string(aad_np, "dlg,jack-det-rate", &of_str)) 588 if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
587 aad_pdata->jack_det_rate = 589 aad_pdata->jack_det_rate =
588 da7219_aad_of_jack_det_rate(codec, of_str); 590 da7219_aad_fw_jack_det_rate(codec, fw_str);
589 else 591 else
590 aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS; 592 aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
591 593
592 if (of_property_read_u32(aad_np, "dlg,jack-rem-deb", &of_val32) >= 0) 594 if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0)
593 aad_pdata->jack_rem_deb = 595 aad_pdata->jack_rem_deb =
594 da7219_aad_of_jack_rem_deb(codec, of_val32); 596 da7219_aad_fw_jack_rem_deb(codec, fw_val32);
595 else 597 else
596 aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS; 598 aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
597 599
598 if (of_property_read_u32(aad_np, "dlg,a-d-btn-thr", &of_val32) >= 0) 600 if (fwnode_property_read_u32(aad_np, "dlg,a-d-btn-thr", &fw_val32) >= 0)
599 aad_pdata->a_d_btn_thr = (u8) of_val32; 601 aad_pdata->a_d_btn_thr = (u8) fw_val32;
600 else 602 else
601 aad_pdata->a_d_btn_thr = 0xA; 603 aad_pdata->a_d_btn_thr = 0xA;
602 604
603 if (of_property_read_u32(aad_np, "dlg,d-b-btn-thr", &of_val32) >= 0) 605 if (fwnode_property_read_u32(aad_np, "dlg,d-b-btn-thr", &fw_val32) >= 0)
604 aad_pdata->d_b_btn_thr = (u8) of_val32; 606 aad_pdata->d_b_btn_thr = (u8) fw_val32;
605 else 607 else
606 aad_pdata->d_b_btn_thr = 0x16; 608 aad_pdata->d_b_btn_thr = 0x16;
607 609
608 if (of_property_read_u32(aad_np, "dlg,b-c-btn-thr", &of_val32) >= 0) 610 if (fwnode_property_read_u32(aad_np, "dlg,b-c-btn-thr", &fw_val32) >= 0)
609 aad_pdata->b_c_btn_thr = (u8) of_val32; 611 aad_pdata->b_c_btn_thr = (u8) fw_val32;
610 else 612 else
611 aad_pdata->b_c_btn_thr = 0x21; 613 aad_pdata->b_c_btn_thr = 0x21;
612 614
613 if (of_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &of_val32) >= 0) 615 if (fwnode_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &fw_val32) >= 0)
614 aad_pdata->c_mic_btn_thr = (u8) of_val32; 616 aad_pdata->c_mic_btn_thr = (u8) fw_val32;
615 else 617 else
616 aad_pdata->c_mic_btn_thr = 0x3E; 618 aad_pdata->c_mic_btn_thr = 0x3E;
617 619
618 if (of_property_read_u32(aad_np, "dlg,btn-avg", &of_val32) >= 0) 620 if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0)
619 aad_pdata->btn_avg = da7219_aad_of_btn_avg(codec, of_val32); 621 aad_pdata->btn_avg = da7219_aad_fw_btn_avg(codec, fw_val32);
620 else 622 else
621 aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2; 623 aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
622 624
623 if (of_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &of_val32) >= 0) 625 if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
624 aad_pdata->adc_1bit_rpt = 626 aad_pdata->adc_1bit_rpt =
625 da7219_aad_of_adc_1bit_rpt(codec, of_val32); 627 da7219_aad_fw_adc_1bit_rpt(codec, fw_val32);
626 else 628 else
627 aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1; 629 aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
628 630
629out:
630 of_node_put(aad_np);
631
632 return aad_pdata; 631 return aad_pdata;
633} 632}
634 633
@@ -769,9 +768,9 @@ int da7219_aad_init(struct snd_soc_codec *codec)
769 da7219->aad = da7219_aad; 768 da7219->aad = da7219_aad;
770 da7219_aad->codec = codec; 769 da7219_aad->codec = codec;
771 770
772 /* Handle any DT/platform data */ 771 /* Handle any DT/ACPI/platform data */
773 if ((codec->dev->of_node) && (da7219->pdata)) 772 if (da7219->pdata && !da7219->pdata->aad_pdata)
774 da7219->pdata->aad_pdata = da7219_aad_of_to_pdata(codec); 773 da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(codec);
775 774
776 da7219_aad_handle_pdata(codec); 775 da7219_aad_handle_pdata(codec);
777 776
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index 5c93899f1f0e..50ea94317cb3 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -15,6 +15,7 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/of_device.h> 17#include <linux/of_device.h>
18#include <linux/property.h>
18#include <linux/regmap.h> 19#include <linux/regmap.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <linux/pm.h> 21#include <linux/pm.h>
@@ -1418,7 +1419,7 @@ static struct snd_soc_dai_driver da7219_dai = {
1418 1419
1419 1420
1420/* 1421/*
1421 * DT 1422 * DT/ACPI
1422 */ 1423 */
1423 1424
1424static const struct of_device_id da7219_of_match[] = { 1425static const struct of_device_id da7219_of_match[] = {
@@ -1434,7 +1435,7 @@ static const struct acpi_device_id da7219_acpi_match[] = {
1434MODULE_DEVICE_TABLE(acpi, da7219_acpi_match); 1435MODULE_DEVICE_TABLE(acpi, da7219_acpi_match);
1435 1436
1436static enum da7219_micbias_voltage 1437static enum da7219_micbias_voltage
1437 da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val) 1438 da7219_fw_micbias_lvl(struct device *dev, u32 val)
1438{ 1439{
1439 switch (val) { 1440 switch (val) {
1440 case 1600: 1441 case 1600:
@@ -1450,13 +1451,13 @@ static enum da7219_micbias_voltage
1450 case 2600: 1451 case 2600:
1451 return DA7219_MICBIAS_2_6V; 1452 return DA7219_MICBIAS_2_6V;
1452 default: 1453 default:
1453 dev_warn(codec->dev, "Invalid micbias level"); 1454 dev_warn(dev, "Invalid micbias level");
1454 return DA7219_MICBIAS_2_2V; 1455 return DA7219_MICBIAS_2_2V;
1455 } 1456 }
1456} 1457}
1457 1458
1458static enum da7219_mic_amp_in_sel 1459static enum da7219_mic_amp_in_sel
1459 da7219_of_mic_amp_in_sel(struct snd_soc_codec *codec, const char *str) 1460 da7219_fw_mic_amp_in_sel(struct device *dev, const char *str)
1460{ 1461{
1461 if (!strcmp(str, "diff")) { 1462 if (!strcmp(str, "diff")) {
1462 return DA7219_MIC_AMP_IN_SEL_DIFF; 1463 return DA7219_MIC_AMP_IN_SEL_DIFF;
@@ -1465,29 +1466,29 @@ static enum da7219_mic_amp_in_sel
1465 } else if (!strcmp(str, "se_n")) { 1466 } else if (!strcmp(str, "se_n")) {
1466 return DA7219_MIC_AMP_IN_SEL_SE_N; 1467 return DA7219_MIC_AMP_IN_SEL_SE_N;
1467 } else { 1468 } else {
1468 dev_warn(codec->dev, "Invalid mic input type selection"); 1469 dev_warn(dev, "Invalid mic input type selection");
1469 return DA7219_MIC_AMP_IN_SEL_DIFF; 1470 return DA7219_MIC_AMP_IN_SEL_DIFF;
1470 } 1471 }
1471} 1472}
1472 1473
1473static struct da7219_pdata *da7219_of_to_pdata(struct snd_soc_codec *codec) 1474static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
1474{ 1475{
1475 struct device_node *np = codec->dev->of_node; 1476 struct device *dev = codec->dev;
1476 struct da7219_pdata *pdata; 1477 struct da7219_pdata *pdata;
1477 const char *of_str; 1478 const char *of_str;
1478 u32 of_val32; 1479 u32 of_val32;
1479 1480
1480 pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL); 1481 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
1481 if (!pdata) 1482 if (!pdata)
1482 return NULL; 1483 return NULL;
1483 1484
1484 if (of_property_read_u32(np, "dlg,micbias-lvl", &of_val32) >= 0) 1485 if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0)
1485 pdata->micbias_lvl = da7219_of_micbias_lvl(codec, of_val32); 1486 pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32);
1486 else 1487 else
1487 pdata->micbias_lvl = DA7219_MICBIAS_2_2V; 1488 pdata->micbias_lvl = DA7219_MICBIAS_2_2V;
1488 1489
1489 if (!of_property_read_string(np, "dlg,mic-amp-in-sel", &of_str)) 1490 if (!device_property_read_string(dev, "dlg,mic-amp-in-sel", &of_str))
1490 pdata->mic_amp_in_sel = da7219_of_mic_amp_in_sel(codec, of_str); 1491 pdata->mic_amp_in_sel = da7219_fw_mic_amp_in_sel(dev, of_str);
1491 else 1492 else
1492 pdata->mic_amp_in_sel = DA7219_MIC_AMP_IN_SEL_DIFF; 1493 pdata->mic_amp_in_sel = DA7219_MIC_AMP_IN_SEL_DIFF;
1493 1494
@@ -1662,11 +1663,10 @@ static int da7219_probe(struct snd_soc_codec *codec)
1662 break; 1663 break;
1663 } 1664 }
1664 1665
1665 /* Handle DT/Platform data */ 1666 /* Handle DT/ACPI/Platform data */
1666 if (codec->dev->of_node) 1667 da7219->pdata = dev_get_platdata(codec->dev);
1667 da7219->pdata = da7219_of_to_pdata(codec); 1668 if (!da7219->pdata)
1668 else 1669 da7219->pdata = da7219_fw_to_pdata(codec);
1669 da7219->pdata = dev_get_platdata(codec->dev);
1670 1670
1671 da7219_handle_pdata(codec); 1671 da7219_handle_pdata(codec);
1672 1672
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 2abb742fc47b..4e181b270d95 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1124,8 +1124,10 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
1124 } 1124 }
1125 hdac_hdmi_parse_eld(edev, pin); 1125 hdac_hdmi_parse_eld(edev, pin);
1126 1126
1127 print_hex_dump_bytes("ELD: ", DUMP_PREFIX_OFFSET, 1127 print_hex_dump_debug("ELD: ",
1128 pin->eld.eld_buffer, pin->eld.eld_size); 1128 DUMP_PREFIX_OFFSET, 16, 1,
1129 pin->eld.eld_buffer, pin->eld.eld_size,
1130 true);
1129 } else { 1131 } else {
1130 pin->eld.monitor_present = false; 1132 pin->eld.monitor_present = false;
1131 pin->eld.eld_valid = false; 1133 pin->eld.eld_valid = false;
@@ -1816,6 +1818,7 @@ static const struct dev_pm_ops hdac_hdmi_pm = {
1816static const struct hda_device_id hdmi_list[] = { 1818static const struct hda_device_id hdmi_list[] = {
1817 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0), 1819 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
1818 HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0), 1820 HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0),
1821 HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0),
1819 {} 1822 {}
1820}; 1823};
1821 1824
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 8e36e883e453..f27d115626db 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -112,7 +112,7 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
112 return ret; 112 return ret;
113 113
114 if (hcp->hcd.ops->audio_startup) { 114 if (hcp->hcd.ops->audio_startup) {
115 ret = hcp->hcd.ops->audio_startup(dai->dev->parent); 115 ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data);
116 if (ret) { 116 if (ret) {
117 mutex_lock(&hcp->current_stream_lock); 117 mutex_lock(&hcp->current_stream_lock);
118 hcp->current_stream = NULL; 118 hcp->current_stream = NULL;
@@ -122,8 +122,8 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
122 } 122 }
123 123
124 if (hcp->hcd.ops->get_eld) { 124 if (hcp->hcd.ops->get_eld) {
125 ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->eld, 125 ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
126 sizeof(hcp->eld)); 126 hcp->eld, sizeof(hcp->eld));
127 127
128 if (!ret) { 128 if (!ret) {
129 ret = snd_pcm_hw_constraint_eld(substream->runtime, 129 ret = snd_pcm_hw_constraint_eld(substream->runtime,
@@ -144,7 +144,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
144 144
145 WARN_ON(hcp->current_stream != substream); 145 WARN_ON(hcp->current_stream != substream);
146 146
147 hcp->hcd.ops->audio_shutdown(dai->dev->parent); 147 hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
148 148
149 mutex_lock(&hcp->current_stream_lock); 149 mutex_lock(&hcp->current_stream_lock);
150 hcp->current_stream = NULL; 150 hcp->current_stream = NULL;
@@ -195,8 +195,8 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
195 hp.sample_rate = params_rate(params); 195 hp.sample_rate = params_rate(params);
196 hp.channels = params_channels(params); 196 hp.channels = params_channels(params);
197 197
198 return hcp->hcd.ops->hw_params(dai->dev->parent, &hcp->daifmt[dai->id], 198 return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
199 &hp); 199 &hcp->daifmt[dai->id], &hp);
200} 200}
201 201
202static int hdmi_codec_set_fmt(struct snd_soc_dai *dai, 202static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
@@ -280,7 +280,8 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
280 dev_dbg(dai->dev, "%s()\n", __func__); 280 dev_dbg(dai->dev, "%s()\n", __func__);
281 281
282 if (hcp->hcd.ops->digital_mute) 282 if (hcp->hcd.ops->digital_mute)
283 return hcp->hcd.ops->digital_mute(dai->dev->parent, mute); 283 return hcp->hcd.ops->digital_mute(dai->dev->parent,
284 hcp->hcd.data, mute);
284 285
285 return 0; 286 return 0;
286} 287}
diff --git a/sound/soc/codecs/max98504.c b/sound/soc/codecs/max98504.c
new file mode 100644
index 000000000000..a7320e709890
--- /dev/null
+++ b/sound/soc/codecs/max98504.c
@@ -0,0 +1,383 @@
1/*
2 * MAX98504 ALSA SoC Audio driver
3 *
4 * Copyright 2013 - 2014 Maxim Integrated Products
5 * Copyright 2016 Samsung Electronics Co., Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/delay.h>
13#include <linux/i2c.h>
14#include <linux/module.h>
15#include <linux/regulator/consumer.h>
16#include <linux/slab.h>
17#include <linux/types.h>
18#include <sound/soc.h>
19
20#include "max98504.h"
21
22static const char * const max98504_supply_names[] = {
23 "DVDD",
24 "DIOVDD",
25 "PVDD",
26};
27#define MAX98504_NUM_SUPPLIES ARRAY_SIZE(max98504_supply_names)
28
29struct max98504_priv {
30 struct regmap *regmap;
31 struct regulator_bulk_data supplies[MAX98504_NUM_SUPPLIES];
32 unsigned int pcm_rx_channels;
33 bool brownout_enable;
34 unsigned int brownout_threshold;
35 unsigned int brownout_attenuation;
36 unsigned int brownout_attack_hold;
37 unsigned int brownout_timed_hold;
38 unsigned int brownout_release_rate;
39};
40
41static struct reg_default max98504_reg_defaults[] = {
42 { 0x01, 0},
43 { 0x02, 0},
44 { 0x03, 0},
45 { 0x04, 0},
46 { 0x10, 0},
47 { 0x11, 0},
48 { 0x12, 0},
49 { 0x13, 0},
50 { 0x14, 0},
51 { 0x15, 0},
52 { 0x16, 0},
53 { 0x17, 0},
54 { 0x18, 0},
55 { 0x19, 0},
56 { 0x1A, 0},
57 { 0x20, 0},
58 { 0x21, 0},
59 { 0x22, 0},
60 { 0x23, 0},
61 { 0x24, 0},
62 { 0x25, 0},
63 { 0x26, 0},
64 { 0x27, 0},
65 { 0x28, 0},
66 { 0x30, 0},
67 { 0x31, 0},
68 { 0x32, 0},
69 { 0x33, 0},
70 { 0x34, 0},
71 { 0x35, 0},
72 { 0x36, 0},
73 { 0x37, 0},
74 { 0x38, 0},
75 { 0x39, 0},
76 { 0x40, 0},
77 { 0x41, 0},
78};
79
80static bool max98504_volatile_register(struct device *dev, unsigned int reg)
81{
82 switch (reg) {
83 case MAX98504_INTERRUPT_STATUS:
84 case MAX98504_INTERRUPT_FLAGS:
85 case MAX98504_INTERRUPT_FLAG_CLEARS:
86 case MAX98504_WATCHDOG_CLEAR:
87 case MAX98504_GLOBAL_ENABLE:
88 case MAX98504_SOFTWARE_RESET:
89 return true;
90 default:
91 return false;
92 }
93}
94
95static bool max98504_readable_register(struct device *dev, unsigned int reg)
96{
97 switch (reg) {
98 case MAX98504_SOFTWARE_RESET:
99 case MAX98504_WATCHDOG_CLEAR:
100 case MAX98504_INTERRUPT_FLAG_CLEARS:
101 return false;
102 default:
103 return true;
104 }
105}
106
107static int max98504_pcm_rx_ev(struct snd_soc_dapm_widget *w,
108 struct snd_kcontrol *kcontrol, int event)
109{
110 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
111 struct max98504_priv *max98504 = snd_soc_component_get_drvdata(c);
112
113 switch (event) {
114 case SND_SOC_DAPM_PRE_PMU:
115 regmap_write(max98504->regmap, MAX98504_PCM_RX_ENABLE,
116 max98504->pcm_rx_channels);
117 break;
118 case SND_SOC_DAPM_POST_PMD:
119 regmap_write(max98504->regmap, MAX98504_PCM_RX_ENABLE, 0);
120 break;
121 }
122
123 return 0;
124}
125
126static int max98504_component_probe(struct snd_soc_component *c)
127{
128 struct max98504_priv *max98504 = snd_soc_component_get_drvdata(c);
129 struct regmap *map = max98504->regmap;
130 int ret;
131
132 ret = regulator_bulk_enable(MAX98504_NUM_SUPPLIES, max98504->supplies);
133 if (ret < 0)
134 return ret;
135
136 regmap_write(map, MAX98504_SOFTWARE_RESET, 0x1);
137 msleep(20);
138
139 if (!max98504->brownout_enable)
140 return 0;
141
142 regmap_write(map, MAX98504_PVDD_BROWNOUT_ENABLE, 0x1);
143
144 regmap_write(map, MAX98504_PVDD_BROWNOUT_CONFIG_1,
145 (max98504->brownout_threshold & 0x1f) << 3 |
146 (max98504->brownout_attenuation & 0x3));
147
148 regmap_write(map, MAX98504_PVDD_BROWNOUT_CONFIG_2,
149 max98504->brownout_attack_hold & 0xff);
150
151 regmap_write(map, MAX98504_PVDD_BROWNOUT_CONFIG_3,
152 max98504->brownout_timed_hold & 0xff);
153
154 regmap_write(map, MAX98504_PVDD_BROWNOUT_CONFIG_4,
155 max98504->brownout_release_rate & 0xff);
156
157 return 0;
158}
159
160static void max98504_component_remove(struct snd_soc_component *c)
161{
162 struct max98504_priv *max98504 = snd_soc_component_get_drvdata(c);
163
164 regulator_bulk_disable(MAX98504_NUM_SUPPLIES, max98504->supplies);
165}
166
167static const char *spk_source_mux_text[] = {
168 "PCM Monomix", "Analog In", "PDM Left", "PDM Right"
169};
170
171static const struct soc_enum spk_source_mux_enum =
172 SOC_ENUM_SINGLE(MAX98504_SPEAKER_SOURCE_SELECT,
173 0, ARRAY_SIZE(spk_source_mux_text),
174 spk_source_mux_text);
175
176static const struct snd_kcontrol_new spk_source_mux =
177 SOC_DAPM_ENUM("SPK Source", spk_source_mux_enum);
178
179static const struct snd_soc_dapm_route max98504_dapm_routes[] = {
180 { "SPKOUT", NULL, "Global Enable" },
181 { "SPK Source", "PCM Monomix", "DAC PCM" },
182 { "SPK Source", "Analog In", "AIN" },
183 { "SPK Source", "PDM Left", "DAC PDM" },
184 { "SPK Source", "PDM Right", "DAC PDM" },
185};
186
187static const struct snd_soc_dapm_widget max98504_dapm_widgets[] = {
188 SND_SOC_DAPM_SUPPLY("Global Enable", MAX98504_GLOBAL_ENABLE,
189 0, 0, NULL, 0),
190 SND_SOC_DAPM_INPUT("AIN"),
191 SND_SOC_DAPM_AIF_OUT("AIF2OUTL", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
192 SND_SOC_DAPM_AIF_OUT("AIF2OUTR", "AIF2 Capture", 1, SND_SOC_NOPM, 0, 0),
193 SND_SOC_DAPM_DAC_E("DAC PCM", NULL, SND_SOC_NOPM, 0, 0,
194 max98504_pcm_rx_ev,
195 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
196 SND_SOC_DAPM_DAC("DAC PDM", NULL, MAX98504_PDM_RX_ENABLE, 0, 0),
197 SND_SOC_DAPM_MUX("SPK Source", SND_SOC_NOPM, 0, 0, &spk_source_mux),
198 SND_SOC_DAPM_REG(snd_soc_dapm_spk, "SPKOUT",
199 MAX98504_SPEAKER_ENABLE, 0, 1, 1, 0),
200};
201
202static int max98504_set_tdm_slot(struct snd_soc_dai *dai,
203 unsigned int tx_mask, unsigned int rx_mask,
204 int slots, int slot_width)
205{
206 struct max98504_priv *max98504 = snd_soc_dai_get_drvdata(dai);
207 struct regmap *map = max98504->regmap;
208
209
210 switch (dai->id) {
211 case MAX98504_DAI_ID_PCM:
212 regmap_write(map, MAX98504_PCM_TX_ENABLE, tx_mask);
213 max98504->pcm_rx_channels = rx_mask;
214 break;
215
216 case MAX98504_DAI_ID_PDM:
217 regmap_write(map, MAX98504_PDM_TX_ENABLE, tx_mask);
218 break;
219 default:
220 WARN_ON(1);
221 }
222
223 return 0;
224}
225static int max98504_set_channel_map(struct snd_soc_dai *dai,
226 unsigned int tx_num, unsigned int *tx_slot,
227 unsigned int rx_num, unsigned int *rx_slot)
228{
229 struct max98504_priv *max98504 = snd_soc_dai_get_drvdata(dai);
230 struct regmap *map = max98504->regmap;
231 unsigned int i, sources = 0;
232
233 for (i = 0; i < tx_num; i++)
234 if (tx_slot[i])
235 sources |= (1 << i);
236
237 switch (dai->id) {
238 case MAX98504_DAI_ID_PCM:
239 regmap_write(map, MAX98504_PCM_TX_CHANNEL_SOURCES,
240 sources);
241 break;
242
243 case MAX98504_DAI_ID_PDM:
244 regmap_write(map, MAX98504_PDM_TX_CONTROL, sources);
245 break;
246 default:
247 WARN_ON(1);
248 }
249
250 regmap_write(map, MAX98504_MEASUREMENT_ENABLE, sources ? 0x3 : 0x01);
251
252 return 0;
253}
254
255static const struct snd_soc_dai_ops max98504_dai_ops = {
256 .set_tdm_slot = max98504_set_tdm_slot,
257 .set_channel_map = max98504_set_channel_map,
258};
259
260#define MAX98504_FORMATS (SNDRV_PCM_FMTBIT_S8|SNDRV_PCM_FMTBIT_S16_LE|\
261 SNDRV_PCM_FMTBIT_S24_LE|SNDRV_PCM_FMTBIT_S32_LE)
262#define MAX98504_PDM_RATES (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|\
263 SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|\
264 SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_88200|\
265 SNDRV_PCM_RATE_96000)
266
267static struct snd_soc_dai_driver max98504_dai[] = {
268 /* TODO: Add the PCM interface definitions */
269 {
270 .name = "max98504-aif2",
271 .id = MAX98504_DAI_ID_PDM,
272 .playback = {
273 .stream_name = "AIF2 Playback",
274 .channels_min = 1,
275 .channels_max = 2,
276 .rates = MAX98504_PDM_RATES,
277 .formats = MAX98504_FORMATS,
278 },
279 .capture = {
280 .stream_name = "AIF2 Capture",
281 .channels_min = 1,
282 .channels_max = 2,
283 .rates = MAX98504_PDM_RATES,
284 .formats = MAX98504_FORMATS,
285 },
286 .ops = &max98504_dai_ops,
287 },
288};
289
290static const struct snd_soc_component_driver max98504_component_driver = {
291 .probe = max98504_component_probe,
292 .remove = max98504_component_remove,
293 .dapm_widgets = max98504_dapm_widgets,
294 .num_dapm_widgets = ARRAY_SIZE(max98504_dapm_widgets),
295 .dapm_routes = max98504_dapm_routes,
296 .num_dapm_routes = ARRAY_SIZE(max98504_dapm_routes),
297};
298
299static const struct regmap_config max98504_regmap = {
300 .reg_bits = 16,
301 .val_bits = 8,
302 .max_register = MAX98504_MAX_REGISTER,
303 .reg_defaults = max98504_reg_defaults,
304 .num_reg_defaults = ARRAY_SIZE(max98504_reg_defaults),
305 .volatile_reg = max98504_volatile_register,
306 .readable_reg = max98504_readable_register,
307 .cache_type = REGCACHE_RBTREE,
308};
309
310static int max98504_i2c_probe(struct i2c_client *client,
311 const struct i2c_device_id *id)
312{
313 struct device *dev = &client->dev;
314 struct device_node *node = dev->of_node;
315 struct max98504_priv *max98504;
316 int i, ret;
317
318 max98504 = devm_kzalloc(dev, sizeof(*max98504), GFP_KERNEL);
319 if (!max98504)
320 return -ENOMEM;
321
322 if (node) {
323 if (!of_property_read_u32(node, "maxim,brownout-threshold",
324 &max98504->brownout_threshold))
325 max98504->brownout_enable = true;
326
327 of_property_read_u32(node, "maxim,brownout-attenuation",
328 &max98504->brownout_attenuation);
329 of_property_read_u32(node, "maxim,brownout-attack-hold-ms",
330 &max98504->brownout_attack_hold);
331 of_property_read_u32(node, "maxim,brownout-timed-hold-ms",
332 &max98504->brownout_timed_hold);
333 of_property_read_u32(node, "maxim,brownout-release-rate-ms",
334 &max98504->brownout_release_rate);
335 }
336
337 max98504->regmap = devm_regmap_init_i2c(client, &max98504_regmap);
338 if (IS_ERR(max98504->regmap)) {
339 ret = PTR_ERR(max98504->regmap);
340 dev_err(&client->dev, "regmap initialization failed: %d\n", ret);
341 return ret;
342 }
343
344 for (i = 0; i < MAX98504_NUM_SUPPLIES; i++)
345 max98504->supplies[i].supply = max98504_supply_names[i];
346
347 ret = devm_regulator_bulk_get(dev, MAX98504_NUM_SUPPLIES,
348 max98504->supplies);
349 if (ret < 0)
350 return ret;
351
352 i2c_set_clientdata(client, max98504);
353
354 return devm_snd_soc_register_component(dev, &max98504_component_driver,
355 max98504_dai, ARRAY_SIZE(max98504_dai));
356}
357
358#ifdef CONFIG_OF
359static const struct of_device_id max98504_of_match[] = {
360 { .compatible = "maxim,max98504" },
361 { },
362};
363MODULE_DEVICE_TABLE(of, max98504_of_match);
364#endif
365
366static const struct i2c_device_id max98504_i2c_id[] = {
367 { "max98504" },
368 { }
369};
370MODULE_DEVICE_TABLE(i2c, max98504_i2c_id);
371
372static struct i2c_driver max98504_i2c_driver = {
373 .driver = {
374 .name = "max98504",
375 .of_match_table = of_match_ptr(max98504_of_match),
376 },
377 .probe = max98504_i2c_probe,
378 .id_table = max98504_i2c_id,
379};
380module_i2c_driver(max98504_i2c_driver);
381
382MODULE_DESCRIPTION("ASoC MAX98504 driver");
383MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98504.h b/sound/soc/codecs/max98504.h
new file mode 100644
index 000000000000..afbefad2d5ce
--- /dev/null
+++ b/sound/soc/codecs/max98504.h
@@ -0,0 +1,59 @@
1/*
2 * MAX98504 ALSA SoC Audio driver
3 *
4 * Copyright 2011 - 2012 Maxim Integrated Products
5 * Copyright 2016 Samsung Electronics Co., Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef MAX98504_H_
12#define MAX98504_H_
13
14/*
15 * MAX98504 Register Definitions
16 */
17#define MAX98504_INTERRUPT_STATUS 0x01
18#define MAX98504_INTERRUPT_FLAGS 0x02
19#define MAX98504_INTERRUPT_ENABLE 0x03
20#define MAX98504_INTERRUPT_FLAG_CLEARS 0x04
21#define MAX98504_GPIO_ENABLE 0x10
22#define MAX98504_GPIO_CONFIG 0x11
23#define MAX98504_WATCHDOG_ENABLE 0x12
24#define MAX98504_WATCHDOG_CONFIG 0x13
25#define MAX98504_WATCHDOG_CLEAR 0x14
26#define MAX98504_CLOCK_MONITOR_ENABLE 0x15
27#define MAX98504_PVDD_BROWNOUT_ENABLE 0x16
28#define MAX98504_PVDD_BROWNOUT_CONFIG_1 0x17
29#define MAX98504_PVDD_BROWNOUT_CONFIG_2 0x18
30#define MAX98504_PVDD_BROWNOUT_CONFIG_3 0x19
31#define MAX98504_PVDD_BROWNOUT_CONFIG_4 0x1a
32#define MAX98504_PCM_RX_ENABLE 0x20
33#define MAX98504_PCM_TX_ENABLE 0x21
34#define MAX98504_PCM_TX_HIZ_CONTROL 0x22
35#define MAX98504_PCM_TX_CHANNEL_SOURCES 0x23
36#define MAX98504_PCM_MODE_CONFIG 0x24
37#define MAX98504_PCM_DSP_CONFIG 0x25
38#define MAX98504_PCM_CLOCK_SETUP 0x26
39#define MAX98504_PCM_SAMPLE_RATE_SETUP 0x27
40#define MAX98504_PCM_TO_SPEAKER_MONOMIX 0x28
41#define MAX98504_PDM_TX_ENABLE 0x30
42#define MAX98504_PDM_TX_HIZ_CONTROL 0x31
43#define MAX98504_PDM_TX_CONTROL 0x32
44#define MAX98504_PDM_RX_ENABLE 0x33
45#define MAX98504_SPEAKER_ENABLE 0x34
46#define MAX98504_SPEAKER_SOURCE_SELECT 0x35
47#define MAX98504_MEASUREMENT_ENABLE 0x36
48#define MAX98504_ANALOGUE_INPUT_GAIN 0x37
49#define MAX98504_TEMPERATURE_LIMIT_CONFIG 0x38
50#define MAX98504_GLOBAL_ENABLE 0x40
51#define MAX98504_SOFTWARE_RESET 0x41
52#define MAX98504_REV_ID 0x7fff
53
54#define MAX98504_MAX_REGISTER 0x7fff
55
56#define MAX98504_DAI_ID_PCM 1
57#define MAX98504_DAI_ID_PDM 2
58
59#endif /* MAX98504_H_ */
diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c
new file mode 100644
index 000000000000..68074c92a7c0
--- /dev/null
+++ b/sound/soc/codecs/max9860.c
@@ -0,0 +1,753 @@
1/*
2 * Driver for the MAX9860 Mono Audio Voice Codec
3 *
4 * https://datasheets.maximintegrated.com/en/ds/MAX9860.pdf
5 *
6 * The driver does not support sidetone since the DVST register field is
7 * backwards with the mute near the maximum level instead of the minimum.
8 *
9 * Author: Peter Rosin <peda@axentia.s>
10 * Copyright 2016 Axentia Technologies
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/clk.h>
25#include <linux/kernel.h>
26#include <linux/pm_runtime.h>
27#include <linux/regmap.h>
28#include <linux/i2c.h>
29#include <linux/regulator/consumer.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/pcm_params.h>
33#include <sound/tlv.h>
34
35#include "max9860.h"
36
37struct max9860_priv {
38 struct regmap *regmap;
39 struct regulator *dvddio;
40 struct notifier_block dvddio_nb;
41 u8 psclk;
42 unsigned long pclk_rate;
43 int fmt;
44};
45
46static int max9860_dvddio_event(struct notifier_block *nb,
47 unsigned long event, void *data)
48{
49 struct max9860_priv *max9860 = container_of(nb, struct max9860_priv,
50 dvddio_nb);
51 if (event & REGULATOR_EVENT_DISABLE) {
52 regcache_mark_dirty(max9860->regmap);
53 regcache_cache_only(max9860->regmap, true);
54 }
55
56 return 0;
57}
58
59static const struct reg_default max9860_reg_defaults[] = {
60 { MAX9860_PWRMAN, 0x00 },
61 { MAX9860_INTEN, 0x00 },
62 { MAX9860_SYSCLK, 0x00 },
63 { MAX9860_AUDIOCLKHIGH, 0x00 },
64 { MAX9860_AUDIOCLKLOW, 0x00 },
65 { MAX9860_IFC1A, 0x00 },
66 { MAX9860_IFC1B, 0x00 },
67 { MAX9860_VOICEFLTR, 0x00 },
68 { MAX9860_DACATTN, 0x00 },
69 { MAX9860_ADCLEVEL, 0x00 },
70 { MAX9860_DACGAIN, 0x00 },
71 { MAX9860_MICGAIN, 0x00 },
72 { MAX9860_MICADC, 0x00 },
73 { MAX9860_NOISEGATE, 0x00 },
74};
75
76static bool max9860_readable(struct device *dev, unsigned int reg)
77{
78 switch (reg) {
79 case MAX9860_INTRSTATUS ... MAX9860_MICGAIN:
80 case MAX9860_MICADC ... MAX9860_PWRMAN:
81 case MAX9860_REVISION:
82 return true;
83 }
84
85 return false;
86}
87
88static bool max9860_writeable(struct device *dev, unsigned int reg)
89{
90 switch (reg) {
91 case MAX9860_INTEN ... MAX9860_MICGAIN:
92 case MAX9860_MICADC ... MAX9860_PWRMAN:
93 return true;
94 }
95
96 return false;
97}
98
99static bool max9860_volatile(struct device *dev, unsigned int reg)
100{
101 switch (reg) {
102 case MAX9860_INTRSTATUS:
103 case MAX9860_MICREADBACK:
104 return true;
105 }
106
107 return false;
108}
109
110static bool max9860_precious(struct device *dev, unsigned int reg)
111{
112 switch (reg) {
113 case MAX9860_INTRSTATUS:
114 return true;
115 }
116
117 return false;
118}
119
120static const struct regmap_config max9860_regmap = {
121 .reg_bits = 8,
122 .val_bits = 8,
123
124 .readable_reg = max9860_readable,
125 .writeable_reg = max9860_writeable,
126 .volatile_reg = max9860_volatile,
127 .precious_reg = max9860_precious,
128
129 .max_register = MAX9860_MAX_REGISTER,
130 .reg_defaults = max9860_reg_defaults,
131 .num_reg_defaults = ARRAY_SIZE(max9860_reg_defaults),
132 .cache_type = REGCACHE_RBTREE,
133};
134
135static const DECLARE_TLV_DB_SCALE(dva_tlv, -9100, 100, 1);
136static const DECLARE_TLV_DB_SCALE(dvg_tlv, 0, 600, 0);
137static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0);
138static const DECLARE_TLV_DB_RANGE(pam_tlv,
139 0, MAX9860_PAM_MAX - 1, TLV_DB_SCALE_ITEM(-2000, 2000, 1),
140 MAX9860_PAM_MAX, MAX9860_PAM_MAX, TLV_DB_SCALE_ITEM(3000, 0, 0));
141static const DECLARE_TLV_DB_SCALE(pgam_tlv, 0, 100, 0);
142static const DECLARE_TLV_DB_SCALE(anth_tlv, -7600, 400, 1);
143static const DECLARE_TLV_DB_SCALE(agcth_tlv, -1800, 100, 0);
144
145static const char * const agchld_text[] = {
146 "AGC Disabled", "50ms", "100ms", "400ms"
147};
148
149static SOC_ENUM_SINGLE_DECL(agchld_enum, MAX9860_MICADC,
150 MAX9860_AGCHLD_SHIFT, agchld_text);
151
152static const char * const agcsrc_text[] = {
153 "Left ADC", "Left/Right ADC"
154};
155
156static SOC_ENUM_SINGLE_DECL(agcsrc_enum, MAX9860_MICADC,
157 MAX9860_AGCSRC_SHIFT, agcsrc_text);
158
159static const char * const agcatk_text[] = {
160 "3ms", "12ms", "50ms", "200ms"
161};
162
163static SOC_ENUM_SINGLE_DECL(agcatk_enum, MAX9860_MICADC,
164 MAX9860_AGCATK_SHIFT, agcatk_text);
165
166static const char * const agcrls_text[] = {
167 "78ms", "156ms", "312ms", "625ms",
168 "1.25s", "2.5s", "5s", "10s"
169};
170
171static SOC_ENUM_SINGLE_DECL(agcrls_enum, MAX9860_MICADC,
172 MAX9860_AGCRLS_SHIFT, agcrls_text);
173
174static const char * const filter_text[] = {
175 "Disabled",
176 "Elliptical HP 217Hz notch (16kHz)",
177 "Butterworth HP 500Hz (16kHz)",
178 "Elliptical HP 217Hz notch (8kHz)",
179 "Butterworth HP 500Hz (8kHz)",
180 "Butterworth HP 200Hz (48kHz)"
181};
182
183static SOC_ENUM_SINGLE_DECL(avflt_enum, MAX9860_VOICEFLTR,
184 MAX9860_AVFLT_SHIFT, filter_text);
185
186static SOC_ENUM_SINGLE_DECL(dvflt_enum, MAX9860_VOICEFLTR,
187 MAX9860_DVFLT_SHIFT, filter_text);
188
189static const struct snd_kcontrol_new max9860_controls[] = {
190SOC_SINGLE_TLV("Master Playback Volume", MAX9860_DACATTN,
191 MAX9860_DVA_SHIFT, MAX9860_DVA_MUTE, 1, dva_tlv),
192SOC_SINGLE_TLV("DAC Gain Volume", MAX9860_DACGAIN,
193 MAX9860_DVG_SHIFT, MAX9860_DVG_MAX, 0, dvg_tlv),
194SOC_DOUBLE_TLV("Line Capture Volume", MAX9860_ADCLEVEL,
195 MAX9860_ADCLL_SHIFT, MAX9860_ADCRL_SHIFT, MAX9860_ADCxL_MIN, 1,
196 adc_tlv),
197
198SOC_ENUM("AGC Hold Time", agchld_enum),
199SOC_ENUM("AGC/Noise Gate Source", agcsrc_enum),
200SOC_ENUM("AGC Attack Time", agcatk_enum),
201SOC_ENUM("AGC Release Time", agcrls_enum),
202
203SOC_SINGLE_TLV("Noise Gate Threshold Volume", MAX9860_NOISEGATE,
204 MAX9860_ANTH_SHIFT, MAX9860_ANTH_MAX, 0, anth_tlv),
205SOC_SINGLE_TLV("AGC Signal Threshold Volume", MAX9860_NOISEGATE,
206 MAX9860_AGCTH_SHIFT, MAX9860_AGCTH_MIN, 1, agcth_tlv),
207
208SOC_SINGLE_TLV("Mic PGA Volume", MAX9860_MICGAIN,
209 MAX9860_PGAM_SHIFT, MAX9860_PGAM_MIN, 1, pgam_tlv),
210SOC_SINGLE_TLV("Mic Preamp Volume", MAX9860_MICGAIN,
211 MAX9860_PAM_SHIFT, MAX9860_PAM_MAX, 0, pam_tlv),
212
213SOC_ENUM("ADC Filter", avflt_enum),
214SOC_ENUM("DAC Filter", dvflt_enum),
215};
216
217static const struct snd_soc_dapm_widget max9860_dapm_widgets[] = {
218SND_SOC_DAPM_INPUT("MICL"),
219SND_SOC_DAPM_INPUT("MICR"),
220
221SND_SOC_DAPM_ADC("ADCL", NULL, MAX9860_PWRMAN, MAX9860_ADCLEN_SHIFT, 0),
222SND_SOC_DAPM_ADC("ADCR", NULL, MAX9860_PWRMAN, MAX9860_ADCREN_SHIFT, 0),
223
224SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
225SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
226
227SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
228SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
229
230SND_SOC_DAPM_DAC("DAC", NULL, MAX9860_PWRMAN, MAX9860_DACEN_SHIFT, 0),
231
232SND_SOC_DAPM_OUTPUT("OUT"),
233
234SND_SOC_DAPM_SUPPLY("Supply", SND_SOC_NOPM, 0, 0,
235 NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
236SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 0, 0),
237SND_SOC_DAPM_REGULATOR_SUPPLY("DVDD", 0, 0),
238SND_SOC_DAPM_CLOCK_SUPPLY("mclk"),
239};
240
241static const struct snd_soc_dapm_route max9860_dapm_routes[] = {
242 { "ADCL", NULL, "MICL" },
243 { "ADCR", NULL, "MICR" },
244 { "AIFOUTL", NULL, "ADCL" },
245 { "AIFOUTR", NULL, "ADCR" },
246
247 { "DAC", NULL, "AIFINL" },
248 { "DAC", NULL, "AIFINR" },
249 { "OUT", NULL, "DAC" },
250
251 { "Supply", NULL, "AVDD" },
252 { "Supply", NULL, "DVDD" },
253 { "Supply", NULL, "mclk" },
254
255 { "DAC", NULL, "Supply" },
256 { "ADCL", NULL, "Supply" },
257 { "ADCR", NULL, "Supply" },
258};
259
260static int max9860_hw_params(struct snd_pcm_substream *substream,
261 struct snd_pcm_hw_params *params,
262 struct snd_soc_dai *dai)
263{
264 struct snd_soc_codec *codec = dai->codec;
265 struct max9860_priv *max9860 = snd_soc_codec_get_drvdata(codec);
266 u8 master;
267 u8 ifc1a = 0;
268 u8 ifc1b = 0;
269 u8 sysclk = 0;
270 unsigned long n;
271 int ret;
272
273 dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n",
274 params_rate(params),
275 params_channels(params));
276
277 if (params_channels(params) == 2)
278 ifc1b |= MAX9860_ST;
279
280 switch (max9860->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
281 case SND_SOC_DAIFMT_CBS_CFS:
282 master = 0;
283 break;
284 case SND_SOC_DAIFMT_CBM_CFM:
285 master = MAX9860_MASTER;
286 break;
287 default:
288 return -EINVAL;
289 }
290 ifc1a |= master;
291
292 if (master) {
293 if (params_width(params) * params_channels(params) > 48)
294 ifc1b |= MAX9860_BSEL_64X;
295 else
296 ifc1b |= MAX9860_BSEL_48X;
297 }
298
299 switch (max9860->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
300 case SND_SOC_DAIFMT_I2S:
301 ifc1a |= MAX9860_DDLY;
302 ifc1b |= MAX9860_ADLY;
303 break;
304 case SND_SOC_DAIFMT_LEFT_J:
305 ifc1a |= MAX9860_WCI;
306 break;
307 case SND_SOC_DAIFMT_DSP_A:
308 if (params_width(params) != 16) {
309 dev_err(codec->dev,
310 "DSP_A works for 16 bits per sample only.\n");
311 return -EINVAL;
312 }
313 ifc1a |= MAX9860_DDLY | MAX9860_WCI | MAX9860_HIZ | MAX9860_TDM;
314 ifc1b |= MAX9860_ADLY;
315 break;
316 case SND_SOC_DAIFMT_DSP_B:
317 if (params_width(params) != 16) {
318 dev_err(codec->dev,
319 "DSP_B works for 16 bits per sample only.\n");
320 return -EINVAL;
321 }
322 ifc1a |= MAX9860_WCI | MAX9860_HIZ | MAX9860_TDM;
323 break;
324 default:
325 return -EINVAL;
326 }
327
328 switch (max9860->fmt & SND_SOC_DAIFMT_INV_MASK) {
329 case SND_SOC_DAIFMT_NB_NF:
330 break;
331 case SND_SOC_DAIFMT_NB_IF:
332 switch (max9860->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
333 case SND_SOC_DAIFMT_DSP_A:
334 case SND_SOC_DAIFMT_DSP_B:
335 return -EINVAL;
336 }
337 ifc1a ^= MAX9860_WCI;
338 break;
339 case SND_SOC_DAIFMT_IB_IF:
340 switch (max9860->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
341 case SND_SOC_DAIFMT_DSP_A:
342 case SND_SOC_DAIFMT_DSP_B:
343 return -EINVAL;
344 }
345 ifc1a ^= MAX9860_WCI;
346 /* fall through */
347 case SND_SOC_DAIFMT_IB_NF:
348 ifc1a ^= MAX9860_DBCI;
349 ifc1b ^= MAX9860_ABCI;
350 break;
351 default:
352 return -EINVAL;
353 }
354
355 dev_dbg(codec->dev, "IFC1A %02x\n", ifc1a);
356 ret = regmap_write(max9860->regmap, MAX9860_IFC1A, ifc1a);
357 if (ret) {
358 dev_err(codec->dev, "Failed to set IFC1A: %d\n", ret);
359 return ret;
360 }
361 dev_dbg(codec->dev, "IFC1B %02x\n", ifc1b);
362 ret = regmap_write(max9860->regmap, MAX9860_IFC1B, ifc1b);
363 if (ret) {
364 dev_err(codec->dev, "Failed to set IFC1B: %d\n", ret);
365 return ret;
366 }
367
368 /*
369 * Check if Integer Clock Mode is possible, but avoid it in slave mode
370 * since we then do not know if lrclk is derived from pclk and the
371 * datasheet mentions that the frequencies have to match exactly in
372 * order for this to work.
373 */
374 if (params_rate(params) == 8000 || params_rate(params) == 16000) {
375 if (master) {
376 switch (max9860->pclk_rate) {
377 case 12000000:
378 sysclk = MAX9860_FREQ_12MHZ;
379 break;
380 case 13000000:
381 sysclk = MAX9860_FREQ_13MHZ;
382 break;
383 case 19200000:
384 sysclk = MAX9860_FREQ_19_2MHZ;
385 break;
386 default:
387 /*
388 * Integer Clock Mode not possible. Leave
389 * sysclk at zero and fall through to the
390 * code below for PLL mode.
391 */
392 break;
393 }
394
395 if (sysclk && params_rate(params) == 16000)
396 sysclk |= MAX9860_16KHZ;
397 }
398 }
399
400 /*
401 * Largest possible n:
402 * 65536 * 96 * 48kHz / 10MHz -> 30199
403 * Smallest possible n:
404 * 65536 * 96 * 8kHz / 20MHz -> 2517
405 * Both fit nicely in the available 15 bits, no need to apply any mask.
406 */
407 n = DIV_ROUND_CLOSEST_ULL(65536ULL * 96 * params_rate(params),
408 max9860->pclk_rate);
409
410 if (!sysclk) {
411 /* PLL mode */
412 if (params_rate(params) > 24000)
413 sysclk |= MAX9860_16KHZ;
414
415 if (!master)
416 n |= 1; /* trigger rapid pll lock mode */
417 }
418
419 sysclk |= max9860->psclk;
420 dev_dbg(codec->dev, "SYSCLK %02x\n", sysclk);
421 ret = regmap_write(max9860->regmap,
422 MAX9860_SYSCLK, sysclk);
423 if (ret) {
424 dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
425 return ret;
426 }
427 dev_dbg(codec->dev, "N %lu\n", n);
428 ret = regmap_write(max9860->regmap,
429 MAX9860_AUDIOCLKHIGH, n >> 8);
430 if (ret) {
431 dev_err(codec->dev, "Failed to set NHI: %d\n", ret);
432 return ret;
433 }
434 ret = regmap_write(max9860->regmap,
435 MAX9860_AUDIOCLKLOW, n & 0xff);
436 if (ret) {
437 dev_err(codec->dev, "Failed to set NLO: %d\n", ret);
438 return ret;
439 }
440
441 if (!master) {
442 dev_dbg(codec->dev, "Enable PLL\n");
443 ret = regmap_update_bits(max9860->regmap, MAX9860_AUDIOCLKHIGH,
444 MAX9860_PLL, MAX9860_PLL);
445 if (ret) {
446 dev_err(codec->dev, "Failed to enable PLL: %d\n", ret);
447 return ret;
448 }
449 }
450
451 return 0;
452}
453
454static int max9860_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
455{
456 struct snd_soc_codec *codec = dai->codec;
457 struct max9860_priv *max9860 = snd_soc_codec_get_drvdata(codec);
458
459 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
460 case SND_SOC_DAIFMT_CBM_CFM:
461 case SND_SOC_DAIFMT_CBS_CFS:
462 max9860->fmt = fmt;
463 return 0;
464
465 default:
466 return -EINVAL;
467 }
468}
469
470static const struct snd_soc_dai_ops max9860_dai_ops = {
471 .hw_params = max9860_hw_params,
472 .set_fmt = max9860_set_fmt,
473};
474
475static struct snd_soc_dai_driver max9860_dai = {
476 .name = "max9860-hifi",
477 .playback = {
478 .stream_name = "Playback",
479 .channels_min = 1,
480 .channels_max = 2,
481 .rates = SNDRV_PCM_RATE_CONTINUOUS,
482 .rate_min = 8000,
483 .rate_max = 48000,
484 .formats = SNDRV_PCM_FMTBIT_S16_LE |
485 SNDRV_PCM_FMTBIT_S24_LE |
486 SNDRV_PCM_FMTBIT_S32_LE,
487 },
488 .capture = {
489 .stream_name = "Capture",
490 .channels_min = 1,
491 .channels_max = 2,
492 .rates = SNDRV_PCM_RATE_CONTINUOUS,
493 .rate_min = 8000,
494 .rate_max = 48000,
495 .formats = SNDRV_PCM_FMTBIT_S16_LE |
496 SNDRV_PCM_FMTBIT_S24_LE |
497 SNDRV_PCM_FMTBIT_S32_LE,
498 },
499 .ops = &max9860_dai_ops,
500 .symmetric_rates = 1,
501};
502
503static int max9860_set_bias_level(struct snd_soc_codec *codec,
504 enum snd_soc_bias_level level)
505{
506 struct max9860_priv *max9860 = dev_get_drvdata(codec->dev);
507 int ret;
508
509 switch (level) {
510 case SND_SOC_BIAS_ON:
511 case SND_SOC_BIAS_PREPARE:
512 break;
513
514 case SND_SOC_BIAS_STANDBY:
515 ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
516 MAX9860_SHDN, MAX9860_SHDN);
517 if (ret) {
518 dev_err(codec->dev, "Failed to remove SHDN: %d\n", ret);
519 return ret;
520 }
521 break;
522
523 case SND_SOC_BIAS_OFF:
524 ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
525 MAX9860_SHDN, 0);
526 if (ret) {
527 dev_err(codec->dev, "Failed to request SHDN: %d\n",
528 ret);
529 return ret;
530 }
531 break;
532 }
533
534 return 0;
535}
536
537static struct snd_soc_codec_driver max9860_codec_driver = {
538 .set_bias_level = max9860_set_bias_level,
539 .idle_bias_off = true,
540
541 .controls = max9860_controls,
542 .num_controls = ARRAY_SIZE(max9860_controls),
543 .dapm_widgets = max9860_dapm_widgets,
544 .num_dapm_widgets = ARRAY_SIZE(max9860_dapm_widgets),
545 .dapm_routes = max9860_dapm_routes,
546 .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes),
547};
548
549#ifdef CONFIG_PM
550static int max9860_suspend(struct device *dev)
551{
552 struct max9860_priv *max9860 = dev_get_drvdata(dev);
553 int ret;
554
555 ret = regmap_update_bits(max9860->regmap, MAX9860_SYSCLK,
556 MAX9860_PSCLK, MAX9860_PSCLK_OFF);
557 if (ret) {
558 dev_err(dev, "Failed to disable clock: %d\n", ret);
559 return ret;
560 }
561
562 regulator_disable(max9860->dvddio);
563
564 return 0;
565}
566
567static int max9860_resume(struct device *dev)
568{
569 struct max9860_priv *max9860 = dev_get_drvdata(dev);
570 int ret;
571
572 ret = regulator_enable(max9860->dvddio);
573 if (ret) {
574 dev_err(dev, "Failed to enable DVDDIO: %d\n", ret);
575 return ret;
576 }
577
578 regcache_cache_only(max9860->regmap, false);
579 ret = regcache_sync(max9860->regmap);
580 if (ret) {
581 dev_err(dev, "Failed to sync cache: %d\n", ret);
582 return ret;
583 }
584
585 ret = regmap_update_bits(max9860->regmap, MAX9860_SYSCLK,
586 MAX9860_PSCLK, max9860->psclk);
587 if (ret) {
588 dev_err(dev, "Failed to enable clock: %d\n", ret);
589 return ret;
590 }
591
592 return 0;
593}
594#endif
595
596static const struct dev_pm_ops max9860_pm_ops = {
597 SET_RUNTIME_PM_OPS(max9860_suspend, max9860_resume, NULL)
598};
599
600static int max9860_probe(struct i2c_client *i2c,
601 const struct i2c_device_id *id)
602{
603 struct device *dev = &i2c->dev;
604 struct max9860_priv *max9860;
605 int ret;
606 struct clk *mclk;
607 unsigned long mclk_rate;
608 int i;
609 int intr;
610
611 max9860 = devm_kzalloc(dev, sizeof(struct max9860_priv), GFP_KERNEL);
612 if (!max9860)
613 return -ENOMEM;
614
615 max9860->dvddio = devm_regulator_get(dev, "DVDDIO");
616 if (IS_ERR(max9860->dvddio)) {
617 ret = PTR_ERR(max9860->dvddio);
618 if (ret != -EPROBE_DEFER)
619 dev_err(dev, "Failed to get DVDDIO supply: %d\n", ret);
620 return ret;
621 }
622
623 max9860->dvddio_nb.notifier_call = max9860_dvddio_event;
624
625 ret = regulator_register_notifier(max9860->dvddio, &max9860->dvddio_nb);
626 if (ret)
627 dev_err(dev, "Failed to register DVDDIO notifier: %d\n", ret);
628
629 ret = regulator_enable(max9860->dvddio);
630 if (ret != 0) {
631 dev_err(dev, "Failed to enable DVDDIO: %d\n", ret);
632 return ret;
633 }
634
635 max9860->regmap = devm_regmap_init_i2c(i2c, &max9860_regmap);
636 if (IS_ERR(max9860->regmap)) {
637 ret = PTR_ERR(max9860->regmap);
638 goto err_regulator;
639 }
640
641 dev_set_drvdata(dev, max9860);
642
643 /*
644 * mclk has to be in the 10MHz to 60MHz range.
645 * psclk is used to scale mclk into pclk so that
646 * pclk is in the 10MHz to 20MHz range.
647 */
648 mclk = clk_get(dev, "mclk");
649
650 if (IS_ERR(mclk)) {
651 ret = PTR_ERR(mclk);
652 if (ret != -EPROBE_DEFER)
653 dev_err(dev, "Failed to get MCLK: %d\n", ret);
654 goto err_regulator;
655 }
656
657 mclk_rate = clk_get_rate(mclk);
658 clk_put(mclk);
659
660 if (mclk_rate > 60000000 || mclk_rate < 10000000) {
661 dev_err(dev, "Bad mclk %luHz (needs 10MHz - 60MHz)\n",
662 mclk_rate);
663 ret = -EINVAL;
664 goto err_regulator;
665 }
666 if (mclk_rate >= 40000000)
667 max9860->psclk = 3;
668 else if (mclk_rate >= 20000000)
669 max9860->psclk = 2;
670 else
671 max9860->psclk = 1;
672 max9860->pclk_rate = mclk_rate >> (max9860->psclk - 1);
673 max9860->psclk <<= MAX9860_PSCLK_SHIFT;
674 dev_dbg(dev, "mclk %lu pclk %lu\n", mclk_rate, max9860->pclk_rate);
675
676 regcache_cache_bypass(max9860->regmap, true);
677 for (i = 0; i < max9860_regmap.num_reg_defaults; ++i) {
678 ret = regmap_write(max9860->regmap,
679 max9860_regmap.reg_defaults[i].reg,
680 max9860_regmap.reg_defaults[i].def);
681 if (ret) {
682 dev_err(dev, "Failed to initialize register %u: %d\n",
683 max9860_regmap.reg_defaults[i].reg, ret);
684 goto err_regulator;
685 }
686 }
687 regcache_cache_bypass(max9860->regmap, false);
688
689 ret = regmap_read(max9860->regmap, MAX9860_INTRSTATUS, &intr);
690 if (ret) {
691 dev_err(dev, "Failed to clear INTRSTATUS: %d\n", ret);
692 goto err_regulator;
693 }
694
695 pm_runtime_set_active(dev);
696 pm_runtime_enable(dev);
697 pm_runtime_idle(dev);
698
699 ret = snd_soc_register_codec(dev, &max9860_codec_driver,
700 &max9860_dai, 1);
701 if (ret) {
702 dev_err(dev, "Failed to register CODEC: %d\n", ret);
703 goto err_pm;
704 }
705
706 return 0;
707
708err_pm:
709 pm_runtime_disable(dev);
710err_regulator:
711 regulator_disable(max9860->dvddio);
712 return ret;
713}
714
715static int max9860_remove(struct i2c_client *i2c)
716{
717 struct device *dev = &i2c->dev;
718 struct max9860_priv *max9860 = dev_get_drvdata(dev);
719
720 snd_soc_unregister_codec(dev);
721 pm_runtime_disable(dev);
722 regulator_disable(max9860->dvddio);
723 return 0;
724}
725
726static const struct i2c_device_id max9860_i2c_id[] = {
727 { "max9860", },
728 { }
729};
730MODULE_DEVICE_TABLE(i2c, max9860_i2c_id);
731
732static const struct of_device_id max9860_of_match[] = {
733 { .compatible = "maxim,max9860", },
734 { }
735};
736MODULE_DEVICE_TABLE(of, max9860_of_match);
737
738static struct i2c_driver max9860_i2c_driver = {
739 .probe = max9860_probe,
740 .remove = max9860_remove,
741 .id_table = max9860_i2c_id,
742 .driver = {
743 .name = "max9860",
744 .of_match_table = max9860_of_match,
745 .pm = &max9860_pm_ops,
746 },
747};
748
749module_i2c_driver(max9860_i2c_driver);
750
751MODULE_DESCRIPTION("ASoC MAX9860 Mono Audio Voice Codec driver");
752MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
753MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/max9860.h b/sound/soc/codecs/max9860.h
new file mode 100644
index 000000000000..22041bd67a7d
--- /dev/null
+++ b/sound/soc/codecs/max9860.h
@@ -0,0 +1,162 @@
1/*
2 * Driver for the MAX9860 Mono Audio Voice Codec
3 *
4 * Author: Peter Rosin <peda@axentia.s>
5 * Copyright 2016 Axentia Technologies
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#ifndef _SND_SOC_MAX9860
18#define _SND_SOC_MAX9860
19
20#define MAX9860_INTRSTATUS 0x00
21#define MAX9860_MICREADBACK 0x01
22#define MAX9860_INTEN 0x02
23#define MAX9860_SYSCLK 0x03
24#define MAX9860_AUDIOCLKHIGH 0x04
25#define MAX9860_AUDIOCLKLOW 0x05
26#define MAX9860_IFC1A 0x06
27#define MAX9860_IFC1B 0x07
28#define MAX9860_VOICEFLTR 0x08
29#define MAX9860_DACATTN 0x09
30#define MAX9860_ADCLEVEL 0x0a
31#define MAX9860_DACGAIN 0x0b
32#define MAX9860_MICGAIN 0x0c
33#define MAX9860_RESERVED 0x0d
34#define MAX9860_MICADC 0x0e
35#define MAX9860_NOISEGATE 0x0f
36#define MAX9860_PWRMAN 0x10
37#define MAX9860_REVISION 0xff
38
39#define MAX9860_MAX_REGISTER 0xff
40
41/* INTRSTATUS */
42#define MAX9860_CLD 0x80
43#define MAX9860_SLD 0x40
44#define MAX9860_ULK 0x20
45
46/* MICREADBACK */
47#define MAX9860_NG 0xe0
48#define MAX9860_AGC 0x1f
49
50/* INTEN */
51#define MAX9860_ICLD 0x80
52#define MAX9860_ISLD 0x40
53#define MAX9860_IULK 0x20
54
55/* SYSCLK */
56#define MAX9860_PSCLK 0x30
57#define MAX9860_PSCLK_OFF 0x00
58#define MAX9860_PSCLK_SHIFT 4
59#define MAX9860_FREQ 0x06
60#define MAX9860_FREQ_NORMAL 0x00
61#define MAX9860_FREQ_12MHZ 0x02
62#define MAX9860_FREQ_13MHZ 0x04
63#define MAX9860_FREQ_19_2MHZ 0x06
64#define MAX9860_16KHZ 0x01
65
66/* AUDIOCLKHIGH */
67#define MAX9860_PLL 0x80
68#define MAX9860_NHI 0x7f
69
70/* AUDIOCLKLOW */
71#define MAX9860_NLO 0xff
72
73/* IFC1A */
74#define MAX9860_MASTER 0x80
75#define MAX9860_WCI 0x40
76#define MAX9860_DBCI 0x20
77#define MAX9860_DDLY 0x10
78#define MAX9860_HIZ 0x08
79#define MAX9860_TDM 0x04
80
81/* IFC1B */
82#define MAX9860_ABCI 0x20
83#define MAX9860_ADLY 0x10
84#define MAX9860_ST 0x08
85#define MAX9860_BSEL 0x07
86#define MAX9860_BSEL_OFF 0x00
87#define MAX9860_BSEL_64X 0x01
88#define MAX9860_BSEL_48X 0x02
89#define MAX9860_BSEL_PCLK_2 0x04
90#define MAX9860_BSEL_PCLK_4 0x05
91#define MAX9860_BSEL_PCLK_8 0x06
92#define MAX9860_BSEL_PCLK_16 0x07
93
94/* VOICEFLTR */
95#define MAX9860_AVFLT 0xf0
96#define MAX9860_AVFLT_SHIFT 4
97#define MAX9860_AVFLT_COUNT 6
98#define MAX9860_DVFLT 0x0f
99#define MAX9860_DVFLT_SHIFT 0
100#define MAX9860_DVFLT_COUNT 6
101
102/* DACATTN */
103#define MAX9860_DVA 0xfe
104#define MAX9860_DVA_SHIFT 1
105#define MAX9860_DVA_MUTE 0x5e
106
107/* ADCLEVEL */
108#define MAX9860_ADCRL 0xf0
109#define MAX9860_ADCRL_SHIFT 4
110#define MAX9860_ADCLL 0x0f
111#define MAX9860_ADCLL_SHIFT 0
112#define MAX9860_ADCxL_MIN 15
113
114/* DACGAIN */
115#define MAX9860_DVG 0x60
116#define MAX9860_DVG_SHIFT 5
117#define MAX9860_DVG_MAX 3
118#define MAX9860_DVST 0x1f
119#define MAX9860_DVST_SHIFT 0
120#define MAX9860_DVST_MIN 31
121
122/* MICGAIN */
123#define MAX9860_PAM 0x60
124#define MAX9860_PAM_SHIFT 5
125#define MAX9860_PAM_MAX 3
126#define MAX9860_PGAM 0x1f
127#define MAX9860_PGAM_SHIFT 0
128#define MAX9860_PGAM_MIN 20
129
130/* MICADC */
131#define MAX9860_AGCSRC 0x80
132#define MAX9860_AGCSRC_SHIFT 7
133#define MAX9860_AGCSRC_COUNT 2
134#define MAX9860_AGCRLS 0x70
135#define MAX9860_AGCRLS_SHIFT 4
136#define MAX9860_AGCRLS_COUNT 8
137#define MAX9860_AGCATK 0x0c
138#define MAX9860_AGCATK_SHIFT 2
139#define MAX9860_AGCATK_COUNT 4
140#define MAX9860_AGCHLD 0x03
141#define MAX9860_AGCHLD_OFF 0x00
142#define MAX9860_AGCHLD_SHIFT 0
143#define MAX9860_AGCHLD_COUNT 4
144
145/* NOISEGATE */
146#define MAX9860_ANTH 0xf0
147#define MAX9860_ANTH_SHIFT 4
148#define MAX9860_ANTH_MAX 15
149#define MAX9860_AGCTH 0x0f
150#define MAX9860_AGCTH_SHIFT 0
151#define MAX9860_AGCTH_MIN 15
152
153/* PWRMAN */
154#define MAX9860_SHDN 0x80
155#define MAX9860_DACEN 0x08
156#define MAX9860_DACEN_SHIFT 3
157#define MAX9860_ADCLEN 0x02
158#define MAX9860_ADCLEN_SHIFT 1
159#define MAX9860_ADCREN 0x01
160#define MAX9860_ADCREN_SHIFT 0
161
162#endif /* _SND_SOC_MAX9860 */
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c
index 2a22fddeb6af..2a22fddeb6af 100755..100644
--- a/sound/soc/codecs/max9867.c
+++ b/sound/soc/codecs/max9867.c
diff --git a/sound/soc/codecs/max9867.h b/sound/soc/codecs/max9867.h
index 65590b4ad62a..65590b4ad62a 100755..100644
--- a/sound/soc/codecs/max9867.h
+++ b/sound/soc/codecs/max9867.h
diff --git a/sound/soc/codecs/max9877.h b/sound/soc/codecs/max9877.h
index 6da72290ac58..368343f29dd0 100644
--- a/sound/soc/codecs/max9877.h
+++ b/sound/soc/codecs/max9877.h
@@ -32,6 +32,4 @@
32#define MAX9877_BYPASS (1 << 6) 32#define MAX9877_BYPASS (1 << 6)
33#define MAX9877_SHDN (1 << 7) 33#define MAX9877_SHDN (1 << 7)
34 34
35extern int max9877_add_controls(struct snd_soc_codec *codec);
36
37#endif 35#endif
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index 683769f0f246..5c9707ac4bbf 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -18,6 +18,7 @@
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/acpi.h> 19#include <linux/acpi.h>
20#include <linux/math64.h> 20#include <linux/math64.h>
21#include <linux/semaphore.h>
21 22
22#include <sound/initval.h> 23#include <sound/initval.h>
23#include <sound/tlv.h> 24#include <sound/tlv.h>
@@ -30,10 +31,22 @@
30 31
31#include "nau8825.h" 32#include "nau8825.h"
32 33
34
35#define NUVOTON_CODEC_DAI "nau8825-hifi"
36
33#define NAU_FREF_MAX 13500000 37#define NAU_FREF_MAX 13500000
34#define NAU_FVCO_MAX 100000000 38#define NAU_FVCO_MAX 124000000
35#define NAU_FVCO_MIN 90000000 39#define NAU_FVCO_MIN 90000000
36 40
41/* cross talk suppression detection */
42#define LOG10_MAGIC 646456993
43#define GAIN_AUGMENT 22500
44#define SIDETONE_BASE 207000
45
46
47static int nau8825_configure_sysclk(struct nau8825 *nau8825,
48 int clk_id, unsigned int freq);
49
37struct nau8825_fll { 50struct nau8825_fll {
38 int mclk_src; 51 int mclk_src;
39 int ratio; 52 int ratio;
@@ -156,6 +169,661 @@ static const struct reg_default nau8825_reg_defaults[] = {
156 { NAU8825_REG_CHARGE_PUMP, 0x0 }, 169 { NAU8825_REG_CHARGE_PUMP, 0x0 },
157}; 170};
158 171
172/* register backup table when cross talk detection */
173static struct reg_default nau8825_xtalk_baktab[] = {
174 { NAU8825_REG_ADC_DGAIN_CTRL, 0 },
175 { NAU8825_REG_HSVOL_CTRL, 0 },
176 { NAU8825_REG_DACL_CTRL, 0 },
177 { NAU8825_REG_DACR_CTRL, 0 },
178};
179
180static const unsigned short logtable[256] = {
181 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,
182 0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508,
183 0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6,
184 0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37,
185 0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f,
186 0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41,
187 0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1,
188 0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142,
189 0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68,
190 0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355,
191 0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c,
192 0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490,
193 0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3,
194 0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507,
195 0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe,
196 0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca,
197 0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c,
198 0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7,
199 0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c,
200 0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c,
201 0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a,
202 0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065,
203 0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730,
204 0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc,
205 0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469,
206 0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9,
207 0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c,
208 0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765,
209 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83,
210 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387,
211 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973,
212 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47
213};
214
215static struct snd_soc_dai *nau8825_get_codec_dai(struct nau8825 *nau8825)
216{
217 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(nau8825->dapm);
218 struct snd_soc_component *component = &codec->component;
219 struct snd_soc_dai *codec_dai, *_dai;
220
221 list_for_each_entry_safe(codec_dai, _dai, &component->dai_list, list) {
222 if (!strncmp(codec_dai->name, NUVOTON_CODEC_DAI,
223 strlen(NUVOTON_CODEC_DAI)))
224 return codec_dai;
225 }
226 return NULL;
227}
228
229static bool nau8825_dai_is_active(struct nau8825 *nau8825)
230{
231 struct snd_soc_dai *codec_dai = nau8825_get_codec_dai(nau8825);
232
233 if (codec_dai) {
234 if (codec_dai->playback_active || codec_dai->capture_active)
235 return true;
236 }
237 return false;
238}
239
240/**
241 * nau8825_sema_acquire - acquire the semaphore of nau88l25
242 * @nau8825: component to register the codec private data with
243 * @timeout: how long in jiffies to wait before failure or zero to wait
244 * until release
245 *
246 * Attempts to acquire the semaphore with number of jiffies. If no more
247 * tasks are allowed to acquire the semaphore, calling this function will
248 * put the task to sleep. If the semaphore is not released within the
249 * specified number of jiffies, this function returns.
250 * Acquires the semaphore without jiffies. If no more tasks are allowed
251 * to acquire the semaphore, calling this function will put the task to
252 * sleep until the semaphore is released.
253 * It returns if the semaphore was acquired.
254 */
255static void nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
256{
257 int ret;
258
259 if (timeout)
260 ret = down_timeout(&nau8825->xtalk_sem, timeout);
261 else
262 ret = down_interruptible(&nau8825->xtalk_sem);
263
264 if (ret < 0)
265 dev_warn(nau8825->dev, "Acquire semaphone fail\n");
266}
267
268/**
269 * nau8825_sema_release - release the semaphore of nau88l25
270 * @nau8825: component to register the codec private data with
271 *
272 * Release the semaphore which may be called from any context and
273 * even by tasks which have never called down().
274 */
275static inline void nau8825_sema_release(struct nau8825 *nau8825)
276{
277 up(&nau8825->xtalk_sem);
278}
279
280/**
281 * nau8825_sema_reset - reset the semaphore for nau88l25
282 * @nau8825: component to register the codec private data with
283 *
284 * Reset the counter of the semaphore. Call this function to restart
285 * a new round task management.
286 */
287static inline void nau8825_sema_reset(struct nau8825 *nau8825)
288{
289 nau8825->xtalk_sem.count = 1;
290}
291
292/**
293 * Ramp up the headphone volume change gradually to target level.
294 *
295 * @nau8825: component to register the codec private data with
296 * @vol_from: the volume to start up
297 * @vol_to: the target volume
298 * @step: the volume span to move on
299 *
300 * The headphone volume is from 0dB to minimum -54dB and -1dB per step.
301 * If the volume changes sharp, there is a pop noise heard in headphone. We
302 * provide the function to ramp up the volume up or down by delaying 10ms
303 * per step.
304 */
305static void nau8825_hpvol_ramp(struct nau8825 *nau8825,
306 unsigned int vol_from, unsigned int vol_to, unsigned int step)
307{
308 unsigned int value, volume, ramp_up, from, to;
309
310 if (vol_from == vol_to || step == 0) {
311 return;
312 } else if (vol_from < vol_to) {
313 ramp_up = true;
314 from = vol_from;
315 to = vol_to;
316 } else {
317 ramp_up = false;
318 from = vol_to;
319 to = vol_from;
320 }
321 /* only handle volume from 0dB to minimum -54dB */
322 if (to > NAU8825_HP_VOL_MIN)
323 to = NAU8825_HP_VOL_MIN;
324
325 for (volume = from; volume < to; volume += step) {
326 if (ramp_up)
327 value = volume;
328 else
329 value = to - volume + from;
330 regmap_update_bits(nau8825->regmap, NAU8825_REG_HSVOL_CTRL,
331 NAU8825_HPL_VOL_MASK | NAU8825_HPR_VOL_MASK,
332 (value << NAU8825_HPL_VOL_SFT) | value);
333 usleep_range(10000, 10500);
334 }
335 if (ramp_up)
336 value = to;
337 else
338 value = from;
339 regmap_update_bits(nau8825->regmap, NAU8825_REG_HSVOL_CTRL,
340 NAU8825_HPL_VOL_MASK | NAU8825_HPR_VOL_MASK,
341 (value << NAU8825_HPL_VOL_SFT) | value);
342}
343
344/**
345 * Computes log10 of a value; the result is round off to 3 decimal. This func-
346 * tion takes reference to dvb-math. The source code locates as the following.
347 * Linux/drivers/media/dvb-core/dvb_math.c
348 *
349 * return log10(value) * 1000
350 */
351static u32 nau8825_intlog10_dec3(u32 value)
352{
353 u32 msb, logentry, significand, interpolation, log10val;
354 u64 log2val;
355
356 /* first detect the msb (count begins at 0) */
357 msb = fls(value) - 1;
358 /**
359 * now we use a logtable after the following method:
360 *
361 * log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24
362 * where x = msb and therefore 1 <= y < 2
363 * first y is determined by shifting the value left
364 * so that msb is bit 31
365 * 0x00231f56 -> 0x8C7D5800
366 * the result is y * 2^31 -> "significand"
367 * then the highest 9 bits are used for a table lookup
368 * the highest bit is discarded because it's always set
369 * the highest nine bits in our example are 100011000
370 * so we would use the entry 0x18
371 */
372 significand = value << (31 - msb);
373 logentry = (significand >> 23) & 0xff;
374 /**
375 * last step we do is interpolation because of the
376 * limitations of the log table the error is that part of
377 * the significand which isn't used for lookup then we
378 * compute the ratio between the error and the next table entry
379 * and interpolate it between the log table entry used and the
380 * next one the biggest error possible is 0x7fffff
381 * (in our example it's 0x7D5800)
382 * needed value for next table entry is 0x800000
383 * so the interpolation is
384 * (error / 0x800000) * (logtable_next - logtable_current)
385 * in the implementation the division is moved to the end for
386 * better accuracy there is also an overflow correction if
387 * logtable_next is 256
388 */
389 interpolation = ((significand & 0x7fffff) *
390 ((logtable[(logentry + 1) & 0xff] -
391 logtable[logentry]) & 0xffff)) >> 15;
392
393 log2val = ((msb << 24) + (logtable[logentry] << 8) + interpolation);
394 /**
395 * log10(x) = log2(x) * log10(2)
396 */
397 log10val = (log2val * LOG10_MAGIC) >> 31;
398 /**
399 * the result is round off to 3 decimal
400 */
401 return log10val / ((1 << 24) / 1000);
402}
403
404/**
405 * computes cross talk suppression sidetone gain.
406 *
407 * @sig_org: orignal signal level
408 * @sig_cros: cross talk signal level
409 *
410 * The orignal and cross talk signal vlues need to be characterized.
411 * Once these values have been characterized, this sidetone value
412 * can be converted to decibel with the equation below.
413 * sidetone = 20 * log (original signal level / crosstalk signal level)
414 *
415 * return cross talk sidetone gain
416 */
417static u32 nau8825_xtalk_sidetone(u32 sig_org, u32 sig_cros)
418{
419 u32 gain, sidetone;
420
421 if (unlikely(sig_org == 0) || unlikely(sig_cros == 0)) {
422 WARN_ON(1);
423 return 0;
424 }
425
426 sig_org = nau8825_intlog10_dec3(sig_org);
427 sig_cros = nau8825_intlog10_dec3(sig_cros);
428 if (sig_org >= sig_cros)
429 gain = (sig_org - sig_cros) * 20 + GAIN_AUGMENT;
430 else
431 gain = (sig_cros - sig_org) * 20 + GAIN_AUGMENT;
432 sidetone = SIDETONE_BASE - gain * 2;
433 sidetone /= 1000;
434
435 return sidetone;
436}
437
438static int nau8825_xtalk_baktab_index_by_reg(unsigned int reg)
439{
440 int index;
441
442 for (index = 0; index < ARRAY_SIZE(nau8825_xtalk_baktab); index++)
443 if (nau8825_xtalk_baktab[index].reg == reg)
444 return index;
445 return -EINVAL;
446}
447
448static void nau8825_xtalk_backup(struct nau8825 *nau8825)
449{
450 int i;
451
452 /* Backup some register values to backup table */
453 for (i = 0; i < ARRAY_SIZE(nau8825_xtalk_baktab); i++)
454 regmap_read(nau8825->regmap, nau8825_xtalk_baktab[i].reg,
455 &nau8825_xtalk_baktab[i].def);
456}
457
458static void nau8825_xtalk_restore(struct nau8825 *nau8825)
459{
460 int i, volume;
461
462 /* Restore register values from backup table; When the driver restores
463 * the headphone volumem, it needs recover to original level gradually
464 * with 3dB per step for less pop noise.
465 */
466 for (i = 0; i < ARRAY_SIZE(nau8825_xtalk_baktab); i++) {
467 if (nau8825_xtalk_baktab[i].reg == NAU8825_REG_HSVOL_CTRL) {
468 /* Ramping up the volume change to reduce pop noise */
469 volume = nau8825_xtalk_baktab[i].def &
470 NAU8825_HPR_VOL_MASK;
471 nau8825_hpvol_ramp(nau8825, 0, volume, 3);
472 continue;
473 }
474 regmap_write(nau8825->regmap, nau8825_xtalk_baktab[i].reg,
475 nau8825_xtalk_baktab[i].def);
476 }
477}
478
479static void nau8825_xtalk_prepare_dac(struct nau8825 *nau8825)
480{
481 /* Enable power of DAC path */
482 regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL,
483 NAU8825_ENABLE_DACR | NAU8825_ENABLE_DACL |
484 NAU8825_ENABLE_ADC | NAU8825_ENABLE_ADC_CLK |
485 NAU8825_ENABLE_DAC_CLK, NAU8825_ENABLE_DACR |
486 NAU8825_ENABLE_DACL | NAU8825_ENABLE_ADC |
487 NAU8825_ENABLE_ADC_CLK | NAU8825_ENABLE_DAC_CLK);
488 /* Prevent startup click by letting charge pump to ramp up and
489 * change bump enable
490 */
491 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
492 NAU8825_JAMNODCLOW | NAU8825_CHANRGE_PUMP_EN,
493 NAU8825_JAMNODCLOW | NAU8825_CHANRGE_PUMP_EN);
494 /* Enable clock sync of DAC and DAC clock */
495 regmap_update_bits(nau8825->regmap, NAU8825_REG_RDAC,
496 NAU8825_RDAC_EN | NAU8825_RDAC_CLK_EN |
497 NAU8825_RDAC_FS_BCLK_ENB,
498 NAU8825_RDAC_EN | NAU8825_RDAC_CLK_EN);
499 /* Power up output driver with 2 stage */
500 regmap_update_bits(nau8825->regmap, NAU8825_REG_POWER_UP_CONTROL,
501 NAU8825_POWERUP_INTEGR_R | NAU8825_POWERUP_INTEGR_L |
502 NAU8825_POWERUP_DRV_IN_R | NAU8825_POWERUP_DRV_IN_L,
503 NAU8825_POWERUP_INTEGR_R | NAU8825_POWERUP_INTEGR_L |
504 NAU8825_POWERUP_DRV_IN_R | NAU8825_POWERUP_DRV_IN_L);
505 regmap_update_bits(nau8825->regmap, NAU8825_REG_POWER_UP_CONTROL,
506 NAU8825_POWERUP_HP_DRV_R | NAU8825_POWERUP_HP_DRV_L,
507 NAU8825_POWERUP_HP_DRV_R | NAU8825_POWERUP_HP_DRV_L);
508 /* HP outputs not shouted to ground */
509 regmap_update_bits(nau8825->regmap, NAU8825_REG_HSD_CTRL,
510 NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L, 0);
511 /* Enable HP boost driver */
512 regmap_update_bits(nau8825->regmap, NAU8825_REG_BOOST,
513 NAU8825_HP_BOOST_DIS, NAU8825_HP_BOOST_DIS);
514 /* Enable class G compare path to supply 1.8V or 0.9V. */
515 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLASSG_CTRL,
516 NAU8825_CLASSG_LDAC_EN | NAU8825_CLASSG_RDAC_EN,
517 NAU8825_CLASSG_LDAC_EN | NAU8825_CLASSG_RDAC_EN);
518}
519
520static void nau8825_xtalk_prepare_adc(struct nau8825 *nau8825)
521{
522 /* Power up left ADC and raise 5dB than Vmid for Vref */
523 regmap_update_bits(nau8825->regmap, NAU8825_REG_ANALOG_ADC_2,
524 NAU8825_POWERUP_ADCL | NAU8825_ADC_VREFSEL_MASK,
525 NAU8825_POWERUP_ADCL | NAU8825_ADC_VREFSEL_VMID_PLUS_0_5DB);
526}
527
528static void nau8825_xtalk_clock(struct nau8825 *nau8825)
529{
530 /* Recover FLL default value */
531 regmap_write(nau8825->regmap, NAU8825_REG_FLL1, 0x0);
532 regmap_write(nau8825->regmap, NAU8825_REG_FLL2, 0x3126);
533 regmap_write(nau8825->regmap, NAU8825_REG_FLL3, 0x0008);
534 regmap_write(nau8825->regmap, NAU8825_REG_FLL4, 0x0010);
535 regmap_write(nau8825->regmap, NAU8825_REG_FLL5, 0x0);
536 regmap_write(nau8825->regmap, NAU8825_REG_FLL6, 0x6000);
537 /* Enable internal VCO clock for detection signal generated */
538 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
539 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_VCO);
540 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL6, NAU8825_DCO_EN,
541 NAU8825_DCO_EN);
542 /* Given specific clock frequency of internal clock to
543 * generate signal.
544 */
545 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
546 NAU8825_CLK_MCLK_SRC_MASK, 0xf);
547 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL1,
548 NAU8825_FLL_RATIO_MASK, 0x10);
549}
550
551static void nau8825_xtalk_prepare(struct nau8825 *nau8825)
552{
553 int volume, index;
554
555 /* Backup those registers changed by cross talk detection */
556 nau8825_xtalk_backup(nau8825);
557 /* Config IIS as master to output signal by codec */
558 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
559 NAU8825_I2S_MS_MASK | NAU8825_I2S_DRV_MASK |
560 NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_MASTER |
561 (0x2 << NAU8825_I2S_DRV_SFT) | 0x1);
562 /* Ramp up headphone volume to 0dB to get better performance and
563 * avoid pop noise in headphone.
564 */
565 index = nau8825_xtalk_baktab_index_by_reg(NAU8825_REG_HSVOL_CTRL);
566 if (index != -EINVAL) {
567 volume = nau8825_xtalk_baktab[index].def &
568 NAU8825_HPR_VOL_MASK;
569 nau8825_hpvol_ramp(nau8825, volume, 0, 3);
570 }
571 nau8825_xtalk_clock(nau8825);
572 nau8825_xtalk_prepare_dac(nau8825);
573 nau8825_xtalk_prepare_adc(nau8825);
574 /* Config channel path and digital gain */
575 regmap_update_bits(nau8825->regmap, NAU8825_REG_DACL_CTRL,
576 NAU8825_DACL_CH_SEL_MASK | NAU8825_DACL_CH_VOL_MASK,
577 NAU8825_DACL_CH_SEL_L | 0xab);
578 regmap_update_bits(nau8825->regmap, NAU8825_REG_DACR_CTRL,
579 NAU8825_DACR_CH_SEL_MASK | NAU8825_DACR_CH_VOL_MASK,
580 NAU8825_DACR_CH_SEL_R | 0xab);
581 /* Config cross talk parameters and generate the 23Hz sine wave with
582 * 1/16 full scale of signal level for impedance measurement.
583 */
584 regmap_update_bits(nau8825->regmap, NAU8825_REG_IMM_MODE_CTRL,
585 NAU8825_IMM_THD_MASK | NAU8825_IMM_GEN_VOL_MASK |
586 NAU8825_IMM_CYC_MASK | NAU8825_IMM_DAC_SRC_MASK,
587 (0x9 << NAU8825_IMM_THD_SFT) | NAU8825_IMM_GEN_VOL_1_16th |
588 NAU8825_IMM_CYC_8192 | NAU8825_IMM_DAC_SRC_SIN);
589 /* RMS intrruption enable */
590 regmap_update_bits(nau8825->regmap,
591 NAU8825_REG_INTERRUPT_MASK, NAU8825_IRQ_RMS_EN, 0);
592 /* Power up left and right DAC */
593 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
594 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL, 0);
595}
596
597static void nau8825_xtalk_clean_dac(struct nau8825 *nau8825)
598{
599 /* Disable HP boost driver */
600 regmap_update_bits(nau8825->regmap, NAU8825_REG_BOOST,
601 NAU8825_HP_BOOST_DIS, 0);
602 /* HP outputs shouted to ground */
603 regmap_update_bits(nau8825->regmap, NAU8825_REG_HSD_CTRL,
604 NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L,
605 NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L);
606 /* Power down left and right DAC */
607 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
608 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL,
609 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL);
610 /* Enable the TESTDAC and disable L/R HP impedance */
611 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
612 NAU8825_BIAS_HPR_IMP | NAU8825_BIAS_HPL_IMP |
613 NAU8825_BIAS_TESTDAC_EN, NAU8825_BIAS_TESTDAC_EN);
614 /* Power down output driver with 2 stage */
615 regmap_update_bits(nau8825->regmap, NAU8825_REG_POWER_UP_CONTROL,
616 NAU8825_POWERUP_HP_DRV_R | NAU8825_POWERUP_HP_DRV_L, 0);
617 regmap_update_bits(nau8825->regmap, NAU8825_REG_POWER_UP_CONTROL,
618 NAU8825_POWERUP_INTEGR_R | NAU8825_POWERUP_INTEGR_L |
619 NAU8825_POWERUP_DRV_IN_R | NAU8825_POWERUP_DRV_IN_L, 0);
620 /* Disable clock sync of DAC and DAC clock */
621 regmap_update_bits(nau8825->regmap, NAU8825_REG_RDAC,
622 NAU8825_RDAC_EN | NAU8825_RDAC_CLK_EN, 0);
623 /* Disable charge pump ramp up function and change bump */
624 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
625 NAU8825_JAMNODCLOW | NAU8825_CHANRGE_PUMP_EN, 0);
626 /* Disable power of DAC path */
627 regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL,
628 NAU8825_ENABLE_DACR | NAU8825_ENABLE_DACL |
629 NAU8825_ENABLE_ADC_CLK | NAU8825_ENABLE_DAC_CLK, 0);
630 if (!nau8825->irq)
631 regmap_update_bits(nau8825->regmap,
632 NAU8825_REG_ENA_CTRL, NAU8825_ENABLE_ADC, 0);
633}
634
635static void nau8825_xtalk_clean_adc(struct nau8825 *nau8825)
636{
637 /* Power down left ADC and restore voltage to Vmid */
638 regmap_update_bits(nau8825->regmap, NAU8825_REG_ANALOG_ADC_2,
639 NAU8825_POWERUP_ADCL | NAU8825_ADC_VREFSEL_MASK, 0);
640}
641
642static void nau8825_xtalk_clean(struct nau8825 *nau8825)
643{
644 /* Enable internal VCO needed for interruptions */
645 nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0);
646 nau8825_xtalk_clean_dac(nau8825);
647 nau8825_xtalk_clean_adc(nau8825);
648 /* Clear cross talk parameters and disable */
649 regmap_write(nau8825->regmap, NAU8825_REG_IMM_MODE_CTRL, 0);
650 /* RMS intrruption disable */
651 regmap_update_bits(nau8825->regmap, NAU8825_REG_INTERRUPT_MASK,
652 NAU8825_IRQ_RMS_EN, NAU8825_IRQ_RMS_EN);
653 /* Recover default value for IIS */
654 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
655 NAU8825_I2S_MS_MASK | NAU8825_I2S_DRV_MASK |
656 NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_SLAVE);
657 /* Restore value of specific register for cross talk */
658 nau8825_xtalk_restore(nau8825);
659}
660
661static void nau8825_xtalk_imm_start(struct nau8825 *nau8825, int vol)
662{
663 /* Apply ADC volume for better cross talk performance */
664 regmap_update_bits(nau8825->regmap, NAU8825_REG_ADC_DGAIN_CTRL,
665 NAU8825_ADC_DIG_VOL_MASK, vol);
666 /* Disables JKTIP(HPL) DAC channel for right to left measurement.
667 * Do it before sending signal in order to erase pop noise.
668 */
669 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
670 NAU8825_BIAS_TESTDACR_EN | NAU8825_BIAS_TESTDACL_EN,
671 NAU8825_BIAS_TESTDACL_EN);
672 switch (nau8825->xtalk_state) {
673 case NAU8825_XTALK_HPR_R2L:
674 /* Enable right headphone impedance */
675 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
676 NAU8825_BIAS_HPR_IMP | NAU8825_BIAS_HPL_IMP,
677 NAU8825_BIAS_HPR_IMP);
678 break;
679 case NAU8825_XTALK_HPL_R2L:
680 /* Enable left headphone impedance */
681 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
682 NAU8825_BIAS_HPR_IMP | NAU8825_BIAS_HPL_IMP,
683 NAU8825_BIAS_HPL_IMP);
684 break;
685 default:
686 break;
687 }
688 msleep(100);
689 /* Impedance measurement mode enable */
690 regmap_update_bits(nau8825->regmap, NAU8825_REG_IMM_MODE_CTRL,
691 NAU8825_IMM_EN, NAU8825_IMM_EN);
692}
693
694static void nau8825_xtalk_imm_stop(struct nau8825 *nau8825)
695{
696 /* Impedance measurement mode disable */
697 regmap_update_bits(nau8825->regmap,
698 NAU8825_REG_IMM_MODE_CTRL, NAU8825_IMM_EN, 0);
699}
700
701/* The cross talk measurement function can reduce cross talk across the
702 * JKTIP(HPL) and JKR1(HPR) outputs which measures the cross talk signal
703 * level to determine what cross talk reduction gain is. This system works by
704 * sending a 23Hz -24dBV sine wave into the headset output DAC and through
705 * the PGA. The output of the PGA is then connected to an internal current
706 * sense which measures the attenuated 23Hz signal and passing the output to
707 * an ADC which converts the measurement to a binary code. With two separated
708 * measurement, one for JKR1(HPR) and the other JKTIP(HPL), measurement data
709 * can be separated read in IMM_RMS_L for HSR and HSL after each measurement.
710 * Thus, the measurement function has four states to complete whole sequence.
711 * 1. Prepare state : Prepare the resource for detection and transfer to HPR
712 * IMM stat to make JKR1(HPR) impedance measure.
713 * 2. HPR IMM state : Read out orignal signal level of JKR1(HPR) and transfer
714 * to HPL IMM state to make JKTIP(HPL) impedance measure.
715 * 3. HPL IMM state : Read out cross talk signal level of JKTIP(HPL) and
716 * transfer to IMM state to determine suppression sidetone gain.
717 * 4. IMM state : Computes cross talk suppression sidetone gain with orignal
718 * and cross talk signal level. Apply this gain and then restore codec
719 * configuration. Then transfer to Done state for ending.
720 */
721static void nau8825_xtalk_measure(struct nau8825 *nau8825)
722{
723 u32 sidetone;
724
725 switch (nau8825->xtalk_state) {
726 case NAU8825_XTALK_PREPARE:
727 /* In prepare state, set up clock, intrruption, DAC path, ADC
728 * path and cross talk detection parameters for preparation.
729 */
730 nau8825_xtalk_prepare(nau8825);
731 msleep(280);
732 /* Trigger right headphone impedance detection */
733 nau8825->xtalk_state = NAU8825_XTALK_HPR_R2L;
734 nau8825_xtalk_imm_start(nau8825, 0x00d2);
735 break;
736 case NAU8825_XTALK_HPR_R2L:
737 /* In right headphone IMM state, read out right headphone
738 * impedance measure result, and then start up left side.
739 */
740 regmap_read(nau8825->regmap, NAU8825_REG_IMM_RMS_L,
741 &nau8825->imp_rms[NAU8825_XTALK_HPR_R2L]);
742 dev_dbg(nau8825->dev, "HPR_R2L imm: %x\n",
743 nau8825->imp_rms[NAU8825_XTALK_HPR_R2L]);
744 /* Disable then re-enable IMM mode to update */
745 nau8825_xtalk_imm_stop(nau8825);
746 /* Trigger left headphone impedance detection */
747 nau8825->xtalk_state = NAU8825_XTALK_HPL_R2L;
748 nau8825_xtalk_imm_start(nau8825, 0x00ff);
749 break;
750 case NAU8825_XTALK_HPL_R2L:
751 /* In left headphone IMM state, read out left headphone
752 * impedance measure result, and delay some time to wait
753 * detection sine wave output finish. Then, we can calculate
754 * the cross talk suppresstion side tone according to the L/R
755 * headphone imedance.
756 */
757 regmap_read(nau8825->regmap, NAU8825_REG_IMM_RMS_L,
758 &nau8825->imp_rms[NAU8825_XTALK_HPL_R2L]);
759 dev_dbg(nau8825->dev, "HPL_R2L imm: %x\n",
760 nau8825->imp_rms[NAU8825_XTALK_HPL_R2L]);
761 nau8825_xtalk_imm_stop(nau8825);
762 msleep(150);
763 nau8825->xtalk_state = NAU8825_XTALK_IMM;
764 break;
765 case NAU8825_XTALK_IMM:
766 /* In impedance measure state, the orignal and cross talk
767 * signal level vlues are ready. The side tone gain is deter-
768 * mined with these signal level. After all, restore codec
769 * configuration.
770 */
771 sidetone = nau8825_xtalk_sidetone(
772 nau8825->imp_rms[NAU8825_XTALK_HPR_R2L],
773 nau8825->imp_rms[NAU8825_XTALK_HPL_R2L]);
774 dev_dbg(nau8825->dev, "cross talk sidetone: %x\n", sidetone);
775 regmap_write(nau8825->regmap, NAU8825_REG_DAC_DGAIN_CTRL,
776 (sidetone << 8) | sidetone);
777 nau8825_xtalk_clean(nau8825);
778 nau8825->xtalk_state = NAU8825_XTALK_DONE;
779 break;
780 default:
781 break;
782 }
783}
784
785static void nau8825_xtalk_work(struct work_struct *work)
786{
787 struct nau8825 *nau8825 = container_of(
788 work, struct nau8825, xtalk_work);
789
790 nau8825_xtalk_measure(nau8825);
791 /* To determine the cross talk side tone gain when reach
792 * the impedance measure state.
793 */
794 if (nau8825->xtalk_state == NAU8825_XTALK_IMM)
795 nau8825_xtalk_measure(nau8825);
796
797 /* Delay jack report until cross talk detection process
798 * completed. It can avoid application to do playback
799 * preparation before cross talk detection is still working.
800 * Meanwhile, the protection of the cross talk detection
801 * is released.
802 */
803 if (nau8825->xtalk_state == NAU8825_XTALK_DONE) {
804 snd_soc_jack_report(nau8825->jack, nau8825->xtalk_event,
805 nau8825->xtalk_event_mask);
806 nau8825_sema_release(nau8825);
807 nau8825->xtalk_protect = false;
808 }
809}
810
811static void nau8825_xtalk_cancel(struct nau8825 *nau8825)
812{
813 /* If the xtalk_protect is true, that means the process is still
814 * on going. The driver forces to cancel the cross talk task and
815 * restores the configuration to original status.
816 */
817 if (nau8825->xtalk_protect) {
818 cancel_work_sync(&nau8825->xtalk_work);
819 nau8825_xtalk_clean(nau8825);
820 }
821 /* Reset parameters for cross talk suppression function */
822 nau8825_sema_reset(nau8825);
823 nau8825->xtalk_state = NAU8825_XTALK_DONE;
824 nau8825->xtalk_protect = false;
825}
826
159static bool nau8825_readable_reg(struct device *dev, unsigned int reg) 827static bool nau8825_readable_reg(struct device *dev, unsigned int reg)
160{ 828{
161 switch (reg) { 829 switch (reg) {
@@ -217,12 +885,36 @@ static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
217 case NAU8825_REG_SARDOUT_RAM_STATUS: 885 case NAU8825_REG_SARDOUT_RAM_STATUS:
218 case NAU8825_REG_CHARGE_PUMP_INPUT_READ: 886 case NAU8825_REG_CHARGE_PUMP_INPUT_READ:
219 case NAU8825_REG_GENERAL_STATUS: 887 case NAU8825_REG_GENERAL_STATUS:
888 case NAU8825_REG_BIQ_CTRL ... NAU8825_REG_BIQ_COF10:
220 return true; 889 return true;
221 default: 890 default:
222 return false; 891 return false;
223 } 892 }
224} 893}
225 894
895static int nau8825_adc_event(struct snd_soc_dapm_widget *w,
896 struct snd_kcontrol *kcontrol, int event)
897{
898 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
899 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
900
901 switch (event) {
902 case SND_SOC_DAPM_POST_PMU:
903 regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL,
904 NAU8825_ENABLE_ADC, NAU8825_ENABLE_ADC);
905 break;
906 case SND_SOC_DAPM_POST_PMD:
907 if (!nau8825->irq)
908 regmap_update_bits(nau8825->regmap,
909 NAU8825_REG_ENA_CTRL, NAU8825_ENABLE_ADC, 0);
910 break;
911 default:
912 return -EINVAL;
913 }
914
915 return 0;
916}
917
226static int nau8825_pump_event(struct snd_soc_dapm_widget *w, 918static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
227 struct snd_kcontrol *kcontrol, int event) 919 struct snd_kcontrol *kcontrol, int event)
228{ 920{
@@ -270,6 +962,54 @@ static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
270 return 0; 962 return 0;
271} 963}
272 964
965static int nau8825_biq_coeff_get(struct snd_kcontrol *kcontrol,
966 struct snd_ctl_elem_value *ucontrol)
967{
968 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
969 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
970
971 if (!component->regmap)
972 return -EINVAL;
973
974 regmap_raw_read(component->regmap, NAU8825_REG_BIQ_COF1,
975 ucontrol->value.bytes.data, params->max);
976 return 0;
977}
978
979static int nau8825_biq_coeff_put(struct snd_kcontrol *kcontrol,
980 struct snd_ctl_elem_value *ucontrol)
981{
982 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
983 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
984 void *data;
985
986 if (!component->regmap)
987 return -EINVAL;
988
989 data = kmemdup(ucontrol->value.bytes.data,
990 params->max, GFP_KERNEL | GFP_DMA);
991 if (!data)
992 return -ENOMEM;
993
994 regmap_update_bits(component->regmap, NAU8825_REG_BIQ_CTRL,
995 NAU8825_BIQ_WRT_EN, 0);
996 regmap_raw_write(component->regmap, NAU8825_REG_BIQ_COF1,
997 data, params->max);
998 regmap_update_bits(component->regmap, NAU8825_REG_BIQ_CTRL,
999 NAU8825_BIQ_WRT_EN, NAU8825_BIQ_WRT_EN);
1000
1001 kfree(data);
1002 return 0;
1003}
1004
1005static const char * const nau8825_biq_path[] = {
1006 "ADC", "DAC"
1007};
1008
1009static const struct soc_enum nau8825_biq_path_enum =
1010 SOC_ENUM_SINGLE(NAU8825_REG_BIQ_CTRL, NAU8825_BIQ_PATH_SFT,
1011 ARRAY_SIZE(nau8825_biq_path), nau8825_biq_path);
1012
273static const char * const nau8825_adc_decimation[] = { 1013static const char * const nau8825_adc_decimation[] = {
274 "32", "64", "128", "256" 1014 "32", "64", "128", "256"
275}; 1015};
@@ -306,6 +1046,10 @@ static const struct snd_kcontrol_new nau8825_controls[] = {
306 1046
307 SOC_ENUM("ADC Decimation Rate", nau8825_adc_decimation_enum), 1047 SOC_ENUM("ADC Decimation Rate", nau8825_adc_decimation_enum),
308 SOC_ENUM("DAC Oversampling Rate", nau8825_dac_oversampl_enum), 1048 SOC_ENUM("DAC Oversampling Rate", nau8825_dac_oversampl_enum),
1049 /* programmable biquad filter */
1050 SOC_ENUM("BIQ Path Select", nau8825_biq_path_enum),
1051 SND_SOC_BYTES_EXT("BIQ Coefficients", 20,
1052 nau8825_biq_coeff_get, nau8825_biq_coeff_put),
309}; 1053};
310 1054
311/* DAC Mux 0x33[9] and 0x34[9] */ 1055/* DAC Mux 0x33[9] and 0x34[9] */
@@ -338,7 +1082,9 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = {
338 SND_SOC_DAPM_PGA("Frontend PGA", NAU8825_REG_POWER_UP_CONTROL, 14, 0, 1082 SND_SOC_DAPM_PGA("Frontend PGA", NAU8825_REG_POWER_UP_CONTROL, 14, 0,
339 NULL, 0), 1083 NULL, 0),
340 1084
341 SND_SOC_DAPM_ADC("ADC", NULL, NAU8825_REG_ENA_CTRL, 8, 0), 1085 SND_SOC_DAPM_ADC_E("ADC", NULL, SND_SOC_NOPM, 0, 0,
1086 nau8825_adc_event, SND_SOC_DAPM_POST_PMU |
1087 SND_SOC_DAPM_POST_PMD),
342 SND_SOC_DAPM_SUPPLY("ADC Clock", NAU8825_REG_ENA_CTRL, 7, 0, NULL, 0), 1088 SND_SOC_DAPM_SUPPLY("ADC Clock", NAU8825_REG_ENA_CTRL, 7, 0, NULL, 0),
343 SND_SOC_DAPM_SUPPLY("ADC Power", NAU8825_REG_ANALOG_ADC_2, 6, 0, NULL, 1089 SND_SOC_DAPM_SUPPLY("ADC Power", NAU8825_REG_ANALOG_ADC_2, 6, 0, NULL,
344 0), 1090 0),
@@ -592,9 +1338,6 @@ int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
592 NAU8825_HSD_AUTO_MODE | NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L, 1338 NAU8825_HSD_AUTO_MODE | NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L,
593 NAU8825_HSD_AUTO_MODE | NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L); 1339 NAU8825_HSD_AUTO_MODE | NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L);
594 1340
595 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
596 NAU8825_IRQ_HEADSET_COMPLETE_EN | NAU8825_IRQ_EJECT_EN, 0);
597
598 return 0; 1341 return 0;
599} 1342}
600EXPORT_SYMBOL_GPL(nau8825_enable_jack_detect); 1343EXPORT_SYMBOL_GPL(nau8825_enable_jack_detect);
@@ -602,24 +1345,21 @@ EXPORT_SYMBOL_GPL(nau8825_enable_jack_detect);
602 1345
603static bool nau8825_is_jack_inserted(struct regmap *regmap) 1346static bool nau8825_is_jack_inserted(struct regmap *regmap)
604{ 1347{
605 int status; 1348 bool active_high, is_high;
1349 int status, jkdet;
606 1350
1351 regmap_read(regmap, NAU8825_REG_JACK_DET_CTRL, &jkdet);
1352 active_high = jkdet & NAU8825_JACK_POLARITY;
607 regmap_read(regmap, NAU8825_REG_I2C_DEVICE_ID, &status); 1353 regmap_read(regmap, NAU8825_REG_I2C_DEVICE_ID, &status);
608 return !(status & NAU8825_GPIO2JD1); 1354 is_high = status & NAU8825_GPIO2JD1;
1355 /* return jack connection status according to jack insertion logic
1356 * active high or active low.
1357 */
1358 return active_high == is_high;
609} 1359}
610 1360
611static void nau8825_restart_jack_detection(struct regmap *regmap) 1361static void nau8825_restart_jack_detection(struct regmap *regmap)
612{ 1362{
613 /* Chip needs one FSCLK cycle in order to generate interrupts,
614 * as we cannot guarantee one will be provided by the system. Turning
615 * master mode on then off enables us to generate that FSCLK cycle
616 * with a minimum of contention on the clock bus.
617 */
618 regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
619 NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER);
620 regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
621 NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE);
622
623 /* this will restart the entire jack detection process including MIC/GND 1363 /* this will restart the entire jack detection process including MIC/GND
624 * switching and create interrupts. We have to go from 0 to 1 and back 1364 * switching and create interrupts. We have to go from 0 to 1 and back
625 * to 0 to restart. 1365 * to 0 to restart.
@@ -630,11 +1370,30 @@ static void nau8825_restart_jack_detection(struct regmap *regmap)
630 NAU8825_JACK_DET_RESTART, 0); 1370 NAU8825_JACK_DET_RESTART, 0);
631} 1371}
632 1372
1373static void nau8825_int_status_clear_all(struct regmap *regmap)
1374{
1375 int active_irq, clear_irq, i;
1376
1377 /* Reset the intrruption status from rightmost bit if the corres-
1378 * ponding irq event occurs.
1379 */
1380 regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq);
1381 for (i = 0; i < NAU8825_REG_DATA_LEN; i++) {
1382 clear_irq = (0x1 << i);
1383 if (active_irq & clear_irq)
1384 regmap_write(regmap,
1385 NAU8825_REG_INT_CLR_KEY_STATUS, clear_irq);
1386 }
1387}
1388
633static void nau8825_eject_jack(struct nau8825 *nau8825) 1389static void nau8825_eject_jack(struct nau8825 *nau8825)
634{ 1390{
635 struct snd_soc_dapm_context *dapm = nau8825->dapm; 1391 struct snd_soc_dapm_context *dapm = nau8825->dapm;
636 struct regmap *regmap = nau8825->regmap; 1392 struct regmap *regmap = nau8825->regmap;
637 1393
1394 /* Force to cancel the cross talk detection process */
1395 nau8825_xtalk_cancel(nau8825);
1396
638 snd_soc_dapm_disable_pin(dapm, "SAR"); 1397 snd_soc_dapm_disable_pin(dapm, "SAR");
639 snd_soc_dapm_disable_pin(dapm, "MICBIAS"); 1398 snd_soc_dapm_disable_pin(dapm, "MICBIAS");
640 /* Detach 2kOhm Resistors from MICBIAS to MICGND1/2 */ 1399 /* Detach 2kOhm Resistors from MICBIAS to MICGND1/2 */
@@ -644,6 +1403,69 @@ static void nau8825_eject_jack(struct nau8825 *nau8825)
644 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0xf, 0xf); 1403 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0xf, 0xf);
645 1404
646 snd_soc_dapm_sync(dapm); 1405 snd_soc_dapm_sync(dapm);
1406
1407 /* Clear all interruption status */
1408 nau8825_int_status_clear_all(regmap);
1409
1410 /* Enable the insertion interruption, disable the ejection inter-
1411 * ruption, and then bypass de-bounce circuit.
1412 */
1413 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_DIS_CTRL,
1414 NAU8825_IRQ_EJECT_DIS | NAU8825_IRQ_INSERT_DIS,
1415 NAU8825_IRQ_EJECT_DIS);
1416 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
1417 NAU8825_IRQ_OUTPUT_EN | NAU8825_IRQ_EJECT_EN |
1418 NAU8825_IRQ_HEADSET_COMPLETE_EN | NAU8825_IRQ_INSERT_EN,
1419 NAU8825_IRQ_OUTPUT_EN | NAU8825_IRQ_EJECT_EN |
1420 NAU8825_IRQ_HEADSET_COMPLETE_EN);
1421 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
1422 NAU8825_JACK_DET_DB_BYPASS, NAU8825_JACK_DET_DB_BYPASS);
1423
1424 /* Disable ADC needed for interruptions at audo mode */
1425 regmap_update_bits(regmap, NAU8825_REG_ENA_CTRL,
1426 NAU8825_ENABLE_ADC, 0);
1427
1428 /* Close clock for jack type detection at manual mode */
1429 nau8825_configure_sysclk(nau8825, NAU8825_CLK_DIS, 0);
1430}
1431
1432/* Enable audo mode interruptions with internal clock. */
1433static void nau8825_setup_auto_irq(struct nau8825 *nau8825)
1434{
1435 struct regmap *regmap = nau8825->regmap;
1436
1437 /* Enable headset jack type detection complete interruption and
1438 * jack ejection interruption.
1439 */
1440 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
1441 NAU8825_IRQ_HEADSET_COMPLETE_EN | NAU8825_IRQ_EJECT_EN, 0);
1442
1443 /* Enable internal VCO needed for interruptions */
1444 nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0);
1445
1446 /* Enable ADC needed for interruptions */
1447 regmap_update_bits(regmap, NAU8825_REG_ENA_CTRL,
1448 NAU8825_ENABLE_ADC, NAU8825_ENABLE_ADC);
1449
1450 /* Chip needs one FSCLK cycle in order to generate interruptions,
1451 * as we cannot guarantee one will be provided by the system. Turning
1452 * master mode on then off enables us to generate that FSCLK cycle
1453 * with a minimum of contention on the clock bus.
1454 */
1455 regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
1456 NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER);
1457 regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
1458 NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE);
1459
1460 /* Not bypass de-bounce circuit */
1461 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
1462 NAU8825_JACK_DET_DB_BYPASS, 0);
1463
1464 /* Unmask all interruptions */
1465 regmap_write(regmap, NAU8825_REG_INTERRUPT_DIS_CTRL, 0);
1466
1467 /* Restart the jack detection process at auto mode */
1468 nau8825_restart_jack_detection(regmap);
647} 1469}
648 1470
649static int nau8825_button_decode(int value) 1471static int nau8825_button_decode(int value)
@@ -676,6 +1498,11 @@ static int nau8825_jack_insert(struct nau8825 *nau8825)
676 1498
677 regmap_read(regmap, NAU8825_REG_GENERAL_STATUS, &jack_status_reg); 1499 regmap_read(regmap, NAU8825_REG_GENERAL_STATUS, &jack_status_reg);
678 mic_detected = (jack_status_reg >> 10) & 3; 1500 mic_detected = (jack_status_reg >> 10) & 3;
1501 /* The JKSLV and JKR2 all detected in high impedance headset */
1502 if (mic_detected == 0x3)
1503 nau8825->high_imped = true;
1504 else
1505 nau8825->high_imped = false;
679 1506
680 switch (mic_detected) { 1507 switch (mic_detected) {
681 case 0: 1508 case 0:
@@ -773,6 +1600,33 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
773 } else if (active_irq & NAU8825_HEADSET_COMPLETION_IRQ) { 1600 } else if (active_irq & NAU8825_HEADSET_COMPLETION_IRQ) {
774 if (nau8825_is_jack_inserted(regmap)) { 1601 if (nau8825_is_jack_inserted(regmap)) {
775 event |= nau8825_jack_insert(nau8825); 1602 event |= nau8825_jack_insert(nau8825);
1603 if (!nau8825->high_imped) {
1604 /* Apply the cross talk suppression in the
1605 * headset without high impedance.
1606 */
1607 if (!nau8825->xtalk_protect) {
1608 /* Raise protection for cross talk de-
1609 * tection if no protection before.
1610 * The driver has to cancel the pro-
1611 * cess and restore changes if process
1612 * is ongoing when ejection.
1613 */
1614 nau8825->xtalk_protect = true;
1615 nau8825_sema_acquire(nau8825, 0);
1616 }
1617 /* Startup cross talk detection process */
1618 nau8825->xtalk_state = NAU8825_XTALK_PREPARE;
1619 schedule_work(&nau8825->xtalk_work);
1620 } else {
1621 /* The cross talk suppression shouldn't apply
1622 * in the headset with high impedance. Thus,
1623 * relieve the protection raised before.
1624 */
1625 if (nau8825->xtalk_protect) {
1626 nau8825_sema_release(nau8825);
1627 nau8825->xtalk_protect = false;
1628 }
1629 }
776 } else { 1630 } else {
777 dev_warn(nau8825->dev, "Headset completion IRQ fired but no headset connected\n"); 1631 dev_warn(nau8825->dev, "Headset completion IRQ fired but no headset connected\n");
778 nau8825_eject_jack(nau8825); 1632 nau8825_eject_jack(nau8825);
@@ -780,6 +1634,37 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
780 1634
781 event_mask |= SND_JACK_HEADSET; 1635 event_mask |= SND_JACK_HEADSET;
782 clear_irq = NAU8825_HEADSET_COMPLETION_IRQ; 1636 clear_irq = NAU8825_HEADSET_COMPLETION_IRQ;
1637 /* Record the interruption report event for driver to report
1638 * the event later. The jack report will delay until cross
1639 * talk detection process is done.
1640 */
1641 if (nau8825->xtalk_state == NAU8825_XTALK_PREPARE) {
1642 nau8825->xtalk_event = event;
1643 nau8825->xtalk_event_mask = event_mask;
1644 }
1645 } else if (active_irq & NAU8825_IMPEDANCE_MEAS_IRQ) {
1646 schedule_work(&nau8825->xtalk_work);
1647 clear_irq = NAU8825_IMPEDANCE_MEAS_IRQ;
1648 } else if ((active_irq & NAU8825_JACK_INSERTION_IRQ_MASK) ==
1649 NAU8825_JACK_INSERTION_DETECTED) {
1650 /* One more step to check GPIO status directly. Thus, the
1651 * driver can confirm the real insertion interruption because
1652 * the intrruption at manual mode has bypassed debounce
1653 * circuit which can get rid of unstable status.
1654 */
1655 if (nau8825_is_jack_inserted(regmap)) {
1656 /* Turn off insertion interruption at manual mode */
1657 regmap_update_bits(regmap,
1658 NAU8825_REG_INTERRUPT_DIS_CTRL,
1659 NAU8825_IRQ_INSERT_DIS,
1660 NAU8825_IRQ_INSERT_DIS);
1661 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
1662 NAU8825_IRQ_INSERT_EN, NAU8825_IRQ_INSERT_EN);
1663 /* Enable interruption for jack type detection at audo
1664 * mode which can detect microphone and jack type.
1665 */
1666 nau8825_setup_auto_irq(nau8825);
1667 }
783 } 1668 }
784 1669
785 if (!clear_irq) 1670 if (!clear_irq)
@@ -787,7 +1672,12 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
787 /* clears the rightmost interruption */ 1672 /* clears the rightmost interruption */
788 regmap_write(regmap, NAU8825_REG_INT_CLR_KEY_STATUS, clear_irq); 1673 regmap_write(regmap, NAU8825_REG_INT_CLR_KEY_STATUS, clear_irq);
789 1674
790 if (event_mask) 1675 /* Delay jack report until cross talk detection is done. It can avoid
1676 * application to do playback preparation when cross talk detection
1677 * process is still working. Otherwise, the resource like clock and
1678 * power will be issued by them at the same time and conflict happens.
1679 */
1680 if (event_mask && nau8825->xtalk_state == NAU8825_XTALK_DONE)
791 snd_soc_jack_report(nau8825->jack, event, event_mask); 1681 snd_soc_jack_report(nau8825->jack, event, event_mask);
792 1682
793 return IRQ_HANDLED; 1683 return IRQ_HANDLED;
@@ -921,11 +1811,16 @@ static void nau8825_init_regs(struct nau8825 *nau8825)
921 NAU8825_RDAC_CLK_DELAY_MASK | NAU8825_RDAC_VREF_MASK, 1811 NAU8825_RDAC_CLK_DELAY_MASK | NAU8825_RDAC_VREF_MASK,
922 (0x2 << NAU8825_RDAC_CLK_DELAY_SFT) | 1812 (0x2 << NAU8825_RDAC_CLK_DELAY_SFT) |
923 (0x3 << NAU8825_RDAC_VREF_SFT)); 1813 (0x3 << NAU8825_RDAC_VREF_SFT));
1814 /* Config L/R channel */
1815 regmap_update_bits(nau8825->regmap, NAU8825_REG_DACL_CTRL,
1816 NAU8825_DACL_CH_SEL_MASK, NAU8825_DACL_CH_SEL_L);
1817 regmap_update_bits(nau8825->regmap, NAU8825_REG_DACR_CTRL,
1818 NAU8825_DACL_CH_SEL_MASK, NAU8825_DACL_CH_SEL_R);
924} 1819}
925 1820
926static const struct regmap_config nau8825_regmap_config = { 1821static const struct regmap_config nau8825_regmap_config = {
927 .val_bits = 16, 1822 .val_bits = NAU8825_REG_DATA_LEN,
928 .reg_bits = 16, 1823 .reg_bits = NAU8825_REG_ADDR_LEN,
929 1824
930 .max_register = NAU8825_REG_MAX, 1825 .max_register = NAU8825_REG_MAX,
931 .readable_reg = nau8825_readable_reg, 1826 .readable_reg = nau8825_readable_reg,
@@ -944,18 +1839,15 @@ static int nau8825_codec_probe(struct snd_soc_codec *codec)
944 1839
945 nau8825->dapm = dapm; 1840 nau8825->dapm = dapm;
946 1841
947 /* The interrupt clock is gated by x1[10:8], 1842 return 0;
948 * one of them needs to be enabled all the time for 1843}
949 * interrupts to happen.
950 */
951 snd_soc_dapm_force_enable_pin(dapm, "DDACR");
952 snd_soc_dapm_sync(dapm);
953 1844
954 /* Unmask interruptions. Handler uses dapm object so we can enable 1845static int nau8825_codec_remove(struct snd_soc_codec *codec)
955 * interruptions only after dapm is fully initialized. 1846{
956 */ 1847 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
957 regmap_write(nau8825->regmap, NAU8825_REG_INTERRUPT_DIS_CTRL, 0); 1848
958 nau8825_restart_jack_detection(nau8825->regmap); 1849 /* Cancel and reset cross tak suppresstion detection funciton */
1850 nau8825_xtalk_cancel(nau8825);
959 1851
960 return 0; 1852 return 0;
961} 1853}
@@ -973,8 +1865,8 @@ static int nau8825_codec_probe(struct snd_soc_codec *codec)
973static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs, 1865static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
974 struct nau8825_fll *fll_param) 1866 struct nau8825_fll *fll_param)
975{ 1867{
976 u64 fvco; 1868 u64 fvco, fvco_max;
977 unsigned int fref, i; 1869 unsigned int fref, i, fvco_sel;
978 1870
979 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing 1871 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
980 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar. 1872 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
@@ -999,18 +1891,23 @@ static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
999 fll_param->ratio = fll_ratio[i].val; 1891 fll_param->ratio = fll_ratio[i].val;
1000 1892
1001 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs. 1893 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.
1002 * FDCO must be within the 90MHz - 100MHz or the FFL cannot be 1894 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be
1003 * guaranteed across the full range of operation. 1895 * guaranteed across the full range of operation.
1004 * FDCO = freq_out * 2 * mclk_src_scaling 1896 * FDCO = freq_out * 2 * mclk_src_scaling
1005 */ 1897 */
1898 fvco_max = 0;
1899 fvco_sel = ARRAY_SIZE(mclk_src_scaling);
1006 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) { 1900 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
1007 fvco = 256 * fs * 2 * mclk_src_scaling[i].param; 1901 fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
1008 if (NAU_FVCO_MIN < fvco && fvco < NAU_FVCO_MAX) 1902 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
1009 break; 1903 fvco_max < fvco) {
1904 fvco_max = fvco;
1905 fvco_sel = i;
1906 }
1010 } 1907 }
1011 if (i == ARRAY_SIZE(mclk_src_scaling)) 1908 if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel)
1012 return -EINVAL; 1909 return -EINVAL;
1013 fll_param->mclk_src = mclk_src_scaling[i].val; 1910 fll_param->mclk_src = mclk_src_scaling[fvco_sel].val;
1014 1911
1015 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional 1912 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
1016 * input based on FDCO, FREF and FLL ratio. 1913 * input based on FDCO, FREF and FLL ratio.
@@ -1025,7 +1922,8 @@ static void nau8825_fll_apply(struct nau8825 *nau8825,
1025 struct nau8825_fll *fll_param) 1922 struct nau8825_fll *fll_param)
1026{ 1923{
1027 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, 1924 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
1028 NAU8825_CLK_MCLK_SRC_MASK, fll_param->mclk_src); 1925 NAU8825_CLK_SRC_MASK | NAU8825_CLK_MCLK_SRC_MASK,
1926 NAU8825_CLK_SRC_MCLK | fll_param->mclk_src);
1029 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL1, 1927 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL1,
1030 NAU8825_FLL_RATIO_MASK, fll_param->ratio); 1928 NAU8825_FLL_RATIO_MASK, fll_param->ratio);
1031 /* FLL 16-bit fractional input */ 1929 /* FLL 16-bit fractional input */
@@ -1038,10 +1936,25 @@ static void nau8825_fll_apply(struct nau8825 *nau8825,
1038 NAU8825_FLL_REF_DIV_MASK, fll_param->clk_ref_div); 1936 NAU8825_FLL_REF_DIV_MASK, fll_param->clk_ref_div);
1039 /* select divided VCO input */ 1937 /* select divided VCO input */
1040 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5, 1938 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
1041 NAU8825_FLL_FILTER_SW_MASK, 0x0000); 1939 NAU8825_FLL_CLK_SW_MASK, NAU8825_FLL_CLK_SW_REF);
1042 /* FLL sigma delta modulator enable */ 1940 /* Disable free-running mode */
1043 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL6, 1941 regmap_update_bits(nau8825->regmap,
1044 NAU8825_SDM_EN_MASK, NAU8825_SDM_EN); 1942 NAU8825_REG_FLL6, NAU8825_DCO_EN, 0);
1943 if (fll_param->fll_frac) {
1944 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
1945 NAU8825_FLL_PDB_DAC_EN | NAU8825_FLL_LOOP_FTR_EN |
1946 NAU8825_FLL_FTR_SW_MASK,
1947 NAU8825_FLL_PDB_DAC_EN | NAU8825_FLL_LOOP_FTR_EN |
1948 NAU8825_FLL_FTR_SW_FILTER);
1949 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL6,
1950 NAU8825_SDM_EN, NAU8825_SDM_EN);
1951 } else {
1952 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
1953 NAU8825_FLL_PDB_DAC_EN | NAU8825_FLL_LOOP_FTR_EN |
1954 NAU8825_FLL_FTR_SW_MASK, NAU8825_FLL_FTR_SW_ACCU);
1955 regmap_update_bits(nau8825->regmap,
1956 NAU8825_REG_FLL6, NAU8825_SDM_EN, 0);
1957 }
1045} 1958}
1046 1959
1047/* freq_out must be 256*Fs in order to achieve the best performance */ 1960/* freq_out must be 256*Fs in order to achieve the best performance */
@@ -1069,6 +1982,45 @@ static int nau8825_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
1069 return 0; 1982 return 0;
1070} 1983}
1071 1984
1985static int nau8825_mclk_prepare(struct nau8825 *nau8825, unsigned int freq)
1986{
1987 int ret = 0;
1988
1989 nau8825->mclk = devm_clk_get(nau8825->dev, "mclk");
1990 if (IS_ERR(nau8825->mclk)) {
1991 dev_info(nau8825->dev, "No 'mclk' clock found, assume MCLK is managed externally");
1992 return 0;
1993 }
1994
1995 if (!nau8825->mclk_freq) {
1996 ret = clk_prepare_enable(nau8825->mclk);
1997 if (ret) {
1998 dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
1999 return ret;
2000 }
2001 }
2002
2003 if (nau8825->mclk_freq != freq) {
2004 freq = clk_round_rate(nau8825->mclk, freq);
2005 ret = clk_set_rate(nau8825->mclk, freq);
2006 if (ret) {
2007 dev_err(nau8825->dev, "Unable to set mclk rate\n");
2008 return ret;
2009 }
2010 nau8825->mclk_freq = freq;
2011 }
2012
2013 return 0;
2014}
2015
2016static void nau8825_configure_mclk_as_sysclk(struct regmap *regmap)
2017{
2018 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
2019 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_MCLK);
2020 regmap_update_bits(regmap, NAU8825_REG_FLL6,
2021 NAU8825_DCO_EN, 0);
2022}
2023
1072static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, 2024static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
1073 unsigned int freq) 2025 unsigned int freq)
1074{ 2026{
@@ -1076,40 +2028,106 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
1076 int ret; 2028 int ret;
1077 2029
1078 switch (clk_id) { 2030 switch (clk_id) {
2031 case NAU8825_CLK_DIS:
2032 /* Clock provided externally and disable internal VCO clock */
2033 nau8825_configure_mclk_as_sysclk(regmap);
2034 if (nau8825->mclk_freq) {
2035 clk_disable_unprepare(nau8825->mclk);
2036 nau8825->mclk_freq = 0;
2037 }
2038
2039 break;
1079 case NAU8825_CLK_MCLK: 2040 case NAU8825_CLK_MCLK:
2041 /* Acquire the semaphone to synchronize the playback and
2042 * interrupt handler. In order to avoid the playback inter-
2043 * fered by cross talk process, the driver make the playback
2044 * preparation halted until cross talk process finish.
2045 */
2046 nau8825_sema_acquire(nau8825, 2 * HZ);
2047 nau8825_configure_mclk_as_sysclk(regmap);
2048 /* MCLK not changed by clock tree */
1080 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER, 2049 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
1081 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_MCLK); 2050 NAU8825_CLK_MCLK_SRC_MASK, 0);
1082 regmap_update_bits(regmap, NAU8825_REG_FLL6, NAU8825_DCO_EN, 0); 2051 /* Release the semaphone. */
2052 nau8825_sema_release(nau8825);
1083 2053
1084 /* We selected MCLK source but the clock itself managed externally */ 2054 ret = nau8825_mclk_prepare(nau8825, freq);
1085 if (!nau8825->mclk) 2055 if (ret)
1086 break; 2056 return ret;
1087 2057
1088 if (!nau8825->mclk_freq) { 2058 break;
1089 ret = clk_prepare_enable(nau8825->mclk); 2059 case NAU8825_CLK_INTERNAL:
1090 if (ret) { 2060 if (nau8825_is_jack_inserted(nau8825->regmap)) {
1091 dev_err(nau8825->dev, "Unable to prepare codec mclk\n"); 2061 regmap_update_bits(regmap, NAU8825_REG_FLL6,
1092 return ret; 2062 NAU8825_DCO_EN, NAU8825_DCO_EN);
1093 } 2063 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
2064 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_VCO);
2065 /* Decrease the VCO frequency for power saving */
2066 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
2067 NAU8825_CLK_MCLK_SRC_MASK, 0xf);
2068 regmap_update_bits(regmap, NAU8825_REG_FLL1,
2069 NAU8825_FLL_RATIO_MASK, 0x10);
2070 regmap_update_bits(regmap, NAU8825_REG_FLL6,
2071 NAU8825_SDM_EN, NAU8825_SDM_EN);
2072 } else {
2073 /* The clock turns off intentionally for power saving
2074 * when no headset connected.
2075 */
2076 nau8825_configure_mclk_as_sysclk(regmap);
2077 dev_warn(nau8825->dev, "Disable clock for power saving when no headset connected\n");
2078 }
2079 if (nau8825->mclk_freq) {
2080 clk_disable_unprepare(nau8825->mclk);
2081 nau8825->mclk_freq = 0;
1094 } 2082 }
1095 2083
1096 if (nau8825->mclk_freq != freq) { 2084 break;
1097 nau8825->mclk_freq = freq; 2085 case NAU8825_CLK_FLL_MCLK:
2086 /* Acquire the semaphone to synchronize the playback and
2087 * interrupt handler. In order to avoid the playback inter-
2088 * fered by cross talk process, the driver make the playback
2089 * preparation halted until cross talk process finish.
2090 */
2091 nau8825_sema_acquire(nau8825, 2 * HZ);
2092 regmap_update_bits(regmap, NAU8825_REG_FLL3,
2093 NAU8825_FLL_CLK_SRC_MASK, NAU8825_FLL_CLK_SRC_MCLK);
2094 /* Release the semaphone. */
2095 nau8825_sema_release(nau8825);
1098 2096
1099 freq = clk_round_rate(nau8825->mclk, freq); 2097 ret = nau8825_mclk_prepare(nau8825, freq);
1100 ret = clk_set_rate(nau8825->mclk, freq); 2098 if (ret)
1101 if (ret) { 2099 return ret;
1102 dev_err(nau8825->dev, "Unable to set mclk rate\n"); 2100
1103 return ret; 2101 break;
1104 } 2102 case NAU8825_CLK_FLL_BLK:
2103 /* Acquire the semaphone to synchronize the playback and
2104 * interrupt handler. In order to avoid the playback inter-
2105 * fered by cross talk process, the driver make the playback
2106 * preparation halted until cross talk process finish.
2107 */
2108 nau8825_sema_acquire(nau8825, 2 * HZ);
2109 regmap_update_bits(regmap, NAU8825_REG_FLL3,
2110 NAU8825_FLL_CLK_SRC_MASK, NAU8825_FLL_CLK_SRC_BLK);
2111 /* Release the semaphone. */
2112 nau8825_sema_release(nau8825);
2113
2114 if (nau8825->mclk_freq) {
2115 clk_disable_unprepare(nau8825->mclk);
2116 nau8825->mclk_freq = 0;
1105 } 2117 }
1106 2118
1107 break; 2119 break;
1108 case NAU8825_CLK_INTERNAL: 2120 case NAU8825_CLK_FLL_FS:
1109 regmap_update_bits(regmap, NAU8825_REG_FLL6, NAU8825_DCO_EN, 2121 /* Acquire the semaphone to synchronize the playback and
1110 NAU8825_DCO_EN); 2122 * interrupt handler. In order to avoid the playback inter-
1111 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER, 2123 * fered by cross talk process, the driver make the playback
1112 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_VCO); 2124 * preparation halted until cross talk process finish.
2125 */
2126 nau8825_sema_acquire(nau8825, 2 * HZ);
2127 regmap_update_bits(regmap, NAU8825_REG_FLL3,
2128 NAU8825_FLL_CLK_SRC_MASK, NAU8825_FLL_CLK_SRC_FS);
2129 /* Release the semaphone. */
2130 nau8825_sema_release(nau8825);
1113 2131
1114 if (nau8825->mclk_freq) { 2132 if (nau8825->mclk_freq) {
1115 clk_disable_unprepare(nau8825->mclk); 2133 clk_disable_unprepare(nau8825->mclk);
@@ -1135,6 +2153,31 @@ static int nau8825_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1135 return nau8825_configure_sysclk(nau8825, clk_id, freq); 2153 return nau8825_configure_sysclk(nau8825, clk_id, freq);
1136} 2154}
1137 2155
2156static int nau8825_resume_setup(struct nau8825 *nau8825)
2157{
2158 struct regmap *regmap = nau8825->regmap;
2159
2160 /* Close clock when jack type detection at manual mode */
2161 nau8825_configure_sysclk(nau8825, NAU8825_CLK_DIS, 0);
2162
2163 /* Clear all interruption status */
2164 nau8825_int_status_clear_all(regmap);
2165
2166 /* Enable both insertion and ejection interruptions, and then
2167 * bypass de-bounce circuit.
2168 */
2169 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
2170 NAU8825_IRQ_OUTPUT_EN | NAU8825_IRQ_HEADSET_COMPLETE_EN |
2171 NAU8825_IRQ_EJECT_EN | NAU8825_IRQ_INSERT_EN,
2172 NAU8825_IRQ_OUTPUT_EN | NAU8825_IRQ_HEADSET_COMPLETE_EN);
2173 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
2174 NAU8825_JACK_DET_DB_BYPASS, NAU8825_JACK_DET_DB_BYPASS);
2175 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_DIS_CTRL,
2176 NAU8825_IRQ_INSERT_DIS | NAU8825_IRQ_EJECT_DIS, 0);
2177
2178 return 0;
2179}
2180
1138static int nau8825_set_bias_level(struct snd_soc_codec *codec, 2181static int nau8825_set_bias_level(struct snd_soc_codec *codec,
1139 enum snd_soc_bias_level level) 2182 enum snd_soc_bias_level level)
1140{ 2183{
@@ -1157,10 +2200,22 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
1157 return ret; 2200 return ret;
1158 } 2201 }
1159 } 2202 }
2203 /* Setup codec configuration after resume */
2204 nau8825_resume_setup(nau8825);
1160 } 2205 }
1161 break; 2206 break;
1162 2207
1163 case SND_SOC_BIAS_OFF: 2208 case SND_SOC_BIAS_OFF:
2209 /* Cancel and reset cross talk detection funciton */
2210 nau8825_xtalk_cancel(nau8825);
2211 /* Turn off all interruptions before system shutdown. Keep the
2212 * interruption quiet before resume setup completes.
2213 */
2214 regmap_write(nau8825->regmap,
2215 NAU8825_REG_INTERRUPT_DIS_CTRL, 0xffff);
2216 /* Disable ADC needed for interruptions at audo mode */
2217 regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL,
2218 NAU8825_ENABLE_ADC, 0);
1164 if (nau8825->mclk_freq) 2219 if (nau8825->mclk_freq)
1165 clk_disable_unprepare(nau8825->mclk); 2220 clk_disable_unprepare(nau8825->mclk);
1166 break; 2221 break;
@@ -1168,57 +2223,46 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
1168 return 0; 2223 return 0;
1169} 2224}
1170 2225
1171#ifdef CONFIG_PM 2226static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
1172static int nau8825_suspend(struct snd_soc_codec *codec)
1173{ 2227{
1174 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); 2228 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
1175 2229
1176 disable_irq(nau8825->irq); 2230 disable_irq(nau8825->irq);
2231 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
1177 regcache_cache_only(nau8825->regmap, true); 2232 regcache_cache_only(nau8825->regmap, true);
1178 regcache_mark_dirty(nau8825->regmap); 2233 regcache_mark_dirty(nau8825->regmap);
1179 2234
1180 return 0; 2235 return 0;
1181} 2236}
1182 2237
1183static int nau8825_resume(struct snd_soc_codec *codec) 2238static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
1184{ 2239{
1185 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); 2240 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
1186 2241
1187 /* The chip may lose power and reset in S3. regcache_sync restores
1188 * register values including configurations for sysclk, irq, and
1189 * jack/button detection.
1190 */
1191 regcache_cache_only(nau8825->regmap, false); 2242 regcache_cache_only(nau8825->regmap, false);
1192 regcache_sync(nau8825->regmap); 2243 regcache_sync(nau8825->regmap);
1193 2244 if (nau8825_is_jack_inserted(nau8825->regmap)) {
1194 /* Check the jack plug status directly. If the headset is unplugged 2245 /* If the jack is inserted, we need to check whether the play-
1195 * during S3 when the chip has no power, there will be no jack 2246 * back is active before suspend. If active, the driver has to
1196 * detection irq even after the nau8825_restart_jack_detection below, 2247 * raise the protection for cross talk function to avoid the
1197 * because the chip just thinks no headset has ever been plugged in. 2248 * playback recovers before cross talk process finish. Other-
1198 */ 2249 * wise, the playback will be interfered by cross talk func-
1199 if (!nau8825_is_jack_inserted(nau8825->regmap)) { 2250 * tion. It is better to apply hardware related parameters
1200 nau8825_eject_jack(nau8825); 2251 * before starting playback or record.
1201 snd_soc_jack_report(nau8825->jack, 0, SND_JACK_HEADSET); 2252 */
2253 if (nau8825_dai_is_active(nau8825)) {
2254 nau8825->xtalk_protect = true;
2255 nau8825_sema_acquire(nau8825, 0);
2256 }
1202 } 2257 }
1203
1204 enable_irq(nau8825->irq); 2258 enable_irq(nau8825->irq);
1205 2259
1206 /* Run jack detection to check the type (OMTP or CTIA) of the headset
1207 * if there is one. This handles the case where a different type of
1208 * headset is plugged in during S3. This triggers an IRQ iff a headset
1209 * is already plugged in.
1210 */
1211 nau8825_restart_jack_detection(nau8825->regmap);
1212
1213 return 0; 2260 return 0;
1214} 2261}
1215#else
1216#define nau8825_suspend NULL
1217#define nau8825_resume NULL
1218#endif
1219 2262
1220static struct snd_soc_codec_driver nau8825_codec_driver = { 2263static struct snd_soc_codec_driver nau8825_codec_driver = {
1221 .probe = nau8825_codec_probe, 2264 .probe = nau8825_codec_probe,
2265 .remove = nau8825_codec_remove,
1222 .set_sysclk = nau8825_set_sysclk, 2266 .set_sysclk = nau8825_set_sysclk,
1223 .set_pll = nau8825_set_pll, 2267 .set_pll = nau8825_set_pll,
1224 .set_bias_level = nau8825_set_bias_level, 2268 .set_bias_level = nau8825_set_bias_level,
@@ -1318,22 +2362,8 @@ static int nau8825_read_device_properties(struct device *dev,
1318 2362
1319static int nau8825_setup_irq(struct nau8825 *nau8825) 2363static int nau8825_setup_irq(struct nau8825 *nau8825)
1320{ 2364{
1321 struct regmap *regmap = nau8825->regmap;
1322 int ret; 2365 int ret;
1323 2366
1324 /* IRQ Output Enable */
1325 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
1326 NAU8825_IRQ_OUTPUT_EN, NAU8825_IRQ_OUTPUT_EN);
1327
1328 /* Enable internal VCO needed for interruptions */
1329 nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0);
1330
1331 /* Enable DDACR needed for interrupts
1332 * It is the same as force_enable_pin("DDACR") we do later
1333 */
1334 regmap_update_bits(regmap, NAU8825_REG_ENA_CTRL,
1335 NAU8825_ENABLE_DACR, NAU8825_ENABLE_DACR);
1336
1337 ret = devm_request_threaded_irq(nau8825->dev, nau8825->irq, NULL, 2367 ret = devm_request_threaded_irq(nau8825->dev, nau8825->irq, NULL,
1338 nau8825_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT, 2368 nau8825_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1339 "nau8825", nau8825); 2369 "nau8825", nau8825);
@@ -1370,6 +2400,13 @@ static int nau8825_i2c_probe(struct i2c_client *i2c,
1370 return PTR_ERR(nau8825->regmap); 2400 return PTR_ERR(nau8825->regmap);
1371 nau8825->dev = dev; 2401 nau8825->dev = dev;
1372 nau8825->irq = i2c->irq; 2402 nau8825->irq = i2c->irq;
2403 /* Initiate parameters, semaphone and work queue which are needed in
2404 * cross talk suppression measurment function.
2405 */
2406 nau8825->xtalk_state = NAU8825_XTALK_DONE;
2407 nau8825->xtalk_protect = false;
2408 sema_init(&nau8825->xtalk_sem, 1);
2409 INIT_WORK(&nau8825->xtalk_work, nau8825_xtalk_work);
1373 2410
1374 nau8825_print_device_properties(nau8825); 2411 nau8825_print_device_properties(nau8825);
1375 2412
@@ -1405,6 +2442,7 @@ static const struct i2c_device_id nau8825_i2c_ids[] = {
1405 { "nau8825", 0 }, 2442 { "nau8825", 0 },
1406 { } 2443 { }
1407}; 2444};
2445MODULE_DEVICE_TABLE(i2c, nau8825_i2c_ids);
1408 2446
1409#ifdef CONFIG_OF 2447#ifdef CONFIG_OF
1410static const struct of_device_id nau8825_of_ids[] = { 2448static const struct of_device_id nau8825_of_ids[] = {
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h
index 8ceb5f385478..1c63e2abafa9 100644
--- a/sound/soc/codecs/nau8825.h
+++ b/sound/soc/codecs/nau8825.h
@@ -93,12 +93,21 @@
93#define NAU8825_REG_CHARGE_PUMP_INPUT_READ 0x81 93#define NAU8825_REG_CHARGE_PUMP_INPUT_READ 0x81
94#define NAU8825_REG_GENERAL_STATUS 0x82 94#define NAU8825_REG_GENERAL_STATUS 0x82
95#define NAU8825_REG_MAX NAU8825_REG_GENERAL_STATUS 95#define NAU8825_REG_MAX NAU8825_REG_GENERAL_STATUS
96/* 16-bit control register address, and 16-bits control register data */
97#define NAU8825_REG_ADDR_LEN 16
98#define NAU8825_REG_DATA_LEN 16
96 99
97/* ENA_CTRL (0x1) */ 100/* ENA_CTRL (0x1) */
98#define NAU8825_ENABLE_DACR_SFT 10 101#define NAU8825_ENABLE_DACR_SFT 10
99#define NAU8825_ENABLE_DACR (1 << NAU8825_ENABLE_DACR_SFT) 102#define NAU8825_ENABLE_DACR (1 << NAU8825_ENABLE_DACR_SFT)
100#define NAU8825_ENABLE_DACL_SFT 9 103#define NAU8825_ENABLE_DACL_SFT 9
104#define NAU8825_ENABLE_DACL (1 << NAU8825_ENABLE_DACL_SFT)
101#define NAU8825_ENABLE_ADC_SFT 8 105#define NAU8825_ENABLE_ADC_SFT 8
106#define NAU8825_ENABLE_ADC (1 << NAU8825_ENABLE_ADC_SFT)
107#define NAU8825_ENABLE_ADC_CLK_SFT 7
108#define NAU8825_ENABLE_ADC_CLK (1 << NAU8825_ENABLE_ADC_CLK_SFT)
109#define NAU8825_ENABLE_DAC_CLK_SFT 6
110#define NAU8825_ENABLE_DAC_CLK (1 << NAU8825_ENABLE_DAC_CLK_SFT)
102#define NAU8825_ENABLE_SAR_SFT 1 111#define NAU8825_ENABLE_SAR_SFT 1
103 112
104/* CLK_DIVIDER (0x3) */ 113/* CLK_DIVIDER (0x3) */
@@ -113,20 +122,28 @@
113 122
114/* FLL3 (0x06) */ 123/* FLL3 (0x06) */
115#define NAU8825_FLL_INTEGER_MASK (0x3ff << 0) 124#define NAU8825_FLL_INTEGER_MASK (0x3ff << 0)
125#define NAU8825_FLL_CLK_SRC_SFT 10
126#define NAU8825_FLL_CLK_SRC_MASK (0x3 << NAU8825_FLL_CLK_SRC_SFT)
127#define NAU8825_FLL_CLK_SRC_MCLK (0 << NAU8825_FLL_CLK_SRC_SFT)
128#define NAU8825_FLL_CLK_SRC_BLK (0x2 << NAU8825_FLL_CLK_SRC_SFT)
129#define NAU8825_FLL_CLK_SRC_FS (0x3 << NAU8825_FLL_CLK_SRC_SFT)
116 130
117/* FLL4 (0x07) */ 131/* FLL4 (0x07) */
118#define NAU8825_FLL_REF_DIV_MASK (0x3 << 10) 132#define NAU8825_FLL_REF_DIV_MASK (0x3 << 10)
119 133
120/* FLL5 (0x08) */ 134/* FLL5 (0x08) */
121#define NAU8825_FLL_FILTER_SW_MASK (0x1 << 14) 135#define NAU8825_FLL_PDB_DAC_EN (0x1 << 15)
136#define NAU8825_FLL_LOOP_FTR_EN (0x1 << 14)
137#define NAU8825_FLL_CLK_SW_MASK (0x1 << 13)
138#define NAU8825_FLL_CLK_SW_N2 (0x1 << 13)
139#define NAU8825_FLL_CLK_SW_REF (0x0 << 13)
140#define NAU8825_FLL_FTR_SW_MASK (0x1 << 12)
141#define NAU8825_FLL_FTR_SW_ACCU (0x1 << 12)
142#define NAU8825_FLL_FTR_SW_FILTER (0x0 << 12)
122 143
123/* FLL6 (0x9) */ 144/* FLL6 (0x9) */
124#define NAU8825_DCO_EN_MASK (0x1 << 15)
125#define NAU8825_DCO_EN (0x1 << 15) 145#define NAU8825_DCO_EN (0x1 << 15)
126#define NAU8825_DCO_DIS (0x0 << 15)
127#define NAU8825_SDM_EN_MASK (0x1 << 14)
128#define NAU8825_SDM_EN (0x1 << 14) 146#define NAU8825_SDM_EN (0x1 << 14)
129#define NAU8825_SDM_DIS (0x0 << 14)
130 147
131/* HSD_CTRL (0xc) */ 148/* HSD_CTRL (0xc) */
132#define NAU8825_HSD_AUTO_MODE (1 << 6) 149#define NAU8825_HSD_AUTO_MODE (1 << 6)
@@ -136,6 +153,7 @@
136 153
137/* JACK_DET_CTRL (0xd) */ 154/* JACK_DET_CTRL (0xd) */
138#define NAU8825_JACK_DET_RESTART (1 << 9) 155#define NAU8825_JACK_DET_RESTART (1 << 9)
156#define NAU8825_JACK_DET_DB_BYPASS (1 << 8)
139#define NAU8825_JACK_INSERT_DEBOUNCE_SFT 5 157#define NAU8825_JACK_INSERT_DEBOUNCE_SFT 5
140#define NAU8825_JACK_INSERT_DEBOUNCE_MASK (0x7 << NAU8825_JACK_INSERT_DEBOUNCE_SFT) 158#define NAU8825_JACK_INSERT_DEBOUNCE_MASK (0x7 << NAU8825_JACK_INSERT_DEBOUNCE_SFT)
141#define NAU8825_JACK_EJECT_DEBOUNCE_SFT 2 159#define NAU8825_JACK_EJECT_DEBOUNCE_SFT 2
@@ -145,9 +163,11 @@
145/* INTERRUPT_MASK (0xf) */ 163/* INTERRUPT_MASK (0xf) */
146#define NAU8825_IRQ_OUTPUT_EN (1 << 11) 164#define NAU8825_IRQ_OUTPUT_EN (1 << 11)
147#define NAU8825_IRQ_HEADSET_COMPLETE_EN (1 << 10) 165#define NAU8825_IRQ_HEADSET_COMPLETE_EN (1 << 10)
166#define NAU8825_IRQ_RMS_EN (1 << 8)
148#define NAU8825_IRQ_KEY_RELEASE_EN (1 << 7) 167#define NAU8825_IRQ_KEY_RELEASE_EN (1 << 7)
149#define NAU8825_IRQ_KEY_SHORT_PRESS_EN (1 << 5) 168#define NAU8825_IRQ_KEY_SHORT_PRESS_EN (1 << 5)
150#define NAU8825_IRQ_EJECT_EN (1 << 2) 169#define NAU8825_IRQ_EJECT_EN (1 << 2)
170#define NAU8825_IRQ_INSERT_EN (1 << 0)
151 171
152/* IRQ_STATUS (0x10) */ 172/* IRQ_STATUS (0x10) */
153#define NAU8825_HEADSET_COMPLETION_IRQ (1 << 10) 173#define NAU8825_HEADSET_COMPLETION_IRQ (1 << 10)
@@ -168,6 +188,7 @@
168#define NAU8825_IRQ_KEY_RELEASE_DIS (1 << 7) 188#define NAU8825_IRQ_KEY_RELEASE_DIS (1 << 7)
169#define NAU8825_IRQ_KEY_SHORT_PRESS_DIS (1 << 5) 189#define NAU8825_IRQ_KEY_SHORT_PRESS_DIS (1 << 5)
170#define NAU8825_IRQ_EJECT_DIS (1 << 2) 190#define NAU8825_IRQ_EJECT_DIS (1 << 2)
191#define NAU8825_IRQ_INSERT_DIS (1 << 0)
171 192
172/* SAR_CTRL (0x13) */ 193/* SAR_CTRL (0x13) */
173#define NAU8825_SAR_ADC_EN_SFT 12 194#define NAU8825_SAR_ADC_EN_SFT 12
@@ -217,10 +238,21 @@
217 238
218/* I2S_PCM_CTRL2 (0x1d) */ 239/* I2S_PCM_CTRL2 (0x1d) */
219#define NAU8825_I2S_TRISTATE (1 << 15) /* 0 - normal mode, 1 - Hi-Z output */ 240#define NAU8825_I2S_TRISTATE (1 << 15) /* 0 - normal mode, 1 - Hi-Z output */
241#define NAU8825_I2S_DRV_SFT 12
242#define NAU8825_I2S_DRV_MASK (0x3 << NAU8825_I2S_DRV_SFT)
220#define NAU8825_I2S_MS_SFT 3 243#define NAU8825_I2S_MS_SFT 3
221#define NAU8825_I2S_MS_MASK (1 << NAU8825_I2S_MS_SFT) 244#define NAU8825_I2S_MS_MASK (1 << NAU8825_I2S_MS_SFT)
222#define NAU8825_I2S_MS_MASTER (1 << NAU8825_I2S_MS_SFT) 245#define NAU8825_I2S_MS_MASTER (1 << NAU8825_I2S_MS_SFT)
223#define NAU8825_I2S_MS_SLAVE (0 << NAU8825_I2S_MS_SFT) 246#define NAU8825_I2S_MS_SLAVE (0 << NAU8825_I2S_MS_SFT)
247#define NAU8825_I2S_BLK_DIV_MASK 0x7
248
249/* BIQ_CTRL (0x20) */
250#define NAU8825_BIQ_WRT_SFT 4
251#define NAU8825_BIQ_WRT_EN (1 << NAU8825_BIQ_WRT_SFT)
252#define NAU8825_BIQ_PATH_SFT 0
253#define NAU8825_BIQ_PATH_MASK (1 << NAU8825_BIQ_PATH_SFT)
254#define NAU8825_BIQ_PATH_ADC (0 << NAU8825_BIQ_PATH_SFT)
255#define NAU8825_BIQ_PATH_DAC (1 << NAU8825_BIQ_PATH_SFT)
224 256
225/* ADC_RATE (0x2b) */ 257/* ADC_RATE (0x2b) */
226#define NAU8825_ADC_SYNC_DOWN_SFT 0 258#define NAU8825_ADC_SYNC_DOWN_SFT 0
@@ -239,22 +271,72 @@
239#define NAU8825_DAC_OVERSAMPLE_128 2 271#define NAU8825_DAC_OVERSAMPLE_128 2
240#define NAU8825_DAC_OVERSAMPLE_32 4 272#define NAU8825_DAC_OVERSAMPLE_32 4
241 273
274/* ADC_DGAIN_CTRL (0x30) */
275#define NAU8825_ADC_DIG_VOL_MASK 0xff
276
242/* MUTE_CTRL (0x31) */ 277/* MUTE_CTRL (0x31) */
243#define NAU8825_DAC_ZERO_CROSSING_EN (1 << 9) 278#define NAU8825_DAC_ZERO_CROSSING_EN (1 << 9)
244#define NAU8825_DAC_SOFT_MUTE (1 << 9) 279#define NAU8825_DAC_SOFT_MUTE (1 << 9)
245 280
246/* HSVOL_CTRL (0x32) */ 281/* HSVOL_CTRL (0x32) */
247#define NAU8825_HP_MUTE (1 << 15) 282#define NAU8825_HP_MUTE (1 << 15)
283#define NAU8825_HP_MUTE_AUTO (1 << 14)
284#define NAU8825_HPL_MUTE (1 << 13)
285#define NAU8825_HPR_MUTE (1 << 12)
286#define NAU8825_HPL_VOL_SFT 6
287#define NAU8825_HPL_VOL_MASK (0x3f << NAU8825_HPL_VOL_SFT)
288#define NAU8825_HPR_VOL_SFT 0
289#define NAU8825_HPR_VOL_MASK (0x3f << NAU8825_HPR_VOL_SFT)
290#define NAU8825_HP_VOL_MIN 0x36
248 291
249/* DACL_CTRL (0x33) */ 292/* DACL_CTRL (0x33) */
250#define NAU8825_DACL_CH_SEL_SFT 9 293#define NAU8825_DACL_CH_SEL_SFT 9
294#define NAU8825_DACL_CH_SEL_MASK (0x1 << NAU8825_DACL_CH_SEL_SFT)
295#define NAU8825_DACL_CH_SEL_L (0x0 << NAU8825_DACL_CH_SEL_SFT)
296#define NAU8825_DACL_CH_SEL_R (0x1 << NAU8825_DACL_CH_SEL_SFT)
297#define NAU8825_DACL_CH_VOL_MASK 0xff
251 298
252/* DACR_CTRL (0x34) */ 299/* DACR_CTRL (0x34) */
253#define NAU8825_DACR_CH_SEL_SFT 9 300#define NAU8825_DACR_CH_SEL_SFT 9
301#define NAU8825_DACR_CH_SEL_MASK (0x1 << NAU8825_DACR_CH_SEL_SFT)
302#define NAU8825_DACR_CH_SEL_L (0x0 << NAU8825_DACR_CH_SEL_SFT)
303#define NAU8825_DACR_CH_SEL_R (0x1 << NAU8825_DACR_CH_SEL_SFT)
304#define NAU8825_DACR_CH_VOL_MASK 0xff
305
306/* IMM_MODE_CTRL (0x4C) */
307#define NAU8825_IMM_THD_SFT 8
308#define NAU8825_IMM_THD_MASK (0x3f << NAU8825_IMM_THD_SFT)
309#define NAU8825_IMM_GEN_VOL_SFT 6
310#define NAU8825_IMM_GEN_VOL_MASK (0x3 << NAU8825_IMM_GEN_VOL_SFT)
311#define NAU8825_IMM_GEN_VOL_1_2nd (0x0 << NAU8825_IMM_GEN_VOL_SFT)
312#define NAU8825_IMM_GEN_VOL_1_4th (0x1 << NAU8825_IMM_GEN_VOL_SFT)
313#define NAU8825_IMM_GEN_VOL_1_8th (0x2 << NAU8825_IMM_GEN_VOL_SFT)
314#define NAU8825_IMM_GEN_VOL_1_16th (0x3 << NAU8825_IMM_GEN_VOL_SFT)
315
316#define NAU8825_IMM_CYC_SFT 4
317#define NAU8825_IMM_CYC_MASK (0x3 << NAU8825_IMM_CYC_SFT)
318#define NAU8825_IMM_CYC_1024 (0x0 << NAU8825_IMM_CYC_SFT)
319#define NAU8825_IMM_CYC_2048 (0x1 << NAU8825_IMM_CYC_SFT)
320#define NAU8825_IMM_CYC_4096 (0x2 << NAU8825_IMM_CYC_SFT)
321#define NAU8825_IMM_CYC_8192 (0x3 << NAU8825_IMM_CYC_SFT)
322#define NAU8825_IMM_EN (1 << 3)
323#define NAU8825_IMM_DAC_SRC_MASK 0x7
324#define NAU8825_IMM_DAC_SRC_BIQ 0x0
325#define NAU8825_IMM_DAC_SRC_DRC 0x1
326#define NAU8825_IMM_DAC_SRC_MIX 0x2
327#define NAU8825_IMM_DAC_SRC_SIN 0x3
254 328
255/* CLASSG_CTRL (0x50) */ 329/* CLASSG_CTRL (0x50) */
256#define NAU8825_CLASSG_TIMER_SFT 8 330#define NAU8825_CLASSG_TIMER_SFT 8
257#define NAU8825_CLASSG_TIMER_MASK (0x3f << NAU8825_CLASSG_TIMER_SFT) 331#define NAU8825_CLASSG_TIMER_MASK (0x3f << NAU8825_CLASSG_TIMER_SFT)
332#define NAU8825_CLASSG_TIMER_1ms (0x1 << NAU8825_CLASSG_TIMER_SFT)
333#define NAU8825_CLASSG_TIMER_2ms (0x2 << NAU8825_CLASSG_TIMER_SFT)
334#define NAU8825_CLASSG_TIMER_8ms (0x4 << NAU8825_CLASSG_TIMER_SFT)
335#define NAU8825_CLASSG_TIMER_16ms (0x8 << NAU8825_CLASSG_TIMER_SFT)
336#define NAU8825_CLASSG_TIMER_32ms (0x10 << NAU8825_CLASSG_TIMER_SFT)
337#define NAU8825_CLASSG_TIMER_64ms (0x20 << NAU8825_CLASSG_TIMER_SFT)
338#define NAU8825_CLASSG_LDAC_EN (0x1 << 2)
339#define NAU8825_CLASSG_RDAC_EN (0x1 << 1)
258#define NAU8825_CLASSG_EN (1 << 0) 340#define NAU8825_CLASSG_EN (1 << 0)
259 341
260/* I2C_DEVICE_ID (0x58) */ 342/* I2C_DEVICE_ID (0x58) */
@@ -263,7 +345,12 @@
263#define NAU8825_SOFTWARE_ID_NAU8825 0x0 345#define NAU8825_SOFTWARE_ID_NAU8825 0x0
264 346
265/* BIAS_ADJ (0x66) */ 347/* BIAS_ADJ (0x66) */
266#define NAU8825_BIAS_TESTDAC_EN (0x3 << 8) 348#define NAU8825_BIAS_HPR_IMP (1 << 15)
349#define NAU8825_BIAS_HPL_IMP (1 << 14)
350#define NAU8825_BIAS_TESTDAC_SFT 8
351#define NAU8825_BIAS_TESTDAC_EN (0x3 << NAU8825_BIAS_TESTDAC_SFT)
352#define NAU8825_BIAS_TESTDACR_EN (0x2 << NAU8825_BIAS_TESTDAC_SFT)
353#define NAU8825_BIAS_TESTDACL_EN (0x1 << NAU8825_BIAS_TESTDAC_SFT)
267#define NAU8825_BIAS_VMID (1 << 6) 354#define NAU8825_BIAS_VMID (1 << 6)
268#define NAU8825_BIAS_VMID_SEL_SFT 4 355#define NAU8825_BIAS_VMID_SEL_SFT 4
269#define NAU8825_BIAS_VMID_SEL_MASK (3 << NAU8825_BIAS_VMID_SEL_SFT) 356#define NAU8825_BIAS_VMID_SEL_MASK (3 << NAU8825_BIAS_VMID_SEL_SFT)
@@ -282,6 +369,11 @@
282#define NAU8825_POWERUP_ADCL (1 << 6) 369#define NAU8825_POWERUP_ADCL (1 << 6)
283 370
284/* RDAC (0x73) */ 371/* RDAC (0x73) */
372#define NAU8825_RDAC_FS_BCLK_ENB (1 << 15)
373#define NAU8825_RDAC_EN_SFT 12
374#define NAU8825_RDAC_EN (0x3 << NAU8825_RDAC_EN_SFT)
375#define NAU8825_RDAC_CLK_EN_SFT 8
376#define NAU8825_RDAC_CLK_EN (0x3 << NAU8825_RDAC_CLK_EN_SFT)
285#define NAU8825_RDAC_CLK_DELAY_SFT 4 377#define NAU8825_RDAC_CLK_DELAY_SFT 4
286#define NAU8825_RDAC_CLK_DELAY_MASK (0x7 << NAU8825_RDAC_CLK_DELAY_SFT) 378#define NAU8825_RDAC_CLK_DELAY_MASK (0x7 << NAU8825_RDAC_CLK_DELAY_SFT)
287#define NAU8825_RDAC_VREF_SFT 2 379#define NAU8825_RDAC_VREF_SFT 2
@@ -318,8 +410,21 @@
318 410
319/* System Clock Source */ 411/* System Clock Source */
320enum { 412enum {
321 NAU8825_CLK_MCLK = 0, 413 NAU8825_CLK_DIS = 0,
414 NAU8825_CLK_MCLK,
322 NAU8825_CLK_INTERNAL, 415 NAU8825_CLK_INTERNAL,
416 NAU8825_CLK_FLL_MCLK,
417 NAU8825_CLK_FLL_BLK,
418 NAU8825_CLK_FLL_FS,
419};
420
421/* Cross talk detection state */
422enum {
423 NAU8825_XTALK_PREPARE = 0,
424 NAU8825_XTALK_HPR_R2L,
425 NAU8825_XTALK_HPL_R2L,
426 NAU8825_XTALK_IMM,
427 NAU8825_XTALK_DONE,
323}; 428};
324 429
325struct nau8825 { 430struct nau8825 {
@@ -328,6 +433,8 @@ struct nau8825 {
328 struct snd_soc_dapm_context *dapm; 433 struct snd_soc_dapm_context *dapm;
329 struct snd_soc_jack *jack; 434 struct snd_soc_jack *jack;
330 struct clk *mclk; 435 struct clk *mclk;
436 struct work_struct xtalk_work;
437 struct semaphore xtalk_sem;
331 int irq; 438 int irq;
332 int mclk_freq; /* 0 - mclk is disabled */ 439 int mclk_freq; /* 0 - mclk is disabled */
333 int button_pressed; 440 int button_pressed;
@@ -346,6 +453,12 @@ struct nau8825 {
346 int key_debounce; 453 int key_debounce;
347 int jack_insert_debounce; 454 int jack_insert_debounce;
348 int jack_eject_debounce; 455 int jack_eject_debounce;
456 int high_imped;
457 int xtalk_state;
458 int xtalk_event;
459 int xtalk_event_mask;
460 bool xtalk_protect;
461 int imp_rms[NAU8825_XTALK_IMM];
349}; 462};
350 463
351int nau8825_enable_jack_detect(struct snd_soc_codec *codec, 464int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c
index 58325234285c..33e1fc2d1598 100644
--- a/sound/soc/codecs/pcm1681.c
+++ b/sound/soc/codecs/pcm1681.c
@@ -73,7 +73,7 @@ static bool pcm1681_accessible_reg(struct device *dev, unsigned int reg)
73 return !((reg == 0x00) || (reg == 0x0f)); 73 return !((reg == 0x00) || (reg == 0x0f));
74} 74}
75 75
76static bool pcm1681_writeable_reg(struct device *dev, unsigned register reg) 76static bool pcm1681_writeable_reg(struct device *dev, unsigned int reg)
77{ 77{
78 return pcm1681_accessible_reg(dev, reg) && 78 return pcm1681_accessible_reg(dev, reg) &&
79 (reg != PCM1681_ZERO_DETECT_STATUS); 79 (reg != PCM1681_ZERO_DETECT_STATUS);
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c
index 06a66579ca6d..88fbdd184aa0 100644
--- a/sound/soc/codecs/pcm179x.c
+++ b/sound/soc/codecs/pcm179x.c
@@ -59,7 +59,7 @@ static bool pcm179x_accessible_reg(struct device *dev, unsigned int reg)
59 return reg >= 0x10 && reg <= 0x17; 59 return reg >= 0x10 && reg <= 0x17;
60} 60}
61 61
62static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) 62static bool pcm179x_writeable_reg(struct device *dev, unsigned int reg)
63{ 63{
64 bool accessible; 64 bool accessible;
65 65
diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c
index ed515677409b..8ba322a00363 100644
--- a/sound/soc/codecs/pcm5102a.c
+++ b/sound/soc/codecs/pcm5102a.c
@@ -57,7 +57,6 @@ static struct platform_driver pcm5102a_codec_driver = {
57 .remove = pcm5102a_remove, 57 .remove = pcm5102a_remove,
58 .driver = { 58 .driver = {
59 .name = "pcm5102a-codec", 59 .name = "pcm5102a-codec",
60 .owner = THIS_MODULE,
61 .of_match_table = pcm5102a_of_match, 60 .of_match_table = pcm5102a_of_match,
62 }, 61 },
63}; 62};
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 1bd31644a782..74c0e4eb3788 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -1100,6 +1100,13 @@ static const struct dmi_system_id force_combo_jack_table[] = {
1100 DMI_MATCH(DMI_PRODUCT_NAME, "Skylake Client platform") 1100 DMI_MATCH(DMI_PRODUCT_NAME, "Skylake Client platform")
1101 } 1101 }
1102 }, 1102 },
1103 {
1104 .ident = "Intel Kabylake RVP",
1105 .matches = {
1106 DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform")
1107 }
1108 },
1109
1103 { } 1110 { }
1104}; 1111};
1105 1112
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
new file mode 100644
index 000000000000..77ff8ebe6dfb
--- /dev/null
+++ b/sound/soc/codecs/rt5514-spi.c
@@ -0,0 +1,447 @@
1/*
2 * rt5514-spi.c -- RT5514 SPI driver
3 *
4 * Copyright 2015 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/input.h>
14#include <linux/spi/spi.h>
15#include <linux/device.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/slab.h>
21#include <linux/gpio.h>
22#include <linux/sched.h>
23#include <linux/kthread.h>
24#include <linux/uaccess.h>
25#include <linux/miscdevice.h>
26#include <linux/regulator/consumer.h>
27#include <linux/pm_qos.h>
28#include <linux/sysfs.h>
29#include <linux/clk.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37
38#include "rt5514-spi.h"
39
40static struct spi_device *rt5514_spi;
41
42struct rt5514_dsp {
43 struct device *dev;
44 struct delayed_work copy_work;
45 struct mutex dma_lock;
46 struct snd_pcm_substream *substream;
47 unsigned int buf_base, buf_limit, buf_rp;
48 size_t buf_size;
49 size_t dma_offset;
50 size_t dsp_offset;
51};
52
53static const struct snd_pcm_hardware rt5514_spi_pcm_hardware = {
54 .info = SNDRV_PCM_INFO_MMAP |
55 SNDRV_PCM_INFO_MMAP_VALID |
56 SNDRV_PCM_INFO_INTERLEAVED,
57 .formats = SNDRV_PCM_FMTBIT_S16_LE,
58 .period_bytes_min = PAGE_SIZE,
59 .period_bytes_max = 0x20000 / 8,
60 .periods_min = 8,
61 .periods_max = 8,
62 .channels_min = 1,
63 .channels_max = 1,
64 .buffer_bytes_max = 0x20000,
65};
66
67static struct snd_soc_dai_driver rt5514_spi_dai = {
68 .name = "rt5514-dsp-cpu-dai",
69 .id = 0,
70 .capture = {
71 .stream_name = "DSP Capture",
72 .channels_min = 1,
73 .channels_max = 1,
74 .rates = SNDRV_PCM_RATE_16000,
75 .formats = SNDRV_PCM_FMTBIT_S16_LE,
76 },
77};
78
79static void rt5514_spi_copy_work(struct work_struct *work)
80{
81 struct rt5514_dsp *rt5514_dsp =
82 container_of(work, struct rt5514_dsp, copy_work.work);
83 struct snd_pcm_runtime *runtime;
84 size_t period_bytes, truncated_bytes = 0;
85
86 mutex_lock(&rt5514_dsp->dma_lock);
87 if (!rt5514_dsp->substream) {
88 dev_err(rt5514_dsp->dev, "No pcm substream\n");
89 goto done;
90 }
91
92 runtime = rt5514_dsp->substream->runtime;
93 period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream);
94
95 if (rt5514_dsp->buf_size - rt5514_dsp->dsp_offset < period_bytes)
96 period_bytes = rt5514_dsp->buf_size - rt5514_dsp->dsp_offset;
97
98 if (rt5514_dsp->buf_rp + period_bytes <= rt5514_dsp->buf_limit) {
99 rt5514_spi_burst_read(rt5514_dsp->buf_rp,
100 runtime->dma_area + rt5514_dsp->dma_offset,
101 period_bytes);
102
103 if (rt5514_dsp->buf_rp + period_bytes == rt5514_dsp->buf_limit)
104 rt5514_dsp->buf_rp = rt5514_dsp->buf_base;
105 else
106 rt5514_dsp->buf_rp += period_bytes;
107 } else {
108 truncated_bytes = rt5514_dsp->buf_limit - rt5514_dsp->buf_rp;
109 rt5514_spi_burst_read(rt5514_dsp->buf_rp,
110 runtime->dma_area + rt5514_dsp->dma_offset,
111 truncated_bytes);
112
113 rt5514_spi_burst_read(rt5514_dsp->buf_base,
114 runtime->dma_area + rt5514_dsp->dma_offset +
115 truncated_bytes, period_bytes - truncated_bytes);
116
117 rt5514_dsp->buf_rp = rt5514_dsp->buf_base +
118 period_bytes - truncated_bytes;
119 }
120
121 rt5514_dsp->dma_offset += period_bytes;
122 if (rt5514_dsp->dma_offset >= runtime->dma_bytes)
123 rt5514_dsp->dma_offset = 0;
124
125 rt5514_dsp->dsp_offset += period_bytes;
126
127 snd_pcm_period_elapsed(rt5514_dsp->substream);
128
129 if (rt5514_dsp->dsp_offset < rt5514_dsp->buf_size)
130 schedule_delayed_work(&rt5514_dsp->copy_work, 5);
131done:
132 mutex_unlock(&rt5514_dsp->dma_lock);
133}
134
135/* PCM for streaming audio from the DSP buffer */
136static int rt5514_spi_pcm_open(struct snd_pcm_substream *substream)
137{
138 snd_soc_set_runtime_hwparams(substream, &rt5514_spi_pcm_hardware);
139
140 return 0;
141}
142
143static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
144 struct snd_pcm_hw_params *hw_params)
145{
146 struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 struct rt5514_dsp *rt5514_dsp =
148 snd_soc_platform_get_drvdata(rtd->platform);
149 int ret;
150
151 mutex_lock(&rt5514_dsp->dma_lock);
152 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
153 params_buffer_bytes(hw_params));
154 rt5514_dsp->substream = substream;
155 mutex_unlock(&rt5514_dsp->dma_lock);
156
157 return ret;
158}
159
160static int rt5514_spi_hw_free(struct snd_pcm_substream *substream)
161{
162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
163 struct rt5514_dsp *rt5514_dsp =
164 snd_soc_platform_get_drvdata(rtd->platform);
165
166 mutex_lock(&rt5514_dsp->dma_lock);
167 rt5514_dsp->substream = NULL;
168 mutex_unlock(&rt5514_dsp->dma_lock);
169
170 cancel_delayed_work_sync(&rt5514_dsp->copy_work);
171
172 return snd_pcm_lib_free_vmalloc_buffer(substream);
173}
174
175static int rt5514_spi_prepare(struct snd_pcm_substream *substream)
176{
177 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178 struct rt5514_dsp *rt5514_dsp =
179 snd_soc_platform_get_drvdata(rtd->platform);
180 u8 buf[8];
181
182 rt5514_dsp->dma_offset = 0;
183 rt5514_dsp->dsp_offset = 0;
184
185 /**
186 * The address area x1800XXXX is the register address, and it cannot
187 * support spi burst read perfectly. So we use the spi burst read
188 * individually to make sure the data correctly.
189 */
190 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf,
191 sizeof(buf));
192 rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 |
193 buf[3] << 24;
194
195 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf,
196 sizeof(buf));
197 rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 |
198 buf[3] << 24;
199
200 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_RP, (u8 *)&buf,
201 sizeof(buf));
202 rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 |
203 buf[3] << 24;
204
205 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_SIZE, (u8 *)&buf,
206 sizeof(buf));
207 rt5514_dsp->buf_size = buf[0] | buf[1] << 8 | buf[2] << 16 |
208 buf[3] << 24;
209
210 return 0;
211}
212
213static int rt5514_spi_trigger(struct snd_pcm_substream *substream, int cmd)
214{
215 struct snd_soc_pcm_runtime *rtd = substream->private_data;
216 struct rt5514_dsp *rt5514_dsp =
217 snd_soc_platform_get_drvdata(rtd->platform);
218
219 if (cmd == SNDRV_PCM_TRIGGER_START) {
220 if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
221 rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
222 schedule_delayed_work(&rt5514_dsp->copy_work, 0);
223 }
224
225 return 0;
226}
227
228static snd_pcm_uframes_t rt5514_spi_pcm_pointer(
229 struct snd_pcm_substream *substream)
230{
231 struct snd_pcm_runtime *runtime = substream->runtime;
232 struct snd_soc_pcm_runtime *rtd = substream->private_data;
233 struct rt5514_dsp *rt5514_dsp =
234 snd_soc_platform_get_drvdata(rtd->platform);
235
236 return bytes_to_frames(runtime, rt5514_dsp->dma_offset);
237}
238
239static struct snd_pcm_ops rt5514_spi_pcm_ops = {
240 .open = rt5514_spi_pcm_open,
241 .hw_params = rt5514_spi_hw_params,
242 .hw_free = rt5514_spi_hw_free,
243 .trigger = rt5514_spi_trigger,
244 .prepare = rt5514_spi_prepare,
245 .pointer = rt5514_spi_pcm_pointer,
246 .mmap = snd_pcm_lib_mmap_vmalloc,
247 .page = snd_pcm_lib_get_vmalloc_page,
248};
249
250static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform)
251{
252 struct rt5514_dsp *rt5514_dsp;
253
254 rt5514_dsp = devm_kzalloc(platform->dev, sizeof(*rt5514_dsp),
255 GFP_KERNEL);
256
257 rt5514_dsp->dev = &rt5514_spi->dev;
258 mutex_init(&rt5514_dsp->dma_lock);
259 INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work);
260 snd_soc_platform_set_drvdata(platform, rt5514_dsp);
261
262 return 0;
263}
264
265static struct snd_soc_platform_driver rt5514_spi_platform = {
266 .probe = rt5514_spi_pcm_probe,
267 .ops = &rt5514_spi_pcm_ops,
268};
269
270static const struct snd_soc_component_driver rt5514_spi_dai_component = {
271 .name = "rt5514-spi-dai",
272};
273
274/**
275 * rt5514_spi_burst_read - Read data from SPI by rt5514 address.
276 * @addr: Start address.
277 * @rxbuf: Data Buffer for reading.
278 * @len: Data length, it must be a multiple of 8.
279 *
280 *
281 * Returns true for success.
282 */
283int rt5514_spi_burst_read(unsigned int addr, u8 *rxbuf, size_t len)
284{
285 u8 spi_cmd = RT5514_SPI_CMD_BURST_READ;
286 int status;
287 u8 write_buf[8];
288 unsigned int i, end, offset = 0;
289
290 struct spi_message message;
291 struct spi_transfer x[3];
292
293 while (offset < len) {
294 if (offset + RT5514_SPI_BUF_LEN <= len)
295 end = RT5514_SPI_BUF_LEN;
296 else
297 end = len % RT5514_SPI_BUF_LEN;
298
299 write_buf[0] = spi_cmd;
300 write_buf[1] = ((addr + offset) & 0xff000000) >> 24;
301 write_buf[2] = ((addr + offset) & 0x00ff0000) >> 16;
302 write_buf[3] = ((addr + offset) & 0x0000ff00) >> 8;
303 write_buf[4] = ((addr + offset) & 0x000000ff) >> 0;
304
305 spi_message_init(&message);
306 memset(x, 0, sizeof(x));
307
308 x[0].len = 5;
309 x[0].tx_buf = write_buf;
310 spi_message_add_tail(&x[0], &message);
311
312 x[1].len = 4;
313 x[1].tx_buf = write_buf;
314 spi_message_add_tail(&x[1], &message);
315
316 x[2].len = end;
317 x[2].rx_buf = rxbuf + offset;
318 spi_message_add_tail(&x[2], &message);
319
320 status = spi_sync(rt5514_spi, &message);
321
322 if (status)
323 return false;
324
325 offset += RT5514_SPI_BUF_LEN;
326 }
327
328 for (i = 0; i < len; i += 8) {
329 write_buf[0] = rxbuf[i + 0];
330 write_buf[1] = rxbuf[i + 1];
331 write_buf[2] = rxbuf[i + 2];
332 write_buf[3] = rxbuf[i + 3];
333 write_buf[4] = rxbuf[i + 4];
334 write_buf[5] = rxbuf[i + 5];
335 write_buf[6] = rxbuf[i + 6];
336 write_buf[7] = rxbuf[i + 7];
337
338 rxbuf[i + 0] = write_buf[7];
339 rxbuf[i + 1] = write_buf[6];
340 rxbuf[i + 2] = write_buf[5];
341 rxbuf[i + 3] = write_buf[4];
342 rxbuf[i + 4] = write_buf[3];
343 rxbuf[i + 5] = write_buf[2];
344 rxbuf[i + 6] = write_buf[1];
345 rxbuf[i + 7] = write_buf[0];
346 }
347
348 return true;
349}
350
351/**
352 * rt5514_spi_burst_write - Write data to SPI by rt5514 address.
353 * @addr: Start address.
354 * @txbuf: Data Buffer for writng.
355 * @len: Data length, it must be a multiple of 8.
356 *
357 *
358 * Returns true for success.
359 */
360int rt5514_spi_burst_write(u32 addr, const u8 *txbuf, size_t len)
361{
362 u8 spi_cmd = RT5514_SPI_CMD_BURST_WRITE;
363 u8 *write_buf;
364 unsigned int i, end, offset = 0;
365
366 write_buf = kmalloc(RT5514_SPI_BUF_LEN + 6, GFP_KERNEL);
367
368 if (write_buf == NULL)
369 return -ENOMEM;
370
371 while (offset < len) {
372 if (offset + RT5514_SPI_BUF_LEN <= len)
373 end = RT5514_SPI_BUF_LEN;
374 else
375 end = len % RT5514_SPI_BUF_LEN;
376
377 write_buf[0] = spi_cmd;
378 write_buf[1] = ((addr + offset) & 0xff000000) >> 24;
379 write_buf[2] = ((addr + offset) & 0x00ff0000) >> 16;
380 write_buf[3] = ((addr + offset) & 0x0000ff00) >> 8;
381 write_buf[4] = ((addr + offset) & 0x000000ff) >> 0;
382
383 for (i = 0; i < end; i += 8) {
384 write_buf[i + 12] = txbuf[offset + i + 0];
385 write_buf[i + 11] = txbuf[offset + i + 1];
386 write_buf[i + 10] = txbuf[offset + i + 2];
387 write_buf[i + 9] = txbuf[offset + i + 3];
388 write_buf[i + 8] = txbuf[offset + i + 4];
389 write_buf[i + 7] = txbuf[offset + i + 5];
390 write_buf[i + 6] = txbuf[offset + i + 6];
391 write_buf[i + 5] = txbuf[offset + i + 7];
392 }
393
394 write_buf[end + 5] = spi_cmd;
395
396 spi_write(rt5514_spi, write_buf, end + 6);
397
398 offset += RT5514_SPI_BUF_LEN;
399 }
400
401 kfree(write_buf);
402
403 return 0;
404}
405EXPORT_SYMBOL_GPL(rt5514_spi_burst_write);
406
407static int rt5514_spi_probe(struct spi_device *spi)
408{
409 int ret;
410
411 rt5514_spi = spi;
412
413 ret = devm_snd_soc_register_platform(&spi->dev, &rt5514_spi_platform);
414 if (ret < 0) {
415 dev_err(&spi->dev, "Failed to register platform.\n");
416 return ret;
417 }
418
419 ret = devm_snd_soc_register_component(&spi->dev,
420 &rt5514_spi_dai_component,
421 &rt5514_spi_dai, 1);
422 if (ret < 0) {
423 dev_err(&spi->dev, "Failed to register component.\n");
424 return ret;
425 }
426
427 return 0;
428}
429
430static const struct of_device_id rt5514_of_match[] = {
431 { .compatible = "realtek,rt5514", },
432 {},
433};
434MODULE_DEVICE_TABLE(of, rt5514_of_match);
435
436static struct spi_driver rt5514_spi_driver = {
437 .driver = {
438 .name = "rt5514",
439 .of_match_table = of_match_ptr(rt5514_of_match),
440 },
441 .probe = rt5514_spi_probe,
442};
443module_spi_driver(rt5514_spi_driver);
444
445MODULE_DESCRIPTION("RT5514 SPI driver");
446MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
447MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5514-spi.h b/sound/soc/codecs/rt5514-spi.h
new file mode 100644
index 000000000000..f69b1cdf2f9b
--- /dev/null
+++ b/sound/soc/codecs/rt5514-spi.h
@@ -0,0 +1,38 @@
1/*
2 * rt5514-spi.h -- RT5514 driver
3 *
4 * Copyright 2015 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __RT5514_SPI_H__
13#define __RT5514_SPI_H__
14
15/**
16 * RT5514_SPI_BUF_LEN is the buffer size of SPI master controller.
17*/
18#define RT5514_SPI_BUF_LEN 240
19
20#define RT5514_BUFFER_VOICE_BASE 0x18001034
21#define RT5514_BUFFER_VOICE_LIMIT 0x18001038
22#define RT5514_BUFFER_VOICE_RP 0x1800103c
23#define RT5514_BUFFER_VOICE_SIZE 0x18001040
24
25/* SPI Command */
26enum {
27 RT5514_SPI_CMD_16_READ = 0,
28 RT5514_SPI_CMD_16_WRITE,
29 RT5514_SPI_CMD_32_READ,
30 RT5514_SPI_CMD_32_WRITE,
31 RT5514_SPI_CMD_BURST_READ,
32 RT5514_SPI_CMD_BURST_WRITE,
33};
34
35int rt5514_spi_burst_read(unsigned int addr, u8 *rxbuf, size_t len);
36int rt5514_spi_burst_write(u32 addr, const u8 *txbuf, size_t len);
37
38#endif /* __RT5514_SPI_H__ */
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index 879bf60f4965..7162f05101d9 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -30,6 +30,9 @@
30 30
31#include "rl6231.h" 31#include "rl6231.h"
32#include "rt5514.h" 32#include "rt5514.h"
33#if defined(CONFIG_SND_SOC_RT5514_SPI)
34#include "rt5514-spi.h"
35#endif
33 36
34static const struct reg_sequence rt5514_i2c_patch[] = { 37static const struct reg_sequence rt5514_i2c_patch[] = {
35 {0x1800101c, 0x00000000}, 38 {0x1800101c, 0x00000000},
@@ -110,6 +113,35 @@ static const struct reg_default rt5514_reg[] = {
110 {RT5514_VENDOR_ID2, 0x10ec5514}, 113 {RT5514_VENDOR_ID2, 0x10ec5514},
111}; 114};
112 115
116static void rt5514_enable_dsp_prepare(struct rt5514_priv *rt5514)
117{
118 /* Reset */
119 regmap_write(rt5514->i2c_regmap, 0x18002000, 0x000010ec);
120 /* LDO_I_limit */
121 regmap_write(rt5514->i2c_regmap, 0x18002200, 0x00028604);
122 /* I2C bypass enable */
123 regmap_write(rt5514->i2c_regmap, 0xfafafafa, 0x00000001);
124 /* mini-core reset */
125 regmap_write(rt5514->i2c_regmap, 0x18002f00, 0x0005514b);
126 regmap_write(rt5514->i2c_regmap, 0x18002f00, 0x00055149);
127 /* I2C bypass disable */
128 regmap_write(rt5514->i2c_regmap, 0xfafafafa, 0x00000000);
129 /* PIN config */
130 regmap_write(rt5514->i2c_regmap, 0x18002070, 0x00000040);
131 /* PLL3(QN)=RCOSC*(10+2) */
132 regmap_write(rt5514->i2c_regmap, 0x18002240, 0x0000000a);
133 /* PLL3 source=RCOSC, fsi=rt_clk */
134 regmap_write(rt5514->i2c_regmap, 0x18002100, 0x0000000b);
135 /* Power on RCOSC, pll3 */
136 regmap_write(rt5514->i2c_regmap, 0x18002004, 0x00808b81);
137 /* DSP clk source = pll3, ENABLE DSP clk */
138 regmap_write(rt5514->i2c_regmap, 0x18002f08, 0x00000005);
139 /* Enable DSP clk auto switch */
140 regmap_write(rt5514->i2c_regmap, 0x18001114, 0x00000001);
141 /* Reduce DSP power */
142 regmap_write(rt5514->i2c_regmap, 0x18001118, 0x00000001);
143}
144
113static bool rt5514_volatile_register(struct device *dev, unsigned int reg) 145static bool rt5514_volatile_register(struct device *dev, unsigned int reg)
114{ 146{
115 switch (reg) { 147 switch (reg) {
@@ -248,6 +280,74 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv,
248 280
249static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); 281static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
250 282
283static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol,
284 struct snd_ctl_elem_value *ucontrol)
285{
286 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
287 struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
288
289 ucontrol->value.integer.value[0] = rt5514->dsp_enabled;
290
291 return 0;
292}
293
294static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
295 struct snd_ctl_elem_value *ucontrol)
296{
297 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
298 struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
299 struct snd_soc_codec *codec = rt5514->codec;
300 const struct firmware *fw = NULL;
301
302 if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled)
303 return 0;
304
305 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
306 rt5514->dsp_enabled = ucontrol->value.integer.value[0];
307
308 if (rt5514->dsp_enabled) {
309 rt5514_enable_dsp_prepare(rt5514);
310
311 request_firmware(&fw, RT5514_FIRMWARE1, codec->dev);
312 if (fw) {
313#if defined(CONFIG_SND_SOC_RT5514_SPI)
314 rt5514_spi_burst_write(0x4ff60000, fw->data,
315 ((fw->size/8)+1)*8);
316#else
317 dev_err(codec->dev, "There is no SPI driver for"
318 " loading the firmware\n");
319#endif
320 release_firmware(fw);
321 fw = NULL;
322 }
323
324 request_firmware(&fw, RT5514_FIRMWARE2, codec->dev);
325 if (fw) {
326#if defined(CONFIG_SND_SOC_RT5514_SPI)
327 rt5514_spi_burst_write(0x4ffc0000, fw->data,
328 ((fw->size/8)+1)*8);
329#else
330 dev_err(codec->dev, "There is no SPI driver for"
331 " loading the firmware\n");
332#endif
333 release_firmware(fw);
334 fw = NULL;
335 }
336
337 /* DSP run */
338 regmap_write(rt5514->i2c_regmap, 0x18002f00,
339 0x00055148);
340 } else {
341 regmap_multi_reg_write(rt5514->i2c_regmap,
342 rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch));
343 regcache_mark_dirty(rt5514->regmap);
344 regcache_sync(rt5514->regmap);
345 }
346 }
347
348 return 0;
349}
350
251static const struct snd_kcontrol_new rt5514_snd_controls[] = { 351static const struct snd_kcontrol_new rt5514_snd_controls[] = {
252 SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST, 352 SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
253 RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), 353 RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
@@ -257,6 +357,8 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = {
257 SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1, 357 SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1,
258 RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 127, 0, 358 RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 127, 0,
259 adc_vol_tlv), 359 adc_vol_tlv),
360 SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0,
361 rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put),
260}; 362};
261 363
262/* ADC Mixer*/ 364/* ADC Mixer*/
@@ -365,6 +467,35 @@ static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
365 return 0; 467 return 0;
366} 468}
367 469
470static int rt5514_pre_event(struct snd_soc_dapm_widget *w,
471 struct snd_kcontrol *kcontrol, int event)
472{
473 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
474 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
475
476 switch (event) {
477 case SND_SOC_DAPM_PRE_PMU:
478 /**
479 * If the DSP is enabled in start of recording, the DSP
480 * should be disabled, and sync back to normal recording
481 * settings to make sure recording properly.
482 */
483 if (rt5514->dsp_enabled) {
484 rt5514->dsp_enabled = 0;
485 regmap_multi_reg_write(rt5514->i2c_regmap,
486 rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch));
487 regcache_mark_dirty(rt5514->regmap);
488 regcache_sync(rt5514->regmap);
489 }
490 break;
491
492 default:
493 return 0;
494 }
495
496 return 0;
497}
498
368static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { 499static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = {
369 /* Input Lines */ 500 /* Input Lines */
370 SND_SOC_DAPM_INPUT("DMIC1L"), 501 SND_SOC_DAPM_INPUT("DMIC1L"),
@@ -472,6 +603,8 @@ static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = {
472 603
473 /* Audio Interface */ 604 /* Audio Interface */
474 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), 605 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
606
607 SND_SOC_DAPM_PRE("DAPM Pre", rt5514_pre_event),
475}; 608};
476 609
477static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { 610static const struct snd_soc_dapm_route rt5514_dapm_routes[] = {
@@ -799,10 +932,41 @@ static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
799 return 0; 932 return 0;
800} 933}
801 934
935static int rt5514_set_bias_level(struct snd_soc_codec *codec,
936 enum snd_soc_bias_level level)
937{
938 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
939 int ret;
940
941 switch (level) {
942 case SND_SOC_BIAS_PREPARE:
943 if (IS_ERR(rt5514->mclk))
944 break;
945
946 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
947 clk_disable_unprepare(rt5514->mclk);
948 } else {
949 ret = clk_prepare_enable(rt5514->mclk);
950 if (ret)
951 return ret;
952 }
953 break;
954
955 default:
956 break;
957 }
958
959 return 0;
960}
961
802static int rt5514_probe(struct snd_soc_codec *codec) 962static int rt5514_probe(struct snd_soc_codec *codec)
803{ 963{
804 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); 964 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
805 965
966 rt5514->mclk = devm_clk_get(codec->dev, "mclk");
967 if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER)
968 return -EPROBE_DEFER;
969
806 rt5514->codec = codec; 970 rt5514->codec = codec;
807 971
808 return 0; 972 return 0;
@@ -858,6 +1022,7 @@ struct snd_soc_dai_driver rt5514_dai[] = {
858static struct snd_soc_codec_driver soc_codec_dev_rt5514 = { 1022static struct snd_soc_codec_driver soc_codec_dev_rt5514 = {
859 .probe = rt5514_probe, 1023 .probe = rt5514_probe,
860 .idle_bias_off = true, 1024 .idle_bias_off = true,
1025 .set_bias_level = rt5514_set_bias_level,
861 .controls = rt5514_snd_controls, 1026 .controls = rt5514_snd_controls,
862 .num_controls = ARRAY_SIZE(rt5514_snd_controls), 1027 .num_controls = ARRAY_SIZE(rt5514_snd_controls),
863 .dapm_widgets = rt5514_dapm_widgets, 1028 .dapm_widgets = rt5514_dapm_widgets,
@@ -871,7 +1036,6 @@ static const struct regmap_config rt5514_i2c_regmap = {
871 .reg_bits = 32, 1036 .reg_bits = 32,
872 .val_bits = 32, 1037 .val_bits = 32,
873 1038
874 .max_register = RT5514_DSP_MAPPING | RT5514_VENDOR_ID2,
875 .readable_reg = rt5514_i2c_readable_register, 1039 .readable_reg = rt5514_i2c_readable_register,
876 1040
877 .cache_type = REGCACHE_NONE, 1041 .cache_type = REGCACHE_NONE,
@@ -944,7 +1108,7 @@ static int rt5514_i2c_probe(struct i2c_client *i2c,
944 return -ENODEV; 1108 return -ENODEV;
945 } 1109 }
946 1110
947 ret = regmap_register_patch(rt5514->i2c_regmap, rt5514_i2c_patch, 1111 ret = regmap_multi_reg_write(rt5514->i2c_regmap, rt5514_i2c_patch,
948 ARRAY_SIZE(rt5514_i2c_patch)); 1112 ARRAY_SIZE(rt5514_i2c_patch));
949 if (ret != 0) 1113 if (ret != 0)
950 dev_warn(&i2c->dev, "Failed to apply i2c_regmap patch: %d\n", 1114 dev_warn(&i2c->dev, "Failed to apply i2c_regmap patch: %d\n",
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h
index 6ad8a612f659..68883c68e999 100644
--- a/sound/soc/codecs/rt5514.h
+++ b/sound/soc/codecs/rt5514.h
@@ -12,6 +12,8 @@
12#ifndef __RT5514_H__ 12#ifndef __RT5514_H__
13#define __RT5514_H__ 13#define __RT5514_H__
14 14
15#include <linux/clk.h>
16
15#define RT5514_DEVICE_ID 0x10ec5514 17#define RT5514_DEVICE_ID 0x10ec5514
16 18
17#define RT5514_RESET 0x2000 19#define RT5514_RESET 0x2000
@@ -225,6 +227,9 @@
225#define RT5514_PLL_INP_MAX 40000000 227#define RT5514_PLL_INP_MAX 40000000
226#define RT5514_PLL_INP_MIN 256000 228#define RT5514_PLL_INP_MIN 256000
227 229
230#define RT5514_FIRMWARE1 "rt5514_dsp_fw1.bin"
231#define RT5514_FIRMWARE2 "rt5514_dsp_fw2.bin"
232
228/* System Clock Source */ 233/* System Clock Source */
229enum { 234enum {
230 RT5514_SCLK_S_MCLK, 235 RT5514_SCLK_S_MCLK,
@@ -240,6 +245,7 @@ enum {
240struct rt5514_priv { 245struct rt5514_priv {
241 struct snd_soc_codec *codec; 246 struct snd_soc_codec *codec;
242 struct regmap *i2c_regmap, *regmap; 247 struct regmap *i2c_regmap, *regmap;
248 struct clk *mclk;
243 int sysclk; 249 int sysclk;
244 int sysclk_src; 250 int sysclk_src;
245 int lrck; 251 int lrck;
@@ -247,6 +253,7 @@ struct rt5514_priv {
247 int pll_src; 253 int pll_src;
248 int pll_in; 254 int pll_in;
249 int pll_out; 255 int pll_out;
256 int dsp_enabled;
250}; 257};
251 258
252#endif /* __RT5514_H__ */ 259#endif /* __RT5514_H__ */
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index d70847c9eeb0..490bfe661346 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -63,6 +63,7 @@ static const struct reg_sequence init_list[] = {
63 {RT5645_PR_BASE + 0x20, 0x611f}, 63 {RT5645_PR_BASE + 0x20, 0x611f},
64 {RT5645_PR_BASE + 0x21, 0x4040}, 64 {RT5645_PR_BASE + 0x21, 0x4040},
65 {RT5645_PR_BASE + 0x23, 0x0004}, 65 {RT5645_PR_BASE + 0x23, 0x0004},
66 {RT5645_ASRC_4, 0x0120},
66}; 67};
67 68
68static const struct reg_sequence rt5650_init_list[] = { 69static const struct reg_sequence rt5650_init_list[] = {
@@ -157,7 +158,7 @@ static const struct reg_default rt5645_reg[] = {
157 { 0x83, 0x0000 }, 158 { 0x83, 0x0000 },
158 { 0x84, 0x0000 }, 159 { 0x84, 0x0000 },
159 { 0x85, 0x0000 }, 160 { 0x85, 0x0000 },
160 { 0x8a, 0x0000 }, 161 { 0x8a, 0x0120 },
161 { 0x8e, 0x0004 }, 162 { 0x8e, 0x0004 },
162 { 0x8f, 0x1100 }, 163 { 0x8f, 0x1100 },
163 { 0x90, 0x0646 }, 164 { 0x90, 0x0646 },
@@ -314,7 +315,7 @@ static const struct reg_default rt5650_reg[] = {
314 { 0x83, 0x0000 }, 315 { 0x83, 0x0000 },
315 { 0x84, 0x0000 }, 316 { 0x84, 0x0000 },
316 { 0x85, 0x0000 }, 317 { 0x85, 0x0000 },
317 { 0x8a, 0x0000 }, 318 { 0x8a, 0x0120 },
318 { 0x8e, 0x0004 }, 319 { 0x8e, 0x0004 },
319 { 0x8f, 0x1100 }, 320 { 0x8f, 0x1100 },
320 { 0x90, 0x0646 }, 321 { 0x90, 0x0646 },
@@ -440,6 +441,7 @@ static bool rt5645_volatile_register(struct device *dev, unsigned int reg)
440 441
441 switch (reg) { 442 switch (reg) {
442 case RT5645_RESET: 443 case RT5645_RESET:
444 case RT5645_PRIV_INDEX:
443 case RT5645_PRIV_DATA: 445 case RT5645_PRIV_DATA:
444 case RT5645_IN1_CTRL1: 446 case RT5645_IN1_CTRL1:
445 case RT5645_IN1_CTRL2: 447 case RT5645_IN1_CTRL2:
@@ -740,6 +742,14 @@ static int rt5645_spk_put_volsw(struct snd_kcontrol *kcontrol,
740 return ret; 742 return ret;
741} 743}
742 744
745static const char * const rt5645_dac1_vol_ctrl_mode_text[] = {
746 "immediately", "zero crossing", "soft ramp"
747};
748
749static SOC_ENUM_SINGLE_DECL(
750 rt5645_dac1_vol_ctrl_mode, RT5645_PR_BASE,
751 RT5645_DA1_ZDET_SFT, rt5645_dac1_vol_ctrl_mode_text);
752
743static const struct snd_kcontrol_new rt5645_snd_controls[] = { 753static const struct snd_kcontrol_new rt5645_snd_controls[] = {
744 /* Speaker Output Volume */ 754 /* Speaker Output Volume */
745 SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, 755 SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL,
@@ -806,6 +816,9 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
806 SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, 816 SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT,
807 1, 1), 817 1, 1),
808 RT5645_HWEQ("Speaker HWEQ"), 818 RT5645_HWEQ("Speaker HWEQ"),
819
820 /* Digital Soft Volume Control */
821 SOC_ENUM("DAC1 Digital Volume Control Func", rt5645_dac1_vol_ctrl_mode),
809}; 822};
810 823
811/** 824/**
@@ -3531,6 +3544,7 @@ MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
3531static const struct acpi_device_id rt5645_acpi_match[] = { 3544static const struct acpi_device_id rt5645_acpi_match[] = {
3532 { "10EC5645", 0 }, 3545 { "10EC5645", 0 },
3533 { "10EC5650", 0 }, 3546 { "10EC5650", 0 },
3547 { "10EC5640", 0 },
3534 {}, 3548 {},
3535}; 3549};
3536MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); 3550MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
@@ -3561,6 +3575,12 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
3561 DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), 3575 DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"),
3562 }, 3576 },
3563 }, 3577 },
3578 {
3579 .ident = "Microsoft Surface 3",
3580 .matches = {
3581 DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
3582 },
3583 },
3564 { } 3584 { }
3565}; 3585};
3566 3586
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index 205e0715c99a..cfc5f97549eb 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -2018,6 +2018,9 @@
2018 2018
2019 2019
2020/* Codec Private Register definition */ 2020/* Codec Private Register definition */
2021/* DAC ADC Digital Volume (0x00) */
2022#define RT5645_DA1_ZDET_SFT 6
2023
2021/* 3D Speaker Control (0x63) */ 2024/* 3D Speaker Control (0x63) */
2022#define RT5645_3D_SPK_MASK (0x1 << 15) 2025#define RT5645_3D_SPK_MASK (0x1 << 15)
2023#define RT5645_3D_SPK_SFT 15 2026#define RT5645_3D_SPK_SFT 15
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 0af5ddbef1da..8ef467f64f03 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -55,6 +55,7 @@ static const struct reg_sequence init_list[] = {
55 { RT5670_PR_BASE + 0x14, 0x9a8a }, 55 { RT5670_PR_BASE + 0x14, 0x9a8a },
56 { RT5670_PR_BASE + 0x38, 0x3ba1 }, 56 { RT5670_PR_BASE + 0x38, 0x3ba1 },
57 { RT5670_PR_BASE + 0x3d, 0x3640 }, 57 { RT5670_PR_BASE + 0x3d, 0x3640 },
58 { 0x8a, 0x0123 },
58}; 59};
59 60
60static const struct reg_default rt5670_reg[] = { 61static const struct reg_default rt5670_reg[] = {
@@ -131,7 +132,7 @@ static const struct reg_default rt5670_reg[] = {
131 { 0x87, 0x0000 }, 132 { 0x87, 0x0000 },
132 { 0x88, 0x0000 }, 133 { 0x88, 0x0000 },
133 { 0x89, 0x0000 }, 134 { 0x89, 0x0000 },
134 { 0x8a, 0x0000 }, 135 { 0x8a, 0x0123 },
135 { 0x8b, 0x0000 }, 136 { 0x8b, 0x0000 },
136 { 0x8c, 0x0003 }, 137 { 0x8c, 0x0003 },
137 { 0x8d, 0x0000 }, 138 { 0x8d, 0x0000 },
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 08b40460663c..527b759c1562 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -38,7 +38,6 @@
38/* default value of sgtl5000 registers */ 38/* default value of sgtl5000 registers */
39static const struct reg_default sgtl5000_reg_defaults[] = { 39static const struct reg_default sgtl5000_reg_defaults[] = {
40 { SGTL5000_CHIP_DIG_POWER, 0x0000 }, 40 { SGTL5000_CHIP_DIG_POWER, 0x0000 },
41 { SGTL5000_CHIP_CLK_CTRL, 0x0008 },
42 { SGTL5000_CHIP_I2S_CTRL, 0x0010 }, 41 { SGTL5000_CHIP_I2S_CTRL, 0x0010 },
43 { SGTL5000_CHIP_SSS_CTRL, 0x0010 }, 42 { SGTL5000_CHIP_SSS_CTRL, 0x0010 },
44 { SGTL5000_CHIP_ADCDAC_CTRL, 0x020c }, 43 { SGTL5000_CHIP_ADCDAC_CTRL, 0x020c },
@@ -47,12 +46,10 @@ static const struct reg_default sgtl5000_reg_defaults[] = {
47 { SGTL5000_CHIP_ANA_ADC_CTRL, 0x0000 }, 46 { SGTL5000_CHIP_ANA_ADC_CTRL, 0x0000 },
48 { SGTL5000_CHIP_ANA_HP_CTRL, 0x1818 }, 47 { SGTL5000_CHIP_ANA_HP_CTRL, 0x1818 },
49 { SGTL5000_CHIP_ANA_CTRL, 0x0111 }, 48 { SGTL5000_CHIP_ANA_CTRL, 0x0111 },
50 { SGTL5000_CHIP_LINREG_CTRL, 0x0000 },
51 { SGTL5000_CHIP_REF_CTRL, 0x0000 }, 49 { SGTL5000_CHIP_REF_CTRL, 0x0000 },
52 { SGTL5000_CHIP_MIC_CTRL, 0x0000 }, 50 { SGTL5000_CHIP_MIC_CTRL, 0x0000 },
53 { SGTL5000_CHIP_LINE_OUT_CTRL, 0x0000 }, 51 { SGTL5000_CHIP_LINE_OUT_CTRL, 0x0000 },
54 { SGTL5000_CHIP_LINE_OUT_VOL, 0x0404 }, 52 { SGTL5000_CHIP_LINE_OUT_VOL, 0x0404 },
55 { SGTL5000_CHIP_ANA_POWER, 0x7060 },
56 { SGTL5000_CHIP_PLL_CTRL, 0x5000 }, 53 { SGTL5000_CHIP_PLL_CTRL, 0x5000 },
57 { SGTL5000_CHIP_CLK_TOP_CTRL, 0x0000 }, 54 { SGTL5000_CHIP_CLK_TOP_CTRL, 0x0000 },
58 { SGTL5000_CHIP_ANA_STATUS, 0x0000 }, 55 { SGTL5000_CHIP_ANA_STATUS, 0x0000 },
@@ -92,35 +89,8 @@ static const char *supply_names[SGTL5000_SUPPLY_NUM] = {
92 "VDDD" 89 "VDDD"
93}; 90};
94 91
95#define LDO_CONSUMER_NAME "VDDD_LDO"
96#define LDO_VOLTAGE 1200000 92#define LDO_VOLTAGE 1200000
97 93#define LINREG_VDDD ((1600 - LDO_VOLTAGE / 1000) / 50)
98static struct regulator_consumer_supply ldo_consumer[] = {
99 REGULATOR_SUPPLY(LDO_CONSUMER_NAME, NULL),
100};
101
102static struct regulator_init_data ldo_init_data = {
103 .constraints = {
104 .min_uV = 1200000,
105 .max_uV = 1200000,
106 .valid_modes_mask = REGULATOR_MODE_NORMAL,
107 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
108 },
109 .num_consumer_supplies = 1,
110 .consumer_supplies = &ldo_consumer[0],
111};
112
113/*
114 * sgtl5000 internal ldo regulator,
115 * enabled when VDDD not provided
116 */
117struct ldo_regulator {
118 struct regulator_desc desc;
119 struct regulator_dev *dev;
120 int voltage;
121 void *codec_data;
122 bool enabled;
123};
124 94
125enum sgtl5000_micbias_resistor { 95enum sgtl5000_micbias_resistor {
126 SGTL5000_MICBIAS_OFF = 0, 96 SGTL5000_MICBIAS_OFF = 0,
@@ -135,7 +105,7 @@ struct sgtl5000_priv {
135 int master; /* i2s master or not */ 105 int master; /* i2s master or not */
136 int fmt; /* i2s data format */ 106 int fmt; /* i2s data format */
137 struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM]; 107 struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
138 struct ldo_regulator *ldo; 108 int num_supplies;
139 struct regmap *regmap; 109 struct regmap *regmap;
140 struct clk *mclk; 110 struct clk *mclk;
141 int revision; 111 int revision;
@@ -415,6 +385,9 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
415/* tlv for hp volume, -51.5db to 12.0db, step .5db */ 385/* tlv for hp volume, -51.5db to 12.0db, step .5db */
416static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0); 386static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
417 387
388/* tlv for lineout volume, 31 steps of .5db each */
389static const DECLARE_TLV_DB_SCALE(lineout_volume, -1550, 50, 0);
390
418static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { 391static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
419 /* SOC_DOUBLE_S8_TLV with invert */ 392 /* SOC_DOUBLE_S8_TLV with invert */
420 { 393 {
@@ -443,6 +416,13 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
443 416
444 SOC_SINGLE_TLV("Mic Volume", SGTL5000_CHIP_MIC_CTRL, 417 SOC_SINGLE_TLV("Mic Volume", SGTL5000_CHIP_MIC_CTRL,
445 0, 3, 0, mic_gain_tlv), 418 0, 3, 0, mic_gain_tlv),
419
420 SOC_DOUBLE_TLV("Lineout Playback Volume",
421 SGTL5000_CHIP_LINE_OUT_VOL,
422 SGTL5000_LINE_OUT_VOL_LEFT_SHIFT,
423 SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT,
424 0x1f, 1,
425 lineout_volume),
446}; 426};
447 427
448/* mute the codec used by alsa core */ 428/* mute the codec used by alsa core */
@@ -778,155 +758,6 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
778 return 0; 758 return 0;
779} 759}
780 760
781#ifdef CONFIG_REGULATOR
782static int ldo_regulator_is_enabled(struct regulator_dev *dev)
783{
784 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
785
786 return ldo->enabled;
787}
788
789static int ldo_regulator_enable(struct regulator_dev *dev)
790{
791 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
792 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
793 int reg;
794
795 if (ldo_regulator_is_enabled(dev))
796 return 0;
797
798 /* set regulator value firstly */
799 reg = (1600 - ldo->voltage / 1000) / 50;
800 reg = clamp(reg, 0x0, 0xf);
801
802 /* amend the voltage value, unit: uV */
803 ldo->voltage = (1600 - reg * 50) * 1000;
804
805 /* set voltage to register */
806 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
807 SGTL5000_LINREG_VDDD_MASK, reg);
808
809 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
810 SGTL5000_LINEREG_D_POWERUP,
811 SGTL5000_LINEREG_D_POWERUP);
812
813 /* when internal ldo is enabled, simple digital power can be disabled */
814 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
815 SGTL5000_LINREG_SIMPLE_POWERUP,
816 0);
817
818 ldo->enabled = 1;
819 return 0;
820}
821
822static int ldo_regulator_disable(struct regulator_dev *dev)
823{
824 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
825 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
826
827 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
828 SGTL5000_LINEREG_D_POWERUP,
829 0);
830
831 /* clear voltage info */
832 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
833 SGTL5000_LINREG_VDDD_MASK, 0);
834
835 ldo->enabled = 0;
836
837 return 0;
838}
839
840static int ldo_regulator_get_voltage(struct regulator_dev *dev)
841{
842 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
843
844 return ldo->voltage;
845}
846
847static struct regulator_ops ldo_regulator_ops = {
848 .is_enabled = ldo_regulator_is_enabled,
849 .enable = ldo_regulator_enable,
850 .disable = ldo_regulator_disable,
851 .get_voltage = ldo_regulator_get_voltage,
852};
853
854static int ldo_regulator_register(struct snd_soc_codec *codec,
855 struct regulator_init_data *init_data,
856 int voltage)
857{
858 struct ldo_regulator *ldo;
859 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
860 struct regulator_config config = { };
861
862 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
863
864 if (!ldo)
865 return -ENOMEM;
866
867 ldo->desc.name = kstrdup(dev_name(codec->dev), GFP_KERNEL);
868 if (!ldo->desc.name) {
869 kfree(ldo);
870 dev_err(codec->dev, "failed to allocate decs name memory\n");
871 return -ENOMEM;
872 }
873
874 ldo->desc.type = REGULATOR_VOLTAGE;
875 ldo->desc.owner = THIS_MODULE;
876 ldo->desc.ops = &ldo_regulator_ops;
877 ldo->desc.n_voltages = 1;
878
879 ldo->codec_data = codec;
880 ldo->voltage = voltage;
881
882 config.dev = codec->dev;
883 config.driver_data = ldo;
884 config.init_data = init_data;
885
886 ldo->dev = regulator_register(&ldo->desc, &config);
887 if (IS_ERR(ldo->dev)) {
888 int ret = PTR_ERR(ldo->dev);
889
890 dev_err(codec->dev, "failed to register regulator\n");
891 kfree(ldo->desc.name);
892 kfree(ldo);
893
894 return ret;
895 }
896 sgtl5000->ldo = ldo;
897
898 return 0;
899}
900
901static int ldo_regulator_remove(struct snd_soc_codec *codec)
902{
903 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
904 struct ldo_regulator *ldo = sgtl5000->ldo;
905
906 if (!ldo)
907 return 0;
908
909 regulator_unregister(ldo->dev);
910 kfree(ldo->desc.name);
911 kfree(ldo);
912
913 return 0;
914}
915#else
916static int ldo_regulator_register(struct snd_soc_codec *codec,
917 struct regulator_init_data *init_data,
918 int voltage)
919{
920 dev_err(codec->dev, "this setup needs regulator support in the kernel\n");
921 return -EINVAL;
922}
923
924static int ldo_regulator_remove(struct snd_soc_codec *codec)
925{
926 return 0;
927}
928#endif
929
930/* 761/*
931 * set dac bias 762 * set dac bias
932 * common state changes: 763 * common state changes:
@@ -940,42 +771,17 @@ static int ldo_regulator_remove(struct snd_soc_codec *codec)
940static int sgtl5000_set_bias_level(struct snd_soc_codec *codec, 771static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
941 enum snd_soc_bias_level level) 772 enum snd_soc_bias_level level)
942{ 773{
943 int ret;
944 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
945
946 switch (level) { 774 switch (level) {
947 case SND_SOC_BIAS_ON: 775 case SND_SOC_BIAS_ON:
948 case SND_SOC_BIAS_PREPARE: 776 case SND_SOC_BIAS_PREPARE:
949 break;
950 case SND_SOC_BIAS_STANDBY: 777 case SND_SOC_BIAS_STANDBY:
951 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 778 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
952 ret = regulator_bulk_enable( 779 SGTL5000_REFTOP_POWERUP,
953 ARRAY_SIZE(sgtl5000->supplies), 780 SGTL5000_REFTOP_POWERUP);
954 sgtl5000->supplies);
955 if (ret)
956 return ret;
957 udelay(10);
958
959 regcache_cache_only(sgtl5000->regmap, false);
960
961 ret = regcache_sync(sgtl5000->regmap);
962 if (ret != 0) {
963 dev_err(codec->dev,
964 "Failed to restore cache: %d\n", ret);
965
966 regcache_cache_only(sgtl5000->regmap, true);
967 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
968 sgtl5000->supplies);
969
970 return ret;
971 }
972 }
973
974 break; 781 break;
975 case SND_SOC_BIAS_OFF: 782 case SND_SOC_BIAS_OFF:
976 regcache_cache_only(sgtl5000->regmap, true); 783 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
977 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), 784 SGTL5000_REFTOP_POWERUP, 0);
978 sgtl5000->supplies);
979 break; 785 break;
980 } 786 }
981 787
@@ -1113,7 +919,6 @@ static const u8 vol_quot_table[] = {
1113 * and should be set according to: 919 * and should be set according to:
1114 * 1. vddd provided by external or not 920 * 1. vddd provided by external or not
1115 * 2. vdda and vddio voltage value. > 3.1v or not 921 * 2. vdda and vddio voltage value. > 3.1v or not
1116 * 3. chip revision >=0x11 or not. If >=0x11, not use external vddd.
1117 */ 922 */
1118static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) 923static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1119{ 924{
@@ -1131,7 +936,9 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1131 936
1132 vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer); 937 vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
1133 vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer); 938 vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer);
1134 vddd = regulator_get_voltage(sgtl5000->supplies[VDDD].consumer); 939 vddd = (sgtl5000->num_supplies > VDDD)
940 ? regulator_get_voltage(sgtl5000->supplies[VDDD].consumer)
941 : LDO_VOLTAGE;
1135 942
1136 vdda = vdda / 1000; 943 vdda = vdda / 1000;
1137 vddio = vddio / 1000; 944 vddio = vddio / 1000;
@@ -1178,25 +985,6 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1178 985
1179 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr); 986 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr);
1180 987
1181 /* set voltage to register */
1182 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
1183 SGTL5000_LINREG_VDDD_MASK, 0x8);
1184
1185 /*
1186 * if vddd linear reg has been enabled,
1187 * simple digital supply should be clear to get
1188 * proper VDDD voltage.
1189 */
1190 if (ana_pwr & SGTL5000_LINEREG_D_POWERUP)
1191 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1192 SGTL5000_LINREG_SIMPLE_POWERUP,
1193 0);
1194 else
1195 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1196 SGTL5000_LINREG_SIMPLE_POWERUP |
1197 SGTL5000_STARTUP_POWERUP,
1198 0);
1199
1200 /* 988 /*
1201 * set ADC/DAC VAG to vdda / 2, 989 * set ADC/DAC VAG to vdda / 2,
1202 * should stay in range (0.8v, 1.575v) 990 * should stay in range (0.8v, 1.575v)
@@ -1256,78 +1044,43 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1256 return 0; 1044 return 0;
1257} 1045}
1258 1046
1259static int sgtl5000_replace_vddd_with_ldo(struct snd_soc_codec *codec) 1047static int sgtl5000_enable_regulators(struct i2c_client *client)
1260{
1261 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1262 int ret;
1263
1264 /* set internal ldo to 1.2v */
1265 ret = ldo_regulator_register(codec, &ldo_init_data, LDO_VOLTAGE);
1266 if (ret) {
1267 dev_err(codec->dev,
1268 "Failed to register vddd internal supplies: %d\n", ret);
1269 return ret;
1270 }
1271
1272 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1273
1274 dev_info(codec->dev, "Using internal LDO instead of VDDD\n");
1275 return 0;
1276}
1277
1278static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1279{ 1048{
1280 int ret; 1049 int ret;
1281 int i; 1050 int i;
1282 int external_vddd = 0; 1051 int external_vddd = 0;
1283 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1284 struct regulator *vddd; 1052 struct regulator *vddd;
1053 struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
1285 1054
1286 for (i = 0; i < ARRAY_SIZE(sgtl5000->supplies); i++) 1055 for (i = 0; i < ARRAY_SIZE(sgtl5000->supplies); i++)
1287 sgtl5000->supplies[i].supply = supply_names[i]; 1056 sgtl5000->supplies[i].supply = supply_names[i];
1288 1057
1289 /* External VDDD only works before revision 0x11 */ 1058 vddd = regulator_get_optional(&client->dev, "VDDD");
1290 if (sgtl5000->revision < 0x11) { 1059 if (IS_ERR(vddd)) {
1291 vddd = regulator_get_optional(codec->dev, "VDDD"); 1060 /* See if it's just not registered yet */
1292 if (IS_ERR(vddd)) { 1061 if (PTR_ERR(vddd) == -EPROBE_DEFER)
1293 /* See if it's just not registered yet */ 1062 return -EPROBE_DEFER;
1294 if (PTR_ERR(vddd) == -EPROBE_DEFER) 1063 } else {
1295 return -EPROBE_DEFER; 1064 external_vddd = 1;
1296 } else { 1065 regulator_put(vddd);
1297 external_vddd = 1;
1298 regulator_put(vddd);
1299 }
1300 }
1301
1302 if (!external_vddd) {
1303 ret = sgtl5000_replace_vddd_with_ldo(codec);
1304 if (ret)
1305 return ret;
1306 } 1066 }
1307 1067
1308 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), 1068 sgtl5000->num_supplies = ARRAY_SIZE(sgtl5000->supplies)
1069 - 1 + external_vddd;
1070 ret = regulator_bulk_get(&client->dev, sgtl5000->num_supplies,
1309 sgtl5000->supplies); 1071 sgtl5000->supplies);
1310 if (ret) 1072 if (ret)
1311 goto err_ldo_remove; 1073 return ret;
1312
1313 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1314 sgtl5000->supplies);
1315 if (ret)
1316 goto err_regulator_free;
1317
1318 /* wait for all power rails bring up */
1319 udelay(10);
1320 1074
1321 return 0; 1075 ret = regulator_bulk_enable(sgtl5000->num_supplies,
1076 sgtl5000->supplies);
1077 if (!ret)
1078 usleep_range(10, 20);
1079 else
1080 regulator_bulk_free(sgtl5000->num_supplies,
1081 sgtl5000->supplies);
1322 1082
1323err_regulator_free:
1324 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1325 sgtl5000->supplies);
1326err_ldo_remove:
1327 if (!external_vddd)
1328 ldo_regulator_remove(codec);
1329 return ret; 1083 return ret;
1330
1331} 1084}
1332 1085
1333static int sgtl5000_probe(struct snd_soc_codec *codec) 1086static int sgtl5000_probe(struct snd_soc_codec *codec)
@@ -1335,10 +1088,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1335 int ret; 1088 int ret;
1336 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); 1089 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1337 1090
1338 ret = sgtl5000_enable_regulators(codec);
1339 if (ret)
1340 return ret;
1341
1342 /* power up sgtl5000 */ 1091 /* power up sgtl5000 */
1343 ret = sgtl5000_set_power_regs(codec); 1092 ret = sgtl5000_set_power_regs(codec);
1344 if (ret) 1093 if (ret)
@@ -1389,25 +1138,11 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1389 return 0; 1138 return 0;
1390 1139
1391err: 1140err:
1392 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1393 sgtl5000->supplies);
1394 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1395 sgtl5000->supplies);
1396 ldo_regulator_remove(codec);
1397
1398 return ret; 1141 return ret;
1399} 1142}
1400 1143
1401static int sgtl5000_remove(struct snd_soc_codec *codec) 1144static int sgtl5000_remove(struct snd_soc_codec *codec)
1402{ 1145{
1403 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1404
1405 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1406 sgtl5000->supplies);
1407 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1408 sgtl5000->supplies);
1409 ldo_regulator_remove(codec);
1410
1411 return 0; 1146 return 0;
1412} 1147}
1413 1148
@@ -1448,8 +1183,9 @@ static const struct regmap_config sgtl5000_regmap = {
1448 * and avoid problems like, not being able to probe after an audio playback 1183 * and avoid problems like, not being able to probe after an audio playback
1449 * followed by a system reset or a 'reboot' command in Linux 1184 * followed by a system reset or a 'reboot' command in Linux
1450 */ 1185 */
1451static int sgtl5000_fill_defaults(struct sgtl5000_priv *sgtl5000) 1186static void sgtl5000_fill_defaults(struct i2c_client *client)
1452{ 1187{
1188 struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
1453 int i, ret, val, index; 1189 int i, ret, val, index;
1454 1190
1455 for (i = 0; i < ARRAY_SIZE(sgtl5000_reg_defaults); i++) { 1191 for (i = 0; i < ARRAY_SIZE(sgtl5000_reg_defaults); i++) {
@@ -1457,10 +1193,10 @@ static int sgtl5000_fill_defaults(struct sgtl5000_priv *sgtl5000)
1457 index = sgtl5000_reg_defaults[i].reg; 1193 index = sgtl5000_reg_defaults[i].reg;
1458 ret = regmap_write(sgtl5000->regmap, index, val); 1194 ret = regmap_write(sgtl5000->regmap, index, val);
1459 if (ret) 1195 if (ret)
1460 return ret; 1196 dev_err(&client->dev,
1197 "%s: error %d setting reg 0x%02x to 0x%04x\n",
1198 __func__, ret, index, val);
1461 } 1199 }
1462
1463 return 0;
1464} 1200}
1465 1201
1466static int sgtl5000_i2c_probe(struct i2c_client *client, 1202static int sgtl5000_i2c_probe(struct i2c_client *client,
@@ -1470,16 +1206,23 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1470 int ret, reg, rev; 1206 int ret, reg, rev;
1471 struct device_node *np = client->dev.of_node; 1207 struct device_node *np = client->dev.of_node;
1472 u32 value; 1208 u32 value;
1209 u16 ana_pwr;
1473 1210
1474 sgtl5000 = devm_kzalloc(&client->dev, sizeof(*sgtl5000), GFP_KERNEL); 1211 sgtl5000 = devm_kzalloc(&client->dev, sizeof(*sgtl5000), GFP_KERNEL);
1475 if (!sgtl5000) 1212 if (!sgtl5000)
1476 return -ENOMEM; 1213 return -ENOMEM;
1477 1214
1215 i2c_set_clientdata(client, sgtl5000);
1216
1217 ret = sgtl5000_enable_regulators(client);
1218 if (ret)
1219 return ret;
1220
1478 sgtl5000->regmap = devm_regmap_init_i2c(client, &sgtl5000_regmap); 1221 sgtl5000->regmap = devm_regmap_init_i2c(client, &sgtl5000_regmap);
1479 if (IS_ERR(sgtl5000->regmap)) { 1222 if (IS_ERR(sgtl5000->regmap)) {
1480 ret = PTR_ERR(sgtl5000->regmap); 1223 ret = PTR_ERR(sgtl5000->regmap);
1481 dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret); 1224 dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);
1482 return ret; 1225 goto disable_regs;
1483 } 1226 }
1484 1227
1485 sgtl5000->mclk = devm_clk_get(&client->dev, NULL); 1228 sgtl5000->mclk = devm_clk_get(&client->dev, NULL);
@@ -1488,21 +1231,25 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1488 dev_err(&client->dev, "Failed to get mclock: %d\n", ret); 1231 dev_err(&client->dev, "Failed to get mclock: %d\n", ret);
1489 /* Defer the probe to see if the clk will be provided later */ 1232 /* Defer the probe to see if the clk will be provided later */
1490 if (ret == -ENOENT) 1233 if (ret == -ENOENT)
1491 return -EPROBE_DEFER; 1234 ret = -EPROBE_DEFER;
1492 return ret; 1235 goto disable_regs;
1493 } 1236 }
1494 1237
1495 ret = clk_prepare_enable(sgtl5000->mclk); 1238 ret = clk_prepare_enable(sgtl5000->mclk);
1496 if (ret) 1239 if (ret) {
1497 return ret; 1240 dev_err(&client->dev, "Error enabling clock %d\n", ret);
1241 goto disable_regs;
1242 }
1498 1243
1499 /* Need 8 clocks before I2C accesses */ 1244 /* Need 8 clocks before I2C accesses */
1500 udelay(1); 1245 udelay(1);
1501 1246
1502 /* read chip information */ 1247 /* read chip information */
1503 ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, &reg); 1248 ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, &reg);
1504 if (ret) 1249 if (ret) {
1250 dev_err(&client->dev, "Error reading chip id %d\n", ret);
1505 goto disable_clk; 1251 goto disable_clk;
1252 }
1506 1253
1507 if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) != 1254 if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
1508 SGTL5000_PARTID_PART_ID) { 1255 SGTL5000_PARTID_PART_ID) {
@@ -1516,6 +1263,44 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1516 dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev); 1263 dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev);
1517 sgtl5000->revision = rev; 1264 sgtl5000->revision = rev;
1518 1265
1266 /* reconfigure the clocks in case we're using the PLL */
1267 ret = regmap_write(sgtl5000->regmap,
1268 SGTL5000_CHIP_CLK_CTRL,
1269 SGTL5000_CHIP_CLK_CTRL_DEFAULT);
1270 if (ret)
1271 dev_err(&client->dev,
1272 "Error %d initializing CHIP_CLK_CTRL\n", ret);
1273
1274 /* Follow section 2.2.1.1 of AN3663 */
1275 ana_pwr = SGTL5000_ANA_POWER_DEFAULT;
1276 if (sgtl5000->num_supplies <= VDDD) {
1277 /* internal VDDD at 1.2V */
1278 ret = regmap_update_bits(sgtl5000->regmap,
1279 SGTL5000_CHIP_LINREG_CTRL,
1280 SGTL5000_LINREG_VDDD_MASK,
1281 LINREG_VDDD);
1282 if (ret)
1283 dev_err(&client->dev,
1284 "Error %d setting LINREG_VDDD\n", ret);
1285
1286 ana_pwr |= SGTL5000_LINEREG_D_POWERUP;
1287 dev_info(&client->dev,
1288 "Using internal LDO instead of VDDD: check ER1\n");
1289 } else {
1290 /* using external LDO for VDDD
1291 * Clear startup powerup and simple powerup
1292 * bits to save power
1293 */
1294 ana_pwr &= ~(SGTL5000_STARTUP_POWERUP
1295 | SGTL5000_LINREG_SIMPLE_POWERUP);
1296 dev_dbg(&client->dev, "Using external VDDD\n");
1297 }
1298 ret = regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, ana_pwr);
1299 if (ret)
1300 dev_err(&client->dev,
1301 "Error %d setting CHIP_ANA_POWER to %04x\n",
1302 ret, ana_pwr);
1303
1519 if (np) { 1304 if (np) {
1520 if (!of_property_read_u32(np, 1305 if (!of_property_read_u32(np,
1521 "micbias-resistor-k-ohms", &value)) { 1306 "micbias-resistor-k-ohms", &value)) {
@@ -1557,12 +1342,8 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1557 } 1342 }
1558 } 1343 }
1559 1344
1560 i2c_set_clientdata(client, sgtl5000);
1561
1562 /* Ensure sgtl5000 will start with sane register values */ 1345 /* Ensure sgtl5000 will start with sane register values */
1563 ret = sgtl5000_fill_defaults(sgtl5000); 1346 sgtl5000_fill_defaults(client);
1564 if (ret)
1565 goto disable_clk;
1566 1347
1567 ret = snd_soc_register_codec(&client->dev, 1348 ret = snd_soc_register_codec(&client->dev,
1568 &sgtl5000_driver, &sgtl5000_dai, 1); 1349 &sgtl5000_driver, &sgtl5000_dai, 1);
@@ -1573,6 +1354,11 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1573 1354
1574disable_clk: 1355disable_clk:
1575 clk_disable_unprepare(sgtl5000->mclk); 1356 clk_disable_unprepare(sgtl5000->mclk);
1357
1358disable_regs:
1359 regulator_bulk_disable(sgtl5000->num_supplies, sgtl5000->supplies);
1360 regulator_bulk_free(sgtl5000->num_supplies, sgtl5000->supplies);
1361
1576 return ret; 1362 return ret;
1577} 1363}
1578 1364
@@ -1582,6 +1368,9 @@ static int sgtl5000_i2c_remove(struct i2c_client *client)
1582 1368
1583 snd_soc_unregister_codec(&client->dev); 1369 snd_soc_unregister_codec(&client->dev);
1584 clk_disable_unprepare(sgtl5000->mclk); 1370 clk_disable_unprepare(sgtl5000->mclk);
1371 regulator_bulk_disable(sgtl5000->num_supplies, sgtl5000->supplies);
1372 regulator_bulk_free(sgtl5000->num_supplies, sgtl5000->supplies);
1373
1585 return 0; 1374 return 0;
1586} 1375}
1587 1376
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index 1c317de26176..22f3442af982 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -92,6 +92,7 @@
92/* 92/*
93 * SGTL5000_CHIP_CLK_CTRL 93 * SGTL5000_CHIP_CLK_CTRL
94 */ 94 */
95#define SGTL5000_CHIP_CLK_CTRL_DEFAULT 0x0008
95#define SGTL5000_RATE_MODE_MASK 0x0030 96#define SGTL5000_RATE_MODE_MASK 0x0030
96#define SGTL5000_RATE_MODE_SHIFT 4 97#define SGTL5000_RATE_MODE_SHIFT 4
97#define SGTL5000_RATE_MODE_WIDTH 2 98#define SGTL5000_RATE_MODE_WIDTH 2
@@ -325,6 +326,7 @@
325/* 326/*
326 * SGTL5000_CHIP_ANA_POWER 327 * SGTL5000_CHIP_ANA_POWER
327 */ 328 */
329#define SGTL5000_ANA_POWER_DEFAULT 0x7060
328#define SGTL5000_DAC_STEREO 0x4000 330#define SGTL5000_DAC_STEREO 0x4000
329#define SGTL5000_LINREG_SIMPLE_POWERUP 0x2000 331#define SGTL5000_LINREG_SIMPLE_POWERUP 0x2000
330#define SGTL5000_STARTUP_POWERUP 0x1000 332#define SGTL5000_STARTUP_POWERUP 0x1000
diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c
index b8d19b77bde9..d8baca3f8413 100644
--- a/sound/soc/codecs/tas571x.c
+++ b/sound/soc/codecs/tas571x.c
@@ -28,6 +28,7 @@
28#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <asm/unaligned.h>
31 32
32#include "tas571x.h" 33#include "tas571x.h"
33 34
@@ -63,6 +64,10 @@ static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
63 case TAS571X_INPUT_MUX_REG: 64 case TAS571X_INPUT_MUX_REG:
64 case TAS571X_CH4_SRC_SELECT_REG: 65 case TAS571X_CH4_SRC_SELECT_REG:
65 case TAS571X_PWM_MUX_REG: 66 case TAS571X_PWM_MUX_REG:
67 case TAS5717_CH1_RIGHT_CH_MIX_REG:
68 case TAS5717_CH1_LEFT_CH_MIX_REG:
69 case TAS5717_CH2_LEFT_CH_MIX_REG:
70 case TAS5717_CH2_RIGHT_CH_MIX_REG:
66 return 4; 71 return 4;
67 default: 72 default:
68 return 1; 73 return 1;
@@ -135,6 +140,129 @@ static int tas571x_reg_read(void *context, unsigned int reg,
135 return 0; 140 return 0;
136} 141}
137 142
143/*
144 * register write for 8- and 20-byte registers
145 */
146static int tas571x_reg_write_multiword(struct i2c_client *client,
147 unsigned int reg, const long values[], size_t len)
148{
149 size_t i;
150 uint8_t *buf, *p;
151 int ret;
152 size_t send_size = 1 + len * sizeof(uint32_t);
153
154 buf = kzalloc(send_size, GFP_KERNEL | GFP_DMA);
155 if (!buf)
156 return -ENOMEM;
157 buf[0] = reg;
158
159 for (i = 0, p = buf + 1; i < len; i++, p += sizeof(uint32_t))
160 put_unaligned_be32(values[i], p);
161
162 ret = i2c_master_send(client, buf, send_size);
163
164 kfree(buf);
165
166 if (ret == send_size)
167 return 0;
168 else if (ret < 0)
169 return ret;
170 else
171 return -EIO;
172}
173
174/*
175 * register read for 8- and 20-byte registers
176 */
177static int tas571x_reg_read_multiword(struct i2c_client *client,
178 unsigned int reg, long values[], size_t len)
179{
180 unsigned int i;
181 uint8_t send_buf;
182 uint8_t *recv_buf, *p;
183 struct i2c_msg msgs[2];
184 unsigned int recv_size = len * sizeof(uint32_t);
185 int ret;
186
187 recv_buf = kzalloc(recv_size, GFP_KERNEL | GFP_DMA);
188 if (!recv_buf)
189 return -ENOMEM;
190
191 send_buf = reg;
192
193 msgs[0].addr = client->addr;
194 msgs[0].len = sizeof(send_buf);
195 msgs[0].buf = &send_buf;
196 msgs[0].flags = 0;
197
198 msgs[1].addr = client->addr;
199 msgs[1].len = recv_size;
200 msgs[1].buf = recv_buf;
201 msgs[1].flags = I2C_M_RD;
202
203 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
204 if (ret < 0)
205 goto err_ret;
206 else if (ret != ARRAY_SIZE(msgs)) {
207 ret = -EIO;
208 goto err_ret;
209 }
210
211 for (i = 0, p = recv_buf; i < len; i++, p += sizeof(uint32_t))
212 values[i] = get_unaligned_be32(p);
213
214err_ret:
215 kfree(recv_buf);
216 return ret;
217}
218
219/*
220 * Integer array controls for setting biquad, mixer, DRC coefficients.
221 * According to the datasheet each coefficient is effectively 26bits,
222 * i.e. stored as 32bits, where bits [31:26] are ignored.
223 * TI's TAS57xx Graphical Development Environment tool however produces
224 * coefficients with more than 26 bits. For this reason we allow values
225 * in the full 32-bits reange.
226 * The coefficients are ordered as given in the TAS571x data sheet:
227 * b0, b1, b2, a1, a2
228 */
229
230static int tas571x_coefficient_info(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_info *uinfo)
232{
233 int numcoef = kcontrol->private_value >> 16;
234
235 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
236 uinfo->count = numcoef;
237 uinfo->value.integer.min = 0;
238 uinfo->value.integer.max = 0xffffffff;
239 return 0;
240}
241
242static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,
243 struct snd_ctl_elem_value *ucontrol)
244{
245 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
246 struct i2c_client *i2c = to_i2c_client(codec->dev);
247 int numcoef = kcontrol->private_value >> 16;
248 int index = kcontrol->private_value & 0xffff;
249
250 return tas571x_reg_read_multiword(i2c, index,
251 ucontrol->value.integer.value, numcoef);
252}
253
254static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,
255 struct snd_ctl_elem_value *ucontrol)
256{
257 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
258 struct i2c_client *i2c = to_i2c_client(codec->dev);
259 int numcoef = kcontrol->private_value >> 16;
260 int index = kcontrol->private_value & 0xffff;
261
262 return tas571x_reg_write_multiword(i2c, index,
263 ucontrol->value.integer.value, numcoef);
264}
265
138static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format) 266static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
139{ 267{
140 struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec); 268 struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
@@ -241,6 +369,15 @@ static const struct snd_soc_dai_ops tas571x_dai_ops = {
241 .digital_mute = tas571x_mute, 369 .digital_mute = tas571x_mute,
242}; 370};
243 371
372
373#define BIQUAD_COEFS(xname, reg) \
374{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
375 .info = tas571x_coefficient_info, \
376 .get = tas571x_coefficient_get,\
377 .put = tas571x_coefficient_put, \
378 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
379 .private_value = reg | (5 << 16) }
380
244static const char *const tas5711_supply_names[] = { 381static const char *const tas5711_supply_names[] = {
245 "AVDD", 382 "AVDD",
246 "DVDD", 383 "DVDD",
@@ -264,6 +401,16 @@ static const struct snd_kcontrol_new tas5711_controls[] = {
264 TAS571X_SOFT_MUTE_REG, 401 TAS571X_SOFT_MUTE_REG,
265 TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT, 402 TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
266 1, 1), 403 1, 1),
404
405 SOC_DOUBLE_R_RANGE("CH1 Mixer Volume",
406 TAS5717_CH1_LEFT_CH_MIX_REG,
407 TAS5717_CH1_RIGHT_CH_MIX_REG,
408 16, 0, 0x80, 0),
409
410 SOC_DOUBLE_R_RANGE("CH2 Mixer Volume",
411 TAS5717_CH2_LEFT_CH_MIX_REG,
412 TAS5717_CH2_RIGHT_CH_MIX_REG,
413 16, 0, 0x80, 0),
267}; 414};
268 415
269static const struct regmap_range tas571x_readonly_regs_range[] = { 416static const struct regmap_range tas571x_readonly_regs_range[] = {
@@ -340,6 +487,43 @@ static const struct snd_kcontrol_new tas5717_controls[] = {
340 TAS571X_SOFT_MUTE_REG, 487 TAS571X_SOFT_MUTE_REG,
341 TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT, 488 TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
342 1, 1), 489 1, 1),
490
491 /*
492 * The biquads are named according to the register names.
493 * Please note that TI's TAS57xx Graphical Development Environment
494 * tool names them different.
495 */
496 BIQUAD_COEFS("CH1 - Biquad 0", TAS5717_CH1_BQ0_REG),
497 BIQUAD_COEFS("CH1 - Biquad 1", TAS5717_CH1_BQ1_REG),
498 BIQUAD_COEFS("CH1 - Biquad 2", TAS5717_CH1_BQ2_REG),
499 BIQUAD_COEFS("CH1 - Biquad 3", TAS5717_CH1_BQ3_REG),
500 BIQUAD_COEFS("CH1 - Biquad 4", TAS5717_CH1_BQ4_REG),
501 BIQUAD_COEFS("CH1 - Biquad 5", TAS5717_CH1_BQ5_REG),
502 BIQUAD_COEFS("CH1 - Biquad 6", TAS5717_CH1_BQ6_REG),
503 BIQUAD_COEFS("CH1 - Biquad 7", TAS5717_CH1_BQ7_REG),
504 BIQUAD_COEFS("CH1 - Biquad 8", TAS5717_CH1_BQ8_REG),
505 BIQUAD_COEFS("CH1 - Biquad 9", TAS5717_CH1_BQ9_REG),
506 BIQUAD_COEFS("CH1 - Biquad 10", TAS5717_CH1_BQ10_REG),
507 BIQUAD_COEFS("CH1 - Biquad 11", TAS5717_CH1_BQ11_REG),
508
509 BIQUAD_COEFS("CH2 - Biquad 0", TAS5717_CH2_BQ0_REG),
510 BIQUAD_COEFS("CH2 - Biquad 1", TAS5717_CH2_BQ1_REG),
511 BIQUAD_COEFS("CH2 - Biquad 2", TAS5717_CH2_BQ2_REG),
512 BIQUAD_COEFS("CH2 - Biquad 3", TAS5717_CH2_BQ3_REG),
513 BIQUAD_COEFS("CH2 - Biquad 4", TAS5717_CH2_BQ4_REG),
514 BIQUAD_COEFS("CH2 - Biquad 5", TAS5717_CH2_BQ5_REG),
515 BIQUAD_COEFS("CH2 - Biquad 6", TAS5717_CH2_BQ6_REG),
516 BIQUAD_COEFS("CH2 - Biquad 7", TAS5717_CH2_BQ7_REG),
517 BIQUAD_COEFS("CH2 - Biquad 8", TAS5717_CH2_BQ8_REG),
518 BIQUAD_COEFS("CH2 - Biquad 9", TAS5717_CH2_BQ9_REG),
519 BIQUAD_COEFS("CH2 - Biquad 10", TAS5717_CH2_BQ10_REG),
520 BIQUAD_COEFS("CH2 - Biquad 11", TAS5717_CH2_BQ11_REG),
521
522 BIQUAD_COEFS("CH3 - Biquad 0", TAS5717_CH3_BQ0_REG),
523 BIQUAD_COEFS("CH3 - Biquad 1", TAS5717_CH3_BQ1_REG),
524
525 BIQUAD_COEFS("CH4 - Biquad 0", TAS5717_CH4_BQ0_REG),
526 BIQUAD_COEFS("CH4 - Biquad 1", TAS5717_CH4_BQ1_REG),
343}; 527};
344 528
345static const struct reg_default tas5717_reg_defaults[] = { 529static const struct reg_default tas5717_reg_defaults[] = {
@@ -350,6 +534,10 @@ static const struct reg_default tas5717_reg_defaults[] = {
350 { 0x08, 0x00c0 }, 534 { 0x08, 0x00c0 },
351 { 0x09, 0x00c0 }, 535 { 0x09, 0x00c0 },
352 { 0x1b, 0x82 }, 536 { 0x1b, 0x82 },
537 { TAS5717_CH1_RIGHT_CH_MIX_REG, 0x0 },
538 { TAS5717_CH1_LEFT_CH_MIX_REG, 0x800000},
539 { TAS5717_CH2_LEFT_CH_MIX_REG, 0x0 },
540 { TAS5717_CH2_RIGHT_CH_MIX_REG, 0x800000},
353}; 541};
354 542
355static const struct regmap_config tas5717_regmap_config = { 543static const struct regmap_config tas5717_regmap_config = {
diff --git a/sound/soc/codecs/tas571x.h b/sound/soc/codecs/tas571x.h
index cf800c364f0f..c45677bc26ad 100644
--- a/sound/soc/codecs/tas571x.h
+++ b/sound/soc/codecs/tas571x.h
@@ -52,4 +52,44 @@
52#define TAS571X_CH4_SRC_SELECT_REG 0x21 52#define TAS571X_CH4_SRC_SELECT_REG 0x21
53#define TAS571X_PWM_MUX_REG 0x25 53#define TAS571X_PWM_MUX_REG 0x25
54 54
55/* 20-byte biquad registers */
56#define TAS5717_CH1_BQ0_REG 0x26
57#define TAS5717_CH1_BQ1_REG 0x27
58#define TAS5717_CH1_BQ2_REG 0x28
59#define TAS5717_CH1_BQ3_REG 0x29
60#define TAS5717_CH1_BQ4_REG 0x2a
61#define TAS5717_CH1_BQ5_REG 0x2b
62#define TAS5717_CH1_BQ6_REG 0x2c
63#define TAS5717_CH1_BQ7_REG 0x2d
64#define TAS5717_CH1_BQ8_REG 0x2e
65#define TAS5717_CH1_BQ9_REG 0x2f
66
67#define TAS5717_CH2_BQ0_REG 0x30
68#define TAS5717_CH2_BQ1_REG 0x31
69#define TAS5717_CH2_BQ2_REG 0x32
70#define TAS5717_CH2_BQ3_REG 0x33
71#define TAS5717_CH2_BQ4_REG 0x34
72#define TAS5717_CH2_BQ5_REG 0x35
73#define TAS5717_CH2_BQ6_REG 0x36
74#define TAS5717_CH2_BQ7_REG 0x37
75#define TAS5717_CH2_BQ8_REG 0x38
76#define TAS5717_CH2_BQ9_REG 0x39
77
78#define TAS5717_CH1_BQ10_REG 0x58
79#define TAS5717_CH1_BQ11_REG 0x59
80
81#define TAS5717_CH4_BQ0_REG 0x5a
82#define TAS5717_CH4_BQ1_REG 0x5b
83
84#define TAS5717_CH2_BQ10_REG 0x5c
85#define TAS5717_CH2_BQ11_REG 0x5d
86
87#define TAS5717_CH3_BQ0_REG 0x5e
88#define TAS5717_CH3_BQ1_REG 0x5f
89
90#define TAS5717_CH1_RIGHT_CH_MIX_REG 0x72
91#define TAS5717_CH1_LEFT_CH_MIX_REG 0x73
92#define TAS5717_CH2_LEFT_CH_MIX_REG 0x76
93#define TAS5717_CH2_RIGHT_CH_MIX_REG 0x77
94
55#endif /* _TAS571X_H */ 95#endif /* _TAS571X_H */
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h
index fe16c34607bb..ac9b146526eb 100644
--- a/sound/soc/codecs/tlv320aic31xx.h
+++ b/sound/soc/codecs/tlv320aic31xx.h
@@ -38,141 +38,143 @@ struct aic31xx_pdata {
38 int micbias_vg; 38 int micbias_vg;
39}; 39};
40 40
41#define AIC31XX_REG(page, reg) ((page * 128) + reg)
42
41/* Page Control Register */ 43/* Page Control Register */
42#define AIC31XX_PAGECTL 0x00 44#define AIC31XX_PAGECTL AIC31XX_REG(0, 0)
43 45
44/* Page 0 Registers */ 46/* Page 0 Registers */
45/* Software reset register */ 47/* Software reset register */
46#define AIC31XX_RESET 0x01 48#define AIC31XX_RESET AIC31XX_REG(0, 1)
47/* OT FLAG register */ 49/* OT FLAG register */
48#define AIC31XX_OT_FLAG 0x03 50#define AIC31XX_OT_FLAG AIC31XX_REG(0, 3)
49/* Clock clock Gen muxing, Multiplexers*/ 51/* Clock clock Gen muxing, Multiplexers*/
50#define AIC31XX_CLKMUX 0x04 52#define AIC31XX_CLKMUX AIC31XX_REG(0, 4)
51/* PLL P and R-VAL register */ 53/* PLL P and R-VAL register */
52#define AIC31XX_PLLPR 0x05 54#define AIC31XX_PLLPR AIC31XX_REG(0, 5)
53/* PLL J-VAL register */ 55/* PLL J-VAL register */
54#define AIC31XX_PLLJ 0x06 56#define AIC31XX_PLLJ AIC31XX_REG(0, 6)
55/* PLL D-VAL MSB register */ 57/* PLL D-VAL MSB register */
56#define AIC31XX_PLLDMSB 0x07 58#define AIC31XX_PLLDMSB AIC31XX_REG(0, 7)
57/* PLL D-VAL LSB register */ 59/* PLL D-VAL LSB register */
58#define AIC31XX_PLLDLSB 0x08 60#define AIC31XX_PLLDLSB AIC31XX_REG(0, 8)
59/* DAC NDAC_VAL register*/ 61/* DAC NDAC_VAL register*/
60#define AIC31XX_NDAC 0x0B 62#define AIC31XX_NDAC AIC31XX_REG(0, 11)
61/* DAC MDAC_VAL register */ 63/* DAC MDAC_VAL register */
62#define AIC31XX_MDAC 0x0C 64#define AIC31XX_MDAC AIC31XX_REG(0, 12)
63/* DAC OSR setting register 1, MSB value */ 65/* DAC OSR setting register 1, MSB value */
64#define AIC31XX_DOSRMSB 0x0D 66#define AIC31XX_DOSRMSB AIC31XX_REG(0, 13)
65/* DAC OSR setting register 2, LSB value */ 67/* DAC OSR setting register 2, LSB value */
66#define AIC31XX_DOSRLSB 0x0E 68#define AIC31XX_DOSRLSB AIC31XX_REG(0, 14)
67#define AIC31XX_MINI_DSP_INPOL 0x10 69#define AIC31XX_MINI_DSP_INPOL AIC31XX_REG(0, 16)
68/* Clock setting register 8, PLL */ 70/* Clock setting register 8, PLL */
69#define AIC31XX_NADC 0x12 71#define AIC31XX_NADC AIC31XX_REG(0, 18)
70/* Clock setting register 9, PLL */ 72/* Clock setting register 9, PLL */
71#define AIC31XX_MADC 0x13 73#define AIC31XX_MADC AIC31XX_REG(0, 19)
72/* ADC Oversampling (AOSR) Register */ 74/* ADC Oversampling (AOSR) Register */
73#define AIC31XX_AOSR 0x14 75#define AIC31XX_AOSR AIC31XX_REG(0, 20)
74/* Clock setting register 9, Multiplexers */ 76/* Clock setting register 9, Multiplexers */
75#define AIC31XX_CLKOUTMUX 0x19 77#define AIC31XX_CLKOUTMUX AIC31XX_REG(0, 25)
76/* Clock setting register 10, CLOCKOUT M divider value */ 78/* Clock setting register 10, CLOCKOUT M divider value */
77#define AIC31XX_CLKOUTMVAL 0x1A 79#define AIC31XX_CLKOUTMVAL AIC31XX_REG(0, 26)
78/* Audio Interface Setting Register 1 */ 80/* Audio Interface Setting Register 1 */
79#define AIC31XX_IFACE1 0x1B 81#define AIC31XX_IFACE1 AIC31XX_REG(0, 27)
80/* Audio Data Slot Offset Programming */ 82/* Audio Data Slot Offset Programming */
81#define AIC31XX_DATA_OFFSET 0x1C 83#define AIC31XX_DATA_OFFSET AIC31XX_REG(0, 28)
82/* Audio Interface Setting Register 2 */ 84/* Audio Interface Setting Register 2 */
83#define AIC31XX_IFACE2 0x1D 85#define AIC31XX_IFACE2 AIC31XX_REG(0, 29)
84/* Clock setting register 11, BCLK N Divider */ 86/* Clock setting register 11, BCLK N Divider */
85#define AIC31XX_BCLKN 0x1E 87#define AIC31XX_BCLKN AIC31XX_REG(0, 30)
86/* Audio Interface Setting Register 3, Secondary Audio Interface */ 88/* Audio Interface Setting Register 3, Secondary Audio Interface */
87#define AIC31XX_IFACESEC1 0x1F 89#define AIC31XX_IFACESEC1 AIC31XX_REG(0, 31)
88/* Audio Interface Setting Register 4 */ 90/* Audio Interface Setting Register 4 */
89#define AIC31XX_IFACESEC2 0x20 91#define AIC31XX_IFACESEC2 AIC31XX_REG(0, 32)
90/* Audio Interface Setting Register 5 */ 92/* Audio Interface Setting Register 5 */
91#define AIC31XX_IFACESEC3 0x21 93#define AIC31XX_IFACESEC3 AIC31XX_REG(0, 33)
92/* I2C Bus Condition */ 94/* I2C Bus Condition */
93#define AIC31XX_I2C 0x22 95#define AIC31XX_I2C AIC31XX_REG(0, 34)
94/* ADC FLAG */ 96/* ADC FLAG */
95#define AIC31XX_ADCFLAG 0x24 97#define AIC31XX_ADCFLAG AIC31XX_REG(0, 36)
96/* DAC Flag Registers */ 98/* DAC Flag Registers */
97#define AIC31XX_DACFLAG1 0x25 99#define AIC31XX_DACFLAG1 AIC31XX_REG(0, 37)
98#define AIC31XX_DACFLAG2 0x26 100#define AIC31XX_DACFLAG2 AIC31XX_REG(0, 38)
99/* Sticky Interrupt flag (overflow) */ 101/* Sticky Interrupt flag (overflow) */
100#define AIC31XX_OFFLAG 0x27 102#define AIC31XX_OFFLAG AIC31XX_REG(0, 39)
101/* Sticy DAC Interrupt flags */ 103/* Sticy DAC Interrupt flags */
102#define AIC31XX_INTRDACFLAG 0x2C 104#define AIC31XX_INTRDACFLAG AIC31XX_REG(0, 44)
103/* Sticy ADC Interrupt flags */ 105/* Sticy ADC Interrupt flags */
104#define AIC31XX_INTRADCFLAG 0x2D 106#define AIC31XX_INTRADCFLAG AIC31XX_REG(0, 45)
105/* DAC Interrupt flags 2 */ 107/* DAC Interrupt flags 2 */
106#define AIC31XX_INTRDACFLAG2 0x2E 108#define AIC31XX_INTRDACFLAG2 AIC31XX_REG(0, 46)
107/* ADC Interrupt flags 2 */ 109/* ADC Interrupt flags 2 */
108#define AIC31XX_INTRADCFLAG2 0x2F 110#define AIC31XX_INTRADCFLAG2 AIC31XX_REG(0, 47)
109/* INT1 interrupt control */ 111/* INT1 interrupt control */
110#define AIC31XX_INT1CTRL 0x30 112#define AIC31XX_INT1CTRL AIC31XX_REG(0, 48)
111/* INT2 interrupt control */ 113/* INT2 interrupt control */
112#define AIC31XX_INT2CTRL 0x31 114#define AIC31XX_INT2CTRL AIC31XX_REG(0, 49)
113/* GPIO1 control */ 115/* GPIO1 control */
114#define AIC31XX_GPIO1 0x33 116#define AIC31XX_GPIO1 AIC31XX_REG(0, 50)
115 117
116#define AIC31XX_DACPRB 0x3C 118#define AIC31XX_DACPRB AIC31XX_REG(0, 60)
117/* ADC Instruction Set Register */ 119/* ADC Instruction Set Register */
118#define AIC31XX_ADCPRB 0x3D 120#define AIC31XX_ADCPRB AIC31XX_REG(0, 61)
119/* DAC channel setup register */ 121/* DAC channel setup register */
120#define AIC31XX_DACSETUP 0x3F 122#define AIC31XX_DACSETUP AIC31XX_REG(0, 63)
121/* DAC Mute and volume control register */ 123/* DAC Mute and volume control register */
122#define AIC31XX_DACMUTE 0x40 124#define AIC31XX_DACMUTE AIC31XX_REG(0, 64)
123/* Left DAC channel digital volume control */ 125/* Left DAC channel digital volume control */
124#define AIC31XX_LDACVOL 0x41 126#define AIC31XX_LDACVOL AIC31XX_REG(0, 65)
125/* Right DAC channel digital volume control */ 127/* Right DAC channel digital volume control */
126#define AIC31XX_RDACVOL 0x42 128#define AIC31XX_RDACVOL AIC31XX_REG(0, 66)
127/* Headset detection */ 129/* Headset detection */
128#define AIC31XX_HSDETECT 0x43 130#define AIC31XX_HSDETECT AIC31XX_REG(0, 67)
129/* ADC Digital Mic */ 131/* ADC Digital Mic */
130#define AIC31XX_ADCSETUP 0x51 132#define AIC31XX_ADCSETUP AIC31XX_REG(0, 81)
131/* ADC Digital Volume Control Fine Adjust */ 133/* ADC Digital Volume Control Fine Adjust */
132#define AIC31XX_ADCFGA 0x52 134#define AIC31XX_ADCFGA AIC31XX_REG(0, 82)
133/* ADC Digital Volume Control Coarse Adjust */ 135/* ADC Digital Volume Control Coarse Adjust */
134#define AIC31XX_ADCVOL 0x53 136#define AIC31XX_ADCVOL AIC31XX_REG(0, 83)
135 137
136 138
137/* Page 1 Registers */ 139/* Page 1 Registers */
138/* Headphone drivers */ 140/* Headphone drivers */
139#define AIC31XX_HPDRIVER 0x9F 141#define AIC31XX_HPDRIVER AIC31XX_REG(1, 31)
140/* Class-D Speakear Amplifier */ 142/* Class-D Speakear Amplifier */
141#define AIC31XX_SPKAMP 0xA0 143#define AIC31XX_SPKAMP AIC31XX_REG(1, 32)
142/* HP Output Drivers POP Removal Settings */ 144/* HP Output Drivers POP Removal Settings */
143#define AIC31XX_HPPOP 0xA1 145#define AIC31XX_HPPOP AIC31XX_REG(1, 33)
144/* Output Driver PGA Ramp-Down Period Control */ 146/* Output Driver PGA Ramp-Down Period Control */
145#define AIC31XX_SPPGARAMP 0xA2 147#define AIC31XX_SPPGARAMP AIC31XX_REG(1, 34)
146/* DAC_L and DAC_R Output Mixer Routing */ 148/* DAC_L and DAC_R Output Mixer Routing */
147#define AIC31XX_DACMIXERROUTE 0xA3 149#define AIC31XX_DACMIXERROUTE AIC31XX_REG(1, 35)
148/* Left Analog Vol to HPL */ 150/* Left Analog Vol to HPL */
149#define AIC31XX_LANALOGHPL 0xA4 151#define AIC31XX_LANALOGHPL AIC31XX_REG(1, 36)
150/* Right Analog Vol to HPR */ 152/* Right Analog Vol to HPR */
151#define AIC31XX_RANALOGHPR 0xA5 153#define AIC31XX_RANALOGHPR AIC31XX_REG(1, 37)
152/* Left Analog Vol to SPL */ 154/* Left Analog Vol to SPL */
153#define AIC31XX_LANALOGSPL 0xA6 155#define AIC31XX_LANALOGSPL AIC31XX_REG(1, 38)
154/* Right Analog Vol to SPR */ 156/* Right Analog Vol to SPR */
155#define AIC31XX_RANALOGSPR 0xA7 157#define AIC31XX_RANALOGSPR AIC31XX_REG(1, 39)
156/* HPL Driver */ 158/* HPL Driver */
157#define AIC31XX_HPLGAIN 0xA8 159#define AIC31XX_HPLGAIN AIC31XX_REG(1, 40)
158/* HPR Driver */ 160/* HPR Driver */
159#define AIC31XX_HPRGAIN 0xA9 161#define AIC31XX_HPRGAIN AIC31XX_REG(1, 41)
160/* SPL Driver */ 162/* SPL Driver */
161#define AIC31XX_SPLGAIN 0xAA 163#define AIC31XX_SPLGAIN AIC31XX_REG(1, 42)
162/* SPR Driver */ 164/* SPR Driver */
163#define AIC31XX_SPRGAIN 0xAB 165#define AIC31XX_SPRGAIN AIC31XX_REG(1, 43)
164/* HP Driver Control */ 166/* HP Driver Control */
165#define AIC31XX_HPCONTROL 0xAC 167#define AIC31XX_HPCONTROL AIC31XX_REG(1, 44)
166/* MIC Bias Control */ 168/* MIC Bias Control */
167#define AIC31XX_MICBIAS 0xAE 169#define AIC31XX_MICBIAS AIC31XX_REG(1, 46)
168/* MIC PGA*/ 170/* MIC PGA*/
169#define AIC31XX_MICPGA 0xAF 171#define AIC31XX_MICPGA AIC31XX_REG(1, 47)
170/* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */ 172/* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */
171#define AIC31XX_MICPGAPI 0xB0 173#define AIC31XX_MICPGAPI AIC31XX_REG(1, 48)
172/* ADC Input Selection for M-Terminal */ 174/* ADC Input Selection for M-Terminal */
173#define AIC31XX_MICPGAMI 0xB1 175#define AIC31XX_MICPGAMI AIC31XX_REG(1, 49)
174/* Input CM Settings */ 176/* Input CM Settings */
175#define AIC31XX_MICPGACM 0xB2 177#define AIC31XX_MICPGACM AIC31XX_REG(1, 50)
176 178
177/* Bits, masks and shifts */ 179/* Bits, masks and shifts */
178 180
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 11d85c5c787a..f1ea052a822e 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -32,6 +32,7 @@
32#include <sound/tlv.h> 32#include <sound/tlv.h>
33#include <linux/of.h> 33#include <linux/of.h>
34#include <linux/of_gpio.h> 34#include <linux/of_gpio.h>
35#include <linux/regmap.h>
35 36
36#include "tpa6130a2.h" 37#include "tpa6130a2.h"
37 38
@@ -40,219 +41,72 @@ enum tpa_model {
40 TPA6140A2, 41 TPA6140A2,
41}; 42};
42 43
43static struct i2c_client *tpa6130a2_client;
44
45/* This struct is used to save the context */ 44/* This struct is used to save the context */
46struct tpa6130a2_data { 45struct tpa6130a2_data {
47 struct mutex mutex; 46 struct device *dev;
48 unsigned char regs[TPA6130A2_CACHEREGNUM]; 47 struct regmap *regmap;
49 struct regulator *supply; 48 struct regulator *supply;
50 int power_gpio; 49 int power_gpio;
51 u8 power_state:1;
52 enum tpa_model id; 50 enum tpa_model id;
53}; 51};
54 52
55static int tpa6130a2_i2c_read(int reg) 53static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
56{
57 struct tpa6130a2_data *data;
58 int val;
59
60 if (WARN_ON(!tpa6130a2_client))
61 return -EINVAL;
62 data = i2c_get_clientdata(tpa6130a2_client);
63
64 /* If powered off, return the cached value */
65 if (data->power_state) {
66 val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
67 if (val < 0)
68 dev_err(&tpa6130a2_client->dev, "Read failed\n");
69 else
70 data->regs[reg] = val;
71 } else {
72 val = data->regs[reg];
73 }
74
75 return val;
76}
77
78static int tpa6130a2_i2c_write(int reg, u8 value)
79{
80 struct tpa6130a2_data *data;
81 int val = 0;
82
83 if (WARN_ON(!tpa6130a2_client))
84 return -EINVAL;
85 data = i2c_get_clientdata(tpa6130a2_client);
86
87 if (data->power_state) {
88 val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
89 if (val < 0) {
90 dev_err(&tpa6130a2_client->dev, "Write failed\n");
91 return val;
92 }
93 }
94
95 /* Either powered on or off, we save the context */
96 data->regs[reg] = value;
97
98 return val;
99}
100
101static u8 tpa6130a2_read(int reg)
102{
103 struct tpa6130a2_data *data;
104
105 if (WARN_ON(!tpa6130a2_client))
106 return 0;
107 data = i2c_get_clientdata(tpa6130a2_client);
108
109 return data->regs[reg];
110}
111
112static int tpa6130a2_initialize(void)
113{
114 struct tpa6130a2_data *data;
115 int i, ret = 0;
116
117 if (WARN_ON(!tpa6130a2_client))
118 return -EINVAL;
119 data = i2c_get_clientdata(tpa6130a2_client);
120
121 for (i = 1; i < TPA6130A2_REG_VERSION; i++) {
122 ret = tpa6130a2_i2c_write(i, data->regs[i]);
123 if (ret < 0)
124 break;
125 }
126
127 return ret;
128}
129
130static int tpa6130a2_power(u8 power)
131{ 54{
132 struct tpa6130a2_data *data; 55 int ret;
133 u8 val;
134 int ret = 0;
135
136 if (WARN_ON(!tpa6130a2_client))
137 return -EINVAL;
138 data = i2c_get_clientdata(tpa6130a2_client);
139
140 mutex_lock(&data->mutex);
141 if (power == data->power_state)
142 goto exit;
143 56
144 if (power) { 57 if (enable) {
145 ret = regulator_enable(data->supply); 58 ret = regulator_enable(data->supply);
146 if (ret != 0) { 59 if (ret != 0) {
147 dev_err(&tpa6130a2_client->dev, 60 dev_err(data->dev,
148 "Failed to enable supply: %d\n", ret); 61 "Failed to enable supply: %d\n", ret);
149 goto exit; 62 return ret;
150 } 63 }
151 /* Power on */ 64 /* Power on */
152 if (data->power_gpio >= 0) 65 if (data->power_gpio >= 0)
153 gpio_set_value(data->power_gpio, 1); 66 gpio_set_value(data->power_gpio, 1);
154
155 data->power_state = 1;
156 ret = tpa6130a2_initialize();
157 if (ret < 0) {
158 dev_err(&tpa6130a2_client->dev,
159 "Failed to initialize chip\n");
160 if (data->power_gpio >= 0)
161 gpio_set_value(data->power_gpio, 0);
162 regulator_disable(data->supply);
163 data->power_state = 0;
164 goto exit;
165 }
166 } else { 67 } else {
167 /* set SWS */
168 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
169 val |= TPA6130A2_SWS;
170 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
171
172 /* Power off */ 68 /* Power off */
173 if (data->power_gpio >= 0) 69 if (data->power_gpio >= 0)
174 gpio_set_value(data->power_gpio, 0); 70 gpio_set_value(data->power_gpio, 0);
175 71
176 ret = regulator_disable(data->supply); 72 ret = regulator_disable(data->supply);
177 if (ret != 0) { 73 if (ret != 0) {
178 dev_err(&tpa6130a2_client->dev, 74 dev_err(data->dev,
179 "Failed to disable supply: %d\n", ret); 75 "Failed to disable supply: %d\n", ret);
180 goto exit; 76 return ret;
181 } 77 }
182 78
183 data->power_state = 0; 79 /* device regs does not match the cache state anymore */
80 regcache_mark_dirty(data->regmap);
184 } 81 }
185 82
186exit:
187 mutex_unlock(&data->mutex);
188 return ret; 83 return ret;
189} 84}
190 85
191static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol, 86static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
192 struct snd_ctl_elem_value *ucontrol) 87 struct snd_kcontrol *kctrl, int event)
193{ 88{
194 struct soc_mixer_control *mc = 89 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
195 (struct soc_mixer_control *)kcontrol->private_value; 90 struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
196 struct tpa6130a2_data *data; 91 int ret;
197 unsigned int reg = mc->reg;
198 unsigned int shift = mc->shift;
199 int max = mc->max;
200 unsigned int mask = (1 << fls(max)) - 1;
201 unsigned int invert = mc->invert;
202
203 if (WARN_ON(!tpa6130a2_client))
204 return -EINVAL;
205 data = i2c_get_clientdata(tpa6130a2_client);
206
207 mutex_lock(&data->mutex);
208
209 ucontrol->value.integer.value[0] =
210 (tpa6130a2_read(reg) >> shift) & mask;
211
212 if (invert)
213 ucontrol->value.integer.value[0] =
214 max - ucontrol->value.integer.value[0];
215
216 mutex_unlock(&data->mutex);
217 return 0;
218}
219 92
220static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol, 93 /* before widget power up */
221 struct snd_ctl_elem_value *ucontrol) 94 if (SND_SOC_DAPM_EVENT_ON(event)) {
222{ 95 /* Turn on the chip */
223 struct soc_mixer_control *mc = 96 tpa6130a2_power(data, true);
224 (struct soc_mixer_control *)kcontrol->private_value; 97 /* Sync the registers */
225 struct tpa6130a2_data *data; 98 ret = regcache_sync(data->regmap);
226 unsigned int reg = mc->reg; 99 if (ret < 0) {
227 unsigned int shift = mc->shift; 100 dev_err(c->dev, "Failed to initialize chip\n");
228 int max = mc->max; 101 tpa6130a2_power(data, false);
229 unsigned int mask = (1 << fls(max)) - 1; 102 return ret;
230 unsigned int invert = mc->invert; 103 }
231 unsigned int val = (ucontrol->value.integer.value[0] & mask); 104 /* after widget power down */
232 unsigned int val_reg; 105 } else {
233 106 tpa6130a2_power(data, false);
234 if (WARN_ON(!tpa6130a2_client))
235 return -EINVAL;
236 data = i2c_get_clientdata(tpa6130a2_client);
237
238 if (invert)
239 val = max - val;
240
241 mutex_lock(&data->mutex);
242
243 val_reg = tpa6130a2_read(reg);
244 if (((val_reg >> shift) & mask) == val) {
245 mutex_unlock(&data->mutex);
246 return 0;
247 } 107 }
248 108
249 val_reg &= ~(mask << shift); 109 return 0;
250 val_reg |= val << shift;
251 tpa6130a2_i2c_write(reg, val_reg);
252
253 mutex_unlock(&data->mutex);
254
255 return 1;
256} 110}
257 111
258/* 112/*
@@ -273,9 +127,8 @@ static const DECLARE_TLV_DB_RANGE(tpa6130_tlv,
273); 127);
274 128
275static const struct snd_kcontrol_new tpa6130a2_controls[] = { 129static const struct snd_kcontrol_new tpa6130a2_controls[] = {
276 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume", 130 SOC_SINGLE_TLV("Headphone Playback Volume",
277 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0, 131 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
278 tpa6130a2_get_volsw, tpa6130a2_put_volsw,
279 tpa6130_tlv), 132 tpa6130_tlv),
280}; 133};
281 134
@@ -286,85 +139,79 @@ static const DECLARE_TLV_DB_RANGE(tpa6140_tlv,
286); 139);
287 140
288static const struct snd_kcontrol_new tpa6140a2_controls[] = { 141static const struct snd_kcontrol_new tpa6140a2_controls[] = {
289 SOC_SINGLE_EXT_TLV("TPA6140A2 Headphone Playback Volume", 142 SOC_SINGLE_TLV("Headphone Playback Volume",
290 TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0, 143 TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
291 tpa6130a2_get_volsw, tpa6130a2_put_volsw,
292 tpa6140_tlv), 144 tpa6140_tlv),
293}; 145};
294 146
295/* 147static int tpa6130a2_component_probe(struct snd_soc_component *component)
296 * Enable or disable channel (left or right)
297 * The bit number for mute and amplifier are the same per channel:
298 * bit 6: Right channel
299 * bit 7: Left channel
300 * in both registers.
301 */
302static void tpa6130a2_channel_enable(u8 channel, int enable)
303{ 148{
304 u8 val; 149 struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
305 150
306 if (enable) { 151 if (data->id == TPA6140A2)
307 /* Enable channel */ 152 return snd_soc_add_component_controls(component,
308 /* Enable amplifier */ 153 tpa6140a2_controls, ARRAY_SIZE(tpa6140a2_controls));
309 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 154 else
310 val |= channel; 155 return snd_soc_add_component_controls(component,
311 val &= ~TPA6130A2_SWS; 156 tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
312 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
313
314 /* Unmute channel */
315 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
316 val &= ~channel;
317 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
318 } else {
319 /* Disable channel */
320 /* Mute channel */
321 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
322 val |= channel;
323 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
324
325 /* Disable amplifier */
326 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
327 val &= ~channel;
328 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
329 }
330} 157}
331 158
332int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable) 159static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
333{ 160 SND_SOC_DAPM_INPUT("LEFTIN"),
334 int ret = 0; 161 SND_SOC_DAPM_INPUT("RIGHTIN"),
335 if (enable) { 162 SND_SOC_DAPM_OUTPUT("HPLEFT"),
336 ret = tpa6130a2_power(1); 163 SND_SOC_DAPM_OUTPUT("HPRIGHT"),
337 if (ret < 0) 164
338 return ret; 165 SND_SOC_DAPM_PGA("Left Mute", TPA6130A2_REG_VOL_MUTE,
339 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, 166 TPA6130A2_HP_EN_L_SHIFT, 1, NULL, 0),
340 1); 167 SND_SOC_DAPM_PGA("Right Mute", TPA6130A2_REG_VOL_MUTE,
341 } else { 168 TPA6130A2_HP_EN_R_SHIFT, 1, NULL, 0),
342 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, 169 SND_SOC_DAPM_PGA("Left PGA", TPA6130A2_REG_CONTROL,
343 0); 170 TPA6130A2_HP_EN_L_SHIFT, 0, NULL, 0),
344 ret = tpa6130a2_power(0); 171 SND_SOC_DAPM_PGA("Right PGA", TPA6130A2_REG_CONTROL,
345 } 172 TPA6130A2_HP_EN_R_SHIFT, 0, NULL, 0),
173
174 SND_SOC_DAPM_SUPPLY("Power", TPA6130A2_REG_CONTROL,
175 TPA6130A2_SWS_SHIFT, 1, tpa6130a2_power_event,
176 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
177};
346 178
347 return ret; 179static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = {
348} 180 { "Left PGA", NULL, "LEFTIN" },
349EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable); 181 { "Right PGA", NULL, "RIGHTIN" },
350 182
351int tpa6130a2_add_controls(struct snd_soc_codec *codec) 183 { "Left Mute", NULL, "Left PGA" },
352{ 184 { "Right Mute", NULL, "Right PGA" },
353 struct tpa6130a2_data *data;
354 185
355 if (tpa6130a2_client == NULL) 186 { "HPLEFT", NULL, "Left Mute" },
356 return -ENODEV; 187 { "HPRIGHT", NULL, "Right Mute" },
357 188
358 data = i2c_get_clientdata(tpa6130a2_client); 189 { "Left PGA", NULL, "Power" },
190 { "Right PGA", NULL, "Power" },
191};
359 192
360 if (data->id == TPA6140A2) 193struct snd_soc_component_driver tpa6130a2_component_driver = {
361 return snd_soc_add_codec_controls(codec, tpa6140a2_controls, 194 .name = "tpa6130a2",
362 ARRAY_SIZE(tpa6140a2_controls)); 195 .probe = tpa6130a2_component_probe,
363 else 196 .dapm_widgets = tpa6130a2_dapm_widgets,
364 return snd_soc_add_codec_controls(codec, tpa6130a2_controls, 197 .num_dapm_widgets = ARRAY_SIZE(tpa6130a2_dapm_widgets),
365 ARRAY_SIZE(tpa6130a2_controls)); 198 .dapm_routes = tpa6130a2_dapm_routes,
366} 199 .num_dapm_routes = ARRAY_SIZE(tpa6130a2_dapm_routes),
367EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 200};
201
202static const struct reg_default tpa6130a2_reg_defaults[] = {
203 { TPA6130A2_REG_CONTROL, TPA6130A2_SWS },
204 { TPA6130A2_REG_VOL_MUTE, TPA6130A2_MUTE_R | TPA6130A2_MUTE_L },
205};
206
207static const struct regmap_config tpa6130a2_regmap_config = {
208 .reg_bits = 8,
209 .val_bits = 8,
210 .max_register = TPA6130A2_REG_VERSION,
211 .reg_defaults = tpa6130a2_reg_defaults,
212 .num_reg_defaults = ARRAY_SIZE(tpa6130a2_reg_defaults),
213 .cache_type = REGCACHE_RBTREE,
214};
368 215
369static int tpa6130a2_probe(struct i2c_client *client, 216static int tpa6130a2_probe(struct i2c_client *client,
370 const struct i2c_device_id *id) 217 const struct i2c_device_id *id)
@@ -374,6 +221,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
374 struct tpa6130a2_platform_data *pdata = client->dev.platform_data; 221 struct tpa6130a2_platform_data *pdata = client->dev.platform_data;
375 struct device_node *np = client->dev.of_node; 222 struct device_node *np = client->dev.of_node;
376 const char *regulator; 223 const char *regulator;
224 unsigned int version;
377 int ret; 225 int ret;
378 226
379 dev = &client->dev; 227 dev = &client->dev;
@@ -382,6 +230,12 @@ static int tpa6130a2_probe(struct i2c_client *client,
382 if (!data) 230 if (!data)
383 return -ENOMEM; 231 return -ENOMEM;
384 232
233 data->dev = dev;
234
235 data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
236 if (IS_ERR(data->regmap))
237 return PTR_ERR(data->regmap);
238
385 if (pdata) { 239 if (pdata) {
386 data->power_gpio = pdata->power_gpio; 240 data->power_gpio = pdata->power_gpio;
387 } else if (np) { 241 } else if (np) {
@@ -392,26 +246,17 @@ static int tpa6130a2_probe(struct i2c_client *client,
392 return -ENODEV; 246 return -ENODEV;
393 } 247 }
394 248
395 tpa6130a2_client = client; 249 i2c_set_clientdata(client, data);
396
397 i2c_set_clientdata(tpa6130a2_client, data);
398 250
399 data->id = id->driver_data; 251 data->id = id->driver_data;
400 252
401 mutex_init(&data->mutex);
402
403 /* Set default register values */
404 data->regs[TPA6130A2_REG_CONTROL] = TPA6130A2_SWS;
405 data->regs[TPA6130A2_REG_VOL_MUTE] = TPA6130A2_MUTE_R |
406 TPA6130A2_MUTE_L;
407
408 if (data->power_gpio >= 0) { 253 if (data->power_gpio >= 0) {
409 ret = devm_gpio_request(dev, data->power_gpio, 254 ret = devm_gpio_request(dev, data->power_gpio,
410 "tpa6130a2 enable"); 255 "tpa6130a2 enable");
411 if (ret < 0) { 256 if (ret < 0) {
412 dev_err(dev, "Failed to request power GPIO (%d)\n", 257 dev_err(dev, "Failed to request power GPIO (%d)\n",
413 data->power_gpio); 258 data->power_gpio);
414 goto err_gpio; 259 return ret;
415 } 260 }
416 gpio_direction_output(data->power_gpio, 0); 261 gpio_direction_output(data->power_gpio, 0);
417 } 262 }
@@ -432,39 +277,27 @@ static int tpa6130a2_probe(struct i2c_client *client,
432 if (IS_ERR(data->supply)) { 277 if (IS_ERR(data->supply)) {
433 ret = PTR_ERR(data->supply); 278 ret = PTR_ERR(data->supply);
434 dev_err(dev, "Failed to request supply: %d\n", ret); 279 dev_err(dev, "Failed to request supply: %d\n", ret);
435 goto err_gpio; 280 return ret;
436 } 281 }
437 282
438 ret = tpa6130a2_power(1); 283 ret = tpa6130a2_power(data, true);
439 if (ret != 0) 284 if (ret != 0)
440 goto err_gpio; 285 return ret;
441 286
442 287
443 /* Read version */ 288 /* Read version */
444 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) & 289 regmap_read(data->regmap, TPA6130A2_REG_VERSION, &version);
445 TPA6130A2_VERSION_MASK; 290 version &= TPA6130A2_VERSION_MASK;
446 if ((ret != 1) && (ret != 2)) 291 if ((version != 1) && (version != 2))
447 dev_warn(dev, "UNTESTED version detected (%d)\n", ret); 292 dev_warn(dev, "UNTESTED version detected (%d)\n", version);
448 293
449 /* Disable the chip */ 294 /* Disable the chip */
450 ret = tpa6130a2_power(0); 295 ret = tpa6130a2_power(data, false);
451 if (ret != 0) 296 if (ret != 0)
452 goto err_gpio; 297 return ret;
453
454 return 0;
455
456err_gpio:
457 tpa6130a2_client = NULL;
458 298
459 return ret; 299 return devm_snd_soc_register_component(&client->dev,
460} 300 &tpa6130a2_component_driver, NULL, 0);
461
462static int tpa6130a2_remove(struct i2c_client *client)
463{
464 tpa6130a2_power(0);
465 tpa6130a2_client = NULL;
466
467 return 0;
468} 301}
469 302
470static const struct i2c_device_id tpa6130a2_id[] = { 303static const struct i2c_device_id tpa6130a2_id[] = {
@@ -489,7 +322,6 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
489 .of_match_table = of_match_ptr(tpa6130a2_of_match), 322 .of_match_table = of_match_ptr(tpa6130a2_of_match),
490 }, 323 },
491 .probe = tpa6130a2_probe, 324 .probe = tpa6130a2_probe,
492 .remove = tpa6130a2_remove,
493 .id_table = tpa6130a2_id, 325 .id_table = tpa6130a2_id,
494}; 326};
495 327
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 417444020ba6..f19cad5d4172 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -30,19 +30,20 @@
30#define TPA6130A2_REG_OUT_IMPEDANCE 0x03 30#define TPA6130A2_REG_OUT_IMPEDANCE 0x03
31#define TPA6130A2_REG_VERSION 0x04 31#define TPA6130A2_REG_VERSION 0x04
32 32
33#define TPA6130A2_CACHEREGNUM (TPA6130A2_REG_VERSION + 1)
34
35/* Register bits */ 33/* Register bits */
36/* TPA6130A2_REG_CONTROL (0x01) */ 34/* TPA6130A2_REG_CONTROL (0x01) */
37#define TPA6130A2_SWS (0x01 << 0) 35#define TPA6130A2_SWS_SHIFT 0
36#define TPA6130A2_SWS (0x01 << TPA6130A2_SWS_SHIFT)
38#define TPA6130A2_TERMAL (0x01 << 1) 37#define TPA6130A2_TERMAL (0x01 << 1)
39#define TPA6130A2_MODE(x) (x << 4) 38#define TPA6130A2_MODE(x) (x << 4)
40#define TPA6130A2_MODE_STEREO (0x00) 39#define TPA6130A2_MODE_STEREO (0x00)
41#define TPA6130A2_MODE_DUAL_MONO (0x01) 40#define TPA6130A2_MODE_DUAL_MONO (0x01)
42#define TPA6130A2_MODE_BRIDGE (0x02) 41#define TPA6130A2_MODE_BRIDGE (0x02)
43#define TPA6130A2_MODE_MASK (0x03) 42#define TPA6130A2_MODE_MASK (0x03)
44#define TPA6130A2_HP_EN_R (0x01 << 6) 43#define TPA6130A2_HP_EN_R_SHIFT 6
45#define TPA6130A2_HP_EN_L (0x01 << 7) 44#define TPA6130A2_HP_EN_R (0x01 << TPA6130A2_HP_EN_R_SHIFT)
45#define TPA6130A2_HP_EN_L_SHIFT 7
46#define TPA6130A2_HP_EN_L (0x01 << TPA6130A2_HP_EN_L_SHIFT)
46 47
47/* TPA6130A2_REG_VOL_MUTE (0x02) */ 48/* TPA6130A2_REG_VOL_MUTE (0x02) */
48#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0) 49#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
@@ -56,7 +57,4 @@
56/* TPA6130A2_REG_VERSION (0x04) */ 57/* TPA6130A2_REG_VERSION (0x04) */
57#define TPA6130A2_VERSION_MASK (0x0f) 58#define TPA6130A2_VERSION_MASK (0x0f)
58 59
59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
60extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
61
62#endif /* __TPA6130A2_H__ */ 60#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index e7fe6b7b95b7..846deed6af41 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1713,6 +1713,7 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1713 1713
1714 { "MICSUPP", NULL, "SYSCLK" }, 1714 { "MICSUPP", NULL, "SYSCLK" },
1715 1715
1716 { "DRC1 Signal Activity", NULL, "SYSCLK" },
1716 { "DRC1 Signal Activity", NULL, "DRC1L" }, 1717 { "DRC1 Signal Activity", NULL, "DRC1L" },
1717 { "DRC1 Signal Activity", NULL, "DRC1R" }, 1718 { "DRC1 Signal Activity", NULL, "DRC1R" },
1718}; 1719};
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index d54f1b46c9ec..156547026a40 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -1104,6 +1104,11 @@ SND_SOC_DAPM_INPUT("IN4R"),
1104SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"), 1104SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
1105SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"), 1105SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
1106 1106
1107SND_SOC_DAPM_OUTPUT("DSP Voice Trigger"),
1108
1109SND_SOC_DAPM_SWITCH("DSP3 Voice Trigger", SND_SOC_NOPM, 2, 0,
1110 &arizona_voice_trigger_switch[2]),
1111
1107SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 1112SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
1108 0, NULL, 0, wm5110_in_ev, 1113 0, NULL, 0, wm5110_in_ev,
1109 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1114 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
@@ -1998,10 +2003,16 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1998 2003
1999 { "MICSUPP", NULL, "SYSCLK" }, 2004 { "MICSUPP", NULL, "SYSCLK" },
2000 2005
2006 { "DRC1 Signal Activity", NULL, "SYSCLK" },
2007 { "DRC2 Signal Activity", NULL, "SYSCLK" },
2001 { "DRC1 Signal Activity", NULL, "DRC1L" }, 2008 { "DRC1 Signal Activity", NULL, "DRC1L" },
2002 { "DRC1 Signal Activity", NULL, "DRC1R" }, 2009 { "DRC1 Signal Activity", NULL, "DRC1R" },
2003 { "DRC2 Signal Activity", NULL, "DRC2L" }, 2010 { "DRC2 Signal Activity", NULL, "DRC2L" },
2004 { "DRC2 Signal Activity", NULL, "DRC2R" }, 2011 { "DRC2 Signal Activity", NULL, "DRC2R" },
2012
2013 { "DSP Voice Trigger", NULL, "SYSCLK" },
2014 { "DSP Voice Trigger", NULL, "DSP3 Voice Trigger" },
2015 { "DSP3 Voice Trigger", "Switch", "DSP3" },
2005}; 2016};
2006 2017
2007static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source, 2018static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
@@ -2223,6 +2234,7 @@ static irqreturn_t wm5110_adsp2_irq(int irq, void *data)
2223{ 2234{
2224 struct wm5110_priv *priv = data; 2235 struct wm5110_priv *priv = data;
2225 struct arizona *arizona = priv->core.arizona; 2236 struct arizona *arizona = priv->core.arizona;
2237 struct arizona_voice_trigger_info info;
2226 int serviced = 0; 2238 int serviced = 0;
2227 int i, ret; 2239 int i, ret;
2228 2240
@@ -2230,6 +2242,12 @@ static irqreturn_t wm5110_adsp2_irq(int irq, void *data)
2230 ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]); 2242 ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]);
2231 if (ret != -ENODEV) 2243 if (ret != -ENODEV)
2232 serviced++; 2244 serviced++;
2245 if (ret == WM_ADSP_COMPR_VOICE_TRIGGER) {
2246 info.core = i;
2247 arizona_call_notifiers(arizona,
2248 ARIZONA_NOTIFY_VOICE_TRIGGER,
2249 &info);
2250 }
2233 } 2251 }
2234 2252
2235 if (!serviced) { 2253 if (!serviced) {
@@ -2252,6 +2270,7 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
2252 arizona_init_spk(codec); 2270 arizona_init_spk(codec);
2253 arizona_init_gpio(codec); 2271 arizona_init_gpio(codec);
2254 arizona_init_mono(codec); 2272 arizona_init_mono(codec);
2273 arizona_init_notifiers(codec);
2255 2274
2256 ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, 2275 ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
2257 "ADSP2 Compressed IRQ", wm5110_adsp2_irq, 2276 "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 4bcf5f8ece50..d18261a44256 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -358,6 +358,9 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
358 case 24: 358 case 24:
359 iface |= 0x0008; 359 iface |= 0x0008;
360 break; 360 break;
361 case 32:
362 iface |= 0x000c;
363 break;
361 } 364 }
362 365
363 wm8731_set_deemph(codec); 366 wm8731_set_deemph(codec);
@@ -541,7 +544,7 @@ static int wm8731_startup(struct snd_pcm_substream *substream,
541#define WM8731_RATES SNDRV_PCM_RATE_8000_96000 544#define WM8731_RATES SNDRV_PCM_RATE_8000_96000
542 545
543#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 546#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
544 SNDRV_PCM_FMTBIT_S24_LE) 547 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
545 548
546static const struct snd_soc_dai_ops wm8731_dai_ops = { 549static const struct snd_soc_dai_ops wm8731_dai_ops = {
547 .startup = wm8731_startup, 550 .startup = wm8731_startup,
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 6f1024f48b19..cdcc91282e8a 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -32,7 +32,6 @@
32 */ 32 */
33 33
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/kernel.h> 35#include <linux/kernel.h>
37#include <linux/init.h> 36#include <linux/init.h>
38#include <linux/delay.h> 37#include <linux/delay.h>
@@ -486,7 +485,7 @@ SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0),
486SND_SOC_DAPM_OUTPUT("MONO1"), 485SND_SOC_DAPM_OUTPUT("MONO1"),
487SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls), 486SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls),
488SND_SOC_DAPM_OUTPUT("MONO2"), 487SND_SOC_DAPM_OUTPUT("MONO2"),
489SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0), 488SND_SOC_DAPM_MIXER("Out3 Left + Right", SND_SOC_NOPM, 0, 0, NULL, 0),
490SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls), 489SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls),
491SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0), 490SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0),
492SND_SOC_DAPM_OUTPUT("OUT3"), 491SND_SOC_DAPM_OUTPUT("OUT3"),
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index 6ac76fe116b0..7347abff4b2c 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -1,10 +1,13 @@
1/* 1/*
2 * wm8985.c -- WM8985 ALSA SoC Audio driver 2 * wm8985.c -- WM8985 / WM8758 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2010 Wolfson Microelectronics plc 4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> 5 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 * 6 *
7 * WM8758 support:
8 * Copyright: 2016 Barix AG
9 * Author: Petr Kulhavy <petr@barix.com>
10 *
8 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
@@ -40,6 +43,11 @@ static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = {
40 "AVDD2" 43 "AVDD2"
41}; 44};
42 45
46enum wm8985_type {
47 WM8985,
48 WM8758,
49};
50
43static const struct reg_default wm8985_reg_defaults[] = { 51static const struct reg_default wm8985_reg_defaults[] = {
44 { 1, 0x0000 }, /* R1 - Power management 1 */ 52 { 1, 0x0000 }, /* R1 - Power management 1 */
45 { 2, 0x0000 }, /* R2 - Power management 2 */ 53 { 2, 0x0000 }, /* R2 - Power management 2 */
@@ -181,6 +189,7 @@ static const int volume_update_regs[] = {
181struct wm8985_priv { 189struct wm8985_priv {
182 struct regmap *regmap; 190 struct regmap *regmap;
183 struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES]; 191 struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES];
192 enum wm8985_type dev_type;
184 unsigned int sysclk; 193 unsigned int sysclk;
185 unsigned int bclk; 194 unsigned int bclk;
186}; 195};
@@ -289,7 +298,7 @@ static const char *depth_3d_text[] = {
289}; 298};
290static SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, depth_3d_text); 299static SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0, depth_3d_text);
291 300
292static const struct snd_kcontrol_new wm8985_snd_controls[] = { 301static const struct snd_kcontrol_new wm8985_common_snd_controls[] = {
293 SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL, 302 SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL,
294 0, 1, 0), 303 0, 1, 0),
295 304
@@ -355,10 +364,6 @@ static const struct snd_kcontrol_new wm8985_snd_controls[] = {
355 SOC_ENUM("High Pass Filter Mode", filter_mode), 364 SOC_ENUM("High Pass Filter Mode", filter_mode),
356 SOC_SINGLE("High Pass Filter Cutoff", WM8985_ADC_CONTROL, 4, 7, 0), 365 SOC_SINGLE("High Pass Filter Cutoff", WM8985_ADC_CONTROL, 4, 7, 0),
357 366
358 SOC_DOUBLE_R_TLV("Aux Bypass Volume",
359 WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 6, 7, 0,
360 aux_tlv),
361
362 SOC_DOUBLE_R_TLV("Input PGA Bypass Volume", 367 SOC_DOUBLE_R_TLV("Input PGA Bypass Volume",
363 WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 2, 7, 0, 368 WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 2, 7, 0,
364 bypass_tlv), 369 bypass_tlv),
@@ -379,20 +384,30 @@ static const struct snd_kcontrol_new wm8985_snd_controls[] = {
379 SOC_SINGLE_TLV("EQ5 Volume", WM8985_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv), 384 SOC_SINGLE_TLV("EQ5 Volume", WM8985_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),
380 385
381 SOC_ENUM("3D Depth", depth_3d), 386 SOC_ENUM("3D Depth", depth_3d),
387};
388
389static const struct snd_kcontrol_new wm8985_specific_snd_controls[] = {
390 SOC_DOUBLE_R_TLV("Aux Bypass Volume",
391 WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 6, 7, 0,
392 aux_tlv),
382 393
383 SOC_ENUM("Speaker Mode", speaker_mode) 394 SOC_ENUM("Speaker Mode", speaker_mode)
384}; 395};
385 396
386static const struct snd_kcontrol_new left_out_mixer[] = { 397static const struct snd_kcontrol_new left_out_mixer[] = {
387 SOC_DAPM_SINGLE("Line Switch", WM8985_LEFT_MIXER_CTRL, 1, 1, 0), 398 SOC_DAPM_SINGLE("Line Switch", WM8985_LEFT_MIXER_CTRL, 1, 1, 0),
388 SOC_DAPM_SINGLE("Aux Switch", WM8985_LEFT_MIXER_CTRL, 5, 1, 0),
389 SOC_DAPM_SINGLE("PCM Switch", WM8985_LEFT_MIXER_CTRL, 0, 1, 0), 399 SOC_DAPM_SINGLE("PCM Switch", WM8985_LEFT_MIXER_CTRL, 0, 1, 0),
400
401 /* --- WM8985 only --- */
402 SOC_DAPM_SINGLE("Aux Switch", WM8985_LEFT_MIXER_CTRL, 5, 1, 0),
390}; 403};
391 404
392static const struct snd_kcontrol_new right_out_mixer[] = { 405static const struct snd_kcontrol_new right_out_mixer[] = {
393 SOC_DAPM_SINGLE("Line Switch", WM8985_RIGHT_MIXER_CTRL, 1, 1, 0), 406 SOC_DAPM_SINGLE("Line Switch", WM8985_RIGHT_MIXER_CTRL, 1, 1, 0),
394 SOC_DAPM_SINGLE("Aux Switch", WM8985_RIGHT_MIXER_CTRL, 5, 1, 0),
395 SOC_DAPM_SINGLE("PCM Switch", WM8985_RIGHT_MIXER_CTRL, 0, 1, 0), 407 SOC_DAPM_SINGLE("PCM Switch", WM8985_RIGHT_MIXER_CTRL, 0, 1, 0),
408
409 /* --- WM8985 only --- */
410 SOC_DAPM_SINGLE("Aux Switch", WM8985_RIGHT_MIXER_CTRL, 5, 1, 0),
396}; 411};
397 412
398static const struct snd_kcontrol_new left_input_mixer[] = { 413static const struct snd_kcontrol_new left_input_mixer[] = {
@@ -410,6 +425,8 @@ static const struct snd_kcontrol_new right_input_mixer[] = {
410static const struct snd_kcontrol_new left_boost_mixer[] = { 425static const struct snd_kcontrol_new left_boost_mixer[] = {
411 SOC_DAPM_SINGLE_TLV("L2 Volume", WM8985_LEFT_ADC_BOOST_CTRL, 426 SOC_DAPM_SINGLE_TLV("L2 Volume", WM8985_LEFT_ADC_BOOST_CTRL,
412 4, 7, 0, boost_tlv), 427 4, 7, 0, boost_tlv),
428
429 /* --- WM8985 only --- */
413 SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8985_LEFT_ADC_BOOST_CTRL, 430 SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8985_LEFT_ADC_BOOST_CTRL,
414 0, 7, 0, boost_tlv) 431 0, 7, 0, boost_tlv)
415}; 432};
@@ -417,11 +434,13 @@ static const struct snd_kcontrol_new left_boost_mixer[] = {
417static const struct snd_kcontrol_new right_boost_mixer[] = { 434static const struct snd_kcontrol_new right_boost_mixer[] = {
418 SOC_DAPM_SINGLE_TLV("R2 Volume", WM8985_RIGHT_ADC_BOOST_CTRL, 435 SOC_DAPM_SINGLE_TLV("R2 Volume", WM8985_RIGHT_ADC_BOOST_CTRL,
419 4, 7, 0, boost_tlv), 436 4, 7, 0, boost_tlv),
437
438 /* --- WM8985 only --- */
420 SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8985_RIGHT_ADC_BOOST_CTRL, 439 SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8985_RIGHT_ADC_BOOST_CTRL,
421 0, 7, 0, boost_tlv) 440 0, 7, 0, boost_tlv)
422}; 441};
423 442
424static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = { 443static const struct snd_soc_dapm_widget wm8985_common_dapm_widgets[] = {
425 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8985_POWER_MANAGEMENT_3, 444 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8985_POWER_MANAGEMENT_3,
426 0, 0), 445 0, 0),
427 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8985_POWER_MANAGEMENT_3, 446 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8985_POWER_MANAGEMENT_3,
@@ -431,21 +450,11 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
431 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8985_POWER_MANAGEMENT_2, 450 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8985_POWER_MANAGEMENT_2,
432 1, 0), 451 1, 0),
433 452
434 SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3,
435 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),
436 SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3,
437 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),
438
439 SND_SOC_DAPM_MIXER("Left Input Mixer", WM8985_POWER_MANAGEMENT_2, 453 SND_SOC_DAPM_MIXER("Left Input Mixer", WM8985_POWER_MANAGEMENT_2,
440 2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)), 454 2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)),
441 SND_SOC_DAPM_MIXER("Right Input Mixer", WM8985_POWER_MANAGEMENT_2, 455 SND_SOC_DAPM_MIXER("Right Input Mixer", WM8985_POWER_MANAGEMENT_2,
442 3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)), 456 3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)),
443 457
444 SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2,
445 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),
446 SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2,
447 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),
448
449 SND_SOC_DAPM_PGA("Left Capture PGA", WM8985_LEFT_INP_PGA_GAIN_CTRL, 458 SND_SOC_DAPM_PGA("Left Capture PGA", WM8985_LEFT_INP_PGA_GAIN_CTRL,
450 6, 1, NULL, 0), 459 6, 1, NULL, 0),
451 SND_SOC_DAPM_PGA("Right Capture PGA", WM8985_RIGHT_INP_PGA_GAIN_CTRL, 460 SND_SOC_DAPM_PGA("Right Capture PGA", WM8985_RIGHT_INP_PGA_GAIN_CTRL,
@@ -468,8 +477,6 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
468 SND_SOC_DAPM_INPUT("LIP"), 477 SND_SOC_DAPM_INPUT("LIP"),
469 SND_SOC_DAPM_INPUT("RIN"), 478 SND_SOC_DAPM_INPUT("RIN"),
470 SND_SOC_DAPM_INPUT("RIP"), 479 SND_SOC_DAPM_INPUT("RIP"),
471 SND_SOC_DAPM_INPUT("AUXL"),
472 SND_SOC_DAPM_INPUT("AUXR"),
473 SND_SOC_DAPM_INPUT("L2"), 480 SND_SOC_DAPM_INPUT("L2"),
474 SND_SOC_DAPM_INPUT("R2"), 481 SND_SOC_DAPM_INPUT("R2"),
475 SND_SOC_DAPM_OUTPUT("HPL"), 482 SND_SOC_DAPM_OUTPUT("HPL"),
@@ -478,13 +485,42 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
478 SND_SOC_DAPM_OUTPUT("SPKR") 485 SND_SOC_DAPM_OUTPUT("SPKR")
479}; 486};
480 487
481static const struct snd_soc_dapm_route wm8985_dapm_routes[] = { 488static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
489 SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3,
490 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),
491 SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3,
492 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),
493
494 SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2,
495 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),
496 SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2,
497 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),
498
499 SND_SOC_DAPM_INPUT("AUXL"),
500 SND_SOC_DAPM_INPUT("AUXR"),
501};
502
503static const struct snd_soc_dapm_widget wm8758_dapm_widgets[] = {
504 SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3,
505 2, 0, left_out_mixer,
506 ARRAY_SIZE(left_out_mixer) - 1),
507 SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3,
508 3, 0, right_out_mixer,
509 ARRAY_SIZE(right_out_mixer) - 1),
510
511 SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2,
512 4, 0, left_boost_mixer,
513 ARRAY_SIZE(left_boost_mixer) - 1),
514 SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2,
515 5, 0, right_boost_mixer,
516 ARRAY_SIZE(right_boost_mixer) - 1),
517};
518
519static const struct snd_soc_dapm_route wm8985_common_dapm_routes[] = {
482 { "Right Output Mixer", "PCM Switch", "Right DAC" }, 520 { "Right Output Mixer", "PCM Switch", "Right DAC" },
483 { "Right Output Mixer", "Aux Switch", "AUXR" },
484 { "Right Output Mixer", "Line Switch", "Right Boost Mixer" }, 521 { "Right Output Mixer", "Line Switch", "Right Boost Mixer" },
485 522
486 { "Left Output Mixer", "PCM Switch", "Left DAC" }, 523 { "Left Output Mixer", "PCM Switch", "Left DAC" },
487 { "Left Output Mixer", "Aux Switch", "AUXL" },
488 { "Left Output Mixer", "Line Switch", "Left Boost Mixer" }, 524 { "Left Output Mixer", "Line Switch", "Left Boost Mixer" },
489 525
490 { "Right Headphone Out", NULL, "Right Output Mixer" }, 526 { "Right Headphone Out", NULL, "Right Output Mixer" },
@@ -501,13 +537,11 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
501 537
502 { "Right ADC", NULL, "Right Boost Mixer" }, 538 { "Right ADC", NULL, "Right Boost Mixer" },
503 539
504 { "Right Boost Mixer", "AUXR Volume", "AUXR" },
505 { "Right Boost Mixer", NULL, "Right Capture PGA" }, 540 { "Right Boost Mixer", NULL, "Right Capture PGA" },
506 { "Right Boost Mixer", "R2 Volume", "R2" }, 541 { "Right Boost Mixer", "R2 Volume", "R2" },
507 542
508 { "Left ADC", NULL, "Left Boost Mixer" }, 543 { "Left ADC", NULL, "Left Boost Mixer" },
509 544
510 { "Left Boost Mixer", "AUXL Volume", "AUXL" },
511 { "Left Boost Mixer", NULL, "Left Capture PGA" }, 545 { "Left Boost Mixer", NULL, "Left Capture PGA" },
512 { "Left Boost Mixer", "L2 Volume", "L2" }, 546 { "Left Boost Mixer", "L2 Volume", "L2" },
513 547
@@ -522,6 +556,38 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
522 { "Left Input Mixer", "MicN Switch", "LIN" }, 556 { "Left Input Mixer", "MicN Switch", "LIN" },
523 { "Left Input Mixer", "MicP Switch", "LIP" }, 557 { "Left Input Mixer", "MicP Switch", "LIP" },
524}; 558};
559static const struct snd_soc_dapm_route wm8985_aux_dapm_routes[] = {
560 { "Right Output Mixer", "Aux Switch", "AUXR" },
561 { "Left Output Mixer", "Aux Switch", "AUXL" },
562
563 { "Right Boost Mixer", "AUXR Volume", "AUXR" },
564 { "Left Boost Mixer", "AUXL Volume", "AUXL" },
565};
566
567static int wm8985_add_widgets(struct snd_soc_codec *codec)
568{
569 struct wm8985_priv *wm8985 = snd_soc_codec_get_drvdata(codec);
570 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
571
572 switch (wm8985->dev_type) {
573 case WM8758:
574 snd_soc_dapm_new_controls(dapm, wm8758_dapm_widgets,
575 ARRAY_SIZE(wm8758_dapm_widgets));
576 break;
577
578 case WM8985:
579 snd_soc_add_codec_controls(codec, wm8985_specific_snd_controls,
580 ARRAY_SIZE(wm8985_specific_snd_controls));
581
582 snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
583 ARRAY_SIZE(wm8985_dapm_widgets));
584 snd_soc_dapm_add_routes(dapm, wm8985_aux_dapm_routes,
585 ARRAY_SIZE(wm8985_aux_dapm_routes));
586 break;
587 }
588
589 return 0;
590}
525 591
526static int eqmode_get(struct snd_kcontrol *kcontrol, 592static int eqmode_get(struct snd_kcontrol *kcontrol,
527 struct snd_ctl_elem_value *ucontrol) 593 struct snd_ctl_elem_value *ucontrol)
@@ -999,6 +1065,8 @@ static int wm8985_probe(struct snd_soc_codec *codec)
999 snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT, 1065 snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT,
1000 WM8985_BIASCUT); 1066 WM8985_BIASCUT);
1001 1067
1068 wm8985_add_widgets(codec);
1069
1002 return 0; 1070 return 0;
1003 1071
1004err_reg_enable: 1072err_reg_enable:
@@ -1042,12 +1110,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
1042 .set_bias_level = wm8985_set_bias_level, 1110 .set_bias_level = wm8985_set_bias_level,
1043 .suspend_bias_off = true, 1111 .suspend_bias_off = true,
1044 1112
1045 .controls = wm8985_snd_controls, 1113 .controls = wm8985_common_snd_controls,
1046 .num_controls = ARRAY_SIZE(wm8985_snd_controls), 1114 .num_controls = ARRAY_SIZE(wm8985_common_snd_controls),
1047 .dapm_widgets = wm8985_dapm_widgets, 1115 .dapm_widgets = wm8985_common_dapm_widgets,
1048 .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets), 1116 .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets),
1049 .dapm_routes = wm8985_dapm_routes, 1117 .dapm_routes = wm8985_common_dapm_routes,
1050 .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes), 1118 .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes),
1051}; 1119};
1052 1120
1053static const struct regmap_config wm8985_regmap = { 1121static const struct regmap_config wm8985_regmap = {
@@ -1074,6 +1142,8 @@ static int wm8985_spi_probe(struct spi_device *spi)
1074 1142
1075 spi_set_drvdata(spi, wm8985); 1143 spi_set_drvdata(spi, wm8985);
1076 1144
1145 wm8985->dev_type = WM8985;
1146
1077 wm8985->regmap = devm_regmap_init_spi(spi, &wm8985_regmap); 1147 wm8985->regmap = devm_regmap_init_spi(spi, &wm8985_regmap);
1078 if (IS_ERR(wm8985->regmap)) { 1148 if (IS_ERR(wm8985->regmap)) {
1079 ret = PTR_ERR(wm8985->regmap); 1149 ret = PTR_ERR(wm8985->regmap);
@@ -1115,6 +1185,8 @@ static int wm8985_i2c_probe(struct i2c_client *i2c,
1115 1185
1116 i2c_set_clientdata(i2c, wm8985); 1186 i2c_set_clientdata(i2c, wm8985);
1117 1187
1188 wm8985->dev_type = id->driver_data;
1189
1118 wm8985->regmap = devm_regmap_init_i2c(i2c, &wm8985_regmap); 1190 wm8985->regmap = devm_regmap_init_i2c(i2c, &wm8985_regmap);
1119 if (IS_ERR(wm8985->regmap)) { 1191 if (IS_ERR(wm8985->regmap)) {
1120 ret = PTR_ERR(wm8985->regmap); 1192 ret = PTR_ERR(wm8985->regmap);
@@ -1135,7 +1207,8 @@ static int wm8985_i2c_remove(struct i2c_client *i2c)
1135} 1207}
1136 1208
1137static const struct i2c_device_id wm8985_i2c_id[] = { 1209static const struct i2c_device_id wm8985_i2c_id[] = {
1138 { "wm8985", 0 }, 1210 { "wm8985", WM8985 },
1211 { "wm8758", WM8758 },
1139 { } 1212 { }
1140}; 1213};
1141MODULE_DEVICE_TABLE(i2c, wm8985_i2c_id); 1214MODULE_DEVICE_TABLE(i2c, wm8985_i2c_id);
@@ -1183,6 +1256,6 @@ static void __exit wm8985_exit(void)
1183} 1256}
1184module_exit(wm8985_exit); 1257module_exit(wm8985_exit);
1185 1258
1186MODULE_DESCRIPTION("ASoC WM8985 driver"); 1259MODULE_DESCRIPTION("ASoC WM8985 / WM8758 driver");
1187MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); 1260MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
1188MODULE_LICENSE("GPL"); 1261MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8985.h b/sound/soc/codecs/wm8985.h
index 2e71ff507638..41b1048e3c97 100644
--- a/sound/soc/codecs/wm8985.h
+++ b/sound/soc/codecs/wm8985.h
@@ -290,6 +290,9 @@
290#define WM8985_GPIO1GPD_MASK 0x0040 /* GPIO1GPD */ 290#define WM8985_GPIO1GPD_MASK 0x0040 /* GPIO1GPD */
291#define WM8985_GPIO1GPD_SHIFT 6 /* GPIO1GPD */ 291#define WM8985_GPIO1GPD_SHIFT 6 /* GPIO1GPD */
292#define WM8985_GPIO1GPD_WIDTH 1 /* GPIO1GPD */ 292#define WM8985_GPIO1GPD_WIDTH 1 /* GPIO1GPD */
293#define WM8758_OPCLKDIV_MASK 0x0030 /* OPCLKDIV - [1:0] */
294#define WM8758_OPCLKDIV_SHIFT 4 /* OPCLKDIV - [1:0] */
295#define WM8758_OPCLKDIV_WIDTH 2 /* OPCLKDIV - [1:0] */
293#define WM8985_GPIO1POL 0x0008 /* GPIO1POL */ 296#define WM8985_GPIO1POL 0x0008 /* GPIO1POL */
294#define WM8985_GPIO1POL_MASK 0x0008 /* GPIO1POL */ 297#define WM8985_GPIO1POL_MASK 0x0008 /* GPIO1POL */
295#define WM8985_GPIO1POL_SHIFT 3 /* GPIO1POL */ 298#define WM8985_GPIO1POL_SHIFT 3 /* GPIO1POL */
@@ -301,6 +304,12 @@
301/* 304/*
302 * R9 (0x09) - Jack Detect Control 1 305 * R9 (0x09) - Jack Detect Control 1
303 */ 306 */
307#define WM8758_JD_VMID1_MASK 0x0100 /* JD_VMID1 */
308#define WM8758_JD_VMID1_SHIFT 8 /* JD_VMID1 */
309#define WM8758_JD_VMID1_WIDTH 1 /* JD_VMID1 */
310#define WM8758_JD_VMID0_MASK 0x0080 /* JD_VMID0 */
311#define WM8758_JD_VMID0_SHIFT 7 /* JD_VMID0 */
312#define WM8758_JD_VMID0_WIDTH 1 /* JD_VMID0 */
304#define WM8985_JD_EN 0x0040 /* JD_EN */ 313#define WM8985_JD_EN 0x0040 /* JD_EN */
305#define WM8985_JD_EN_MASK 0x0040 /* JD_EN */ 314#define WM8985_JD_EN_MASK 0x0040 /* JD_EN */
306#define WM8985_JD_EN_SHIFT 6 /* JD_EN */ 315#define WM8985_JD_EN_SHIFT 6 /* JD_EN */
@@ -649,6 +658,12 @@
649#define WM8985_OUT4_2LNR_MASK 0x0020 /* OUT4_2LNR */ 658#define WM8985_OUT4_2LNR_MASK 0x0020 /* OUT4_2LNR */
650#define WM8985_OUT4_2LNR_SHIFT 5 /* OUT4_2LNR */ 659#define WM8985_OUT4_2LNR_SHIFT 5 /* OUT4_2LNR */
651#define WM8985_OUT4_2LNR_WIDTH 1 /* OUT4_2LNR */ 660#define WM8985_OUT4_2LNR_WIDTH 1 /* OUT4_2LNR */
661#define WM8758_VMIDTOG_MASK 0x0010 /* VMIDTOG */
662#define WM8758_VMIDTOG_SHIFT 4 /* VMIDTOG */
663#define WM8758_VMIDTOG_WIDTH 1 /* VMIDTOG */
664#define WM8758_OUT2DEL_MASK 0x0008 /* OUT2DEL */
665#define WM8758_OUT2DEL_SHIFT 3 /* OUT2DEL */
666#define WM8758_OUT2DEL_WIDTH 1 /* OUT2DEL */
652#define WM8985_POBCTRL 0x0004 /* POBCTRL */ 667#define WM8985_POBCTRL 0x0004 /* POBCTRL */
653#define WM8985_POBCTRL_MASK 0x0004 /* POBCTRL */ 668#define WM8985_POBCTRL_MASK 0x0004 /* POBCTRL */
654#define WM8985_POBCTRL_SHIFT 2 /* POBCTRL */ 669#define WM8985_POBCTRL_SHIFT 2 /* POBCTRL */
@@ -684,6 +699,9 @@
684#define WM8985_BEEPVOL_MASK 0x000E /* BEEPVOL - [3:1] */ 699#define WM8985_BEEPVOL_MASK 0x000E /* BEEPVOL - [3:1] */
685#define WM8985_BEEPVOL_SHIFT 1 /* BEEPVOL - [3:1] */ 700#define WM8985_BEEPVOL_SHIFT 1 /* BEEPVOL - [3:1] */
686#define WM8985_BEEPVOL_WIDTH 3 /* BEEPVOL - [3:1] */ 701#define WM8985_BEEPVOL_WIDTH 3 /* BEEPVOL - [3:1] */
702#define WM8758_DELEN2_MASK 0x0004 /* DELEN2 */
703#define WM8758_DELEN2_SHIFT 2 /* DELEN2 */
704#define WM8758_DELEN2_WIDTH 1 /* DELEN2 */
687#define WM8985_BEEPEN 0x0001 /* BEEPEN */ 705#define WM8985_BEEPEN 0x0001 /* BEEPEN */
688#define WM8985_BEEPEN_MASK 0x0001 /* BEEPEN */ 706#define WM8985_BEEPEN_MASK 0x0001 /* BEEPEN */
689#define WM8985_BEEPEN_SHIFT 0 /* BEEPEN */ 707#define WM8985_BEEPEN_SHIFT 0 /* BEEPEN */
@@ -790,6 +808,14 @@
790/* 808/*
791 * R49 (0x31) - Output ctrl 809 * R49 (0x31) - Output ctrl
792 */ 810 */
811#define WM8758_HP_COM 0x0100 /* HP_COM */
812#define WM8758_HP_COM_MASK 0x0100 /* HP_COM */
813#define WM8758_HP_COM_SHIFT 8 /* HP_COM */
814#define WM8758_HP_COM_WIDTH 1 /* HP_COM */
815#define WM8758_LINE_COM 0x0080 /* LINE_COM */
816#define WM8758_LINE_COM_MASK 0x0080 /* LINE_COM */
817#define WM8758_LINE_COM_SHIFT 7 /* LINE_COM */
818#define WM8758_LINE_COM_WIDTH 1 /* LINE_COM */
793#define WM8985_DACL2RMIX 0x0040 /* DACL2RMIX */ 819#define WM8985_DACL2RMIX 0x0040 /* DACL2RMIX */
794#define WM8985_DACL2RMIX_MASK 0x0040 /* DACL2RMIX */ 820#define WM8985_DACL2RMIX_MASK 0x0040 /* DACL2RMIX */
795#define WM8985_DACL2RMIX_SHIFT 6 /* DACL2RMIX */ 821#define WM8985_DACL2RMIX_SHIFT 6 /* DACL2RMIX */
@@ -806,6 +832,14 @@
806#define WM8985_OUT3BOOST_MASK 0x0008 /* OUT3BOOST */ 832#define WM8985_OUT3BOOST_MASK 0x0008 /* OUT3BOOST */
807#define WM8985_OUT3BOOST_SHIFT 3 /* OUT3BOOST */ 833#define WM8985_OUT3BOOST_SHIFT 3 /* OUT3BOOST */
808#define WM8985_OUT3BOOST_WIDTH 1 /* OUT3BOOST */ 834#define WM8985_OUT3BOOST_WIDTH 1 /* OUT3BOOST */
835#define WM8758_OUT4ENDEL 0x0010 /* OUT4ENDEL */
836#define WM8758_OUT4ENDEL_MASK 0x0010 /* OUT4ENDEL */
837#define WM8758_OUT4ENDEL_SHIFT 4 /* OUT4ENDEL */
838#define WM8758_OUT4ENDEL_WIDTH 1 /* OUT4ENDEL */
839#define WM8758_OUT3ENDEL 0x0008 /* OUT3ENDEL */
840#define WM8758_OUT3ENDEL_MASK 0x0008 /* OUT3ENDEL */
841#define WM8758_OUT3ENDEL_SHIFT 3 /* OUT3ENDEL */
842#define WM8758_OUT3ENDEL_WIDTH 1 /* OUT3ENDEL */
809#define WM8985_TSOPCTRL 0x0004 /* TSOPCTRL */ 843#define WM8985_TSOPCTRL 0x0004 /* TSOPCTRL */
810#define WM8985_TSOPCTRL_MASK 0x0004 /* TSOPCTRL */ 844#define WM8985_TSOPCTRL_MASK 0x0004 /* TSOPCTRL */
811#define WM8985_TSOPCTRL_SHIFT 2 /* TSOPCTRL */ 845#define WM8985_TSOPCTRL_SHIFT 2 /* TSOPCTRL */
@@ -1021,6 +1055,10 @@
1021#define WM8985_HALFIPBIAS_MASK 0x0080 /* HALFIPBIAS */ 1055#define WM8985_HALFIPBIAS_MASK 0x0080 /* HALFIPBIAS */
1022#define WM8985_HALFIPBIAS_SHIFT 7 /* HALFIPBIAS */ 1056#define WM8985_HALFIPBIAS_SHIFT 7 /* HALFIPBIAS */
1023#define WM8985_HALFIPBIAS_WIDTH 1 /* HALFIPBIAS */ 1057#define WM8985_HALFIPBIAS_WIDTH 1 /* HALFIPBIAS */
1058#define WM8758_HALFIPBIAS 0x0040 /* HALFI_IPGA */
1059#define WM8758_HALFI_IPGA_MASK 0x0040 /* HALFI_IPGA */
1060#define WM8758_HALFI_IPGA_SHIFT 6 /* HALFI_IPGA */
1061#define WM8758_HALFI_IPGA_WIDTH 1 /* HALFI_IPGA */
1024#define WM8985_VBBIASTST_MASK 0x0060 /* VBBIASTST - [6:5] */ 1062#define WM8985_VBBIASTST_MASK 0x0060 /* VBBIASTST - [6:5] */
1025#define WM8985_VBBIASTST_SHIFT 5 /* VBBIASTST - [6:5] */ 1063#define WM8985_VBBIASTST_SHIFT 5 /* VBBIASTST - [6:5] */
1026#define WM8985_VBBIASTST_WIDTH 2 /* VBBIASTST - [6:5] */ 1064#define WM8985_VBBIASTST_WIDTH 2 /* VBBIASTST - [6:5] */
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 449f66636205..3a5c896a2d13 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -1166,6 +1166,7 @@ static const struct snd_soc_dapm_route wm8998_dapm_routes[] = {
1166 1166
1167 { "MICSUPP", NULL, "SYSCLK" }, 1167 { "MICSUPP", NULL, "SYSCLK" },
1168 1168
1169 { "DRC1 Signal Activity", NULL, "SYSCLK" },
1169 { "DRC1 Signal Activity", NULL, "DRC1L" }, 1170 { "DRC1 Signal Activity", NULL, "DRC1L" },
1170 { "DRC1 Signal Activity", NULL, "DRC1R" }, 1171 { "DRC1 Signal Activity", NULL, "DRC1R" },
1171}; 1172};
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index a07bd7c2c587..21fbe7d07063 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -394,6 +394,7 @@ static const struct {
394 int compr_direction; 394 int compr_direction;
395 int num_caps; 395 int num_caps;
396 const struct wm_adsp_fw_caps *caps; 396 const struct wm_adsp_fw_caps *caps;
397 bool voice_trigger;
397} wm_adsp_fw[WM_ADSP_NUM_FW] = { 398} wm_adsp_fw[WM_ADSP_NUM_FW] = {
398 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, 399 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" },
399 [WM_ADSP_FW_HIFI] = { .file = "hifi" }, 400 [WM_ADSP_FW_HIFI] = { .file = "hifi" },
@@ -406,6 +407,7 @@ static const struct {
406 .compr_direction = SND_COMPRESS_CAPTURE, 407 .compr_direction = SND_COMPRESS_CAPTURE,
407 .num_caps = ARRAY_SIZE(ctrl_caps), 408 .num_caps = ARRAY_SIZE(ctrl_caps),
408 .caps = ctrl_caps, 409 .caps = ctrl_caps,
410 .voice_trigger = true,
409 }, 411 },
410 [WM_ADSP_FW_ASR] = { .file = "asr" }, 412 [WM_ADSP_FW_ASR] = { .file = "asr" },
411 [WM_ADSP_FW_TRACE] = { 413 [WM_ADSP_FW_TRACE] = {
@@ -2366,13 +2368,15 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2366 dsp->running = false; 2368 dsp->running = false;
2367 2369
2368 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2370 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2369 ADSP2_SYS_ENA | ADSP2_CORE_ENA | 2371 ADSP2_CORE_ENA | ADSP2_START, 0);
2370 ADSP2_START, 0);
2371 2372
2372 /* Make sure DMAs are quiesced */ 2373 /* Make sure DMAs are quiesced */
2374 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
2373 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); 2375 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
2374 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); 2376 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
2375 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); 2377
2378 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2379 ADSP2_SYS_ENA, 0);
2376 2380
2377 list_for_each_entry(ctl, &dsp->ctl_list, list) 2381 list_for_each_entry(ctl, &dsp->ctl_list, list)
2378 ctl->enabled = 0; 2382 ctl->enabled = 0;
@@ -2998,6 +3002,9 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp)
2998 goto out; 3002 goto out;
2999 } 3003 }
3000 3004
3005 if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2)
3006 ret = WM_ADSP_COMPR_VOICE_TRIGGER;
3007
3001out_notify: 3008out_notify:
3002 if (compr && compr->stream) 3009 if (compr && compr->stream)
3003 snd_compr_fragment_elapsed(compr->stream); 3010 snd_compr_fragment_elapsed(compr->stream);
@@ -3037,12 +3044,8 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
3037 3044
3038 buf = compr->buf; 3045 buf = compr->buf;
3039 3046
3040 if (!compr->buf) { 3047 if (!compr->buf || compr->buf->error) {
3041 ret = -ENXIO; 3048 snd_compr_stop_error(stream, SNDRV_PCM_STATE_XRUN);
3042 goto out;
3043 }
3044
3045 if (compr->buf->error) {
3046 ret = -EIO; 3049 ret = -EIO;
3047 goto out; 3050 goto out;
3048 } 3051 }
@@ -3060,8 +3063,12 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
3060 */ 3063 */
3061 if (buf->avail < wm_adsp_compr_frag_words(compr)) { 3064 if (buf->avail < wm_adsp_compr_frag_words(compr)) {
3062 ret = wm_adsp_buffer_get_error(buf); 3065 ret = wm_adsp_buffer_get_error(buf);
3063 if (ret < 0) 3066 if (ret < 0) {
3067 if (compr->buf->error)
3068 snd_compr_stop_error(stream,
3069 SNDRV_PCM_STATE_XRUN);
3064 goto out; 3070 goto out;
3071 }
3065 3072
3066 ret = wm_adsp_buffer_reenable_irq(buf); 3073 ret = wm_adsp_buffer_reenable_irq(buf);
3067 if (ret < 0) { 3074 if (ret < 0) {
@@ -3156,11 +3163,10 @@ static int wm_adsp_compr_read(struct wm_adsp_compr *compr,
3156 3163
3157 adsp_dbg(dsp, "Requested read of %zu bytes\n", count); 3164 adsp_dbg(dsp, "Requested read of %zu bytes\n", count);
3158 3165
3159 if (!compr->buf) 3166 if (!compr->buf || compr->buf->error) {
3160 return -ENXIO; 3167 snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN);
3161
3162 if (compr->buf->error)
3163 return -EIO; 3168 return -EIO;
3169 }
3164 3170
3165 count /= WM_ADSP_DATA_WORD_SIZE; 3171 count /= WM_ADSP_DATA_WORD_SIZE;
3166 3172
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index feb61e2c4bb4..be3b5bcb7f17 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -19,6 +19,10 @@
19 19
20#include "wmfw.h" 20#include "wmfw.h"
21 21
22/* Return values for wm_adsp_compr_handle_irq */
23#define WM_ADSP_COMPR_OK 0
24#define WM_ADSP_COMPR_VOICE_TRIGGER 1
25
22struct wm_adsp_region { 26struct wm_adsp_region {
23 int type; 27 int type;
24 unsigned int base; 28 unsigned int base;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 237dc67002ef..05c2d33aa74d 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1599,7 +1599,14 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of(
1599 pdata = pdev->dev.platform_data; 1599 pdata = pdev->dev.platform_data;
1600 return pdata; 1600 return pdata;
1601 } else if (match) { 1601 } else if (match) {
1602 pdata = (struct davinci_mcasp_pdata*) match->data; 1602 pdata = devm_kmemdup(&pdev->dev, match->data, sizeof(*pdata),
1603 GFP_KERNEL);
1604 if (!pdata) {
1605 dev_err(&pdev->dev,
1606 "Failed to allocate memory for pdata\n");
1607 ret = -ENOMEM;
1608 return pdata;
1609 }
1603 } else { 1610 } else {
1604 /* control shouldn't reach here. something is wrong */ 1611 /* control shouldn't reach here. something is wrong */
1605 ret = -EINVAL; 1612 ret = -EINVAL;
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
index d50e08517dce..c297efe43861 100644
--- a/sound/soc/dwc/Kconfig
+++ b/sound/soc/dwc/Kconfig
@@ -7,4 +7,13 @@ config SND_DESIGNWARE_I2S
7 Synopsys desigwnware I2S device. The device supports upto 7 Synopsys desigwnware I2S device. The device supports upto
8 maximum of 8 channels each for play and record. 8 maximum of 8 channels each for play and record.
9 9
10config SND_DESIGNWARE_PCM
11 tristate "PCM PIO extension for I2S driver"
12 depends on SND_DESIGNWARE_I2S
13 help
14 Say Y, M or N if you want to add a custom ALSA extension that registers
15 a PCM and uses PIO to transfer data.
16
17 This functionality is specially suited for I2S devices that don't have
18 DMA support.
10 19
diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile
index 319371f690f4..38f1ca31c5fa 100644
--- a/sound/soc/dwc/Makefile
+++ b/sound/soc/dwc/Makefile
@@ -1,3 +1,5 @@
1# SYNOPSYS Platform Support 1# SYNOPSYS Platform Support
2obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o 2obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o
3 3ifdef CONFIG_SND_DESIGNWARE_PCM
4obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_pcm.o
5endif
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 0db69b7e9617..dc97f4349e66 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -24,90 +24,7 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/dmaengine_pcm.h> 26#include <sound/dmaengine_pcm.h>
27 27#include "local.h"
28/* common register for all channel */
29#define IER 0x000
30#define IRER 0x004
31#define ITER 0x008
32#define CER 0x00C
33#define CCR 0x010
34#define RXFFR 0x014
35#define TXFFR 0x018
36
37/* I2STxRxRegisters for all channels */
38#define LRBR_LTHR(x) (0x40 * x + 0x020)
39#define RRBR_RTHR(x) (0x40 * x + 0x024)
40#define RER(x) (0x40 * x + 0x028)
41#define TER(x) (0x40 * x + 0x02C)
42#define RCR(x) (0x40 * x + 0x030)
43#define TCR(x) (0x40 * x + 0x034)
44#define ISR(x) (0x40 * x + 0x038)
45#define IMR(x) (0x40 * x + 0x03C)
46#define ROR(x) (0x40 * x + 0x040)
47#define TOR(x) (0x40 * x + 0x044)
48#define RFCR(x) (0x40 * x + 0x048)
49#define TFCR(x) (0x40 * x + 0x04C)
50#define RFF(x) (0x40 * x + 0x050)
51#define TFF(x) (0x40 * x + 0x054)
52
53/* I2SCOMPRegisters */
54#define I2S_COMP_PARAM_2 0x01F0
55#define I2S_COMP_PARAM_1 0x01F4
56#define I2S_COMP_VERSION 0x01F8
57#define I2S_COMP_TYPE 0x01FC
58
59/*
60 * Component parameter register fields - define the I2S block's
61 * configuration.
62 */
63#define COMP1_TX_WORDSIZE_3(r) (((r) & GENMASK(27, 25)) >> 25)
64#define COMP1_TX_WORDSIZE_2(r) (((r) & GENMASK(24, 22)) >> 22)
65#define COMP1_TX_WORDSIZE_1(r) (((r) & GENMASK(21, 19)) >> 19)
66#define COMP1_TX_WORDSIZE_0(r) (((r) & GENMASK(18, 16)) >> 16)
67#define COMP1_TX_CHANNELS(r) (((r) & GENMASK(10, 9)) >> 9)
68#define COMP1_RX_CHANNELS(r) (((r) & GENMASK(8, 7)) >> 7)
69#define COMP1_RX_ENABLED(r) (((r) & BIT(6)) >> 6)
70#define COMP1_TX_ENABLED(r) (((r) & BIT(5)) >> 5)
71#define COMP1_MODE_EN(r) (((r) & BIT(4)) >> 4)
72#define COMP1_FIFO_DEPTH_GLOBAL(r) (((r) & GENMASK(3, 2)) >> 2)
73#define COMP1_APB_DATA_WIDTH(r) (((r) & GENMASK(1, 0)) >> 0)
74
75#define COMP2_RX_WORDSIZE_3(r) (((r) & GENMASK(12, 10)) >> 10)
76#define COMP2_RX_WORDSIZE_2(r) (((r) & GENMASK(9, 7)) >> 7)
77#define COMP2_RX_WORDSIZE_1(r) (((r) & GENMASK(5, 3)) >> 3)
78#define COMP2_RX_WORDSIZE_0(r) (((r) & GENMASK(2, 0)) >> 0)
79
80/* Number of entries in WORDSIZE and DATA_WIDTH parameter registers */
81#define COMP_MAX_WORDSIZE (1 << 3)
82#define COMP_MAX_DATA_WIDTH (1 << 2)
83
84#define MAX_CHANNEL_NUM 8
85#define MIN_CHANNEL_NUM 2
86
87union dw_i2s_snd_dma_data {
88 struct i2s_dma_data pd;
89 struct snd_dmaengine_dai_dma_data dt;
90};
91
92struct dw_i2s_dev {
93 void __iomem *i2s_base;
94 struct clk *clk;
95 int active;
96 unsigned int capability;
97 unsigned int quirks;
98 unsigned int i2s_reg_comp1;
99 unsigned int i2s_reg_comp2;
100 struct device *dev;
101 u32 ccr;
102 u32 xfer_resolution;
103 u32 fifo_th;
104
105 /* data related to DMA transfers b/w i2s and DMAC */
106 union dw_i2s_snd_dma_data play_dma_data;
107 union dw_i2s_snd_dma_data capture_dma_data;
108 struct i2s_clk_config_data config;
109 int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
110};
111 28
112static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val) 29static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
113{ 30{
@@ -145,51 +62,115 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
145 } 62 }
146} 63}
147 64
148static void i2s_start(struct dw_i2s_dev *dev, 65static inline void i2s_disable_irqs(struct dw_i2s_dev *dev, u32 stream,
149 struct snd_pcm_substream *substream) 66 int chan_nr)
67{
68 u32 i, irq;
69
70 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
71 for (i = 0; i < (chan_nr / 2); i++) {
72 irq = i2s_read_reg(dev->i2s_base, IMR(i));
73 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
74 }
75 } else {
76 for (i = 0; i < (chan_nr / 2); i++) {
77 irq = i2s_read_reg(dev->i2s_base, IMR(i));
78 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
79 }
80 }
81}
82
83static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
84 int chan_nr)
150{ 85{
151 struct i2s_clk_config_data *config = &dev->config;
152 u32 i, irq; 86 u32 i, irq;
153 i2s_write_reg(dev->i2s_base, IER, 1);
154 87
155 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 88 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
156 for (i = 0; i < (config->chan_nr / 2); i++) { 89 for (i = 0; i < (chan_nr / 2); i++) {
157 irq = i2s_read_reg(dev->i2s_base, IMR(i)); 90 irq = i2s_read_reg(dev->i2s_base, IMR(i));
158 i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30); 91 i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30);
159 } 92 }
160 i2s_write_reg(dev->i2s_base, ITER, 1);
161 } else { 93 } else {
162 for (i = 0; i < (config->chan_nr / 2); i++) { 94 for (i = 0; i < (chan_nr / 2); i++) {
163 irq = i2s_read_reg(dev->i2s_base, IMR(i)); 95 irq = i2s_read_reg(dev->i2s_base, IMR(i));
164 i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03); 96 i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03);
165 } 97 }
166 i2s_write_reg(dev->i2s_base, IRER, 1); 98 }
99}
100
101static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
102{
103 struct dw_i2s_dev *dev = dev_id;
104 bool irq_valid = false;
105 u32 isr[4];
106 int i;
107
108 for (i = 0; i < 4; i++)
109 isr[i] = i2s_read_reg(dev->i2s_base, ISR(i));
110
111 i2s_clear_irqs(dev, SNDRV_PCM_STREAM_PLAYBACK);
112 i2s_clear_irqs(dev, SNDRV_PCM_STREAM_CAPTURE);
113
114 for (i = 0; i < 4; i++) {
115 /*
116 * Check if TX fifo is empty. If empty fill FIFO with samples
117 * NOTE: Only two channels supported
118 */
119 if ((isr[i] & ISR_TXFE) && (i == 0) && dev->use_pio) {
120 dw_pcm_push_tx(dev);
121 irq_valid = true;
122 }
123
124 /* Data available. Record mode not supported in PIO mode */
125 if (isr[i] & ISR_RXDA)
126 irq_valid = true;
127
128 /* Error Handling: TX */
129 if (isr[i] & ISR_TXFO) {
130 dev_err(dev->dev, "TX overrun (ch_id=%d)\n", i);
131 irq_valid = true;
132 }
133
134 /* Error Handling: TX */
135 if (isr[i] & ISR_RXFO) {
136 dev_err(dev->dev, "RX overrun (ch_id=%d)\n", i);
137 irq_valid = true;
138 }
167 } 139 }
168 140
141 if (irq_valid)
142 return IRQ_HANDLED;
143 else
144 return IRQ_NONE;
145}
146
147static void i2s_start(struct dw_i2s_dev *dev,
148 struct snd_pcm_substream *substream)
149{
150 struct i2s_clk_config_data *config = &dev->config;
151
152 i2s_write_reg(dev->i2s_base, IER, 1);
153 i2s_enable_irqs(dev, substream->stream, config->chan_nr);
154
155 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
156 i2s_write_reg(dev->i2s_base, ITER, 1);
157 else
158 i2s_write_reg(dev->i2s_base, IRER, 1);
159
169 i2s_write_reg(dev->i2s_base, CER, 1); 160 i2s_write_reg(dev->i2s_base, CER, 1);
170} 161}
171 162
172static void i2s_stop(struct dw_i2s_dev *dev, 163static void i2s_stop(struct dw_i2s_dev *dev,
173 struct snd_pcm_substream *substream) 164 struct snd_pcm_substream *substream)
174{ 165{
175 u32 i = 0, irq;
176 166
177 i2s_clear_irqs(dev, substream->stream); 167 i2s_clear_irqs(dev, substream->stream);
178 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 168 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
179 i2s_write_reg(dev->i2s_base, ITER, 0); 169 i2s_write_reg(dev->i2s_base, ITER, 0);
180 170 else
181 for (i = 0; i < 4; i++) {
182 irq = i2s_read_reg(dev->i2s_base, IMR(i));
183 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
184 }
185 } else {
186 i2s_write_reg(dev->i2s_base, IRER, 0); 171 i2s_write_reg(dev->i2s_base, IRER, 0);
187 172
188 for (i = 0; i < 4; i++) { 173 i2s_disable_irqs(dev, substream->stream, 8);
189 irq = i2s_read_reg(dev->i2s_base, IMR(i));
190 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
191 }
192 }
193 174
194 if (!dev->active) { 175 if (!dev->active) {
195 i2s_write_reg(dev->i2s_base, CER, 0); 176 i2s_write_reg(dev->i2s_base, CER, 0);
@@ -223,7 +204,7 @@ static int dw_i2s_startup(struct snd_pcm_substream *substream,
223 204
224static void dw_i2s_config(struct dw_i2s_dev *dev, int stream) 205static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
225{ 206{
226 u32 ch_reg, irq; 207 u32 ch_reg;
227 struct i2s_clk_config_data *config = &dev->config; 208 struct i2s_clk_config_data *config = &dev->config;
228 209
229 210
@@ -235,16 +216,12 @@ static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
235 dev->xfer_resolution); 216 dev->xfer_resolution);
236 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 217 i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
237 dev->fifo_th - 1); 218 dev->fifo_th - 1);
238 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
239 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
240 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1); 219 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
241 } else { 220 } else {
242 i2s_write_reg(dev->i2s_base, RCR(ch_reg), 221 i2s_write_reg(dev->i2s_base, RCR(ch_reg),
243 dev->xfer_resolution); 222 dev->xfer_resolution);
244 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 223 i2s_write_reg(dev->i2s_base, RFCR(ch_reg),
245 dev->fifo_th - 1); 224 dev->fifo_th - 1);
246 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
247 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
248 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1); 225 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
249 } 226 }
250 227
@@ -278,7 +255,7 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
278 break; 255 break;
279 256
280 default: 257 default:
281 dev_err(dev->dev, "designware-i2s: unsuppted PCM fmt"); 258 dev_err(dev->dev, "designware-i2s: unsupported PCM fmt");
282 return -EINVAL; 259 return -EINVAL;
283 } 260 }
284 261
@@ -626,7 +603,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
626 const struct i2s_platform_data *pdata = pdev->dev.platform_data; 603 const struct i2s_platform_data *pdata = pdev->dev.platform_data;
627 struct dw_i2s_dev *dev; 604 struct dw_i2s_dev *dev;
628 struct resource *res; 605 struct resource *res;
629 int ret; 606 int ret, irq;
630 struct snd_soc_dai_driver *dw_i2s_dai; 607 struct snd_soc_dai_driver *dw_i2s_dai;
631 const char *clk_id; 608 const char *clk_id;
632 609
@@ -651,6 +628,16 @@ static int dw_i2s_probe(struct platform_device *pdev)
651 628
652 dev->dev = &pdev->dev; 629 dev->dev = &pdev->dev;
653 630
631 irq = platform_get_irq(pdev, 0);
632 if (irq >= 0) {
633 ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
634 pdev->name, dev);
635 if (ret < 0) {
636 dev_err(&pdev->dev, "failed to request irq\n");
637 return ret;
638 }
639 }
640
654 dev->i2s_reg_comp1 = I2S_COMP_PARAM_1; 641 dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
655 dev->i2s_reg_comp2 = I2S_COMP_PARAM_2; 642 dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
656 if (pdata) { 643 if (pdata) {
@@ -697,12 +684,24 @@ static int dw_i2s_probe(struct platform_device *pdev)
697 684
698 if (!pdata) { 685 if (!pdata) {
699 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 686 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
700 if (ret) { 687 if (ret == -EPROBE_DEFER) {
688 dev_err(&pdev->dev,
689 "failed to register PCM, deferring probe\n");
690 return ret;
691 } else if (ret) {
701 dev_err(&pdev->dev, 692 dev_err(&pdev->dev,
702 "Could not register PCM: %d\n", ret); 693 "Could not register DMA PCM: %d\n"
703 goto err_clk_disable; 694 "falling back to PIO mode\n", ret);
695 ret = dw_pcm_register(pdev);
696 if (ret) {
697 dev_err(&pdev->dev,
698 "Could not register PIO PCM: %d\n",
699 ret);
700 goto err_clk_disable;
701 }
704 } 702 }
705 } 703 }
704
706 pm_runtime_enable(&pdev->dev); 705 pm_runtime_enable(&pdev->dev);
707 return 0; 706 return 0;
708 707
diff --git a/sound/soc/dwc/designware_pcm.c b/sound/soc/dwc/designware_pcm.c
new file mode 100644
index 000000000000..4a83a22fa3cb
--- /dev/null
+++ b/sound/soc/dwc/designware_pcm.c
@@ -0,0 +1,225 @@
1/*
2 * ALSA SoC Synopsys PIO PCM for I2S driver
3 *
4 * sound/soc/dwc/designware_pcm.c
5 *
6 * Copyright (C) 2016 Synopsys
7 * Jose Abreu <joabreu@synopsys.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/io.h>
15#include <linux/rcupdate.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include "local.h"
19
20#define BUFFER_BYTES_MAX (3 * 2 * 8 * PERIOD_BYTES_MIN)
21#define PERIOD_BYTES_MIN 4096
22#define PERIODS_MIN 2
23
24#define dw_pcm_tx_fn(sample_bits) \
25static unsigned int dw_pcm_tx_##sample_bits(struct dw_i2s_dev *dev, \
26 struct snd_pcm_runtime *runtime, unsigned int tx_ptr, \
27 bool *period_elapsed) \
28{ \
29 const u##sample_bits (*p)[2] = (void *)runtime->dma_area; \
30 unsigned int period_pos = tx_ptr % runtime->period_size; \
31 int i; \
32\
33 for (i = 0; i < dev->fifo_th; i++) { \
34 iowrite32(p[tx_ptr][0], dev->i2s_base + LRBR_LTHR(0)); \
35 iowrite32(p[tx_ptr][1], dev->i2s_base + RRBR_RTHR(0)); \
36 period_pos++; \
37 if (++tx_ptr >= runtime->buffer_size) \
38 tx_ptr = 0; \
39 } \
40 *period_elapsed = period_pos >= runtime->period_size; \
41 return tx_ptr; \
42}
43
44dw_pcm_tx_fn(16);
45dw_pcm_tx_fn(32);
46
47#undef dw_pcm_tx_fn
48
49static const struct snd_pcm_hardware dw_pcm_hardware = {
50 .info = SNDRV_PCM_INFO_INTERLEAVED |
51 SNDRV_PCM_INFO_MMAP |
52 SNDRV_PCM_INFO_MMAP_VALID |
53 SNDRV_PCM_INFO_BLOCK_TRANSFER,
54 .rates = SNDRV_PCM_RATE_32000 |
55 SNDRV_PCM_RATE_44100 |
56 SNDRV_PCM_RATE_48000,
57 .rate_min = 32000,
58 .rate_max = 48000,
59 .formats = SNDRV_PCM_FMTBIT_S16_LE |
60 SNDRV_PCM_FMTBIT_S32_LE,
61 .channels_min = 2,
62 .channels_max = 2,
63 .buffer_bytes_max = BUFFER_BYTES_MAX,
64 .period_bytes_min = PERIOD_BYTES_MIN,
65 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
66 .periods_min = PERIODS_MIN,
67 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
68 .fifo_size = 16,
69};
70
71void dw_pcm_push_tx(struct dw_i2s_dev *dev)
72{
73 struct snd_pcm_substream *tx_substream;
74 bool tx_active, period_elapsed;
75
76 rcu_read_lock();
77 tx_substream = rcu_dereference(dev->tx_substream);
78 tx_active = tx_substream && snd_pcm_running(tx_substream);
79 if (tx_active) {
80 unsigned int tx_ptr = READ_ONCE(dev->tx_ptr);
81 unsigned int new_tx_ptr = dev->tx_fn(dev, tx_substream->runtime,
82 tx_ptr, &period_elapsed);
83 cmpxchg(&dev->tx_ptr, tx_ptr, new_tx_ptr);
84
85 if (period_elapsed)
86 snd_pcm_period_elapsed(tx_substream);
87 }
88 rcu_read_unlock();
89}
90EXPORT_SYMBOL_GPL(dw_pcm_push_tx);
91
92static int dw_pcm_open(struct snd_pcm_substream *substream)
93{
94 struct snd_pcm_runtime *runtime = substream->runtime;
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
97
98 snd_soc_set_runtime_hwparams(substream, &dw_pcm_hardware);
99 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
100 runtime->private_data = dev;
101
102 return 0;
103}
104
105static int dw_pcm_close(struct snd_pcm_substream *substream)
106{
107 synchronize_rcu();
108 return 0;
109}
110
111static int dw_pcm_hw_params(struct snd_pcm_substream *substream,
112 struct snd_pcm_hw_params *hw_params)
113{
114 struct snd_pcm_runtime *runtime = substream->runtime;
115 struct dw_i2s_dev *dev = runtime->private_data;
116 int ret;
117
118 switch (params_channels(hw_params)) {
119 case 2:
120 break;
121 default:
122 dev_err(dev->dev, "invalid channels number\n");
123 return -EINVAL;
124 }
125
126 switch (params_format(hw_params)) {
127 case SNDRV_PCM_FORMAT_S16_LE:
128 dev->tx_fn = dw_pcm_tx_16;
129 break;
130 case SNDRV_PCM_FORMAT_S32_LE:
131 dev->tx_fn = dw_pcm_tx_32;
132 break;
133 default:
134 dev_err(dev->dev, "invalid format\n");
135 return -EINVAL;
136 }
137
138 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
139 dev_err(dev->dev, "only playback is available\n");
140 return -EINVAL;
141 }
142
143 ret = snd_pcm_lib_malloc_pages(substream,
144 params_buffer_bytes(hw_params));
145 if (ret < 0)
146 return ret;
147 else
148 return 0;
149}
150
151static int dw_pcm_hw_free(struct snd_pcm_substream *substream)
152{
153 return snd_pcm_lib_free_pages(substream);
154}
155
156static int dw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
157{
158 struct snd_pcm_runtime *runtime = substream->runtime;
159 struct dw_i2s_dev *dev = runtime->private_data;
160 int ret = 0;
161
162 switch (cmd) {
163 case SNDRV_PCM_TRIGGER_START:
164 case SNDRV_PCM_TRIGGER_RESUME:
165 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
166 WRITE_ONCE(dev->tx_ptr, 0);
167 rcu_assign_pointer(dev->tx_substream, substream);
168 break;
169 case SNDRV_PCM_TRIGGER_STOP:
170 case SNDRV_PCM_TRIGGER_SUSPEND:
171 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
172 rcu_assign_pointer(dev->tx_substream, NULL);
173 break;
174 default:
175 ret = -EINVAL;
176 break;
177 }
178
179 return ret;
180}
181
182static snd_pcm_uframes_t dw_pcm_pointer(struct snd_pcm_substream *substream)
183{
184 struct snd_pcm_runtime *runtime = substream->runtime;
185 struct dw_i2s_dev *dev = runtime->private_data;
186 snd_pcm_uframes_t pos = READ_ONCE(dev->tx_ptr);
187
188 return pos < runtime->buffer_size ? pos : 0;
189}
190
191static int dw_pcm_new(struct snd_soc_pcm_runtime *rtd)
192{
193 size_t size = dw_pcm_hardware.buffer_bytes_max;
194
195 return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
196 SNDRV_DMA_TYPE_CONTINUOUS,
197 snd_dma_continuous_data(GFP_KERNEL), size, size);
198}
199
200static void dw_pcm_free(struct snd_pcm *pcm)
201{
202 snd_pcm_lib_preallocate_free_for_all(pcm);
203}
204
205static const struct snd_pcm_ops dw_pcm_ops = {
206 .open = dw_pcm_open,
207 .close = dw_pcm_close,
208 .ioctl = snd_pcm_lib_ioctl,
209 .hw_params = dw_pcm_hw_params,
210 .hw_free = dw_pcm_hw_free,
211 .trigger = dw_pcm_trigger,
212 .pointer = dw_pcm_pointer,
213};
214
215static const struct snd_soc_platform_driver dw_pcm_platform = {
216 .pcm_new = dw_pcm_new,
217 .pcm_free = dw_pcm_free,
218 .ops = &dw_pcm_ops,
219};
220
221int dw_pcm_register(struct platform_device *pdev)
222{
223 return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform);
224}
225EXPORT_SYMBOL_GPL(dw_pcm_register);
diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h
new file mode 100644
index 000000000000..68afd7577343
--- /dev/null
+++ b/sound/soc/dwc/local.h
@@ -0,0 +1,128 @@
1/*
2 * Copyright (ST) 2012 Rajeev Kumar (rajeevkumar.linux@gmail.com)
3 *
4 * This file is licensed under the terms of the GNU General Public
5 * License version 2. This program is licensed "as is" without any
6 * warranty of any kind, whether express or implied.
7 */
8
9#ifndef __DESIGNWARE_LOCAL_H
10#define __DESIGNWARE_LOCAL_H
11
12#include <linux/clk.h>
13#include <linux/device.h>
14#include <linux/types.h>
15#include <sound/dmaengine_pcm.h>
16#include <sound/pcm.h>
17#include <sound/designware_i2s.h>
18
19/* common register for all channel */
20#define IER 0x000
21#define IRER 0x004
22#define ITER 0x008
23#define CER 0x00C
24#define CCR 0x010
25#define RXFFR 0x014
26#define TXFFR 0x018
27
28/* Interrupt status register fields */
29#define ISR_TXFO BIT(5)
30#define ISR_TXFE BIT(4)
31#define ISR_RXFO BIT(1)
32#define ISR_RXDA BIT(0)
33
34/* I2STxRxRegisters for all channels */
35#define LRBR_LTHR(x) (0x40 * x + 0x020)
36#define RRBR_RTHR(x) (0x40 * x + 0x024)
37#define RER(x) (0x40 * x + 0x028)
38#define TER(x) (0x40 * x + 0x02C)
39#define RCR(x) (0x40 * x + 0x030)
40#define TCR(x) (0x40 * x + 0x034)
41#define ISR(x) (0x40 * x + 0x038)
42#define IMR(x) (0x40 * x + 0x03C)
43#define ROR(x) (0x40 * x + 0x040)
44#define TOR(x) (0x40 * x + 0x044)
45#define RFCR(x) (0x40 * x + 0x048)
46#define TFCR(x) (0x40 * x + 0x04C)
47#define RFF(x) (0x40 * x + 0x050)
48#define TFF(x) (0x40 * x + 0x054)
49
50/* I2SCOMPRegisters */
51#define I2S_COMP_PARAM_2 0x01F0
52#define I2S_COMP_PARAM_1 0x01F4
53#define I2S_COMP_VERSION 0x01F8
54#define I2S_COMP_TYPE 0x01FC
55
56/*
57 * Component parameter register fields - define the I2S block's
58 * configuration.
59 */
60#define COMP1_TX_WORDSIZE_3(r) (((r) & GENMASK(27, 25)) >> 25)
61#define COMP1_TX_WORDSIZE_2(r) (((r) & GENMASK(24, 22)) >> 22)
62#define COMP1_TX_WORDSIZE_1(r) (((r) & GENMASK(21, 19)) >> 19)
63#define COMP1_TX_WORDSIZE_0(r) (((r) & GENMASK(18, 16)) >> 16)
64#define COMP1_TX_CHANNELS(r) (((r) & GENMASK(10, 9)) >> 9)
65#define COMP1_RX_CHANNELS(r) (((r) & GENMASK(8, 7)) >> 7)
66#define COMP1_RX_ENABLED(r) (((r) & BIT(6)) >> 6)
67#define COMP1_TX_ENABLED(r) (((r) & BIT(5)) >> 5)
68#define COMP1_MODE_EN(r) (((r) & BIT(4)) >> 4)
69#define COMP1_FIFO_DEPTH_GLOBAL(r) (((r) & GENMASK(3, 2)) >> 2)
70#define COMP1_APB_DATA_WIDTH(r) (((r) & GENMASK(1, 0)) >> 0)
71
72#define COMP2_RX_WORDSIZE_3(r) (((r) & GENMASK(12, 10)) >> 10)
73#define COMP2_RX_WORDSIZE_2(r) (((r) & GENMASK(9, 7)) >> 7)
74#define COMP2_RX_WORDSIZE_1(r) (((r) & GENMASK(5, 3)) >> 3)
75#define COMP2_RX_WORDSIZE_0(r) (((r) & GENMASK(2, 0)) >> 0)
76
77/* Number of entries in WORDSIZE and DATA_WIDTH parameter registers */
78#define COMP_MAX_WORDSIZE (1 << 3)
79#define COMP_MAX_DATA_WIDTH (1 << 2)
80
81#define MAX_CHANNEL_NUM 8
82#define MIN_CHANNEL_NUM 2
83
84union dw_i2s_snd_dma_data {
85 struct i2s_dma_data pd;
86 struct snd_dmaengine_dai_dma_data dt;
87};
88
89struct dw_i2s_dev {
90 void __iomem *i2s_base;
91 struct clk *clk;
92 int active;
93 unsigned int capability;
94 unsigned int quirks;
95 unsigned int i2s_reg_comp1;
96 unsigned int i2s_reg_comp2;
97 struct device *dev;
98 u32 ccr;
99 u32 xfer_resolution;
100 u32 fifo_th;
101
102 /* data related to DMA transfers b/w i2s and DMAC */
103 union dw_i2s_snd_dma_data play_dma_data;
104 union dw_i2s_snd_dma_data capture_dma_data;
105 struct i2s_clk_config_data config;
106 int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
107
108 /* data related to PIO transfers (TX) */
109 bool use_pio;
110 struct snd_pcm_substream __rcu *tx_substream;
111 unsigned int (*tx_fn)(struct dw_i2s_dev *dev,
112 struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
113 bool *period_elapsed);
114 unsigned int tx_ptr;
115};
116
117#if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM)
118void dw_pcm_push_tx(struct dw_i2s_dev *dev);
119int dw_pcm_register(struct platform_device *pdev);
120#else
121void dw_pcm_push_tx(struct dw_i2s_dev *dev) { }
122int dw_pcm_register(struct platform_device *pdev)
123{
124 return -EINVAL;
125}
126#endif
127
128#endif
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 35aabf9dc503..19bdcac71775 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -4,6 +4,7 @@ comment "Common SoC Audio options for Freescale CPUs:"
4 4
5config SND_SOC_FSL_ASRC 5config SND_SOC_FSL_ASRC
6 tristate "Asynchronous Sample Rate Converter (ASRC) module support" 6 tristate "Asynchronous Sample Rate Converter (ASRC) module support"
7 depends on HAS_DMA
7 select REGMAP_MMIO 8 select REGMAP_MMIO
8 select SND_SOC_GENERIC_DMAENGINE_PCM 9 select SND_SOC_GENERIC_DMAENGINE_PCM
9 help 10 help
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 151849f79863..beec7934a265 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -172,7 +172,7 @@ static void spdif_irq_uqrx_full(struct fsl_spdif_priv *spdif_priv, char name)
172 if (*pos >= size * 2) { 172 if (*pos >= size * 2) {
173 *pos = 0; 173 *pos = 0;
174 } else if (unlikely((*pos % size) + 3 > size)) { 174 } else if (unlikely((*pos % size) + 3 > size)) {
175 dev_err(&pdev->dev, "User bit receivce buffer overflow\n"); 175 dev_err(&pdev->dev, "User bit receive buffer overflow\n");
176 return; 176 return;
177 } 177 }
178 178
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index 610f61251640..c01c5dd68601 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -1,4 +1,8 @@
1config SND_SIMPLE_CARD_UTILS
2 tristate
3
1config SND_SIMPLE_CARD 4config SND_SIMPLE_CARD
2 tristate "ASoC Simple sound card support" 5 tristate "ASoC Simple sound card support"
6 select SND_SIMPLE_CARD_UTILS
3 help 7 help
4 This option enables generic simple sound card support 8 This option enables generic simple sound card support
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index 9c3b246792bf..45602ca8536e 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -1,3 +1,5 @@
1obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) := simple-card-utils.o
2
1snd-soc-simple-card-objs := simple-card.o 3snd-soc-simple-card-objs := simple-card.o
2 4
3obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o 5obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
new file mode 100644
index 000000000000..d89a9a1b2471
--- /dev/null
+++ b/sound/soc/generic/simple-card-utils.c
@@ -0,0 +1,97 @@
1/*
2 * simple-card-core.c
3 *
4 * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/of.h>
11#include <sound/simple_card_utils.h>
12
13int asoc_simple_card_parse_daifmt(struct device *dev,
14 struct device_node *node,
15 struct device_node *codec,
16 char *prefix,
17 unsigned int *retfmt)
18{
19 struct device_node *bitclkmaster = NULL;
20 struct device_node *framemaster = NULL;
21 int prefix_len = prefix ? strlen(prefix) : 0;
22 unsigned int daifmt;
23
24 daifmt = snd_soc_of_parse_daifmt(node, prefix,
25 &bitclkmaster, &framemaster);
26 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
27
28 if (prefix_len && !bitclkmaster && !framemaster) {
29 /*
30 * No dai-link level and master setting was not found from
31 * sound node level, revert back to legacy DT parsing and
32 * take the settings from codec node.
33 */
34 dev_dbg(dev, "Revert to legacy daifmt parsing\n");
35
36 daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
37 (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
38 } else {
39 if (codec == bitclkmaster)
40 daifmt |= (codec == framemaster) ?
41 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
42 else
43 daifmt |= (codec == framemaster) ?
44 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
45 }
46
47 of_node_put(bitclkmaster);
48 of_node_put(framemaster);
49
50 *retfmt = daifmt;
51
52 return 0;
53}
54EXPORT_SYMBOL_GPL(asoc_simple_card_parse_daifmt);
55
56int asoc_simple_card_set_dailink_name(struct device *dev,
57 struct snd_soc_dai_link *dai_link,
58 const char *fmt, ...)
59{
60 va_list ap;
61 char *name = NULL;
62 int ret = -ENOMEM;
63
64 va_start(ap, fmt);
65 name = devm_kvasprintf(dev, GFP_KERNEL, fmt, ap);
66 va_end(ap);
67
68 if (name) {
69 ret = 0;
70
71 dai_link->name = name;
72 dai_link->stream_name = name;
73 }
74
75 return ret;
76}
77EXPORT_SYMBOL_GPL(asoc_simple_card_set_dailink_name);
78
79int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
80 char *prefix)
81{
82 char prop[128];
83 int ret;
84
85 snprintf(prop, sizeof(prop), "%sname", prefix);
86
87 /* Parse the card name from DT */
88 ret = snd_soc_of_parse_card_name(card, prop);
89 if (ret < 0)
90 return ret;
91
92 if (!card->name && card->dai_link)
93 card->name = card->dai_link->name;
94
95 return 0;
96}
97EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 466492b7d4f5..43295f024982 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -21,6 +21,12 @@
21#include <sound/soc-dai.h> 21#include <sound/soc-dai.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23 23
24struct asoc_simple_jack {
25 struct snd_soc_jack jack;
26 struct snd_soc_jack_pin pin;
27 struct snd_soc_jack_gpio gpio;
28};
29
24struct simple_card_data { 30struct simple_card_data {
25 struct snd_soc_card snd_card; 31 struct snd_soc_card snd_card;
26 struct simple_dai_props { 32 struct simple_dai_props {
@@ -29,10 +35,8 @@ struct simple_card_data {
29 unsigned int mclk_fs; 35 unsigned int mclk_fs;
30 } *dai_props; 36 } *dai_props;
31 unsigned int mclk_fs; 37 unsigned int mclk_fs;
32 int gpio_hp_det; 38 struct asoc_simple_jack hp_jack;
33 int gpio_hp_det_invert; 39 struct asoc_simple_jack mic_jack;
34 int gpio_mic_det;
35 int gpio_mic_det_invert;
36 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ 40 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
37}; 41};
38 42
@@ -40,6 +44,69 @@ struct simple_card_data {
40#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) 44#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
41#define simple_priv_to_props(priv, i) ((priv)->dai_props + i) 45#define simple_priv_to_props(priv, i) ((priv)->dai_props + i)
42 46
47#define PREFIX "simple-audio-card,"
48
49#define asoc_simple_card_init_hp(card, sjack, prefix)\
50 asoc_simple_card_init_jack(card, sjack, 1, prefix)
51#define asoc_simple_card_init_mic(card, sjack, prefix)\
52 asoc_simple_card_init_jack(card, sjack, 0, prefix)
53static int asoc_simple_card_init_jack(struct snd_soc_card *card,
54 struct asoc_simple_jack *sjack,
55 int is_hp, char *prefix)
56{
57 struct device *dev = card->dev;
58 enum of_gpio_flags flags;
59 char prop[128];
60 char *pin_name;
61 char *gpio_name;
62 int mask;
63 int det;
64
65 sjack->gpio.gpio = -ENOENT;
66
67 if (is_hp) {
68 snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
69 pin_name = "Headphones";
70 gpio_name = "Headphone detection";
71 mask = SND_JACK_HEADPHONE;
72 } else {
73 snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
74 pin_name = "Mic Jack";
75 gpio_name = "Mic detection";
76 mask = SND_JACK_MICROPHONE;
77 }
78
79 det = of_get_named_gpio_flags(dev->of_node, prop, 0, &flags);
80 if (det == -EPROBE_DEFER)
81 return -EPROBE_DEFER;
82
83 if (gpio_is_valid(det)) {
84 sjack->pin.pin = pin_name;
85 sjack->pin.mask = mask;
86
87 sjack->gpio.name = gpio_name;
88 sjack->gpio.report = mask;
89 sjack->gpio.gpio = det;
90 sjack->gpio.invert = !!(flags & OF_GPIO_ACTIVE_LOW);
91 sjack->gpio.debounce_time = 150;
92
93 snd_soc_card_jack_new(card, pin_name, mask,
94 &sjack->jack,
95 &sjack->pin, 1);
96
97 snd_soc_jack_add_gpios(&sjack->jack, 1,
98 &sjack->gpio);
99 }
100
101 return 0;
102}
103
104static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack)
105{
106 if (gpio_is_valid(sjack->gpio.gpio))
107 snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio);
108}
109
43static int asoc_simple_card_startup(struct snd_pcm_substream *substream) 110static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
44{ 111{
45 struct snd_soc_pcm_runtime *rtd = substream->private_data; 112 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -110,32 +177,6 @@ static struct snd_soc_ops asoc_simple_card_ops = {
110 .hw_params = asoc_simple_card_hw_params, 177 .hw_params = asoc_simple_card_hw_params,
111}; 178};
112 179
113static struct snd_soc_jack simple_card_hp_jack;
114static struct snd_soc_jack_pin simple_card_hp_jack_pins[] = {
115 {
116 .pin = "Headphones",
117 .mask = SND_JACK_HEADPHONE,
118 },
119};
120static struct snd_soc_jack_gpio simple_card_hp_jack_gpio = {
121 .name = "Headphone detection",
122 .report = SND_JACK_HEADPHONE,
123 .debounce_time = 150,
124};
125
126static struct snd_soc_jack simple_card_mic_jack;
127static struct snd_soc_jack_pin simple_card_mic_jack_pins[] = {
128 {
129 .pin = "Mic Jack",
130 .mask = SND_JACK_MICROPHONE,
131 },
132};
133static struct snd_soc_jack_gpio simple_card_mic_jack_gpio = {
134 .name = "Mic detection",
135 .report = SND_JACK_MICROPHONE,
136 .debounce_time = 150,
137};
138
139static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, 180static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
140 struct asoc_simple_dai *set) 181 struct asoc_simple_dai *set)
141{ 182{
@@ -184,30 +225,14 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
184 if (ret < 0) 225 if (ret < 0)
185 return ret; 226 return ret;
186 227
187 if (gpio_is_valid(priv->gpio_hp_det)) { 228 ret = asoc_simple_card_init_hp(rtd->card, &priv->hp_jack, PREFIX);
188 snd_soc_card_jack_new(rtd->card, "Headphones", 229 if (ret < 0)
189 SND_JACK_HEADPHONE, 230 return ret;
190 &simple_card_hp_jack, 231
191 simple_card_hp_jack_pins, 232 ret = asoc_simple_card_init_mic(rtd->card, &priv->hp_jack, PREFIX);
192 ARRAY_SIZE(simple_card_hp_jack_pins)); 233 if (ret < 0)
193 234 return ret;
194 simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det;
195 simple_card_hp_jack_gpio.invert = priv->gpio_hp_det_invert;
196 snd_soc_jack_add_gpios(&simple_card_hp_jack, 1,
197 &simple_card_hp_jack_gpio);
198 }
199 235
200 if (gpio_is_valid(priv->gpio_mic_det)) {
201 snd_soc_card_jack_new(rtd->card, "Mic Jack",
202 SND_JACK_MICROPHONE,
203 &simple_card_mic_jack,
204 simple_card_mic_jack_pins,
205 ARRAY_SIZE(simple_card_mic_jack_pins));
206 simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det;
207 simple_card_mic_jack_gpio.invert = priv->gpio_mic_det_invert;
208 snd_soc_jack_add_gpios(&simple_card_mic_jack, 1,
209 &simple_card_mic_jack_gpio);
210 }
211 return 0; 236 return 0;
212} 237}
213 238
@@ -223,6 +248,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
223 u32 val; 248 u32 val;
224 int ret; 249 int ret;
225 250
251 if (!np)
252 return 0;
253
226 /* 254 /*
227 * Get node via "sound-dai = <&phandle port>" 255 * Get node via "sound-dai = <&phandle port>"
228 * it will be used as xxx_of_node on soc_bind_dai_link() 256 * it will be used as xxx_of_node on soc_bind_dai_link()
@@ -238,9 +266,14 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
238 *args_count = args.args_count; 266 *args_count = args.args_count;
239 267
240 /* Get dai->name */ 268 /* Get dai->name */
241 ret = snd_soc_of_get_dai_name(np, name); 269 if (name) {
242 if (ret < 0) 270 ret = snd_soc_of_get_dai_name(np, name);
243 return ret; 271 if (ret < 0)
272 return ret;
273 }
274
275 if (!dai)
276 return 0;
244 277
245 /* Parse TDM slot */ 278 /* Parse TDM slot */
246 ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask, 279 ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask,
@@ -275,48 +308,6 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
275 return 0; 308 return 0;
276} 309}
277 310
278static int asoc_simple_card_parse_daifmt(struct device_node *node,
279 struct simple_card_data *priv,
280 struct device_node *codec,
281 char *prefix, int idx)
282{
283 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
284 struct device *dev = simple_priv_to_dev(priv);
285 struct device_node *bitclkmaster = NULL;
286 struct device_node *framemaster = NULL;
287 unsigned int daifmt;
288
289 daifmt = snd_soc_of_parse_daifmt(node, prefix,
290 &bitclkmaster, &framemaster);
291 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
292
293 if (strlen(prefix) && !bitclkmaster && !framemaster) {
294 /*
295 * No dai-link level and master setting was not found from
296 * sound node level, revert back to legacy DT parsing and
297 * take the settings from codec node.
298 */
299 dev_dbg(dev, "Revert to legacy daifmt parsing\n");
300
301 daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
302 (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
303 } else {
304 if (codec == bitclkmaster)
305 daifmt |= (codec == framemaster) ?
306 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
307 else
308 daifmt |= (codec == framemaster) ?
309 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
310 }
311
312 dai_link->dai_fmt = daifmt;
313
314 of_node_put(bitclkmaster);
315 of_node_put(framemaster);
316
317 return 0;
318}
319
320static int asoc_simple_card_dai_link_of(struct device_node *node, 311static int asoc_simple_card_dai_link_of(struct device_node *node,
321 struct simple_card_data *priv, 312 struct simple_card_data *priv,
322 int idx, 313 int idx,
@@ -328,7 +319,6 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
328 struct device_node *cpu = NULL; 319 struct device_node *cpu = NULL;
329 struct device_node *plat = NULL; 320 struct device_node *plat = NULL;
330 struct device_node *codec = NULL; 321 struct device_node *codec = NULL;
331 char *name;
332 char prop[128]; 322 char prop[128];
333 char *prefix = ""; 323 char *prefix = "";
334 int ret, cpu_args; 324 int ret, cpu_args;
@@ -336,7 +326,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
336 326
337 /* For single DAI link & old style of DT node */ 327 /* For single DAI link & old style of DT node */
338 if (is_top_level_node) 328 if (is_top_level_node)
339 prefix = "simple-audio-card,"; 329 prefix = PREFIX;
340 330
341 snprintf(prop, sizeof(prop), "%scpu", prefix); 331 snprintf(prop, sizeof(prop), "%scpu", prefix);
342 cpu = of_get_child_by_name(node, prop); 332 cpu = of_get_child_by_name(node, prop);
@@ -353,8 +343,8 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
353 goto dai_link_of_err; 343 goto dai_link_of_err;
354 } 344 }
355 345
356 ret = asoc_simple_card_parse_daifmt(node, priv, 346 ret = asoc_simple_card_parse_daifmt(dev, node, codec,
357 codec, prefix, idx); 347 prefix, &dai_link->dai_fmt);
358 if (ret < 0) 348 if (ret < 0)
359 goto dai_link_of_err; 349 goto dai_link_of_err;
360 350
@@ -374,35 +364,28 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
374 if (ret < 0) 364 if (ret < 0)
375 goto dai_link_of_err; 365 goto dai_link_of_err;
376 366
367 ret = asoc_simple_card_sub_parse_of(plat, NULL,
368 &dai_link->platform_of_node,
369 NULL, NULL);
370 if (ret < 0)
371 goto dai_link_of_err;
372
377 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { 373 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
378 ret = -EINVAL; 374 ret = -EINVAL;
379 goto dai_link_of_err; 375 goto dai_link_of_err;
380 } 376 }
381 377
382 if (plat) { 378 /* Assumes platform == cpu */
383 struct of_phandle_args args; 379 if (!dai_link->platform_of_node)
384
385 ret = of_parse_phandle_with_args(plat, "sound-dai",
386 "#sound-dai-cells", 0, &args);
387 dai_link->platform_of_node = args.np;
388 } else {
389 /* Assumes platform == cpu */
390 dai_link->platform_of_node = dai_link->cpu_of_node; 380 dai_link->platform_of_node = dai_link->cpu_of_node;
391 }
392 381
393 /* DAI link name is created from CPU/CODEC dai name */ 382 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
394 name = devm_kzalloc(dev, 383 "%s-%s",
395 strlen(dai_link->cpu_dai_name) + 384 dai_link->cpu_dai_name,
396 strlen(dai_link->codec_dai_name) + 2, 385 dai_link->codec_dai_name);
397 GFP_KERNEL); 386 if (ret < 0)
398 if (!name) {
399 ret = -ENOMEM;
400 goto dai_link_of_err; 387 goto dai_link_of_err;
401 }
402 388
403 sprintf(name, "%s-%s", dai_link->cpu_dai_name,
404 dai_link->codec_dai_name);
405 dai_link->name = dai_link->stream_name = name;
406 dai_link->ops = &asoc_simple_card_ops; 389 dai_link->ops = &asoc_simple_card_ops;
407 dai_link->init = asoc_simple_card_dai_init; 390 dai_link->init = asoc_simple_card_dai_init;
408 391
@@ -438,42 +421,35 @@ static int asoc_simple_card_parse_of(struct device_node *node,
438 struct simple_card_data *priv) 421 struct simple_card_data *priv)
439{ 422{
440 struct device *dev = simple_priv_to_dev(priv); 423 struct device *dev = simple_priv_to_dev(priv);
441 enum of_gpio_flags flags;
442 u32 val; 424 u32 val;
443 int ret; 425 int ret;
444 426
445 if (!node) 427 if (!node)
446 return -EINVAL; 428 return -EINVAL;
447 429
448 /* Parse the card name from DT */
449 snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
450
451 /* The off-codec widgets */ 430 /* The off-codec widgets */
452 if (of_property_read_bool(node, "simple-audio-card,widgets")) { 431 if (of_property_read_bool(node, PREFIX "widgets")) {
453 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, 432 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
454 "simple-audio-card,widgets"); 433 PREFIX "widgets");
455 if (ret) 434 if (ret)
456 return ret; 435 return ret;
457 } 436 }
458 437
459 /* DAPM routes */ 438 /* DAPM routes */
460 if (of_property_read_bool(node, "simple-audio-card,routing")) { 439 if (of_property_read_bool(node, PREFIX "routing")) {
461 ret = snd_soc_of_parse_audio_routing(&priv->snd_card, 440 ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
462 "simple-audio-card,routing"); 441 PREFIX "routing");
463 if (ret) 442 if (ret)
464 return ret; 443 return ret;
465 } 444 }
466 445
467 /* Factor to mclk, used in hw_params() */ 446 /* Factor to mclk, used in hw_params() */
468 ret = of_property_read_u32(node, "simple-audio-card,mclk-fs", &val); 447 ret = of_property_read_u32(node, PREFIX "mclk-fs", &val);
469 if (ret == 0) 448 if (ret == 0)
470 priv->mclk_fs = val; 449 priv->mclk_fs = val;
471 450
472 dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
473 priv->snd_card.name : "");
474
475 /* Single/Muti DAI link(s) & New style of DT node */ 451 /* Single/Muti DAI link(s) & New style of DT node */
476 if (of_get_child_by_name(node, "simple-audio-card,dai-link")) { 452 if (of_get_child_by_name(node, PREFIX "dai-link")) {
477 struct device_node *np = NULL; 453 struct device_node *np = NULL;
478 int i = 0; 454 int i = 0;
479 455
@@ -494,20 +470,9 @@ static int asoc_simple_card_parse_of(struct device_node *node,
494 return ret; 470 return ret;
495 } 471 }
496 472
497 priv->gpio_hp_det = of_get_named_gpio_flags(node, 473 ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
498 "simple-audio-card,hp-det-gpio", 0, &flags); 474 if (ret)
499 priv->gpio_hp_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW); 475 return ret;
500 if (priv->gpio_hp_det == -EPROBE_DEFER)
501 return -EPROBE_DEFER;
502
503 priv->gpio_mic_det = of_get_named_gpio_flags(node,
504 "simple-audio-card,mic-det-gpio", 0, &flags);
505 priv->gpio_mic_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW);
506 if (priv->gpio_mic_det == -EPROBE_DEFER)
507 return -EPROBE_DEFER;
508
509 if (!priv->snd_card.name)
510 priv->snd_card.name = priv->snd_card.dai_link->name;
511 476
512 return 0; 477 return 0;
513} 478}
@@ -536,7 +501,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
536 int num_links, ret; 501 int num_links, ret;
537 502
538 /* Get the number of DAI links */ 503 /* Get the number of DAI links */
539 if (np && of_get_child_by_name(np, "simple-audio-card,dai-link")) 504 if (np && of_get_child_by_name(np, PREFIX "dai-link"))
540 num_links = of_get_child_count(np); 505 num_links = of_get_child_count(np);
541 else 506 else
542 num_links = 1; 507 num_links = 1;
@@ -555,9 +520,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
555 priv->snd_card.dai_link = dai_link; 520 priv->snd_card.dai_link = dai_link;
556 priv->snd_card.num_links = num_links; 521 priv->snd_card.num_links = num_links;
557 522
558 priv->gpio_hp_det = -ENOENT;
559 priv->gpio_mic_det = -ENOENT;
560
561 /* Get room for the other properties */ 523 /* Get room for the other properties */
562 priv->dai_props = devm_kzalloc(dev, 524 priv->dai_props = devm_kzalloc(dev,
563 sizeof(*priv->dai_props) * num_links, 525 sizeof(*priv->dai_props) * num_links,
@@ -624,12 +586,8 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
624 struct snd_soc_card *card = platform_get_drvdata(pdev); 586 struct snd_soc_card *card = platform_get_drvdata(pdev);
625 struct simple_card_data *priv = snd_soc_card_get_drvdata(card); 587 struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
626 588
627 if (gpio_is_valid(priv->gpio_hp_det)) 589 asoc_simple_card_remove_jack(&priv->hp_jack);
628 snd_soc_jack_free_gpios(&simple_card_hp_jack, 1, 590 asoc_simple_card_remove_jack(&priv->mic_jack);
629 &simple_card_hp_jack_gpio);
630 if (gpio_is_valid(priv->gpio_mic_det))
631 snd_soc_jack_free_gpios(&simple_card_mic_jack, 1,
632 &simple_card_mic_jack_gpio);
633 591
634 return asoc_simple_card_unref(card); 592 return asoc_simple_card_unref(card);
635} 593}
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 91c15abb625e..a20c3dfbcb5d 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -7,7 +7,7 @@ config SND_MFLD_MACHINE
7 help 7 help
8 This adds support for ASoC machine driver for Intel(R) MID Medfield platform 8 This adds support for ASoC machine driver for Intel(R) MID Medfield platform
9 used as alsa device in audio substem in Intel(R) MID devices 9 used as alsa device in audio substem in Intel(R) MID devices
10 Say Y if you have such a device 10 Say Y if you have such a device.
11 If unsure select "N". 11 If unsure select "N".
12 12
13config SND_SST_MFLD_PLATFORM 13config SND_SST_MFLD_PLATFORM
@@ -25,7 +25,6 @@ config SND_SST_IPC_ACPI
25 tristate 25 tristate
26 select SND_SST_IPC 26 select SND_SST_IPC
27 select SND_SOC_INTEL_SST 27 select SND_SOC_INTEL_SST
28 depends on ACPI
29 28
30config SND_SOC_INTEL_SST 29config SND_SOC_INTEL_SST
31 tristate 30 tristate
@@ -33,6 +32,12 @@ config SND_SOC_INTEL_SST
33 select SND_SOC_INTEL_SST_MATCH if ACPI 32 select SND_SOC_INTEL_SST_MATCH if ACPI
34 depends on (X86 || COMPILE_TEST) 33 depends on (X86 || COMPILE_TEST)
35 34
35# firmware stuff depends DW_DMAC_CORE; since there is no depends-on from
36# the reverse selection, each machine driver needs to select
37# SND_SOC_INTEL_SST_FIRMWARE carefully depending on DW_DMAC_CORE
38config SND_SOC_INTEL_SST_FIRMWARE
39 tristate
40
36config SND_SOC_INTEL_SST_ACPI 41config SND_SOC_INTEL_SST_ACPI
37 tristate 42 tristate
38 43
@@ -48,16 +53,33 @@ config SND_SOC_INTEL_BAYTRAIL
48config SND_SOC_INTEL_HASWELL_MACH 53config SND_SOC_INTEL_HASWELL_MACH
49 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" 54 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
50 depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM 55 depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
51 depends on DW_DMAC_CORE=y 56 depends on DW_DMAC_CORE
52 select SND_SOC_INTEL_SST 57 select SND_SOC_INTEL_SST
58 select SND_SOC_INTEL_SST_FIRMWARE
53 select SND_SOC_INTEL_HASWELL 59 select SND_SOC_INTEL_HASWELL
54 select SND_SOC_RT5640 60 select SND_SOC_RT5640
55 help 61 help
56 This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell 62 This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell
57 Ultrabook platforms. 63 Ultrabook platforms.
58 Say Y if you have such a device 64 Say Y if you have such a device.
59 If unsure select "N". 65 If unsure select "N".
60 66
67config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
68 tristate "ASoC Audio driver for Broxton with DA7219 and MAX98357A in I2S Mode"
69 depends on X86 && ACPI && I2C
70 select SND_SOC_INTEL_SST
71 select SND_SOC_INTEL_SKYLAKE
72 select SND_SOC_DA7219
73 select SND_SOC_MAX98357A
74 select SND_SOC_DMIC
75 select SND_SOC_HDAC_HDMI
76 select SND_HDA_DSP_LOADER
77 help
78 This adds support for ASoC machine driver for Broxton-P platforms
79 with DA7219 + MAX98357A I2S audio codec.
80 Say Y if you have such a device.
81 If unsure select "N".
82
61config SND_SOC_INTEL_BXT_RT298_MACH 83config SND_SOC_INTEL_BXT_RT298_MACH
62 tristate "ASoC Audio driver for Broxton with RT298 I2S mode" 84 tristate "ASoC Audio driver for Broxton with RT298 I2S mode"
63 depends on X86 && ACPI && I2C 85 depends on X86 && ACPI && I2C
@@ -70,26 +92,28 @@ config SND_SOC_INTEL_BXT_RT298_MACH
70 help 92 help
71 This adds support for ASoC machine driver for Broxton platforms 93 This adds support for ASoC machine driver for Broxton platforms
72 with RT286 I2S audio codec. 94 with RT286 I2S audio codec.
73 Say Y if you have such a device 95 Say Y if you have such a device.
74 If unsure select "N". 96 If unsure select "N".
75 97
76config SND_SOC_INTEL_BYT_RT5640_MACH 98config SND_SOC_INTEL_BYT_RT5640_MACH
77 tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" 99 tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
78 depends on X86_INTEL_LPSS && I2C 100 depends on X86_INTEL_LPSS && I2C
79 depends on DW_DMAC_CORE=y && (SND_SST_IPC_ACPI = n) 101 depends on DW_DMAC_CORE && (SND_SST_IPC_ACPI = n)
80 select SND_SOC_INTEL_SST 102 select SND_SOC_INTEL_SST
103 select SND_SOC_INTEL_SST_FIRMWARE
81 select SND_SOC_INTEL_BAYTRAIL 104 select SND_SOC_INTEL_BAYTRAIL
82 select SND_SOC_RT5640 105 select SND_SOC_RT5640
83 help 106 help
84 This adds audio driver for Intel Baytrail platform based boards 107 This adds audio driver for Intel Baytrail platform based boards
85 with the RT5640 audio codec. This driver is deprecated, use 108 with the RT5640 audio codec. This driver is deprecated, use
86 SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality 109 SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality.
87 110
88config SND_SOC_INTEL_BYT_MAX98090_MACH 111config SND_SOC_INTEL_BYT_MAX98090_MACH
89 tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" 112 tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
90 depends on X86_INTEL_LPSS && I2C 113 depends on X86_INTEL_LPSS && I2C
91 depends on DW_DMAC_CORE=y && (SND_SST_IPC_ACPI = n) 114 depends on DW_DMAC_CORE && (SND_SST_IPC_ACPI = n)
92 select SND_SOC_INTEL_SST 115 select SND_SOC_INTEL_SST
116 select SND_SOC_INTEL_SST_FIRMWARE
93 select SND_SOC_INTEL_BAYTRAIL 117 select SND_SOC_INTEL_BAYTRAIL
94 select SND_SOC_MAX98090 118 select SND_SOC_MAX98090
95 help 119 help
@@ -100,19 +124,20 @@ config SND_SOC_INTEL_BROADWELL_MACH
100 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" 124 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
101 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ 125 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \
102 I2C_DESIGNWARE_PLATFORM 126 I2C_DESIGNWARE_PLATFORM
103 depends on DW_DMAC_CORE=y 127 depends on DW_DMAC_CORE
104 select SND_SOC_INTEL_SST 128 select SND_SOC_INTEL_SST
129 select SND_SOC_INTEL_SST_FIRMWARE
105 select SND_SOC_INTEL_HASWELL 130 select SND_SOC_INTEL_HASWELL
106 select SND_SOC_RT286 131 select SND_SOC_RT286
107 help 132 help
108 This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell 133 This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell
109 Ultrabook platforms. 134 Ultrabook platforms.
110 Say Y if you have such a device 135 Say Y if you have such a device.
111 If unsure select "N". 136 If unsure select "N".
112 137
113config SND_SOC_INTEL_BYTCR_RT5640_MACH 138config SND_SOC_INTEL_BYTCR_RT5640_MACH
114 tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec" 139 tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec"
115 depends on X86 && I2C 140 depends on X86 && I2C && ACPI
116 select SND_SOC_RT5640 141 select SND_SOC_RT5640
117 select SND_SST_MFLD_PLATFORM 142 select SND_SST_MFLD_PLATFORM
118 select SND_SST_IPC_ACPI 143 select SND_SST_IPC_ACPI
@@ -120,12 +145,12 @@ config SND_SOC_INTEL_BYTCR_RT5640_MACH
120 help 145 help
121 This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR 146 This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
122 platforms with RT5640 audio codec. 147 platforms with RT5640 audio codec.
123 Say Y if you have such a device 148 Say Y if you have such a device.
124 If unsure select "N". 149 If unsure select "N".
125 150
126config SND_SOC_INTEL_BYTCR_RT5651_MACH 151config SND_SOC_INTEL_BYTCR_RT5651_MACH
127 tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5651 codec" 152 tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5651 codec"
128 depends on X86 && I2C 153 depends on X86 && I2C && ACPI
129 select SND_SOC_RT5651 154 select SND_SOC_RT5651
130 select SND_SST_MFLD_PLATFORM 155 select SND_SST_MFLD_PLATFORM
131 select SND_SST_IPC_ACPI 156 select SND_SST_IPC_ACPI
@@ -133,12 +158,12 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH
133 help 158 help
134 This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR 159 This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
135 platforms with RT5651 audio codec. 160 platforms with RT5651 audio codec.
136 Say Y if you have such a device 161 Say Y if you have such a device.
137 If unsure select "N". 162 If unsure select "N".
138 163
139config SND_SOC_INTEL_CHT_BSW_RT5672_MACH 164config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
140 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" 165 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec"
141 depends on X86_INTEL_LPSS && I2C 166 depends on X86_INTEL_LPSS && I2C && ACPI
142 select SND_SOC_RT5670 167 select SND_SOC_RT5670
143 select SND_SST_MFLD_PLATFORM 168 select SND_SST_MFLD_PLATFORM
144 select SND_SST_IPC_ACPI 169 select SND_SST_IPC_ACPI
@@ -146,12 +171,12 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
146 help 171 help
147 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell 172 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
148 platforms with RT5672 audio codec. 173 platforms with RT5672 audio codec.
149 Say Y if you have such a device 174 Say Y if you have such a device.
150 If unsure select "N". 175 If unsure select "N".
151 176
152config SND_SOC_INTEL_CHT_BSW_RT5645_MACH 177config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
153 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec" 178 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec"
154 depends on X86_INTEL_LPSS && I2C 179 depends on X86_INTEL_LPSS && I2C && ACPI
155 select SND_SOC_RT5645 180 select SND_SOC_RT5645
156 select SND_SST_MFLD_PLATFORM 181 select SND_SST_MFLD_PLATFORM
157 select SND_SST_IPC_ACPI 182 select SND_SST_IPC_ACPI
@@ -163,16 +188,16 @@ config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
163 188
164config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH 189config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
165 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec" 190 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec"
166 depends on X86_INTEL_LPSS && I2C 191 depends on X86_INTEL_LPSS && I2C && ACPI
167 select SND_SOC_MAX98090 192 select SND_SOC_MAX98090
168 select SND_SOC_TS3A227E 193 select SND_SOC_TS3A227E
169 select SND_SST_MFLD_PLATFORM 194 select SND_SST_MFLD_PLATFORM
170 select SND_SST_IPC_ACPI 195 select SND_SST_IPC_ACPI
171 select SND_SOC_INTEL_SST_MATCH if ACPI 196 select SND_SOC_INTEL_SST_MATCH if ACPI
172 help 197 help
173 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell 198 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
174 platforms with MAX98090 audio codec it also can support TI jack chip as aux device. 199 platforms with MAX98090 audio codec it also can support TI jack chip as aux device.
175 If unsure select "N". 200 If unsure select "N".
176 201
177config SND_SOC_INTEL_SKYLAKE 202config SND_SOC_INTEL_SKYLAKE
178 tristate 203 tristate
@@ -192,7 +217,7 @@ config SND_SOC_INTEL_SKL_RT286_MACH
192 help 217 help
193 This adds support for ASoC machine driver for Skylake platforms 218 This adds support for ASoC machine driver for Skylake platforms
194 with RT286 I2S audio codec. 219 with RT286 I2S audio codec.
195 Say Y if you have such a device 220 Say Y if you have such a device.
196 If unsure select "N". 221 If unsure select "N".
197 222
198config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH 223config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
@@ -207,7 +232,7 @@ config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
207 help 232 help
208 This adds support for ASoC Onboard Codec I2S machine driver. This will 233 This adds support for ASoC Onboard Codec I2S machine driver. This will
209 create an alsa sound card for NAU88L25 + SSM4567. 234 create an alsa sound card for NAU88L25 + SSM4567.
210 Say Y if you have such a device 235 Say Y if you have such a device.
211 If unsure select "N". 236 If unsure select "N".
212 237
213config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH 238config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
@@ -222,5 +247,5 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
222 help 247 help
223 This adds support for ASoC Onboard Codec I2S machine driver. This will 248 This adds support for ASoC Onboard Codec I2S machine driver. This will
224 create an alsa sound card for NAU88L25 + MAX98357A. 249 create an alsa sound card for NAU88L25 + MAX98357A.
225 Say Y if you have such a device 250 Say Y if you have such a device.
226 If unsure select "N". 251 If unsure select "N".
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 3bc4b63b2f9d..4d3184971227 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -28,6 +28,7 @@
28#include <linux/firmware.h> 28#include <linux/firmware.h>
29#include <linux/pm_runtime.h> 29#include <linux/pm_runtime.h>
30#include <linux/pm_qos.h> 30#include <linux/pm_qos.h>
31#include <linux/dmi.h>
31#include <linux/acpi.h> 32#include <linux/acpi.h>
32#include <asm/platform_sst_audio.h> 33#include <asm/platform_sst_audio.h>
33#include <sound/core.h> 34#include <sound/core.h>
@@ -237,6 +238,9 @@ static int sst_acpi_probe(struct platform_device *pdev)
237 dev_err(dev, "No matching machine driver found\n"); 238 dev_err(dev, "No matching machine driver found\n");
238 return -ENODEV; 239 return -ENODEV;
239 } 240 }
241 if (mach->machine_quirk)
242 mach = mach->machine_quirk(mach);
243
240 pdata = mach->pdata; 244 pdata = mach->pdata;
241 245
242 ret = kstrtouint(id->id, 16, &dev_id); 246 ret = kstrtouint(id->id, 16, &dev_id);
@@ -320,6 +324,44 @@ static int sst_acpi_remove(struct platform_device *pdev)
320 return 0; 324 return 0;
321} 325}
322 326
327static unsigned long cht_machine_id;
328
329#define CHT_SURFACE_MACH 1
330
331static int cht_surface_quirk_cb(const struct dmi_system_id *id)
332{
333 cht_machine_id = CHT_SURFACE_MACH;
334 return 1;
335}
336
337
338static const struct dmi_system_id cht_table[] = {
339 {
340 .callback = cht_surface_quirk_cb,
341 .matches = {
342 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
343 DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
344 },
345 },
346};
347
348
349static struct sst_acpi_mach cht_surface_mach = {
350 "10EC5640", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
351 &chv_platform_data };
352
353static struct sst_acpi_mach *cht_quirk(void *arg)
354{
355 struct sst_acpi_mach *mach = arg;
356
357 dmi_check_system(cht_table);
358
359 if (cht_machine_id == CHT_SURFACE_MACH)
360 return &cht_surface_mach;
361 else
362 return mach;
363}
364
323static struct sst_acpi_mach sst_acpi_bytcr[] = { 365static struct sst_acpi_mach sst_acpi_bytcr[] = {
324 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, 366 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL,
325 &byt_rvp_platform_data }, 367 &byt_rvp_platform_data },
@@ -343,7 +385,7 @@ static struct sst_acpi_mach sst_acpi_chv[] = {
343 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL, 385 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
344 &chv_platform_data }, 386 &chv_platform_data },
345 /* some CHT-T platforms rely on RT5640, use Baytrail machine driver */ 387 /* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
346 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_22a8.bin", "bytcr_rt5640", NULL, 388 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_22a8.bin", "bytcr_rt5640", cht_quirk,
347 &chv_platform_data }, 389 &chv_platform_data },
348 390
349 {}, 391 {},
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index a8506774f510..dac03a06bfd8 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -2,6 +2,7 @@ snd-soc-sst-haswell-objs := haswell.o
2snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o 2snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
3snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o 3snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
4snd-soc-sst-broadwell-objs := broadwell.o 4snd-soc-sst-broadwell-objs := broadwell.o
5snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o
5snd-soc-sst-bxt-rt298-objs := bxt_rt298.o 6snd-soc-sst-bxt-rt298-objs := bxt_rt298.o
6snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o 7snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
7snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o 8snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
@@ -15,6 +16,7 @@ snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
15obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 16obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
16obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 17obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
17obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o 18obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
19obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o
18obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o 20obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o
19obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o 21obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
20obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o 22obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
new file mode 100644
index 000000000000..3774b117d365
--- /dev/null
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -0,0 +1,460 @@
1/*
2 * Intel Broxton-P I2S Machine Driver
3 *
4 * Copyright (C) 2016, Intel Corporation. All rights reserved.
5 *
6 * Modified from:
7 * Intel Skylake I2S Machine driver
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version
11 * 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <sound/core.h>
22#include <sound/jack.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include "../../codecs/hdac_hdmi.h"
27#include "../../codecs/da7219.h"
28#include "../../codecs/da7219-aad.h"
29
30#define BXT_DIALOG_CODEC_DAI "da7219-hifi"
31#define BXT_MAXIM_CODEC_DAI "HiFi"
32#define DUAL_CHANNEL 2
33
34static struct snd_soc_jack broxton_headset;
35
36enum {
37 BXT_DPCM_AUDIO_PB = 0,
38 BXT_DPCM_AUDIO_CP,
39 BXT_DPCM_AUDIO_REF_CP,
40 BXT_DPCM_AUDIO_HDMI1_PB,
41 BXT_DPCM_AUDIO_HDMI2_PB,
42 BXT_DPCM_AUDIO_HDMI3_PB,
43};
44
45static const struct snd_kcontrol_new broxton_controls[] = {
46 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
47 SOC_DAPM_PIN_SWITCH("Headset Mic"),
48 SOC_DAPM_PIN_SWITCH("Spk"),
49};
50
51static const struct snd_soc_dapm_widget broxton_widgets[] = {
52 SND_SOC_DAPM_HP("Headphone Jack", NULL),
53 SND_SOC_DAPM_MIC("Headset Mic", NULL),
54 SND_SOC_DAPM_SPK("Spk", NULL),
55 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
56 SND_SOC_DAPM_SPK("HDMI1", NULL),
57 SND_SOC_DAPM_SPK("HDMI2", NULL),
58 SND_SOC_DAPM_SPK("HDMI3", NULL),
59};
60
61static const struct snd_soc_dapm_route broxton_map[] = {
62 /* HP jack connectors - unknown if we have jack detection */
63 {"Headphone Jack", NULL, "HPL"},
64 {"Headphone Jack", NULL, "HPR"},
65
66 /* speaker */
67 {"Spk", NULL, "Speaker"},
68
69 /* other jacks */
70 {"MIC", NULL, "Headset Mic"},
71
72 /* digital mics */
73 {"DMic", NULL, "SoC DMIC"},
74
75 /* CODEC BE connections */
76 {"HiFi Playback", NULL, "ssp5 Tx"},
77 {"ssp5 Tx", NULL, "codec0_out"},
78
79 {"Playback", NULL, "ssp1 Tx"},
80 {"ssp1 Tx", NULL, "codec1_out"},
81
82 {"codec0_in", NULL, "ssp1 Rx"},
83 {"ssp1 Rx", NULL, "Capture"},
84
85 {"HDMI1", NULL, "hif5 Output"},
86 {"HDMI2", NULL, "hif6 Output"},
87 {"HDMI3", NULL, "hif7 Output"},
88
89 {"hifi3", NULL, "iDisp3 Tx"},
90 {"iDisp3 Tx", NULL, "iDisp3_out"},
91 {"hifi2", NULL, "iDisp2 Tx"},
92 {"iDisp2 Tx", NULL, "iDisp2_out"},
93 {"hifi1", NULL, "iDisp1 Tx"},
94 {"iDisp1 Tx", NULL, "iDisp1_out"},
95
96 /* DMIC */
97 {"dmic01_hifi", NULL, "DMIC01 Rx"},
98 {"DMIC01 Rx", NULL, "DMIC AIF"},
99};
100
101static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
102 struct snd_pcm_hw_params *params)
103{
104 struct snd_interval *rate = hw_param_interval(params,
105 SNDRV_PCM_HW_PARAM_RATE);
106 struct snd_interval *channels = hw_param_interval(params,
107 SNDRV_PCM_HW_PARAM_CHANNELS);
108 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
109
110 /* The ADSP will convert the FE rate to 48k, stereo */
111 rate->min = rate->max = 48000;
112 channels->min = channels->max = DUAL_CHANNEL;
113
114 /* set SSP to 24 bit */
115 snd_mask_none(fmt);
116 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
117
118 return 0;
119}
120
121static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
122{
123 int ret;
124 struct snd_soc_codec *codec = rtd->codec;
125
126 /*
127 * Headset buttons map to the google Reference headset.
128 * These can be configured by userspace.
129 */
130 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
131 SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
132 SND_JACK_BTN_2 | SND_JACK_BTN_3, &broxton_headset,
133 NULL, 0);
134 if (ret) {
135 dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
136 return ret;
137 }
138
139 da7219_aad_jack_det(codec, &broxton_headset);
140
141 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
142
143 return ret;
144}
145
146static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd)
147{
148 struct snd_soc_dai *dai = rtd->codec_dai;
149
150 return hdac_hdmi_jack_init(dai, BXT_DPCM_AUDIO_HDMI1_PB + dai->id);
151}
152
153static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
154{
155 struct snd_soc_dapm_context *dapm;
156 struct snd_soc_component *component = rtd->cpu_dai->component;
157
158 dapm = snd_soc_component_get_dapm(component);
159 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
160
161 return 0;
162}
163
164static unsigned int rates[] = {
165 48000,
166};
167
168static struct snd_pcm_hw_constraint_list constraints_rates = {
169 .count = ARRAY_SIZE(rates),
170 .list = rates,
171 .mask = 0,
172};
173
174static unsigned int channels[] = {
175 DUAL_CHANNEL,
176};
177
178static struct snd_pcm_hw_constraint_list constraints_channels = {
179 .count = ARRAY_SIZE(channels),
180 .list = channels,
181 .mask = 0,
182};
183
184static int bxt_fe_startup(struct snd_pcm_substream *substream)
185{
186 struct snd_pcm_runtime *runtime = substream->runtime;
187
188 /*
189 * On this platform for PCM device we support,
190 * 48Khz
191 * stereo
192 * 16 bit audio
193 */
194
195 runtime->hw.channels_max = DUAL_CHANNEL;
196 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
197 &constraints_channels);
198
199 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
200 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
201
202 snd_pcm_hw_constraint_list(runtime, 0,
203 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
204
205 return 0;
206}
207
208static const struct snd_soc_ops broxton_da7219_fe_ops = {
209 .startup = bxt_fe_startup,
210};
211
212static int broxton_da7219_hw_params(struct snd_pcm_substream *substream,
213 struct snd_pcm_hw_params *params)
214{
215 struct snd_soc_pcm_runtime *rtd = substream->private_data;
216 struct snd_soc_dai *codec_dai = rtd->codec_dai;
217 int ret;
218
219 ret = snd_soc_dai_set_sysclk(codec_dai,
220 DA7219_CLKSRC_MCLK, 19200000, SND_SOC_CLOCK_IN);
221 if (ret < 0)
222 dev_err(codec_dai->dev, "can't set codec sysclk configuration\n");
223
224 ret = snd_soc_dai_set_pll(codec_dai, 0,
225 DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304);
226 if (ret < 0) {
227 dev_err(codec_dai->dev, "failed to start PLL: %d\n", ret);
228 return -EIO;
229 }
230
231 return ret;
232}
233
234static int broxton_da7219_hw_free(struct snd_pcm_substream *substream)
235{
236 struct snd_soc_pcm_runtime *rtd = substream->private_data;
237 struct snd_soc_dai *codec_dai = rtd->codec_dai;
238 int ret;
239
240 ret = snd_soc_dai_set_pll(codec_dai, 0,
241 DA7219_SYSCLK_MCLK, 0, 0);
242 if (ret < 0) {
243 dev_err(codec_dai->dev, "failed to stop PLL: %d\n", ret);
244 return -EIO;
245 }
246
247 return ret;
248}
249
250static struct snd_soc_ops broxton_da7219_ops = {
251 .hw_params = broxton_da7219_hw_params,
252 .hw_free = broxton_da7219_hw_free,
253};
254
255/* broxton digital audio interface glue - connects codec <--> CPU */
256static struct snd_soc_dai_link broxton_dais[] = {
257 /* Front End DAI links */
258 [BXT_DPCM_AUDIO_PB]
259 {
260 .name = "Bxt Audio Port",
261 .stream_name = "Audio",
262 .cpu_dai_name = "System Pin",
263 .platform_name = "0000:00:0e.0",
264 .dynamic = 1,
265 .codec_name = "snd-soc-dummy",
266 .codec_dai_name = "snd-soc-dummy-dai",
267 .nonatomic = 1,
268 .init = broxton_da7219_fe_init,
269 .trigger = {
270 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
271 .dpcm_playback = 1,
272 .ops = &broxton_da7219_fe_ops,
273 },
274 [BXT_DPCM_AUDIO_CP]
275 {
276 .name = "Bxt Audio Capture Port",
277 .stream_name = "Audio Record",
278 .cpu_dai_name = "System Pin",
279 .platform_name = "0000:00:0e.0",
280 .dynamic = 1,
281 .codec_name = "snd-soc-dummy",
282 .codec_dai_name = "snd-soc-dummy-dai",
283 .nonatomic = 1,
284 .trigger = {
285 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
286 .dpcm_capture = 1,
287 .ops = &broxton_da7219_fe_ops,
288 },
289 [BXT_DPCM_AUDIO_REF_CP]
290 {
291 .name = "Bxt Audio Reference cap",
292 .stream_name = "Refcap",
293 .cpu_dai_name = "Reference Pin",
294 .codec_name = "snd-soc-dummy",
295 .codec_dai_name = "snd-soc-dummy-dai",
296 .platform_name = "0000:00:0e.0",
297 .init = NULL,
298 .dpcm_capture = 1,
299 .ignore_suspend = 1,
300 .nonatomic = 1,
301 .dynamic = 1,
302 },
303 [BXT_DPCM_AUDIO_HDMI1_PB]
304 {
305 .name = "Bxt HDMI Port1",
306 .stream_name = "Hdmi1",
307 .cpu_dai_name = "HDMI1 Pin",
308 .codec_name = "snd-soc-dummy",
309 .codec_dai_name = "snd-soc-dummy-dai",
310 .platform_name = "0000:00:0e.0",
311 .dpcm_playback = 1,
312 .init = NULL,
313 .nonatomic = 1,
314 .dynamic = 1,
315 },
316 [BXT_DPCM_AUDIO_HDMI2_PB]
317 {
318 .name = "Bxt HDMI Port2",
319 .stream_name = "Hdmi2",
320 .cpu_dai_name = "HDMI2 Pin",
321 .codec_name = "snd-soc-dummy",
322 .codec_dai_name = "snd-soc-dummy-dai",
323 .platform_name = "0000:00:0e.0",
324 .dpcm_playback = 1,
325 .init = NULL,
326 .nonatomic = 1,
327 .dynamic = 1,
328 },
329 [BXT_DPCM_AUDIO_HDMI3_PB]
330 {
331 .name = "Bxt HDMI Port3",
332 .stream_name = "Hdmi3",
333 .cpu_dai_name = "HDMI3 Pin",
334 .codec_name = "snd-soc-dummy",
335 .codec_dai_name = "snd-soc-dummy-dai",
336 .platform_name = "0000:00:0e.0",
337 .dpcm_playback = 1,
338 .init = NULL,
339 .nonatomic = 1,
340 .dynamic = 1,
341 },
342 /* Back End DAI links */
343 {
344 /* SSP5 - Codec */
345 .name = "SSP5-Codec",
346 .id = 0,
347 .cpu_dai_name = "SSP5 Pin",
348 .platform_name = "0000:00:0e.0",
349 .no_pcm = 1,
350 .codec_name = "MX98357A:00",
351 .codec_dai_name = BXT_MAXIM_CODEC_DAI,
352 .dai_fmt = SND_SOC_DAIFMT_I2S |
353 SND_SOC_DAIFMT_NB_NF |
354 SND_SOC_DAIFMT_CBS_CFS,
355 .ignore_pmdown_time = 1,
356 .be_hw_params_fixup = broxton_ssp_fixup,
357 .dpcm_playback = 1,
358 },
359 {
360 /* SSP1 - Codec */
361 .name = "SSP1-Codec",
362 .id = 1,
363 .cpu_dai_name = "SSP1 Pin",
364 .platform_name = "0000:00:0e.0",
365 .no_pcm = 1,
366 .codec_name = "i2c-DLGS7219:00",
367 .codec_dai_name = BXT_DIALOG_CODEC_DAI,
368 .init = broxton_da7219_codec_init,
369 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
370 SND_SOC_DAIFMT_CBS_CFS,
371 .ignore_pmdown_time = 1,
372 .be_hw_params_fixup = broxton_ssp_fixup,
373 .ops = &broxton_da7219_ops,
374 .dpcm_playback = 1,
375 .dpcm_capture = 1,
376 },
377 {
378 .name = "dmic01",
379 .id = 2,
380 .cpu_dai_name = "DMIC01 Pin",
381 .codec_name = "dmic-codec",
382 .codec_dai_name = "dmic-hifi",
383 .platform_name = "0000:00:0e.0",
384 .ignore_suspend = 1,
385 .dpcm_capture = 1,
386 .no_pcm = 1,
387 },
388 {
389 .name = "iDisp1",
390 .id = 3,
391 .cpu_dai_name = "iDisp1 Pin",
392 .codec_name = "ehdaudio0D2",
393 .codec_dai_name = "intel-hdmi-hifi1",
394 .platform_name = "0000:00:0e.0",
395 .init = broxton_hdmi_init,
396 .dpcm_playback = 1,
397 .no_pcm = 1,
398 },
399 {
400 .name = "iDisp2",
401 .id = 4,
402 .cpu_dai_name = "iDisp2 Pin",
403 .codec_name = "ehdaudio0D2",
404 .codec_dai_name = "intel-hdmi-hifi2",
405 .platform_name = "0000:00:0e.0",
406 .init = broxton_hdmi_init,
407 .dpcm_playback = 1,
408 .no_pcm = 1,
409 },
410 {
411 .name = "iDisp3",
412 .id = 5,
413 .cpu_dai_name = "iDisp3 Pin",
414 .codec_name = "ehdaudio0D2",
415 .codec_dai_name = "intel-hdmi-hifi3",
416 .platform_name = "0000:00:0e.0",
417 .init = broxton_hdmi_init,
418 .dpcm_playback = 1,
419 .no_pcm = 1,
420 },
421};
422
423/* broxton audio machine driver for SPT + da7219 */
424static struct snd_soc_card broxton_audio_card = {
425 .name = "bxtda7219max",
426 .owner = THIS_MODULE,
427 .dai_link = broxton_dais,
428 .num_links = ARRAY_SIZE(broxton_dais),
429 .controls = broxton_controls,
430 .num_controls = ARRAY_SIZE(broxton_controls),
431 .dapm_widgets = broxton_widgets,
432 .num_dapm_widgets = ARRAY_SIZE(broxton_widgets),
433 .dapm_routes = broxton_map,
434 .num_dapm_routes = ARRAY_SIZE(broxton_map),
435 .fully_routed = true,
436};
437
438static int broxton_audio_probe(struct platform_device *pdev)
439{
440 broxton_audio_card.dev = &pdev->dev;
441 return devm_snd_soc_register_card(&pdev->dev, &broxton_audio_card);
442}
443
444static struct platform_driver broxton_audio = {
445 .probe = broxton_audio_probe,
446 .driver = {
447 .name = "bxt_da7219_max98357a_i2s",
448 .pm = &snd_soc_pm_ops,
449 },
450};
451module_platform_driver(broxton_audio)
452
453/* Module information */
454MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode");
455MODULE_AUTHOR("Sathyanarayana Nujella <sathyanarayana.nujella@intel.com>");
456MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>");
457MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
458MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
459MODULE_LICENSE("GPL v2");
460MODULE_ALIAS("platform:bxt_da7219_max98357a_i2s");
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index f4787515c0ed..253d7bfbf511 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -33,6 +33,7 @@ enum {
33 BXT_DPCM_AUDIO_PB = 0, 33 BXT_DPCM_AUDIO_PB = 0,
34 BXT_DPCM_AUDIO_CP, 34 BXT_DPCM_AUDIO_CP,
35 BXT_DPCM_AUDIO_REF_CP, 35 BXT_DPCM_AUDIO_REF_CP,
36 BXT_DPCM_AUDIO_DMIC_CP,
36 BXT_DPCM_AUDIO_HDMI1_PB, 37 BXT_DPCM_AUDIO_HDMI1_PB,
37 BXT_DPCM_AUDIO_HDMI2_PB, 38 BXT_DPCM_AUDIO_HDMI2_PB,
38 BXT_DPCM_AUDIO_HDMI3_PB, 39 BXT_DPCM_AUDIO_HDMI3_PB,
@@ -88,6 +89,7 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = {
88 /* CODEC BE connections */ 89 /* CODEC BE connections */
89 { "AIF1 Playback", NULL, "ssp5 Tx"}, 90 { "AIF1 Playback", NULL, "ssp5 Tx"},
90 { "ssp5 Tx", NULL, "codec0_out"}, 91 { "ssp5 Tx", NULL, "codec0_out"},
92 { "ssp5 Tx", NULL, "codec1_out"},
91 93
92 { "codec0_in", NULL, "ssp5 Rx" }, 94 { "codec0_in", NULL, "ssp5 Rx" },
93 { "ssp5 Rx", NULL, "AIF1 Capture" }, 95 { "ssp5 Rx", NULL, "AIF1 Capture" },
@@ -104,6 +106,17 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = {
104 106
105}; 107};
106 108
109static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd)
110{
111 struct snd_soc_dapm_context *dapm;
112 struct snd_soc_component *component = rtd->cpu_dai->component;
113
114 dapm = snd_soc_component_get_dapm(component);
115 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
116
117 return 0;
118}
119
107static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) 120static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
108{ 121{
109 struct snd_soc_codec *codec = rtd->codec; 122 struct snd_soc_codec *codec = rtd->codec;
@@ -118,6 +131,9 @@ static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
118 return ret; 131 return ret;
119 132
120 rt298_mic_detect(codec, &broxton_headset); 133 rt298_mic_detect(codec, &broxton_headset);
134
135 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
136
121 return 0; 137 return 0;
122} 138}
123 139
@@ -169,6 +185,89 @@ static struct snd_soc_ops broxton_rt298_ops = {
169 .hw_params = broxton_rt298_hw_params, 185 .hw_params = broxton_rt298_hw_params,
170}; 186};
171 187
188static unsigned int rates[] = {
189 48000,
190};
191
192static struct snd_pcm_hw_constraint_list constraints_rates = {
193 .count = ARRAY_SIZE(rates),
194 .list = rates,
195 .mask = 0,
196};
197
198static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
199 struct snd_pcm_hw_params *params)
200{
201 struct snd_interval *channels = hw_param_interval(params,
202 SNDRV_PCM_HW_PARAM_CHANNELS);
203 if (params_channels(params) == 2)
204 channels->min = channels->max = 2;
205 else
206 channels->min = channels->max = 4;
207
208 return 0;
209}
210
211static unsigned int channels_dmic[] = {
212 2, 4,
213};
214
215static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
216 .count = ARRAY_SIZE(channels_dmic),
217 .list = channels_dmic,
218 .mask = 0,
219};
220
221static int broxton_dmic_startup(struct snd_pcm_substream *substream)
222{
223 struct snd_pcm_runtime *runtime = substream->runtime;
224
225 runtime->hw.channels_max = 4;
226 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
227 &constraints_dmic_channels);
228
229 return snd_pcm_hw_constraint_list(substream->runtime, 0,
230 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
231}
232
233static struct snd_soc_ops broxton_dmic_ops = {
234 .startup = broxton_dmic_startup,
235};
236
237static unsigned int channels[] = {
238 2,
239};
240
241static struct snd_pcm_hw_constraint_list constraints_channels = {
242 .count = ARRAY_SIZE(channels),
243 .list = channels,
244 .mask = 0,
245};
246
247static int bxt_fe_startup(struct snd_pcm_substream *substream)
248{
249 struct snd_pcm_runtime *runtime = substream->runtime;
250
251 /*
252 * on this platform for PCM device we support:
253 * 48Khz
254 * stereo
255 */
256
257 runtime->hw.channels_max = 2;
258 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
259 &constraints_channels);
260
261 snd_pcm_hw_constraint_list(runtime, 0,
262 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
263
264 return 0;
265}
266
267static const struct snd_soc_ops broxton_rt286_fe_ops = {
268 .startup = bxt_fe_startup,
269};
270
172/* broxton digital audio interface glue - connects codec <--> CPU */ 271/* broxton digital audio interface glue - connects codec <--> CPU */
173static struct snd_soc_dai_link broxton_rt298_dais[] = { 272static struct snd_soc_dai_link broxton_rt298_dais[] = {
174 /* Front End DAI links */ 273 /* Front End DAI links */
@@ -182,8 +281,10 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
182 .dynamic = 1, 281 .dynamic = 1,
183 .codec_name = "snd-soc-dummy", 282 .codec_name = "snd-soc-dummy",
184 .codec_dai_name = "snd-soc-dummy-dai", 283 .codec_dai_name = "snd-soc-dummy-dai",
284 .init = broxton_rt298_fe_init,
185 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 285 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
186 .dpcm_playback = 1, 286 .dpcm_playback = 1,
287 .ops = &broxton_rt286_fe_ops,
187 }, 288 },
188 [BXT_DPCM_AUDIO_CP] 289 [BXT_DPCM_AUDIO_CP]
189 { 290 {
@@ -197,6 +298,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
197 .codec_dai_name = "snd-soc-dummy-dai", 298 .codec_dai_name = "snd-soc-dummy-dai",
198 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, 299 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
199 .dpcm_capture = 1, 300 .dpcm_capture = 1,
301 .ops = &broxton_rt286_fe_ops,
200 }, 302 },
201 [BXT_DPCM_AUDIO_REF_CP] 303 [BXT_DPCM_AUDIO_REF_CP]
202 { 304 {
@@ -211,6 +313,20 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
211 .nonatomic = 1, 313 .nonatomic = 1,
212 .dynamic = 1, 314 .dynamic = 1,
213 }, 315 },
316 [BXT_DPCM_AUDIO_DMIC_CP]
317 {
318 .name = "Bxt Audio DMIC cap",
319 .stream_name = "dmiccap",
320 .cpu_dai_name = "DMIC Pin",
321 .codec_name = "snd-soc-dummy",
322 .codec_dai_name = "snd-soc-dummy-dai",
323 .platform_name = "0000:00:0e.0",
324 .init = NULL,
325 .dpcm_capture = 1,
326 .nonatomic = 1,
327 .dynamic = 1,
328 .ops = &broxton_dmic_ops,
329 },
214 [BXT_DPCM_AUDIO_HDMI1_PB] 330 [BXT_DPCM_AUDIO_HDMI1_PB]
215 { 331 {
216 .name = "Bxt HDMI Port1", 332 .name = "Bxt HDMI Port1",
@@ -276,6 +392,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
276 .codec_name = "dmic-codec", 392 .codec_name = "dmic-codec",
277 .codec_dai_name = "dmic-hifi", 393 .codec_dai_name = "dmic-hifi",
278 .platform_name = "0000:00:0e.0", 394 .platform_name = "0000:00:0e.0",
395 .be_hw_params_fixup = broxton_dmic_fixup,
279 .ignore_suspend = 1, 396 .ignore_suspend = 1,
280 .dpcm_capture = 1, 397 .dpcm_capture = 1,
281 .no_pcm = 1, 398 .no_pcm = 1,
@@ -341,6 +458,7 @@ static struct platform_driver broxton_audio = {
341 .probe = broxton_audio_probe, 458 .probe = broxton_audio_probe,
342 .driver = { 459 .driver = {
343 .name = "bxt_alc298s_i2s", 460 .name = "bxt_alc298s_i2s",
461 .pm = &snd_soc_pm_ops,
344 }, 462 },
345}; 463};
346module_platform_driver(broxton_audio) 464module_platform_driver(broxton_audio)
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index d7ef292c402d..56056ed7fcfd 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -30,6 +30,7 @@
30#include <sound/jack.h> 30#include <sound/jack.h>
31#include "../../codecs/rt5645.h" 31#include "../../codecs/rt5645.h"
32#include "../atom/sst-atom-controls.h" 32#include "../atom/sst-atom-controls.h"
33#include "../common/sst-acpi.h"
33 34
34#define CHT_PLAT_CLK_3_HZ 19200000 35#define CHT_PLAT_CLK_3_HZ 19200000
35#define CHT_CODEC_DAI "rt5645-aif1" 36#define CHT_CODEC_DAI "rt5645-aif1"
@@ -340,10 +341,13 @@ static struct snd_soc_card snd_soc_card_chtrt5650 = {
340}; 341};
341 342
342static struct cht_acpi_card snd_soc_cards[] = { 343static struct cht_acpi_card snd_soc_cards[] = {
344 {"10EC5640", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645},
343 {"10EC5645", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645}, 345 {"10EC5645", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645},
344 {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650}, 346 {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650},
345}; 347};
346 348
349static char cht_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
350
347static int snd_cht_mc_probe(struct platform_device *pdev) 351static int snd_cht_mc_probe(struct platform_device *pdev)
348{ 352{
349 int ret_val = 0; 353 int ret_val = 0;
@@ -351,6 +355,9 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
351 struct cht_mc_private *drv; 355 struct cht_mc_private *drv;
352 struct snd_soc_card *card = snd_soc_cards[0].soc_card; 356 struct snd_soc_card *card = snd_soc_cards[0].soc_card;
353 char codec_name[16]; 357 char codec_name[16];
358 struct sst_acpi_mach *mach;
359 const char *i2c_name = NULL;
360 int dai_index = 0;
354 361
355 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); 362 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
356 if (!drv) 363 if (!drv)
@@ -366,12 +373,23 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
366 } 373 }
367 } 374 }
368 card->dev = &pdev->dev; 375 card->dev = &pdev->dev;
376 mach = card->dev->platform_data;
369 sprintf(codec_name, "i2c-%s:00", drv->acpi_card->codec_id); 377 sprintf(codec_name, "i2c-%s:00", drv->acpi_card->codec_id);
370 378
371 /* set correct codec name */ 379 /* set correct codec name */
372 for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) 380 for (i = 0; i < ARRAY_SIZE(cht_dailink); i++)
373 if (!strcmp(card->dai_link[i].codec_name, "i2c-10EC5645:00")) 381 if (!strcmp(card->dai_link[i].codec_name, "i2c-10EC5645:00")) {
374 card->dai_link[i].codec_name = kstrdup(codec_name, GFP_KERNEL); 382 card->dai_link[i].codec_name = kstrdup(codec_name, GFP_KERNEL);
383 dai_index = i;
384 }
385
386 /* fixup codec name based on HID */
387 i2c_name = sst_acpi_find_name_from_hid(mach->id);
388 if (i2c_name != NULL) {
389 snprintf(cht_rt5640_codec_name, sizeof(cht_rt5640_codec_name),
390 "%s%s", "i2c-", i2c_name);
391 cht_dailink[dai_index].codec_name = cht_rt5640_codec_name;
392 }
375 393
376 snd_soc_card_set_drvdata(card, drv); 394 snd_soc_card_set_drvdata(card, drv);
377 ret_val = devm_snd_soc_register_card(&pdev->dev, card); 395 ret_val = devm_snd_soc_register_card(&pdev->dev, card);
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index d2808652b974..25db5be7fdfa 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -23,12 +23,15 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include "../../codecs/nau8825.h" 24#include "../../codecs/nau8825.h"
25#include "../../codecs/hdac_hdmi.h" 25#include "../../codecs/hdac_hdmi.h"
26#include "../skylake/skl.h"
26 27
27#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" 28#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
28#define SKL_MAXIM_CODEC_DAI "HiFi" 29#define SKL_MAXIM_CODEC_DAI "HiFi"
30#define DMIC_CH(p) p->list[p->count-1]
29 31
30static struct snd_soc_jack skylake_headset; 32static struct snd_soc_jack skylake_headset;
31static struct snd_soc_card skylake_audio_card; 33static struct snd_soc_card skylake_audio_card;
34static const struct snd_pcm_hw_constraint_list *dmic_constraints;
32 35
33struct skl_hdmi_pcm { 36struct skl_hdmi_pcm {
34 struct list_head head; 37 struct list_head head;
@@ -339,7 +342,7 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
339 struct snd_interval *channels = hw_param_interval(params, 342 struct snd_interval *channels = hw_param_interval(params,
340 SNDRV_PCM_HW_PARAM_CHANNELS); 343 SNDRV_PCM_HW_PARAM_CHANNELS);
341 344
342 if (params_channels(params) == 2) 345 if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2)
343 channels->min = channels->max = 2; 346 channels->min = channels->max = 2;
344 else 347 else
345 channels->min = channels->max = 4; 348 channels->min = channels->max = 4;
@@ -357,13 +360,23 @@ static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
357 .mask = 0, 360 .mask = 0,
358}; 361};
359 362
363static const unsigned int dmic_2ch[] = {
364 2,
365};
366
367static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = {
368 .count = ARRAY_SIZE(dmic_2ch),
369 .list = dmic_2ch,
370 .mask = 0,
371};
372
360static int skylake_dmic_startup(struct snd_pcm_substream *substream) 373static int skylake_dmic_startup(struct snd_pcm_substream *substream)
361{ 374{
362 struct snd_pcm_runtime *runtime = substream->runtime; 375 struct snd_pcm_runtime *runtime = substream->runtime;
363 376
364 runtime->hw.channels_max = 4; 377 runtime->hw.channels_max = DMIC_CH(dmic_constraints);
365 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 378 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
366 &constraints_dmic_channels); 379 dmic_constraints);
367 380
368 return snd_pcm_hw_constraint_list(substream->runtime, 0, 381 return snd_pcm_hw_constraint_list(substream->runtime, 0,
369 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 382 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
@@ -382,8 +395,22 @@ static struct snd_pcm_hw_constraint_list constraints_16000 = {
382 .list = rates_16000, 395 .list = rates_16000,
383}; 396};
384 397
398static const unsigned int ch_mono[] = {
399 1,
400};
401
402static const struct snd_pcm_hw_constraint_list constraints_refcap = {
403 .count = ARRAY_SIZE(ch_mono),
404 .list = ch_mono,
405};
406
385static int skylake_refcap_startup(struct snd_pcm_substream *substream) 407static int skylake_refcap_startup(struct snd_pcm_substream *substream)
386{ 408{
409 substream->runtime->hw.channels_max = 1;
410 snd_pcm_hw_constraint_list(substream->runtime, 0,
411 SNDRV_PCM_HW_PARAM_CHANNELS,
412 &constraints_refcap);
413
387 return snd_pcm_hw_constraint_list(substream->runtime, 0, 414 return snd_pcm_hw_constraint_list(substream->runtime, 0,
388 SNDRV_PCM_HW_PARAM_RATE, 415 SNDRV_PCM_HW_PARAM_RATE,
389 &constraints_16000); 416 &constraints_16000);
@@ -610,6 +637,7 @@ static struct snd_soc_card skylake_audio_card = {
610static int skylake_audio_probe(struct platform_device *pdev) 637static int skylake_audio_probe(struct platform_device *pdev)
611{ 638{
612 struct skl_nau8825_private *ctx; 639 struct skl_nau8825_private *ctx;
640 struct skl_machine_pdata *pdata;
613 641
614 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 642 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
615 if (!ctx) 643 if (!ctx)
@@ -620,15 +648,27 @@ static int skylake_audio_probe(struct platform_device *pdev)
620 skylake_audio_card.dev = &pdev->dev; 648 skylake_audio_card.dev = &pdev->dev;
621 snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 649 snd_soc_card_set_drvdata(&skylake_audio_card, ctx);
622 650
651 pdata = dev_get_drvdata(&pdev->dev);
652 if (pdata)
653 dmic_constraints = pdata->dmic_num == 2 ?
654 &constraints_dmic_2ch : &constraints_dmic_channels;
655
623 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 656 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
624} 657}
625 658
659static const struct platform_device_id skl_board_ids[] = {
660 { .name = "skl_n88l25_m98357a" },
661 { .name = "kbl_n88l25_m98357a" },
662 { }
663};
664
626static struct platform_driver skylake_audio = { 665static struct platform_driver skylake_audio = {
627 .probe = skylake_audio_probe, 666 .probe = skylake_audio_probe,
628 .driver = { 667 .driver = {
629 .name = "skl_nau88l25_max98357a_i2s", 668 .name = "skl_n88l25_m98357a",
630 .pm = &snd_soc_pm_ops, 669 .pm = &snd_soc_pm_ops,
631 }, 670 },
671 .id_table = skl_board_ids,
632}; 672};
633 673
634module_platform_driver(skylake_audio) 674module_platform_driver(skylake_audio)
@@ -637,4 +677,5 @@ module_platform_driver(skylake_audio)
637MODULE_DESCRIPTION("Audio Machine driver-NAU88L25 & MAX98357A in I2S mode"); 677MODULE_DESCRIPTION("Audio Machine driver-NAU88L25 & MAX98357A in I2S mode");
638MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com"); 678MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com");
639MODULE_LICENSE("GPL v2"); 679MODULE_LICENSE("GPL v2");
640MODULE_ALIAS("platform:skl_nau88l25_max98357a_i2s"); 680MODULE_ALIAS("platform:skl_n88l25_m98357a");
681MODULE_ALIAS("platform:kbl_n88l25_m98357a");
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index e19aa99c4f72..69c5d5da4e86 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -27,12 +27,15 @@
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include "../../codecs/nau8825.h" 28#include "../../codecs/nau8825.h"
29#include "../../codecs/hdac_hdmi.h" 29#include "../../codecs/hdac_hdmi.h"
30#include "../skylake/skl.h"
30 31
31#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" 32#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
32#define SKL_SSM_CODEC_DAI "ssm4567-hifi" 33#define SKL_SSM_CODEC_DAI "ssm4567-hifi"
34#define DMIC_CH(p) p->list[p->count-1]
33 35
34static struct snd_soc_jack skylake_headset; 36static struct snd_soc_jack skylake_headset;
35static struct snd_soc_card skylake_audio_card; 37static struct snd_soc_card skylake_audio_card;
38static const struct snd_pcm_hw_constraint_list *dmic_constraints;
36 39
37struct skl_hdmi_pcm { 40struct skl_hdmi_pcm {
38 struct list_head head; 41 struct list_head head;
@@ -367,7 +370,7 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
367{ 370{
368 struct snd_interval *channels = hw_param_interval(params, 371 struct snd_interval *channels = hw_param_interval(params,
369 SNDRV_PCM_HW_PARAM_CHANNELS); 372 SNDRV_PCM_HW_PARAM_CHANNELS);
370 if (params_channels(params) == 2) 373 if (params_channels(params) == 2 || DMIC_CH(dmic_constraints) == 2)
371 channels->min = channels->max = 2; 374 channels->min = channels->max = 2;
372 else 375 else
373 channels->min = channels->max = 4; 376 channels->min = channels->max = 4;
@@ -405,13 +408,23 @@ static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
405 .mask = 0, 408 .mask = 0,
406}; 409};
407 410
411static const unsigned int dmic_2ch[] = {
412 2,
413};
414
415static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = {
416 .count = ARRAY_SIZE(dmic_2ch),
417 .list = dmic_2ch,
418 .mask = 0,
419};
420
408static int skylake_dmic_startup(struct snd_pcm_substream *substream) 421static int skylake_dmic_startup(struct snd_pcm_substream *substream)
409{ 422{
410 struct snd_pcm_runtime *runtime = substream->runtime; 423 struct snd_pcm_runtime *runtime = substream->runtime;
411 424
412 runtime->hw.channels_max = 4; 425 runtime->hw.channels_max = DMIC_CH(dmic_constraints);
413 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 426 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
414 &constraints_dmic_channels); 427 dmic_constraints);
415 428
416 return snd_pcm_hw_constraint_list(substream->runtime, 0, 429 return snd_pcm_hw_constraint_list(substream->runtime, 0,
417 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 430 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
@@ -430,8 +443,22 @@ static struct snd_pcm_hw_constraint_list constraints_16000 = {
430 .list = rates_16000, 443 .list = rates_16000,
431}; 444};
432 445
446static const unsigned int ch_mono[] = {
447 1,
448};
449
450static const struct snd_pcm_hw_constraint_list constraints_refcap = {
451 .count = ARRAY_SIZE(ch_mono),
452 .list = ch_mono,
453};
454
433static int skylake_refcap_startup(struct snd_pcm_substream *substream) 455static int skylake_refcap_startup(struct snd_pcm_substream *substream)
434{ 456{
457 substream->runtime->hw.channels_max = 1;
458 snd_pcm_hw_constraint_list(substream->runtime, 0,
459 SNDRV_PCM_HW_PARAM_CHANNELS,
460 &constraints_refcap);
461
435 return snd_pcm_hw_constraint_list(substream->runtime, 0, 462 return snd_pcm_hw_constraint_list(substream->runtime, 0,
436 SNDRV_PCM_HW_PARAM_RATE, 463 SNDRV_PCM_HW_PARAM_RATE,
437 &constraints_16000); 464 &constraints_16000);
@@ -662,6 +689,7 @@ static struct snd_soc_card skylake_audio_card = {
662static int skylake_audio_probe(struct platform_device *pdev) 689static int skylake_audio_probe(struct platform_device *pdev)
663{ 690{
664 struct skl_nau88125_private *ctx; 691 struct skl_nau88125_private *ctx;
692 struct skl_machine_pdata *pdata;
665 693
666 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 694 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
667 if (!ctx) 695 if (!ctx)
@@ -672,15 +700,27 @@ static int skylake_audio_probe(struct platform_device *pdev)
672 skylake_audio_card.dev = &pdev->dev; 700 skylake_audio_card.dev = &pdev->dev;
673 snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 701 snd_soc_card_set_drvdata(&skylake_audio_card, ctx);
674 702
703 pdata = dev_get_drvdata(&pdev->dev);
704 if (pdata)
705 dmic_constraints = pdata->dmic_num == 2 ?
706 &constraints_dmic_2ch : &constraints_dmic_channels;
707
675 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 708 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
676} 709}
677 710
711static const struct platform_device_id skl_board_ids[] = {
712 { .name = "skl_n88l25_s4567" },
713 { .name = "kbl_n88l25_s4567" },
714 { }
715};
716
678static struct platform_driver skylake_audio = { 717static struct platform_driver skylake_audio = {
679 .probe = skylake_audio_probe, 718 .probe = skylake_audio_probe,
680 .driver = { 719 .driver = {
681 .name = "skl_nau88l25_ssm4567_i2s", 720 .name = "skl_n88l25_s4567",
682 .pm = &snd_soc_pm_ops, 721 .pm = &snd_soc_pm_ops,
683 }, 722 },
723 .id_table = skl_board_ids,
684}; 724};
685 725
686module_platform_driver(skylake_audio) 726module_platform_driver(skylake_audio)
@@ -693,4 +733,5 @@ MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
693MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); 733MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>");
694MODULE_DESCRIPTION("Intel Audio Machine driver for SKL with NAU88L25 and SSM4567 in I2S Mode"); 734MODULE_DESCRIPTION("Intel Audio Machine driver for SKL with NAU88L25 and SSM4567 in I2S Mode");
695MODULE_LICENSE("GPL v2"); 735MODULE_LICENSE("GPL v2");
696MODULE_ALIAS("platform:skl_nau88l25_ssm4567_i2s"); 736MODULE_ALIAS("platform:skl_n88l25_s4567");
737MODULE_ALIAS("platform:kbl_n88l25_s4567");
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index 426b48233fdb..88c61e8cb87f 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -505,12 +505,20 @@ static int skylake_audio_probe(struct platform_device *pdev)
505 return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286); 505 return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286);
506} 506}
507 507
508static const struct platform_device_id skl_board_ids[] = {
509 { .name = "skl_alc286s_i2s" },
510 { .name = "kbl_alc286s_i2s" },
511 { }
512};
513
508static struct platform_driver skylake_audio = { 514static struct platform_driver skylake_audio = {
509 .probe = skylake_audio_probe, 515 .probe = skylake_audio_probe,
510 .driver = { 516 .driver = {
511 .name = "skl_alc286s_i2s", 517 .name = "skl_alc286s_i2s",
512 .pm = &snd_soc_pm_ops, 518 .pm = &snd_soc_pm_ops,
513 }, 519 },
520 .id_table = skl_board_ids,
521
514}; 522};
515 523
516module_platform_driver(skylake_audio) 524module_platform_driver(skylake_audio)
@@ -520,3 +528,4 @@ MODULE_AUTHOR("Omair Mohammed Abdullah <omair.m.abdullah@intel.com>");
520MODULE_DESCRIPTION("Intel SST Audio for Skylake"); 528MODULE_DESCRIPTION("Intel SST Audio for Skylake");
521MODULE_LICENSE("GPL v2"); 529MODULE_LICENSE("GPL v2");
522MODULE_ALIAS("platform:skl_alc286s_i2s"); 530MODULE_ALIAS("platform:skl_alc286s_i2s");
531MODULE_ALIAS("platform:kbl_alc286s_i2s");
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index fbbb25c2ceed..1a35149bcad7 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -2,9 +2,9 @@ snd-soc-sst-dsp-objs := sst-dsp.o
2snd-soc-sst-acpi-objs := sst-acpi.o 2snd-soc-sst-acpi-objs := sst-acpi.o
3snd-soc-sst-match-objs := sst-match-acpi.o 3snd-soc-sst-match-objs := sst-match-acpi.o
4snd-soc-sst-ipc-objs := sst-ipc.o 4snd-soc-sst-ipc-objs := sst-ipc.o
5 5snd-soc-sst-firmware-objs := sst-firmware.o
6snd-soc-sst-dsp-$(CONFIG_DW_DMAC_CORE) += sst-firmware.o
7 6
8obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o 7obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
9obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o 8obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
10obj-$(CONFIG_SND_SOC_INTEL_SST_MATCH) += snd-soc-sst-match.o 9obj-$(CONFIG_SND_SOC_INTEL_SST_MATCH) += snd-soc-sst-match.o
10obj-$(CONFIG_SND_SOC_INTEL_SST_FIRMWARE) += snd-soc-sst-firmware.o
diff --git a/sound/soc/intel/common/sst-acpi.h b/sound/soc/intel/common/sst-acpi.h
index 8398cb227ba9..5d2949324d0e 100644
--- a/sound/soc/intel/common/sst-acpi.h
+++ b/sound/soc/intel/common/sst-acpi.h
@@ -20,7 +20,7 @@
20#if IS_ENABLED(CONFIG_ACPI) 20#if IS_ENABLED(CONFIG_ACPI)
21const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]); 21const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]);
22#else 22#else
23inline const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) 23static inline const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
24{ 24{
25 return NULL; 25 return NULL;
26} 26}
@@ -40,6 +40,6 @@ struct sst_acpi_mach {
40 40
41 /* board name */ 41 /* board name */
42 const char *board; 42 const char *board;
43 void (*machine_quirk)(void); 43 struct sst_acpi_mach * (*machine_quirk)(void *arg);
44 void *pdata; 44 void *pdata;
45}; 45};
diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
index 97dc1ae05e69..d13c84364c3c 100644
--- a/sound/soc/intel/common/sst-dsp-priv.h
+++ b/sound/soc/intel/common/sst-dsp-priv.h
@@ -383,10 +383,6 @@ struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
383 u32 index, void *private); 383 u32 index, void *private);
384void sst_mem_block_unregister_all(struct sst_dsp *dsp); 384void sst_mem_block_unregister_all(struct sst_dsp *dsp);
385 385
386/* Create/Free DMA resources */
387int sst_dma_new(struct sst_dsp *sst);
388void sst_dma_free(struct sst_dma *dma);
389
390u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset, 386u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset,
391 enum sst_mem_type type); 387 enum sst_mem_type type);
392#endif 388#endif
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index b5bbdf4fe93a..c00ede4ea4d7 100644
--- a/sound/soc/intel/common/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
@@ -285,7 +285,7 @@ int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
285 } 285 }
286 286
287 reg = sst_dsp_shim_read_unlocked(ctx, offset); 287 reg = sst_dsp_shim_read_unlocked(ctx, offset);
288 dev_info(ctx->dev, "FW Poll Status: reg=%#x %s %s\n", reg, operation, 288 dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s %s\n", reg, operation,
289 (time < timeout) ? "successful" : "timedout"); 289 (time < timeout) ? "successful" : "timedout");
290 ret = time < timeout ? 0 : -ETIME; 290 ret = time < timeout ? 0 : -ETIME;
291 291
@@ -420,73 +420,6 @@ void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes)
420} 420}
421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read); 421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read);
422 422
423#ifdef CONFIG_DW_DMAC_CORE
424struct sst_dsp *sst_dsp_new(struct device *dev,
425 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata)
426{
427 struct sst_dsp *sst;
428 int err;
429
430 dev_dbg(dev, "initialising audio DSP id 0x%x\n", pdata->id);
431
432 sst = devm_kzalloc(dev, sizeof(*sst), GFP_KERNEL);
433 if (sst == NULL)
434 return NULL;
435
436 spin_lock_init(&sst->spinlock);
437 mutex_init(&sst->mutex);
438 sst->dev = dev;
439 sst->dma_dev = pdata->dma_dev;
440 sst->thread_context = sst_dev->thread_context;
441 sst->sst_dev = sst_dev;
442 sst->id = pdata->id;
443 sst->irq = pdata->irq;
444 sst->ops = sst_dev->ops;
445 sst->pdata = pdata;
446 INIT_LIST_HEAD(&sst->used_block_list);
447 INIT_LIST_HEAD(&sst->free_block_list);
448 INIT_LIST_HEAD(&sst->module_list);
449 INIT_LIST_HEAD(&sst->fw_list);
450 INIT_LIST_HEAD(&sst->scratch_block_list);
451
452 /* Initialise SST Audio DSP */
453 if (sst->ops->init) {
454 err = sst->ops->init(sst, pdata);
455 if (err < 0)
456 return NULL;
457 }
458
459 /* Register the ISR */
460 err = request_threaded_irq(sst->irq, sst->ops->irq_handler,
461 sst_dev->thread, IRQF_SHARED, "AudioDSP", sst);
462 if (err)
463 goto irq_err;
464
465 err = sst_dma_new(sst);
466 if (err)
467 dev_warn(dev, "sst_dma_new failed %d\n", err);
468
469 return sst;
470
471irq_err:
472 if (sst->ops->free)
473 sst->ops->free(sst);
474
475 return NULL;
476}
477EXPORT_SYMBOL_GPL(sst_dsp_new);
478
479void sst_dsp_free(struct sst_dsp *sst)
480{
481 free_irq(sst->irq, sst);
482 if (sst->ops->free)
483 sst->ops->free(sst);
484
485 sst_dma_free(sst->dma);
486}
487EXPORT_SYMBOL_GPL(sst_dsp_free);
488#endif
489
490/* Module information */ 423/* Module information */
491MODULE_AUTHOR("Liam Girdwood"); 424MODULE_AUTHOR("Liam Girdwood");
492MODULE_DESCRIPTION("Intel SST Core"); 425MODULE_DESCRIPTION("Intel SST Core");
diff --git a/sound/soc/intel/common/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h
index 0b84c719ec48..859f0de00339 100644
--- a/sound/soc/intel/common/sst-dsp.h
+++ b/sound/soc/intel/common/sst-dsp.h
@@ -216,7 +216,7 @@ struct sst_pdata {
216 void *dsp; 216 void *dsp;
217}; 217};
218 218
219#ifdef CONFIG_DW_DMAC_CORE 219#if IS_ENABLED(CONFIG_DW_DMAC_CORE)
220/* Initialization */ 220/* Initialization */
221struct sst_dsp *sst_dsp_new(struct device *dev, 221struct sst_dsp *sst_dsp_new(struct device *dev,
222 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata); 222 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata);
diff --git a/sound/soc/intel/common/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c
index 25993527370b..a086c35f91bb 100644
--- a/sound/soc/intel/common/sst-firmware.c
+++ b/sound/soc/intel/common/sst-firmware.c
@@ -1211,3 +1211,71 @@ u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset,
1211 } 1211 }
1212} 1212}
1213EXPORT_SYMBOL_GPL(sst_dsp_get_offset); 1213EXPORT_SYMBOL_GPL(sst_dsp_get_offset);
1214
1215struct sst_dsp *sst_dsp_new(struct device *dev,
1216 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata)
1217{
1218 struct sst_dsp *sst;
1219 int err;
1220
1221 dev_dbg(dev, "initialising audio DSP id 0x%x\n", pdata->id);
1222
1223 sst = devm_kzalloc(dev, sizeof(*sst), GFP_KERNEL);
1224 if (sst == NULL)
1225 return NULL;
1226
1227 spin_lock_init(&sst->spinlock);
1228 mutex_init(&sst->mutex);
1229 sst->dev = dev;
1230 sst->dma_dev = pdata->dma_dev;
1231 sst->thread_context = sst_dev->thread_context;
1232 sst->sst_dev = sst_dev;
1233 sst->id = pdata->id;
1234 sst->irq = pdata->irq;
1235 sst->ops = sst_dev->ops;
1236 sst->pdata = pdata;
1237 INIT_LIST_HEAD(&sst->used_block_list);
1238 INIT_LIST_HEAD(&sst->free_block_list);
1239 INIT_LIST_HEAD(&sst->module_list);
1240 INIT_LIST_HEAD(&sst->fw_list);
1241 INIT_LIST_HEAD(&sst->scratch_block_list);
1242
1243 /* Initialise SST Audio DSP */
1244 if (sst->ops->init) {
1245 err = sst->ops->init(sst, pdata);
1246 if (err < 0)
1247 return NULL;
1248 }
1249
1250 /* Register the ISR */
1251 err = request_threaded_irq(sst->irq, sst->ops->irq_handler,
1252 sst_dev->thread, IRQF_SHARED, "AudioDSP", sst);
1253 if (err)
1254 goto irq_err;
1255
1256 err = sst_dma_new(sst);
1257 if (err)
1258 dev_warn(dev, "sst_dma_new failed %d\n", err);
1259
1260 return sst;
1261
1262irq_err:
1263 if (sst->ops->free)
1264 sst->ops->free(sst);
1265
1266 return NULL;
1267}
1268EXPORT_SYMBOL_GPL(sst_dsp_new);
1269
1270void sst_dsp_free(struct sst_dsp *sst)
1271{
1272 free_irq(sst->irq, sst);
1273 if (sst->ops->free)
1274 sst->ops->free(sst);
1275
1276 sst_dma_free(sst->dma);
1277}
1278EXPORT_SYMBOL_GPL(sst_dsp_free);
1279
1280MODULE_DESCRIPTION("Intel SST Firmware Loader");
1281MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/haswell/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c
index 994256b39b9c..3154525c2b83 100644
--- a/sound/soc/intel/haswell/sst-haswell-pcm.c
+++ b/sound/soc/intel/haswell/sst-haswell-pcm.c
@@ -819,7 +819,6 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
819 mutex_lock(&pcm_data->mutex); 819 mutex_lock(&pcm_data->mutex);
820 pm_runtime_get_sync(pdata->dev); 820 pm_runtime_get_sync(pdata->dev);
821 821
822 snd_soc_pcm_set_drvdata(rtd, pcm_data);
823 pcm_data->substream = substream; 822 pcm_data->substream = substream;
824 823
825 snd_soc_set_runtime_hwparams(substream, &hsw_pcm_hardware); 824 snd_soc_set_runtime_hwparams(substream, &hsw_pcm_hardware);
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
index c28f5d0e1d99..60fbc9bbe473 100644
--- a/sound/soc/intel/skylake/Makefile
+++ b/sound/soc/intel/skylake/Makefile
@@ -5,6 +5,6 @@ obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o
5 5
6# Skylake IPC Support 6# Skylake IPC Support
7snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o skl-sst-cldma.o \ 7snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o skl-sst-cldma.o \
8 skl-sst.o bxt-sst.o 8 skl-sst.o bxt-sst.o skl-sst-utils.o
9 9
10obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o 10obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 8b95e09e23e8..2663781278aa 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -37,11 +37,19 @@
37 37
38#define BXT_ADSP_SRAM1_BASE 0xA0000 38#define BXT_ADSP_SRAM1_BASE 0xA0000
39 39
40#define BXT_INSTANCE_ID 0
41#define BXT_BASE_FW_MODULE_ID 0
42
40static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 43static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
41{ 44{
42 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); 45 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
43} 46}
44 47
48/*
49 * First boot sequence has some extra steps. Core 0 waits for power
50 * status on core 1, so power up core 1 also momentarily, keep it in
51 * reset/stall and then turn it off
52 */
45static int sst_bxt_prepare_fw(struct sst_dsp *ctx, 53static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
46 const void *fwdata, u32 fwsize) 54 const void *fwdata, u32 fwsize)
47{ 55{
@@ -49,7 +57,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
49 u32 reg; 57 u32 reg;
50 58
51 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab); 59 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab);
52 if (stream_tag < 0) { 60 if (stream_tag <= 0) {
53 dev_err(ctx->dev, "Failed to prepare DMA FW loading err: %x\n", 61 dev_err(ctx->dev, "Failed to prepare DMA FW loading err: %x\n",
54 stream_tag); 62 stream_tag);
55 return stream_tag; 63 return stream_tag;
@@ -58,17 +66,27 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
58 ctx->dsp_ops.stream_tag = stream_tag; 66 ctx->dsp_ops.stream_tag = stream_tag;
59 memcpy(ctx->dmab.area, fwdata, fwsize); 67 memcpy(ctx->dmab.area, fwdata, fwsize);
60 68
61 /* Purge FW request */ 69 /* Step 1: Power up core 0 and core1 */
70 ret = skl_dsp_core_power_up(ctx, SKL_DSP_CORE0_MASK |
71 SKL_DSP_CORE_MASK(1));
72 if (ret < 0) {
73 dev_err(ctx->dev, "dsp core0/1 power up failed\n");
74 goto base_fw_load_failed;
75 }
76
77 /* Step 2: Purge FW request */
62 sst_dsp_shim_write(ctx, SKL_ADSP_REG_HIPCI, SKL_ADSP_REG_HIPCI_BUSY | 78 sst_dsp_shim_write(ctx, SKL_ADSP_REG_HIPCI, SKL_ADSP_REG_HIPCI_BUSY |
63 BXT_IPC_PURGE_FW | (stream_tag - 1)); 79 (BXT_IPC_PURGE_FW | ((stream_tag - 1) << 9)));
64 80
65 ret = skl_dsp_enable_core(ctx); 81 /* Step 3: Unset core0 reset state & unstall/run core0 */
82 ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK);
66 if (ret < 0) { 83 if (ret < 0) {
67 dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret); 84 dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret);
68 ret = -EIO; 85 ret = -EIO;
69 goto base_fw_load_failed; 86 goto base_fw_load_failed;
70 } 87 }
71 88
89 /* Step 4: Wait for DONE Bit */
72 for (i = BXT_INIT_TIMEOUT; i > 0; --i) { 90 for (i = BXT_INIT_TIMEOUT; i > 0; --i) {
73 reg = sst_dsp_shim_read(ctx, SKL_ADSP_REG_HIPCIE); 91 reg = sst_dsp_shim_read(ctx, SKL_ADSP_REG_HIPCIE);
74 92
@@ -88,10 +106,18 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
88 SKL_ADSP_REG_HIPCIE_DONE); 106 SKL_ADSP_REG_HIPCIE_DONE);
89 } 107 }
90 108
91 /* enable Interrupt */ 109 /* Step 5: power down core1 */
110 ret = skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
111 if (ret < 0) {
112 dev_err(ctx->dev, "dsp core1 power down failed\n");
113 goto base_fw_load_failed;
114 }
115
116 /* Step 6: Enable Interrupt */
92 skl_ipc_int_enable(ctx); 117 skl_ipc_int_enable(ctx);
93 skl_ipc_op_int_enable(ctx); 118 skl_ipc_op_int_enable(ctx);
94 119
120 /* Step 7: Wait for ROM init */
95 for (i = BXT_INIT_TIMEOUT; i > 0; --i) { 121 for (i = BXT_INIT_TIMEOUT; i > 0; --i) {
96 if (SKL_FW_INIT == 122 if (SKL_FW_INIT ==
97 (sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS) & 123 (sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS) &
@@ -112,7 +138,8 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
112 138
113base_fw_load_failed: 139base_fw_load_failed:
114 ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag); 140 ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag);
115 skl_dsp_disable_core(ctx); 141 skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
142 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
116 return ret; 143 return ret;
117} 144}
118 145
@@ -130,23 +157,41 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
130 return ret; 157 return ret;
131} 158}
132 159
160#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
161
133static int bxt_load_base_firmware(struct sst_dsp *ctx) 162static int bxt_load_base_firmware(struct sst_dsp *ctx)
134{ 163{
135 const struct firmware *fw = NULL; 164 struct firmware stripped_fw;
136 struct skl_sst *skl = ctx->thread_context; 165 struct skl_sst *skl = ctx->thread_context;
137 int ret; 166 int ret;
138 167
139 ret = request_firmware(&fw, ctx->fw_name, ctx->dev); 168 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
140 if (ret < 0) { 169 if (ret < 0) {
141 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 170 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
142 goto sst_load_base_firmware_failed; 171 goto sst_load_base_firmware_failed;
143 } 172 }
144 173
145 ret = sst_bxt_prepare_fw(ctx, fw->data, fw->size); 174 /* check for extended manifest */
175 if (ctx->fw == NULL)
176 goto sst_load_base_firmware_failed;
177
178 ret = snd_skl_parse_uuids(ctx, BXT_ADSP_FW_BIN_HDR_OFFSET);
179 if (ret < 0)
180 goto sst_load_base_firmware_failed;
181
182 stripped_fw.data = ctx->fw->data;
183 stripped_fw.size = ctx->fw->size;
184 skl_dsp_strip_extended_manifest(&stripped_fw);
185
186 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
146 /* Retry Enabling core and ROM load. Retry seemed to help */ 187 /* Retry Enabling core and ROM load. Retry seemed to help */
147 if (ret < 0) { 188 if (ret < 0) {
148 ret = sst_bxt_prepare_fw(ctx, fw->data, fw->size); 189 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
149 if (ret < 0) { 190 if (ret < 0) {
191 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
192 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
193 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
194
150 dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret); 195 dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret);
151 goto sst_load_base_firmware_failed; 196 goto sst_load_base_firmware_failed;
152 } 197 }
@@ -159,83 +204,135 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
159 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), 204 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
160 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); 205 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
161 206
162 skl_dsp_disable_core(ctx); 207 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
163 } else { 208 } else {
164 dev_dbg(ctx->dev, "Firmware download successful\n"); 209 dev_dbg(ctx->dev, "Firmware download successful\n");
165 ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, 210 ret = wait_event_timeout(skl->boot_wait, skl->boot_complete,
166 msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); 211 msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
167 if (ret == 0) { 212 if (ret == 0) {
168 dev_err(ctx->dev, "DSP boot fail, FW Ready timeout\n"); 213 dev_err(ctx->dev, "DSP boot fail, FW Ready timeout\n");
169 skl_dsp_disable_core(ctx); 214 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
170 ret = -EIO; 215 ret = -EIO;
171 } else { 216 } else {
172 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING);
173 ret = 0; 217 ret = 0;
218 skl->fw_loaded = true;
174 } 219 }
175 } 220 }
176 221
177sst_load_base_firmware_failed: 222sst_load_base_firmware_failed:
178 release_firmware(fw); 223 release_firmware(ctx->fw);
179 return ret; 224 return ret;
180} 225}
181 226
182static int bxt_set_dsp_D0(struct sst_dsp *ctx) 227static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
183{ 228{
184 struct skl_sst *skl = ctx->thread_context; 229 struct skl_sst *skl = ctx->thread_context;
185 int ret; 230 int ret;
231 struct skl_ipc_dxstate_info dx;
232 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
186 233
187 skl->boot_complete = false; 234 if (skl->fw_loaded == false) {
188 235 skl->boot_complete = false;
189 ret = skl_dsp_enable_core(ctx); 236 ret = bxt_load_base_firmware(ctx);
190 if (ret < 0) { 237 if (ret < 0)
191 dev_err(ctx->dev, "enable dsp core failed ret: %d\n", ret); 238 dev_err(ctx->dev, "reload fw failed: %d\n", ret);
192 return ret; 239 return ret;
193 } 240 }
194 241
195 /* enable interrupt */ 242 /* If core 0 is being turned on, turn on core 1 as well */
196 skl_ipc_int_enable(ctx); 243 if (core_id == SKL_DSP_CORE0_ID)
197 skl_ipc_op_int_enable(ctx); 244 ret = skl_dsp_core_power_up(ctx, core_mask |
245 SKL_DSP_CORE_MASK(1));
246 else
247 ret = skl_dsp_core_power_up(ctx, core_mask);
248
249 if (ret < 0)
250 goto err;
251
252 if (core_id == SKL_DSP_CORE0_ID) {
253
254 /*
255 * Enable interrupt after SPA is set and before
256 * DSP is unstalled
257 */
258 skl_ipc_int_enable(ctx);
259 skl_ipc_op_int_enable(ctx);
260 skl->boot_complete = false;
261 }
198 262
199 ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, 263 ret = skl_dsp_start_core(ctx, core_mask);
200 msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); 264 if (ret < 0)
201 if (ret == 0) { 265 goto err;
202 dev_err(ctx->dev, "ipc: error DSP boot timeout\n"); 266
203 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n", 267 if (core_id == SKL_DSP_CORE0_ID) {
204 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), 268 ret = wait_event_timeout(skl->boot_wait,
205 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); 269 skl->boot_complete,
206 return -EIO; 270 msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
271
272 /* If core 1 was turned on for booting core 0, turn it off */
273 skl_dsp_core_power_down(ctx, SKL_DSP_CORE_MASK(1));
274 if (ret == 0) {
275 dev_err(ctx->dev, "%s: DSP boot timeout\n", __func__);
276 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
277 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
278 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
279 dev_err(ctx->dev, "Failed to set core0 to D0 state\n");
280 ret = -EIO;
281 goto err;
282 }
283 }
284
285 /* Tell FW if additional core in now On */
286
287 if (core_id != SKL_DSP_CORE0_ID) {
288 dx.core_mask = core_mask;
289 dx.dx_mask = core_mask;
290
291 ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID,
292 BXT_BASE_FW_MODULE_ID, &dx);
293 if (ret < 0) {
294 dev_err(ctx->dev, "IPC set_dx for core %d fail: %d\n",
295 core_id, ret);
296 goto err;
297 }
207 } 298 }
208 299
209 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); 300 skl->cores.state[core_id] = SKL_DSP_RUNNING;
210 return 0; 301 return 0;
302err:
303 if (core_id == SKL_DSP_CORE0_ID)
304 core_mask |= SKL_DSP_CORE_MASK(1);
305 skl_dsp_disable_core(ctx, core_mask);
306
307 return ret;
211} 308}
212 309
213static int bxt_set_dsp_D3(struct sst_dsp *ctx) 310static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
214{ 311{
312 int ret;
215 struct skl_ipc_dxstate_info dx; 313 struct skl_ipc_dxstate_info dx;
216 struct skl_sst *skl = ctx->thread_context; 314 struct skl_sst *skl = ctx->thread_context;
217 int ret = 0; 315 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
218 316
219 if (!is_skl_dsp_running(ctx)) 317 dx.core_mask = core_mask;
220 return ret;
221
222 dx.core_mask = SKL_DSP_CORE0_MASK;
223 dx.dx_mask = SKL_IPC_D3_MASK; 318 dx.dx_mask = SKL_IPC_D3_MASK;
224 319
225 ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, 320 dev_dbg(ctx->dev, "core mask=%x dx_mask=%x\n",
226 SKL_BASE_FW_MODULE_ID, &dx); 321 dx.core_mask, dx.dx_mask);
227 if (ret < 0) { 322
228 dev_err(ctx->dev, "Failed to set DSP to D3 state: %d\n", ret); 323 ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID,
229 return ret; 324 BXT_BASE_FW_MODULE_ID, &dx);
230 } 325 if (ret < 0)
326 dev_err(ctx->dev,
327 "Failed to set DSP to D3:core id = %d;Continue reset\n",
328 core_id);
231 329
232 ret = skl_dsp_disable_core(ctx); 330 ret = skl_dsp_disable_core(ctx, core_mask);
233 if (ret < 0) { 331 if (ret < 0) {
234 dev_err(ctx->dev, "disbale dsp core failed: %d\n", ret); 332 dev_err(ctx->dev, "Failed to disable core %d", ret);
235 ret = -EIO; 333 return ret;
236 } 334 }
237 335 skl->cores.state[core_id] = SKL_DSP_RESET;
238 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
239 return 0; 336 return 0;
240} 337}
241 338
@@ -274,6 +371,7 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
274 371
275 skl->dev = dev; 372 skl->dev = dev;
276 skl_dev.thread_context = skl; 373 skl_dev.thread_context = skl;
374 INIT_LIST_HEAD(&skl->uuid_list);
277 375
278 skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq); 376 skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq);
279 if (!skl->dsp) { 377 if (!skl->dsp) {
@@ -296,6 +394,7 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
296 if (ret) 394 if (ret)
297 return ret; 395 return ret;
298 396
397 skl->cores.count = 2;
299 skl->boot_complete = false; 398 skl->boot_complete = false;
300 init_waitqueue_head(&skl->boot_wait); 399 init_waitqueue_head(&skl->boot_wait);
301 400
@@ -305,6 +404,8 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
305 return ret; 404 return ret;
306 } 405 }
307 406
407 skl_dsp_init_core_state(sst);
408
308 if (dsp) 409 if (dsp)
309 *dsp = skl; 410 *dsp = skl;
310 411
@@ -315,6 +416,7 @@ EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
315 416
316void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 417void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
317{ 418{
419 skl_freeup_uuid_list(ctx);
318 skl_ipc_free(&ctx->ipc); 420 skl_ipc_free(&ctx->ipc);
319 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); 421 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
320 422
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 226db84ba20f..44ab595ce21a 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -206,6 +206,12 @@ static const struct skl_dsp_ops dsp_ops[] = {
206 .cleanup = skl_sst_dsp_cleanup 206 .cleanup = skl_sst_dsp_cleanup
207 }, 207 },
208 { 208 {
209 .id = 0x9d71,
210 .loader_ops = skl_get_loader_ops,
211 .init = skl_sst_dsp_init,
212 .cleanup = skl_sst_dsp_cleanup
213 },
214 {
209 .id = 0x5a98, 215 .id = 0x5a98,
210 .loader_ops = bxt_get_loader_ops, 216 .loader_ops = bxt_get_loader_ops,
211 .init = bxt_sst_dsp_init, 217 .init = bxt_sst_dsp_init,
@@ -730,7 +736,7 @@ static int skl_set_module_format(struct skl_sst *ctx,
730 736
731 dev_dbg(ctx->dev, "Module type=%d config size: %d bytes\n", 737 dev_dbg(ctx->dev, "Module type=%d config size: %d bytes\n",
732 module_config->id.module_id, param_size); 738 module_config->id.module_id, param_size);
733 print_hex_dump(KERN_DEBUG, "Module params:", DUMP_PREFIX_OFFSET, 8, 4, 739 print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4,
734 *param_data, param_size, false); 740 *param_data, param_size, false);
735 return 0; 741 return 0;
736} 742}
@@ -1046,7 +1052,7 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1046 1052
1047 dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1053 dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
1048 1054
1049 /* If pipe is not started, do not try to stop the pipe in FW. */ 1055 /* If pipe is started, do stop the pipe in FW. */
1050 if (pipe->state > SKL_PIPE_STARTED) { 1056 if (pipe->state > SKL_PIPE_STARTED) {
1051 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1057 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED);
1052 if (ret < 0) { 1058 if (ret < 0) {
@@ -1055,18 +1061,20 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1055 } 1061 }
1056 1062
1057 pipe->state = SKL_PIPE_PAUSED; 1063 pipe->state = SKL_PIPE_PAUSED;
1058 } else { 1064 }
1059 /* If pipe was not created in FW, do not try to delete it */
1060 if (pipe->state < SKL_PIPE_CREATED)
1061 return 0;
1062 1065
1063 ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id); 1066 /* If pipe was not created in FW, do not try to delete it */
1064 if (ret < 0) 1067 if (pipe->state < SKL_PIPE_CREATED)
1065 dev_err(ctx->dev, "Failed to delete pipeline\n"); 1068 return 0;
1066 1069
1067 pipe->state = SKL_PIPE_INVALID; 1070 ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id);
1071 if (ret < 0) {
1072 dev_err(ctx->dev, "Failed to delete pipeline\n");
1073 return ret;
1068 } 1074 }
1069 1075
1076 pipe->state = SKL_PIPE_INVALID;
1077
1070 return ret; 1078 return ret;
1071} 1079}
1072 1080
@@ -1125,7 +1133,30 @@ int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1125 return ret; 1133 return ret;
1126 } 1134 }
1127 1135
1128 pipe->state = SKL_PIPE_CREATED; 1136 pipe->state = SKL_PIPE_PAUSED;
1137
1138 return 0;
1139}
1140
1141/*
1142 * Reset the pipeline by sending set pipe state IPC this will reset the DMA
1143 * from the DSP side
1144 */
1145int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1146{
1147 int ret;
1148
1149 /* If pipe was not created in FW, do not try to pause or delete */
1150 if (pipe->state < SKL_PIPE_PAUSED)
1151 return 0;
1152
1153 ret = skl_set_pipe_state(ctx, pipe, PPL_RESET);
1154 if (ret < 0) {
1155 dev_dbg(ctx->dev, "Failed to reset pipe ret=%d\n", ret);
1156 return ret;
1157 }
1158
1159 pipe->state = SKL_PIPE_RESET;
1129 1160
1130 return 0; 1161 return 0;
1131} 1162}
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 7d73648e5f9a..3f8e6f0b7eb5 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -17,6 +17,7 @@
17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 * 18 *
19 */ 19 */
20#include <linux/pci.h>
20#include "skl.h" 21#include "skl.h"
21 22
22/* Unique identification for getting NHLT blobs */ 23/* Unique identification for getting NHLT blobs */
@@ -149,6 +150,45 @@ struct nhlt_specific_cfg
149 return NULL; 150 return NULL;
150} 151}
151 152
153int skl_get_dmic_geo(struct skl *skl)
154{
155 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
156 struct nhlt_endpoint *epnt;
157 struct nhlt_dmic_array_config *cfg;
158 struct device *dev = &skl->pci->dev;
159 unsigned int dmic_geo = 0;
160 u8 j;
161
162 epnt = (struct nhlt_endpoint *)nhlt->desc;
163
164 for (j = 0; j < nhlt->endpoint_count; j++) {
165 if (epnt->linktype == NHLT_LINK_DMIC) {
166 cfg = (struct nhlt_dmic_array_config *)
167 (epnt->config.caps);
168 switch (cfg->array_type) {
169 case NHLT_MIC_ARRAY_2CH_SMALL:
170 case NHLT_MIC_ARRAY_2CH_BIG:
171 dmic_geo |= MIC_ARRAY_2CH;
172 break;
173
174 case NHLT_MIC_ARRAY_4CH_1ST_GEOM:
175 case NHLT_MIC_ARRAY_4CH_L_SHAPED:
176 case NHLT_MIC_ARRAY_4CH_2ND_GEOM:
177 dmic_geo |= MIC_ARRAY_4CH;
178 break;
179
180 default:
181 dev_warn(dev, "undefined DMIC array_type 0x%0x\n",
182 cfg->array_type);
183
184 }
185 }
186 epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
187 }
188
189 return dmic_geo;
190}
191
152static void skl_nhlt_trim_space(struct skl *skl) 192static void skl_nhlt_trim_space(struct skl *skl)
153{ 193{
154 char *s = skl->tplg_name; 194 char *s = skl->tplg_name;
diff --git a/sound/soc/intel/skylake/skl-nhlt.h b/sound/soc/intel/skylake/skl-nhlt.h
index 3769f9fefe2b..116534e7b3c5 100644
--- a/sound/soc/intel/skylake/skl-nhlt.h
+++ b/sound/soc/intel/skylake/skl-nhlt.h
@@ -103,4 +103,26 @@ struct nhlt_resource_desc {
103 u64 length; 103 u64 length;
104} __packed; 104} __packed;
105 105
106#define MIC_ARRAY_2CH 2
107#define MIC_ARRAY_4CH 4
108
109struct nhlt_tdm_config {
110 u8 virtual_slot;
111 u8 config_type;
112} __packed;
113
114struct nhlt_dmic_array_config {
115 struct nhlt_tdm_config tdm_config;
116 u8 array_type;
117} __packed;
118
119enum {
120 NHLT_MIC_ARRAY_2CH_SMALL = 0xa,
121 NHLT_MIC_ARRAY_2CH_BIG = 0xb,
122 NHLT_MIC_ARRAY_4CH_1ST_GEOM = 0xc,
123 NHLT_MIC_ARRAY_4CH_L_SHAPED = 0xd,
124 NHLT_MIC_ARRAY_4CH_2ND_GEOM = 0xe,
125 NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf,
126};
127
106#endif 128#endif
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 7c81b31748ff..6e05bf8622f7 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -227,16 +227,25 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream,
227 struct snd_soc_dai *dai) 227 struct snd_soc_dai *dai)
228{ 228{
229 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 229 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
230 struct skl *skl = get_skl_ctx(dai->dev);
230 unsigned int format_val; 231 unsigned int format_val;
231 int err; 232 int err;
233 struct skl_module_cfg *mconfig;
232 234
233 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 235 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
234 236
237 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
238
235 format_val = skl_get_format(substream, dai); 239 format_val = skl_get_format(substream, dai);
236 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d\n", 240 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d\n",
237 hdac_stream(stream)->stream_tag, format_val); 241 hdac_stream(stream)->stream_tag, format_val);
238 snd_hdac_stream_reset(hdac_stream(stream)); 242 snd_hdac_stream_reset(hdac_stream(stream));
239 243
244 /* In case of XRUN recovery, reset the FW pipe to clean state */
245 if (mconfig && (substream->runtime->status->state ==
246 SNDRV_PCM_STATE_XRUN))
247 skl_reset_pipe(skl->skl_sst, mconfig->pipe);
248
240 err = snd_hdac_stream_set_params(hdac_stream(stream), format_val); 249 err = snd_hdac_stream_set_params(hdac_stream(stream), format_val);
241 if (err < 0) 250 if (err < 0)
242 return err; 251 return err;
@@ -521,6 +530,8 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
521 struct skl_dma_params *dma_params; 530 struct skl_dma_params *dma_params;
522 struct snd_soc_dai *codec_dai = rtd->codec_dai; 531 struct snd_soc_dai *codec_dai = rtd->codec_dai;
523 struct hdac_ext_link *link; 532 struct hdac_ext_link *link;
533 struct skl *skl = get_skl_ctx(dai->dev);
534 struct skl_module_cfg *mconfig = NULL;
524 535
525 dma_params = (struct skl_dma_params *) 536 dma_params = (struct skl_dma_params *)
526 snd_soc_dai_get_dma_data(codec_dai, substream); 537 snd_soc_dai_get_dma_data(codec_dai, substream);
@@ -535,6 +546,12 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
535 546
536 snd_hdac_ext_link_stream_reset(link_dev); 547 snd_hdac_ext_link_stream_reset(link_dev);
537 548
549 /* In case of XRUN recovery, reset the FW pipe to clean state */
550 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
551 if (mconfig && (substream->runtime->status->state ==
552 SNDRV_PCM_STATE_XRUN))
553 skl_reset_pipe(skl->skl_sst, mconfig->pipe);
554
538 snd_hdac_ext_link_stream_setup(link_dev, format_val); 555 snd_hdac_ext_link_stream_setup(link_dev, format_val);
539 556
540 snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_dev)->stream_tag); 557 snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_dev)->stream_tag);
@@ -1009,51 +1026,11 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
1009 return 0; 1026 return 0;
1010} 1027}
1011 1028
1012/* calculate runtime delay from LPIB */ 1029static snd_pcm_uframes_t skl_platform_pcm_pointer
1013static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus, 1030 (struct snd_pcm_substream *substream)
1014 struct hdac_ext_stream *sstream,
1015 unsigned int pos)
1016{
1017 struct hdac_bus *bus = ebus_to_hbus(ebus);
1018 struct hdac_stream *hstream = hdac_stream(sstream);
1019 struct snd_pcm_substream *substream = hstream->substream;
1020 int stream = substream->stream;
1021 unsigned int lpib_pos = snd_hdac_stream_get_pos_lpib(hstream);
1022 int delay;
1023
1024 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1025 delay = pos - lpib_pos;
1026 else
1027 delay = lpib_pos - pos;
1028
1029 if (delay < 0) {
1030 if (delay >= hstream->delay_negative_threshold)
1031 delay = 0;
1032 else
1033 delay += hstream->bufsize;
1034 }
1035
1036 if (hstream->bufsize == delay)
1037 delay = 0;
1038
1039 if (delay >= hstream->period_bytes) {
1040 dev_info(bus->dev,
1041 "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
1042 delay, hstream->period_bytes);
1043 delay = 0;
1044 }
1045
1046 return bytes_to_frames(substream->runtime, delay);
1047}
1048
1049static unsigned int skl_get_position(struct hdac_ext_stream *hstream,
1050 int codec_delay)
1051{ 1031{
1052 struct hdac_stream *hstr = hdac_stream(hstream); 1032 struct hdac_ext_stream *hstream = get_hdac_ext_stream(substream);
1053 struct snd_pcm_substream *substream = hstr->substream;
1054 struct hdac_ext_bus *ebus;
1055 unsigned int pos; 1033 unsigned int pos;
1056 int delay;
1057 1034
1058 /* use the position buffer as default */ 1035 /* use the position buffer as default */
1059 pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream)); 1036 pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream));
@@ -1061,23 +1038,7 @@ static unsigned int skl_get_position(struct hdac_ext_stream *hstream,
1061 if (pos >= hdac_stream(hstream)->bufsize) 1038 if (pos >= hdac_stream(hstream)->bufsize)
1062 pos = 0; 1039 pos = 0;
1063 1040
1064 if (substream->runtime) { 1041 return bytes_to_frames(substream->runtime, pos);
1065 ebus = get_bus_ctx(substream);
1066 delay = skl_get_delay_from_lpib(ebus, hstream, pos)
1067 + codec_delay;
1068 substream->runtime->delay += delay;
1069 }
1070
1071 return pos;
1072}
1073
1074static snd_pcm_uframes_t skl_platform_pcm_pointer
1075 (struct snd_pcm_substream *substream)
1076{
1077 struct hdac_ext_stream *hstream = get_hdac_ext_stream(substream);
1078
1079 return bytes_to_frames(substream->runtime,
1080 skl_get_position(hstream, 0));
1081} 1042}
1082 1043
1083static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream, 1044static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream,
@@ -1180,9 +1141,17 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1180static int skl_platform_soc_probe(struct snd_soc_platform *platform) 1141static int skl_platform_soc_probe(struct snd_soc_platform *platform)
1181{ 1142{
1182 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); 1143 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
1144 struct skl *skl = ebus_to_skl(ebus);
1145 int ret;
1183 1146
1184 if (ebus->ppcap) 1147 if (ebus->ppcap) {
1185 return skl_tplg_init(platform, ebus); 1148 ret = skl_tplg_init(platform, ebus);
1149 if (ret < 0) {
1150 dev_err(platform->dev, "Failed to init topology!\n");
1151 return ret;
1152 }
1153 skl->platform = platform;
1154 }
1186 1155
1187 return 0; 1156 return 0;
1188} 1157}
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
index 13c19855ee1a..c3deefab65d6 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ b/sound/soc/intel/skylake/skl-sst-dsp.c
@@ -34,33 +34,84 @@ void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state)
34 mutex_unlock(&ctx->mutex); 34 mutex_unlock(&ctx->mutex);
35} 35}
36 36
37static int skl_dsp_core_set_reset_state(struct sst_dsp *ctx) 37/*
38 * Initialize core power state and usage count. To be called after
39 * successful first boot. Hence core 0 will be running and other cores
40 * will be reset
41 */
42void skl_dsp_init_core_state(struct sst_dsp *ctx)
43{
44 struct skl_sst *skl = ctx->thread_context;
45 int i;
46
47 skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING;
48 skl->cores.usage_count[SKL_DSP_CORE0_ID] = 1;
49
50 for (i = SKL_DSP_CORE0_ID + 1; i < SKL_DSP_CORES_MAX; i++) {
51 skl->cores.state[i] = SKL_DSP_RESET;
52 skl->cores.usage_count[i] = 0;
53 }
54}
55
56/* Get the mask for all enabled cores */
57unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx)
58{
59 struct skl_sst *skl = ctx->thread_context;
60 unsigned int core_mask, en_cores_mask;
61 u32 val;
62
63 core_mask = SKL_DSP_CORES_MASK(skl->cores.count);
64
65 val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS);
66
67 /* Cores having CPA bit set */
68 en_cores_mask = (val & SKL_ADSPCS_CPA_MASK(core_mask)) >>
69 SKL_ADSPCS_CPA_SHIFT;
70
71 /* And cores having CRST bit cleared */
72 en_cores_mask &= (~val & SKL_ADSPCS_CRST_MASK(core_mask)) >>
73 SKL_ADSPCS_CRST_SHIFT;
74
75 /* And cores having CSTALL bit cleared */
76 en_cores_mask &= (~val & SKL_ADSPCS_CSTALL_MASK(core_mask)) >>
77 SKL_ADSPCS_CSTALL_SHIFT;
78 en_cores_mask &= core_mask;
79
80 dev_dbg(ctx->dev, "DSP enabled cores mask = %x\n", en_cores_mask);
81
82 return en_cores_mask;
83}
84
85static int
86skl_dsp_core_set_reset_state(struct sst_dsp *ctx, unsigned int core_mask)
38{ 87{
39 int ret; 88 int ret;
40 89
41 /* update bits */ 90 /* update bits */
42 sst_dsp_shim_update_bits_unlocked(ctx, 91 sst_dsp_shim_update_bits_unlocked(ctx,
43 SKL_ADSP_REG_ADSPCS, SKL_ADSPCS_CRST_MASK, 92 SKL_ADSP_REG_ADSPCS, SKL_ADSPCS_CRST_MASK(core_mask),
44 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)); 93 SKL_ADSPCS_CRST_MASK(core_mask));
45 94
46 /* poll with timeout to check if operation successful */ 95 /* poll with timeout to check if operation successful */
47 ret = sst_dsp_register_poll(ctx, 96 ret = sst_dsp_register_poll(ctx,
48 SKL_ADSP_REG_ADSPCS, 97 SKL_ADSP_REG_ADSPCS,
49 SKL_ADSPCS_CRST_MASK, 98 SKL_ADSPCS_CRST_MASK(core_mask),
50 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK), 99 SKL_ADSPCS_CRST_MASK(core_mask),
51 SKL_DSP_RESET_TO, 100 SKL_DSP_RESET_TO,
52 "Set reset"); 101 "Set reset");
53 if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & 102 if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
54 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) != 103 SKL_ADSPCS_CRST_MASK(core_mask)) !=
55 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) { 104 SKL_ADSPCS_CRST_MASK(core_mask)) {
56 dev_err(ctx->dev, "Set reset state failed\n"); 105 dev_err(ctx->dev, "Set reset state failed: core_mask %x\n",
106 core_mask);
57 ret = -EIO; 107 ret = -EIO;
58 } 108 }
59 109
60 return ret; 110 return ret;
61} 111}
62 112
63static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx) 113int skl_dsp_core_unset_reset_state(
114 struct sst_dsp *ctx, unsigned int core_mask)
64{ 115{
65 int ret; 116 int ret;
66 117
@@ -68,152 +119,160 @@ static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx)
68 119
69 /* update bits */ 120 /* update bits */
70 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, 121 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
71 SKL_ADSPCS_CRST_MASK, 0); 122 SKL_ADSPCS_CRST_MASK(core_mask), 0);
72 123
73 /* poll with timeout to check if operation successful */ 124 /* poll with timeout to check if operation successful */
74 ret = sst_dsp_register_poll(ctx, 125 ret = sst_dsp_register_poll(ctx,
75 SKL_ADSP_REG_ADSPCS, 126 SKL_ADSP_REG_ADSPCS,
76 SKL_ADSPCS_CRST_MASK, 127 SKL_ADSPCS_CRST_MASK(core_mask),
77 0, 128 0,
78 SKL_DSP_RESET_TO, 129 SKL_DSP_RESET_TO,
79 "Unset reset"); 130 "Unset reset");
80 131
81 if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & 132 if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
82 SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) != 0) { 133 SKL_ADSPCS_CRST_MASK(core_mask)) != 0) {
83 dev_err(ctx->dev, "Unset reset state failed\n"); 134 dev_err(ctx->dev, "Unset reset state failed: core_mask %x\n",
135 core_mask);
84 ret = -EIO; 136 ret = -EIO;
85 } 137 }
86 138
87 return ret; 139 return ret;
88} 140}
89 141
90static bool is_skl_dsp_core_enable(struct sst_dsp *ctx) 142static bool
143is_skl_dsp_core_enable(struct sst_dsp *ctx, unsigned int core_mask)
91{ 144{
92 int val; 145 int val;
93 bool is_enable; 146 bool is_enable;
94 147
95 val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS); 148 val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS);
96 149
97 is_enable = ((val & SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) && 150 is_enable = ((val & SKL_ADSPCS_CPA_MASK(core_mask)) &&
98 (val & SKL_ADSPCS_SPA(SKL_DSP_CORES_MASK)) && 151 (val & SKL_ADSPCS_SPA_MASK(core_mask)) &&
99 !(val & SKL_ADSPCS_CRST(SKL_DSP_CORES_MASK)) && 152 !(val & SKL_ADSPCS_CRST_MASK(core_mask)) &&
100 !(val & SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK))); 153 !(val & SKL_ADSPCS_CSTALL_MASK(core_mask)));
154
155 dev_dbg(ctx->dev, "DSP core(s) enabled? %d : core_mask %x\n",
156 is_enable, core_mask);
101 157
102 dev_dbg(ctx->dev, "DSP core is enabled=%d\n", is_enable);
103 return is_enable; 158 return is_enable;
104} 159}
105 160
106static int skl_dsp_reset_core(struct sst_dsp *ctx) 161static int skl_dsp_reset_core(struct sst_dsp *ctx, unsigned int core_mask)
107{ 162{
108 /* stall core */ 163 /* stall core */
109 sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_ADSPCS, 164 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
110 sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & 165 SKL_ADSPCS_CSTALL_MASK(core_mask),
111 SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK)); 166 SKL_ADSPCS_CSTALL_MASK(core_mask));
112 167
113 /* set reset state */ 168 /* set reset state */
114 return skl_dsp_core_set_reset_state(ctx); 169 return skl_dsp_core_set_reset_state(ctx, core_mask);
115} 170}
116 171
117static int skl_dsp_start_core(struct sst_dsp *ctx) 172int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask)
118{ 173{
119 int ret; 174 int ret;
120 175
121 /* unset reset state */ 176 /* unset reset state */
122 ret = skl_dsp_core_unset_reset_state(ctx); 177 ret = skl_dsp_core_unset_reset_state(ctx, core_mask);
123 if (ret < 0) { 178 if (ret < 0)
124 dev_dbg(ctx->dev, "dsp unset reset fails\n");
125 return ret; 179 return ret;
126 }
127 180
128 /* run core */ 181 /* run core */
129 dev_dbg(ctx->dev, "run core...\n"); 182 dev_dbg(ctx->dev, "unstall/run core: core_mask = %x\n", core_mask);
130 sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_ADSPCS, 183 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
131 sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & 184 SKL_ADSPCS_CSTALL_MASK(core_mask), 0);
132 ~SKL_ADSPCS_CSTALL(SKL_DSP_CORES_MASK)); 185
133 186 if (!is_skl_dsp_core_enable(ctx, core_mask)) {
134 if (!is_skl_dsp_core_enable(ctx)) { 187 skl_dsp_reset_core(ctx, core_mask);
135 skl_dsp_reset_core(ctx); 188 dev_err(ctx->dev, "DSP start core failed: core_mask %x\n",
136 dev_err(ctx->dev, "DSP core enable failed\n"); 189 core_mask);
137 ret = -EIO; 190 ret = -EIO;
138 } 191 }
139 192
140 return ret; 193 return ret;
141} 194}
142 195
143static int skl_dsp_core_power_up(struct sst_dsp *ctx) 196int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask)
144{ 197{
145 int ret; 198 int ret;
146 199
147 /* update bits */ 200 /* update bits */
148 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, 201 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
149 SKL_ADSPCS_SPA_MASK, SKL_ADSPCS_SPA(SKL_DSP_CORES_MASK)); 202 SKL_ADSPCS_SPA_MASK(core_mask),
203 SKL_ADSPCS_SPA_MASK(core_mask));
150 204
151 /* poll with timeout to check if operation successful */ 205 /* poll with timeout to check if operation successful */
152 ret = sst_dsp_register_poll(ctx, 206 ret = sst_dsp_register_poll(ctx,
153 SKL_ADSP_REG_ADSPCS, 207 SKL_ADSP_REG_ADSPCS,
154 SKL_ADSPCS_CPA_MASK, 208 SKL_ADSPCS_CPA_MASK(core_mask),
155 SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK), 209 SKL_ADSPCS_CPA_MASK(core_mask),
156 SKL_DSP_PU_TO, 210 SKL_DSP_PU_TO,
157 "Power up"); 211 "Power up");
158 212
159 if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) & 213 if ((sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPCS) &
160 SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) != 214 SKL_ADSPCS_CPA_MASK(core_mask)) !=
161 SKL_ADSPCS_CPA(SKL_DSP_CORES_MASK)) { 215 SKL_ADSPCS_CPA_MASK(core_mask)) {
162 dev_err(ctx->dev, "DSP core power up failed\n"); 216 dev_err(ctx->dev, "DSP core power up failed: core_mask %x\n",
217 core_mask);
163 ret = -EIO; 218 ret = -EIO;
164 } 219 }
165 220
166 return ret; 221 return ret;
167} 222}
168 223
169static int skl_dsp_core_power_down(struct sst_dsp *ctx) 224int skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask)
170{ 225{
171 /* update bits */ 226 /* update bits */
172 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS, 227 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
173 SKL_ADSPCS_SPA_MASK, 0); 228 SKL_ADSPCS_SPA_MASK(core_mask), 0);
174 229
175 /* poll with timeout to check if operation successful */ 230 /* poll with timeout to check if operation successful */
176 return sst_dsp_register_poll(ctx, 231 return sst_dsp_register_poll(ctx,
177 SKL_ADSP_REG_ADSPCS, 232 SKL_ADSP_REG_ADSPCS,
178 SKL_ADSPCS_CPA_MASK, 233 SKL_ADSPCS_CPA_MASK(core_mask),
179 0, 234 0,
180 SKL_DSP_PD_TO, 235 SKL_DSP_PD_TO,
181 "Power down"); 236 "Power down");
182} 237}
183 238
184int skl_dsp_enable_core(struct sst_dsp *ctx) 239int skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask)
185{ 240{
186 int ret; 241 int ret;
187 242
188 /* power up */ 243 /* power up */
189 ret = skl_dsp_core_power_up(ctx); 244 ret = skl_dsp_core_power_up(ctx, core_mask);
190 if (ret < 0) { 245 if (ret < 0) {
191 dev_dbg(ctx->dev, "dsp core power up failed\n"); 246 dev_err(ctx->dev, "dsp core power up failed: core_mask %x\n",
247 core_mask);
192 return ret; 248 return ret;
193 } 249 }
194 250
195 return skl_dsp_start_core(ctx); 251 return skl_dsp_start_core(ctx, core_mask);
196} 252}
197 253
198int skl_dsp_disable_core(struct sst_dsp *ctx) 254int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask)
199{ 255{
200 int ret; 256 int ret;
201 257
202 ret = skl_dsp_reset_core(ctx); 258 ret = skl_dsp_reset_core(ctx, core_mask);
203 if (ret < 0) { 259 if (ret < 0) {
204 dev_err(ctx->dev, "dsp core reset failed\n"); 260 dev_err(ctx->dev, "dsp core reset failed: core_mask %x\n",
261 core_mask);
205 return ret; 262 return ret;
206 } 263 }
207 264
208 /* power down core*/ 265 /* power down core*/
209 ret = skl_dsp_core_power_down(ctx); 266 ret = skl_dsp_core_power_down(ctx, core_mask);
210 if (ret < 0) { 267 if (ret < 0) {
211 dev_err(ctx->dev, "dsp core power down failed\n"); 268 dev_err(ctx->dev, "dsp core power down fail mask %x: %d\n",
269 core_mask, ret);
212 return ret; 270 return ret;
213 } 271 }
214 272
215 if (is_skl_dsp_core_enable(ctx)) { 273 if (is_skl_dsp_core_enable(ctx, core_mask)) {
216 dev_err(ctx->dev, "DSP core disable failed\n"); 274 dev_err(ctx->dev, "dsp core disable fail mask %x: %d\n",
275 core_mask, ret);
217 ret = -EIO; 276 ret = -EIO;
218 } 277 }
219 278
@@ -224,28 +283,25 @@ int skl_dsp_boot(struct sst_dsp *ctx)
224{ 283{
225 int ret; 284 int ret;
226 285
227 if (is_skl_dsp_core_enable(ctx)) { 286 if (is_skl_dsp_core_enable(ctx, SKL_DSP_CORE0_MASK)) {
228 dev_dbg(ctx->dev, "dsp core is already enabled, so reset the dap core\n"); 287 ret = skl_dsp_reset_core(ctx, SKL_DSP_CORE0_MASK);
229 ret = skl_dsp_reset_core(ctx);
230 if (ret < 0) { 288 if (ret < 0) {
231 dev_err(ctx->dev, "dsp reset failed\n"); 289 dev_err(ctx->dev, "dsp core0 reset fail: %d\n", ret);
232 return ret; 290 return ret;
233 } 291 }
234 292
235 ret = skl_dsp_start_core(ctx); 293 ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK);
236 if (ret < 0) { 294 if (ret < 0) {
237 dev_err(ctx->dev, "dsp start failed\n"); 295 dev_err(ctx->dev, "dsp core0 start fail: %d\n", ret);
238 return ret; 296 return ret;
239 } 297 }
240 } else { 298 } else {
241 dev_dbg(ctx->dev, "disable and enable to make sure DSP is invalid state\n"); 299 ret = skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
242 ret = skl_dsp_disable_core(ctx);
243
244 if (ret < 0) { 300 if (ret < 0) {
245 dev_err(ctx->dev, "dsp disable core failes\n"); 301 dev_err(ctx->dev, "dsp core0 disable fail: %d\n", ret);
246 return ret; 302 return ret;
247 } 303 }
248 ret = skl_dsp_enable_core(ctx); 304 ret = skl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK);
249 } 305 }
250 306
251 return ret; 307 return ret;
@@ -281,16 +337,74 @@ irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id)
281 337
282 return result; 338 return result;
283} 339}
340/*
341 * skl_dsp_get_core/skl_dsp_put_core will be called inside DAPM context
342 * within the dapm mutex. Hence no separate lock is used.
343 */
344int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
345{
346 struct skl_sst *skl = ctx->thread_context;
347 int ret = 0;
348
349 if (core_id >= skl->cores.count) {
350 dev_err(ctx->dev, "invalid core id: %d\n", core_id);
351 return -EINVAL;
352 }
353
354 if (skl->cores.state[core_id] == SKL_DSP_RESET) {
355 ret = ctx->fw_ops.set_state_D0(ctx, core_id);
356 if (ret < 0) {
357 dev_err(ctx->dev, "unable to get core%d\n", core_id);
358 return ret;
359 }
360 }
361
362 skl->cores.usage_count[core_id]++;
363
364 dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
365 core_id, skl->cores.state[core_id],
366 skl->cores.usage_count[core_id]);
367
368 return ret;
369}
370EXPORT_SYMBOL_GPL(skl_dsp_get_core);
371
372int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id)
373{
374 struct skl_sst *skl = ctx->thread_context;
375 int ret = 0;
376
377 if (core_id >= skl->cores.count) {
378 dev_err(ctx->dev, "invalid core id: %d\n", core_id);
379 return -EINVAL;
380 }
381
382 if (--skl->cores.usage_count[core_id] == 0) {
383 ret = ctx->fw_ops.set_state_D3(ctx, core_id);
384 if (ret < 0) {
385 dev_err(ctx->dev, "unable to put core %d: %d\n",
386 core_id, ret);
387 skl->cores.usage_count[core_id]++;
388 }
389 }
390
391 dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
392 core_id, skl->cores.state[core_id],
393 skl->cores.usage_count[core_id]);
394
395 return ret;
396}
397EXPORT_SYMBOL_GPL(skl_dsp_put_core);
284 398
285int skl_dsp_wake(struct sst_dsp *ctx) 399int skl_dsp_wake(struct sst_dsp *ctx)
286{ 400{
287 return ctx->fw_ops.set_state_D0(ctx); 401 return skl_dsp_get_core(ctx, SKL_DSP_CORE0_ID);
288} 402}
289EXPORT_SYMBOL_GPL(skl_dsp_wake); 403EXPORT_SYMBOL_GPL(skl_dsp_wake);
290 404
291int skl_dsp_sleep(struct sst_dsp *ctx) 405int skl_dsp_sleep(struct sst_dsp *ctx)
292{ 406{
293 return ctx->fw_ops.set_state_D3(ctx); 407 return skl_dsp_put_core(ctx, SKL_DSP_CORE0_ID);
294} 408}
295EXPORT_SYMBOL_GPL(skl_dsp_sleep); 409EXPORT_SYMBOL_GPL(skl_dsp_sleep);
296 410
@@ -337,9 +451,7 @@ void skl_dsp_free(struct sst_dsp *dsp)
337 451
338 free_irq(dsp->irq, dsp); 452 free_irq(dsp->irq, dsp);
339 skl_ipc_op_int_disable(dsp); 453 skl_ipc_op_int_disable(dsp);
340 skl_ipc_int_disable(dsp); 454 skl_dsp_disable_core(dsp, SKL_DSP_CORE0_MASK);
341
342 skl_dsp_disable_core(dsp);
343} 455}
344EXPORT_SYMBOL_GPL(skl_dsp_free); 456EXPORT_SYMBOL_GPL(skl_dsp_free);
345 457
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index deabe7308d3b..0f8629ef79ac 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -19,6 +19,7 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <sound/memalloc.h> 20#include <sound/memalloc.h>
21#include "skl-sst-cldma.h" 21#include "skl-sst-cldma.h"
22#include "skl-tplg-interface.h"
22 23
23struct sst_dsp; 24struct sst_dsp;
24struct skl_sst; 25struct skl_sst;
@@ -76,35 +77,53 @@ struct sst_dsp_device;
76#define SKL_ADSPIC_IPC 1 77#define SKL_ADSPIC_IPC 1
77#define SKL_ADSPIS_IPC 1 78#define SKL_ADSPIS_IPC 1
78 79
80/* Core ID of core0 */
81#define SKL_DSP_CORE0_ID 0
82
83/* Mask for a given core index, c = 0.. number of supported cores - 1 */
84#define SKL_DSP_CORE_MASK(c) BIT(c)
85
86/*
87 * Core 0 mask = SKL_DSP_CORE_MASK(0); Defined separately
88 * since Core0 is primary core and it is used often
89 */
90#define SKL_DSP_CORE0_MASK BIT(0)
91
92/*
93 * Mask for a given number of cores
94 * nc = number of supported cores
95 */
96#define SKL_DSP_CORES_MASK(nc) GENMASK((nc - 1), 0)
97
79/* ADSPCS - Audio DSP Control & Status */ 98/* ADSPCS - Audio DSP Control & Status */
80#define SKL_DSP_CORES 1 99
81#define SKL_DSP_CORE0_MASK 1 100/*
82#define SKL_DSP_CORES_MASK ((1 << SKL_DSP_CORES) - 1) 101 * Core Reset - asserted high
83 102 * CRST Mask for a given core mask pattern, cm
84/* Core Reset - asserted high */ 103 */
85#define SKL_ADSPCS_CRST_SHIFT 0 104#define SKL_ADSPCS_CRST_SHIFT 0
86#define SKL_ADSPCS_CRST_MASK (SKL_DSP_CORES_MASK << SKL_ADSPCS_CRST_SHIFT) 105#define SKL_ADSPCS_CRST_MASK(cm) ((cm) << SKL_ADSPCS_CRST_SHIFT)
87#define SKL_ADSPCS_CRST(x) ((x << SKL_ADSPCS_CRST_SHIFT) & SKL_ADSPCS_CRST_MASK) 106
88 107/*
89/* Core run/stall - when set to '1' core is stalled */ 108 * Core run/stall - when set to '1' core is stalled
90#define SKL_ADSPCS_CSTALL_SHIFT 8 109 * CSTALL Mask for a given core mask pattern, cm
91#define SKL_ADSPCS_CSTALL_MASK (SKL_DSP_CORES_MASK << \ 110 */
92 SKL_ADSPCS_CSTALL_SHIFT) 111#define SKL_ADSPCS_CSTALL_SHIFT 8
93#define SKL_ADSPCS_CSTALL(x) ((x << SKL_ADSPCS_CSTALL_SHIFT) & \ 112#define SKL_ADSPCS_CSTALL_MASK(cm) ((cm) << SKL_ADSPCS_CSTALL_SHIFT)
94 SKL_ADSPCS_CSTALL_MASK) 113
95 114/*
96/* Set Power Active - when set to '1' turn cores on */ 115 * Set Power Active - when set to '1' turn cores on
97#define SKL_ADSPCS_SPA_SHIFT 16 116 * SPA Mask for a given core mask pattern, cm
98#define SKL_ADSPCS_SPA_MASK (SKL_DSP_CORES_MASK << SKL_ADSPCS_SPA_SHIFT) 117 */
99#define SKL_ADSPCS_SPA(x) ((x << SKL_ADSPCS_SPA_SHIFT) & SKL_ADSPCS_SPA_MASK) 118#define SKL_ADSPCS_SPA_SHIFT 16
100 119#define SKL_ADSPCS_SPA_MASK(cm) ((cm) << SKL_ADSPCS_SPA_SHIFT)
101/* Current Power Active - power status of cores, set by hardware */ 120
102#define SKL_ADSPCS_CPA_SHIFT 24 121/*
103#define SKL_ADSPCS_CPA_MASK (SKL_DSP_CORES_MASK << SKL_ADSPCS_CPA_SHIFT) 122 * Current Power Active - power status of cores, set by hardware
104#define SKL_ADSPCS_CPA(x) ((x << SKL_ADSPCS_CPA_SHIFT) & SKL_ADSPCS_CPA_MASK) 123 * CPA Mask for a given core mask pattern, cm
105 124 */
106#define SST_DSP_POWER_D0 0x0 /* full On */ 125#define SKL_ADSPCS_CPA_SHIFT 24
107#define SST_DSP_POWER_D3 0x3 /* Off */ 126#define SKL_ADSPCS_CPA_MASK(cm) ((cm) << SKL_ADSPCS_CPA_SHIFT)
108 127
109enum skl_dsp_states { 128enum skl_dsp_states {
110 SKL_DSP_RUNNING = 1, 129 SKL_DSP_RUNNING = 1,
@@ -115,8 +134,8 @@ struct skl_dsp_fw_ops {
115 int (*load_fw)(struct sst_dsp *ctx); 134 int (*load_fw)(struct sst_dsp *ctx);
116 /* FW module parser/loader */ 135 /* FW module parser/loader */
117 int (*parse_fw)(struct sst_dsp *ctx); 136 int (*parse_fw)(struct sst_dsp *ctx);
118 int (*set_state_D0)(struct sst_dsp *ctx); 137 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
119 int (*set_state_D3)(struct sst_dsp *ctx); 138 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
120 unsigned int (*get_fw_errcode)(struct sst_dsp *ctx); 139 unsigned int (*get_fw_errcode)(struct sst_dsp *ctx);
121 int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, u8 *mod_name); 140 int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, u8 *mod_name);
122 int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id); 141 int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id);
@@ -157,14 +176,26 @@ int skl_cldma_prepare(struct sst_dsp *ctx);
157void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); 176void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
158struct sst_dsp *skl_dsp_ctx_init(struct device *dev, 177struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
159 struct sst_dsp_device *sst_dev, int irq); 178 struct sst_dsp_device *sst_dev, int irq);
160int skl_dsp_enable_core(struct sst_dsp *ctx);
161int skl_dsp_disable_core(struct sst_dsp *ctx);
162bool is_skl_dsp_running(struct sst_dsp *ctx); 179bool is_skl_dsp_running(struct sst_dsp *ctx);
180
181unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx);
182void skl_dsp_init_core_state(struct sst_dsp *ctx);
183int skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask);
184int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask);
185int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask);
186int skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask);
187int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx,
188 unsigned int core_mask);
189int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask);
190
163irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id); 191irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id);
164int skl_dsp_wake(struct sst_dsp *ctx); 192int skl_dsp_wake(struct sst_dsp *ctx);
165int skl_dsp_sleep(struct sst_dsp *ctx); 193int skl_dsp_sleep(struct sst_dsp *ctx);
166void skl_dsp_free(struct sst_dsp *dsp); 194void skl_dsp_free(struct sst_dsp *dsp);
167 195
196int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id);
197int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id);
198
168int skl_dsp_boot(struct sst_dsp *ctx); 199int skl_dsp_boot(struct sst_dsp *ctx);
169int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 200int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
170 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 201 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
@@ -175,4 +206,11 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
175void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 206void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
176void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 207void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
177 208
209int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
210 struct skl_dfw_module *dfw_config);
211int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset);
212void skl_freeup_uuid_list(struct skl_sst *ctx);
213
214int skl_dsp_strip_extended_manifest(struct firmware *fw);
215
178#endif /*__SKL_SST_DSP_H__*/ 216#endif /*__SKL_SST_DSP_H__*/
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 543460293b00..96f2f6889b18 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -363,7 +363,7 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
363 /* first process the header */ 363 /* first process the header */
364 switch (reply) { 364 switch (reply) {
365 case IPC_GLB_REPLY_SUCCESS: 365 case IPC_GLB_REPLY_SUCCESS:
366 dev_info(ipc->dev, "ipc FW reply %x: success\n", header.primary); 366 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
367 /* copy the rx data from the mailbox */ 367 /* copy the rx data from the mailbox */
368 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size); 368 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
369 break; 369 break;
@@ -692,7 +692,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
692 /* param_block_size must be in dwords */ 692 /* param_block_size must be in dwords */
693 u16 param_block_size = msg->param_data_size / sizeof(u32); 693 u16 param_block_size = msg->param_data_size / sizeof(u32);
694 694
695 print_hex_dump(KERN_DEBUG, NULL, DUMP_PREFIX_NONE, 695 print_hex_dump_debug("Param data:", DUMP_PREFIX_NONE,
696 16, 4, buffer, param_block_size, false); 696 16, 4, buffer, param_block_size, false);
697 697
698 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); 698 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index d59d1ba62a43..2e3d4e80ef97 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -45,6 +45,14 @@ struct skl_ipc_header {
45 u32 extension; 45 u32 extension;
46}; 46};
47 47
48#define SKL_DSP_CORES_MAX 2
49
50struct skl_dsp_cores {
51 unsigned int count;
52 enum skl_dsp_states state[SKL_DSP_CORES_MAX];
53 int usage_count[SKL_DSP_CORES_MAX];
54};
55
48struct skl_sst { 56struct skl_sst {
49 struct device *dev; 57 struct device *dev;
50 struct sst_dsp *dsp; 58 struct sst_dsp *dsp;
@@ -60,6 +68,15 @@ struct skl_sst {
60 void (*enable_miscbdcge)(struct device *dev, bool enable); 68 void (*enable_miscbdcge)(struct device *dev, bool enable);
61 /*Is CGCTL.MISCBDCGE disabled*/ 69 /*Is CGCTL.MISCBDCGE disabled*/
62 bool miscbdcg_disabled; 70 bool miscbdcg_disabled;
71
72 /* Populate module information */
73 struct list_head uuid_list;
74
75 /* Is firmware loaded */
76 bool fw_loaded;
77
78 /* multi-core */
79 struct skl_dsp_cores cores;
63}; 80};
64 81
65struct skl_ipc_init_instance_msg { 82struct skl_ipc_init_instance_msg {
@@ -136,5 +153,6 @@ void skl_ipc_int_disable(struct sst_dsp *dsp);
136bool skl_ipc_int_status(struct sst_dsp *dsp); 153bool skl_ipc_int_status(struct sst_dsp *dsp);
137void skl_ipc_free(struct sst_generic_ipc *ipc); 154void skl_ipc_free(struct sst_generic_ipc *ipc);
138int skl_ipc_init(struct device *dev, struct skl_sst *skl); 155int skl_ipc_init(struct device *dev, struct skl_sst *skl);
156void skl_clear_module_cnt(struct sst_dsp *ctx);
139 157
140#endif /* __SKL_IPC_H */ 158#endif /* __SKL_IPC_H */
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
new file mode 100644
index 000000000000..25fcb796bd86
--- /dev/null
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -0,0 +1,256 @@
1/*
2 * skl-sst-utils.c - SKL sst utils functions
3 *
4 * Copyright (C) 2016 Intel Corp
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#include <linux/device.h>
17#include <linux/slab.h>
18#include <linux/uuid.h>
19#include "skl-sst-dsp.h"
20#include "../common/sst-dsp.h"
21#include "../common/sst-dsp-priv.h"
22#include "skl-sst-ipc.h"
23
24
25#define UUID_STR_SIZE 37
26#define DEFAULT_HASH_SHA256_LEN 32
27
28/* FW Extended Manifest Header id = $AE1 */
29#define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124
30
31struct skl_dfw_module_mod {
32 char name[100];
33 struct skl_dfw_module skl_dfw_mod;
34};
35
36struct UUID {
37 u8 id[16];
38};
39
40union seg_flags {
41 u32 ul;
42 struct {
43 u32 contents : 1;
44 u32 alloc : 1;
45 u32 load : 1;
46 u32 read_only : 1;
47 u32 code : 1;
48 u32 data : 1;
49 u32 _rsvd0 : 2;
50 u32 type : 4;
51 u32 _rsvd1 : 4;
52 u32 length : 16;
53 } r;
54} __packed;
55
56struct segment_desc {
57 union seg_flags flags;
58 u32 v_base_addr;
59 u32 file_offset;
60};
61
62struct module_type {
63 u32 load_type : 4;
64 u32 auto_start : 1;
65 u32 domain_ll : 1;
66 u32 domain_dp : 1;
67 u32 rsvd : 25;
68} __packed;
69
70struct adsp_module_entry {
71 u32 struct_id;
72 u8 name[8];
73 struct UUID uuid;
74 struct module_type type;
75 u8 hash1[DEFAULT_HASH_SHA256_LEN];
76 u32 entry_point;
77 u16 cfg_offset;
78 u16 cfg_count;
79 u32 affinity_mask;
80 u16 instance_max_count;
81 u16 instance_bss_size;
82 struct segment_desc segments[3];
83} __packed;
84
85struct adsp_fw_hdr {
86 u32 id;
87 u32 len;
88 u8 name[8];
89 u32 preload_page_count;
90 u32 fw_image_flags;
91 u32 feature_mask;
92 u16 major;
93 u16 minor;
94 u16 hotfix;
95 u16 build;
96 u32 num_modules;
97 u32 hw_buf_base;
98 u32 hw_buf_length;
99 u32 load_offset;
100} __packed;
101
102struct uuid_module {
103 uuid_le uuid;
104 int id;
105 int is_loadable;
106
107 struct list_head list;
108};
109
110struct skl_ext_manifest_hdr {
111 u32 id;
112 u32 len;
113 u16 version_major;
114 u16 version_minor;
115 u32 entries;
116};
117
118int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
119 struct skl_dfw_module *dfw_config)
120{
121 struct uuid_module *module;
122 uuid_le *uuid_mod;
123
124 uuid_mod = (uuid_le *)uuid;
125
126 list_for_each_entry(module, &ctx->uuid_list, list) {
127 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
128 dfw_config->module_id = module->id;
129 dfw_config->is_loadable = module->is_loadable;
130
131 return 0;
132 }
133 }
134
135 return -EINVAL;
136}
137EXPORT_SYMBOL_GPL(snd_skl_get_module_info);
138
139/*
140 * Parse the firmware binary to get the UUID, module id
141 * and loadable flags
142 */
143int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
144{
145 struct adsp_fw_hdr *adsp_hdr;
146 struct adsp_module_entry *mod_entry;
147 int i, num_entry;
148 uuid_le *uuid_bin;
149 const char *buf;
150 struct skl_sst *skl = ctx->thread_context;
151 struct uuid_module *module;
152 struct firmware stripped_fw;
153 unsigned int safe_file;
154
155 /* Get the FW pointer to derive ADSP header */
156 stripped_fw.data = ctx->fw->data;
157 stripped_fw.size = ctx->fw->size;
158
159 skl_dsp_strip_extended_manifest(&stripped_fw);
160
161 buf = stripped_fw.data;
162
163 /* check if we have enough space in file to move to header */
164 safe_file = sizeof(*adsp_hdr) + offset;
165 if (stripped_fw.size <= safe_file) {
166 dev_err(ctx->dev, "Small fw file size, No space for hdr\n");
167 return -EINVAL;
168 }
169
170 adsp_hdr = (struct adsp_fw_hdr *)(buf + offset);
171
172 /* check 1st module entry is in file */
173 safe_file += adsp_hdr->len + sizeof(*mod_entry);
174 if (stripped_fw.size <= safe_file) {
175 dev_err(ctx->dev, "Small fw file size, No module entry\n");
176 return -EINVAL;
177 }
178
179 mod_entry = (struct adsp_module_entry *)
180 (buf + offset + adsp_hdr->len);
181
182 num_entry = adsp_hdr->num_modules;
183
184 /* check all entries are in file */
185 safe_file += num_entry * sizeof(*mod_entry);
186 if (stripped_fw.size <= safe_file) {
187 dev_err(ctx->dev, "Small fw file size, No modules\n");
188 return -EINVAL;
189 }
190
191
192 /*
193 * Read the UUID(GUID) from FW Manifest.
194 *
195 * The 16 byte UUID format is: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
196 * Populate the UUID table to store module_id and loadable flags
197 * for the module.
198 */
199
200 for (i = 0; i < num_entry; i++, mod_entry++) {
201 module = kzalloc(sizeof(*module), GFP_KERNEL);
202 if (!module)
203 return -ENOMEM;
204
205 uuid_bin = (uuid_le *)mod_entry->uuid.id;
206 memcpy(&module->uuid, uuid_bin, sizeof(module->uuid));
207
208 module->id = i;
209 module->is_loadable = mod_entry->type.load_type;
210
211 list_add_tail(&module->list, &skl->uuid_list);
212
213 dev_dbg(ctx->dev,
214 "Adding uuid :%pUL mod id: %d Loadable: %d\n",
215 &module->uuid, module->id, module->is_loadable);
216 }
217
218 return 0;
219}
220
221void skl_freeup_uuid_list(struct skl_sst *ctx)
222{
223 struct uuid_module *uuid, *_uuid;
224
225 list_for_each_entry_safe(uuid, _uuid, &ctx->uuid_list, list) {
226 list_del(&uuid->list);
227 kfree(uuid);
228 }
229}
230
231/*
232 * some firmware binary contains some extended manifest. This needs
233 * to be stripped in that case before we load and use that image.
234 *
235 * Get the module id for the module by checking
236 * the table for the UUID for the module
237 */
238int skl_dsp_strip_extended_manifest(struct firmware *fw)
239{
240 struct skl_ext_manifest_hdr *hdr;
241
242 /* check if fw file is greater than header we are looking */
243 if (fw->size < sizeof(hdr)) {
244 pr_err("%s: Firmware file small, no hdr\n", __func__);
245 return -EINVAL;
246 }
247
248 hdr = (struct skl_ext_manifest_hdr *)fw->data;
249
250 if (hdr->id == SKL_EXT_MANIFEST_HEADER_MAGIC) {
251 fw->size -= hdr->len;
252 fw->data += hdr->len;
253 }
254
255 return 0;
256}
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 13ec8d53b526..588f899ceb65 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -68,10 +68,13 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
68 return ret; 68 return ret;
69} 69}
70 70
71#define SKL_ADSP_FW_BIN_HDR_OFFSET 0x284
72
71static int skl_load_base_firmware(struct sst_dsp *ctx) 73static int skl_load_base_firmware(struct sst_dsp *ctx)
72{ 74{
73 int ret = 0, i; 75 int ret = 0, i;
74 struct skl_sst *skl = ctx->thread_context; 76 struct skl_sst *skl = ctx->thread_context;
77 struct firmware stripped_fw;
75 u32 reg; 78 u32 reg;
76 79
77 skl->boot_complete = false; 80 skl->boot_complete = false;
@@ -81,11 +84,25 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
81 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); 84 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
82 if (ret < 0) { 85 if (ret < 0) {
83 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 86 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
84 skl_dsp_disable_core(ctx);
85 return -EIO; 87 return -EIO;
86 } 88 }
87 } 89 }
88 90
91 ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET);
92 if (ret < 0) {
93 dev_err(ctx->dev,
94 "UUID parsing err: %d\n", ret);
95 release_firmware(ctx->fw);
96 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
97 return ret;
98 }
99
100 /* check for extended manifest */
101 stripped_fw.data = ctx->fw->data;
102 stripped_fw.size = ctx->fw->size;
103
104 skl_dsp_strip_extended_manifest(&stripped_fw);
105
89 ret = skl_dsp_boot(ctx); 106 ret = skl_dsp_boot(ctx);
90 if (ret < 0) { 107 if (ret < 0) {
91 dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret); 108 dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret);
@@ -119,7 +136,7 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
119 goto transfer_firmware_failed; 136 goto transfer_firmware_failed;
120 } 137 }
121 138
122 ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size); 139 ret = skl_transfer_firmware(ctx, stripped_fw.data, stripped_fw.size);
123 if (ret < 0) { 140 if (ret < 0) {
124 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret); 141 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
125 goto transfer_firmware_failed; 142 goto transfer_firmware_failed;
@@ -133,67 +150,87 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
133 } 150 }
134 151
135 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret); 152 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
136 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); 153 skl->fw_loaded = true;
137 } 154 }
138 return 0; 155 return 0;
139transfer_firmware_failed: 156transfer_firmware_failed:
140 ctx->cl_dev.ops.cl_cleanup_controller(ctx); 157 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
141skl_load_base_firmware_failed: 158skl_load_base_firmware_failed:
142 skl_dsp_disable_core(ctx); 159 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
143 release_firmware(ctx->fw); 160 release_firmware(ctx->fw);
144 ctx->fw = NULL; 161 ctx->fw = NULL;
145 return ret; 162 return ret;
146} 163}
147 164
148static int skl_set_dsp_D0(struct sst_dsp *ctx) 165static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
149{ 166{
150 int ret; 167 int ret;
168 struct skl_ipc_dxstate_info dx;
169 struct skl_sst *skl = ctx->thread_context;
170 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
151 171
152 ret = skl_load_base_firmware(ctx); 172 /* If core0 is being turned on, we need to load the FW */
153 if (ret < 0) { 173 if (core_id == SKL_DSP_CORE0_ID) {
154 dev_err(ctx->dev, "unable to load firmware\n"); 174 ret = skl_load_base_firmware(ctx);
155 return ret; 175 if (ret < 0) {
176 dev_err(ctx->dev, "unable to load firmware\n");
177 return ret;
178 }
156 } 179 }
157 180
158 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); 181 /*
182 * If any core other than core 0 is being moved to D0, enable the
183 * core and send the set dx IPC for the core.
184 */
185 if (core_id != SKL_DSP_CORE0_ID) {
186 ret = skl_dsp_enable_core(ctx, core_mask);
187 if (ret < 0)
188 return ret;
189
190 dx.core_mask = core_mask;
191 dx.dx_mask = core_mask;
192
193 ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID,
194 SKL_BASE_FW_MODULE_ID, &dx);
195 if (ret < 0) {
196 dev_err(ctx->dev, "Failed to set dsp to D0:core id= %d\n",
197 core_id);
198 skl_dsp_disable_core(ctx, core_mask);
199 }
200 }
201
202 skl->cores.state[core_id] = SKL_DSP_RUNNING;
159 203
160 return ret; 204 return ret;
161} 205}
162 206
163static int skl_set_dsp_D3(struct sst_dsp *ctx) 207static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
164{ 208{
165 int ret; 209 int ret;
166 struct skl_ipc_dxstate_info dx; 210 struct skl_ipc_dxstate_info dx;
167 struct skl_sst *skl = ctx->thread_context; 211 struct skl_sst *skl = ctx->thread_context;
212 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
168 213
169 dev_dbg(ctx->dev, "In %s:\n", __func__); 214 dx.core_mask = core_mask;
170 mutex_lock(&ctx->mutex);
171 if (!is_skl_dsp_running(ctx)) {
172 mutex_unlock(&ctx->mutex);
173 return 0;
174 }
175 mutex_unlock(&ctx->mutex);
176
177 dx.core_mask = SKL_DSP_CORE0_MASK;
178 dx.dx_mask = SKL_IPC_D3_MASK; 215 dx.dx_mask = SKL_IPC_D3_MASK;
216
179 ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, SKL_BASE_FW_MODULE_ID, &dx); 217 ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, SKL_BASE_FW_MODULE_ID, &dx);
180 if (ret < 0) 218 if (ret < 0)
181 dev_err(ctx->dev, 219 dev_err(ctx->dev, "set Dx core %d fail: %d\n", core_id, ret);
182 "D3 request to FW failed, continuing reset: %d", ret); 220
183 221 if (core_id == SKL_DSP_CORE0_ID) {
184 /* disable Interrupt */ 222 /* disable Interrupt */
185 ctx->cl_dev.ops.cl_cleanup_controller(ctx); 223 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
186 skl_cldma_int_disable(ctx); 224 skl_cldma_int_disable(ctx);
187 skl_ipc_op_int_disable(ctx); 225 skl_ipc_op_int_disable(ctx);
188 skl_ipc_int_disable(ctx); 226 skl_ipc_int_disable(ctx);
189
190 ret = skl_dsp_disable_core(ctx);
191 if (ret < 0) {
192 dev_err(ctx->dev, "disable dsp core failed ret: %d\n", ret);
193 ret = -EIO;
194 } 227 }
195 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
196 228
229 ret = skl_dsp_disable_core(ctx, core_mask);
230 if (ret < 0)
231 return ret;
232
233 skl->cores.state[core_id] = SKL_DSP_RESET;
197 return ret; 234 return ret;
198} 235}
199 236
@@ -360,6 +397,19 @@ static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
360 return ret; 397 return ret;
361} 398}
362 399
400void skl_clear_module_cnt(struct sst_dsp *ctx)
401{
402 struct skl_module_table *module;
403
404 if (list_empty(&ctx->module_list))
405 return;
406
407 list_for_each_entry(module, &ctx->module_list, list) {
408 module->usage_cnt = 0;
409 }
410}
411EXPORT_SYMBOL_GPL(skl_clear_module_cnt);
412
363static void skl_clear_module_table(struct sst_dsp *ctx) 413static void skl_clear_module_table(struct sst_dsp *ctx)
364{ 414{
365 struct skl_module_table *module, *tmp; 415 struct skl_module_table *module, *tmp;
@@ -409,6 +459,7 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
409 459
410 skl->dev = dev; 460 skl->dev = dev;
411 skl_dev.thread_context = skl; 461 skl_dev.thread_context = skl;
462 INIT_LIST_HEAD(&skl->uuid_list);
412 463
413 skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq); 464 skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq);
414 if (!skl->dsp) { 465 if (!skl->dsp) {
@@ -432,12 +483,16 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
432 if (ret) 483 if (ret)
433 return ret; 484 return ret;
434 485
486 skl->cores.count = 2;
487
435 ret = sst->fw_ops.load_fw(sst); 488 ret = sst->fw_ops.load_fw(sst);
436 if (ret < 0) { 489 if (ret < 0) {
437 dev_err(dev, "Load base fw failed : %d", ret); 490 dev_err(dev, "Load base fw failed : %d", ret);
438 goto cleanup; 491 goto cleanup;
439 } 492 }
440 493
494 skl_dsp_init_core_state(sst);
495
441 if (dsp) 496 if (dsp)
442 *dsp = skl; 497 *dsp = skl;
443 498
@@ -452,6 +507,7 @@ EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
452void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 507void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
453{ 508{
454 skl_clear_module_table(ctx->dsp); 509 skl_clear_module_table(ctx->dsp);
510 skl_freeup_uuid_list(ctx);
455 skl_ipc_free(&ctx->ipc); 511 skl_ipc_free(&ctx->ipc);
456 ctx->dsp->ops->free(ctx->dsp); 512 ctx->dsp->ops->free(ctx->dsp);
457 if (ctx->boot_complete) { 513 if (ctx->boot_complete) {
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 3e036b0349b9..cc0150fc2601 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -379,43 +379,6 @@ static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
379} 379}
380 380
381/* 381/*
382 * A pipe can have multiple modules, each of them will be a DAPM widget as
383 * well. While managing a pipeline we need to get the list of all the
384 * widgets in a pipelines, so this helper - skl_tplg_get_pipe_widget() helps
385 * to get the SKL type widgets in that pipeline
386 */
387static int skl_tplg_alloc_pipe_widget(struct device *dev,
388 struct snd_soc_dapm_widget *w, struct skl_pipe *pipe)
389{
390 struct skl_module_cfg *src_module = NULL;
391 struct snd_soc_dapm_path *p = NULL;
392 struct skl_pipe_module *p_module = NULL;
393
394 p_module = devm_kzalloc(dev, sizeof(*p_module), GFP_KERNEL);
395 if (!p_module)
396 return -ENOMEM;
397
398 p_module->w = w;
399 list_add_tail(&p_module->node, &pipe->w_list);
400
401 snd_soc_dapm_widget_for_each_sink_path(w, p) {
402 if ((p->sink->priv == NULL)
403 && (!is_skl_dsp_widget_type(w)))
404 continue;
405
406 if ((p->sink->priv != NULL) && p->connect
407 && is_skl_dsp_widget_type(p->sink)) {
408
409 src_module = p->sink->priv;
410 if (pipe->ppl_id == src_module->pipe->ppl_id)
411 skl_tplg_alloc_pipe_widget(dev,
412 p->sink, pipe);
413 }
414 }
415 return 0;
416}
417
418/*
419 * some modules can have multiple params set from user control and 382 * some modules can have multiple params set from user control and
420 * need to be set after module is initialized. If set_param flag is 383 * need to be set after module is initialized. If set_param flag is
421 * set module params will be done after module is initialised. 384 * set module params will be done after module is initialised.
@@ -448,7 +411,7 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
448 411
449 if (bc->set_params == SKL_PARAM_SET) { 412 if (bc->set_params == SKL_PARAM_SET) {
450 ret = skl_set_module_params(ctx, 413 ret = skl_set_module_params(ctx,
451 (u32 *)bc->params, bc->max, 414 (u32 *)bc->params, bc->size,
452 bc->param_id, mconfig); 415 bc->param_id, mconfig);
453 if (ret < 0) 416 if (ret < 0)
454 return ret; 417 return ret;
@@ -483,7 +446,7 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
483 continue; 446 continue;
484 447
485 mconfig->formats_config.caps = (u32 *)&bc->params; 448 mconfig->formats_config.caps = (u32 *)&bc->params;
486 mconfig->formats_config.caps_size = bc->max; 449 mconfig->formats_config.caps_size = bc->size;
487 450
488 break; 451 break;
489 } 452 }
@@ -514,8 +477,6 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
514 if (!skl_is_pipe_mcps_avail(skl, mconfig)) 477 if (!skl_is_pipe_mcps_avail(skl, mconfig))
515 return -ENOMEM; 478 return -ENOMEM;
516 479
517 skl_tplg_alloc_pipe_mcps(skl, mconfig);
518
519 if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) { 480 if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) {
520 ret = ctx->dsp->fw_ops.load_mod(ctx->dsp, 481 ret = ctx->dsp->fw_ops.load_mod(ctx->dsp,
521 mconfig->id.module_id, mconfig->guid); 482 mconfig->id.module_id, mconfig->guid);
@@ -539,6 +500,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
539 if (ret < 0) 500 if (ret < 0)
540 return ret; 501 return ret;
541 502
503 skl_tplg_alloc_pipe_mcps(skl, mconfig);
542 ret = skl_tplg_set_module_params(w, ctx); 504 ret = skl_tplg_set_module_params(w, ctx);
543 if (ret < 0) 505 if (ret < 0)
544 return ret; 506 return ret;
@@ -591,9 +553,6 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
591 if (!skl_is_pipe_mem_avail(skl, mconfig)) 553 if (!skl_is_pipe_mem_avail(skl, mconfig))
592 return -ENOMEM; 554 return -ENOMEM;
593 555
594 skl_tplg_alloc_pipe_mem(skl, mconfig);
595 skl_tplg_alloc_pipe_mcps(skl, mconfig);
596
597 /* 556 /*
598 * Create a list of modules for pipe. 557 * Create a list of modules for pipe.
599 * This list contains modules from source to sink 558 * This list contains modules from source to sink
@@ -602,19 +561,8 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
602 if (ret < 0) 561 if (ret < 0)
603 return ret; 562 return ret;
604 563
605 /* 564 skl_tplg_alloc_pipe_mem(skl, mconfig);
606 * we create a w_list of all widgets in that pipe. This list is not 565 skl_tplg_alloc_pipe_mcps(skl, mconfig);
607 * freed on PMD event as widgets within a pipe are static. This
608 * saves us cycles to get widgets in pipe every time.
609 *
610 * So if we have already initialized all the widgets of a pipeline
611 * we skip, so check for list_empty and create the list if empty
612 */
613 if (list_empty(&s_pipe->w_list)) {
614 ret = skl_tplg_alloc_pipe_widget(ctx->dev, w, s_pipe);
615 if (ret < 0)
616 return ret;
617 }
618 566
619 /* Init all pipe modules from source to sink */ 567 /* Init all pipe modules from source to sink */
620 ret = skl_tplg_init_pipe_modules(skl, s_pipe); 568 ret = skl_tplg_init_pipe_modules(skl, s_pipe);
@@ -949,13 +897,17 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
949 struct skl_pipe *s_pipe = mconfig->pipe; 897 struct skl_pipe *s_pipe = mconfig->pipe;
950 int ret = 0; 898 int ret = 0;
951 899
900 if (s_pipe->state == SKL_PIPE_INVALID)
901 return -EINVAL;
902
952 skl_tplg_free_pipe_mcps(skl, mconfig); 903 skl_tplg_free_pipe_mcps(skl, mconfig);
953 skl_tplg_free_pipe_mem(skl, mconfig); 904 skl_tplg_free_pipe_mem(skl, mconfig);
954 905
955 list_for_each_entry(w_module, &s_pipe->w_list, node) { 906 list_for_each_entry(w_module, &s_pipe->w_list, node) {
956 dst_module = w_module->w->priv; 907 dst_module = w_module->w->priv;
957 908
958 skl_tplg_free_pipe_mcps(skl, dst_module); 909 if (mconfig->m_state >= SKL_MODULE_INIT_DONE)
910 skl_tplg_free_pipe_mcps(skl, dst_module);
959 if (src_module == NULL) { 911 if (src_module == NULL) {
960 src_module = dst_module; 912 src_module = dst_module;
961 continue; 913 continue;
@@ -1102,7 +1054,7 @@ static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
1102 1054
1103 if (w->power) 1055 if (w->power)
1104 skl_get_module_params(skl->skl_sst, (u32 *)bc->params, 1056 skl_get_module_params(skl->skl_sst, (u32 *)bc->params,
1105 bc->max, bc->param_id, mconfig); 1057 bc->size, bc->param_id, mconfig);
1106 1058
1107 /* decrement size for TLV header */ 1059 /* decrement size for TLV header */
1108 size -= 2 * sizeof(u32); 1060 size -= 2 * sizeof(u32);
@@ -1136,6 +1088,10 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
1136 struct skl *skl = get_skl_ctx(w->dapm->dev); 1088 struct skl *skl = get_skl_ctx(w->dapm->dev);
1137 1089
1138 if (ac->params) { 1090 if (ac->params) {
1091 if (size > ac->max)
1092 return -EINVAL;
1093
1094 ac->size = size;
1139 /* 1095 /*
1140 * if the param_is is of type Vendor, firmware expects actual 1096 * if the param_is is of type Vendor, firmware expects actual
1141 * parameter id and size from the control. 1097 * parameter id and size from the control.
@@ -1151,7 +1107,7 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
1151 1107
1152 if (w->power) 1108 if (w->power)
1153 return skl_set_module_params(skl->skl_sst, 1109 return skl_set_module_params(skl->skl_sst,
1154 (u32 *)ac->params, ac->max, 1110 (u32 *)ac->params, ac->size,
1155 ac->param_id, mconfig); 1111 ac->param_id, mconfig);
1156 } 1112 }
1157 1113
@@ -1159,6 +1115,39 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
1159} 1115}
1160 1116
1161/* 1117/*
1118 * Fill the dma id for host and link. In case of passthrough
1119 * pipeline, this will both host and link in the same
1120 * pipeline, so need to copy the link and host based on dev_type
1121 */
1122static void skl_tplg_fill_dma_id(struct skl_module_cfg *mcfg,
1123 struct skl_pipe_params *params)
1124{
1125 struct skl_pipe *pipe = mcfg->pipe;
1126
1127 if (pipe->passthru) {
1128 switch (mcfg->dev_type) {
1129 case SKL_DEVICE_HDALINK:
1130 pipe->p_params->link_dma_id = params->link_dma_id;
1131 break;
1132
1133 case SKL_DEVICE_HDAHOST:
1134 pipe->p_params->host_dma_id = params->host_dma_id;
1135 break;
1136
1137 default:
1138 break;
1139 }
1140 pipe->p_params->s_fmt = params->s_fmt;
1141 pipe->p_params->ch = params->ch;
1142 pipe->p_params->s_freq = params->s_freq;
1143 pipe->p_params->stream = params->stream;
1144
1145 } else {
1146 memcpy(pipe->p_params, params, sizeof(*params));
1147 }
1148}
1149
1150/*
1162 * The FE params are passed by hw_params of the DAI. 1151 * The FE params are passed by hw_params of the DAI.
1163 * On hw_params, the params are stored in Gateway module of the FE and we 1152 * On hw_params, the params are stored in Gateway module of the FE and we
1164 * need to calculate the format in DSP module configuration, that 1153 * need to calculate the format in DSP module configuration, that
@@ -1168,10 +1157,9 @@ int skl_tplg_update_pipe_params(struct device *dev,
1168 struct skl_module_cfg *mconfig, 1157 struct skl_module_cfg *mconfig,
1169 struct skl_pipe_params *params) 1158 struct skl_pipe_params *params)
1170{ 1159{
1171 struct skl_pipe *pipe = mconfig->pipe;
1172 struct skl_module_fmt *format = NULL; 1160 struct skl_module_fmt *format = NULL;
1173 1161
1174 memcpy(pipe->p_params, params, sizeof(*params)); 1162 skl_tplg_fill_dma_id(mconfig, params);
1175 1163
1176 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) 1164 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK)
1177 format = &mconfig->in_fmt[0]; 1165 format = &mconfig->in_fmt[0];
@@ -1358,12 +1346,11 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
1358 struct skl_module_cfg *mconfig, 1346 struct skl_module_cfg *mconfig,
1359 struct skl_pipe_params *params) 1347 struct skl_pipe_params *params)
1360{ 1348{
1361 struct skl_pipe *pipe = mconfig->pipe;
1362 struct nhlt_specific_cfg *cfg; 1349 struct nhlt_specific_cfg *cfg;
1363 struct skl *skl = get_skl_ctx(dai->dev); 1350 struct skl *skl = get_skl_ctx(dai->dev);
1364 int link_type = skl_tplg_be_link_type(mconfig->dev_type); 1351 int link_type = skl_tplg_be_link_type(mconfig->dev_type);
1365 1352
1366 memcpy(pipe->p_params, params, sizeof(*params)); 1353 skl_tplg_fill_dma_id(mconfig, params);
1367 1354
1368 if (link_type == NHLT_LINK_HDA) 1355 if (link_type == NHLT_LINK_HDA)
1369 return 0; 1356 return 0;
@@ -1554,6 +1541,55 @@ static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt,
1554 } 1541 }
1555} 1542}
1556 1543
1544static void skl_clear_pin_config(struct snd_soc_platform *platform,
1545 struct snd_soc_dapm_widget *w)
1546{
1547 int i;
1548 struct skl_module_cfg *mconfig;
1549 struct skl_pipe *pipe;
1550
1551 if (!strncmp(w->dapm->component->name, platform->component.name,
1552 strlen(platform->component.name))) {
1553 mconfig = w->priv;
1554 pipe = mconfig->pipe;
1555 for (i = 0; i < mconfig->max_in_queue; i++) {
1556 mconfig->m_in_pin[i].in_use = false;
1557 mconfig->m_in_pin[i].pin_state = SKL_PIN_UNBIND;
1558 }
1559 for (i = 0; i < mconfig->max_out_queue; i++) {
1560 mconfig->m_out_pin[i].in_use = false;
1561 mconfig->m_out_pin[i].pin_state = SKL_PIN_UNBIND;
1562 }
1563 pipe->state = SKL_PIPE_INVALID;
1564 mconfig->m_state = SKL_MODULE_UNINIT;
1565 }
1566}
1567
1568void skl_cleanup_resources(struct skl *skl)
1569{
1570 struct skl_sst *ctx = skl->skl_sst;
1571 struct snd_soc_platform *soc_platform = skl->platform;
1572 struct snd_soc_dapm_widget *w;
1573 struct snd_soc_card *card;
1574
1575 if (soc_platform == NULL)
1576 return;
1577
1578 card = soc_platform->component.card;
1579 if (!card || !card->instantiated)
1580 return;
1581
1582 skl->resource.mem = 0;
1583 skl->resource.mcps = 0;
1584
1585 list_for_each_entry(w, &card->widgets, list) {
1586 if (is_skl_dsp_widget_type(w) && (w->priv != NULL))
1587 skl_clear_pin_config(soc_platform, w);
1588 }
1589
1590 skl_clear_module_cnt(ctx->dsp);
1591}
1592
1557/* 1593/*
1558 * Topology core widget load callback 1594 * Topology core widget load callback
1559 * 1595 *
@@ -1585,6 +1621,10 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1585 w->priv = mconfig; 1621 w->priv = mconfig;
1586 memcpy(&mconfig->guid, &dfw_config->uuid, 16); 1622 memcpy(&mconfig->guid, &dfw_config->uuid, 16);
1587 1623
1624 ret = snd_skl_get_module_info(skl->skl_sst, mconfig->guid, dfw_config);
1625 if (ret < 0)
1626 return ret;
1627
1588 mconfig->id.module_id = dfw_config->module_id; 1628 mconfig->id.module_id = dfw_config->module_id;
1589 mconfig->id.instance_id = dfw_config->instance_id; 1629 mconfig->id.instance_id = dfw_config->instance_id;
1590 mconfig->mcps = dfw_config->max_mcps; 1630 mconfig->mcps = dfw_config->max_mcps;
@@ -1683,6 +1723,7 @@ static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be,
1683 ac->max = dfw_ac->max; 1723 ac->max = dfw_ac->max;
1684 ac->param_id = dfw_ac->param_id; 1724 ac->param_id = dfw_ac->param_id;
1685 ac->set_params = dfw_ac->set_params; 1725 ac->set_params = dfw_ac->set_params;
1726 ac->size = dfw_ac->max;
1686 1727
1687 if (ac->max) { 1728 if (ac->max) {
1688 ac->params = (char *) devm_kzalloc(dev, ac->max, GFP_KERNEL); 1729 ac->params = (char *) devm_kzalloc(dev, ac->max, GFP_KERNEL);
@@ -1733,6 +1774,60 @@ static struct snd_soc_tplg_ops skl_tplg_ops = {
1733 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops), 1774 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
1734}; 1775};
1735 1776
1777/*
1778 * A pipe can have multiple modules, each of them will be a DAPM widget as
1779 * well. While managing a pipeline we need to get the list of all the
1780 * widgets in a pipelines, so this helper - skl_tplg_create_pipe_widget_list()
1781 * helps to get the SKL type widgets in that pipeline
1782 */
1783static int skl_tplg_create_pipe_widget_list(struct snd_soc_platform *platform)
1784{
1785 struct snd_soc_dapm_widget *w;
1786 struct skl_module_cfg *mcfg = NULL;
1787 struct skl_pipe_module *p_module = NULL;
1788 struct skl_pipe *pipe;
1789
1790 list_for_each_entry(w, &platform->component.card->widgets, list) {
1791 if (is_skl_dsp_widget_type(w) && w->priv != NULL) {
1792 mcfg = w->priv;
1793 pipe = mcfg->pipe;
1794
1795 p_module = devm_kzalloc(platform->dev,
1796 sizeof(*p_module), GFP_KERNEL);
1797 if (!p_module)
1798 return -ENOMEM;
1799
1800 p_module->w = w;
1801 list_add_tail(&p_module->node, &pipe->w_list);
1802 }
1803 }
1804
1805 return 0;
1806}
1807
1808static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe)
1809{
1810 struct skl_pipe_module *w_module;
1811 struct snd_soc_dapm_widget *w;
1812 struct skl_module_cfg *mconfig;
1813 bool host_found = false, link_found = false;
1814
1815 list_for_each_entry(w_module, &pipe->w_list, node) {
1816 w = w_module->w;
1817 mconfig = w->priv;
1818
1819 if (mconfig->dev_type == SKL_DEVICE_HDAHOST)
1820 host_found = true;
1821 else if (mconfig->dev_type != SKL_DEVICE_NONE)
1822 link_found = true;
1823 }
1824
1825 if (host_found && link_found)
1826 pipe->passthru = true;
1827 else
1828 pipe->passthru = false;
1829}
1830
1736/* This will be read from topology manifest, currently defined here */ 1831/* This will be read from topology manifest, currently defined here */
1737#define SKL_MAX_MCPS 30000000 1832#define SKL_MAX_MCPS 30000000
1738#define SKL_FW_MAX_MEM 1000000 1833#define SKL_FW_MAX_MEM 1000000
@@ -1746,6 +1841,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
1746 const struct firmware *fw; 1841 const struct firmware *fw;
1747 struct hdac_bus *bus = ebus_to_hbus(ebus); 1842 struct hdac_bus *bus = ebus_to_hbus(ebus);
1748 struct skl *skl = ebus_to_skl(ebus); 1843 struct skl *skl = ebus_to_skl(ebus);
1844 struct skl_pipeline *ppl;
1749 1845
1750 ret = request_firmware(&fw, skl->tplg_name, bus->dev); 1846 ret = request_firmware(&fw, skl->tplg_name, bus->dev);
1751 if (ret < 0) { 1847 if (ret < 0) {
@@ -1775,6 +1871,12 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
1775 skl->resource.max_mem = SKL_FW_MAX_MEM; 1871 skl->resource.max_mem = SKL_FW_MAX_MEM;
1776 1872
1777 skl->tplg = fw; 1873 skl->tplg = fw;
1874 ret = skl_tplg_create_pipe_widget_list(platform);
1875 if (ret < 0)
1876 return ret;
1877
1878 list_for_each_entry(ppl, &skl->ppl_list, node)
1879 skl_tplg_set_pipe_type(skl, ppl->pipe);
1778 1880
1779 return 0; 1881 return 0;
1780} 1882}
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index e4b399cd7868..22d3ef83817d 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -244,7 +244,8 @@ enum skl_pipe_state {
244 SKL_PIPE_INVALID = 0, 244 SKL_PIPE_INVALID = 0,
245 SKL_PIPE_CREATED = 1, 245 SKL_PIPE_CREATED = 1,
246 SKL_PIPE_PAUSED = 2, 246 SKL_PIPE_PAUSED = 2,
247 SKL_PIPE_STARTED = 3 247 SKL_PIPE_STARTED = 3,
248 SKL_PIPE_RESET = 4
248}; 249};
249 250
250struct skl_pipe_module { 251struct skl_pipe_module {
@@ -270,6 +271,7 @@ struct skl_pipe {
270 struct skl_pipe_params *p_params; 271 struct skl_pipe_params *p_params;
271 enum skl_pipe_state state; 272 enum skl_pipe_state state;
272 struct list_head w_list; 273 struct list_head w_list;
274 bool passthru;
273}; 275};
274 276
275enum skl_module_state { 277enum skl_module_state {
@@ -319,6 +321,7 @@ struct skl_algo_data {
319 u32 param_id; 321 u32 param_id;
320 u32 set_params; 322 u32 set_params;
321 u32 max; 323 u32 max;
324 u32 size;
322 char *params; 325 char *params;
323}; 326};
324 327
@@ -357,6 +360,8 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
357 360
358int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 361int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
359 362
363int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
364
360int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config); 365int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config);
361 366
362int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg 367int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 06d8c263c68f..cd59536a761d 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -35,6 +35,8 @@
35#include "skl-sst-dsp.h" 35#include "skl-sst-dsp.h"
36#include "skl-sst-ipc.h" 36#include "skl-sst-ipc.h"
37 37
38static struct skl_machine_pdata skl_dmic_data;
39
38/* 40/*
39 * initialize the PCI registers 41 * initialize the PCI registers
40 */ 42 */
@@ -184,6 +186,7 @@ static int _skl_suspend(struct hdac_ext_bus *ebus)
184{ 186{
185 struct skl *skl = ebus_to_skl(ebus); 187 struct skl *skl = ebus_to_skl(ebus);
186 struct hdac_bus *bus = ebus_to_hbus(ebus); 188 struct hdac_bus *bus = ebus_to_hbus(ebus);
189 struct pci_dev *pci = to_pci_dev(bus->dev);
187 int ret; 190 int ret;
188 191
189 snd_hdac_ext_bus_link_power_down_all(ebus); 192 snd_hdac_ext_bus_link_power_down_all(ebus);
@@ -193,9 +196,12 @@ static int _skl_suspend(struct hdac_ext_bus *ebus)
193 return ret; 196 return ret;
194 197
195 snd_hdac_bus_stop_chip(bus); 198 snd_hdac_bus_stop_chip(bus);
199 update_pci_dword(pci, AZX_PCIREG_PGCTL,
200 AZX_PGCTL_LSRMD_MASK, AZX_PGCTL_LSRMD_MASK);
196 skl_enable_miscbdcge(bus->dev, false); 201 skl_enable_miscbdcge(bus->dev, false);
197 snd_hdac_bus_enter_link_reset(bus); 202 snd_hdac_bus_enter_link_reset(bus);
198 skl_enable_miscbdcge(bus->dev, true); 203 skl_enable_miscbdcge(bus->dev, true);
204 skl_cleanup_resources(skl);
199 205
200 return 0; 206 return 0;
201} 207}
@@ -242,6 +248,7 @@ static int skl_suspend(struct device *dev)
242 ret = _skl_suspend(ebus); 248 ret = _skl_suspend(ebus);
243 if (ret < 0) 249 if (ret < 0)
244 return ret; 250 return ret;
251 skl->skl_sst->fw_loaded = false;
245 } 252 }
246 253
247 if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { 254 if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
@@ -397,6 +404,10 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data)
397 platform_device_put(pdev); 404 platform_device_put(pdev);
398 return -EIO; 405 return -EIO;
399 } 406 }
407
408 if (mach->pdata)
409 dev_set_drvdata(&pdev->dev, mach->pdata);
410
400 skl->i2s_dev = pdev; 411 skl->i2s_dev = pdev;
401 412
402 return 0; 413 return 0;
@@ -657,6 +668,8 @@ static int skl_probe(struct pci_dev *pci,
657 668
658 skl->pci_id = pci->device; 669 skl->pci_id = pci->device;
659 670
671 device_disable_async_suspend(bus->dev);
672
660 skl->nhlt = skl_nhlt_init(bus->dev); 673 skl->nhlt = skl_nhlt_init(bus->dev);
661 674
662 if (skl->nhlt == NULL) 675 if (skl->nhlt == NULL)
@@ -666,6 +679,8 @@ static int skl_probe(struct pci_dev *pci,
666 679
667 pci_set_drvdata(skl->pci, ebus); 680 pci_set_drvdata(skl->pci, ebus);
668 681
682 skl_dmic_data.dmic_num = skl_get_dmic_geo(skl);
683
669 /* check if dsp is there */ 684 /* check if dsp is there */
670 if (ebus->ppcap) { 685 if (ebus->ppcap) {
671 err = skl_machine_device_register(skl, 686 err = skl_machine_device_register(skl,
@@ -713,7 +728,7 @@ static int skl_probe(struct pci_dev *pci,
713 list_for_each_entry(hlink, &ebus->hlink_list, list) 728 list_for_each_entry(hlink, &ebus->hlink_list, list)
714 snd_hdac_ext_bus_link_put(ebus, hlink); 729 snd_hdac_ext_bus_link_put(ebus, hlink);
715 730
716 /*configure PM */ 731 /* configure PM */
717 pm_runtime_put_noidle(bus->dev); 732 pm_runtime_put_noidle(bus->dev);
718 pm_runtime_allow(bus->dev); 733 pm_runtime_allow(bus->dev);
719 734
@@ -766,8 +781,7 @@ static void skl_remove(struct pci_dev *pci)
766 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 781 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
767 struct skl *skl = ebus_to_skl(ebus); 782 struct skl *skl = ebus_to_skl(ebus);
768 783
769 if (skl->tplg) 784 release_firmware(skl->tplg);
770 release_firmware(skl->tplg);
771 785
772 if (pci_dev_run_wake(pci)) 786 if (pci_dev_run_wake(pci))
773 pm_runtime_get_noresume(&pci->dev); 787 pm_runtime_get_noresume(&pci->dev);
@@ -786,15 +800,23 @@ static void skl_remove(struct pci_dev *pci)
786 800
787static struct sst_acpi_mach sst_skl_devdata[] = { 801static struct sst_acpi_mach sst_skl_devdata[] = {
788 { "INT343A", "skl_alc286s_i2s", "intel/dsp_fw_release.bin", NULL, NULL, NULL }, 802 { "INT343A", "skl_alc286s_i2s", "intel/dsp_fw_release.bin", NULL, NULL, NULL },
789 { "INT343B", "skl_nau88l25_ssm4567_i2s", "intel/dsp_fw_release.bin", 803 { "INT343B", "skl_n88l25_s4567", "intel/dsp_fw_release.bin",
790 NULL, NULL, NULL }, 804 NULL, NULL, &skl_dmic_data },
791 { "MX98357A", "skl_nau88l25_max98357a_i2s", "intel/dsp_fw_release.bin", 805 { "MX98357A", "skl_n88l25_m98357a", "intel/dsp_fw_release.bin",
792 NULL, NULL, NULL }, 806 NULL, NULL, &skl_dmic_data },
793 {} 807 {}
794}; 808};
795 809
796static struct sst_acpi_mach sst_bxtp_devdata[] = { 810static struct sst_acpi_mach sst_bxtp_devdata[] = {
797 { "INT343A", "bxt_alc298s_i2s", "intel/dsp_fw_bxtn.bin", NULL, NULL, NULL }, 811 { "INT343A", "bxt_alc298s_i2s", "intel/dsp_fw_bxtn.bin", NULL, NULL, NULL },
812 { "DLGS7219", "bxt_da7219_max98357a_i2s", "intel/dsp_fw_bxtn.bin", NULL, NULL, NULL },
813};
814
815static struct sst_acpi_mach sst_kbl_devdata[] = {
816 { "INT343A", "kbl_alc286s_i2s", "intel/dsp_fw_kbl.bin", NULL, NULL, NULL },
817 { "INT343B", "kbl_n88l25_s4567", "intel/dsp_fw_kbl.bin", NULL, NULL, &skl_dmic_data },
818 { "MX98357A", "kbl_n88l25_m98357a", "intel/dsp_fw_kbl.bin", NULL, NULL, &skl_dmic_data },
819 {}
798}; 820};
799 821
800/* PCI IDs */ 822/* PCI IDs */
@@ -805,6 +827,9 @@ static const struct pci_device_id skl_ids[] = {
805 /* BXT-P */ 827 /* BXT-P */
806 { PCI_DEVICE(0x8086, 0x5a98), 828 { PCI_DEVICE(0x8086, 0x5a98),
807 .driver_data = (unsigned long)&sst_bxtp_devdata}, 829 .driver_data = (unsigned long)&sst_bxtp_devdata},
830 /* KBL */
831 { PCI_DEVICE(0x8086, 0x9D71),
832 .driver_data = (unsigned long)&sst_kbl_devdata},
808 { 0, } 833 { 0, }
809}; 834};
810MODULE_DEVICE_TABLE(pci, skl_ids); 835MODULE_DEVICE_TABLE(pci, skl_ids);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 4b4b3876aea9..9064e5b0d676 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -48,6 +48,8 @@
48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094 48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094
49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20 49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20
50 50
51#define AZX_PCIREG_PGCTL 0x44
52#define AZX_PGCTL_LSRMD_MASK (1 << 4)
51#define AZX_PCIREG_CGCTL 0x48 53#define AZX_PCIREG_CGCTL 0x48
52#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6) 54#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6)
53 55
@@ -65,6 +67,7 @@ struct skl {
65 unsigned int init_failed:1; /* delayed init failed */ 67 unsigned int init_failed:1; /* delayed init failed */
66 struct platform_device *dmic_dev; 68 struct platform_device *dmic_dev;
67 struct platform_device *i2s_dev; 69 struct platform_device *i2s_dev;
70 struct snd_soc_platform *platform;
68 71
69 struct nhlt_acpi_table *nhlt; /* nhlt ptr */ 72 struct nhlt_acpi_table *nhlt; /* nhlt ptr */
70 struct skl_sst *skl_sst; /* sst skl ctx */ 73 struct skl_sst *skl_sst; /* sst skl ctx */
@@ -90,6 +93,11 @@ struct skl_dma_params {
90 u8 stream_tag; 93 u8 stream_tag;
91}; 94};
92 95
96/* to pass dmic data */
97struct skl_machine_pdata {
98 u32 dmic_num;
99};
100
93struct skl_dsp_ops { 101struct skl_dsp_ops {
94 int id; 102 int id;
95 struct skl_dsp_loader_ops (*loader_ops)(void); 103 struct skl_dsp_loader_ops (*loader_ops)(void);
@@ -108,9 +116,11 @@ void skl_nhlt_free(struct nhlt_acpi_table *addr);
108struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance, 116struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
109 u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn); 117 u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn);
110 118
119int skl_get_dmic_geo(struct skl *skl);
111int skl_nhlt_update_topology_bin(struct skl *skl); 120int skl_nhlt_update_topology_bin(struct skl *skl);
112int skl_init_dsp(struct skl *skl); 121int skl_init_dsp(struct skl *skl);
113int skl_free_dsp(struct skl *skl); 122int skl_free_dsp(struct skl *skl);
114int skl_suspend_dsp(struct skl *skl); 123int skl_suspend_dsp(struct skl *skl);
115int skl_resume_dsp(struct skl *skl); 124int skl_resume_dsp(struct skl *skl);
125void skl_cleanup_resources(struct skl *skl);
116#endif /* __SOUND_SOC_SKL_H */ 126#endif /* __SOUND_SOC_SKL_H */
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 3abf51c07851..05cf809cf9e1 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -1,15 +1,40 @@
1config SND_SOC_MEDIATEK 1config SND_SOC_MEDIATEK
2 tristate "ASoC support for Mediatek chip" 2 tristate
3
4config SND_SOC_MT2701
5 tristate "ASoC support for Mediatek MT2701 chip"
6 depends on ARCH_MEDIATEK
7 select SND_SOC_MEDIATEK
8 help
9 This adds ASoC driver for Mediatek MT2701 boards
10 that can be used with other codecs.
11 Select Y if you have such device.
12 If unsure select "N".
13
14config SND_SOC_MT2701_CS42448
15 tristate "ASoc Audio driver for MT2701 with CS42448 codec"
16 depends on SND_SOC_MT2701
17 select SND_SOC_CS42XX8_I2C
18 select SND_SOC_BT_SCO
19 help
20 This adds ASoC driver for Mediatek MT2701 boards
21 with the CS42448 codecs.
22 Select Y if you have such device.
23 If unsure select "N".
24
25config SND_SOC_MT8173
26 tristate "ASoC support for Mediatek MT8173 chip"
3 depends on ARCH_MEDIATEK 27 depends on ARCH_MEDIATEK
28 select SND_SOC_MEDIATEK
4 help 29 help
5 This adds ASoC platform driver support for Mediatek chip 30 This adds ASoC platform driver support for Mediatek MT8173 chip
6 that can be used with other codecs. 31 that can be used with other codecs.
7 Select Y if you have such device. 32 Select Y if you have such device.
8 Ex: MT8173 33 Ex: MT8173
9 34
10config SND_SOC_MT8173_MAX98090 35config SND_SOC_MT8173_MAX98090
11 tristate "ASoC Audio driver for MT8173 with MAX98090 codec" 36 tristate "ASoC Audio driver for MT8173 with MAX98090 codec"
12 depends on SND_SOC_MEDIATEK && I2C 37 depends on SND_SOC_MT8173 && I2C
13 select SND_SOC_MAX98090 38 select SND_SOC_MAX98090
14 help 39 help
15 This adds ASoC driver for Mediatek MT8173 boards 40 This adds ASoC driver for Mediatek MT8173 boards
@@ -19,8 +44,9 @@ config SND_SOC_MT8173_MAX98090
19 44
20config SND_SOC_MT8173_RT5650 45config SND_SOC_MT8173_RT5650
21 tristate "ASoC Audio driver for MT8173 with RT5650 codec" 46 tristate "ASoC Audio driver for MT8173 with RT5650 codec"
22 depends on SND_SOC_MEDIATEK && I2C 47 depends on SND_SOC_MT8173 && I2C
23 select SND_SOC_RT5645 48 select SND_SOC_RT5645
49 select SND_SOC_HDMI_CODEC
24 help 50 help
25 This adds ASoC driver for Mediatek MT8173 boards 51 This adds ASoC driver for Mediatek MT8173 boards
26 with the RT5650 audio codec. 52 with the RT5650 audio codec.
@@ -29,7 +55,7 @@ config SND_SOC_MT8173_RT5650
29 55
30config SND_SOC_MT8173_RT5650_RT5514 56config SND_SOC_MT8173_RT5650_RT5514
31 tristate "ASoC Audio driver for MT8173 with RT5650 RT5514 codecs" 57 tristate "ASoC Audio driver for MT8173 with RT5650 RT5514 codecs"
32 depends on SND_SOC_MEDIATEK && I2C 58 depends on SND_SOC_MT8173 && I2C
33 select SND_SOC_RT5645 59 select SND_SOC_RT5645
34 select SND_SOC_RT5514 60 select SND_SOC_RT5514
35 help 61 help
@@ -40,7 +66,7 @@ config SND_SOC_MT8173_RT5650_RT5514
40 66
41config SND_SOC_MT8173_RT5650_RT5676 67config SND_SOC_MT8173_RT5650_RT5676
42 tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs" 68 tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs"
43 depends on SND_SOC_MEDIATEK && I2C 69 depends on SND_SOC_MT8173 && I2C
44 select SND_SOC_RT5645 70 select SND_SOC_RT5645
45 select SND_SOC_RT5677 71 select SND_SOC_RT5677
46 select SND_SOC_HDMI_CODEC 72 select SND_SOC_HDMI_CODEC
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index d486860c0a88..6bcab35dc828 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -1,7 +1,3 @@
1# MTK Platform Support 1obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
2obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o 2obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
3# Machine support 3obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
4obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
5obj-$(CONFIG_SND_SOC_MT8173_RT5650) += mt8173-rt5650.o
6obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5514) += mt8173-rt5650-rt5514.o
7obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
diff --git a/sound/soc/mediatek/common/Makefile b/sound/soc/mediatek/common/Makefile
new file mode 100644
index 000000000000..a55d33bc7b01
--- /dev/null
+++ b/sound/soc/mediatek/common/Makefile
@@ -0,0 +1,16 @@
1#
2# Copyright (C) 2015 MediaTek Inc.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License version 2 as
6# published by the Free Software Foundation.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13
14# platform driver
15snd-soc-mtk-common-objs := mtk-afe-platform-driver.o mtk-afe-fe-dai.o
16obj-$(CONFIG_SND_SOC_MEDIATEK) += snd-soc-mtk-common.o
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
new file mode 100644
index 000000000000..b788791b0a35
--- /dev/null
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -0,0 +1,379 @@
1/*
2 * mtk-afe-fe-dais.c -- Mediatek afe fe dai operator
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/pm_runtime.h>
19#include <linux/regmap.h>
20#include <sound/soc.h>
21#include "mtk-afe-fe-dai.h"
22#include "mtk-base-afe.h"
23
24#define AFE_BASE_END_OFFSET 8
25
26int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask,
27 unsigned int val)
28{
29 if (reg < 0)
30 return 0;
31 return regmap_update_bits(map, reg, mask, val);
32}
33
34int mtk_regmap_write(struct regmap *map, int reg, unsigned int val)
35{
36 if (reg < 0)
37 return 0;
38 return regmap_write(map, reg, val);
39}
40
41int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
42 struct snd_soc_dai *dai)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
46 struct snd_pcm_runtime *runtime = substream->runtime;
47 int memif_num = rtd->cpu_dai->id;
48 struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
49 const struct snd_pcm_hardware *mtk_afe_hardware = afe->mtk_afe_hardware;
50 int ret;
51
52 memif->substream = substream;
53
54 snd_pcm_hw_constraint_step(substream->runtime, 0,
55 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
56 /* enable agent */
57 mtk_regmap_update_bits(afe->regmap, memif->data->agent_disable_reg,
58 1 << memif->data->agent_disable_shift,
59 0 << memif->data->agent_disable_shift);
60
61 snd_soc_set_runtime_hwparams(substream, mtk_afe_hardware);
62
63 /*
64 * Capture cannot use ping-pong buffer since hw_ptr at IRQ may be
65 * smaller than period_size due to AFE's internal buffer.
66 * This easily leads to overrun when avail_min is period_size.
67 * One more period can hold the possible unread buffer.
68 */
69 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
70 int periods_max = mtk_afe_hardware->periods_max;
71
72 ret = snd_pcm_hw_constraint_minmax(runtime,
73 SNDRV_PCM_HW_PARAM_PERIODS,
74 3, periods_max);
75 if (ret < 0) {
76 dev_err(afe->dev, "hw_constraint_minmax failed\n");
77 return ret;
78 }
79 }
80
81 ret = snd_pcm_hw_constraint_integer(runtime,
82 SNDRV_PCM_HW_PARAM_PERIODS);
83 if (ret < 0)
84 dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");
85
86 /* dynamic allocate irq to memif */
87 if (memif->irq_usage < 0) {
88 int irq_id = mtk_dynamic_irq_acquire(afe);
89
90 if (irq_id != afe->irqs_size) {
91 /* link */
92 memif->irq_usage = irq_id;
93 } else {
94 dev_err(afe->dev, "%s() error: no more asys irq\n",
95 __func__);
96 ret = -EBUSY;
97 }
98 }
99 return ret;
100}
101EXPORT_SYMBOL_GPL(mtk_afe_fe_startup);
102
103void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
104 struct snd_soc_dai *dai)
105{
106 struct snd_soc_pcm_runtime *rtd = substream->private_data;
107 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
108 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
109 int irq_id;
110
111 irq_id = memif->irq_usage;
112
113 mtk_regmap_update_bits(afe->regmap, memif->data->agent_disable_reg,
114 1 << memif->data->agent_disable_shift,
115 1 << memif->data->agent_disable_shift);
116
117 if (!memif->const_irq) {
118 mtk_dynamic_irq_release(afe, irq_id);
119 memif->irq_usage = -1;
120 memif->substream = NULL;
121 }
122}
123EXPORT_SYMBOL_GPL(mtk_afe_fe_shutdown);
124
125int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
126 struct snd_pcm_hw_params *params,
127 struct snd_soc_dai *dai)
128{
129 struct snd_soc_pcm_runtime *rtd = substream->private_data;
130 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
131 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
132 int msb_at_bit33 = 0;
133 int ret, fs = 0;
134
135 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
136 if (ret < 0)
137 return ret;
138
139 msb_at_bit33 = upper_32_bits(substream->runtime->dma_addr) ? 1 : 0;
140 memif->phys_buf_addr = lower_32_bits(substream->runtime->dma_addr);
141 memif->buffer_size = substream->runtime->dma_bytes;
142
143 /* start */
144 mtk_regmap_write(afe->regmap, memif->data->reg_ofs_base,
145 memif->phys_buf_addr);
146 /* end */
147 mtk_regmap_write(afe->regmap,
148 memif->data->reg_ofs_base + AFE_BASE_END_OFFSET,
149 memif->phys_buf_addr + memif->buffer_size - 1);
150
151 /* set MSB to 33-bit */
152 mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg,
153 1 << memif->data->msb_shift,
154 msb_at_bit33 << memif->data->msb_shift);
155
156 /* set channel */
157 if (memif->data->mono_shift >= 0) {
158 unsigned int mono = (params_channels(params) == 1) ? 1 : 0;
159
160 mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg,
161 1 << memif->data->mono_shift,
162 mono << memif->data->mono_shift);
163 }
164
165 /* set rate */
166 if (memif->data->fs_shift < 0)
167 return 0;
168
169 fs = afe->memif_fs(substream, params_rate(params));
170
171 if (fs < 0)
172 return -EINVAL;
173
174 mtk_regmap_update_bits(afe->regmap, memif->data->fs_reg,
175 memif->data->fs_maskbit << memif->data->fs_shift,
176 fs << memif->data->fs_shift);
177
178 return 0;
179}
180EXPORT_SYMBOL_GPL(mtk_afe_fe_hw_params);
181
182int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream,
183 struct snd_soc_dai *dai)
184{
185 return snd_pcm_lib_free_pages(substream);
186}
187EXPORT_SYMBOL_GPL(mtk_afe_fe_hw_free);
188
189int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
190 struct snd_soc_dai *dai)
191{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct snd_pcm_runtime * const runtime = substream->runtime;
194 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
195 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
196 struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage];
197 const struct mtk_base_irq_data *irq_data = irqs->irq_data;
198 unsigned int counter = runtime->period_size;
199 int fs;
200
201 dev_dbg(afe->dev, "%s %s cmd=%d\n", __func__, memif->data->name, cmd);
202
203 switch (cmd) {
204 case SNDRV_PCM_TRIGGER_START:
205 case SNDRV_PCM_TRIGGER_RESUME:
206 if (memif->data->enable_shift >= 0)
207 mtk_regmap_update_bits(afe->regmap,
208 memif->data->enable_reg,
209 1 << memif->data->enable_shift,
210 1 << memif->data->enable_shift);
211
212 /* set irq counter */
213 mtk_regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
214 irq_data->irq_cnt_maskbit
215 << irq_data->irq_cnt_shift,
216 counter << irq_data->irq_cnt_shift);
217
218 /* set irq fs */
219 fs = afe->irq_fs(substream, runtime->rate);
220
221 if (fs < 0)
222 return -EINVAL;
223
224 mtk_regmap_update_bits(afe->regmap, irq_data->irq_fs_reg,
225 irq_data->irq_fs_maskbit
226 << irq_data->irq_fs_shift,
227 fs << irq_data->irq_fs_shift);
228
229 /* enable interrupt */
230 mtk_regmap_update_bits(afe->regmap, irq_data->irq_en_reg,
231 1 << irq_data->irq_en_shift,
232 1 << irq_data->irq_en_shift);
233
234 return 0;
235 case SNDRV_PCM_TRIGGER_STOP:
236 case SNDRV_PCM_TRIGGER_SUSPEND:
237 mtk_regmap_update_bits(afe->regmap, memif->data->enable_reg,
238 1 << memif->data->enable_shift, 0);
239 /* disable interrupt */
240 mtk_regmap_update_bits(afe->regmap, irq_data->irq_en_reg,
241 1 << irq_data->irq_en_shift,
242 0 << irq_data->irq_en_shift);
243 /* and clear pending IRQ */
244 mtk_regmap_write(afe->regmap, irq_data->irq_clr_reg,
245 1 << irq_data->irq_clr_shift);
246 return 0;
247 default:
248 return -EINVAL;
249 }
250}
251EXPORT_SYMBOL_GPL(mtk_afe_fe_trigger);
252
253int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
254 struct snd_soc_dai *dai)
255{
256 struct snd_soc_pcm_runtime *rtd = substream->private_data;
257 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
258 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
259 int hd_audio = 0;
260
261 /* set hd mode */
262 switch (substream->runtime->format) {
263 case SNDRV_PCM_FORMAT_S16_LE:
264 hd_audio = 0;
265 break;
266 case SNDRV_PCM_FORMAT_S32_LE:
267 hd_audio = 1;
268 break;
269 case SNDRV_PCM_FORMAT_S24_LE:
270 hd_audio = 1;
271 break;
272 default:
273 dev_err(afe->dev, "%s() error: unsupported format %d\n",
274 __func__, substream->runtime->format);
275 break;
276 }
277
278 mtk_regmap_update_bits(afe->regmap, memif->data->hd_reg,
279 1 << memif->data->hd_shift,
280 hd_audio << memif->data->hd_shift);
281
282 return 0;
283}
284EXPORT_SYMBOL_GPL(mtk_afe_fe_prepare);
285
286const struct snd_soc_dai_ops mtk_afe_fe_ops = {
287 .startup = mtk_afe_fe_startup,
288 .shutdown = mtk_afe_fe_shutdown,
289 .hw_params = mtk_afe_fe_hw_params,
290 .hw_free = mtk_afe_fe_hw_free,
291 .prepare = mtk_afe_fe_prepare,
292 .trigger = mtk_afe_fe_trigger,
293};
294EXPORT_SYMBOL_GPL(mtk_afe_fe_ops);
295
296static DEFINE_MUTEX(irqs_lock);
297int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe)
298{
299 int i;
300
301 mutex_lock(&afe->irq_alloc_lock);
302 for (i = 0; i < afe->irqs_size; ++i) {
303 if (afe->irqs[i].irq_occupyed == 0) {
304 afe->irqs[i].irq_occupyed = 1;
305 mutex_unlock(&afe->irq_alloc_lock);
306 return i;
307 }
308 }
309 mutex_unlock(&afe->irq_alloc_lock);
310 return afe->irqs_size;
311}
312EXPORT_SYMBOL_GPL(mtk_dynamic_irq_acquire);
313
314int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id)
315{
316 mutex_lock(&afe->irq_alloc_lock);
317 if (irq_id >= 0 && irq_id < afe->irqs_size) {
318 afe->irqs[irq_id].irq_occupyed = 0;
319 mutex_unlock(&afe->irq_alloc_lock);
320 return 0;
321 }
322 mutex_unlock(&afe->irq_alloc_lock);
323 return -EINVAL;
324}
325EXPORT_SYMBOL_GPL(mtk_dynamic_irq_release);
326
327int mtk_afe_dai_suspend(struct snd_soc_dai *dai)
328{
329 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
330 struct device *dev = afe->dev;
331 struct regmap *regmap = afe->regmap;
332 int i;
333
334 if (pm_runtime_status_suspended(dev) || afe->suspended)
335 return 0;
336
337 if (!afe->reg_back_up)
338 afe->reg_back_up =
339 devm_kcalloc(dev, afe->reg_back_up_list_num,
340 sizeof(unsigned int), GFP_KERNEL);
341
342 for (i = 0; i < afe->reg_back_up_list_num; i++)
343 regmap_read(regmap, afe->reg_back_up_list[i],
344 &afe->reg_back_up[i]);
345
346 afe->suspended = true;
347 afe->runtime_suspend(dev);
348 return 0;
349}
350EXPORT_SYMBOL_GPL(mtk_afe_dai_suspend);
351
352int mtk_afe_dai_resume(struct snd_soc_dai *dai)
353{
354 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
355 struct device *dev = afe->dev;
356 struct regmap *regmap = afe->regmap;
357 int i = 0;
358
359 if (pm_runtime_status_suspended(dev) || !afe->suspended)
360 return 0;
361
362 afe->runtime_resume(dev);
363
364 if (!afe->reg_back_up)
365 dev_dbg(dev, "%s no reg_backup\n", __func__);
366
367 for (i = 0; i < afe->reg_back_up_list_num; i++)
368 mtk_regmap_write(regmap, afe->reg_back_up_list[i],
369 afe->reg_back_up[i]);
370
371 afe->suspended = false;
372 return 0;
373}
374EXPORT_SYMBOL_GPL(mtk_afe_dai_resume);
375
376MODULE_DESCRIPTION("Mediatek simple fe dai operator");
377MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
378MODULE_LICENSE("GPL v2");
379
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.h b/sound/soc/mediatek/common/mtk-afe-fe-dai.h
new file mode 100644
index 000000000000..28cb17854da1
--- /dev/null
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.h
@@ -0,0 +1,45 @@
1/*
2 * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _MTK_AFE_FE_DAI_H_
18#define _MTK_AFE_FE_DAI_H_
19
20struct snd_soc_dai_ops;
21struct mtk_base_afe;
22struct mtk_base_afe_memif;
23
24int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
25 struct snd_soc_dai *dai);
26void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
27 struct snd_soc_dai *dai);
28int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
29 struct snd_pcm_hw_params *params,
30 struct snd_soc_dai *dai);
31int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream,
32 struct snd_soc_dai *dai);
33int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
34 struct snd_soc_dai *dai);
35int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
36 struct snd_soc_dai *dai);
37
38extern const struct snd_soc_dai_ops mtk_afe_fe_ops;
39
40int mtk_dynamic_irq_acquire(struct mtk_base_afe *afe);
41int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id);
42int mtk_afe_dai_suspend(struct snd_soc_dai *dai);
43int mtk_afe_dai_resume(struct snd_soc_dai *dai);
44
45#endif
diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
new file mode 100644
index 000000000000..82d439c15f4e
--- /dev/null
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
@@ -0,0 +1,90 @@
1/*
2 * mtk-afe-platform-driver.c -- Mediatek afe platform driver
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/dma-mapping.h>
19#include <sound/soc.h>
20
21#include "mtk-afe-platform-driver.h"
22#include "mtk-base-afe.h"
23
24static snd_pcm_uframes_t mtk_afe_pcm_pointer
25 (struct snd_pcm_substream *substream)
26{
27 struct snd_soc_pcm_runtime *rtd = substream->private_data;
28 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
29 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
30 const struct mtk_base_memif_data *memif_data = memif->data;
31 struct regmap *regmap = afe->regmap;
32 struct device *dev = afe->dev;
33 int reg_ofs_base = memif_data->reg_ofs_base;
34 int reg_ofs_cur = memif_data->reg_ofs_cur;
35 unsigned int hw_ptr = 0, hw_base = 0;
36 int ret, pcm_ptr_bytes;
37
38 ret = regmap_read(regmap, reg_ofs_cur, &hw_ptr);
39 if (ret || hw_ptr == 0) {
40 dev_err(dev, "%s hw_ptr err\n", __func__);
41 pcm_ptr_bytes = 0;
42 goto POINTER_RETURN_FRAMES;
43 }
44
45 ret = regmap_read(regmap, reg_ofs_base, &hw_base);
46 if (ret || hw_base == 0) {
47 dev_err(dev, "%s hw_ptr err\n", __func__);
48 pcm_ptr_bytes = 0;
49 goto POINTER_RETURN_FRAMES;
50 }
51
52 pcm_ptr_bytes = hw_ptr - hw_base;
53
54POINTER_RETURN_FRAMES:
55 return bytes_to_frames(substream->runtime, pcm_ptr_bytes);
56}
57
58static const struct snd_pcm_ops mtk_afe_pcm_ops = {
59 .ioctl = snd_pcm_lib_ioctl,
60 .pointer = mtk_afe_pcm_pointer,
61};
62
63static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
64{
65 size_t size;
66 struct snd_card *card = rtd->card->snd_card;
67 struct snd_pcm *pcm = rtd->pcm;
68 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
69
70 size = afe->mtk_afe_hardware->buffer_bytes_max;
71 return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
72 card->dev, size, size);
73}
74
75static void mtk_afe_pcm_free(struct snd_pcm *pcm)
76{
77 snd_pcm_lib_preallocate_free_for_all(pcm);
78}
79
80const struct snd_soc_platform_driver mtk_afe_pcm_platform = {
81 .ops = &mtk_afe_pcm_ops,
82 .pcm_new = mtk_afe_pcm_new,
83 .pcm_free = mtk_afe_pcm_free,
84};
85EXPORT_SYMBOL_GPL(mtk_afe_pcm_platform);
86
87MODULE_DESCRIPTION("Mediatek simple platform driver");
88MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
89MODULE_LICENSE("GPL v2");
90
diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.h b/sound/soc/mediatek/common/mtk-afe-platform-driver.h
new file mode 100644
index 000000000000..a973fc9253b4
--- /dev/null
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.h
@@ -0,0 +1,23 @@
1/*
2 * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _MTK_AFE_PLATFORM_DRIVER_H_
18#define _MTK_AFE_PLATFORM_DRIVER_H_
19
20extern const struct snd_soc_platform_driver mtk_afe_pcm_platform;
21
22#endif
23
diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h
new file mode 100644
index 000000000000..3a78f6f17195
--- /dev/null
+++ b/sound/soc/mediatek/common/mtk-base-afe.h
@@ -0,0 +1,104 @@
1/*
2 * mtk-base-afe.h -- Mediatek base afe structure
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _MTK_BASE_AFE_H_
18#define _MTK_BASE_AFE_H_
19
20struct mtk_base_memif_data {
21 int id;
22 const char *name;
23 int reg_ofs_base;
24 int reg_ofs_cur;
25 int fs_reg;
26 int fs_shift;
27 int fs_maskbit;
28 int mono_reg;
29 int mono_shift;
30 int enable_reg;
31 int enable_shift;
32 int hd_reg;
33 int hd_shift;
34 int msb_reg;
35 int msb_shift;
36 int agent_disable_reg;
37 int agent_disable_shift;
38};
39
40struct mtk_base_irq_data {
41 int id;
42 int irq_cnt_reg;
43 int irq_cnt_shift;
44 int irq_cnt_maskbit;
45 int irq_fs_reg;
46 int irq_fs_shift;
47 int irq_fs_maskbit;
48 int irq_en_reg;
49 int irq_en_shift;
50 int irq_clr_reg;
51 int irq_clr_shift;
52};
53
54struct device;
55struct mtk_base_afe_memif;
56struct mtk_base_afe_irq;
57struct regmap;
58struct snd_pcm_substream;
59struct snd_soc_dai;
60
61struct mtk_base_afe {
62 void __iomem *base_addr;
63 struct device *dev;
64 struct regmap *regmap;
65 struct mutex irq_alloc_lock; /* dynamic alloc irq lock */
66
67 unsigned int const *reg_back_up_list;
68 unsigned int *reg_back_up;
69 unsigned int reg_back_up_list_num;
70
71 int (*runtime_suspend)(struct device *dev);
72 int (*runtime_resume)(struct device *dev);
73 bool suspended;
74
75 struct mtk_base_afe_memif *memif;
76 int memif_size;
77 struct mtk_base_afe_irq *irqs;
78 int irqs_size;
79
80 const struct snd_pcm_hardware *mtk_afe_hardware;
81 int (*memif_fs)(struct snd_pcm_substream *substream,
82 unsigned int rate);
83 int (*irq_fs)(struct snd_pcm_substream *substream,
84 unsigned int rate);
85
86 void *platform_priv;
87};
88
89struct mtk_base_afe_memif {
90 unsigned int phys_buf_addr;
91 int buffer_size;
92 struct snd_pcm_substream *substream;
93 const struct mtk_base_memif_data *data;
94 int irq_usage;
95 int const_irq;
96};
97
98struct mtk_base_afe_irq {
99 const struct mtk_base_irq_data *irq_data;
100 int irq_occupyed;
101};
102
103#endif
104
diff --git a/sound/soc/mediatek/mt2701/Makefile b/sound/soc/mediatek/mt2701/Makefile
new file mode 100644
index 000000000000..31c3d04d4942
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/Makefile
@@ -0,0 +1,19 @@
1#
2# Copyright (C) 2015 MediaTek Inc.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License version 2 as
6# published by the Free Software Foundation.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13
14# platform driver
15snd-soc-mt2701-afe-objs := mt2701-afe-pcm.o mt2701-afe-clock-ctrl.o
16obj-$(CONFIG_SND_SOC_MT2701) += snd-soc-mt2701-afe.o
17
18# machine driver
19obj-$(CONFIG_SND_SOC_MT2701_CS42448) += mt2701-cs42448.o
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
new file mode 100644
index 000000000000..b815ecc6bbf6
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
@@ -0,0 +1,464 @@
1/*
2 * mt2701-afe-clock-ctrl.c -- Mediatek 2701 afe clock ctrl
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <sound/soc.h>
18#include <linux/regmap.h>
19#include <linux/pm_runtime.h>
20
21#include "mt2701-afe-common.h"
22#include "mt2701-afe-clock-ctrl.h"
23
24static const char *aud_clks[MT2701_CLOCK_NUM] = {
25 [MT2701_AUD_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
26 [MT2701_AUD_AUD_MUX1_SEL] = "top_audio_mux1_sel",
27 [MT2701_AUD_AUD_MUX2_SEL] = "top_audio_mux2_sel",
28 [MT2701_AUD_AUD_MUX1_DIV] = "top_audio_mux1_div",
29 [MT2701_AUD_AUD_MUX2_DIV] = "top_audio_mux2_div",
30 [MT2701_AUD_AUD_48K_TIMING] = "top_audio_48k_timing",
31 [MT2701_AUD_AUD_44K_TIMING] = "top_audio_44k_timing",
32 [MT2701_AUD_AUDPLL_MUX_SEL] = "top_audpll_mux_sel",
33 [MT2701_AUD_APLL_SEL] = "top_apll_sel",
34 [MT2701_AUD_AUD1PLL_98M] = "top_aud1_pll_98M",
35 [MT2701_AUD_AUD2PLL_90M] = "top_aud2_pll_90M",
36 [MT2701_AUD_HADDS2PLL_98M] = "top_hadds2_pll_98M",
37 [MT2701_AUD_HADDS2PLL_294M] = "top_hadds2_pll_294M",
38 [MT2701_AUD_AUDPLL] = "top_audpll",
39 [MT2701_AUD_AUDPLL_D4] = "top_audpll_d4",
40 [MT2701_AUD_AUDPLL_D8] = "top_audpll_d8",
41 [MT2701_AUD_AUDPLL_D16] = "top_audpll_d16",
42 [MT2701_AUD_AUDPLL_D24] = "top_audpll_d24",
43 [MT2701_AUD_AUDINTBUS] = "top_audintbus_sel",
44 [MT2701_AUD_CLK_26M] = "clk_26m",
45 [MT2701_AUD_SYSPLL1_D4] = "top_syspll1_d4",
46 [MT2701_AUD_AUD_K1_SRC_SEL] = "top_aud_k1_src_sel",
47 [MT2701_AUD_AUD_K2_SRC_SEL] = "top_aud_k2_src_sel",
48 [MT2701_AUD_AUD_K3_SRC_SEL] = "top_aud_k3_src_sel",
49 [MT2701_AUD_AUD_K4_SRC_SEL] = "top_aud_k4_src_sel",
50 [MT2701_AUD_AUD_K5_SRC_SEL] = "top_aud_k5_src_sel",
51 [MT2701_AUD_AUD_K6_SRC_SEL] = "top_aud_k6_src_sel",
52 [MT2701_AUD_AUD_K1_SRC_DIV] = "top_aud_k1_src_div",
53 [MT2701_AUD_AUD_K2_SRC_DIV] = "top_aud_k2_src_div",
54 [MT2701_AUD_AUD_K3_SRC_DIV] = "top_aud_k3_src_div",
55 [MT2701_AUD_AUD_K4_SRC_DIV] = "top_aud_k4_src_div",
56 [MT2701_AUD_AUD_K5_SRC_DIV] = "top_aud_k5_src_div",
57 [MT2701_AUD_AUD_K6_SRC_DIV] = "top_aud_k6_src_div",
58 [MT2701_AUD_AUD_I2S1_MCLK] = "top_aud_i2s1_mclk",
59 [MT2701_AUD_AUD_I2S2_MCLK] = "top_aud_i2s2_mclk",
60 [MT2701_AUD_AUD_I2S3_MCLK] = "top_aud_i2s3_mclk",
61 [MT2701_AUD_AUD_I2S4_MCLK] = "top_aud_i2s4_mclk",
62 [MT2701_AUD_AUD_I2S5_MCLK] = "top_aud_i2s5_mclk",
63 [MT2701_AUD_AUD_I2S6_MCLK] = "top_aud_i2s6_mclk",
64 [MT2701_AUD_ASM_M_SEL] = "top_asm_m_sel",
65 [MT2701_AUD_ASM_H_SEL] = "top_asm_h_sel",
66 [MT2701_AUD_UNIVPLL2_D4] = "top_univpll2_d4",
67 [MT2701_AUD_UNIVPLL2_D2] = "top_univpll2_d2",
68 [MT2701_AUD_SYSPLL_D5] = "top_syspll_d5",
69};
70
71int mt2701_init_clock(struct mtk_base_afe *afe)
72{
73 struct mt2701_afe_private *afe_priv = afe->platform_priv;
74 int i = 0;
75
76 for (i = 0; i < MT2701_CLOCK_NUM; i++) {
77 afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
78 if (IS_ERR(aud_clks[i])) {
79 dev_warn(afe->dev, "%s devm_clk_get %s fail\n",
80 __func__, aud_clks[i]);
81 return PTR_ERR(aud_clks[i]);
82 }
83 }
84
85 return 0;
86}
87
88int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
89{
90 int ret = 0;
91
92 ret = mt2701_turn_on_a1sys_clock(afe);
93 if (ret) {
94 dev_err(afe->dev, "%s turn_on_a1sys_clock fail %d\n",
95 __func__, ret);
96 return ret;
97 }
98
99 ret = mt2701_turn_on_a2sys_clock(afe);
100 if (ret) {
101 dev_err(afe->dev, "%s turn_on_a2sys_clock fail %d\n",
102 __func__, ret);
103 mt2701_turn_off_a1sys_clock(afe);
104 return ret;
105 }
106
107 ret = mt2701_turn_on_afe_clock(afe);
108 if (ret) {
109 dev_err(afe->dev, "%s turn_on_afe_clock fail %d\n",
110 __func__, ret);
111 mt2701_turn_off_a1sys_clock(afe);
112 mt2701_turn_off_a2sys_clock(afe);
113 return ret;
114 }
115
116 regmap_update_bits(afe->regmap, ASYS_TOP_CON,
117 AUDIO_TOP_CON0_A1SYS_A2SYS_ON,
118 AUDIO_TOP_CON0_A1SYS_A2SYS_ON);
119 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
120 AFE_DAC_CON0_AFE_ON,
121 AFE_DAC_CON0_AFE_ON);
122 regmap_write(afe->regmap, PWR2_TOP_CON,
123 PWR2_TOP_CON_INIT_VAL);
124 regmap_write(afe->regmap, PWR1_ASM_CON1,
125 PWR1_ASM_CON1_INIT_VAL);
126 regmap_write(afe->regmap, PWR2_ASM_CON1,
127 PWR2_ASM_CON1_INIT_VAL);
128
129 return 0;
130}
131
132void mt2701_afe_disable_clock(struct mtk_base_afe *afe)
133{
134 mt2701_turn_off_afe_clock(afe);
135 mt2701_turn_off_a1sys_clock(afe);
136 mt2701_turn_off_a2sys_clock(afe);
137 regmap_update_bits(afe->regmap, ASYS_TOP_CON,
138 AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0);
139 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
140 AFE_DAC_CON0_AFE_ON, 0);
141}
142
143int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe)
144{
145 struct mt2701_afe_private *afe_priv = afe->platform_priv;
146 int ret = 0;
147
148 /* Set Mux */
149 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
150 if (ret) {
151 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
152 __func__, aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret);
153 goto A1SYS_CLK_AUD_MUX1_SEL_ERR;
154 }
155
156 ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL],
157 afe_priv->clocks[MT2701_AUD_AUD1PLL_98M]);
158 if (ret) {
159 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
160 aud_clks[MT2701_AUD_AUD_MUX1_SEL],
161 aud_clks[MT2701_AUD_AUD1PLL_98M], ret);
162 goto A1SYS_CLK_AUD_MUX1_SEL_ERR;
163 }
164
165 /* Set Divider */
166 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
167 if (ret) {
168 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
169 __func__,
170 aud_clks[MT2701_AUD_AUD_MUX1_DIV],
171 ret);
172 goto A1SYS_CLK_AUD_MUX1_DIV_ERR;
173 }
174
175 ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV],
176 MT2701_AUD_AUD_MUX1_DIV_RATE);
177 if (ret) {
178 dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__,
179 aud_clks[MT2701_AUD_AUD_MUX1_DIV],
180 MT2701_AUD_AUD_MUX1_DIV_RATE, ret);
181 goto A1SYS_CLK_AUD_MUX1_DIV_ERR;
182 }
183
184 /* Enable clock gate */
185 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
186 if (ret) {
187 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
188 __func__, aud_clks[MT2701_AUD_AUD_48K_TIMING], ret);
189 goto A1SYS_CLK_AUD_48K_ERR;
190 }
191
192 /* Enable infra audio */
193 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
194 if (ret) {
195 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
196 __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
197 goto A1SYS_CLK_INFRA_ERR;
198 }
199
200 return 0;
201
202A1SYS_CLK_INFRA_ERR:
203 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
204A1SYS_CLK_AUD_48K_ERR:
205 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
206A1SYS_CLK_AUD_MUX1_DIV_ERR:
207 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
208A1SYS_CLK_AUD_MUX1_SEL_ERR:
209 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
210
211 return ret;
212}
213
214void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe)
215{
216 struct mt2701_afe_private *afe_priv = afe->platform_priv;
217
218 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
219 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
220 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
221 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
222}
223
224int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe)
225{
226 struct mt2701_afe_private *afe_priv = afe->platform_priv;
227 int ret = 0;
228
229 /* Set Mux */
230 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
231 if (ret) {
232 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
233 __func__, aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret);
234 goto A2SYS_CLK_AUD_MUX2_SEL_ERR;
235 }
236
237 ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL],
238 afe_priv->clocks[MT2701_AUD_AUD2PLL_90M]);
239 if (ret) {
240 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
241 aud_clks[MT2701_AUD_AUD_MUX2_SEL],
242 aud_clks[MT2701_AUD_AUD2PLL_90M], ret);
243 goto A2SYS_CLK_AUD_MUX2_SEL_ERR;
244 }
245
246 /* Set Divider */
247 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
248 if (ret) {
249 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
250 __func__, aud_clks[MT2701_AUD_AUD_MUX2_DIV], ret);
251 goto A2SYS_CLK_AUD_MUX2_DIV_ERR;
252 }
253
254 ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV],
255 MT2701_AUD_AUD_MUX2_DIV_RATE);
256 if (ret) {
257 dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__,
258 aud_clks[MT2701_AUD_AUD_MUX2_DIV],
259 MT2701_AUD_AUD_MUX2_DIV_RATE, ret);
260 goto A2SYS_CLK_AUD_MUX2_DIV_ERR;
261 }
262
263 /* Enable clock gate */
264 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
265 if (ret) {
266 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
267 __func__, aud_clks[MT2701_AUD_AUD_44K_TIMING], ret);
268 goto A2SYS_CLK_AUD_44K_ERR;
269 }
270
271 /* Enable infra audio */
272 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
273 if (ret) {
274 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
275 __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
276 goto A2SYS_CLK_INFRA_ERR;
277 }
278
279 return 0;
280
281A2SYS_CLK_INFRA_ERR:
282 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
283A2SYS_CLK_AUD_44K_ERR:
284 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
285A2SYS_CLK_AUD_MUX2_DIV_ERR:
286 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
287A2SYS_CLK_AUD_MUX2_SEL_ERR:
288 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
289
290 return ret;
291}
292
293void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe)
294{
295 struct mt2701_afe_private *afe_priv = afe->platform_priv;
296
297 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
298 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
299 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
300 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
301}
302
303int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe)
304{
305 struct mt2701_afe_private *afe_priv = afe->platform_priv;
306 int ret;
307
308 /* enable INFRA_SYS */
309 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
310 if (ret) {
311 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
312 __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
313 goto AFE_AUD_INFRA_ERR;
314 }
315
316 /* Set MT2701_AUD_AUDINTBUS to MT2701_AUD_SYSPLL1_D4 */
317 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
318 if (ret) {
319 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
320 __func__, aud_clks[MT2701_AUD_AUDINTBUS], ret);
321 goto AFE_AUD_AUDINTBUS_ERR;
322 }
323
324 ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUDINTBUS],
325 afe_priv->clocks[MT2701_AUD_SYSPLL1_D4]);
326 if (ret) {
327 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
328 aud_clks[MT2701_AUD_AUDINTBUS],
329 aud_clks[MT2701_AUD_SYSPLL1_D4], ret);
330 goto AFE_AUD_AUDINTBUS_ERR;
331 }
332
333 /* Set MT2701_AUD_ASM_H_SEL to MT2701_AUD_UNIVPLL2_D2 */
334 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
335 if (ret) {
336 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
337 __func__, aud_clks[MT2701_AUD_ASM_H_SEL], ret);
338 goto AFE_AUD_ASM_H_ERR;
339 }
340
341 ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_H_SEL],
342 afe_priv->clocks[MT2701_AUD_UNIVPLL2_D2]);
343 if (ret) {
344 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
345 aud_clks[MT2701_AUD_ASM_H_SEL],
346 aud_clks[MT2701_AUD_UNIVPLL2_D2], ret);
347 goto AFE_AUD_ASM_H_ERR;
348 }
349
350 /* Set MT2701_AUD_ASM_M_SEL to MT2701_AUD_UNIVPLL2_D4 */
351 ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
352 if (ret) {
353 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
354 __func__, aud_clks[MT2701_AUD_ASM_M_SEL], ret);
355 goto AFE_AUD_ASM_M_ERR;
356 }
357
358 ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_M_SEL],
359 afe_priv->clocks[MT2701_AUD_UNIVPLL2_D4]);
360 if (ret) {
361 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
362 aud_clks[MT2701_AUD_ASM_M_SEL],
363 aud_clks[MT2701_AUD_UNIVPLL2_D4], ret);
364 goto AFE_AUD_ASM_M_ERR;
365 }
366
367 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
368 AUDIO_TOP_CON0_PDN_AFE, 0);
369 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
370 AUDIO_TOP_CON0_PDN_APLL_CK, 0);
371 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
372 AUDIO_TOP_CON4_PDN_A1SYS, 0);
373 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
374 AUDIO_TOP_CON4_PDN_A2SYS, 0);
375 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
376 AUDIO_TOP_CON4_PDN_AFE_CONN, 0);
377
378 return 0;
379
380AFE_AUD_ASM_M_ERR:
381 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
382AFE_AUD_ASM_H_ERR:
383 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
384AFE_AUD_AUDINTBUS_ERR:
385 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
386AFE_AUD_INFRA_ERR:
387 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
388
389 return ret;
390}
391
392void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe)
393{
394 struct mt2701_afe_private *afe_priv = afe->platform_priv;
395
396 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
397
398 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
399 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
400 clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
401
402 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
403 AUDIO_TOP_CON0_PDN_AFE, AUDIO_TOP_CON0_PDN_AFE);
404 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
405 AUDIO_TOP_CON0_PDN_APLL_CK,
406 AUDIO_TOP_CON0_PDN_APLL_CK);
407 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
408 AUDIO_TOP_CON4_PDN_A1SYS,
409 AUDIO_TOP_CON4_PDN_A1SYS);
410 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
411 AUDIO_TOP_CON4_PDN_A2SYS,
412 AUDIO_TOP_CON4_PDN_A2SYS);
413 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
414 AUDIO_TOP_CON4_PDN_AFE_CONN,
415 AUDIO_TOP_CON4_PDN_AFE_CONN);
416}
417
418void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,
419 int mclk)
420{
421 struct mt2701_afe_private *afe_priv = afe->platform_priv;
422 int ret;
423 int aud_src_div_id = MT2701_AUD_AUD_K1_SRC_DIV + id;
424 int aud_src_clk_id = MT2701_AUD_AUD_K1_SRC_SEL + id;
425
426 /* Set MCLK Kx_SRC_SEL(domain) */
427 ret = clk_prepare_enable(afe_priv->clocks[aud_src_clk_id]);
428 if (ret)
429 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
430 __func__, aud_clks[aud_src_clk_id], ret);
431
432 if (domain == 0) {
433 ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id],
434 afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
435 if (ret)
436 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
437 __func__, aud_clks[aud_src_clk_id],
438 aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret);
439 } else {
440 ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id],
441 afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
442 if (ret)
443 dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
444 __func__, aud_clks[aud_src_clk_id],
445 aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret);
446 }
447 clk_disable_unprepare(afe_priv->clocks[aud_src_clk_id]);
448
449 /* Set MCLK Kx_SRC_DIV(divider) */
450 ret = clk_prepare_enable(afe_priv->clocks[aud_src_div_id]);
451 if (ret)
452 dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
453 __func__, aud_clks[aud_src_div_id], ret);
454
455 ret = clk_set_rate(afe_priv->clocks[aud_src_div_id], mclk);
456 if (ret)
457 dev_err(afe->dev, "%s clk_set_rate %s-%d fail %d\n", __func__,
458 aud_clks[aud_src_div_id], mclk, ret);
459 clk_disable_unprepare(afe_priv->clocks[aud_src_div_id]);
460}
461
462MODULE_DESCRIPTION("MT2701 afe clock control");
463MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
464MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
new file mode 100644
index 000000000000..6497d570cf09
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
@@ -0,0 +1,38 @@
1/*
2 * mt2701-afe-clock-ctrl.h -- Mediatek 2701 afe clock ctrl definition
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _MT2701_AFE_CLOCK_CTRL_H_
18#define _MT2701_AFE_CLOCK_CTRL_H_
19
20struct mtk_base_afe;
21
22int mt2701_init_clock(struct mtk_base_afe *afe);
23int mt2701_afe_enable_clock(struct mtk_base_afe *afe);
24void mt2701_afe_disable_clock(struct mtk_base_afe *afe);
25
26int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe);
27void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe);
28
29int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe);
30void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe);
31
32int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe);
33void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe);
34
35void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,
36 int mclk);
37
38#endif
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
new file mode 100644
index 000000000000..c19430e98adf
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
@@ -0,0 +1,172 @@
1/*
2 * mt2701-afe-common.h -- Mediatek 2701 audio driver definitions
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _MT_2701_AFE_COMMON_H_
18#define _MT_2701_AFE_COMMON_H_
19#include <sound/soc.h>
20#include <linux/clk.h>
21#include <linux/regmap.h>
22#include "mt2701-reg.h"
23#include "../common/mtk-base-afe.h"
24
25#define MT2701_STREAM_DIR_NUM (SNDRV_PCM_STREAM_LAST + 1)
26#define MT2701_PLL_DOMAIN_0_RATE 98304000
27#define MT2701_PLL_DOMAIN_1_RATE 90316800
28#define MT2701_AUD_AUD_MUX1_DIV_RATE (MT2701_PLL_DOMAIN_0_RATE / 2)
29#define MT2701_AUD_AUD_MUX2_DIV_RATE (MT2701_PLL_DOMAIN_1_RATE / 2)
30
31enum {
32 MT2701_I2S_1,
33 MT2701_I2S_2,
34 MT2701_I2S_3,
35 MT2701_I2S_4,
36 MT2701_I2S_NUM,
37};
38
39enum {
40 MT2701_MEMIF_DL1,
41 MT2701_MEMIF_DL2,
42 MT2701_MEMIF_DL3,
43 MT2701_MEMIF_DL4,
44 MT2701_MEMIF_DL5,
45 MT2701_MEMIF_DL_SINGLE_NUM,
46 MT2701_MEMIF_DLM = MT2701_MEMIF_DL_SINGLE_NUM,
47 MT2701_MEMIF_UL1,
48 MT2701_MEMIF_UL2,
49 MT2701_MEMIF_UL3,
50 MT2701_MEMIF_UL4,
51 MT2701_MEMIF_UL5,
52 MT2701_MEMIF_DLBT,
53 MT2701_MEMIF_ULBT,
54 MT2701_MEMIF_NUM,
55 MT2701_IO_I2S = MT2701_MEMIF_NUM,
56 MT2701_IO_2ND_I2S,
57 MT2701_IO_3RD_I2S,
58 MT2701_IO_4TH_I2S,
59 MT2701_IO_5TH_I2S,
60 MT2701_IO_6TH_I2S,
61 MT2701_IO_MRG,
62};
63
64enum {
65 MT2701_IRQ_ASYS_START,
66 MT2701_IRQ_ASYS_IRQ1 = MT2701_IRQ_ASYS_START,
67 MT2701_IRQ_ASYS_IRQ2,
68 MT2701_IRQ_ASYS_IRQ3,
69 MT2701_IRQ_ASYS_END,
70};
71
72/* 2701 clock def */
73enum audio_system_clock_type {
74 MT2701_AUD_INFRA_SYS_AUDIO,
75 MT2701_AUD_AUD_MUX1_SEL,
76 MT2701_AUD_AUD_MUX2_SEL,
77 MT2701_AUD_AUD_MUX1_DIV,
78 MT2701_AUD_AUD_MUX2_DIV,
79 MT2701_AUD_AUD_48K_TIMING,
80 MT2701_AUD_AUD_44K_TIMING,
81 MT2701_AUD_AUDPLL_MUX_SEL,
82 MT2701_AUD_APLL_SEL,
83 MT2701_AUD_AUD1PLL_98M,
84 MT2701_AUD_AUD2PLL_90M,
85 MT2701_AUD_HADDS2PLL_98M,
86 MT2701_AUD_HADDS2PLL_294M,
87 MT2701_AUD_AUDPLL,
88 MT2701_AUD_AUDPLL_D4,
89 MT2701_AUD_AUDPLL_D8,
90 MT2701_AUD_AUDPLL_D16,
91 MT2701_AUD_AUDPLL_D24,
92 MT2701_AUD_AUDINTBUS,
93 MT2701_AUD_CLK_26M,
94 MT2701_AUD_SYSPLL1_D4,
95 MT2701_AUD_AUD_K1_SRC_SEL,
96 MT2701_AUD_AUD_K2_SRC_SEL,
97 MT2701_AUD_AUD_K3_SRC_SEL,
98 MT2701_AUD_AUD_K4_SRC_SEL,
99 MT2701_AUD_AUD_K5_SRC_SEL,
100 MT2701_AUD_AUD_K6_SRC_SEL,
101 MT2701_AUD_AUD_K1_SRC_DIV,
102 MT2701_AUD_AUD_K2_SRC_DIV,
103 MT2701_AUD_AUD_K3_SRC_DIV,
104 MT2701_AUD_AUD_K4_SRC_DIV,
105 MT2701_AUD_AUD_K5_SRC_DIV,
106 MT2701_AUD_AUD_K6_SRC_DIV,
107 MT2701_AUD_AUD_I2S1_MCLK,
108 MT2701_AUD_AUD_I2S2_MCLK,
109 MT2701_AUD_AUD_I2S3_MCLK,
110 MT2701_AUD_AUD_I2S4_MCLK,
111 MT2701_AUD_AUD_I2S5_MCLK,
112 MT2701_AUD_AUD_I2S6_MCLK,
113 MT2701_AUD_ASM_M_SEL,
114 MT2701_AUD_ASM_H_SEL,
115 MT2701_AUD_UNIVPLL2_D4,
116 MT2701_AUD_UNIVPLL2_D2,
117 MT2701_AUD_SYSPLL_D5,
118 MT2701_CLOCK_NUM
119};
120
121static const unsigned int mt2701_afe_backup_list[] = {
122 AUDIO_TOP_CON0,
123 AUDIO_TOP_CON4,
124 AUDIO_TOP_CON5,
125 ASYS_TOP_CON,
126 AFE_CONN0,
127 AFE_CONN1,
128 AFE_CONN2,
129 AFE_CONN3,
130 AFE_CONN15,
131 AFE_CONN16,
132 AFE_CONN17,
133 AFE_CONN18,
134 AFE_CONN19,
135 AFE_CONN20,
136 AFE_CONN21,
137 AFE_CONN22,
138 AFE_DAC_CON0,
139 AFE_MEMIF_PBUF_SIZE,
140};
141
142struct snd_pcm_substream;
143struct mtk_base_irq_data;
144
145struct mt2701_i2s_data {
146 int i2s_ctrl_reg;
147 int i2s_pwn_shift;
148 int i2s_asrc_fs_shift;
149 int i2s_asrc_fs_mask;
150};
151
152enum mt2701_i2s_dir {
153 I2S_OUT,
154 I2S_IN,
155 I2S_DIR_NUM,
156};
157
158struct mt2701_i2s_path {
159 int dai_id;
160 int mclk_rate;
161 int on[I2S_DIR_NUM];
162 int occupied[I2S_DIR_NUM];
163 const struct mt2701_i2s_data *i2s_data[2];
164};
165
166struct mt2701_afe_private {
167 struct clk *clocks[MT2701_CLOCK_NUM];
168 struct mt2701_i2s_path i2s_path[MT2701_I2S_NUM];
169 bool mrg_enable[MT2701_STREAM_DIR_NUM];
170};
171
172#endif
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
new file mode 100644
index 000000000000..34a6123480d3
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -0,0 +1,1656 @@
1/*
2 * Mediatek ALSA SoC AFE platform driver for 2701
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 * Ir Lian <ir.lian@mediatek.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 and
10 * only version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/delay.h>
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/of_address.h>
22#include <linux/pm_runtime.h>
23#include <sound/soc.h>
24
25#include "mt2701-afe-common.h"
26
27#include "mt2701-afe-clock-ctrl.h"
28#include "../common/mtk-afe-platform-driver.h"
29#include "../common/mtk-afe-fe-dai.h"
30
31#define AFE_IRQ_STATUS_BITS 0xff
32
33static const struct snd_pcm_hardware mt2701_afe_hardware = {
34 .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED
35 | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID,
36 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE
37 | SNDRV_PCM_FMTBIT_S32_LE,
38 .period_bytes_min = 1024,
39 .period_bytes_max = 1024 * 256,
40 .periods_min = 4,
41 .periods_max = 1024,
42 .buffer_bytes_max = 1024 * 1024 * 16,
43 .fifo_size = 0,
44};
45
46struct mt2701_afe_rate {
47 unsigned int rate;
48 unsigned int regvalue;
49};
50
51static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
52 { .rate = 8000, .regvalue = 0 },
53 { .rate = 12000, .regvalue = 1 },
54 { .rate = 16000, .regvalue = 2 },
55 { .rate = 24000, .regvalue = 3 },
56 { .rate = 32000, .regvalue = 4 },
57 { .rate = 48000, .regvalue = 5 },
58 { .rate = 96000, .regvalue = 6 },
59 { .rate = 192000, .regvalue = 7 },
60 { .rate = 384000, .regvalue = 8 },
61 { .rate = 7350, .regvalue = 16 },
62 { .rate = 11025, .regvalue = 17 },
63 { .rate = 14700, .regvalue = 18 },
64 { .rate = 22050, .regvalue = 19 },
65 { .rate = 29400, .regvalue = 20 },
66 { .rate = 44100, .regvalue = 21 },
67 { .rate = 88200, .regvalue = 22 },
68 { .rate = 176400, .regvalue = 23 },
69 { .rate = 352800, .regvalue = 24 },
70};
71
72static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
73{
74 int val = num - MT2701_IO_I2S;
75
76 if (val < 0 || val >= MT2701_I2S_NUM) {
77 dev_err(afe->dev, "%s, num not available, num %d, val %d\n",
78 __func__, num, val);
79 return -EINVAL;
80 }
81 return val;
82}
83
84static int mt2701_afe_i2s_fs(unsigned int sample_rate)
85{
86 int i;
87
88 for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++)
89 if (mt2701_afe_i2s_rates[i].rate == sample_rate)
90 return mt2701_afe_i2s_rates[i].regvalue;
91
92 return -EINVAL;
93}
94
95static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
96 struct snd_soc_dai *dai)
97{
98 struct snd_soc_pcm_runtime *rtd = substream->private_data;
99 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
100 struct mt2701_afe_private *afe_priv = afe->platform_priv;
101 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
102 int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num;
103 int ret = 0;
104
105 if (i2s_num < 0)
106 return i2s_num;
107
108 /* enable mclk */
109 ret = clk_prepare_enable(afe_priv->clocks[clk_num]);
110 if (ret)
111 dev_err(afe->dev, "Failed to enable mclk for I2S: %d\n",
112 i2s_num);
113
114 return ret;
115}
116
117static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
118 struct snd_soc_dai *dai,
119 int dir_invert)
120{
121 struct snd_soc_pcm_runtime *rtd = substream->private_data;
122 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
123 struct mt2701_afe_private *afe_priv = afe->platform_priv;
124 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
125 struct mt2701_i2s_path *i2s_path;
126 const struct mt2701_i2s_data *i2s_data;
127 int stream_dir = substream->stream;
128
129 if (i2s_num < 0)
130 return i2s_num;
131
132 i2s_path = &afe_priv->i2s_path[i2s_num];
133
134 if (dir_invert) {
135 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
136 stream_dir = SNDRV_PCM_STREAM_CAPTURE;
137 else
138 stream_dir = SNDRV_PCM_STREAM_PLAYBACK;
139 }
140 i2s_data = i2s_path->i2s_data[stream_dir];
141
142 i2s_path->on[stream_dir]--;
143 if (i2s_path->on[stream_dir] < 0) {
144 dev_warn(afe->dev, "i2s_path->on: %d, dir: %d\n",
145 i2s_path->on[stream_dir], stream_dir);
146 i2s_path->on[stream_dir] = 0;
147 }
148 if (i2s_path->on[stream_dir])
149 return 0;
150
151 /* disable i2s */
152 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
153 ASYS_I2S_CON_I2S_EN, 0);
154 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
155 1 << i2s_data->i2s_pwn_shift,
156 1 << i2s_data->i2s_pwn_shift);
157 return 0;
158}
159
160static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
161 struct snd_soc_dai *dai)
162{
163 struct snd_soc_pcm_runtime *rtd = substream->private_data;
164 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
165 struct mt2701_afe_private *afe_priv = afe->platform_priv;
166 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
167 struct mt2701_i2s_path *i2s_path;
168 int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num;
169
170 if (i2s_num < 0)
171 return;
172
173 i2s_path = &afe_priv->i2s_path[i2s_num];
174
175 if (i2s_path->occupied[substream->stream])
176 i2s_path->occupied[substream->stream] = 0;
177 else
178 goto I2S_UNSTART;
179
180 mt2701_afe_i2s_path_shutdown(substream, dai, 0);
181
182 /* need to disable i2s-out path when disable i2s-in */
183 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
184 mt2701_afe_i2s_path_shutdown(substream, dai, 1);
185
186I2S_UNSTART:
187 /* disable mclk */
188 clk_disable_unprepare(afe_priv->clocks[clk_num]);
189}
190
191static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
192 struct snd_soc_dai *dai,
193 int dir_invert)
194{
195 struct snd_soc_pcm_runtime *rtd = substream->private_data;
196 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
197 struct mt2701_afe_private *afe_priv = afe->platform_priv;
198 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
199 struct mt2701_i2s_path *i2s_path;
200 const struct mt2701_i2s_data *i2s_data;
201 struct snd_pcm_runtime * const runtime = substream->runtime;
202 int reg, fs, w_len = 1; /* now we support bck 64bits only */
203 int stream_dir = substream->stream;
204 unsigned int mask = 0, val = 0;
205
206 if (i2s_num < 0)
207 return i2s_num;
208
209 i2s_path = &afe_priv->i2s_path[i2s_num];
210
211 if (dir_invert) {
212 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
213 stream_dir = SNDRV_PCM_STREAM_CAPTURE;
214 else
215 stream_dir = SNDRV_PCM_STREAM_PLAYBACK;
216 }
217 i2s_data = i2s_path->i2s_data[stream_dir];
218
219 /* no need to enable if already done */
220 i2s_path->on[stream_dir]++;
221
222 if (i2s_path->on[stream_dir] != 1)
223 return 0;
224
225 fs = mt2701_afe_i2s_fs(runtime->rate);
226
227 mask = ASYS_I2S_CON_FS |
228 ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */
229 ASYS_I2S_CON_I2S_MODE |
230 ASYS_I2S_CON_WIDE_MODE;
231
232 val = ASYS_I2S_CON_FS_SET(fs) |
233 ASYS_I2S_CON_I2S_MODE |
234 ASYS_I2S_CON_WIDE_MODE_SET(w_len);
235
236 if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) {
237 mask |= ASYS_I2S_IN_PHASE_FIX;
238 val |= ASYS_I2S_IN_PHASE_FIX;
239 }
240
241 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val);
242
243 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
244 reg = ASMO_TIMING_CON1;
245 else
246 reg = ASMI_TIMING_CON1;
247
248 regmap_update_bits(afe->regmap, reg,
249 i2s_data->i2s_asrc_fs_mask
250 << i2s_data->i2s_asrc_fs_shift,
251 fs << i2s_data->i2s_asrc_fs_shift);
252
253 /* enable i2s */
254 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
255 1 << i2s_data->i2s_pwn_shift,
256 0 << i2s_data->i2s_pwn_shift);
257
258 /* reset i2s hw status before enable */
259 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
260 ASYS_I2S_CON_RESET, ASYS_I2S_CON_RESET);
261 udelay(1);
262 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
263 ASYS_I2S_CON_RESET, 0);
264 udelay(1);
265 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
266 ASYS_I2S_CON_I2S_EN, ASYS_I2S_CON_I2S_EN);
267 return 0;
268}
269
270static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
271 struct snd_soc_dai *dai)
272{
273 int clk_domain;
274 struct snd_soc_pcm_runtime *rtd = substream->private_data;
275 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
276 struct mt2701_afe_private *afe_priv = afe->platform_priv;
277 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
278 struct mt2701_i2s_path *i2s_path;
279 int mclk_rate;
280
281 if (i2s_num < 0)
282 return i2s_num;
283
284 i2s_path = &afe_priv->i2s_path[i2s_num];
285 mclk_rate = i2s_path->mclk_rate;
286
287 if (i2s_path->occupied[substream->stream])
288 return -EBUSY;
289 i2s_path->occupied[substream->stream] = 1;
290
291 if (MT2701_PLL_DOMAIN_0_RATE % mclk_rate == 0) {
292 clk_domain = 0;
293 } else if (MT2701_PLL_DOMAIN_1_RATE % mclk_rate == 0) {
294 clk_domain = 1;
295 } else {
296 dev_err(dai->dev, "%s() bad mclk rate %d\n",
297 __func__, mclk_rate);
298 return -EINVAL;
299 }
300 mt2701_mclk_configuration(afe, i2s_num, clk_domain, mclk_rate);
301
302 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
303 mt2701_i2s_path_prepare_enable(substream, dai, 0);
304 } else {
305 /* need to enable i2s-out path when enable i2s-in */
306 /* prepare for another direction "out" */
307 mt2701_i2s_path_prepare_enable(substream, dai, 1);
308 /* prepare for "in" */
309 mt2701_i2s_path_prepare_enable(substream, dai, 0);
310 }
311
312 return 0;
313}
314
315static int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
316 unsigned int freq, int dir)
317{
318 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
319 struct mt2701_afe_private *afe_priv = afe->platform_priv;
320 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
321
322 if (i2s_num < 0)
323 return i2s_num;
324
325 /* mclk */
326 if (dir == SND_SOC_CLOCK_IN) {
327 dev_warn(dai->dev,
328 "%s() warning: mt2701 doesn't support mclk input\n",
329 __func__);
330 return -EINVAL;
331 }
332 afe_priv->i2s_path[i2s_num].mclk_rate = freq;
333 return 0;
334}
335
336static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
337 struct snd_soc_dai *dai)
338{
339 struct snd_soc_pcm_runtime *rtd = substream->private_data;
340 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
341 struct mt2701_afe_private *afe_priv = afe->platform_priv;
342
343 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
344 AUDIO_TOP_CON4_PDN_MRGIF, 0);
345
346 afe_priv->mrg_enable[substream->stream] = 1;
347 return 0;
348}
349
350static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
351 struct snd_pcm_hw_params *params,
352 struct snd_soc_dai *dai)
353{
354 struct snd_soc_pcm_runtime *rtd = substream->private_data;
355 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
356 int stream_fs;
357 u32 val, msk;
358
359 stream_fs = params_rate(params);
360
361 if ((stream_fs != 8000) && (stream_fs != 16000)) {
362 dev_err(afe->dev, "%s() btmgr not supprt this stream_fs %d\n",
363 __func__, stream_fs);
364 return -EINVAL;
365 }
366
367 regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
368 AFE_MRGIF_CON_I2S_MODE_MASK,
369 AFE_MRGIF_CON_I2S_MODE_32K);
370
371 val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY
372 | AFE_DAIBT_CON0_MRG_USE;
373 msk = val;
374
375 if (stream_fs == 16000)
376 val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
377
378 msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
379
380 regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val);
381
382 regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
383 AFE_DAIBT_CON0_DAIBT_EN,
384 AFE_DAIBT_CON0_DAIBT_EN);
385 regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
386 AFE_MRGIF_CON_MRG_I2S_EN,
387 AFE_MRGIF_CON_MRG_I2S_EN);
388 regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
389 AFE_MRGIF_CON_MRG_EN,
390 AFE_MRGIF_CON_MRG_EN);
391 return 0;
392}
393
394static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
395 struct snd_soc_dai *dai)
396{
397 struct snd_soc_pcm_runtime *rtd = substream->private_data;
398 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
399 struct mt2701_afe_private *afe_priv = afe->platform_priv;
400
401 /* if the other direction stream is not occupied */
402 if (!afe_priv->mrg_enable[!substream->stream]) {
403 regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
404 AFE_DAIBT_CON0_DAIBT_EN, 0);
405 regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
406 AFE_MRGIF_CON_MRG_EN, 0);
407 regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
408 AFE_MRGIF_CON_MRG_I2S_EN, 0);
409 regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
410 AUDIO_TOP_CON4_PDN_MRGIF,
411 AUDIO_TOP_CON4_PDN_MRGIF);
412 }
413 afe_priv->mrg_enable[substream->stream] = 0;
414}
415
416static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
417 struct snd_soc_dai *dai)
418{
419 struct snd_soc_pcm_runtime *rtd = substream->private_data;
420 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
421 int stream_dir = substream->stream;
422 int memif_num = rtd->cpu_dai->id;
423 struct mtk_base_afe_memif *memif_tmp;
424
425 /* can't run single DL & DLM at the same time */
426 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) {
427 memif_tmp = &afe->memif[MT2701_MEMIF_DLM];
428 if (memif_tmp->substream) {
429 dev_warn(afe->dev, "%s memif is not available, stream_dir %d, memif_num %d\n",
430 __func__, stream_dir, memif_num);
431 return -EBUSY;
432 }
433 }
434 return mtk_afe_fe_startup(substream, dai);
435}
436
437static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream,
438 struct snd_pcm_hw_params *params,
439 struct snd_soc_dai *dai)
440{
441 struct snd_soc_pcm_runtime *rtd = substream->private_data;
442 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
443 int stream_dir = substream->stream;
444
445 /* single DL use PAIR_INTERLEAVE */
446 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) {
447 regmap_update_bits(afe->regmap,
448 AFE_MEMIF_PBUF_SIZE,
449 AFE_MEMIF_PBUF_SIZE_DLM_MASK,
450 AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE);
451 }
452 return mtk_afe_fe_hw_params(substream, params, dai);
453}
454
455static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,
456 struct snd_soc_dai *dai)
457{
458 struct snd_soc_pcm_runtime *rtd = substream->private_data;
459 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
460 struct mtk_base_afe_memif *memif_tmp;
461 const struct mtk_base_memif_data *memif_data;
462 int i;
463
464 for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
465 memif_tmp = &afe->memif[i];
466 if (memif_tmp->substream)
467 return -EBUSY;
468 }
469
470 /* enable agent for all signal DL (due to hw design) */
471 for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
472 memif_data = afe->memif[i].data;
473 regmap_update_bits(afe->regmap,
474 memif_data->agent_disable_reg,
475 1 << memif_data->agent_disable_shift,
476 0 << memif_data->agent_disable_shift);
477 }
478
479 return mtk_afe_fe_startup(substream, dai);
480}
481
482static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,
483 struct snd_soc_dai *dai)
484{
485 struct snd_soc_pcm_runtime *rtd = substream->private_data;
486 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
487 const struct mtk_base_memif_data *memif_data;
488 int i;
489
490 for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
491 memif_data = afe->memif[i].data;
492 regmap_update_bits(afe->regmap,
493 memif_data->agent_disable_reg,
494 1 << memif_data->agent_disable_shift,
495 1 << memif_data->agent_disable_shift);
496 }
497 return mtk_afe_fe_shutdown(substream, dai);
498}
499
500static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,
501 struct snd_pcm_hw_params *params,
502 struct snd_soc_dai *dai)
503{
504 struct snd_soc_pcm_runtime *rtd = substream->private_data;
505 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
506 int channels = params_channels(params);
507
508 regmap_update_bits(afe->regmap,
509 AFE_MEMIF_PBUF_SIZE,
510 AFE_MEMIF_PBUF_SIZE_DLM_MASK,
511 AFE_MEMIF_PBUF_SIZE_FULL_INTERLEAVE);
512 regmap_update_bits(afe->regmap,
513 AFE_MEMIF_PBUF_SIZE,
514 AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK,
515 AFE_MEMIF_PBUF_SIZE_DLM_32BYTES);
516 regmap_update_bits(afe->regmap,
517 AFE_MEMIF_PBUF_SIZE,
518 AFE_MEMIF_PBUF_SIZE_DLM_CH_MASK,
519 AFE_MEMIF_PBUF_SIZE_DLM_CH(channels));
520
521 return mtk_afe_fe_hw_params(substream, params, dai);
522}
523
524static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream,
525 int cmd, struct snd_soc_dai *dai)
526{
527 struct snd_soc_pcm_runtime *rtd = substream->private_data;
528 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
529 struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1];
530
531 switch (cmd) {
532 case SNDRV_PCM_TRIGGER_START:
533 case SNDRV_PCM_TRIGGER_RESUME:
534 regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,
535 1 << memif_tmp->data->enable_shift,
536 1 << memif_tmp->data->enable_shift);
537 mtk_afe_fe_trigger(substream, cmd, dai);
538 return 0;
539 case SNDRV_PCM_TRIGGER_STOP:
540 case SNDRV_PCM_TRIGGER_SUSPEND:
541 mtk_afe_fe_trigger(substream, cmd, dai);
542 regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,
543 1 << memif_tmp->data->enable_shift, 0);
544
545 return 0;
546 default:
547 return -EINVAL;
548 }
549}
550
551static int mt2701_memif_fs(struct snd_pcm_substream *substream,
552 unsigned int rate)
553{
554 struct snd_soc_pcm_runtime *rtd = substream->private_data;
555 int fs;
556
557 if (rtd->cpu_dai->id != MT2701_MEMIF_ULBT)
558 fs = mt2701_afe_i2s_fs(rate);
559 else
560 fs = (rate == 16000 ? 1 : 0);
561 return fs;
562}
563
564static int mt2701_irq_fs(struct snd_pcm_substream *substream, unsigned int rate)
565{
566 return mt2701_afe_i2s_fs(rate);
567}
568
569/* FE DAIs */
570static const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = {
571 .startup = mt2701_simple_fe_startup,
572 .shutdown = mtk_afe_fe_shutdown,
573 .hw_params = mt2701_simple_fe_hw_params,
574 .hw_free = mtk_afe_fe_hw_free,
575 .prepare = mtk_afe_fe_prepare,
576 .trigger = mtk_afe_fe_trigger,
577
578};
579
580static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = {
581 .startup = mt2701_dlm_fe_startup,
582 .shutdown = mt2701_dlm_fe_shutdown,
583 .hw_params = mt2701_dlm_fe_hw_params,
584 .hw_free = mtk_afe_fe_hw_free,
585 .prepare = mtk_afe_fe_prepare,
586 .trigger = mt2701_dlm_fe_trigger,
587};
588
589/* I2S BE DAIs */
590static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = {
591 .startup = mt2701_afe_i2s_startup,
592 .shutdown = mt2701_afe_i2s_shutdown,
593 .prepare = mt2701_afe_i2s_prepare,
594 .set_sysclk = mt2701_afe_i2s_set_sysclk,
595};
596
597/* MRG BE DAIs */
598static struct snd_soc_dai_ops mt2701_btmrg_ops = {
599 .startup = mt2701_btmrg_startup,
600 .shutdown = mt2701_btmrg_shutdown,
601 .hw_params = mt2701_btmrg_hw_params,
602};
603
604static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
605 /* FE DAIs: memory intefaces to CPU */
606 {
607 .name = "PCM_multi",
608 .id = MT2701_MEMIF_DLM,
609 .suspend = mtk_afe_dai_suspend,
610 .resume = mtk_afe_dai_resume,
611 .playback = {
612 .stream_name = "DLM",
613 .channels_min = 1,
614 .channels_max = 8,
615 .rates = SNDRV_PCM_RATE_8000_192000,
616 .formats = (SNDRV_PCM_FMTBIT_S16_LE
617 | SNDRV_PCM_FMTBIT_S24_LE
618 | SNDRV_PCM_FMTBIT_S32_LE)
619
620 },
621 .ops = &mt2701_dlm_memif_dai_ops,
622 },
623 {
624 .name = "PCM0",
625 .id = MT2701_MEMIF_UL1,
626 .suspend = mtk_afe_dai_suspend,
627 .resume = mtk_afe_dai_resume,
628 .capture = {
629 .stream_name = "UL1",
630 .channels_min = 1,
631 .channels_max = 2,
632 .rates = SNDRV_PCM_RATE_8000_48000,
633 .formats = (SNDRV_PCM_FMTBIT_S16_LE
634 | SNDRV_PCM_FMTBIT_S24_LE
635 | SNDRV_PCM_FMTBIT_S32_LE)
636 },
637 .ops = &mt2701_single_memif_dai_ops,
638 },
639 {
640 .name = "PCM1",
641 .id = MT2701_MEMIF_UL2,
642 .suspend = mtk_afe_dai_suspend,
643 .resume = mtk_afe_dai_resume,
644 .capture = {
645 .stream_name = "UL2",
646 .channels_min = 1,
647 .channels_max = 2,
648 .rates = SNDRV_PCM_RATE_8000_192000,
649 .formats = (SNDRV_PCM_FMTBIT_S16_LE
650 | SNDRV_PCM_FMTBIT_S24_LE
651 | SNDRV_PCM_FMTBIT_S32_LE)
652
653 },
654 .ops = &mt2701_single_memif_dai_ops,
655 },
656 {
657 .name = "PCM_BT_DL",
658 .id = MT2701_MEMIF_DLBT,
659 .suspend = mtk_afe_dai_suspend,
660 .resume = mtk_afe_dai_resume,
661 .playback = {
662 .stream_name = "DLBT",
663 .channels_min = 1,
664 .channels_max = 1,
665 .rates = (SNDRV_PCM_RATE_8000
666 | SNDRV_PCM_RATE_16000),
667 .formats = SNDRV_PCM_FMTBIT_S16_LE,
668 },
669 .ops = &mt2701_single_memif_dai_ops,
670 },
671 {
672 .name = "PCM_BT_UL",
673 .id = MT2701_MEMIF_ULBT,
674 .suspend = mtk_afe_dai_suspend,
675 .resume = mtk_afe_dai_resume,
676 .capture = {
677 .stream_name = "ULBT",
678 .channels_min = 1,
679 .channels_max = 1,
680 .rates = (SNDRV_PCM_RATE_8000
681 | SNDRV_PCM_RATE_16000),
682 .formats = SNDRV_PCM_FMTBIT_S16_LE,
683 },
684 .ops = &mt2701_single_memif_dai_ops,
685 },
686 /* BE DAIs */
687 {
688 .name = "I2S0",
689 .id = MT2701_IO_I2S,
690 .playback = {
691 .stream_name = "I2S0 Playback",
692 .channels_min = 1,
693 .channels_max = 2,
694 .rates = SNDRV_PCM_RATE_8000_192000,
695 .formats = (SNDRV_PCM_FMTBIT_S16_LE
696 | SNDRV_PCM_FMTBIT_S24_LE
697 | SNDRV_PCM_FMTBIT_S32_LE)
698
699 },
700 .capture = {
701 .stream_name = "I2S0 Capture",
702 .channels_min = 1,
703 .channels_max = 2,
704 .rates = SNDRV_PCM_RATE_8000_192000,
705 .formats = (SNDRV_PCM_FMTBIT_S16_LE
706 | SNDRV_PCM_FMTBIT_S24_LE
707 | SNDRV_PCM_FMTBIT_S32_LE)
708
709 },
710 .ops = &mt2701_afe_i2s_ops,
711 .symmetric_rates = 1,
712 },
713 {
714 .name = "I2S1",
715 .id = MT2701_IO_2ND_I2S,
716 .playback = {
717 .stream_name = "I2S1 Playback",
718 .channels_min = 1,
719 .channels_max = 2,
720 .rates = SNDRV_PCM_RATE_8000_192000,
721 .formats = (SNDRV_PCM_FMTBIT_S16_LE
722 | SNDRV_PCM_FMTBIT_S24_LE
723 | SNDRV_PCM_FMTBIT_S32_LE)
724 },
725 .capture = {
726 .stream_name = "I2S1 Capture",
727 .channels_min = 1,
728 .channels_max = 2,
729 .rates = SNDRV_PCM_RATE_8000_192000,
730 .formats = (SNDRV_PCM_FMTBIT_S16_LE
731 | SNDRV_PCM_FMTBIT_S24_LE
732 | SNDRV_PCM_FMTBIT_S32_LE)
733 },
734 .ops = &mt2701_afe_i2s_ops,
735 .symmetric_rates = 1,
736 },
737 {
738 .name = "I2S2",
739 .id = MT2701_IO_3RD_I2S,
740 .playback = {
741 .stream_name = "I2S2 Playback",
742 .channels_min = 1,
743 .channels_max = 2,
744 .rates = SNDRV_PCM_RATE_8000_192000,
745 .formats = (SNDRV_PCM_FMTBIT_S16_LE
746 | SNDRV_PCM_FMTBIT_S24_LE
747 | SNDRV_PCM_FMTBIT_S32_LE)
748 },
749 .capture = {
750 .stream_name = "I2S2 Capture",
751 .channels_min = 1,
752 .channels_max = 2,
753 .rates = SNDRV_PCM_RATE_8000_192000,
754 .formats = (SNDRV_PCM_FMTBIT_S16_LE
755 | SNDRV_PCM_FMTBIT_S24_LE
756 | SNDRV_PCM_FMTBIT_S32_LE)
757 },
758 .ops = &mt2701_afe_i2s_ops,
759 .symmetric_rates = 1,
760 },
761 {
762 .name = "I2S3",
763 .id = MT2701_IO_4TH_I2S,
764 .playback = {
765 .stream_name = "I2S3 Playback",
766 .channels_min = 1,
767 .channels_max = 2,
768 .rates = SNDRV_PCM_RATE_8000_192000,
769 .formats = (SNDRV_PCM_FMTBIT_S16_LE
770 | SNDRV_PCM_FMTBIT_S24_LE
771 | SNDRV_PCM_FMTBIT_S32_LE)
772 },
773 .capture = {
774 .stream_name = "I2S3 Capture",
775 .channels_min = 1,
776 .channels_max = 2,
777 .rates = SNDRV_PCM_RATE_8000_192000,
778 .formats = (SNDRV_PCM_FMTBIT_S16_LE
779 | SNDRV_PCM_FMTBIT_S24_LE
780 | SNDRV_PCM_FMTBIT_S32_LE)
781 },
782 .ops = &mt2701_afe_i2s_ops,
783 .symmetric_rates = 1,
784 },
785 {
786 .name = "MRG BT",
787 .id = MT2701_IO_MRG,
788 .playback = {
789 .stream_name = "BT Playback",
790 .channels_min = 1,
791 .channels_max = 1,
792 .rates = (SNDRV_PCM_RATE_8000
793 | SNDRV_PCM_RATE_16000),
794 .formats = SNDRV_PCM_FMTBIT_S16_LE,
795 },
796 .capture = {
797 .stream_name = "BT Capture",
798 .channels_min = 1,
799 .channels_max = 1,
800 .rates = (SNDRV_PCM_RATE_8000
801 | SNDRV_PCM_RATE_16000),
802 .formats = SNDRV_PCM_FMTBIT_S16_LE,
803 },
804 .ops = &mt2701_btmrg_ops,
805 .symmetric_rates = 1,
806 }
807};
808
809static const struct snd_kcontrol_new mt2701_afe_o00_mix[] = {
810 SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN0, 0, 1, 0),
811};
812
813static const struct snd_kcontrol_new mt2701_afe_o01_mix[] = {
814 SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN1, 1, 1, 0),
815};
816
817static const struct snd_kcontrol_new mt2701_afe_o02_mix[] = {
818 SOC_DAPM_SINGLE_AUTODISABLE("I02 Switch", AFE_CONN2, 2, 1, 0),
819};
820
821static const struct snd_kcontrol_new mt2701_afe_o03_mix[] = {
822 SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 3, 1, 0),
823};
824
825static const struct snd_kcontrol_new mt2701_afe_o14_mix[] = {
826 SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN14, 26, 1, 0),
827};
828
829static const struct snd_kcontrol_new mt2701_afe_o15_mix[] = {
830 SOC_DAPM_SINGLE_AUTODISABLE("I12 Switch", AFE_CONN15, 12, 1, 0),
831};
832
833static const struct snd_kcontrol_new mt2701_afe_o16_mix[] = {
834 SOC_DAPM_SINGLE_AUTODISABLE("I13 Switch", AFE_CONN16, 13, 1, 0),
835};
836
837static const struct snd_kcontrol_new mt2701_afe_o17_mix[] = {
838 SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0),
839};
840
841static const struct snd_kcontrol_new mt2701_afe_o18_mix[] = {
842 SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0),
843};
844
845static const struct snd_kcontrol_new mt2701_afe_o19_mix[] = {
846 SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0),
847};
848
849static const struct snd_kcontrol_new mt2701_afe_o20_mix[] = {
850 SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0),
851};
852
853static const struct snd_kcontrol_new mt2701_afe_o21_mix[] = {
854 SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0),
855};
856
857static const struct snd_kcontrol_new mt2701_afe_o22_mix[] = {
858 SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0),
859};
860
861static const struct snd_kcontrol_new mt2701_afe_o23_mix[] = {
862 SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN23, 20, 1, 0),
863};
864
865static const struct snd_kcontrol_new mt2701_afe_o24_mix[] = {
866 SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN24, 21, 1, 0),
867};
868
869static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = {
870 SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0),
871};
872
873static const struct snd_kcontrol_new mt2701_afe_i02_mix[] = {
874 SOC_DAPM_SINGLE("I2S0 Switch", SND_SOC_NOPM, 0, 1, 0),
875};
876
877static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s0[] = {
878 SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S0 Out Switch",
879 ASYS_I2SO1_CON, 26, 1, 0),
880};
881
882static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s1[] = {
883 SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S1 Out Switch",
884 ASYS_I2SO2_CON, 26, 1, 0),
885};
886
887static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s2[] = {
888 SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S2 Out Switch",
889 PWR2_TOP_CON, 17, 1, 0),
890};
891
892static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = {
893 SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S3 Out Switch",
894 PWR2_TOP_CON, 18, 1, 0),
895};
896
897static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s4[] = {
898 SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S4 Out Switch",
899 PWR2_TOP_CON, 19, 1, 0),
900};
901
902static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc0[] = {
903 SOC_DAPM_SINGLE_AUTODISABLE("Asrc0 out Switch", AUDIO_TOP_CON4, 14, 1,
904 1),
905};
906
907static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc1[] = {
908 SOC_DAPM_SINGLE_AUTODISABLE("Asrc1 out Switch", AUDIO_TOP_CON4, 15, 1,
909 1),
910};
911
912static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc2[] = {
913 SOC_DAPM_SINGLE_AUTODISABLE("Asrc2 out Switch", PWR2_TOP_CON, 6, 1,
914 1),
915};
916
917static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc3[] = {
918 SOC_DAPM_SINGLE_AUTODISABLE("Asrc3 out Switch", PWR2_TOP_CON, 7, 1,
919 1),
920};
921
922static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc4[] = {
923 SOC_DAPM_SINGLE_AUTODISABLE("Asrc4 out Switch", PWR2_TOP_CON, 8, 1,
924 1),
925};
926
927static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = {
928 /* inter-connections */
929 SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0),
930 SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0),
931 SND_SOC_DAPM_MIXER("I02", SND_SOC_NOPM, 0, 0, mt2701_afe_i02_mix,
932 ARRAY_SIZE(mt2701_afe_i02_mix)),
933 SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),
934 SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0),
935 SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0),
936 SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0),
937 SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0),
938 SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0),
939 SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),
940 SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0),
941 SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0),
942 SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0),
943 SND_SOC_DAPM_MIXER("I35", SND_SOC_NOPM, 0, 0, NULL, 0),
944
945 SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0, mt2701_afe_o00_mix,
946 ARRAY_SIZE(mt2701_afe_o00_mix)),
947 SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0, mt2701_afe_o01_mix,
948 ARRAY_SIZE(mt2701_afe_o01_mix)),
949 SND_SOC_DAPM_MIXER("O02", SND_SOC_NOPM, 0, 0, mt2701_afe_o02_mix,
950 ARRAY_SIZE(mt2701_afe_o02_mix)),
951 SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, mt2701_afe_o03_mix,
952 ARRAY_SIZE(mt2701_afe_o03_mix)),
953 SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0, mt2701_afe_o14_mix,
954 ARRAY_SIZE(mt2701_afe_o14_mix)),
955 SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0, mt2701_afe_o15_mix,
956 ARRAY_SIZE(mt2701_afe_o15_mix)),
957 SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0, mt2701_afe_o16_mix,
958 ARRAY_SIZE(mt2701_afe_o16_mix)),
959 SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0, mt2701_afe_o17_mix,
960 ARRAY_SIZE(mt2701_afe_o17_mix)),
961 SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0, mt2701_afe_o18_mix,
962 ARRAY_SIZE(mt2701_afe_o18_mix)),
963 SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0, mt2701_afe_o19_mix,
964 ARRAY_SIZE(mt2701_afe_o19_mix)),
965 SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0, mt2701_afe_o20_mix,
966 ARRAY_SIZE(mt2701_afe_o20_mix)),
967 SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0, mt2701_afe_o21_mix,
968 ARRAY_SIZE(mt2701_afe_o21_mix)),
969 SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0, mt2701_afe_o22_mix,
970 ARRAY_SIZE(mt2701_afe_o22_mix)),
971 SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0, mt2701_afe_o31_mix,
972 ARRAY_SIZE(mt2701_afe_o31_mix)),
973
974 SND_SOC_DAPM_MIXER("I12I13", SND_SOC_NOPM, 0, 0,
975 mt2701_afe_multi_ch_out_i2s0,
976 ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s0)),
977 SND_SOC_DAPM_MIXER("I14I15", SND_SOC_NOPM, 0, 0,
978 mt2701_afe_multi_ch_out_i2s1,
979 ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s1)),
980 SND_SOC_DAPM_MIXER("I16I17", SND_SOC_NOPM, 0, 0,
981 mt2701_afe_multi_ch_out_i2s2,
982 ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s2)),
983 SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0,
984 mt2701_afe_multi_ch_out_i2s3,
985 ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)),
986
987 SND_SOC_DAPM_MIXER("ASRC_O0", SND_SOC_NOPM, 0, 0,
988 mt2701_afe_multi_ch_out_asrc0,
989 ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc0)),
990 SND_SOC_DAPM_MIXER("ASRC_O1", SND_SOC_NOPM, 0, 0,
991 mt2701_afe_multi_ch_out_asrc1,
992 ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc1)),
993 SND_SOC_DAPM_MIXER("ASRC_O2", SND_SOC_NOPM, 0, 0,
994 mt2701_afe_multi_ch_out_asrc2,
995 ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc2)),
996 SND_SOC_DAPM_MIXER("ASRC_O3", SND_SOC_NOPM, 0, 0,
997 mt2701_afe_multi_ch_out_asrc3,
998 ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc3)),
999};
1000
1001static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
1002 {"I12", NULL, "DL1"},
1003 {"I13", NULL, "DL1"},
1004 {"I35", NULL, "DLBT"},
1005
1006 {"I2S0 Playback", NULL, "O15"},
1007 {"I2S0 Playback", NULL, "O16"},
1008
1009 {"I2S1 Playback", NULL, "O17"},
1010 {"I2S1 Playback", NULL, "O18"},
1011 {"I2S2 Playback", NULL, "O19"},
1012 {"I2S2 Playback", NULL, "O20"},
1013 {"I2S3 Playback", NULL, "O21"},
1014 {"I2S3 Playback", NULL, "O22"},
1015 {"BT Playback", NULL, "O31"},
1016
1017 {"UL1", NULL, "O00"},
1018 {"UL1", NULL, "O01"},
1019 {"UL2", NULL, "O02"},
1020 {"UL2", NULL, "O03"},
1021 {"ULBT", NULL, "O14"},
1022
1023 {"I00", NULL, "I2S0 Capture"},
1024 {"I01", NULL, "I2S0 Capture"},
1025
1026 {"I02", NULL, "I2S1 Capture"},
1027 {"I03", NULL, "I2S1 Capture"},
1028 /* I02,03 link to UL2, also need to open I2S0 */
1029 {"I02", "I2S0 Switch", "I2S0 Capture"},
1030
1031 {"I26", NULL, "BT Capture"},
1032
1033 {"ASRC_O0", "Asrc0 out Switch", "DLM"},
1034 {"ASRC_O1", "Asrc1 out Switch", "DLM"},
1035 {"ASRC_O2", "Asrc2 out Switch", "DLM"},
1036 {"ASRC_O3", "Asrc3 out Switch", "DLM"},
1037
1038 {"I12I13", "Multich I2S0 Out Switch", "ASRC_O0"},
1039 {"I14I15", "Multich I2S1 Out Switch", "ASRC_O1"},
1040 {"I16I17", "Multich I2S2 Out Switch", "ASRC_O2"},
1041 {"I18I19", "Multich I2S3 Out Switch", "ASRC_O3"},
1042
1043 { "I12", NULL, "I12I13" },
1044 { "I13", NULL, "I12I13" },
1045 { "I14", NULL, "I14I15" },
1046 { "I15", NULL, "I14I15" },
1047 { "I16", NULL, "I16I17" },
1048 { "I17", NULL, "I16I17" },
1049 { "I18", NULL, "I18I19" },
1050 { "I19", NULL, "I18I19" },
1051
1052 { "O00", "I00 Switch", "I00" },
1053 { "O01", "I01 Switch", "I01" },
1054 { "O02", "I02 Switch", "I02" },
1055 { "O03", "I03 Switch", "I03" },
1056 { "O14", "I26 Switch", "I26" },
1057 { "O15", "I12 Switch", "I12" },
1058 { "O16", "I13 Switch", "I13" },
1059 { "O17", "I14 Switch", "I14" },
1060 { "O18", "I15 Switch", "I15" },
1061 { "O19", "I16 Switch", "I16" },
1062 { "O20", "I17 Switch", "I17" },
1063 { "O21", "I18 Switch", "I18" },
1064 { "O22", "I19 Switch", "I19" },
1065 { "O31", "I35 Switch", "I35" },
1066
1067};
1068
1069static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = {
1070 .name = "mt2701-afe-pcm-dai",
1071 .dapm_widgets = mt2701_afe_pcm_widgets,
1072 .num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets),
1073 .dapm_routes = mt2701_afe_pcm_routes,
1074 .num_dapm_routes = ARRAY_SIZE(mt2701_afe_pcm_routes),
1075};
1076
1077static const struct mtk_base_memif_data memif_data[MT2701_MEMIF_NUM] = {
1078 {
1079 .name = "DL1",
1080 .id = MT2701_MEMIF_DL1,
1081 .reg_ofs_base = AFE_DL1_BASE,
1082 .reg_ofs_cur = AFE_DL1_CUR,
1083 .fs_reg = AFE_DAC_CON1,
1084 .fs_shift = 0,
1085 .fs_maskbit = 0x1f,
1086 .mono_reg = AFE_DAC_CON3,
1087 .mono_shift = 16,
1088 .enable_reg = AFE_DAC_CON0,
1089 .enable_shift = 1,
1090 .hd_reg = AFE_MEMIF_HD_CON0,
1091 .hd_shift = 0,
1092 .agent_disable_reg = AUDIO_TOP_CON5,
1093 .agent_disable_shift = 6,
1094 .msb_reg = -1,
1095 .msb_shift = -1,
1096 },
1097 {
1098 .name = "DL2",
1099 .id = MT2701_MEMIF_DL2,
1100 .reg_ofs_base = AFE_DL2_BASE,
1101 .reg_ofs_cur = AFE_DL2_CUR,
1102 .fs_reg = AFE_DAC_CON1,
1103 .fs_shift = 5,
1104 .fs_maskbit = 0x1f,
1105 .mono_reg = AFE_DAC_CON3,
1106 .mono_shift = 17,
1107 .enable_reg = AFE_DAC_CON0,
1108 .enable_shift = 2,
1109 .hd_reg = AFE_MEMIF_HD_CON0,
1110 .hd_shift = 2,
1111 .agent_disable_reg = AUDIO_TOP_CON5,
1112 .agent_disable_shift = 7,
1113 .msb_reg = -1,
1114 .msb_shift = -1,
1115 },
1116 {
1117 .name = "DL3",
1118 .id = MT2701_MEMIF_DL3,
1119 .reg_ofs_base = AFE_DL3_BASE,
1120 .reg_ofs_cur = AFE_DL3_CUR,
1121 .fs_reg = AFE_DAC_CON1,
1122 .fs_shift = 10,
1123 .fs_maskbit = 0x1f,
1124 .mono_reg = AFE_DAC_CON3,
1125 .mono_shift = 18,
1126 .enable_reg = AFE_DAC_CON0,
1127 .enable_shift = 3,
1128 .hd_reg = AFE_MEMIF_HD_CON0,
1129 .hd_shift = 4,
1130 .agent_disable_reg = AUDIO_TOP_CON5,
1131 .agent_disable_shift = 8,
1132 .msb_reg = -1,
1133 .msb_shift = -1,
1134 },
1135 {
1136 .name = "DL4",
1137 .id = MT2701_MEMIF_DL4,
1138 .reg_ofs_base = AFE_DL4_BASE,
1139 .reg_ofs_cur = AFE_DL4_CUR,
1140 .fs_reg = AFE_DAC_CON1,
1141 .fs_shift = 15,
1142 .fs_maskbit = 0x1f,
1143 .mono_reg = AFE_DAC_CON3,
1144 .mono_shift = 19,
1145 .enable_reg = AFE_DAC_CON0,
1146 .enable_shift = 4,
1147 .hd_reg = AFE_MEMIF_HD_CON0,
1148 .hd_shift = 6,
1149 .agent_disable_reg = AUDIO_TOP_CON5,
1150 .agent_disable_shift = 9,
1151 .msb_reg = -1,
1152 .msb_shift = -1,
1153 },
1154 {
1155 .name = "DL5",
1156 .id = MT2701_MEMIF_DL5,
1157 .reg_ofs_base = AFE_DL5_BASE,
1158 .reg_ofs_cur = AFE_DL5_CUR,
1159 .fs_reg = AFE_DAC_CON1,
1160 .fs_shift = 20,
1161 .fs_maskbit = 0x1f,
1162 .mono_reg = AFE_DAC_CON3,
1163 .mono_shift = 20,
1164 .enable_reg = AFE_DAC_CON0,
1165 .enable_shift = 5,
1166 .hd_reg = AFE_MEMIF_HD_CON0,
1167 .hd_shift = 8,
1168 .agent_disable_reg = AUDIO_TOP_CON5,
1169 .agent_disable_shift = 10,
1170 .msb_reg = -1,
1171 .msb_shift = -1,
1172 },
1173 {
1174 .name = "DLM",
1175 .id = MT2701_MEMIF_DLM,
1176 .reg_ofs_base = AFE_DLMCH_BASE,
1177 .reg_ofs_cur = AFE_DLMCH_CUR,
1178 .fs_reg = AFE_DAC_CON1,
1179 .fs_shift = 0,
1180 .fs_maskbit = 0x1f,
1181 .mono_reg = -1,
1182 .mono_shift = -1,
1183 .enable_reg = AFE_DAC_CON0,
1184 .enable_shift = 7,
1185 .hd_reg = AFE_MEMIF_PBUF_SIZE,
1186 .hd_shift = 28,
1187 .agent_disable_reg = AUDIO_TOP_CON5,
1188 .agent_disable_shift = 12,
1189 .msb_reg = -1,
1190 .msb_shift = -1,
1191 },
1192 {
1193 .name = "UL1",
1194 .id = MT2701_MEMIF_UL1,
1195 .reg_ofs_base = AFE_VUL_BASE,
1196 .reg_ofs_cur = AFE_VUL_CUR,
1197 .fs_reg = AFE_DAC_CON2,
1198 .fs_shift = 0,
1199 .fs_maskbit = 0x1f,
1200 .mono_reg = AFE_DAC_CON4,
1201 .mono_shift = 0,
1202 .enable_reg = AFE_DAC_CON0,
1203 .enable_shift = 10,
1204 .hd_reg = AFE_MEMIF_HD_CON1,
1205 .hd_shift = 0,
1206 .agent_disable_reg = AUDIO_TOP_CON5,
1207 .agent_disable_shift = 0,
1208 .msb_reg = -1,
1209 .msb_shift = -1,
1210 },
1211 {
1212 .name = "UL2",
1213 .id = MT2701_MEMIF_UL2,
1214 .reg_ofs_base = AFE_UL2_BASE,
1215 .reg_ofs_cur = AFE_UL2_CUR,
1216 .fs_reg = AFE_DAC_CON2,
1217 .fs_shift = 5,
1218 .fs_maskbit = 0x1f,
1219 .mono_reg = AFE_DAC_CON4,
1220 .mono_shift = 2,
1221 .enable_reg = AFE_DAC_CON0,
1222 .enable_shift = 11,
1223 .hd_reg = AFE_MEMIF_HD_CON1,
1224 .hd_shift = 2,
1225 .agent_disable_reg = AUDIO_TOP_CON5,
1226 .agent_disable_shift = 1,
1227 .msb_reg = -1,
1228 .msb_shift = -1,
1229 },
1230 {
1231 .name = "UL3",
1232 .id = MT2701_MEMIF_UL3,
1233 .reg_ofs_base = AFE_UL3_BASE,
1234 .reg_ofs_cur = AFE_UL3_CUR,
1235 .fs_reg = AFE_DAC_CON2,
1236 .fs_shift = 10,
1237 .fs_maskbit = 0x1f,
1238 .mono_reg = AFE_DAC_CON4,
1239 .mono_shift = 4,
1240 .enable_reg = AFE_DAC_CON0,
1241 .enable_shift = 12,
1242 .hd_reg = AFE_MEMIF_HD_CON0,
1243 .hd_shift = 0,
1244 .agent_disable_reg = AUDIO_TOP_CON5,
1245 .agent_disable_shift = 2,
1246 .msb_reg = -1,
1247 .msb_shift = -1,
1248 },
1249 {
1250 .name = "UL4",
1251 .id = MT2701_MEMIF_UL4,
1252 .reg_ofs_base = AFE_UL4_BASE,
1253 .reg_ofs_cur = AFE_UL4_CUR,
1254 .fs_reg = AFE_DAC_CON2,
1255 .fs_shift = 15,
1256 .fs_maskbit = 0x1f,
1257 .mono_reg = AFE_DAC_CON4,
1258 .mono_shift = 6,
1259 .enable_reg = AFE_DAC_CON0,
1260 .enable_shift = 13,
1261 .hd_reg = AFE_MEMIF_HD_CON0,
1262 .hd_shift = 6,
1263 .agent_disable_reg = AUDIO_TOP_CON5,
1264 .agent_disable_shift = 3,
1265 .msb_reg = -1,
1266 .msb_shift = -1,
1267 },
1268 {
1269 .name = "UL5",
1270 .id = MT2701_MEMIF_UL5,
1271 .reg_ofs_base = AFE_UL5_BASE,
1272 .reg_ofs_cur = AFE_UL5_CUR,
1273 .fs_reg = AFE_DAC_CON2,
1274 .fs_shift = 20,
1275 .mono_reg = AFE_DAC_CON4,
1276 .mono_shift = 8,
1277 .fs_maskbit = 0x1f,
1278 .enable_reg = AFE_DAC_CON0,
1279 .enable_shift = 14,
1280 .hd_reg = AFE_MEMIF_HD_CON0,
1281 .hd_shift = 8,
1282 .agent_disable_reg = AUDIO_TOP_CON5,
1283 .agent_disable_shift = 4,
1284 .msb_reg = -1,
1285 .msb_shift = -1,
1286 },
1287 {
1288 .name = "DLBT",
1289 .id = MT2701_MEMIF_DLBT,
1290 .reg_ofs_base = AFE_ARB1_BASE,
1291 .reg_ofs_cur = AFE_ARB1_CUR,
1292 .fs_reg = AFE_DAC_CON3,
1293 .fs_shift = 10,
1294 .fs_maskbit = 0x1f,
1295 .mono_reg = AFE_DAC_CON3,
1296 .mono_shift = 22,
1297 .enable_reg = AFE_DAC_CON0,
1298 .enable_shift = 8,
1299 .hd_reg = AFE_MEMIF_HD_CON0,
1300 .hd_shift = 14,
1301 .agent_disable_reg = AUDIO_TOP_CON5,
1302 .agent_disable_shift = 13,
1303 .msb_reg = -1,
1304 .msb_shift = -1,
1305 },
1306 {
1307 .name = "ULBT",
1308 .id = MT2701_MEMIF_ULBT,
1309 .reg_ofs_base = AFE_DAI_BASE,
1310 .reg_ofs_cur = AFE_DAI_CUR,
1311 .fs_reg = AFE_DAC_CON2,
1312 .fs_shift = 30,
1313 .fs_maskbit = 0x1,
1314 .mono_reg = -1,
1315 .mono_shift = -1,
1316 .enable_reg = AFE_DAC_CON0,
1317 .enable_shift = 17,
1318 .hd_reg = AFE_MEMIF_HD_CON1,
1319 .hd_shift = 20,
1320 .agent_disable_reg = AUDIO_TOP_CON5,
1321 .agent_disable_shift = 16,
1322 .msb_reg = -1,
1323 .msb_shift = -1,
1324 },
1325};
1326
1327static const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = {
1328 {
1329 .id = MT2701_IRQ_ASYS_IRQ1,
1330 .irq_cnt_reg = ASYS_IRQ1_CON,
1331 .irq_cnt_shift = 0,
1332 .irq_cnt_maskbit = 0xffffff,
1333 .irq_fs_reg = ASYS_IRQ1_CON,
1334 .irq_fs_shift = 24,
1335 .irq_fs_maskbit = 0x1f,
1336 .irq_en_reg = ASYS_IRQ1_CON,
1337 .irq_en_shift = 31,
1338 .irq_clr_reg = ASYS_IRQ_CLR,
1339 .irq_clr_shift = 0,
1340 },
1341 {
1342 .id = MT2701_IRQ_ASYS_IRQ2,
1343 .irq_cnt_reg = ASYS_IRQ2_CON,
1344 .irq_cnt_shift = 0,
1345 .irq_cnt_maskbit = 0xffffff,
1346 .irq_fs_reg = ASYS_IRQ2_CON,
1347 .irq_fs_shift = 24,
1348 .irq_fs_maskbit = 0x1f,
1349 .irq_en_reg = ASYS_IRQ2_CON,
1350 .irq_en_shift = 31,
1351 .irq_clr_reg = ASYS_IRQ_CLR,
1352 .irq_clr_shift = 1,
1353 },
1354 {
1355 .id = MT2701_IRQ_ASYS_IRQ3,
1356 .irq_cnt_reg = ASYS_IRQ3_CON,
1357 .irq_cnt_shift = 0,
1358 .irq_cnt_maskbit = 0xffffff,
1359 .irq_fs_reg = ASYS_IRQ3_CON,
1360 .irq_fs_shift = 24,
1361 .irq_fs_maskbit = 0x1f,
1362 .irq_en_reg = ASYS_IRQ3_CON,
1363 .irq_en_shift = 31,
1364 .irq_clr_reg = ASYS_IRQ_CLR,
1365 .irq_clr_shift = 2,
1366 }
1367};
1368
1369static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = {
1370 {
1371 {
1372 .i2s_ctrl_reg = ASYS_I2SO1_CON,
1373 .i2s_pwn_shift = 6,
1374 .i2s_asrc_fs_shift = 0,
1375 .i2s_asrc_fs_mask = 0x1f,
1376
1377 },
1378 {
1379 .i2s_ctrl_reg = ASYS_I2SIN1_CON,
1380 .i2s_pwn_shift = 0,
1381 .i2s_asrc_fs_shift = 0,
1382 .i2s_asrc_fs_mask = 0x1f,
1383
1384 },
1385 },
1386 {
1387 {
1388 .i2s_ctrl_reg = ASYS_I2SO2_CON,
1389 .i2s_pwn_shift = 7,
1390 .i2s_asrc_fs_shift = 5,
1391 .i2s_asrc_fs_mask = 0x1f,
1392
1393 },
1394 {
1395 .i2s_ctrl_reg = ASYS_I2SIN2_CON,
1396 .i2s_pwn_shift = 1,
1397 .i2s_asrc_fs_shift = 5,
1398 .i2s_asrc_fs_mask = 0x1f,
1399
1400 },
1401 },
1402 {
1403 {
1404 .i2s_ctrl_reg = ASYS_I2SO3_CON,
1405 .i2s_pwn_shift = 8,
1406 .i2s_asrc_fs_shift = 10,
1407 .i2s_asrc_fs_mask = 0x1f,
1408
1409 },
1410 {
1411 .i2s_ctrl_reg = ASYS_I2SIN3_CON,
1412 .i2s_pwn_shift = 2,
1413 .i2s_asrc_fs_shift = 10,
1414 .i2s_asrc_fs_mask = 0x1f,
1415
1416 },
1417 },
1418 {
1419 {
1420 .i2s_ctrl_reg = ASYS_I2SO4_CON,
1421 .i2s_pwn_shift = 9,
1422 .i2s_asrc_fs_shift = 15,
1423 .i2s_asrc_fs_mask = 0x1f,
1424
1425 },
1426 {
1427 .i2s_ctrl_reg = ASYS_I2SIN4_CON,
1428 .i2s_pwn_shift = 3,
1429 .i2s_asrc_fs_shift = 15,
1430 .i2s_asrc_fs_mask = 0x1f,
1431
1432 },
1433 },
1434};
1435
1436static const struct regmap_config mt2701_afe_regmap_config = {
1437 .reg_bits = 32,
1438 .reg_stride = 4,
1439 .val_bits = 32,
1440 .max_register = AFE_END_ADDR,
1441 .cache_type = REGCACHE_NONE,
1442};
1443
1444static irqreturn_t mt2701_asys_isr(int irq_id, void *dev)
1445{
1446 int id;
1447 struct mtk_base_afe *afe = dev;
1448 struct mtk_base_afe_memif *memif;
1449 struct mtk_base_afe_irq *irq;
1450 u32 status;
1451
1452 regmap_read(afe->regmap, ASYS_IRQ_STATUS, &status);
1453 regmap_write(afe->regmap, ASYS_IRQ_CLR, status);
1454
1455 for (id = 0; id < MT2701_MEMIF_NUM; ++id) {
1456 memif = &afe->memif[id];
1457 if (memif->irq_usage < 0)
1458 continue;
1459 irq = &afe->irqs[memif->irq_usage];
1460 if (status & 1 << (irq->irq_data->irq_clr_shift))
1461 snd_pcm_period_elapsed(memif->substream);
1462 }
1463 return IRQ_HANDLED;
1464}
1465
1466static int mt2701_afe_runtime_suspend(struct device *dev)
1467{
1468 struct mtk_base_afe *afe = dev_get_drvdata(dev);
1469
1470 mt2701_afe_disable_clock(afe);
1471 return 0;
1472}
1473
1474static int mt2701_afe_runtime_resume(struct device *dev)
1475{
1476 struct mtk_base_afe *afe = dev_get_drvdata(dev);
1477
1478 return mt2701_afe_enable_clock(afe);
1479}
1480
1481static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
1482{
1483 int ret, i;
1484 unsigned int irq_id;
1485 struct mtk_base_afe *afe;
1486 struct mt2701_afe_private *afe_priv;
1487 struct resource *res;
1488 struct device *dev;
1489
1490 ret = 0;
1491 afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
1492 if (!afe)
1493 return -ENOMEM;
1494 afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
1495 GFP_KERNEL);
1496 if (!afe->platform_priv)
1497 return -ENOMEM;
1498 afe_priv = afe->platform_priv;
1499
1500 afe->dev = &pdev->dev;
1501 dev = afe->dev;
1502
1503 irq_id = platform_get_irq(pdev, 0);
1504 if (!irq_id) {
1505 dev_err(dev, "%s no irq found\n", dev->of_node->name);
1506 return -ENXIO;
1507 }
1508 ret = devm_request_irq(dev, irq_id, mt2701_asys_isr,
1509 IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
1510 if (ret) {
1511 dev_err(dev, "could not request_irq for asys-isr\n");
1512 return ret;
1513 }
1514
1515 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1516
1517 afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
1518
1519 if (IS_ERR(afe->base_addr))
1520 return PTR_ERR(afe->base_addr);
1521
1522 afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
1523 &mt2701_afe_regmap_config);
1524 if (IS_ERR(afe->regmap))
1525 return PTR_ERR(afe->regmap);
1526
1527 mutex_init(&afe->irq_alloc_lock);
1528
1529 /* memif initialize */
1530 afe->memif_size = MT2701_MEMIF_NUM;
1531 afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
1532 GFP_KERNEL);
1533
1534 if (!afe->memif)
1535 return -ENOMEM;
1536
1537 for (i = 0; i < afe->memif_size; i++) {
1538 afe->memif[i].data = &memif_data[i];
1539 afe->memif[i].irq_usage = -1;
1540 }
1541
1542 /* irq initialize */
1543 afe->irqs_size = MT2701_IRQ_ASYS_END;
1544 afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
1545 GFP_KERNEL);
1546
1547 if (!afe->irqs)
1548 return -ENOMEM;
1549
1550 for (i = 0; i < afe->irqs_size; i++)
1551 afe->irqs[i].irq_data = &irq_data[i];
1552
1553 /* I2S initialize */
1554 for (i = 0; i < MT2701_I2S_NUM; i++) {
1555 afe_priv->i2s_path[i].i2s_data[I2S_OUT]
1556 = &mt2701_i2s_data[i][I2S_OUT];
1557 afe_priv->i2s_path[i].i2s_data[I2S_IN]
1558 = &mt2701_i2s_data[i][I2S_IN];
1559 }
1560
1561 afe->mtk_afe_hardware = &mt2701_afe_hardware;
1562 afe->memif_fs = mt2701_memif_fs;
1563 afe->irq_fs = mt2701_irq_fs;
1564
1565 afe->reg_back_up_list = mt2701_afe_backup_list;
1566 afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list);
1567 afe->runtime_resume = mt2701_afe_runtime_resume;
1568 afe->runtime_suspend = mt2701_afe_runtime_suspend;
1569
1570 /* initial audio related clock */
1571 ret = mt2701_init_clock(afe);
1572 if (ret) {
1573 dev_err(dev, "init clock error\n");
1574 return ret;
1575 }
1576
1577 platform_set_drvdata(pdev, afe);
1578 pm_runtime_enable(&pdev->dev);
1579 if (!pm_runtime_enabled(&pdev->dev))
1580 goto err_pm_disable;
1581
1582 ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform);
1583 if (ret) {
1584 dev_warn(dev, "err_platform\n");
1585 goto err_platform;
1586 }
1587
1588 ret = snd_soc_register_component(&pdev->dev,
1589 &mt2701_afe_pcm_dai_component,
1590 mt2701_afe_pcm_dais,
1591 ARRAY_SIZE(mt2701_afe_pcm_dais));
1592 if (ret) {
1593 dev_warn(dev, "err_dai_component\n");
1594 goto err_dai_component;
1595 }
1596
1597 mt2701_afe_runtime_resume(&pdev->dev);
1598
1599 return 0;
1600
1601err_dai_component:
1602 snd_soc_unregister_component(&pdev->dev);
1603
1604err_platform:
1605 snd_soc_unregister_platform(&pdev->dev);
1606
1607err_pm_disable:
1608 pm_runtime_disable(&pdev->dev);
1609
1610 return ret;
1611}
1612
1613static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
1614{
1615 struct mtk_base_afe *afe = platform_get_drvdata(pdev);
1616
1617 pm_runtime_disable(&pdev->dev);
1618 if (!pm_runtime_status_suspended(&pdev->dev))
1619 mt2701_afe_runtime_suspend(&pdev->dev);
1620
1621 snd_soc_unregister_component(&pdev->dev);
1622 snd_soc_unregister_platform(&pdev->dev);
1623 /* disable afe clock */
1624 mt2701_afe_disable_clock(afe);
1625 return 0;
1626}
1627
1628static const struct of_device_id mt2701_afe_pcm_dt_match[] = {
1629 { .compatible = "mediatek,mt2701-audio", },
1630 {},
1631};
1632MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match);
1633
1634static const struct dev_pm_ops mt2701_afe_pm_ops = {
1635 SET_RUNTIME_PM_OPS(mt2701_afe_runtime_suspend,
1636 mt2701_afe_runtime_resume, NULL)
1637};
1638
1639static struct platform_driver mt2701_afe_pcm_driver = {
1640 .driver = {
1641 .name = "mt2701-audio",
1642 .of_match_table = mt2701_afe_pcm_dt_match,
1643#ifdef CONFIG_PM
1644 .pm = &mt2701_afe_pm_ops,
1645#endif
1646 },
1647 .probe = mt2701_afe_pcm_dev_probe,
1648 .remove = mt2701_afe_pcm_dev_remove,
1649};
1650
1651module_platform_driver(mt2701_afe_pcm_driver);
1652
1653MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701");
1654MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
1655MODULE_LICENSE("GPL v2");
1656
diff --git a/sound/soc/mediatek/mt2701/mt2701-cs42448.c b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
new file mode 100644
index 000000000000..1e7e8d43fd8a
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
@@ -0,0 +1,412 @@
1/*
2 * mt2701-cs42448.c -- MT2701 CS42448 ALSA SoC machine driver
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Ir Lian <ir.lian@mediatek.com>
6 * Garlic Tseng <garlic.tseng@mediatek.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 and
11 * only version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <sound/soc.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/pinctrl/consumer.h>
24#include <linux/of_gpio.h>
25
26#include "mt2701-afe-common.h"
27
28struct mt2701_cs42448_private {
29 int i2s1_in_mux;
30 int i2s1_in_mux_gpio_sel_1;
31 int i2s1_in_mux_gpio_sel_2;
32};
33
34static const char * const i2sin_mux_switch_text[] = {
35 "ADC_SDOUT2",
36 "ADC_SDOUT3",
37 "I2S_IN_1",
38 "I2S_IN_2",
39};
40
41static const struct soc_enum i2sin_mux_enum =
42 SOC_ENUM_SINGLE_EXT(4, i2sin_mux_switch_text);
43
44static int mt2701_cs42448_i2sin1_mux_get(struct snd_kcontrol *kcontrol,
45 struct snd_ctl_elem_value *ucontrol)
46{
47 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
48 struct mt2701_cs42448_private *priv = snd_soc_card_get_drvdata(card);
49
50 ucontrol->value.integer.value[0] = priv->i2s1_in_mux;
51 return 0;
52}
53
54static int mt2701_cs42448_i2sin1_mux_set(struct snd_kcontrol *kcontrol,
55 struct snd_ctl_elem_value *ucontrol)
56{
57 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
58 struct mt2701_cs42448_private *priv = snd_soc_card_get_drvdata(card);
59
60 if (ucontrol->value.integer.value[0] == priv->i2s1_in_mux)
61 return 0;
62
63 switch (ucontrol->value.integer.value[0]) {
64 case 0:
65 gpio_set_value(priv->i2s1_in_mux_gpio_sel_1, 0);
66 gpio_set_value(priv->i2s1_in_mux_gpio_sel_2, 0);
67 break;
68 case 1:
69 gpio_set_value(priv->i2s1_in_mux_gpio_sel_1, 1);
70 gpio_set_value(priv->i2s1_in_mux_gpio_sel_2, 0);
71 break;
72 case 2:
73 gpio_set_value(priv->i2s1_in_mux_gpio_sel_1, 0);
74 gpio_set_value(priv->i2s1_in_mux_gpio_sel_2, 1);
75 break;
76 case 3:
77 gpio_set_value(priv->i2s1_in_mux_gpio_sel_1, 1);
78 gpio_set_value(priv->i2s1_in_mux_gpio_sel_2, 1);
79 break;
80 default:
81 dev_warn(card->dev, "%s invalid setting\n", __func__);
82 }
83
84 priv->i2s1_in_mux = ucontrol->value.integer.value[0];
85 return 0;
86}
87
88static const struct snd_soc_dapm_widget
89 mt2701_cs42448_asoc_card_dapm_widgets[] = {
90 SND_SOC_DAPM_LINE("Line Out Jack", NULL),
91 SND_SOC_DAPM_MIC("AMIC", NULL),
92 SND_SOC_DAPM_LINE("Tuner In", NULL),
93 SND_SOC_DAPM_LINE("Satellite Tuner In", NULL),
94 SND_SOC_DAPM_LINE("AUX In", NULL),
95};
96
97static const struct snd_kcontrol_new mt2701_cs42448_controls[] = {
98 SOC_DAPM_PIN_SWITCH("Line Out Jack"),
99 SOC_DAPM_PIN_SWITCH("AMIC"),
100 SOC_DAPM_PIN_SWITCH("Tuner In"),
101 SOC_DAPM_PIN_SWITCH("Satellite Tuner In"),
102 SOC_DAPM_PIN_SWITCH("AUX In"),
103 SOC_ENUM_EXT("I2SIN1_MUX_Switch", i2sin_mux_enum,
104 mt2701_cs42448_i2sin1_mux_get,
105 mt2701_cs42448_i2sin1_mux_set),
106};
107
108static const unsigned int mt2701_cs42448_sampling_rates[] = {48000};
109
110static struct snd_pcm_hw_constraint_list mt2701_cs42448_constraints_rates = {
111 .count = ARRAY_SIZE(mt2701_cs42448_sampling_rates),
112 .list = mt2701_cs42448_sampling_rates,
113 .mask = 0,
114};
115
116static int mt2701_cs42448_fe_ops_startup(struct snd_pcm_substream *substream)
117{
118 int err;
119
120 err = snd_pcm_hw_constraint_list(substream->runtime, 0,
121 SNDRV_PCM_HW_PARAM_RATE,
122 &mt2701_cs42448_constraints_rates);
123 if (err < 0) {
124 dev_err(substream->pcm->card->dev,
125 "%s snd_pcm_hw_constraint_list failed: 0x%x\n",
126 __func__, err);
127 return err;
128 }
129 return 0;
130}
131
132static struct snd_soc_ops mt2701_cs42448_48k_fe_ops = {
133 .startup = mt2701_cs42448_fe_ops_startup,
134};
135
136static int mt2701_cs42448_be_ops_hw_params(struct snd_pcm_substream *substream,
137 struct snd_pcm_hw_params *params)
138{
139 struct snd_soc_pcm_runtime *rtd = substream->private_data;
140 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
141 struct snd_soc_dai *codec_dai = rtd->codec_dai;
142 unsigned int mclk_rate;
143 unsigned int rate = params_rate(params);
144 unsigned int div_mclk_over_bck = rate > 192000 ? 2 : 4;
145 unsigned int div_bck_over_lrck = 64;
146
147 mclk_rate = rate * div_bck_over_lrck * div_mclk_over_bck;
148
149 /* mt2701 mclk */
150 snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate, SND_SOC_CLOCK_OUT);
151
152 /* codec mclk */
153 snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate, SND_SOC_CLOCK_IN);
154
155 return 0;
156}
157
158static struct snd_soc_ops mt2701_cs42448_be_ops = {
159 .hw_params = mt2701_cs42448_be_ops_hw_params
160};
161
162enum {
163 DAI_LINK_FE_MULTI_CH_OUT,
164 DAI_LINK_FE_PCM0_IN,
165 DAI_LINK_FE_PCM1_IN,
166 DAI_LINK_FE_BT_OUT,
167 DAI_LINK_FE_BT_IN,
168 DAI_LINK_BE_I2S0,
169 DAI_LINK_BE_I2S1,
170 DAI_LINK_BE_I2S2,
171 DAI_LINK_BE_I2S3,
172 DAI_LINK_BE_MRG_BT,
173};
174
175static struct snd_soc_dai_link mt2701_cs42448_dai_links[] = {
176 /* FE */
177 [DAI_LINK_FE_MULTI_CH_OUT] = {
178 .name = "mt2701-cs42448-multi-ch-out",
179 .stream_name = "mt2701-cs42448-multi-ch-out",
180 .cpu_dai_name = "PCM_multi",
181 .codec_name = "snd-soc-dummy",
182 .codec_dai_name = "snd-soc-dummy-dai",
183 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
184 SND_SOC_DPCM_TRIGGER_POST},
185 .ops = &mt2701_cs42448_48k_fe_ops,
186 .dynamic = 1,
187 .dpcm_playback = 1,
188 },
189 [DAI_LINK_FE_PCM0_IN] = {
190 .name = "mt2701-cs42448-pcm0",
191 .stream_name = "mt2701-cs42448-pcm0-data-UL",
192 .cpu_dai_name = "PCM0",
193 .codec_name = "snd-soc-dummy",
194 .codec_dai_name = "snd-soc-dummy-dai",
195 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
196 SND_SOC_DPCM_TRIGGER_POST},
197 .ops = &mt2701_cs42448_48k_fe_ops,
198 .dynamic = 1,
199 .dpcm_capture = 1,
200 },
201 [DAI_LINK_FE_PCM1_IN] = {
202 .name = "mt2701-cs42448-pcm1-data-UL",
203 .stream_name = "mt2701-cs42448-pcm1-data-UL",
204 .cpu_dai_name = "PCM1",
205 .codec_name = "snd-soc-dummy",
206 .codec_dai_name = "snd-soc-dummy-dai",
207 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
208 SND_SOC_DPCM_TRIGGER_POST},
209 .ops = &mt2701_cs42448_48k_fe_ops,
210 .dynamic = 1,
211 .dpcm_capture = 1,
212 },
213 [DAI_LINK_FE_BT_OUT] = {
214 .name = "mt2701-cs42448-pcm-BT-out",
215 .stream_name = "mt2701-cs42448-pcm-BT",
216 .cpu_dai_name = "PCM_BT_DL",
217 .codec_name = "snd-soc-dummy",
218 .codec_dai_name = "snd-soc-dummy-dai",
219 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
220 SND_SOC_DPCM_TRIGGER_POST},
221 .dynamic = 1,
222 .dpcm_playback = 1,
223 },
224 [DAI_LINK_FE_BT_IN] = {
225 .name = "mt2701-cs42448-pcm-BT-in",
226 .stream_name = "mt2701-cs42448-pcm-BT",
227 .cpu_dai_name = "PCM_BT_UL",
228 .codec_name = "snd-soc-dummy",
229 .codec_dai_name = "snd-soc-dummy-dai",
230 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
231 SND_SOC_DPCM_TRIGGER_POST},
232 .dynamic = 1,
233 .dpcm_capture = 1,
234 },
235 /* BE */
236 [DAI_LINK_BE_I2S0] = {
237 .name = "mt2701-cs42448-I2S0",
238 .cpu_dai_name = "I2S0",
239 .no_pcm = 1,
240 .codec_dai_name = "cs42448",
241 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS
242 | SND_SOC_DAIFMT_GATED,
243 .ops = &mt2701_cs42448_be_ops,
244 .dpcm_playback = 1,
245 .dpcm_capture = 1,
246 },
247 [DAI_LINK_BE_I2S1] = {
248 .name = "mt2701-cs42448-I2S1",
249 .cpu_dai_name = "I2S1",
250 .no_pcm = 1,
251 .codec_dai_name = "cs42448",
252 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS
253 | SND_SOC_DAIFMT_GATED,
254 .ops = &mt2701_cs42448_be_ops,
255 .dpcm_playback = 1,
256 .dpcm_capture = 1,
257 },
258 [DAI_LINK_BE_I2S2] = {
259 .name = "mt2701-cs42448-I2S2",
260 .cpu_dai_name = "I2S2",
261 .no_pcm = 1,
262 .codec_dai_name = "cs42448",
263 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS
264 | SND_SOC_DAIFMT_GATED,
265 .ops = &mt2701_cs42448_be_ops,
266 .dpcm_playback = 1,
267 .dpcm_capture = 1,
268 },
269 [DAI_LINK_BE_I2S3] = {
270 .name = "mt2701-cs42448-I2S3",
271 .cpu_dai_name = "I2S3",
272 .no_pcm = 1,
273 .codec_dai_name = "cs42448",
274 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS
275 | SND_SOC_DAIFMT_GATED,
276 .ops = &mt2701_cs42448_be_ops,
277 .dpcm_playback = 1,
278 .dpcm_capture = 1,
279 },
280 [DAI_LINK_BE_MRG_BT] = {
281 .name = "mt2701-cs42448-MRG-BT",
282 .cpu_dai_name = "MRG BT",
283 .no_pcm = 1,
284 .codec_dai_name = "bt-sco-pcm-wb",
285 .dpcm_playback = 1,
286 .dpcm_capture = 1,
287 },
288};
289
290static struct snd_soc_card mt2701_cs42448_soc_card = {
291 .name = "mt2701-cs42448",
292 .owner = THIS_MODULE,
293 .dai_link = mt2701_cs42448_dai_links,
294 .num_links = ARRAY_SIZE(mt2701_cs42448_dai_links),
295 .controls = mt2701_cs42448_controls,
296 .num_controls = ARRAY_SIZE(mt2701_cs42448_controls),
297 .dapm_widgets = mt2701_cs42448_asoc_card_dapm_widgets,
298 .num_dapm_widgets = ARRAY_SIZE(mt2701_cs42448_asoc_card_dapm_widgets),
299};
300
301static int mt2701_cs42448_machine_probe(struct platform_device *pdev)
302{
303 struct snd_soc_card *card = &mt2701_cs42448_soc_card;
304 int ret;
305 int i;
306 struct device_node *platform_node, *codec_node, *codec_node_bt_mrg;
307 struct mt2701_cs42448_private *priv =
308 devm_kzalloc(&pdev->dev, sizeof(struct mt2701_cs42448_private),
309 GFP_KERNEL);
310 struct device *dev = &pdev->dev;
311
312 if (!priv)
313 return -ENOMEM;
314
315 platform_node = of_parse_phandle(pdev->dev.of_node,
316 "mediatek,platform", 0);
317 if (!platform_node) {
318 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
319 return -EINVAL;
320 }
321 for (i = 0; i < card->num_links; i++) {
322 if (mt2701_cs42448_dai_links[i].platform_name)
323 continue;
324 mt2701_cs42448_dai_links[i].platform_of_node = platform_node;
325 }
326
327 card->dev = dev;
328
329 codec_node = of_parse_phandle(pdev->dev.of_node,
330 "mediatek,audio-codec", 0);
331 if (!codec_node) {
332 dev_err(&pdev->dev,
333 "Property 'audio-codec' missing or invalid\n");
334 return -EINVAL;
335 }
336 for (i = 0; i < card->num_links; i++) {
337 if (mt2701_cs42448_dai_links[i].codec_name)
338 continue;
339 mt2701_cs42448_dai_links[i].codec_of_node = codec_node;
340 }
341
342 codec_node_bt_mrg = of_parse_phandle(pdev->dev.of_node,
343 "mediatek,audio-codec-bt-mrg", 0);
344 if (!codec_node_bt_mrg) {
345 dev_err(&pdev->dev,
346 "Property 'audio-codec-bt-mrg' missing or invalid\n");
347 return -EINVAL;
348 }
349 mt2701_cs42448_dai_links[DAI_LINK_BE_MRG_BT].codec_of_node
350 = codec_node_bt_mrg;
351
352 ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
353 if (ret) {
354 dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
355 return ret;
356 }
357
358 priv->i2s1_in_mux_gpio_sel_1 =
359 of_get_named_gpio(dev->of_node, "i2s1-in-sel-gpio1", 0);
360 if (gpio_is_valid(priv->i2s1_in_mux_gpio_sel_1)) {
361 ret = devm_gpio_request(dev, priv->i2s1_in_mux_gpio_sel_1,
362 "i2s1_in_mux_gpio_sel_1");
363 if (ret)
364 dev_warn(&pdev->dev, "%s devm_gpio_request fail %d\n",
365 __func__, ret);
366 gpio_direction_output(priv->i2s1_in_mux_gpio_sel_1, 0);
367 }
368
369 priv->i2s1_in_mux_gpio_sel_2 =
370 of_get_named_gpio(dev->of_node, "i2s1-in-sel-gpio2", 0);
371 if (gpio_is_valid(priv->i2s1_in_mux_gpio_sel_2)) {
372 ret = devm_gpio_request(dev, priv->i2s1_in_mux_gpio_sel_2,
373 "i2s1_in_mux_gpio_sel_2");
374 if (ret)
375 dev_warn(&pdev->dev, "%s devm_gpio_request fail2 %d\n",
376 __func__, ret);
377 gpio_direction_output(priv->i2s1_in_mux_gpio_sel_2, 0);
378 }
379 snd_soc_card_set_drvdata(card, priv);
380
381 ret = devm_snd_soc_register_card(&pdev->dev, card);
382
383 if (ret)
384 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
385 __func__, ret);
386 return ret;
387}
388
389#ifdef CONFIG_OF
390static const struct of_device_id mt2701_cs42448_machine_dt_match[] = {
391 {.compatible = "mediatek,mt2701-cs42448-machine",},
392 {}
393};
394#endif
395
396static struct platform_driver mt2701_cs42448_machine = {
397 .driver = {
398 .name = "mt2701-cs42448",
399 #ifdef CONFIG_OF
400 .of_match_table = mt2701_cs42448_machine_dt_match,
401 #endif
402 },
403 .probe = mt2701_cs42448_machine_probe,
404};
405
406module_platform_driver(mt2701_cs42448_machine);
407
408/* Module information */
409MODULE_DESCRIPTION("MT2701 CS42448 ALSA SoC machine driver");
410MODULE_AUTHOR("Ir Lian <ir.lian@mediatek.com>");
411MODULE_LICENSE("GPL v2");
412MODULE_ALIAS("mt2701 cs42448 soc card");
diff --git a/sound/soc/mediatek/mt2701/mt2701-reg.h b/sound/soc/mediatek/mt2701/mt2701-reg.h
new file mode 100644
index 000000000000..bb62b1c55957
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-reg.h
@@ -0,0 +1,186 @@
1/*
2 * mt2701-reg.h -- Mediatek 2701 audio driver reg definition
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _MT2701_REG_H_
18#define _MT2701_REG_H_
19
20#include <linux/delay.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/of_address.h>
24#include <linux/pm_runtime.h>
25#include <sound/soc.h>
26#include "mt2701-afe-common.h"
27
28/*****************************************************************************
29 * R E G I S T E R D E F I N I T I O N
30 *****************************************************************************/
31#define AUDIO_TOP_CON0 0x0000
32#define AUDIO_TOP_CON4 0x0010
33#define AUDIO_TOP_CON5 0x0014
34#define AFE_DAIBT_CON0 0x001c
35#define AFE_MRGIF_CON 0x003c
36#define ASMI_TIMING_CON1 0x0100
37#define ASMO_TIMING_CON1 0x0104
38#define PWR1_ASM_CON1 0x0108
39#define ASYS_TOP_CON 0x0600
40#define ASYS_I2SIN1_CON 0x0604
41#define ASYS_I2SIN2_CON 0x0608
42#define ASYS_I2SIN3_CON 0x060c
43#define ASYS_I2SIN4_CON 0x0610
44#define ASYS_I2SIN5_CON 0x0614
45#define ASYS_I2SO1_CON 0x061C
46#define ASYS_I2SO2_CON 0x0620
47#define ASYS_I2SO3_CON 0x0624
48#define ASYS_I2SO4_CON 0x0628
49#define ASYS_I2SO5_CON 0x062c
50#define PWR2_TOP_CON 0x0634
51#define AFE_CONN0 0x06c0
52#define AFE_CONN1 0x06c4
53#define AFE_CONN2 0x06c8
54#define AFE_CONN3 0x06cc
55#define AFE_CONN14 0x06f8
56#define AFE_CONN15 0x06fc
57#define AFE_CONN16 0x0700
58#define AFE_CONN17 0x0704
59#define AFE_CONN18 0x0708
60#define AFE_CONN19 0x070c
61#define AFE_CONN20 0x0710
62#define AFE_CONN21 0x0714
63#define AFE_CONN22 0x0718
64#define AFE_CONN23 0x071c
65#define AFE_CONN24 0x0720
66#define AFE_CONN41 0x0764
67#define ASYS_IRQ1_CON 0x0780
68#define ASYS_IRQ2_CON 0x0784
69#define ASYS_IRQ3_CON 0x0788
70#define ASYS_IRQ_CLR 0x07c0
71#define ASYS_IRQ_STATUS 0x07c4
72#define PWR2_ASM_CON1 0x1070
73#define AFE_DAC_CON0 0x1200
74#define AFE_DAC_CON1 0x1204
75#define AFE_DAC_CON2 0x1208
76#define AFE_DAC_CON3 0x120c
77#define AFE_DAC_CON4 0x1210
78#define AFE_MEMIF_HD_CON1 0x121c
79#define AFE_MEMIF_PBUF_SIZE 0x1238
80#define AFE_MEMIF_HD_CON0 0x123c
81#define AFE_DL1_BASE 0x1240
82#define AFE_DL1_CUR 0x1244
83#define AFE_DL2_BASE 0x1250
84#define AFE_DL2_CUR 0x1254
85#define AFE_DL3_BASE 0x1260
86#define AFE_DL3_CUR 0x1264
87#define AFE_DL4_BASE 0x1270
88#define AFE_DL4_CUR 0x1274
89#define AFE_DL5_BASE 0x1280
90#define AFE_DL5_CUR 0x1284
91#define AFE_DLMCH_BASE 0x12a0
92#define AFE_DLMCH_CUR 0x12a4
93#define AFE_ARB1_BASE 0x12b0
94#define AFE_ARB1_CUR 0x12b4
95#define AFE_VUL_BASE 0x1300
96#define AFE_VUL_CUR 0x130c
97#define AFE_UL2_BASE 0x1310
98#define AFE_UL2_END 0x1318
99#define AFE_UL2_CUR 0x131c
100#define AFE_UL3_BASE 0x1320
101#define AFE_UL3_END 0x1328
102#define AFE_UL3_CUR 0x132c
103#define AFE_UL4_BASE 0x1330
104#define AFE_UL4_END 0x1338
105#define AFE_UL4_CUR 0x133c
106#define AFE_UL5_BASE 0x1340
107#define AFE_UL5_END 0x1348
108#define AFE_UL5_CUR 0x134c
109#define AFE_DAI_BASE 0x1370
110#define AFE_DAI_CUR 0x137c
111
112/* AUDIO_TOP_CON0 (0x0000) */
113#define AUDIO_TOP_CON0_A1SYS_A2SYS_ON (0x3 << 0)
114#define AUDIO_TOP_CON0_PDN_AFE (0x1 << 2)
115#define AUDIO_TOP_CON0_PDN_APLL_CK (0x1 << 23)
116
117/* AUDIO_TOP_CON4 (0x0010) */
118#define AUDIO_TOP_CON4_I2SO1_PWN (0x1 << 6)
119#define AUDIO_TOP_CON4_PDN_A1SYS (0x1 << 21)
120#define AUDIO_TOP_CON4_PDN_A2SYS (0x1 << 22)
121#define AUDIO_TOP_CON4_PDN_AFE_CONN (0x1 << 23)
122#define AUDIO_TOP_CON4_PDN_MRGIF (0x1 << 25)
123
124/* AFE_DAIBT_CON0 (0x001c) */
125#define AFE_DAIBT_CON0_DAIBT_EN (0x1 << 0)
126#define AFE_DAIBT_CON0_BT_FUNC_EN (0x1 << 1)
127#define AFE_DAIBT_CON0_BT_FUNC_RDY (0x1 << 3)
128#define AFE_DAIBT_CON0_BT_WIDE_MODE_EN (0x1 << 9)
129#define AFE_DAIBT_CON0_MRG_USE (0x1 << 12)
130
131/* PWR1_ASM_CON1 (0x0108) */
132#define PWR1_ASM_CON1_INIT_VAL (0x492)
133
134/* AFE_MRGIF_CON (0x003c) */
135#define AFE_MRGIF_CON_MRG_EN (0x1 << 0)
136#define AFE_MRGIF_CON_MRG_I2S_EN (0x1 << 16)
137#define AFE_MRGIF_CON_I2S_MODE_MASK (0xf << 20)
138#define AFE_MRGIF_CON_I2S_MODE_32K (0x4 << 20)
139
140/* ASYS_I2SO1_CON (0x061c) */
141#define ASYS_I2SO1_CON_FS (0x1f << 8)
142#define ASYS_I2SO1_CON_FS_SET(x) ((x) << 8)
143#define ASYS_I2SO1_CON_MULTI_CH (0x1 << 16)
144#define ASYS_I2SO1_CON_SIDEGEN (0x1 << 30)
145#define ASYS_I2SO1_CON_I2S_EN (0x1 << 0)
146/* 0:EIAJ 1:I2S */
147#define ASYS_I2SO1_CON_I2S_MODE (0x1 << 3)
148#define ASYS_I2SO1_CON_WIDE_MODE (0x1 << 1)
149#define ASYS_I2SO1_CON_WIDE_MODE_SET(x) ((x) << 1)
150
151/* PWR2_TOP_CON (0x0634) */
152#define PWR2_TOP_CON_INIT_VAL (0xffe1ffff)
153
154/* ASYS_IRQ_CLR (0x07c0) */
155#define ASYS_IRQ_CLR_ALL (0xffffffff)
156
157/* PWR2_ASM_CON1 (0x1070) */
158#define PWR2_ASM_CON1_INIT_VAL (0x492492)
159
160/* AFE_DAC_CON0 (0x1200) */
161#define AFE_DAC_CON0_AFE_ON (0x1 << 0)
162
163/* AFE_MEMIF_PBUF_SIZE (0x1238) */
164#define AFE_MEMIF_PBUF_SIZE_DLM_MASK (0x1 << 29)
165#define AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE (0x0 << 29)
166#define AFE_MEMIF_PBUF_SIZE_FULL_INTERLEAVE (0x1 << 29)
167#define DLMCH_BIT_WIDTH_MASK (0x1 << 28)
168#define AFE_MEMIF_PBUF_SIZE_DLM_CH_MASK (0xf << 24)
169#define AFE_MEMIF_PBUF_SIZE_DLM_CH(x) ((x) << 24)
170#define AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK (0x3 << 12)
171#define AFE_MEMIF_PBUF_SIZE_DLM_32BYTES (0x1 << 12)
172
173/* I2S in/out register bit control */
174#define ASYS_I2S_CON_FS (0x1f << 8)
175#define ASYS_I2S_CON_FS_SET(x) ((x) << 8)
176#define ASYS_I2S_CON_RESET (0x1 << 30)
177#define ASYS_I2S_CON_I2S_EN (0x1 << 0)
178#define ASYS_I2S_CON_I2S_COUPLE_MODE (0x1 << 17)
179/* 0:EIAJ 1:I2S */
180#define ASYS_I2S_CON_I2S_MODE (0x1 << 3)
181#define ASYS_I2S_CON_WIDE_MODE (0x1 << 1)
182#define ASYS_I2S_CON_WIDE_MODE_SET(x) ((x) << 1)
183#define ASYS_I2S_IN_PHASE_FIX (0x1 << 31)
184
185#define AFE_END_ADDR 0x15e0
186#endif
diff --git a/sound/soc/mediatek/mt8173/Makefile b/sound/soc/mediatek/mt8173/Makefile
new file mode 100644
index 000000000000..0357b27d29f2
--- /dev/null
+++ b/sound/soc/mediatek/mt8173/Makefile
@@ -0,0 +1,7 @@
1# MTK Platform Support
2obj-$(CONFIG_SND_SOC_MT8173) += mt8173-afe-pcm.o
3# Machine support
4obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
5obj-$(CONFIG_SND_SOC_MT8173_RT5650) += mt8173-rt5650.o
6obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5514) += mt8173-rt5650-rt5514.o
7obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-common.h b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
new file mode 100644
index 000000000000..9a4837cc181a
--- /dev/null
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
@@ -0,0 +1,73 @@
1/*
2 * mt8173_afe_common.h -- Mediatek 8173 audio driver common definitions
3 *
4 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 * Sascha Hauer <s.hauer@pengutronix.de>
7 * Hidalgo Huang <hidalgo.huang@mediatek.com>
8 * Ir Lian <ir.lian@mediatek.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 and
12 * only version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#ifndef _MT8173_AFE_COMMON_H_
21#define _MT8173_AFE_COMMON_H_
22
23#include <linux/clk.h>
24#include <linux/regmap.h>
25
26enum {
27 MT8173_AFE_MEMIF_DL1,
28 MT8173_AFE_MEMIF_DL2,
29 MT8173_AFE_MEMIF_VUL,
30 MT8173_AFE_MEMIF_DAI,
31 MT8173_AFE_MEMIF_AWB,
32 MT8173_AFE_MEMIF_MOD_DAI,
33 MT8173_AFE_MEMIF_HDMI,
34 MT8173_AFE_MEMIF_NUM,
35 MT8173_AFE_IO_MOD_PCM1 = MT8173_AFE_MEMIF_NUM,
36 MT8173_AFE_IO_MOD_PCM2,
37 MT8173_AFE_IO_PMIC,
38 MT8173_AFE_IO_I2S,
39 MT8173_AFE_IO_2ND_I2S,
40 MT8173_AFE_IO_HW_GAIN1,
41 MT8173_AFE_IO_HW_GAIN2,
42 MT8173_AFE_IO_MRG_O,
43 MT8173_AFE_IO_MRG_I,
44 MT8173_AFE_IO_DAIBT,
45 MT8173_AFE_IO_HDMI,
46};
47
48enum {
49 MT8173_AFE_IRQ_DL1,
50 MT8173_AFE_IRQ_DL2,
51 MT8173_AFE_IRQ_VUL,
52 MT8173_AFE_IRQ_DAI,
53 MT8173_AFE_IRQ_AWB,
54 MT8173_AFE_IRQ_MOD_DAI,
55 MT8173_AFE_IRQ_HDMI,
56 MT8173_AFE_IRQ_NUM,
57};
58
59enum {
60 MT8173_CLK_INFRASYS_AUD,
61 MT8173_CLK_TOP_PDN_AUD,
62 MT8173_CLK_TOP_PDN_AUD_BUS,
63 MT8173_CLK_I2S0_M,
64 MT8173_CLK_I2S1_M,
65 MT8173_CLK_I2S2_M,
66 MT8173_CLK_I2S3_M,
67 MT8173_CLK_I2S3_B,
68 MT8173_CLK_BCK0,
69 MT8173_CLK_BCK1,
70 MT8173_CLK_NUM
71};
72
73#endif
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index 2b5df2ef51a3..8a643a35d3d4 100644
--- a/sound/soc/mediatek/mtk-afe-pcm.c
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Mediatek ALSA SoC AFE platform driver 2 * Mediatek 8173 ALSA SoC AFE platform driver
3 * 3 *
4 * Copyright (c) 2015 MediaTek Inc. 4 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com> 5 * Author: Koro Chen <koro.chen@mediatek.com>
@@ -24,7 +24,10 @@
24#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/pm_runtime.h> 25#include <linux/pm_runtime.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include "mtk-afe-common.h" 27#include "mt8173-afe-common.h"
28#include "../common/mtk-base-afe.h"
29#include "../common/mtk-afe-platform-driver.h"
30#include "../common/mtk-afe-fe-dai.h"
28 31
29/***************************************************************************** 32/*****************************************************************************
30 * R E G I S T E R D E F I N I T I O N 33 * R E G I S T E R D E F I N I T I O N
@@ -81,7 +84,6 @@
81#define AFE_TDM_CON1 0x0548 84#define AFE_TDM_CON1 0x0548
82#define AFE_TDM_CON2 0x054c 85#define AFE_TDM_CON2 0x054c
83 86
84#define AFE_BASE_END_OFFSET 8
85#define AFE_IRQ_STATUS_BITS 0xff 87#define AFE_IRQ_STATUS_BITS 0xff
86 88
87/* AUDIO_TOP_CON0 (0x0000) */ 89/* AUDIO_TOP_CON0 (0x0000) */
@@ -135,7 +137,7 @@ enum afe_tdm_ch_start {
135 AFE_TDM_CH_ZERO, 137 AFE_TDM_CH_ZERO,
136}; 138};
137 139
138static const unsigned int mtk_afe_backup_list[] = { 140static const unsigned int mt8173_afe_backup_list[] = {
139 AUDIO_TOP_CON0, 141 AUDIO_TOP_CON0,
140 AFE_CONN1, 142 AFE_CONN1,
141 AFE_CONN2, 143 AFE_CONN2,
@@ -152,18 +154,11 @@ static const unsigned int mtk_afe_backup_list[] = {
152 AFE_DAC_CON0, 154 AFE_DAC_CON0,
153}; 155};
154 156
155struct mtk_afe { 157struct mt8173_afe_private {
156 /* address for ioremap audio hardware register */ 158 struct clk *clocks[MT8173_CLK_NUM];
157 void __iomem *base_addr;
158 struct device *dev;
159 struct regmap *regmap;
160 struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM];
161 struct clk *clocks[MTK_CLK_NUM];
162 unsigned int backup_regs[ARRAY_SIZE(mtk_afe_backup_list)];
163 bool suspended;
164}; 159};
165 160
166static const struct snd_pcm_hardware mtk_afe_hardware = { 161static const struct snd_pcm_hardware mt8173_afe_hardware = {
167 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 162 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
168 SNDRV_PCM_INFO_MMAP_VALID), 163 SNDRV_PCM_INFO_MMAP_VALID),
169 .buffer_bytes_max = 256 * 1024, 164 .buffer_bytes_max = 256 * 1024,
@@ -174,59 +169,12 @@ static const struct snd_pcm_hardware mtk_afe_hardware = {
174 .fifo_size = 0, 169 .fifo_size = 0,
175}; 170};
176 171
177static snd_pcm_uframes_t mtk_afe_pcm_pointer 172struct mt8173_afe_rate {
178 (struct snd_pcm_substream *substream)
179{
180 struct snd_soc_pcm_runtime *rtd = substream->private_data;
181 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
182 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
183 unsigned int hw_ptr;
184 int ret;
185
186 ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, &hw_ptr);
187 if (ret || hw_ptr == 0) {
188 dev_err(afe->dev, "%s hw_ptr err\n", __func__);
189 hw_ptr = memif->phys_buf_addr;
190 }
191
192 return bytes_to_frames(substream->runtime,
193 hw_ptr - memif->phys_buf_addr);
194}
195
196static const struct snd_pcm_ops mtk_afe_pcm_ops = {
197 .ioctl = snd_pcm_lib_ioctl,
198 .pointer = mtk_afe_pcm_pointer,
199};
200
201static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
202{
203 size_t size;
204 struct snd_card *card = rtd->card->snd_card;
205 struct snd_pcm *pcm = rtd->pcm;
206
207 size = mtk_afe_hardware.buffer_bytes_max;
208
209 return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
210 card->dev, size, size);
211}
212
213static void mtk_afe_pcm_free(struct snd_pcm *pcm)
214{
215 snd_pcm_lib_preallocate_free_for_all(pcm);
216}
217
218static const struct snd_soc_platform_driver mtk_afe_pcm_platform = {
219 .ops = &mtk_afe_pcm_ops,
220 .pcm_new = mtk_afe_pcm_new,
221 .pcm_free = mtk_afe_pcm_free,
222};
223
224struct mtk_afe_rate {
225 unsigned int rate; 173 unsigned int rate;
226 unsigned int regvalue; 174 unsigned int regvalue;
227}; 175};
228 176
229static const struct mtk_afe_rate mtk_afe_i2s_rates[] = { 177static const struct mt8173_afe_rate mt8173_afe_i2s_rates[] = {
230 { .rate = 8000, .regvalue = 0 }, 178 { .rate = 8000, .regvalue = 0 },
231 { .rate = 11025, .regvalue = 1 }, 179 { .rate = 11025, .regvalue = 1 },
232 { .rate = 12000, .regvalue = 2 }, 180 { .rate = 12000, .regvalue = 2 },
@@ -242,21 +190,21 @@ static const struct mtk_afe_rate mtk_afe_i2s_rates[] = {
242 { .rate = 192000, .regvalue = 14 }, 190 { .rate = 192000, .regvalue = 14 },
243}; 191};
244 192
245static int mtk_afe_i2s_fs(unsigned int sample_rate) 193static int mt8173_afe_i2s_fs(unsigned int sample_rate)
246{ 194{
247 int i; 195 int i;
248 196
249 for (i = 0; i < ARRAY_SIZE(mtk_afe_i2s_rates); i++) 197 for (i = 0; i < ARRAY_SIZE(mt8173_afe_i2s_rates); i++)
250 if (mtk_afe_i2s_rates[i].rate == sample_rate) 198 if (mt8173_afe_i2s_rates[i].rate == sample_rate)
251 return mtk_afe_i2s_rates[i].regvalue; 199 return mt8173_afe_i2s_rates[i].regvalue;
252 200
253 return -EINVAL; 201 return -EINVAL;
254} 202}
255 203
256static int mtk_afe_set_i2s(struct mtk_afe *afe, unsigned int rate) 204static int mt8173_afe_set_i2s(struct mtk_base_afe *afe, unsigned int rate)
257{ 205{
258 unsigned int val; 206 unsigned int val;
259 int fs = mtk_afe_i2s_fs(rate); 207 int fs = mt8173_afe_i2s_fs(rate);
260 208
261 if (fs < 0) 209 if (fs < 0)
262 return -EINVAL; 210 return -EINVAL;
@@ -281,7 +229,7 @@ static int mtk_afe_set_i2s(struct mtk_afe *afe, unsigned int rate)
281 return 0; 229 return 0;
282} 230}
283 231
284static void mtk_afe_set_i2s_enable(struct mtk_afe *afe, bool enable) 232static void mt8173_afe_set_i2s_enable(struct mtk_base_afe *afe, bool enable)
285{ 233{
286 unsigned int val; 234 unsigned int val;
287 235
@@ -296,8 +244,8 @@ static void mtk_afe_set_i2s_enable(struct mtk_afe *afe, bool enable)
296 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, enable); 244 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, enable);
297} 245}
298 246
299static int mtk_afe_dais_enable_clks(struct mtk_afe *afe, 247static int mt8173_afe_dais_enable_clks(struct mtk_base_afe *afe,
300 struct clk *m_ck, struct clk *b_ck) 248 struct clk *m_ck, struct clk *b_ck)
301{ 249{
302 int ret; 250 int ret;
303 251
@@ -319,9 +267,9 @@ static int mtk_afe_dais_enable_clks(struct mtk_afe *afe,
319 return 0; 267 return 0;
320} 268}
321 269
322static int mtk_afe_dais_set_clks(struct mtk_afe *afe, 270static int mt8173_afe_dais_set_clks(struct mtk_base_afe *afe,
323 struct clk *m_ck, unsigned int mck_rate, 271 struct clk *m_ck, unsigned int mck_rate,
324 struct clk *b_ck, unsigned int bck_rate) 272 struct clk *b_ck, unsigned int bck_rate)
325{ 273{
326 int ret; 274 int ret;
327 275
@@ -343,8 +291,8 @@ static int mtk_afe_dais_set_clks(struct mtk_afe *afe,
343 return 0; 291 return 0;
344} 292}
345 293
346static void mtk_afe_dais_disable_clks(struct mtk_afe *afe, 294static void mt8173_afe_dais_disable_clks(struct mtk_base_afe *afe,
347 struct clk *m_ck, struct clk *b_ck) 295 struct clk *m_ck, struct clk *b_ck)
348{ 296{
349 if (m_ck) 297 if (m_ck)
350 clk_disable_unprepare(m_ck); 298 clk_disable_unprepare(m_ck);
@@ -352,102 +300,101 @@ static void mtk_afe_dais_disable_clks(struct mtk_afe *afe,
352 clk_disable_unprepare(b_ck); 300 clk_disable_unprepare(b_ck);
353} 301}
354 302
355static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream, 303static int mt8173_afe_i2s_startup(struct snd_pcm_substream *substream,
356 struct snd_soc_dai *dai) 304 struct snd_soc_dai *dai)
357{ 305{
358 struct snd_soc_pcm_runtime *rtd = substream->private_data; 306 struct snd_soc_pcm_runtime *rtd = substream->private_data;
359 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 307 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
360 308
361 if (dai->active) 309 if (dai->active)
362 return 0; 310 return 0;
363 311
364 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
365 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S2_M], NULL);
366 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 312 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
367 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0); 313 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
368 return 0; 314 return 0;
369} 315}
370 316
371static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream, 317static void mt8173_afe_i2s_shutdown(struct snd_pcm_substream *substream,
372 struct snd_soc_dai *dai) 318 struct snd_soc_dai *dai)
373{ 319{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 320 struct snd_soc_pcm_runtime *rtd = substream->private_data;
375 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 321 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
376 322
377 if (dai->active) 323 if (dai->active)
378 return; 324 return;
379 325
380 mtk_afe_set_i2s_enable(afe, false); 326 mt8173_afe_set_i2s_enable(afe, false);
381 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 327 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
382 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 328 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
383 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M); 329 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
384 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
385 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S2_M], NULL);
386} 330}
387 331
388static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, 332static int mt8173_afe_i2s_prepare(struct snd_pcm_substream *substream,
389 struct snd_soc_dai *dai) 333 struct snd_soc_dai *dai)
390{ 334{
391 struct snd_soc_pcm_runtime *rtd = substream->private_data; 335 struct snd_soc_pcm_runtime *rtd = substream->private_data;
392 struct snd_pcm_runtime * const runtime = substream->runtime; 336 struct snd_pcm_runtime * const runtime = substream->runtime;
393 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 337 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
338 struct mt8173_afe_private *afe_priv = afe->platform_priv;
394 int ret; 339 int ret;
395 340
396 mtk_afe_dais_set_clks(afe, 341 mt8173_afe_dais_set_clks(afe, afe_priv->clocks[MT8173_CLK_I2S1_M],
397 afe->clocks[MTK_CLK_I2S1_M], runtime->rate * 256, 342 runtime->rate * 256, NULL, 0);
398 NULL, 0); 343 mt8173_afe_dais_set_clks(afe, afe_priv->clocks[MT8173_CLK_I2S2_M],
399 mtk_afe_dais_set_clks(afe, 344 runtime->rate * 256, NULL, 0);
400 afe->clocks[MTK_CLK_I2S2_M], runtime->rate * 256,
401 NULL, 0);
402 /* config I2S */ 345 /* config I2S */
403 ret = mtk_afe_set_i2s(afe, substream->runtime->rate); 346 ret = mt8173_afe_set_i2s(afe, substream->runtime->rate);
404 if (ret) 347 if (ret)
405 return ret; 348 return ret;
406 349
407 mtk_afe_set_i2s_enable(afe, true); 350 mt8173_afe_set_i2s_enable(afe, true);
408 351
409 return 0; 352 return 0;
410} 353}
411 354
412static int mtk_afe_hdmi_startup(struct snd_pcm_substream *substream, 355static int mt8173_afe_hdmi_startup(struct snd_pcm_substream *substream,
413 struct snd_soc_dai *dai) 356 struct snd_soc_dai *dai)
414{ 357{
415 struct snd_soc_pcm_runtime *rtd = substream->private_data; 358 struct snd_soc_pcm_runtime *rtd = substream->private_data;
416 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 359 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
360 struct mt8173_afe_private *afe_priv = afe->platform_priv;
417 361
418 if (dai->active) 362 if (dai->active)
419 return 0; 363 return 0;
420 364
421 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S3_M], 365 mt8173_afe_dais_enable_clks(afe, afe_priv->clocks[MT8173_CLK_I2S3_M],
422 afe->clocks[MTK_CLK_I2S3_B]); 366 afe_priv->clocks[MT8173_CLK_I2S3_B]);
423 return 0; 367 return 0;
424} 368}
425 369
426static void mtk_afe_hdmi_shutdown(struct snd_pcm_substream *substream, 370static void mt8173_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
427 struct snd_soc_dai *dai) 371 struct snd_soc_dai *dai)
428{ 372{
429 struct snd_soc_pcm_runtime *rtd = substream->private_data; 373 struct snd_soc_pcm_runtime *rtd = substream->private_data;
430 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 374 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
375 struct mt8173_afe_private *afe_priv = afe->platform_priv;
431 376
432 if (dai->active) 377 if (dai->active)
433 return; 378 return;
434 379
435 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M], 380 mt8173_afe_dais_disable_clks(afe, afe_priv->clocks[MT8173_CLK_I2S3_M],
436 afe->clocks[MTK_CLK_I2S3_B]); 381 afe_priv->clocks[MT8173_CLK_I2S3_B]);
437} 382}
438 383
439static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream, 384static int mt8173_afe_hdmi_prepare(struct snd_pcm_substream *substream,
440 struct snd_soc_dai *dai) 385 struct snd_soc_dai *dai)
441{ 386{
442 struct snd_soc_pcm_runtime *rtd = substream->private_data; 387 struct snd_soc_pcm_runtime *rtd = substream->private_data;
443 struct snd_pcm_runtime * const runtime = substream->runtime; 388 struct snd_pcm_runtime * const runtime = substream->runtime;
444 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 389 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
390 struct mt8173_afe_private *afe_priv = afe->platform_priv;
391
445 unsigned int val; 392 unsigned int val;
446 393
447 mtk_afe_dais_set_clks(afe, 394 mt8173_afe_dais_set_clks(afe, afe_priv->clocks[MT8173_CLK_I2S3_M],
448 afe->clocks[MTK_CLK_I2S3_M], runtime->rate * 128, 395 runtime->rate * 128,
449 afe->clocks[MTK_CLK_I2S3_B], 396 afe_priv->clocks[MT8173_CLK_I2S3_B],
450 runtime->rate * runtime->channels * 32); 397 runtime->rate * runtime->channels * 32);
451 398
452 val = AFE_TDM_CON1_BCK_INV | 399 val = AFE_TDM_CON1_BCK_INV |
453 AFE_TDM_CON1_LRCK_INV | 400 AFE_TDM_CON1_LRCK_INV |
@@ -498,11 +445,11 @@ static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream,
498 return 0; 445 return 0;
499} 446}
500 447
501static int mtk_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd, 448static int mt8173_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
502 struct snd_soc_dai *dai) 449 struct snd_soc_dai *dai)
503{ 450{
504 struct snd_soc_pcm_runtime *rtd = substream->private_data; 451 struct snd_soc_pcm_runtime *rtd = substream->private_data;
505 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 452 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
506 453
507 dev_info(afe->dev, "%s cmd=%d %s\n", __func__, cmd, dai->name); 454 dev_info(afe->dev, "%s cmd=%d %s\n", __func__, cmd, dai->name);
508 455
@@ -514,10 +461,14 @@ static int mtk_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
514 461
515 /* set connections: O30~O37: L/R/LS/RS/C/LFE/CH7/CH8 */ 462 /* set connections: O30~O37: L/R/LS/RS/C/LFE/CH7/CH8 */
516 regmap_write(afe->regmap, AFE_HDMI_CONN0, 463 regmap_write(afe->regmap, AFE_HDMI_CONN0,
517 AFE_HDMI_CONN0_O30_I30 | AFE_HDMI_CONN0_O31_I31 | 464 AFE_HDMI_CONN0_O30_I30 |
518 AFE_HDMI_CONN0_O32_I34 | AFE_HDMI_CONN0_O33_I35 | 465 AFE_HDMI_CONN0_O31_I31 |
519 AFE_HDMI_CONN0_O34_I32 | AFE_HDMI_CONN0_O35_I33 | 466 AFE_HDMI_CONN0_O32_I34 |
520 AFE_HDMI_CONN0_O36_I36 | AFE_HDMI_CONN0_O37_I37); 467 AFE_HDMI_CONN0_O33_I35 |
468 AFE_HDMI_CONN0_O34_I32 |
469 AFE_HDMI_CONN0_O35_I33 |
470 AFE_HDMI_CONN0_O36_I36 |
471 AFE_HDMI_CONN0_O37_I37);
521 472
522 /* enable Out control */ 473 /* enable Out control */
523 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 0x1, 0x1); 474 regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, 0x1, 0x1);
@@ -537,284 +488,65 @@ static int mtk_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
537 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 488 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
538 AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF, 489 AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF,
539 AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF); 490 AUD_TCON0_PDN_HDMI | AUD_TCON0_PDN_SPDF);
540
541 return 0; 491 return 0;
542 default: 492 default:
543 return -EINVAL; 493 return -EINVAL;
544 } 494 }
545} 495}
546 496
547static int mtk_afe_dais_startup(struct snd_pcm_substream *substream, 497static int mt8173_memif_fs(struct snd_pcm_substream *substream,
548 struct snd_soc_dai *dai) 498 unsigned int rate)
549{
550 struct snd_soc_pcm_runtime *rtd = substream->private_data;
551 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
552 struct snd_pcm_runtime *runtime = substream->runtime;
553 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
554 int ret;
555
556 memif->substream = substream;
557
558 snd_soc_set_runtime_hwparams(substream, &mtk_afe_hardware);
559
560 /*
561 * Capture cannot use ping-pong buffer since hw_ptr at IRQ may be
562 * smaller than period_size due to AFE's internal buffer.
563 * This easily leads to overrun when avail_min is period_size.
564 * One more period can hold the possible unread buffer.
565 */
566 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
567 ret = snd_pcm_hw_constraint_minmax(runtime,
568 SNDRV_PCM_HW_PARAM_PERIODS,
569 3,
570 mtk_afe_hardware.periods_max);
571 if (ret < 0) {
572 dev_err(afe->dev, "hw_constraint_minmax failed\n");
573 return ret;
574 }
575 }
576 ret = snd_pcm_hw_constraint_integer(runtime,
577 SNDRV_PCM_HW_PARAM_PERIODS);
578 if (ret < 0)
579 dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");
580 return ret;
581}
582
583static void mtk_afe_dais_shutdown(struct snd_pcm_substream *substream,
584 struct snd_soc_dai *dai)
585{ 499{
586 struct snd_soc_pcm_runtime *rtd = substream->private_data; 500 struct snd_soc_pcm_runtime *rtd = substream->private_data;
587 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 501 struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
588 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 502 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
589 503 int fs;
590 memif->substream = NULL;
591}
592
593static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream,
594 struct snd_pcm_hw_params *params,
595 struct snd_soc_dai *dai)
596{
597 struct snd_soc_pcm_runtime *rtd = substream->private_data;
598 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
599 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
600 int msb_at_bit33 = 0;
601 int ret;
602
603 dev_dbg(afe->dev,
604 "%s period = %u, rate= %u, channels=%u\n",
605 __func__, params_period_size(params), params_rate(params),
606 params_channels(params));
607 504
608 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 505 if (memif->data->id == MT8173_AFE_MEMIF_DAI ||
609 if (ret < 0) 506 memif->data->id == MT8173_AFE_MEMIF_MOD_DAI) {
610 return ret; 507 switch (rate) {
611
612 msb_at_bit33 = upper_32_bits(substream->runtime->dma_addr) ? 1 : 0;
613 memif->phys_buf_addr = lower_32_bits(substream->runtime->dma_addr);
614 memif->buffer_size = substream->runtime->dma_bytes;
615
616 /* start */
617 regmap_write(afe->regmap,
618 memif->data->reg_ofs_base, memif->phys_buf_addr);
619 /* end */
620 regmap_write(afe->regmap,
621 memif->data->reg_ofs_base + AFE_BASE_END_OFFSET,
622 memif->phys_buf_addr + memif->buffer_size - 1);
623
624 /* set MSB to 33-bit */
625 regmap_update_bits(afe->regmap, AFE_MEMIF_MSB,
626 1 << memif->data->msb_shift,
627 msb_at_bit33 << memif->data->msb_shift);
628
629 /* set channel */
630 if (memif->data->mono_shift >= 0) {
631 unsigned int mono = (params_channels(params) == 1) ? 1 : 0;
632
633 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
634 1 << memif->data->mono_shift,
635 mono << memif->data->mono_shift);
636 }
637
638 /* set rate */
639 if (memif->data->fs_shift < 0)
640 return 0;
641 if (memif->data->id == MTK_AFE_MEMIF_DAI ||
642 memif->data->id == MTK_AFE_MEMIF_MOD_DAI) {
643 unsigned int val;
644
645 switch (params_rate(params)) {
646 case 8000: 508 case 8000:
647 val = 0; 509 fs = 0;
648 break; 510 break;
649 case 16000: 511 case 16000:
650 val = 1; 512 fs = 1;
651 break; 513 break;
652 case 32000: 514 case 32000:
653 val = 2; 515 fs = 2;
654 break; 516 break;
655 default: 517 default:
656 return -EINVAL; 518 return -EINVAL;
657 } 519 }
658
659 if (memif->data->id == MTK_AFE_MEMIF_DAI)
660 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
661 0x3 << memif->data->fs_shift,
662 val << memif->data->fs_shift);
663 else
664 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
665 0x3 << memif->data->fs_shift,
666 val << memif->data->fs_shift);
667
668 } else { 520 } else {
669 int fs = mtk_afe_i2s_fs(params_rate(params)); 521 fs = mt8173_afe_i2s_fs(rate);
670
671 if (fs < 0)
672 return -EINVAL;
673
674 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
675 0xf << memif->data->fs_shift,
676 fs << memif->data->fs_shift);
677 } 522 }
678 523 return fs;
679 return 0;
680} 524}
681 525
682static int mtk_afe_dais_hw_free(struct snd_pcm_substream *substream, 526static int mt8173_irq_fs(struct snd_pcm_substream *substream, unsigned int rate)
683 struct snd_soc_dai *dai)
684{ 527{
685 return snd_pcm_lib_free_pages(substream); 528 return mt8173_afe_i2s_fs(rate);
686} 529}
687 530
688static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd,
689 struct snd_soc_dai *dai)
690{
691 struct snd_soc_pcm_runtime *rtd = substream->private_data;
692 struct snd_pcm_runtime * const runtime = substream->runtime;
693 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
694 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
695 unsigned int counter = runtime->period_size;
696
697 dev_info(afe->dev, "%s %s cmd=%d\n", __func__, memif->data->name, cmd);
698
699 switch (cmd) {
700 case SNDRV_PCM_TRIGGER_START:
701 case SNDRV_PCM_TRIGGER_RESUME:
702 if (memif->data->enable_shift >= 0)
703 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
704 1 << memif->data->enable_shift,
705 1 << memif->data->enable_shift);
706
707 /* set irq counter */
708 regmap_update_bits(afe->regmap,
709 memif->data->irq_reg_cnt,
710 0x3ffff << memif->data->irq_cnt_shift,
711 counter << memif->data->irq_cnt_shift);
712
713 /* set irq fs */
714 if (memif->data->irq_fs_shift >= 0) {
715 int fs = mtk_afe_i2s_fs(runtime->rate);
716
717 if (fs < 0)
718 return -EINVAL;
719
720 regmap_update_bits(afe->regmap,
721 AFE_IRQ_MCU_CON,
722 0xf << memif->data->irq_fs_shift,
723 fs << memif->data->irq_fs_shift);
724 }
725 /* enable interrupt */
726 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CON,
727 1 << memif->data->irq_en_shift,
728 1 << memif->data->irq_en_shift);
729
730 return 0;
731 case SNDRV_PCM_TRIGGER_STOP:
732 case SNDRV_PCM_TRIGGER_SUSPEND:
733 if (memif->data->enable_shift >= 0)
734 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
735 1 << memif->data->enable_shift, 0);
736 /* disable interrupt */
737 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CON,
738 1 << memif->data->irq_en_shift,
739 0 << memif->data->irq_en_shift);
740 /* and clear pending IRQ */
741 regmap_write(afe->regmap, AFE_IRQ_CLR,
742 1 << memif->data->irq_clr_shift);
743 return 0;
744 default:
745 return -EINVAL;
746 }
747}
748
749/* FE DAIs */
750static const struct snd_soc_dai_ops mtk_afe_dai_ops = {
751 .startup = mtk_afe_dais_startup,
752 .shutdown = mtk_afe_dais_shutdown,
753 .hw_params = mtk_afe_dais_hw_params,
754 .hw_free = mtk_afe_dais_hw_free,
755 .trigger = mtk_afe_dais_trigger,
756};
757
758/* BE DAIs */ 531/* BE DAIs */
759static const struct snd_soc_dai_ops mtk_afe_i2s_ops = { 532static const struct snd_soc_dai_ops mt8173_afe_i2s_ops = {
760 .startup = mtk_afe_i2s_startup, 533 .startup = mt8173_afe_i2s_startup,
761 .shutdown = mtk_afe_i2s_shutdown, 534 .shutdown = mt8173_afe_i2s_shutdown,
762 .prepare = mtk_afe_i2s_prepare, 535 .prepare = mt8173_afe_i2s_prepare,
763}; 536};
764 537
765static const struct snd_soc_dai_ops mtk_afe_hdmi_ops = { 538static const struct snd_soc_dai_ops mt8173_afe_hdmi_ops = {
766 .startup = mtk_afe_hdmi_startup, 539 .startup = mt8173_afe_hdmi_startup,
767 .shutdown = mtk_afe_hdmi_shutdown, 540 .shutdown = mt8173_afe_hdmi_shutdown,
768 .prepare = mtk_afe_hdmi_prepare, 541 .prepare = mt8173_afe_hdmi_prepare,
769 .trigger = mtk_afe_hdmi_trigger, 542 .trigger = mt8173_afe_hdmi_trigger,
770
771}; 543};
772 544
773static int mtk_afe_runtime_suspend(struct device *dev); 545static struct snd_soc_dai_driver mt8173_afe_pcm_dais[] = {
774static int mtk_afe_runtime_resume(struct device *dev);
775
776static int mtk_afe_dai_suspend(struct snd_soc_dai *dai)
777{
778 struct mtk_afe *afe = snd_soc_dai_get_drvdata(dai);
779 int i;
780
781 dev_dbg(afe->dev, "%s\n", __func__);
782 if (pm_runtime_status_suspended(afe->dev) || afe->suspended)
783 return 0;
784
785 for (i = 0; i < ARRAY_SIZE(mtk_afe_backup_list); i++)
786 regmap_read(afe->regmap, mtk_afe_backup_list[i],
787 &afe->backup_regs[i]);
788
789 afe->suspended = true;
790 mtk_afe_runtime_suspend(afe->dev);
791 return 0;
792}
793
794static int mtk_afe_dai_resume(struct snd_soc_dai *dai)
795{
796 struct mtk_afe *afe = snd_soc_dai_get_drvdata(dai);
797 int i = 0;
798
799 dev_dbg(afe->dev, "%s\n", __func__);
800 if (pm_runtime_status_suspended(afe->dev) || !afe->suspended)
801 return 0;
802
803 mtk_afe_runtime_resume(afe->dev);
804
805 for (i = 0; i < ARRAY_SIZE(mtk_afe_backup_list); i++)
806 regmap_write(afe->regmap, mtk_afe_backup_list[i],
807 afe->backup_regs[i]);
808
809 afe->suspended = false;
810 return 0;
811}
812
813static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = {
814 /* FE DAIs: memory intefaces to CPU */ 546 /* FE DAIs: memory intefaces to CPU */
815 { 547 {
816 .name = "DL1", /* downlink 1 */ 548 .name = "DL1", /* downlink 1 */
817 .id = MTK_AFE_MEMIF_DL1, 549 .id = MT8173_AFE_MEMIF_DL1,
818 .suspend = mtk_afe_dai_suspend, 550 .suspend = mtk_afe_dai_suspend,
819 .resume = mtk_afe_dai_resume, 551 .resume = mtk_afe_dai_resume,
820 .playback = { 552 .playback = {
@@ -824,10 +556,10 @@ static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = {
824 .rates = SNDRV_PCM_RATE_8000_48000, 556 .rates = SNDRV_PCM_RATE_8000_48000,
825 .formats = SNDRV_PCM_FMTBIT_S16_LE, 557 .formats = SNDRV_PCM_FMTBIT_S16_LE,
826 }, 558 },
827 .ops = &mtk_afe_dai_ops, 559 .ops = &mtk_afe_fe_ops,
828 }, { 560 }, {
829 .name = "VUL", /* voice uplink */ 561 .name = "VUL", /* voice uplink */
830 .id = MTK_AFE_MEMIF_VUL, 562 .id = MT8173_AFE_MEMIF_VUL,
831 .suspend = mtk_afe_dai_suspend, 563 .suspend = mtk_afe_dai_suspend,
832 .resume = mtk_afe_dai_resume, 564 .resume = mtk_afe_dai_resume,
833 .capture = { 565 .capture = {
@@ -837,11 +569,11 @@ static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = {
837 .rates = SNDRV_PCM_RATE_8000_48000, 569 .rates = SNDRV_PCM_RATE_8000_48000,
838 .formats = SNDRV_PCM_FMTBIT_S16_LE, 570 .formats = SNDRV_PCM_FMTBIT_S16_LE,
839 }, 571 },
840 .ops = &mtk_afe_dai_ops, 572 .ops = &mtk_afe_fe_ops,
841 }, { 573 }, {
842 /* BE DAIs */ 574 /* BE DAIs */
843 .name = "I2S", 575 .name = "I2S",
844 .id = MTK_AFE_IO_I2S, 576 .id = MT8173_AFE_IO_I2S,
845 .playback = { 577 .playback = {
846 .stream_name = "I2S Playback", 578 .stream_name = "I2S Playback",
847 .channels_min = 1, 579 .channels_min = 1,
@@ -856,16 +588,16 @@ static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = {
856 .rates = SNDRV_PCM_RATE_8000_48000, 588 .rates = SNDRV_PCM_RATE_8000_48000,
857 .formats = SNDRV_PCM_FMTBIT_S16_LE, 589 .formats = SNDRV_PCM_FMTBIT_S16_LE,
858 }, 590 },
859 .ops = &mtk_afe_i2s_ops, 591 .ops = &mt8173_afe_i2s_ops,
860 .symmetric_rates = 1, 592 .symmetric_rates = 1,
861 }, 593 },
862}; 594};
863 595
864static struct snd_soc_dai_driver mtk_afe_hdmi_dais[] = { 596static struct snd_soc_dai_driver mt8173_afe_hdmi_dais[] = {
865 /* FE DAIs */ 597 /* FE DAIs */
866 { 598 {
867 .name = "HDMI", 599 .name = "HDMI",
868 .id = MTK_AFE_MEMIF_HDMI, 600 .id = MT8173_AFE_MEMIF_HDMI,
869 .suspend = mtk_afe_dai_suspend, 601 .suspend = mtk_afe_dai_suspend,
870 .resume = mtk_afe_dai_resume, 602 .resume = mtk_afe_dai_resume,
871 .playback = { 603 .playback = {
@@ -878,11 +610,11 @@ static struct snd_soc_dai_driver mtk_afe_hdmi_dais[] = {
878 SNDRV_PCM_RATE_192000, 610 SNDRV_PCM_RATE_192000,
879 .formats = SNDRV_PCM_FMTBIT_S16_LE, 611 .formats = SNDRV_PCM_FMTBIT_S16_LE,
880 }, 612 },
881 .ops = &mtk_afe_dai_ops, 613 .ops = &mtk_afe_fe_ops,
882 }, { 614 }, {
883 /* BE DAIs */ 615 /* BE DAIs */
884 .name = "HDMIO", 616 .name = "HDMIO",
885 .id = MTK_AFE_IO_HDMI, 617 .id = MT8173_AFE_IO_HDMI,
886 .playback = { 618 .playback = {
887 .stream_name = "HDMIO Playback", 619 .stream_name = "HDMIO Playback",
888 .channels_min = 2, 620 .channels_min = 2,
@@ -893,29 +625,29 @@ static struct snd_soc_dai_driver mtk_afe_hdmi_dais[] = {
893 SNDRV_PCM_RATE_192000, 625 SNDRV_PCM_RATE_192000,
894 .formats = SNDRV_PCM_FMTBIT_S16_LE, 626 .formats = SNDRV_PCM_FMTBIT_S16_LE,
895 }, 627 },
896 .ops = &mtk_afe_hdmi_ops, 628 .ops = &mt8173_afe_hdmi_ops,
897 }, 629 },
898}; 630};
899 631
900static const struct snd_kcontrol_new mtk_afe_o03_mix[] = { 632static const struct snd_kcontrol_new mt8173_afe_o03_mix[] = {
901 SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN1, 21, 1, 0), 633 SOC_DAPM_SINGLE_AUTODISABLE("I05 Switch", AFE_CONN1, 21, 1, 0),
902}; 634};
903 635
904static const struct snd_kcontrol_new mtk_afe_o04_mix[] = { 636static const struct snd_kcontrol_new mt8173_afe_o04_mix[] = {
905 SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN2, 6, 1, 0), 637 SOC_DAPM_SINGLE_AUTODISABLE("I06 Switch", AFE_CONN2, 6, 1, 0),
906}; 638};
907 639
908static const struct snd_kcontrol_new mtk_afe_o09_mix[] = { 640static const struct snd_kcontrol_new mt8173_afe_o09_mix[] = {
909 SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 0, 1, 0), 641 SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 0, 1, 0),
910 SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN7, 30, 1, 0), 642 SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN7, 30, 1, 0),
911}; 643};
912 644
913static const struct snd_kcontrol_new mtk_afe_o10_mix[] = { 645static const struct snd_kcontrol_new mt8173_afe_o10_mix[] = {
914 SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN3, 3, 1, 0), 646 SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN3, 3, 1, 0),
915 SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN8, 0, 1, 0), 647 SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN8, 0, 1, 0),
916}; 648};
917 649
918static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = { 650static const struct snd_soc_dapm_widget mt8173_afe_pcm_widgets[] = {
919 /* inter-connections */ 651 /* inter-connections */
920 SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0), 652 SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),
921 SND_SOC_DAPM_MIXER("I04", SND_SOC_NOPM, 0, 0, NULL, 0), 653 SND_SOC_DAPM_MIXER("I04", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -925,16 +657,16 @@ static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = {
925 SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0), 657 SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0),
926 658
927 SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, 659 SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0,
928 mtk_afe_o03_mix, ARRAY_SIZE(mtk_afe_o03_mix)), 660 mt8173_afe_o03_mix, ARRAY_SIZE(mt8173_afe_o03_mix)),
929 SND_SOC_DAPM_MIXER("O04", SND_SOC_NOPM, 0, 0, 661 SND_SOC_DAPM_MIXER("O04", SND_SOC_NOPM, 0, 0,
930 mtk_afe_o04_mix, ARRAY_SIZE(mtk_afe_o04_mix)), 662 mt8173_afe_o04_mix, ARRAY_SIZE(mt8173_afe_o04_mix)),
931 SND_SOC_DAPM_MIXER("O09", SND_SOC_NOPM, 0, 0, 663 SND_SOC_DAPM_MIXER("O09", SND_SOC_NOPM, 0, 0,
932 mtk_afe_o09_mix, ARRAY_SIZE(mtk_afe_o09_mix)), 664 mt8173_afe_o09_mix, ARRAY_SIZE(mt8173_afe_o09_mix)),
933 SND_SOC_DAPM_MIXER("O10", SND_SOC_NOPM, 0, 0, 665 SND_SOC_DAPM_MIXER("O10", SND_SOC_NOPM, 0, 0,
934 mtk_afe_o10_mix, ARRAY_SIZE(mtk_afe_o10_mix)), 666 mt8173_afe_o10_mix, ARRAY_SIZE(mt8173_afe_o10_mix)),
935}; 667};
936 668
937static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = { 669static const struct snd_soc_dapm_route mt8173_afe_pcm_routes[] = {
938 {"I05", NULL, "DL1"}, 670 {"I05", NULL, "DL1"},
939 {"I06", NULL, "DL1"}, 671 {"I06", NULL, "DL1"},
940 {"I2S Playback", NULL, "O03"}, 672 {"I2S Playback", NULL, "O03"},
@@ -953,140 +685,257 @@ static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = {
953 { "O10", "I04 Switch", "I04" }, 685 { "O10", "I04 Switch", "I04" },
954}; 686};
955 687
956static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = { 688static const struct snd_soc_dapm_route mt8173_afe_hdmi_routes[] = {
957 {"HDMIO Playback", NULL, "HDMI"}, 689 {"HDMIO Playback", NULL, "HDMI"},
958}; 690};
959 691
960static const struct snd_soc_component_driver mtk_afe_pcm_dai_component = { 692static const struct snd_soc_component_driver mt8173_afe_pcm_dai_component = {
961 .name = "mtk-afe-pcm-dai", 693 .name = "mt8173-afe-pcm-dai",
962 .dapm_widgets = mtk_afe_pcm_widgets, 694 .dapm_widgets = mt8173_afe_pcm_widgets,
963 .num_dapm_widgets = ARRAY_SIZE(mtk_afe_pcm_widgets), 695 .num_dapm_widgets = ARRAY_SIZE(mt8173_afe_pcm_widgets),
964 .dapm_routes = mtk_afe_pcm_routes, 696 .dapm_routes = mt8173_afe_pcm_routes,
965 .num_dapm_routes = ARRAY_SIZE(mtk_afe_pcm_routes), 697 .num_dapm_routes = ARRAY_SIZE(mt8173_afe_pcm_routes),
966}; 698};
967 699
968static const struct snd_soc_component_driver mtk_afe_hdmi_dai_component = { 700static const struct snd_soc_component_driver mt8173_afe_hdmi_dai_component = {
969 .name = "mtk-afe-hdmi-dai", 701 .name = "mt8173-afe-hdmi-dai",
970 .dapm_routes = mtk_afe_hdmi_routes, 702 .dapm_routes = mt8173_afe_hdmi_routes,
971 .num_dapm_routes = ARRAY_SIZE(mtk_afe_hdmi_routes), 703 .num_dapm_routes = ARRAY_SIZE(mt8173_afe_hdmi_routes),
972}; 704};
973 705
974static const char *aud_clks[MTK_CLK_NUM] = { 706static const char *aud_clks[MT8173_CLK_NUM] = {
975 [MTK_CLK_INFRASYS_AUD] = "infra_sys_audio_clk", 707 [MT8173_CLK_INFRASYS_AUD] = "infra_sys_audio_clk",
976 [MTK_CLK_TOP_PDN_AUD] = "top_pdn_audio", 708 [MT8173_CLK_TOP_PDN_AUD] = "top_pdn_audio",
977 [MTK_CLK_TOP_PDN_AUD_BUS] = "top_pdn_aud_intbus", 709 [MT8173_CLK_TOP_PDN_AUD_BUS] = "top_pdn_aud_intbus",
978 [MTK_CLK_I2S0_M] = "i2s0_m", 710 [MT8173_CLK_I2S0_M] = "i2s0_m",
979 [MTK_CLK_I2S1_M] = "i2s1_m", 711 [MT8173_CLK_I2S1_M] = "i2s1_m",
980 [MTK_CLK_I2S2_M] = "i2s2_m", 712 [MT8173_CLK_I2S2_M] = "i2s2_m",
981 [MTK_CLK_I2S3_M] = "i2s3_m", 713 [MT8173_CLK_I2S3_M] = "i2s3_m",
982 [MTK_CLK_I2S3_B] = "i2s3_b", 714 [MT8173_CLK_I2S3_B] = "i2s3_b",
983 [MTK_CLK_BCK0] = "bck0", 715 [MT8173_CLK_BCK0] = "bck0",
984 [MTK_CLK_BCK1] = "bck1", 716 [MT8173_CLK_BCK1] = "bck1",
985}; 717};
986 718
987static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { 719static const struct mtk_base_memif_data memif_data[MT8173_AFE_MEMIF_NUM] = {
988 { 720 {
989 .name = "DL1", 721 .name = "DL1",
990 .id = MTK_AFE_MEMIF_DL1, 722 .id = MT8173_AFE_MEMIF_DL1,
991 .reg_ofs_base = AFE_DL1_BASE, 723 .reg_ofs_base = AFE_DL1_BASE,
992 .reg_ofs_cur = AFE_DL1_CUR, 724 .reg_ofs_cur = AFE_DL1_CUR,
725 .fs_reg = AFE_DAC_CON1,
993 .fs_shift = 0, 726 .fs_shift = 0,
727 .fs_maskbit = 0xf,
728 .mono_reg = AFE_DAC_CON1,
994 .mono_shift = 21, 729 .mono_shift = 21,
730 .hd_reg = -1,
731 .hd_shift = -1,
732 .enable_reg = AFE_DAC_CON0,
995 .enable_shift = 1, 733 .enable_shift = 1,
996 .irq_reg_cnt = AFE_IRQ_CNT1, 734 .msb_reg = AFE_MEMIF_MSB,
997 .irq_cnt_shift = 0,
998 .irq_en_shift = 0,
999 .irq_fs_shift = 4,
1000 .irq_clr_shift = 0,
1001 .msb_shift = 0, 735 .msb_shift = 0,
736 .agent_disable_reg = -1,
737 .agent_disable_shift = -1,
1002 }, { 738 }, {
1003 .name = "DL2", 739 .name = "DL2",
1004 .id = MTK_AFE_MEMIF_DL2, 740 .id = MT8173_AFE_MEMIF_DL2,
1005 .reg_ofs_base = AFE_DL2_BASE, 741 .reg_ofs_base = AFE_DL2_BASE,
1006 .reg_ofs_cur = AFE_DL2_CUR, 742 .reg_ofs_cur = AFE_DL2_CUR,
743 .fs_reg = AFE_DAC_CON1,
1007 .fs_shift = 4, 744 .fs_shift = 4,
745 .fs_maskbit = 0xf,
746 .mono_reg = AFE_DAC_CON1,
1008 .mono_shift = 22, 747 .mono_shift = 22,
748 .hd_reg = -1,
749 .hd_shift = -1,
750 .enable_reg = AFE_DAC_CON0,
1009 .enable_shift = 2, 751 .enable_shift = 2,
1010 .irq_reg_cnt = AFE_IRQ_CNT1, 752 .msb_reg = AFE_MEMIF_MSB,
1011 .irq_cnt_shift = 20,
1012 .irq_en_shift = 2,
1013 .irq_fs_shift = 16,
1014 .irq_clr_shift = 2,
1015 .msb_shift = 1, 753 .msb_shift = 1,
754 .agent_disable_reg = -1,
755 .agent_disable_shift = -1,
1016 }, { 756 }, {
1017 .name = "VUL", 757 .name = "VUL",
1018 .id = MTK_AFE_MEMIF_VUL, 758 .id = MT8173_AFE_MEMIF_VUL,
1019 .reg_ofs_base = AFE_VUL_BASE, 759 .reg_ofs_base = AFE_VUL_BASE,
1020 .reg_ofs_cur = AFE_VUL_CUR, 760 .reg_ofs_cur = AFE_VUL_CUR,
761 .fs_reg = AFE_DAC_CON1,
1021 .fs_shift = 16, 762 .fs_shift = 16,
763 .fs_maskbit = 0xf,
764 .mono_reg = AFE_DAC_CON1,
1022 .mono_shift = 27, 765 .mono_shift = 27,
766 .hd_reg = -1,
767 .hd_shift = -1,
768 .enable_reg = AFE_DAC_CON0,
1023 .enable_shift = 3, 769 .enable_shift = 3,
1024 .irq_reg_cnt = AFE_IRQ_CNT2, 770 .msb_reg = AFE_MEMIF_MSB,
1025 .irq_cnt_shift = 0,
1026 .irq_en_shift = 1,
1027 .irq_fs_shift = 8,
1028 .irq_clr_shift = 1,
1029 .msb_shift = 6, 771 .msb_shift = 6,
772 .agent_disable_reg = -1,
773 .agent_disable_shift = -1,
1030 }, { 774 }, {
1031 .name = "DAI", 775 .name = "DAI",
1032 .id = MTK_AFE_MEMIF_DAI, 776 .id = MT8173_AFE_MEMIF_DAI,
1033 .reg_ofs_base = AFE_DAI_BASE, 777 .reg_ofs_base = AFE_DAI_BASE,
1034 .reg_ofs_cur = AFE_DAI_CUR, 778 .reg_ofs_cur = AFE_DAI_CUR,
779 .fs_reg = AFE_DAC_CON0,
1035 .fs_shift = 24, 780 .fs_shift = 24,
781 .fs_maskbit = 0x3,
782 .mono_reg = -1,
1036 .mono_shift = -1, 783 .mono_shift = -1,
784 .hd_reg = -1,
785 .hd_shift = -1,
786 .enable_reg = AFE_DAC_CON0,
1037 .enable_shift = 4, 787 .enable_shift = 4,
1038 .irq_reg_cnt = AFE_IRQ_CNT2, 788 .msb_reg = AFE_MEMIF_MSB,
1039 .irq_cnt_shift = 20,
1040 .irq_en_shift = 3,
1041 .irq_fs_shift = 20,
1042 .irq_clr_shift = 3,
1043 .msb_shift = 5, 789 .msb_shift = 5,
790 .agent_disable_reg = -1,
791 .agent_disable_shift = -1,
1044 }, { 792 }, {
1045 .name = "AWB", 793 .name = "AWB",
1046 .id = MTK_AFE_MEMIF_AWB, 794 .id = MT8173_AFE_MEMIF_AWB,
1047 .reg_ofs_base = AFE_AWB_BASE, 795 .reg_ofs_base = AFE_AWB_BASE,
1048 .reg_ofs_cur = AFE_AWB_CUR, 796 .reg_ofs_cur = AFE_AWB_CUR,
797 .fs_reg = AFE_DAC_CON1,
1049 .fs_shift = 12, 798 .fs_shift = 12,
799 .fs_maskbit = 0xf,
800 .mono_reg = AFE_DAC_CON1,
1050 .mono_shift = 24, 801 .mono_shift = 24,
802 .hd_reg = -1,
803 .hd_shift = -1,
804 .enable_reg = AFE_DAC_CON0,
1051 .enable_shift = 6, 805 .enable_shift = 6,
1052 .irq_reg_cnt = AFE_IRQ_CNT7, 806 .msb_reg = AFE_MEMIF_MSB,
1053 .irq_cnt_shift = 0,
1054 .irq_en_shift = 14,
1055 .irq_fs_shift = 24,
1056 .irq_clr_shift = 6,
1057 .msb_shift = 3, 807 .msb_shift = 3,
808 .agent_disable_reg = -1,
809 .agent_disable_shift = -1,
1058 }, { 810 }, {
1059 .name = "MOD_DAI", 811 .name = "MOD_DAI",
1060 .id = MTK_AFE_MEMIF_MOD_DAI, 812 .id = MT8173_AFE_MEMIF_MOD_DAI,
1061 .reg_ofs_base = AFE_MOD_PCM_BASE, 813 .reg_ofs_base = AFE_MOD_PCM_BASE,
1062 .reg_ofs_cur = AFE_MOD_PCM_CUR, 814 .reg_ofs_cur = AFE_MOD_PCM_CUR,
815 .fs_reg = AFE_DAC_CON1,
1063 .fs_shift = 30, 816 .fs_shift = 30,
817 .fs_maskbit = 0x3,
818 .mono_reg = AFE_DAC_CON1,
1064 .mono_shift = 30, 819 .mono_shift = 30,
820 .hd_reg = -1,
821 .hd_shift = -1,
822 .enable_reg = AFE_DAC_CON0,
1065 .enable_shift = 7, 823 .enable_shift = 7,
1066 .irq_reg_cnt = AFE_IRQ_CNT2, 824 .msb_reg = AFE_MEMIF_MSB,
1067 .irq_cnt_shift = 20,
1068 .irq_en_shift = 3,
1069 .irq_fs_shift = 20,
1070 .irq_clr_shift = 3,
1071 .msb_shift = 4, 825 .msb_shift = 4,
826 .agent_disable_reg = -1,
827 .agent_disable_shift = -1,
1072 }, { 828 }, {
1073 .name = "HDMI", 829 .name = "HDMI",
1074 .id = MTK_AFE_MEMIF_HDMI, 830 .id = MT8173_AFE_MEMIF_HDMI,
1075 .reg_ofs_base = AFE_HDMI_OUT_BASE, 831 .reg_ofs_base = AFE_HDMI_OUT_BASE,
1076 .reg_ofs_cur = AFE_HDMI_OUT_CUR, 832 .reg_ofs_cur = AFE_HDMI_OUT_CUR,
833 .fs_reg = -1,
1077 .fs_shift = -1, 834 .fs_shift = -1,
835 .fs_maskbit = -1,
836 .mono_reg = -1,
1078 .mono_shift = -1, 837 .mono_shift = -1,
838 .hd_reg = -1,
839 .hd_shift = -1,
840 .enable_reg = -1,
1079 .enable_shift = -1, 841 .enable_shift = -1,
1080 .irq_reg_cnt = AFE_IRQ_CNT5, 842 .msb_reg = AFE_MEMIF_MSB,
843 .msb_shift = 8,
844 .agent_disable_reg = -1,
845 .agent_disable_shift = -1,
846 },
847};
848
849static const struct mtk_base_irq_data irq_data[MT8173_AFE_IRQ_NUM] = {
850 {
851 .id = MT8173_AFE_IRQ_DL1,
852 .irq_cnt_reg = AFE_IRQ_CNT1,
853 .irq_cnt_shift = 0,
854 .irq_cnt_maskbit = 0x3ffff,
855 .irq_en_reg = AFE_IRQ_MCU_CON,
856 .irq_en_shift = 0,
857 .irq_fs_reg = AFE_IRQ_MCU_CON,
858 .irq_fs_shift = 4,
859 .irq_fs_maskbit = 0xf,
860 .irq_clr_reg = AFE_IRQ_CLR,
861 .irq_clr_shift = 0,
862 }, {
863 .id = MT8173_AFE_IRQ_DL2,
864 .irq_cnt_reg = AFE_IRQ_CNT1,
865 .irq_cnt_shift = 20,
866 .irq_cnt_maskbit = 0x3ffff,
867 .irq_en_reg = AFE_IRQ_MCU_CON,
868 .irq_en_shift = 2,
869 .irq_fs_reg = AFE_IRQ_MCU_CON,
870 .irq_fs_shift = 16,
871 .irq_fs_maskbit = 0xf,
872 .irq_clr_reg = AFE_IRQ_CLR,
873 .irq_clr_shift = 2,
874
875 }, {
876 .id = MT8173_AFE_IRQ_VUL,
877 .irq_cnt_reg = AFE_IRQ_CNT2,
878 .irq_cnt_shift = 0,
879 .irq_cnt_maskbit = 0x3ffff,
880 .irq_en_reg = AFE_IRQ_MCU_CON,
881 .irq_en_shift = 1,
882 .irq_fs_reg = AFE_IRQ_MCU_CON,
883 .irq_fs_shift = 8,
884 .irq_fs_maskbit = 0xf,
885 .irq_clr_reg = AFE_IRQ_CLR,
886 .irq_clr_shift = 1,
887 }, {
888 .id = MT8173_AFE_IRQ_DAI,
889 .irq_cnt_reg = AFE_IRQ_CNT2,
890 .irq_cnt_shift = 20,
891 .irq_cnt_maskbit = 0x3ffff,
892 .irq_en_reg = AFE_IRQ_MCU_CON,
893 .irq_en_shift = 3,
894 .irq_fs_reg = AFE_IRQ_MCU_CON,
895 .irq_fs_shift = 20,
896 .irq_fs_maskbit = 0xf,
897 .irq_clr_reg = AFE_IRQ_CLR,
898 .irq_clr_shift = 3,
899 }, {
900 .id = MT8173_AFE_IRQ_AWB,
901 .irq_cnt_reg = AFE_IRQ_CNT7,
1081 .irq_cnt_shift = 0, 902 .irq_cnt_shift = 0,
903 .irq_cnt_maskbit = 0x3ffff,
904 .irq_en_reg = AFE_IRQ_MCU_CON,
905 .irq_en_shift = 14,
906 .irq_fs_reg = AFE_IRQ_MCU_CON,
907 .irq_fs_shift = 24,
908 .irq_fs_maskbit = 0xf,
909 .irq_clr_reg = AFE_IRQ_CLR,
910 .irq_clr_shift = 6,
911 }, {
912 .id = MT8173_AFE_IRQ_DAI,
913 .irq_cnt_reg = AFE_IRQ_CNT2,
914 .irq_cnt_shift = 20,
915 .irq_cnt_maskbit = 0x3ffff,
916 .irq_en_reg = AFE_IRQ_MCU_CON,
917 .irq_en_shift = 3,
918 .irq_fs_reg = AFE_IRQ_MCU_CON,
919 .irq_fs_shift = 20,
920 .irq_fs_maskbit = 0xf,
921 .irq_clr_reg = AFE_IRQ_CLR,
922 .irq_clr_shift = 3,
923 }, {
924 .id = MT8173_AFE_IRQ_HDMI,
925 .irq_cnt_reg = AFE_IRQ_CNT5,
926 .irq_cnt_shift = 0,
927 .irq_cnt_maskbit = 0x3ffff,
928 .irq_en_reg = AFE_IRQ_MCU_CON,
1082 .irq_en_shift = 12, 929 .irq_en_shift = 12,
930 .irq_fs_reg = -1,
1083 .irq_fs_shift = -1, 931 .irq_fs_shift = -1,
932 .irq_fs_maskbit = -1,
933 .irq_clr_reg = AFE_IRQ_CLR,
1084 .irq_clr_shift = 4, 934 .irq_clr_shift = 4,
1085 .msb_shift = 8,
1086 }, 935 },
1087}; 936};
1088 937
1089static const struct regmap_config mtk_afe_regmap_config = { 938static const struct regmap_config mt8173_afe_regmap_config = {
1090 .reg_bits = 32, 939 .reg_bits = 32,
1091 .reg_stride = 4, 940 .reg_stride = 4,
1092 .val_bits = 32, 941 .val_bits = 32,
@@ -1094,9 +943,9 @@ static const struct regmap_config mtk_afe_regmap_config = {
1094 .cache_type = REGCACHE_NONE, 943 .cache_type = REGCACHE_NONE,
1095}; 944};
1096 945
1097static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id) 946static irqreturn_t mt8173_afe_irq_handler(int irq, void *dev_id)
1098{ 947{
1099 struct mtk_afe *afe = dev_id; 948 struct mtk_base_afe *afe = dev_id;
1100 unsigned int reg_value; 949 unsigned int reg_value;
1101 int i, ret; 950 int i, ret;
1102 951
@@ -1107,10 +956,16 @@ static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id)
1107 goto err_irq; 956 goto err_irq;
1108 } 957 }
1109 958
1110 for (i = 0; i < MTK_AFE_MEMIF_NUM; i++) { 959 for (i = 0; i < MT8173_AFE_MEMIF_NUM; i++) {
1111 struct mtk_afe_memif *memif = &afe->memif[i]; 960 struct mtk_base_afe_memif *memif = &afe->memif[i];
961 struct mtk_base_afe_irq *irq;
1112 962
1113 if (!(reg_value & (1 << memif->data->irq_clr_shift))) 963 if (memif->irq_usage < 0)
964 continue;
965
966 irq = &afe->irqs[memif->irq_usage];
967
968 if (!(reg_value & (1 << irq->irq_data->irq_clr_shift)))
1114 continue; 969 continue;
1115 970
1116 snd_pcm_period_elapsed(memif->substream); 971 snd_pcm_period_elapsed(memif->substream);
@@ -1118,14 +973,16 @@ static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id)
1118 973
1119err_irq: 974err_irq:
1120 /* clear irq */ 975 /* clear irq */
1121 regmap_write(afe->regmap, AFE_IRQ_CLR, reg_value & AFE_IRQ_STATUS_BITS); 976 regmap_write(afe->regmap, AFE_IRQ_CLR,
977 reg_value & AFE_IRQ_STATUS_BITS);
1122 978
1123 return IRQ_HANDLED; 979 return IRQ_HANDLED;
1124} 980}
1125 981
1126static int mtk_afe_runtime_suspend(struct device *dev) 982static int mt8173_afe_runtime_suspend(struct device *dev)
1127{ 983{
1128 struct mtk_afe *afe = dev_get_drvdata(dev); 984 struct mtk_base_afe *afe = dev_get_drvdata(dev);
985 struct mt8173_afe_private *afe_priv = afe->platform_priv;
1129 986
1130 /* disable AFE */ 987 /* disable AFE */
1131 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0); 988 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
@@ -1134,38 +991,47 @@ static int mtk_afe_runtime_suspend(struct device *dev)
1134 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 991 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
1135 AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE); 992 AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE);
1136 993
1137 clk_disable_unprepare(afe->clocks[MTK_CLK_BCK0]); 994 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_I2S1_M]);
1138 clk_disable_unprepare(afe->clocks[MTK_CLK_BCK1]); 995 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_I2S2_M]);
1139 clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD]); 996 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_BCK0]);
1140 clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]); 997 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_BCK1]);
1141 clk_disable_unprepare(afe->clocks[MTK_CLK_INFRASYS_AUD]); 998 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_TOP_PDN_AUD]);
999 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_TOP_PDN_AUD_BUS]);
1000 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_INFRASYS_AUD]);
1142 return 0; 1001 return 0;
1143} 1002}
1144 1003
1145static int mtk_afe_runtime_resume(struct device *dev) 1004static int mt8173_afe_runtime_resume(struct device *dev)
1146{ 1005{
1147 struct mtk_afe *afe = dev_get_drvdata(dev); 1006 struct mtk_base_afe *afe = dev_get_drvdata(dev);
1007 struct mt8173_afe_private *afe_priv = afe->platform_priv;
1148 int ret; 1008 int ret;
1149 1009
1150 ret = clk_prepare_enable(afe->clocks[MTK_CLK_INFRASYS_AUD]); 1010 ret = clk_prepare_enable(afe_priv->clocks[MT8173_CLK_INFRASYS_AUD]);
1151 if (ret) 1011 if (ret)
1152 return ret; 1012 return ret;
1153 1013
1154 ret = clk_prepare_enable(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]); 1014 ret = clk_prepare_enable(afe_priv->clocks[MT8173_CLK_TOP_PDN_AUD_BUS]);
1155 if (ret) 1015 if (ret)
1156 goto err_infra; 1016 goto err_infra;
1157 1017
1158 ret = clk_prepare_enable(afe->clocks[MTK_CLK_TOP_PDN_AUD]); 1018 ret = clk_prepare_enable(afe_priv->clocks[MT8173_CLK_TOP_PDN_AUD]);
1159 if (ret) 1019 if (ret)
1160 goto err_top_aud_bus; 1020 goto err_top_aud_bus;
1161 1021
1162 ret = clk_prepare_enable(afe->clocks[MTK_CLK_BCK0]); 1022 ret = clk_prepare_enable(afe_priv->clocks[MT8173_CLK_BCK0]);
1163 if (ret) 1023 if (ret)
1164 goto err_top_aud; 1024 goto err_top_aud;
1165 1025
1166 ret = clk_prepare_enable(afe->clocks[MTK_CLK_BCK1]); 1026 ret = clk_prepare_enable(afe_priv->clocks[MT8173_CLK_BCK1]);
1167 if (ret) 1027 if (ret)
1168 goto err_bck0; 1028 goto err_bck0;
1029 ret = clk_prepare_enable(afe_priv->clocks[MT8173_CLK_I2S1_M]);
1030 if (ret)
1031 goto err_i2s1_m;
1032 ret = clk_prepare_enable(afe_priv->clocks[MT8173_CLK_I2S2_M]);
1033 if (ret)
1034 goto err_i2s2_m;
1169 1035
1170 /* enable AFE clk */ 1036 /* enable AFE clk */
1171 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, AUD_TCON0_PDN_AFE, 0); 1037 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, AUD_TCON0_PDN_AFE, 0);
@@ -1181,39 +1047,45 @@ static int mtk_afe_runtime_resume(struct device *dev)
1181 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1); 1047 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
1182 return 0; 1048 return 0;
1183 1049
1050err_i2s1_m:
1051 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_I2S1_M]);
1052err_i2s2_m:
1053 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_I2S2_M]);
1184err_bck0: 1054err_bck0:
1185 clk_disable_unprepare(afe->clocks[MTK_CLK_BCK0]); 1055 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_BCK0]);
1186err_top_aud: 1056err_top_aud:
1187 clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD]); 1057 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_TOP_PDN_AUD]);
1188err_top_aud_bus: 1058err_top_aud_bus:
1189 clk_disable_unprepare(afe->clocks[MTK_CLK_TOP_PDN_AUD_BUS]); 1059 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_TOP_PDN_AUD_BUS]);
1190err_infra: 1060err_infra:
1191 clk_disable_unprepare(afe->clocks[MTK_CLK_INFRASYS_AUD]); 1061 clk_disable_unprepare(afe_priv->clocks[MT8173_CLK_INFRASYS_AUD]);
1192 return ret; 1062 return ret;
1193} 1063}
1194 1064
1195static int mtk_afe_init_audio_clk(struct mtk_afe *afe) 1065static int mt8173_afe_init_audio_clk(struct mtk_base_afe *afe)
1196{ 1066{
1197 size_t i; 1067 size_t i;
1068 struct mt8173_afe_private *afe_priv = afe->platform_priv;
1198 1069
1199 for (i = 0; i < ARRAY_SIZE(aud_clks); i++) { 1070 for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
1200 afe->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]); 1071 afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
1201 if (IS_ERR(afe->clocks[i])) { 1072 if (IS_ERR(afe_priv->clocks[i])) {
1202 dev_err(afe->dev, "%s devm_clk_get %s fail\n", 1073 dev_err(afe->dev, "%s devm_clk_get %s fail\n",
1203 __func__, aud_clks[i]); 1074 __func__, aud_clks[i]);
1204 return PTR_ERR(afe->clocks[i]); 1075 return PTR_ERR(afe_priv->clocks[i]);
1205 } 1076 }
1206 } 1077 }
1207 clk_set_rate(afe->clocks[MTK_CLK_BCK0], 22579200); /* 22M */ 1078 clk_set_rate(afe_priv->clocks[MT8173_CLK_BCK0], 22579200); /* 22M */
1208 clk_set_rate(afe->clocks[MTK_CLK_BCK1], 24576000); /* 24M */ 1079 clk_set_rate(afe_priv->clocks[MT8173_CLK_BCK1], 24576000); /* 24M */
1209 return 0; 1080 return 0;
1210} 1081}
1211 1082
1212static int mtk_afe_pcm_dev_probe(struct platform_device *pdev) 1083static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
1213{ 1084{
1214 int ret, i; 1085 int ret, i;
1215 unsigned int irq_id; 1086 unsigned int irq_id;
1216 struct mtk_afe *afe; 1087 struct mtk_base_afe *afe;
1088 struct mt8173_afe_private *afe_priv;
1217 struct resource *res; 1089 struct resource *res;
1218 1090
1219 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33)); 1091 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
@@ -1224,6 +1096,12 @@ static int mtk_afe_pcm_dev_probe(struct platform_device *pdev)
1224 if (!afe) 1096 if (!afe)
1225 return -ENOMEM; 1097 return -ENOMEM;
1226 1098
1099 afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
1100 GFP_KERNEL);
1101 afe_priv = afe->platform_priv;
1102 if (!afe_priv)
1103 return -ENOMEM;
1104
1227 afe->dev = &pdev->dev; 1105 afe->dev = &pdev->dev;
1228 1106
1229 irq_id = platform_get_irq(pdev, 0); 1107 irq_id = platform_get_irq(pdev, 0);
@@ -1231,7 +1109,7 @@ static int mtk_afe_pcm_dev_probe(struct platform_device *pdev)
1231 dev_err(afe->dev, "np %s no irq\n", afe->dev->of_node->name); 1109 dev_err(afe->dev, "np %s no irq\n", afe->dev->of_node->name);
1232 return -ENXIO; 1110 return -ENXIO;
1233 } 1111 }
1234 ret = devm_request_irq(afe->dev, irq_id, mtk_afe_irq_handler, 1112 ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
1235 0, "Afe_ISR_Handle", (void *)afe); 1113 0, "Afe_ISR_Handle", (void *)afe);
1236 if (ret) { 1114 if (ret) {
1237 dev_err(afe->dev, "could not request_irq\n"); 1115 dev_err(afe->dev, "could not request_irq\n");
@@ -1244,48 +1122,75 @@ static int mtk_afe_pcm_dev_probe(struct platform_device *pdev)
1244 return PTR_ERR(afe->base_addr); 1122 return PTR_ERR(afe->base_addr);
1245 1123
1246 afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, 1124 afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
1247 &mtk_afe_regmap_config); 1125 &mt8173_afe_regmap_config);
1248 if (IS_ERR(afe->regmap)) 1126 if (IS_ERR(afe->regmap))
1249 return PTR_ERR(afe->regmap); 1127 return PTR_ERR(afe->regmap);
1250 1128
1251 /* initial audio related clock */ 1129 /* initial audio related clock */
1252 ret = mtk_afe_init_audio_clk(afe); 1130 ret = mt8173_afe_init_audio_clk(afe);
1253 if (ret) { 1131 if (ret) {
1254 dev_err(afe->dev, "mtk_afe_init_audio_clk fail\n"); 1132 dev_err(afe->dev, "mt8173_afe_init_audio_clk fail\n");
1255 return ret; 1133 return ret;
1256 } 1134 }
1257 1135
1258 for (i = 0; i < MTK_AFE_MEMIF_NUM; i++) 1136 /* memif % irq initialize*/
1137 afe->memif_size = MT8173_AFE_MEMIF_NUM;
1138 afe->memif = devm_kcalloc(afe->dev, afe->memif_size,
1139 sizeof(*afe->memif), GFP_KERNEL);
1140 if (!afe->memif)
1141 return -ENOMEM;
1142
1143 afe->irqs_size = MT8173_AFE_IRQ_NUM;
1144 afe->irqs = devm_kcalloc(afe->dev, afe->irqs_size,
1145 sizeof(*afe->irqs), GFP_KERNEL);
1146 if (!afe->irqs)
1147 return -ENOMEM;
1148
1149 for (i = 0; i < afe->irqs_size; i++) {
1259 afe->memif[i].data = &memif_data[i]; 1150 afe->memif[i].data = &memif_data[i];
1151 afe->irqs[i].irq_data = &irq_data[i];
1152 afe->irqs[i].irq_occupyed = true;
1153 afe->memif[i].irq_usage = i;
1154 afe->memif[i].const_irq = 1;
1155 }
1156
1157 afe->mtk_afe_hardware = &mt8173_afe_hardware;
1158 afe->memif_fs = mt8173_memif_fs;
1159 afe->irq_fs = mt8173_irq_fs;
1260 1160
1261 platform_set_drvdata(pdev, afe); 1161 platform_set_drvdata(pdev, afe);
1262 1162
1263 pm_runtime_enable(&pdev->dev); 1163 pm_runtime_enable(&pdev->dev);
1264 if (!pm_runtime_enabled(&pdev->dev)) { 1164 if (!pm_runtime_enabled(&pdev->dev)) {
1265 ret = mtk_afe_runtime_resume(&pdev->dev); 1165 ret = mt8173_afe_runtime_resume(&pdev->dev);
1266 if (ret) 1166 if (ret)
1267 goto err_pm_disable; 1167 goto err_pm_disable;
1268 } 1168 }
1269 1169
1170 afe->reg_back_up_list = mt8173_afe_backup_list;
1171 afe->reg_back_up_list_num = ARRAY_SIZE(mt8173_afe_backup_list);
1172 afe->runtime_resume = mt8173_afe_runtime_resume;
1173 afe->runtime_suspend = mt8173_afe_runtime_suspend;
1174
1270 ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform); 1175 ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform);
1271 if (ret) 1176 if (ret)
1272 goto err_pm_disable; 1177 goto err_pm_disable;
1273 1178
1274 ret = snd_soc_register_component(&pdev->dev, 1179 ret = snd_soc_register_component(&pdev->dev,
1275 &mtk_afe_pcm_dai_component, 1180 &mt8173_afe_pcm_dai_component,
1276 mtk_afe_pcm_dais, 1181 mt8173_afe_pcm_dais,
1277 ARRAY_SIZE(mtk_afe_pcm_dais)); 1182 ARRAY_SIZE(mt8173_afe_pcm_dais));
1278 if (ret) 1183 if (ret)
1279 goto err_platform; 1184 goto err_platform;
1280 1185
1281 ret = snd_soc_register_component(&pdev->dev, 1186 ret = snd_soc_register_component(&pdev->dev,
1282 &mtk_afe_hdmi_dai_component, 1187 &mt8173_afe_hdmi_dai_component,
1283 mtk_afe_hdmi_dais, 1188 mt8173_afe_hdmi_dais,
1284 ARRAY_SIZE(mtk_afe_hdmi_dais)); 1189 ARRAY_SIZE(mt8173_afe_hdmi_dais));
1285 if (ret) 1190 if (ret)
1286 goto err_comp; 1191 goto err_comp;
1287 1192
1288 dev_info(&pdev->dev, "MTK AFE driver initialized.\n"); 1193 dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
1289 return 0; 1194 return 0;
1290 1195
1291err_comp: 1196err_comp:
@@ -1297,38 +1202,38 @@ err_pm_disable:
1297 return ret; 1202 return ret;
1298} 1203}
1299 1204
1300static int mtk_afe_pcm_dev_remove(struct platform_device *pdev) 1205static int mt8173_afe_pcm_dev_remove(struct platform_device *pdev)
1301{ 1206{
1302 pm_runtime_disable(&pdev->dev); 1207 pm_runtime_disable(&pdev->dev);
1303 if (!pm_runtime_status_suspended(&pdev->dev)) 1208 if (!pm_runtime_status_suspended(&pdev->dev))
1304 mtk_afe_runtime_suspend(&pdev->dev); 1209 mt8173_afe_runtime_suspend(&pdev->dev);
1305 snd_soc_unregister_component(&pdev->dev); 1210 snd_soc_unregister_component(&pdev->dev);
1306 snd_soc_unregister_platform(&pdev->dev); 1211 snd_soc_unregister_platform(&pdev->dev);
1307 return 0; 1212 return 0;
1308} 1213}
1309 1214
1310static const struct of_device_id mtk_afe_pcm_dt_match[] = { 1215static const struct of_device_id mt8173_afe_pcm_dt_match[] = {
1311 { .compatible = "mediatek,mt8173-afe-pcm", }, 1216 { .compatible = "mediatek,mt8173-afe-pcm", },
1312 { } 1217 { }
1313}; 1218};
1314MODULE_DEVICE_TABLE(of, mtk_afe_pcm_dt_match); 1219MODULE_DEVICE_TABLE(of, mt8173_afe_pcm_dt_match);
1315 1220
1316static const struct dev_pm_ops mtk_afe_pm_ops = { 1221static const struct dev_pm_ops mt8173_afe_pm_ops = {
1317 SET_RUNTIME_PM_OPS(mtk_afe_runtime_suspend, mtk_afe_runtime_resume, 1222 SET_RUNTIME_PM_OPS(mt8173_afe_runtime_suspend,
1318 NULL) 1223 mt8173_afe_runtime_resume, NULL)
1319}; 1224};
1320 1225
1321static struct platform_driver mtk_afe_pcm_driver = { 1226static struct platform_driver mt8173_afe_pcm_driver = {
1322 .driver = { 1227 .driver = {
1323 .name = "mtk-afe-pcm", 1228 .name = "mt8173-afe-pcm",
1324 .of_match_table = mtk_afe_pcm_dt_match, 1229 .of_match_table = mt8173_afe_pcm_dt_match,
1325 .pm = &mtk_afe_pm_ops, 1230 .pm = &mt8173_afe_pm_ops,
1326 }, 1231 },
1327 .probe = mtk_afe_pcm_dev_probe, 1232 .probe = mt8173_afe_pcm_dev_probe,
1328 .remove = mtk_afe_pcm_dev_remove, 1233 .remove = mt8173_afe_pcm_dev_remove,
1329}; 1234};
1330 1235
1331module_platform_driver(mtk_afe_pcm_driver); 1236module_platform_driver(mt8173_afe_pcm_driver);
1332 1237
1333MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver"); 1238MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver");
1334MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>"); 1239MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index 71a1a35047ba..5524a2c727ec 100644
--- a/sound/soc/mediatek/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -18,7 +18,7 @@
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/jack.h> 19#include <sound/jack.h>
20#include <linux/gpio.h> 20#include <linux/gpio.h>
21#include "../codecs/max98090.h" 21#include "../../codecs/max98090.h"
22 22
23static struct snd_soc_jack mt8173_max98090_jack; 23static struct snd_soc_jack mt8173_max98090_jack;
24 24
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 58e083642dea..467f7049a288 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -19,7 +19,7 @@
19#include <linux/of_gpio.h> 19#include <linux/of_gpio.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/jack.h> 21#include <sound/jack.h>
22#include "../codecs/rt5645.h" 22#include "../../codecs/rt5645.h"
23 23
24#define MCLK_FOR_CODECS 12288000 24#define MCLK_FOR_CODECS 12288000
25 25
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index bb593926c62d..1b8b2a778845 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -19,8 +19,8 @@
19#include <linux/of_gpio.h> 19#include <linux/of_gpio.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/jack.h> 21#include <sound/jack.h>
22#include "../codecs/rt5645.h" 22#include "../../codecs/rt5645.h"
23#include "../codecs/rt5677.h" 23#include "../../codecs/rt5677.h"
24 24
25#define MCLK_FOR_CODECS 12288000 25#define MCLK_FOR_CODECS 12288000
26 26
diff --git a/sound/soc/mediatek/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index a27a6673dbe3..ba65f4157a7e 100644
--- a/sound/soc/mediatek/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -19,10 +19,24 @@
19#include <linux/of_gpio.h> 19#include <linux/of_gpio.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/jack.h> 21#include <sound/jack.h>
22#include "../codecs/rt5645.h" 22#include "../../codecs/rt5645.h"
23 23
24#define MCLK_FOR_CODECS 12288000 24#define MCLK_FOR_CODECS 12288000
25 25
26enum mt8173_rt5650_mclk {
27 MT8173_RT5650_MCLK_EXTERNAL = 0,
28 MT8173_RT5650_MCLK_INTERNAL,
29};
30
31struct mt8173_rt5650_platform_data {
32 enum mt8173_rt5650_mclk pll_from;
33 /* 0 = external oscillator; 1 = internal source from mt8173 */
34};
35
36static struct mt8173_rt5650_platform_data mt8173_rt5650_priv = {
37 .pll_from = MT8173_RT5650_MCLK_EXTERNAL,
38};
39
26static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = { 40static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = {
27 SND_SOC_DAPM_SPK("Speaker", NULL), 41 SND_SOC_DAPM_SPK("Speaker", NULL),
28 SND_SOC_DAPM_MIC("Int Mic", NULL), 42 SND_SOC_DAPM_MIC("Int Mic", NULL),
@@ -54,13 +68,29 @@ static int mt8173_rt5650_hw_params(struct snd_pcm_substream *substream,
54 struct snd_pcm_hw_params *params) 68 struct snd_pcm_hw_params *params)
55{ 69{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data; 70 struct snd_soc_pcm_runtime *rtd = substream->private_data;
71 unsigned int mclk_clock;
57 int i, ret; 72 int i, ret;
58 73
74 switch (mt8173_rt5650_priv.pll_from) {
75 case MT8173_RT5650_MCLK_EXTERNAL:
76 /* mclk = 12.288M */
77 mclk_clock = MCLK_FOR_CODECS;
78 break;
79 case MT8173_RT5650_MCLK_INTERNAL:
80 /* mclk = sampling rate*256 */
81 mclk_clock = params_rate(params) * 256;
82 break;
83 default:
84 /* mclk = 12.288M */
85 mclk_clock = MCLK_FOR_CODECS;
86 break;
87 }
88
59 for (i = 0; i < rtd->num_codecs; i++) { 89 for (i = 0; i < rtd->num_codecs; i++) {
60 struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; 90 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
61 91
62 /* pll from mclk 12.288M */ 92 /* pll from mclk */
63 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS, 93 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, mclk_clock,
64 params_rate(params) * 512); 94 params_rate(params) * 512);
65 if (ret) 95 if (ret)
66 return ret; 96 return ret;
@@ -139,7 +169,9 @@ static struct snd_soc_dai_link_component mt8173_rt5650_codecs[] = {
139enum { 169enum {
140 DAI_LINK_PLAYBACK, 170 DAI_LINK_PLAYBACK,
141 DAI_LINK_CAPTURE, 171 DAI_LINK_CAPTURE,
172 DAI_LINK_HDMI,
142 DAI_LINK_CODEC_I2S, 173 DAI_LINK_CODEC_I2S,
174 DAI_LINK_HDMI_I2S,
143}; 175};
144 176
145/* Digital audio interface glue - connects codec <---> CPU */ 177/* Digital audio interface glue - connects codec <---> CPU */
@@ -165,6 +197,16 @@ static struct snd_soc_dai_link mt8173_rt5650_dais[] = {
165 .dynamic = 1, 197 .dynamic = 1,
166 .dpcm_capture = 1, 198 .dpcm_capture = 1,
167 }, 199 },
200 [DAI_LINK_HDMI] = {
201 .name = "HDMI",
202 .stream_name = "HDMI PCM",
203 .cpu_dai_name = "HDMI",
204 .codec_name = "snd-soc-dummy",
205 .codec_dai_name = "snd-soc-dummy-dai",
206 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
207 .dynamic = 1,
208 .dpcm_playback = 1,
209 },
168 /* Back End DAI links */ 210 /* Back End DAI links */
169 [DAI_LINK_CODEC_I2S] = { 211 [DAI_LINK_CODEC_I2S] = {
170 .name = "Codec", 212 .name = "Codec",
@@ -180,6 +222,13 @@ static struct snd_soc_dai_link mt8173_rt5650_dais[] = {
180 .dpcm_playback = 1, 222 .dpcm_playback = 1,
181 .dpcm_capture = 1, 223 .dpcm_capture = 1,
182 }, 224 },
225 [DAI_LINK_HDMI_I2S] = {
226 .name = "HDMI BE",
227 .cpu_dai_name = "HDMIO",
228 .no_pcm = 1,
229 .codec_dai_name = "i2s-hifi",
230 .dpcm_playback = 1,
231 },
183}; 232};
184 233
185static struct snd_soc_card mt8173_rt5650_card = { 234static struct snd_soc_card mt8173_rt5650_card = {
@@ -243,6 +292,24 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
243 mt8173_rt5650_codecs[1].dai_name = codec_capture_dai; 292 mt8173_rt5650_codecs[1].dai_name = codec_capture_dai;
244 } 293 }
245 294
295 if (device_property_present(&pdev->dev, "mediatek,mclk")) {
296 ret = device_property_read_u32(&pdev->dev,
297 "mediatek,mclk",
298 &mt8173_rt5650_priv.pll_from);
299 if (ret) {
300 dev_err(&pdev->dev,
301 "%s snd_soc_register_card fail %d\n",
302 __func__, ret);
303 }
304 }
305
306 mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codec_of_node =
307 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
308 if (!mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codec_of_node) {
309 dev_err(&pdev->dev,
310 "Property 'audio-codec' missing or invalid\n");
311 return -EINVAL;
312 }
246 card->dev = &pdev->dev; 313 card->dev = &pdev->dev;
247 platform_set_drvdata(pdev, card); 314 platform_set_drvdata(pdev, card);
248 315
diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h
deleted file mode 100644
index f341f623e887..000000000000
--- a/sound/soc/mediatek/mtk-afe-common.h
+++ /dev/null
@@ -1,101 +0,0 @@
1/*
2 * mtk_afe_common.h -- Mediatek audio driver common definitions
3 *
4 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 * Sascha Hauer <s.hauer@pengutronix.de>
7 * Hidalgo Huang <hidalgo.huang@mediatek.com>
8 * Ir Lian <ir.lian@mediatek.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 and
12 * only version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#ifndef _MTK_AFE_COMMON_H_
21#define _MTK_AFE_COMMON_H_
22
23#include <linux/clk.h>
24#include <linux/regmap.h>
25
26enum {
27 MTK_AFE_MEMIF_DL1,
28 MTK_AFE_MEMIF_DL2,
29 MTK_AFE_MEMIF_VUL,
30 MTK_AFE_MEMIF_DAI,
31 MTK_AFE_MEMIF_AWB,
32 MTK_AFE_MEMIF_MOD_DAI,
33 MTK_AFE_MEMIF_HDMI,
34 MTK_AFE_MEMIF_NUM,
35 MTK_AFE_IO_MOD_PCM1 = MTK_AFE_MEMIF_NUM,
36 MTK_AFE_IO_MOD_PCM2,
37 MTK_AFE_IO_PMIC,
38 MTK_AFE_IO_I2S,
39 MTK_AFE_IO_2ND_I2S,
40 MTK_AFE_IO_HW_GAIN1,
41 MTK_AFE_IO_HW_GAIN2,
42 MTK_AFE_IO_MRG_O,
43 MTK_AFE_IO_MRG_I,
44 MTK_AFE_IO_DAIBT,
45 MTK_AFE_IO_HDMI,
46};
47
48enum {
49 MTK_AFE_IRQ_1,
50 MTK_AFE_IRQ_2,
51 MTK_AFE_IRQ_3,
52 MTK_AFE_IRQ_4,
53 MTK_AFE_IRQ_5,
54 MTK_AFE_IRQ_6,
55 MTK_AFE_IRQ_7,
56 MTK_AFE_IRQ_8,
57 MTK_AFE_IRQ_NUM,
58};
59
60enum {
61 MTK_CLK_INFRASYS_AUD,
62 MTK_CLK_TOP_PDN_AUD,
63 MTK_CLK_TOP_PDN_AUD_BUS,
64 MTK_CLK_I2S0_M,
65 MTK_CLK_I2S1_M,
66 MTK_CLK_I2S2_M,
67 MTK_CLK_I2S3_M,
68 MTK_CLK_I2S3_B,
69 MTK_CLK_BCK0,
70 MTK_CLK_BCK1,
71 MTK_CLK_NUM
72};
73
74struct mtk_afe;
75struct snd_pcm_substream;
76
77struct mtk_afe_memif_data {
78 int id;
79 const char *name;
80 int reg_ofs_base;
81 int reg_ofs_cur;
82 int fs_shift;
83 int mono_shift;
84 int enable_shift;
85 int irq_reg_cnt;
86 int irq_cnt_shift;
87 int irq_en_shift;
88 int irq_fs_shift;
89 int irq_clr_shift;
90 int msb_shift;
91};
92
93struct mtk_afe_memif {
94 unsigned int phys_buf_addr;
95 int buffer_size;
96 struct snd_pcm_substream *substream;
97 const struct mtk_afe_memif_data *data;
98 const struct mtk_afe_irq_data *irqdata;
99};
100
101#endif
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 5185a3844da9..f5451c78ede5 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -100,13 +100,14 @@ config SND_OMAP_SOC_OMAP_TWL4030
100 100
101config SND_OMAP_SOC_OMAP_ABE_TWL6040 101config SND_OMAP_SOC_OMAP_ABE_TWL6040
102 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" 102 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
103 depends on TWL6040_CORE && SND_OMAP_SOC 103 depends on TWL6040_CORE && SND_OMAP_SOC && COMMON_CLK
104 depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST 104 depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST
105 select SND_OMAP_SOC_DMIC 105 select SND_OMAP_SOC_DMIC
106 select SND_OMAP_SOC_MCPDM 106 select SND_OMAP_SOC_MCPDM
107 select SND_SOC_TWL6040 107 select SND_SOC_TWL6040
108 select SND_SOC_DMIC 108 select SND_SOC_DMIC
109 select COMMON_CLK_PALMAS if (SOC_OMAP5 && MFD_PALMAS) 109 select COMMON_CLK_PALMAS if (SOC_OMAP5 && MFD_PALMAS)
110 select CLK_TWL6040
110 help 111 help
111 Say Y if you want to add support for SoC audio on OMAP boards using 112 Say Y if you want to add support for SoC audio on OMAP boards using
112 ABE and twl6040 codec. This driver currently supports: 113 ABE and twl6040 codec. This driver currently supports:
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index b837265ac3e9..e7cdc51fd806 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -31,6 +31,7 @@
31#include <linux/err.h> 31#include <linux/err.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/irq.h> 33#include <linux/irq.h>
34#include <linux/clk.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
36#include <linux/of_device.h> 37#include <linux/of_device.h>
@@ -54,6 +55,7 @@ struct omap_mcpdm {
54 unsigned long phys_base; 55 unsigned long phys_base;
55 void __iomem *io_base; 56 void __iomem *io_base;
56 int irq; 57 int irq;
58 struct clk *pdmclk;
57 59
58 struct mutex mutex; 60 struct mutex mutex;
59 61
@@ -66,6 +68,9 @@ struct omap_mcpdm {
66 /* McPDM needs to be restarted due to runtime reconfiguration */ 68 /* McPDM needs to be restarted due to runtime reconfiguration */
67 bool restart; 69 bool restart;
68 70
71 /* pm state for suspend/resume handling */
72 int pm_active_count;
73
69 struct snd_dmaengine_dai_dma_data dma_data[2]; 74 struct snd_dmaengine_dai_dma_data dma_data[2];
70}; 75};
71 76
@@ -173,6 +178,10 @@ static inline int omap_mcpdm_active(struct omap_mcpdm *mcpdm)
173 */ 178 */
174static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm) 179static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
175{ 180{
181 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
182
183 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl | MCPDM_WD_EN);
184
176 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_SET, 185 omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_SET,
177 MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL | 186 MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL |
178 MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL); 187 MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
@@ -258,12 +267,9 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
258 267
259 mutex_lock(&mcpdm->mutex); 268 mutex_lock(&mcpdm->mutex);
260 269
261 if (!dai->active) { 270 if (!dai->active)
262 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
263
264 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl | MCPDM_WD_EN);
265 omap_mcpdm_open_streams(mcpdm); 271 omap_mcpdm_open_streams(mcpdm);
266 } 272
267 mutex_unlock(&mcpdm->mutex); 273 mutex_unlock(&mcpdm->mutex);
268 274
269 return 0; 275 return 0;
@@ -384,6 +390,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
384 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 390 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
385 int ret; 391 int ret;
386 392
393 clk_prepare_enable(mcpdm->pdmclk);
387 pm_runtime_enable(mcpdm->dev); 394 pm_runtime_enable(mcpdm->dev);
388 395
389 /* Disable lines while request is ongoing */ 396 /* Disable lines while request is ongoing */
@@ -418,8 +425,54 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
418 425
419 pm_runtime_disable(mcpdm->dev); 426 pm_runtime_disable(mcpdm->dev);
420 427
428 clk_disable_unprepare(mcpdm->pdmclk);
429 return 0;
430}
431
432#ifdef CONFIG_PM_SLEEP
433static int omap_mcpdm_suspend(struct snd_soc_dai *dai)
434{
435 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
436
437 if (dai->active) {
438 omap_mcpdm_stop(mcpdm);
439 omap_mcpdm_close_streams(mcpdm);
440 }
441
442 mcpdm->pm_active_count = 0;
443 while (pm_runtime_active(mcpdm->dev)) {
444 pm_runtime_put_sync(mcpdm->dev);
445 mcpdm->pm_active_count++;
446 }
447
448 clk_disable_unprepare(mcpdm->pdmclk);
449
450 return 0;
451}
452
453static int omap_mcpdm_resume(struct snd_soc_dai *dai)
454{
455 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
456
457 clk_prepare_enable(mcpdm->pdmclk);
458
459 if (mcpdm->pm_active_count) {
460 while (mcpdm->pm_active_count--)
461 pm_runtime_get_sync(mcpdm->dev);
462
463 if (dai->active) {
464 omap_mcpdm_open_streams(mcpdm);
465 omap_mcpdm_start(mcpdm);
466 }
467 }
468
469
421 return 0; 470 return 0;
422} 471}
472#else
473#define omap_mcpdm_suspend NULL
474#define omap_mcpdm_resume NULL
475#endif
423 476
424#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 477#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
425#define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE 478#define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE
@@ -427,6 +480,8 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
427static struct snd_soc_dai_driver omap_mcpdm_dai = { 480static struct snd_soc_dai_driver omap_mcpdm_dai = {
428 .probe = omap_mcpdm_probe, 481 .probe = omap_mcpdm_probe,
429 .remove = omap_mcpdm_remove, 482 .remove = omap_mcpdm_remove,
483 .suspend = omap_mcpdm_suspend,
484 .resume = omap_mcpdm_resume,
430 .probe_order = SND_SOC_COMP_ORDER_LATE, 485 .probe_order = SND_SOC_COMP_ORDER_LATE,
431 .remove_order = SND_SOC_COMP_ORDER_EARLY, 486 .remove_order = SND_SOC_COMP_ORDER_EARLY,
432 .playback = { 487 .playback = {
@@ -494,6 +549,15 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
494 549
495 mcpdm->dev = &pdev->dev; 550 mcpdm->dev = &pdev->dev;
496 551
552 mcpdm->pdmclk = devm_clk_get(&pdev->dev, "pdmclk");
553 if (IS_ERR(mcpdm->pdmclk)) {
554 if (PTR_ERR(mcpdm->pdmclk) == -EPROBE_DEFER)
555 return -EPROBE_DEFER;
556 dev_warn(&pdev->dev, "Error getting pdmclk (%ld)!\n",
557 PTR_ERR(mcpdm->pdmclk));
558 mcpdm->pdmclk = NULL;
559 }
560
497 ret = devm_snd_soc_register_component(&pdev->dev, 561 ret = devm_snd_soc_register_component(&pdev->dev,
498 &omap_mcpdm_component, 562 &omap_mcpdm_component,
499 &omap_mcpdm_dai, 1); 563 &omap_mcpdm_dai, 1);
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 54949242bc70..a76845748a10 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -33,7 +33,6 @@
33#include <sound/pcm.h> 33#include <sound/pcm.h>
34#include <sound/soc.h> 34#include <sound/soc.h>
35#include <linux/platform_data/asoc-ti-mcbsp.h> 35#include <linux/platform_data/asoc-ti-mcbsp.h>
36#include "../codecs/tpa6130a2.h"
37 36
38#include <asm/mach-types.h> 37#include <asm/mach-types.h>
39 38
@@ -164,19 +163,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
164 return 0; 163 return 0;
165} 164}
166 165
167static int rx51_hp_event(struct snd_soc_dapm_widget *w,
168 struct snd_kcontrol *k, int event)
169{
170 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
171
172 if (SND_SOC_DAPM_EVENT_ON(event))
173 tpa6130a2_stereo_enable(codec, 1);
174 else
175 tpa6130a2_stereo_enable(codec, 0);
176
177 return 0;
178}
179
180static int rx51_get_input(struct snd_kcontrol *kcontrol, 166static int rx51_get_input(struct snd_kcontrol *kcontrol,
181 struct snd_ctl_elem_value *ucontrol) 167 struct snd_ctl_elem_value *ucontrol)
182{ 168{
@@ -235,7 +221,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
235static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { 221static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
236 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event), 222 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
237 SND_SOC_DAPM_MIC("DMic", NULL), 223 SND_SOC_DAPM_MIC("DMic", NULL),
238 SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event), 224 SND_SOC_DAPM_HP("Headphone Jack", NULL),
239 SND_SOC_DAPM_MIC("HS Mic", NULL), 225 SND_SOC_DAPM_MIC("HS Mic", NULL),
240 SND_SOC_DAPM_LINE("FM Transmitter", NULL), 226 SND_SOC_DAPM_LINE("FM Transmitter", NULL),
241 SND_SOC_DAPM_SPK("Earphone", NULL), 227 SND_SOC_DAPM_SPK("Earphone", NULL),
@@ -246,11 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
246 {"Ext Spk", NULL, "HPROUT"}, 232 {"Ext Spk", NULL, "HPROUT"},
247 {"Ext Spk", NULL, "HPLCOM"}, 233 {"Ext Spk", NULL, "HPLCOM"},
248 {"Ext Spk", NULL, "HPRCOM"}, 234 {"Ext Spk", NULL, "HPRCOM"},
249 {"Headphone Jack", NULL, "LLOUT"},
250 {"Headphone Jack", NULL, "RLOUT"},
251 {"FM Transmitter", NULL, "LLOUT"}, 235 {"FM Transmitter", NULL, "LLOUT"},
252 {"FM Transmitter", NULL, "RLOUT"}, 236 {"FM Transmitter", NULL, "RLOUT"},
253 237
238 {"Headphone Jack", NULL, "TPA6130A2 HPLEFT"},
239 {"Headphone Jack", NULL, "TPA6130A2 HPRIGHT"},
240 {"TPA6130A2 LEFTIN", NULL, "LLOUT"},
241 {"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
242
254 {"DMic Rate 64", NULL, "DMic"}, 243 {"DMic Rate 64", NULL, "DMic"},
255 {"DMic", NULL, "Mic Bias"}, 244 {"DMic", NULL, "Mic Bias"},
256 245
@@ -286,16 +275,10 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
286 275
287static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) 276static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
288{ 277{
289 struct snd_soc_codec *codec = rtd->codec;
290 struct snd_soc_card *card = rtd->card; 278 struct snd_soc_card *card = rtd->card;
291 struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); 279 struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
292 int err; 280 int err;
293 281
294 err = tpa6130a2_add_controls(codec);
295 if (err < 0) {
296 dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
297 return err;
298 }
299 snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42); 282 snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42);
300 283
301 err = omap_mcbsp_st_add_controls(rtd, 2); 284 err = omap_mcbsp_st_add_controls(rtd, 2);
@@ -357,6 +340,10 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = {
357 .name = "TLV320AIC34b", 340 .name = "TLV320AIC34b",
358 .codec_name = "tlv320aic3x-codec.2-0019", 341 .codec_name = "tlv320aic3x-codec.2-0019",
359 }, 342 },
343 {
344 .name = "TPA61320A2",
345 .codec_name = "tpa6130a2.2-0060",
346 },
360}; 347};
361 348
362static struct snd_soc_codec_conf rx51_codec_conf[] = { 349static struct snd_soc_codec_conf rx51_codec_conf[] = {
@@ -364,6 +351,10 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = {
364 .dev_name = "tlv320aic3x-codec.2-0019", 351 .dev_name = "tlv320aic3x-codec.2-0019",
365 .name_prefix = "b", 352 .name_prefix = "b",
366 }, 353 },
354 {
355 .dev_name = "tpa6130a2.2-0060",
356 .name_prefix = "TPA6130A2",
357 },
367}; 358};
368 359
369/* Audio card */ 360/* Audio card */
@@ -435,11 +426,10 @@ static int rx51_soc_probe(struct platform_device *pdev)
435 dev_err(&pdev->dev, "Headphone amplifier node is not provided\n"); 426 dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
436 return -EINVAL; 427 return -EINVAL;
437 } 428 }
438 429 rx51_aux_dev[1].codec_name = NULL;
439 /* TODO: tpa6130a2a driver supports only a single instance, so 430 rx51_aux_dev[1].codec_of_node = dai_node;
440 * this driver ignores the headphone-amplifier node for now. 431 rx51_codec_conf[1].dev_name = NULL;
441 * It's already mandatory in the DT binding to be future proof. 432 rx51_codec_conf[1].of_node = dai_node;
442 */
443 } 433 }
444 434
445 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 435 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 574c6af28c06..652e8c5ea166 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -11,8 +11,10 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/mfd/syscon.h>
14#include <linux/delay.h> 15#include <linux/delay.h>
15#include <linux/of_gpio.h> 16#include <linux/of_gpio.h>
17#include <linux/of_device.h>
16#include <linux/clk.h> 18#include <linux/clk.h>
17#include <linux/pm_runtime.h> 19#include <linux/pm_runtime.h>
18#include <linux/regmap.h> 20#include <linux/regmap.h>
@@ -23,6 +25,11 @@
23 25
24#define DRV_NAME "rockchip-i2s" 26#define DRV_NAME "rockchip-i2s"
25 27
28struct rk_i2s_pins {
29 u32 reg_offset;
30 u32 shift;
31};
32
26struct rk_i2s_dev { 33struct rk_i2s_dev {
27 struct device *dev; 34 struct device *dev;
28 35
@@ -33,6 +40,7 @@ struct rk_i2s_dev {
33 struct snd_dmaengine_dai_dma_data playback_dma_data; 40 struct snd_dmaengine_dai_dma_data playback_dma_data;
34 41
35 struct regmap *regmap; 42 struct regmap *regmap;
43 struct regmap *grf;
36 44
37/* 45/*
38 * Used to indicate the tx/rx status. 46 * Used to indicate the tx/rx status.
@@ -42,6 +50,7 @@ struct rk_i2s_dev {
42 bool tx_start; 50 bool tx_start;
43 bool rx_start; 51 bool rx_start;
44 bool is_master_mode; 52 bool is_master_mode;
53 const struct rk_i2s_pins *pins;
45}; 54};
46 55
47static int i2s_runtime_suspend(struct device *dev) 56static int i2s_runtime_suspend(struct device *dev)
@@ -300,14 +309,38 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
300 I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK, 309 I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
301 val); 310 val);
302 311
312 if (!IS_ERR(i2s->grf) && i2s->pins) {
313 regmap_read(i2s->regmap, I2S_TXCR, &val);
314 val &= I2S_TXCR_CSR_MASK;
315
316 switch (val) {
317 case I2S_CHN_4:
318 val = I2S_IO_4CH_OUT_6CH_IN;
319 break;
320 case I2S_CHN_6:
321 val = I2S_IO_6CH_OUT_4CH_IN;
322 break;
323 case I2S_CHN_8:
324 val = I2S_IO_8CH_OUT_2CH_IN;
325 break;
326 default:
327 val = I2S_IO_2CH_OUT_8CH_IN;
328 break;
329 }
330
331 val <<= i2s->pins->shift;
332 val |= (I2S_IO_DIRECTION_MASK << i2s->pins->shift) << 16;
333 regmap_write(i2s->grf, i2s->pins->reg_offset, val);
334 }
335
303 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, 336 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
304 I2S_DMACR_TDL(16)); 337 I2S_DMACR_TDL(16));
305 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, 338 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
306 I2S_DMACR_RDL(16)); 339 I2S_DMACR_RDL(16));
307 340
308 val = I2S_CKR_TRCM_TXRX; 341 val = I2S_CKR_TRCM_TXRX;
309 if (dai->driver->symmetric_rates || rtd->dai_link->symmetric_rates) 342 if (dai->driver->symmetric_rates && rtd->dai_link->symmetric_rates)
310 val = I2S_CKR_TRCM_TXSHARE; 343 val = I2S_CKR_TRCM_TXONLY;
311 344
312 regmap_update_bits(i2s->regmap, I2S_CKR, 345 regmap_update_bits(i2s->regmap, I2S_CKR,
313 I2S_CKR_TRCM_MASK, 346 I2S_CKR_TRCM_MASK,
@@ -485,9 +518,23 @@ static const struct regmap_config rockchip_i2s_regmap_config = {
485 .cache_type = REGCACHE_FLAT, 518 .cache_type = REGCACHE_FLAT,
486}; 519};
487 520
521static const struct rk_i2s_pins rk3399_i2s_pins = {
522 .reg_offset = 0xe220,
523 .shift = 11,
524};
525
526static const struct of_device_id rockchip_i2s_match[] = {
527 { .compatible = "rockchip,rk3066-i2s", },
528 { .compatible = "rockchip,rk3188-i2s", },
529 { .compatible = "rockchip,rk3288-i2s", },
530 { .compatible = "rockchip,rk3399-i2s", .data = &rk3399_i2s_pins },
531 {},
532};
533
488static int rockchip_i2s_probe(struct platform_device *pdev) 534static int rockchip_i2s_probe(struct platform_device *pdev)
489{ 535{
490 struct device_node *node = pdev->dev.of_node; 536 struct device_node *node = pdev->dev.of_node;
537 const struct of_device_id *of_id;
491 struct rk_i2s_dev *i2s; 538 struct rk_i2s_dev *i2s;
492 struct snd_soc_dai_driver *soc_dai; 539 struct snd_soc_dai_driver *soc_dai;
493 struct resource *res; 540 struct resource *res;
@@ -501,6 +548,17 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
501 return -ENOMEM; 548 return -ENOMEM;
502 } 549 }
503 550
551 i2s->dev = &pdev->dev;
552
553 i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
554 if (!IS_ERR(i2s->grf)) {
555 of_id = of_match_device(rockchip_i2s_match, &pdev->dev);
556 if (!of_id || !of_id->data)
557 return -EINVAL;
558
559 i2s->pins = of_id->data;
560 }
561
504 /* try to prepare related clocks */ 562 /* try to prepare related clocks */
505 i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk"); 563 i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk");
506 if (IS_ERR(i2s->hclk)) { 564 if (IS_ERR(i2s->hclk)) {
@@ -540,7 +598,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
540 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 598 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
541 i2s->capture_dma_data.maxburst = 4; 599 i2s->capture_dma_data.maxburst = 4;
542 600
543 i2s->dev = &pdev->dev;
544 dev_set_drvdata(&pdev->dev, i2s); 601 dev_set_drvdata(&pdev->dev, i2s);
545 602
546 pm_runtime_enable(&pdev->dev); 603 pm_runtime_enable(&pdev->dev);
@@ -606,14 +663,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev)
606 return 0; 663 return 0;
607} 664}
608 665
609static const struct of_device_id rockchip_i2s_match[] = {
610 { .compatible = "rockchip,rk3066-i2s", },
611 { .compatible = "rockchip,rk3188-i2s", },
612 { .compatible = "rockchip,rk3288-i2s", },
613 { .compatible = "rockchip,rk3399-i2s", },
614 {},
615};
616
617static const struct dev_pm_ops rockchip_i2s_pm_ops = { 666static const struct dev_pm_ops rockchip_i2s_pm_ops = {
618 SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume, 667 SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume,
619 NULL) 668 NULL)
diff --git a/sound/soc/rockchip/rockchip_i2s.h b/sound/soc/rockchip/rockchip_i2s.h
index dc6e2c74d088..31f11fd25393 100644
--- a/sound/soc/rockchip/rockchip_i2s.h
+++ b/sound/soc/rockchip/rockchip_i2s.h
@@ -81,8 +81,8 @@
81#define I2S_CKR_TRCM_SHIFT 28 81#define I2S_CKR_TRCM_SHIFT 28
82#define I2S_CKR_TRCM(x) (x << I2S_CKR_TRCM_SHIFT) 82#define I2S_CKR_TRCM(x) (x << I2S_CKR_TRCM_SHIFT)
83#define I2S_CKR_TRCM_TXRX (0 << I2S_CKR_TRCM_SHIFT) 83#define I2S_CKR_TRCM_TXRX (0 << I2S_CKR_TRCM_SHIFT)
84#define I2S_CKR_TRCM_TXSHARE (1 << I2S_CKR_TRCM_SHIFT) 84#define I2S_CKR_TRCM_TXONLY (1 << I2S_CKR_TRCM_SHIFT)
85#define I2S_CKR_TRCM_RXSHARE (2 << I2S_CKR_TRCM_SHIFT) 85#define I2S_CKR_TRCM_RXONLY (2 << I2S_CKR_TRCM_SHIFT)
86#define I2S_CKR_TRCM_MASK (3 << I2S_CKR_TRCM_SHIFT) 86#define I2S_CKR_TRCM_MASK (3 << I2S_CKR_TRCM_SHIFT)
87#define I2S_CKR_MSS_SHIFT 27 87#define I2S_CKR_MSS_SHIFT 27
88#define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT) 88#define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT)
@@ -236,4 +236,11 @@ enum {
236#define I2S_TXDR (0x0024) 236#define I2S_TXDR (0x0024)
237#define I2S_RXDR (0x0028) 237#define I2S_RXDR (0x0028)
238 238
239/* io direction cfg register */
240#define I2S_IO_DIRECTION_MASK (7)
241#define I2S_IO_8CH_OUT_2CH_IN (0)
242#define I2S_IO_6CH_OUT_4CH_IN (4)
243#define I2S_IO_4CH_OUT_6CH_IN (6)
244#define I2S_IO_2CH_OUT_8CH_IN (7)
245
239#endif /* _ROCKCHIP_IIS_H */ 246#endif /* _ROCKCHIP_IIS_H */
diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c
index 543610282cdb..e70ffad07184 100644
--- a/sound/soc/rockchip/rockchip_max98090.c
+++ b/sound/soc/rockchip/rockchip_max98090.c
@@ -34,13 +34,18 @@
34#define DRV_NAME "rockchip-snd-max98090" 34#define DRV_NAME "rockchip-snd-max98090"
35 35
36static struct snd_soc_jack headset_jack; 36static struct snd_soc_jack headset_jack;
37
38/* Headset jack detection DAPM pins */
37static struct snd_soc_jack_pin headset_jack_pins[] = { 39static struct snd_soc_jack_pin headset_jack_pins[] = {
38 { 40 {
39 .pin = "Headset Jack", 41 .pin = "Headphone",
40 .mask = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | 42 .mask = SND_JACK_HEADPHONE,
41 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 43 },
42 SND_JACK_BTN_2 | SND_JACK_BTN_3, 44 {
45 .pin = "Headset Mic",
46 .mask = SND_JACK_MICROPHONE,
43 }, 47 },
48
44}; 49};
45 50
46static const struct snd_soc_dapm_widget rk_dapm_widgets[] = { 51static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
@@ -53,7 +58,7 @@ static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
53static const struct snd_soc_dapm_route rk_audio_map[] = { 58static const struct snd_soc_dapm_route rk_audio_map[] = {
54 {"IN34", NULL, "Headset Mic"}, 59 {"IN34", NULL, "Headset Mic"},
55 {"IN34", NULL, "MICBIAS"}, 60 {"IN34", NULL, "MICBIAS"},
56 {"MICBIAS", NULL, "Headset Mic"}, 61 {"Headset Mic", NULL, "MICBIAS"},
57 {"DMICL", NULL, "Int Mic"}, 62 {"DMICL", NULL, "Int Mic"},
58 {"Headphone", NULL, "HPL"}, 63 {"Headphone", NULL, "HPL"},
59 {"Headphone", NULL, "HPR"}, 64 {"Headphone", NULL, "HPR"},
@@ -114,43 +119,27 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
114 return ret; 119 return ret;
115} 120}
116 121
117static int rk_init(struct snd_soc_pcm_runtime *runtime)
118{
119 /* Enable Headset and 4 Buttons Jack detection */
120 return snd_soc_card_jack_new(runtime->card, "Headset Jack",
121 SND_JACK_HEADSET |
122 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
123 SND_JACK_BTN_2 | SND_JACK_BTN_3,
124 &headset_jack,
125 headset_jack_pins,
126 ARRAY_SIZE(headset_jack_pins));
127}
128
129static int rk_98090_headset_init(struct snd_soc_component *component)
130{
131 return ts3a227e_enable_jack_detect(component, &headset_jack);
132}
133
134static struct snd_soc_ops rk_aif1_ops = { 122static struct snd_soc_ops rk_aif1_ops = {
135 .hw_params = rk_aif1_hw_params, 123 .hw_params = rk_aif1_hw_params,
136}; 124};
137 125
138static struct snd_soc_aux_dev rk_98090_headset_dev = {
139 .name = "Headset Chip",
140 .init = rk_98090_headset_init,
141};
142
143static struct snd_soc_dai_link rk_dailink = { 126static struct snd_soc_dai_link rk_dailink = {
144 .name = "max98090", 127 .name = "max98090",
145 .stream_name = "Audio", 128 .stream_name = "Audio",
146 .codec_dai_name = "HiFi", 129 .codec_dai_name = "HiFi",
147 .init = rk_init,
148 .ops = &rk_aif1_ops, 130 .ops = &rk_aif1_ops,
149 /* set max98090 as slave */ 131 /* set max98090 as slave */
150 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 132 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
151 SND_SOC_DAIFMT_CBS_CFS, 133 SND_SOC_DAIFMT_CBS_CFS,
152}; 134};
153 135
136static int rk_98090_headset_init(struct snd_soc_component *component);
137
138static struct snd_soc_aux_dev rk_98090_headset_dev = {
139 .name = "Headset Chip",
140 .init = rk_98090_headset_init,
141};
142
154static struct snd_soc_card snd_soc_card_rk = { 143static struct snd_soc_card snd_soc_card_rk = {
155 .name = "ROCKCHIP-I2S", 144 .name = "ROCKCHIP-I2S",
156 .owner = THIS_MODULE, 145 .owner = THIS_MODULE,
@@ -166,6 +155,26 @@ static struct snd_soc_card snd_soc_card_rk = {
166 .num_controls = ARRAY_SIZE(rk_mc_controls), 155 .num_controls = ARRAY_SIZE(rk_mc_controls),
167}; 156};
168 157
158static int rk_98090_headset_init(struct snd_soc_component *component)
159{
160 int ret;
161
162 /* Enable Headset and 4 Buttons Jack detection */
163 ret = snd_soc_card_jack_new(&snd_soc_card_rk, "Headset Jack",
164 SND_JACK_HEADSET |
165 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
166 SND_JACK_BTN_2 | SND_JACK_BTN_3,
167 &headset_jack,
168 headset_jack_pins,
169 ARRAY_SIZE(headset_jack_pins));
170 if (ret)
171 return ret;
172
173 ret = ts3a227e_enable_jack_detect(component, &headset_jack);
174
175 return ret;
176}
177
169static int snd_rk_mc_probe(struct platform_device *pdev) 178static int snd_rk_mc_probe(struct platform_device *pdev)
170{ 179{
171 int ret = 0; 180 int ret = 0;
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
index 100781e37848..4ca265737eda 100644
--- a/sound/soc/rockchip/rockchip_spdif.c
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -101,21 +101,7 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
101 int ret; 101 int ret;
102 102
103 srate = params_rate(params); 103 srate = params_rate(params);
104 switch (srate) { 104 mclk = srate * 128;
105 case 32000:
106 case 48000:
107 case 96000:
108 mclk = 96000 * 128; /* 12288000 hz */
109 break;
110 case 44100:
111 mclk = 44100 * 256; /* 11289600 hz */
112 break;
113 case 192000:
114 mclk = 192000 * 128; /* 24576000 hz */
115 break;
116 default:
117 return -EINVAL;
118 }
119 105
120 switch (params_format(params)) { 106 switch (params_format(params)) {
121 case SNDRV_PCM_FORMAT_S16_LE: 107 case SNDRV_PCM_FORMAT_S16_LE:
@@ -139,7 +125,6 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
139 return ret; 125 return ret;
140 } 126 }
141 127
142 val |= SPDIF_CFGR_CLK_DIV(mclk/(srate * 256));
143 ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR, 128 ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
144 SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE | 129 SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE |
145 SDPIF_CFGR_VDW_MASK, 130 SDPIF_CFGR_VDW_MASK,
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 78baa26e938b..7b722b0094d9 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -224,14 +224,6 @@ config SND_SOC_SNOW
224 Say Y if you want to add audio support for various Snow 224 Say Y if you want to add audio support for various Snow
225 boards based on Exynos5 series of SoCs. 225 boards based on Exynos5 series of SoCs.
226 226
227config SND_SOC_ODROIDX2
228 tristate "Audio support for Odroid-X2 and Odroid-U3"
229 depends on SND_SOC_SAMSUNG && I2C
230 select SND_SOC_MAX98090
231 select SND_SAMSUNG_I2S
232 help
233 Say Y here to enable audio support for the Odroid-X2/U3.
234
235config SND_SOC_ARNDALE_RT5631_ALC5631 227config SND_SOC_ARNDALE_RT5631_ALC5631
236 tristate "Audio support for RT5631(ALC5631) on Arndale Board" 228 tristate "Audio support for RT5631(ALC5631) on Arndale Board"
237 depends on SND_SOC_SAMSUNG && I2C 229 depends on SND_SOC_SAMSUNG && I2C
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 052fe71be518..5d03f5ce6916 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -43,7 +43,6 @@ snd-soc-tobermory-objs := tobermory.o
43snd-soc-lowland-objs := lowland.o 43snd-soc-lowland-objs := lowland.o
44snd-soc-littlemill-objs := littlemill.o 44snd-soc-littlemill-objs := littlemill.o
45snd-soc-bells-objs := bells.o 45snd-soc-bells-objs := bells.o
46snd-soc-odroidx2-max98090-objs := odroidx2_max98090.o
47snd-soc-arndale-rt5631-objs := arndale_rt5631.o 46snd-soc-arndale-rt5631-objs := arndale_rt5631.o
48 47
49obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 48obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
@@ -69,5 +68,4 @@ obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
69obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o 68obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
70obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o 69obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
71obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o 70obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
72obj-$(CONFIG_SND_SOC_ODROIDX2) += snd-soc-odroidx2-max98090.o
73obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o 71obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 4a7a503fe13c..547d31032088 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -389,7 +389,8 @@ static int s3c_ac97_probe(struct platform_device *pdev)
389 goto err5; 389 goto err5;
390 390
391 ret = samsung_asoc_dma_platform_register(&pdev->dev, 391 ret = samsung_asoc_dma_platform_register(&pdev->dev,
392 ac97_pdata->dma_filter); 392 ac97_pdata->dma_filter,
393 NULL, NULL);
393 if (ret) { 394 if (ret) {
394 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 395 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
395 goto err5; 396 goto err5;
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index a7616cc9b39e..3830f297e0b6 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -26,7 +26,10 @@ struct s3c_dma_params {
26void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, 26void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
27 struct s3c_dma_params *playback, 27 struct s3c_dma_params *playback,
28 struct s3c_dma_params *capture); 28 struct s3c_dma_params *capture);
29int samsung_asoc_dma_platform_register(struct device *dev, 29/*
30 dma_filter_fn fn); 30 * @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx",
31 31 * otherwise actual DMA channel names must be passed to this function.
32 */
33int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
34 const char *tx, const char *rx);
32#endif 35#endif
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c
index 063125937311..2c87f380bfc4 100644
--- a/sound/soc/samsung/dmaengine.c
+++ b/sound/soc/samsung/dmaengine.c
@@ -28,10 +28,6 @@
28 28
29#include "dma.h" 29#include "dma.h"
30 30
31static struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = {
32 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
33};
34
35void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, 31void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
36 struct s3c_dma_params *playback, 32 struct s3c_dma_params *playback,
37 struct s3c_dma_params *capture) 33 struct s3c_dma_params *capture)
@@ -58,15 +54,28 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
58} 54}
59EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); 55EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
60 56
61int samsung_asoc_dma_platform_register(struct device *dev, 57int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
62 dma_filter_fn filter) 58 const char *tx, const char *rx)
63{ 59{
64 samsung_dmaengine_pcm_config.compat_filter_fn = filter; 60 unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT;
61
62 struct snd_dmaengine_pcm_config *pcm_conf;
63
64 pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL);
65 if (!pcm_conf)
66 return -ENOMEM;
67
68 pcm_conf->prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config;
69 pcm_conf->compat_filter_fn = filter;
70
71 if (dev->of_node) {
72 pcm_conf->chan_names[SNDRV_PCM_STREAM_PLAYBACK] = tx;
73 pcm_conf->chan_names[SNDRV_PCM_STREAM_CAPTURE] = rx;
74 } else {
75 flags |= SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME;
76 }
65 77
66 return devm_snd_dmaengine_pcm_register(dev, 78 return devm_snd_dmaengine_pcm_register(dev, pcm_conf, flags);
67 &samsung_dmaengine_pcm_config,
68 SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |
69 SND_DMAENGINE_PCM_FLAG_COMPAT);
70} 79}
71EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); 80EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register);
72 81
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 70a2559b63f9..50635ee8ff20 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -18,6 +18,7 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_device.h>
21#include <linux/of_gpio.h> 22#include <linux/of_gpio.h>
22#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
23 24
@@ -1106,19 +1107,9 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
1106 return i2s; 1107 return i2s;
1107} 1108}
1108 1109
1109static const struct of_device_id exynos_i2s_match[]; 1110static void i2s_free_sec_dai(struct i2s_dai *i2s)
1110
1111static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data(
1112 struct platform_device *pdev)
1113{ 1111{
1114 if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { 1112 platform_device_del(i2s->pdev);
1115 const struct of_device_id *match;
1116 match = of_match_node(exynos_i2s_match, pdev->dev.of_node);
1117 return match ? match->data : NULL;
1118 } else {
1119 return (struct samsung_i2s_dai_data *)
1120 platform_get_device_id(pdev)->driver_data;
1121 }
1122} 1113}
1123 1114
1124#ifdef CONFIG_PM 1115#ifdef CONFIG_PM
@@ -1233,9 +1224,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1233 const struct samsung_i2s_dai_data *i2s_dai_data; 1224 const struct samsung_i2s_dai_data *i2s_dai_data;
1234 int ret; 1225 int ret;
1235 1226
1236 /* Call during Seconday interface registration */ 1227 if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
1237 i2s_dai_data = samsung_i2s_get_driver_data(pdev); 1228 i2s_dai_data = of_device_get_match_data(&pdev->dev);
1229 else
1230 i2s_dai_data = (struct samsung_i2s_dai_data *)
1231 platform_get_device_id(pdev)->driver_data;
1238 1232
1233 /* Call during the secondary interface registration */
1239 if (i2s_dai_data->dai_type == TYPE_SEC) { 1234 if (i2s_dai_data->dai_type == TYPE_SEC) {
1240 sec_dai = dev_get_drvdata(&pdev->dev); 1235 sec_dai = dev_get_drvdata(&pdev->dev);
1241 if (!sec_dai) { 1236 if (!sec_dai) {
@@ -1249,7 +1244,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1249 return ret; 1244 return ret;
1250 1245
1251 return samsung_asoc_dma_platform_register(&pdev->dev, 1246 return samsung_asoc_dma_platform_register(&pdev->dev,
1252 sec_dai->filter); 1247 sec_dai->filter, "tx-sec", NULL);
1253 } 1248 }
1254 1249
1255 pri_dai = i2s_alloc_dai(pdev, false); 1250 pri_dai = i2s_alloc_dai(pdev, false);
@@ -1350,17 +1345,28 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1350 return -EINVAL; 1345 return -EINVAL;
1351 } 1346 }
1352 1347
1353 devm_snd_soc_register_component(&pri_dai->pdev->dev, 1348 ret = devm_snd_soc_register_component(&pri_dai->pdev->dev,
1354 &samsung_i2s_component, 1349 &samsung_i2s_component,
1355 &pri_dai->i2s_dai_drv, 1); 1350 &pri_dai->i2s_dai_drv, 1);
1351 if (ret < 0)
1352 goto err_free_dai;
1353
1354 ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
1355 NULL, NULL);
1356 if (ret < 0)
1357 goto err_free_dai;
1356 1358
1357 pm_runtime_enable(&pdev->dev); 1359 pm_runtime_enable(&pdev->dev);
1358 1360
1359 ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter); 1361 ret = i2s_register_clock_provider(pdev);
1360 if (ret != 0) 1362 if (!ret)
1361 return ret; 1363 return 0;
1362 1364
1363 return i2s_register_clock_provider(pdev); 1365 pm_runtime_disable(&pdev->dev);
1366err_free_dai:
1367 if (sec_dai)
1368 i2s_free_sec_dai(sec_dai);
1369 return ret;
1364} 1370}
1365 1371
1366static int samsung_i2s_remove(struct platform_device *pdev) 1372static int samsung_i2s_remove(struct platform_device *pdev)
@@ -1477,10 +1483,6 @@ static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = {
1477 .i2s_variant_regs = &i2sv5_i2s1_regs, 1483 .i2s_variant_regs = &i2sv5_i2s1_regs,
1478}; 1484};
1479 1485
1480static const struct samsung_i2s_dai_data samsung_dai_type_pri = {
1481 .dai_type = TYPE_PRI,
1482};
1483
1484static const struct samsung_i2s_dai_data samsung_dai_type_sec = { 1486static const struct samsung_i2s_dai_data samsung_dai_type_sec = {
1485 .dai_type = TYPE_SEC, 1487 .dai_type = TYPE_SEC,
1486}; 1488};
@@ -1492,9 +1494,6 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = {
1492 }, { 1494 }, {
1493 .name = "samsung-i2s-sec", 1495 .name = "samsung-i2s-sec",
1494 .driver_data = (kernel_ulong_t)&samsung_dai_type_sec, 1496 .driver_data = (kernel_ulong_t)&samsung_dai_type_sec,
1495 }, {
1496 .name = "samsung-i2sv4",
1497 .driver_data = (kernel_ulong_t)&i2sv5_dai_type,
1498 }, 1497 },
1499 {}, 1498 {},
1500}; 1499};
diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c
deleted file mode 100644
index 04217279fe25..000000000000
--- a/sound/soc/samsung/odroidx2_max98090.c
+++ /dev/null
@@ -1,185 +0,0 @@
1/*
2 * Copyright (C) 2014 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/of.h>
11#include <linux/module.h>
12#include <sound/soc.h>
13#include <sound/pcm_params.h>
14#include "i2s.h"
15
16struct odroidx2_drv_data {
17 const struct snd_soc_dapm_widget *dapm_widgets;
18 unsigned int num_dapm_widgets;
19};
20
21/* The I2S CDCLK output clock frequency for the MAX98090 codec */
22#define MAX98090_MCLK 19200000
23
24static struct snd_soc_dai_link odroidx2_dai[];
25
26static int odroidx2_late_probe(struct snd_soc_card *card)
27{
28 struct snd_soc_pcm_runtime *rtd;
29 struct snd_soc_dai *codec_dai;
30 struct snd_soc_dai *cpu_dai;
31 int ret;
32
33 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
34 codec_dai = rtd->codec_dai;
35 cpu_dai = rtd->cpu_dai;
36
37 ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK,
38 SND_SOC_CLOCK_IN);
39
40 if (ret < 0 || of_find_property(odroidx2_dai[0].codec_of_node,
41 "clocks", NULL))
42 return ret;
43
44 /* Set the cpu DAI configuration in order to use CDCLK */
45 return snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
46 0, SND_SOC_CLOCK_OUT);
47}
48
49static const struct snd_soc_dapm_widget odroidx2_dapm_widgets[] = {
50 SND_SOC_DAPM_HP("Headphone Jack", NULL),
51 SND_SOC_DAPM_MIC("Mic Jack", NULL),
52 SND_SOC_DAPM_MIC("DMIC", NULL),
53};
54
55static const struct snd_soc_dapm_widget odroidu3_dapm_widgets[] = {
56 SND_SOC_DAPM_HP("Headphone Jack", NULL),
57 SND_SOC_DAPM_SPK("Speakers", NULL),
58};
59
60static struct snd_soc_dai_link odroidx2_dai[] = {
61 {
62 .name = "MAX98090",
63 .stream_name = "MAX98090 PCM",
64 .codec_dai_name = "HiFi",
65 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
66 SND_SOC_DAIFMT_CBM_CFM,
67 }
68};
69
70static struct snd_soc_card odroidx2 = {
71 .owner = THIS_MODULE,
72 .dai_link = odroidx2_dai,
73 .num_links = ARRAY_SIZE(odroidx2_dai),
74 .fully_routed = true,
75 .late_probe = odroidx2_late_probe,
76};
77
78static const struct odroidx2_drv_data odroidx2_drvdata = {
79 .dapm_widgets = odroidx2_dapm_widgets,
80 .num_dapm_widgets = ARRAY_SIZE(odroidx2_dapm_widgets),
81};
82
83static const struct odroidx2_drv_data odroidu3_drvdata = {
84 .dapm_widgets = odroidu3_dapm_widgets,
85 .num_dapm_widgets = ARRAY_SIZE(odroidu3_dapm_widgets),
86};
87
88static const struct of_device_id odroidx2_audio_of_match[] = {
89 {
90 .compatible = "samsung,odroidx2-audio",
91 .data = &odroidx2_drvdata,
92 }, {
93 .compatible = "samsung,odroidu3-audio",
94 .data = &odroidu3_drvdata,
95 },
96 { },
97};
98MODULE_DEVICE_TABLE(of, odroidx2_audio_of_match);
99
100static int odroidx2_audio_probe(struct platform_device *pdev)
101{
102 struct device_node *snd_node = pdev->dev.of_node;
103 struct snd_soc_card *card = &odroidx2;
104 struct device_node *i2s_node, *codec_node;
105 struct odroidx2_drv_data *dd;
106 const struct of_device_id *of_id;
107 int ret;
108
109 of_id = of_match_node(odroidx2_audio_of_match, snd_node);
110 dd = (struct odroidx2_drv_data *)of_id->data;
111
112 card->num_dapm_widgets = dd->num_dapm_widgets;
113 card->dapm_widgets = dd->dapm_widgets;
114
115 card->dev = &pdev->dev;
116
117 ret = snd_soc_of_parse_card_name(card, "samsung,model");
118 if (ret < 0)
119 return ret;
120
121 ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing");
122 if (ret < 0)
123 return ret;
124
125 codec_node = of_parse_phandle(snd_node, "samsung,audio-codec", 0);
126 if (!codec_node) {
127 dev_err(&pdev->dev,
128 "Failed parsing samsung,i2s-codec property\n");
129 return -EINVAL;
130 }
131
132 i2s_node = of_parse_phandle(snd_node, "samsung,i2s-controller", 0);
133 if (!i2s_node) {
134 dev_err(&pdev->dev,
135 "Failed parsing samsung,i2s-controller property\n");
136 ret = -EINVAL;
137 goto err_put_codec_n;
138 }
139
140 odroidx2_dai[0].codec_of_node = codec_node;
141 odroidx2_dai[0].cpu_of_node = i2s_node;
142 odroidx2_dai[0].platform_of_node = i2s_node;
143
144 ret = snd_soc_register_card(card);
145 if (ret) {
146 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
147 ret);
148 goto err_put_i2s_n;
149 }
150 return 0;
151
152err_put_i2s_n:
153 of_node_put(i2s_node);
154err_put_codec_n:
155 of_node_put(codec_node);
156 return ret;
157}
158
159static int odroidx2_audio_remove(struct platform_device *pdev)
160{
161 struct snd_soc_card *card = platform_get_drvdata(pdev);
162
163 snd_soc_unregister_card(card);
164
165 of_node_put(odroidx2_dai[0].cpu_of_node);
166 of_node_put(odroidx2_dai[0].codec_of_node);
167
168 return 0;
169}
170
171static struct platform_driver odroidx2_audio_driver = {
172 .driver = {
173 .name = "odroidx2-audio",
174 .of_match_table = odroidx2_audio_of_match,
175 .pm = &snd_soc_pm_ops,
176 },
177 .probe = odroidx2_audio_probe,
178 .remove = odroidx2_audio_remove,
179};
180module_platform_driver(odroidx2_audio_driver);
181
182MODULE_AUTHOR("Chen Zhen <zhen1.chen@samsung.com>");
183MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
184MODULE_DESCRIPTION("ALSA SoC Odroid X2/U3 Audio Support");
185MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 498f563a4c9c..490c1a87fd66 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -576,7 +576,8 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
576 goto err5; 576 goto err5;
577 } 577 }
578 578
579 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter); 579 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
580 NULL, NULL);
580 if (ret) { 581 if (ret) {
581 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 582 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
582 goto err5; 583 goto err5;
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index b6ab3fc5789e..bf8ae79b0fd2 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -268,7 +268,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
268 iismod &= ~S3C2412_IISMOD_SLAVE; 268 iismod &= ~S3C2412_IISMOD_SLAVE;
269 break; 269 break;
270 default: 270 default:
271 pr_err("unknwon master/slave format\n"); 271 pr_err("unknown master/slave format\n");
272 return -EINVAL; 272 return -EINVAL;
273 } 273 }
274 274
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 204029d12f5b..d45dffb297d8 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -177,7 +177,8 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
177 } 177 }
178 178
179 ret = samsung_asoc_dma_platform_register(&pdev->dev, 179 ret = samsung_asoc_dma_platform_register(&pdev->dev,
180 pdata->dma_filter); 180 pdata->dma_filter,
181 NULL, NULL);
181 if (ret) 182 if (ret)
182 pr_err("failed to register the DMA: %d\n", ret); 183 pr_err("failed to register the DMA: %d\n", ret);
183 184
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index b3a475d73ba7..3e76f2a75a24 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -482,7 +482,8 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
482 } 482 }
483 483
484 ret = samsung_asoc_dma_platform_register(&pdev->dev, 484 ret = samsung_asoc_dma_platform_register(&pdev->dev,
485 pdata->dma_filter); 485 pdata->dma_filter,
486 NULL, NULL);
486 if (ret) 487 if (ret)
487 pr_err("failed to register the dma: %d\n", ret); 488 pr_err("failed to register the dma: %d\n", ret);
488 489
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 4687f521197c..0cb9c8567546 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -435,7 +435,8 @@ static int spdif_probe(struct platform_device *pdev)
435 435
436 spdif->dma_playback = &spdif_stereo_out; 436 spdif->dma_playback = &spdif_stereo_out;
437 437
438 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter); 438 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter,
439 NULL, NULL);
439 if (ret) { 440 if (ret) {
440 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); 441 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
441 goto err4; 442 goto err4;
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index c9902a6d6fa0..9311f119feb5 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -44,6 +44,7 @@ config SND_SOC_RCAR
44 44
45config SND_SOC_RSRC_CARD 45config SND_SOC_RSRC_CARD
46 tristate "Renesas Sampling Rate Convert Sound Card" 46 tristate "Renesas Sampling Rate Convert Sound Card"
47 select SND_SIMPLE_CARD_UTILS
47 help 48 help
48 This option enables simple sound if you need sampling rate convert 49 This option enables simple sound if you need sampling rate convert
49 50
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index c4c51a4d3c8f..2145957d0229 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -33,11 +33,15 @@ struct rsnd_adg {
33 struct clk *clkout[CLKOUTMAX]; 33 struct clk *clkout[CLKOUTMAX];
34 struct clk_onecell_data onecell; 34 struct clk_onecell_data onecell;
35 struct rsnd_mod mod; 35 struct rsnd_mod mod;
36 u32 flags;
36 37
37 int rbga_rate_for_441khz; /* RBGA */ 38 int rbga_rate_for_441khz; /* RBGA */
38 int rbgb_rate_for_48khz; /* RBGB */ 39 int rbgb_rate_for_48khz; /* RBGB */
39}; 40};
40 41
42#define LRCLK_ASYNC (1 << 0)
43#define adg_mode_flags(adg) (adg->flags)
44
41#define for_each_rsnd_clk(pos, adg, i) \ 45#define for_each_rsnd_clk(pos, adg, i) \
42 for (i = 0; \ 46 for (i = 0; \
43 (i < CLKMAX) && \ 47 (i < CLKMAX) && \
@@ -355,6 +359,16 @@ found_clock:
355 359
356 rsnd_adg_set_ssi_clk(ssi_mod, data); 360 rsnd_adg_set_ssi_clk(ssi_mod, data);
357 361
362 if (!(adg_mode_flags(adg) & LRCLK_ASYNC)) {
363 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
364 u32 ckr = 0;
365
366 if (0 == (rate % 8000))
367 ckr = 0x80000000;
368
369 rsnd_mod_bset(adg_mod, SSICKR, 0x80000000, ckr);
370 }
371
358 dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n", 372 dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n",
359 rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod), 373 rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod),
360 data, rate); 374 data, rate);
@@ -532,6 +546,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
532{ 546{
533 struct rsnd_adg *adg; 547 struct rsnd_adg *adg;
534 struct device *dev = rsnd_priv_to_dev(priv); 548 struct device *dev = rsnd_priv_to_dev(priv);
549 struct device_node *np = dev->of_node;
535 550
536 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); 551 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
537 if (!adg) { 552 if (!adg) {
@@ -545,6 +560,9 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
545 rsnd_adg_get_clkin(priv, adg); 560 rsnd_adg_get_clkin(priv, adg);
546 rsnd_adg_get_clkout(priv, adg); 561 rsnd_adg_get_clkout(priv, adg);
547 562
563 if (of_get_property(np, "clkout-lr-asynchronous", NULL))
564 adg->flags = LRCLK_ASYNC;
565
548 priv->adg = adg; 566 priv->adg = adg;
549 567
550 return 0; 568 return 0;
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 46c0ba7b6414..7d2fdf8dd188 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -206,7 +206,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
206 */ 206 */
207static int rsnd_gen2_probe(struct rsnd_priv *priv) 207static int rsnd_gen2_probe(struct rsnd_priv *priv)
208{ 208{
209 const static struct rsnd_regmap_field_conf conf_ssiu[] = { 209 static const struct rsnd_regmap_field_conf conf_ssiu[] = {
210 RSND_GEN_S_REG(SSI_MODE0, 0x800), 210 RSND_GEN_S_REG(SSI_MODE0, 0x800),
211 RSND_GEN_S_REG(SSI_MODE1, 0x804), 211 RSND_GEN_S_REG(SSI_MODE1, 0x804),
212 RSND_GEN_S_REG(SSI_MODE2, 0x808), 212 RSND_GEN_S_REG(SSI_MODE2, 0x808),
@@ -221,7 +221,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
221 RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80), 221 RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80),
222 }; 222 };
223 223
224 const static struct rsnd_regmap_field_conf conf_scu[] = { 224 static const struct rsnd_regmap_field_conf conf_scu[] = {
225 RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0, 0x20), 225 RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0, 0x20),
226 RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4, 0x20), 226 RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4, 0x20),
227 RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20), 227 RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20),
@@ -308,7 +308,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
308 RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100), 308 RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100),
309 RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), 309 RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100),
310 }; 310 };
311 const static struct rsnd_regmap_field_conf conf_adg[] = { 311 static const struct rsnd_regmap_field_conf conf_adg[] = {
312 RSND_GEN_S_REG(BRRA, 0x00), 312 RSND_GEN_S_REG(BRRA, 0x00),
313 RSND_GEN_S_REG(BRRB, 0x04), 313 RSND_GEN_S_REG(BRRB, 0x04),
314 RSND_GEN_S_REG(SSICKR, 0x08), 314 RSND_GEN_S_REG(SSICKR, 0x08),
@@ -328,7 +328,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
328 RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58), 328 RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58),
329 RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c), 329 RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c),
330 }; 330 };
331 const static struct rsnd_regmap_field_conf conf_ssi[] = { 331 static const struct rsnd_regmap_field_conf conf_ssi[] = {
332 RSND_GEN_M_REG(SSICR, 0x00, 0x40), 332 RSND_GEN_M_REG(SSICR, 0x00, 0x40),
333 RSND_GEN_M_REG(SSISR, 0x04, 0x40), 333 RSND_GEN_M_REG(SSISR, 0x04, 0x40),
334 RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 334 RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
@@ -359,14 +359,14 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
359 359
360static int rsnd_gen1_probe(struct rsnd_priv *priv) 360static int rsnd_gen1_probe(struct rsnd_priv *priv)
361{ 361{
362 const static struct rsnd_regmap_field_conf conf_adg[] = { 362 static const struct rsnd_regmap_field_conf conf_adg[] = {
363 RSND_GEN_S_REG(BRRA, 0x00), 363 RSND_GEN_S_REG(BRRA, 0x00),
364 RSND_GEN_S_REG(BRRB, 0x04), 364 RSND_GEN_S_REG(BRRB, 0x04),
365 RSND_GEN_S_REG(SSICKR, 0x08), 365 RSND_GEN_S_REG(SSICKR, 0x08),
366 RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 366 RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c),
367 RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 367 RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10),
368 }; 368 };
369 const static struct rsnd_regmap_field_conf conf_ssi[] = { 369 static const struct rsnd_regmap_field_conf conf_ssi[] = {
370 RSND_GEN_M_REG(SSICR, 0x00, 0x40), 370 RSND_GEN_M_REG(SSICR, 0x00, 0x40),
371 RSND_GEN_M_REG(SSISR, 0x04, 0x40), 371 RSND_GEN_M_REG(SSISR, 0x04, 0x40),
372 RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 372 RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
index 1bc7ecfc42a9..fa37f842b62f 100644
--- a/sound/soc/sh/rcar/rsrc-card.c
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -20,6 +20,7 @@
20#include <sound/jack.h> 20#include <sound/jack.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/soc-dai.h> 22#include <sound/soc-dai.h>
23#include <sound/simple_card_utils.h>
23 24
24struct rsrc_card_of_data { 25struct rsrc_card_of_data {
25 const char *prefix; 26 const char *prefix;
@@ -46,25 +47,13 @@ static const struct of_device_id rsrc_card_of_match[] = {
46}; 47};
47MODULE_DEVICE_TABLE(of, rsrc_card_of_match); 48MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
48 49
49#define DAI_NAME_NUM 32
50struct rsrc_card_dai {
51 unsigned int sysclk;
52 unsigned int tx_slot_mask;
53 unsigned int rx_slot_mask;
54 int slots;
55 int slot_width;
56 struct clk *clk;
57 char dai_name[DAI_NAME_NUM];
58};
59
60#define IDX_CPU 0 50#define IDX_CPU 0
61#define IDX_CODEC 1 51#define IDX_CODEC 1
62struct rsrc_card_priv { 52struct rsrc_card_priv {
63 struct snd_soc_card snd_card; 53 struct snd_soc_card snd_card;
64 struct snd_soc_codec_conf codec_conf; 54 struct snd_soc_codec_conf codec_conf;
65 struct rsrc_card_dai *dai_props; 55 struct asoc_simple_dai *dai_props;
66 struct snd_soc_dai_link *dai_link; 56 struct snd_soc_dai_link *dai_link;
67 int dai_num;
68 u32 convert_rate; 57 u32 convert_rate;
69 u32 convert_channels; 58 u32 convert_channels;
70}; 59};
@@ -77,7 +66,7 @@ static int rsrc_card_startup(struct snd_pcm_substream *substream)
77{ 66{
78 struct snd_soc_pcm_runtime *rtd = substream->private_data; 67 struct snd_soc_pcm_runtime *rtd = substream->private_data;
79 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 68 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
80 struct rsrc_card_dai *dai_props = 69 struct asoc_simple_dai *dai_props =
81 rsrc_priv_to_props(priv, rtd->num); 70 rsrc_priv_to_props(priv, rtd->num);
82 71
83 return clk_prepare_enable(dai_props->clk); 72 return clk_prepare_enable(dai_props->clk);
@@ -87,7 +76,7 @@ static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
87{ 76{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data; 77 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 78 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
90 struct rsrc_card_dai *dai_props = 79 struct asoc_simple_dai *dai_props =
91 rsrc_priv_to_props(priv, rtd->num); 80 rsrc_priv_to_props(priv, rtd->num);
92 81
93 clk_disable_unprepare(dai_props->clk); 82 clk_disable_unprepare(dai_props->clk);
@@ -103,7 +92,7 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
103 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 92 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
104 struct snd_soc_dai *dai; 93 struct snd_soc_dai *dai;
105 struct snd_soc_dai_link *dai_link; 94 struct snd_soc_dai_link *dai_link;
106 struct rsrc_card_dai *dai_props; 95 struct asoc_simple_dai *dai_props;
107 int num = rtd->num; 96 int num = rtd->num;
108 int ret; 97 int ret;
109 98
@@ -159,44 +148,13 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
159 return 0; 148 return 0;
160} 149}
161 150
162static int rsrc_card_parse_daifmt(struct device_node *node,
163 struct device_node *codec,
164 struct rsrc_card_priv *priv,
165 struct snd_soc_dai_link *dai_link,
166 unsigned int *retfmt)
167{
168 struct device_node *bitclkmaster = NULL;
169 struct device_node *framemaster = NULL;
170 unsigned int daifmt;
171
172 daifmt = snd_soc_of_parse_daifmt(node, NULL,
173 &bitclkmaster, &framemaster);
174 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
175
176 if (!bitclkmaster && !framemaster)
177 return -EINVAL;
178
179 if (codec == bitclkmaster)
180 daifmt |= (codec == framemaster) ?
181 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
182 else
183 daifmt |= (codec == framemaster) ?
184 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
185
186 of_node_put(bitclkmaster);
187 of_node_put(framemaster);
188
189 *retfmt = daifmt;
190
191 return 0;
192}
193
194static int rsrc_card_parse_links(struct device_node *np, 151static int rsrc_card_parse_links(struct device_node *np,
195 struct rsrc_card_priv *priv, 152 struct rsrc_card_priv *priv,
196 int idx, bool is_fe) 153 int idx, bool is_fe)
197{ 154{
155 struct device *dev = rsrc_priv_to_dev(priv);
198 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); 156 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
199 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); 157 struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
200 struct of_phandle_args args; 158 struct of_phandle_args args;
201 int ret; 159 int ret;
202 160
@@ -232,9 +190,11 @@ static int rsrc_card_parse_links(struct device_node *np,
232 if (ret < 0) 190 if (ret < 0)
233 return ret; 191 return ret;
234 192
235 /* set dai_name */ 193 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
236 snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s", 194 "fe.%s",
237 dai_link->cpu_dai_name); 195 dai_link->cpu_dai_name);
196 if (ret < 0)
197 return ret;
238 198
239 /* 199 /*
240 * In soc_bind_dai_link() will check cpu name after 200 * In soc_bind_dai_link() will check cpu name after
@@ -248,7 +208,6 @@ static int rsrc_card_parse_links(struct device_node *np,
248 if (!args.args_count) 208 if (!args.args_count)
249 dai_link->cpu_dai_name = NULL; 209 dai_link->cpu_dai_name = NULL;
250 } else { 210 } else {
251 struct device *dev = rsrc_priv_to_dev(priv);
252 const struct rsrc_card_of_data *of_data; 211 const struct rsrc_card_of_data *of_data;
253 212
254 of_data = of_device_get_match_data(dev); 213 of_data = of_device_get_match_data(dev);
@@ -266,6 +225,12 @@ static int rsrc_card_parse_links(struct device_node *np,
266 if (ret < 0) 225 if (ret < 0)
267 return ret; 226 return ret;
268 227
228 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
229 "be.%s",
230 dai_link->codec_dai_name);
231 if (ret < 0)
232 return ret;
233
269 /* additional name prefix */ 234 /* additional name prefix */
270 if (of_data) { 235 if (of_data) {
271 priv->codec_conf.of_node = dai_link->codec_of_node; 236 priv->codec_conf.of_node = dai_link->codec_of_node;
@@ -276,18 +241,12 @@ static int rsrc_card_parse_links(struct device_node *np,
276 dai_link->codec_of_node, 241 dai_link->codec_of_node,
277 "audio-prefix"); 242 "audio-prefix");
278 } 243 }
279
280 /* set dai_name */
281 snprintf(dai_props->dai_name, DAI_NAME_NUM, "be.%s",
282 dai_link->codec_dai_name);
283 } 244 }
284 245
285 /* Simple Card assumes platform == cpu */ 246 /* Simple Card assumes platform == cpu */
286 dai_link->platform_of_node = dai_link->cpu_of_node; 247 dai_link->platform_of_node = dai_link->cpu_of_node;
287 dai_link->dpcm_playback = 1; 248 dai_link->dpcm_playback = 1;
288 dai_link->dpcm_capture = 1; 249 dai_link->dpcm_capture = 1;
289 dai_link->name = dai_props->dai_name;
290 dai_link->stream_name = dai_props->dai_name;
291 dai_link->ops = &rsrc_card_ops; 250 dai_link->ops = &rsrc_card_ops;
292 dai_link->init = rsrc_card_dai_init; 251 dai_link->init = rsrc_card_dai_init;
293 252
@@ -299,7 +258,7 @@ static int rsrc_card_parse_clk(struct device_node *np,
299 int idx, bool is_fe) 258 int idx, bool is_fe)
300{ 259{
301 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); 260 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
302 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); 261 struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
303 struct clk *clk; 262 struct clk *clk;
304 struct device_node *of_np = is_fe ? dai_link->cpu_of_node : 263 struct device_node *of_np = is_fe ? dai_link->cpu_of_node :
305 dai_link->codec_of_node; 264 dai_link->codec_of_node;
@@ -336,7 +295,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node,
336{ 295{
337 struct device *dev = rsrc_priv_to_dev(priv); 296 struct device *dev = rsrc_priv_to_dev(priv);
338 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); 297 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
339 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); 298 struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
340 int ret; 299 int ret;
341 300
342 ret = rsrc_card_parse_links(np, priv, idx, is_fe); 301 ret = rsrc_card_parse_links(np, priv, idx, is_fe);
@@ -348,7 +307,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node,
348 return ret; 307 return ret;
349 308
350 dev_dbg(dev, "\t%s / %04x / %d\n", 309 dev_dbg(dev, "\t%s / %04x / %d\n",
351 dai_props->dai_name, 310 dai_link->name,
352 dai_link->dai_fmt, 311 dai_link->dai_fmt,
353 dai_props->sysclk); 312 dai_props->sysclk);
354 313
@@ -358,6 +317,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node,
358static int rsrc_card_dai_link_of(struct device_node *node, 317static int rsrc_card_dai_link_of(struct device_node *node,
359 struct rsrc_card_priv *priv) 318 struct rsrc_card_priv *priv)
360{ 319{
320 struct device *dev = rsrc_priv_to_dev(priv);
361 struct snd_soc_dai_link *dai_link; 321 struct snd_soc_dai_link *dai_link;
362 struct device_node *np; 322 struct device_node *np;
363 unsigned int daifmt = 0; 323 unsigned int daifmt = 0;
@@ -370,8 +330,8 @@ static int rsrc_card_dai_link_of(struct device_node *node,
370 dai_link = rsrc_priv_to_link(priv, i); 330 dai_link = rsrc_priv_to_link(priv, i);
371 331
372 if (strcmp(np->name, "codec") == 0) { 332 if (strcmp(np->name, "codec") == 0) {
373 ret = rsrc_card_parse_daifmt(node, np, priv, 333 ret = asoc_simple_card_parse_daifmt(dev, node, np,
374 dai_link, &daifmt); 334 NULL, &daifmt);
375 if (ret < 0) 335 if (ret < 0)
376 return ret; 336 return ret;
377 break; 337 break;
@@ -402,7 +362,7 @@ static int rsrc_card_parse_of(struct device_node *node,
402 struct device *dev) 362 struct device *dev)
403{ 363{
404 const struct rsrc_card_of_data *of_data = of_device_get_match_data(dev); 364 const struct rsrc_card_of_data *of_data = of_device_get_match_data(dev);
405 struct rsrc_card_dai *props; 365 struct asoc_simple_dai *props;
406 struct snd_soc_dai_link *links; 366 struct snd_soc_dai_link *links;
407 int ret; 367 int ret;
408 int num; 368 int num;
@@ -418,7 +378,6 @@ static int rsrc_card_parse_of(struct device_node *node,
418 378
419 priv->dai_props = props; 379 priv->dai_props = props;
420 priv->dai_link = links; 380 priv->dai_link = links;
421 priv->dai_num = num;
422 381
423 /* Init snd_soc_card */ 382 /* Init snd_soc_card */
424 priv->snd_card.owner = THIS_MODULE; 383 priv->snd_card.owner = THIS_MODULE;
@@ -436,9 +395,6 @@ static int rsrc_card_parse_of(struct device_node *node,
436 "audio-routing"); 395 "audio-routing");
437 } 396 }
438 397
439 /* Parse the card name from DT */
440 snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
441
442 /* sampling rate convert */ 398 /* sampling rate convert */
443 of_property_read_u32(node, "convert-rate", &priv->convert_rate); 399 of_property_read_u32(node, "convert-rate", &priv->convert_rate);
444 400
@@ -454,8 +410,9 @@ static int rsrc_card_parse_of(struct device_node *node,
454 if (ret < 0) 410 if (ret < 0)
455 return ret; 411 return ret;
456 412
457 if (!priv->snd_card.name) 413 ret = asoc_simple_card_parse_card_name(&priv->snd_card, "card-");
458 priv->snd_card.name = priv->snd_card.dai_link->name; 414 if (ret < 0)
415 return ret;
459 416
460 return 0; 417 return 0;
461} 418}
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 875733c52953..d2df46c14c68 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -530,14 +530,15 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
530{ 530{
531 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 531 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
532 struct snd_soc_platform *platform = rtd->platform; 532 struct snd_soc_platform *platform = rtd->platform;
533 int ret = 0;
533 534
534 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 535 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
535 536
536 if (platform->driver->compr_ops && platform->driver->compr_ops->pointer) 537 if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
537 platform->driver->compr_ops->pointer(cstream, tstamp); 538 ret = platform->driver->compr_ops->pointer(cstream, tstamp);
538 539
539 mutex_unlock(&rtd->pcm_mutex); 540 mutex_unlock(&rtd->pcm_mutex);
540 return 0; 541 return ret;
541} 542}
542 543
543static int soc_compr_copy(struct snd_compr_stream *cstream, 544static int soc_compr_copy(struct snd_compr_stream *cstream,
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index c4464858bf01..8698c26773b3 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1073,7 +1073,11 @@ static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list,
1073 */ 1073 */
1074static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget, 1074static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
1075 struct list_head *list, enum snd_soc_dapm_direction dir, 1075 struct list_head *list, enum snd_soc_dapm_direction dir,
1076 int (*fn)(struct snd_soc_dapm_widget *, struct list_head *)) 1076 int (*fn)(struct snd_soc_dapm_widget *, struct list_head *,
1077 bool (*custom_stop_condition)(struct snd_soc_dapm_widget *,
1078 enum snd_soc_dapm_direction)),
1079 bool (*custom_stop_condition)(struct snd_soc_dapm_widget *,
1080 enum snd_soc_dapm_direction))
1077{ 1081{
1078 enum snd_soc_dapm_direction rdir = SND_SOC_DAPM_DIR_REVERSE(dir); 1082 enum snd_soc_dapm_direction rdir = SND_SOC_DAPM_DIR_REVERSE(dir);
1079 struct snd_soc_dapm_path *path; 1083 struct snd_soc_dapm_path *path;
@@ -1088,6 +1092,11 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
1088 if (list) 1092 if (list)
1089 list_add_tail(&widget->work_list, list); 1093 list_add_tail(&widget->work_list, list);
1090 1094
1095 if (custom_stop_condition && custom_stop_condition(widget, dir)) {
1096 widget->endpoints[dir] = 1;
1097 return widget->endpoints[dir];
1098 }
1099
1091 if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) { 1100 if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) {
1092 widget->endpoints[dir] = snd_soc_dapm_suspend_check(widget); 1101 widget->endpoints[dir] = snd_soc_dapm_suspend_check(widget);
1093 return widget->endpoints[dir]; 1102 return widget->endpoints[dir];
@@ -1106,7 +1115,7 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
1106 1115
1107 if (path->connect) { 1116 if (path->connect) {
1108 path->walking = 1; 1117 path->walking = 1;
1109 con += fn(path->node[dir], list); 1118 con += fn(path->node[dir], list, custom_stop_condition);
1110 path->walking = 0; 1119 path->walking = 0;
1111 } 1120 }
1112 } 1121 }
@@ -1119,23 +1128,37 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
1119/* 1128/*
1120 * Recursively check for a completed path to an active or physically connected 1129 * Recursively check for a completed path to an active or physically connected
1121 * output widget. Returns number of complete paths. 1130 * output widget. Returns number of complete paths.
1131 *
1132 * Optionally, can be supplied with a function acting as a stopping condition.
1133 * This function takes the dapm widget currently being examined and the walk
1134 * direction as an arguments, it should return true if the walk should be
1135 * stopped and false otherwise.
1122 */ 1136 */
1123static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, 1137static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
1124 struct list_head *list) 1138 struct list_head *list,
1139 bool (*custom_stop_condition)(struct snd_soc_dapm_widget *i,
1140 enum snd_soc_dapm_direction))
1125{ 1141{
1126 return is_connected_ep(widget, list, SND_SOC_DAPM_DIR_OUT, 1142 return is_connected_ep(widget, list, SND_SOC_DAPM_DIR_OUT,
1127 is_connected_output_ep); 1143 is_connected_output_ep, custom_stop_condition);
1128} 1144}
1129 1145
1130/* 1146/*
1131 * Recursively check for a completed path to an active or physically connected 1147 * Recursively check for a completed path to an active or physically connected
1132 * input widget. Returns number of complete paths. 1148 * input widget. Returns number of complete paths.
1149 *
1150 * Optionally, can be supplied with a function acting as a stopping condition.
1151 * This function takes the dapm widget currently being examined and the walk
1152 * direction as an arguments, it should return true if the walk should be
1153 * stopped and false otherwise.
1133 */ 1154 */
1134static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, 1155static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
1135 struct list_head *list) 1156 struct list_head *list,
1157 bool (*custom_stop_condition)(struct snd_soc_dapm_widget *i,
1158 enum snd_soc_dapm_direction))
1136{ 1159{
1137 return is_connected_ep(widget, list, SND_SOC_DAPM_DIR_IN, 1160 return is_connected_ep(widget, list, SND_SOC_DAPM_DIR_IN,
1138 is_connected_input_ep); 1161 is_connected_input_ep, custom_stop_condition);
1139} 1162}
1140 1163
1141/** 1164/**
@@ -1143,15 +1166,24 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
1143 * @dai: the soc DAI. 1166 * @dai: the soc DAI.
1144 * @stream: stream direction. 1167 * @stream: stream direction.
1145 * @list: list of active widgets for this stream. 1168 * @list: list of active widgets for this stream.
1169 * @custom_stop_condition: (optional) a function meant to stop the widget graph
1170 * walk based on custom logic.
1146 * 1171 *
1147 * Queries DAPM graph as to whether an valid audio stream path exists for 1172 * Queries DAPM graph as to whether an valid audio stream path exists for
1148 * the initial stream specified by name. This takes into account 1173 * the initial stream specified by name. This takes into account
1149 * current mixer and mux kcontrol settings. Creates list of valid widgets. 1174 * current mixer and mux kcontrol settings. Creates list of valid widgets.
1150 * 1175 *
1176 * Optionally, can be supplied with a function acting as a stopping condition.
1177 * This function takes the dapm widget currently being examined and the walk
1178 * direction as an arguments, it should return true if the walk should be
1179 * stopped and false otherwise.
1180 *
1151 * Returns the number of valid paths or negative error. 1181 * Returns the number of valid paths or negative error.
1152 */ 1182 */
1153int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, 1183int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
1154 struct snd_soc_dapm_widget_list **list) 1184 struct snd_soc_dapm_widget_list **list,
1185 bool (*custom_stop_condition)(struct snd_soc_dapm_widget *,
1186 enum snd_soc_dapm_direction))
1155{ 1187{
1156 struct snd_soc_card *card = dai->component->card; 1188 struct snd_soc_card *card = dai->component->card;
1157 struct snd_soc_dapm_widget *w; 1189 struct snd_soc_dapm_widget *w;
@@ -1171,9 +1203,11 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
1171 } 1203 }
1172 1204
1173 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1205 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1174 paths = is_connected_output_ep(dai->playback_widget, &widgets); 1206 paths = is_connected_output_ep(dai->playback_widget, &widgets,
1207 custom_stop_condition);
1175 else 1208 else
1176 paths = is_connected_input_ep(dai->capture_widget, &widgets); 1209 paths = is_connected_input_ep(dai->capture_widget, &widgets,
1210 custom_stop_condition);
1177 1211
1178 /* Drop starting point */ 1212 /* Drop starting point */
1179 list_del(widgets.next); 1213 list_del(widgets.next);
@@ -1268,8 +1302,8 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
1268 1302
1269 DAPM_UPDATE_STAT(w, power_checks); 1303 DAPM_UPDATE_STAT(w, power_checks);
1270 1304
1271 in = is_connected_input_ep(w, NULL); 1305 in = is_connected_input_ep(w, NULL, NULL);
1272 out = is_connected_output_ep(w, NULL); 1306 out = is_connected_output_ep(w, NULL, NULL);
1273 return out != 0 && in != 0; 1307 return out != 0 && in != 0;
1274} 1308}
1275 1309
@@ -1928,8 +1962,8 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1928 in = 0; 1962 in = 0;
1929 out = 0; 1963 out = 0;
1930 } else { 1964 } else {
1931 in = is_connected_input_ep(w, NULL); 1965 in = is_connected_input_ep(w, NULL, NULL);
1932 out = is_connected_output_ep(w, NULL); 1966 out = is_connected_output_ep(w, NULL, NULL);
1933 } 1967 }
1934 1968
1935 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", 1969 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
@@ -3282,6 +3316,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3282 mutex_unlock(&dapm->card->dapm_mutex); 3316 mutex_unlock(&dapm->card->dapm_mutex);
3283 return w; 3317 return w;
3284} 3318}
3319EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
3285 3320
3286struct snd_soc_dapm_widget * 3321struct snd_soc_dapm_widget *
3287snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, 3322snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index aa99dac31b3b..60d702f8b9f0 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1287,6 +1287,46 @@ static int widget_in_list(struct snd_soc_dapm_widget_list *list,
1287 return 0; 1287 return 0;
1288} 1288}
1289 1289
1290static bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget,
1291 enum snd_soc_dapm_direction dir)
1292{
1293 struct snd_soc_card *card = widget->dapm->card;
1294 struct snd_soc_pcm_runtime *rtd;
1295 int i;
1296
1297 if (dir == SND_SOC_DAPM_DIR_OUT) {
1298 list_for_each_entry(rtd, &card->rtd_list, list) {
1299 if (!rtd->dai_link->no_pcm)
1300 continue;
1301
1302 if (rtd->cpu_dai->playback_widget == widget)
1303 return true;
1304
1305 for (i = 0; i < rtd->num_codecs; ++i) {
1306 struct snd_soc_dai *dai = rtd->codec_dais[i];
1307 if (dai->playback_widget == widget)
1308 return true;
1309 }
1310 }
1311 } else { /* SND_SOC_DAPM_DIR_IN */
1312 list_for_each_entry(rtd, &card->rtd_list, list) {
1313 if (!rtd->dai_link->no_pcm)
1314 continue;
1315
1316 if (rtd->cpu_dai->capture_widget == widget)
1317 return true;
1318
1319 for (i = 0; i < rtd->num_codecs; ++i) {
1320 struct snd_soc_dai *dai = rtd->codec_dais[i];
1321 if (dai->capture_widget == widget)
1322 return true;
1323 }
1324 }
1325 }
1326
1327 return false;
1328}
1329
1290int dpcm_path_get(struct snd_soc_pcm_runtime *fe, 1330int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
1291 int stream, struct snd_soc_dapm_widget_list **list) 1331 int stream, struct snd_soc_dapm_widget_list **list)
1292{ 1332{
@@ -1294,7 +1334,8 @@ int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
1294 int paths; 1334 int paths;
1295 1335
1296 /* get number of valid DAI paths and their widgets */ 1336 /* get number of valid DAI paths and their widgets */
1297 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, list); 1337 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, list,
1338 dpcm_end_walk_at_be);
1298 1339
1299 dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths, 1340 dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths,
1300 stream ? "capture" : "playback"); 1341 stream ? "capture" : "playback");
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
index ee1c7c245bc7..1ac2db205a0d 100644
--- a/sound/soc/sti/uniperif_player.c
+++ b/sound/soc/sti/uniperif_player.c
@@ -1029,9 +1029,9 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
1029 1029
1030 regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg"); 1030 regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg");
1031 1031
1032 if (!regmap) { 1032 if (IS_ERR(regmap)) {
1033 dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n"); 1033 dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n");
1034 return -EINVAL; 1034 return PTR_ERR(regmap);
1035 } 1035 }
1036 1036
1037 player->clk_sel = regmap_field_alloc(regmap, regfield[0]); 1037 player->clk_sel = regmap_field_alloc(regmap, regfield[0]);
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index ae42294ef688..2a954bd01fd8 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -8,6 +8,15 @@ config SND_SUN4I_CODEC
8 Select Y or M to add support for the Codec embedded in the Allwinner 8 Select Y or M to add support for the Codec embedded in the Allwinner
9 A10 and affiliated SoCs. 9 A10 and affiliated SoCs.
10 10
11config SND_SUN4I_I2S
12 tristate "Allwinner A10 I2S Support"
13 select SND_SOC_GENERIC_DMAENGINE_PCM
14 select REGMAP_MMIO
15 help
16 Say Y or M if you want to add support for codecs attached to
17 the Allwinner A10 I2S. You will also need to select the
18 individual machine drivers to support below.
19
11config SND_SUN4I_SPDIF 20config SND_SUN4I_SPDIF
12 tristate "Allwinner A10 SPDIF Support" 21 tristate "Allwinner A10 SPDIF Support"
13 depends on OF 22 depends on OF
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 8f5e889667f1..604c7b842837 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,3 +1,3 @@
1obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o 1obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
2 2obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
3obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o 3obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
new file mode 100644
index 000000000000..687a8f83dbe5
--- /dev/null
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -0,0 +1,701 @@
1/*
2 * Copyright (C) 2015 Andrea Venturi
3 * Andrea Venturi <be17068@iperbole.bo.it>
4 *
5 * Copyright (C) 2016 Maxime Ripard
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 */
13
14#include <linux/clk.h>
15#include <linux/dmaengine.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/pm_runtime.h>
19#include <linux/regmap.h>
20
21#include <sound/dmaengine_pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/soc-dai.h>
25
26#define SUN4I_I2S_CTRL_REG 0x00
27#define SUN4I_I2S_CTRL_SDO_EN_MASK GENMASK(11, 8)
28#define SUN4I_I2S_CTRL_SDO_EN(sdo) BIT(8 + (sdo))
29#define SUN4I_I2S_CTRL_MODE_MASK BIT(5)
30#define SUN4I_I2S_CTRL_MODE_SLAVE (1 << 5)
31#define SUN4I_I2S_CTRL_MODE_MASTER (0 << 5)
32#define SUN4I_I2S_CTRL_TX_EN BIT(2)
33#define SUN4I_I2S_CTRL_RX_EN BIT(1)
34#define SUN4I_I2S_CTRL_GL_EN BIT(0)
35
36#define SUN4I_I2S_FMT0_REG 0x04
37#define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(7)
38#define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 7)
39#define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 7)
40#define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK BIT(6)
41#define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 6)
42#define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 6)
43#define SUN4I_I2S_FMT0_SR_MASK GENMASK(5, 4)
44#define SUN4I_I2S_FMT0_SR(sr) ((sr) << 4)
45#define SUN4I_I2S_FMT0_WSS_MASK GENMASK(3, 2)
46#define SUN4I_I2S_FMT0_WSS(wss) ((wss) << 2)
47#define SUN4I_I2S_FMT0_FMT_MASK GENMASK(1, 0)
48#define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0)
49#define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0)
50#define SUN4I_I2S_FMT0_FMT_I2S (0 << 0)
51
52#define SUN4I_I2S_FMT1_REG 0x08
53#define SUN4I_I2S_FIFO_TX_REG 0x0c
54#define SUN4I_I2S_FIFO_RX_REG 0x10
55
56#define SUN4I_I2S_FIFO_CTRL_REG 0x14
57#define SUN4I_I2S_FIFO_CTRL_FLUSH_TX BIT(25)
58#define SUN4I_I2S_FIFO_CTRL_FLUSH_RX BIT(24)
59#define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK BIT(2)
60#define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode) ((mode) << 2)
61#define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK GENMASK(1, 0)
62#define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode) (mode)
63
64#define SUN4I_I2S_FIFO_STA_REG 0x18
65
66#define SUN4I_I2S_DMA_INT_CTRL_REG 0x1c
67#define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN BIT(7)
68#define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN BIT(3)
69
70#define SUN4I_I2S_INT_STA_REG 0x20
71
72#define SUN4I_I2S_CLK_DIV_REG 0x24
73#define SUN4I_I2S_CLK_DIV_MCLK_EN BIT(7)
74#define SUN4I_I2S_CLK_DIV_BCLK_MASK GENMASK(6, 4)
75#define SUN4I_I2S_CLK_DIV_BCLK(bclk) ((bclk) << 4)
76#define SUN4I_I2S_CLK_DIV_MCLK_MASK GENMASK(3, 0)
77#define SUN4I_I2S_CLK_DIV_MCLK(mclk) ((mclk) << 0)
78
79#define SUN4I_I2S_RX_CNT_REG 0x28
80#define SUN4I_I2S_TX_CNT_REG 0x2c
81
82#define SUN4I_I2S_TX_CHAN_SEL_REG 0x30
83#define SUN4I_I2S_TX_CHAN_SEL(num_chan) (((num_chan) - 1) << 0)
84
85#define SUN4I_I2S_TX_CHAN_MAP_REG 0x34
86#define SUN4I_I2S_TX_CHAN_MAP(chan, sample) ((sample) << (chan << 2))
87
88#define SUN4I_I2S_RX_CHAN_SEL_REG 0x38
89#define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c
90
91struct sun4i_i2s {
92 struct clk *bus_clk;
93 struct clk *mod_clk;
94 struct regmap *regmap;
95
96 struct snd_dmaengine_dai_dma_data playback_dma_data;
97};
98
99struct sun4i_i2s_clk_div {
100 u8 div;
101 u8 val;
102};
103
104static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
105 { .div = 2, .val = 0 },
106 { .div = 4, .val = 1 },
107 { .div = 6, .val = 2 },
108 { .div = 8, .val = 3 },
109 { .div = 12, .val = 4 },
110 { .div = 16, .val = 5 },
111};
112
113static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
114 { .div = 1, .val = 0 },
115 { .div = 2, .val = 1 },
116 { .div = 4, .val = 2 },
117 { .div = 6, .val = 3 },
118 { .div = 8, .val = 4 },
119 { .div = 12, .val = 5 },
120 { .div = 16, .val = 6 },
121 { .div = 24, .val = 7 },
122};
123
124static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
125 unsigned int oversample_rate,
126 unsigned int word_size)
127{
128 int div = oversample_rate / word_size / 2;
129 int i;
130
131 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) {
132 const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i];
133
134 if (bdiv->div == div)
135 return bdiv->val;
136 }
137
138 return -EINVAL;
139}
140
141static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
142 unsigned int oversample_rate,
143 unsigned int module_rate,
144 unsigned int sampling_rate)
145{
146 int div = module_rate / sampling_rate / oversample_rate;
147 int i;
148
149 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) {
150 const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i];
151
152 if (mdiv->div == div)
153 return mdiv->val;
154 }
155
156 return -EINVAL;
157}
158
159static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
160
161static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,
162 unsigned int rate,
163 unsigned int word_size)
164{
165 unsigned int clk_rate;
166 int bclk_div, mclk_div;
167 int ret, i;
168
169 switch (rate) {
170 case 176400:
171 case 88200:
172 case 44100:
173 case 22050:
174 case 11025:
175 clk_rate = 22579200;
176 break;
177
178 case 192000:
179 case 128000:
180 case 96000:
181 case 64000:
182 case 48000:
183 case 32000:
184 case 24000:
185 case 16000:
186 case 12000:
187 case 8000:
188 clk_rate = 24576000;
189 break;
190
191 default:
192 return -EINVAL;
193 }
194
195 ret = clk_set_rate(i2s->mod_clk, clk_rate);
196 if (ret)
197 return ret;
198
199 /* Always favor the highest oversampling rate */
200 for (i = (ARRAY_SIZE(sun4i_i2s_oversample_rates) - 1); i >= 0; i--) {
201 unsigned int oversample_rate = sun4i_i2s_oversample_rates[i];
202
203 bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
204 word_size);
205 mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
206 clk_rate,
207 rate);
208
209 if ((bclk_div >= 0) && (mclk_div >= 0))
210 break;
211 }
212
213 if ((bclk_div < 0) || (mclk_div < 0))
214 return -EINVAL;
215
216 regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
217 SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
218 SUN4I_I2S_CLK_DIV_MCLK(mclk_div) |
219 SUN4I_I2S_CLK_DIV_MCLK_EN);
220
221 return 0;
222}
223
224static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
225 struct snd_pcm_hw_params *params,
226 struct snd_soc_dai *dai)
227{
228 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
229 int sr, wss;
230 u32 width;
231
232 if (params_channels(params) != 2)
233 return -EINVAL;
234
235 switch (params_physical_width(params)) {
236 case 16:
237 width = DMA_SLAVE_BUSWIDTH_2_BYTES;
238 break;
239 default:
240 return -EINVAL;
241 }
242 i2s->playback_dma_data.addr_width = width;
243
244 switch (params_width(params)) {
245 case 16:
246 sr = 0;
247 wss = 0;
248 break;
249
250 default:
251 return -EINVAL;
252 }
253
254 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
255 SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK,
256 SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr));
257
258 return sun4i_i2s_set_clk_rate(i2s, params_rate(params),
259 params_width(params));
260}
261
262static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
263{
264 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
265 u32 val;
266
267 /* DAI Mode */
268 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
269 case SND_SOC_DAIFMT_I2S:
270 val = SUN4I_I2S_FMT0_FMT_I2S;
271 break;
272 case SND_SOC_DAIFMT_LEFT_J:
273 val = SUN4I_I2S_FMT0_FMT_LEFT_J;
274 break;
275 case SND_SOC_DAIFMT_RIGHT_J:
276 val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
277 break;
278 default:
279 return -EINVAL;
280 }
281
282 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
283 SUN4I_I2S_FMT0_FMT_MASK,
284 val);
285
286 /* DAI clock polarity */
287 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
288 case SND_SOC_DAIFMT_IB_IF:
289 /* Invert both clocks */
290 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
291 SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
292 break;
293 case SND_SOC_DAIFMT_IB_NF:
294 /* Invert bit clock */
295 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
296 SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
297 break;
298 case SND_SOC_DAIFMT_NB_IF:
299 /* Invert frame clock */
300 val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED |
301 SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL;
302 break;
303 case SND_SOC_DAIFMT_NB_NF:
304 /* Nothing to do for both normal cases */
305 val = SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL |
306 SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
307 break;
308 default:
309 return -EINVAL;
310 }
311
312 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
313 SUN4I_I2S_FMT0_BCLK_POLARITY_MASK |
314 SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK,
315 val);
316
317 /* DAI clock master masks */
318 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
319 case SND_SOC_DAIFMT_CBS_CFS:
320 /* BCLK and LRCLK master */
321 val = SUN4I_I2S_CTRL_MODE_MASTER;
322 break;
323 case SND_SOC_DAIFMT_CBM_CFM:
324 /* BCLK and LRCLK slave */
325 val = SUN4I_I2S_CTRL_MODE_SLAVE;
326 break;
327 default:
328 return -EINVAL;
329 }
330
331 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
332 SUN4I_I2S_CTRL_MODE_MASK,
333 val);
334
335 /* Set significant bits in our FIFOs */
336 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
337 SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
338 SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
339 SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
340 SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
341 return 0;
342}
343
344static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
345{
346 /* Flush TX FIFO */
347 regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
348 SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
349 SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
350
351 /* Clear TX counter */
352 regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
353
354 /* Enable TX Block */
355 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
356 SUN4I_I2S_CTRL_TX_EN,
357 SUN4I_I2S_CTRL_TX_EN);
358
359 /* Enable TX DRQ */
360 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
361 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
362 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
363}
364
365
366static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
367{
368 /* Disable TX Block */
369 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
370 SUN4I_I2S_CTRL_TX_EN,
371 0);
372
373 /* Disable TX DRQ */
374 regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
375 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
376 0);
377}
378
379static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
380 struct snd_soc_dai *dai)
381{
382 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
383
384 switch (cmd) {
385 case SNDRV_PCM_TRIGGER_START:
386 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
387 case SNDRV_PCM_TRIGGER_RESUME:
388 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
389 sun4i_i2s_start_playback(i2s);
390 else
391 return -EINVAL;
392 break;
393
394 case SNDRV_PCM_TRIGGER_STOP:
395 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
396 case SNDRV_PCM_TRIGGER_SUSPEND:
397 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
398 sun4i_i2s_stop_playback(i2s);
399 else
400 return -EINVAL;
401 break;
402
403 default:
404 return -EINVAL;
405 }
406
407 return 0;
408}
409
410static int sun4i_i2s_startup(struct snd_pcm_substream *substream,
411 struct snd_soc_dai *dai)
412{
413 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
414
415 /* Enable the whole hardware block */
416 regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG,
417 SUN4I_I2S_CTRL_GL_EN);
418
419 /* Enable the first output line */
420 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
421 SUN4I_I2S_CTRL_SDO_EN_MASK,
422 SUN4I_I2S_CTRL_SDO_EN(0));
423
424 /* Enable the first two channels */
425 regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
426 SUN4I_I2S_TX_CHAN_SEL(2));
427
428 /* Map them to the two first samples coming in */
429 regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG,
430 SUN4I_I2S_TX_CHAN_MAP(0, 0) | SUN4I_I2S_TX_CHAN_MAP(1, 1));
431
432 return clk_prepare_enable(i2s->mod_clk);
433}
434
435static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream,
436 struct snd_soc_dai *dai)
437{
438 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
439
440 clk_disable_unprepare(i2s->mod_clk);
441
442 /* Disable our output lines */
443 regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
444 SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
445
446 /* Disable the whole hardware block */
447 regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 0);
448}
449
450static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
451 .hw_params = sun4i_i2s_hw_params,
452 .set_fmt = sun4i_i2s_set_fmt,
453 .shutdown = sun4i_i2s_shutdown,
454 .startup = sun4i_i2s_startup,
455 .trigger = sun4i_i2s_trigger,
456};
457
458static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
459{
460 struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
461
462 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, NULL);
463
464 snd_soc_dai_set_drvdata(dai, i2s);
465
466 return 0;
467}
468
469static struct snd_soc_dai_driver sun4i_i2s_dai = {
470 .probe = sun4i_i2s_dai_probe,
471 .playback = {
472 .stream_name = "Playback",
473 .channels_min = 2,
474 .channels_max = 2,
475 .rates = SNDRV_PCM_RATE_8000_192000,
476 .formats = SNDRV_PCM_FMTBIT_S16_LE,
477 },
478 .ops = &sun4i_i2s_dai_ops,
479 .symmetric_rates = 1,
480};
481
482static const struct snd_soc_component_driver sun4i_i2s_component = {
483 .name = "sun4i-dai",
484};
485
486static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
487{
488 switch (reg) {
489 case SUN4I_I2S_FIFO_TX_REG:
490 return false;
491
492 default:
493 return true;
494 }
495}
496
497static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
498{
499 switch (reg) {
500 case SUN4I_I2S_FIFO_RX_REG:
501 case SUN4I_I2S_FIFO_STA_REG:
502 return false;
503
504 default:
505 return true;
506 }
507}
508
509static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
510{
511 switch (reg) {
512 case SUN4I_I2S_FIFO_RX_REG:
513 case SUN4I_I2S_INT_STA_REG:
514 case SUN4I_I2S_RX_CNT_REG:
515 case SUN4I_I2S_TX_CNT_REG:
516 return true;
517
518 default:
519 return false;
520 }
521}
522
523static const struct reg_default sun4i_i2s_reg_defaults[] = {
524 { SUN4I_I2S_CTRL_REG, 0x00000000 },
525 { SUN4I_I2S_FMT0_REG, 0x0000000c },
526 { SUN4I_I2S_FMT1_REG, 0x00004020 },
527 { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
528 { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
529 { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
530 { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
531 { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
532 { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
533 { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
534};
535
536static const struct regmap_config sun4i_i2s_regmap_config = {
537 .reg_bits = 32,
538 .reg_stride = 4,
539 .val_bits = 32,
540 .max_register = SUN4I_I2S_RX_CHAN_MAP_REG,
541
542 .cache_type = REGCACHE_FLAT,
543 .reg_defaults = sun4i_i2s_reg_defaults,
544 .num_reg_defaults = ARRAY_SIZE(sun4i_i2s_reg_defaults),
545 .writeable_reg = sun4i_i2s_wr_reg,
546 .readable_reg = sun4i_i2s_rd_reg,
547 .volatile_reg = sun4i_i2s_volatile_reg,
548};
549
550static int sun4i_i2s_runtime_resume(struct device *dev)
551{
552 struct sun4i_i2s *i2s = dev_get_drvdata(dev);
553 int ret;
554
555 ret = clk_prepare_enable(i2s->bus_clk);
556 if (ret) {
557 dev_err(dev, "Failed to enable bus clock\n");
558 return ret;
559 }
560
561 regcache_cache_only(i2s->regmap, false);
562 regcache_mark_dirty(i2s->regmap);
563
564 ret = regcache_sync(i2s->regmap);
565 if (ret) {
566 dev_err(dev, "Failed to sync regmap cache\n");
567 goto err_disable_clk;
568 }
569
570 return 0;
571
572err_disable_clk:
573 clk_disable_unprepare(i2s->bus_clk);
574 return ret;
575}
576
577static int sun4i_i2s_runtime_suspend(struct device *dev)
578{
579 struct sun4i_i2s *i2s = dev_get_drvdata(dev);
580
581 regcache_cache_only(i2s->regmap, true);
582
583 clk_disable_unprepare(i2s->bus_clk);
584
585 return 0;
586}
587
588static int sun4i_i2s_probe(struct platform_device *pdev)
589{
590 struct sun4i_i2s *i2s;
591 struct resource *res;
592 void __iomem *regs;
593 int irq, ret;
594
595 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
596 if (!i2s)
597 return -ENOMEM;
598 platform_set_drvdata(pdev, i2s);
599
600 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
601 regs = devm_ioremap_resource(&pdev->dev, res);
602 if (IS_ERR(regs))
603 return PTR_ERR(regs);
604
605 irq = platform_get_irq(pdev, 0);
606 if (irq < 0) {
607 dev_err(&pdev->dev, "Can't retrieve our interrupt\n");
608 return irq;
609 }
610
611 i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
612 if (IS_ERR(i2s->bus_clk)) {
613 dev_err(&pdev->dev, "Can't get our bus clock\n");
614 return PTR_ERR(i2s->bus_clk);
615 }
616
617 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
618 &sun4i_i2s_regmap_config);
619 if (IS_ERR(i2s->regmap)) {
620 dev_err(&pdev->dev, "Regmap initialisation failed\n");
621 return PTR_ERR(i2s->regmap);
622 }
623
624 i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
625 if (IS_ERR(i2s->mod_clk)) {
626 dev_err(&pdev->dev, "Can't get our mod clock\n");
627 return PTR_ERR(i2s->mod_clk);
628 }
629
630 i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
631 i2s->playback_dma_data.maxburst = 4;
632
633 pm_runtime_enable(&pdev->dev);
634 if (!pm_runtime_enabled(&pdev->dev)) {
635 ret = sun4i_i2s_runtime_resume(&pdev->dev);
636 if (ret)
637 goto err_pm_disable;
638 }
639
640 ret = devm_snd_soc_register_component(&pdev->dev,
641 &sun4i_i2s_component,
642 &sun4i_i2s_dai, 1);
643 if (ret) {
644 dev_err(&pdev->dev, "Could not register DAI\n");
645 goto err_suspend;
646 }
647
648 ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
649 if (ret) {
650 dev_err(&pdev->dev, "Could not register PCM\n");
651 goto err_suspend;
652 }
653
654 return 0;
655
656err_suspend:
657 if (!pm_runtime_status_suspended(&pdev->dev))
658 sun4i_i2s_runtime_suspend(&pdev->dev);
659err_pm_disable:
660 pm_runtime_disable(&pdev->dev);
661
662 return ret;
663}
664
665static int sun4i_i2s_remove(struct platform_device *pdev)
666{
667 snd_dmaengine_pcm_unregister(&pdev->dev);
668
669 pm_runtime_disable(&pdev->dev);
670 if (!pm_runtime_status_suspended(&pdev->dev))
671 sun4i_i2s_runtime_suspend(&pdev->dev);
672
673 return 0;
674}
675
676static const struct of_device_id sun4i_i2s_match[] = {
677 { .compatible = "allwinner,sun4i-a10-i2s", },
678 {}
679};
680MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
681
682static const struct dev_pm_ops sun4i_i2s_pm_ops = {
683 .runtime_resume = sun4i_i2s_runtime_resume,
684 .runtime_suspend = sun4i_i2s_runtime_suspend,
685};
686
687static struct platform_driver sun4i_i2s_driver = {
688 .probe = sun4i_i2s_probe,
689 .remove = sun4i_i2s_remove,
690 .driver = {
691 .name = "sun4i-i2s",
692 .of_match_table = sun4i_i2s_match,
693 .pm = &sun4i_i2s_pm_ops,
694 },
695};
696module_platform_driver(sun4i_i2s_driver);
697
698MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
699MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
700MODULE_DESCRIPTION("Allwinner A10 I2S driver");
701MODULE_LICENSE("GPL");