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