aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ad193x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ad193x.c')
-rw-r--r--sound/soc/codecs/ad193x.c209
1 files changed, 98 insertions, 111 deletions
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 120602130b5c..a4a6bef2c0bb 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -30,21 +30,23 @@ struct ad193x_priv {
30/* 30/*
31 * AD193X volume/mute/de-emphasis etc. controls 31 * AD193X volume/mute/de-emphasis etc. controls
32 */ 32 */
33static const char *ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; 33static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
34 34
35static const struct soc_enum ad193x_deemp_enum = 35static const struct soc_enum ad193x_deemp_enum =
36 SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp); 36 SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp);
37 37
38static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
39
38static const struct snd_kcontrol_new ad193x_snd_controls[] = { 40static const struct snd_kcontrol_new ad193x_snd_controls[] = {
39 /* DAC volume control */ 41 /* DAC volume control */
40 SOC_DOUBLE_R("DAC1 Volume", AD193X_DAC_L1_VOL, 42 SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL,
41 AD193X_DAC_R1_VOL, 0, 0xFF, 1), 43 AD193X_DAC_R1_VOL, 0, 0xFF, 1, adau193x_tlv),
42 SOC_DOUBLE_R("DAC2 Volume", AD193X_DAC_L2_VOL, 44 SOC_DOUBLE_R_TLV("DAC2 Volume", AD193X_DAC_L2_VOL,
43 AD193X_DAC_R2_VOL, 0, 0xFF, 1), 45 AD193X_DAC_R2_VOL, 0, 0xFF, 1, adau193x_tlv),
44 SOC_DOUBLE_R("DAC3 Volume", AD193X_DAC_L3_VOL, 46 SOC_DOUBLE_R_TLV("DAC3 Volume", AD193X_DAC_L3_VOL,
45 AD193X_DAC_R3_VOL, 0, 0xFF, 1), 47 AD193X_DAC_R3_VOL, 0, 0xFF, 1, adau193x_tlv),
46 SOC_DOUBLE_R("DAC4 Volume", AD193X_DAC_L4_VOL, 48 SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL,
47 AD193X_DAC_R4_VOL, 0, 0xFF, 1), 49 AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv),
48 50
49 /* ADC switch control */ 51 /* ADC switch control */
50 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE, 52 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
@@ -75,6 +77,7 @@ static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
75 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 77 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
76 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0), 78 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
77 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0), 79 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
80 SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0),
78 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 81 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
79 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 82 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
80 SND_SOC_DAPM_OUTPUT("DAC3OUT"), 83 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
@@ -84,16 +87,17 @@ static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
84}; 87};
85 88
86static const struct snd_soc_dapm_route audio_paths[] = { 89static const struct snd_soc_dapm_route audio_paths[] = {
87 { "DAC", NULL, "PLL_PWR" }, 90 { "DAC", NULL, "SYSCLK" },
88 { "ADC", NULL, "PLL_PWR" }, 91 { "ADC", NULL, "SYSCLK" },
89 { "DAC", NULL, "ADC_PWR" }, 92 { "DAC", NULL, "ADC_PWR" },
90 { "ADC", NULL, "ADC_PWR" }, 93 { "ADC", NULL, "ADC_PWR" },
91 { "DAC1OUT", "DAC1 Switch", "DAC" }, 94 { "DAC1OUT", NULL, "DAC" },
92 { "DAC2OUT", "DAC2 Switch", "DAC" }, 95 { "DAC2OUT", NULL, "DAC" },
93 { "DAC3OUT", "DAC3 Switch", "DAC" }, 96 { "DAC3OUT", NULL, "DAC" },
94 { "DAC4OUT", "DAC4 Switch", "DAC" }, 97 { "DAC4OUT", NULL, "DAC" },
95 { "ADC", "ADC1 Switch", "ADC1IN" }, 98 { "ADC", NULL, "ADC1IN" },
96 { "ADC", "ADC2 Switch", "ADC2IN" }, 99 { "ADC", NULL, "ADC2IN" },
100 { "SYSCLK", NULL, "PLL_PWR" },
97}; 101};
98 102
99/* 103/*
@@ -102,14 +106,14 @@ static const struct snd_soc_dapm_route audio_paths[] = {
102 106
103static int ad193x_mute(struct snd_soc_dai *dai, int mute) 107static int ad193x_mute(struct snd_soc_dai *dai, int mute)
104{ 108{
105 struct snd_soc_codec *codec = dai->codec; 109 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
106 110
107 if (mute) 111 if (mute)
108 snd_soc_update_bits(codec, AD193X_DAC_CTRL2, 112 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
109 AD193X_DAC_MASTER_MUTE, 113 AD193X_DAC_MASTER_MUTE,
110 AD193X_DAC_MASTER_MUTE); 114 AD193X_DAC_MASTER_MUTE);
111 else 115 else
112 snd_soc_update_bits(codec, AD193X_DAC_CTRL2, 116 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
113 AD193X_DAC_MASTER_MUTE, 0); 117 AD193X_DAC_MASTER_MUTE, 0);
114 118
115 return 0; 119 return 0;
@@ -118,36 +122,30 @@ static int ad193x_mute(struct snd_soc_dai *dai, int mute)
118static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 122static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
119 unsigned int rx_mask, int slots, int width) 123 unsigned int rx_mask, int slots, int width)
120{ 124{
121 struct snd_soc_codec *codec = dai->codec; 125 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
122 int dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1); 126 unsigned int channels;
123 int adc_reg = snd_soc_read(codec, AD193X_ADC_CTRL2);
124
125 dac_reg &= ~AD193X_DAC_CHAN_MASK;
126 adc_reg &= ~AD193X_ADC_CHAN_MASK;
127 127
128 switch (slots) { 128 switch (slots) {
129 case 2: 129 case 2:
130 dac_reg |= AD193X_DAC_2_CHANNELS << AD193X_DAC_CHAN_SHFT; 130 channels = AD193X_2_CHANNELS;
131 adc_reg |= AD193X_ADC_2_CHANNELS << AD193X_ADC_CHAN_SHFT;
132 break; 131 break;
133 case 4: 132 case 4:
134 dac_reg |= AD193X_DAC_4_CHANNELS << AD193X_DAC_CHAN_SHFT; 133 channels = AD193X_4_CHANNELS;
135 adc_reg |= AD193X_ADC_4_CHANNELS << AD193X_ADC_CHAN_SHFT;
136 break; 134 break;
137 case 8: 135 case 8:
138 dac_reg |= AD193X_DAC_8_CHANNELS << AD193X_DAC_CHAN_SHFT; 136 channels = AD193X_8_CHANNELS;
139 adc_reg |= AD193X_ADC_8_CHANNELS << AD193X_ADC_CHAN_SHFT;
140 break; 137 break;
141 case 16: 138 case 16:
142 dac_reg |= AD193X_DAC_16_CHANNELS << AD193X_DAC_CHAN_SHFT; 139 channels = AD193X_16_CHANNELS;
143 adc_reg |= AD193X_ADC_16_CHANNELS << AD193X_ADC_CHAN_SHFT;
144 break; 140 break;
145 default: 141 default:
146 return -EINVAL; 142 return -EINVAL;
147 } 143 }
148 144
149 snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg); 145 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
150 snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg); 146 AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT);
147 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
148 AD193X_ADC_CHAN_MASK, channels << AD193X_ADC_CHAN_SHFT);
151 149
152 return 0; 150 return 0;
153} 151}
@@ -155,24 +153,20 @@ static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
155static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, 153static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
156 unsigned int fmt) 154 unsigned int fmt)
157{ 155{
158 struct snd_soc_codec *codec = codec_dai->codec; 156 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec_dai->codec);
159 int adc_reg1, adc_reg2, dac_reg; 157 unsigned int adc_serfmt = 0;
160 158 unsigned int adc_fmt = 0;
161 adc_reg1 = snd_soc_read(codec, AD193X_ADC_CTRL1); 159 unsigned int dac_fmt = 0;
162 adc_reg2 = snd_soc_read(codec, AD193X_ADC_CTRL2);
163 dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
164 160
165 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S 161 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
166 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) 162 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
167 */ 163 */
168 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 164 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
169 case SND_SOC_DAIFMT_I2S: 165 case SND_SOC_DAIFMT_I2S:
170 adc_reg1 &= ~AD193X_ADC_SERFMT_MASK; 166 adc_serfmt |= AD193X_ADC_SERFMT_TDM;
171 adc_reg1 |= AD193X_ADC_SERFMT_TDM;
172 break; 167 break;
173 case SND_SOC_DAIFMT_DSP_A: 168 case SND_SOC_DAIFMT_DSP_A:
174 adc_reg1 &= ~AD193X_ADC_SERFMT_MASK; 169 adc_serfmt |= AD193X_ADC_SERFMT_AUX;
175 adc_reg1 |= AD193X_ADC_SERFMT_AUX;
176 break; 170 break;
177 default: 171 default:
178 return -EINVAL; 172 return -EINVAL;
@@ -180,29 +174,20 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
180 174
181 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 175 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
182 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */ 176 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
183 adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
184 adc_reg2 &= ~AD193X_ADC_BCLK_INV;
185 dac_reg &= ~AD193X_DAC_LEFT_HIGH;
186 dac_reg &= ~AD193X_DAC_BCLK_INV;
187 break; 177 break;
188 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */ 178 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
189 adc_reg2 |= AD193X_ADC_LEFT_HIGH; 179 adc_fmt |= AD193X_ADC_LEFT_HIGH;
190 adc_reg2 &= ~AD193X_ADC_BCLK_INV; 180 dac_fmt |= AD193X_DAC_LEFT_HIGH;
191 dac_reg |= AD193X_DAC_LEFT_HIGH;
192 dac_reg &= ~AD193X_DAC_BCLK_INV;
193 break; 181 break;
194 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */ 182 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
195 adc_reg2 &= ~AD193X_ADC_LEFT_HIGH; 183 adc_fmt |= AD193X_ADC_BCLK_INV;
196 adc_reg2 |= AD193X_ADC_BCLK_INV; 184 dac_fmt |= AD193X_DAC_BCLK_INV;
197 dac_reg &= ~AD193X_DAC_LEFT_HIGH;
198 dac_reg |= AD193X_DAC_BCLK_INV;
199 break; 185 break;
200
201 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */ 186 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
202 adc_reg2 |= AD193X_ADC_LEFT_HIGH; 187 adc_fmt |= AD193X_ADC_LEFT_HIGH;
203 adc_reg2 |= AD193X_ADC_BCLK_INV; 188 adc_fmt |= AD193X_ADC_BCLK_INV;
204 dac_reg |= AD193X_DAC_LEFT_HIGH; 189 dac_fmt |= AD193X_DAC_LEFT_HIGH;
205 dac_reg |= AD193X_DAC_BCLK_INV; 190 dac_fmt |= AD193X_DAC_BCLK_INV;
206 break; 191 break;
207 default: 192 default:
208 return -EINVAL; 193 return -EINVAL;
@@ -210,36 +195,31 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
210 195
211 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 196 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
212 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */ 197 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
213 adc_reg2 |= AD193X_ADC_LCR_MASTER; 198 adc_fmt |= AD193X_ADC_LCR_MASTER;
214 adc_reg2 |= AD193X_ADC_BCLK_MASTER; 199 adc_fmt |= AD193X_ADC_BCLK_MASTER;
215 dac_reg |= AD193X_DAC_LCR_MASTER; 200 dac_fmt |= AD193X_DAC_LCR_MASTER;
216 dac_reg |= AD193X_DAC_BCLK_MASTER; 201 dac_fmt |= AD193X_DAC_BCLK_MASTER;
217 break; 202 break;
218 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */ 203 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
219 adc_reg2 |= AD193X_ADC_LCR_MASTER; 204 adc_fmt |= AD193X_ADC_LCR_MASTER;
220 adc_reg2 &= ~AD193X_ADC_BCLK_MASTER; 205 dac_fmt |= AD193X_DAC_LCR_MASTER;
221 dac_reg |= AD193X_DAC_LCR_MASTER;
222 dac_reg &= ~AD193X_DAC_BCLK_MASTER;
223 break; 206 break;
224 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */ 207 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
225 adc_reg2 &= ~AD193X_ADC_LCR_MASTER; 208 adc_fmt |= AD193X_ADC_BCLK_MASTER;
226 adc_reg2 |= AD193X_ADC_BCLK_MASTER; 209 dac_fmt |= AD193X_DAC_BCLK_MASTER;
227 dac_reg &= ~AD193X_DAC_LCR_MASTER;
228 dac_reg |= AD193X_DAC_BCLK_MASTER;
229 break; 210 break;
230 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */ 211 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
231 adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
232 adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
233 dac_reg &= ~AD193X_DAC_LCR_MASTER;
234 dac_reg &= ~AD193X_DAC_BCLK_MASTER;
235 break; 212 break;
236 default: 213 default:
237 return -EINVAL; 214 return -EINVAL;
238 } 215 }
239 216
240 snd_soc_write(codec, AD193X_ADC_CTRL1, adc_reg1); 217 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
241 snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg2); 218 AD193X_ADC_SERFMT_MASK, adc_serfmt);
242 snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg); 219 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
220 AD193X_ADC_FMT_MASK, adc_fmt);
221 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
222 AD193X_DAC_FMT_MASK, dac_fmt);
243 223
244 return 0; 224 return 0;
245} 225}
@@ -299,20 +279,20 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
299 break; 279 break;
300 } 280 }
301 281
302 snd_soc_update_bits(codec, AD193X_PLL_CLK_CTRL0, 282 regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0,
303 AD193X_PLL_INPUT_MASK, master_rate); 283 AD193X_PLL_INPUT_MASK, master_rate);
304 284
305 snd_soc_update_bits(codec, AD193X_DAC_CTRL2, 285 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
306 AD193X_DAC_WORD_LEN_MASK, 286 AD193X_DAC_WORD_LEN_MASK,
307 word_len << AD193X_DAC_WORD_LEN_SHFT); 287 word_len << AD193X_DAC_WORD_LEN_SHFT);
308 288
309 snd_soc_update_bits(codec, AD193X_ADC_CTRL1, 289 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
310 AD193X_ADC_WORD_LEN_MASK, word_len); 290 AD193X_ADC_WORD_LEN_MASK, word_len);
311 291
312 return 0; 292 return 0;
313} 293}
314 294
315static struct snd_soc_dai_ops ad193x_dai_ops = { 295static const struct snd_soc_dai_ops ad193x_dai_ops = {
316 .hw_params = ad193x_hw_params, 296 .hw_params = ad193x_hw_params,
317 .digital_mute = ad193x_mute, 297 .digital_mute = ad193x_mute,
318 .set_tdm_slot = ad193x_set_tdm_slot, 298 .set_tdm_slot = ad193x_set_tdm_slot,
@@ -345,7 +325,6 @@ static struct snd_soc_dai_driver ad193x_dai = {
345static int ad193x_probe(struct snd_soc_codec *codec) 325static int ad193x_probe(struct snd_soc_codec *codec)
346{ 326{
347 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 327 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
348 struct snd_soc_dapm_context *dapm = &codec->dapm;
349 int ret; 328 int ret;
350 329
351 codec->control_data = ad193x->regmap; 330 codec->control_data = ad193x->regmap;
@@ -358,32 +337,37 @@ static int ad193x_probe(struct snd_soc_codec *codec)
358 /* default setting for ad193x */ 337 /* default setting for ad193x */
359 338
360 /* unmute dac channels */ 339 /* unmute dac channels */
361 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0); 340 regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0);
362 /* de-emphasis: 48kHz, powedown dac */ 341 /* de-emphasis: 48kHz, powedown dac */
363 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A); 342 regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
364 /* powerdown dac, dac in tdm mode */ 343 /* powerdown dac, dac in tdm mode */
365 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41); 344 regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x41);
366 /* high-pass filter enable */ 345 /* high-pass filter enable */
367 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3); 346 regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
368 /* sata delay=1, adc aux mode */ 347 /* sata delay=1, adc aux mode */
369 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43); 348 regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
370 /* pll input: mclki/xi */ 349 /* pll input: mclki/xi */
371 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ 350 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
372 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04); 351 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
373
374 snd_soc_add_controls(codec, ad193x_snd_controls,
375 ARRAY_SIZE(ad193x_snd_controls));
376 snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets,
377 ARRAY_SIZE(ad193x_dapm_widgets));
378 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
379 352
380 return ret; 353 return ret;
381} 354}
382 355
383static struct snd_soc_codec_driver soc_codec_dev_ad193x = { 356static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
384 .probe = ad193x_probe, 357 .probe = ad193x_probe,
358 .controls = ad193x_snd_controls,
359 .num_controls = ARRAY_SIZE(ad193x_snd_controls),
360 .dapm_widgets = ad193x_dapm_widgets,
361 .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets),
362 .dapm_routes = audio_paths,
363 .num_dapm_routes = ARRAY_SIZE(audio_paths),
385}; 364};
386 365
366static bool adau193x_reg_volatile(struct device *dev, unsigned int reg)
367{
368 return false;
369}
370
387#if defined(CONFIG_SPI_MASTER) 371#if defined(CONFIG_SPI_MASTER)
388 372
389static const struct regmap_config ad193x_spi_regmap_config = { 373static const struct regmap_config ad193x_spi_regmap_config = {
@@ -391,6 +375,9 @@ static const struct regmap_config ad193x_spi_regmap_config = {
391 .reg_bits = 16, 375 .reg_bits = 16,
392 .read_flag_mask = 0x09, 376 .read_flag_mask = 0x09,
393 .write_flag_mask = 0x08, 377 .write_flag_mask = 0x08,
378
379 .max_register = AD193X_NUM_REGS - 1,
380 .volatile_reg = adau193x_reg_volatile,
394}; 381};
395 382
396static int __devinit ad193x_spi_probe(struct spi_device *spi) 383static int __devinit ad193x_spi_probe(struct spi_device *spi)
@@ -398,14 +385,15 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
398 struct ad193x_priv *ad193x; 385 struct ad193x_priv *ad193x;
399 int ret; 386 int ret;
400 387
401 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL); 388 ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv),
389 GFP_KERNEL);
402 if (ad193x == NULL) 390 if (ad193x == NULL)
403 return -ENOMEM; 391 return -ENOMEM;
404 392
405 ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config); 393 ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
406 if (IS_ERR(ad193x->regmap)) { 394 if (IS_ERR(ad193x->regmap)) {
407 ret = PTR_ERR(ad193x->regmap); 395 ret = PTR_ERR(ad193x->regmap);
408 goto err_free; 396 goto err_out;
409 } 397 }
410 398
411 spi_set_drvdata(spi, ad193x); 399 spi_set_drvdata(spi, ad193x);
@@ -419,9 +407,7 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
419 407
420err_regmap_exit: 408err_regmap_exit:
421 regmap_exit(ad193x->regmap); 409 regmap_exit(ad193x->regmap);
422err_free: 410err_out:
423 kfree(ad193x);
424
425 return ret; 411 return ret;
426} 412}
427 413
@@ -431,7 +417,6 @@ static int __devexit ad193x_spi_remove(struct spi_device *spi)
431 417
432 snd_soc_unregister_codec(&spi->dev); 418 snd_soc_unregister_codec(&spi->dev);
433 regmap_exit(ad193x->regmap); 419 regmap_exit(ad193x->regmap);
434 kfree(ad193x);
435 return 0; 420 return 0;
436} 421}
437 422
@@ -450,6 +435,9 @@ static struct spi_driver ad193x_spi_driver = {
450static const struct regmap_config ad193x_i2c_regmap_config = { 435static const struct regmap_config ad193x_i2c_regmap_config = {
451 .val_bits = 8, 436 .val_bits = 8,
452 .reg_bits = 8, 437 .reg_bits = 8,
438
439 .max_register = AD193X_NUM_REGS - 1,
440 .volatile_reg = adau193x_reg_volatile,
453}; 441};
454 442
455static const struct i2c_device_id ad193x_id[] = { 443static const struct i2c_device_id ad193x_id[] = {
@@ -465,14 +453,15 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
465 struct ad193x_priv *ad193x; 453 struct ad193x_priv *ad193x;
466 int ret; 454 int ret;
467 455
468 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL); 456 ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv),
457 GFP_KERNEL);
469 if (ad193x == NULL) 458 if (ad193x == NULL)
470 return -ENOMEM; 459 return -ENOMEM;
471 460
472 ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config); 461 ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
473 if (IS_ERR(ad193x->regmap)) { 462 if (IS_ERR(ad193x->regmap)) {
474 ret = PTR_ERR(ad193x->regmap); 463 ret = PTR_ERR(ad193x->regmap);
475 goto err_free; 464 goto err_out;
476 } 465 }
477 466
478 i2c_set_clientdata(client, ad193x); 467 i2c_set_clientdata(client, ad193x);
@@ -486,8 +475,7 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
486 475
487err_regmap_exit: 476err_regmap_exit:
488 regmap_exit(ad193x->regmap); 477 regmap_exit(ad193x->regmap);
489err_free: 478err_out:
490 kfree(ad193x);
491 return ret; 479 return ret;
492} 480}
493 481
@@ -497,7 +485,6 @@ static int __devexit ad193x_i2c_remove(struct i2c_client *client)
497 485
498 snd_soc_unregister_codec(&client->dev); 486 snd_soc_unregister_codec(&client->dev);
499 regmap_exit(ad193x->regmap); 487 regmap_exit(ad193x->regmap);
500 kfree(ad193x);
501 return 0; 488 return 0;
502} 489}
503 490