aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/max98357a.c138
-rw-r--r--sound/soc/codecs/rt5645.c239
-rw-r--r--sound/soc/codecs/rt5645.h87
-rw-r--r--sound/soc/codecs/rt5670.c83
-rw-r--r--sound/soc/codecs/rt5670.h80
-rw-r--r--sound/soc/fsl/fsl_spdif.c15
-rw-r--r--sound/soc/fsl/fsl_ssi.c2
-rw-r--r--sound/soc/fsl/imx-spdif.c1
-rw-r--r--sound/soc/intel/Kconfig11
-rw-r--r--sound/soc/intel/Makefile2
-rw-r--r--sound/soc/intel/broadwell.c10
-rw-r--r--sound/soc/intel/byt-rt5640.c12
-rw-r--r--sound/soc/intel/cht_bsw_rt5645.c326
-rw-r--r--sound/soc/intel/cht_bsw_rt5672.c14
-rw-r--r--sound/soc/intel/sst-baytrail-pcm.c6
-rw-r--r--sound/soc/intel/sst-dsp.c3
-rw-r--r--sound/soc/intel/sst-firmware.c2
-rw-r--r--sound/soc/intel/sst-haswell-dsp.c17
-rw-r--r--sound/soc/intel/sst-haswell-ipc.c173
-rw-r--r--sound/soc/intel/sst-haswell-ipc.h31
-rw-r--r--sound/soc/intel/sst-haswell-pcm.c167
-rw-r--r--sound/soc/intel/sst-mfld-platform-pcm.c7
-rw-r--r--sound/soc/intel/sst/sst_acpi.c2
-rw-r--r--sound/soc/intel/sst/sst_loader.c3
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c21
27 files changed, 1033 insertions, 425 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 8349f982a586..6ecac1e4428e 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -69,6 +69,7 @@ config SND_SOC_ALL_CODECS
69 select SND_SOC_MAX98088 if I2C 69 select SND_SOC_MAX98088 if I2C
70 select SND_SOC_MAX98090 if I2C 70 select SND_SOC_MAX98090 if I2C
71 select SND_SOC_MAX98095 if I2C 71 select SND_SOC_MAX98095 if I2C
72 select SND_SOC_MAX98357A
72 select SND_SOC_MAX9850 if I2C 73 select SND_SOC_MAX9850 if I2C
73 select SND_SOC_MAX9768 if I2C 74 select SND_SOC_MAX9768 if I2C
74 select SND_SOC_MAX9877 if I2C 75 select SND_SOC_MAX9877 if I2C
@@ -456,6 +457,9 @@ config SND_SOC_MAX98090
456config SND_SOC_MAX98095 457config SND_SOC_MAX98095
457 tristate 458 tristate
458 459
460config SND_SOC_MAX98357A
461 tristate
462
459config SND_SOC_MAX9850 463config SND_SOC_MAX9850
460 tristate 464 tristate
461 465
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index bbdfd1e1c182..69b8666d187a 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -64,6 +64,7 @@ snd-soc-max9768-objs := max9768.o
64snd-soc-max98088-objs := max98088.o 64snd-soc-max98088-objs := max98088.o
65snd-soc-max98090-objs := max98090.o 65snd-soc-max98090-objs := max98090.o
66snd-soc-max98095-objs := max98095.o 66snd-soc-max98095-objs := max98095.o
67snd-soc-max98357a-objs := max98357a.o
67snd-soc-max9850-objs := max9850.o 68snd-soc-max9850-objs := max9850.o
68snd-soc-mc13783-objs := mc13783.o 69snd-soc-mc13783-objs := mc13783.o
69snd-soc-ml26124-objs := ml26124.o 70snd-soc-ml26124-objs := ml26124.o
@@ -245,6 +246,7 @@ obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
245obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 246obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
246obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o 247obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o
247obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 248obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
249obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
248obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 250obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
249obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 251obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
250obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 252obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c
new file mode 100644
index 000000000000..1806333ea29e
--- /dev/null
+++ b/sound/soc/codecs/max98357a.c
@@ -0,0 +1,138 @@
1/* Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * max98357a.c -- MAX98357A ALSA SoC Codec driver
13 */
14
15#include <linux/module.h>
16#include <linux/gpio.h>
17#include <sound/soc.h>
18
19#define DRV_NAME "max98357a"
20
21static int max98357a_daiops_trigger(struct snd_pcm_substream *substream,
22 int cmd, struct snd_soc_dai *dai)
23{
24 struct gpio_desc *sdmode = snd_soc_dai_get_drvdata(dai);
25
26 switch (cmd) {
27 case SNDRV_PCM_TRIGGER_START:
28 case SNDRV_PCM_TRIGGER_RESUME:
29 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
30 gpiod_set_value(sdmode, 1);
31 break;
32 case SNDRV_PCM_TRIGGER_STOP:
33 case SNDRV_PCM_TRIGGER_SUSPEND:
34 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
35 gpiod_set_value(sdmode, 0);
36 break;
37 }
38
39 return 0;
40}
41
42static const struct snd_soc_dapm_widget max98357a_dapm_widgets[] = {
43 SND_SOC_DAPM_DAC("SDMode", NULL, SND_SOC_NOPM, 0, 0),
44 SND_SOC_DAPM_OUTPUT("Speaker"),
45};
46
47static const struct snd_soc_dapm_route max98357a_dapm_routes[] = {
48 {"Speaker", NULL, "SDMode"},
49};
50
51static int max98357a_codec_probe(struct snd_soc_codec *codec)
52{
53 struct gpio_desc *sdmode;
54
55 sdmode = devm_gpiod_get(codec->dev, "sdmode");
56 if (IS_ERR(sdmode)) {
57 dev_err(codec->dev, "%s() unable to get sdmode GPIO: %ld\n",
58 __func__, PTR_ERR(sdmode));
59 return PTR_ERR(sdmode);
60 }
61 gpiod_direction_output(sdmode, 0);
62 snd_soc_codec_set_drvdata(codec, sdmode);
63
64 return 0;
65}
66
67static struct snd_soc_codec_driver max98357a_codec_driver = {
68 .probe = max98357a_codec_probe,
69 .dapm_widgets = max98357a_dapm_widgets,
70 .num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets),
71 .dapm_routes = max98357a_dapm_routes,
72 .num_dapm_routes = ARRAY_SIZE(max98357a_dapm_routes),
73};
74
75static struct snd_soc_dai_ops max98357a_dai_ops = {
76 .trigger = max98357a_daiops_trigger,
77};
78
79static struct snd_soc_dai_driver max98357a_dai_driver = {
80 .name = DRV_NAME,
81 .playback = {
82 .stream_name = DRV_NAME "-playback",
83 .formats = SNDRV_PCM_FMTBIT_S16 |
84 SNDRV_PCM_FMTBIT_S24 |
85 SNDRV_PCM_FMTBIT_S32,
86 .rates = SNDRV_PCM_RATE_8000 |
87 SNDRV_PCM_RATE_16000 |
88 SNDRV_PCM_RATE_48000 |
89 SNDRV_PCM_RATE_96000,
90 .rate_min = 8000,
91 .rate_max = 96000,
92 .channels_min = 1,
93 .channels_max = 2,
94 },
95 .ops = &max98357a_dai_ops,
96};
97
98static int max98357a_platform_probe(struct platform_device *pdev)
99{
100 int ret;
101
102 ret = snd_soc_register_codec(&pdev->dev, &max98357a_codec_driver,
103 &max98357a_dai_driver, 1);
104 if (ret)
105 dev_err(&pdev->dev, "%s() error registering codec driver: %d\n",
106 __func__, ret);
107
108 return ret;
109}
110
111static int max98357a_platform_remove(struct platform_device *pdev)
112{
113 snd_soc_unregister_codec(&pdev->dev);
114
115 return 0;
116}
117
118#ifdef CONFIG_OF
119static const struct of_device_id max98357a_device_id[] = {
120 { .compatible = "maxim," DRV_NAME, },
121 {}
122};
123MODULE_DEVICE_TABLE(of, max98357a_device_id);
124#endif
125
126static struct platform_driver max98357a_platform_driver = {
127 .driver = {
128 .name = DRV_NAME,
129 .of_match_table = of_match_ptr(max98357a_device_id),
130 },
131 .probe = max98357a_platform_probe,
132 .remove = max98357a_platform_remove,
133};
134module_platform_driver(max98357a_platform_driver);
135
136MODULE_DESCRIPTION("Maxim MAX98357A Codec Driver");
137MODULE_LICENSE("GPL v2");
138MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 068dfd5c7640..c9a4c5be083b 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -31,6 +31,7 @@
31#include "rt5645.h" 31#include "rt5645.h"
32 32
33#define RT5645_DEVICE_ID 0x6308 33#define RT5645_DEVICE_ID 0x6308
34#define RT5650_DEVICE_ID 0x6419
34 35
35#define RT5645_PR_RANGE_BASE (0xff + 1) 36#define RT5645_PR_RANGE_BASE (0xff + 1)
36#define RT5645_PR_SPACING 0x100 37#define RT5645_PR_SPACING 0x100
@@ -59,6 +60,10 @@ static const struct reg_default init_list[] = {
59}; 60};
60#define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list) 61#define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list)
61 62
63static const struct reg_default rt5650_init_list[] = {
64 {0xf6, 0x0100},
65};
66
62static const struct reg_default rt5645_reg[] = { 67static const struct reg_default rt5645_reg[] = {
63 { 0x00, 0x0000 }, 68 { 0x00, 0x0000 },
64 { 0x01, 0xc8c8 }, 69 { 0x01, 0xc8c8 },
@@ -86,6 +91,7 @@ static const struct reg_default rt5645_reg[] = {
86 { 0x2a, 0x5656 }, 91 { 0x2a, 0x5656 },
87 { 0x2b, 0x5454 }, 92 { 0x2b, 0x5454 },
88 { 0x2c, 0xaaa0 }, 93 { 0x2c, 0xaaa0 },
94 { 0x2d, 0x0000 },
89 { 0x2f, 0x1002 }, 95 { 0x2f, 0x1002 },
90 { 0x31, 0x5000 }, 96 { 0x31, 0x5000 },
91 { 0x32, 0x0000 }, 97 { 0x32, 0x0000 },
@@ -193,6 +199,8 @@ static const struct reg_default rt5645_reg[] = {
193 { 0xdb, 0x0003 }, 199 { 0xdb, 0x0003 },
194 { 0xdc, 0x0049 }, 200 { 0xdc, 0x0049 },
195 { 0xdd, 0x001b }, 201 { 0xdd, 0x001b },
202 { 0xdf, 0x0008 },
203 { 0xe0, 0x4000 },
196 { 0xe6, 0x8000 }, 204 { 0xe6, 0x8000 },
197 { 0xe7, 0x0200 }, 205 { 0xe7, 0x0200 },
198 { 0xec, 0xb300 }, 206 { 0xec, 0xb300 },
@@ -242,6 +250,7 @@ static bool rt5645_volatile_register(struct device *dev, unsigned int reg)
242 case RT5645_IRQ_CTRL3: 250 case RT5645_IRQ_CTRL3:
243 case RT5645_INT_IRQ_ST: 251 case RT5645_INT_IRQ_ST:
244 case RT5645_IL_CMD: 252 case RT5645_IL_CMD:
253 case RT5650_4BTN_IL_CMD1:
245 case RT5645_VENDOR_ID: 254 case RT5645_VENDOR_ID:
246 case RT5645_VENDOR_ID1: 255 case RT5645_VENDOR_ID1:
247 case RT5645_VENDOR_ID2: 256 case RT5645_VENDOR_ID2:
@@ -287,6 +296,7 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg)
287 case RT5645_STO_DAC_MIXER: 296 case RT5645_STO_DAC_MIXER:
288 case RT5645_MONO_DAC_MIXER: 297 case RT5645_MONO_DAC_MIXER:
289 case RT5645_DIG_MIXER: 298 case RT5645_DIG_MIXER:
299 case RT5650_A_DAC_SOUR:
290 case RT5645_DIG_INF1_DATA: 300 case RT5645_DIG_INF1_DATA:
291 case RT5645_PDM_OUT_CTRL: 301 case RT5645_PDM_OUT_CTRL:
292 case RT5645_REC_L1_MIXER: 302 case RT5645_REC_L1_MIXER:
@@ -378,6 +388,8 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg)
378 case RT5645_IL_CMD: 388 case RT5645_IL_CMD:
379 case RT5645_IL_CMD2: 389 case RT5645_IL_CMD2:
380 case RT5645_IL_CMD3: 390 case RT5645_IL_CMD3:
391 case RT5650_4BTN_IL_CMD1:
392 case RT5650_4BTN_IL_CMD2:
381 case RT5645_DRC1_HL_CTRL1: 393 case RT5645_DRC1_HL_CTRL1:
382 case RT5645_DRC2_HL_CTRL1: 394 case RT5645_DRC2_HL_CTRL1:
383 case RT5645_ADC_MONO_HP_CTRL1: 395 case RT5645_ADC_MONO_HP_CTRL1:
@@ -603,6 +615,87 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
603 615
604} 616}
605 617
618/**
619 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
620 * @codec: SoC audio codec device.
621 * @filter_mask: mask of filters.
622 * @clk_src: clock source
623 *
624 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5645 can
625 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
626 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
627 * ASRC function will track i2s clock and generate a corresponding system clock
628 * for codec. This function provides an API to select the clock source for a
629 * set of filters specified by the mask. And the codec driver will turn on ASRC
630 * for these filters if ASRC is selected as their clock source.
631 */
632int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
633 unsigned int filter_mask, unsigned int clk_src)
634{
635 unsigned int asrc2_mask = 0;
636 unsigned int asrc2_value = 0;
637 unsigned int asrc3_mask = 0;
638 unsigned int asrc3_value = 0;
639
640 switch (clk_src) {
641 case RT5645_CLK_SEL_SYS:
642 case RT5645_CLK_SEL_I2S1_ASRC:
643 case RT5645_CLK_SEL_I2S2_ASRC:
644 case RT5645_CLK_SEL_SYS2:
645 break;
646
647 default:
648 return -EINVAL;
649 }
650
651 if (filter_mask & RT5645_DA_STEREO_FILTER) {
652 asrc2_mask |= RT5645_DA_STO_CLK_SEL_MASK;
653 asrc2_value = (asrc2_value & ~RT5645_DA_STO_CLK_SEL_MASK)
654 | (clk_src << RT5645_DA_STO_CLK_SEL_SFT);
655 }
656
657 if (filter_mask & RT5645_DA_MONO_L_FILTER) {
658 asrc2_mask |= RT5645_DA_MONOL_CLK_SEL_MASK;
659 asrc2_value = (asrc2_value & ~RT5645_DA_MONOL_CLK_SEL_MASK)
660 | (clk_src << RT5645_DA_MONOL_CLK_SEL_SFT);
661 }
662
663 if (filter_mask & RT5645_DA_MONO_R_FILTER) {
664 asrc2_mask |= RT5645_DA_MONOR_CLK_SEL_MASK;
665 asrc2_value = (asrc2_value & ~RT5645_DA_MONOR_CLK_SEL_MASK)
666 | (clk_src << RT5645_DA_MONOR_CLK_SEL_SFT);
667 }
668
669 if (filter_mask & RT5645_AD_STEREO_FILTER) {
670 asrc2_mask |= RT5645_AD_STO1_CLK_SEL_MASK;
671 asrc2_value = (asrc2_value & ~RT5645_AD_STO1_CLK_SEL_MASK)
672 | (clk_src << RT5645_AD_STO1_CLK_SEL_SFT);
673 }
674
675 if (filter_mask & RT5645_AD_MONO_L_FILTER) {
676 asrc3_mask |= RT5645_AD_MONOL_CLK_SEL_MASK;
677 asrc3_value = (asrc3_value & ~RT5645_AD_MONOL_CLK_SEL_MASK)
678 | (clk_src << RT5645_AD_MONOL_CLK_SEL_SFT);
679 }
680
681 if (filter_mask & RT5645_AD_MONO_R_FILTER) {
682 asrc3_mask |= RT5645_AD_MONOR_CLK_SEL_MASK;
683 asrc3_value = (asrc3_value & ~RT5645_AD_MONOR_CLK_SEL_MASK)
684 | (clk_src << RT5645_AD_MONOR_CLK_SEL_SFT);
685 }
686
687 if (asrc2_mask)
688 snd_soc_update_bits(codec, RT5645_ASRC_2,
689 asrc2_mask, asrc2_value);
690
691 if (asrc3_mask)
692 snd_soc_update_bits(codec, RT5645_ASRC_3,
693 asrc3_mask, asrc3_value);
694
695 return 0;
696}
697EXPORT_SYMBOL_GPL(rt5645_sel_asrc_clk_src);
698
606/* Digital Mixer */ 699/* Digital Mixer */
607static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { 700static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = {
608 SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, 701 SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER,
@@ -1009,6 +1102,44 @@ static SOC_ENUM_SINGLE_DECL(
1009static const struct snd_kcontrol_new rt5645_if1_adc_in_mux = 1102static const struct snd_kcontrol_new rt5645_if1_adc_in_mux =
1010 SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum); 1103 SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum);
1011 1104
1105/* MX-2d [3] [2] */
1106static const char * const rt5650_a_dac1_src[] = {
1107 "DAC1", "Stereo DAC Mixer"
1108};
1109
1110static SOC_ENUM_SINGLE_DECL(
1111 rt5650_a_dac1_l_enum, RT5650_A_DAC_SOUR,
1112 RT5650_A_DAC1_L_IN_SFT, rt5650_a_dac1_src);
1113
1114static const struct snd_kcontrol_new rt5650_a_dac1_l_mux =
1115 SOC_DAPM_ENUM("A DAC1 L source", rt5650_a_dac1_l_enum);
1116
1117static SOC_ENUM_SINGLE_DECL(
1118 rt5650_a_dac1_r_enum, RT5650_A_DAC_SOUR,
1119 RT5650_A_DAC1_R_IN_SFT, rt5650_a_dac1_src);
1120
1121static const struct snd_kcontrol_new rt5650_a_dac1_r_mux =
1122 SOC_DAPM_ENUM("A DAC1 R source", rt5650_a_dac1_r_enum);
1123
1124/* MX-2d [1] [0] */
1125static const char * const rt5650_a_dac2_src[] = {
1126 "Stereo DAC Mixer", "Mono DAC Mixer"
1127};
1128
1129static SOC_ENUM_SINGLE_DECL(
1130 rt5650_a_dac2_l_enum, RT5650_A_DAC_SOUR,
1131 RT5650_A_DAC2_L_IN_SFT, rt5650_a_dac2_src);
1132
1133static const struct snd_kcontrol_new rt5650_a_dac2_l_mux =
1134 SOC_DAPM_ENUM("A DAC2 L source", rt5650_a_dac2_l_enum);
1135
1136static SOC_ENUM_SINGLE_DECL(
1137 rt5650_a_dac2_r_enum, RT5650_A_DAC_SOUR,
1138 RT5650_A_DAC2_R_IN_SFT, rt5650_a_dac2_src);
1139
1140static const struct snd_kcontrol_new rt5650_a_dac2_r_mux =
1141 SOC_DAPM_ENUM("A DAC2 R source", rt5650_a_dac2_r_enum);
1142
1012/* MX-2F [13:12] */ 1143/* MX-2F [13:12] */
1013static const char * const rt5645_if2_adc_in_src[] = { 1144static const char * const rt5645_if2_adc_in_src[] = {
1014 "IF_ADC1", "IF_ADC2", "VAD_ADC" 1145 "IF_ADC1", "IF_ADC2", "VAD_ADC"
@@ -1153,11 +1284,16 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
1153 case SND_SOC_DAPM_POST_PMU: 1284 case SND_SOC_DAPM_POST_PMU:
1154 hp_amp_power(codec, 1); 1285 hp_amp_power(codec, 1);
1155 /* headphone unmute sequence */ 1286 /* headphone unmute sequence */
1156 snd_soc_update_bits(codec, RT5645_DEPOP_M3, RT5645_CP_FQ1_MASK | 1287 if (rt5645->codec_type == CODEC_TYPE_RT5650) {
1157 RT5645_CP_FQ2_MASK | RT5645_CP_FQ3_MASK, 1288 snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
1158 (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) | 1289 } else {
1159 (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | 1290 snd_soc_update_bits(codec, RT5645_DEPOP_M3,
1160 (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT)); 1291 RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
1292 RT5645_CP_FQ3_MASK,
1293 (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) |
1294 (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
1295 (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT));
1296 }
1161 regmap_write(rt5645->regmap, 1297 regmap_write(rt5645->regmap,
1162 RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); 1298 RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00);
1163 snd_soc_update_bits(codec, RT5645_DEPOP_M1, 1299 snd_soc_update_bits(codec, RT5645_DEPOP_M1,
@@ -1177,12 +1313,16 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
1177 1313
1178 case SND_SOC_DAPM_PRE_PMD: 1314 case SND_SOC_DAPM_PRE_PMD:
1179 /* headphone mute sequence */ 1315 /* headphone mute sequence */
1180 snd_soc_update_bits(codec, RT5645_DEPOP_M3, 1316 if (rt5645->codec_type == CODEC_TYPE_RT5650) {
1181 RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | 1317 snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
1182 RT5645_CP_FQ3_MASK, 1318 } else {
1183 (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) | 1319 snd_soc_update_bits(codec, RT5645_DEPOP_M3,
1184 (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | 1320 RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
1185 (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT)); 1321 RT5645_CP_FQ3_MASK,
1322 (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) |
1323 (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
1324 (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT));
1325 }
1186 regmap_write(rt5645->regmap, 1326 regmap_write(rt5645->regmap,
1187 RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); 1327 RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00);
1188 snd_soc_update_bits(codec, RT5645_DEPOP_M1, 1328 snd_soc_update_bits(codec, RT5645_DEPOP_M1,
@@ -1576,6 +1716,17 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
1576 SND_SOC_DAPM_OUTPUT("SPOR"), 1716 SND_SOC_DAPM_OUTPUT("SPOR"),
1577}; 1717};
1578 1718
1719static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = {
1720 SND_SOC_DAPM_MUX("A DAC1 L Mux", SND_SOC_NOPM,
1721 0, 0, &rt5650_a_dac1_l_mux),
1722 SND_SOC_DAPM_MUX("A DAC1 R Mux", SND_SOC_NOPM,
1723 0, 0, &rt5650_a_dac1_r_mux),
1724 SND_SOC_DAPM_MUX("A DAC2 L Mux", SND_SOC_NOPM,
1725 0, 0, &rt5650_a_dac2_l_mux),
1726 SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM,
1727 0, 0, &rt5650_a_dac2_r_mux),
1728};
1729
1579static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { 1730static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
1580 { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, 1731 { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc },
1581 { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc }, 1732 { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc },
@@ -1781,13 +1932,9 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
1781 { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" }, 1932 { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
1782 { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" }, 1933 { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
1783 1934
1784 { "DAC L1", NULL, "Stereo DAC MIXL" },
1785 { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll }, 1935 { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll },
1786 { "DAC R1", NULL, "Stereo DAC MIXR" },
1787 { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll }, 1936 { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll },
1788 { "DAC L2", NULL, "Mono DAC MIXL" },
1789 { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll }, 1937 { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll },
1790 { "DAC R2", NULL, "Mono DAC MIXR" },
1791 { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll }, 1938 { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll },
1792 1939
1793 { "SPK MIXL", "BST1 Switch", "BST1" }, 1940 { "SPK MIXL", "BST1 Switch", "BST1" },
@@ -1876,6 +2023,30 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
1876 { "SPOR", NULL, "SPK amp" }, 2023 { "SPOR", NULL, "SPK amp" },
1877}; 2024};
1878 2025
2026static const struct snd_soc_dapm_route rt5650_specific_dapm_routes[] = {
2027 { "A DAC1 L Mux", "DAC1", "DAC1 MIXL"},
2028 { "A DAC1 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"},
2029 { "A DAC1 R Mux", "DAC1", "DAC1 MIXR"},
2030 { "A DAC1 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"},
2031
2032 { "A DAC2 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"},
2033 { "A DAC2 L Mux", "Mono DAC Mixer", "Mono DAC MIXL"},
2034 { "A DAC2 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"},
2035 { "A DAC2 R Mux", "Mono DAC Mixer", "Mono DAC MIXR"},
2036
2037 { "DAC L1", NULL, "A DAC1 L Mux" },
2038 { "DAC R1", NULL, "A DAC1 R Mux" },
2039 { "DAC L2", NULL, "A DAC2 L Mux" },
2040 { "DAC R2", NULL, "A DAC2 R Mux" },
2041};
2042
2043static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = {
2044 { "DAC L1", NULL, "Stereo DAC MIXL" },
2045 { "DAC R1", NULL, "Stereo DAC MIXR" },
2046 { "DAC L2", NULL, "Mono DAC MIXL" },
2047 { "DAC R2", NULL, "Mono DAC MIXR" },
2048};
2049
1879static int rt5645_hw_params(struct snd_pcm_substream *substream, 2050static int rt5645_hw_params(struct snd_pcm_substream *substream,
1880 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 2051 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1881{ 2052{
@@ -2295,6 +2466,22 @@ static int rt5645_probe(struct snd_soc_codec *codec)
2295 2466
2296 rt5645->codec = codec; 2467 rt5645->codec = codec;
2297 2468
2469 switch (rt5645->codec_type) {
2470 case CODEC_TYPE_RT5645:
2471 snd_soc_dapm_add_routes(&codec->dapm,
2472 rt5645_specific_dapm_routes,
2473 ARRAY_SIZE(rt5645_specific_dapm_routes));
2474 break;
2475 case CODEC_TYPE_RT5650:
2476 snd_soc_dapm_new_controls(&codec->dapm,
2477 rt5650_specific_dapm_widgets,
2478 ARRAY_SIZE(rt5650_specific_dapm_widgets));
2479 snd_soc_dapm_add_routes(&codec->dapm,
2480 rt5650_specific_dapm_routes,
2481 ARRAY_SIZE(rt5650_specific_dapm_routes));
2482 break;
2483 }
2484
2298 rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF); 2485 rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF);
2299 2486
2300 snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); 2487 snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200);
@@ -2426,6 +2613,7 @@ static const struct regmap_config rt5645_regmap = {
2426 2613
2427static const struct i2c_device_id rt5645_i2c_id[] = { 2614static const struct i2c_device_id rt5645_i2c_id[] = {
2428 { "rt5645", 0 }, 2615 { "rt5645", 0 },
2616 { "rt5650", 0 },
2429 { } 2617 { }
2430}; 2618};
2431MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); 2619MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
@@ -2458,9 +2646,18 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
2458 } 2646 }
2459 2647
2460 regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); 2648 regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val);
2461 if (val != RT5645_DEVICE_ID) { 2649
2650 switch (val) {
2651 case RT5645_DEVICE_ID:
2652 rt5645->codec_type = CODEC_TYPE_RT5645;
2653 break;
2654 case RT5650_DEVICE_ID:
2655 rt5645->codec_type = CODEC_TYPE_RT5650;
2656 break;
2657 default:
2462 dev_err(&i2c->dev, 2658 dev_err(&i2c->dev,
2463 "Device with ID register %x is not rt5645\n", val); 2659 "Device with ID register %x is not rt5645 or rt5650\n",
2660 val);
2464 return -ENODEV; 2661 return -ENODEV;
2465 } 2662 }
2466 2663
@@ -2471,6 +2668,14 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
2471 if (ret != 0) 2668 if (ret != 0)
2472 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); 2669 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
2473 2670
2671 if (rt5645->codec_type == CODEC_TYPE_RT5650) {
2672 ret = regmap_register_patch(rt5645->regmap, rt5650_init_list,
2673 ARRAY_SIZE(rt5650_init_list));
2674 if (ret != 0)
2675 dev_warn(&i2c->dev, "Apply rt5650 patch failed: %d\n",
2676 ret);
2677 }
2678
2474 if (rt5645->pdata.in2_diff) 2679 if (rt5645->pdata.in2_diff)
2475 regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL, 2680 regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL,
2476 RT5645_IN_DF2, RT5645_IN_DF2); 2681 RT5645_IN_DF2, RT5645_IN_DF2);
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index a815e36a2bdb..dbfd98c22f4d 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -47,6 +47,7 @@
47#define RT5645_STO_DAC_MIXER 0x2a 47#define RT5645_STO_DAC_MIXER 0x2a
48#define RT5645_MONO_DAC_MIXER 0x2b 48#define RT5645_MONO_DAC_MIXER 0x2b
49#define RT5645_DIG_MIXER 0x2c 49#define RT5645_DIG_MIXER 0x2c
50#define RT5650_A_DAC_SOUR 0x2d
50#define RT5645_DIG_INF1_DATA 0x2f 51#define RT5645_DIG_INF1_DATA 0x2f
51/* Mixer - PDM */ 52/* Mixer - PDM */
52#define RT5645_PDM_OUT_CTRL 0x31 53#define RT5645_PDM_OUT_CTRL 0x31
@@ -150,6 +151,8 @@
150#define RT5645_IL_CMD 0xdb 151#define RT5645_IL_CMD 0xdb
151#define RT5645_IL_CMD2 0xdc 152#define RT5645_IL_CMD2 0xdc
152#define RT5645_IL_CMD3 0xdd 153#define RT5645_IL_CMD3 0xdd
154#define RT5650_4BTN_IL_CMD1 0xdf
155#define RT5650_4BTN_IL_CMD2 0xe0
153#define RT5645_DRC1_HL_CTRL1 0xe7 156#define RT5645_DRC1_HL_CTRL1 0xe7
154#define RT5645_DRC2_HL_CTRL1 0xe9 157#define RT5645_DRC2_HL_CTRL1 0xe9
155#define RT5645_MUTI_DRC_CTRL1 0xea 158#define RT5645_MUTI_DRC_CTRL1 0xea
@@ -472,6 +475,12 @@
472#define RT5645_DAC_L2_DAC_R_VOL_MASK (0x1 << 4) 475#define RT5645_DAC_L2_DAC_R_VOL_MASK (0x1 << 4)
473#define RT5645_DAC_L2_DAC_R_VOL_SFT 4 476#define RT5645_DAC_L2_DAC_R_VOL_SFT 4
474 477
478/* Analog DAC1/2 Input Source Control (0x2d) */
479#define RT5650_A_DAC1_L_IN_SFT 3
480#define RT5650_A_DAC1_R_IN_SFT 2
481#define RT5650_A_DAC2_L_IN_SFT 1
482#define RT5650_A_DAC2_R_IN_SFT 0
483
475/* Digital Interface Data Control (0x2f) */ 484/* Digital Interface Data Control (0x2f) */
476#define RT5645_IF1_ADC2_IN_SEL (0x1 << 15) 485#define RT5645_IF1_ADC2_IN_SEL (0x1 << 15)
477#define RT5645_IF1_ADC2_IN_SFT 15 486#define RT5645_IF1_ADC2_IN_SFT 15
@@ -1111,50 +1120,27 @@
1111#define RT5645_DMIC_2_M_NOR (0x0 << 8) 1120#define RT5645_DMIC_2_M_NOR (0x0 << 8)
1112#define RT5645_DMIC_2_M_ASYN (0x1 << 8) 1121#define RT5645_DMIC_2_M_ASYN (0x1 << 8)
1113 1122
1123/* ASRC clock source selection (0x84, 0x85) */
1124#define RT5645_CLK_SEL_SYS (0x0)
1125#define RT5645_CLK_SEL_I2S1_ASRC (0x1)
1126#define RT5645_CLK_SEL_I2S2_ASRC (0x2)
1127#define RT5645_CLK_SEL_SYS2 (0x5)
1128
1114/* ASRC Control 2 (0x84) */ 1129/* ASRC Control 2 (0x84) */
1115#define RT5645_MDA_L_M_MASK (0x1 << 15) 1130#define RT5645_DA_STO_CLK_SEL_MASK (0xf << 12)
1116#define RT5645_MDA_L_M_SFT 15 1131#define RT5645_DA_STO_CLK_SEL_SFT 12
1117#define RT5645_MDA_L_M_NOR (0x0 << 15) 1132#define RT5645_DA_MONOL_CLK_SEL_MASK (0xf << 8)
1118#define RT5645_MDA_L_M_ASYN (0x1 << 15) 1133#define RT5645_DA_MONOL_CLK_SEL_SFT 8
1119#define RT5645_MDA_R_M_MASK (0x1 << 14) 1134#define RT5645_DA_MONOR_CLK_SEL_MASK (0xf << 4)
1120#define RT5645_MDA_R_M_SFT 14 1135#define RT5645_DA_MONOR_CLK_SEL_SFT 4
1121#define RT5645_MDA_R_M_NOR (0x0 << 14) 1136#define RT5645_AD_STO1_CLK_SEL_MASK (0xf << 0)
1122#define RT5645_MDA_R_M_ASYN (0x1 << 14) 1137#define RT5645_AD_STO1_CLK_SEL_SFT 0
1123#define RT5645_MAD_L_M_MASK (0x1 << 13)
1124#define RT5645_MAD_L_M_SFT 13
1125#define RT5645_MAD_L_M_NOR (0x0 << 13)
1126#define RT5645_MAD_L_M_ASYN (0x1 << 13)
1127#define RT5645_MAD_R_M_MASK (0x1 << 12)
1128#define RT5645_MAD_R_M_SFT 12
1129#define RT5645_MAD_R_M_NOR (0x0 << 12)
1130#define RT5645_MAD_R_M_ASYN (0x1 << 12)
1131#define RT5645_ADC_M_MASK (0x1 << 11)
1132#define RT5645_ADC_M_SFT 11
1133#define RT5645_ADC_M_NOR (0x0 << 11)
1134#define RT5645_ADC_M_ASYN (0x1 << 11)
1135#define RT5645_STO_DAC_M_MASK (0x1 << 5)
1136#define RT5645_STO_DAC_M_SFT 5
1137#define RT5645_STO_DAC_M_NOR (0x0 << 5)
1138#define RT5645_STO_DAC_M_ASYN (0x1 << 5)
1139#define RT5645_I2S1_R_D_MASK (0x1 << 4)
1140#define RT5645_I2S1_R_D_SFT 4
1141#define RT5645_I2S1_R_D_DIS (0x0 << 4)
1142#define RT5645_I2S1_R_D_EN (0x1 << 4)
1143#define RT5645_I2S2_R_D_MASK (0x1 << 3)
1144#define RT5645_I2S2_R_D_SFT 3
1145#define RT5645_I2S2_R_D_DIS (0x0 << 3)
1146#define RT5645_I2S2_R_D_EN (0x1 << 3)
1147#define RT5645_PRE_SCLK_MASK (0x3)
1148#define RT5645_PRE_SCLK_SFT 0
1149#define RT5645_PRE_SCLK_512 (0x0)
1150#define RT5645_PRE_SCLK_1024 (0x1)
1151#define RT5645_PRE_SCLK_2048 (0x2)
1152 1138
1153/* ASRC Control 3 (0x85) */ 1139/* ASRC Control 3 (0x85) */
1154#define RT5645_I2S1_RATE_MASK (0xf << 12) 1140#define RT5645_AD_MONOL_CLK_SEL_MASK (0xf << 4)
1155#define RT5645_I2S1_RATE_SFT 12 1141#define RT5645_AD_MONOL_CLK_SEL_SFT 4
1156#define RT5645_I2S2_RATE_MASK (0xf << 8) 1142#define RT5645_AD_MONOR_CLK_SEL_MASK (0xf << 0)
1157#define RT5645_I2S2_RATE_SFT 8 1143#define RT5645_AD_MONOR_CLK_SEL_SFT 0
1158 1144
1159/* ASRC Control 4 (0x89) */ 1145/* ASRC Control 4 (0x89) */
1160#define RT5645_I2S1_PD_MASK (0x7 << 12) 1146#define RT5645_I2S1_PD_MASK (0x7 << 12)
@@ -2175,6 +2161,24 @@ enum {
2175 RT5645_DMIC_DATA_GPIO11, 2161 RT5645_DMIC_DATA_GPIO11,
2176}; 2162};
2177 2163
2164enum {
2165 CODEC_TYPE_RT5645,
2166 CODEC_TYPE_RT5650,
2167};
2168
2169/* filter mask */
2170enum {
2171 RT5645_DA_STEREO_FILTER = 0x1,
2172 RT5645_DA_MONO_L_FILTER = (0x1 << 1),
2173 RT5645_DA_MONO_R_FILTER = (0x1 << 2),
2174 RT5645_AD_STEREO_FILTER = (0x1 << 3),
2175 RT5645_AD_MONO_L_FILTER = (0x1 << 4),
2176 RT5645_AD_MONO_R_FILTER = (0x1 << 5),
2177};
2178
2179int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
2180 unsigned int filter_mask, unsigned int clk_src);
2181
2178struct rt5645_priv { 2182struct rt5645_priv {
2179 struct snd_soc_codec *codec; 2183 struct snd_soc_codec *codec;
2180 struct rt5645_platform_data pdata; 2184 struct rt5645_platform_data pdata;
@@ -2184,6 +2188,7 @@ struct rt5645_priv {
2184 struct snd_soc_jack *mic_jack; 2188 struct snd_soc_jack *mic_jack;
2185 struct delayed_work jack_detect_work; 2189 struct delayed_work jack_detect_work;
2186 2190
2191 int codec_type;
2187 int sysclk; 2192 int sysclk;
2188 int sysclk_src; 2193 int sysclk_src;
2189 int lrck[RT5645_AIFS]; 2194 int lrck[RT5645_AIFS];
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index f5b054de481e..7b3d6b5992f1 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -592,6 +592,89 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
592 return 0; 592 return 0;
593} 593}
594 594
595
596/**
597 * rt5670_sel_asrc_clk_src - select ASRC clock source for a set of filters
598 * @codec: SoC audio codec device.
599 * @filter_mask: mask of filters.
600 * @clk_src: clock source
601 *
602 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5670 can
603 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
604 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
605 * ASRC function will track i2s clock and generate a corresponding system clock
606 * for codec. This function provides an API to select the clock source for a
607 * set of filters specified by the mask. And the codec driver will turn on ASRC
608 * for these filters if ASRC is selected as their clock source.
609 */
610int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
611 unsigned int filter_mask, unsigned int clk_src)
612{
613 unsigned int asrc2_mask = 0, asrc2_value = 0;
614 unsigned int asrc3_mask = 0, asrc3_value = 0;
615
616 if (clk_src > RT5670_CLK_SEL_SYS3)
617 return -EINVAL;
618
619 if (filter_mask & RT5670_DA_STEREO_FILTER) {
620 asrc2_mask |= RT5670_DA_STO_CLK_SEL_MASK;
621 asrc2_value = (asrc2_value & ~RT5670_DA_STO_CLK_SEL_MASK)
622 | (clk_src << RT5670_DA_STO_CLK_SEL_SFT);
623 }
624
625 if (filter_mask & RT5670_DA_MONO_L_FILTER) {
626 asrc2_mask |= RT5670_DA_MONOL_CLK_SEL_MASK;
627 asrc2_value = (asrc2_value & ~RT5670_DA_MONOL_CLK_SEL_MASK)
628 | (clk_src << RT5670_DA_MONOL_CLK_SEL_SFT);
629 }
630
631 if (filter_mask & RT5670_DA_MONO_R_FILTER) {
632 asrc2_mask |= RT5670_DA_MONOR_CLK_SEL_MASK;
633 asrc2_value = (asrc2_value & ~RT5670_DA_MONOR_CLK_SEL_MASK)
634 | (clk_src << RT5670_DA_MONOR_CLK_SEL_SFT);
635 }
636
637 if (filter_mask & RT5670_AD_STEREO_FILTER) {
638 asrc2_mask |= RT5670_AD_STO1_CLK_SEL_MASK;
639 asrc2_value = (asrc2_value & ~RT5670_AD_STO1_CLK_SEL_MASK)
640 | (clk_src << RT5670_AD_STO1_CLK_SEL_SFT);
641 }
642
643 if (filter_mask & RT5670_AD_MONO_L_FILTER) {
644 asrc3_mask |= RT5670_AD_MONOL_CLK_SEL_MASK;
645 asrc3_value = (asrc3_value & ~RT5670_AD_MONOL_CLK_SEL_MASK)
646 | (clk_src << RT5670_AD_MONOL_CLK_SEL_SFT);
647 }
648
649 if (filter_mask & RT5670_AD_MONO_R_FILTER) {
650 asrc3_mask |= RT5670_AD_MONOR_CLK_SEL_MASK;
651 asrc3_value = (asrc3_value & ~RT5670_AD_MONOR_CLK_SEL_MASK)
652 | (clk_src << RT5670_AD_MONOR_CLK_SEL_SFT);
653 }
654
655 if (filter_mask & RT5670_UP_RATE_FILTER) {
656 asrc3_mask |= RT5670_UP_CLK_SEL_MASK;
657 asrc3_value = (asrc3_value & ~RT5670_UP_CLK_SEL_MASK)
658 | (clk_src << RT5670_UP_CLK_SEL_SFT);
659 }
660
661 if (filter_mask & RT5670_DOWN_RATE_FILTER) {
662 asrc3_mask |= RT5670_DOWN_CLK_SEL_MASK;
663 asrc3_value = (asrc3_value & ~RT5670_DOWN_CLK_SEL_MASK)
664 | (clk_src << RT5670_DOWN_CLK_SEL_SFT);
665 }
666
667 if (asrc2_mask)
668 snd_soc_update_bits(codec, RT5670_ASRC_2,
669 asrc2_mask, asrc2_value);
670
671 if (asrc3_mask)
672 snd_soc_update_bits(codec, RT5670_ASRC_3,
673 asrc3_mask, asrc3_value);
674 return 0;
675}
676EXPORT_SYMBOL_GPL(rt5670_sel_asrc_clk_src);
677
595/* Digital Mixer */ 678/* Digital Mixer */
596static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = { 679static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = {
597 SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER, 680 SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
index d11b9c207e26..21f8e18c13c4 100644
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -1023,50 +1023,33 @@
1023#define RT5670_DMIC_2_M_NOR (0x0 << 8) 1023#define RT5670_DMIC_2_M_NOR (0x0 << 8)
1024#define RT5670_DMIC_2_M_ASYN (0x1 << 8) 1024#define RT5670_DMIC_2_M_ASYN (0x1 << 8)
1025 1025
1026/* ASRC clock source selection (0x84, 0x85) */
1027#define RT5670_CLK_SEL_SYS (0x0)
1028#define RT5670_CLK_SEL_I2S1_ASRC (0x1)
1029#define RT5670_CLK_SEL_I2S2_ASRC (0x2)
1030#define RT5670_CLK_SEL_I2S3_ASRC (0x3)
1031#define RT5670_CLK_SEL_SYS2 (0x5)
1032#define RT5670_CLK_SEL_SYS3 (0x6)
1033
1026/* ASRC Control 2 (0x84) */ 1034/* ASRC Control 2 (0x84) */
1027#define RT5670_MDA_L_M_MASK (0x1 << 15) 1035#define RT5670_DA_STO_CLK_SEL_MASK (0xf << 12)
1028#define RT5670_MDA_L_M_SFT 15 1036#define RT5670_DA_STO_CLK_SEL_SFT 12
1029#define RT5670_MDA_L_M_NOR (0x0 << 15) 1037#define RT5670_DA_MONOL_CLK_SEL_MASK (0xf << 8)
1030#define RT5670_MDA_L_M_ASYN (0x1 << 15) 1038#define RT5670_DA_MONOL_CLK_SEL_SFT 8
1031#define RT5670_MDA_R_M_MASK (0x1 << 14) 1039#define RT5670_DA_MONOR_CLK_SEL_MASK (0xf << 4)
1032#define RT5670_MDA_R_M_SFT 14 1040#define RT5670_DA_MONOR_CLK_SEL_SFT 4
1033#define RT5670_MDA_R_M_NOR (0x0 << 14) 1041#define RT5670_AD_STO1_CLK_SEL_MASK (0xf << 0)
1034#define RT5670_MDA_R_M_ASYN (0x1 << 14) 1042#define RT5670_AD_STO1_CLK_SEL_SFT 0
1035#define RT5670_MAD_L_M_MASK (0x1 << 13)
1036#define RT5670_MAD_L_M_SFT 13
1037#define RT5670_MAD_L_M_NOR (0x0 << 13)
1038#define RT5670_MAD_L_M_ASYN (0x1 << 13)
1039#define RT5670_MAD_R_M_MASK (0x1 << 12)
1040#define RT5670_MAD_R_M_SFT 12
1041#define RT5670_MAD_R_M_NOR (0x0 << 12)
1042#define RT5670_MAD_R_M_ASYN (0x1 << 12)
1043#define RT5670_ADC_M_MASK (0x1 << 11)
1044#define RT5670_ADC_M_SFT 11
1045#define RT5670_ADC_M_NOR (0x0 << 11)
1046#define RT5670_ADC_M_ASYN (0x1 << 11)
1047#define RT5670_STO_DAC_M_MASK (0x1 << 5)
1048#define RT5670_STO_DAC_M_SFT 5
1049#define RT5670_STO_DAC_M_NOR (0x0 << 5)
1050#define RT5670_STO_DAC_M_ASYN (0x1 << 5)
1051#define RT5670_I2S1_R_D_MASK (0x1 << 4)
1052#define RT5670_I2S1_R_D_SFT 4
1053#define RT5670_I2S1_R_D_DIS (0x0 << 4)
1054#define RT5670_I2S1_R_D_EN (0x1 << 4)
1055#define RT5670_I2S2_R_D_MASK (0x1 << 3)
1056#define RT5670_I2S2_R_D_SFT 3
1057#define RT5670_I2S2_R_D_DIS (0x0 << 3)
1058#define RT5670_I2S2_R_D_EN (0x1 << 3)
1059#define RT5670_PRE_SCLK_MASK (0x3)
1060#define RT5670_PRE_SCLK_SFT 0
1061#define RT5670_PRE_SCLK_512 (0x0)
1062#define RT5670_PRE_SCLK_1024 (0x1)
1063#define RT5670_PRE_SCLK_2048 (0x2)
1064 1043
1065/* ASRC Control 3 (0x85) */ 1044/* ASRC Control 3 (0x85) */
1066#define RT5670_I2S1_RATE_MASK (0xf << 12) 1045#define RT5670_UP_CLK_SEL_MASK (0xf << 12)
1067#define RT5670_I2S1_RATE_SFT 12 1046#define RT5670_UP_CLK_SEL_SFT 12
1068#define RT5670_I2S2_RATE_MASK (0xf << 8) 1047#define RT5670_DOWN_CLK_SEL_MASK (0xf << 8)
1069#define RT5670_I2S2_RATE_SFT 8 1048#define RT5670_DOWN_CLK_SEL_SFT 8
1049#define RT5670_AD_MONOL_CLK_SEL_MASK (0xf << 4)
1050#define RT5670_AD_MONOL_CLK_SEL_SFT 4
1051#define RT5670_AD_MONOR_CLK_SEL_MASK (0xf << 0)
1052#define RT5670_AD_MONOR_CLK_SEL_SFT 0
1070 1053
1071/* ASRC Control 4 (0x89) */ 1054/* ASRC Control 4 (0x89) */
1072#define RT5670_I2S1_PD_MASK (0x7 << 12) 1055#define RT5670_I2S1_PD_MASK (0x7 << 12)
@@ -1983,6 +1966,21 @@ enum {
1983 RT5670_DMIC_DATA_GPIO5, 1966 RT5670_DMIC_DATA_GPIO5,
1984}; 1967};
1985 1968
1969/* filter mask */
1970enum {
1971 RT5670_DA_STEREO_FILTER = 0x1,
1972 RT5670_DA_MONO_L_FILTER = (0x1 << 1),
1973 RT5670_DA_MONO_R_FILTER = (0x1 << 2),
1974 RT5670_AD_STEREO_FILTER = (0x1 << 3),
1975 RT5670_AD_MONO_L_FILTER = (0x1 << 4),
1976 RT5670_AD_MONO_R_FILTER = (0x1 << 5),
1977 RT5670_UP_RATE_FILTER = (0x1 << 6),
1978 RT5670_DOWN_RATE_FILTER = (0x1 << 7),
1979};
1980
1981int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
1982 unsigned int filter_mask, unsigned int clk_src);
1983
1986struct rt5670_priv { 1984struct rt5670_priv {
1987 struct snd_soc_codec *codec; 1985 struct snd_soc_codec *codec;
1988 struct rt5670_platform_data pdata; 1986 struct rt5670_platform_data pdata;
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 735e2eec52f7..75870c0ea2c9 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -90,7 +90,6 @@ struct spdif_mixer_control {
90 * @sysclk: system clock for rx clock rate measurement 90 * @sysclk: system clock for rx clock rate measurement
91 * @dma_params_tx: DMA parameters for transmit channel 91 * @dma_params_tx: DMA parameters for transmit channel
92 * @dma_params_rx: DMA parameters for receive channel 92 * @dma_params_rx: DMA parameters for receive channel
93 * @name: driver name
94 */ 93 */
95struct fsl_spdif_priv { 94struct fsl_spdif_priv {
96 struct spdif_mixer_control fsl_spdif_control; 95 struct spdif_mixer_control fsl_spdif_control;
@@ -109,12 +108,8 @@ struct fsl_spdif_priv {
109 struct clk *sysclk; 108 struct clk *sysclk;
110 struct snd_dmaengine_dai_dma_data dma_params_tx; 109 struct snd_dmaengine_dai_dma_data dma_params_tx;
111 struct snd_dmaengine_dai_dma_data dma_params_rx; 110 struct snd_dmaengine_dai_dma_data dma_params_rx;
112
113 /* The name space will be allocated dynamically */
114 char name[0];
115}; 111};
116 112
117
118/* DPLL locked and lock loss interrupt handler */ 113/* DPLL locked and lock loss interrupt handler */
119static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv) 114static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
120{ 115{
@@ -1169,19 +1164,15 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1169 if (!np) 1164 if (!np)
1170 return -ENODEV; 1165 return -ENODEV;
1171 1166
1172 spdif_priv = devm_kzalloc(&pdev->dev, 1167 spdif_priv = devm_kzalloc(&pdev->dev, sizeof(*spdif_priv), GFP_KERNEL);
1173 sizeof(struct fsl_spdif_priv) + strlen(np->name) + 1,
1174 GFP_KERNEL);
1175 if (!spdif_priv) 1168 if (!spdif_priv)
1176 return -ENOMEM; 1169 return -ENOMEM;
1177 1170
1178 strcpy(spdif_priv->name, np->name);
1179
1180 spdif_priv->pdev = pdev; 1171 spdif_priv->pdev = pdev;
1181 1172
1182 /* Initialize this copy of the CPU DAI driver structure */ 1173 /* Initialize this copy of the CPU DAI driver structure */
1183 memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); 1174 memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
1184 spdif_priv->cpu_dai_drv.name = spdif_priv->name; 1175 spdif_priv->cpu_dai_drv.name = dev_name(&pdev->dev);
1185 1176
1186 /* Get the addresses and IRQ */ 1177 /* Get the addresses and IRQ */
1187 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1178 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1203,7 +1194,7 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1203 } 1194 }
1204 1195
1205 ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, 1196 ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0,
1206 spdif_priv->name, spdif_priv); 1197 dev_name(&pdev->dev), spdif_priv);
1207 if (ret) { 1198 if (ret) {
1208 dev_err(&pdev->dev, "could not claim irq %u\n", irq); 1199 dev_err(&pdev->dev, "could not claim irq %u\n", irq);
1209 return ret; 1200 return ret;
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 65400bef013c..46549de60e50 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -160,7 +160,7 @@ struct fsl_ssi_soc_data {
160 */ 160 */
161struct fsl_ssi_private { 161struct fsl_ssi_private {
162 struct regmap *regs; 162 struct regmap *regs;
163 unsigned int irq; 163 int irq;
164 struct snd_soc_dai_driver cpu_dai_drv; 164 struct snd_soc_dai_driver cpu_dai_drv;
165 165
166 unsigned int dai_fmt; 166 unsigned int dai_fmt;
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
index e94704f1b9ee..33da26a12457 100644
--- a/sound/soc/fsl/imx-spdif.c
+++ b/sound/soc/fsl/imx-spdif.c
@@ -60,6 +60,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
60 data->card.dev = &pdev->dev; 60 data->card.dev = &pdev->dev;
61 data->card.dai_link = &data->dai; 61 data->card.dai_link = &data->dai;
62 data->card.num_links = 1; 62 data->card.num_links = 1;
63 data->card.owner = THIS_MODULE;
63 64
64 ret = snd_soc_of_parse_card_name(&data->card, "model"); 65 ret = snd_soc_of_parse_card_name(&data->card, "model");
65 if (ret) 66 if (ret)
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index c0813f546d1f..ee03dbdda235 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -110,3 +110,14 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
110 platforms with RT5672 audio codec. 110 platforms with RT5672 audio codec.
111 Say Y if you have such a device 111 Say Y if you have such a device
112 If unsure select "N". 112 If unsure select "N".
113
114config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
115 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645 codec"
116 depends on X86_INTEL_LPSS
117 select SND_SOC_RT5645
118 select SND_SST_MFLD_PLATFORM
119 select SND_SST_IPC_ACPI
120 help
121 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
122 platforms with RT5645 audio codec.
123 If unsure select "N".
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index e928ec385300..a8e53c45c6b6 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -28,6 +28,7 @@ snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
28snd-soc-sst-broadwell-objs := broadwell.o 28snd-soc-sst-broadwell-objs := broadwell.o
29snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o 29snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o
30snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o 30snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
31snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
31 32
32obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 33obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
33obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 34obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
@@ -35,6 +36,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
35obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o 36obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
36obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o 37obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o
37obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 38obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
39obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
38 40
39# DSP driver 41# DSP driver
40obj-$(CONFIG_SND_SST_IPC) += sst/ 42obj-$(CONFIG_SND_SST_IPC) += sst/
diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/broadwell.c
index 7cf95d5d5d80..9cf7d01479ad 100644
--- a/sound/soc/intel/broadwell.c
+++ b/sound/soc/intel/broadwell.c
@@ -140,8 +140,6 @@ static struct snd_soc_ops broadwell_rt286_ops = {
140 140
141static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) 141static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
142{ 142{
143 struct snd_soc_codec *codec = rtd->codec;
144 struct snd_soc_dapm_context *dapm = &codec->dapm;
145 struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev); 143 struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
146 struct sst_hsw *broadwell = pdata->dsp; 144 struct sst_hsw *broadwell = pdata->dsp;
147 int ret; 145 int ret;
@@ -155,14 +153,6 @@ static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
155 return ret; 153 return ret;
156 } 154 }
157 155
158 /* always connected - check HP for jack detect */
159 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
160 snd_soc_dapm_enable_pin(dapm, "Speaker");
161 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
162 snd_soc_dapm_enable_pin(dapm, "Line Jack");
163 snd_soc_dapm_enable_pin(dapm, "DMIC1");
164 snd_soc_dapm_enable_pin(dapm, "DMIC2");
165
166 return 0; 156 return 0;
167} 157}
168 158
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/byt-rt5640.c
index 0cba7830c5e9..354eaad886e1 100644
--- a/sound/soc/intel/byt-rt5640.c
+++ b/sound/soc/intel/byt-rt5640.c
@@ -132,7 +132,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
132{ 132{
133 int ret; 133 int ret;
134 struct snd_soc_codec *codec = runtime->codec; 134 struct snd_soc_codec *codec = runtime->codec;
135 struct snd_soc_dapm_context *dapm = &codec->dapm;
136 struct snd_soc_card *card = runtime->card; 135 struct snd_soc_card *card = runtime->card;
137 const struct snd_soc_dapm_route *custom_map; 136 const struct snd_soc_dapm_route *custom_map;
138 int num_routes; 137 int num_routes;
@@ -161,7 +160,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
161 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); 160 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
162 } 161 }
163 162
164 ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); 163 ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
165 if (ret) 164 if (ret)
166 return ret; 165 return ret;
167 166
@@ -171,13 +170,8 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
171 return ret; 170 return ret;
172 } 171 }
173 172
174 snd_soc_dapm_ignore_suspend(dapm, "HPOL"); 173 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
175 snd_soc_dapm_ignore_suspend(dapm, "HPOR"); 174 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
176
177 snd_soc_dapm_ignore_suspend(dapm, "SPOLP");
178 snd_soc_dapm_ignore_suspend(dapm, "SPOLN");
179 snd_soc_dapm_ignore_suspend(dapm, "SPORP");
180 snd_soc_dapm_ignore_suspend(dapm, "SPORN");
181 175
182 return ret; 176 return ret;
183} 177}
diff --git a/sound/soc/intel/cht_bsw_rt5645.c b/sound/soc/intel/cht_bsw_rt5645.c
new file mode 100644
index 000000000000..bd29617a9ab9
--- /dev/null
+++ b/sound/soc/intel/cht_bsw_rt5645.c
@@ -0,0 +1,326 @@
1/*
2 * cht-bsw-rt5645.c - ASoc Machine driver for Intel Cherryview-based platforms
3 * Cherrytrail and Braswell, with RT5645 codec.
4 *
5 * Copyright (C) 2015 Intel Corp
6 * Author: Fang, Yang A <yang.a.fang@intel.com>
7 * N,Harshapriya <harshapriya.n@intel.com>
8 * This file is modified from cht_bsw_rt5672.c
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 */
22
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/jack.h>
30#include "../codecs/rt5645.h"
31#include "sst-atom-controls.h"
32
33#define CHT_PLAT_CLK_3_HZ 19200000
34#define CHT_CODEC_DAI "rt5645-aif1"
35
36struct cht_mc_private {
37 struct snd_soc_jack hp_jack;
38 struct snd_soc_jack mic_jack;
39};
40
41static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
42{
43 int i;
44
45 for (i = 0; i < card->num_rtd; i++) {
46 struct snd_soc_pcm_runtime *rtd;
47
48 rtd = card->rtd + i;
49 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
50 strlen(CHT_CODEC_DAI)))
51 return rtd->codec_dai;
52 }
53 return NULL;
54}
55
56static int platform_clock_control(struct snd_soc_dapm_widget *w,
57 struct snd_kcontrol *k, int event)
58{
59 struct snd_soc_dapm_context *dapm = w->dapm;
60 struct snd_soc_card *card = dapm->card;
61 struct snd_soc_dai *codec_dai;
62 int ret;
63
64 codec_dai = cht_get_codec_dai(card);
65 if (!codec_dai) {
66 dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
67 return -EIO;
68 }
69
70 if (!SND_SOC_DAPM_EVENT_OFF(event))
71 return 0;
72
73 /* Set codec sysclk source to its internal clock because codec PLL will
74 * be off when idle and MCLK will also be off by ACPI when codec is
75 * runtime suspended. Codec needs clock for jack detection and button
76 * press.
77 */
78 ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK,
79 0, SND_SOC_CLOCK_IN);
80 if (ret < 0) {
81 dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
82 return ret;
83 }
84
85 return 0;
86}
87
88static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
89 SND_SOC_DAPM_HP("Headphone", NULL),
90 SND_SOC_DAPM_MIC("Headset Mic", NULL),
91 SND_SOC_DAPM_MIC("Int Mic", NULL),
92 SND_SOC_DAPM_SPK("Ext Spk", NULL),
93 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
94 platform_clock_control, SND_SOC_DAPM_POST_PMD),
95};
96
97static const struct snd_soc_dapm_route cht_audio_map[] = {
98 {"IN1P", NULL, "Headset Mic"},
99 {"IN1N", NULL, "Headset Mic"},
100 {"DMIC L1", NULL, "Int Mic"},
101 {"DMIC R1", NULL, "Int Mic"},
102 {"Headphone", NULL, "HPOL"},
103 {"Headphone", NULL, "HPOR"},
104 {"Ext Spk", NULL, "SPOL"},
105 {"Ext Spk", NULL, "SPOR"},
106 {"AIF1 Playback", NULL, "ssp2 Tx"},
107 {"ssp2 Tx", NULL, "codec_out0"},
108 {"ssp2 Tx", NULL, "codec_out1"},
109 {"codec_in0", NULL, "ssp2 Rx" },
110 {"codec_in1", NULL, "ssp2 Rx" },
111 {"ssp2 Rx", NULL, "AIF1 Capture"},
112 {"Headphone", NULL, "Platform Clock"},
113 {"Headset Mic", NULL, "Platform Clock"},
114 {"Int Mic", NULL, "Platform Clock"},
115 {"Ext Spk", NULL, "Platform Clock"},
116};
117
118static const struct snd_kcontrol_new cht_mc_controls[] = {
119 SOC_DAPM_PIN_SWITCH("Headphone"),
120 SOC_DAPM_PIN_SWITCH("Headset Mic"),
121 SOC_DAPM_PIN_SWITCH("Int Mic"),
122 SOC_DAPM_PIN_SWITCH("Ext Spk"),
123};
124
125static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
126 struct snd_pcm_hw_params *params)
127{
128 struct snd_soc_pcm_runtime *rtd = substream->private_data;
129 struct snd_soc_dai *codec_dai = rtd->codec_dai;
130 int ret;
131
132 /* set codec PLL source to the 19.2MHz platform clock (MCLK) */
133 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5645_PLL1_S_MCLK,
134 CHT_PLAT_CLK_3_HZ, params_rate(params) * 512);
135 if (ret < 0) {
136 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
137 return ret;
138 }
139
140 ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_PLL1,
141 params_rate(params) * 512, SND_SOC_CLOCK_IN);
142 if (ret < 0) {
143 dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
144 return ret;
145 }
146
147 return 0;
148}
149
150static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
151{
152 int ret;
153 struct snd_soc_codec *codec = runtime->codec;
154 struct snd_soc_dai *codec_dai = runtime->codec_dai;
155 struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
156
157 /* Select clk_i2s1_asrc as ASRC clock source */
158 rt5645_sel_asrc_clk_src(codec,
159 RT5645_DA_STEREO_FILTER |
160 RT5645_DA_MONO_L_FILTER |
161 RT5645_DA_MONO_R_FILTER |
162 RT5645_AD_STEREO_FILTER,
163 RT5645_CLK_SEL_I2S1_ASRC);
164
165 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
166 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24);
167 if (ret < 0) {
168 dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret);
169 return ret;
170 }
171
172 ret = snd_soc_jack_new(codec, "Headphone Jack",
173 SND_JACK_HEADPHONE,
174 &ctx->hp_jack);
175 if (ret) {
176 dev_err(runtime->dev, "HP jack creation failed %d\n", ret);
177 return ret;
178 }
179
180 ret = snd_soc_jack_new(codec, "Mic Jack",
181 SND_JACK_MICROPHONE,
182 &ctx->mic_jack);
183 if (ret) {
184 dev_err(runtime->dev, "Mic jack creation failed %d\n", ret);
185 return ret;
186 }
187
188 rt5645_set_jack_detect(codec, &ctx->hp_jack, &ctx->mic_jack);
189
190 return ret;
191}
192
193static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
194 struct snd_pcm_hw_params *params)
195{
196 struct snd_interval *rate = hw_param_interval(params,
197 SNDRV_PCM_HW_PARAM_RATE);
198 struct snd_interval *channels = hw_param_interval(params,
199 SNDRV_PCM_HW_PARAM_CHANNELS);
200
201 /* The DSP will covert the FE rate to 48k, stereo, 24bits */
202 rate->min = rate->max = 48000;
203 channels->min = channels->max = 2;
204
205 /* set SSP2 to 24-bit */
206 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
207 SNDRV_PCM_HW_PARAM_FIRST_MASK],
208 SNDRV_PCM_FORMAT_S24_LE);
209 return 0;
210}
211
212static unsigned int rates_48000[] = {
213 48000,
214};
215
216static struct snd_pcm_hw_constraint_list constraints_48000 = {
217 .count = ARRAY_SIZE(rates_48000),
218 .list = rates_48000,
219};
220
221static int cht_aif1_startup(struct snd_pcm_substream *substream)
222{
223 return snd_pcm_hw_constraint_list(substream->runtime, 0,
224 SNDRV_PCM_HW_PARAM_RATE,
225 &constraints_48000);
226}
227
228static struct snd_soc_ops cht_aif1_ops = {
229 .startup = cht_aif1_startup,
230};
231
232static struct snd_soc_ops cht_be_ssp2_ops = {
233 .hw_params = cht_aif1_hw_params,
234};
235
236static struct snd_soc_dai_link cht_dailink[] = {
237 [MERR_DPCM_AUDIO] = {
238 .name = "Audio Port",
239 .stream_name = "Audio",
240 .cpu_dai_name = "media-cpu-dai",
241 .codec_dai_name = "snd-soc-dummy-dai",
242 .codec_name = "snd-soc-dummy",
243 .platform_name = "sst-mfld-platform",
244 .ignore_suspend = 1,
245 .dynamic = 1,
246 .dpcm_playback = 1,
247 .dpcm_capture = 1,
248 .ops = &cht_aif1_ops,
249 },
250 [MERR_DPCM_COMPR] = {
251 .name = "Compressed Port",
252 .stream_name = "Compress",
253 .cpu_dai_name = "compress-cpu-dai",
254 .codec_dai_name = "snd-soc-dummy-dai",
255 .codec_name = "snd-soc-dummy",
256 .platform_name = "sst-mfld-platform",
257 },
258 /* CODEC<->CODEC link */
259 /* back ends */
260 {
261 .name = "SSP2-Codec",
262 .be_id = 1,
263 .cpu_dai_name = "ssp2-port",
264 .platform_name = "sst-mfld-platform",
265 .no_pcm = 1,
266 .codec_dai_name = "rt5645-aif1",
267 .codec_name = "i2c-10EC5645:00",
268 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF
269 | SND_SOC_DAIFMT_CBS_CFS,
270 .init = cht_codec_init,
271 .be_hw_params_fixup = cht_codec_fixup,
272 .ignore_suspend = 1,
273 .dpcm_playback = 1,
274 .dpcm_capture = 1,
275 .ops = &cht_be_ssp2_ops,
276 },
277};
278
279/* SoC card */
280static struct snd_soc_card snd_soc_card_cht = {
281 .name = "chtrt5645",
282 .dai_link = cht_dailink,
283 .num_links = ARRAY_SIZE(cht_dailink),
284 .dapm_widgets = cht_dapm_widgets,
285 .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
286 .dapm_routes = cht_audio_map,
287 .num_dapm_routes = ARRAY_SIZE(cht_audio_map),
288 .controls = cht_mc_controls,
289 .num_controls = ARRAY_SIZE(cht_mc_controls),
290};
291
292static int snd_cht_mc_probe(struct platform_device *pdev)
293{
294 int ret_val = 0;
295 struct cht_mc_private *drv;
296
297 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
298 if (!drv)
299 return -ENOMEM;
300
301 snd_soc_card_cht.dev = &pdev->dev;
302 snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
303 ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
304 if (ret_val) {
305 dev_err(&pdev->dev,
306 "snd_soc_register_card failed %d\n", ret_val);
307 return ret_val;
308 }
309 platform_set_drvdata(pdev, &snd_soc_card_cht);
310 return ret_val;
311}
312
313static struct platform_driver snd_cht_mc_driver = {
314 .driver = {
315 .name = "cht-bsw-rt5645",
316 .pm = &snd_soc_pm_ops,
317 },
318 .probe = snd_cht_mc_probe,
319};
320
321module_platform_driver(snd_cht_mc_driver)
322
323MODULE_DESCRIPTION("ASoC Intel(R) Braswell Machine driver");
324MODULE_AUTHOR("Fang, Yang A,N,Harshapriya");
325MODULE_LICENSE("GPL v2");
326MODULE_ALIAS("platform:cht-bsw-rt5645");
diff --git a/sound/soc/intel/cht_bsw_rt5672.c b/sound/soc/intel/cht_bsw_rt5672.c
index a406c6104897..ff016621583a 100644
--- a/sound/soc/intel/cht_bsw_rt5672.c
+++ b/sound/soc/intel/cht_bsw_rt5672.c
@@ -140,6 +140,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
140{ 140{
141 int ret; 141 int ret;
142 struct snd_soc_dai *codec_dai = runtime->codec_dai; 142 struct snd_soc_dai *codec_dai = runtime->codec_dai;
143 struct snd_soc_codec *codec = codec_dai->codec;
143 144
144 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ 145 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
145 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); 146 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24);
@@ -148,6 +149,19 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
148 return ret; 149 return ret;
149 } 150 }
150 151
152 /* Select codec ASRC clock source to track I2S1 clock, because codec
153 * is in slave mode and 100fs I2S format (BCLK = 100 * LRCLK) cannot
154 * be supported by RT5672. Otherwise, ASRC will be disabled and cause
155 * noise.
156 */
157 rt5670_sel_asrc_clk_src(codec,
158 RT5670_DA_STEREO_FILTER
159 | RT5670_DA_MONO_L_FILTER
160 | RT5670_DA_MONO_R_FILTER
161 | RT5670_AD_STEREO_FILTER
162 | RT5670_AD_MONO_L_FILTER
163 | RT5670_AD_MONO_R_FILTER,
164 RT5670_CLK_SEL_I2S1_ASRC);
151 return 0; 165 return 0;
152} 166}
153 167
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c
index 3bb6288d8b4d..224c49c9f135 100644
--- a/sound/soc/intel/sst-baytrail-pcm.c
+++ b/sound/soc/intel/sst-baytrail-pcm.c
@@ -320,11 +320,6 @@ static struct snd_pcm_ops sst_byt_pcm_ops = {
320 .mmap = sst_byt_pcm_mmap, 320 .mmap = sst_byt_pcm_mmap,
321}; 321};
322 322
323static void sst_byt_pcm_free(struct snd_pcm *pcm)
324{
325 snd_pcm_lib_preallocate_free_for_all(pcm);
326}
327
328static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd) 323static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd)
329{ 324{
330 struct snd_pcm *pcm = rtd->pcm; 325 struct snd_pcm *pcm = rtd->pcm;
@@ -403,7 +398,6 @@ static struct snd_soc_platform_driver byt_soc_platform = {
403 .remove = sst_byt_pcm_remove, 398 .remove = sst_byt_pcm_remove,
404 .ops = &sst_byt_pcm_ops, 399 .ops = &sst_byt_pcm_ops,
405 .pcm_new = sst_byt_pcm_new, 400 .pcm_new = sst_byt_pcm_new,
406 .pcm_free = sst_byt_pcm_free,
407}; 401};
408 402
409static const struct snd_soc_component_driver byt_dai_component = { 403static const struct snd_soc_component_driver byt_dai_component = {
diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/sst-dsp.c
index 86e410845670..64e94212d2d2 100644
--- a/sound/soc/intel/sst-dsp.c
+++ b/sound/soc/intel/sst-dsp.c
@@ -410,8 +410,7 @@ void sst_dsp_free(struct sst_dsp *sst)
410 if (sst->ops->free) 410 if (sst->ops->free)
411 sst->ops->free(sst); 411 sst->ops->free(sst);
412 412
413 if (sst->dma) 413 sst_dma_free(sst->dma);
414 sst_dma_free(sst->dma);
415} 414}
416EXPORT_SYMBOL_GPL(sst_dsp_free); 415EXPORT_SYMBOL_GPL(sst_dsp_free);
417 416
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c
index a2ae2c5f2e9f..5f71ef607a57 100644
--- a/sound/soc/intel/sst-firmware.c
+++ b/sound/soc/intel/sst-firmware.c
@@ -791,6 +791,7 @@ int sst_module_alloc_blocks(struct sst_module *module)
791 struct sst_block_allocator ba; 791 struct sst_block_allocator ba;
792 int ret; 792 int ret;
793 793
794 memset(&ba, 0, sizeof(ba));
794 ba.size = module->size; 795 ba.size = module->size;
795 ba.type = module->type; 796 ba.type = module->type;
796 ba.offset = module->offset; 797 ba.offset = module->offset;
@@ -864,6 +865,7 @@ int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime,
864 if (module->persistent_size == 0) 865 if (module->persistent_size == 0)
865 return 0; 866 return 0;
866 867
868 memset(&ba, 0, sizeof(ba));
867 ba.size = module->persistent_size; 869 ba.size = module->persistent_size;
868 ba.type = SST_MEM_DRAM; 870 ba.type = SST_MEM_DRAM;
869 871
diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c
index 57039b00efc2..c42ffae5fe9f 100644
--- a/sound/soc/intel/sst-haswell-dsp.c
+++ b/sound/soc/intel/sst-haswell-dsp.c
@@ -306,7 +306,7 @@ static void hsw_reset(struct sst_dsp *sst)
306static int hsw_set_dsp_D0(struct sst_dsp *sst) 306static int hsw_set_dsp_D0(struct sst_dsp *sst)
307{ 307{
308 int tries = 10; 308 int tries = 10;
309 u32 reg; 309 u32 reg, fw_dump_bit;
310 310
311 /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ 311 /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
312 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); 312 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
@@ -368,7 +368,9 @@ finish:
368 can't be accessed, please enable each block before accessing. */ 368 can't be accessed, please enable each block before accessing. */
369 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); 369 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
370 reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK; 370 reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK;
371 writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); 371 /* for D0, always enable the block(DSRAM[0]) used for FW dump */
372 fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
373 writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
372 374
373 375
374 /* disable DMA finish function for SSP0 & SSP1 */ 376 /* disable DMA finish function for SSP0 & SSP1 */
@@ -491,6 +493,7 @@ static const struct sst_sram_shift sram_shift[] = {
491 {SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */ 493 {SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */
492 {SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */ 494 {SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */
493}; 495};
496
494static u32 hsw_block_get_bit(struct sst_mem_block *block) 497static u32 hsw_block_get_bit(struct sst_mem_block *block)
495{ 498{
496 u32 bit = 0, shift = 0, index; 499 u32 bit = 0, shift = 0, index;
@@ -587,7 +590,9 @@ static int hsw_block_disable(struct sst_mem_block *block)
587 590
588 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); 591 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
589 bit = hsw_block_get_bit(block); 592 bit = hsw_block_get_bit(block);
590 writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0); 593 /* don't disable DSRAM[0], keep it always enable for FW dump*/
594 if (bit != (1 << SST_VDRTCL0_DSRAMPGE_SHIFT))
595 writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0);
591 596
592 /* wait 18 DSP clock ticks */ 597 /* wait 18 DSP clock ticks */
593 udelay(10); 598 udelay(10);
@@ -612,7 +617,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
612 const struct sst_adsp_memregion *region; 617 const struct sst_adsp_memregion *region;
613 struct device *dev; 618 struct device *dev;
614 int ret = -ENODEV, i, j, region_count; 619 int ret = -ENODEV, i, j, region_count;
615 u32 offset, size; 620 u32 offset, size, fw_dump_bit;
616 621
617 dev = sst->dma_dev; 622 dev = sst->dma_dev;
618 623
@@ -669,9 +674,11 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
669 } 674 }
670 } 675 }
671 676
677 /* always enable the block(DSRAM[0]) used for FW dump */
678 fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
672 /* set default power gating control, enable power gating control for all blocks. that is, 679 /* set default power gating control, enable power gating control for all blocks. that is,
673 can't be accessed, please enable each block before accessing. */ 680 can't be accessed, please enable each block before accessing. */
674 writel(0xffffffff, sst->addr.pci_cfg + SST_VDRTCTL0); 681 writel(0xffffffff & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
675 682
676 return 0; 683 return 0;
677} 684}
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c
index 8156cc1accb7..0ab1309ef274 100644
--- a/sound/soc/intel/sst-haswell-ipc.c
+++ b/sound/soc/intel/sst-haswell-ipc.c
@@ -94,6 +94,8 @@
94/* Mailbox */ 94/* Mailbox */
95#define IPC_MAX_MAILBOX_BYTES 256 95#define IPC_MAX_MAILBOX_BYTES 256
96 96
97#define INVALID_STREAM_HW_ID 0xffffffff
98
97/* Global Message - Types and Replies */ 99/* Global Message - Types and Replies */
98enum ipc_glb_type { 100enum ipc_glb_type {
99 IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */ 101 IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */
@@ -275,7 +277,6 @@ struct sst_hsw {
275 /* FW config */ 277 /* FW config */
276 struct sst_hsw_ipc_fw_ready fw_ready; 278 struct sst_hsw_ipc_fw_ready fw_ready;
277 struct sst_hsw_ipc_fw_version version; 279 struct sst_hsw_ipc_fw_version version;
278 struct sst_module *scratch;
279 bool fw_done; 280 bool fw_done;
280 struct sst_fw *sst_fw; 281 struct sst_fw *sst_fw;
281 282
@@ -337,12 +338,6 @@ static inline u32 msg_get_stage_type(u32 msg)
337 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT; 338 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT;
338} 339}
339 340
340static inline u32 msg_set_stage_type(u32 msg, u32 type)
341{
342 return (msg & ~IPC_STG_TYPE_MASK) +
343 (type << IPC_STG_TYPE_SHIFT);
344}
345
346static inline u32 msg_get_stream_id(u32 msg) 341static inline u32 msg_get_stream_id(u32 msg)
347{ 342{
348 return (msg & IPC_STR_ID_MASK) >> IPC_STR_ID_SHIFT; 343 return (msg & IPC_STR_ID_MASK) >> IPC_STR_ID_SHIFT;
@@ -969,45 +964,6 @@ int sst_hsw_fw_get_version(struct sst_hsw *hsw,
969} 964}
970 965
971/* Mixer Controls */ 966/* Mixer Controls */
972int sst_hsw_stream_mute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
973 u32 stage_id, u32 channel)
974{
975 int ret;
976
977 ret = sst_hsw_stream_get_volume(hsw, stream, stage_id, channel,
978 &stream->mute_volume[channel]);
979 if (ret < 0)
980 return ret;
981
982 ret = sst_hsw_stream_set_volume(hsw, stream, stage_id, channel, 0);
983 if (ret < 0) {
984 dev_err(hsw->dev, "error: can't unmute stream %d channel %d\n",
985 stream->reply.stream_hw_id, channel);
986 return ret;
987 }
988
989 stream->mute[channel] = 1;
990 return 0;
991}
992
993int sst_hsw_stream_unmute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
994 u32 stage_id, u32 channel)
995
996{
997 int ret;
998
999 stream->mute[channel] = 0;
1000 ret = sst_hsw_stream_set_volume(hsw, stream, stage_id, channel,
1001 stream->mute_volume[channel]);
1002 if (ret < 0) {
1003 dev_err(hsw->dev, "error: can't unmute stream %d channel %d\n",
1004 stream->reply.stream_hw_id, channel);
1005 return ret;
1006 }
1007
1008 return 0;
1009}
1010
1011int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream, 967int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
1012 u32 stage_id, u32 channel, u32 *volume) 968 u32 stage_id, u32 channel, u32 *volume)
1013{ 969{
@@ -1021,17 +977,6 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream
1021 return 0; 977 return 0;
1022} 978}
1023 979
1024int sst_hsw_stream_set_volume_curve(struct sst_hsw *hsw,
1025 struct sst_hsw_stream *stream, u64 curve_duration,
1026 enum sst_hsw_volume_curve curve)
1027{
1028 /* curve duration in steps of 100ns */
1029 stream->vol_req.curve_duration = curve_duration;
1030 stream->vol_req.curve_type = curve;
1031
1032 return 0;
1033}
1034
1035/* stream volume */ 980/* stream volume */
1036int sst_hsw_stream_set_volume(struct sst_hsw *hsw, 981int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
1037 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) 982 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume)
@@ -1083,42 +1028,6 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
1083 return 0; 1028 return 0;
1084} 1029}
1085 1030
1086int sst_hsw_mixer_mute(struct sst_hsw *hsw, u32 stage_id, u32 channel)
1087{
1088 int ret;
1089
1090 ret = sst_hsw_mixer_get_volume(hsw, stage_id, channel,
1091 &hsw->mute_volume[channel]);
1092 if (ret < 0)
1093 return ret;
1094
1095 ret = sst_hsw_mixer_set_volume(hsw, stage_id, channel, 0);
1096 if (ret < 0) {
1097 dev_err(hsw->dev, "error: failed to unmute mixer channel %d\n",
1098 channel);
1099 return ret;
1100 }
1101
1102 hsw->mute[channel] = 1;
1103 return 0;
1104}
1105
1106int sst_hsw_mixer_unmute(struct sst_hsw *hsw, u32 stage_id, u32 channel)
1107{
1108 int ret;
1109
1110 ret = sst_hsw_mixer_set_volume(hsw, stage_id, channel,
1111 hsw->mixer_info.volume_register_address[channel]);
1112 if (ret < 0) {
1113 dev_err(hsw->dev, "error: failed to unmute mixer channel %d\n",
1114 channel);
1115 return ret;
1116 }
1117
1118 hsw->mute[channel] = 0;
1119 return 0;
1120}
1121
1122int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, 1031int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1123 u32 *volume) 1032 u32 *volume)
1124{ 1033{
@@ -1132,16 +1041,6 @@ int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1132 return 0; 1041 return 0;
1133} 1042}
1134 1043
1135int sst_hsw_mixer_set_volume_curve(struct sst_hsw *hsw,
1136 u64 curve_duration, enum sst_hsw_volume_curve curve)
1137{
1138 /* curve duration in steps of 100ns */
1139 hsw->curve_duration = curve_duration;
1140 hsw->curve_type = curve;
1141
1142 return 0;
1143}
1144
1145/* global mixer volume */ 1044/* global mixer volume */
1146int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, 1045int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1147 u32 volume) 1046 u32 volume)
@@ -1208,6 +1107,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
1208 return NULL; 1107 return NULL;
1209 1108
1210 spin_lock_irqsave(&sst->spinlock, flags); 1109 spin_lock_irqsave(&sst->spinlock, flags);
1110 stream->reply.stream_hw_id = INVALID_STREAM_HW_ID;
1211 list_add(&stream->node, &hsw->stream_list); 1111 list_add(&stream->node, &hsw->stream_list);
1212 stream->notify_position = notify_position; 1112 stream->notify_position = notify_position;
1213 stream->pdata = data; 1113 stream->pdata = data;
@@ -1449,48 +1349,6 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1449 1349
1450/* Stream Information - these calls could be inline but we want the IPC 1350/* Stream Information - these calls could be inline but we want the IPC
1451 ABI to be opaque to client PCM drivers to cope with any future ABI changes */ 1351 ABI to be opaque to client PCM drivers to cope with any future ABI changes */
1452int sst_hsw_stream_get_hw_id(struct sst_hsw *hsw,
1453 struct sst_hsw_stream *stream)
1454{
1455 return stream->reply.stream_hw_id;
1456}
1457
1458int sst_hsw_stream_get_mixer_id(struct sst_hsw *hsw,
1459 struct sst_hsw_stream *stream)
1460{
1461 return stream->reply.mixer_hw_id;
1462}
1463
1464u32 sst_hsw_stream_get_read_reg(struct sst_hsw *hsw,
1465 struct sst_hsw_stream *stream)
1466{
1467 return stream->reply.read_position_register_address;
1468}
1469
1470u32 sst_hsw_stream_get_pointer_reg(struct sst_hsw *hsw,
1471 struct sst_hsw_stream *stream)
1472{
1473 return stream->reply.presentation_position_register_address;
1474}
1475
1476u32 sst_hsw_stream_get_peak_reg(struct sst_hsw *hsw,
1477 struct sst_hsw_stream *stream, u32 channel)
1478{
1479 if (channel >= 2)
1480 return 0;
1481
1482 return stream->reply.peak_meter_register_address[channel];
1483}
1484
1485u32 sst_hsw_stream_get_vol_reg(struct sst_hsw *hsw,
1486 struct sst_hsw_stream *stream, u32 channel)
1487{
1488 if (channel >= 2)
1489 return 0;
1490
1491 return stream->reply.volume_register_address[channel];
1492}
1493
1494int sst_hsw_mixer_get_info(struct sst_hsw *hsw) 1352int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
1495{ 1353{
1496 struct sst_hsw_ipc_stream_info_reply *reply; 1354 struct sst_hsw_ipc_stream_info_reply *reply;
@@ -1628,30 +1486,6 @@ u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
1628 return ppos; 1486 return ppos;
1629} 1487}
1630 1488
1631int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
1632 struct sst_hsw_stream *stream, u32 stage_id, u32 position)
1633{
1634 u32 header;
1635 int ret;
1636
1637 trace_stream_write_position(stream->reply.stream_hw_id, position);
1638
1639 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
1640 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
1641 header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
1642 header |= (IPC_STG_SET_WRITE_POSITION << IPC_STG_TYPE_SHIFT);
1643 header |= (stage_id << IPC_STG_ID_SHIFT);
1644 stream->wpos.position = position;
1645
1646 ret = ipc_tx_message_nowait(hsw, header, &stream->wpos,
1647 sizeof(stream->wpos));
1648 if (ret < 0)
1649 dev_err(hsw->dev, "error: stream %d set position %d failed\n",
1650 stream->reply.stream_hw_id, position);
1651
1652 return ret;
1653}
1654
1655/* physical BE config */ 1489/* physical BE config */
1656int sst_hsw_device_set_config(struct sst_hsw *hsw, 1490int sst_hsw_device_set_config(struct sst_hsw *hsw,
1657 enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, 1491 enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk,
@@ -2132,7 +1966,6 @@ void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata)
2132 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, 1966 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE,
2133 hsw->dx_context, hsw->dx_context_paddr); 1967 hsw->dx_context, hsw->dx_context_paddr);
2134 sst_dsp_free(hsw->dsp); 1968 sst_dsp_free(hsw->dsp);
2135 kfree(hsw->scratch);
2136 kthread_stop(hsw->tx_thread); 1969 kthread_stop(hsw->tx_thread);
2137 kfree(hsw->msg); 1970 kfree(hsw->msg);
2138} 1971}
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h
index 138e894ab413..c1ad901342f2 100644
--- a/sound/soc/intel/sst-haswell-ipc.h
+++ b/sound/soc/intel/sst-haswell-ipc.h
@@ -376,32 +376,17 @@ int sst_hsw_fw_get_version(struct sst_hsw *hsw,
376u32 create_channel_map(enum sst_hsw_channel_config config); 376u32 create_channel_map(enum sst_hsw_channel_config config);
377 377
378/* Stream Mixer Controls - */ 378/* Stream Mixer Controls - */
379int sst_hsw_stream_mute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
380 u32 stage_id, u32 channel);
381int sst_hsw_stream_unmute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
382 u32 stage_id, u32 channel);
383
384int sst_hsw_stream_set_volume(struct sst_hsw *hsw, 379int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
385 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume); 380 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume);
386int sst_hsw_stream_get_volume(struct sst_hsw *hsw, 381int sst_hsw_stream_get_volume(struct sst_hsw *hsw,
387 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 *volume); 382 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 *volume);
388 383
389int sst_hsw_stream_set_volume_curve(struct sst_hsw *hsw,
390 struct sst_hsw_stream *stream, u64 curve_duration,
391 enum sst_hsw_volume_curve curve);
392
393/* Global Mixer Controls - */ 384/* Global Mixer Controls - */
394int sst_hsw_mixer_mute(struct sst_hsw *hsw, u32 stage_id, u32 channel);
395int sst_hsw_mixer_unmute(struct sst_hsw *hsw, u32 stage_id, u32 channel);
396
397int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, 385int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
398 u32 volume); 386 u32 volume);
399int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, 387int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
400 u32 *volume); 388 u32 *volume);
401 389
402int sst_hsw_mixer_set_volume_curve(struct sst_hsw *hsw,
403 u64 curve_duration, enum sst_hsw_volume_curve curve);
404
405/* Stream API */ 390/* Stream API */
406struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, 391struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
407 u32 (*get_write_position)(struct sst_hsw_stream *stream, void *data), 392 u32 (*get_write_position)(struct sst_hsw_stream *stream, void *data),
@@ -440,18 +425,6 @@ int sst_hsw_stream_set_pmemory_info(struct sst_hsw *hsw,
440 struct sst_hsw_stream *stream, u32 offset, u32 size); 425 struct sst_hsw_stream *stream, u32 offset, u32 size);
441int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw, 426int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw,
442 struct sst_hsw_stream *stream, u32 offset, u32 size); 427 struct sst_hsw_stream *stream, u32 offset, u32 size);
443int sst_hsw_stream_get_hw_id(struct sst_hsw *hsw,
444 struct sst_hsw_stream *stream);
445int sst_hsw_stream_get_mixer_id(struct sst_hsw *hsw,
446 struct sst_hsw_stream *stream);
447u32 sst_hsw_stream_get_read_reg(struct sst_hsw *hsw,
448 struct sst_hsw_stream *stream);
449u32 sst_hsw_stream_get_pointer_reg(struct sst_hsw *hsw,
450 struct sst_hsw_stream *stream);
451u32 sst_hsw_stream_get_peak_reg(struct sst_hsw *hsw,
452 struct sst_hsw_stream *stream, u32 channel);
453u32 sst_hsw_stream_get_vol_reg(struct sst_hsw *hsw,
454 struct sst_hsw_stream *stream, u32 channel);
455int sst_hsw_mixer_get_info(struct sst_hsw *hsw); 428int sst_hsw_mixer_get_info(struct sst_hsw *hsw);
456 429
457/* Stream ALSA trigger operations */ 430/* Stream ALSA trigger operations */
@@ -466,8 +439,6 @@ int sst_hsw_stream_get_read_pos(struct sst_hsw *hsw,
466 struct sst_hsw_stream *stream, u32 *position); 439 struct sst_hsw_stream *stream, u32 *position);
467int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw, 440int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw,
468 struct sst_hsw_stream *stream, u32 *position); 441 struct sst_hsw_stream *stream, u32 *position);
469int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
470 struct sst_hsw_stream *stream, u32 stage_id, u32 position);
471u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, 442u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
472 struct sst_hsw_stream *stream); 443 struct sst_hsw_stream *stream);
473u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, 444u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
@@ -481,8 +452,6 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
481/* DX Config */ 452/* DX Config */
482int sst_hsw_dx_set_state(struct sst_hsw *hsw, 453int sst_hsw_dx_set_state(struct sst_hsw *hsw,
483 enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx); 454 enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx);
484int sst_hsw_dx_get_state(struct sst_hsw *hsw, u32 item,
485 u32 *offset, u32 *size, u32 *source);
486 455
487/* init */ 456/* init */
488int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata); 457int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata);
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c
index 619525200705..78fa01be57f2 100644
--- a/sound/soc/intel/sst-haswell-pcm.c
+++ b/sound/soc/intel/sst-haswell-pcm.c
@@ -78,7 +78,6 @@ static const u32 volume_map[] = {
78#define HSW_PCM_DAI_ID_OFFLOAD0 1 78#define HSW_PCM_DAI_ID_OFFLOAD0 1
79#define HSW_PCM_DAI_ID_OFFLOAD1 2 79#define HSW_PCM_DAI_ID_OFFLOAD1 2
80#define HSW_PCM_DAI_ID_LOOPBACK 3 80#define HSW_PCM_DAI_ID_LOOPBACK 3
81#define HSW_PCM_DAI_ID_CAPTURE 4
82 81
83 82
84static const struct snd_pcm_hardware hsw_pcm_hardware = { 83static const struct snd_pcm_hardware hsw_pcm_hardware = {
@@ -99,6 +98,7 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = {
99 98
100struct hsw_pcm_module_map { 99struct hsw_pcm_module_map {
101 int dai_id; 100 int dai_id;
101 int stream;
102 enum sst_hsw_module_id mod_id; 102 enum sst_hsw_module_id mod_id;
103}; 103};
104 104
@@ -119,8 +119,9 @@ struct hsw_pcm_data {
119}; 119};
120 120
121enum hsw_pm_state { 121enum hsw_pm_state {
122 HSW_PM_STATE_D3 = 0, 122 HSW_PM_STATE_D0 = 0,
123 HSW_PM_STATE_D0 = 1, 123 HSW_PM_STATE_RTD3 = 1,
124 HSW_PM_STATE_D3 = 2,
124}; 125};
125 126
126/* private data for the driver */ 127/* private data for the driver */
@@ -135,7 +136,17 @@ struct hsw_priv_data {
135 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; 136 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
136 137
137 /* DAI data */ 138 /* DAI data */
138 struct hsw_pcm_data pcm[HSW_PCM_COUNT]; 139 struct hsw_pcm_data pcm[HSW_PCM_COUNT][2];
140};
141
142
143/* static mappings between PCMs and modules - may be dynamic in future */
144static struct hsw_pcm_module_map mod_map[] = {
145 {HSW_PCM_DAI_ID_SYSTEM, 0, SST_HSW_MODULE_PCM_SYSTEM},
146 {HSW_PCM_DAI_ID_OFFLOAD0, 0, SST_HSW_MODULE_PCM},
147 {HSW_PCM_DAI_ID_OFFLOAD1, 0, SST_HSW_MODULE_PCM},
148 {HSW_PCM_DAI_ID_LOOPBACK, 1, SST_HSW_MODULE_PCM_REFERENCE},
149 {HSW_PCM_DAI_ID_SYSTEM, 1, SST_HSW_MODULE_PCM_CAPTURE},
139}; 150};
140 151
141static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data); 152static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data);
@@ -168,9 +179,14 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
168 (struct soc_mixer_control *)kcontrol->private_value; 179 (struct soc_mixer_control *)kcontrol->private_value;
169 struct hsw_priv_data *pdata = 180 struct hsw_priv_data *pdata =
170 snd_soc_platform_get_drvdata(platform); 181 snd_soc_platform_get_drvdata(platform);
171 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 182 struct hsw_pcm_data *pcm_data;
172 struct sst_hsw *hsw = pdata->hsw; 183 struct sst_hsw *hsw = pdata->hsw;
173 u32 volume; 184 u32 volume;
185 int dai, stream;
186
187 dai = mod_map[mc->reg].dai_id;
188 stream = mod_map[mc->reg].stream;
189 pcm_data = &pdata->pcm[dai][stream];
174 190
175 mutex_lock(&pcm_data->mutex); 191 mutex_lock(&pcm_data->mutex);
176 pm_runtime_get_sync(pdata->dev); 192 pm_runtime_get_sync(pdata->dev);
@@ -212,9 +228,14 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
212 (struct soc_mixer_control *)kcontrol->private_value; 228 (struct soc_mixer_control *)kcontrol->private_value;
213 struct hsw_priv_data *pdata = 229 struct hsw_priv_data *pdata =
214 snd_soc_platform_get_drvdata(platform); 230 snd_soc_platform_get_drvdata(platform);
215 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 231 struct hsw_pcm_data *pcm_data;
216 struct sst_hsw *hsw = pdata->hsw; 232 struct sst_hsw *hsw = pdata->hsw;
217 u32 volume; 233 u32 volume;
234 int dai, stream;
235
236 dai = mod_map[mc->reg].dai_id;
237 stream = mod_map[mc->reg].stream;
238 pcm_data = &pdata->pcm[dai][stream];
218 239
219 mutex_lock(&pcm_data->mutex); 240 mutex_lock(&pcm_data->mutex);
220 pm_runtime_get_sync(pdata->dev); 241 pm_runtime_get_sync(pdata->dev);
@@ -309,7 +330,7 @@ static const struct snd_kcontrol_new hsw_volume_controls[] = {
309 ARRAY_SIZE(volume_map) - 1, 0, 330 ARRAY_SIZE(volume_map) - 1, 0,
310 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 331 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
311 /* Mic Capture volume */ 332 /* Mic Capture volume */
312 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 0, 0, 8, 333 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
313 ARRAY_SIZE(volume_map) - 1, 0, 334 ARRAY_SIZE(volume_map) - 1, 0,
314 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 335 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
315}; 336};
@@ -353,7 +374,7 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
353 struct snd_pcm_runtime *runtime = substream->runtime; 374 struct snd_pcm_runtime *runtime = substream->runtime;
354 struct hsw_priv_data *pdata = 375 struct hsw_priv_data *pdata =
355 snd_soc_platform_get_drvdata(rtd->platform); 376 snd_soc_platform_get_drvdata(rtd->platform);
356 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 377 struct hsw_pcm_data *pcm_data;
357 struct sst_hsw *hsw = pdata->hsw; 378 struct sst_hsw *hsw = pdata->hsw;
358 struct sst_module *module_data; 379 struct sst_module *module_data;
359 struct sst_dsp *dsp; 380 struct sst_dsp *dsp;
@@ -362,7 +383,10 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
362 enum sst_hsw_stream_path_id path_id; 383 enum sst_hsw_stream_path_id path_id;
363 u32 rate, bits, map, pages, module_id; 384 u32 rate, bits, map, pages, module_id;
364 u8 channels; 385 u8 channels;
365 int ret; 386 int ret, dai;
387
388 dai = mod_map[rtd->cpu_dai->id].dai_id;
389 pcm_data = &pdata->pcm[dai][substream->stream];
366 390
367 /* check if we are being called a subsequent time */ 391 /* check if we are being called a subsequent time */
368 if (pcm_data->allocated) { 392 if (pcm_data->allocated) {
@@ -552,8 +576,12 @@ static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
552 struct snd_soc_pcm_runtime *rtd = substream->private_data; 576 struct snd_soc_pcm_runtime *rtd = substream->private_data;
553 struct hsw_priv_data *pdata = 577 struct hsw_priv_data *pdata =
554 snd_soc_platform_get_drvdata(rtd->platform); 578 snd_soc_platform_get_drvdata(rtd->platform);
555 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 579 struct hsw_pcm_data *pcm_data;
556 struct sst_hsw *hsw = pdata->hsw; 580 struct sst_hsw *hsw = pdata->hsw;
581 int dai;
582
583 dai = mod_map[rtd->cpu_dai->id].dai_id;
584 pcm_data = &pdata->pcm[dai][substream->stream];
557 585
558 switch (cmd) { 586 switch (cmd) {
559 case SNDRV_PCM_TRIGGER_START: 587 case SNDRV_PCM_TRIGGER_START:
@@ -597,11 +625,16 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
597 struct snd_pcm_runtime *runtime = substream->runtime; 625 struct snd_pcm_runtime *runtime = substream->runtime;
598 struct hsw_priv_data *pdata = 626 struct hsw_priv_data *pdata =
599 snd_soc_platform_get_drvdata(rtd->platform); 627 snd_soc_platform_get_drvdata(rtd->platform);
600 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 628 struct hsw_pcm_data *pcm_data;
601 struct sst_hsw *hsw = pdata->hsw; 629 struct sst_hsw *hsw = pdata->hsw;
602 snd_pcm_uframes_t offset; 630 snd_pcm_uframes_t offset;
603 uint64_t ppos; 631 uint64_t ppos;
604 u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream); 632 u32 position;
633 int dai;
634
635 dai = mod_map[rtd->cpu_dai->id].dai_id;
636 pcm_data = &pdata->pcm[dai][substream->stream];
637 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
605 638
606 offset = bytes_to_frames(runtime, position); 639 offset = bytes_to_frames(runtime, position);
607 ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); 640 ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
@@ -618,8 +651,10 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
618 snd_soc_platform_get_drvdata(rtd->platform); 651 snd_soc_platform_get_drvdata(rtd->platform);
619 struct hsw_pcm_data *pcm_data; 652 struct hsw_pcm_data *pcm_data;
620 struct sst_hsw *hsw = pdata->hsw; 653 struct sst_hsw *hsw = pdata->hsw;
654 int dai;
621 655
622 pcm_data = &pdata->pcm[rtd->cpu_dai->id]; 656 dai = mod_map[rtd->cpu_dai->id].dai_id;
657 pcm_data = &pdata->pcm[dai][substream->stream];
623 658
624 mutex_lock(&pcm_data->mutex); 659 mutex_lock(&pcm_data->mutex);
625 pm_runtime_get_sync(pdata->dev); 660 pm_runtime_get_sync(pdata->dev);
@@ -648,9 +683,12 @@ static int hsw_pcm_close(struct snd_pcm_substream *substream)
648 struct snd_soc_pcm_runtime *rtd = substream->private_data; 683 struct snd_soc_pcm_runtime *rtd = substream->private_data;
649 struct hsw_priv_data *pdata = 684 struct hsw_priv_data *pdata =
650 snd_soc_platform_get_drvdata(rtd->platform); 685 snd_soc_platform_get_drvdata(rtd->platform);
651 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 686 struct hsw_pcm_data *pcm_data;
652 struct sst_hsw *hsw = pdata->hsw; 687 struct sst_hsw *hsw = pdata->hsw;
653 int ret; 688 int ret, dai;
689
690 dai = mod_map[rtd->cpu_dai->id].dai_id;
691 pcm_data = &pdata->pcm[dai][substream->stream];
654 692
655 mutex_lock(&pcm_data->mutex); 693 mutex_lock(&pcm_data->mutex);
656 ret = sst_hsw_stream_reset(hsw, pcm_data->stream); 694 ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
@@ -685,15 +723,6 @@ static struct snd_pcm_ops hsw_pcm_ops = {
685 .page = snd_pcm_sgbuf_ops_page, 723 .page = snd_pcm_sgbuf_ops_page,
686}; 724};
687 725
688/* static mappings between PCMs and modules - may be dynamic in future */
689static struct hsw_pcm_module_map mod_map[] = {
690 {HSW_PCM_DAI_ID_SYSTEM, SST_HSW_MODULE_PCM_SYSTEM},
691 {HSW_PCM_DAI_ID_OFFLOAD0, SST_HSW_MODULE_PCM},
692 {HSW_PCM_DAI_ID_OFFLOAD1, SST_HSW_MODULE_PCM},
693 {HSW_PCM_DAI_ID_LOOPBACK, SST_HSW_MODULE_PCM_REFERENCE},
694 {HSW_PCM_DAI_ID_CAPTURE, SST_HSW_MODULE_PCM_CAPTURE},
695};
696
697static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) 726static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
698{ 727{
699 struct sst_hsw *hsw = pdata->hsw; 728 struct sst_hsw *hsw = pdata->hsw;
@@ -701,7 +730,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
701 int i; 730 int i;
702 731
703 for (i = 0; i < ARRAY_SIZE(mod_map); i++) { 732 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
704 pcm_data = &pdata->pcm[i]; 733 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
705 734
706 /* create new runtime module, use same offset if recreated */ 735 /* create new runtime module, use same offset if recreated */
707 pcm_data->runtime = sst_hsw_runtime_module_create(hsw, 736 pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
@@ -716,7 +745,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
716 745
717err: 746err:
718 for (--i; i >= 0; i--) { 747 for (--i; i >= 0; i--) {
719 pcm_data = &pdata->pcm[i]; 748 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
720 sst_hsw_runtime_module_free(pcm_data->runtime); 749 sst_hsw_runtime_module_free(pcm_data->runtime);
721 } 750 }
722 751
@@ -729,17 +758,12 @@ static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
729 int i; 758 int i;
730 759
731 for (i = 0; i < ARRAY_SIZE(mod_map); i++) { 760 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
732 pcm_data = &pdata->pcm[i]; 761 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
733 762
734 sst_hsw_runtime_module_free(pcm_data->runtime); 763 sst_hsw_runtime_module_free(pcm_data->runtime);
735 } 764 }
736} 765}
737 766
738static void hsw_pcm_free(struct snd_pcm *pcm)
739{
740 snd_pcm_lib_preallocate_free_for_all(pcm);
741}
742
743static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) 767static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
744{ 768{
745 struct snd_pcm *pcm = rtd->pcm; 769 struct snd_pcm *pcm = rtd->pcm;
@@ -762,7 +786,10 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
762 return ret; 786 return ret;
763 } 787 }
764 } 788 }
765 priv_data->pcm[rtd->cpu_dai->id].hsw_pcm = pcm; 789 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
790 priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_PLAYBACK].hsw_pcm = pcm;
791 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
792 priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_CAPTURE].hsw_pcm = pcm;
766 793
767 return ret; 794 return ret;
768} 795}
@@ -871,10 +898,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
871 /* allocate DSP buffer page tables */ 898 /* allocate DSP buffer page tables */
872 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { 899 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
873 900
874 mutex_init(&priv_data->pcm[i].mutex);
875
876 /* playback */ 901 /* playback */
877 if (hsw_dais[i].playback.channels_min) { 902 if (hsw_dais[i].playback.channels_min) {
903 mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_PLAYBACK].mutex);
878 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, 904 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
879 PAGE_SIZE, &priv_data->dmab[i][0]); 905 PAGE_SIZE, &priv_data->dmab[i][0]);
880 if (ret < 0) 906 if (ret < 0)
@@ -883,6 +909,7 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
883 909
884 /* capture */ 910 /* capture */
885 if (hsw_dais[i].capture.channels_min) { 911 if (hsw_dais[i].capture.channels_min) {
912 mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_CAPTURE].mutex);
886 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, 913 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
887 PAGE_SIZE, &priv_data->dmab[i][1]); 914 PAGE_SIZE, &priv_data->dmab[i][1]);
888 if (ret < 0) 915 if (ret < 0)
@@ -936,7 +963,6 @@ static struct snd_soc_platform_driver hsw_soc_platform = {
936 .remove = hsw_pcm_remove, 963 .remove = hsw_pcm_remove,
937 .ops = &hsw_pcm_ops, 964 .ops = &hsw_pcm_ops,
938 .pcm_new = hsw_pcm_new, 965 .pcm_new = hsw_pcm_new,
939 .pcm_free = hsw_pcm_free,
940}; 966};
941 967
942static const struct snd_soc_component_driver hsw_dai_component = { 968static const struct snd_soc_component_driver hsw_dai_component = {
@@ -1010,12 +1036,12 @@ static int hsw_pcm_runtime_suspend(struct device *dev)
1010 struct hsw_priv_data *pdata = dev_get_drvdata(dev); 1036 struct hsw_priv_data *pdata = dev_get_drvdata(dev);
1011 struct sst_hsw *hsw = pdata->hsw; 1037 struct sst_hsw *hsw = pdata->hsw;
1012 1038
1013 if (pdata->pm_state == HSW_PM_STATE_D3) 1039 if (pdata->pm_state >= HSW_PM_STATE_RTD3)
1014 return 0; 1040 return 0;
1015 1041
1016 sst_hsw_dsp_runtime_suspend(hsw); 1042 sst_hsw_dsp_runtime_suspend(hsw);
1017 sst_hsw_dsp_runtime_sleep(hsw); 1043 sst_hsw_dsp_runtime_sleep(hsw);
1018 pdata->pm_state = HSW_PM_STATE_D3; 1044 pdata->pm_state = HSW_PM_STATE_RTD3;
1019 1045
1020 return 0; 1046 return 0;
1021} 1047}
@@ -1026,7 +1052,7 @@ static int hsw_pcm_runtime_resume(struct device *dev)
1026 struct sst_hsw *hsw = pdata->hsw; 1052 struct sst_hsw *hsw = pdata->hsw;
1027 int ret; 1053 int ret;
1028 1054
1029 if (pdata->pm_state == HSW_PM_STATE_D0) 1055 if (pdata->pm_state != HSW_PM_STATE_RTD3)
1030 return 0; 1056 return 0;
1031 1057
1032 ret = sst_hsw_dsp_load(hsw); 1058 ret = sst_hsw_dsp_load(hsw);
@@ -1066,7 +1092,7 @@ static void hsw_pcm_complete(struct device *dev)
1066 struct hsw_pcm_data *pcm_data; 1092 struct hsw_pcm_data *pcm_data;
1067 int i, err; 1093 int i, err;
1068 1094
1069 if (pdata->pm_state == HSW_PM_STATE_D0) 1095 if (pdata->pm_state != HSW_PM_STATE_D3)
1070 return; 1096 return;
1071 1097
1072 err = sst_hsw_dsp_load(hsw); 1098 err = sst_hsw_dsp_load(hsw);
@@ -1081,8 +1107,8 @@ static void hsw_pcm_complete(struct device *dev)
1081 return; 1107 return;
1082 } 1108 }
1083 1109
1084 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { 1110 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
1085 pcm_data = &pdata->pcm[i]; 1111 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
1086 1112
1087 if (!pcm_data->substream) 1113 if (!pcm_data->substream)
1088 continue; 1114 continue;
@@ -1114,41 +1140,42 @@ static int hsw_pcm_prepare(struct device *dev)
1114 1140
1115 if (pdata->pm_state == HSW_PM_STATE_D3) 1141 if (pdata->pm_state == HSW_PM_STATE_D3)
1116 return 0; 1142 return 0;
1117 /* suspend all active streams */ 1143 else if (pdata->pm_state == HSW_PM_STATE_D0) {
1118 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { 1144 /* suspend all active streams */
1119 pcm_data = &pdata->pcm[i]; 1145 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
1146 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
1147
1148 if (!pcm_data->substream)
1149 continue;
1150 dev_dbg(dev, "suspending pcm %d\n", i);
1151 snd_pcm_suspend_all(pcm_data->hsw_pcm);
1152
1153 /* We need to wait until the DSP FW stops the streams */
1154 msleep(2);
1155 }
1120 1156
1121 if (!pcm_data->substream) 1157 /* preserve persistent memory */
1122 continue; 1158 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
1123 dev_dbg(dev, "suspending pcm %d\n", i); 1159 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
1124 snd_pcm_suspend_all(pcm_data->hsw_pcm); 1160
1161 if (!pcm_data->substream)
1162 continue;
1125 1163
1126 /* We need to wait until the DSP FW stops the streams */ 1164 dev_dbg(dev, "saving context pcm %d\n", i);
1127 msleep(2); 1165 err = sst_module_runtime_save(pcm_data->runtime,
1166 &pcm_data->context);
1167 if (err < 0)
1168 dev_err(dev, "failed to save context for PCM %d\n", i);
1169 }
1170 /* enter D3 state and stall */
1171 sst_hsw_dsp_runtime_suspend(hsw);
1172 /* put the DSP to sleep */
1173 sst_hsw_dsp_runtime_sleep(hsw);
1128 } 1174 }
1129 1175
1130 snd_soc_suspend(pdata->soc_card->dev); 1176 snd_soc_suspend(pdata->soc_card->dev);
1131 snd_soc_poweroff(pdata->soc_card->dev); 1177 snd_soc_poweroff(pdata->soc_card->dev);
1132 1178
1133 /* enter D3 state and stall */
1134 sst_hsw_dsp_runtime_suspend(hsw);
1135
1136 /* preserve persistent memory */
1137 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) {
1138 pcm_data = &pdata->pcm[i];
1139
1140 if (!pcm_data->substream)
1141 continue;
1142
1143 dev_dbg(dev, "saving context pcm %d\n", i);
1144 err = sst_module_runtime_save(pcm_data->runtime,
1145 &pcm_data->context);
1146 if (err < 0)
1147 dev_err(dev, "failed to save context for PCM %d\n", i);
1148 }
1149
1150 /* put the DSP to sleep */
1151 sst_hsw_dsp_runtime_sleep(hsw);
1152 pdata->pm_state = HSW_PM_STATE_D3; 1179 pdata->pm_state = HSW_PM_STATE_D3;
1153 1180
1154 return 0; 1181 return 0;
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c
index a1a8d9d91539..7523cbef8780 100644
--- a/sound/soc/intel/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/sst-mfld-platform-pcm.c
@@ -643,12 +643,6 @@ static struct snd_pcm_ops sst_platform_ops = {
643 .pointer = sst_platform_pcm_pointer, 643 .pointer = sst_platform_pcm_pointer,
644}; 644};
645 645
646static void sst_pcm_free(struct snd_pcm *pcm)
647{
648 dev_dbg(pcm->dev, "sst_pcm_free called\n");
649 snd_pcm_lib_preallocate_free_for_all(pcm);
650}
651
652static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) 646static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
653{ 647{
654 struct snd_soc_dai *dai = rtd->cpu_dai; 648 struct snd_soc_dai *dai = rtd->cpu_dai;
@@ -679,7 +673,6 @@ static struct snd_soc_platform_driver sst_soc_platform_drv = {
679 .ops = &sst_platform_ops, 673 .ops = &sst_platform_ops,
680 .compr_ops = &sst_platform_compr_ops, 674 .compr_ops = &sst_platform_compr_ops,
681 .pcm_new = sst_pcm_new, 675 .pcm_new = sst_pcm_new,
682 .pcm_free = sst_pcm_free,
683}; 676};
684 677
685static const struct snd_soc_component_driver sst_component = { 678static const struct snd_soc_component_driver sst_component = {
diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c
index e541d0e69ea2..b782dfdcdbba 100644
--- a/sound/soc/intel/sst/sst_acpi.c
+++ b/sound/soc/intel/sst/sst_acpi.c
@@ -352,6 +352,8 @@ static struct sst_machines sst_acpi_bytcr[] = {
352static struct sst_machines sst_acpi_chv[] = { 352static struct sst_machines sst_acpi_chv[] = {
353 {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "intel/fw_sst_22a8.bin", 353 {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "intel/fw_sst_22a8.bin",
354 &chv_platform_data }, 354 &chv_platform_data },
355 {"10EC5645", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin",
356 &chv_platform_data },
355 {}, 357 {},
356}; 358};
357 359
diff --git a/sound/soc/intel/sst/sst_loader.c b/sound/soc/intel/sst/sst_loader.c
index b580f96e25e5..7888cd707853 100644
--- a/sound/soc/intel/sst/sst_loader.c
+++ b/sound/soc/intel/sst/sst_loader.c
@@ -324,8 +324,7 @@ void sst_firmware_load_cb(const struct firmware *fw, void *context)
324 324
325 if (ctx->sst_state != SST_RESET || 325 if (ctx->sst_state != SST_RESET ||
326 ctx->fw_in_mem != NULL) { 326 ctx->fw_in_mem != NULL) {
327 if (fw != NULL) 327 release_firmware(fw);
328 release_firmware(fw);
329 mutex_unlock(&ctx->sst_lock); 328 mutex_unlock(&ctx->sst_lock);
330 return; 329 return;
331 } 330 }
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index d3d45c6f064f..07f77815a586 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -14,6 +14,8 @@
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/of.h>
18#include <linux/of_device.h>
17#include <linux/kernel.h> 19#include <linux/kernel.h>
18#include <linux/module.h> 20#include <linux/module.h>
19#include <linux/platform_device.h> 21#include <linux/platform_device.h>
@@ -83,6 +85,8 @@
83#define JZ_AIC_I2S_STATUS_BUSY BIT(2) 85#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
84 86
85#define JZ_AIC_CLK_DIV_MASK 0xf 87#define JZ_AIC_CLK_DIV_MASK 0xf
88#define I2SDIV_DV_SHIFT 8
89#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
86 90
87struct jz4740_i2s { 91struct jz4740_i2s {
88 struct resource *mem; 92 struct resource *mem;
@@ -237,10 +241,14 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
237{ 241{
238 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); 242 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
239 unsigned int sample_size; 243 unsigned int sample_size;
240 uint32_t ctrl; 244 uint32_t ctrl, div_reg;
245 int div;
241 246
242 ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL); 247 ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
243 248
249 div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV);
250 div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
251
244 switch (params_format(params)) { 252 switch (params_format(params)) {
245 case SNDRV_PCM_FORMAT_S8: 253 case SNDRV_PCM_FORMAT_S8:
246 sample_size = 0; 254 sample_size = 0;
@@ -264,7 +272,10 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
264 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; 272 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
265 } 273 }
266 274
275 div_reg &= ~I2SDIV_DV_MASK;
276 div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
267 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); 277 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
278 jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
268 279
269 return 0; 280 return 0;
270} 281}
@@ -415,6 +426,13 @@ static const struct snd_soc_component_driver jz4740_i2s_component = {
415 .name = "jz4740-i2s", 426 .name = "jz4740-i2s",
416}; 427};
417 428
429#ifdef CONFIG_OF
430static const struct of_device_id jz4740_of_matches[] = {
431 { .compatible = "ingenic,jz4740-i2s" },
432 { /* sentinel */ }
433};
434#endif
435
418static int jz4740_i2s_dev_probe(struct platform_device *pdev) 436static int jz4740_i2s_dev_probe(struct platform_device *pdev)
419{ 437{
420 struct jz4740_i2s *i2s; 438 struct jz4740_i2s *i2s;
@@ -455,6 +473,7 @@ static struct platform_driver jz4740_i2s_driver = {
455 .probe = jz4740_i2s_dev_probe, 473 .probe = jz4740_i2s_dev_probe,
456 .driver = { 474 .driver = {
457 .name = "jz4740-i2s", 475 .name = "jz4740-i2s",
476 .of_match_table = of_match_ptr(jz4740_of_matches)
458 }, 477 },
459}; 478};
460 479