aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-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 d10d65191fd2..c80218f23bb9 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)
3730 case 3: 3730 case 3:
3731 wm8994->hubs.dcs_codes = -5; 3731 wm8994->hubs.dcs_codes = -5;
3732 wm8994->hubs.hp_startup_mode = 1; 3732 wm8994->hubs.hp_startup_mode = 1;
3733 wm8994->hubs.dcs_readback_mode = 1;
3733 break; 3734 break;
3734 default: 3735 default:
3736 wm8994->hubs.dcs_readback_mode = 1;
3735 break; 3737 break;
3736 } 3738 }
3737
3738 3739
3739 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3740 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3740 * configured on init - if a system wants to do this dynamically 3741 * 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 3729a12b151f..2b5c0924f615 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)
86static void calibrate_dc_servo(struct snd_soc_codec *codec) 86static void calibrate_dc_servo(struct snd_soc_codec *codec)
87{ 87{
88 struct wm_hubs_data *hubs = codec->private_data; 88 struct wm_hubs_data *hubs = codec->private_data;
89 u16 reg, dcs_cfg; 89 u16 reg, reg_l, reg_r, dcs_cfg;
90 90
91 /* Set for 32 series updates */ 91 /* Set for 32 series updates */
92 snd_soc_update_bits(codec, WM8993_DC_SERVO_1, 92 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
@@ -110,19 +110,38 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
110 dev_dbg(codec->dev, "Applying %d code DC servo correction\n", 110 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
111 hubs->dcs_codes); 111 hubs->dcs_codes);
112 112
113 /* Different chips in the family support different
114 * readback methods.
115 */
116 switch (hubs->dcs_readback_mode) {
117 case 0:
118 reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
119 & WM8993_DCS_INTEG_CHAN_0_MASK;;
120 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
121 & WM8993_DCS_INTEG_CHAN_1_MASK;
122 break;
123 case 1:
124 reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
125 reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
126 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
127 reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
128 break;
129 default:
130 WARN(1, "Unknown DCS readback method");
131 break;
132 }
133
113 /* HPOUT1L */ 134 /* HPOUT1L */
114 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) & 135 if (reg_l + hubs->dcs_codes > 0 &&
115 WM8993_DCS_INTEG_CHAN_0_MASK;; 136 reg_l + hubs->dcs_codes < 0xff)
116 if (reg + hubs->dcs_codes > 0 && reg + hubs->dcs_codes < 0xff) 137 reg_l += hubs->dcs_codes;
117 reg += hubs->dcs_codes; 138 dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
118 dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
119 139
120 /* HPOUT1R */ 140 /* HPOUT1R */
121 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) & 141 if (reg_r + hubs->dcs_codes > 0 &&
122 WM8993_DCS_INTEG_CHAN_1_MASK; 142 reg_r + hubs->dcs_codes < 0xff)
123 if (reg + hubs->dcs_codes > 0 && reg + hubs->dcs_codes < 0xff) 143 reg_r += hubs->dcs_codes;
124 reg += hubs->dcs_codes; 144 dcs_cfg |= reg_r;
125 dcs_cfg |= reg;
126 145
127 /* Do it */ 146 /* Do it */
128 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); 147 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 420104fe9c90..e51c16683589 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[];
21/* This *must* be the first element of the codec->private_data struct */ 21/* This *must* be the first element of the codec->private_data struct */
22struct wm_hubs_data { 22struct wm_hubs_data {
23 int dcs_codes; 23 int dcs_codes;
24 int dcs_readback_mode;
24 int hp_startup_mode; 25 int hp_startup_mode;
25}; 26};
26 27