ASoC: wm9081: fix resource reclaim in wm9081_register error path
[deliverable/linux.git] / sound / soc / codecs / twl4030.c
CommitLineData
cc17557e
SS
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman, <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/platform_device.h>
b07682b6 29#include <linux/i2c/twl.h>
5a0e3ad6 30#include <linux/slab.h>
cc17557e
SS
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/soc.h>
35#include <sound/soc-dapm.h>
36#include <sound/initval.h>
c10b82cf 37#include <sound/tlv.h>
cc17557e
SS
38
39#include "twl4030.h"
40
41/*
42 * twl4030 register cache & default register settings
43 */
44static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
45 0x00, /* this register not used */
33f92ed4 46 0x00, /* REG_CODEC_MODE (0x1) */
ee4ccac7 47 0x00, /* REG_OPTION (0x2) */
cc17557e
SS
48 0x00, /* REG_UNKNOWN (0x3) */
49 0x00, /* REG_MICBIAS_CTL (0x4) */
979bb1f4 50 0x00, /* REG_ANAMICL (0x5) */
5920b453
GI
51 0x00, /* REG_ANAMICR (0x6) */
52 0x00, /* REG_AVADC_CTL (0x7) */
cc17557e
SS
53 0x00, /* REG_ADCMICSEL (0x8) */
54 0x00, /* REG_DIGMIXING (0x9) */
33f92ed4
PU
55 0x0f, /* REG_ATXL1PGA (0xA) */
56 0x0f, /* REG_ATXR1PGA (0xB) */
57 0x0f, /* REG_AVTXL2PGA (0xC) */
58 0x0f, /* REG_AVTXR2PGA (0xD) */
c42a59ea 59 0x00, /* REG_AUDIO_IF (0xE) */
cc17557e 60 0x00, /* REG_VOICE_IF (0xF) */
33f92ed4
PU
61 0x3f, /* REG_ARXR1PGA (0x10) */
62 0x3f, /* REG_ARXL1PGA (0x11) */
63 0x3f, /* REG_ARXR2PGA (0x12) */
64 0x3f, /* REG_ARXL2PGA (0x13) */
65 0x25, /* REG_VRXPGA (0x14) */
cc17557e
SS
66 0x00, /* REG_VSTPGA (0x15) */
67 0x00, /* REG_VRX2ARXPGA (0x16) */
c8124593 68 0x00, /* REG_AVDAC_CTL (0x17) */
cc17557e 69 0x00, /* REG_ARX2VTXPGA (0x18) */
33f92ed4
PU
70 0x32, /* REG_ARXL1_APGA_CTL (0x19) */
71 0x32, /* REG_ARXR1_APGA_CTL (0x1A) */
72 0x32, /* REG_ARXL2_APGA_CTL (0x1B) */
73 0x32, /* REG_ARXR2_APGA_CTL (0x1C) */
cc17557e
SS
74 0x00, /* REG_ATX2ARXPGA (0x1D) */
75 0x00, /* REG_BT_IF (0x1E) */
33f92ed4 76 0x55, /* REG_BTPGA (0x1F) */
cc17557e
SS
77 0x00, /* REG_BTSTPGA (0x20) */
78 0x00, /* REG_EAR_CTL (0x21) */
e47c796d
PU
79 0x00, /* REG_HS_SEL (0x22) */
80 0x00, /* REG_HS_GAIN_SET (0x23) */
cc17557e
SS
81 0x00, /* REG_HS_POPN_SET (0x24) */
82 0x00, /* REG_PREDL_CTL (0x25) */
83 0x00, /* REG_PREDR_CTL (0x26) */
84 0x00, /* REG_PRECKL_CTL (0x27) */
85 0x00, /* REG_PRECKR_CTL (0x28) */
86 0x00, /* REG_HFL_CTL (0x29) */
87 0x00, /* REG_HFR_CTL (0x2A) */
33f92ed4 88 0x05, /* REG_ALC_CTL (0x2B) */
cc17557e
SS
89 0x00, /* REG_ALC_SET1 (0x2C) */
90 0x00, /* REG_ALC_SET2 (0x2D) */
91 0x00, /* REG_BOOST_CTL (0x2E) */
f8d05bdb 92 0x00, /* REG_SOFTVOL_CTL (0x2F) */
33f92ed4 93 0x13, /* REG_DTMF_FREQSEL (0x30) */
cc17557e
SS
94 0x00, /* REG_DTMF_TONEXT1H (0x31) */
95 0x00, /* REG_DTMF_TONEXT1L (0x32) */
96 0x00, /* REG_DTMF_TONEXT2H (0x33) */
97 0x00, /* REG_DTMF_TONEXT2L (0x34) */
33f92ed4
PU
98 0x79, /* REG_DTMF_TONOFF (0x35) */
99 0x11, /* REG_DTMF_WANONOFF (0x36) */
cc17557e
SS
100 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
102 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
c8124593 103 0x06, /* REG_APLL_CTL (0x3A) */
cc17557e 104 0x00, /* REG_DTMF_CTL (0x3B) */
33f92ed4
PU
105 0x44, /* REG_DTMF_PGA_CTL2 (0x3C) */
106 0x69, /* REG_DTMF_PGA_CTL1 (0x3D) */
cc17557e
SS
107 0x00, /* REG_MISC_SET_1 (0x3E) */
108 0x00, /* REG_PCMBTMUX (0x3F) */
109 0x00, /* not used (0x40) */
110 0x00, /* not used (0x41) */
111 0x00, /* not used (0x42) */
112 0x00, /* REG_RX_PATH_SEL (0x43) */
33f92ed4 113 0x32, /* REG_VDL_APGA_CTL (0x44) */
cc17557e
SS
114 0x00, /* REG_VIBRA_CTL (0x45) */
115 0x00, /* REG_VIBRA_SET (0x46) */
116 0x00, /* REG_VIBRA_PWM_SET (0x47) */
117 0x00, /* REG_ANAMIC_GAIN (0x48) */
118 0x00, /* REG_MISC_SET_2 (0x49) */
f3b5d300 119 0x00, /* REG_SW_SHADOW (0x4A) - Shadow, non HW register */
cc17557e
SS
120};
121
7393958f
PU
122/* codec private data */
123struct twl4030_priv {
7a1fecf5
PU
124 struct snd_soc_codec codec;
125
7393958f 126 unsigned int codec_powered;
7b4c734e
PU
127
128 /* reference counts of AIF/APLL users */
2845fa13 129 unsigned int apll_enabled;
7220b9f4
PU
130
131 struct snd_pcm_substream *master_substream;
132 struct snd_pcm_substream *slave_substream;
6b87a91f
PU
133
134 unsigned int configured;
135 unsigned int rate;
136 unsigned int sample_bits;
137 unsigned int channels;
6943c92e
PU
138
139 unsigned int sysclk;
140
c96907f2
PU
141 /* Output (with associated amp) states */
142 u8 hsl_enabled, hsr_enabled;
143 u8 earpiece_enabled;
144 u8 predrivel_enabled, predriver_enabled;
145 u8 carkitl_enabled, carkitr_enabled;
01ea6ba2
PU
146
147 /* Delay needed after enabling the digimic interface */
148 unsigned int digimic_delay;
7393958f
PU
149};
150
cc17557e
SS
151/*
152 * read twl4030 register cache
153 */
154static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
155 unsigned int reg)
156{
d08664fd 157 u8 *cache = codec->reg_cache;
cc17557e 158
91432e97
IM
159 if (reg >= TWL4030_CACHEREGNUM)
160 return -EIO;
161
cc17557e
SS
162 return cache[reg];
163}
164
165/*
166 * write twl4030 register cache
167 */
168static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
169 u8 reg, u8 value)
170{
171 u8 *cache = codec->reg_cache;
172
173 if (reg >= TWL4030_CACHEREGNUM)
174 return;
175 cache[reg] = value;
176}
177
178/*
179 * write to the twl4030 register space
180 */
181static int twl4030_write(struct snd_soc_codec *codec,
182 unsigned int reg, unsigned int value)
183{
b2c812e2 184 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
c96907f2
PU
185 int write_to_reg = 0;
186
cc17557e 187 twl4030_write_reg_cache(codec, reg, value);
c96907f2
PU
188 if (likely(reg < TWL4030_REG_SW_SHADOW)) {
189 /* Decide if the given register can be written */
190 switch (reg) {
191 case TWL4030_REG_EAR_CTL:
192 if (twl4030->earpiece_enabled)
193 write_to_reg = 1;
194 break;
195 case TWL4030_REG_PREDL_CTL:
196 if (twl4030->predrivel_enabled)
197 write_to_reg = 1;
198 break;
199 case TWL4030_REG_PREDR_CTL:
200 if (twl4030->predriver_enabled)
201 write_to_reg = 1;
202 break;
203 case TWL4030_REG_PRECKL_CTL:
204 if (twl4030->carkitl_enabled)
205 write_to_reg = 1;
206 break;
207 case TWL4030_REG_PRECKR_CTL:
208 if (twl4030->carkitr_enabled)
209 write_to_reg = 1;
210 break;
211 case TWL4030_REG_HS_GAIN_SET:
212 if (twl4030->hsl_enabled || twl4030->hsr_enabled)
213 write_to_reg = 1;
214 break;
215 default:
216 /* All other register can be written */
217 write_to_reg = 1;
218 break;
219 }
220 if (write_to_reg)
221 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
222 value, reg);
223 }
224 return 0;
cc17557e
SS
225}
226
db04e2c5 227static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
cc17557e 228{
b2c812e2 229 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
7a1fecf5 230 int mode;
cc17557e 231
7393958f
PU
232 if (enable == twl4030->codec_powered)
233 return;
234
db04e2c5 235 if (enable)
7a1fecf5 236 mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
db04e2c5 237 else
7a1fecf5 238 mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
cc17557e 239
7a1fecf5
PU
240 if (mode >= 0) {
241 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
242 twl4030->codec_powered = enable;
243 }
cc17557e
SS
244
245 /* REVISIT: this delay is present in TI sample drivers */
246 /* but there seems to be no TRM requirement for it */
247 udelay(10);
248}
249
9fdcc0f7 250static inline void twl4030_check_defaults(struct snd_soc_codec *codec)
cc17557e 251{
9fdcc0f7
PU
252 int i, difference = 0;
253 u8 val;
254
255 dev_dbg(codec->dev, "Checking TWL audio default configuration\n");
256 for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) {
257 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i);
258 if (val != twl4030_reg[i]) {
259 difference++;
260 dev_dbg(codec->dev,
261 "Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n",
262 i, val, twl4030_reg[i]);
263 }
264 }
265 dev_dbg(codec->dev, "Found %d non maching registers. %s\n",
266 difference, difference ? "Not OK" : "OK");
267}
cc17557e 268
a3a29b55
PU
269static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
270{
271 int i;
cc17557e
SS
272
273 /* set all audio section registers to reasonable defaults */
274 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
68d01955 275 if (i != TWL4030_REG_APLL_CTL)
a3a29b55 276 twl4030_write(codec, i, twl4030_reg[i]);
cc17557e
SS
277
278}
279
ee4ccac7 280static void twl4030_init_chip(struct platform_device *pdev)
7393958f 281{
ee4ccac7
PU
282 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
283 struct twl4030_setup_data *setup = socdev->codec_data;
284 struct snd_soc_codec *codec = socdev->card->codec;
b2c812e2 285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
ee4ccac7
PU
286 u8 reg, byte;
287 int i = 0;
7393958f 288
9fdcc0f7
PU
289 /* Check defaults, if instructed before anything else */
290 if (setup && setup->check_defaults)
291 twl4030_check_defaults(codec);
7a1fecf5 292
a3a29b55
PU
293 /* Reset registers, if no setup data or if instructed to do so */
294 if (!setup || (setup && setup->reset_registers))
295 twl4030_reset_registers(codec);
7393958f 296
ee4ccac7 297 /* Refresh APLL_CTL register from HW */
9fdcc0f7 298 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
ee4ccac7
PU
299 TWL4030_REG_APLL_CTL);
300 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte);
006f367e 301
ee4ccac7
PU
302 /* anti-pop when changing analog gain */
303 reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
304 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
305 reg | TWL4030_SMOOTH_ANAVOL_EN);
7393958f 306
ee4ccac7
PU
307 twl4030_write(codec, TWL4030_REG_OPTION,
308 TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
309 TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
006f367e 310
3c36cc68
PU
311 /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */
312 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
313
ee4ccac7
PU
314 /* Machine dependent setup */
315 if (!setup)
7393958f
PU
316 return;
317
01ea6ba2
PU
318 twl4030->digimic_delay = setup->digimic_delay;
319
ee4ccac7
PU
320 /* Configuration for headset ramp delay from setup data */
321 if (setup->sysclk != twl4030->sysclk)
322 dev_warn(codec->dev,
323 "Mismatch in APLL mclk: %u (configured: %u)\n",
324 setup->sysclk, twl4030->sysclk);
325
326 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
327 reg &= ~TWL4030_RAMP_DELAY;
328 reg |= (setup->ramp_delay_value << 2);
329 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
006f367e
PU
330
331 /* initiate offset cancellation */
ee4ccac7
PU
332 twl4030_codec_enable(codec, 1);
333
334 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
335 reg &= ~TWL4030_OFFSET_CNCL_SEL;
336 reg |= setup->offset_cncl_path;
006f367e 337 twl4030_write(codec, TWL4030_REG_ANAMICL,
ee4ccac7 338 reg | TWL4030_CNCL_OFFSET_START);
006f367e
PU
339
340 /* wait for offset cancellation to complete */
341 do {
342 /* this takes a little while, so don't slam i2c */
343 udelay(2000);
fc7b92fc 344 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
006f367e
PU
345 TWL4030_REG_ANAMICL);
346 } while ((i++ < 100) &&
347 ((byte & TWL4030_CNCL_OFFSET_START) ==
348 TWL4030_CNCL_OFFSET_START));
349
350 /* Make sure that the reg_cache has the same value as the HW */
351 twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte);
352
006f367e 353 twl4030_codec_enable(codec, 0);
006f367e
PU
354}
355
ee4ccac7 356static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
006f367e 357{
ee4ccac7
PU
358 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
359 int status = -1;
360
361 if (enable) {
362 twl4030->apll_enabled++;
363 if (twl4030->apll_enabled == 1)
364 status = twl4030_codec_enable_resource(
365 TWL4030_CODEC_RES_APLL);
366 } else {
367 twl4030->apll_enabled--;
368 if (!twl4030->apll_enabled)
369 status = twl4030_codec_disable_resource(
370 TWL4030_CODEC_RES_APLL);
371 }
372
373 if (status >= 0)
374 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
006f367e
PU
375}
376
5e98a464 377/* Earpiece */
1a787e7a
JS
378static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = {
379 SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0),
380 SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0),
381 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0),
382 SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0),
383};
5e98a464 384
2a6f5c58 385/* PreDrive Left */
1a787e7a
JS
386static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = {
387 SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0),
388 SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0),
389 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0),
390 SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0),
391};
2a6f5c58
PU
392
393/* PreDrive Right */
1a787e7a
JS
394static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = {
395 SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0),
396 SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0),
397 SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0),
398 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0),
399};
2a6f5c58 400
dfad21a2 401/* Headset Left */
1a787e7a
JS
402static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = {
403 SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0),
404 SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0),
405 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0),
406};
dfad21a2
PU
407
408/* Headset Right */
1a787e7a
JS
409static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = {
410 SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0),
411 SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0),
412 SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0),
413};
dfad21a2 414
5152d8c2 415/* Carkit Left */
1a787e7a
JS
416static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = {
417 SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0),
418 SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0),
419 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0),
420};
5152d8c2
PU
421
422/* Carkit Right */
1a787e7a
JS
423static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = {
424 SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0),
425 SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0),
426 SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0),
427};
5152d8c2 428
df339804
PU
429/* Handsfree Left */
430static const char *twl4030_handsfreel_texts[] =
1a787e7a 431 {"Voice", "AudioL1", "AudioL2", "AudioR2"};
df339804
PU
432
433static const struct soc_enum twl4030_handsfreel_enum =
434 SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
435 ARRAY_SIZE(twl4030_handsfreel_texts),
436 twl4030_handsfreel_texts);
437
438static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
439SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
440
0f89bdca
PU
441/* Handsfree Left virtual mute */
442static const struct snd_kcontrol_new twl4030_dapm_handsfreelmute_control =
443 SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 0, 1, 0);
444
df339804
PU
445/* Handsfree Right */
446static const char *twl4030_handsfreer_texts[] =
1a787e7a 447 {"Voice", "AudioR1", "AudioR2", "AudioL2"};
df339804
PU
448
449static const struct soc_enum twl4030_handsfreer_enum =
450 SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
451 ARRAY_SIZE(twl4030_handsfreer_texts),
452 twl4030_handsfreer_texts);
453
454static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
455SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
456
0f89bdca
PU
457/* Handsfree Right virtual mute */
458static const struct snd_kcontrol_new twl4030_dapm_handsfreermute_control =
459 SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 1, 1, 0);
460
376f7839
PU
461/* Vibra */
462/* Vibra audio path selection */
463static const char *twl4030_vibra_texts[] =
464 {"AudioL1", "AudioR1", "AudioL2", "AudioR2"};
465
466static const struct soc_enum twl4030_vibra_enum =
467 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2,
468 ARRAY_SIZE(twl4030_vibra_texts),
469 twl4030_vibra_texts);
470
471static const struct snd_kcontrol_new twl4030_dapm_vibra_control =
472SOC_DAPM_ENUM("Route", twl4030_vibra_enum);
473
474/* Vibra path selection: local vibrator (PWM) or audio driven */
475static const char *twl4030_vibrapath_texts[] =
476 {"Local vibrator", "Audio"};
477
478static const struct soc_enum twl4030_vibrapath_enum =
479 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4,
480 ARRAY_SIZE(twl4030_vibrapath_texts),
481 twl4030_vibrapath_texts);
482
483static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control =
484SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
485
276c6222 486/* Left analog microphone selection */
97b8096d 487static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = {
9028935d
PU
488 SOC_DAPM_SINGLE("Main Mic Capture Switch",
489 TWL4030_REG_ANAMICL, 0, 1, 0),
490 SOC_DAPM_SINGLE("Headset Mic Capture Switch",
491 TWL4030_REG_ANAMICL, 1, 1, 0),
492 SOC_DAPM_SINGLE("AUXL Capture Switch",
493 TWL4030_REG_ANAMICL, 2, 1, 0),
494 SOC_DAPM_SINGLE("Carkit Mic Capture Switch",
495 TWL4030_REG_ANAMICL, 3, 1, 0),
97b8096d 496};
276c6222
PU
497
498/* Right analog microphone selection */
97b8096d 499static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = {
9028935d
PU
500 SOC_DAPM_SINGLE("Sub Mic Capture Switch", TWL4030_REG_ANAMICR, 0, 1, 0),
501 SOC_DAPM_SINGLE("AUXR Capture Switch", TWL4030_REG_ANAMICR, 2, 1, 0),
97b8096d 502};
276c6222
PU
503
504/* TX1 L/R Analog/Digital microphone selection */
505static const char *twl4030_micpathtx1_texts[] =
506 {"Analog", "Digimic0"};
507
508static const struct soc_enum twl4030_micpathtx1_enum =
509 SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 0,
510 ARRAY_SIZE(twl4030_micpathtx1_texts),
511 twl4030_micpathtx1_texts);
512
513static const struct snd_kcontrol_new twl4030_dapm_micpathtx1_control =
514SOC_DAPM_ENUM("Route", twl4030_micpathtx1_enum);
515
516/* TX2 L/R Analog/Digital microphone selection */
517static const char *twl4030_micpathtx2_texts[] =
518 {"Analog", "Digimic1"};
519
520static const struct soc_enum twl4030_micpathtx2_enum =
521 SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 2,
522 ARRAY_SIZE(twl4030_micpathtx2_texts),
523 twl4030_micpathtx2_texts);
524
525static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control =
526SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum);
527
7393958f
PU
528/* Analog bypass for AudioR1 */
529static const struct snd_kcontrol_new twl4030_dapm_abypassr1_control =
530 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR1_APGA_CTL, 2, 1, 0);
531
532/* Analog bypass for AudioL1 */
533static const struct snd_kcontrol_new twl4030_dapm_abypassl1_control =
534 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL1_APGA_CTL, 2, 1, 0);
535
536/* Analog bypass for AudioR2 */
537static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control =
538 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR2_APGA_CTL, 2, 1, 0);
539
540/* Analog bypass for AudioL2 */
541static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
542 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
543
fcd274a3
LCM
544/* Analog bypass for Voice */
545static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
546 SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
547
8b0d3153 548/* Digital bypass gain, mute instead of -30dB */
6bab83fd 549static const unsigned int twl4030_dapm_dbypass_tlv[] = {
8b0d3153
PU
550 TLV_DB_RANGE_HEAD(3),
551 0, 1, TLV_DB_SCALE_ITEM(-3000, 600, 1),
552 2, 3, TLV_DB_SCALE_ITEM(-2400, 0, 0),
6bab83fd
PU
553 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0),
554};
555
556/* Digital bypass left (TX1L -> RX2L) */
557static const struct snd_kcontrol_new twl4030_dapm_dbypassl_control =
558 SOC_DAPM_SINGLE_TLV("Volume",
559 TWL4030_REG_ATX2ARXPGA, 3, 7, 0,
560 twl4030_dapm_dbypass_tlv);
561
562/* Digital bypass right (TX1R -> RX2R) */
563static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control =
564 SOC_DAPM_SINGLE_TLV("Volume",
565 TWL4030_REG_ATX2ARXPGA, 0, 7, 0,
566 twl4030_dapm_dbypass_tlv);
567
ee8f6894
LCM
568/*
569 * Voice Sidetone GAIN volume control:
570 * from -51 to -10 dB in 1 dB steps (mute instead of -51 dB)
571 */
572static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1);
573
574/* Digital bypass voice: sidetone (VUL -> VDL)*/
575static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
576 SOC_DAPM_SINGLE_TLV("Volume",
577 TWL4030_REG_VSTPGA, 0, 0x29, 0,
578 twl4030_dapm_dbypassv_tlv);
579
276c6222
PU
580static int micpath_event(struct snd_soc_dapm_widget *w,
581 struct snd_kcontrol *kcontrol, int event)
582{
583 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
584 unsigned char adcmicsel, micbias_ctl;
585
586 adcmicsel = twl4030_read_reg_cache(w->codec, TWL4030_REG_ADCMICSEL);
587 micbias_ctl = twl4030_read_reg_cache(w->codec, TWL4030_REG_MICBIAS_CTL);
588 /* Prepare the bits for the given TX path:
589 * shift_l == 0: TX1 microphone path
590 * shift_l == 2: TX2 microphone path */
591 if (e->shift_l) {
592 /* TX2 microphone path */
593 if (adcmicsel & TWL4030_TX2IN_SEL)
594 micbias_ctl |= TWL4030_MICBIAS2_CTL; /* digimic */
595 else
596 micbias_ctl &= ~TWL4030_MICBIAS2_CTL;
597 } else {
598 /* TX1 microphone path */
599 if (adcmicsel & TWL4030_TX1IN_SEL)
600 micbias_ctl |= TWL4030_MICBIAS1_CTL; /* digimic */
601 else
602 micbias_ctl &= ~TWL4030_MICBIAS1_CTL;
603 }
604
605 twl4030_write(w->codec, TWL4030_REG_MICBIAS_CTL, micbias_ctl);
606
607 return 0;
608}
609
9008adf9
PU
610/*
611 * Output PGA builder:
612 * Handle the muting and unmuting of the given output (turning off the
613 * amplifier associated with the output pin)
c96907f2
PU
614 * On mute bypass the reg_cache and write 0 to the register
615 * On unmute: restore the register content from the reg_cache
9008adf9
PU
616 * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R
617 */
618#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
619static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
620 struct snd_kcontrol *kcontrol, int event) \
621{ \
b2c812e2 622 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \
9008adf9
PU
623 \
624 switch (event) { \
625 case SND_SOC_DAPM_POST_PMU: \
c96907f2 626 twl4030->pin_name##_enabled = 1; \
9008adf9
PU
627 twl4030_write(w->codec, reg, \
628 twl4030_read_reg_cache(w->codec, reg)); \
629 break; \
630 case SND_SOC_DAPM_POST_PMD: \
c96907f2
PU
631 twl4030->pin_name##_enabled = 0; \
632 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
633 0, reg); \
9008adf9
PU
634 break; \
635 } \
636 return 0; \
637}
638
639TWL4030_OUTPUT_PGA(earpiece, TWL4030_REG_EAR_CTL, TWL4030_EAR_GAIN);
640TWL4030_OUTPUT_PGA(predrivel, TWL4030_REG_PREDL_CTL, TWL4030_PREDL_GAIN);
641TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
642TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
643TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
644
5a2e9a48 645static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
49d92c7d 646{
49d92c7d
SM
647 unsigned char hs_ctl;
648
5a2e9a48 649 hs_ctl = twl4030_read_reg_cache(codec, reg);
49d92c7d 650
5a2e9a48
PU
651 if (ramp) {
652 /* HF ramp-up */
653 hs_ctl |= TWL4030_HF_CTL_REF_EN;
654 twl4030_write(codec, reg, hs_ctl);
655 udelay(10);
49d92c7d 656 hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
5a2e9a48
PU
657 twl4030_write(codec, reg, hs_ctl);
658 udelay(40);
49d92c7d 659 hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
49d92c7d 660 hs_ctl |= TWL4030_HF_CTL_HB_EN;
5a2e9a48 661 twl4030_write(codec, reg, hs_ctl);
49d92c7d 662 } else {
5a2e9a48
PU
663 /* HF ramp-down */
664 hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
665 hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
666 twl4030_write(codec, reg, hs_ctl);
667 hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
668 twl4030_write(codec, reg, hs_ctl);
669 udelay(40);
670 hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
671 twl4030_write(codec, reg, hs_ctl);
49d92c7d 672 }
5a2e9a48 673}
49d92c7d 674
5a2e9a48
PU
675static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
676 struct snd_kcontrol *kcontrol, int event)
677{
678 switch (event) {
679 case SND_SOC_DAPM_POST_PMU:
680 handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1);
681 break;
682 case SND_SOC_DAPM_POST_PMD:
683 handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0);
684 break;
685 }
686 return 0;
687}
688
689static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
690 struct snd_kcontrol *kcontrol, int event)
691{
692 switch (event) {
693 case SND_SOC_DAPM_POST_PMU:
694 handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1);
695 break;
696 case SND_SOC_DAPM_POST_PMD:
697 handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0);
698 break;
699 }
49d92c7d
SM
700 return 0;
701}
702
86139a13
JV
703static int vibramux_event(struct snd_soc_dapm_widget *w,
704 struct snd_kcontrol *kcontrol, int event)
705{
706 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
707 return 0;
708}
709
7729cf74
PU
710static int apll_event(struct snd_soc_dapm_widget *w,
711 struct snd_kcontrol *kcontrol, int event)
712{
713 switch (event) {
714 case SND_SOC_DAPM_PRE_PMU:
715 twl4030_apll_enable(w->codec, 1);
716 break;
717 case SND_SOC_DAPM_POST_PMD:
718 twl4030_apll_enable(w->codec, 0);
719 break;
720 }
721 return 0;
722}
723
7b4c734e
PU
724static int aif_event(struct snd_soc_dapm_widget *w,
725 struct snd_kcontrol *kcontrol, int event)
726{
727 u8 audio_if;
728
729 audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF);
730 switch (event) {
731 case SND_SOC_DAPM_PRE_PMU:
732 /* Enable AIF */
733 /* enable the PLL before we use it to clock the DAI */
734 twl4030_apll_enable(w->codec, 1);
735
736 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
737 audio_if | TWL4030_AIF_EN);
738 break;
739 case SND_SOC_DAPM_POST_PMD:
740 /* disable the DAI before we stop it's source PLL */
741 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
742 audio_if & ~TWL4030_AIF_EN);
743 twl4030_apll_enable(w->codec, 0);
744 break;
745 }
746 return 0;
747}
748
6943c92e 749static void headset_ramp(struct snd_soc_codec *codec, int ramp)
aad749e5 750{
4e49ffd1
CVJ
751 struct snd_soc_device *socdev = codec->socdev;
752 struct twl4030_setup_data *setup = socdev->codec_data;
753
aad749e5 754 unsigned char hs_gain, hs_pop;
b2c812e2 755 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
6943c92e
PU
756 /* Base values for ramp delay calculation: 2^19 - 2^26 */
757 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
758 8388608, 16777216, 33554432, 67108864};
aad749e5 759
6943c92e
PU
760 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
761 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
aad749e5 762
4e49ffd1
CVJ
763 /* Enable external mute control, this dramatically reduces
764 * the pop-noise */
765 if (setup && setup->hs_extmute) {
766 if (setup->set_hs_extmute) {
767 setup->set_hs_extmute(1);
768 } else {
769 hs_pop |= TWL4030_EXTMUTE;
770 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
771 }
772 }
773
6943c92e
PU
774 if (ramp) {
775 /* Headset ramp-up according to the TRM */
aad749e5 776 hs_pop |= TWL4030_VMID_EN;
6943c92e 777 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
c96907f2
PU
778 /* Actually write to the register */
779 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
780 hs_gain,
781 TWL4030_REG_HS_GAIN_SET);
aad749e5 782 hs_pop |= TWL4030_RAMP_EN;
6943c92e 783 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
4e49ffd1
CVJ
784 /* Wait ramp delay time + 1, so the VMID can settle */
785 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
786 twl4030->sysclk) + 1);
6943c92e
PU
787 } else {
788 /* Headset ramp-down _not_ according to
789 * the TRM, but in a way that it is working */
aad749e5 790 hs_pop &= ~TWL4030_RAMP_EN;
6943c92e
PU
791 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
792 /* Wait ramp delay time + 1, so the VMID can settle */
793 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
794 twl4030->sysclk) + 1);
aad749e5 795 /* Bypass the reg_cache to mute the headset */
fc7b92fc 796 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
aad749e5
PU
797 hs_gain & (~0x0f),
798 TWL4030_REG_HS_GAIN_SET);
6943c92e 799
aad749e5 800 hs_pop &= ~TWL4030_VMID_EN;
6943c92e
PU
801 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
802 }
4e49ffd1
CVJ
803
804 /* Disable external mute */
805 if (setup && setup->hs_extmute) {
806 if (setup->set_hs_extmute) {
807 setup->set_hs_extmute(0);
808 } else {
809 hs_pop &= ~TWL4030_EXTMUTE;
810 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
811 }
812 }
6943c92e
PU
813}
814
815static int headsetlpga_event(struct snd_soc_dapm_widget *w,
816 struct snd_kcontrol *kcontrol, int event)
817{
b2c812e2 818 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
6943c92e
PU
819
820 switch (event) {
821 case SND_SOC_DAPM_POST_PMU:
822 /* Do the ramp-up only once */
823 if (!twl4030->hsr_enabled)
824 headset_ramp(w->codec, 1);
825
826 twl4030->hsl_enabled = 1;
827 break;
828 case SND_SOC_DAPM_POST_PMD:
829 /* Do the ramp-down only if both headsetL/R is disabled */
830 if (!twl4030->hsr_enabled)
831 headset_ramp(w->codec, 0);
832
833 twl4030->hsl_enabled = 0;
834 break;
835 }
836 return 0;
837}
838
839static int headsetrpga_event(struct snd_soc_dapm_widget *w,
840 struct snd_kcontrol *kcontrol, int event)
841{
b2c812e2 842 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
6943c92e
PU
843
844 switch (event) {
845 case SND_SOC_DAPM_POST_PMU:
846 /* Do the ramp-up only once */
847 if (!twl4030->hsl_enabled)
848 headset_ramp(w->codec, 1);
849
850 twl4030->hsr_enabled = 1;
851 break;
852 case SND_SOC_DAPM_POST_PMD:
853 /* Do the ramp-down only if both headsetL/R is disabled */
854 if (!twl4030->hsl_enabled)
855 headset_ramp(w->codec, 0);
856
857 twl4030->hsr_enabled = 0;
aad749e5
PU
858 break;
859 }
860 return 0;
861}
862
01ea6ba2
PU
863static int digimic_event(struct snd_soc_dapm_widget *w,
864 struct snd_kcontrol *kcontrol, int event)
865{
866 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
867
868 if (twl4030->digimic_delay)
869 mdelay(twl4030->digimic_delay);
870 return 0;
871}
872
b0bd53a7
PU
873/*
874 * Some of the gain controls in TWL (mostly those which are associated with
875 * the outputs) are implemented in an interesting way:
876 * 0x0 : Power down (mute)
877 * 0x1 : 6dB
878 * 0x2 : 0 dB
879 * 0x3 : -6 dB
880 * Inverting not going to help with these.
881 * Custom volsw and volsw_2r get/put functions to handle these gain bits.
882 */
883#define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
884 xinvert, tlv_array) \
885{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
886 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
887 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
888 .tlv.p = (tlv_array), \
889 .info = snd_soc_info_volsw, \
890 .get = snd_soc_get_volsw_twl4030, \
891 .put = snd_soc_put_volsw_twl4030, \
892 .private_value = (unsigned long)&(struct soc_mixer_control) \
893 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
894 .max = xmax, .invert = xinvert} }
895#define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
896 xinvert, tlv_array) \
897{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
898 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
899 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
900 .tlv.p = (tlv_array), \
901 .info = snd_soc_info_volsw_2r, \
902 .get = snd_soc_get_volsw_r2_twl4030,\
903 .put = snd_soc_put_volsw_r2_twl4030, \
904 .private_value = (unsigned long)&(struct soc_mixer_control) \
905 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
64089b84 906 .rshift = xshift, .max = xmax, .invert = xinvert} }
b0bd53a7
PU
907#define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
908 SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
909 xinvert, tlv_array)
910
911static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
912 struct snd_ctl_elem_value *ucontrol)
913{
914 struct soc_mixer_control *mc =
915 (struct soc_mixer_control *)kcontrol->private_value;
916 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
917 unsigned int reg = mc->reg;
918 unsigned int shift = mc->shift;
919 unsigned int rshift = mc->rshift;
920 int max = mc->max;
921 int mask = (1 << fls(max)) - 1;
922
923 ucontrol->value.integer.value[0] =
924 (snd_soc_read(codec, reg) >> shift) & mask;
925 if (ucontrol->value.integer.value[0])
926 ucontrol->value.integer.value[0] =
927 max + 1 - ucontrol->value.integer.value[0];
928
929 if (shift != rshift) {
930 ucontrol->value.integer.value[1] =
931 (snd_soc_read(codec, reg) >> rshift) & mask;
932 if (ucontrol->value.integer.value[1])
933 ucontrol->value.integer.value[1] =
934 max + 1 - ucontrol->value.integer.value[1];
935 }
936
937 return 0;
938}
939
940static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
941 struct snd_ctl_elem_value *ucontrol)
942{
943 struct soc_mixer_control *mc =
944 (struct soc_mixer_control *)kcontrol->private_value;
945 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
946 unsigned int reg = mc->reg;
947 unsigned int shift = mc->shift;
948 unsigned int rshift = mc->rshift;
949 int max = mc->max;
950 int mask = (1 << fls(max)) - 1;
951 unsigned short val, val2, val_mask;
952
953 val = (ucontrol->value.integer.value[0] & mask);
954
955 val_mask = mask << shift;
956 if (val)
957 val = max + 1 - val;
958 val = val << shift;
959 if (shift != rshift) {
960 val2 = (ucontrol->value.integer.value[1] & mask);
961 val_mask |= mask << rshift;
962 if (val2)
963 val2 = max + 1 - val2;
964 val |= val2 << rshift;
965 }
966 return snd_soc_update_bits(codec, reg, val_mask, val);
967}
968
969static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
970 struct snd_ctl_elem_value *ucontrol)
971{
972 struct soc_mixer_control *mc =
973 (struct soc_mixer_control *)kcontrol->private_value;
974 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
975 unsigned int reg = mc->reg;
976 unsigned int reg2 = mc->rreg;
977 unsigned int shift = mc->shift;
978 int max = mc->max;
979 int mask = (1<<fls(max))-1;
980
981 ucontrol->value.integer.value[0] =
982 (snd_soc_read(codec, reg) >> shift) & mask;
983 ucontrol->value.integer.value[1] =
984 (snd_soc_read(codec, reg2) >> shift) & mask;
985
986 if (ucontrol->value.integer.value[0])
987 ucontrol->value.integer.value[0] =
988 max + 1 - ucontrol->value.integer.value[0];
989 if (ucontrol->value.integer.value[1])
990 ucontrol->value.integer.value[1] =
991 max + 1 - ucontrol->value.integer.value[1];
992
993 return 0;
994}
995
996static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
997 struct snd_ctl_elem_value *ucontrol)
998{
999 struct soc_mixer_control *mc =
1000 (struct soc_mixer_control *)kcontrol->private_value;
1001 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1002 unsigned int reg = mc->reg;
1003 unsigned int reg2 = mc->rreg;
1004 unsigned int shift = mc->shift;
1005 int max = mc->max;
1006 int mask = (1 << fls(max)) - 1;
1007 int err;
1008 unsigned short val, val2, val_mask;
1009
1010 val_mask = mask << shift;
1011 val = (ucontrol->value.integer.value[0] & mask);
1012 val2 = (ucontrol->value.integer.value[1] & mask);
1013
1014 if (val)
1015 val = max + 1 - val;
1016 if (val2)
1017 val2 = max + 1 - val2;
1018
1019 val = val << shift;
1020 val2 = val2 << shift;
1021
1022 err = snd_soc_update_bits(codec, reg, val_mask, val);
1023 if (err < 0)
1024 return err;
1025
1026 err = snd_soc_update_bits(codec, reg2, val_mask, val2);
1027 return err;
1028}
1029
b74bd40f
LCM
1030/* Codec operation modes */
1031static const char *twl4030_op_modes_texts[] = {
1032 "Option 2 (voice/audio)", "Option 1 (audio)"
1033};
1034
1035static const struct soc_enum twl4030_op_modes_enum =
1036 SOC_ENUM_SINGLE(TWL4030_REG_CODEC_MODE, 0,
1037 ARRAY_SIZE(twl4030_op_modes_texts),
1038 twl4030_op_modes_texts);
1039
423c238d 1040static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
b74bd40f
LCM
1041 struct snd_ctl_elem_value *ucontrol)
1042{
1043 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
b2c812e2 1044 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
b74bd40f
LCM
1045 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1046 unsigned short val;
1047 unsigned short mask, bitmask;
1048
1049 if (twl4030->configured) {
1050 printk(KERN_ERR "twl4030 operation mode cannot be "
1051 "changed on-the-fly\n");
1052 return -EBUSY;
1053 }
1054
1055 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1056 ;
1057 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1058 return -EINVAL;
1059
1060 val = ucontrol->value.enumerated.item[0] << e->shift_l;
1061 mask = (bitmask - 1) << e->shift_l;
1062 if (e->shift_l != e->shift_r) {
1063 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1064 return -EINVAL;
1065 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1066 mask |= (bitmask - 1) << e->shift_r;
1067 }
1068
1069 return snd_soc_update_bits(codec, e->reg, mask, val);
1070}
1071
c10b82cf
PU
1072/*
1073 * FGAIN volume control:
1074 * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
1075 */
d889a72c 1076static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
c10b82cf 1077
0d33ea0b
PU
1078/*
1079 * CGAIN volume control:
1080 * 0 dB to 12 dB in 6 dB steps
1081 * value 2 and 3 means 12 dB
1082 */
d889a72c
PU
1083static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
1084
1a787e7a
JS
1085/*
1086 * Voice Downlink GAIN volume control:
1087 * from -37 to 12 dB in 1 dB steps (mute instead of -37 dB)
1088 */
1089static DECLARE_TLV_DB_SCALE(digital_voice_downlink_tlv, -3700, 100, 1);
1090
d889a72c
PU
1091/*
1092 * Analog playback gain
1093 * -24 dB to 12 dB in 2 dB steps
1094 */
1095static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
0d33ea0b 1096
4290239c
PU
1097/*
1098 * Gain controls tied to outputs
1099 * -6 dB to 6 dB in 6 dB steps (mute instead of -12)
1100 */
1101static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
1102
18cc8d8d
JS
1103/*
1104 * Gain control for earpiece amplifier
1105 * 0 dB to 12 dB in 6 dB steps (mute instead of -6)
1106 */
1107static DECLARE_TLV_DB_SCALE(output_ear_tvl, -600, 600, 1);
1108
381a22b5
PU
1109/*
1110 * Capture gain after the ADCs
1111 * from 0 dB to 31 dB in 1 dB steps
1112 */
1113static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
1114
5920b453
GI
1115/*
1116 * Gain control for input amplifiers
1117 * 0 dB to 30 dB in 6 dB steps
1118 */
1119static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
1120
328d0a13
LCM
1121/* AVADC clock priority */
1122static const char *twl4030_avadc_clk_priority_texts[] = {
1123 "Voice high priority", "HiFi high priority"
1124};
1125
1126static const struct soc_enum twl4030_avadc_clk_priority_enum =
1127 SOC_ENUM_SINGLE(TWL4030_REG_AVADC_CTL, 2,
1128 ARRAY_SIZE(twl4030_avadc_clk_priority_texts),
1129 twl4030_avadc_clk_priority_texts);
1130
89492be8
PU
1131static const char *twl4030_rampdelay_texts[] = {
1132 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms",
1133 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms",
1134 "3495/2581/1748 ms"
1135};
1136
1137static const struct soc_enum twl4030_rampdelay_enum =
1138 SOC_ENUM_SINGLE(TWL4030_REG_HS_POPN_SET, 2,
1139 ARRAY_SIZE(twl4030_rampdelay_texts),
1140 twl4030_rampdelay_texts);
1141
376f7839
PU
1142/* Vibra H-bridge direction mode */
1143static const char *twl4030_vibradirmode_texts[] = {
1144 "Vibra H-bridge direction", "Audio data MSB",
1145};
1146
1147static const struct soc_enum twl4030_vibradirmode_enum =
1148 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5,
1149 ARRAY_SIZE(twl4030_vibradirmode_texts),
1150 twl4030_vibradirmode_texts);
1151
1152/* Vibra H-bridge direction */
1153static const char *twl4030_vibradir_texts[] = {
1154 "Positive polarity", "Negative polarity",
1155};
1156
1157static const struct soc_enum twl4030_vibradir_enum =
1158 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1,
1159 ARRAY_SIZE(twl4030_vibradir_texts),
1160 twl4030_vibradir_texts);
1161
36aeff61
PU
1162/* Digimic Left and right swapping */
1163static const char *twl4030_digimicswap_texts[] = {
1164 "Not swapped", "Swapped",
1165};
1166
1167static const struct soc_enum twl4030_digimicswap_enum =
1168 SOC_ENUM_SINGLE(TWL4030_REG_MISC_SET_1, 0,
1169 ARRAY_SIZE(twl4030_digimicswap_texts),
1170 twl4030_digimicswap_texts);
1171
cc17557e 1172static const struct snd_kcontrol_new twl4030_snd_controls[] = {
b74bd40f
LCM
1173 /* Codec operation mode control */
1174 SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum,
1175 snd_soc_get_enum_double,
1176 snd_soc_put_twl4030_opmode_enum_double),
1177
d889a72c
PU
1178 /* Common playback gain controls */
1179 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
1180 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
1181 0, 0x3f, 0, digital_fine_tlv),
1182 SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume",
1183 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
1184 0, 0x3f, 0, digital_fine_tlv),
1185
1186 SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume",
1187 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
1188 6, 0x2, 0, digital_coarse_tlv),
1189 SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume",
1190 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
1191 6, 0x2, 0, digital_coarse_tlv),
1192
1193 SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume",
1194 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
1195 3, 0x12, 1, analog_tlv),
1196 SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume",
1197 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
1198 3, 0x12, 1, analog_tlv),
44c55870
PU
1199 SOC_DOUBLE_R("DAC1 Analog Playback Switch",
1200 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
1201 1, 1, 0),
1202 SOC_DOUBLE_R("DAC2 Analog Playback Switch",
1203 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
1204 1, 1, 0),
381a22b5 1205
1a787e7a
JS
1206 /* Common voice downlink gain controls */
1207 SOC_SINGLE_TLV("DAC Voice Digital Downlink Volume",
1208 TWL4030_REG_VRXPGA, 0, 0x31, 0, digital_voice_downlink_tlv),
1209
1210 SOC_SINGLE_TLV("DAC Voice Analog Downlink Volume",
1211 TWL4030_REG_VDL_APGA_CTL, 3, 0x12, 1, analog_tlv),
1212
1213 SOC_SINGLE("DAC Voice Analog Downlink Switch",
1214 TWL4030_REG_VDL_APGA_CTL, 1, 1, 0),
1215
4290239c
PU
1216 /* Separate output gain controls */
1217 SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
1218 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
1219 4, 3, 0, output_tvl),
1220
1221 SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume",
1222 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl),
1223
1224 SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume",
1225 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
1226 4, 3, 0, output_tvl),
1227
1228 SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume",
18cc8d8d 1229 TWL4030_REG_EAR_CTL, 4, 3, 0, output_ear_tvl),
4290239c 1230
381a22b5 1231 /* Common capture gain controls */
276c6222 1232 SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume",
381a22b5
PU
1233 TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
1234 0, 0x1f, 0, digital_capture_tlv),
276c6222
PU
1235 SOC_DOUBLE_R_TLV("TX2 Digital Capture Volume",
1236 TWL4030_REG_AVTXL2PGA, TWL4030_REG_AVTXR2PGA,
1237 0, 0x1f, 0, digital_capture_tlv),
5920b453 1238
276c6222 1239 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
5920b453 1240 0, 3, 5, 0, input_gain_tlv),
89492be8 1241
328d0a13
LCM
1242 SOC_ENUM("AVADC Clock Priority", twl4030_avadc_clk_priority_enum),
1243
89492be8 1244 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
376f7839
PU
1245
1246 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
1247 SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum),
36aeff61
PU
1248
1249 SOC_ENUM("Digimic LR Swap", twl4030_digimicswap_enum),
cc17557e
SS
1250};
1251
cc17557e 1252static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
276c6222
PU
1253 /* Left channel inputs */
1254 SND_SOC_DAPM_INPUT("MAINMIC"),
1255 SND_SOC_DAPM_INPUT("HSMIC"),
1256 SND_SOC_DAPM_INPUT("AUXL"),
1257 SND_SOC_DAPM_INPUT("CARKITMIC"),
1258 /* Right channel inputs */
1259 SND_SOC_DAPM_INPUT("SUBMIC"),
1260 SND_SOC_DAPM_INPUT("AUXR"),
1261 /* Digital microphones (Stereo) */
1262 SND_SOC_DAPM_INPUT("DIGIMIC0"),
1263 SND_SOC_DAPM_INPUT("DIGIMIC1"),
1264
1265 /* Outputs */
5e98a464 1266 SND_SOC_DAPM_OUTPUT("EARPIECE"),
2a6f5c58
PU
1267 SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
1268 SND_SOC_DAPM_OUTPUT("PREDRIVER"),
dfad21a2
PU
1269 SND_SOC_DAPM_OUTPUT("HSOL"),
1270 SND_SOC_DAPM_OUTPUT("HSOR"),
6a1bee4a
PU
1271 SND_SOC_DAPM_OUTPUT("CARKITL"),
1272 SND_SOC_DAPM_OUTPUT("CARKITR"),
df339804
PU
1273 SND_SOC_DAPM_OUTPUT("HFL"),
1274 SND_SOC_DAPM_OUTPUT("HFR"),
376f7839 1275 SND_SOC_DAPM_OUTPUT("VIBRA"),
cc17557e 1276
7b4c734e
PU
1277 /* AIF and APLL clocks for running DAIs (including loopback) */
1278 SND_SOC_DAPM_OUTPUT("Virtual HiFi OUT"),
1279 SND_SOC_DAPM_INPUT("Virtual HiFi IN"),
1280 SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
1281
53b5047d 1282 /* DACs */
b4852b79 1283 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
7393958f 1284 SND_SOC_NOPM, 0, 0),
b4852b79 1285 SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback",
7393958f 1286 SND_SOC_NOPM, 0, 0),
b4852b79 1287 SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback",
7393958f 1288 SND_SOC_NOPM, 0, 0),
b4852b79 1289 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback",
7393958f 1290 SND_SOC_NOPM, 0, 0),
1a787e7a 1291 SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
fcd274a3 1292 SND_SOC_NOPM, 0, 0),
cc17557e 1293
7393958f 1294 /* Analog bypasses */
78e08e2f
PU
1295 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1296 &twl4030_dapm_abypassr1_control),
1297 SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1298 &twl4030_dapm_abypassl1_control),
1299 SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1300 &twl4030_dapm_abypassr2_control),
1301 SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1302 &twl4030_dapm_abypassl2_control),
1303 SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1304 &twl4030_dapm_abypassv_control),
1305
1306 /* Master analog loopback switch */
1307 SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
1308 NULL, 0),
7393958f 1309
6bab83fd 1310 /* Digital bypasses */
78e08e2f
PU
1311 SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
1312 &twl4030_dapm_dbypassl_control),
1313 SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
1314 &twl4030_dapm_dbypassr_control),
1315 SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1316 &twl4030_dapm_dbypassv_control),
6bab83fd 1317
4005d39a
PU
1318 /* Digital mixers, power control for the physical DACs */
1319 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
1320 TWL4030_REG_AVDAC_CTL, 0, 0, NULL, 0),
1321 SND_SOC_DAPM_MIXER("Digital L1 Playback Mixer",
1322 TWL4030_REG_AVDAC_CTL, 1, 0, NULL, 0),
1323 SND_SOC_DAPM_MIXER("Digital R2 Playback Mixer",
1324 TWL4030_REG_AVDAC_CTL, 2, 0, NULL, 0),
1325 SND_SOC_DAPM_MIXER("Digital L2 Playback Mixer",
1326 TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0),
1327 SND_SOC_DAPM_MIXER("Digital Voice Playback Mixer",
1328 TWL4030_REG_AVDAC_CTL, 4, 0, NULL, 0),
1329
1330 /* Analog mixers, power control for the physical PGAs */
1331 SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer",
1332 TWL4030_REG_ARXR1_APGA_CTL, 0, 0, NULL, 0),
1333 SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer",
1334 TWL4030_REG_ARXL1_APGA_CTL, 0, 0, NULL, 0),
1335 SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer",
1336 TWL4030_REG_ARXR2_APGA_CTL, 0, 0, NULL, 0),
1337 SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer",
1338 TWL4030_REG_ARXL2_APGA_CTL, 0, 0, NULL, 0),
1339 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
1340 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
7393958f 1341
7729cf74
PU
1342 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1343 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1344
7b4c734e
PU
1345 SND_SOC_DAPM_SUPPLY("AIF Enable", SND_SOC_NOPM, 0, 0, aif_event,
1346 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
c42a59ea 1347
1a787e7a 1348 /* Output MIXER controls */
5e98a464 1349 /* Earpiece */
1a787e7a
JS
1350 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
1351 &twl4030_dapm_earpiece_controls[0],
1352 ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
9008adf9
PU
1353 SND_SOC_DAPM_PGA_E("Earpiece PGA", SND_SOC_NOPM,
1354 0, 0, NULL, 0, earpiecepga_event,
1355 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
2a6f5c58 1356 /* PreDrivL/R */
1a787e7a
JS
1357 SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
1358 &twl4030_dapm_predrivel_controls[0],
1359 ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
9008adf9
PU
1360 SND_SOC_DAPM_PGA_E("PredriveL PGA", SND_SOC_NOPM,
1361 0, 0, NULL, 0, predrivelpga_event,
1362 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1a787e7a
JS
1363 SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
1364 &twl4030_dapm_predriver_controls[0],
1365 ARRAY_SIZE(twl4030_dapm_predriver_controls)),
9008adf9
PU
1366 SND_SOC_DAPM_PGA_E("PredriveR PGA", SND_SOC_NOPM,
1367 0, 0, NULL, 0, predriverpga_event,
1368 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
dfad21a2 1369 /* HeadsetL/R */
6943c92e 1370 SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
1a787e7a 1371 &twl4030_dapm_hsol_controls[0],
6943c92e
PU
1372 ARRAY_SIZE(twl4030_dapm_hsol_controls)),
1373 SND_SOC_DAPM_PGA_E("HeadsetL PGA", SND_SOC_NOPM,
1374 0, 0, NULL, 0, headsetlpga_event,
1a787e7a
JS
1375 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1376 SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0,
1377 &twl4030_dapm_hsor_controls[0],
1378 ARRAY_SIZE(twl4030_dapm_hsor_controls)),
6943c92e
PU
1379 SND_SOC_DAPM_PGA_E("HeadsetR PGA", SND_SOC_NOPM,
1380 0, 0, NULL, 0, headsetrpga_event,
1381 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
5152d8c2 1382 /* CarkitL/R */
1a787e7a
JS
1383 SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
1384 &twl4030_dapm_carkitl_controls[0],
1385 ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
9008adf9
PU
1386 SND_SOC_DAPM_PGA_E("CarkitL PGA", SND_SOC_NOPM,
1387 0, 0, NULL, 0, carkitlpga_event,
1388 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1a787e7a
JS
1389 SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
1390 &twl4030_dapm_carkitr_controls[0],
1391 ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
9008adf9
PU
1392 SND_SOC_DAPM_PGA_E("CarkitR PGA", SND_SOC_NOPM,
1393 0, 0, NULL, 0, carkitrpga_event,
1394 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1a787e7a
JS
1395
1396 /* Output MUX controls */
df339804 1397 /* HandsfreeL/R */
5a2e9a48
PU
1398 SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
1399 &twl4030_dapm_handsfreel_control),
e3c7dbb0 1400 SND_SOC_DAPM_SWITCH("HandsfreeL", SND_SOC_NOPM, 0, 0,
0f89bdca 1401 &twl4030_dapm_handsfreelmute_control),
5a2e9a48
PU
1402 SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
1403 0, 0, NULL, 0, handsfreelpga_event,
1404 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1405 SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
1406 &twl4030_dapm_handsfreer_control),
e3c7dbb0 1407 SND_SOC_DAPM_SWITCH("HandsfreeR", SND_SOC_NOPM, 0, 0,
0f89bdca 1408 &twl4030_dapm_handsfreermute_control),
5a2e9a48
PU
1409 SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
1410 0, 0, NULL, 0, handsfreerpga_event,
1411 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
376f7839 1412 /* Vibra */
86139a13
JV
1413 SND_SOC_DAPM_MUX_E("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1414 &twl4030_dapm_vibra_control, vibramux_event,
1415 SND_SOC_DAPM_PRE_PMU),
376f7839
PU
1416 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
1417 &twl4030_dapm_vibrapath_control),
5e98a464 1418
276c6222
PU
1419 /* Introducing four virtual ADC, since TWL4030 have four channel for
1420 capture */
1421 SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture",
1422 SND_SOC_NOPM, 0, 0),
1423 SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture",
1424 SND_SOC_NOPM, 0, 0),
1425 SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture",
1426 SND_SOC_NOPM, 0, 0),
1427 SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture",
1428 SND_SOC_NOPM, 0, 0),
1429
1430 /* Analog/Digital mic path selection.
1431 TX1 Left/Right: either analog Left/Right or Digimic0
1432 TX2 Left/Right: either analog Left/Right or Digimic1 */
1433 SND_SOC_DAPM_MUX_E("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
1434 &twl4030_dapm_micpathtx1_control, micpath_event,
276c6222
PU
1435 SND_SOC_DAPM_POST_REG),
1436 SND_SOC_DAPM_MUX_E("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
1437 &twl4030_dapm_micpathtx2_control, micpath_event,
276c6222
PU
1438 SND_SOC_DAPM_POST_REG),
1439
97b8096d 1440 /* Analog input mixers for the capture amplifiers */
9028935d 1441 SND_SOC_DAPM_MIXER("Analog Left",
97b8096d
JS
1442 TWL4030_REG_ANAMICL, 4, 0,
1443 &twl4030_dapm_analoglmic_controls[0],
1444 ARRAY_SIZE(twl4030_dapm_analoglmic_controls)),
9028935d 1445 SND_SOC_DAPM_MIXER("Analog Right",
97b8096d
JS
1446 TWL4030_REG_ANAMICR, 4, 0,
1447 &twl4030_dapm_analogrmic_controls[0],
1448 ARRAY_SIZE(twl4030_dapm_analogrmic_controls)),
276c6222 1449
fb2a2f84
PU
1450 SND_SOC_DAPM_PGA("ADC Physical Left",
1451 TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0),
1452 SND_SOC_DAPM_PGA("ADC Physical Right",
1453 TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0),
276c6222 1454
01ea6ba2
PU
1455 SND_SOC_DAPM_PGA_E("Digimic0 Enable",
1456 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0,
1457 digimic_event, SND_SOC_DAPM_POST_PMU),
1458 SND_SOC_DAPM_PGA_E("Digimic1 Enable",
1459 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0,
1460 digimic_event, SND_SOC_DAPM_POST_PMU),
276c6222
PU
1461
1462 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
1463 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
1464 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0),
7393958f 1465
cc17557e
SS
1466};
1467
1468static const struct snd_soc_dapm_route intercon[] = {
4005d39a
PU
1469 {"Digital L1 Playback Mixer", NULL, "DAC Left1"},
1470 {"Digital R1 Playback Mixer", NULL, "DAC Right1"},
1471 {"Digital L2 Playback Mixer", NULL, "DAC Left2"},
1472 {"Digital R2 Playback Mixer", NULL, "DAC Right2"},
1473 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1474
7729cf74 1475 /* Supply for the digital part (APLL) */
7729cf74
PU
1476 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1477
27eeb1fe
PU
1478 {"DAC Left1", NULL, "AIF Enable"},
1479 {"DAC Right1", NULL, "AIF Enable"},
1480 {"DAC Left2", NULL, "AIF Enable"},
1481 {"DAC Right1", NULL, "AIF Enable"},
1482
c42a59ea
PU
1483 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1484 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1485
4005d39a
PU
1486 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1487 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1488 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
1489 {"Analog R2 Playback Mixer", NULL, "Digital R2 Playback Mixer"},
1490 {"Analog Voice Playback Mixer", NULL, "Digital Voice Playback Mixer"},
1a787e7a 1491
5e98a464
PU
1492 /* Internal playback routings */
1493 /* Earpiece */
4005d39a
PU
1494 {"Earpiece Mixer", "Voice", "Analog Voice Playback Mixer"},
1495 {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1496 {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1497 {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"},
9008adf9 1498 {"Earpiece PGA", NULL, "Earpiece Mixer"},
2a6f5c58 1499 /* PreDrivL */
4005d39a
PU
1500 {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"},
1501 {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1502 {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1503 {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"},
9008adf9 1504 {"PredriveL PGA", NULL, "PredriveL Mixer"},
2a6f5c58 1505 /* PreDrivR */
4005d39a
PU
1506 {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"},
1507 {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1508 {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1509 {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"},
9008adf9 1510 {"PredriveR PGA", NULL, "PredriveR Mixer"},
dfad21a2 1511 /* HeadsetL */
4005d39a
PU
1512 {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"},
1513 {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1514 {"HeadsetL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
6943c92e 1515 {"HeadsetL PGA", NULL, "HeadsetL Mixer"},
dfad21a2 1516 /* HeadsetR */
4005d39a
PU
1517 {"HeadsetR Mixer", "Voice", "Analog Voice Playback Mixer"},
1518 {"HeadsetR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1519 {"HeadsetR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
6943c92e 1520 {"HeadsetR PGA", NULL, "HeadsetR Mixer"},
5152d8c2 1521 /* CarkitL */
4005d39a
PU
1522 {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"},
1523 {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1524 {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
9008adf9 1525 {"CarkitL PGA", NULL, "CarkitL Mixer"},
5152d8c2 1526 /* CarkitR */
4005d39a
PU
1527 {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"},
1528 {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1529 {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
9008adf9 1530 {"CarkitR PGA", NULL, "CarkitR Mixer"},
df339804 1531 /* HandsfreeL */
4005d39a
PU
1532 {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"},
1533 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
1534 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
1535 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
e3c7dbb0
LCM
1536 {"HandsfreeL", "Switch", "HandsfreeL Mux"},
1537 {"HandsfreeL PGA", NULL, "HandsfreeL"},
df339804 1538 /* HandsfreeR */
4005d39a
PU
1539 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
1540 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
1541 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
1542 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
e3c7dbb0
LCM
1543 {"HandsfreeR", "Switch", "HandsfreeR Mux"},
1544 {"HandsfreeR PGA", NULL, "HandsfreeR"},
376f7839
PU
1545 /* Vibra */
1546 {"Vibra Mux", "AudioL1", "DAC Left1"},
1547 {"Vibra Mux", "AudioR1", "DAC Right1"},
1548 {"Vibra Mux", "AudioL2", "DAC Left2"},
1549 {"Vibra Mux", "AudioR2", "DAC Right2"},
5e98a464 1550
cc17557e 1551 /* outputs */
7b4c734e 1552 /* Must be always connected (for AIF and APLL) */
27eeb1fe
PU
1553 {"Virtual HiFi OUT", NULL, "DAC Left1"},
1554 {"Virtual HiFi OUT", NULL, "DAC Right1"},
1555 {"Virtual HiFi OUT", NULL, "DAC Left2"},
1556 {"Virtual HiFi OUT", NULL, "DAC Right2"},
7b4c734e
PU
1557 /* Must be always connected (for APLL) */
1558 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"},
1559 /* Physical outputs */
9008adf9
PU
1560 {"EARPIECE", NULL, "Earpiece PGA"},
1561 {"PREDRIVEL", NULL, "PredriveL PGA"},
1562 {"PREDRIVER", NULL, "PredriveR PGA"},
6943c92e
PU
1563 {"HSOL", NULL, "HeadsetL PGA"},
1564 {"HSOR", NULL, "HeadsetR PGA"},
9008adf9
PU
1565 {"CARKITL", NULL, "CarkitL PGA"},
1566 {"CARKITR", NULL, "CarkitR PGA"},
5a2e9a48
PU
1567 {"HFL", NULL, "HandsfreeL PGA"},
1568 {"HFR", NULL, "HandsfreeR PGA"},
376f7839
PU
1569 {"Vibra Route", "Audio", "Vibra Mux"},
1570 {"VIBRA", NULL, "Vibra Route"},
cc17557e 1571
276c6222 1572 /* Capture path */
7b4c734e
PU
1573 /* Must be always connected (for AIF and APLL) */
1574 {"ADC Virtual Left1", NULL, "Virtual HiFi IN"},
1575 {"ADC Virtual Right1", NULL, "Virtual HiFi IN"},
1576 {"ADC Virtual Left2", NULL, "Virtual HiFi IN"},
1577 {"ADC Virtual Right2", NULL, "Virtual HiFi IN"},
1578 /* Physical inputs */
9028935d
PU
1579 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
1580 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
1581 {"Analog Left", "AUXL Capture Switch", "AUXL"},
1582 {"Analog Left", "Carkit Mic Capture Switch", "CARKITMIC"},
276c6222 1583
9028935d
PU
1584 {"Analog Right", "Sub Mic Capture Switch", "SUBMIC"},
1585 {"Analog Right", "AUXR Capture Switch", "AUXR"},
276c6222 1586
9028935d
PU
1587 {"ADC Physical Left", NULL, "Analog Left"},
1588 {"ADC Physical Right", NULL, "Analog Right"},
276c6222
PU
1589
1590 {"Digimic0 Enable", NULL, "DIGIMIC0"},
1591 {"Digimic1 Enable", NULL, "DIGIMIC1"},
1592
1593 /* TX1 Left capture path */
fb2a2f84 1594 {"TX1 Capture Route", "Analog", "ADC Physical Left"},
276c6222
PU
1595 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
1596 /* TX1 Right capture path */
fb2a2f84 1597 {"TX1 Capture Route", "Analog", "ADC Physical Right"},
276c6222
PU
1598 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
1599 /* TX2 Left capture path */
fb2a2f84 1600 {"TX2 Capture Route", "Analog", "ADC Physical Left"},
276c6222
PU
1601 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
1602 /* TX2 Right capture path */
fb2a2f84 1603 {"TX2 Capture Route", "Analog", "ADC Physical Right"},
276c6222
PU
1604 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
1605
1606 {"ADC Virtual Left1", NULL, "TX1 Capture Route"},
1607 {"ADC Virtual Right1", NULL, "TX1 Capture Route"},
1608 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1609 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1610
c42a59ea
PU
1611 {"ADC Virtual Left1", NULL, "AIF Enable"},
1612 {"ADC Virtual Right1", NULL, "AIF Enable"},
1613 {"ADC Virtual Left2", NULL, "AIF Enable"},
1614 {"ADC Virtual Right2", NULL, "AIF Enable"},
1615
7393958f 1616 /* Analog bypass routes */
9028935d
PU
1617 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1618 {"Left1 Analog Loopback", "Switch", "Analog Left"},
1619 {"Right2 Analog Loopback", "Switch", "Analog Right"},
1620 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1621 {"Voice Analog Loopback", "Switch", "Analog Left"},
7393958f 1622
78e08e2f
PU
1623 /* Supply for the Analog loopbacks */
1624 {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
1625 {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
1626 {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
1627 {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
1628 {"Voice Analog Loopback", NULL, "FM Loop Enable"},
1629
7393958f
PU
1630 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1631 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1632 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
1633 {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
fcd274a3 1634 {"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"},
7393958f 1635
6bab83fd
PU
1636 /* Digital bypass routes */
1637 {"Right Digital Loopback", "Volume", "TX1 Capture Route"},
1638 {"Left Digital Loopback", "Volume", "TX1 Capture Route"},
ee8f6894 1639 {"Voice Digital Loopback", "Volume", "TX2 Capture Route"},
6bab83fd 1640
4005d39a
PU
1641 {"Digital R2 Playback Mixer", NULL, "Right Digital Loopback"},
1642 {"Digital L2 Playback Mixer", NULL, "Left Digital Loopback"},
1643 {"Digital Voice Playback Mixer", NULL, "Voice Digital Loopback"},
6bab83fd 1644
cc17557e
SS
1645};
1646
1647static int twl4030_add_widgets(struct snd_soc_codec *codec)
1648{
1649 snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
1650 ARRAY_SIZE(twl4030_dapm_widgets));
1651
1652 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
1653
cc17557e
SS
1654 return 0;
1655}
1656
cc17557e
SS
1657static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1658 enum snd_soc_bias_level level)
1659{
1660 switch (level) {
1661 case SND_SOC_BIAS_ON:
cc17557e
SS
1662 break;
1663 case SND_SOC_BIAS_PREPARE:
cc17557e
SS
1664 break;
1665 case SND_SOC_BIAS_STANDBY:
78e08e2f 1666 if (codec->bias_level == SND_SOC_BIAS_OFF)
ee4ccac7 1667 twl4030_codec_enable(codec, 1);
cc17557e
SS
1668 break;
1669 case SND_SOC_BIAS_OFF:
cbd2db12 1670 twl4030_codec_enable(codec, 0);
cc17557e
SS
1671 break;
1672 }
1673 codec->bias_level = level;
1674
1675 return 0;
1676}
1677
6b87a91f
PU
1678static void twl4030_constraints(struct twl4030_priv *twl4030,
1679 struct snd_pcm_substream *mst_substream)
1680{
1681 struct snd_pcm_substream *slv_substream;
1682
1683 /* Pick the stream, which need to be constrained */
1684 if (mst_substream == twl4030->master_substream)
1685 slv_substream = twl4030->slave_substream;
1686 else if (mst_substream == twl4030->slave_substream)
1687 slv_substream = twl4030->master_substream;
1688 else /* This should not happen.. */
1689 return;
1690
1691 /* Set the constraints according to the already configured stream */
1692 snd_pcm_hw_constraint_minmax(slv_substream->runtime,
1693 SNDRV_PCM_HW_PARAM_RATE,
1694 twl4030->rate,
1695 twl4030->rate);
1696
1697 snd_pcm_hw_constraint_minmax(slv_substream->runtime,
1698 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1699 twl4030->sample_bits,
1700 twl4030->sample_bits);
1701
1702 snd_pcm_hw_constraint_minmax(slv_substream->runtime,
1703 SNDRV_PCM_HW_PARAM_CHANNELS,
1704 twl4030->channels,
1705 twl4030->channels);
1706}
1707
8a1f936a
PU
1708/* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for
1709 * capture has to be enabled/disabled. */
1710static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
1711 int enable)
1712{
1713 u8 reg, mask;
1714
1715 reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
1716
1717 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1718 mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN;
1719 else
1720 mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
1721
1722 if (enable)
1723 reg |= mask;
1724 else
1725 reg &= ~mask;
1726
1727 twl4030_write(codec, TWL4030_REG_OPTION, reg);
1728}
1729
d6648da1
PU
1730static int twl4030_startup(struct snd_pcm_substream *substream,
1731 struct snd_soc_dai *dai)
7220b9f4
PU
1732{
1733 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1734 struct snd_soc_device *socdev = rtd->socdev;
d6648da1 1735 struct snd_soc_codec *codec = socdev->card->codec;
b2c812e2 1736 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
7220b9f4 1737
7220b9f4 1738 if (twl4030->master_substream) {
7220b9f4 1739 twl4030->slave_substream = substream;
6b87a91f
PU
1740 /* The DAI has one configuration for playback and capture, so
1741 * if the DAI has been already configured then constrain this
1742 * substream to match it. */
1743 if (twl4030->configured)
1744 twl4030_constraints(twl4030, twl4030->master_substream);
1745 } else {
8a1f936a
PU
1746 if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) &
1747 TWL4030_OPTION_1)) {
1748 /* In option2 4 channel is not supported, set the
1749 * constraint for the first stream for channels, the
1750 * second stream will 'inherit' this cosntraint */
1751 snd_pcm_hw_constraint_minmax(substream->runtime,
1752 SNDRV_PCM_HW_PARAM_CHANNELS,
1753 2, 2);
1754 }
7220b9f4 1755 twl4030->master_substream = substream;
6b87a91f 1756 }
7220b9f4
PU
1757
1758 return 0;
1759}
1760
d6648da1
PU
1761static void twl4030_shutdown(struct snd_pcm_substream *substream,
1762 struct snd_soc_dai *dai)
7220b9f4
PU
1763{
1764 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1765 struct snd_soc_device *socdev = rtd->socdev;
d6648da1 1766 struct snd_soc_codec *codec = socdev->card->codec;
b2c812e2 1767 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
7220b9f4
PU
1768
1769 if (twl4030->master_substream == substream)
1770 twl4030->master_substream = twl4030->slave_substream;
1771
1772 twl4030->slave_substream = NULL;
6b87a91f
PU
1773
1774 /* If all streams are closed, or the remaining stream has not yet
1775 * been configured than set the DAI as not configured. */
1776 if (!twl4030->master_substream)
1777 twl4030->configured = 0;
1778 else if (!twl4030->master_substream->runtime->channels)
1779 twl4030->configured = 0;
8a1f936a
PU
1780
1781 /* If the closing substream had 4 channel, do the necessary cleanup */
1782 if (substream->runtime->channels == 4)
1783 twl4030_tdm_enable(codec, substream->stream, 0);
7220b9f4
PU
1784}
1785
cc17557e 1786static int twl4030_hw_params(struct snd_pcm_substream *substream,
dee89c4d
MB
1787 struct snd_pcm_hw_params *params,
1788 struct snd_soc_dai *dai)
cc17557e
SS
1789{
1790 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1791 struct snd_soc_device *socdev = rtd->socdev;
6627a653 1792 struct snd_soc_codec *codec = socdev->card->codec;
b2c812e2 1793 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
cc17557e
SS
1794 u8 mode, old_mode, format, old_format;
1795
8a1f936a
PU
1796 /* If the substream has 4 channel, do the necessary setup */
1797 if (params_channels(params) == 4) {
eaf1ac8b
PU
1798 format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1799 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
1800
1801 /* Safety check: are we in the correct operating mode and
1802 * the interface is in TDM mode? */
1803 if ((mode & TWL4030_OPTION_1) &&
1804 ((format & TWL4030_AIF_FORMAT) == TWL4030_AIF_FORMAT_TDM))
8a1f936a
PU
1805 twl4030_tdm_enable(codec, substream->stream, 1);
1806 else
1807 return -EINVAL;
1808 }
1809
6b87a91f
PU
1810 if (twl4030->configured)
1811 /* Ignoring hw_params for already configured DAI */
7220b9f4
PU
1812 return 0;
1813
cc17557e
SS
1814 /* bit rate */
1815 old_mode = twl4030_read_reg_cache(codec,
1816 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
1817 mode = old_mode & ~TWL4030_APLL_RATE;
1818
1819 switch (params_rate(params)) {
1820 case 8000:
1821 mode |= TWL4030_APLL_RATE_8000;
1822 break;
1823 case 11025:
1824 mode |= TWL4030_APLL_RATE_11025;
1825 break;
1826 case 12000:
1827 mode |= TWL4030_APLL_RATE_12000;
1828 break;
1829 case 16000:
1830 mode |= TWL4030_APLL_RATE_16000;
1831 break;
1832 case 22050:
1833 mode |= TWL4030_APLL_RATE_22050;
1834 break;
1835 case 24000:
1836 mode |= TWL4030_APLL_RATE_24000;
1837 break;
1838 case 32000:
1839 mode |= TWL4030_APLL_RATE_32000;
1840 break;
1841 case 44100:
1842 mode |= TWL4030_APLL_RATE_44100;
1843 break;
1844 case 48000:
1845 mode |= TWL4030_APLL_RATE_48000;
1846 break;
103f211d
PU
1847 case 96000:
1848 mode |= TWL4030_APLL_RATE_96000;
1849 break;
cc17557e
SS
1850 default:
1851 printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
1852 params_rate(params));
1853 return -EINVAL;
1854 }
1855
cc17557e
SS
1856 /* sample size */
1857 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1858 format = old_format;
1859 format &= ~TWL4030_DATA_WIDTH;
1860 switch (params_format(params)) {
1861 case SNDRV_PCM_FORMAT_S16_LE:
1862 format |= TWL4030_DATA_WIDTH_16S_16W;
1863 break;
1864 case SNDRV_PCM_FORMAT_S24_LE:
1865 format |= TWL4030_DATA_WIDTH_32S_24W;
1866 break;
1867 default:
1868 printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
1869 params_format(params));
1870 return -EINVAL;
1871 }
1872
2046f175
PU
1873 if (format != old_format || mode != old_mode) {
1874 if (twl4030->codec_powered) {
1875 /*
1876 * If the codec is powered, than we need to toggle the
1877 * codec power.
1878 */
1879 twl4030_codec_enable(codec, 0);
1880 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1881 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1882 twl4030_codec_enable(codec, 1);
1883 } else {
1884 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1885 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1886 }
cc17557e 1887 }
6b87a91f
PU
1888
1889 /* Store the important parameters for the DAI configuration and set
1890 * the DAI as configured */
1891 twl4030->configured = 1;
1892 twl4030->rate = params_rate(params);
1893 twl4030->sample_bits = hw_param_interval(params,
1894 SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
1895 twl4030->channels = params_channels(params);
1896
1897 /* If both playback and capture streams are open, and one of them
1898 * is setting the hw parameters right now (since we are here), set
1899 * constraints to the other stream to match the current one. */
1900 if (twl4030->slave_substream)
1901 twl4030_constraints(twl4030, substream);
1902
cc17557e
SS
1903 return 0;
1904}
1905
1906static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1907 int clk_id, unsigned int freq, int dir)
1908{
1909 struct snd_soc_codec *codec = codec_dai->codec;
b2c812e2 1910 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
cc17557e
SS
1911
1912 switch (freq) {
1913 case 19200000:
cc17557e 1914 case 26000000:
cc17557e 1915 case 38400000:
cc17557e
SS
1916 break;
1917 default:
68d01955 1918 dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq);
cc17557e
SS
1919 return -EINVAL;
1920 }
1921
68d01955
PU
1922 if ((freq / 1000) != twl4030->sysclk) {
1923 dev_err(codec->dev,
1924 "Mismatch in APLL mclk: %u (configured: %u)\n",
1925 freq, twl4030->sysclk * 1000);
1926 return -EINVAL;
1927 }
cc17557e
SS
1928
1929 return 0;
1930}
1931
1932static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1933 unsigned int fmt)
1934{
1935 struct snd_soc_codec *codec = codec_dai->codec;
2046f175 1936 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
cc17557e
SS
1937 u8 old_format, format;
1938
1939 /* get format */
1940 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1941 format = old_format;
1942
1943 /* set master/slave audio interface */
1944 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1945 case SND_SOC_DAIFMT_CBM_CFM:
1946 format &= ~(TWL4030_AIF_SLAVE_EN);
e18c94d2 1947 format &= ~(TWL4030_CLK256FS_EN);
cc17557e
SS
1948 break;
1949 case SND_SOC_DAIFMT_CBS_CFS:
cc17557e 1950 format |= TWL4030_AIF_SLAVE_EN;
e18c94d2 1951 format |= TWL4030_CLK256FS_EN;
cc17557e
SS
1952 break;
1953 default:
1954 return -EINVAL;
1955 }
1956
1957 /* interface format */
1958 format &= ~TWL4030_AIF_FORMAT;
1959 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1960 case SND_SOC_DAIFMT_I2S:
1961 format |= TWL4030_AIF_FORMAT_CODEC;
1962 break;
8a1f936a
PU
1963 case SND_SOC_DAIFMT_DSP_A:
1964 format |= TWL4030_AIF_FORMAT_TDM;
1965 break;
cc17557e
SS
1966 default:
1967 return -EINVAL;
1968 }
1969
1970 if (format != old_format) {
2046f175
PU
1971 if (twl4030->codec_powered) {
1972 /*
1973 * If the codec is powered, than we need to toggle the
1974 * codec power.
1975 */
1976 twl4030_codec_enable(codec, 0);
1977 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1978 twl4030_codec_enable(codec, 1);
1979 } else {
1980 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1981 }
cc17557e
SS
1982 }
1983
1984 return 0;
1985}
1986
68140443
LCM
1987static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
1988{
1989 struct snd_soc_codec *codec = dai->codec;
1990 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1991
1992 if (tristate)
1993 reg |= TWL4030_AIF_TRI_EN;
1994 else
1995 reg &= ~TWL4030_AIF_TRI_EN;
1996
1997 return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
1998}
1999
b7a755a8
MLC
2000/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
2001 * (VTXL, VTXR) for uplink has to be enabled/disabled. */
2002static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
2003 int enable)
2004{
2005 u8 reg, mask;
2006
2007 reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
2008
2009 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
2010 mask = TWL4030_ARXL1_VRX_EN;
2011 else
2012 mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
2013
2014 if (enable)
2015 reg |= mask;
2016 else
2017 reg &= ~mask;
2018
2019 twl4030_write(codec, TWL4030_REG_OPTION, reg);
2020}
2021
7154b3e8
JS
2022static int twl4030_voice_startup(struct snd_pcm_substream *substream,
2023 struct snd_soc_dai *dai)
2024{
2025 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2026 struct snd_soc_device *socdev = rtd->socdev;
2027 struct snd_soc_codec *codec = socdev->card->codec;
b2c812e2 2028 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
7154b3e8
JS
2029 u8 mode;
2030
2031 /* If the system master clock is not 26MHz, the voice PCM interface is
2032 * not avilable.
2033 */
68d01955
PU
2034 if (twl4030->sysclk != 26000) {
2035 dev_err(codec->dev, "The board is configured for %u Hz, while"
2036 "the Voice interface needs 26MHz APLL mclk\n",
2037 twl4030->sysclk * 1000);
7154b3e8
JS
2038 return -EINVAL;
2039 }
2040
2041 /* If the codec mode is not option2, the voice PCM interface is not
2042 * avilable.
2043 */
2044 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
2045 & TWL4030_OPT_MODE;
2046
2047 if (mode != TWL4030_OPTION_2) {
2048 printk(KERN_ERR "TWL4030 voice startup: "
2049 "the codec mode is not option2\n");
2050 return -EINVAL;
2051 }
2052
2053 return 0;
2054}
2055
b7a755a8
MLC
2056static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2057 struct snd_soc_dai *dai)
2058{
2059 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2060 struct snd_soc_device *socdev = rtd->socdev;
2061 struct snd_soc_codec *codec = socdev->card->codec;
2062
2063 /* Enable voice digital filters */
2064 twl4030_voice_enable(codec, substream->stream, 0);
2065}
2066
7154b3e8
JS
2067static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2068 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
2069{
2070 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2071 struct snd_soc_device *socdev = rtd->socdev;
2072 struct snd_soc_codec *codec = socdev->card->codec;
2046f175 2073 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
7154b3e8
JS
2074 u8 old_mode, mode;
2075
b7a755a8
MLC
2076 /* Enable voice digital filters */
2077 twl4030_voice_enable(codec, substream->stream, 1);
2078
7154b3e8
JS
2079 /* bit rate */
2080 old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
2081 & ~(TWL4030_CODECPDZ);
2082 mode = old_mode;
2083
2084 switch (params_rate(params)) {
2085 case 8000:
2086 mode &= ~(TWL4030_SEL_16K);
2087 break;
2088 case 16000:
2089 mode |= TWL4030_SEL_16K;
2090 break;
2091 default:
2092 printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n",
2093 params_rate(params));
2094 return -EINVAL;
2095 }
2096
2097 if (mode != old_mode) {
2046f175
PU
2098 if (twl4030->codec_powered) {
2099 /*
2100 * If the codec is powered, than we need to toggle the
2101 * codec power.
2102 */
2103 twl4030_codec_enable(codec, 0);
2104 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
2105 twl4030_codec_enable(codec, 1);
2106 } else {
2107 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
2108 }
7154b3e8
JS
2109 }
2110
2111 return 0;
2112}
2113
2114static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
2115 int clk_id, unsigned int freq, int dir)
2116{
2117 struct snd_soc_codec *codec = codec_dai->codec;
d4a8ca24 2118 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
7154b3e8 2119
68d01955
PU
2120 if (freq != 26000000) {
2121 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
2122 "interface needs 26MHz APLL mclk\n", freq);
2123 return -EINVAL;
2124 }
2125 if ((freq / 1000) != twl4030->sysclk) {
2126 dev_err(codec->dev,
2127 "Mismatch in APLL mclk: %u (configured: %u)\n",
2128 freq, twl4030->sysclk * 1000);
7154b3e8
JS
2129 return -EINVAL;
2130 }
7154b3e8
JS
2131 return 0;
2132}
2133
2134static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
2135 unsigned int fmt)
2136{
2137 struct snd_soc_codec *codec = codec_dai->codec;
2046f175 2138 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
7154b3e8
JS
2139 u8 old_format, format;
2140
2141 /* get format */
2142 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
2143 format = old_format;
2144
2145 /* set master/slave audio interface */
2146 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
c264301c 2147 case SND_SOC_DAIFMT_CBM_CFM:
7154b3e8
JS
2148 format &= ~(TWL4030_VIF_SLAVE_EN);
2149 break;
2150 case SND_SOC_DAIFMT_CBS_CFS:
2151 format |= TWL4030_VIF_SLAVE_EN;
2152 break;
2153 default:
2154 return -EINVAL;
2155 }
2156
2157 /* clock inversion */
2158 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2159 case SND_SOC_DAIFMT_IB_NF:
2160 format &= ~(TWL4030_VIF_FORMAT);
2161 break;
2162 case SND_SOC_DAIFMT_NB_IF:
2163 format |= TWL4030_VIF_FORMAT;
2164 break;
2165 default:
2166 return -EINVAL;
2167 }
2168
2169 if (format != old_format) {
2046f175
PU
2170 if (twl4030->codec_powered) {
2171 /*
2172 * If the codec is powered, than we need to toggle the
2173 * codec power.
2174 */
2175 twl4030_codec_enable(codec, 0);
2176 twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
2177 twl4030_codec_enable(codec, 1);
2178 } else {
2179 twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
2180 }
7154b3e8
JS
2181 }
2182
2183 return 0;
2184}
2185
68140443
LCM
2186static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2187{
2188 struct snd_soc_codec *codec = dai->codec;
2189 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
2190
2191 if (tristate)
2192 reg |= TWL4030_VIF_TRI_EN;
2193 else
2194 reg &= ~TWL4030_VIF_TRI_EN;
2195
2196 return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
2197}
2198
bbba9444 2199#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
cc17557e
SS
2200#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
2201
10d9e3d9 2202static struct snd_soc_dai_ops twl4030_dai_ops = {
7220b9f4
PU
2203 .startup = twl4030_startup,
2204 .shutdown = twl4030_shutdown,
10d9e3d9
JS
2205 .hw_params = twl4030_hw_params,
2206 .set_sysclk = twl4030_set_dai_sysclk,
2207 .set_fmt = twl4030_set_dai_fmt,
68140443 2208 .set_tristate = twl4030_set_tristate,
10d9e3d9
JS
2209};
2210
7154b3e8
JS
2211static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
2212 .startup = twl4030_voice_startup,
b7a755a8 2213 .shutdown = twl4030_voice_shutdown,
7154b3e8
JS
2214 .hw_params = twl4030_voice_hw_params,
2215 .set_sysclk = twl4030_voice_set_dai_sysclk,
2216 .set_fmt = twl4030_voice_set_dai_fmt,
68140443 2217 .set_tristate = twl4030_voice_set_tristate,
7154b3e8
JS
2218};
2219
2220struct snd_soc_dai twl4030_dai[] = {
2221{
cc17557e
SS
2222 .name = "twl4030",
2223 .playback = {
b4852b79 2224 .stream_name = "HiFi Playback",
cc17557e 2225 .channels_min = 2,
8a1f936a 2226 .channels_max = 4,
31ad0f31 2227 .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
cc17557e
SS
2228 .formats = TWL4030_FORMATS,},
2229 .capture = {
2230 .stream_name = "Capture",
2231 .channels_min = 2,
8a1f936a 2232 .channels_max = 4,
cc17557e
SS
2233 .rates = TWL4030_RATES,
2234 .formats = TWL4030_FORMATS,},
10d9e3d9 2235 .ops = &twl4030_dai_ops,
7154b3e8
JS
2236},
2237{
2238 .name = "twl4030 Voice",
2239 .playback = {
b4852b79 2240 .stream_name = "Voice Playback",
7154b3e8
JS
2241 .channels_min = 1,
2242 .channels_max = 1,
2243 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
2244 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
2245 .capture = {
2246 .stream_name = "Capture",
2247 .channels_min = 1,
2248 .channels_max = 2,
2249 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
2250 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
2251 .ops = &twl4030_dai_voice_ops,
2252},
cc17557e
SS
2253};
2254EXPORT_SYMBOL_GPL(twl4030_dai);
2255
7a1fecf5 2256static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state)
cc17557e
SS
2257{
2258 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
6627a653 2259 struct snd_soc_codec *codec = socdev->card->codec;
cc17557e
SS
2260
2261 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2262
2263 return 0;
2264}
2265
7a1fecf5 2266static int twl4030_soc_resume(struct platform_device *pdev)
cc17557e
SS
2267{
2268 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
6627a653 2269 struct snd_soc_codec *codec = socdev->card->codec;
cc17557e
SS
2270
2271 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
cc17557e
SS
2272 return 0;
2273}
2274
7a1fecf5 2275static struct snd_soc_codec *twl4030_codec;
cc17557e 2276
7a1fecf5 2277static int twl4030_soc_probe(struct platform_device *pdev)
cc17557e 2278{
7a1fecf5 2279 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
7a1fecf5 2280 struct snd_soc_codec *codec;
7a1fecf5 2281 int ret;
cc17557e 2282
7a1fecf5 2283 BUG_ON(!twl4030_codec);
cc17557e 2284
7a1fecf5 2285 codec = twl4030_codec;
7a1fecf5 2286 socdev->card->codec = codec;
cc17557e 2287
ee4ccac7 2288 twl4030_init_chip(pdev);
9da28c7b 2289
cc17557e
SS
2290 /* register pcms */
2291 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2292 if (ret < 0) {
7a1fecf5
PU
2293 dev_err(&pdev->dev, "failed to create pcms\n");
2294 return ret;
cc17557e
SS
2295 }
2296
3e8e1952
IM
2297 snd_soc_add_controls(codec, twl4030_snd_controls,
2298 ARRAY_SIZE(twl4030_snd_controls));
cc17557e
SS
2299 twl4030_add_widgets(codec);
2300
7a1fecf5 2301 return 0;
cc17557e
SS
2302}
2303
7a1fecf5 2304static int twl4030_soc_remove(struct platform_device *pdev)
cc17557e
SS
2305{
2306 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
7a1fecf5
PU
2307 struct snd_soc_codec *codec = socdev->card->codec;
2308
a3a29b55
PU
2309 /* Reset registers to their chip default before leaving */
2310 twl4030_reset_registers(codec);
7a1fecf5
PU
2311 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2312 snd_soc_free_pcms(socdev);
2313 snd_soc_dapm_free(socdev);
7a1fecf5
PU
2314
2315 return 0;
2316}
2317
2318static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2319{
2320 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
cc17557e 2321 struct snd_soc_codec *codec;
7393958f 2322 struct twl4030_priv *twl4030;
7a1fecf5 2323 int ret;
cc17557e 2324
68d01955
PU
2325 if (!pdata) {
2326 dev_err(&pdev->dev, "platform_data is missing\n");
7a1fecf5
PU
2327 return -EINVAL;
2328 }
cc17557e 2329
7393958f
PU
2330 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2331 if (twl4030 == NULL) {
7a1fecf5 2332 dev_err(&pdev->dev, "Can not allocate memroy\n");
7393958f
PU
2333 return -ENOMEM;
2334 }
2335
7a1fecf5 2336 codec = &twl4030->codec;
b2c812e2 2337 snd_soc_codec_set_drvdata(codec, twl4030);
7a1fecf5
PU
2338 codec->dev = &pdev->dev;
2339 twl4030_dai[0].dev = &pdev->dev;
2340 twl4030_dai[1].dev = &pdev->dev;
2341
cc17557e
SS
2342 mutex_init(&codec->mutex);
2343 INIT_LIST_HEAD(&codec->dapm_widgets);
2344 INIT_LIST_HEAD(&codec->dapm_paths);
2345
7a1fecf5
PU
2346 codec->name = "twl4030";
2347 codec->owner = THIS_MODULE;
2348 codec->read = twl4030_read_reg_cache;
2349 codec->write = twl4030_write;
2350 codec->set_bias_level = twl4030_set_bias_level;
2046f175 2351 codec->idle_bias_off = 1;
7a1fecf5 2352 codec->dai = twl4030_dai;
fd63df22 2353 codec->num_dai = ARRAY_SIZE(twl4030_dai);
7a1fecf5
PU
2354 codec->reg_cache_size = sizeof(twl4030_reg);
2355 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2356 GFP_KERNEL);
2357 if (codec->reg_cache == NULL) {
2358 ret = -ENOMEM;
2359 goto error_cache;
2360 }
2361
2362 platform_set_drvdata(pdev, twl4030);
2363 twl4030_codec = codec;
2364
2365 /* Set the defaults, and power up the codec */
68d01955 2366 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
b3f5a272 2367 codec->bias_level = SND_SOC_BIAS_OFF;
7a1fecf5
PU
2368
2369 ret = snd_soc_register_codec(codec);
2370 if (ret != 0) {
2371 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2372 goto error_codec;
2373 }
2374
2375 ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2376 if (ret != 0) {
2377 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
2378 snd_soc_unregister_codec(codec);
2379 goto error_codec;
2380 }
cc17557e
SS
2381
2382 return 0;
7a1fecf5
PU
2383
2384error_codec:
cbd2db12 2385 twl4030_codec_enable(codec, 0);
7a1fecf5
PU
2386 kfree(codec->reg_cache);
2387error_cache:
2388 kfree(twl4030);
2389 return ret;
cc17557e
SS
2390}
2391
7a1fecf5 2392static int __devexit twl4030_codec_remove(struct platform_device *pdev)
cc17557e 2393{
7a1fecf5 2394 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
cc17557e 2395
cb67286d
PU
2396 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2397 snd_soc_unregister_codec(&twl4030->codec);
2398 kfree(twl4030->codec.reg_cache);
7a1fecf5 2399 kfree(twl4030);
cc17557e 2400
7a1fecf5 2401 twl4030_codec = NULL;
cc17557e
SS
2402 return 0;
2403}
2404
7a1fecf5
PU
2405MODULE_ALIAS("platform:twl4030_codec_audio");
2406
2407static struct platform_driver twl4030_codec_driver = {
2408 .probe = twl4030_codec_probe,
2409 .remove = __devexit_p(twl4030_codec_remove),
2410 .driver = {
2411 .name = "twl4030_codec_audio",
2412 .owner = THIS_MODULE,
2413 },
cc17557e 2414};
cc17557e 2415
24e07db8 2416static int __init twl4030_modinit(void)
64089b84 2417{
7a1fecf5 2418 return platform_driver_register(&twl4030_codec_driver);
64089b84 2419}
24e07db8 2420module_init(twl4030_modinit);
64089b84
MB
2421
2422static void __exit twl4030_exit(void)
2423{
7a1fecf5 2424 platform_driver_unregister(&twl4030_codec_driver);
64089b84
MB
2425}
2426module_exit(twl4030_exit);
2427
7a1fecf5
PU
2428struct snd_soc_codec_device soc_codec_dev_twl4030 = {
2429 .probe = twl4030_soc_probe,
2430 .remove = twl4030_soc_remove,
2431 .suspend = twl4030_soc_suspend,
2432 .resume = twl4030_soc_resume,
2433};
2434EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2435
cc17557e
SS
2436MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2437MODULE_AUTHOR("Steve Sakoman");
2438MODULE_LICENSE("GPL");
This page took 0.209168 seconds and 5 git commands to generate.