1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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>
29#include <linux/i2c/twl.h>
30#include <linux/slab.h>
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/soc.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37
38
39#include <linux/mfd/twl4030-codec.h>
40
41
42#define TWL4030_REG_SW_SHADOW 0x4A
43#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
44
45
46#define TWL4030_HFL_EN 0x01
47#define TWL4030_HFR_EN 0x02
48
49
50
51
52static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
53 0x00,
54 0x00,
55 0x00,
56 0x00,
57 0x00,
58 0x00,
59 0x00,
60 0x00,
61 0x00,
62 0x00,
63 0x0f,
64 0x0f,
65 0x0f,
66 0x0f,
67 0x00,
68 0x00,
69 0x3f,
70 0x3f,
71 0x3f,
72 0x3f,
73 0x25,
74 0x00,
75 0x00,
76 0x00,
77 0x00,
78 0x32,
79 0x32,
80 0x32,
81 0x32,
82 0x00,
83 0x00,
84 0x55,
85 0x00,
86 0x00,
87 0x00,
88 0x00,
89 0x00,
90 0x00,
91 0x00,
92 0x00,
93 0x00,
94 0x00,
95 0x00,
96 0x05,
97 0x00,
98 0x00,
99 0x00,
100 0x00,
101 0x13,
102 0x00,
103 0x00,
104 0x00,
105 0x00,
106 0x79,
107 0x11,
108 0x00,
109 0x00,
110 0x00,
111 0x06,
112 0x00,
113 0x44,
114 0x69,
115 0x00,
116 0x00,
117 0x00,
118 0x00,
119 0x00,
120 0x00,
121 0x32,
122 0x00,
123 0x00,
124 0x00,
125 0x00,
126 0x00,
127 0x00,
128};
129
130
131struct twl4030_priv {
132 struct snd_soc_codec codec;
133
134 unsigned int codec_powered;
135
136
137 unsigned int apll_enabled;
138
139 struct snd_pcm_substream *master_substream;
140 struct snd_pcm_substream *slave_substream;
141
142 unsigned int configured;
143 unsigned int rate;
144 unsigned int sample_bits;
145 unsigned int channels;
146
147 unsigned int sysclk;
148
149
150 u8 hsl_enabled, hsr_enabled;
151 u8 earpiece_enabled;
152 u8 predrivel_enabled, predriver_enabled;
153 u8 carkitl_enabled, carkitr_enabled;
154
155
156 unsigned int digimic_delay;
157};
158
159
160
161
162static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
163 unsigned int reg)
164{
165 u8 *cache = codec->reg_cache;
166
167 if (reg >= TWL4030_CACHEREGNUM)
168 return -EIO;
169
170 return cache[reg];
171}
172
173
174
175
176static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
177 u8 reg, u8 value)
178{
179 u8 *cache = codec->reg_cache;
180
181 if (reg >= TWL4030_CACHEREGNUM)
182 return;
183 cache[reg] = value;
184}
185
186
187
188
189static int twl4030_write(struct snd_soc_codec *codec,
190 unsigned int reg, unsigned int value)
191{
192 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
193 int write_to_reg = 0;
194
195 twl4030_write_reg_cache(codec, reg, value);
196 if (likely(reg < TWL4030_REG_SW_SHADOW)) {
197
198 switch (reg) {
199 case TWL4030_REG_EAR_CTL:
200 if (twl4030->earpiece_enabled)
201 write_to_reg = 1;
202 break;
203 case TWL4030_REG_PREDL_CTL:
204 if (twl4030->predrivel_enabled)
205 write_to_reg = 1;
206 break;
207 case TWL4030_REG_PREDR_CTL:
208 if (twl4030->predriver_enabled)
209 write_to_reg = 1;
210 break;
211 case TWL4030_REG_PRECKL_CTL:
212 if (twl4030->carkitl_enabled)
213 write_to_reg = 1;
214 break;
215 case TWL4030_REG_PRECKR_CTL:
216 if (twl4030->carkitr_enabled)
217 write_to_reg = 1;
218 break;
219 case TWL4030_REG_HS_GAIN_SET:
220 if (twl4030->hsl_enabled || twl4030->hsr_enabled)
221 write_to_reg = 1;
222 break;
223 default:
224
225 write_to_reg = 1;
226 break;
227 }
228 if (write_to_reg)
229 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
230 value, reg);
231 }
232 return 0;
233}
234
235static inline void twl4030_wait_ms(int time)
236{
237 if (time < 60) {
238 time *= 1000;
239 usleep_range(time, time + 500);
240 } else {
241 msleep(time);
242 }
243}
244
245static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
246{
247 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
248 int mode;
249
250 if (enable == twl4030->codec_powered)
251 return;
252
253 if (enable)
254 mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
255 else
256 mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
257
258 if (mode >= 0) {
259 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
260 twl4030->codec_powered = enable;
261 }
262
263
264
265 udelay(10);
266}
267
268static inline void twl4030_check_defaults(struct snd_soc_codec *codec)
269{
270 int i, difference = 0;
271 u8 val;
272
273 dev_dbg(codec->dev, "Checking TWL audio default configuration\n");
274 for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) {
275 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i);
276 if (val != twl4030_reg[i]) {
277 difference++;
278 dev_dbg(codec->dev,
279 "Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n",
280 i, val, twl4030_reg[i]);
281 }
282 }
283 dev_dbg(codec->dev, "Found %d non maching registers. %s\n",
284 difference, difference ? "Not OK" : "OK");
285}
286
287static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
288{
289 int i;
290
291
292 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
293 if (i != TWL4030_REG_APLL_CTL)
294 twl4030_write(codec, i, twl4030_reg[i]);
295
296}
297
298static void twl4030_init_chip(struct snd_soc_codec *codec)
299{
300 struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev);
301 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
302 u8 reg, byte;
303 int i = 0;
304
305
306 if (pdata && pdata->check_defaults)
307 twl4030_check_defaults(codec);
308
309
310 if (!pdata || (pdata && pdata->reset_registers))
311 twl4030_reset_registers(codec);
312
313
314 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
315 TWL4030_REG_APLL_CTL);
316 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte);
317
318
319 reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
320 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
321 reg | TWL4030_SMOOTH_ANAVOL_EN);
322
323 twl4030_write(codec, TWL4030_REG_OPTION,
324 TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
325 TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
326
327
328 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
329
330
331 if (!pdata)
332 return;
333
334 twl4030->digimic_delay = pdata->digimic_delay;
335
336 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
337 reg &= ~TWL4030_RAMP_DELAY;
338 reg |= (pdata->ramp_delay_value << 2);
339 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
340
341
342 twl4030_codec_enable(codec, 1);
343
344 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
345 reg &= ~TWL4030_OFFSET_CNCL_SEL;
346 reg |= pdata->offset_cncl_path;
347 twl4030_write(codec, TWL4030_REG_ANAMICL,
348 reg | TWL4030_CNCL_OFFSET_START);
349
350
351
352
353
354
355 msleep(20);
356 do {
357 usleep_range(1000, 2000);
358 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
359 TWL4030_REG_ANAMICL);
360 } while ((i++ < 100) &&
361 ((byte & TWL4030_CNCL_OFFSET_START) ==
362 TWL4030_CNCL_OFFSET_START));
363
364
365 twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte);
366
367 twl4030_codec_enable(codec, 0);
368}
369
370static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
371{
372 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
373 int status = -1;
374
375 if (enable) {
376 twl4030->apll_enabled++;
377 if (twl4030->apll_enabled == 1)
378 status = twl4030_codec_enable_resource(
379 TWL4030_CODEC_RES_APLL);
380 } else {
381 twl4030->apll_enabled--;
382 if (!twl4030->apll_enabled)
383 status = twl4030_codec_disable_resource(
384 TWL4030_CODEC_RES_APLL);
385 }
386
387 if (status >= 0)
388 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
389}
390
391
392static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = {
393 SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0),
394 SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0),
395 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0),
396 SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0),
397};
398
399
400static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = {
401 SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0),
402 SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0),
403 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0),
404 SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0),
405};
406
407
408static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = {
409 SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0),
410 SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0),
411 SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0),
412 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0),
413};
414
415
416static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = {
417 SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0),
418 SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0),
419 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0),
420};
421
422
423static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = {
424 SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0),
425 SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0),
426 SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0),
427};
428
429
430static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = {
431 SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0),
432 SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0),
433 SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0),
434};
435
436
437static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = {
438 SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0),
439 SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0),
440 SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0),
441};
442
443
444static const char *twl4030_handsfreel_texts[] =
445 {"Voice", "AudioL1", "AudioL2", "AudioR2"};
446
447static const struct soc_enum twl4030_handsfreel_enum =
448 SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
449 ARRAY_SIZE(twl4030_handsfreel_texts),
450 twl4030_handsfreel_texts);
451
452static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
453SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
454
455
456static const struct snd_kcontrol_new twl4030_dapm_handsfreelmute_control =
457 SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 0, 1, 0);
458
459
460static const char *twl4030_handsfreer_texts[] =
461 {"Voice", "AudioR1", "AudioR2", "AudioL2"};
462
463static const struct soc_enum twl4030_handsfreer_enum =
464 SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
465 ARRAY_SIZE(twl4030_handsfreer_texts),
466 twl4030_handsfreer_texts);
467
468static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
469SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
470
471
472static const struct snd_kcontrol_new twl4030_dapm_handsfreermute_control =
473 SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 1, 1, 0);
474
475
476
477static const char *twl4030_vibra_texts[] =
478 {"AudioL1", "AudioR1", "AudioL2", "AudioR2"};
479
480static const struct soc_enum twl4030_vibra_enum =
481 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2,
482 ARRAY_SIZE(twl4030_vibra_texts),
483 twl4030_vibra_texts);
484
485static const struct snd_kcontrol_new twl4030_dapm_vibra_control =
486SOC_DAPM_ENUM("Route", twl4030_vibra_enum);
487
488
489static const char *twl4030_vibrapath_texts[] =
490 {"Local vibrator", "Audio"};
491
492static const struct soc_enum twl4030_vibrapath_enum =
493 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4,
494 ARRAY_SIZE(twl4030_vibrapath_texts),
495 twl4030_vibrapath_texts);
496
497static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control =
498SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
499
500
501static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = {
502 SOC_DAPM_SINGLE("Main Mic Capture Switch",
503 TWL4030_REG_ANAMICL, 0, 1, 0),
504 SOC_DAPM_SINGLE("Headset Mic Capture Switch",
505 TWL4030_REG_ANAMICL, 1, 1, 0),
506 SOC_DAPM_SINGLE("AUXL Capture Switch",
507 TWL4030_REG_ANAMICL, 2, 1, 0),
508 SOC_DAPM_SINGLE("Carkit Mic Capture Switch",
509 TWL4030_REG_ANAMICL, 3, 1, 0),
510};
511
512
513static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = {
514 SOC_DAPM_SINGLE("Sub Mic Capture Switch", TWL4030_REG_ANAMICR, 0, 1, 0),
515 SOC_DAPM_SINGLE("AUXR Capture Switch", TWL4030_REG_ANAMICR, 2, 1, 0),
516};
517
518
519static const char *twl4030_micpathtx1_texts[] =
520 {"Analog", "Digimic0"};
521
522static const struct soc_enum twl4030_micpathtx1_enum =
523 SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 0,
524 ARRAY_SIZE(twl4030_micpathtx1_texts),
525 twl4030_micpathtx1_texts);
526
527static const struct snd_kcontrol_new twl4030_dapm_micpathtx1_control =
528SOC_DAPM_ENUM("Route", twl4030_micpathtx1_enum);
529
530
531static const char *twl4030_micpathtx2_texts[] =
532 {"Analog", "Digimic1"};
533
534static const struct soc_enum twl4030_micpathtx2_enum =
535 SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 2,
536 ARRAY_SIZE(twl4030_micpathtx2_texts),
537 twl4030_micpathtx2_texts);
538
539static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control =
540SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum);
541
542
543static const struct snd_kcontrol_new twl4030_dapm_abypassr1_control =
544 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR1_APGA_CTL, 2, 1, 0);
545
546
547static const struct snd_kcontrol_new twl4030_dapm_abypassl1_control =
548 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL1_APGA_CTL, 2, 1, 0);
549
550
551static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control =
552 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXR2_APGA_CTL, 2, 1, 0);
553
554
555static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
556 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
557
558
559static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
560 SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
561
562
563static const unsigned int twl4030_dapm_dbypass_tlv[] = {
564 TLV_DB_RANGE_HEAD(3),
565 0, 1, TLV_DB_SCALE_ITEM(-3000, 600, 1),
566 2, 3, TLV_DB_SCALE_ITEM(-2400, 0, 0),
567 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0),
568};
569
570
571static const struct snd_kcontrol_new twl4030_dapm_dbypassl_control =
572 SOC_DAPM_SINGLE_TLV("Volume",
573 TWL4030_REG_ATX2ARXPGA, 3, 7, 0,
574 twl4030_dapm_dbypass_tlv);
575
576
577static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control =
578 SOC_DAPM_SINGLE_TLV("Volume",
579 TWL4030_REG_ATX2ARXPGA, 0, 7, 0,
580 twl4030_dapm_dbypass_tlv);
581
582
583
584
585
586static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1);
587
588
589static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
590 SOC_DAPM_SINGLE_TLV("Volume",
591 TWL4030_REG_VSTPGA, 0, 0x29, 0,
592 twl4030_dapm_dbypassv_tlv);
593
594
595
596
597
598
599
600
601
602#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
603static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
604 struct snd_kcontrol *kcontrol, int event) \
605{ \
606 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \
607 \
608 switch (event) { \
609 case SND_SOC_DAPM_POST_PMU: \
610 twl4030->pin_name##_enabled = 1; \
611 twl4030_write(w->codec, reg, \
612 twl4030_read_reg_cache(w->codec, reg)); \
613 break; \
614 case SND_SOC_DAPM_POST_PMD: \
615 twl4030->pin_name##_enabled = 0; \
616 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
617 0, reg); \
618 break; \
619 } \
620 return 0; \
621}
622
623TWL4030_OUTPUT_PGA(earpiece, TWL4030_REG_EAR_CTL, TWL4030_EAR_GAIN);
624TWL4030_OUTPUT_PGA(predrivel, TWL4030_REG_PREDL_CTL, TWL4030_PREDL_GAIN);
625TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
626TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
627TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
628
629static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
630{
631 unsigned char hs_ctl;
632
633 hs_ctl = twl4030_read_reg_cache(codec, reg);
634
635 if (ramp) {
636
637 hs_ctl |= TWL4030_HF_CTL_REF_EN;
638 twl4030_write(codec, reg, hs_ctl);
639 udelay(10);
640 hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
641 twl4030_write(codec, reg, hs_ctl);
642 udelay(40);
643 hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
644 hs_ctl |= TWL4030_HF_CTL_HB_EN;
645 twl4030_write(codec, reg, hs_ctl);
646 } else {
647
648 hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
649 hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
650 twl4030_write(codec, reg, hs_ctl);
651 hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
652 twl4030_write(codec, reg, hs_ctl);
653 udelay(40);
654 hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
655 twl4030_write(codec, reg, hs_ctl);
656 }
657}
658
659static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
660 struct snd_kcontrol *kcontrol, int event)
661{
662 switch (event) {
663 case SND_SOC_DAPM_POST_PMU:
664 handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1);
665 break;
666 case SND_SOC_DAPM_POST_PMD:
667 handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0);
668 break;
669 }
670 return 0;
671}
672
673static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
674 struct snd_kcontrol *kcontrol, int event)
675{
676 switch (event) {
677 case SND_SOC_DAPM_POST_PMU:
678 handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1);
679 break;
680 case SND_SOC_DAPM_POST_PMD:
681 handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0);
682 break;
683 }
684 return 0;
685}
686
687static int vibramux_event(struct snd_soc_dapm_widget *w,
688 struct snd_kcontrol *kcontrol, int event)
689{
690 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
691 return 0;
692}
693
694static int apll_event(struct snd_soc_dapm_widget *w,
695 struct snd_kcontrol *kcontrol, int event)
696{
697 switch (event) {
698 case SND_SOC_DAPM_PRE_PMU:
699 twl4030_apll_enable(w->codec, 1);
700 break;
701 case SND_SOC_DAPM_POST_PMD:
702 twl4030_apll_enable(w->codec, 0);
703 break;
704 }
705 return 0;
706}
707
708static int aif_event(struct snd_soc_dapm_widget *w,
709 struct snd_kcontrol *kcontrol, int event)
710{
711 u8 audio_if;
712
713 audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF);
714 switch (event) {
715 case SND_SOC_DAPM_PRE_PMU:
716
717
718 twl4030_apll_enable(w->codec, 1);
719
720 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
721 audio_if | TWL4030_AIF_EN);
722 break;
723 case SND_SOC_DAPM_POST_PMD:
724
725 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
726 audio_if & ~TWL4030_AIF_EN);
727 twl4030_apll_enable(w->codec, 0);
728 break;
729 }
730 return 0;
731}
732
733static void headset_ramp(struct snd_soc_codec *codec, int ramp)
734{
735 struct twl4030_codec_audio_data *pdata = codec->dev->platform_data;
736 unsigned char hs_gain, hs_pop;
737 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
738
739 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
740 8388608, 16777216, 33554432, 67108864};
741 unsigned int delay;
742
743 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
744 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
745 delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
746 twl4030->sysclk) + 1;
747
748
749
750 if (pdata && pdata->hs_extmute) {
751 if (pdata->set_hs_extmute) {
752 pdata->set_hs_extmute(1);
753 } else {
754 hs_pop |= TWL4030_EXTMUTE;
755 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
756 }
757 }
758
759 if (ramp) {
760
761 hs_pop |= TWL4030_VMID_EN;
762 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
763
764 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
765 hs_gain,
766 TWL4030_REG_HS_GAIN_SET);
767 hs_pop |= TWL4030_RAMP_EN;
768 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
769
770 twl4030_wait_ms(delay);
771 } else {
772
773
774 hs_pop &= ~TWL4030_RAMP_EN;
775 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
776
777 twl4030_wait_ms(delay);
778
779 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
780 hs_gain & (~0x0f),
781 TWL4030_REG_HS_GAIN_SET);
782
783 hs_pop &= ~TWL4030_VMID_EN;
784 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
785 }
786
787
788 if (pdata && pdata->hs_extmute) {
789 if (pdata->set_hs_extmute) {
790 pdata->set_hs_extmute(0);
791 } else {
792 hs_pop &= ~TWL4030_EXTMUTE;
793 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
794 }
795 }
796}
797
798static int headsetlpga_event(struct snd_soc_dapm_widget *w,
799 struct snd_kcontrol *kcontrol, int event)
800{
801 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
802
803 switch (event) {
804 case SND_SOC_DAPM_POST_PMU:
805
806 if (!twl4030->hsr_enabled)
807 headset_ramp(w->codec, 1);
808
809 twl4030->hsl_enabled = 1;
810 break;
811 case SND_SOC_DAPM_POST_PMD:
812
813 if (!twl4030->hsr_enabled)
814 headset_ramp(w->codec, 0);
815
816 twl4030->hsl_enabled = 0;
817 break;
818 }
819 return 0;
820}
821
822static int headsetrpga_event(struct snd_soc_dapm_widget *w,
823 struct snd_kcontrol *kcontrol, int event)
824{
825 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
826
827 switch (event) {
828 case SND_SOC_DAPM_POST_PMU:
829
830 if (!twl4030->hsl_enabled)
831 headset_ramp(w->codec, 1);
832
833 twl4030->hsr_enabled = 1;
834 break;
835 case SND_SOC_DAPM_POST_PMD:
836
837 if (!twl4030->hsl_enabled)
838 headset_ramp(w->codec, 0);
839
840 twl4030->hsr_enabled = 0;
841 break;
842 }
843 return 0;
844}
845
846static int digimic_event(struct snd_soc_dapm_widget *w,
847 struct snd_kcontrol *kcontrol, int event)
848{
849 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
850
851 if (twl4030->digimic_delay)
852 twl4030_wait_ms(twl4030->digimic_delay);
853 return 0;
854}
855
856
857
858
859
860
861
862
863
864
865
866#define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
867 xinvert, tlv_array) \
868{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
869 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
870 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
871 .tlv.p = (tlv_array), \
872 .info = snd_soc_info_volsw, \
873 .get = snd_soc_get_volsw_twl4030, \
874 .put = snd_soc_put_volsw_twl4030, \
875 .private_value = (unsigned long)&(struct soc_mixer_control) \
876 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
877 .max = xmax, .invert = xinvert} }
878#define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
879 xinvert, tlv_array) \
880{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
881 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
882 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
883 .tlv.p = (tlv_array), \
884 .info = snd_soc_info_volsw_2r, \
885 .get = snd_soc_get_volsw_r2_twl4030,\
886 .put = snd_soc_put_volsw_r2_twl4030, \
887 .private_value = (unsigned long)&(struct soc_mixer_control) \
888 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
889 .rshift = xshift, .max = xmax, .invert = xinvert} }
890#define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
891 SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
892 xinvert, tlv_array)
893
894static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
895 struct snd_ctl_elem_value *ucontrol)
896{
897 struct soc_mixer_control *mc =
898 (struct soc_mixer_control *)kcontrol->private_value;
899 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
900 unsigned int reg = mc->reg;
901 unsigned int shift = mc->shift;
902 unsigned int rshift = mc->rshift;
903 int max = mc->max;
904 int mask = (1 << fls(max)) - 1;
905
906 ucontrol->value.integer.value[0] =
907 (snd_soc_read(codec, reg) >> shift) & mask;
908 if (ucontrol->value.integer.value[0])
909 ucontrol->value.integer.value[0] =
910 max + 1 - ucontrol->value.integer.value[0];
911
912 if (shift != rshift) {
913 ucontrol->value.integer.value[1] =
914 (snd_soc_read(codec, reg) >> rshift) & mask;
915 if (ucontrol->value.integer.value[1])
916 ucontrol->value.integer.value[1] =
917 max + 1 - ucontrol->value.integer.value[1];
918 }
919
920 return 0;
921}
922
923static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
924 struct snd_ctl_elem_value *ucontrol)
925{
926 struct soc_mixer_control *mc =
927 (struct soc_mixer_control *)kcontrol->private_value;
928 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
929 unsigned int reg = mc->reg;
930 unsigned int shift = mc->shift;
931 unsigned int rshift = mc->rshift;
932 int max = mc->max;
933 int mask = (1 << fls(max)) - 1;
934 unsigned short val, val2, val_mask;
935
936 val = (ucontrol->value.integer.value[0] & mask);
937
938 val_mask = mask << shift;
939 if (val)
940 val = max + 1 - val;
941 val = val << shift;
942 if (shift != rshift) {
943 val2 = (ucontrol->value.integer.value[1] & mask);
944 val_mask |= mask << rshift;
945 if (val2)
946 val2 = max + 1 - val2;
947 val |= val2 << rshift;
948 }
949 return snd_soc_update_bits(codec, reg, val_mask, val);
950}
951
952static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
953 struct snd_ctl_elem_value *ucontrol)
954{
955 struct soc_mixer_control *mc =
956 (struct soc_mixer_control *)kcontrol->private_value;
957 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
958 unsigned int reg = mc->reg;
959 unsigned int reg2 = mc->rreg;
960 unsigned int shift = mc->shift;
961 int max = mc->max;
962 int mask = (1<<fls(max))-1;
963
964 ucontrol->value.integer.value[0] =
965 (snd_soc_read(codec, reg) >> shift) & mask;
966 ucontrol->value.integer.value[1] =
967 (snd_soc_read(codec, reg2) >> shift) & mask;
968
969 if (ucontrol->value.integer.value[0])
970 ucontrol->value.integer.value[0] =
971 max + 1 - ucontrol->value.integer.value[0];
972 if (ucontrol->value.integer.value[1])
973 ucontrol->value.integer.value[1] =
974 max + 1 - ucontrol->value.integer.value[1];
975
976 return 0;
977}
978
979static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
980 struct snd_ctl_elem_value *ucontrol)
981{
982 struct soc_mixer_control *mc =
983 (struct soc_mixer_control *)kcontrol->private_value;
984 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
985 unsigned int reg = mc->reg;
986 unsigned int reg2 = mc->rreg;
987 unsigned int shift = mc->shift;
988 int max = mc->max;
989 int mask = (1 << fls(max)) - 1;
990 int err;
991 unsigned short val, val2, val_mask;
992
993 val_mask = mask << shift;
994 val = (ucontrol->value.integer.value[0] & mask);
995 val2 = (ucontrol->value.integer.value[1] & mask);
996
997 if (val)
998 val = max + 1 - val;
999 if (val2)
1000 val2 = max + 1 - val2;
1001
1002 val = val << shift;
1003 val2 = val2 << shift;
1004
1005 err = snd_soc_update_bits(codec, reg, val_mask, val);
1006 if (err < 0)
1007 return err;
1008
1009 err = snd_soc_update_bits(codec, reg2, val_mask, val2);
1010 return err;
1011}
1012
1013
1014static const char *twl4030_op_modes_texts[] = {
1015 "Option 2 (voice/audio)", "Option 1 (audio)"
1016};
1017
1018static const struct soc_enum twl4030_op_modes_enum =
1019 SOC_ENUM_SINGLE(TWL4030_REG_CODEC_MODE, 0,
1020 ARRAY_SIZE(twl4030_op_modes_texts),
1021 twl4030_op_modes_texts);
1022
1023static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
1024 struct snd_ctl_elem_value *ucontrol)
1025{
1026 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1027 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1028 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1029 unsigned short val;
1030 unsigned short mask, bitmask;
1031
1032 if (twl4030->configured) {
1033 printk(KERN_ERR "twl4030 operation mode cannot be "
1034 "changed on-the-fly\n");
1035 return -EBUSY;
1036 }
1037
1038 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1039 ;
1040 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1041 return -EINVAL;
1042
1043 val = ucontrol->value.enumerated.item[0] << e->shift_l;
1044 mask = (bitmask - 1) << e->shift_l;
1045 if (e->shift_l != e->shift_r) {
1046 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1047 return -EINVAL;
1048 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1049 mask |= (bitmask - 1) << e->shift_r;
1050 }
1051
1052 return snd_soc_update_bits(codec, e->reg, mask, val);
1053}
1054
1055
1056
1057
1058
1059static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
1060
1061
1062
1063
1064
1065
1066static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
1067
1068
1069
1070
1071
1072static DECLARE_TLV_DB_SCALE(digital_voice_downlink_tlv, -3700, 100, 1);
1073
1074
1075
1076
1077
1078static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
1079
1080
1081
1082
1083
1084static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
1085
1086
1087
1088
1089
1090static DECLARE_TLV_DB_SCALE(output_ear_tvl, -600, 600, 1);
1091
1092
1093
1094
1095
1096static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
1097
1098
1099
1100
1101
1102static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
1103
1104
1105static const char *twl4030_avadc_clk_priority_texts[] = {
1106 "Voice high priority", "HiFi high priority"
1107};
1108
1109static const struct soc_enum twl4030_avadc_clk_priority_enum =
1110 SOC_ENUM_SINGLE(TWL4030_REG_AVADC_CTL, 2,
1111 ARRAY_SIZE(twl4030_avadc_clk_priority_texts),
1112 twl4030_avadc_clk_priority_texts);
1113
1114static const char *twl4030_rampdelay_texts[] = {
1115 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms",
1116 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms",
1117 "3495/2581/1748 ms"
1118};
1119
1120static const struct soc_enum twl4030_rampdelay_enum =
1121 SOC_ENUM_SINGLE(TWL4030_REG_HS_POPN_SET, 2,
1122 ARRAY_SIZE(twl4030_rampdelay_texts),
1123 twl4030_rampdelay_texts);
1124
1125
1126static const char *twl4030_vibradirmode_texts[] = {
1127 "Vibra H-bridge direction", "Audio data MSB",
1128};
1129
1130static const struct soc_enum twl4030_vibradirmode_enum =
1131 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5,
1132 ARRAY_SIZE(twl4030_vibradirmode_texts),
1133 twl4030_vibradirmode_texts);
1134
1135
1136static const char *twl4030_vibradir_texts[] = {
1137 "Positive polarity", "Negative polarity",
1138};
1139
1140static const struct soc_enum twl4030_vibradir_enum =
1141 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1,
1142 ARRAY_SIZE(twl4030_vibradir_texts),
1143 twl4030_vibradir_texts);
1144
1145
1146static const char *twl4030_digimicswap_texts[] = {
1147 "Not swapped", "Swapped",
1148};
1149
1150static const struct soc_enum twl4030_digimicswap_enum =
1151 SOC_ENUM_SINGLE(TWL4030_REG_MISC_SET_1, 0,
1152 ARRAY_SIZE(twl4030_digimicswap_texts),
1153 twl4030_digimicswap_texts);
1154
1155static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1156
1157 SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum,
1158 snd_soc_get_enum_double,
1159 snd_soc_put_twl4030_opmode_enum_double),
1160
1161
1162 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
1163 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
1164 0, 0x3f, 0, digital_fine_tlv),
1165 SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume",
1166 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
1167 0, 0x3f, 0, digital_fine_tlv),
1168
1169 SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume",
1170 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
1171 6, 0x2, 0, digital_coarse_tlv),
1172 SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume",
1173 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
1174 6, 0x2, 0, digital_coarse_tlv),
1175
1176 SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume",
1177 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
1178 3, 0x12, 1, analog_tlv),
1179 SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume",
1180 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
1181 3, 0x12, 1, analog_tlv),
1182 SOC_DOUBLE_R("DAC1 Analog Playback Switch",
1183 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
1184 1, 1, 0),
1185 SOC_DOUBLE_R("DAC2 Analog Playback Switch",
1186 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
1187 1, 1, 0),
1188
1189
1190 SOC_SINGLE_TLV("DAC Voice Digital Downlink Volume",
1191 TWL4030_REG_VRXPGA, 0, 0x31, 0, digital_voice_downlink_tlv),
1192
1193 SOC_SINGLE_TLV("DAC Voice Analog Downlink Volume",
1194 TWL4030_REG_VDL_APGA_CTL, 3, 0x12, 1, analog_tlv),
1195
1196 SOC_SINGLE("DAC Voice Analog Downlink Switch",
1197 TWL4030_REG_VDL_APGA_CTL, 1, 1, 0),
1198
1199
1200 SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
1201 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
1202 4, 3, 0, output_tvl),
1203
1204 SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume",
1205 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl),
1206
1207 SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume",
1208 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
1209 4, 3, 0, output_tvl),
1210
1211 SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume",
1212 TWL4030_REG_EAR_CTL, 4, 3, 0, output_ear_tvl),
1213
1214
1215 SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume",
1216 TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
1217 0, 0x1f, 0, digital_capture_tlv),
1218 SOC_DOUBLE_R_TLV("TX2 Digital Capture Volume",
1219 TWL4030_REG_AVTXL2PGA, TWL4030_REG_AVTXR2PGA,
1220 0, 0x1f, 0, digital_capture_tlv),
1221
1222 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
1223 0, 3, 5, 0, input_gain_tlv),
1224
1225 SOC_ENUM("AVADC Clock Priority", twl4030_avadc_clk_priority_enum),
1226
1227 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
1228
1229 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
1230 SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum),
1231
1232 SOC_ENUM("Digimic LR Swap", twl4030_digimicswap_enum),
1233};
1234
1235static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1236
1237 SND_SOC_DAPM_INPUT("MAINMIC"),
1238 SND_SOC_DAPM_INPUT("HSMIC"),
1239 SND_SOC_DAPM_INPUT("AUXL"),
1240 SND_SOC_DAPM_INPUT("CARKITMIC"),
1241
1242 SND_SOC_DAPM_INPUT("SUBMIC"),
1243 SND_SOC_DAPM_INPUT("AUXR"),
1244
1245 SND_SOC_DAPM_INPUT("DIGIMIC0"),
1246 SND_SOC_DAPM_INPUT("DIGIMIC1"),
1247
1248
1249 SND_SOC_DAPM_OUTPUT("EARPIECE"),
1250 SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
1251 SND_SOC_DAPM_OUTPUT("PREDRIVER"),
1252 SND_SOC_DAPM_OUTPUT("HSOL"),
1253 SND_SOC_DAPM_OUTPUT("HSOR"),
1254 SND_SOC_DAPM_OUTPUT("CARKITL"),
1255 SND_SOC_DAPM_OUTPUT("CARKITR"),
1256 SND_SOC_DAPM_OUTPUT("HFL"),
1257 SND_SOC_DAPM_OUTPUT("HFR"),
1258 SND_SOC_DAPM_OUTPUT("VIBRA"),
1259
1260
1261 SND_SOC_DAPM_OUTPUT("Virtual HiFi OUT"),
1262 SND_SOC_DAPM_INPUT("Virtual HiFi IN"),
1263 SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
1264
1265
1266 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
1267 SND_SOC_NOPM, 0, 0),
1268 SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback",
1269 SND_SOC_NOPM, 0, 0),
1270 SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback",
1271 SND_SOC_NOPM, 0, 0),
1272 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback",
1273 SND_SOC_NOPM, 0, 0),
1274 SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
1275 SND_SOC_NOPM, 0, 0),
1276
1277
1278 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1279 &twl4030_dapm_abypassr1_control),
1280 SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1281 &twl4030_dapm_abypassl1_control),
1282 SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1283 &twl4030_dapm_abypassr2_control),
1284 SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1285 &twl4030_dapm_abypassl2_control),
1286 SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1287 &twl4030_dapm_abypassv_control),
1288
1289
1290 SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
1291 NULL, 0),
1292
1293
1294 SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
1295 &twl4030_dapm_dbypassl_control),
1296 SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
1297 &twl4030_dapm_dbypassr_control),
1298 SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1299 &twl4030_dapm_dbypassv_control),
1300
1301
1302 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
1303 TWL4030_REG_AVDAC_CTL, 0, 0, NULL, 0),
1304 SND_SOC_DAPM_MIXER("Digital L1 Playback Mixer",
1305 TWL4030_REG_AVDAC_CTL, 1, 0, NULL, 0),
1306 SND_SOC_DAPM_MIXER("Digital R2 Playback Mixer",
1307 TWL4030_REG_AVDAC_CTL, 2, 0, NULL, 0),
1308 SND_SOC_DAPM_MIXER("Digital L2 Playback Mixer",
1309 TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0),
1310 SND_SOC_DAPM_MIXER("Digital Voice Playback Mixer",
1311 TWL4030_REG_AVDAC_CTL, 4, 0, NULL, 0),
1312
1313
1314 SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer",
1315 TWL4030_REG_ARXR1_APGA_CTL, 0, 0, NULL, 0),
1316 SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer",
1317 TWL4030_REG_ARXL1_APGA_CTL, 0, 0, NULL, 0),
1318 SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer",
1319 TWL4030_REG_ARXR2_APGA_CTL, 0, 0, NULL, 0),
1320 SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer",
1321 TWL4030_REG_ARXL2_APGA_CTL, 0, 0, NULL, 0),
1322 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
1323 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
1324
1325 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1326 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1327
1328 SND_SOC_DAPM_SUPPLY("AIF Enable", SND_SOC_NOPM, 0, 0, aif_event,
1329 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1330
1331
1332
1333 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
1334 &twl4030_dapm_earpiece_controls[0],
1335 ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
1336 SND_SOC_DAPM_PGA_E("Earpiece PGA", SND_SOC_NOPM,
1337 0, 0, NULL, 0, earpiecepga_event,
1338 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1339
1340 SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
1341 &twl4030_dapm_predrivel_controls[0],
1342 ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
1343 SND_SOC_DAPM_PGA_E("PredriveL PGA", SND_SOC_NOPM,
1344 0, 0, NULL, 0, predrivelpga_event,
1345 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1346 SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
1347 &twl4030_dapm_predriver_controls[0],
1348 ARRAY_SIZE(twl4030_dapm_predriver_controls)),
1349 SND_SOC_DAPM_PGA_E("PredriveR PGA", SND_SOC_NOPM,
1350 0, 0, NULL, 0, predriverpga_event,
1351 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1352
1353 SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
1354 &twl4030_dapm_hsol_controls[0],
1355 ARRAY_SIZE(twl4030_dapm_hsol_controls)),
1356 SND_SOC_DAPM_PGA_E("HeadsetL PGA", SND_SOC_NOPM,
1357 0, 0, NULL, 0, headsetlpga_event,
1358 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1359 SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0,
1360 &twl4030_dapm_hsor_controls[0],
1361 ARRAY_SIZE(twl4030_dapm_hsor_controls)),
1362 SND_SOC_DAPM_PGA_E("HeadsetR PGA", SND_SOC_NOPM,
1363 0, 0, NULL, 0, headsetrpga_event,
1364 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1365
1366 SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
1367 &twl4030_dapm_carkitl_controls[0],
1368 ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
1369 SND_SOC_DAPM_PGA_E("CarkitL PGA", SND_SOC_NOPM,
1370 0, 0, NULL, 0, carkitlpga_event,
1371 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1372 SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
1373 &twl4030_dapm_carkitr_controls[0],
1374 ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
1375 SND_SOC_DAPM_PGA_E("CarkitR PGA", SND_SOC_NOPM,
1376 0, 0, NULL, 0, carkitrpga_event,
1377 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1378
1379
1380
1381 SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
1382 &twl4030_dapm_handsfreel_control),
1383 SND_SOC_DAPM_SWITCH("HandsfreeL", SND_SOC_NOPM, 0, 0,
1384 &twl4030_dapm_handsfreelmute_control),
1385 SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
1386 0, 0, NULL, 0, handsfreelpga_event,
1387 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1388 SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
1389 &twl4030_dapm_handsfreer_control),
1390 SND_SOC_DAPM_SWITCH("HandsfreeR", SND_SOC_NOPM, 0, 0,
1391 &twl4030_dapm_handsfreermute_control),
1392 SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
1393 0, 0, NULL, 0, handsfreerpga_event,
1394 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1395
1396 SND_SOC_DAPM_MUX_E("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1397 &twl4030_dapm_vibra_control, vibramux_event,
1398 SND_SOC_DAPM_PRE_PMU),
1399 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
1400 &twl4030_dapm_vibrapath_control),
1401
1402
1403
1404 SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture",
1405 SND_SOC_NOPM, 0, 0),
1406 SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture",
1407 SND_SOC_NOPM, 0, 0),
1408 SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture",
1409 SND_SOC_NOPM, 0, 0),
1410 SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture",
1411 SND_SOC_NOPM, 0, 0),
1412
1413
1414
1415
1416 SND_SOC_DAPM_MUX("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
1417 &twl4030_dapm_micpathtx1_control),
1418 SND_SOC_DAPM_MUX("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
1419 &twl4030_dapm_micpathtx2_control),
1420
1421
1422 SND_SOC_DAPM_MIXER("Analog Left",
1423 TWL4030_REG_ANAMICL, 4, 0,
1424 &twl4030_dapm_analoglmic_controls[0],
1425 ARRAY_SIZE(twl4030_dapm_analoglmic_controls)),
1426 SND_SOC_DAPM_MIXER("Analog Right",
1427 TWL4030_REG_ANAMICR, 4, 0,
1428 &twl4030_dapm_analogrmic_controls[0],
1429 ARRAY_SIZE(twl4030_dapm_analogrmic_controls)),
1430
1431 SND_SOC_DAPM_PGA("ADC Physical Left",
1432 TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0),
1433 SND_SOC_DAPM_PGA("ADC Physical Right",
1434 TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0),
1435
1436 SND_SOC_DAPM_PGA_E("Digimic0 Enable",
1437 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0,
1438 digimic_event, SND_SOC_DAPM_POST_PMU),
1439 SND_SOC_DAPM_PGA_E("Digimic1 Enable",
1440 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0,
1441 digimic_event, SND_SOC_DAPM_POST_PMU),
1442
1443 SND_SOC_DAPM_SUPPLY("micbias1 select", TWL4030_REG_MICBIAS_CTL, 5, 0,
1444 NULL, 0),
1445 SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0,
1446 NULL, 0),
1447
1448 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
1449 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
1450 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0),
1451
1452};
1453
1454static const struct snd_soc_dapm_route intercon[] = {
1455 {"Digital L1 Playback Mixer", NULL, "DAC Left1"},
1456 {"Digital R1 Playback Mixer", NULL, "DAC Right1"},
1457 {"Digital L2 Playback Mixer", NULL, "DAC Left2"},
1458 {"Digital R2 Playback Mixer", NULL, "DAC Right2"},
1459 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1460
1461
1462 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1463
1464 {"DAC Left1", NULL, "AIF Enable"},
1465 {"DAC Right1", NULL, "AIF Enable"},
1466 {"DAC Left2", NULL, "AIF Enable"},
1467 {"DAC Right1", NULL, "AIF Enable"},
1468
1469 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1470 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1471
1472 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1473 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1474 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
1475 {"Analog R2 Playback Mixer", NULL, "Digital R2 Playback Mixer"},
1476 {"Analog Voice Playback Mixer", NULL, "Digital Voice Playback Mixer"},
1477
1478
1479
1480 {"Earpiece Mixer", "Voice", "Analog Voice Playback Mixer"},
1481 {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1482 {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1483 {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1484 {"Earpiece PGA", NULL, "Earpiece Mixer"},
1485
1486 {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"},
1487 {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1488 {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1489 {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1490 {"PredriveL PGA", NULL, "PredriveL Mixer"},
1491
1492 {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"},
1493 {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1494 {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1495 {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1496 {"PredriveR PGA", NULL, "PredriveR Mixer"},
1497
1498 {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"},
1499 {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1500 {"HeadsetL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1501 {"HeadsetL PGA", NULL, "HeadsetL Mixer"},
1502
1503 {"HeadsetR Mixer", "Voice", "Analog Voice Playback Mixer"},
1504 {"HeadsetR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1505 {"HeadsetR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1506 {"HeadsetR PGA", NULL, "HeadsetR Mixer"},
1507
1508 {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"},
1509 {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1510 {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1511 {"CarkitL PGA", NULL, "CarkitL Mixer"},
1512
1513 {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"},
1514 {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1515 {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1516 {"CarkitR PGA", NULL, "CarkitR Mixer"},
1517
1518 {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"},
1519 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
1520 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
1521 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
1522 {"HandsfreeL", "Switch", "HandsfreeL Mux"},
1523 {"HandsfreeL PGA", NULL, "HandsfreeL"},
1524
1525 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
1526 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
1527 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
1528 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
1529 {"HandsfreeR", "Switch", "HandsfreeR Mux"},
1530 {"HandsfreeR PGA", NULL, "HandsfreeR"},
1531
1532 {"Vibra Mux", "AudioL1", "DAC Left1"},
1533 {"Vibra Mux", "AudioR1", "DAC Right1"},
1534 {"Vibra Mux", "AudioL2", "DAC Left2"},
1535 {"Vibra Mux", "AudioR2", "DAC Right2"},
1536
1537
1538
1539 {"Virtual HiFi OUT", NULL, "DAC Left1"},
1540 {"Virtual HiFi OUT", NULL, "DAC Right1"},
1541 {"Virtual HiFi OUT", NULL, "DAC Left2"},
1542 {"Virtual HiFi OUT", NULL, "DAC Right2"},
1543
1544 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"},
1545
1546 {"EARPIECE", NULL, "Earpiece PGA"},
1547 {"PREDRIVEL", NULL, "PredriveL PGA"},
1548 {"PREDRIVER", NULL, "PredriveR PGA"},
1549 {"HSOL", NULL, "HeadsetL PGA"},
1550 {"HSOR", NULL, "HeadsetR PGA"},
1551 {"CARKITL", NULL, "CarkitL PGA"},
1552 {"CARKITR", NULL, "CarkitR PGA"},
1553 {"HFL", NULL, "HandsfreeL PGA"},
1554 {"HFR", NULL, "HandsfreeR PGA"},
1555 {"Vibra Route", "Audio", "Vibra Mux"},
1556 {"VIBRA", NULL, "Vibra Route"},
1557
1558
1559
1560 {"ADC Virtual Left1", NULL, "Virtual HiFi IN"},
1561 {"ADC Virtual Right1", NULL, "Virtual HiFi IN"},
1562 {"ADC Virtual Left2", NULL, "Virtual HiFi IN"},
1563 {"ADC Virtual Right2", NULL, "Virtual HiFi IN"},
1564
1565 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
1566 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
1567 {"Analog Left", "AUXL Capture Switch", "AUXL"},
1568 {"Analog Left", "Carkit Mic Capture Switch", "CARKITMIC"},
1569
1570 {"Analog Right", "Sub Mic Capture Switch", "SUBMIC"},
1571 {"Analog Right", "AUXR Capture Switch", "AUXR"},
1572
1573 {"ADC Physical Left", NULL, "Analog Left"},
1574 {"ADC Physical Right", NULL, "Analog Right"},
1575
1576 {"Digimic0 Enable", NULL, "DIGIMIC0"},
1577 {"Digimic1 Enable", NULL, "DIGIMIC1"},
1578
1579 {"DIGIMIC0", NULL, "micbias1 select"},
1580 {"DIGIMIC1", NULL, "micbias2 select"},
1581
1582
1583 {"TX1 Capture Route", "Analog", "ADC Physical Left"},
1584 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
1585
1586 {"TX1 Capture Route", "Analog", "ADC Physical Right"},
1587 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
1588
1589 {"TX2 Capture Route", "Analog", "ADC Physical Left"},
1590 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
1591
1592 {"TX2 Capture Route", "Analog", "ADC Physical Right"},
1593 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
1594
1595 {"ADC Virtual Left1", NULL, "TX1 Capture Route"},
1596 {"ADC Virtual Right1", NULL, "TX1 Capture Route"},
1597 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1598 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1599
1600 {"ADC Virtual Left1", NULL, "AIF Enable"},
1601 {"ADC Virtual Right1", NULL, "AIF Enable"},
1602 {"ADC Virtual Left2", NULL, "AIF Enable"},
1603 {"ADC Virtual Right2", NULL, "AIF Enable"},
1604
1605
1606 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1607 {"Left1 Analog Loopback", "Switch", "Analog Left"},
1608 {"Right2 Analog Loopback", "Switch", "Analog Right"},
1609 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1610 {"Voice Analog Loopback", "Switch", "Analog Left"},
1611
1612
1613 {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
1614 {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
1615 {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
1616 {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
1617 {"Voice Analog Loopback", NULL, "FM Loop Enable"},
1618
1619 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1620 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1621 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
1622 {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
1623 {"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"},
1624
1625
1626 {"Right Digital Loopback", "Volume", "TX1 Capture Route"},
1627 {"Left Digital Loopback", "Volume", "TX1 Capture Route"},
1628 {"Voice Digital Loopback", "Volume", "TX2 Capture Route"},
1629
1630 {"Digital R2 Playback Mixer", NULL, "Right Digital Loopback"},
1631 {"Digital L2 Playback Mixer", NULL, "Left Digital Loopback"},
1632 {"Digital Voice Playback Mixer", NULL, "Voice Digital Loopback"},
1633
1634};
1635
1636static int twl4030_add_widgets(struct snd_soc_codec *codec)
1637{
1638 struct snd_soc_dapm_context *dapm = &codec->dapm;
1639
1640 snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets,
1641 ARRAY_SIZE(twl4030_dapm_widgets));
1642 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1643
1644 return 0;
1645}
1646
1647static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1648 enum snd_soc_bias_level level)
1649{
1650 switch (level) {
1651 case SND_SOC_BIAS_ON:
1652 break;
1653 case SND_SOC_BIAS_PREPARE:
1654 break;
1655 case SND_SOC_BIAS_STANDBY:
1656 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1657 twl4030_codec_enable(codec, 1);
1658 break;
1659 case SND_SOC_BIAS_OFF:
1660 twl4030_codec_enable(codec, 0);
1661 break;
1662 }
1663 codec->dapm.bias_level = level;
1664
1665 return 0;
1666}
1667
1668static void twl4030_constraints(struct twl4030_priv *twl4030,
1669 struct snd_pcm_substream *mst_substream)
1670{
1671 struct snd_pcm_substream *slv_substream;
1672
1673
1674 if (mst_substream == twl4030->master_substream)
1675 slv_substream = twl4030->slave_substream;
1676 else if (mst_substream == twl4030->slave_substream)
1677 slv_substream = twl4030->master_substream;
1678 else
1679 return;
1680
1681
1682 snd_pcm_hw_constraint_minmax(slv_substream->runtime,
1683 SNDRV_PCM_HW_PARAM_RATE,
1684 twl4030->rate,
1685 twl4030->rate);
1686
1687 snd_pcm_hw_constraint_minmax(slv_substream->runtime,
1688 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1689 twl4030->sample_bits,
1690 twl4030->sample_bits);
1691
1692 snd_pcm_hw_constraint_minmax(slv_substream->runtime,
1693 SNDRV_PCM_HW_PARAM_CHANNELS,
1694 twl4030->channels,
1695 twl4030->channels);
1696}
1697
1698
1699
1700static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
1701 int enable)
1702{
1703 u8 reg, mask;
1704
1705 reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
1706
1707 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1708 mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN;
1709 else
1710 mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
1711
1712 if (enable)
1713 reg |= mask;
1714 else
1715 reg &= ~mask;
1716
1717 twl4030_write(codec, TWL4030_REG_OPTION, reg);
1718}
1719
1720static int twl4030_startup(struct snd_pcm_substream *substream,
1721 struct snd_soc_dai *dai)
1722{
1723 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1724 struct snd_soc_codec *codec = rtd->codec;
1725 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1726
1727 snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
1728 if (twl4030->master_substream) {
1729 twl4030->slave_substream = substream;
1730
1731
1732
1733 if (twl4030->configured)
1734 twl4030_constraints(twl4030, twl4030->master_substream);
1735 } else {
1736 if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) &
1737 TWL4030_OPTION_1)) {
1738
1739
1740
1741 snd_pcm_hw_constraint_minmax(substream->runtime,
1742 SNDRV_PCM_HW_PARAM_CHANNELS,
1743 2, 2);
1744 }
1745 twl4030->master_substream = substream;
1746 }
1747
1748 return 0;
1749}
1750
1751static void twl4030_shutdown(struct snd_pcm_substream *substream,
1752 struct snd_soc_dai *dai)
1753{
1754 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1755 struct snd_soc_codec *codec = rtd->codec;
1756 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1757
1758 if (twl4030->master_substream == substream)
1759 twl4030->master_substream = twl4030->slave_substream;
1760
1761 twl4030->slave_substream = NULL;
1762
1763
1764
1765 if (!twl4030->master_substream)
1766 twl4030->configured = 0;
1767 else if (!twl4030->master_substream->runtime->channels)
1768 twl4030->configured = 0;
1769
1770
1771 if (substream->runtime->channels == 4)
1772 twl4030_tdm_enable(codec, substream->stream, 0);
1773}
1774
1775static int twl4030_hw_params(struct snd_pcm_substream *substream,
1776 struct snd_pcm_hw_params *params,
1777 struct snd_soc_dai *dai)
1778{
1779 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1780 struct snd_soc_codec *codec = rtd->codec;
1781 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1782 u8 mode, old_mode, format, old_format;
1783
1784
1785 if (params_channels(params) == 4) {
1786 format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1787 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
1788
1789
1790
1791 if ((mode & TWL4030_OPTION_1) &&
1792 ((format & TWL4030_AIF_FORMAT) == TWL4030_AIF_FORMAT_TDM))
1793 twl4030_tdm_enable(codec, substream->stream, 1);
1794 else
1795 return -EINVAL;
1796 }
1797
1798 if (twl4030->configured)
1799
1800 return 0;
1801
1802
1803 old_mode = twl4030_read_reg_cache(codec,
1804 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
1805 mode = old_mode & ~TWL4030_APLL_RATE;
1806
1807 switch (params_rate(params)) {
1808 case 8000:
1809 mode |= TWL4030_APLL_RATE_8000;
1810 break;
1811 case 11025:
1812 mode |= TWL4030_APLL_RATE_11025;
1813 break;
1814 case 12000:
1815 mode |= TWL4030_APLL_RATE_12000;
1816 break;
1817 case 16000:
1818 mode |= TWL4030_APLL_RATE_16000;
1819 break;
1820 case 22050:
1821 mode |= TWL4030_APLL_RATE_22050;
1822 break;
1823 case 24000:
1824 mode |= TWL4030_APLL_RATE_24000;
1825 break;
1826 case 32000:
1827 mode |= TWL4030_APLL_RATE_32000;
1828 break;
1829 case 44100:
1830 mode |= TWL4030_APLL_RATE_44100;
1831 break;
1832 case 48000:
1833 mode |= TWL4030_APLL_RATE_48000;
1834 break;
1835 case 96000:
1836 mode |= TWL4030_APLL_RATE_96000;
1837 break;
1838 default:
1839 printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
1840 params_rate(params));
1841 return -EINVAL;
1842 }
1843
1844
1845 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1846 format = old_format;
1847 format &= ~TWL4030_DATA_WIDTH;
1848 switch (params_format(params)) {
1849 case SNDRV_PCM_FORMAT_S16_LE:
1850 format |= TWL4030_DATA_WIDTH_16S_16W;
1851 break;
1852 case SNDRV_PCM_FORMAT_S32_LE:
1853 format |= TWL4030_DATA_WIDTH_32S_24W;
1854 break;
1855 default:
1856 printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
1857 params_format(params));
1858 return -EINVAL;
1859 }
1860
1861 if (format != old_format || mode != old_mode) {
1862 if (twl4030->codec_powered) {
1863
1864
1865
1866
1867 twl4030_codec_enable(codec, 0);
1868 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1869 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1870 twl4030_codec_enable(codec, 1);
1871 } else {
1872 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1873 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1874 }
1875 }
1876
1877
1878
1879 twl4030->configured = 1;
1880 twl4030->rate = params_rate(params);
1881 twl4030->sample_bits = hw_param_interval(params,
1882 SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
1883 twl4030->channels = params_channels(params);
1884
1885
1886
1887
1888 if (twl4030->slave_substream)
1889 twl4030_constraints(twl4030, substream);
1890
1891 return 0;
1892}
1893
1894static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1895 int clk_id, unsigned int freq, int dir)
1896{
1897 struct snd_soc_codec *codec = codec_dai->codec;
1898 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1899
1900 switch (freq) {
1901 case 19200000:
1902 case 26000000:
1903 case 38400000:
1904 break;
1905 default:
1906 dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq);
1907 return -EINVAL;
1908 }
1909
1910 if ((freq / 1000) != twl4030->sysclk) {
1911 dev_err(codec->dev,
1912 "Mismatch in APLL mclk: %u (configured: %u)\n",
1913 freq, twl4030->sysclk * 1000);
1914 return -EINVAL;
1915 }
1916
1917 return 0;
1918}
1919
1920static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1921 unsigned int fmt)
1922{
1923 struct snd_soc_codec *codec = codec_dai->codec;
1924 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1925 u8 old_format, format;
1926
1927
1928 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1929 format = old_format;
1930
1931
1932 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1933 case SND_SOC_DAIFMT_CBM_CFM:
1934 format &= ~(TWL4030_AIF_SLAVE_EN);
1935 format &= ~(TWL4030_CLK256FS_EN);
1936 break;
1937 case SND_SOC_DAIFMT_CBS_CFS:
1938 format |= TWL4030_AIF_SLAVE_EN;
1939 format |= TWL4030_CLK256FS_EN;
1940 break;
1941 default:
1942 return -EINVAL;
1943 }
1944
1945
1946 format &= ~TWL4030_AIF_FORMAT;
1947 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1948 case SND_SOC_DAIFMT_I2S:
1949 format |= TWL4030_AIF_FORMAT_CODEC;
1950 break;
1951 case SND_SOC_DAIFMT_DSP_A:
1952 format |= TWL4030_AIF_FORMAT_TDM;
1953 break;
1954 default:
1955 return -EINVAL;
1956 }
1957
1958 if (format != old_format) {
1959 if (twl4030->codec_powered) {
1960
1961
1962
1963
1964 twl4030_codec_enable(codec, 0);
1965 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1966 twl4030_codec_enable(codec, 1);
1967 } else {
1968 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1969 }
1970 }
1971
1972 return 0;
1973}
1974
1975static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
1976{
1977 struct snd_soc_codec *codec = dai->codec;
1978 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1979
1980 if (tristate)
1981 reg |= TWL4030_AIF_TRI_EN;
1982 else
1983 reg &= ~TWL4030_AIF_TRI_EN;
1984
1985 return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
1986}
1987
1988
1989
1990static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
1991 int enable)
1992{
1993 u8 reg, mask;
1994
1995 reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION);
1996
1997 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1998 mask = TWL4030_ARXL1_VRX_EN;
1999 else
2000 mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN;
2001
2002 if (enable)
2003 reg |= mask;
2004 else
2005 reg &= ~mask;
2006
2007 twl4030_write(codec, TWL4030_REG_OPTION, reg);
2008}
2009
2010static int twl4030_voice_startup(struct snd_pcm_substream *substream,
2011 struct snd_soc_dai *dai)
2012{
2013 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2014 struct snd_soc_codec *codec = rtd->codec;
2015 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2016 u8 mode;
2017
2018
2019
2020
2021 if (twl4030->sysclk != 26000) {
2022 dev_err(codec->dev, "The board is configured for %u Hz, while"
2023 "the Voice interface needs 26MHz APLL mclk\n",
2024 twl4030->sysclk * 1000);
2025 return -EINVAL;
2026 }
2027
2028
2029
2030
2031 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
2032 & TWL4030_OPT_MODE;
2033
2034 if (mode != TWL4030_OPTION_2) {
2035 printk(KERN_ERR "TWL4030 voice startup: "
2036 "the codec mode is not option2\n");
2037 return -EINVAL;
2038 }
2039
2040 return 0;
2041}
2042
2043static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2044 struct snd_soc_dai *dai)
2045{
2046 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2047 struct snd_soc_codec *codec = rtd->codec;
2048
2049
2050 twl4030_voice_enable(codec, substream->stream, 0);
2051}
2052
2053static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2054 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
2055{
2056 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2057 struct snd_soc_codec *codec = rtd->codec;
2058 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2059 u8 old_mode, mode;
2060
2061
2062 twl4030_voice_enable(codec, substream->stream, 1);
2063
2064
2065 old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
2066 & ~(TWL4030_CODECPDZ);
2067 mode = old_mode;
2068
2069 switch (params_rate(params)) {
2070 case 8000:
2071 mode &= ~(TWL4030_SEL_16K);
2072 break;
2073 case 16000:
2074 mode |= TWL4030_SEL_16K;
2075 break;
2076 default:
2077 printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n",
2078 params_rate(params));
2079 return -EINVAL;
2080 }
2081
2082 if (mode != old_mode) {
2083 if (twl4030->codec_powered) {
2084
2085
2086
2087
2088 twl4030_codec_enable(codec, 0);
2089 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
2090 twl4030_codec_enable(codec, 1);
2091 } else {
2092 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
2093 }
2094 }
2095
2096 return 0;
2097}
2098
2099static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
2100 int clk_id, unsigned int freq, int dir)
2101{
2102 struct snd_soc_codec *codec = codec_dai->codec;
2103 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2104
2105 if (freq != 26000000) {
2106 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
2107 "interface needs 26MHz APLL mclk\n", freq);
2108 return -EINVAL;
2109 }
2110 if ((freq / 1000) != twl4030->sysclk) {
2111 dev_err(codec->dev,
2112 "Mismatch in APLL mclk: %u (configured: %u)\n",
2113 freq, twl4030->sysclk * 1000);
2114 return -EINVAL;
2115 }
2116 return 0;
2117}
2118
2119static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
2120 unsigned int fmt)
2121{
2122 struct snd_soc_codec *codec = codec_dai->codec;
2123 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2124 u8 old_format, format;
2125
2126
2127 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
2128 format = old_format;
2129
2130
2131 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2132 case SND_SOC_DAIFMT_CBM_CFM:
2133 format &= ~(TWL4030_VIF_SLAVE_EN);
2134 break;
2135 case SND_SOC_DAIFMT_CBS_CFS:
2136 format |= TWL4030_VIF_SLAVE_EN;
2137 break;
2138 default:
2139 return -EINVAL;
2140 }
2141
2142
2143 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2144 case SND_SOC_DAIFMT_IB_NF:
2145 format &= ~(TWL4030_VIF_FORMAT);
2146 break;
2147 case SND_SOC_DAIFMT_NB_IF:
2148 format |= TWL4030_VIF_FORMAT;
2149 break;
2150 default:
2151 return -EINVAL;
2152 }
2153
2154 if (format != old_format) {
2155 if (twl4030->codec_powered) {
2156
2157
2158
2159
2160 twl4030_codec_enable(codec, 0);
2161 twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
2162 twl4030_codec_enable(codec, 1);
2163 } else {
2164 twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
2165 }
2166 }
2167
2168 return 0;
2169}
2170
2171static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2172{
2173 struct snd_soc_codec *codec = dai->codec;
2174 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
2175
2176 if (tristate)
2177 reg |= TWL4030_VIF_TRI_EN;
2178 else
2179 reg &= ~TWL4030_VIF_TRI_EN;
2180
2181 return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
2182}
2183
2184#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
2185#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
2186
2187static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
2188 .startup = twl4030_startup,
2189 .shutdown = twl4030_shutdown,
2190 .hw_params = twl4030_hw_params,
2191 .set_sysclk = twl4030_set_dai_sysclk,
2192 .set_fmt = twl4030_set_dai_fmt,
2193 .set_tristate = twl4030_set_tristate,
2194};
2195
2196static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
2197 .startup = twl4030_voice_startup,
2198 .shutdown = twl4030_voice_shutdown,
2199 .hw_params = twl4030_voice_hw_params,
2200 .set_sysclk = twl4030_voice_set_dai_sysclk,
2201 .set_fmt = twl4030_voice_set_dai_fmt,
2202 .set_tristate = twl4030_voice_set_tristate,
2203};
2204
2205static struct snd_soc_dai_driver twl4030_dai[] = {
2206{
2207 .name = "twl4030-hifi",
2208 .playback = {
2209 .stream_name = "HiFi Playback",
2210 .channels_min = 2,
2211 .channels_max = 4,
2212 .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
2213 .formats = TWL4030_FORMATS,},
2214 .capture = {
2215 .stream_name = "Capture",
2216 .channels_min = 2,
2217 .channels_max = 4,
2218 .rates = TWL4030_RATES,
2219 .formats = TWL4030_FORMATS,},
2220 .ops = &twl4030_dai_hifi_ops,
2221},
2222{
2223 .name = "twl4030-voice",
2224 .playback = {
2225 .stream_name = "Voice Playback",
2226 .channels_min = 1,
2227 .channels_max = 1,
2228 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
2229 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
2230 .capture = {
2231 .stream_name = "Capture",
2232 .channels_min = 1,
2233 .channels_max = 2,
2234 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
2235 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
2236 .ops = &twl4030_dai_voice_ops,
2237},
2238};
2239
2240static int twl4030_soc_suspend(struct snd_soc_codec *codec, pm_message_t state)
2241{
2242 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2243 return 0;
2244}
2245
2246static int twl4030_soc_resume(struct snd_soc_codec *codec)
2247{
2248 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2249 return 0;
2250}
2251
2252static int twl4030_soc_probe(struct snd_soc_codec *codec)
2253{
2254 struct twl4030_priv *twl4030;
2255
2256 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2257 if (twl4030 == NULL) {
2258 printk("Can not allocate memroy\n");
2259 return -ENOMEM;
2260 }
2261 snd_soc_codec_set_drvdata(codec, twl4030);
2262
2263 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2264 codec->dapm.idle_bias_off = 1;
2265
2266 twl4030_init_chip(codec);
2267
2268 snd_soc_add_controls(codec, twl4030_snd_controls,
2269 ARRAY_SIZE(twl4030_snd_controls));
2270 twl4030_add_widgets(codec);
2271 return 0;
2272}
2273
2274static int twl4030_soc_remove(struct snd_soc_codec *codec)
2275{
2276 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2277
2278
2279 twl4030_reset_registers(codec);
2280 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2281 kfree(twl4030);
2282 return 0;
2283}
2284
2285static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2286 .probe = twl4030_soc_probe,
2287 .remove = twl4030_soc_remove,
2288 .suspend = twl4030_soc_suspend,
2289 .resume = twl4030_soc_resume,
2290 .read = twl4030_read_reg_cache,
2291 .write = twl4030_write,
2292 .set_bias_level = twl4030_set_bias_level,
2293 .reg_cache_size = sizeof(twl4030_reg),
2294 .reg_word_size = sizeof(u8),
2295 .reg_cache_default = twl4030_reg,
2296};
2297
2298static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2299{
2300 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
2301
2302 if (!pdata) {
2303 dev_err(&pdev->dev, "platform_data is missing\n");
2304 return -EINVAL;
2305 }
2306
2307 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
2308 twl4030_dai, ARRAY_SIZE(twl4030_dai));
2309}
2310
2311static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2312{
2313 snd_soc_unregister_codec(&pdev->dev);
2314 return 0;
2315}
2316
2317MODULE_ALIAS("platform:twl4030-codec");
2318
2319static struct platform_driver twl4030_codec_driver = {
2320 .probe = twl4030_codec_probe,
2321 .remove = __devexit_p(twl4030_codec_remove),
2322 .driver = {
2323 .name = "twl4030-codec",
2324 .owner = THIS_MODULE,
2325 },
2326};
2327
2328static int __init twl4030_modinit(void)
2329{
2330 return platform_driver_register(&twl4030_codec_driver);
2331}
2332module_init(twl4030_modinit);
2333
2334static void __exit twl4030_exit(void)
2335{
2336 platform_driver_unregister(&twl4030_codec_driver);
2337}
2338module_exit(twl4030_exit);
2339
2340MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2341MODULE_AUTHOR("Steve Sakoman");
2342MODULE_LICENSE("GPL");
2343