]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - sound/soc/codecs/twl6040.c
b07839b2d912ecd29aa5a1d291e00710bde787c4
[karo-tx-linux.git] / sound / soc / codecs / twl6040.c
1 /*
2  * ALSA SoC TWL6040 codec driver
3  *
4  * Author:       Misael Lopez Cruz <x0052729@ti.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/platform_device.h>
28 #include <linux/slab.h>
29 #include <linux/mfd/twl6040.h>
30
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>
37 #include <sound/tlv.h>
38
39 #include "twl6040.h"
40
41 enum twl6040_dai_id {
42         TWL6040_DAI_LEGACY = 0,
43         TWL6040_DAI_UL,
44         TWL6040_DAI_DL1,
45         TWL6040_DAI_DL2,
46         TWL6040_DAI_VIB,
47 };
48
49 #define TWL6040_RATES           SNDRV_PCM_RATE_8000_96000
50 #define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
51
52 #define TWL6040_OUTHS_0dB 0x00
53 #define TWL6040_OUTHS_M30dB 0x0F
54 #define TWL6040_OUTHF_0dB 0x03
55 #define TWL6040_OUTHF_M52dB 0x1D
56
57 #define TWL6040_CACHEREGNUM     (TWL6040_REG_STATUS + 1)
58
59 struct twl6040_jack_data {
60         struct snd_soc_jack *jack;
61         struct delayed_work work;
62         int report;
63 };
64
65 /* codec private data */
66 struct twl6040_data {
67         int plug_irq;
68         int codec_powered;
69         int pll;
70         int pll_power_mode;
71         int hs_power_mode;
72         int hs_power_mode_locked;
73         bool dl1_unmuted;
74         bool dl2_unmuted;
75         u8 dl12_cache[TWL6040_REG_HFRCTL - TWL6040_REG_HSLCTL + 1];
76         unsigned int clk_in;
77         unsigned int sysclk;
78         struct twl6040_jack_data hs_jack;
79         struct snd_soc_codec *codec;
80         struct mutex mutex;
81 };
82
83 /*
84  * twl6040 register cache & default register settings
85  */
86 static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
87         0x00, /* not used       0x00    */
88         0x4B, /* REG_ASICID     0x01 (ro) */
89         0x00, /* REG_ASICREV    0x02 (ro) */
90         0x00, /* REG_INTID      0x03    */
91         0x00, /* REG_INTMR      0x04    */
92         0x00, /* REG_NCPCTRL    0x05    */
93         0x00, /* REG_LDOCTL     0x06    */
94         0x60, /* REG_HPPLLCTL   0x07    */
95         0x00, /* REG_LPPLLCTL   0x08    */
96         0x4A, /* REG_LPPLLDIV   0x09    */
97         0x00, /* REG_AMICBCTL   0x0A    */
98         0x00, /* REG_DMICBCTL   0x0B    */
99         0x00, /* REG_MICLCTL    0x0C    */
100         0x00, /* REG_MICRCTL    0x0D    */
101         0x00, /* REG_MICGAIN    0x0E    */
102         0x1B, /* REG_LINEGAIN   0x0F    */
103         0x00, /* REG_HSLCTL     0x10    */
104         0x00, /* REG_HSRCTL     0x11    */
105         0x00, /* REG_HSGAIN     0x12    */
106         0x00, /* REG_EARCTL     0x13    */
107         0x00, /* REG_HFLCTL     0x14    */
108         0x00, /* REG_HFLGAIN    0x15    */
109         0x00, /* REG_HFRCTL     0x16    */
110         0x00, /* REG_HFRGAIN    0x17    */
111         0x00, /* REG_VIBCTLL    0x18    */
112         0x00, /* REG_VIBDATL    0x19    */
113         0x00, /* REG_VIBCTLR    0x1A    */
114         0x00, /* REG_VIBDATR    0x1B    */
115         0x00, /* REG_HKCTL1     0x1C    */
116         0x00, /* REG_HKCTL2     0x1D    */
117         0x00, /* REG_GPOCTL     0x1E    */
118         0x00, /* REG_ALB        0x1F    */
119         0x00, /* REG_DLB        0x20    */
120         0x00, /* not used       0x21    */
121         0x00, /* not used       0x22    */
122         0x00, /* not used       0x23    */
123         0x00, /* not used       0x24    */
124         0x00, /* not used       0x25    */
125         0x00, /* not used       0x26    */
126         0x00, /* not used       0x27    */
127         0x00, /* REG_TRIM1      0x28    */
128         0x00, /* REG_TRIM2      0x29    */
129         0x00, /* REG_TRIM3      0x2A    */
130         0x00, /* REG_HSOTRIM    0x2B    */
131         0x00, /* REG_HFOTRIM    0x2C    */
132         0x09, /* REG_ACCCTL     0x2D    */
133         0x00, /* REG_STATUS     0x2E (ro) */
134 };
135
136 /* set of rates for each pll: low-power and high-performance */
137 static unsigned int lp_rates[] = {
138         8000,
139         11250,
140         16000,
141         22500,
142         32000,
143         44100,
144         48000,
145         88200,
146         96000,
147 };
148
149 static unsigned int hp_rates[] = {
150         8000,
151         16000,
152         32000,
153         48000,
154         96000,
155 };
156
157 static struct snd_pcm_hw_constraint_list sysclk_constraints[] = {
158         { .count = ARRAY_SIZE(lp_rates), .list = lp_rates, },
159         { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, },
160 };
161
162 static inline int twl6040_read_dl12_cache(struct snd_soc_codec *codec,
163                                            u8 reg, u8 *value)
164 {
165         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
166         int ret = 0;
167
168         switch (reg) {
169         case TWL6040_REG_HSLCTL:
170         case TWL6040_REG_HSRCTL:
171         case TWL6040_REG_EARCTL:
172         case TWL6040_REG_HFLCTL:
173         case TWL6040_REG_HFRCTL:
174                 *value = priv->dl12_cache[reg - TWL6040_REG_HSLCTL];
175                 break;
176         default:
177                 ret = -EINVAL;
178                 break;
179         }
180
181         return ret;
182 }
183
184 /*
185  * read twl6040 register cache
186  */
187 static inline unsigned int twl6040_read_reg_cache(struct snd_soc_codec *codec,
188                                                   unsigned int reg)
189 {
190         u8 *cache = codec->reg_cache;
191         u8 value;
192
193         if (reg >= TWL6040_CACHEREGNUM)
194                 return -EIO;
195
196         if (twl6040_read_dl12_cache(codec, reg, &value))
197                 value = cache[reg];
198
199         return value;
200 }
201
202 static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec,
203                                              u8 reg, u8 value)
204 {
205         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
206
207         switch (reg) {
208         case TWL6040_REG_HSLCTL:
209         case TWL6040_REG_HSRCTL:
210         case TWL6040_REG_EARCTL:
211         case TWL6040_REG_HFLCTL:
212         case TWL6040_REG_HFRCTL:
213                 priv->dl12_cache[reg - TWL6040_REG_HSLCTL] = value;
214                 break;
215         default:
216                 break;
217         }
218 }
219
220 /*
221  * write twl6040 register cache
222  */
223 static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec,
224                                                 u8 reg, u8 value)
225 {
226         u8 *cache = codec->reg_cache;
227
228         if (reg >= TWL6040_CACHEREGNUM)
229                 return;
230         cache[reg] = value;
231
232         twl6040_update_dl12_cache(codec, reg, value);
233 }
234
235 /*
236  * read from twl6040 hardware register
237  */
238 static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
239                         unsigned int reg)
240 {
241         struct twl6040 *twl6040 = codec->control_data;
242         u8 value;
243
244         if (reg >= TWL6040_CACHEREGNUM)
245                 return -EIO;
246
247         value = twl6040_reg_read(twl6040, reg);
248         twl6040_write_reg_cache(codec, reg, value);
249
250         return value;
251 }
252
253 static bool twl6040_can_write_to_chip(struct snd_soc_codec *codec,
254                                   unsigned int reg)
255 {
256         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
257
258         switch (reg) {
259         case TWL6040_REG_HSLCTL:
260         case TWL6040_REG_HSRCTL:
261         case TWL6040_REG_EARCTL:
262                 /* DL1 path */
263                 return priv->dl1_unmuted;
264         case TWL6040_REG_HFLCTL:
265         case TWL6040_REG_HFRCTL:
266                 return priv->dl2_unmuted;
267         default:
268                 return 1;
269         }
270 }
271
272 /*
273  * write to the twl6040 register space
274  */
275 static int twl6040_write(struct snd_soc_codec *codec,
276                         unsigned int reg, unsigned int value)
277 {
278         struct twl6040 *twl6040 = codec->control_data;
279
280         if (reg >= TWL6040_CACHEREGNUM)
281                 return -EIO;
282
283         twl6040_write_reg_cache(codec, reg, value);
284         if (twl6040_can_write_to_chip(codec, reg))
285                 return twl6040_reg_write(twl6040, reg, value);
286         else
287                 return 0;
288 }
289
290 static void twl6040_init_chip(struct snd_soc_codec *codec)
291 {
292         struct twl6040 *twl6040 = codec->control_data;
293         u8 val;
294
295         /* Update reg_cache: ASICREV, and TRIM values */
296         val = twl6040_get_revid(twl6040);
297         twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val);
298
299         twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM1);
300         twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM2);
301         twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM3);
302         twl6040_read_reg_volatile(codec, TWL6040_REG_HSOTRIM);
303         twl6040_read_reg_volatile(codec, TWL6040_REG_HFOTRIM);
304
305         /* Change chip defaults */
306         /* No imput selected for microphone amplifiers */
307         twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18);
308         twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18);
309
310         /*
311          * We need to lower the default gain values, so the ramp code
312          * can work correctly for the first playback.
313          * This reduces the pop noise heard at the first playback.
314          */
315         twl6040_write_reg_cache(codec, TWL6040_REG_HSGAIN, 0xff);
316         twl6040_write_reg_cache(codec, TWL6040_REG_EARCTL, 0x1e);
317         twl6040_write_reg_cache(codec, TWL6040_REG_HFLGAIN, 0x1d);
318         twl6040_write_reg_cache(codec, TWL6040_REG_HFRGAIN, 0x1d);
319         twl6040_write_reg_cache(codec, TWL6040_REG_LINEGAIN, 0);
320 }
321
322 /* set headset dac and driver power mode */
323 static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
324 {
325         int hslctl, hsrctl;
326         int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE;
327
328         hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
329         hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
330
331         if (high_perf) {
332                 hslctl &= ~mask;
333                 hsrctl &= ~mask;
334         } else {
335                 hslctl |= mask;
336                 hsrctl |= mask;
337         }
338
339         twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
340         twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
341
342         return 0;
343 }
344
345 static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
346                         struct snd_kcontrol *kcontrol, int event)
347 {
348         struct snd_soc_codec *codec = w->codec;
349         u8 hslctl, hsrctl;
350
351         /*
352          * Workaround for Headset DC offset caused pop noise:
353          * Both HS DAC need to be turned on (before the HS driver) and off at
354          * the same time.
355          */
356         hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
357         hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
358         if (SND_SOC_DAPM_EVENT_ON(event)) {
359                 hslctl |= TWL6040_HSDACENA;
360                 hsrctl |= TWL6040_HSDACENA;
361         } else {
362                 hslctl &= ~TWL6040_HSDACENA;
363                 hsrctl &= ~TWL6040_HSDACENA;
364         }
365         twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
366         twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
367
368         msleep(1);
369         return 0;
370 }
371
372 static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
373                         struct snd_kcontrol *kcontrol, int event)
374 {
375         struct snd_soc_codec *codec = w->codec;
376         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
377         int ret = 0;
378
379         if (SND_SOC_DAPM_EVENT_ON(event)) {
380                 /* Earphone doesn't support low power mode */
381                 priv->hs_power_mode_locked = 1;
382                 ret = headset_power_mode(codec, 1);
383         } else {
384                 priv->hs_power_mode_locked = 0;
385                 ret = headset_power_mode(codec, priv->hs_power_mode);
386         }
387
388         msleep(1);
389
390         return ret;
391 }
392
393 static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
394                                    struct snd_soc_jack *jack, int report)
395 {
396         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
397         int status;
398
399         mutex_lock(&priv->mutex);
400
401         /* Sync status */
402         status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS);
403         if (status & TWL6040_PLUGCOMP)
404                 snd_soc_jack_report(jack, report, report);
405         else
406                 snd_soc_jack_report(jack, 0, report);
407
408         mutex_unlock(&priv->mutex);
409 }
410
411 void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
412                                 struct snd_soc_jack *jack, int report)
413 {
414         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
415         struct twl6040_jack_data *hs_jack = &priv->hs_jack;
416
417         hs_jack->jack = jack;
418         hs_jack->report = report;
419
420         twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
421 }
422 EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
423
424 static void twl6040_accessory_work(struct work_struct *work)
425 {
426         struct twl6040_data *priv = container_of(work,
427                                         struct twl6040_data, hs_jack.work.work);
428         struct snd_soc_codec *codec = priv->codec;
429         struct twl6040_jack_data *hs_jack = &priv->hs_jack;
430
431         twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
432 }
433
434 /* audio interrupt handler */
435 static irqreturn_t twl6040_audio_handler(int irq, void *data)
436 {
437         struct snd_soc_codec *codec = data;
438         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
439
440         queue_delayed_work(system_power_efficient_wq,
441                            &priv->hs_jack.work, msecs_to_jiffies(200));
442
443         return IRQ_HANDLED;
444 }
445
446 static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol,
447         struct snd_ctl_elem_value *ucontrol)
448 {
449         struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
450         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
451         unsigned int val;
452
453         /* Do not allow changes while Input/FF efect is running */
454         val = twl6040_read_reg_volatile(codec, e->reg);
455         if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL))
456                 return -EBUSY;
457
458         return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
459 }
460
461 /*
462  * MICATT volume control:
463  * from -6 to 0 dB in 6 dB steps
464  */
465 static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
466
467 /*
468  * MICGAIN volume control:
469  * from 6 to 30 dB in 6 dB steps
470  */
471 static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0);
472
473 /*
474  * AFMGAIN volume control:
475  * from -18 to 24 dB in 6 dB steps
476  */
477 static DECLARE_TLV_DB_SCALE(afm_amp_tlv, -1800, 600, 0);
478
479 /*
480  * HSGAIN volume control:
481  * from -30 to 0 dB in 2 dB steps
482  */
483 static DECLARE_TLV_DB_SCALE(hs_tlv, -3000, 200, 0);
484
485 /*
486  * HFGAIN volume control:
487  * from -52 to 6 dB in 2 dB steps
488  */
489 static DECLARE_TLV_DB_SCALE(hf_tlv, -5200, 200, 0);
490
491 /*
492  * EPGAIN volume control:
493  * from -24 to 6 dB in 2 dB steps
494  */
495 static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0);
496
497 /* Left analog microphone selection */
498 static const char *twl6040_amicl_texts[] =
499         {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"};
500
501 /* Right analog microphone selection */
502 static const char *twl6040_amicr_texts[] =
503         {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
504
505 static const struct soc_enum twl6040_enum[] = {
506         SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 4, twl6040_amicl_texts),
507         SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 4, twl6040_amicr_texts),
508 };
509
510 static const char *twl6040_hs_texts[] = {
511         "Off", "HS DAC", "Line-In amp"
512 };
513
514 static const struct soc_enum twl6040_hs_enum[] = {
515         SOC_ENUM_SINGLE(TWL6040_REG_HSLCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
516                         twl6040_hs_texts),
517         SOC_ENUM_SINGLE(TWL6040_REG_HSRCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
518                         twl6040_hs_texts),
519 };
520
521 static const char *twl6040_hf_texts[] = {
522         "Off", "HF DAC", "Line-In amp"
523 };
524
525 static const struct soc_enum twl6040_hf_enum[] = {
526         SOC_ENUM_SINGLE(TWL6040_REG_HFLCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
527                         twl6040_hf_texts),
528         SOC_ENUM_SINGLE(TWL6040_REG_HFRCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
529                         twl6040_hf_texts),
530 };
531
532 static const char *twl6040_vibrapath_texts[] = {
533         "Input FF", "Audio PDM"
534 };
535
536 static const struct soc_enum twl6040_vibra_enum[] = {
537         SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLL, 1,
538                         ARRAY_SIZE(twl6040_vibrapath_texts),
539                         twl6040_vibrapath_texts),
540         SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLR, 1,
541                         ARRAY_SIZE(twl6040_vibrapath_texts),
542                         twl6040_vibrapath_texts),
543 };
544
545 static const struct snd_kcontrol_new amicl_control =
546         SOC_DAPM_ENUM("Route", twl6040_enum[0]);
547
548 static const struct snd_kcontrol_new amicr_control =
549         SOC_DAPM_ENUM("Route", twl6040_enum[1]);
550
551 /* Headset DAC playback switches */
552 static const struct snd_kcontrol_new hsl_mux_controls =
553         SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]);
554
555 static const struct snd_kcontrol_new hsr_mux_controls =
556         SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]);
557
558 /* Handsfree DAC playback switches */
559 static const struct snd_kcontrol_new hfl_mux_controls =
560         SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]);
561
562 static const struct snd_kcontrol_new hfr_mux_controls =
563         SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
564
565 static const struct snd_kcontrol_new ep_path_enable_control =
566         SOC_DAPM_SINGLE_VIRT("Switch", 1);
567
568 static const struct snd_kcontrol_new auxl_switch_control =
569         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 6, 1, 0);
570
571 static const struct snd_kcontrol_new auxr_switch_control =
572         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 6, 1, 0);
573
574 /* Vibra playback switches */
575 static const struct snd_kcontrol_new vibral_mux_controls =
576         SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[0],
577                 snd_soc_dapm_get_enum_double,
578                 twl6040_soc_dapm_put_vibra_enum);
579
580 static const struct snd_kcontrol_new vibrar_mux_controls =
581         SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[1],
582                 snd_soc_dapm_get_enum_double,
583                 twl6040_soc_dapm_put_vibra_enum);
584
585 /* Headset power mode */
586 static const char *twl6040_power_mode_texts[] = {
587         "Low-Power", "High-Performance",
588 };
589
590 static const struct soc_enum twl6040_power_mode_enum =
591         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl6040_power_mode_texts),
592                         twl6040_power_mode_texts);
593
594 static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
595         struct snd_ctl_elem_value *ucontrol)
596 {
597         struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
598         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
599
600         ucontrol->value.enumerated.item[0] = priv->hs_power_mode;
601
602         return 0;
603 }
604
605 static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
606         struct snd_ctl_elem_value *ucontrol)
607 {
608         struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
609         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
610         int high_perf = ucontrol->value.enumerated.item[0];
611         int ret = 0;
612
613         if (!priv->hs_power_mode_locked)
614                 ret = headset_power_mode(codec, high_perf);
615
616         if (!ret)
617                 priv->hs_power_mode = high_perf;
618
619         return ret;
620 }
621
622 static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol,
623         struct snd_ctl_elem_value *ucontrol)
624 {
625         struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
626         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
627
628         ucontrol->value.enumerated.item[0] = priv->pll_power_mode;
629
630         return 0;
631 }
632
633 static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol,
634         struct snd_ctl_elem_value *ucontrol)
635 {
636         struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
637         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
638
639         priv->pll_power_mode = ucontrol->value.enumerated.item[0];
640
641         return 0;
642 }
643
644 int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
645 {
646         struct snd_soc_dapm_context *dapm = &codec->dapm;
647
648         if (snd_soc_dapm_get_pin_status(dapm, "EP"))
649                 return -1; /* -1dB */
650
651         if (snd_soc_dapm_get_pin_status(dapm, "HSOR") ||
652                 snd_soc_dapm_get_pin_status(dapm, "HSOL")) {
653
654                 u8 val = snd_soc_read(codec, TWL6040_REG_HSLCTL);
655                 if (val & TWL6040_HSDACMODE)
656                         /* HSDACL in LP mode */
657                         return -8; /* -8dB */
658                 else
659                         /* HSDACL in HP mode */
660                         return -1; /* -1dB */
661         }
662         return 0; /* 0dB */
663 }
664 EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain);
665
666 int twl6040_get_clk_id(struct snd_soc_codec *codec)
667 {
668         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
669
670         return priv->pll_power_mode;
671 }
672 EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
673
674 int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
675 {
676         if (unlikely(trim >= TWL6040_TRIM_INVAL))
677                 return -EINVAL;
678
679         return twl6040_read_reg_cache(codec, TWL6040_REG_TRIM1 + trim);
680 }
681 EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
682
683 int twl6040_get_hs_step_size(struct snd_soc_codec *codec)
684 {
685         struct twl6040 *twl6040 = codec->control_data;
686
687         if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3)
688                 /* For ES under ES_1.3 HS step is 2 mV */
689                 return 2;
690         else
691                 /* For ES_1.3 HS step is 1 mV */
692                 return 1;
693 }
694 EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size);
695
696 static const struct snd_kcontrol_new twl6040_snd_controls[] = {
697         /* Capture gains */
698         SOC_DOUBLE_TLV("Capture Preamplifier Volume",
699                 TWL6040_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv),
700         SOC_DOUBLE_TLV("Capture Volume",
701                 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
702
703         /* AFM gains */
704         SOC_DOUBLE_TLV("Aux FM Volume",
705                 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
706
707         /* Playback gains */
708         SOC_DOUBLE_TLV("Headset Playback Volume",
709                 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
710         SOC_DOUBLE_R_TLV("Handsfree Playback Volume",
711                 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
712         SOC_SINGLE_TLV("Earphone Playback Volume",
713                 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
714
715         SOC_ENUM_EXT("Headset Power Mode", twl6040_power_mode_enum,
716                 twl6040_headset_power_get_enum,
717                 twl6040_headset_power_put_enum),
718
719         SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum,
720                 twl6040_pll_get_enum, twl6040_pll_put_enum),
721 };
722
723 static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
724         /* Inputs */
725         SND_SOC_DAPM_INPUT("MAINMIC"),
726         SND_SOC_DAPM_INPUT("HSMIC"),
727         SND_SOC_DAPM_INPUT("SUBMIC"),
728         SND_SOC_DAPM_INPUT("AFML"),
729         SND_SOC_DAPM_INPUT("AFMR"),
730
731         /* Outputs */
732         SND_SOC_DAPM_OUTPUT("HSOL"),
733         SND_SOC_DAPM_OUTPUT("HSOR"),
734         SND_SOC_DAPM_OUTPUT("HFL"),
735         SND_SOC_DAPM_OUTPUT("HFR"),
736         SND_SOC_DAPM_OUTPUT("EP"),
737         SND_SOC_DAPM_OUTPUT("AUXL"),
738         SND_SOC_DAPM_OUTPUT("AUXR"),
739         SND_SOC_DAPM_OUTPUT("VIBRAL"),
740         SND_SOC_DAPM_OUTPUT("VIBRAR"),
741
742         /* Analog input muxes for the capture amplifiers */
743         SND_SOC_DAPM_MUX("Analog Left Capture Route",
744                         SND_SOC_NOPM, 0, 0, &amicl_control),
745         SND_SOC_DAPM_MUX("Analog Right Capture Route",
746                         SND_SOC_NOPM, 0, 0, &amicr_control),
747
748         /* Analog capture PGAs */
749         SND_SOC_DAPM_PGA("MicAmpL",
750                         TWL6040_REG_MICLCTL, 0, 0, NULL, 0),
751         SND_SOC_DAPM_PGA("MicAmpR",
752                         TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
753
754         /* Auxiliary FM PGAs */
755         SND_SOC_DAPM_PGA("AFMAmpL",
756                         TWL6040_REG_MICLCTL, 1, 0, NULL, 0),
757         SND_SOC_DAPM_PGA("AFMAmpR",
758                         TWL6040_REG_MICRCTL, 1, 0, NULL, 0),
759
760         /* ADCs */
761         SND_SOC_DAPM_ADC("ADC Left", NULL, TWL6040_REG_MICLCTL, 2, 0),
762         SND_SOC_DAPM_ADC("ADC Right", NULL, TWL6040_REG_MICRCTL, 2, 0),
763
764         /* Microphone bias */
765         SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
766                             TWL6040_REG_AMICBCTL, 0, 0, NULL, 0),
767         SND_SOC_DAPM_SUPPLY("Main Mic Bias",
768                             TWL6040_REG_AMICBCTL, 4, 0, NULL, 0),
769         SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias",
770                             TWL6040_REG_DMICBCTL, 0, 0, NULL, 0),
771         SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias",
772                             TWL6040_REG_DMICBCTL, 4, 0, NULL, 0),
773
774         /* DACs */
775         SND_SOC_DAPM_DAC("HSDAC Left", NULL, SND_SOC_NOPM, 0, 0),
776         SND_SOC_DAPM_DAC("HSDAC Right", NULL, SND_SOC_NOPM, 0, 0),
777         SND_SOC_DAPM_DAC("HFDAC Left", NULL, TWL6040_REG_HFLCTL, 0, 0),
778         SND_SOC_DAPM_DAC("HFDAC Right", NULL, TWL6040_REG_HFRCTL, 0, 0),
779         /* Virtual DAC for vibra path (DL4 channel) */
780         SND_SOC_DAPM_DAC("VIBRA DAC", NULL, SND_SOC_NOPM, 0, 0),
781
782         SND_SOC_DAPM_MUX("Handsfree Left Playback",
783                         SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
784         SND_SOC_DAPM_MUX("Handsfree Right Playback",
785                         SND_SOC_NOPM, 0, 0, &hfr_mux_controls),
786         /* Analog playback Muxes */
787         SND_SOC_DAPM_MUX("Headset Left Playback",
788                         SND_SOC_NOPM, 0, 0, &hsl_mux_controls),
789         SND_SOC_DAPM_MUX("Headset Right Playback",
790                         SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
791
792         SND_SOC_DAPM_MUX("Vibra Left Playback", SND_SOC_NOPM, 0, 0,
793                         &vibral_mux_controls),
794         SND_SOC_DAPM_MUX("Vibra Right Playback", SND_SOC_NOPM, 0, 0,
795                         &vibrar_mux_controls),
796
797         SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0,
798                         &ep_path_enable_control),
799         SND_SOC_DAPM_SWITCH("AUXL Playback", SND_SOC_NOPM, 0, 0,
800                         &auxl_switch_control),
801         SND_SOC_DAPM_SWITCH("AUXR Playback", SND_SOC_NOPM, 0, 0,
802                         &auxr_switch_control),
803
804         /* Analog playback drivers */
805         SND_SOC_DAPM_OUT_DRV("HF Left Driver",
806                         TWL6040_REG_HFLCTL, 4, 0, NULL, 0),
807         SND_SOC_DAPM_OUT_DRV("HF Right Driver",
808                         TWL6040_REG_HFRCTL, 4, 0, NULL, 0),
809         SND_SOC_DAPM_OUT_DRV("HS Left Driver",
810                         TWL6040_REG_HSLCTL, 2, 0, NULL, 0),
811         SND_SOC_DAPM_OUT_DRV("HS Right Driver",
812                         TWL6040_REG_HSRCTL, 2, 0, NULL, 0),
813         SND_SOC_DAPM_OUT_DRV_E("Earphone Driver",
814                         TWL6040_REG_EARCTL, 0, 0, NULL, 0,
815                         twl6040_ep_drv_event,
816                         SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
817         SND_SOC_DAPM_OUT_DRV("Vibra Left Driver",
818                         TWL6040_REG_VIBCTLL, 0, 0, NULL, 0),
819         SND_SOC_DAPM_OUT_DRV("Vibra Right Driver",
820                         TWL6040_REG_VIBCTLR, 0, 0, NULL, 0),
821
822         SND_SOC_DAPM_SUPPLY("Vibra Left Control", TWL6040_REG_VIBCTLL, 2, 0,
823                             NULL, 0),
824         SND_SOC_DAPM_SUPPLY("Vibra Right Control", TWL6040_REG_VIBCTLR, 2, 0,
825                             NULL, 0),
826         SND_SOC_DAPM_SUPPLY_S("HSDAC Power", 1, SND_SOC_NOPM, 0, 0,
827                               twl6040_hs_dac_event,
828                               SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
829
830         /* Analog playback PGAs */
831         SND_SOC_DAPM_PGA("HF Left PGA",
832                         TWL6040_REG_HFLCTL, 1, 0, NULL, 0),
833         SND_SOC_DAPM_PGA("HF Right PGA",
834                         TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
835
836 };
837
838 static const struct snd_soc_dapm_route intercon[] = {
839         /* Stream -> DAC mapping */
840         {"HSDAC Left", NULL, "Legacy Playback"},
841         {"HSDAC Left", NULL, "Headset Playback"},
842         {"HSDAC Right", NULL, "Legacy Playback"},
843         {"HSDAC Right", NULL, "Headset Playback"},
844
845         {"HFDAC Left", NULL, "Legacy Playback"},
846         {"HFDAC Left", NULL, "Handsfree Playback"},
847         {"HFDAC Right", NULL, "Legacy Playback"},
848         {"HFDAC Right", NULL, "Handsfree Playback"},
849
850         {"VIBRA DAC", NULL, "Legacy Playback"},
851         {"VIBRA DAC", NULL, "Vibra Playback"},
852
853         /* ADC -> Stream mapping */
854         {"Legacy Capture" , NULL, "ADC Left"},
855         {"Capture", NULL, "ADC Left"},
856         {"Legacy Capture", NULL, "ADC Right"},
857         {"Capture" , NULL, "ADC Right"},
858
859         /* Capture path */
860         {"Analog Left Capture Route", "Headset Mic", "HSMIC"},
861         {"Analog Left Capture Route", "Main Mic", "MAINMIC"},
862         {"Analog Left Capture Route", "Aux/FM Left", "AFML"},
863
864         {"Analog Right Capture Route", "Headset Mic", "HSMIC"},
865         {"Analog Right Capture Route", "Sub Mic", "SUBMIC"},
866         {"Analog Right Capture Route", "Aux/FM Right", "AFMR"},
867
868         {"MicAmpL", NULL, "Analog Left Capture Route"},
869         {"MicAmpR", NULL, "Analog Right Capture Route"},
870
871         {"ADC Left", NULL, "MicAmpL"},
872         {"ADC Right", NULL, "MicAmpR"},
873
874         /* AFM path */
875         {"AFMAmpL", NULL, "AFML"},
876         {"AFMAmpR", NULL, "AFMR"},
877
878         {"HSDAC Left", NULL, "HSDAC Power"},
879         {"HSDAC Right", NULL, "HSDAC Power"},
880
881         {"Headset Left Playback", "HS DAC", "HSDAC Left"},
882         {"Headset Left Playback", "Line-In amp", "AFMAmpL"},
883
884         {"Headset Right Playback", "HS DAC", "HSDAC Right"},
885         {"Headset Right Playback", "Line-In amp", "AFMAmpR"},
886
887         {"HS Left Driver", NULL, "Headset Left Playback"},
888         {"HS Right Driver", NULL, "Headset Right Playback"},
889
890         {"HSOL", NULL, "HS Left Driver"},
891         {"HSOR", NULL, "HS Right Driver"},
892
893         /* Earphone playback path */
894         {"Earphone Playback", "Switch", "HSDAC Left"},
895         {"Earphone Driver", NULL, "Earphone Playback"},
896         {"EP", NULL, "Earphone Driver"},
897
898         {"Handsfree Left Playback", "HF DAC", "HFDAC Left"},
899         {"Handsfree Left Playback", "Line-In amp", "AFMAmpL"},
900
901         {"Handsfree Right Playback", "HF DAC", "HFDAC Right"},
902         {"Handsfree Right Playback", "Line-In amp", "AFMAmpR"},
903
904         {"HF Left PGA", NULL, "Handsfree Left Playback"},
905         {"HF Right PGA", NULL, "Handsfree Right Playback"},
906
907         {"HF Left Driver", NULL, "HF Left PGA"},
908         {"HF Right Driver", NULL, "HF Right PGA"},
909
910         {"HFL", NULL, "HF Left Driver"},
911         {"HFR", NULL, "HF Right Driver"},
912
913         {"AUXL Playback", "Switch", "HF Left PGA"},
914         {"AUXR Playback", "Switch", "HF Right PGA"},
915
916         {"AUXL", NULL, "AUXL Playback"},
917         {"AUXR", NULL, "AUXR Playback"},
918
919         /* Vibrator paths */
920         {"Vibra Left Playback", "Audio PDM", "VIBRA DAC"},
921         {"Vibra Right Playback", "Audio PDM", "VIBRA DAC"},
922
923         {"Vibra Left Driver", NULL, "Vibra Left Playback"},
924         {"Vibra Right Driver", NULL, "Vibra Right Playback"},
925         {"Vibra Left Driver", NULL, "Vibra Left Control"},
926         {"Vibra Right Driver", NULL, "Vibra Right Control"},
927
928         {"VIBRAL", NULL, "Vibra Left Driver"},
929         {"VIBRAR", NULL, "Vibra Right Driver"},
930 };
931
932 static int twl6040_set_bias_level(struct snd_soc_codec *codec,
933                                 enum snd_soc_bias_level level)
934 {
935         struct twl6040 *twl6040 = codec->control_data;
936         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
937         int ret;
938
939         switch (level) {
940         case SND_SOC_BIAS_ON:
941                 break;
942         case SND_SOC_BIAS_PREPARE:
943                 break;
944         case SND_SOC_BIAS_STANDBY:
945                 if (priv->codec_powered)
946                         break;
947
948                 ret = twl6040_power(twl6040, 1);
949                 if (ret)
950                         return ret;
951
952                 priv->codec_powered = 1;
953
954                 /* Set external boost GPO */
955                 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
956                 break;
957         case SND_SOC_BIAS_OFF:
958                 if (!priv->codec_powered)
959                         break;
960
961                 twl6040_power(twl6040, 0);
962                 priv->codec_powered = 0;
963                 break;
964         }
965
966         codec->dapm.bias_level = level;
967
968         return 0;
969 }
970
971 static int twl6040_startup(struct snd_pcm_substream *substream,
972                         struct snd_soc_dai *dai)
973 {
974         struct snd_soc_codec *codec = dai->codec;
975         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
976
977         snd_pcm_hw_constraint_list(substream->runtime, 0,
978                                 SNDRV_PCM_HW_PARAM_RATE,
979                                 &sysclk_constraints[priv->pll_power_mode]);
980
981         return 0;
982 }
983
984 static int twl6040_hw_params(struct snd_pcm_substream *substream,
985                         struct snd_pcm_hw_params *params,
986                         struct snd_soc_dai *dai)
987 {
988         struct snd_soc_codec *codec = dai->codec;
989         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
990         int rate;
991
992         rate = params_rate(params);
993         switch (rate) {
994         case 11250:
995         case 22500:
996         case 44100:
997         case 88200:
998                 /* These rates are not supported when HPPLL is in use */
999                 if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) {
1000                         dev_err(codec->dev, "HPPLL does not support rate %d\n",
1001                                 rate);
1002                         return -EINVAL;
1003                 }
1004                 priv->sysclk = 17640000;
1005                 break;
1006         case 8000:
1007         case 16000:
1008         case 32000:
1009         case 48000:
1010         case 96000:
1011                 priv->sysclk = 19200000;
1012                 break;
1013         default:
1014                 dev_err(codec->dev, "unsupported rate %d\n", rate);
1015                 return -EINVAL;
1016         }
1017
1018         return 0;
1019 }
1020
1021 static int twl6040_prepare(struct snd_pcm_substream *substream,
1022                         struct snd_soc_dai *dai)
1023 {
1024         struct snd_soc_codec *codec = dai->codec;
1025         struct twl6040 *twl6040 = codec->control_data;
1026         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1027         int ret;
1028
1029         if (!priv->sysclk) {
1030                 dev_err(codec->dev,
1031                         "no mclk configured, call set_sysclk() on init\n");
1032                 return -EINVAL;
1033         }
1034
1035         ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk);
1036         if (ret) {
1037                 dev_err(codec->dev, "Can not set PLL (%d)\n", ret);
1038                 return -EPERM;
1039         }
1040
1041         return 0;
1042 }
1043
1044 static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1045                 int clk_id, unsigned int freq, int dir)
1046 {
1047         struct snd_soc_codec *codec = codec_dai->codec;
1048         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1049
1050         switch (clk_id) {
1051         case TWL6040_SYSCLK_SEL_LPPLL:
1052         case TWL6040_SYSCLK_SEL_HPPLL:
1053                 priv->pll = clk_id;
1054                 priv->clk_in = freq;
1055                 break;
1056         default:
1057                 dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
1058                 return -EINVAL;
1059         }
1060
1061         return 0;
1062 }
1063
1064 static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id,
1065                              int mute)
1066 {
1067         struct twl6040 *twl6040 = codec->control_data;
1068         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1069         int hslctl, hsrctl, earctl;
1070         int hflctl, hfrctl;
1071
1072         switch (id) {
1073         case TWL6040_DAI_DL1:
1074                 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
1075                 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
1076                 earctl = twl6040_read_reg_cache(codec, TWL6040_REG_EARCTL);
1077
1078                 if (mute) {
1079                         /* Power down drivers and DACs */
1080                         earctl &= ~0x01;
1081                         hslctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA);
1082                         hsrctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA);
1083
1084                 }
1085
1086                 twl6040_reg_write(twl6040, TWL6040_REG_EARCTL, earctl);
1087                 twl6040_reg_write(twl6040, TWL6040_REG_HSLCTL, hslctl);
1088                 twl6040_reg_write(twl6040, TWL6040_REG_HSRCTL, hsrctl);
1089                 priv->dl1_unmuted = !mute;
1090                 break;
1091         case TWL6040_DAI_DL2:
1092                 hflctl = twl6040_read_reg_cache(codec, TWL6040_REG_HFLCTL);
1093                 hfrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HFRCTL);
1094
1095                 if (mute) {
1096                         /* Power down drivers and DACs */
1097                         hflctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA |
1098                                     TWL6040_HFDRVENA);
1099                         hfrctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA |
1100                                     TWL6040_HFDRVENA);
1101                 }
1102
1103                 twl6040_reg_write(twl6040, TWL6040_REG_HFLCTL, hflctl);
1104                 twl6040_reg_write(twl6040, TWL6040_REG_HFRCTL, hfrctl);
1105                 priv->dl2_unmuted = !mute;
1106                 break;
1107         default:
1108                 break;
1109         }
1110 }
1111
1112 static int twl6040_digital_mute(struct snd_soc_dai *dai, int mute)
1113 {
1114         switch (dai->id) {
1115         case TWL6040_DAI_LEGACY:
1116                 twl6040_mute_path(dai->codec, TWL6040_DAI_DL1, mute);
1117                 twl6040_mute_path(dai->codec, TWL6040_DAI_DL2, mute);
1118                 break;
1119         case TWL6040_DAI_DL1:
1120         case TWL6040_DAI_DL2:
1121                 twl6040_mute_path(dai->codec, dai->id, mute);
1122                 break;
1123         default:
1124                 break;
1125         }
1126
1127         return 0;
1128 }
1129
1130 static const struct snd_soc_dai_ops twl6040_dai_ops = {
1131         .startup        = twl6040_startup,
1132         .hw_params      = twl6040_hw_params,
1133         .prepare        = twl6040_prepare,
1134         .set_sysclk     = twl6040_set_dai_sysclk,
1135         .digital_mute   = twl6040_digital_mute,
1136 };
1137
1138 static struct snd_soc_dai_driver twl6040_dai[] = {
1139 {
1140         .name = "twl6040-legacy",
1141         .id = TWL6040_DAI_LEGACY,
1142         .playback = {
1143                 .stream_name = "Legacy Playback",
1144                 .channels_min = 1,
1145                 .channels_max = 5,
1146                 .rates = TWL6040_RATES,
1147                 .formats = TWL6040_FORMATS,
1148         },
1149         .capture = {
1150                 .stream_name = "Legacy Capture",
1151                 .channels_min = 1,
1152                 .channels_max = 2,
1153                 .rates = TWL6040_RATES,
1154                 .formats = TWL6040_FORMATS,
1155         },
1156         .ops = &twl6040_dai_ops,
1157 },
1158 {
1159         .name = "twl6040-ul",
1160         .id = TWL6040_DAI_UL,
1161         .capture = {
1162                 .stream_name = "Capture",
1163                 .channels_min = 1,
1164                 .channels_max = 2,
1165                 .rates = TWL6040_RATES,
1166                 .formats = TWL6040_FORMATS,
1167         },
1168         .ops = &twl6040_dai_ops,
1169 },
1170 {
1171         .name = "twl6040-dl1",
1172         .id = TWL6040_DAI_DL1,
1173         .playback = {
1174                 .stream_name = "Headset Playback",
1175                 .channels_min = 1,
1176                 .channels_max = 2,
1177                 .rates = TWL6040_RATES,
1178                 .formats = TWL6040_FORMATS,
1179         },
1180         .ops = &twl6040_dai_ops,
1181 },
1182 {
1183         .name = "twl6040-dl2",
1184         .id = TWL6040_DAI_DL2,
1185         .playback = {
1186                 .stream_name = "Handsfree Playback",
1187                 .channels_min = 1,
1188                 .channels_max = 2,
1189                 .rates = TWL6040_RATES,
1190                 .formats = TWL6040_FORMATS,
1191         },
1192         .ops = &twl6040_dai_ops,
1193 },
1194 {
1195         .name = "twl6040-vib",
1196         .id = TWL6040_DAI_VIB,
1197         .playback = {
1198                 .stream_name = "Vibra Playback",
1199                 .channels_min = 1,
1200                 .channels_max = 1,
1201                 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1202                 .formats = TWL6040_FORMATS,
1203         },
1204         .ops = &twl6040_dai_ops,
1205 },
1206 };
1207
1208 #ifdef CONFIG_PM
1209 static int twl6040_suspend(struct snd_soc_codec *codec)
1210 {
1211         twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1212
1213         return 0;
1214 }
1215
1216 static int twl6040_resume(struct snd_soc_codec *codec)
1217 {
1218         twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1219
1220         return 0;
1221 }
1222 #else
1223 #define twl6040_suspend NULL
1224 #define twl6040_resume NULL
1225 #endif
1226
1227 static int twl6040_probe(struct snd_soc_codec *codec)
1228 {
1229         struct twl6040_data *priv;
1230         struct platform_device *pdev = container_of(codec->dev,
1231                                                    struct platform_device, dev);
1232         int ret = 0;
1233
1234         priv = devm_kzalloc(codec->dev, sizeof(*priv), GFP_KERNEL);
1235         if (priv == NULL)
1236                 return -ENOMEM;
1237
1238         snd_soc_codec_set_drvdata(codec, priv);
1239
1240         priv->codec = codec;
1241         codec->control_data = dev_get_drvdata(codec->dev->parent);
1242
1243         priv->plug_irq = platform_get_irq(pdev, 0);
1244         if (priv->plug_irq < 0) {
1245                 dev_err(codec->dev, "invalid irq\n");
1246                 return -EINVAL;
1247         }
1248
1249         INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);
1250
1251         mutex_init(&priv->mutex);
1252
1253         ret = request_threaded_irq(priv->plug_irq, NULL,
1254                                         twl6040_audio_handler, IRQF_NO_SUSPEND,
1255                                         "twl6040_irq_plug", codec);
1256         if (ret) {
1257                 dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret);
1258                 return ret;
1259         }
1260
1261         twl6040_init_chip(codec);
1262
1263         /* power on device */
1264         return twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1265 }
1266
1267 static int twl6040_remove(struct snd_soc_codec *codec)
1268 {
1269         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1270
1271         free_irq(priv->plug_irq, codec);
1272         twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1273
1274         return 0;
1275 }
1276
1277 static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1278         .probe = twl6040_probe,
1279         .remove = twl6040_remove,
1280         .suspend = twl6040_suspend,
1281         .resume = twl6040_resume,
1282         .read = twl6040_read_reg_cache,
1283         .write = twl6040_write,
1284         .set_bias_level = twl6040_set_bias_level,
1285         .reg_cache_size = ARRAY_SIZE(twl6040_reg),
1286         .reg_word_size = sizeof(u8),
1287         .reg_cache_default = twl6040_reg,
1288         .ignore_pmdown_time = true,
1289
1290         .controls = twl6040_snd_controls,
1291         .num_controls = ARRAY_SIZE(twl6040_snd_controls),
1292         .dapm_widgets = twl6040_dapm_widgets,
1293         .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
1294         .dapm_routes = intercon,
1295         .num_dapm_routes = ARRAY_SIZE(intercon),
1296 };
1297
1298 static int twl6040_codec_probe(struct platform_device *pdev)
1299 {
1300         return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040,
1301                                       twl6040_dai, ARRAY_SIZE(twl6040_dai));
1302 }
1303
1304 static int twl6040_codec_remove(struct platform_device *pdev)
1305 {
1306         snd_soc_unregister_codec(&pdev->dev);
1307         return 0;
1308 }
1309
1310 static struct platform_driver twl6040_codec_driver = {
1311         .driver = {
1312                 .name = "twl6040-codec",
1313                 .owner = THIS_MODULE,
1314         },
1315         .probe = twl6040_codec_probe,
1316         .remove = twl6040_codec_remove,
1317 };
1318
1319 module_platform_driver(twl6040_codec_driver);
1320
1321 MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
1322 MODULE_AUTHOR("Misael Lopez Cruz");
1323 MODULE_LICENSE("GPL");