aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-29 17:09:45 +0100
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-04-05 16:19:09 +0100
commit8437f7006b9cfa249791e2fd57596683d4561843 (patch)
treec1701c27b37b21c53daec55f730162757511e041
parent3fa49e3ad9ac20b15edfb0c51bbad36e45a84b17 (diff)
downloadkernel_samsung_espresso10-8437f7006b9cfa249791e2fd57596683d4561843.zip
kernel_samsung_espresso10-8437f7006b9cfa249791e2fd57596683d4561843.tar.gz
kernel_samsung_espresso10-8437f7006b9cfa249791e2fd57596683d4561843.tar.bz2
ASoC: Support second DC servo readback method for wm_hubs
More recent Wolfson hubs devices add the ability to read back the DC servo calibration information from the register used to write offsets, and later still ones remove the old readback registers. Add support for the new scheme, and use it for WM8994 device revisions that support it. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--sound/soc/codecs/wm8994.c3
-rw-r--r--sound/soc/codecs/wm_hubs.c41
-rw-r--r--sound/soc/codecs/wm_hubs.h1
3 files changed, 33 insertions, 12 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index d10d651..c80218f 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3730,11 +3730,12 @@ static int wm8994_codec_probe(struct platform_device *pdev)
case 3:
wm8994->hubs.dcs_codes = -5;
wm8994->hubs.hp_startup_mode = 1;
+ wm8994->hubs.dcs_readback_mode = 1;
break;
default:
+ wm8994->hubs.dcs_readback_mode = 1;
break;
}
-
/* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 3729a12..2b5c092 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -86,7 +86,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
static void calibrate_dc_servo(struct snd_soc_codec *codec)
{
struct wm_hubs_data *hubs = codec->private_data;
- u16 reg, dcs_cfg;
+ u16 reg, reg_l, reg_r, dcs_cfg;
/* Set for 32 series updates */
snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
@@ -110,19 +110,38 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
hubs->dcs_codes);
+ /* Different chips in the family support different
+ * readback methods.
+ */
+ switch (hubs->dcs_readback_mode) {
+ case 0:
+ reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+ & WM8993_DCS_INTEG_CHAN_0_MASK;;
+ reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+ & WM8993_DCS_INTEG_CHAN_1_MASK;
+ break;
+ case 1:
+ reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
+ reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
+ >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
+ break;
+ default:
+ WARN(1, "Unknown DCS readback method");
+ break;
+ }
+
/* HPOUT1L */
- reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) &
- WM8993_DCS_INTEG_CHAN_0_MASK;;
- if (reg + hubs->dcs_codes > 0 && reg + hubs->dcs_codes < 0xff)
- reg += hubs->dcs_codes;
- dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ if (reg_l + hubs->dcs_codes > 0 &&
+ reg_l + hubs->dcs_codes < 0xff)
+ reg_l += hubs->dcs_codes;
+ dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
/* HPOUT1R */
- reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) &
- WM8993_DCS_INTEG_CHAN_1_MASK;
- if (reg + hubs->dcs_codes > 0 && reg + hubs->dcs_codes < 0xff)
- reg += hubs->dcs_codes;
- dcs_cfg |= reg;
+ if (reg_r + hubs->dcs_codes > 0 &&
+ reg_r + hubs->dcs_codes < 0xff)
+ reg_r += hubs->dcs_codes;
+ dcs_cfg |= reg_r;
/* Do it */
snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 420104f..e51c166 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
/* This *must* be the first element of the codec->private_data struct */
struct wm_hubs_data {
int dcs_codes;
+ int dcs_readback_mode;
int hp_startup_mode;
};