1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/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/initval.h>
38#include <sound/tlv.h>
39
40#include "twl6040.h"
41
42#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000
43#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
44
45#define TWL6040_OUTHS_0dB 0x00
46#define TWL6040_OUTHS_M30dB 0x0F
47#define TWL6040_OUTHF_0dB 0x03
48#define TWL6040_OUTHF_M52dB 0x1D
49
50#define TWL6040_RAMP_NONE 0
51#define TWL6040_RAMP_UP 1
52#define TWL6040_RAMP_DOWN 2
53
54#define TWL6040_HSL_VOL_MASK 0x0F
55#define TWL6040_HSL_VOL_SHIFT 0
56#define TWL6040_HSR_VOL_MASK 0xF0
57#define TWL6040_HSR_VOL_SHIFT 4
58#define TWL6040_HF_VOL_MASK 0x1F
59#define TWL6040_HF_VOL_SHIFT 0
60
61struct twl6040_output {
62 u16 active;
63 u16 left_vol;
64 u16 right_vol;
65 u16 left_step;
66 u16 right_step;
67 unsigned int step_delay;
68 u16 ramp;
69 u16 mute;
70 struct completion ramp_done;
71};
72
73struct twl6040_jack_data {
74 struct snd_soc_jack *jack;
75 int report;
76};
77
78
79struct twl6040_data {
80 int audpwron;
81 int naudint;
82 int codec_powered;
83 int pll;
84 int non_lp;
85 unsigned int sysclk;
86 struct snd_pcm_hw_constraint_list *sysclk_constraints;
87 struct completion ready;
88 struct twl6040_jack_data hs_jack;
89 struct snd_soc_codec *codec;
90 struct workqueue_struct *workqueue;
91 struct delayed_work delayed_work;
92 struct mutex mutex;
93 struct twl6040_output headset;
94 struct twl6040_output handsfree;
95 struct workqueue_struct *hf_workqueue;
96 struct workqueue_struct *hs_workqueue;
97 struct delayed_work hs_delayed_work;
98 struct delayed_work hf_delayed_work;
99};
100
101
102
103
104static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
105 0x00,
106 0x4B,
107 0x00,
108 0x00,
109 0x00,
110 0x00,
111 0x00,
112 0x60,
113 0x00,
114 0x4A,
115 0x00,
116 0x00,
117 0x18,
118 0x18,
119 0x00,
120 0x1B,
121 0x00,
122 0x00,
123 0x00,
124 0x00,
125 0x00,
126 0x00,
127 0x00,
128 0x00,
129 0x00,
130 0x00,
131 0x00,
132 0x00,
133 0x00,
134 0x00,
135 0x00,
136 0x00,
137 0x00,
138 0x00,
139 0x00,
140 0x00,
141 0x00,
142 0x00,
143 0x00,
144 0x00,
145 0x00,
146 0x00,
147 0x00,
148 0x00,
149 0x00,
150 0x09,
151 0x00,
152};
153
154
155
156
157
158
159static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = {
160 TWL6040_REG_ASICID,
161 TWL6040_REG_ASICREV,
162 TWL6040_REG_INTID,
163 TWL6040_REG_INTMR,
164 TWL6040_REG_NCPCTL,
165 TWL6040_REG_LDOCTL,
166 TWL6040_REG_AMICBCTL,
167 TWL6040_REG_DMICBCTL,
168 TWL6040_REG_HKCTL1,
169 TWL6040_REG_HKCTL2,
170 TWL6040_REG_GPOCTL,
171 TWL6040_REG_TRIM1,
172 TWL6040_REG_TRIM2,
173 TWL6040_REG_TRIM3,
174 TWL6040_REG_HSOTRIM,
175 TWL6040_REG_HFOTRIM,
176 TWL6040_REG_ACCCTL,
177 TWL6040_REG_STATUS,
178};
179
180
181
182
183
184
185static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
186 TWL6040_REG_HPPLLCTL,
187 TWL6040_REG_LPPLLCTL,
188 TWL6040_REG_LPPLLDIV,
189 TWL6040_REG_MICLCTL,
190 TWL6040_REG_MICRCTL,
191 TWL6040_REG_MICGAIN,
192 TWL6040_REG_LINEGAIN,
193 TWL6040_REG_HSLCTL,
194 TWL6040_REG_HSRCTL,
195 TWL6040_REG_HSGAIN,
196 TWL6040_REG_EARCTL,
197 TWL6040_REG_HFLCTL,
198 TWL6040_REG_HFLGAIN,
199 TWL6040_REG_HFRCTL,
200 TWL6040_REG_HFRGAIN,
201 TWL6040_REG_VIBCTLL,
202 TWL6040_REG_VIBDATL,
203 TWL6040_REG_VIBCTLR,
204 TWL6040_REG_VIBDATR,
205 TWL6040_REG_ALB,
206 TWL6040_REG_DLB,
207};
208
209
210
211
212static inline unsigned int twl6040_read_reg_cache(struct snd_soc_codec *codec,
213 unsigned int reg)
214{
215 u8 *cache = codec->reg_cache;
216
217 if (reg >= TWL6040_CACHEREGNUM)
218 return -EIO;
219
220 return cache[reg];
221}
222
223
224
225
226static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec,
227 u8 reg, u8 value)
228{
229 u8 *cache = codec->reg_cache;
230
231 if (reg >= TWL6040_CACHEREGNUM)
232 return;
233 cache[reg] = value;
234}
235
236
237
238
239static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
240 unsigned int reg)
241{
242 u8 value;
243
244 if (reg >= TWL6040_CACHEREGNUM)
245 return -EIO;
246
247 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &value, reg);
248 twl6040_write_reg_cache(codec, reg, value);
249
250 return value;
251}
252
253
254
255
256static int twl6040_write(struct snd_soc_codec *codec,
257 unsigned int reg, unsigned int value)
258{
259 if (reg >= TWL6040_CACHEREGNUM)
260 return -EIO;
261
262 twl6040_write_reg_cache(codec, reg, value);
263 return twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, value, reg);
264}
265
266static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
267{
268 u8 *cache = codec->reg_cache;
269 int reg, i;
270
271
272 twl6040_write(codec, TWL6040_REG_ACCCTL, cache[TWL6040_REG_ACCCTL]);
273
274 for (i = 0; i < TWL6040_VIOREGNUM; i++) {
275 reg = twl6040_vio_reg[i];
276
277 switch (reg) {
278 case TWL6040_REG_ASICID:
279 case TWL6040_REG_ASICREV:
280 case TWL6040_REG_STATUS:
281 continue;
282 default:
283 break;
284 }
285 twl6040_write(codec, reg, cache[reg]);
286 }
287}
288
289static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
290{
291 u8 *cache = codec->reg_cache;
292 int reg, i;
293
294 for (i = 0; i < TWL6040_VDDREGNUM; i++) {
295 reg = twl6040_vdd_reg[i];
296 twl6040_write(codec, reg, cache[reg]);
297 }
298}
299
300
301
302
303static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
304 unsigned int left_step, unsigned int right_step)
305{
306
307 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
308 struct twl6040_output *headset = &priv->headset;
309 int left_complete = 0, right_complete = 0;
310 u8 reg, val;
311
312
313 left_step = (left_step > 0xF) ? 0xF : left_step;
314 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
315 val = (~reg & TWL6040_HSL_VOL_MASK);
316
317 if (headset->ramp == TWL6040_RAMP_UP) {
318
319 if (val < headset->left_vol) {
320 val += left_step;
321 reg &= ~TWL6040_HSL_VOL_MASK;
322 twl6040_write(codec, TWL6040_REG_HSGAIN,
323 (reg | (~val & TWL6040_HSL_VOL_MASK)));
324 } else {
325 left_complete = 1;
326 }
327 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
328
329 if (val > 0x0) {
330 val -= left_step;
331 reg &= ~TWL6040_HSL_VOL_MASK;
332 twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
333 (~val & TWL6040_HSL_VOL_MASK));
334 } else {
335 left_complete = 1;
336 }
337 }
338
339
340 right_step = (right_step > 0xF) ? 0xF : right_step;
341 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
342 val = (~reg & TWL6040_HSR_VOL_MASK) >> TWL6040_HSR_VOL_SHIFT;
343
344 if (headset->ramp == TWL6040_RAMP_UP) {
345
346 if (val < headset->right_vol) {
347 val += right_step;
348 reg &= ~TWL6040_HSR_VOL_MASK;
349 twl6040_write(codec, TWL6040_REG_HSGAIN,
350 (reg | (~val << TWL6040_HSR_VOL_SHIFT)));
351 } else {
352 right_complete = 1;
353 }
354 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
355
356 if (val > 0x0) {
357 val -= right_step;
358 reg &= ~TWL6040_HSR_VOL_MASK;
359 twl6040_write(codec, TWL6040_REG_HSGAIN,
360 reg | (~val << TWL6040_HSR_VOL_SHIFT));
361 } else {
362 right_complete = 1;
363 }
364 }
365
366 return left_complete & right_complete;
367}
368
369
370
371
372static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
373 unsigned int left_step, unsigned int right_step)
374{
375 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
376 struct twl6040_output *handsfree = &priv->handsfree;
377 int left_complete = 0, right_complete = 0;
378 u16 reg, val;
379
380
381 left_step = (left_step > 0x1D) ? 0x1D : left_step;
382 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFLGAIN);
383 reg = 0x1D - reg;
384 val = (reg & TWL6040_HF_VOL_MASK);
385 if (handsfree->ramp == TWL6040_RAMP_UP) {
386
387 if (val < handsfree->left_vol) {
388 val += left_step;
389 reg &= ~TWL6040_HF_VOL_MASK;
390 twl6040_write(codec, TWL6040_REG_HFLGAIN,
391 reg | (0x1D - val));
392 } else {
393 left_complete = 1;
394 }
395 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
396
397 if (val > 0) {
398 val -= left_step;
399 reg &= ~TWL6040_HF_VOL_MASK;
400 twl6040_write(codec, TWL6040_REG_HFLGAIN,
401 reg | (0x1D - val));
402 } else {
403 left_complete = 1;
404 }
405 }
406
407
408 right_step = (right_step > 0x1D) ? 0x1D : right_step;
409 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFRGAIN);
410 reg = 0x1D - reg;
411 val = (reg & TWL6040_HF_VOL_MASK);
412 if (handsfree->ramp == TWL6040_RAMP_UP) {
413
414 if (val < handsfree->right_vol) {
415 val += right_step;
416 reg &= ~TWL6040_HF_VOL_MASK;
417 twl6040_write(codec, TWL6040_REG_HFRGAIN,
418 reg | (0x1D - val));
419 } else {
420 right_complete = 1;
421 }
422 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
423
424 if (val > 0) {
425 val -= right_step;
426 reg &= ~TWL6040_HF_VOL_MASK;
427 twl6040_write(codec, TWL6040_REG_HFRGAIN,
428 reg | (0x1D - val));
429 }
430 }
431
432 return left_complete & right_complete;
433}
434
435
436
437
438
439static void twl6040_pga_hs_work(struct work_struct *work)
440{
441 struct twl6040_data *priv =
442 container_of(work, struct twl6040_data, hs_delayed_work.work);
443 struct snd_soc_codec *codec = priv->codec;
444 struct twl6040_output *headset = &priv->headset;
445 unsigned int delay = headset->step_delay;
446 int i, headset_complete;
447
448
449 if (headset->ramp == TWL6040_RAMP_NONE)
450 return;
451
452
453 for (i = 0; i <= 16; i++) {
454 headset_complete = 1;
455 if (headset->ramp != TWL6040_RAMP_NONE)
456 headset_complete = twl6040_hs_ramp_step(codec,
457 headset->left_step,
458 headset->right_step);
459
460
461 if (headset_complete)
462 break;
463
464
465
466
467
468 if (i >= 8)
469 schedule_timeout_interruptible(msecs_to_jiffies(delay +
470 (delay >> 1)));
471 else
472 schedule_timeout_interruptible(msecs_to_jiffies(delay));
473 }
474
475 if (headset->ramp == TWL6040_RAMP_DOWN) {
476 headset->active = 0;
477 complete(&headset->ramp_done);
478 } else {
479 headset->active = 1;
480 }
481 headset->ramp = TWL6040_RAMP_NONE;
482}
483
484static void twl6040_pga_hf_work(struct work_struct *work)
485{
486 struct twl6040_data *priv =
487 container_of(work, struct twl6040_data, hf_delayed_work.work);
488 struct snd_soc_codec *codec = priv->codec;
489 struct twl6040_output *handsfree = &priv->handsfree;
490 unsigned int delay = handsfree->step_delay;
491 int i, handsfree_complete;
492
493
494 if (handsfree->ramp == TWL6040_RAMP_NONE)
495 return;
496
497
498 for (i = 0; i <= 32; i++) {
499 handsfree_complete = 1;
500 if (handsfree->ramp != TWL6040_RAMP_NONE)
501 handsfree_complete = twl6040_hf_ramp_step(codec,
502 handsfree->left_step,
503 handsfree->right_step);
504
505
506 if (handsfree_complete)
507 break;
508
509
510
511
512
513 if (i >= 16)
514 schedule_timeout_interruptible(msecs_to_jiffies(delay +
515 (delay >> 1)));
516 else
517 schedule_timeout_interruptible(msecs_to_jiffies(delay));
518 }
519
520
521 if (handsfree->ramp == TWL6040_RAMP_DOWN) {
522 handsfree->active = 0;
523 complete(&handsfree->ramp_done);
524 } else
525 handsfree->active = 1;
526 handsfree->ramp = TWL6040_RAMP_NONE;
527}
528
529static int pga_event(struct snd_soc_dapm_widget *w,
530 struct snd_kcontrol *kcontrol, int event)
531{
532 struct snd_soc_codec *codec = w->codec;
533 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
534 struct twl6040_output *out;
535 struct delayed_work *work;
536 struct workqueue_struct *queue;
537
538 switch (w->shift) {
539 case 2:
540 case 3:
541 out = &priv->headset;
542 work = &priv->hs_delayed_work;
543 queue = priv->hs_workqueue;
544 out->step_delay = 5;
545 break;
546 case 4:
547 out = &priv->handsfree;
548 work = &priv->hf_delayed_work;
549 queue = priv->hf_workqueue;
550 out->step_delay = 5;
551 if (SND_SOC_DAPM_EVENT_ON(event))
552 priv->non_lp++;
553 else
554 priv->non_lp--;
555 break;
556 default:
557 return -1;
558 }
559
560 switch (event) {
561 case SND_SOC_DAPM_POST_PMU:
562 if (out->active)
563 break;
564
565
566 out->left_step = out->left_vol;
567 out->right_step = out->right_vol;
568
569 if (!delayed_work_pending(work)) {
570 out->ramp = TWL6040_RAMP_UP;
571 queue_delayed_work(queue, work,
572 msecs_to_jiffies(1));
573 }
574 break;
575
576 case SND_SOC_DAPM_PRE_PMD:
577 if (!out->active)
578 break;
579
580 if (!delayed_work_pending(work)) {
581
582 out->left_step = 1;
583 out->right_step = 1;
584 out->ramp = TWL6040_RAMP_DOWN;
585 INIT_COMPLETION(out->ramp_done);
586
587 queue_delayed_work(queue, work,
588 msecs_to_jiffies(1));
589
590 wait_for_completion_timeout(&out->ramp_done,
591 msecs_to_jiffies(2000));
592 }
593 break;
594 }
595
596 return 0;
597}
598
599
600static void twl6040_power_up(struct snd_soc_codec *codec)
601{
602 u8 ncpctl, ldoctl, lppllctl, accctl;
603
604 ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
605 ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
606 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
607 accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
608
609
610 ldoctl |= TWL6040_REFENA;
611 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
612 msleep(10);
613
614 ldoctl |= TWL6040_OSCENA;
615 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
616 udelay(10);
617
618 ldoctl |= TWL6040_HSLDOENA;
619 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
620 udelay(244);
621
622 ncpctl |= TWL6040_NCPENA | TWL6040_NCPOPEN;
623 twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
624 udelay(488);
625
626 ldoctl |= TWL6040_LSLDOENA;
627 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
628 udelay(244);
629
630 lppllctl |= TWL6040_LPLLENA;
631 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
632
633 accctl |= TWL6040_RESETSPLIT;
634 twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
635 mdelay(5);
636 accctl &= ~TWL6040_RESETSPLIT;
637 twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
638
639 ldoctl &= ~TWL6040_OSCENA;
640 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
641}
642
643
644static void twl6040_power_down(struct snd_soc_codec *codec)
645{
646 u8 ncpctl, ldoctl, lppllctl, accctl;
647
648 ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
649 ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
650 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
651 accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
652
653
654 ldoctl |= TWL6040_OSCENA;
655 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
656 udelay(10);
657
658 lppllctl &= ~TWL6040_LPLLENA;
659 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
660
661 ldoctl &= ~TWL6040_LSLDOENA;
662 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
663 udelay(244);
664
665 ncpctl &= ~(TWL6040_NCPENA | TWL6040_NCPOPEN);
666 twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
667 udelay(488);
668
669 ldoctl &= ~TWL6040_HSLDOENA;
670 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
671 udelay(244);
672
673 ldoctl &= ~TWL6040_OSCENA;
674 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
675
676 ldoctl &= ~TWL6040_REFENA;
677 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
678 msleep(10);
679}
680
681
682static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
683{
684 int hslctl, hsrctl;
685 int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL;
686
687 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
688 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
689
690 if (high_perf) {
691 hslctl &= ~mask;
692 hsrctl &= ~mask;
693 } else {
694 hslctl |= mask;
695 hsrctl |= mask;
696 }
697
698 twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
699 twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
700
701 return 0;
702}
703
704static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
705 struct snd_kcontrol *kcontrol, int event)
706{
707 msleep(1);
708 return 0;
709}
710
711static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
712 struct snd_kcontrol *kcontrol, int event)
713{
714 struct snd_soc_codec *codec = w->codec;
715 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
716
717 if (SND_SOC_DAPM_EVENT_ON(event))
718 priv->non_lp++;
719 else
720 priv->non_lp--;
721
722 msleep(1);
723
724 return 0;
725}
726
727static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
728 struct snd_soc_jack *jack, int report)
729{
730 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
731 int status;
732
733 mutex_lock(&priv->mutex);
734
735
736 status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS);
737 if (status & TWL6040_PLUGCOMP)
738 snd_soc_jack_report(jack, report, report);
739 else
740 snd_soc_jack_report(jack, 0, report);
741
742 mutex_unlock(&priv->mutex);
743}
744
745void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
746 struct snd_soc_jack *jack, int report)
747{
748 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
749 struct twl6040_jack_data *hs_jack = &priv->hs_jack;
750
751 hs_jack->jack = jack;
752 hs_jack->report = report;
753
754 twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
755}
756EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
757
758static void twl6040_accessory_work(struct work_struct *work)
759{
760 struct twl6040_data *priv = container_of(work,
761 struct twl6040_data, delayed_work.work);
762 struct snd_soc_codec *codec = priv->codec;
763 struct twl6040_jack_data *hs_jack = &priv->hs_jack;
764
765 twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
766}
767
768
769static irqreturn_t twl6040_naudint_handler(int irq, void *data)
770{
771 struct snd_soc_codec *codec = data;
772 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
773 u8 intid;
774
775 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
776
777 if (intid & TWL6040_THINT)
778 dev_alert(codec->dev, "die temp over-limit detection\n");
779
780 if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT))
781 queue_delayed_work(priv->workqueue, &priv->delayed_work,
782 msecs_to_jiffies(200));
783
784 if (intid & TWL6040_HOOKINT)
785 dev_info(codec->dev, "hook detection\n");
786
787 if (intid & TWL6040_HFINT)
788 dev_alert(codec->dev, "hf drivers over current detection\n");
789
790 if (intid & TWL6040_VIBINT)
791 dev_alert(codec->dev, "vib drivers over current detection\n");
792
793 if (intid & TWL6040_READYINT)
794 complete(&priv->ready);
795
796 return IRQ_HANDLED;
797}
798
799static int twl6040_put_volsw(struct snd_kcontrol *kcontrol,
800 struct snd_ctl_elem_value *ucontrol)
801{
802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
803 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
804 struct twl6040_output *out = NULL;
805 struct soc_mixer_control *mc =
806 (struct soc_mixer_control *)kcontrol->private_value;
807 int ret;
808 unsigned int reg = mc->reg;
809
810
811
812
813 switch (reg) {
814 case TWL6040_REG_HSGAIN:
815 out = &twl6040_priv->headset;
816 break;
817 default:
818 break;
819 }
820
821 if (out) {
822 out->left_vol = ucontrol->value.integer.value[0];
823 out->right_vol = ucontrol->value.integer.value[1];
824 if (!out->active)
825 return 1;
826 }
827
828 ret = snd_soc_put_volsw(kcontrol, ucontrol);
829 if (ret < 0)
830 return ret;
831
832 return 1;
833}
834
835static int twl6040_get_volsw(struct snd_kcontrol *kcontrol,
836 struct snd_ctl_elem_value *ucontrol)
837{
838 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
839 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
840 struct twl6040_output *out = &twl6040_priv->headset;
841 struct soc_mixer_control *mc =
842 (struct soc_mixer_control *)kcontrol->private_value;
843 unsigned int reg = mc->reg;
844
845 switch (reg) {
846 case TWL6040_REG_HSGAIN:
847 out = &twl6040_priv->headset;
848 ucontrol->value.integer.value[0] = out->left_vol;
849 ucontrol->value.integer.value[1] = out->right_vol;
850 return 0;
851
852 default:
853 break;
854 }
855
856 return snd_soc_get_volsw(kcontrol, ucontrol);
857}
858
859static int twl6040_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
860 struct snd_ctl_elem_value *ucontrol)
861{
862 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
863 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
864 struct twl6040_output *out = NULL;
865 struct soc_mixer_control *mc =
866 (struct soc_mixer_control *)kcontrol->private_value;
867 int ret;
868 unsigned int reg = mc->reg;
869
870
871
872
873 switch (reg) {
874 case TWL6040_REG_HFLGAIN:
875 case TWL6040_REG_HFRGAIN:
876 out = &twl6040_priv->handsfree;
877 break;
878 default:
879 break;
880 }
881
882 if (out) {
883 out->left_vol = ucontrol->value.integer.value[0];
884 out->right_vol = ucontrol->value.integer.value[1];
885 if (!out->active)
886 return 1;
887 }
888
889 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
890 if (ret < 0)
891 return ret;
892
893 return 1;
894}
895
896static int twl6040_get_volsw_2r(struct snd_kcontrol *kcontrol,
897 struct snd_ctl_elem_value *ucontrol)
898{
899 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
900 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
901 struct twl6040_output *out = &twl6040_priv->handsfree;
902 struct soc_mixer_control *mc =
903 (struct soc_mixer_control *)kcontrol->private_value;
904 unsigned int reg = mc->reg;
905
906
907 switch (reg) {
908 case TWL6040_REG_HFLGAIN:
909 case TWL6040_REG_HFRGAIN:
910 out = &twl6040_priv->handsfree;
911 ucontrol->value.integer.value[0] = out->left_vol;
912 ucontrol->value.integer.value[1] = out->right_vol;
913 return 0;
914
915 default:
916 break;
917 }
918
919 return snd_soc_get_volsw_2r(kcontrol, ucontrol);
920}
921
922
923#define SOC_TWL6040_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax,\
924 xinvert, tlv_array)\
925{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
926 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
927 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
928 .tlv.p = (tlv_array), \
929 .info = snd_soc_info_volsw, .get = twl6040_get_volsw, \
930 .put = twl6040_put_volsw, \
931 .private_value = (unsigned long)&(struct soc_mixer_control) \
932 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
933 .max = xmax, .platform_max = xmax, .invert = xinvert} }
934
935
936#define SOC_TWL6040_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax,\
937 xinvert, tlv_array)\
938{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
939 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
940 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
941 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
942 .tlv.p = (tlv_array), \
943 .info = snd_soc_info_volsw_2r, \
944 .get = twl6040_get_volsw_2r, .put = twl6040_put_volsw_2r_vu, \
945 .private_value = (unsigned long)&(struct soc_mixer_control) \
946 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
947 .rshift = xshift, .max = xmax, .invert = xinvert}, }
948
949
950
951
952
953static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
954
955
956
957
958
959static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0);
960
961
962
963
964
965static DECLARE_TLV_DB_SCALE(afm_amp_tlv, -1800, 600, 0);
966
967
968
969
970
971static DECLARE_TLV_DB_SCALE(hs_tlv, -3000, 200, 0);
972
973
974
975
976
977static DECLARE_TLV_DB_SCALE(hf_tlv, -5200, 200, 0);
978
979
980
981
982
983static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0);
984
985
986static const char *twl6040_amicl_texts[] =
987 {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"};
988
989
990static const char *twl6040_amicr_texts[] =
991 {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
992
993static const struct soc_enum twl6040_enum[] = {
994 SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 4, twl6040_amicl_texts),
995 SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 4, twl6040_amicr_texts),
996};
997
998static const char *twl6040_hs_texts[] = {
999 "Off", "HS DAC", "Line-In amp"
1000};
1001
1002static const struct soc_enum twl6040_hs_enum[] = {
1003 SOC_ENUM_SINGLE(TWL6040_REG_HSLCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
1004 twl6040_hs_texts),
1005 SOC_ENUM_SINGLE(TWL6040_REG_HSRCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
1006 twl6040_hs_texts),
1007};
1008
1009static const char *twl6040_hf_texts[] = {
1010 "Off", "HF DAC", "Line-In amp"
1011};
1012
1013static const struct soc_enum twl6040_hf_enum[] = {
1014 SOC_ENUM_SINGLE(TWL6040_REG_HFLCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
1015 twl6040_hf_texts),
1016 SOC_ENUM_SINGLE(TWL6040_REG_HFRCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
1017 twl6040_hf_texts),
1018};
1019
1020static const struct snd_kcontrol_new amicl_control =
1021 SOC_DAPM_ENUM("Route", twl6040_enum[0]);
1022
1023static const struct snd_kcontrol_new amicr_control =
1024 SOC_DAPM_ENUM("Route", twl6040_enum[1]);
1025
1026
1027static const struct snd_kcontrol_new hsl_mux_controls =
1028 SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]);
1029
1030static const struct snd_kcontrol_new hsr_mux_controls =
1031 SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]);
1032
1033
1034static const struct snd_kcontrol_new hfl_mux_controls =
1035 SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]);
1036
1037static const struct snd_kcontrol_new hfr_mux_controls =
1038 SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
1039
1040static const struct snd_kcontrol_new ep_driver_switch_controls =
1041 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
1042
1043static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1044
1045 SOC_DOUBLE_TLV("Capture Preamplifier Volume",
1046 TWL6040_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv),
1047 SOC_DOUBLE_TLV("Capture Volume",
1048 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
1049
1050
1051 SOC_DOUBLE_TLV("Aux FM Volume",
1052 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
1053
1054
1055 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume",
1056 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
1057 SOC_TWL6040_DOUBLE_R_TLV("Handsfree Playback Volume",
1058 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
1059 SOC_SINGLE_TLV("Earphone Playback Volume",
1060 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
1061};
1062
1063static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
1064
1065 SND_SOC_DAPM_INPUT("MAINMIC"),
1066 SND_SOC_DAPM_INPUT("HSMIC"),
1067 SND_SOC_DAPM_INPUT("SUBMIC"),
1068 SND_SOC_DAPM_INPUT("AFML"),
1069 SND_SOC_DAPM_INPUT("AFMR"),
1070
1071
1072 SND_SOC_DAPM_OUTPUT("HSOL"),
1073 SND_SOC_DAPM_OUTPUT("HSOR"),
1074 SND_SOC_DAPM_OUTPUT("HFL"),
1075 SND_SOC_DAPM_OUTPUT("HFR"),
1076 SND_SOC_DAPM_OUTPUT("EP"),
1077
1078
1079 SND_SOC_DAPM_MUX("Analog Left Capture Route",
1080 SND_SOC_NOPM, 0, 0, &amicl_control),
1081 SND_SOC_DAPM_MUX("Analog Right Capture Route",
1082 SND_SOC_NOPM, 0, 0, &amicr_control),
1083
1084
1085 SND_SOC_DAPM_PGA("MicAmpL",
1086 TWL6040_REG_MICLCTL, 0, 0, NULL, 0),
1087 SND_SOC_DAPM_PGA("MicAmpR",
1088 TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
1089
1090
1091 SND_SOC_DAPM_PGA("AFMAmpL",
1092 TWL6040_REG_MICLCTL, 1, 0, NULL, 0),
1093 SND_SOC_DAPM_PGA("AFMAmpR",
1094 TWL6040_REG_MICRCTL, 1, 0, NULL, 0),
1095
1096
1097 SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
1098 TWL6040_REG_MICLCTL, 2, 0),
1099 SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture",
1100 TWL6040_REG_MICRCTL, 2, 0),
1101
1102
1103 SND_SOC_DAPM_MICBIAS("Headset Mic Bias",
1104 TWL6040_REG_AMICBCTL, 0, 0),
1105 SND_SOC_DAPM_MICBIAS("Main Mic Bias",
1106 TWL6040_REG_AMICBCTL, 4, 0),
1107 SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias",
1108 TWL6040_REG_DMICBCTL, 0, 0),
1109 SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias",
1110 TWL6040_REG_DMICBCTL, 4, 0),
1111
1112
1113 SND_SOC_DAPM_DAC_E("HSDAC Left", "Headset Playback",
1114 TWL6040_REG_HSLCTL, 0, 0,
1115 twl6040_hs_dac_event,
1116 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1117 SND_SOC_DAPM_DAC_E("HSDAC Right", "Headset Playback",
1118 TWL6040_REG_HSRCTL, 0, 0,
1119 twl6040_hs_dac_event,
1120 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1121 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback",
1122 TWL6040_REG_HFLCTL, 0, 0,
1123 twl6040_power_mode_event,
1124 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1125 SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback",
1126 TWL6040_REG_HFRCTL, 0, 0,
1127 twl6040_power_mode_event,
1128 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1129
1130 SND_SOC_DAPM_MUX("HF Left Playback",
1131 SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
1132 SND_SOC_DAPM_MUX("HF Right Playback",
1133 SND_SOC_NOPM, 0, 0, &hfr_mux_controls),
1134
1135 SND_SOC_DAPM_MUX("HS Left Playback",
1136 SND_SOC_NOPM, 0, 0, &hsl_mux_controls),
1137 SND_SOC_DAPM_MUX("HS Right Playback",
1138 SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
1139
1140
1141 SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver",
1142 TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
1143 pga_event,
1144 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1145 SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver",
1146 TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
1147 pga_event,
1148 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1149 SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver",
1150 TWL6040_REG_HSLCTL, 2, 0, NULL, 0,
1151 pga_event,
1152 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1153 SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver",
1154 TWL6040_REG_HSRCTL, 2, 0, NULL, 0,
1155 pga_event,
1156 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1157 SND_SOC_DAPM_SWITCH_E("Earphone Driver",
1158 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
1159 twl6040_power_mode_event,
1160 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1161
1162
1163 SND_SOC_DAPM_PGA("HFDAC Left PGA",
1164 TWL6040_REG_HFLCTL, 1, 0, NULL, 0),
1165 SND_SOC_DAPM_PGA("HFDAC Right PGA",
1166 TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
1167
1168};
1169
1170static const struct snd_soc_dapm_route intercon[] = {
1171
1172 {"Analog Left Capture Route", "Headset Mic", "HSMIC"},
1173 {"Analog Left Capture Route", "Main Mic", "MAINMIC"},
1174 {"Analog Left Capture Route", "Aux/FM Left", "AFML"},
1175
1176 {"Analog Right Capture Route", "Headset Mic", "HSMIC"},
1177 {"Analog Right Capture Route", "Sub Mic", "SUBMIC"},
1178 {"Analog Right Capture Route", "Aux/FM Right", "AFMR"},
1179
1180 {"MicAmpL", NULL, "Analog Left Capture Route"},
1181 {"MicAmpR", NULL, "Analog Right Capture Route"},
1182
1183 {"ADC Left", NULL, "MicAmpL"},
1184 {"ADC Right", NULL, "MicAmpR"},
1185
1186
1187 {"AFMAmpL", "NULL", "AFML"},
1188 {"AFMAmpR", "NULL", "AFMR"},
1189
1190 {"HS Left Playback", "HS DAC", "HSDAC Left"},
1191 {"HS Left Playback", "Line-In amp", "AFMAmpL"},
1192
1193 {"HS Right Playback", "HS DAC", "HSDAC Right"},
1194 {"HS Right Playback", "Line-In amp", "AFMAmpR"},
1195
1196 {"Headset Left Driver", "NULL", "HS Left Playback"},
1197 {"Headset Right Driver", "NULL", "HS Right Playback"},
1198
1199 {"HSOL", NULL, "Headset Left Driver"},
1200 {"HSOR", NULL, "Headset Right Driver"},
1201
1202
1203 {"Earphone Driver", "Switch", "HSDAC Left"},
1204 {"EP", NULL, "Earphone Driver"},
1205
1206 {"HF Left Playback", "HF DAC", "HFDAC Left"},
1207 {"HF Left Playback", "Line-In amp", "AFMAmpL"},
1208
1209 {"HF Right Playback", "HF DAC", "HFDAC Right"},
1210 {"HF Right Playback", "Line-In amp", "AFMAmpR"},
1211
1212 {"HFDAC Left PGA", NULL, "HF Left Playback"},
1213 {"HFDAC Right PGA", NULL, "HF Right Playback"},
1214
1215 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"},
1216 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"},
1217
1218 {"HFL", NULL, "Handsfree Left Driver"},
1219 {"HFR", NULL, "Handsfree Right Driver"},
1220};
1221
1222static int twl6040_add_widgets(struct snd_soc_codec *codec)
1223{
1224 struct snd_soc_dapm_context *dapm = &codec->dapm;
1225
1226 snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets,
1227 ARRAY_SIZE(twl6040_dapm_widgets));
1228 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1229 snd_soc_dapm_new_widgets(dapm);
1230
1231 return 0;
1232}
1233
1234static int twl6040_power_up_completion(struct snd_soc_codec *codec,
1235 int naudint)
1236{
1237 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1238 int time_left;
1239 u8 intid;
1240
1241 time_left = wait_for_completion_timeout(&priv->ready,
1242 msecs_to_jiffies(144));
1243
1244 if (!time_left) {
1245 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid,
1246 TWL6040_REG_INTID);
1247 if (!(intid & TWL6040_READYINT)) {
1248 dev_err(codec->dev, "timeout waiting for READYINT\n");
1249 return -ETIMEDOUT;
1250 }
1251 }
1252
1253 priv->codec_powered = 1;
1254
1255 return 0;
1256}
1257
1258static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1259 enum snd_soc_bias_level level)
1260{
1261 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1262 int audpwron = priv->audpwron;
1263 int naudint = priv->naudint;
1264 int ret;
1265
1266 switch (level) {
1267 case SND_SOC_BIAS_ON:
1268 break;
1269 case SND_SOC_BIAS_PREPARE:
1270 break;
1271 case SND_SOC_BIAS_STANDBY:
1272 if (priv->codec_powered)
1273 break;
1274
1275 if (gpio_is_valid(audpwron)) {
1276
1277 gpio_set_value(audpwron, 1);
1278
1279
1280 ret = twl6040_power_up_completion(codec, naudint);
1281 if (ret)
1282 return ret;
1283
1284
1285 twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
1286 twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
1287 twl6040_read_reg_volatile(codec, TWL6040_REG_LPPLLCTL);
1288 } else {
1289
1290 twl6040_power_up(codec);
1291 priv->codec_powered = 1;
1292 }
1293
1294
1295 twl6040_init_vdd_regs(codec);
1296
1297
1298 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
1299
1300
1301 twl6040_write(codec, TWL6040_REG_HSGAIN, 0xFF);
1302 twl6040_write(codec, TWL6040_REG_EARCTL, 0x1E);
1303 twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1D);
1304 twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1D);
1305 break;
1306 case SND_SOC_BIAS_OFF:
1307 if (!priv->codec_powered)
1308 break;
1309
1310 if (gpio_is_valid(audpwron)) {
1311
1312 gpio_set_value(audpwron, 0);
1313
1314
1315 udelay(500);
1316
1317
1318 twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
1319 twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
1320 twl6040_write_reg_cache(codec, TWL6040_REG_LPPLLCTL,
1321 0x00);
1322 } else {
1323
1324 twl6040_power_down(codec);
1325 }
1326
1327 priv->codec_powered = 0;
1328 break;
1329 }
1330
1331 codec->dapm.bias_level = level;
1332
1333 return 0;
1334}
1335
1336
1337
1338static unsigned int lp_rates[] = {
1339 88200,
1340 96000,
1341};
1342
1343static struct snd_pcm_hw_constraint_list lp_constraints = {
1344 .count = ARRAY_SIZE(lp_rates),
1345 .list = lp_rates,
1346};
1347
1348static unsigned int hp_rates[] = {
1349 96000,
1350};
1351
1352static struct snd_pcm_hw_constraint_list hp_constraints = {
1353 .count = ARRAY_SIZE(hp_rates),
1354 .list = hp_rates,
1355};
1356
1357static int twl6040_startup(struct snd_pcm_substream *substream,
1358 struct snd_soc_dai *dai)
1359{
1360 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1361 struct snd_soc_codec *codec = rtd->codec;
1362 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1363
1364 snd_pcm_hw_constraint_list(substream->runtime, 0,
1365 SNDRV_PCM_HW_PARAM_RATE,
1366 priv->sysclk_constraints);
1367
1368 return 0;
1369}
1370
1371static int twl6040_hw_params(struct snd_pcm_substream *substream,
1372 struct snd_pcm_hw_params *params,
1373 struct snd_soc_dai *dai)
1374{
1375 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1376 struct snd_soc_codec *codec = rtd->codec;
1377 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1378 u8 lppllctl;
1379 int rate;
1380
1381
1382 if (priv->pll == TWL6040_HPPLL_ID)
1383 return 0;
1384
1385 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
1386
1387 rate = params_rate(params);
1388 switch (rate) {
1389 case 11250:
1390 case 22500:
1391 case 44100:
1392 case 88200:
1393 lppllctl |= TWL6040_LPLLFIN;
1394 priv->sysclk = 17640000;
1395 break;
1396 case 8000:
1397 case 16000:
1398 case 32000:
1399 case 48000:
1400 case 96000:
1401 lppllctl &= ~TWL6040_LPLLFIN;
1402 priv->sysclk = 19200000;
1403 break;
1404 default:
1405 dev_err(codec->dev, "unsupported rate %d\n", rate);
1406 return -EINVAL;
1407 }
1408
1409 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1410
1411 return 0;
1412}
1413
1414static int twl6040_prepare(struct snd_pcm_substream *substream,
1415 struct snd_soc_dai *dai)
1416{
1417 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1418 struct snd_soc_codec *codec = rtd->codec;
1419 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1420
1421 if (!priv->sysclk) {
1422 dev_err(codec->dev,
1423 "no mclk configured, call set_sysclk() on init\n");
1424 return -EINVAL;
1425 }
1426
1427
1428
1429
1430
1431 if ((priv->sysclk == 17640000) &&
1432 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
1433 dev_err(codec->dev,
1434 "capture mode is not supported at %dHz\n",
1435 priv->sysclk);
1436 return -EINVAL;
1437 }
1438
1439 if ((priv->sysclk == 17640000) && priv->non_lp) {
1440 dev_err(codec->dev,
1441 "some enabled paths aren't supported at %dHz\n",
1442 priv->sysclk);
1443 return -EPERM;
1444 }
1445 return 0;
1446}
1447
1448static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1449 int clk_id, unsigned int freq, int dir)
1450{
1451 struct snd_soc_codec *codec = codec_dai->codec;
1452 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1453 u8 hppllctl, lppllctl;
1454
1455 hppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_HPPLLCTL);
1456 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
1457
1458 switch (clk_id) {
1459 case TWL6040_SYSCLK_SEL_LPPLL:
1460 switch (freq) {
1461 case 32768:
1462
1463 headset_power_mode(codec, 0);
1464
1465
1466 lppllctl |= TWL6040_LPLLENA;
1467 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1468 mdelay(5);
1469 lppllctl &= ~TWL6040_HPLLSEL;
1470 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1471 hppllctl &= ~TWL6040_HPLLENA;
1472 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
1473 break;
1474 default:
1475 dev_err(codec->dev, "unknown mclk freq %d\n", freq);
1476 return -EINVAL;
1477 }
1478
1479
1480 switch (priv->sysclk) {
1481 case 17640000:
1482 lppllctl |= TWL6040_LPLLFIN;
1483 break;
1484 case 19200000:
1485 lppllctl &= ~TWL6040_LPLLFIN;
1486 break;
1487 default:
1488
1489 lppllctl &= ~TWL6040_LPLLFIN;
1490 priv->sysclk = 19200000;
1491 break;
1492 }
1493
1494 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1495
1496 priv->pll = TWL6040_LPPLL_ID;
1497 priv->sysclk_constraints = &lp_constraints;
1498 break;
1499 case TWL6040_SYSCLK_SEL_HPPLL:
1500 hppllctl &= ~TWL6040_MCLK_MSK;
1501
1502 switch (freq) {
1503 case 12000000:
1504
1505 hppllctl |= TWL6040_MCLK_12000KHZ |
1506 TWL6040_HPLLSQRBP |
1507 TWL6040_HPLLENA;
1508 break;
1509 case 19200000:
1510
1511 hppllctl |= TWL6040_MCLK_19200KHZ |
1512 TWL6040_HPLLSQRENA |
1513 TWL6040_HPLLBP;
1514 break;
1515 case 26000000:
1516
1517 hppllctl |= TWL6040_MCLK_26000KHZ |
1518 TWL6040_HPLLSQRBP |
1519 TWL6040_HPLLENA;
1520 break;
1521 case 38400000:
1522
1523 hppllctl |= TWL6040_MCLK_38400KHZ |
1524 TWL6040_HPLLSQRENA |
1525 TWL6040_HPLLBP;
1526 break;
1527 default:
1528 dev_err(codec->dev, "unknown mclk freq %d\n", freq);
1529 return -EINVAL;
1530 }
1531
1532
1533 headset_power_mode(codec, 1);
1534
1535 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
1536 udelay(500);
1537 lppllctl |= TWL6040_HPLLSEL;
1538 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1539 lppllctl &= ~TWL6040_LPLLENA;
1540 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
1541
1542
1543 priv->pll = TWL6040_HPPLL_ID;
1544 priv->sysclk = 19200000;
1545 priv->sysclk_constraints = &hp_constraints;
1546 break;
1547 default:
1548 dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
1549 return -EINVAL;
1550 }
1551
1552 return 0;
1553}
1554
1555static struct snd_soc_dai_ops twl6040_dai_ops = {
1556 .startup = twl6040_startup,
1557 .hw_params = twl6040_hw_params,
1558 .prepare = twl6040_prepare,
1559 .set_sysclk = twl6040_set_dai_sysclk,
1560};
1561
1562static struct snd_soc_dai_driver twl6040_dai = {
1563 .name = "twl6040-hifi",
1564 .playback = {
1565 .stream_name = "Playback",
1566 .channels_min = 1,
1567 .channels_max = 4,
1568 .rates = TWL6040_RATES,
1569 .formats = TWL6040_FORMATS,
1570 },
1571 .capture = {
1572 .stream_name = "Capture",
1573 .channels_min = 1,
1574 .channels_max = 2,
1575 .rates = TWL6040_RATES,
1576 .formats = TWL6040_FORMATS,
1577 },
1578 .ops = &twl6040_dai_ops,
1579};
1580
1581#ifdef CONFIG_PM
1582static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state)
1583{
1584 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1585
1586 return 0;
1587}
1588
1589static int twl6040_resume(struct snd_soc_codec *codec)
1590{
1591 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1592 twl6040_set_bias_level(codec, codec->dapm.suspend_bias_level);
1593
1594 return 0;
1595}
1596#else
1597#define twl6040_suspend NULL
1598#define twl6040_resume NULL
1599#endif
1600
1601static int twl6040_probe(struct snd_soc_codec *codec)
1602{
1603 struct twl4030_codec_data *twl_codec = codec->dev->platform_data;
1604 struct twl6040_data *priv;
1605 int audpwron, naudint;
1606 int ret = 0;
1607 u8 icrev, intmr = TWL6040_ALLINT_MSK;
1608
1609 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
1610 if (priv == NULL)
1611 return -ENOMEM;
1612 snd_soc_codec_set_drvdata(codec, priv);
1613
1614 priv->codec = codec;
1615
1616 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &icrev, TWL6040_REG_ASICREV);
1617
1618 if (twl_codec && (icrev > 0))
1619 audpwron = twl_codec->audpwron_gpio;
1620 else
1621 audpwron = -EINVAL;
1622
1623 if (twl_codec)
1624 naudint = twl_codec->naudint_irq;
1625 else
1626 naudint = 0;
1627
1628 priv->audpwron = audpwron;
1629 priv->naudint = naudint;
1630 priv->workqueue = create_singlethread_workqueue("twl6040-codec");
1631
1632 if (!priv->workqueue) {
1633 ret = -ENOMEM;
1634 goto work_err;
1635 }
1636
1637 INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work);
1638
1639 mutex_init(&priv->mutex);
1640
1641 init_completion(&priv->ready);
1642 init_completion(&priv->headset.ramp_done);
1643 init_completion(&priv->handsfree.ramp_done);
1644
1645 if (gpio_is_valid(audpwron)) {
1646 ret = gpio_request(audpwron, "audpwron");
1647 if (ret)
1648 goto gpio1_err;
1649
1650 ret = gpio_direction_output(audpwron, 0);
1651 if (ret)
1652 goto gpio2_err;
1653
1654 priv->codec_powered = 0;
1655
1656
1657 intmr &= ~(TWL6040_READYMSK | TWL6040_PLUGMSK);
1658
1659
1660 twl6040_read_reg_volatile(codec, TWL6040_REG_INTID);
1661 }
1662 twl6040_write(codec, TWL6040_REG_INTMR, intmr);
1663
1664 if (naudint) {
1665
1666 ret = request_threaded_irq(naudint, NULL,
1667 twl6040_naudint_handler,
1668 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1669 "twl6040_codec", codec);
1670 if (ret)
1671 goto gpio2_err;
1672 }
1673
1674
1675 twl6040_init_vio_regs(codec);
1676
1677 priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf");
1678 if (priv->hf_workqueue == NULL) {
1679 ret = -ENOMEM;
1680 goto irq_err;
1681 }
1682 priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs");
1683 if (priv->hs_workqueue == NULL) {
1684 ret = -ENOMEM;
1685 goto wq_err;
1686 }
1687
1688 INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work);
1689 INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work);
1690
1691
1692 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1693 if (ret)
1694 goto bias_err;
1695
1696 snd_soc_add_controls(codec, twl6040_snd_controls,
1697 ARRAY_SIZE(twl6040_snd_controls));
1698 twl6040_add_widgets(codec);
1699
1700 return 0;
1701
1702bias_err:
1703 destroy_workqueue(priv->hs_workqueue);
1704wq_err:
1705 destroy_workqueue(priv->hf_workqueue);
1706irq_err:
1707 if (naudint)
1708 free_irq(naudint, codec);
1709gpio2_err:
1710 if (gpio_is_valid(audpwron))
1711 gpio_free(audpwron);
1712gpio1_err:
1713 destroy_workqueue(priv->workqueue);
1714work_err:
1715 kfree(priv);
1716 return ret;
1717}
1718
1719static int twl6040_remove(struct snd_soc_codec *codec)
1720{
1721 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1722 int audpwron = priv->audpwron;
1723 int naudint = priv->naudint;
1724
1725 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1726
1727 if (gpio_is_valid(audpwron))
1728 gpio_free(audpwron);
1729
1730 if (naudint)
1731 free_irq(naudint, codec);
1732
1733 destroy_workqueue(priv->workqueue);
1734 destroy_workqueue(priv->hf_workqueue);
1735 destroy_workqueue(priv->hs_workqueue);
1736 kfree(priv);
1737
1738 return 0;
1739}
1740
1741static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1742 .probe = twl6040_probe,
1743 .remove = twl6040_remove,
1744 .suspend = twl6040_suspend,
1745 .resume = twl6040_resume,
1746 .read = twl6040_read_reg_cache,
1747 .write = twl6040_write,
1748 .set_bias_level = twl6040_set_bias_level,
1749 .reg_cache_size = ARRAY_SIZE(twl6040_reg),
1750 .reg_word_size = sizeof(u8),
1751 .reg_cache_default = twl6040_reg,
1752};
1753
1754static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1755{
1756 return snd_soc_register_codec(&pdev->dev,
1757 &soc_codec_dev_twl6040, &twl6040_dai, 1);
1758}
1759
1760static int __devexit twl6040_codec_remove(struct platform_device *pdev)
1761{
1762 snd_soc_unregister_codec(&pdev->dev);
1763 return 0;
1764}
1765
1766static struct platform_driver twl6040_codec_driver = {
1767 .driver = {
1768 .name = "twl6040-codec",
1769 .owner = THIS_MODULE,
1770 },
1771 .probe = twl6040_codec_probe,
1772 .remove = __devexit_p(twl6040_codec_remove),
1773};
1774
1775static int __init twl6040_codec_init(void)
1776{
1777 return platform_driver_register(&twl6040_codec_driver);
1778}
1779module_init(twl6040_codec_init);
1780
1781static void __exit twl6040_codec_exit(void)
1782{
1783 platform_driver_unregister(&twl6040_codec_driver);
1784}
1785module_exit(twl6040_codec_exit);
1786
1787MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
1788MODULE_AUTHOR("Misael Lopez Cruz");
1789MODULE_LICENSE("GPL");
1790