aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorAxel Castaneda Gonzalez <x0055901@ti.com>2011-02-23 21:08:28 -0500
committerPeter Ujfalusi <peter.ujfalusi@ti.com>2011-07-04 12:36:29 -0400
commit1fbe99529d9490fd29982af07731650f112ffdfa (patch)
treef65de0c7602c079cc24c34e233c19dd9db1770a8 /sound
parentf7026c99961da48cc4c09cc4f152db5fb30832e7 (diff)
ASoC: twl6040: Configure ramp step based on platform
Enable ramp down/up step to be configured based on platform. Signed-off-by: Axel Castaneda Gonzalez <x0055901@ti.com> Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/twl6040.c91
1 files changed, 71 insertions, 20 deletions
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 39ecf2f4940d..014504180ff8 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -83,6 +83,10 @@ struct twl6040_data {
83 int hs_power_mode_locked; 83 int hs_power_mode_locked;
84 unsigned int clk_in; 84 unsigned int clk_in;
85 unsigned int sysclk; 85 unsigned int sysclk;
86 u16 hs_left_step;
87 u16 hs_right_step;
88 u16 hf_left_step;
89 u16 hf_right_step;
86 struct snd_pcm_hw_constraint_list *sysclk_constraints; 90 struct snd_pcm_hw_constraint_list *sysclk_constraints;
87 struct twl6040_jack_data hs_jack; 91 struct twl6040_jack_data hs_jack;
88 struct snd_soc_codec *codec; 92 struct snd_soc_codec *codec;
@@ -339,7 +343,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
339 if (headset->ramp == TWL6040_RAMP_UP) { 343 if (headset->ramp == TWL6040_RAMP_UP) {
340 /* ramp step up */ 344 /* ramp step up */
341 if (val < headset->left_vol) { 345 if (val < headset->left_vol) {
342 val += left_step; 346 if (val + left_step > headset->left_vol)
347 val = headset->left_vol;
348 else
349 val += left_step;
350
343 reg &= ~TWL6040_HSL_VOL_MASK; 351 reg &= ~TWL6040_HSL_VOL_MASK;
344 twl6040_write(codec, TWL6040_REG_HSGAIN, 352 twl6040_write(codec, TWL6040_REG_HSGAIN,
345 (reg | (~val & TWL6040_HSL_VOL_MASK))); 353 (reg | (~val & TWL6040_HSL_VOL_MASK)));
@@ -349,7 +357,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
349 } else if (headset->ramp == TWL6040_RAMP_DOWN) { 357 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
350 /* ramp step down */ 358 /* ramp step down */
351 if (val > 0x0) { 359 if (val > 0x0) {
352 val -= left_step; 360 if ((int)val - (int)left_step < 0)
361 val = 0;
362 else
363 val -= left_step;
364
353 reg &= ~TWL6040_HSL_VOL_MASK; 365 reg &= ~TWL6040_HSL_VOL_MASK;
354 twl6040_write(codec, TWL6040_REG_HSGAIN, reg | 366 twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
355 (~val & TWL6040_HSL_VOL_MASK)); 367 (~val & TWL6040_HSL_VOL_MASK));
@@ -366,7 +378,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
366 if (headset->ramp == TWL6040_RAMP_UP) { 378 if (headset->ramp == TWL6040_RAMP_UP) {
367 /* ramp step up */ 379 /* ramp step up */
368 if (val < headset->right_vol) { 380 if (val < headset->right_vol) {
369 val += right_step; 381 if (val + right_step > headset->right_vol)
382 val = headset->right_vol;
383 else
384 val += right_step;
385
370 reg &= ~TWL6040_HSR_VOL_MASK; 386 reg &= ~TWL6040_HSR_VOL_MASK;
371 twl6040_write(codec, TWL6040_REG_HSGAIN, 387 twl6040_write(codec, TWL6040_REG_HSGAIN,
372 (reg | (~val << TWL6040_HSR_VOL_SHIFT))); 388 (reg | (~val << TWL6040_HSR_VOL_SHIFT)));
@@ -376,7 +392,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
376 } else if (headset->ramp == TWL6040_RAMP_DOWN) { 392 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
377 /* ramp step down */ 393 /* ramp step down */
378 if (val > 0x0) { 394 if (val > 0x0) {
379 val -= right_step; 395 if ((int)val - (int)right_step < 0)
396 val = 0;
397 else
398 val -= right_step;
399
380 reg &= ~TWL6040_HSR_VOL_MASK; 400 reg &= ~TWL6040_HSR_VOL_MASK;
381 twl6040_write(codec, TWL6040_REG_HSGAIN, 401 twl6040_write(codec, TWL6040_REG_HSGAIN,
382 reg | (~val << TWL6040_HSR_VOL_SHIFT)); 402 reg | (~val << TWL6040_HSR_VOL_SHIFT));
@@ -407,7 +427,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
407 if (handsfree->ramp == TWL6040_RAMP_UP) { 427 if (handsfree->ramp == TWL6040_RAMP_UP) {
408 /* ramp step up */ 428 /* ramp step up */
409 if (val < handsfree->left_vol) { 429 if (val < handsfree->left_vol) {
410 val += left_step; 430 if (val + left_step > handsfree->left_vol)
431 val = handsfree->left_vol;
432 else
433 val += left_step;
434
411 reg &= ~TWL6040_HF_VOL_MASK; 435 reg &= ~TWL6040_HF_VOL_MASK;
412 twl6040_write(codec, TWL6040_REG_HFLGAIN, 436 twl6040_write(codec, TWL6040_REG_HFLGAIN,
413 reg | (0x1D - val)); 437 reg | (0x1D - val));
@@ -417,7 +441,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
417 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) { 441 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
418 /* ramp step down */ 442 /* ramp step down */
419 if (val > 0) { 443 if (val > 0) {
420 val -= left_step; 444 if ((int)val - (int)left_step < 0)
445 val = 0;
446 else
447 val -= left_step;
448
421 reg &= ~TWL6040_HF_VOL_MASK; 449 reg &= ~TWL6040_HF_VOL_MASK;
422 twl6040_write(codec, TWL6040_REG_HFLGAIN, 450 twl6040_write(codec, TWL6040_REG_HFLGAIN,
423 reg | (0x1D - val)); 451 reg | (0x1D - val));
@@ -434,7 +462,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
434 if (handsfree->ramp == TWL6040_RAMP_UP) { 462 if (handsfree->ramp == TWL6040_RAMP_UP) {
435 /* ramp step up */ 463 /* ramp step up */
436 if (val < handsfree->right_vol) { 464 if (val < handsfree->right_vol) {
437 val += right_step; 465 if (val + right_step > handsfree->right_vol)
466 val = handsfree->right_vol;
467 else
468 val += right_step;
469
438 reg &= ~TWL6040_HF_VOL_MASK; 470 reg &= ~TWL6040_HF_VOL_MASK;
439 twl6040_write(codec, TWL6040_REG_HFRGAIN, 471 twl6040_write(codec, TWL6040_REG_HFRGAIN,
440 reg | (0x1D - val)); 472 reg | (0x1D - val));
@@ -444,7 +476,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
444 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) { 476 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
445 /* ramp step down */ 477 /* ramp step down */
446 if (val > 0) { 478 if (val > 0) {
447 val -= right_step; 479 if ((int)val - (int)right_step < 0)
480 val = 0;
481 else
482 val -= right_step;
483
448 reg &= ~TWL6040_HF_VOL_MASK; 484 reg &= ~TWL6040_HF_VOL_MASK;
449 twl6040_write(codec, TWL6040_REG_HFRGAIN, 485 twl6040_write(codec, TWL6040_REG_HFRGAIN,
450 reg | (0x1D - val)); 486 reg | (0x1D - val));
@@ -473,11 +509,9 @@ static void twl6040_pga_hs_work(struct work_struct *work)
473 509
474 /* HS PGA volumes have 4 bits of resolution to ramp */ 510 /* HS PGA volumes have 4 bits of resolution to ramp */
475 for (i = 0; i <= 16; i++) { 511 for (i = 0; i <= 16; i++) {
476 headset_complete = 1; 512 headset_complete = twl6040_hs_ramp_step(codec,
477 if (headset->ramp != TWL6040_RAMP_NONE) 513 headset->left_step,
478 headset_complete = twl6040_hs_ramp_step(codec, 514 headset->right_step);
479 headset->left_step,
480 headset->right_step);
481 515
482 /* ramp finished ? */ 516 /* ramp finished ? */
483 if (headset_complete) 517 if (headset_complete)
@@ -518,11 +552,9 @@ static void twl6040_pga_hf_work(struct work_struct *work)
518 552
519 /* HF PGA volumes have 5 bits of resolution to ramp */ 553 /* HF PGA volumes have 5 bits of resolution to ramp */
520 for (i = 0; i <= 32; i++) { 554 for (i = 0; i <= 32; i++) {
521 handsfree_complete = 1; 555 handsfree_complete = twl6040_hf_ramp_step(codec,
522 if (handsfree->ramp != TWL6040_RAMP_NONE) 556 handsfree->left_step,
523 handsfree_complete = twl6040_hf_ramp_step(codec, 557 handsfree->right_step);
524 handsfree->left_step,
525 handsfree->right_step);
526 558
527 /* ramp finished ? */ 559 /* ramp finished ? */
528 if (handsfree_complete) 560 if (handsfree_complete)
@@ -563,12 +595,16 @@ static int pga_event(struct snd_soc_dapm_widget *w,
563 out = &priv->headset; 595 out = &priv->headset;
564 work = &priv->hs_delayed_work; 596 work = &priv->hs_delayed_work;
565 queue = priv->hs_workqueue; 597 queue = priv->hs_workqueue;
598 out->left_step = priv->hs_left_step;
599 out->right_step = priv->hs_right_step;
566 out->step_delay = 5; /* 5 ms between volume ramp steps */ 600 out->step_delay = 5; /* 5 ms between volume ramp steps */
567 break; 601 break;
568 case 4: 602 case 4:
569 out = &priv->handsfree; 603 out = &priv->handsfree;
570 work = &priv->hf_delayed_work; 604 work = &priv->hf_delayed_work;
571 queue = priv->hf_workqueue; 605 queue = priv->hf_workqueue;
606 out->left_step = priv->hf_left_step;
607 out->right_step = priv->hf_right_step;
572 out->step_delay = 5; /* 5 ms between volume ramp steps */ 608 out->step_delay = 5; /* 5 ms between volume ramp steps */
573 if (SND_SOC_DAPM_EVENT_ON(event)) 609 if (SND_SOC_DAPM_EVENT_ON(event))
574 priv->non_lp++; 610 priv->non_lp++;
@@ -601,8 +637,6 @@ static int pga_event(struct snd_soc_dapm_widget *w,
601 637
602 if (!delayed_work_pending(work)) { 638 if (!delayed_work_pending(work)) {
603 /* use volume ramp for power-down */ 639 /* use volume ramp for power-down */
604 out->left_step = 1;
605 out->right_step = 1;
606 out->ramp = TWL6040_RAMP_DOWN; 640 out->ramp = TWL6040_RAMP_DOWN;
607 INIT_COMPLETION(out->ramp_done); 641 INIT_COMPLETION(out->ramp_done);
608 642
@@ -1492,6 +1526,7 @@ static int twl6040_resume(struct snd_soc_codec *codec)
1492static int twl6040_probe(struct snd_soc_codec *codec) 1526static int twl6040_probe(struct snd_soc_codec *codec)
1493{ 1527{
1494 struct twl6040_data *priv; 1528 struct twl6040_data *priv;
1529 struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
1495 int ret = 0; 1530 int ret = 0;
1496 1531
1497 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); 1532 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
@@ -1502,6 +1537,22 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1502 priv->codec = codec; 1537 priv->codec = codec;
1503 codec->control_data = dev_get_drvdata(codec->dev->parent); 1538 codec->control_data = dev_get_drvdata(codec->dev->parent);
1504 1539
1540 if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
1541 priv->hs_left_step = pdata->hs_left_step;
1542 priv->hs_right_step = pdata->hs_right_step;
1543 } else {
1544 priv->hs_left_step = 1;
1545 priv->hs_right_step = 1;
1546 }
1547
1548 if (pdata && pdata->hf_left_step && pdata->hf_right_step) {
1549 priv->hf_left_step = pdata->hf_left_step;
1550 priv->hf_right_step = pdata->hf_right_step;
1551 } else {
1552 priv->hf_left_step = 1;
1553 priv->hf_right_step = 1;
1554 }
1555
1505 priv->sysclk_constraints = &hp_constraints; 1556 priv->sysclk_constraints = &hp_constraints;
1506 priv->workqueue = create_singlethread_workqueue("twl6040-codec"); 1557 priv->workqueue = create_singlethread_workqueue("twl6040-codec");
1507 if (!priv->workqueue) { 1558 if (!priv->workqueue) {