summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorAxel Castaneda Gonzalez <x0055901@ti.com>2011-05-31 09:23:13 +0100
committerAndy Green <andy.green@linaro.org>2011-05-31 11:04:43 +0100
commit8d8204fd831715ace98d0714c14eeb4e4f02c0e2 (patch)
tree26b8e759f5aba3b83339485b216001d6d6c75eb0 /sound
parente92d2a02493c18802070ce600a3943caae0ec4da (diff)
ASoC: twl6040: Configure ramp step based on platform
Enable ramp down/up step to be configured based on platform. Change-Id: I4e5aff8b9b6ab477919e5f98af71e77dfd370e92 Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com> Signed-off-by: Axel Castaneda Gonzalez <x0055901@ti.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 f7795846237..d41ffecebd6 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -85,6 +85,10 @@ struct twl6040_data {
int headset_mode;
unsigned int clk_in;
unsigned int sysclk;
+ u16 left_step_hs;
+ u16 right_step_hs;
+ u16 left_step_hf;
+ u16 right_step_hf;
struct snd_pcm_hw_constraint_list *sysclk_constraints;
struct twl6040_jack_data hs_jack;
struct snd_soc_codec *codec;
@@ -340,7 +344,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
if (headset->ramp == TWL6040_RAMP_UP) {
/* ramp step up */
if (val < headset->left_vol) {
- val += left_step;
+ if (val + left_step > headset->left_vol)
+ val = headset->left_vol;
+ else
+ val += left_step;
+
reg &= ~TWL6040_HSL_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HSGAIN,
(reg | (~val & TWL6040_HSL_VOL_MASK)));
@@ -350,7 +358,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
} else if (headset->ramp == TWL6040_RAMP_DOWN) {
/* ramp step down */
if (val > 0x0) {
- val -= left_step;
+ if ((int)val - (int)left_step < 0)
+ val = 0;
+ else
+ val -= left_step;
+
reg &= ~TWL6040_HSL_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
(~val & TWL6040_HSL_VOL_MASK));
@@ -367,7 +379,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
if (headset->ramp == TWL6040_RAMP_UP) {
/* ramp step up */
if (val < headset->right_vol) {
- val += right_step;
+ if (val + right_step > headset->right_vol)
+ val = headset->right_vol;
+ else
+ val += right_step;
+
reg &= ~TWL6040_HSR_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HSGAIN,
(reg | (~val << TWL6040_HSR_VOL_SHIFT)));
@@ -377,7 +393,11 @@ static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
} else if (headset->ramp == TWL6040_RAMP_DOWN) {
/* ramp step down */
if (val > 0x0) {
- val -= right_step;
+ if ((int)val - (int)right_step < 0)
+ val = 0;
+ else
+ val -= right_step;
+
reg &= ~TWL6040_HSR_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HSGAIN,
reg | (~val << TWL6040_HSR_VOL_SHIFT));
@@ -408,7 +428,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
if (handsfree->ramp == TWL6040_RAMP_UP) {
/* ramp step up */
if (val < handsfree->left_vol) {
- val += left_step;
+ if (val + left_step > handsfree->left_vol)
+ val = handsfree->left_vol;
+ else
+ val += left_step;
+
reg &= ~TWL6040_HF_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HFLGAIN,
reg | (0x1D - val));
@@ -418,7 +442,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
} else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
/* ramp step down */
if (val > 0) {
- val -= left_step;
+ if ((int)val - (int)left_step < 0)
+ val = 0;
+ else
+ val -= left_step;
+
reg &= ~TWL6040_HF_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HFLGAIN,
reg | (0x1D - val));
@@ -435,7 +463,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
if (handsfree->ramp == TWL6040_RAMP_UP) {
/* ramp step up */
if (val < handsfree->right_vol) {
- val += right_step;
+ if (val + right_step > handsfree->right_vol)
+ val = handsfree->right_vol;
+ else
+ val += right_step;
+
reg &= ~TWL6040_HF_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HFRGAIN,
reg | (0x1D - val));
@@ -445,7 +477,11 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
} else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
/* ramp step down */
if (val > 0) {
- val -= right_step;
+ if ((int)val - (int)right_step < 0)
+ val = 0;
+ else
+ val -= right_step;
+
reg &= ~TWL6040_HF_VOL_MASK;
twl6040_write(codec, TWL6040_REG_HFRGAIN,
reg | (0x1D - val));
@@ -474,11 +510,9 @@ static void twl6040_pga_hs_work(struct work_struct *work)
/* HS PGA volumes have 4 bits of resolution to ramp */
for (i = 0; i <= 16; i++) {
- headset_complete = 1;
- if (headset->ramp != TWL6040_RAMP_NONE)
- headset_complete = twl6040_hs_ramp_step(codec,
- headset->left_step,
- headset->right_step);
+ headset_complete = twl6040_hs_ramp_step(codec,
+ headset->left_step,
+ headset->right_step);
/* ramp finished ? */
if (headset_complete)
@@ -519,11 +553,9 @@ static void twl6040_pga_hf_work(struct work_struct *work)
/* HF PGA volumes have 5 bits of resolution to ramp */
for (i = 0; i <= 32; i++) {
- handsfree_complete = 1;
- if (handsfree->ramp != TWL6040_RAMP_NONE)
- handsfree_complete = twl6040_hf_ramp_step(codec,
- handsfree->left_step,
- handsfree->right_step);
+ handsfree_complete = twl6040_hf_ramp_step(codec,
+ handsfree->left_step,
+ handsfree->right_step);
/* ramp finished ? */
if (handsfree_complete)
@@ -564,12 +596,16 @@ static int pga_event(struct snd_soc_dapm_widget *w,
out = &priv->headset;
work = &priv->hs_delayed_work;
queue = priv->hs_workqueue;
+ out->left_step = priv->left_step_hs;
+ out->right_step = priv->right_step_hs;
out->step_delay = 5; /* 5 ms between volume ramp steps */
break;
case 4:
out = &priv->handsfree;
work = &priv->hf_delayed_work;
queue = priv->hf_workqueue;
+ out->left_step = priv->left_step_hf;
+ out->right_step = priv->right_step_hf;
out->step_delay = 5; /* 5 ms between volume ramp steps */
if (SND_SOC_DAPM_EVENT_ON(event))
priv->non_lp++;
@@ -602,8 +638,6 @@ static int pga_event(struct snd_soc_dapm_widget *w,
if (!delayed_work_pending(work)) {
/* use volume ramp for power-down */
- out->left_step = 1;
- out->right_step = 1;
out->ramp = TWL6040_RAMP_DOWN;
INIT_COMPLETION(out->ramp_done);
@@ -1483,6 +1517,7 @@ static int twl6040_resume(struct snd_soc_codec *codec)
static int twl6040_probe(struct snd_soc_codec *codec)
{
struct twl6040_data *priv;
+ struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev);
int ret = 0;
priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
@@ -1493,6 +1528,22 @@ static int twl6040_probe(struct snd_soc_codec *codec)
priv->codec = codec;
codec->control_data = dev_get_drvdata(codec->dev->parent);
+ if (pdata && pdata->left_step_hs && pdata->right_step_hs) {
+ priv->left_step_hs = pdata->left_step_hs;
+ priv->right_step_hs = pdata->right_step_hs;
+ } else {
+ priv->left_step_hs = 1;
+ priv->right_step_hs = 1;
+ }
+
+ if (pdata && pdata->left_step_hf && pdata->right_step_hf) {
+ priv->left_step_hf = pdata->left_step_hf;
+ priv->right_step_hf = pdata->right_step_hf;
+ } else {
+ priv->left_step_hf = 1;
+ priv->right_step_hf = 1;
+ }
+
/* default is high-performance mode */
priv->headset_mode = 1;
priv->workqueue = create_singlethread_workqueue("twl6040-codec");