aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-03-24 07:16:33 -0400
committerMark Brown <broonie@linaro.org>2014-03-24 07:16:33 -0400
commitb51086eaee34a2a6fd34f8a37c8e77d1b1c07a44 (patch)
tree932726a834e171663258fbcf88dfde5e04deff2d /sound
parent10885d8734a1bf3543c49851830acf3085428df1 (diff)
parente090d5b6ad20056ec0ef58727e3ae95fd82be090 (diff)
Merge tag 'asoc-v3.15-3' into asoc-next
ASoC: Updates for v3.15 A few more updates for the merge window: - Fixes for the simple-card DAI format DT mess. - A new driver for Cirrus cs42xx8 devices. - DT support for a couple more devices. - A revert of a previous buggy fix for soc-pcm, plus a few more fixes and cleanups. # gpg: Signature made Sun 23 Mar 2014 16:56:11 GMT using RSA key ID 7EA229BD # gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>" # gpg: aka "Mark Brown <broonie@debian.org>" # gpg: aka "Mark Brown <broonie@kernel.org>" # gpg: aka "Mark Brown <broonie@tardis.ed.ac.uk>" # gpg: aka "Mark Brown <broonie@linaro.org>" # gpg: aka "Mark Brown <Mark.Brown@linaro.org>"
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/Kconfig10
-rw-r--r--sound/soc/codecs/Makefile4
-rw-r--r--sound/soc/codecs/cs42xx8-i2c.c64
-rw-r--r--sound/soc/codecs/cs42xx8.c602
-rw-r--r--sound/soc/codecs/cs42xx8.h238
-rw-r--r--sound/soc/codecs/isabelle.c3
-rw-r--r--sound/soc/codecs/max98090.c1
-rw-r--r--sound/soc/codecs/max98090.h1
-rw-r--r--sound/soc/codecs/mc13783.c6
-rw-r--r--sound/soc/codecs/rt5640.c3
-rw-r--r--sound/soc/codecs/sirf-audio-codec.c9
-rw-r--r--sound/soc/codecs/sta529.c3
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c39
-rw-r--r--sound/soc/codecs/uda134x.c3
-rw-r--r--sound/soc/codecs/uda1380.c3
-rw-r--r--sound/soc/codecs/wm8580.c3
-rw-r--r--sound/soc/davinci/davinci-evm.c22
-rw-r--r--sound/soc/davinci/davinci-mcasp.c21
-rw-r--r--sound/soc/davinci/edma-pcm.c57
-rw-r--r--sound/soc/davinci/edma-pcm.h25
-rw-r--r--sound/soc/generic/simple-card.c80
-rw-r--r--sound/soc/intel/mfld_machine.c51
-rw-r--r--sound/soc/kirkwood/Kconfig1
-rw-r--r--sound/soc/kirkwood/armada-370-db.c28
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c3
-rw-r--r--sound/soc/sh/rcar/adg.c1
-rw-r--r--sound/soc/sh/rcar/core.c122
-rw-r--r--sound/soc/sh/rcar/gen.c15
-rw-r--r--sound/soc/sh/rcar/rsnd.h11
-rw-r--r--sound/soc/sh/rcar/src.c36
-rw-r--r--sound/soc/sh/rcar/ssi.c56
-rw-r--r--sound/soc/soc-io.c35
32 files changed, 1393 insertions, 163 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1a8ff1e541ef..f0e840137887 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -44,6 +44,7 @@ config SND_SOC_ALL_CODECS
44 select SND_SOC_CS42L73 if I2C 44 select SND_SOC_CS42L73 if I2C
45 select SND_SOC_CS4270 if I2C 45 select SND_SOC_CS4270 if I2C
46 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI 46 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
47 select SND_SOC_CS42XX8_I2C if I2C
47 select SND_SOC_CX20442 if TTY 48 select SND_SOC_CX20442 if TTY
48 select SND_SOC_DA7210 if I2C 49 select SND_SOC_DA7210 if I2C
49 select SND_SOC_DA7213 if I2C 50 select SND_SOC_DA7213 if I2C
@@ -304,6 +305,15 @@ config SND_SOC_CS4271
304 tristate "Cirrus Logic CS4271 CODEC" 305 tristate "Cirrus Logic CS4271 CODEC"
305 depends on SND_SOC_I2C_AND_SPI 306 depends on SND_SOC_I2C_AND_SPI
306 307
308config SND_SOC_CS42XX8
309 tristate
310
311config SND_SOC_CS42XX8_I2C
312 tristate "Cirrus Logic CS42448/CS42888 CODEC (I2C)"
313 depends on I2C
314 select SND_SOC_CS42XX8
315 select REGMAP_I2C
316
307config SND_SOC_CX20442 317config SND_SOC_CX20442
308 tristate 318 tristate
309 depends on TTY 319 depends on TTY
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 73df822885de..3c4d275d064b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -30,6 +30,8 @@ snd-soc-cs42l52-objs := cs42l52.o
30snd-soc-cs42l73-objs := cs42l73.o 30snd-soc-cs42l73-objs := cs42l73.o
31snd-soc-cs4270-objs := cs4270.o 31snd-soc-cs4270-objs := cs4270.o
32snd-soc-cs4271-objs := cs4271.o 32snd-soc-cs4271-objs := cs4271.o
33snd-soc-cs42xx8-objs := cs42xx8.o
34snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
33snd-soc-cx20442-objs := cx20442.o 35snd-soc-cx20442-objs := cx20442.o
34snd-soc-da7210-objs := da7210.o 36snd-soc-da7210-objs := da7210.o
35snd-soc-da7213-objs := da7213.o 37snd-soc-da7213-objs := da7213.o
@@ -179,6 +181,8 @@ obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
179obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o 181obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
180obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 182obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
181obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o 183obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
184obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
185obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
182obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 186obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
183obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 187obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
184obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o 188obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
diff --git a/sound/soc/codecs/cs42xx8-i2c.c b/sound/soc/codecs/cs42xx8-i2c.c
new file mode 100644
index 000000000000..657dce27eade
--- /dev/null
+++ b/sound/soc/codecs/cs42xx8-i2c.c
@@ -0,0 +1,64 @@
1/*
2 * Cirrus Logic CS42448/CS42888 Audio CODEC DAI I2C driver
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#include <linux/i2c.h>
14#include <linux/module.h>
15#include <linux/pm_runtime.h>
16#include <sound/soc.h>
17
18#include "cs42xx8.h"
19
20static int cs42xx8_i2c_probe(struct i2c_client *i2c,
21 const struct i2c_device_id *id)
22{
23 u32 ret = cs42xx8_probe(&i2c->dev,
24 devm_regmap_init_i2c(i2c, &cs42xx8_regmap_config));
25 if (ret)
26 return ret;
27
28 pm_runtime_enable(&i2c->dev);
29 pm_request_idle(&i2c->dev);
30
31 return 0;
32}
33
34static int cs42xx8_i2c_remove(struct i2c_client *i2c)
35{
36 snd_soc_unregister_codec(&i2c->dev);
37 pm_runtime_disable(&i2c->dev);
38
39 return 0;
40}
41
42static struct i2c_device_id cs42xx8_i2c_id[] = {
43 {"cs42448", (kernel_ulong_t)&cs42448_data},
44 {"cs42888", (kernel_ulong_t)&cs42888_data},
45 {}
46};
47MODULE_DEVICE_TABLE(i2c, cs42xx8_i2c_id);
48
49static struct i2c_driver cs42xx8_i2c_driver = {
50 .driver = {
51 .name = "cs42xx8",
52 .owner = THIS_MODULE,
53 .pm = &cs42xx8_pm,
54 },
55 .probe = cs42xx8_i2c_probe,
56 .remove = cs42xx8_i2c_remove,
57 .id_table = cs42xx8_i2c_id,
58};
59
60module_i2c_driver(cs42xx8_i2c_driver);
61
62MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec I2C Driver");
63MODULE_AUTHOR("Freescale Semiconductor, Inc.");
64MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
new file mode 100644
index 000000000000..082299a4e2fa
--- /dev/null
+++ b/sound/soc/codecs/cs42xx8.c
@@ -0,0 +1,602 @@
1/*
2 * Cirrus Logic CS42448/CS42888 Audio CODEC Digital Audio Interface (DAI) driver
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/module.h>
16#include <linux/of_device.h>
17#include <linux/pm_runtime.h>
18#include <linux/regulator/consumer.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/tlv.h>
22
23#include "cs42xx8.h"
24
25#define CS42XX8_NUM_SUPPLIES 4
26static const char *const cs42xx8_supply_names[CS42XX8_NUM_SUPPLIES] = {
27 "VA",
28 "VD",
29 "VLS",
30 "VLC",
31};
32
33#define CS42XX8_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
34 SNDRV_PCM_FMTBIT_S20_3LE | \
35 SNDRV_PCM_FMTBIT_S24_LE | \
36 SNDRV_PCM_FMTBIT_S32_LE)
37
38/* codec private data */
39struct cs42xx8_priv {
40 struct regulator_bulk_data supplies[CS42XX8_NUM_SUPPLIES];
41 const struct cs42xx8_driver_data *drvdata;
42 struct regmap *regmap;
43 struct clk *clk;
44
45 bool slave_mode;
46 unsigned long sysclk;
47};
48
49/* -127.5dB to 0dB with step of 0.5dB */
50static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
51/* -64dB to 24dB with step of 0.5dB */
52static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 0);
53
54static const char *const cs42xx8_adc_single[] = { "Differential", "Single-Ended" };
55static const char *const cs42xx8_szc[] = { "Immediate Change", "Zero Cross",
56 "Soft Ramp", "Soft Ramp on Zero Cross" };
57
58static const struct soc_enum adc1_single_enum =
59 SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 4, 2, cs42xx8_adc_single);
60static const struct soc_enum adc2_single_enum =
61 SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 3, 2, cs42xx8_adc_single);
62static const struct soc_enum adc3_single_enum =
63 SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 2, 2, cs42xx8_adc_single);
64static const struct soc_enum dac_szc_enum =
65 SOC_ENUM_SINGLE(CS42XX8_TXCTL, 5, 4, cs42xx8_szc);
66static const struct soc_enum adc_szc_enum =
67 SOC_ENUM_SINGLE(CS42XX8_TXCTL, 0, 4, cs42xx8_szc);
68
69static const struct snd_kcontrol_new cs42xx8_snd_controls[] = {
70 SOC_DOUBLE_R_TLV("DAC1 Playback Volume", CS42XX8_VOLAOUT1,
71 CS42XX8_VOLAOUT2, 0, 0xff, 1, dac_tlv),
72 SOC_DOUBLE_R_TLV("DAC2 Playback Volume", CS42XX8_VOLAOUT3,
73 CS42XX8_VOLAOUT4, 0, 0xff, 1, dac_tlv),
74 SOC_DOUBLE_R_TLV("DAC3 Playback Volume", CS42XX8_VOLAOUT5,
75 CS42XX8_VOLAOUT6, 0, 0xff, 1, dac_tlv),
76 SOC_DOUBLE_R_TLV("DAC4 Playback Volume", CS42XX8_VOLAOUT7,
77 CS42XX8_VOLAOUT8, 0, 0xff, 1, dac_tlv),
78 SOC_DOUBLE_R_S_TLV("ADC1 Capture Volume", CS42XX8_VOLAIN1,
79 CS42XX8_VOLAIN2, 0, -0x80, 0x30, 7, 0, adc_tlv),
80 SOC_DOUBLE_R_S_TLV("ADC2 Capture Volume", CS42XX8_VOLAIN3,
81 CS42XX8_VOLAIN4, 0, -0x80, 0x30, 7, 0, adc_tlv),
82 SOC_DOUBLE("DAC1 Invert Switch", CS42XX8_DACINV, 0, 1, 1, 0),
83 SOC_DOUBLE("DAC2 Invert Switch", CS42XX8_DACINV, 2, 3, 1, 0),
84 SOC_DOUBLE("DAC3 Invert Switch", CS42XX8_DACINV, 4, 5, 1, 0),
85 SOC_DOUBLE("DAC4 Invert Switch", CS42XX8_DACINV, 6, 7, 1, 0),
86 SOC_DOUBLE("ADC1 Invert Switch", CS42XX8_ADCINV, 0, 1, 1, 0),
87 SOC_DOUBLE("ADC2 Invert Switch", CS42XX8_ADCINV, 2, 3, 1, 0),
88 SOC_SINGLE("ADC High-Pass Filter Switch", CS42XX8_ADCCTL, 7, 1, 1),
89 SOC_SINGLE("DAC De-emphasis Switch", CS42XX8_ADCCTL, 5, 1, 0),
90 SOC_ENUM("ADC1 Single Ended Mode Switch", adc1_single_enum),
91 SOC_ENUM("ADC2 Single Ended Mode Switch", adc2_single_enum),
92 SOC_SINGLE("DAC Single Volume Control Switch", CS42XX8_TXCTL, 7, 1, 0),
93 SOC_ENUM("DAC Soft Ramp & Zero Cross Control Switch", dac_szc_enum),
94 SOC_SINGLE("DAC Auto Mute Switch", CS42XX8_TXCTL, 4, 1, 0),
95 SOC_SINGLE("Mute ADC Serial Port Switch", CS42XX8_TXCTL, 3, 1, 0),
96 SOC_SINGLE("ADC Single Volume Control Switch", CS42XX8_TXCTL, 2, 1, 0),
97 SOC_ENUM("ADC Soft Ramp & Zero Cross Control Switch", adc_szc_enum),
98};
99
100static const struct snd_kcontrol_new cs42xx8_adc3_snd_controls[] = {
101 SOC_DOUBLE_R_S_TLV("ADC3 Capture Volume", CS42XX8_VOLAIN5,
102 CS42XX8_VOLAIN6, 0, -0x80, 0x30, 7, 0, adc_tlv),
103 SOC_DOUBLE("ADC3 Invert Switch", CS42XX8_ADCINV, 4, 5, 1, 0),
104 SOC_ENUM("ADC3 Single Ended Mode Switch", adc3_single_enum),
105};
106
107static const struct snd_soc_dapm_widget cs42xx8_dapm_widgets[] = {
108 SND_SOC_DAPM_DAC("DAC1", "Playback", CS42XX8_PWRCTL, 1, 1),
109 SND_SOC_DAPM_DAC("DAC2", "Playback", CS42XX8_PWRCTL, 2, 1),
110 SND_SOC_DAPM_DAC("DAC3", "Playback", CS42XX8_PWRCTL, 3, 1),
111 SND_SOC_DAPM_DAC("DAC4", "Playback", CS42XX8_PWRCTL, 4, 1),
112
113 SND_SOC_DAPM_OUTPUT("AOUT1L"),
114 SND_SOC_DAPM_OUTPUT("AOUT1R"),
115 SND_SOC_DAPM_OUTPUT("AOUT2L"),
116 SND_SOC_DAPM_OUTPUT("AOUT2R"),
117 SND_SOC_DAPM_OUTPUT("AOUT3L"),
118 SND_SOC_DAPM_OUTPUT("AOUT3R"),
119 SND_SOC_DAPM_OUTPUT("AOUT4L"),
120 SND_SOC_DAPM_OUTPUT("AOUT4R"),
121
122 SND_SOC_DAPM_ADC("ADC1", "Capture", CS42XX8_PWRCTL, 5, 1),
123 SND_SOC_DAPM_ADC("ADC2", "Capture", CS42XX8_PWRCTL, 6, 1),
124
125 SND_SOC_DAPM_INPUT("AIN1L"),
126 SND_SOC_DAPM_INPUT("AIN1R"),
127 SND_SOC_DAPM_INPUT("AIN2L"),
128 SND_SOC_DAPM_INPUT("AIN2R"),
129
130 SND_SOC_DAPM_SUPPLY("PWR", CS42XX8_PWRCTL, 0, 1, NULL, 0),
131};
132
133static const struct snd_soc_dapm_widget cs42xx8_adc3_dapm_widgets[] = {
134 SND_SOC_DAPM_ADC("ADC3", "Capture", CS42XX8_PWRCTL, 7, 1),
135
136 SND_SOC_DAPM_INPUT("AIN3L"),
137 SND_SOC_DAPM_INPUT("AIN3R"),
138};
139
140static const struct snd_soc_dapm_route cs42xx8_dapm_routes[] = {
141 /* Playback */
142 { "AOUT1L", NULL, "DAC1" },
143 { "AOUT1R", NULL, "DAC1" },
144 { "DAC1", NULL, "PWR" },
145
146 { "AOUT2L", NULL, "DAC2" },
147 { "AOUT2R", NULL, "DAC2" },
148 { "DAC2", NULL, "PWR" },
149
150 { "AOUT3L", NULL, "DAC3" },
151 { "AOUT3R", NULL, "DAC3" },
152 { "DAC3", NULL, "PWR" },
153
154 { "AOUT4L", NULL, "DAC4" },
155 { "AOUT4R", NULL, "DAC4" },
156 { "DAC4", NULL, "PWR" },
157
158 /* Capture */
159 { "ADC1", NULL, "AIN1L" },
160 { "ADC1", NULL, "AIN1R" },
161 { "ADC1", NULL, "PWR" },
162
163 { "ADC2", NULL, "AIN2L" },
164 { "ADC2", NULL, "AIN2R" },
165 { "ADC2", NULL, "PWR" },
166};
167
168static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = {
169 /* Capture */
170 { "ADC3", NULL, "AIN3L" },
171 { "ADC3", NULL, "AIN3R" },
172 { "ADC3", NULL, "PWR" },
173};
174
175struct cs42xx8_ratios {
176 unsigned int ratio;
177 unsigned char speed;
178 unsigned char mclk;
179};
180
181static const struct cs42xx8_ratios cs42xx8_ratios[] = {
182 { 64, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_256(4) },
183 { 96, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_384(4) },
184 { 128, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_512(4) },
185 { 192, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_768(4) },
186 { 256, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_256(1) },
187 { 384, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_384(1) },
188 { 512, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_512(1) },
189 { 768, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_768(1) },
190 { 1024, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_1024(1) }
191};
192
193static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
194 int clk_id, unsigned int freq, int dir)
195{
196 struct snd_soc_codec *codec = codec_dai->codec;
197 struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
198
199 cs42xx8->sysclk = freq;
200
201 return 0;
202}
203
204static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
205 unsigned int format)
206{
207 struct snd_soc_codec *codec = codec_dai->codec;
208 struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
209 u32 val;
210
211 /* Set DAI format */
212 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
213 case SND_SOC_DAIFMT_LEFT_J:
214 val = CS42XX8_INTF_DAC_DIF_LEFTJ | CS42XX8_INTF_ADC_DIF_LEFTJ;
215 break;
216 case SND_SOC_DAIFMT_I2S:
217 val = CS42XX8_INTF_DAC_DIF_I2S | CS42XX8_INTF_ADC_DIF_I2S;
218 break;
219 case SND_SOC_DAIFMT_RIGHT_J:
220 val = CS42XX8_INTF_DAC_DIF_RIGHTJ | CS42XX8_INTF_ADC_DIF_RIGHTJ;
221 break;
222 default:
223 dev_err(codec->dev, "unsupported dai format\n");
224 return -EINVAL;
225 }
226
227 regmap_update_bits(cs42xx8->regmap, CS42XX8_INTF,
228 CS42XX8_INTF_DAC_DIF_MASK |
229 CS42XX8_INTF_ADC_DIF_MASK, val);
230
231 /* Set master/slave audio interface */
232 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
233 case SND_SOC_DAIFMT_CBS_CFS:
234 cs42xx8->slave_mode = true;
235 break;
236 case SND_SOC_DAIFMT_CBM_CFM:
237 cs42xx8->slave_mode = false;
238 break;
239 default:
240 dev_err(codec->dev, "unsupported master/slave mode\n");
241 return -EINVAL;
242 }
243
244 return 0;
245}
246
247static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
248 struct snd_pcm_hw_params *params,
249 struct snd_soc_dai *dai)
250{
251 struct snd_soc_pcm_runtime *rtd = substream->private_data;
252 struct snd_soc_codec *codec = rtd->codec;
253 struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
254 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
255 u32 ratio = cs42xx8->sysclk / params_rate(params);
256 u32 i, fm, val, mask;
257
258 for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
259 if (cs42xx8_ratios[i].ratio == ratio)
260 break;
261 }
262
263 if (i == ARRAY_SIZE(cs42xx8_ratios)) {
264 dev_err(codec->dev, "unsupported sysclk ratio\n");
265 return -EINVAL;
266 }
267
268 mask = CS42XX8_FUNCMOD_MFREQ_MASK;
269 val = cs42xx8_ratios[i].mclk;
270
271 fm = cs42xx8->slave_mode ? CS42XX8_FM_AUTO : cs42xx8_ratios[i].speed;
272
273 regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
274 CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask,
275 CS42XX8_FUNCMOD_xC_FM(tx, fm) | val);
276
277 return 0;
278}
279
280static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute)
281{
282 struct snd_soc_codec *codec = dai->codec;
283 struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
284
285 regmap_update_bits(cs42xx8->regmap, CS42XX8_DACMUTE,
286 CS42XX8_DACMUTE_ALL, mute ? CS42XX8_DACMUTE_ALL : 0);
287
288 return 0;
289}
290
291static const struct snd_soc_dai_ops cs42xx8_dai_ops = {
292 .set_fmt = cs42xx8_set_dai_fmt,
293 .set_sysclk = cs42xx8_set_dai_sysclk,
294 .hw_params = cs42xx8_hw_params,
295 .digital_mute = cs42xx8_digital_mute,
296};
297
298static struct snd_soc_dai_driver cs42xx8_dai = {
299 .playback = {
300 .stream_name = "Playback",
301 .channels_min = 1,
302 .channels_max = 8,
303 .rates = SNDRV_PCM_RATE_8000_192000,
304 .formats = CS42XX8_FORMATS,
305 },
306 .capture = {
307 .stream_name = "Capture",
308 .channels_min = 1,
309 .rates = SNDRV_PCM_RATE_8000_192000,
310 .formats = CS42XX8_FORMATS,
311 },
312 .ops = &cs42xx8_dai_ops,
313};
314
315static const struct reg_default cs42xx8_reg[] = {
316 { 0x01, 0x01 }, /* Chip I.D. and Revision Register */
317 { 0x02, 0x00 }, /* Power Control */
318 { 0x03, 0xF0 }, /* Functional Mode */
319 { 0x04, 0x46 }, /* Interface Formats */
320 { 0x05, 0x00 }, /* ADC Control & DAC De-Emphasis */
321 { 0x06, 0x10 }, /* Transition Control */
322 { 0x07, 0x00 }, /* DAC Channel Mute */
323 { 0x08, 0x00 }, /* Volume Control AOUT1 */
324 { 0x09, 0x00 }, /* Volume Control AOUT2 */
325 { 0x0a, 0x00 }, /* Volume Control AOUT3 */
326 { 0x0b, 0x00 }, /* Volume Control AOUT4 */
327 { 0x0c, 0x00 }, /* Volume Control AOUT5 */
328 { 0x0d, 0x00 }, /* Volume Control AOUT6 */
329 { 0x0e, 0x00 }, /* Volume Control AOUT7 */
330 { 0x0f, 0x00 }, /* Volume Control AOUT8 */
331 { 0x10, 0x00 }, /* DAC Channel Invert */
332 { 0x11, 0x00 }, /* Volume Control AIN1 */
333 { 0x12, 0x00 }, /* Volume Control AIN2 */
334 { 0x13, 0x00 }, /* Volume Control AIN3 */
335 { 0x14, 0x00 }, /* Volume Control AIN4 */
336 { 0x15, 0x00 }, /* Volume Control AIN5 */
337 { 0x16, 0x00 }, /* Volume Control AIN6 */
338 { 0x17, 0x00 }, /* ADC Channel Invert */
339 { 0x18, 0x00 }, /* Status Control */
340 { 0x1a, 0x00 }, /* Status Mask */
341 { 0x1b, 0x00 }, /* MUTEC Pin Control */
342};
343
344static bool cs42xx8_volatile_register(struct device *dev, unsigned int reg)
345{
346 switch (reg) {
347 case CS42XX8_STATUS:
348 return true;
349 default:
350 return false;
351 }
352}
353
354static bool cs42xx8_writeable_register(struct device *dev, unsigned int reg)
355{
356 switch (reg) {
357 case CS42XX8_CHIPID:
358 case CS42XX8_STATUS:
359 return false;
360 default:
361 return true;
362 }
363}
364
365const struct regmap_config cs42xx8_regmap_config = {
366 .reg_bits = 8,
367 .val_bits = 8,
368
369 .max_register = CS42XX8_LASTREG,
370 .reg_defaults = cs42xx8_reg,
371 .num_reg_defaults = ARRAY_SIZE(cs42xx8_reg),
372 .volatile_reg = cs42xx8_volatile_register,
373 .writeable_reg = cs42xx8_writeable_register,
374 .cache_type = REGCACHE_RBTREE,
375};
376EXPORT_SYMBOL_GPL(cs42xx8_regmap_config);
377
378static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
379{
380 struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
381 struct snd_soc_dapm_context *dapm = &codec->dapm;
382
383 switch (cs42xx8->drvdata->num_adcs) {
384 case 3:
385 snd_soc_add_codec_controls(codec, cs42xx8_adc3_snd_controls,
386 ARRAY_SIZE(cs42xx8_adc3_snd_controls));
387 snd_soc_dapm_new_controls(dapm, cs42xx8_adc3_dapm_widgets,
388 ARRAY_SIZE(cs42xx8_adc3_dapm_widgets));
389 snd_soc_dapm_add_routes(dapm, cs42xx8_adc3_dapm_routes,
390 ARRAY_SIZE(cs42xx8_adc3_dapm_routes));
391 break;
392 default:
393 break;
394 }
395
396 /* Mute all DAC channels */
397 regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE, CS42XX8_DACMUTE_ALL);
398
399 return 0;
400}
401
402static const struct snd_soc_codec_driver cs42xx8_driver = {
403 .probe = cs42xx8_codec_probe,
404 .idle_bias_off = true,
405
406 .controls = cs42xx8_snd_controls,
407 .num_controls = ARRAY_SIZE(cs42xx8_snd_controls),
408 .dapm_widgets = cs42xx8_dapm_widgets,
409 .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets),
410 .dapm_routes = cs42xx8_dapm_routes,
411 .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes),
412};
413
414const struct cs42xx8_driver_data cs42448_data = {
415 .name = "cs42448",
416 .num_adcs = 3,
417};
418EXPORT_SYMBOL_GPL(cs42448_data);
419
420const struct cs42xx8_driver_data cs42888_data = {
421 .name = "cs42888",
422 .num_adcs = 2,
423};
424EXPORT_SYMBOL_GPL(cs42888_data);
425
426const struct of_device_id cs42xx8_of_match[] = {
427 { .compatible = "cirrus,cs42448", .data = &cs42448_data, },
428 { .compatible = "cirrus,cs42888", .data = &cs42888_data, },
429 { /* sentinel */ }
430};
431MODULE_DEVICE_TABLE(of, cs42xx8_of_match);
432EXPORT_SYMBOL_GPL(cs42xx8_of_match);
433
434int cs42xx8_probe(struct device *dev, struct regmap *regmap)
435{
436 const struct of_device_id *of_id = of_match_device(cs42xx8_of_match, dev);
437 struct cs42xx8_priv *cs42xx8;
438 int ret, val, i;
439
440 cs42xx8 = devm_kzalloc(dev, sizeof(*cs42xx8), GFP_KERNEL);
441 if (cs42xx8 == NULL)
442 return -ENOMEM;
443
444 dev_set_drvdata(dev, cs42xx8);
445
446 if (of_id)
447 cs42xx8->drvdata = of_id->data;
448
449 if (!cs42xx8->drvdata) {
450 dev_err(dev, "failed to find driver data\n");
451 return -EINVAL;
452 }
453
454 cs42xx8->clk = devm_clk_get(dev, "mclk");
455 if (IS_ERR(cs42xx8->clk)) {
456 dev_err(dev, "failed to get the clock: %ld\n",
457 PTR_ERR(cs42xx8->clk));
458 return -EINVAL;
459 }
460
461 cs42xx8->sysclk = clk_get_rate(cs42xx8->clk);
462
463 for (i = 0; i < ARRAY_SIZE(cs42xx8->supplies); i++)
464 cs42xx8->supplies[i].supply = cs42xx8_supply_names[i];
465
466 ret = devm_regulator_bulk_get(dev,
467 ARRAY_SIZE(cs42xx8->supplies), cs42xx8->supplies);
468 if (ret) {
469 dev_err(dev, "failed to request supplies: %d\n", ret);
470 return ret;
471 }
472
473 ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
474 cs42xx8->supplies);
475 if (ret) {
476 dev_err(dev, "failed to enable supplies: %d\n", ret);
477 return ret;
478 }
479
480 /* Make sure hardware reset done */
481 msleep(5);
482
483 cs42xx8->regmap = regmap;
484 if (IS_ERR(cs42xx8->regmap)) {
485 ret = PTR_ERR(cs42xx8->regmap);
486 dev_err(dev, "failed to allocate regmap: %d\n", ret);
487 goto err_enable;
488 }
489
490 /*
491 * We haven't marked the chip revision as volatile due to
492 * sharing a register with the right input volume; explicitly
493 * bypass the cache to read it.
494 */
495 regcache_cache_bypass(cs42xx8->regmap, true);
496
497 /* Validate the chip ID */
498 regmap_read(cs42xx8->regmap, CS42XX8_CHIPID, &val);
499 if (val < 0) {
500 dev_err(dev, "failed to get device ID: %x", val);
501 ret = -EINVAL;
502 goto err_enable;
503 }
504
505 /* The top four bits of the chip ID should be 0000 */
506 if ((val & CS42XX8_CHIPID_CHIP_ID_MASK) != 0x00) {
507 dev_err(dev, "unmatched chip ID: %d\n",
508 val & CS42XX8_CHIPID_CHIP_ID_MASK);
509 ret = -EINVAL;
510 goto err_enable;
511 }
512
513 dev_info(dev, "found device, revision %X\n",
514 val & CS42XX8_CHIPID_REV_ID_MASK);
515
516 regcache_cache_bypass(cs42xx8->regmap, false);
517
518 cs42xx8_dai.name = cs42xx8->drvdata->name;
519
520 /* Each adc supports stereo input */
521 cs42xx8_dai.capture.channels_max = cs42xx8->drvdata->num_adcs * 2;
522
523 ret = snd_soc_register_codec(dev, &cs42xx8_driver, &cs42xx8_dai, 1);
524 if (ret) {
525 dev_err(dev, "failed to register codec:%d\n", ret);
526 goto err_enable;
527 }
528
529 regcache_cache_only(cs42xx8->regmap, true);
530
531err_enable:
532 regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
533 cs42xx8->supplies);
534
535 return ret;
536}
537EXPORT_SYMBOL_GPL(cs42xx8_probe);
538
539#ifdef CONFIG_PM_RUNTIME
540static int cs42xx8_runtime_resume(struct device *dev)
541{
542 struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev);
543 int ret;
544
545 ret = clk_prepare_enable(cs42xx8->clk);
546 if (ret) {
547 dev_err(dev, "failed to enable mclk: %d\n", ret);
548 return ret;
549 }
550
551 ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
552 cs42xx8->supplies);
553 if (ret) {
554 dev_err(dev, "failed to enable supplies: %d\n", ret);
555 goto err_clk;
556 }
557
558 /* Make sure hardware reset done */
559 msleep(5);
560
561 regcache_cache_only(cs42xx8->regmap, false);
562
563 ret = regcache_sync(cs42xx8->regmap);
564 if (ret) {
565 dev_err(dev, "failed to sync regmap: %d\n", ret);
566 goto err_bulk;
567 }
568
569 return 0;
570
571err_bulk:
572 regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
573 cs42xx8->supplies);
574err_clk:
575 clk_disable_unprepare(cs42xx8->clk);
576
577 return ret;
578}
579
580static int cs42xx8_runtime_suspend(struct device *dev)
581{
582 struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev);
583
584 regcache_cache_only(cs42xx8->regmap, true);
585
586 regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
587 cs42xx8->supplies);
588
589 clk_disable_unprepare(cs42xx8->clk);
590
591 return 0;
592}
593#endif
594
595const struct dev_pm_ops cs42xx8_pm = {
596 SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL)
597};
598EXPORT_SYMBOL_GPL(cs42xx8_pm);
599
600MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec Driver");
601MODULE_AUTHOR("Freescale Semiconductor, Inc.");
602MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42xx8.h b/sound/soc/codecs/cs42xx8.h
new file mode 100644
index 000000000000..da0b94aee419
--- /dev/null
+++ b/sound/soc/codecs/cs42xx8.h
@@ -0,0 +1,238 @@
1/*
2 * cs42xx8.h - Cirrus Logic CS42448/CS42888 Audio CODEC driver header file
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#ifndef _CS42XX8_H
14#define _CS42XX8_H
15
16struct cs42xx8_driver_data {
17 char name[32];
18 int num_adcs;
19};
20
21extern const struct dev_pm_ops cs42xx8_pm;
22extern const struct cs42xx8_driver_data cs42448_data;
23extern const struct cs42xx8_driver_data cs42888_data;
24extern const struct regmap_config cs42xx8_regmap_config;
25int cs42xx8_probe(struct device *dev, struct regmap *regmap);
26
27/* CS42888 register map */
28#define CS42XX8_CHIPID 0x01 /* Chip ID */
29#define CS42XX8_PWRCTL 0x02 /* Power Control */
30#define CS42XX8_FUNCMOD 0x03 /* Functional Mode */
31#define CS42XX8_INTF 0x04 /* Interface Formats */
32#define CS42XX8_ADCCTL 0x05 /* ADC Control */
33#define CS42XX8_TXCTL 0x06 /* Transition Control */
34#define CS42XX8_DACMUTE 0x07 /* DAC Mute Control */
35#define CS42XX8_VOLAOUT1 0x08 /* Volume Control AOUT1 */
36#define CS42XX8_VOLAOUT2 0x09 /* Volume Control AOUT2 */
37#define CS42XX8_VOLAOUT3 0x0A /* Volume Control AOUT3 */
38#define CS42XX8_VOLAOUT4 0x0B /* Volume Control AOUT4 */
39#define CS42XX8_VOLAOUT5 0x0C /* Volume Control AOUT5 */
40#define CS42XX8_VOLAOUT6 0x0D /* Volume Control AOUT6 */
41#define CS42XX8_VOLAOUT7 0x0E /* Volume Control AOUT7 */
42#define CS42XX8_VOLAOUT8 0x0F /* Volume Control AOUT8 */
43#define CS42XX8_DACINV 0x10 /* DAC Channel Invert */
44#define CS42XX8_VOLAIN1 0x11 /* Volume Control AIN1 */
45#define CS42XX8_VOLAIN2 0x12 /* Volume Control AIN2 */
46#define CS42XX8_VOLAIN3 0x13 /* Volume Control AIN3 */
47#define CS42XX8_VOLAIN4 0x14 /* Volume Control AIN4 */
48#define CS42XX8_VOLAIN5 0x15 /* Volume Control AIN5 */
49#define CS42XX8_VOLAIN6 0x16 /* Volume Control AIN6 */
50#define CS42XX8_ADCINV 0x17 /* ADC Channel Invert */
51#define CS42XX8_STATUSCTL 0x18 /* Status Control */
52#define CS42XX8_STATUS 0x19 /* Status */
53#define CS42XX8_STATUSM 0x1A /* Status Mask */
54#define CS42XX8_MUTEC 0x1B /* MUTEC Pin Control */
55
56#define CS42XX8_FIRSTREG CS42XX8_CHIPID
57#define CS42XX8_LASTREG CS42XX8_MUTEC
58#define CS42XX8_NUMREGS (CS42XX8_LASTREG - CS42XX8_FIRSTREG + 1)
59#define CS42XX8_I2C_INCR 0x80
60
61/* Chip I.D. and Revision Register (Address 01h) */
62#define CS42XX8_CHIPID_CHIP_ID_MASK 0xF0
63#define CS42XX8_CHIPID_REV_ID_MASK 0x0F
64
65/* Power Control (Address 02h) */
66#define CS42XX8_PWRCTL_PDN_ADC3_SHIFT 7
67#define CS42XX8_PWRCTL_PDN_ADC3_MASK (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT)
68#define CS42XX8_PWRCTL_PDN_ADC3 (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT)
69#define CS42XX8_PWRCTL_PDN_ADC2_SHIFT 6
70#define CS42XX8_PWRCTL_PDN_ADC2_MASK (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT)
71#define CS42XX8_PWRCTL_PDN_ADC2 (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT)
72#define CS42XX8_PWRCTL_PDN_ADC1_SHIFT 5
73#define CS42XX8_PWRCTL_PDN_ADC1_MASK (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT)
74#define CS42XX8_PWRCTL_PDN_ADC1 (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT)
75#define CS42XX8_PWRCTL_PDN_DAC4_SHIFT 4
76#define CS42XX8_PWRCTL_PDN_DAC4_MASK (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT)
77#define CS42XX8_PWRCTL_PDN_DAC4 (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT)
78#define CS42XX8_PWRCTL_PDN_DAC3_SHIFT 3
79#define CS42XX8_PWRCTL_PDN_DAC3_MASK (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT)
80#define CS42XX8_PWRCTL_PDN_DAC3 (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT)
81#define CS42XX8_PWRCTL_PDN_DAC2_SHIFT 2
82#define CS42XX8_PWRCTL_PDN_DAC2_MASK (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT)
83#define CS42XX8_PWRCTL_PDN_DAC2 (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT)
84#define CS42XX8_PWRCTL_PDN_DAC1_SHIFT 1
85#define CS42XX8_PWRCTL_PDN_DAC1_MASK (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT)
86#define CS42XX8_PWRCTL_PDN_DAC1 (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT)
87#define CS42XX8_PWRCTL_PDN_SHIFT 0
88#define CS42XX8_PWRCTL_PDN_MASK (1 << CS42XX8_PWRCTL_PDN_SHIFT)
89#define CS42XX8_PWRCTL_PDN (1 << CS42XX8_PWRCTL_PDN_SHIFT)
90
91/* Functional Mode (Address 03h) */
92#define CS42XX8_FUNCMOD_DAC_FM_SHIFT 6
93#define CS42XX8_FUNCMOD_DAC_FM_WIDTH 2
94#define CS42XX8_FUNCMOD_DAC_FM_MASK (((1 << CS42XX8_FUNCMOD_DAC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_DAC_FM_SHIFT)
95#define CS42XX8_FUNCMOD_DAC_FM(v) ((v) << CS42XX8_FUNCMOD_DAC_FM_SHIFT)
96#define CS42XX8_FUNCMOD_ADC_FM_SHIFT 4
97#define CS42XX8_FUNCMOD_ADC_FM_WIDTH 2
98#define CS42XX8_FUNCMOD_ADC_FM_MASK (((1 << CS42XX8_FUNCMOD_ADC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_ADC_FM_SHIFT)
99#define CS42XX8_FUNCMOD_ADC_FM(v) ((v) << CS42XX8_FUNCMOD_ADC_FM_SHIFT)
100#define CS42XX8_FUNCMOD_xC_FM_MASK(x) ((x) ? CS42XX8_FUNCMOD_DAC_FM_MASK : CS42XX8_FUNCMOD_ADC_FM_MASK)
101#define CS42XX8_FUNCMOD_xC_FM(x, v) ((x) ? CS42XX8_FUNCMOD_DAC_FM(v) : CS42XX8_FUNCMOD_ADC_FM(v))
102#define CS42XX8_FUNCMOD_MFREQ_SHIFT 1
103#define CS42XX8_FUNCMOD_MFREQ_WIDTH 3
104#define CS42XX8_FUNCMOD_MFREQ_MASK (((1 << CS42XX8_FUNCMOD_MFREQ_WIDTH) - 1) << CS42XX8_FUNCMOD_MFREQ_SHIFT)
105#define CS42XX8_FUNCMOD_MFREQ_256(s) ((0 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
106#define CS42XX8_FUNCMOD_MFREQ_384(s) ((1 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
107#define CS42XX8_FUNCMOD_MFREQ_512(s) ((2 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
108#define CS42XX8_FUNCMOD_MFREQ_768(s) ((3 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
109#define CS42XX8_FUNCMOD_MFREQ_1024(s) ((4 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
110
111#define CS42XX8_FM_SINGLE 0
112#define CS42XX8_FM_DOUBLE 1
113#define CS42XX8_FM_QUAD 2
114#define CS42XX8_FM_AUTO 3
115
116/* Interface Formats (Address 04h) */
117#define CS42XX8_INTF_FREEZE_SHIFT 7
118#define CS42XX8_INTF_FREEZE_MASK (1 << CS42XX8_INTF_FREEZE_SHIFT)
119#define CS42XX8_INTF_FREEZE (1 << CS42XX8_INTF_FREEZE_SHIFT)
120#define CS42XX8_INTF_AUX_DIF_SHIFT 6
121#define CS42XX8_INTF_AUX_DIF_MASK (1 << CS42XX8_INTF_AUX_DIF_SHIFT)
122#define CS42XX8_INTF_AUX_DIF (1 << CS42XX8_INTF_AUX_DIF_SHIFT)
123#define CS42XX8_INTF_DAC_DIF_SHIFT 3
124#define CS42XX8_INTF_DAC_DIF_WIDTH 3
125#define CS42XX8_INTF_DAC_DIF_MASK (((1 << CS42XX8_INTF_DAC_DIF_WIDTH) - 1) << CS42XX8_INTF_DAC_DIF_SHIFT)
126#define CS42XX8_INTF_DAC_DIF_LEFTJ (0 << CS42XX8_INTF_DAC_DIF_SHIFT)
127#define CS42XX8_INTF_DAC_DIF_I2S (1 << CS42XX8_INTF_DAC_DIF_SHIFT)
128#define CS42XX8_INTF_DAC_DIF_RIGHTJ (2 << CS42XX8_INTF_DAC_DIF_SHIFT)
129#define CS42XX8_INTF_DAC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_DAC_DIF_SHIFT)
130#define CS42XX8_INTF_DAC_DIF_ONELINE_20 (4 << CS42XX8_INTF_DAC_DIF_SHIFT)
131#define CS42XX8_INTF_DAC_DIF_ONELINE_24 (6 << CS42XX8_INTF_DAC_DIF_SHIFT)
132#define CS42XX8_INTF_DAC_DIF_TDM (7 << CS42XX8_INTF_DAC_DIF_SHIFT)
133#define CS42XX8_INTF_ADC_DIF_SHIFT 0
134#define CS42XX8_INTF_ADC_DIF_WIDTH 3
135#define CS42XX8_INTF_ADC_DIF_MASK (((1 << CS42XX8_INTF_ADC_DIF_WIDTH) - 1) << CS42XX8_INTF_ADC_DIF_SHIFT)
136#define CS42XX8_INTF_ADC_DIF_LEFTJ (0 << CS42XX8_INTF_ADC_DIF_SHIFT)
137#define CS42XX8_INTF_ADC_DIF_I2S (1 << CS42XX8_INTF_ADC_DIF_SHIFT)
138#define CS42XX8_INTF_ADC_DIF_RIGHTJ (2 << CS42XX8_INTF_ADC_DIF_SHIFT)
139#define CS42XX8_INTF_ADC_DIF_RIGHTJ_16 (3 << CS42XX8_INTF_ADC_DIF_SHIFT)
140#define CS42XX8_INTF_ADC_DIF_ONELINE_20 (4 << CS42XX8_INTF_ADC_DIF_SHIFT)
141#define CS42XX8_INTF_ADC_DIF_ONELINE_24 (6 << CS42XX8_INTF_ADC_DIF_SHIFT)
142#define CS42XX8_INTF_ADC_DIF_TDM (7 << CS42XX8_INTF_ADC_DIF_SHIFT)
143
144/* ADC Control & DAC De-Emphasis (Address 05h) */
145#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT 7
146#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_MASK (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT)
147#define CS42XX8_ADCCTL_ADC_HPF_FREEZE (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT)
148#define CS42XX8_ADCCTL_DAC_DEM_SHIFT 5
149#define CS42XX8_ADCCTL_DAC_DEM_MASK (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT)
150#define CS42XX8_ADCCTL_DAC_DEM (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT)
151#define CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT 4
152#define CS42XX8_ADCCTL_ADC1_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT)
153#define CS42XX8_ADCCTL_ADC1_SINGLE (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT)
154#define CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT 3
155#define CS42XX8_ADCCTL_ADC2_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT)
156#define CS42XX8_ADCCTL_ADC2_SINGLE (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT)
157#define CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT 2
158#define CS42XX8_ADCCTL_ADC3_SINGLE_MASK (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT)
159#define CS42XX8_ADCCTL_ADC3_SINGLE (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT)
160#define CS42XX8_ADCCTL_AIN5_MUX_SHIFT 1
161#define CS42XX8_ADCCTL_AIN5_MUX_MASK (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT)
162#define CS42XX8_ADCCTL_AIN5_MUX (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT)
163#define CS42XX8_ADCCTL_AIN6_MUX_SHIFT 0
164#define CS42XX8_ADCCTL_AIN6_MUX_MASK (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT)
165#define CS42XX8_ADCCTL_AIN6_MUX (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT)
166
167/* Transition Control (Address 06h) */
168#define CS42XX8_TXCTL_DAC_SNGVOL_SHIFT 7
169#define CS42XX8_TXCTL_DAC_SNGVOL_MASK (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT)
170#define CS42XX8_TXCTL_DAC_SNGVOL (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT)
171#define CS42XX8_TXCTL_DAC_SZC_SHIFT 5
172#define CS42XX8_TXCTL_DAC_SZC_WIDTH 2
173#define CS42XX8_TXCTL_DAC_SZC_MASK (((1 << CS42XX8_TXCTL_DAC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_DAC_SZC_SHIFT)
174#define CS42XX8_TXCTL_DAC_SZC_IC (0 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
175#define CS42XX8_TXCTL_DAC_SZC_ZC (1 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
176#define CS42XX8_TXCTL_DAC_SZC_SR (2 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
177#define CS42XX8_TXCTL_DAC_SZC_SRZC (3 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
178#define CS42XX8_TXCTL_AMUTE_SHIFT 4
179#define CS42XX8_TXCTL_AMUTE_MASK (1 << CS42XX8_TXCTL_AMUTE_SHIFT)
180#define CS42XX8_TXCTL_AMUTE (1 << CS42XX8_TXCTL_AMUTE_SHIFT)
181#define CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT 3
182#define CS42XX8_TXCTL_MUTE_ADC_SP_MASK (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT)
183#define CS42XX8_TXCTL_MUTE_ADC_SP (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT)
184#define CS42XX8_TXCTL_ADC_SNGVOL_SHIFT 2
185#define CS42XX8_TXCTL_ADC_SNGVOL_MASK (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT)
186#define CS42XX8_TXCTL_ADC_SNGVOL (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT)
187#define CS42XX8_TXCTL_ADC_SZC_SHIFT 0
188#define CS42XX8_TXCTL_ADC_SZC_MASK (((1 << CS42XX8_TXCTL_ADC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_ADC_SZC_SHIFT)
189#define CS42XX8_TXCTL_ADC_SZC_IC (0 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
190#define CS42XX8_TXCTL_ADC_SZC_ZC (1 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
191#define CS42XX8_TXCTL_ADC_SZC_SR (2 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
192#define CS42XX8_TXCTL_ADC_SZC_SRZC (3 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
193
194/* DAC Channel Mute (Address 07h) */
195#define CS42XX8_DACMUTE_AOUT(n) (0x1 << n)
196#define CS42XX8_DACMUTE_ALL 0xff
197
198/* Status Control (Address 18h)*/
199#define CS42XX8_STATUSCTL_INI_SHIFT 2
200#define CS42XX8_STATUSCTL_INI_WIDTH 2
201#define CS42XX8_STATUSCTL_INI_MASK (((1 << CS42XX8_STATUSCTL_INI_WIDTH) - 1) << CS42XX8_STATUSCTL_INI_SHIFT)
202#define CS42XX8_STATUSCTL_INT_ACTIVE_HIGH (0 << CS42XX8_STATUSCTL_INI_SHIFT)
203#define CS42XX8_STATUSCTL_INT_ACTIVE_LOW (1 << CS42XX8_STATUSCTL_INI_SHIFT)
204#define CS42XX8_STATUSCTL_INT_OPEN_DRAIN (2 << CS42XX8_STATUSCTL_INI_SHIFT)
205
206/* Status (Address 19h)*/
207#define CS42XX8_STATUS_DAC_CLK_ERR_SHIFT 4
208#define CS42XX8_STATUS_DAC_CLK_ERR_MASK (1 << CS42XX8_STATUS_DAC_CLK_ERR_SHIFT)
209#define CS42XX8_STATUS_ADC_CLK_ERR_SHIFT 3
210#define CS42XX8_STATUS_ADC_CLK_ERR_MASK (1 << CS42XX8_STATUS_ADC_CLK_ERR_SHIFT)
211#define CS42XX8_STATUS_ADC3_OVFL_SHIFT 2
212#define CS42XX8_STATUS_ADC3_OVFL_MASK (1 << CS42XX8_STATUS_ADC3_OVFL_SHIFT)
213#define CS42XX8_STATUS_ADC2_OVFL_SHIFT 1
214#define CS42XX8_STATUS_ADC2_OVFL_MASK (1 << CS42XX8_STATUS_ADC2_OVFL_SHIFT)
215#define CS42XX8_STATUS_ADC1_OVFL_SHIFT 0
216#define CS42XX8_STATUS_ADC1_OVFL_MASK (1 << CS42XX8_STATUS_ADC1_OVFL_SHIFT)
217
218/* Status Mask (Address 1Ah) */
219#define CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT 4
220#define CS42XX8_STATUS_DAC_CLK_ERR_M_MASK (1 << CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT)
221#define CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT 3
222#define CS42XX8_STATUS_ADC_CLK_ERR_M_MASK (1 << CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT)
223#define CS42XX8_STATUS_ADC3_OVFL_M_SHIFT 2
224#define CS42XX8_STATUS_ADC3_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC3_OVFL_M_SHIFT)
225#define CS42XX8_STATUS_ADC2_OVFL_M_SHIFT 1
226#define CS42XX8_STATUS_ADC2_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC2_OVFL_M_SHIFT)
227#define CS42XX8_STATUS_ADC1_OVFL_M_SHIFT 0
228#define CS42XX8_STATUS_ADC1_OVFL_M_MASK (1 << CS42XX8_STATUS_ADC1_OVFL_M_SHIFT)
229
230/* MUTEC Pin Control (Address 1Bh) */
231#define CS42XX8_MUTEC_MCPOLARITY_SHIFT 1
232#define CS42XX8_MUTEC_MCPOLARITY_MASK (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
233#define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_LOW (0 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
234#define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_HIGH (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
235#define CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT 0
236#define CS42XX8_MUTEC_MUTEC_ACTIVE_MASK (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT)
237#define CS42XX8_MUTEC_MUTEC_ACTIVE (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT)
238#endif /* _CS42XX8_H */
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index 3e264a78017a..3a89ce66d51d 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -918,8 +918,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
918 struct snd_pcm_hw_params *params, 918 struct snd_pcm_hw_params *params,
919 struct snd_soc_dai *dai) 919 struct snd_soc_dai *dai)
920{ 920{
921 struct snd_soc_pcm_runtime *rtd = substream->private_data; 921 struct snd_soc_codec *codec = dai->codec;
922 struct snd_soc_codec *codec = rtd->codec;
923 u16 aif = 0; 922 u16 aif = 0;
924 unsigned int fs_val = 0; 923 unsigned int fs_val = 0;
925 924
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 96a47459b3d7..98c6e104357c 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2343,7 +2343,6 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
2343 2343
2344 max98090->devtype = id->driver_data; 2344 max98090->devtype = id->driver_data;
2345 i2c_set_clientdata(i2c, max98090); 2345 i2c_set_clientdata(i2c, max98090);
2346 max98090->control_data = i2c;
2347 max98090->pdata = i2c->dev.platform_data; 2346 max98090->pdata = i2c->dev.platform_data;
2348 max98090->irq = i2c->irq; 2347 max98090->irq = i2c->irq;
2349 2348
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h
index 7e103f249053..1a4e2334a7b2 100644
--- a/sound/soc/codecs/max98090.h
+++ b/sound/soc/codecs/max98090.h
@@ -1523,7 +1523,6 @@ struct max98090_priv {
1523 struct regmap *regmap; 1523 struct regmap *regmap;
1524 struct snd_soc_codec *codec; 1524 struct snd_soc_codec *codec;
1525 enum max98090_type devtype; 1525 enum max98090_type devtype;
1526 void *control_data;
1527 struct max98090_pdata *pdata; 1526 struct max98090_pdata *pdata;
1528 unsigned int sysclk; 1527 unsigned int sysclk;
1529 unsigned int bclk; 1528 unsigned int bclk;
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 37d737e567a1..2c59b1fb69dc 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -106,8 +106,7 @@ static int mc13783_pcm_hw_params_dac(struct snd_pcm_substream *substream,
106 struct snd_pcm_hw_params *params, 106 struct snd_pcm_hw_params *params,
107 struct snd_soc_dai *dai) 107 struct snd_soc_dai *dai)
108{ 108{
109 struct snd_soc_pcm_runtime *rtd = substream->private_data; 109 struct snd_soc_codec *codec = dai->codec;
110 struct snd_soc_codec *codec = rtd->codec;
111 unsigned int rate = params_rate(params); 110 unsigned int rate = params_rate(params);
112 int i; 111 int i;
113 112
@@ -126,8 +125,7 @@ static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream,
126 struct snd_pcm_hw_params *params, 125 struct snd_pcm_hw_params *params,
127 struct snd_soc_dai *dai) 126 struct snd_soc_dai *dai)
128{ 127{
129 struct snd_soc_pcm_runtime *rtd = substream->private_data; 128 struct snd_soc_codec *codec = dai->codec;
130 struct snd_soc_codec *codec = rtd->codec;
131 unsigned int rate = params_rate(params); 129 unsigned int rate = params_rate(params);
132 unsigned int val; 130 unsigned int val;
133 131
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 13ccee43cfc5..0061ae6b6716 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -1594,8 +1594,7 @@ static int get_clk_info(int sclk, int rate)
1594static int rt5640_hw_params(struct snd_pcm_substream *substream, 1594static int rt5640_hw_params(struct snd_pcm_substream *substream,
1595 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 1595 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1596{ 1596{
1597 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1597 struct snd_soc_codec *codec = dai->codec;
1598 struct snd_soc_codec *codec = rtd->codec;
1599 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); 1598 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1600 unsigned int val_len = 0, val_clk, mask_clk; 1599 unsigned int val_len = 0, val_clk, mask_clk;
1601 int dai_sel, pre_div, bclk_ms, frame_size; 1600 int dai_sel, pre_div, bclk_ms, frame_size;
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c
index 90e3a228bae4..58e7c1f23771 100644
--- a/sound/soc/codecs/sirf-audio-codec.c
+++ b/sound/soc/codecs/sirf-audio-codec.c
@@ -337,18 +337,9 @@ struct snd_soc_dai_driver sirf_audio_codec_dai = {
337 337
338static int sirf_audio_codec_probe(struct snd_soc_codec *codec) 338static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
339{ 339{
340 int ret;
341 struct snd_soc_dapm_context *dapm = &codec->dapm; 340 struct snd_soc_dapm_context *dapm = &codec->dapm;
342 struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
343 341
344 pm_runtime_enable(codec->dev); 342 pm_runtime_enable(codec->dev);
345 codec->control_data = sirf_audio_codec->regmap;
346
347 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
348 if (ret != 0) {
349 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
350 return ret;
351 }
352 343
353 if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) { 344 if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) {
354 snd_soc_dapm_new_controls(dapm, 345 snd_soc_dapm_new_controls(dapm,
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index a3c61d308bb0..a40c4b0196a3 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -193,8 +193,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
193 struct snd_pcm_hw_params *params, 193 struct snd_pcm_hw_params *params,
194 struct snd_soc_dai *dai) 194 struct snd_soc_dai *dai)
195{ 195{
196 struct snd_soc_pcm_runtime *rtd = substream->private_data; 196 struct snd_soc_codec *codec = dai->codec;
197 struct snd_soc_codec *codec = rtd->codec;
198 int pdata, play_freq_val, record_freq_val; 197 int pdata, play_freq_val, record_freq_val;
199 int bclk_to_fs_ratio; 198 int bclk_to_fs_ratio;
200 199
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index e60e37b43a1b..fa158cfe9b32 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -129,7 +129,7 @@ static const struct regmap_range_cfg aic31xx_ranges[] = {
129 }, 129 },
130}; 130};
131 131
132struct regmap_config aic31xx_i2c_regmap = { 132static const struct regmap_config aic31xx_i2c_regmap = {
133 .reg_bits = 8, 133 .reg_bits = 8,
134 .val_bits = 8, 134 .val_bits = 8,
135 .writeable_reg = aic31xx_writeable, 135 .writeable_reg = aic31xx_writeable,
@@ -321,9 +321,9 @@ static const struct snd_kcontrol_new ldac_in_control =
321static const struct snd_kcontrol_new rdac_in_control = 321static const struct snd_kcontrol_new rdac_in_control =
322 SOC_DAPM_ENUM("DAC Right Input", rdac_in_enum); 322 SOC_DAPM_ENUM("DAC Right Input", rdac_in_enum);
323 323
324int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg, 324static int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg,
325 unsigned int mask, unsigned int wbits, int sleep, 325 unsigned int mask, unsigned int wbits, int sleep,
326 int count) 326 int count)
327{ 327{
328 unsigned int bits; 328 unsigned int bits;
329 int counter = count; 329 int counter = count;
@@ -753,10 +753,9 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
753 753
754static int aic31xx_hw_params(struct snd_pcm_substream *substream, 754static int aic31xx_hw_params(struct snd_pcm_substream *substream,
755 struct snd_pcm_hw_params *params, 755 struct snd_pcm_hw_params *params,
756 struct snd_soc_dai *tmp) 756 struct snd_soc_dai *dai)
757{ 757{
758 struct snd_soc_pcm_runtime *rtd = substream->private_data; 758 struct snd_soc_codec *codec = dai->codec;
759 struct snd_soc_codec *codec = rtd->codec;
760 u8 data = 0; 759 u8 data = 0;
761 760
762 dev_dbg(codec->dev, "## %s: format %d width %d rate %d\n", 761 dev_dbg(codec->dev, "## %s: format %d width %d rate %d\n",
@@ -943,7 +942,6 @@ static void aic31xx_clk_on(struct snd_soc_codec *codec)
943 942
944static void aic31xx_clk_off(struct snd_soc_codec *codec) 943static void aic31xx_clk_off(struct snd_soc_codec *codec)
945{ 944{
946 struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
947 u8 mask = AIC31XX_PM_MASK; 945 u8 mask = AIC31XX_PM_MASK;
948 u8 off = 0; 946 u8 off = 0;
949 947
@@ -1021,7 +1019,8 @@ static int aic31xx_set_bias_level(struct snd_soc_codec *codec,
1021 } 1019 }
1022 break; 1020 break;
1023 case SND_SOC_BIAS_OFF: 1021 case SND_SOC_BIAS_OFF:
1024 aic31xx_power_off(codec); 1022 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
1023 aic31xx_power_off(codec);
1025 break; 1024 break;
1026 } 1025 }
1027 codec->dapm.bias_level = level; 1026 codec->dapm.bias_level = level;
@@ -1050,18 +1049,9 @@ static int aic31xx_codec_probe(struct snd_soc_codec *codec)
1050 dev_dbg(aic31xx->dev, "## %s\n", __func__); 1049 dev_dbg(aic31xx->dev, "## %s\n", __func__);
1051 1050
1052 aic31xx = snd_soc_codec_get_drvdata(codec); 1051 aic31xx = snd_soc_codec_get_drvdata(codec);
1053 codec->control_data = aic31xx->regmap;
1054 1052
1055 aic31xx->codec = codec; 1053 aic31xx->codec = codec;
1056 1054
1057 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1058
1059 if (ret != 0) {
1060 dev_err(codec->dev, "snd_soc_codec_set_cache_io failed %d\n",
1061 ret);
1062 return ret;
1063 }
1064
1065 for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) { 1055 for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) {
1066 aic31xx->disable_nb[i].nb.notifier_call = 1056 aic31xx->disable_nb[i].nb.notifier_call =
1067 aic31xx_regulator_event; 1057 aic31xx_regulator_event;
@@ -1187,7 +1177,7 @@ static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx)
1187} 1177}
1188#endif /* CONFIG_OF */ 1178#endif /* CONFIG_OF */
1189 1179
1190void aic31xx_device_init(struct aic31xx_priv *aic31xx) 1180static void aic31xx_device_init(struct aic31xx_priv *aic31xx)
1191{ 1181{
1192 int ret, i; 1182 int ret, i;
1193 1183
@@ -1238,7 +1228,6 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
1238 return -ENOMEM; 1228 return -ENOMEM;
1239 1229
1240 aic31xx->regmap = devm_regmap_init_i2c(i2c, regmap_config); 1230 aic31xx->regmap = devm_regmap_init_i2c(i2c, regmap_config);
1241
1242 if (IS_ERR(aic31xx->regmap)) { 1231 if (IS_ERR(aic31xx->regmap)) {
1243 ret = PTR_ERR(aic31xx->regmap); 1232 ret = PTR_ERR(aic31xx->regmap);
1244 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 1233 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -1251,18 +1240,14 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
1251 1240
1252 aic31xx_device_init(aic31xx); 1241 aic31xx_device_init(aic31xx);
1253 1242
1254 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx, 1243 return snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx,
1255 aic31xx_dai_driver, 1244 aic31xx_dai_driver,
1256 ARRAY_SIZE(aic31xx_dai_driver)); 1245 ARRAY_SIZE(aic31xx_dai_driver));
1257
1258 return ret;
1259} 1246}
1260 1247
1261static int aic31xx_i2c_remove(struct i2c_client *i2c) 1248static int aic31xx_i2c_remove(struct i2c_client *i2c)
1262{ 1249{
1263 struct aic31xx_priv *aic31xx = dev_get_drvdata(&i2c->dev); 1250 snd_soc_unregister_codec(&i2c->dev);
1264
1265 kfree(aic31xx);
1266 return 0; 1251 return 0;
1267} 1252}
1268 1253
@@ -1284,7 +1269,7 @@ static struct i2c_driver aic31xx_i2c_driver = {
1284 .of_match_table = of_match_ptr(tlv320aic31xx_of_match), 1269 .of_match_table = of_match_ptr(tlv320aic31xx_of_match),
1285 }, 1270 },
1286 .probe = aic31xx_i2c_probe, 1271 .probe = aic31xx_i2c_probe,
1287 .remove = (aic31xx_i2c_remove), 1272 .remove = aic31xx_i2c_remove,
1288 .id_table = aic31xx_i2c_id, 1273 .id_table = aic31xx_i2c_id,
1289}; 1274};
1290 1275
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index c94d4c1e3dac..edf27acc1d77 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -203,8 +203,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
203 struct snd_pcm_hw_params *params, 203 struct snd_pcm_hw_params *params,
204 struct snd_soc_dai *dai) 204 struct snd_soc_dai *dai)
205{ 205{
206 struct snd_soc_pcm_runtime *rtd = substream->private_data; 206 struct snd_soc_codec *codec = dai->codec;
207 struct snd_soc_codec *codec = rtd->codec;
208 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 207 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
209 u8 hw_params; 208 u8 hw_params;
210 209
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 4dadaa8ad46c..e62e70781ec2 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -566,8 +566,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
566static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, 566static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
567 struct snd_soc_dai *dai) 567 struct snd_soc_dai *dai)
568{ 568{
569 struct snd_soc_pcm_runtime *rtd = substream->private_data; 569 struct snd_soc_codec *codec = dai->codec;
570 struct snd_soc_codec *codec = rtd->codec;
571 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 570 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
572 571
573 /* shut down WSPLL power if running from this clock */ 572 /* shut down WSPLL power if running from this clock */
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 7558c838193d..af7ed8b5d4e1 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -504,8 +504,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
504 struct snd_pcm_hw_params *params, 504 struct snd_pcm_hw_params *params,
505 struct snd_soc_dai *dai) 505 struct snd_soc_dai *dai)
506{ 506{
507 struct snd_soc_pcm_runtime *rtd = substream->private_data; 507 struct snd_soc_codec *codec = dai->codec;
508 struct snd_soc_codec *codec = rtd->codec;
509 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); 508 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
510 u16 paifa = 0; 509 u16 paifa = 0;
511 u16 paifb = 0; 510 u16 paifb = 0;
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 621e9a997d4c..cab98a580053 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -123,35 +123,29 @@ static const struct snd_soc_dapm_route audio_map[] = {
123/* Logic for a aic3x as connected on a davinci-evm */ 123/* Logic for a aic3x as connected on a davinci-evm */
124static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) 124static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
125{ 125{
126 struct snd_soc_card *card = rtd->card;
126 struct snd_soc_codec *codec = rtd->codec; 127 struct snd_soc_codec *codec = rtd->codec;
127 struct snd_soc_dapm_context *dapm = &codec->dapm;
128 struct device_node *np = codec->card->dev->of_node; 128 struct device_node *np = codec->card->dev->of_node;
129 int ret; 129 int ret;
130 130
131 /* Add davinci-evm specific widgets */ 131 /* Add davinci-evm specific widgets */
132 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, 132 snd_soc_dapm_new_controls(&card->dapm, aic3x_dapm_widgets,
133 ARRAY_SIZE(aic3x_dapm_widgets)); 133 ARRAY_SIZE(aic3x_dapm_widgets));
134 134
135 if (np) { 135 if (np) {
136 ret = snd_soc_of_parse_audio_routing(codec->card, 136 ret = snd_soc_of_parse_audio_routing(card, "ti,audio-routing");
137 "ti,audio-routing");
138 if (ret) 137 if (ret)
139 return ret; 138 return ret;
140 } else { 139 } else {
141 /* Set up davinci-evm specific audio path audio_map */ 140 /* Set up davinci-evm specific audio path audio_map */
142 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 141 snd_soc_dapm_add_routes(&card->dapm, audio_map,
142 ARRAY_SIZE(audio_map));
143 } 143 }
144 144
145 /* not connected */ 145 /* not connected */
146 snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); 146 snd_soc_dapm_nc_pin(&codec->dapm, "MONO_LOUT");
147 snd_soc_dapm_disable_pin(dapm, "HPLCOM"); 147 snd_soc_dapm_nc_pin(&codec->dapm, "HPLCOM");
148 snd_soc_dapm_disable_pin(dapm, "HPRCOM"); 148 snd_soc_dapm_nc_pin(&codec->dapm, "HPRCOM");
149
150 /* always connected */
151 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
152 snd_soc_dapm_enable_pin(dapm, "Line Out");
153 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
154 snd_soc_dapm_enable_pin(dapm, "Line In");
155 149
156 return 0; 150 return 0;
157} 151}
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index b0ae0677f023..a01ae97c90aa 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1026,6 +1026,7 @@ nodata:
1026static int davinci_mcasp_probe(struct platform_device *pdev) 1026static int davinci_mcasp_probe(struct platform_device *pdev)
1027{ 1027{
1028 struct davinci_pcm_dma_params *dma_params; 1028 struct davinci_pcm_dma_params *dma_params;
1029 struct snd_dmaengine_dai_dma_data *dma_data;
1029 struct resource *mem, *ioarea, *res, *dat; 1030 struct resource *mem, *ioarea, *res, *dat;
1030 struct davinci_mcasp_pdata *pdata; 1031 struct davinci_mcasp_pdata *pdata;
1031 struct davinci_mcasp *mcasp; 1032 struct davinci_mcasp *mcasp;
@@ -1095,6 +1096,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1095 mcasp->dat_port = true; 1096 mcasp->dat_port = true;
1096 1097
1097 dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; 1098 dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
1099 dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
1098 dma_params->asp_chan_q = pdata->asp_chan_q; 1100 dma_params->asp_chan_q = pdata->asp_chan_q;
1099 dma_params->ram_chan_q = pdata->ram_chan_q; 1101 dma_params->ram_chan_q = pdata->ram_chan_q;
1100 dma_params->sram_pool = pdata->sram_pool; 1102 dma_params->sram_pool = pdata->sram_pool;
@@ -1105,7 +1107,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1105 dma_params->dma_addr = mem->start + pdata->tx_dma_offset; 1107 dma_params->dma_addr = mem->start + pdata->tx_dma_offset;
1106 1108
1107 /* Unconditional dmaengine stuff */ 1109 /* Unconditional dmaengine stuff */
1108 mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_params->dma_addr; 1110 dma_data->addr = dma_params->dma_addr;
1109 1111
1110 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1112 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1111 if (res) 1113 if (res)
@@ -1113,7 +1115,14 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1113 else 1115 else
1114 dma_params->channel = pdata->tx_dma_channel; 1116 dma_params->channel = pdata->tx_dma_channel;
1115 1117
1118 /* dmaengine filter data for DT and non-DT boot */
1119 if (pdev->dev.of_node)
1120 dma_data->filter_data = "tx";
1121 else
1122 dma_data->filter_data = &dma_params->channel;
1123
1116 dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE]; 1124 dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE];
1125 dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
1117 dma_params->asp_chan_q = pdata->asp_chan_q; 1126 dma_params->asp_chan_q = pdata->asp_chan_q;
1118 dma_params->ram_chan_q = pdata->ram_chan_q; 1127 dma_params->ram_chan_q = pdata->ram_chan_q;
1119 dma_params->sram_pool = pdata->sram_pool; 1128 dma_params->sram_pool = pdata->sram_pool;
@@ -1124,7 +1133,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1124 dma_params->dma_addr = mem->start + pdata->rx_dma_offset; 1133 dma_params->dma_addr = mem->start + pdata->rx_dma_offset;
1125 1134
1126 /* Unconditional dmaengine stuff */ 1135 /* Unconditional dmaengine stuff */
1127 mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_params->dma_addr; 1136 dma_data->addr = dma_params->dma_addr;
1128 1137
1129 if (mcasp->version < MCASP_VERSION_3) { 1138 if (mcasp->version < MCASP_VERSION_3) {
1130 mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; 1139 mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE;
@@ -1140,9 +1149,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1140 else 1149 else
1141 dma_params->channel = pdata->rx_dma_channel; 1150 dma_params->channel = pdata->rx_dma_channel;
1142 1151
1143 /* Unconditional dmaengine stuff */ 1152 /* dmaengine filter data for DT and non-DT boot */
1144 mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx"; 1153 if (pdev->dev.of_node)
1145 mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx"; 1154 dma_data->filter_data = "rx";
1155 else
1156 dma_data->filter_data = &dma_params->channel;
1146 1157
1147 dev_set_drvdata(&pdev->dev, mcasp); 1158 dev_set_drvdata(&pdev->dev, mcasp);
1148 1159
diff --git a/sound/soc/davinci/edma-pcm.c b/sound/soc/davinci/edma-pcm.c
new file mode 100644
index 000000000000..d38afb1c61ae
--- /dev/null
+++ b/sound/soc/davinci/edma-pcm.c
@@ -0,0 +1,57 @@
1/*
2 * edma-pcm.c - eDMA PCM driver using dmaengine for AM3xxx, AM4xxx
3 *
4 * Copyright (C) 2014 Texas Instruments, Inc.
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 *
8 * Based on: sound/soc/tegra/tegra_pcm.c
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#include <linux/module.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/dmaengine_pcm.h>
26#include <linux/edma.h>
27
28static const struct snd_pcm_hardware edma_pcm_hardware = {
29 .info = SNDRV_PCM_INFO_MMAP |
30 SNDRV_PCM_INFO_MMAP_VALID |
31 SNDRV_PCM_INFO_BATCH |
32 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
33 SNDRV_PCM_INFO_INTERLEAVED,
34 .buffer_bytes_max = 128 * 1024,
35 .period_bytes_min = 32,
36 .period_bytes_max = 64 * 1024,
37 .periods_min = 2,
38 .periods_max = 19, /* Limit by edma dmaengine driver */
39};
40
41static const struct snd_dmaengine_pcm_config edma_dmaengine_pcm_config = {
42 .pcm_hardware = &edma_pcm_hardware,
43 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
44 .compat_filter_fn = edma_filter_fn,
45 .prealloc_buffer_size = 128 * 1024,
46};
47
48int edma_pcm_platform_register(struct device *dev)
49{
50 return devm_snd_dmaengine_pcm_register(dev, &edma_dmaengine_pcm_config,
51 SND_DMAENGINE_PCM_FLAG_COMPAT);
52}
53EXPORT_SYMBOL_GPL(edma_pcm_platform_register);
54
55MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
56MODULE_DESCRIPTION("eDMA PCM ASoC platform driver");
57MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/edma-pcm.h b/sound/soc/davinci/edma-pcm.h
new file mode 100644
index 000000000000..894c378c0f74
--- /dev/null
+++ b/sound/soc/davinci/edma-pcm.h
@@ -0,0 +1,25 @@
1/*
2 * edma-pcm.h - eDMA PCM driver using dmaengine for AM3xxx, AM4xxx
3 *
4 * Copyright (C) 2014 Texas Instruments, Inc.
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 *
8 * Based on: sound/soc/tegra/tegra_pcm.h
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#ifndef __EDMA_PCM_H__
21#define __EDMA_PCM_H__
22
23int edma_pcm_platform_register(struct device *dev);
24
25#endif /* __EDMA_PCM_H__ */
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 5dd47691ba41..2ee8ed56bcf1 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -20,7 +20,6 @@
20 20
21struct simple_card_data { 21struct simple_card_data {
22 struct snd_soc_card snd_card; 22 struct snd_soc_card snd_card;
23 unsigned int daifmt;
24 struct asoc_simple_dai cpu_dai; 23 struct asoc_simple_dai cpu_dai;
25 struct asoc_simple_dai codec_dai; 24 struct asoc_simple_dai codec_dai;
26 struct snd_soc_dai_link snd_link; 25 struct snd_soc_dai_link snd_link;
@@ -105,12 +104,12 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
105 /* get dai->name */ 104 /* get dai->name */
106 ret = snd_soc_of_get_dai_name(np, name); 105 ret = snd_soc_of_get_dai_name(np, name);
107 if (ret < 0) 106 if (ret < 0)
108 goto parse_error; 107 return ret;
109 108
110 /* parse TDM slot */ 109 /* parse TDM slot */
111 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); 110 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
112 if (ret) 111 if (ret)
113 goto parse_error; 112 return ret;
114 113
115 /* 114 /*
116 * bitclock-inversion, frame-inversion 115 * bitclock-inversion, frame-inversion
@@ -130,7 +129,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
130 clk = of_clk_get(np, 0); 129 clk = of_clk_get(np, 0);
131 if (IS_ERR(clk)) { 130 if (IS_ERR(clk)) {
132 ret = PTR_ERR(clk); 131 ret = PTR_ERR(clk);
133 goto parse_error; 132 return ret;
134 } 133 }
135 134
136 dai->sysclk = clk_get_rate(clk); 135 dai->sysclk = clk_get_rate(clk);
@@ -144,12 +143,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
144 dai->sysclk = clk_get_rate(clk); 143 dai->sysclk = clk_get_rate(clk);
145 } 144 }
146 145
147 ret = 0; 146 return 0;
148
149parse_error:
150 of_node_put(node);
151
152 return ret;
153} 147}
154 148
155static int asoc_simple_card_parse_of(struct device_node *node, 149static int asoc_simple_card_parse_of(struct device_node *node,
@@ -157,15 +151,18 @@ static int asoc_simple_card_parse_of(struct device_node *node,
157 struct device *dev) 151 struct device *dev)
158{ 152{
159 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; 153 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link;
154 struct asoc_simple_dai *codec_dai = &priv->codec_dai;
155 struct asoc_simple_dai *cpu_dai = &priv->cpu_dai;
160 struct device_node *np; 156 struct device_node *np;
161 char *name; 157 char *name;
158 unsigned int daifmt;
162 int ret; 159 int ret;
163 160
164 /* parsing the card name from DT */ 161 /* parsing the card name from DT */
165 snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name"); 162 snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
166 163
167 /* get CPU/CODEC common format via simple-audio-card,format */ 164 /* get CPU/CODEC common format via simple-audio-card,format */
168 priv->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & 165 daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") &
169 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK); 166 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK);
170 167
171 /* off-codec widgets */ 168 /* off-codec widgets */
@@ -187,25 +184,35 @@ static int asoc_simple_card_parse_of(struct device_node *node,
187 /* CPU sub-node */ 184 /* CPU sub-node */
188 ret = -EINVAL; 185 ret = -EINVAL;
189 np = of_get_child_by_name(node, "simple-audio-card,cpu"); 186 np = of_get_child_by_name(node, "simple-audio-card,cpu");
190 if (np) 187 if (np) {
191 ret = asoc_simple_card_sub_parse_of(np, priv->daifmt, 188 ret = asoc_simple_card_sub_parse_of(np, daifmt,
192 &priv->cpu_dai, 189 cpu_dai,
193 &dai_link->cpu_of_node, 190 &dai_link->cpu_of_node,
194 &dai_link->cpu_dai_name); 191 &dai_link->cpu_dai_name);
192 of_node_put(np);
193 }
195 if (ret < 0) 194 if (ret < 0)
196 return ret; 195 return ret;
197 196
198 /* CODEC sub-node */ 197 /* CODEC sub-node */
199 ret = -EINVAL; 198 ret = -EINVAL;
200 np = of_get_child_by_name(node, "simple-audio-card,codec"); 199 np = of_get_child_by_name(node, "simple-audio-card,codec");
201 if (np) 200 if (np) {
202 ret = asoc_simple_card_sub_parse_of(np, priv->daifmt, 201 ret = asoc_simple_card_sub_parse_of(np, daifmt,
203 &priv->codec_dai, 202 codec_dai,
204 &dai_link->codec_of_node, 203 &dai_link->codec_of_node,
205 &dai_link->codec_dai_name); 204 &dai_link->codec_dai_name);
205 of_node_put(np);
206 }
206 if (ret < 0) 207 if (ret < 0)
207 return ret; 208 return ret;
208 209
210 /*
211 * overwrite cpu_dai->fmt as its DAIFMT_MASTER bit is based on CODEC
212 * while the other bits should be identical unless buggy SW/HW design.
213 */
214 cpu_dai->fmt = codec_dai->fmt;
215
209 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) 216 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name)
210 return -EINVAL; 217 return -EINVAL;
211 218
@@ -224,15 +231,15 @@ static int asoc_simple_card_parse_of(struct device_node *node,
224 dai_link->platform_of_node = dai_link->cpu_of_node; 231 dai_link->platform_of_node = dai_link->cpu_of_node;
225 232
226 dev_dbg(dev, "card-name : %s\n", name); 233 dev_dbg(dev, "card-name : %s\n", name);
227 dev_dbg(dev, "platform : %04x\n", priv->daifmt); 234 dev_dbg(dev, "platform : %04x\n", daifmt);
228 dev_dbg(dev, "cpu : %s / %04x / %d\n", 235 dev_dbg(dev, "cpu : %s / %04x / %d\n",
229 dai_link->cpu_dai_name, 236 dai_link->cpu_dai_name,
230 priv->cpu_dai.fmt, 237 cpu_dai->fmt,
231 priv->cpu_dai.sysclk); 238 cpu_dai->sysclk);
232 dev_dbg(dev, "codec : %s / %04x / %d\n", 239 dev_dbg(dev, "codec : %s / %04x / %d\n",
233 dai_link->codec_dai_name, 240 dai_link->codec_dai_name,
234 priv->codec_dai.fmt, 241 codec_dai->fmt,
235 priv->codec_dai.sysclk); 242 codec_dai->sysclk);
236 243
237 /* 244 /*
238 * soc_bind_dai_link() will check cpu name 245 * soc_bind_dai_link() will check cpu name
@@ -248,6 +255,27 @@ static int asoc_simple_card_parse_of(struct device_node *node,
248 return 0; 255 return 0;
249} 256}
250 257
258/* update the reference count of the devices nodes at end of probe */
259static int asoc_simple_card_unref(struct platform_device *pdev)
260{
261 struct snd_soc_card *card = platform_get_drvdata(pdev);
262 struct snd_soc_dai_link *dai_link;
263 struct device_node *np;
264 int num_links;
265
266 for (num_links = 0, dai_link = card->dai_link;
267 num_links < card->num_links;
268 num_links++, dai_link++) {
269 np = (struct device_node *) dai_link->cpu_of_node;
270 if (np)
271 of_node_put(np);
272 np = (struct device_node *) dai_link->codec_of_node;
273 if (np)
274 of_node_put(np);
275 }
276 return 0;
277}
278
251static int asoc_simple_card_probe(struct platform_device *pdev) 279static int asoc_simple_card_probe(struct platform_device *pdev)
252{ 280{
253 struct simple_card_data *priv; 281 struct simple_card_data *priv;
@@ -275,7 +303,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
275 if (ret < 0) { 303 if (ret < 0) {
276 if (ret != -EPROBE_DEFER) 304 if (ret != -EPROBE_DEFER)
277 dev_err(dev, "parse error %d\n", ret); 305 dev_err(dev, "parse error %d\n", ret);
278 return ret; 306 goto err;
279 } 307 }
280 } else { 308 } else {
281 struct asoc_simple_card_info *cinfo; 309 struct asoc_simple_card_info *cinfo;
@@ -318,7 +346,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
318 346
319 snd_soc_card_set_drvdata(&priv->snd_card, priv); 347 snd_soc_card_set_drvdata(&priv->snd_card, priv);
320 348
321 return devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 349 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
350
351err:
352 asoc_simple_card_unref(pdev);
353 return ret;
322} 354}
323 355
324static const struct of_device_id asoc_simple_of_match[] = { 356static const struct of_device_id asoc_simple_of_match[] = {
diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/mfld_machine.c
index 0cef32e9d402..031d78783fc8 100644
--- a/sound/soc/intel/mfld_machine.c
+++ b/sound/soc/intel/mfld_machine.c
@@ -53,6 +53,7 @@ enum soc_mic_bias_zones {
53 53
54static unsigned int hs_switch; 54static unsigned int hs_switch;
55static unsigned int lo_dac; 55static unsigned int lo_dac;
56static struct snd_soc_codec *mfld_codec;
56 57
57struct mfld_mc_private { 58struct mfld_mc_private {
58 void __iomem *int_base; 59 void __iomem *int_base;
@@ -100,8 +101,8 @@ static int headset_get_switch(struct snd_kcontrol *kcontrol,
100static int headset_set_switch(struct snd_kcontrol *kcontrol, 101static int headset_set_switch(struct snd_kcontrol *kcontrol,
101 struct snd_ctl_elem_value *ucontrol) 102 struct snd_ctl_elem_value *ucontrol)
102{ 103{
103 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 104 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
104 struct snd_soc_dapm_context *dapm = &codec->dapm; 105 struct snd_soc_dapm_context *dapm = &card->dapm;
105 106
106 if (ucontrol->value.integer.value[0] == hs_switch) 107 if (ucontrol->value.integer.value[0] == hs_switch)
107 return 0; 108 return 0;
@@ -127,10 +128,8 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol,
127 return 0; 128 return 0;
128} 129}
129 130
130static void lo_enable_out_pins(struct snd_soc_codec *codec) 131static void lo_enable_out_pins(struct snd_soc_dapm_context *dapm)
131{ 132{
132 struct snd_soc_dapm_context *dapm = &codec->dapm;
133
134 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTL"); 133 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTL");
135 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTR"); 134 snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTR");
136 snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTL"); 135 snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTL");
@@ -156,8 +155,8 @@ static int lo_get_switch(struct snd_kcontrol *kcontrol,
156static int lo_set_switch(struct snd_kcontrol *kcontrol, 155static int lo_set_switch(struct snd_kcontrol *kcontrol,
157 struct snd_ctl_elem_value *ucontrol) 156 struct snd_ctl_elem_value *ucontrol)
158{ 157{
159 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 158 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
160 struct snd_soc_dapm_context *dapm = &codec->dapm; 159 struct snd_soc_dapm_context *dapm = &card->dapm;
161 160
162 if (ucontrol->value.integer.value[0] == lo_dac) 161 if (ucontrol->value.integer.value[0] == lo_dac)
163 return 0; 162 return 0;
@@ -167,35 +166,35 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol,
167 /* we dont want to work with last state of lineout so just enable all 166 /* we dont want to work with last state of lineout so just enable all
168 * pins and then disable pins not required 167 * pins and then disable pins not required
169 */ 168 */
170 lo_enable_out_pins(codec); 169 lo_enable_out_pins(dapm);
171 170
172 switch (ucontrol->value.integer.value[0]) { 171 switch (ucontrol->value.integer.value[0]) {
173 case 0: 172 case 0:
174 pr_debug("set vibra path\n"); 173 pr_debug("set vibra path\n");
175 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT"); 174 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT");
176 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB2OUT"); 175 snd_soc_dapm_disable_pin_unlocked(dapm, "VIB2OUT");
177 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0); 176 snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0);
178 break; 177 break;
179 178
180 case 1: 179 case 1:
181 pr_debug("set hs path\n"); 180 pr_debug("set hs path\n");
182 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones"); 181 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
183 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT"); 182 snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
184 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); 183 snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x22);
185 break; 184 break;
186 185
187 case 2: 186 case 2:
188 pr_debug("set spkr path\n"); 187 pr_debug("set spkr path\n");
189 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTL"); 188 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTL");
190 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTR"); 189 snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTR");
191 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44); 190 snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x44);
192 break; 191 break;
193 192
194 case 3: 193 case 3:
195 pr_debug("set null path\n"); 194 pr_debug("set null path\n");
196 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTL"); 195 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTL");
197 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTR"); 196 snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTR");
198 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66); 197 snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x66);
199 break; 198 break;
200 } 199 }
201 200
@@ -238,26 +237,11 @@ static void mfld_jack_check(unsigned int intr_status)
238 237
239static int mfld_init(struct snd_soc_pcm_runtime *runtime) 238static int mfld_init(struct snd_soc_pcm_runtime *runtime)
240{ 239{
241 struct snd_soc_codec *codec = runtime->codec; 240 struct snd_soc_dapm_context *dapm = &runtime->card->dapm;
242 struct snd_soc_dapm_context *dapm = &codec->dapm;
243 int ret_val; 241 int ret_val;
244 242
245 /* Add jack sense widgets */ 243 mfld_codec = runtime->codec;
246 snd_soc_dapm_new_controls(dapm, mfld_widgets, ARRAY_SIZE(mfld_widgets));
247
248 /* Set up the map */
249 snd_soc_dapm_add_routes(dapm, mfld_map, ARRAY_SIZE(mfld_map));
250 244
251 /* always connected */
252 snd_soc_dapm_enable_pin(dapm, "Headphones");
253 snd_soc_dapm_enable_pin(dapm, "Mic");
254
255 ret_val = snd_soc_add_codec_controls(codec, mfld_snd_controls,
256 ARRAY_SIZE(mfld_snd_controls));
257 if (ret_val) {
258 pr_err("soc_add_controls failed %d", ret_val);
259 return ret_val;
260 }
261 /* default is earpiece pin, userspace sets it explcitly */ 245 /* default is earpiece pin, userspace sets it explcitly */
262 snd_soc_dapm_disable_pin(dapm, "Headphones"); 246 snd_soc_dapm_disable_pin(dapm, "Headphones");
263 /* default is lineout NC, userspace sets it explcitly */ 247 /* default is lineout NC, userspace sets it explcitly */
@@ -270,7 +254,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
270 snd_soc_dapm_disable_pin(dapm, "LINEINR"); 254 snd_soc_dapm_disable_pin(dapm, "LINEINR");
271 255
272 /* Headset and button jack detection */ 256 /* Headset and button jack detection */
273 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack", 257 ret_val = snd_soc_jack_new(mfld_codec, "Intel(R) MID Audio Jack",
274 SND_JACK_HEADSET | SND_JACK_BTN_0 | 258 SND_JACK_HEADSET | SND_JACK_BTN_0 |
275 SND_JACK_BTN_1, &mfld_jack); 259 SND_JACK_BTN_1, &mfld_jack);
276 if (ret_val) { 260 if (ret_val) {
@@ -352,6 +336,13 @@ static struct snd_soc_card snd_soc_card_mfld = {
352 .owner = THIS_MODULE, 336 .owner = THIS_MODULE,
353 .dai_link = mfld_msic_dailink, 337 .dai_link = mfld_msic_dailink,
354 .num_links = ARRAY_SIZE(mfld_msic_dailink), 338 .num_links = ARRAY_SIZE(mfld_msic_dailink),
339
340 .controls = mfld_snd_controls,
341 .num_controls = ARRAY_SIZE(mfld_snd_controls),
342 .dapm_widgets = mfld_widgets,
343 .num_dapm_widgets = ARRAY_SIZE(mfld_widgets),
344 .dapm_routes = mfld_map,
345 .num_dapm_routes = ARRAY_SIZE(mfld_map),
355}; 346};
356 347
357static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev) 348static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev)
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
index 2dc3ecf34801..49f8437665de 100644
--- a/sound/soc/kirkwood/Kconfig
+++ b/sound/soc/kirkwood/Kconfig
@@ -10,6 +10,7 @@ config SND_KIRKWOOD_SOC_ARMADA370_DB
10 tristate "SoC Audio support for Armada 370 DB" 10 tristate "SoC Audio support for Armada 370 DB"
11 depends on SND_KIRKWOOD_SOC && (ARCH_MVEBU || COMPILE_TEST) && I2C 11 depends on SND_KIRKWOOD_SOC && (ARCH_MVEBU || COMPILE_TEST) && I2C
12 select SND_SOC_CS42L51 12 select SND_SOC_CS42L51
13 select SND_SOC_SPDIF
13 help 14 help
14 Say Y if you want to add support for SoC audio on 15 Say Y if you want to add support for SoC audio on
15 the Armada 370 Development Board. 16 the Armada 370 Development Board.
diff --git a/sound/soc/kirkwood/armada-370-db.c b/sound/soc/kirkwood/armada-370-db.c
index 977639b3ffde..c44333849259 100644
--- a/sound/soc/kirkwood/armada-370-db.c
+++ b/sound/soc/kirkwood/armada-370-db.c
@@ -67,6 +67,20 @@ static struct snd_soc_dai_link a370db_dai[] = {
67 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, 67 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
68 .ops = &a370db_ops, 68 .ops = &a370db_ops,
69}, 69},
70{
71 .name = "S/PDIF out",
72 .stream_name = "spdif-out",
73 .cpu_dai_name = "spdif",
74 .codec_dai_name = "dit-hifi",
75 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
76},
77{
78 .name = "S/PDIF in",
79 .stream_name = "spdif-in",
80 .cpu_dai_name = "spdif",
81 .codec_dai_name = "dir-hifi",
82 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
83},
70}; 84};
71 85
72static struct snd_soc_card a370db = { 86static struct snd_soc_card a370db = {
@@ -95,6 +109,20 @@ static int a370db_probe(struct platform_device *pdev)
95 of_parse_phandle(pdev->dev.of_node, 109 of_parse_phandle(pdev->dev.of_node,
96 "marvell,audio-codec", 0); 110 "marvell,audio-codec", 0);
97 111
112 a370db_dai[1].cpu_of_node = a370db_dai[0].cpu_of_node;
113 a370db_dai[1].platform_of_node = a370db_dai[0].cpu_of_node;
114
115 a370db_dai[1].codec_of_node =
116 of_parse_phandle(pdev->dev.of_node,
117 "marvell,audio-codec", 1);
118
119 a370db_dai[2].cpu_of_node = a370db_dai[0].cpu_of_node;
120 a370db_dai[2].platform_of_node = a370db_dai[0].cpu_of_node;
121
122 a370db_dai[2].codec_of_node =
123 of_parse_phandle(pdev->dev.of_node,
124 "marvell,audio-codec", 2);
125
98 return devm_snd_soc_register_card(card->dev, card); 126 return devm_snd_soc_register_card(card->dev, card);
99} 127}
100 128
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index ebb13906b3a0..024dafc3e298 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -203,8 +203,7 @@ static const struct snd_soc_dapm_route dmic_audio_map[] = {
203 203
204static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd) 204static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd)
205{ 205{
206 struct snd_soc_codec *codec = rtd->codec; 206 struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
207 struct snd_soc_dapm_context *dapm = &codec->dapm;
208 207
209 return snd_soc_dapm_add_routes(dapm, dmic_audio_map, 208 return snd_soc_dapm_add_routes(dapm, dmic_audio_map,
210 ARRAY_SIZE(dmic_audio_map)); 209 ARRAY_SIZE(dmic_audio_map));
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 953f1cce982d..69c44269ebdb 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -392,6 +392,7 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
392} 392}
393 393
394int rsnd_adg_probe(struct platform_device *pdev, 394int rsnd_adg_probe(struct platform_device *pdev,
395 const struct rsnd_of_data *of_data,
395 struct rsnd_priv *priv) 396 struct rsnd_priv *priv)
396{ 397{
397 struct rsnd_adg *adg; 398 struct rsnd_adg *adg;
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index d836e8a9fdce..215b668166be 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -100,6 +100,21 @@
100#define RSND_RATES SNDRV_PCM_RATE_8000_96000 100#define RSND_RATES SNDRV_PCM_RATE_8000_96000
101#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 101#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
102 102
103static struct rsnd_of_data rsnd_of_data_gen1 = {
104 .flags = RSND_GEN1,
105};
106
107static struct rsnd_of_data rsnd_of_data_gen2 = {
108 .flags = RSND_GEN2,
109};
110
111static struct of_device_id rsnd_of_match[] = {
112 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
113 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
114 {},
115};
116MODULE_DEVICE_TABLE(of, rsnd_of_match);
117
103/* 118/*
104 * rsnd_platform functions 119 * rsnd_platform functions
105 */ 120 */
@@ -620,7 +635,92 @@ static int rsnd_path_init(struct rsnd_priv *priv,
620 return ret; 635 return ret;
621} 636}
622 637
638static void rsnd_of_parse_dai(struct platform_device *pdev,
639 const struct rsnd_of_data *of_data,
640 struct rsnd_priv *priv)
641{
642 struct device_node *dai_node, *dai_np;
643 struct device_node *ssi_node, *ssi_np;
644 struct device_node *src_node, *src_np;
645 struct device_node *playback, *capture;
646 struct rsnd_dai_platform_info *dai_info;
647 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
648 struct device *dev = &pdev->dev;
649 int nr, i;
650 int dai_i, ssi_i, src_i;
651
652 if (!of_data)
653 return;
654
655 dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai");
656 if (!dai_node)
657 return;
658
659 nr = of_get_child_count(dai_node);
660 if (!nr)
661 return;
662
663 dai_info = devm_kzalloc(dev,
664 sizeof(struct rsnd_dai_platform_info) * nr,
665 GFP_KERNEL);
666 if (!dai_info) {
667 dev_err(dev, "dai info allocation error\n");
668 return;
669 }
670
671 info->dai_info_nr = nr;
672 info->dai_info = dai_info;
673
674 ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
675 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
676
677#define mod_parse(name) \
678if (name##_node) { \
679 struct rsnd_##name##_platform_info *name##_info; \
680 \
681 name##_i = 0; \
682 for_each_child_of_node(name##_node, name##_np) { \
683 name##_info = info->name##_info + name##_i; \
684 \
685 if (name##_np == playback) \
686 dai_info->playback.name = name##_info; \
687 if (name##_np == capture) \
688 dai_info->capture.name = name##_info; \
689 \
690 name##_i++; \
691 } \
692}
693
694 /*
695 * parse all dai
696 */
697 dai_i = 0;
698 for_each_child_of_node(dai_node, dai_np) {
699 dai_info = info->dai_info + dai_i;
700
701 for (i = 0;; i++) {
702
703 playback = of_parse_phandle(dai_np, "playback", i);
704 capture = of_parse_phandle(dai_np, "capture", i);
705
706 if (!playback && !capture)
707 break;
708
709 mod_parse(ssi);
710 mod_parse(src);
711
712 if (playback)
713 of_node_put(playback);
714 if (capture)
715 of_node_put(capture);
716 }
717
718 dai_i++;
719 }
720}
721
623static int rsnd_dai_probe(struct platform_device *pdev, 722static int rsnd_dai_probe(struct platform_device *pdev,
723 const struct rsnd_of_data *of_data,
624 struct rsnd_priv *priv) 724 struct rsnd_priv *priv)
625{ 725{
626 struct snd_soc_dai_driver *drv; 726 struct snd_soc_dai_driver *drv;
@@ -628,13 +728,16 @@ static int rsnd_dai_probe(struct platform_device *pdev,
628 struct rsnd_dai *rdai; 728 struct rsnd_dai *rdai;
629 struct rsnd_mod *pmod, *cmod; 729 struct rsnd_mod *pmod, *cmod;
630 struct device *dev = rsnd_priv_to_dev(priv); 730 struct device *dev = rsnd_priv_to_dev(priv);
631 int dai_nr = info->dai_info_nr; 731 int dai_nr;
632 int i; 732 int i;
633 733
734 rsnd_of_parse_dai(pdev, of_data, priv);
735
634 /* 736 /*
635 * dai_nr should be set via dai_info_nr, 737 * dai_nr should be set via dai_info_nr,
636 * but allow it to keeping compatible 738 * but allow it to keeping compatible
637 */ 739 */
740 dai_nr = info->dai_info_nr;
638 if (!dai_nr) { 741 if (!dai_nr) {
639 /* get max dai nr */ 742 /* get max dai nr */
640 for (dai_nr = 0; dai_nr < 32; dai_nr++) { 743 for (dai_nr = 0; dai_nr < 32; dai_nr++) {
@@ -802,7 +905,10 @@ static int rsnd_probe(struct platform_device *pdev)
802 struct rsnd_priv *priv; 905 struct rsnd_priv *priv;
803 struct device *dev = &pdev->dev; 906 struct device *dev = &pdev->dev;
804 struct rsnd_dai *rdai; 907 struct rsnd_dai *rdai;
908 const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev);
909 const struct rsnd_of_data *of_data;
805 int (*probe_func[])(struct platform_device *pdev, 910 int (*probe_func[])(struct platform_device *pdev,
911 const struct rsnd_of_data *of_data,
806 struct rsnd_priv *priv) = { 912 struct rsnd_priv *priv) = {
807 rsnd_gen_probe, 913 rsnd_gen_probe,
808 rsnd_ssi_probe, 914 rsnd_ssi_probe,
@@ -812,7 +918,16 @@ static int rsnd_probe(struct platform_device *pdev)
812 }; 918 };
813 int ret, i; 919 int ret, i;
814 920
815 info = pdev->dev.platform_data; 921 info = NULL;
922 of_data = NULL;
923 if (of_id) {
924 info = devm_kzalloc(&pdev->dev,
925 sizeof(struct rcar_snd_info), GFP_KERNEL);
926 of_data = of_id->data;
927 } else {
928 info = pdev->dev.platform_data;
929 }
930
816 if (!info) { 931 if (!info) {
817 dev_err(dev, "driver needs R-Car sound information\n"); 932 dev_err(dev, "driver needs R-Car sound information\n");
818 return -ENODEV; 933 return -ENODEV;
@@ -835,7 +950,7 @@ static int rsnd_probe(struct platform_device *pdev)
835 * init each module 950 * init each module
836 */ 951 */
837 for (i = 0; i < ARRAY_SIZE(probe_func); i++) { 952 for (i = 0; i < ARRAY_SIZE(probe_func); i++) {
838 ret = probe_func[i](pdev, priv); 953 ret = probe_func[i](pdev, of_data, priv);
839 if (ret) 954 if (ret)
840 return ret; 955 return ret;
841 } 956 }
@@ -903,6 +1018,7 @@ static int rsnd_remove(struct platform_device *pdev)
903static struct platform_driver rsnd_driver = { 1018static struct platform_driver rsnd_driver = {
904 .driver = { 1019 .driver = {
905 .name = "rcar_sound", 1020 .name = "rcar_sound",
1021 .of_match_table = rsnd_of_match,
906 }, 1022 },
907 .probe = rsnd_probe, 1023 .probe = rsnd_probe,
908 .remove = rsnd_remove, 1024 .remove = rsnd_remove,
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 9094970dbdfb..50a1ef3eb1c6 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -359,13 +359,28 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
359/* 359/*
360 * Gen 360 * Gen
361 */ 361 */
362static void rsnd_of_parse_gen(struct platform_device *pdev,
363 const struct rsnd_of_data *of_data,
364 struct rsnd_priv *priv)
365{
366 struct rcar_snd_info *info = priv->info;
367
368 if (!of_data)
369 return;
370
371 info->flags = of_data->flags;
372}
373
362int rsnd_gen_probe(struct platform_device *pdev, 374int rsnd_gen_probe(struct platform_device *pdev,
375 const struct rsnd_of_data *of_data,
363 struct rsnd_priv *priv) 376 struct rsnd_priv *priv)
364{ 377{
365 struct device *dev = rsnd_priv_to_dev(priv); 378 struct device *dev = rsnd_priv_to_dev(priv);
366 struct rsnd_gen *gen; 379 struct rsnd_gen *gen;
367 int ret; 380 int ret;
368 381
382 rsnd_of_parse_gen(pdev, of_data, priv);
383
369 gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 384 gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
370 if (!gen) { 385 if (!gen) {
371 dev_err(dev, "GEN allocate failed\n"); 386 dev_err(dev, "GEN allocate failed\n");
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index c46e0afa54ae..619d198c7d2e 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -17,6 +17,8 @@
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/of_device.h>
21#include <linux/of_irq.h>
20#include <linux/sh_dma.h> 22#include <linux/sh_dma.h>
21#include <linux/workqueue.h> 23#include <linux/workqueue.h>
22#include <sound/rcar_snd.h> 24#include <sound/rcar_snd.h>
@@ -113,6 +115,7 @@ enum rsnd_reg {
113#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 115#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18
114#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 116#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
115 117
118struct rsnd_of_data;
116struct rsnd_priv; 119struct rsnd_priv;
117struct rsnd_mod; 120struct rsnd_mod;
118struct rsnd_dai; 121struct rsnd_dai;
@@ -260,6 +263,7 @@ int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
260 * R-Car Gen1/Gen2 263 * R-Car Gen1/Gen2
261 */ 264 */
262int rsnd_gen_probe(struct platform_device *pdev, 265int rsnd_gen_probe(struct platform_device *pdev,
266 const struct rsnd_of_data *of_data,
263 struct rsnd_priv *priv); 267 struct rsnd_priv *priv);
264void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, 268void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
265 struct rsnd_mod *mod, 269 struct rsnd_mod *mod,
@@ -273,6 +277,7 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
273int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); 277int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod);
274int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); 278int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate);
275int rsnd_adg_probe(struct platform_device *pdev, 279int rsnd_adg_probe(struct platform_device *pdev,
280 const struct rsnd_of_data *of_data,
276 struct rsnd_priv *priv); 281 struct rsnd_priv *priv);
277int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, 282int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
278 struct rsnd_mod *mod, 283 struct rsnd_mod *mod,
@@ -290,6 +295,10 @@ int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
290/* 295/*
291 * R-Car sound priv 296 * R-Car sound priv
292 */ 297 */
298struct rsnd_of_data {
299 u32 flags;
300};
301
293struct rsnd_priv { 302struct rsnd_priv {
294 303
295 struct device *dev; 304 struct device *dev;
@@ -348,6 +357,7 @@ struct rsnd_priv {
348 * R-Car SRC 357 * R-Car SRC
349 */ 358 */
350int rsnd_src_probe(struct platform_device *pdev, 359int rsnd_src_probe(struct platform_device *pdev,
360 const struct rsnd_of_data *of_data,
351 struct rsnd_priv *priv); 361 struct rsnd_priv *priv);
352struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); 362struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
353unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 363unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
@@ -366,6 +376,7 @@ int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
366 * R-Car SSI 376 * R-Car SSI
367 */ 377 */
368int rsnd_ssi_probe(struct platform_device *pdev, 378int rsnd_ssi_probe(struct platform_device *pdev,
379 const struct rsnd_of_data *of_data,
369 struct rsnd_priv *priv); 380 struct rsnd_priv *priv);
370struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 381struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
371struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, 382struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index ea6a214985d0..eee75ebf961c 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -628,7 +628,41 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
628 return &((struct rsnd_src *)(priv->src) + id)->mod; 628 return &((struct rsnd_src *)(priv->src) + id)->mod;
629} 629}
630 630
631static void rsnd_of_parse_src(struct platform_device *pdev,
632 const struct rsnd_of_data *of_data,
633 struct rsnd_priv *priv)
634{
635 struct device_node *src_node;
636 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
637 struct rsnd_src_platform_info *src_info;
638 struct device *dev = &pdev->dev;
639 int nr;
640
641 if (!of_data)
642 return;
643
644 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
645 if (!src_node)
646 return;
647
648 nr = of_get_child_count(src_node);
649 if (!nr)
650 return;
651
652 src_info = devm_kzalloc(dev,
653 sizeof(struct rsnd_src_platform_info) * nr,
654 GFP_KERNEL);
655 if (!src_info) {
656 dev_err(dev, "src info allocation error\n");
657 return;
658 }
659
660 info->src_info = src_info;
661 info->src_info_nr = nr;
662}
663
631int rsnd_src_probe(struct platform_device *pdev, 664int rsnd_src_probe(struct platform_device *pdev,
665 const struct rsnd_of_data *of_data,
632 struct rsnd_priv *priv) 666 struct rsnd_priv *priv)
633{ 667{
634 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 668 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
@@ -639,6 +673,8 @@ int rsnd_src_probe(struct platform_device *pdev,
639 char name[RSND_SRC_NAME_SIZE]; 673 char name[RSND_SRC_NAME_SIZE];
640 int i, nr; 674 int i, nr;
641 675
676 rsnd_of_parse_src(pdev, of_data, priv);
677
642 /* 678 /*
643 * init SRC 679 * init SRC
644 */ 680 */
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 633b23d209b9..4b7e20603dd7 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -588,7 +588,61 @@ static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *s
588 } 588 }
589} 589}
590 590
591
592static void rsnd_of_parse_ssi(struct platform_device *pdev,
593 const struct rsnd_of_data *of_data,
594 struct rsnd_priv *priv)
595{
596 struct device_node *node;
597 struct device_node *np;
598 struct rsnd_ssi_platform_info *ssi_info;
599 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
600 struct device *dev = &pdev->dev;
601 int nr, i;
602
603 if (!of_data)
604 return;
605
606 node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
607 if (!node)
608 return;
609
610 nr = of_get_child_count(node);
611 if (!nr)
612 return;
613
614 ssi_info = devm_kzalloc(dev,
615 sizeof(struct rsnd_ssi_platform_info) * nr,
616 GFP_KERNEL);
617 if (!ssi_info) {
618 dev_err(dev, "ssi info allocation error\n");
619 return;
620 }
621
622 info->ssi_info = ssi_info;
623 info->ssi_info_nr = nr;
624
625 i = -1;
626 for_each_child_of_node(node, np) {
627 i++;
628
629 ssi_info = info->ssi_info + i;
630
631 /*
632 * pin settings
633 */
634 if (of_get_property(np, "shared-pin", NULL))
635 ssi_info->flags |= RSND_SSI_CLK_PIN_SHARE;
636
637 /*
638 * irq
639 */
640 ssi_info->pio_irq = irq_of_parse_and_map(np, 0);
641 }
642}
643
591int rsnd_ssi_probe(struct platform_device *pdev, 644int rsnd_ssi_probe(struct platform_device *pdev,
645 const struct rsnd_of_data *of_data,
592 struct rsnd_priv *priv) 646 struct rsnd_priv *priv)
593{ 647{
594 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 648 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
@@ -600,6 +654,8 @@ int rsnd_ssi_probe(struct platform_device *pdev,
600 char name[RSND_SSI_NAME_SIZE]; 654 char name[RSND_SSI_NAME_SIZE];
601 int i, nr; 655 int i, nr;
602 656
657 rsnd_of_parse_ssi(pdev, of_data, priv);
658
603 /* 659 /*
604 * init SSI 660 * init SSI
605 */ 661 */
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 8aa086996866..260efc8466fc 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -23,21 +23,6 @@
23static int hw_write(struct snd_soc_codec *codec, unsigned int reg, 23static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
24 unsigned int value) 24 unsigned int value)
25{ 25{
26 int ret;
27
28 if (!snd_soc_codec_volatile_register(codec, reg) &&
29 reg < codec->driver->reg_cache_size &&
30 !codec->cache_bypass) {
31 ret = snd_soc_cache_write(codec, reg, value);
32 if (ret < 0)
33 return -1;
34 }
35
36 if (codec->cache_only) {
37 codec->cache_sync = 1;
38 return 0;
39 }
40
41 return regmap_write(codec->control_data, reg, value); 26 return regmap_write(codec->control_data, reg, value);
42} 27}
43 28
@@ -46,23 +31,11 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
46 int ret; 31 int ret;
47 unsigned int val; 32 unsigned int val;
48 33
49 if (reg >= codec->driver->reg_cache_size || 34 ret = regmap_read(codec->control_data, reg, &val);
50 snd_soc_codec_volatile_register(codec, reg) || 35 if (ret == 0)
51 codec->cache_bypass) { 36 return val;
52 if (codec->cache_only) 37 else
53 return -1;
54
55 ret = regmap_read(codec->control_data, reg, &val);
56 if (ret == 0)
57 return val;
58 else
59 return -1;
60 }
61
62 ret = snd_soc_cache_read(codec, reg, &val);
63 if (ret < 0)
64 return -1; 38 return -1;
65 return val;
66} 39}
67 40
68/** 41/**