diff options
author | Lee Jones <lee.jones@linaro.org> | 2011-07-26 17:31:06 +0100 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2011-07-26 17:35:08 +0100 |
commit | 6f914cb1efe4aba81bb841ec8f4f5636163c0586 (patch) | |
tree | 7ef04a88618a05c53faa2fd4ccd03e90c06a89bd /sound | |
parent | 232bdfad970ce35177ca12c5527d1c96f7ce44f1 (diff) |
Apply mega patch to make GLK the ALK
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/ab8500_audio.c | 63 | ||||
-rw-r--r-- | sound/soc/codecs/ab8500_audio.h | 4 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 19 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_ab8500.c | 34 |
4 files changed, 105 insertions, 15 deletions
diff --git a/sound/soc/codecs/ab8500_audio.c b/sound/soc/codecs/ab8500_audio.c index 7a87890507c..f65ebe5b786 100644 --- a/sound/soc/codecs/ab8500_audio.c +++ b/sound/soc/codecs/ab8500_audio.c @@ -46,13 +46,10 @@ #define GPIO27_DIR_OUTPUT 0x04 #define GPIO29_DIR_OUTPUT 0x10 #define GPIO31_DIR_OUTPUT 0x40 -#define GPIO35_DIR_OUTPUT 0x04 /* Macrocell register definitions */ #define AB8500_CTRL3_REG 0x0200 #define AB8500_GPIO_DIR4_REG 0x1013 -#define AB8500_GPIO_DIR5_REG 0x1014 -#define AB8500_GPIO_OUT5_REG 0x1024 /* * AB8500 register cache & default register settings @@ -1856,7 +1853,65 @@ void ab8500_audio_power_control(bool power_on) } } -/* Extended interface for codec-driver */ +void ab8500_audio_pwm_vibra(unsigned char speed_left_pos, + unsigned char speed_left_neg, + unsigned char speed_right_pos, + unsigned char speed_right_neg) +{ + unsigned int clear_mask, set_mask; + bool vibra_on; + + if (ab8500_codec == NULL) { + pr_err("%s: ERROR: AB8500 ASoC-driver not yet probed!\n", __func__); + return; + } + + vibra_on = speed_left_pos | speed_left_neg | speed_right_pos | speed_right_neg; + if (!vibra_on) { + clear_mask = BMASK(REG_ANACONF4_ENVIB1) | BMASK(REG_ANACONF4_ENVIB2); + ab8500_codec_update_reg_audio(ab8500_codec, REG_ANACONF4, clear_mask, 0x00); + speed_left_pos = 0; + speed_left_neg = 0; + speed_right_pos = 0; + speed_right_neg = 0; + } + + pr_debug("%s: PWM-vibra (%d, %d, %d, %d).\n", + __func__, + speed_left_pos, + speed_left_neg, + speed_right_pos, + speed_right_neg); + + set_mask = BMASK(REG_PWMGENCONF1_PWMTOVIB1) | + BMASK(REG_PWMGENCONF1_PWMTOVIB2) | + BMASK(REG_PWMGENCONF1_PWM1CTRL) | + BMASK(REG_PWMGENCONF1_PWM2CTRL) | + BMASK(REG_PWMGENCONF1_PWM1NCTRL) | + BMASK(REG_PWMGENCONF1_PWM1PCTRL) | + BMASK(REG_PWMGENCONF1_PWM2NCTRL) | + BMASK(REG_PWMGENCONF1_PWM2PCTRL); + ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF1, 0x00, set_mask); + + if (speed_left_pos > REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX) + speed_left_pos = REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX; + ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF3, REG_MASK_ALL, speed_left_pos); + + if (speed_left_neg > REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX) + speed_left_neg = REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX; + ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF2, REG_MASK_ALL, speed_left_neg); + + if (speed_right_pos > REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX) + speed_right_pos = REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX; + ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF5, REG_MASK_ALL, speed_right_pos); + + if (speed_right_neg > REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX) + speed_right_neg = REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX; + ab8500_codec_update_reg_audio(ab8500_codec, REG_PWMGENCONF4, REG_MASK_ALL, speed_right_neg); + + set_mask = BMASK(REG_ANACONF4_ENVIB1) | BMASK(REG_ANACONF4_ENVIB2); + ab8500_codec_update_reg_audio(ab8500_codec, REG_ANACONF4, 0x00, set_mask); +} int ab8500_audio_set_word_length(struct snd_soc_dai *dai, unsigned int wl) { diff --git a/sound/soc/codecs/ab8500_audio.h b/sound/soc/codecs/ab8500_audio.h index 7cfdd1cc13a..c3b24bbc754 100644 --- a/sound/soc/codecs/ab8500_audio.h +++ b/sound/soc/codecs/ab8500_audio.h @@ -25,6 +25,10 @@ extern struct snd_soc_codec_driver soc_codec_dev_ab8500; /* Extended interface for codec-driver */ void ab8500_audio_power_control(bool power_on); +void ab8500_audio_pwm_vibra(unsigned char speed_left_pos, + unsigned char speed_left_neg, + unsigned char speed_right_pos, + unsigned char speed_right_neg); int ab8500_audio_set_word_length(struct snd_soc_dai *dai, unsigned int wl); int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, unsigned int delay); int ab8500_audio_setup_if1(struct snd_soc_codec *codec, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b194be09e74..3b127009db8 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1256,7 +1256,7 @@ static void soc_resume_deferred(struct work_struct *work) int snd_soc_resume(struct device *dev) { struct snd_soc_card *card = dev_get_drvdata(dev); - int i; + int i, ac97_control = 0; /* AC97 devices might have other drivers hanging off them so * need to resume immediately. Other drivers don't have that @@ -1265,14 +1265,15 @@ int snd_soc_resume(struct device *dev) */ for (i = 0; i < card->num_rtd; i++) { struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; - if (cpu_dai->driver->ac97_control) { - dev_dbg(dev, "Resuming AC97 immediately\n"); - soc_resume_deferred(&card->deferred_resume_work); - } else { - dev_dbg(dev, "Scheduling resume work\n"); - if (!schedule_work(&card->deferred_resume_work)) - dev_err(dev, "resume work item may be lost\n"); - } + ac97_control |= cpu_dai->driver->ac97_control; + } + if (ac97_control) { + dev_dbg(dev, "Resuming AC97 immediately\n"); + soc_resume_deferred(&card->deferred_resume_work); + } else { + dev_dbg(dev, "Scheduling resume work\n"); + if (!schedule_work(&card->deferred_resume_work)) + dev_err(dev, "resume work item may be lost\n"); } return 0; diff --git a/sound/soc/ux500/ux500_ab8500.c b/sound/soc/ux500/ux500_ab8500.c index be647daeeed..805c26448d3 100644 --- a/sound/soc/ux500/ux500_ab8500.c +++ b/sound/soc/ux500/ux500_ab8500.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/jack.h> #include <sound/pcm_params.h> -#include <sound/soc-dapm.h> #include <mach/hardware.h> #include "ux500_pcm.h" #include "ux500_msp_dai.h" @@ -44,6 +43,7 @@ #define DRIVERMODE_CODEC_ONLY 1 static struct snd_soc_jack jack; +static bool vibra_on; /* Power-control */ static DEFINE_MUTEX(power_lock); @@ -58,7 +58,7 @@ static struct clk *clk_ptr_sysclk; static struct clk *clk_ptr_ulpclk; /* Regulators */ -static enum regulator_idx { +enum regulator_idx { REGULATOR_AUDIO, REGULATOR_DMIC, REGULATOR_AMIC1, @@ -531,6 +531,8 @@ int ux500_ab8500_soc_machine_drv_init(void) return status; } + vibra_on = false; + return 0; } @@ -552,6 +554,34 @@ void ux500_ab8500_soc_machine_drv_cleanup(void) /* Extended interface */ +void ux500_ab8500_audio_pwm_vibra(unsigned char speed_left_pos, + unsigned char speed_left_neg, + unsigned char speed_right_pos, + unsigned char speed_right_neg) +{ + bool vibra_on_new; + + vibra_on_new = speed_left_pos | speed_left_neg | speed_right_pos | speed_right_neg; + if ((!vibra_on_new) && (vibra_on)) { + pr_debug("%s: PWM-vibra off.\n", __func__); + vibra_on = false; + + ux500_ab8500_power_control_dec(); + } + + if ((vibra_on_new) && (!vibra_on)) { + pr_debug("%s: PWM-vibra on.\n", __func__); + vibra_on = true; + + ux500_ab8500_power_control_inc(); + } + + ab8500_audio_pwm_vibra(speed_left_pos, + speed_left_neg, + speed_right_pos, + speed_right_neg); +} + void ux500_ab8500_jack_report(int value) { if (jack.jack) |