- patches.arch/x86_mce_intel_decode_physical_address.patch:
[linux-flexiantxendom0-3.2.10.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/i2c.h>
28 #include <linux/gpio.h>
29 #include <linux/platform_device.h>
30 #include <linux/slab.h>
31 #include <linux/i2c/twl.h>
32
33 #include <sound/core.h>
34 #include <sound/pcm.h>
35 #include <sound/pcm_params.h>
36 #include <sound/soc.h>
37 #include <sound/soc-dapm.h>
38 #include <sound/initval.h>
39 #include <sound/tlv.h>
40
41 #include "twl6040.h"
42
43 #define TWL6040_RATES    (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
44 #define TWL6040_FORMATS  (SNDRV_PCM_FMTBIT_S32_LE)
45
46 /* codec private data */
47 struct twl6040_data {
48         struct snd_soc_codec codec;
49         int audpwron;
50         int naudint;
51         int codec_powered;
52         int pll;
53         int non_lp;
54         unsigned int sysclk;
55         struct snd_pcm_hw_constraint_list *sysclk_constraints;
56         struct completion ready;
57 };
58
59 /*
60  * twl6040 register cache & default register settings
61  */
62 static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
63         0x00, /* not used               0x00    */
64         0x4B, /* TWL6040_ASICID (ro)    0x01    */
65         0x00, /* TWL6040_ASICREV (ro)   0x02    */
66         0x00, /* TWL6040_INTID          0x03    */
67         0x00, /* TWL6040_INTMR          0x04    */
68         0x00, /* TWL6040_NCPCTRL        0x05    */
69         0x00, /* TWL6040_LDOCTL         0x06    */
70         0x60, /* TWL6040_HPPLLCTL       0x07    */
71         0x00, /* TWL6040_LPPLLCTL       0x08    */
72         0x4A, /* TWL6040_LPPLLDIV       0x09    */
73         0x00, /* TWL6040_AMICBCTL       0x0A    */
74         0x00, /* TWL6040_DMICBCTL       0x0B    */
75         0x18, /* TWL6040_MICLCTL        0x0C    - No input selected on Left Mic */
76         0x18, /* TWL6040_MICRCTL        0x0D    - No input selected on Right Mic */
77         0x00, /* TWL6040_MICGAIN        0x0E    */
78         0x1B, /* TWL6040_LINEGAIN       0x0F    */
79         0x00, /* TWL6040_HSLCTL         0x10    */
80         0x00, /* TWL6040_HSRCTL         0x11    */
81         0x00, /* TWL6040_HSGAIN         0x12    */
82         0x00, /* TWL6040_EARCTL         0x13    */
83         0x00, /* TWL6040_HFLCTL         0x14    */
84         0x00, /* TWL6040_HFLGAIN        0x15    */
85         0x00, /* TWL6040_HFRCTL         0x16    */
86         0x00, /* TWL6040_HFRGAIN        0x17    */
87         0x00, /* TWL6040_VIBCTLL        0x18    */
88         0x00, /* TWL6040_VIBDATL        0x19    */
89         0x00, /* TWL6040_VIBCTLR        0x1A    */
90         0x00, /* TWL6040_VIBDATR        0x1B    */
91         0x00, /* TWL6040_HKCTL1         0x1C    */
92         0x00, /* TWL6040_HKCTL2         0x1D    */
93         0x00, /* TWL6040_GPOCTL         0x1E    */
94         0x00, /* TWL6040_ALB            0x1F    */
95         0x00, /* TWL6040_DLB            0x20    */
96         0x00, /* not used               0x21    */
97         0x00, /* not used               0x22    */
98         0x00, /* not used               0x23    */
99         0x00, /* not used               0x24    */
100         0x00, /* not used               0x25    */
101         0x00, /* not used               0x26    */
102         0x00, /* not used               0x27    */
103         0x00, /* TWL6040_TRIM1          0x28    */
104         0x00, /* TWL6040_TRIM2          0x29    */
105         0x00, /* TWL6040_TRIM3          0x2A    */
106         0x00, /* TWL6040_HSOTRIM        0x2B    */
107         0x00, /* TWL6040_HFOTRIM        0x2C    */
108         0x09, /* TWL6040_ACCCTL         0x2D    */
109         0x00, /* TWL6040_STATUS (ro)    0x2E    */
110 };
111
112 /*
113  * twl6040 vio/gnd registers:
114  * registers under vio/gnd supply can be accessed
115  * before the power-up sequence, after NRESPWRON goes high
116  */
117 static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = {
118         TWL6040_REG_ASICID,
119         TWL6040_REG_ASICREV,
120         TWL6040_REG_INTID,
121         TWL6040_REG_INTMR,
122         TWL6040_REG_NCPCTL,
123         TWL6040_REG_LDOCTL,
124         TWL6040_REG_AMICBCTL,
125         TWL6040_REG_DMICBCTL,
126         TWL6040_REG_HKCTL1,
127         TWL6040_REG_HKCTL2,
128         TWL6040_REG_GPOCTL,
129         TWL6040_REG_TRIM1,
130         TWL6040_REG_TRIM2,
131         TWL6040_REG_TRIM3,
132         TWL6040_REG_HSOTRIM,
133         TWL6040_REG_HFOTRIM,
134         TWL6040_REG_ACCCTL,
135         TWL6040_REG_STATUS,
136 };
137
138 /*
139  * twl6040 vdd/vss registers:
140  * registers under vdd/vss supplies can only be accessed
141  * after the power-up sequence
142  */
143 static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
144         TWL6040_REG_HPPLLCTL,
145         TWL6040_REG_LPPLLCTL,
146         TWL6040_REG_LPPLLDIV,
147         TWL6040_REG_MICLCTL,
148         TWL6040_REG_MICRCTL,
149         TWL6040_REG_MICGAIN,
150         TWL6040_REG_LINEGAIN,
151         TWL6040_REG_HSLCTL,
152         TWL6040_REG_HSRCTL,
153         TWL6040_REG_HSGAIN,
154         TWL6040_REG_EARCTL,
155         TWL6040_REG_HFLCTL,
156         TWL6040_REG_HFLGAIN,
157         TWL6040_REG_HFRCTL,
158         TWL6040_REG_HFRGAIN,
159         TWL6040_REG_VIBCTLL,
160         TWL6040_REG_VIBDATL,
161         TWL6040_REG_VIBCTLR,
162         TWL6040_REG_VIBDATR,
163         TWL6040_REG_ALB,
164         TWL6040_REG_DLB,
165 };
166
167 /*
168  * read twl6040 register cache
169  */
170 static inline unsigned int twl6040_read_reg_cache(struct snd_soc_codec *codec,
171                                                 unsigned int reg)
172 {
173         u8 *cache = codec->reg_cache;
174
175         if (reg >= TWL6040_CACHEREGNUM)
176                 return -EIO;
177
178         return cache[reg];
179 }
180
181 /*
182  * write twl6040 register cache
183  */
184 static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec,
185                                                 u8 reg, u8 value)
186 {
187         u8 *cache = codec->reg_cache;
188
189         if (reg >= TWL6040_CACHEREGNUM)
190                 return;
191         cache[reg] = value;
192 }
193
194 /*
195  * read from twl6040 hardware register
196  */
197 static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
198                         unsigned int reg)
199 {
200         u8 value;
201
202         if (reg >= TWL6040_CACHEREGNUM)
203                 return -EIO;
204
205         twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg);
206         twl6040_write_reg_cache(codec, reg, value);
207
208         return value;
209 }
210
211 /*
212  * write to the twl6040 register space
213  */
214 static int twl6040_write(struct snd_soc_codec *codec,
215                         unsigned int reg, unsigned int value)
216 {
217         if (reg >= TWL6040_CACHEREGNUM)
218                 return -EIO;
219
220         twl6040_write_reg_cache(codec, reg, value);
221         return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
222 }
223
224 static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
225 {
226         u8 *cache = codec->reg_cache;
227         int reg, i;
228
229         /* allow registers to be accessed by i2c */
230         twl6040_write(codec, TWL6040_REG_ACCCTL, cache[TWL6040_REG_ACCCTL]);
231
232         for (i = 0; i < TWL6040_VIOREGNUM; i++) {
233                 reg = twl6040_vio_reg[i];
234                 /* skip read-only registers (ASICID, ASICREV, STATUS) */
235                 switch (reg) {
236                 case TWL6040_REG_ASICID:
237                 case TWL6040_REG_ASICREV:
238                 case TWL6040_REG_STATUS:
239                         continue;
240                 default:
241                         break;
242                 }
243                 twl6040_write(codec, reg, cache[reg]);
244         }
245 }
246
247 static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
248 {
249         u8 *cache = codec->reg_cache;
250         int reg, i;
251
252         for (i = 0; i < TWL6040_VDDREGNUM; i++) {
253                 reg = twl6040_vdd_reg[i];
254                 twl6040_write(codec, reg, cache[reg]);
255         }
256 }
257
258 /* twl6040 codec manual power-up sequence */
259 static void twl6040_power_up(struct snd_soc_codec *codec)
260 {
261         u8 ncpctl, ldoctl, lppllctl, accctl;
262
263         ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
264         ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
265         lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
266         accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
267
268         /* enable reference system */
269         ldoctl |= TWL6040_REFENA;
270         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
271         msleep(10);
272         /* enable internal oscillator */
273         ldoctl |= TWL6040_OSCENA;
274         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
275         udelay(10);
276         /* enable high-side ldo */
277         ldoctl |= TWL6040_HSLDOENA;
278         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
279         udelay(244);
280         /* enable negative charge pump */
281         ncpctl |= TWL6040_NCPENA | TWL6040_NCPOPEN;
282         twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
283         udelay(488);
284         /* enable low-side ldo */
285         ldoctl |= TWL6040_LSLDOENA;
286         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
287         udelay(244);
288         /* enable low-power pll */
289         lppllctl |= TWL6040_LPLLENA;
290         twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
291         /* reset state machine */
292         accctl |= TWL6040_RESETSPLIT;
293         twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
294         mdelay(5);
295         accctl &= ~TWL6040_RESETSPLIT;
296         twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
297         /* disable internal oscillator */
298         ldoctl &= ~TWL6040_OSCENA;
299         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
300 }
301
302 /* twl6040 codec manual power-down sequence */
303 static void twl6040_power_down(struct snd_soc_codec *codec)
304 {
305         u8 ncpctl, ldoctl, lppllctl, accctl;
306
307         ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
308         ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
309         lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
310         accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
311
312         /* enable internal oscillator */
313         ldoctl |= TWL6040_OSCENA;
314         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
315         udelay(10);
316         /* disable low-power pll */
317         lppllctl &= ~TWL6040_LPLLENA;
318         twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
319         /* disable low-side ldo */
320         ldoctl &= ~TWL6040_LSLDOENA;
321         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
322         udelay(244);
323         /* disable negative charge pump */
324         ncpctl &= ~(TWL6040_NCPENA | TWL6040_NCPOPEN);
325         twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
326         udelay(488);
327         /* disable high-side ldo */
328         ldoctl &= ~TWL6040_HSLDOENA;
329         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
330         udelay(244);
331         /* disable internal oscillator */
332         ldoctl &= ~TWL6040_OSCENA;
333         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
334         /* disable reference system */
335         ldoctl &= ~TWL6040_REFENA;
336         twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
337         msleep(10);
338 }
339
340 /* set headset dac and driver power mode */
341 static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
342 {
343         int hslctl, hsrctl;
344         int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL;
345
346         hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
347         hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
348
349         if (high_perf) {
350                 hslctl &= ~mask;
351                 hsrctl &= ~mask;
352         } else {
353                 hslctl |= mask;
354                 hsrctl |= mask;
355         }
356
357         twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
358         twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
359
360         return 0;
361 }
362
363 static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
364                         struct snd_kcontrol *kcontrol, int event)
365 {
366         struct snd_soc_codec *codec = w->codec;
367         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
368
369         if (SND_SOC_DAPM_EVENT_ON(event))
370                 priv->non_lp++;
371         else
372                 priv->non_lp--;
373
374         return 0;
375 }
376
377 /* audio interrupt handler */
378 static irqreturn_t twl6040_naudint_handler(int irq, void *data)
379 {
380         struct snd_soc_codec *codec = data;
381         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
382         u8 intid;
383
384         twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
385
386         switch (intid) {
387         case TWL6040_THINT:
388                 dev_alert(codec->dev, "die temp over-limit detection\n");
389                 break;
390         case TWL6040_PLUGINT:
391         case TWL6040_UNPLUGINT:
392         case TWL6040_HOOKINT:
393                 break;
394         case TWL6040_HFINT:
395                 dev_alert(codec->dev, "hf drivers over current detection\n");
396                 break;
397         case TWL6040_VIBINT:
398                 dev_alert(codec->dev, "vib drivers over current detection\n");
399                 break;
400         case TWL6040_READYINT:
401                 complete(&priv->ready);
402                 break;
403         default:
404                 dev_err(codec->dev, "unknown audio interrupt %d\n", intid);
405                 break;
406         }
407
408         return IRQ_HANDLED;
409 }
410
411 /*
412  * MICATT volume control:
413  * from -6 to 0 dB in 6 dB steps
414  */
415 static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
416
417 /*
418  * MICGAIN volume control:
419  * from 6 to 30 dB in 6 dB steps
420  */
421 static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0);
422
423 /*
424  * HSGAIN volume control:
425  * from -30 to 0 dB in 2 dB steps
426  */
427 static DECLARE_TLV_DB_SCALE(hs_tlv, -3000, 200, 0);
428
429 /*
430  * HFGAIN volume control:
431  * from -52 to 6 dB in 2 dB steps
432  */
433 static DECLARE_TLV_DB_SCALE(hf_tlv, -5200, 200, 0);
434
435 /*
436  * EPGAIN volume control:
437  * from -24 to 6 dB in 2 dB steps
438  */
439 static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0);
440
441 /* Left analog microphone selection */
442 static const char *twl6040_amicl_texts[] =
443         {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"};
444
445 /* Right analog microphone selection */
446 static const char *twl6040_amicr_texts[] =
447         {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
448
449 static const struct soc_enum twl6040_enum[] = {
450         SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 3, twl6040_amicl_texts),
451         SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts),
452 };
453
454 static const struct snd_kcontrol_new amicl_control =
455         SOC_DAPM_ENUM("Route", twl6040_enum[0]);
456
457 static const struct snd_kcontrol_new amicr_control =
458         SOC_DAPM_ENUM("Route", twl6040_enum[1]);
459
460 /* Headset DAC playback switches */
461 static const struct snd_kcontrol_new hsdacl_switch_controls =
462         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 5, 1, 0);
463
464 static const struct snd_kcontrol_new hsdacr_switch_controls =
465         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 5, 1, 0);
466
467 /* Handsfree DAC playback switches */
468 static const struct snd_kcontrol_new hfdacl_switch_controls =
469         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 2, 1, 0);
470
471 static const struct snd_kcontrol_new hfdacr_switch_controls =
472         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0);
473
474 /* Headset driver switches */
475 static const struct snd_kcontrol_new hsl_driver_switch_controls =
476         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 2, 1, 0);
477
478 static const struct snd_kcontrol_new hsr_driver_switch_controls =
479         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 2, 1, 0);
480
481 /* Handsfree driver switches */
482 static const struct snd_kcontrol_new hfl_driver_switch_controls =
483         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 4, 1, 0);
484
485 static const struct snd_kcontrol_new hfr_driver_switch_controls =
486         SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 4, 1, 0);
487
488 static const struct snd_kcontrol_new ep_driver_switch_controls =
489         SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
490
491 static const struct snd_kcontrol_new twl6040_snd_controls[] = {
492         /* Capture gains */
493         SOC_DOUBLE_TLV("Capture Preamplifier Volume",
494                 TWL6040_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv),
495         SOC_DOUBLE_TLV("Capture Volume",
496                 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
497
498         /* Playback gains */
499         SOC_DOUBLE_TLV("Headset Playback Volume",
500                 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
501         SOC_DOUBLE_R_TLV("Handsfree Playback Volume",
502                 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
503         SOC_SINGLE_TLV("Earphone Playback Volume",
504                 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
505 };
506
507 static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
508         /* Inputs */
509         SND_SOC_DAPM_INPUT("MAINMIC"),
510         SND_SOC_DAPM_INPUT("HSMIC"),
511         SND_SOC_DAPM_INPUT("SUBMIC"),
512         SND_SOC_DAPM_INPUT("AFML"),
513         SND_SOC_DAPM_INPUT("AFMR"),
514
515         /* Outputs */
516         SND_SOC_DAPM_OUTPUT("HSOL"),
517         SND_SOC_DAPM_OUTPUT("HSOR"),
518         SND_SOC_DAPM_OUTPUT("HFL"),
519         SND_SOC_DAPM_OUTPUT("HFR"),
520         SND_SOC_DAPM_OUTPUT("EP"),
521
522         /* Analog input muxes for the capture amplifiers */
523         SND_SOC_DAPM_MUX("Analog Left Capture Route",
524                         SND_SOC_NOPM, 0, 0, &amicl_control),
525         SND_SOC_DAPM_MUX("Analog Right Capture Route",
526                         SND_SOC_NOPM, 0, 0, &amicr_control),
527
528         /* Analog capture PGAs */
529         SND_SOC_DAPM_PGA("MicAmpL",
530                         TWL6040_REG_MICLCTL, 0, 0, NULL, 0),
531         SND_SOC_DAPM_PGA("MicAmpR",
532                         TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
533
534         /* ADCs */
535         SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
536                         TWL6040_REG_MICLCTL, 2, 0),
537         SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture",
538                         TWL6040_REG_MICRCTL, 2, 0),
539
540         /* Microphone bias */
541         SND_SOC_DAPM_MICBIAS("Headset Mic Bias",
542                         TWL6040_REG_AMICBCTL, 0, 0),
543         SND_SOC_DAPM_MICBIAS("Main Mic Bias",
544                         TWL6040_REG_AMICBCTL, 4, 0),
545         SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias",
546                         TWL6040_REG_DMICBCTL, 0, 0),
547         SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias",
548                         TWL6040_REG_DMICBCTL, 4, 0),
549
550         /* DACs */
551         SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback",
552                         TWL6040_REG_HSLCTL, 0, 0),
553         SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback",
554                         TWL6040_REG_HSRCTL, 0, 0),
555         SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback",
556                         TWL6040_REG_HFLCTL, 0, 0,
557                         twl6040_power_mode_event,
558                         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
559         SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback",
560                         TWL6040_REG_HFRCTL, 0, 0,
561                         twl6040_power_mode_event,
562                         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
563
564         /* Analog playback switches */
565         SND_SOC_DAPM_SWITCH("HSDAC Left Playback",
566                         SND_SOC_NOPM, 0, 0, &hsdacl_switch_controls),
567         SND_SOC_DAPM_SWITCH("HSDAC Right Playback",
568                         SND_SOC_NOPM, 0, 0, &hsdacr_switch_controls),
569         SND_SOC_DAPM_SWITCH("HFDAC Left Playback",
570                         SND_SOC_NOPM, 0, 0, &hfdacl_switch_controls),
571         SND_SOC_DAPM_SWITCH("HFDAC Right Playback",
572                         SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls),
573
574         SND_SOC_DAPM_SWITCH("Headset Left Driver",
575                         SND_SOC_NOPM, 0, 0, &hsl_driver_switch_controls),
576         SND_SOC_DAPM_SWITCH("Headset Right Driver",
577                         SND_SOC_NOPM, 0, 0, &hsr_driver_switch_controls),
578         SND_SOC_DAPM_SWITCH_E("Handsfree Left Driver",
579                         SND_SOC_NOPM, 0, 0, &hfl_driver_switch_controls,
580                         twl6040_power_mode_event,
581                         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
582         SND_SOC_DAPM_SWITCH_E("Handsfree Right Driver",
583                         SND_SOC_NOPM, 0, 0, &hfr_driver_switch_controls,
584                         twl6040_power_mode_event,
585                         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
586         SND_SOC_DAPM_SWITCH_E("Earphone Driver",
587                         SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
588                         twl6040_power_mode_event,
589                         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
590
591         /* Analog playback PGAs */
592         SND_SOC_DAPM_PGA("HFDAC Left PGA",
593                         TWL6040_REG_HFLCTL, 1, 0, NULL, 0),
594         SND_SOC_DAPM_PGA("HFDAC Right PGA",
595                         TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
596
597 };
598
599 static const struct snd_soc_dapm_route intercon[] = {
600         /* Capture path */
601         {"Analog Left Capture Route", "Headset Mic", "HSMIC"},
602         {"Analog Left Capture Route", "Main Mic", "MAINMIC"},
603         {"Analog Left Capture Route", "Aux/FM Left", "AFML"},
604
605         {"Analog Right Capture Route", "Headset Mic", "HSMIC"},
606         {"Analog Right Capture Route", "Sub Mic", "SUBMIC"},
607         {"Analog Right Capture Route", "Aux/FM Right", "AFMR"},
608
609         {"MicAmpL", NULL, "Analog Left Capture Route"},
610         {"MicAmpR", NULL, "Analog Right Capture Route"},
611
612         {"ADC Left", NULL, "MicAmpL"},
613         {"ADC Right", NULL, "MicAmpR"},
614
615         /* Headset playback path */
616         {"HSDAC Left Playback", "Switch", "HSDAC Left"},
617         {"HSDAC Right Playback", "Switch", "HSDAC Right"},
618
619         {"Headset Left Driver", "Switch", "HSDAC Left Playback"},
620         {"Headset Right Driver", "Switch", "HSDAC Right Playback"},
621
622         {"HSOL", NULL, "Headset Left Driver"},
623         {"HSOR", NULL, "Headset Right Driver"},
624
625         /* Earphone playback path */
626         {"Earphone Driver", "Switch", "HSDAC Left"},
627         {"EP", NULL, "Earphone Driver"},
628
629         /* Handsfree playback path */
630         {"HFDAC Left Playback", "Switch", "HFDAC Left"},
631         {"HFDAC Right Playback", "Switch", "HFDAC Right"},
632
633         {"HFDAC Left PGA", NULL, "HFDAC Left Playback"},
634         {"HFDAC Right PGA", NULL, "HFDAC Right Playback"},
635
636         {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"},
637         {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"},
638
639         {"HFL", NULL, "Handsfree Left Driver"},
640         {"HFR", NULL, "Handsfree Right Driver"},
641 };
642
643 static int twl6040_add_widgets(struct snd_soc_codec *codec)
644 {
645         snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets,
646                                  ARRAY_SIZE(twl6040_dapm_widgets));
647
648         snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
649
650         snd_soc_dapm_new_widgets(codec);
651
652         return 0;
653 }
654
655 static int twl6040_power_up_completion(struct snd_soc_codec *codec,
656                                         int naudint)
657 {
658         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
659         int time_left;
660         u8 intid;
661
662         time_left = wait_for_completion_timeout(&priv->ready,
663                                 msecs_to_jiffies(48));
664
665         if (!time_left) {
666                 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid,
667                                                         TWL6040_REG_INTID);
668                 if (!(intid & TWL6040_READYINT)) {
669                         dev_err(codec->dev, "timeout waiting for READYINT\n");
670                         return -ETIMEDOUT;
671                 }
672         }
673
674         priv->codec_powered = 1;
675
676         return 0;
677 }
678
679 static int twl6040_set_bias_level(struct snd_soc_codec *codec,
680                                 enum snd_soc_bias_level level)
681 {
682         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
683         int audpwron = priv->audpwron;
684         int naudint = priv->naudint;
685         int ret;
686
687         switch (level) {
688         case SND_SOC_BIAS_ON:
689                 break;
690         case SND_SOC_BIAS_PREPARE:
691                 break;
692         case SND_SOC_BIAS_STANDBY:
693                 if (priv->codec_powered)
694                         break;
695
696                 if (gpio_is_valid(audpwron)) {
697                         /* use AUDPWRON line */
698                         gpio_set_value(audpwron, 1);
699
700                         /* wait for power-up completion */
701                         ret = twl6040_power_up_completion(codec, naudint);
702                         if (ret)
703                                 return ret;
704
705                         /* sync registers updated during power-up sequence */
706                         twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
707                         twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
708                         twl6040_read_reg_volatile(codec, TWL6040_REG_LPPLLCTL);
709                 } else {
710                         /* use manual power-up sequence */
711                         twl6040_power_up(codec);
712                         priv->codec_powered = 1;
713                 }
714
715                 /* initialize vdd/vss registers with reg_cache */
716                 twl6040_init_vdd_regs(codec);
717                 break;
718         case SND_SOC_BIAS_OFF:
719                 if (!priv->codec_powered)
720                         break;
721
722                 if (gpio_is_valid(audpwron)) {
723                         /* use AUDPWRON line */
724                         gpio_set_value(audpwron, 0);
725
726                         /* power-down sequence latency */
727                         udelay(500);
728
729                         /* sync registers updated during power-down sequence */
730                         twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
731                         twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
732                         twl6040_write_reg_cache(codec, TWL6040_REG_LPPLLCTL,
733                                                 0x00);
734                 } else {
735                         /* use manual power-down sequence */
736                         twl6040_power_down(codec);
737                 }
738
739                 priv->codec_powered = 0;
740                 break;
741         }
742
743         codec->bias_level = level;
744
745         return 0;
746 }
747
748 /* set of rates for each pll: low-power and high-performance */
749
750 static unsigned int lp_rates[] = {
751         88200,
752         96000,
753 };
754
755 static struct snd_pcm_hw_constraint_list lp_constraints = {
756         .count  = ARRAY_SIZE(lp_rates),
757         .list   = lp_rates,
758 };
759
760 static unsigned int hp_rates[] = {
761         96000,
762 };
763
764 static struct snd_pcm_hw_constraint_list hp_constraints = {
765         .count  = ARRAY_SIZE(hp_rates),
766         .list   = hp_rates,
767 };
768
769 static int twl6040_startup(struct snd_pcm_substream *substream,
770                         struct snd_soc_dai *dai)
771 {
772         struct snd_soc_pcm_runtime *rtd = substream->private_data;
773         struct snd_soc_device *socdev = rtd->socdev;
774         struct snd_soc_codec *codec = socdev->card->codec;
775         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
776
777         if (!priv->sysclk) {
778                 dev_err(codec->dev,
779                         "no mclk configured, call set_sysclk() on init\n");
780                 return -EINVAL;
781         }
782
783         /*
784          * capture is not supported at 17.64 MHz,
785          * it's reserved for headset low-power playback scenario
786          */
787         if ((priv->sysclk == 17640000) && substream->stream) {
788                 dev_err(codec->dev,
789                         "capture mode is not supported at %dHz\n",
790                         priv->sysclk);
791                 return -EINVAL;
792         }
793
794         snd_pcm_hw_constraint_list(substream->runtime, 0,
795                                 SNDRV_PCM_HW_PARAM_RATE,
796                                 priv->sysclk_constraints);
797
798         return 0;
799 }
800
801 static int twl6040_hw_params(struct snd_pcm_substream *substream,
802                         struct snd_pcm_hw_params *params,
803                         struct snd_soc_dai *dai)
804 {
805         struct snd_soc_pcm_runtime *rtd = substream->private_data;
806         struct snd_soc_device *socdev = rtd->socdev;
807         struct snd_soc_codec *codec = socdev->card->codec;
808         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
809         u8 lppllctl;
810         int rate;
811
812         /* nothing to do for high-perf pll, it supports only 48 kHz */
813         if (priv->pll == TWL6040_HPPLL_ID)
814                 return 0;
815
816         lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
817
818         rate = params_rate(params);
819         switch (rate) {
820         case 88200:
821                 lppllctl |= TWL6040_LPLLFIN;
822                 priv->sysclk = 17640000;
823                 break;
824         case 96000:
825                 lppllctl &= ~TWL6040_LPLLFIN;
826                 priv->sysclk = 19200000;
827                 break;
828         default:
829                 dev_err(codec->dev, "unsupported rate %d\n", rate);
830                 return -EINVAL;
831         }
832
833         twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
834
835         return 0;
836 }
837
838 static int twl6040_trigger(struct snd_pcm_substream *substream,
839                         int cmd, struct snd_soc_dai *dai)
840 {
841         struct snd_soc_pcm_runtime *rtd = substream->private_data;
842         struct snd_soc_device *socdev = rtd->socdev;
843         struct snd_soc_codec *codec = socdev->card->codec;
844         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
845
846         switch (cmd) {
847         case SNDRV_PCM_TRIGGER_START:
848         case SNDRV_PCM_TRIGGER_RESUME:
849                 /*
850                  * low-power playback mode is restricted
851                  * for headset path only
852                  */
853                 if ((priv->sysclk == 17640000) && priv->non_lp) {
854                         dev_err(codec->dev,
855                                 "some enabled paths aren't supported at %dHz\n",
856                                 priv->sysclk);
857                         return -EPERM;
858                 }
859                 break;
860         default:
861                 break;
862         }
863
864         return 0;
865 }
866
867 static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
868                 int clk_id, unsigned int freq, int dir)
869 {
870         struct snd_soc_codec *codec = codec_dai->codec;
871         struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
872         u8 hppllctl, lppllctl;
873
874         hppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_HPPLLCTL);
875         lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
876
877         switch (clk_id) {
878         case TWL6040_SYSCLK_SEL_LPPLL:
879                 switch (freq) {
880                 case 32768:
881                         /* headset dac and driver must be in low-power mode */
882                         headset_power_mode(codec, 0);
883
884                         /* clk32k input requires low-power pll */
885                         lppllctl |= TWL6040_LPLLENA;
886                         twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
887                         mdelay(5);
888                         lppllctl &= ~TWL6040_HPLLSEL;
889                         twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
890                         hppllctl &= ~TWL6040_HPLLENA;
891                         twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
892                         break;
893                 default:
894                         dev_err(codec->dev, "unknown mclk freq %d\n", freq);
895                         return -EINVAL;
896                 }
897
898                 /* lppll divider */
899                 switch (priv->sysclk) {
900                 case 17640000:
901                         lppllctl |= TWL6040_LPLLFIN;
902                         break;
903                 case 19200000:
904                         lppllctl &= ~TWL6040_LPLLFIN;
905                         break;
906                 default:
907                         /* sysclk not yet configured */
908                         lppllctl &= ~TWL6040_LPLLFIN;
909                         priv->sysclk = 19200000;
910                         break;
911                 }
912
913                 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
914
915                 priv->pll = TWL6040_LPPLL_ID;
916                 priv->sysclk_constraints = &lp_constraints;
917                 break;
918         case TWL6040_SYSCLK_SEL_HPPLL:
919                 hppllctl &= ~TWL6040_MCLK_MSK;
920
921                 switch (freq) {
922                 case 12000000:
923                         /* mclk input, pll enabled */
924                         hppllctl |= TWL6040_MCLK_12000KHZ |
925                                     TWL6040_HPLLSQRBP |
926                                     TWL6040_HPLLENA;
927                         break;
928                 case 19200000:
929                         /* mclk input, pll disabled */
930                         hppllctl |= TWL6040_MCLK_19200KHZ |
931                                     TWL6040_HPLLSQRBP |
932                                     TWL6040_HPLLBP;
933                         break;
934                 case 26000000:
935                         /* mclk input, pll enabled */
936                         hppllctl |= TWL6040_MCLK_26000KHZ |
937                                     TWL6040_HPLLSQRBP |
938                                     TWL6040_HPLLENA;
939                         break;
940                 case 38400000:
941                         /* clk slicer, pll disabled */
942                         hppllctl |= TWL6040_MCLK_38400KHZ |
943                                     TWL6040_HPLLSQRENA |
944                                     TWL6040_HPLLBP;
945                         break;
946                 default:
947                         dev_err(codec->dev, "unknown mclk freq %d\n", freq);
948                         return -EINVAL;
949                 }
950
951                 /* headset dac and driver must be in high-performance mode */
952                 headset_power_mode(codec, 1);
953
954                 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
955                 udelay(500);
956                 lppllctl |= TWL6040_HPLLSEL;
957                 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
958                 lppllctl &= ~TWL6040_LPLLENA;
959                 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
960
961                 /* high-performance pll can provide only 19.2 MHz */
962                 priv->pll = TWL6040_HPPLL_ID;
963                 priv->sysclk = 19200000;
964                 priv->sysclk_constraints = &hp_constraints;
965                 break;
966         default:
967                 dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
968                 return -EINVAL;
969         }
970
971         return 0;
972 }
973
974 static struct snd_soc_dai_ops twl6040_dai_ops = {
975         .startup        = twl6040_startup,
976         .hw_params      = twl6040_hw_params,
977         .trigger        = twl6040_trigger,
978         .set_sysclk     = twl6040_set_dai_sysclk,
979 };
980
981 struct snd_soc_dai twl6040_dai = {
982         .name = "twl6040",
983         .playback = {
984                 .stream_name = "Playback",
985                 .channels_min = 1,
986                 .channels_max = 4,
987                 .rates = TWL6040_RATES,
988                 .formats = TWL6040_FORMATS,
989         },
990         .capture = {
991                 .stream_name = "Capture",
992                 .channels_min = 1,
993                 .channels_max = 2,
994                 .rates = TWL6040_RATES,
995                 .formats = TWL6040_FORMATS,
996         },
997         .ops = &twl6040_dai_ops,
998 };
999 EXPORT_SYMBOL_GPL(twl6040_dai);
1000
1001 #ifdef CONFIG_PM
1002 static int twl6040_suspend(struct platform_device *pdev, pm_message_t state)
1003 {
1004         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1005         struct snd_soc_codec *codec = socdev->card->codec;
1006
1007         twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1008
1009         return 0;
1010 }
1011
1012 static int twl6040_resume(struct platform_device *pdev)
1013 {
1014         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1015         struct snd_soc_codec *codec = socdev->card->codec;
1016
1017         twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1018
1019         return 0;
1020 }
1021 #else
1022 #define twl6040_suspend NULL
1023 #define twl6040_resume NULL
1024 #endif
1025
1026 static struct snd_soc_codec *twl6040_codec;
1027
1028 static int twl6040_probe(struct platform_device *pdev)
1029 {
1030         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1031         struct snd_soc_codec *codec;
1032         int ret = 0;
1033
1034         BUG_ON(!twl6040_codec);
1035
1036         codec = twl6040_codec;
1037         socdev->card->codec = codec;
1038
1039         /* register pcms */
1040         ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1041         if (ret < 0) {
1042                 dev_err(&pdev->dev, "failed to create pcms\n");
1043                 return ret;
1044         }
1045
1046         snd_soc_add_controls(codec, twl6040_snd_controls,
1047                                 ARRAY_SIZE(twl6040_snd_controls));
1048         twl6040_add_widgets(codec);
1049
1050         if (ret < 0) {
1051                 dev_err(&pdev->dev, "failed to register card\n");
1052                 goto card_err;
1053         }
1054
1055         return ret;
1056
1057 card_err:
1058         snd_soc_free_pcms(socdev);
1059         snd_soc_dapm_free(socdev);
1060         return ret;
1061 }
1062
1063 static int twl6040_remove(struct platform_device *pdev)
1064 {
1065         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1066         struct snd_soc_codec *codec = socdev->card->codec;
1067
1068         twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1069         snd_soc_free_pcms(socdev);
1070         snd_soc_dapm_free(socdev);
1071         kfree(codec);
1072
1073         return 0;
1074 }
1075
1076 struct snd_soc_codec_device soc_codec_dev_twl6040 = {
1077         .probe = twl6040_probe,
1078         .remove = twl6040_remove,
1079         .suspend = twl6040_suspend,
1080         .resume = twl6040_resume,
1081 };
1082 EXPORT_SYMBOL_GPL(soc_codec_dev_twl6040);
1083
1084 static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1085 {
1086         struct twl4030_codec_data *twl_codec = pdev->dev.platform_data;
1087         struct snd_soc_codec *codec;
1088         struct twl6040_data *priv;
1089         int audpwron, naudint;
1090         int ret = 0;
1091
1092         priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
1093         if (priv == NULL)
1094                 return -ENOMEM;
1095
1096         if (twl_codec) {
1097                 audpwron = twl_codec->audpwron_gpio;
1098                 naudint = twl_codec->naudint_irq;
1099         } else {
1100                 audpwron = -EINVAL;
1101                 naudint = 0;
1102         }
1103
1104         priv->audpwron = audpwron;
1105         priv->naudint = naudint;
1106
1107         codec = &priv->codec;
1108         codec->dev = &pdev->dev;
1109         twl6040_dai.dev = &pdev->dev;
1110
1111         codec->name = "twl6040";
1112         codec->owner = THIS_MODULE;
1113         codec->read = twl6040_read_reg_cache;
1114         codec->write = twl6040_write;
1115         codec->set_bias_level = twl6040_set_bias_level;
1116         snd_soc_codec_set_drvdata(codec, priv);
1117         codec->dai = &twl6040_dai;
1118         codec->num_dai = 1;
1119         codec->reg_cache_size = ARRAY_SIZE(twl6040_reg);
1120         codec->reg_cache = kmemdup(twl6040_reg, sizeof(twl6040_reg),
1121                                         GFP_KERNEL);
1122         if (codec->reg_cache == NULL) {
1123                 ret = -ENOMEM;
1124                 goto cache_err;
1125         }
1126
1127         mutex_init(&codec->mutex);
1128         INIT_LIST_HEAD(&codec->dapm_widgets);
1129         INIT_LIST_HEAD(&codec->dapm_paths);
1130         init_completion(&priv->ready);
1131
1132         if (gpio_is_valid(audpwron)) {
1133                 ret = gpio_request(audpwron, "audpwron");
1134                 if (ret)
1135                         goto gpio1_err;
1136
1137                 ret = gpio_direction_output(audpwron, 0);
1138                 if (ret)
1139                         goto gpio2_err;
1140
1141                 priv->codec_powered = 0;
1142         }
1143
1144         if (naudint) {
1145                 /* audio interrupt */
1146                 ret = request_threaded_irq(naudint, NULL,
1147                                 twl6040_naudint_handler,
1148                                 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1149                                 "twl6040_codec", codec);
1150                 if (ret)
1151                         goto gpio2_err;
1152         } else {
1153                 if (gpio_is_valid(audpwron)) {
1154                         /* enable only codec ready interrupt */
1155                         twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1156                                         ~TWL6040_READYMSK & TWL6040_ALLINT_MSK);
1157                 } else {
1158                         /* no interrupts at all */
1159                         twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1160                                                 TWL6040_ALLINT_MSK);
1161                 }
1162         }
1163
1164         /* init vio registers */
1165         twl6040_init_vio_regs(codec);
1166
1167         /* power on device */
1168         ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1169         if (ret)
1170                 goto irq_err;
1171
1172         ret = snd_soc_register_codec(codec);
1173         if (ret)
1174                 goto reg_err;
1175
1176         twl6040_codec = codec;
1177
1178         ret = snd_soc_register_dai(&twl6040_dai);
1179         if (ret)
1180                 goto dai_err;
1181
1182         return 0;
1183
1184 dai_err:
1185         snd_soc_unregister_codec(codec);
1186         twl6040_codec = NULL;
1187 reg_err:
1188         twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1189 irq_err:
1190         if (naudint)
1191                 free_irq(naudint, codec);
1192 gpio2_err:
1193         if (gpio_is_valid(audpwron))
1194                 gpio_free(audpwron);
1195 gpio1_err:
1196         kfree(codec->reg_cache);
1197 cache_err:
1198         kfree(priv);
1199         return ret;
1200 }
1201
1202 static int __devexit twl6040_codec_remove(struct platform_device *pdev)
1203 {
1204         struct twl6040_data *priv = snd_soc_codec_get_drvdata(twl6040_codec);
1205         int audpwron = priv->audpwron;
1206         int naudint = priv->naudint;
1207
1208         if (gpio_is_valid(audpwron))
1209                 gpio_free(audpwron);
1210
1211         if (naudint)
1212                 free_irq(naudint, twl6040_codec);
1213
1214         snd_soc_unregister_dai(&twl6040_dai);
1215         snd_soc_unregister_codec(twl6040_codec);
1216
1217         kfree(twl6040_codec);
1218         twl6040_codec = NULL;
1219
1220         return 0;
1221 }
1222
1223 static struct platform_driver twl6040_codec_driver = {
1224         .driver = {
1225                 .name = "twl6040_codec",
1226                 .owner = THIS_MODULE,
1227         },
1228         .probe = twl6040_codec_probe,
1229         .remove = __devexit_p(twl6040_codec_remove),
1230 };
1231
1232 static int __init twl6040_codec_init(void)
1233 {
1234         return platform_driver_register(&twl6040_codec_driver);
1235 }
1236 module_init(twl6040_codec_init);
1237
1238 static void __exit twl6040_codec_exit(void)
1239 {
1240         platform_driver_unregister(&twl6040_codec_driver);
1241 }
1242 module_exit(twl6040_codec_exit);
1243
1244 MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
1245 MODULE_AUTHOR("Misael Lopez Cruz");
1246 MODULE_LICENSE("GPL");