aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/xonar_wm87x6.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/oxygen/xonar_wm87x6.c')
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 9d57b5eee3f5..cee07fe3aa36 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -27,8 +27,8 @@
27 * 27 *
28 * GPIO 4 <- headphone detect, 0 = plugged 28 * GPIO 4 <- headphone detect, 0 = plugged
29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1) 29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
30 * GPIO 7 -> enable output to speakers 30 * GPIO 7 -> enable output to front L/R speaker channels
31 * GPIO 8 -> enable output to speakers 31 * GPIO 8 -> enable output to other speaker channels and front panel headphone
32 * 32 *
33 * WM8766: 33 * WM8766:
34 * 34 *
@@ -52,7 +52,8 @@
52 52
53#define GPIO_DS_HP_DETECT 0x0010 53#define GPIO_DS_HP_DETECT 0x0010
54#define GPIO_DS_INPUT_ROUTE 0x0040 54#define GPIO_DS_INPUT_ROUTE 0x0040
55#define GPIO_DS_OUTPUT_ENABLE 0x0180 55#define GPIO_DS_OUTPUT_FRONTLR 0x0080
56#define GPIO_DS_OUTPUT_ENABLE 0x0100
56 57
57#define LC_CONTROL_LIMITER 0x40000000 58#define LC_CONTROL_LIMITER 0x40000000
58#define LC_CONTROL_ALC 0x20000000 59#define LC_CONTROL_ALC 0x20000000
@@ -150,7 +151,10 @@ static void wm8776_registers_init(struct oxygen *chip)
150 151
151static void wm8766_registers_init(struct oxygen *chip) 152static void wm8766_registers_init(struct oxygen *chip)
152{ 153{
154 struct xonar_wm87x6 *data = chip->model_data;
155
153 wm8766_write(chip, WM8766_RESET, 0); 156 wm8766_write(chip, WM8766_RESET, 0);
157 wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]);
154 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); 158 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
155 wm8766_write(chip, WM8766_DAC_CTRL2, 159 wm8766_write(chip, WM8766_DAC_CTRL2,
156 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 160 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
@@ -179,14 +183,38 @@ static void wm8776_init(struct oxygen *chip)
179 wm8776_registers_init(chip); 183 wm8776_registers_init(chip);
180} 184}
181 185
182static void xonar_ds_report_hp_jack(struct oxygen *chip) 186static void wm8766_init(struct oxygen *chip)
183{ 187{
184 struct xonar_wm87x6 *data = chip->model_data; 188 struct xonar_wm87x6 *data = chip->model_data;
185 u16 bits;
186 189
187 bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 190 data->wm8766_regs[WM8766_DAC_CTRL] =
188 snd_jack_report(data->hp_jack, 191 WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
189 bits & GPIO_DS_HP_DETECT ? 0 : SND_JACK_HEADPHONE); 192 wm8766_registers_init(chip);
193}
194
195static void xonar_ds_handle_hp_jack(struct oxygen *chip)
196{
197 struct xonar_wm87x6 *data = chip->model_data;
198 bool hp_plugged;
199 unsigned int reg;
200
201 mutex_lock(&chip->mutex);
202
203 hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
204 GPIO_DS_HP_DETECT);
205
206 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
207 hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR,
208 GPIO_DS_OUTPUT_FRONTLR);
209
210 reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL;
211 if (hp_plugged)
212 reg |= WM8766_MUTEALL;
213 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
214
215 snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
216
217 mutex_unlock(&chip->mutex);
190} 218}
191 219
192static void xonar_ds_init(struct oxygen *chip) 220static void xonar_ds_init(struct oxygen *chip)
@@ -197,10 +225,12 @@ static void xonar_ds_init(struct oxygen *chip)
197 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; 225 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
198 226
199 wm8776_init(chip); 227 wm8776_init(chip);
200 wm8766_registers_init(chip); 228 wm8766_init(chip);
201 229
202 oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE, 230 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
203 GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE); 231 GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR);
232 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
233 GPIO_DS_HP_DETECT);
204 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); 234 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
205 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); 235 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
206 chip->interrupt_mask |= OXYGEN_INT_GPIO; 236 chip->interrupt_mask |= OXYGEN_INT_GPIO;
@@ -209,7 +239,7 @@ static void xonar_ds_init(struct oxygen *chip)
209 239
210 snd_jack_new(chip->card, "Headphone", 240 snd_jack_new(chip->card, "Headphone",
211 SND_JACK_HEADPHONE, &data->hp_jack); 241 SND_JACK_HEADPHONE, &data->hp_jack);
212 xonar_ds_report_hp_jack(chip); 242 xonar_ds_handle_hp_jack(chip);
213 243
214 snd_component_add(chip->card, "WM8776"); 244 snd_component_add(chip->card, "WM8776");
215 snd_component_add(chip->card, "WM8766"); 245 snd_component_add(chip->card, "WM8766");
@@ -231,6 +261,7 @@ static void xonar_ds_resume(struct oxygen *chip)
231 wm8776_registers_init(chip); 261 wm8776_registers_init(chip);
232 wm8766_registers_init(chip); 262 wm8766_registers_init(chip);
233 xonar_enable_output(chip); 263 xonar_enable_output(chip);
264 xonar_ds_handle_hp_jack(chip);
234} 265}
235 266
236static void wm8776_adc_hardware_filter(unsigned int channel, 267static void wm8776_adc_hardware_filter(unsigned int channel,
@@ -348,7 +379,7 @@ static void update_wm87x6_mute(struct oxygen *chip)
348 379
349static void xonar_ds_gpio_changed(struct oxygen *chip) 380static void xonar_ds_gpio_changed(struct oxygen *chip)
350{ 381{
351 xonar_ds_report_hp_jack(chip); 382 xonar_ds_handle_hp_jack(chip);
352} 383}
353 384
354static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, 385static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,