aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/virtuoso.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/oxygen/virtuoso.c')
-rw-r--r--sound/pci/oxygen/virtuoso.c594
1 files changed, 398 insertions, 196 deletions
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index d163397b85cc..7f84fa5deca2 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -18,6 +18,9 @@
18 */ 18 */
19 19
20/* 20/*
21 * Xonar D2/D2X
22 * ------------
23 *
21 * CMI8788: 24 * CMI8788:
22 * 25 *
23 * SPI 0 -> 1st PCM1796 (front) 26 * SPI 0 -> 1st PCM1796 (front)
@@ -30,10 +33,33 @@
30 * GPIO 5 <- external power present (D2X only) 33 * GPIO 5 <- external power present (D2X only)
31 * GPIO 7 -> ALT 34 * GPIO 7 -> ALT
32 * GPIO 8 -> enable output to speakers 35 * GPIO 8 -> enable output to speakers
36 */
37
38/*
39 * Xonar DX
40 * --------
41 *
42 * CMI8788:
43 *
44 * I²C <-> CS4398 (front)
45 * <-> CS4362A (surround, center/LFE, back)
46 *
47 * GPI 0 <- external power present
33 * 48 *
34 * CM9780: 49 * GPIO 0 -> enable output to speakers
50 * GPIO 1 -> enable front panel I/O
51 * GPIO 2 -> M0 of CS5361
52 * GPIO 3 -> M1 of CS5361
53 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
35 * 54 *
36 * GPIO 0 -> enable AC'97 bypass (line in -> ADC) 55 * CS4398:
56 *
57 * AD0 <- 1
58 * AD1 <- 1
59 *
60 * CS4362A:
61 *
62 * AD0 <- 0
37 */ 63 */
38 64
39#include <linux/pci.h> 65#include <linux/pci.h>
@@ -47,11 +73,14 @@
47#include <sound/tlv.h> 73#include <sound/tlv.h>
48#include "oxygen.h" 74#include "oxygen.h"
49#include "cm9780.h" 75#include "cm9780.h"
76#include "pcm1796.h"
77#include "cs4398.h"
78#include "cs4362a.h"
50 79
51MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
52MODULE_DESCRIPTION("Asus AV200 driver"); 81MODULE_DESCRIPTION("Asus AVx00 driver");
53MODULE_LICENSE("GPL"); 82MODULE_LICENSE("GPL");
54MODULE_SUPPORTED_DEVICE("{{Asus,AV200}}"); 83MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}");
55 84
56static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 85static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
57static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 86static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -64,80 +93,44 @@ MODULE_PARM_DESC(id, "ID string");
64module_param_array(enable, bool, NULL, 0444); 93module_param_array(enable, bool, NULL, 0444);
65MODULE_PARM_DESC(enable, "enable card"); 94MODULE_PARM_DESC(enable, "enable card");
66 95
96enum {
97 MODEL_D2,
98 MODEL_D2X,
99 MODEL_DX,
100};
101
67static struct pci_device_id xonar_ids[] __devinitdata = { 102static struct pci_device_id xonar_ids[] __devinitdata = {
68 { OXYGEN_PCI_SUBID(0x1043, 0x8269) }, /* Asus Xonar D2 */ 103 { OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 },
69 { OXYGEN_PCI_SUBID(0x1043, 0x82b7) }, /* Asus Xonar D2X */ 104 { OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX },
105 { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X },
70 { } 106 { }
71}; 107};
72MODULE_DEVICE_TABLE(pci, xonar_ids); 108MODULE_DEVICE_TABLE(pci, xonar_ids);
73 109
74 110
75#define GPIO_CS5381_M_MASK 0x000c 111#define GPIO_CS53x1_M_MASK 0x000c
76#define GPIO_CS5381_M_SINGLE 0x0000 112#define GPIO_CS53x1_M_SINGLE 0x0000
77#define GPIO_CS5381_M_DOUBLE 0x0004 113#define GPIO_CS53x1_M_DOUBLE 0x0004
78#define GPIO_CS5381_M_QUAD 0x0008 114#define GPIO_CS53x1_M_QUAD 0x0008
79#define GPIO_EXT_POWER 0x0020 115
80#define GPIO_ALT 0x0080 116#define GPIO_D2X_EXT_POWER 0x0020
81#define GPIO_OUTPUT_ENABLE 0x0100 117#define GPIO_D2_ALT 0x0080
82 118#define GPIO_D2_OUTPUT_ENABLE 0x0100
83#define GPIO_LINE_MUTE CM9780_GPO0 119
84 120#define GPI_DX_EXT_POWER 0x01
85/* register 16 */ 121#define GPIO_DX_OUTPUT_ENABLE 0x0001
86#define PCM1796_ATL_MASK 0xff 122#define GPIO_DX_FRONT_PANEL 0x0002
87/* register 17 */ 123#define GPIO_DX_INPUT_ROUTE 0x0100
88#define PCM1796_ATR_MASK 0xff 124
89/* register 18 */ 125#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
90#define PCM1796_MUTE 0x01 126#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
91#define PCM1796_DME 0x02
92#define PCM1796_DMF_MASK 0x0c
93#define PCM1796_DMF_DISABLED 0x00
94#define PCM1796_DMF_48 0x04
95#define PCM1796_DMF_441 0x08
96#define PCM1796_DMF_32 0x0c
97#define PCM1796_FMT_MASK 0x70
98#define PCM1796_FMT_16_RJUST 0x00
99#define PCM1796_FMT_20_RJUST 0x10
100#define PCM1796_FMT_24_RJUST 0x20
101#define PCM1796_FMT_24_LJUST 0x30
102#define PCM1796_FMT_16_I2S 0x40
103#define PCM1796_FMT_24_I2S 0x50
104#define PCM1796_ATLD 0x80
105/* register 19 */
106#define PCM1796_INZD 0x01
107#define PCM1796_FLT_MASK 0x02
108#define PCM1796_FLT_SHARP 0x00
109#define PCM1796_FLT_SLOW 0x02
110#define PCM1796_DFMS 0x04
111#define PCM1796_OPE 0x10
112#define PCM1796_ATS_MASK 0x60
113#define PCM1796_ATS_1 0x00
114#define PCM1796_ATS_2 0x20
115#define PCM1796_ATS_4 0x40
116#define PCM1796_ATS_8 0x60
117#define PCM1796_REV 0x80
118/* register 20 */
119#define PCM1796_OS_MASK 0x03
120#define PCM1796_OS_64 0x00
121#define PCM1796_OS_32 0x01
122#define PCM1796_OS_128 0x02
123#define PCM1796_CHSL_MASK 0x04
124#define PCM1796_CHSL_LEFT 0x00
125#define PCM1796_CHSL_RIGHT 0x04
126#define PCM1796_MONO 0x08
127#define PCM1796_DFTH 0x10
128#define PCM1796_DSD 0x20
129#define PCM1796_SRST 0x40
130/* register 21 */
131#define PCM1796_PCMZ 0x01
132#define PCM1796_DZ_MASK 0x06
133/* register 22 */
134#define PCM1796_ZFGL 0x01
135#define PCM1796_ZFGR 0x02
136/* register 23 */
137#define PCM1796_ID_MASK 0x1f
138 127
139struct xonar_data { 128struct xonar_data {
140 u8 is_d2x; 129 unsigned int anti_pop_delay;
130 u16 output_enable_bit;
131 u8 ext_power_reg;
132 u8 ext_power_int_reg;
133 u8 ext_power_bit;
141 u8 has_power; 134 u8 has_power;
142}; 135};
143 136
@@ -156,62 +149,157 @@ static void pcm1796_write(struct oxygen *chip, unsigned int codec,
156 (reg << 8) | value); 149 (reg << 8) | value);
157} 150}
158 151
159static void xonar_init(struct oxygen *chip) 152static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
153{
154 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
155}
156
157static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
158{
159 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
160}
161
162static void xonar_common_init(struct oxygen *chip)
163{
164 struct xonar_data *data = chip->model_data;
165
166 if (data->ext_power_reg) {
167 oxygen_set_bits8(chip, data->ext_power_int_reg,
168 data->ext_power_bit);
169 chip->interrupt_mask |= OXYGEN_INT_GPIO;
170 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
171 & data->ext_power_bit);
172 }
173 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK);
174 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
175 GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
176 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
177 msleep(data->anti_pop_delay);
178 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);
179 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
180}
181
182static void xonar_d2_init(struct oxygen *chip)
160{ 183{
161 struct xonar_data *data = chip->model_data; 184 struct xonar_data *data = chip->model_data;
162 unsigned int i; 185 unsigned int i;
163 186
164 data->is_d2x = chip->pci->subsystem_device == 0x82b7; 187 data->anti_pop_delay = 300;
188 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
165 189
166 for (i = 0; i < 4; ++i) { 190 for (i = 0; i < 4; ++i) {
167 pcm1796_write(chip, i, 18, PCM1796_FMT_24_LJUST | PCM1796_ATLD); 191 pcm1796_write(chip, i, 18, PCM1796_MUTE | PCM1796_DMF_DISABLED |
192 PCM1796_FMT_24_LJUST | PCM1796_ATLD);
168 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); 193 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
169 pcm1796_write(chip, i, 20, PCM1796_OS_64); 194 pcm1796_write(chip, i, 20, PCM1796_OS_64);
170 pcm1796_write(chip, i, 21, 0); 195 pcm1796_write(chip, i, 21, 0);
171 pcm1796_write(chip, i, 16, 0xff); /* set ATL/ATR after ATLD */ 196 pcm1796_write(chip, i, 16, 0x0f); /* set ATL/ATR after ATLD */
172 pcm1796_write(chip, i, 17, 0xff); 197 pcm1796_write(chip, i, 17, 0x0f);
173 } 198 }
174 199
175 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 200 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT);
176 GPIO_CS5381_M_MASK | GPIO_ALT); 201 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT);
177 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 202
178 GPIO_CS5381_M_SINGLE, 203 xonar_common_init(chip);
179 GPIO_CS5381_M_MASK | GPIO_ALT);
180 if (data->is_d2x) {
181 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
182 GPIO_EXT_POWER);
183 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK,
184 GPIO_EXT_POWER);
185 chip->interrupt_mask |= OXYGEN_INT_GPIO;
186 data->has_power = !!(oxygen_read16(chip, OXYGEN_GPIO_DATA)
187 & GPIO_EXT_POWER);
188 }
189 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
190 oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE);
191 msleep(300);
192 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_OUTPUT_ENABLE);
193 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
194 204
195 snd_component_add(chip->card, "PCM1796"); 205 snd_component_add(chip->card, "PCM1796");
196 snd_component_add(chip->card, "CS5381"); 206 snd_component_add(chip->card, "CS5381");
197} 207}
198 208
209static void xonar_d2x_init(struct oxygen *chip)
210{
211 struct xonar_data *data = chip->model_data;
212
213 data->ext_power_reg = OXYGEN_GPIO_DATA;
214 data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
215 data->ext_power_bit = GPIO_D2X_EXT_POWER;
216 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
217 xonar_d2_init(chip);
218}
219
220static void xonar_dx_init(struct oxygen *chip)
221{
222 struct xonar_data *data = chip->model_data;
223
224 data->anti_pop_delay = 800;
225 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
226 data->ext_power_reg = OXYGEN_GPI_DATA;
227 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
228 data->ext_power_bit = GPI_DX_EXT_POWER;
229
230 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
231 OXYGEN_2WIRE_LENGTH_8 |
232 OXYGEN_2WIRE_INTERRUPT_MASK |
233 OXYGEN_2WIRE_SPEED_FAST);
234
235 /* set CPEN (control port mode) and power down */
236 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
237 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
238 /* configure */
239 cs4398_write(chip, 2, CS4398_FM_SINGLE |
240 CS4398_DEM_NONE | CS4398_DIF_LJUST);
241 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
242 cs4398_write(chip, 4, CS4398_MUTEP_LOW | CS4398_PAMUTE);
243 cs4398_write(chip, 5, 0xfe);
244 cs4398_write(chip, 6, 0xfe);
245 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP |
246 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
247 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
248 cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
249 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
250 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
251 cs4362a_write(chip, 0x05, 0);
252 cs4362a_write(chip, 0x06, CS4362A_FM_SINGLE |
253 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
254 cs4362a_write(chip, 0x07, 0x7f | CS4362A_MUTE);
255 cs4362a_write(chip, 0x08, 0x7f | CS4362A_MUTE);
256 cs4362a_write(chip, 0x09, CS4362A_FM_SINGLE |
257 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
258 cs4362a_write(chip, 0x0a, 0x7f | CS4362A_MUTE);
259 cs4362a_write(chip, 0x0b, 0x7f | CS4362A_MUTE);
260 cs4362a_write(chip, 0x0c, CS4362A_FM_SINGLE |
261 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L);
262 cs4362a_write(chip, 0x0d, 0x7f | CS4362A_MUTE);
263 cs4362a_write(chip, 0x0e, 0x7f | CS4362A_MUTE);
264 /* clear power down */
265 cs4398_write(chip, 8, CS4398_CPEN);
266 cs4362a_write(chip, 0x01, CS4362A_CPEN);
267
268 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
269 GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE);
270 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
271 GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE);
272
273 xonar_common_init(chip);
274
275 snd_component_add(chip->card, "CS4398");
276 snd_component_add(chip->card, "CS4362A");
277 snd_component_add(chip->card, "CS5361");
278}
279
199static void xonar_cleanup(struct oxygen *chip) 280static void xonar_cleanup(struct oxygen *chip)
200{ 281{
201 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); 282 struct xonar_data *data = chip->model_data;
283
284 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
285}
286
287static void xonar_dx_cleanup(struct oxygen *chip)
288{
289 xonar_cleanup(chip);
290 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
291 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
202} 292}
203 293
204static void set_pcm1796_params(struct oxygen *chip, 294static void set_pcm1796_params(struct oxygen *chip,
205 struct snd_pcm_hw_params *params) 295 struct snd_pcm_hw_params *params)
206{ 296{
207#if 0
208 unsigned int i; 297 unsigned int i;
209 u8 value; 298 u8 value;
210 299
211 value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64; 300 value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
212 for (i = 0; i < 4; ++i) 301 for (i = 0; i < 4; ++i)
213 pcm1796_write(chip, i, 20, value); 302 pcm1796_write(chip, i, 20, value);
214#endif
215} 303}
216 304
217static void update_pcm1796_volume(struct oxygen *chip) 305static void update_pcm1796_volume(struct oxygen *chip)
@@ -236,19 +324,73 @@ static void update_pcm1796_mute(struct oxygen *chip)
236 pcm1796_write(chip, i, 18, value); 324 pcm1796_write(chip, i, 18, value);
237} 325}
238 326
239static void set_cs5381_params(struct oxygen *chip, 327static void set_cs53x1_params(struct oxygen *chip,
240 struct snd_pcm_hw_params *params) 328 struct snd_pcm_hw_params *params)
241{ 329{
242 unsigned int value; 330 unsigned int value;
243 331
244 if (params_rate(params) <= 54000) 332 if (params_rate(params) <= 54000)
245 value = GPIO_CS5381_M_SINGLE; 333 value = GPIO_CS53x1_M_SINGLE;
246 else if (params_rate(params) <= 108000) 334 else if (params_rate(params) <= 108000)
247 value = GPIO_CS5381_M_DOUBLE; 335 value = GPIO_CS53x1_M_DOUBLE;
248 else 336 else
249 value = GPIO_CS5381_M_QUAD; 337 value = GPIO_CS53x1_M_QUAD;
250 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 338 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
251 value, GPIO_CS5381_M_MASK); 339 value, GPIO_CS53x1_M_MASK);
340}
341
342static void set_cs43xx_params(struct oxygen *chip,
343 struct snd_pcm_hw_params *params)
344{
345 u8 fm_cs4398, fm_cs4362a;
346
347 fm_cs4398 = CS4398_DEM_NONE | CS4398_DIF_LJUST;
348 fm_cs4362a = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
349 if (params_rate(params) <= 50000) {
350 fm_cs4398 |= CS4398_FM_SINGLE;
351 fm_cs4362a |= CS4362A_FM_SINGLE;
352 } else if (params_rate(params) <= 100000) {
353 fm_cs4398 |= CS4398_FM_DOUBLE;
354 fm_cs4362a |= CS4362A_FM_DOUBLE;
355 } else {
356 fm_cs4398 |= CS4398_FM_QUAD;
357 fm_cs4362a |= CS4362A_FM_QUAD;
358 }
359 cs4398_write(chip, 2, fm_cs4398);
360 cs4362a_write(chip, 0x06, fm_cs4362a);
361 cs4362a_write(chip, 0x09, fm_cs4362a);
362 cs4362a_write(chip, 0x0c, fm_cs4362a);
363}
364
365static void update_cs4362a_volumes(struct oxygen *chip)
366{
367 u8 mute;
368
369 mute = chip->dac_mute ? CS4362A_MUTE : 0;
370 cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute);
371 cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
372 cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
373 cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
374 cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
375 cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
376}
377
378static void update_cs43xx_volume(struct oxygen *chip)
379{
380 cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2);
381 cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2);
382 update_cs4362a_volumes(chip);
383}
384
385static void update_cs43xx_mute(struct oxygen *chip)
386{
387 u8 reg;
388
389 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
390 if (chip->dac_mute)
391 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
392 cs4398_write(chip, 4, reg);
393 update_cs4362a_volumes(chip);
252} 394}
253 395
254static void xonar_gpio_changed(struct oxygen *chip) 396static void xonar_gpio_changed(struct oxygen *chip)
@@ -256,10 +398,8 @@ static void xonar_gpio_changed(struct oxygen *chip)
256 struct xonar_data *data = chip->model_data; 398 struct xonar_data *data = chip->model_data;
257 u8 has_power; 399 u8 has_power;
258 400
259 if (!data->is_d2x) 401 has_power = !!(oxygen_read8(chip, data->ext_power_reg)
260 return; 402 & data->ext_power_bit);
261 has_power = !!(oxygen_read16(chip, OXYGEN_GPIO_DATA)
262 & GPIO_EXT_POWER);
263 if (has_power != data->has_power) { 403 if (has_power != data->has_power) {
264 data->has_power = has_power; 404 data->has_power = has_power;
265 if (has_power) { 405 if (has_power) {
@@ -272,66 +412,13 @@ static void xonar_gpio_changed(struct oxygen *chip)
272 } 412 }
273} 413}
274 414
275static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
276{
277 unsigned int index = chip->controls[control]->private_value & 0xff;
278 u16 value;
279
280 value = oxygen_read_ac97(chip, 0, index);
281 if (!(value & 0x8000)) {
282 oxygen_write_ac97(chip, 0, index, value | 0x8000);
283 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
284 &chip->controls[control]->id);
285 }
286}
287
288static void xonar_ac97_switch_hook(struct oxygen *chip, unsigned int codec,
289 unsigned int reg, int mute)
290{
291 if (codec != 0)
292 return;
293 /* line-in is exclusive */
294 switch (reg) {
295 case AC97_LINE:
296 oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
297 mute ? GPIO_LINE_MUTE : 0,
298 GPIO_LINE_MUTE);
299 if (!mute) {
300 mute_ac97_ctl(chip, CONTROL_MIC_CAPTURE_SWITCH);
301 mute_ac97_ctl(chip, CONTROL_CD_CAPTURE_SWITCH);
302 mute_ac97_ctl(chip, CONTROL_AUX_CAPTURE_SWITCH);
303 }
304 break;
305 case AC97_MIC:
306 case AC97_CD:
307 case AC97_VIDEO:
308 case AC97_AUX:
309 if (!mute) {
310 oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_STATUS,
311 GPIO_LINE_MUTE);
312 mute_ac97_ctl(chip, CONTROL_LINE_CAPTURE_SWITCH);
313 }
314 break;
315 }
316}
317
318static int pcm1796_volume_info(struct snd_kcontrol *ctl,
319 struct snd_ctl_elem_info *info)
320{
321 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
322 info->count = 8;
323 info->value.integer.min = 0x0f;
324 info->value.integer.max = 0xff;
325 return 0;
326}
327
328static int alt_switch_get(struct snd_kcontrol *ctl, 415static int alt_switch_get(struct snd_kcontrol *ctl,
329 struct snd_ctl_elem_value *value) 416 struct snd_ctl_elem_value *value)
330{ 417{
331 struct oxygen *chip = ctl->private_data; 418 struct oxygen *chip = ctl->private_data;
332 419
333 value->value.integer.value[0] = 420 value->value.integer.value[0] =
334 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_ALT); 421 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_D2_ALT);
335 return 0; 422 return 0;
336} 423}
337 424
@@ -345,9 +432,9 @@ static int alt_switch_put(struct snd_kcontrol *ctl,
345 spin_lock_irq(&chip->reg_lock); 432 spin_lock_irq(&chip->reg_lock);
346 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 433 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
347 if (value->value.integer.value[0]) 434 if (value->value.integer.value[0])
348 new_bits = old_bits | GPIO_ALT; 435 new_bits = old_bits | GPIO_D2_ALT;
349 else 436 else
350 new_bits = old_bits & ~GPIO_ALT; 437 new_bits = old_bits & ~GPIO_D2_ALT;
351 changed = new_bits != old_bits; 438 changed = new_bits != old_bits;
352 if (changed) 439 if (changed)
353 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits); 440 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
@@ -363,20 +450,68 @@ static const struct snd_kcontrol_new alt_switch = {
363 .put = alt_switch_put, 450 .put = alt_switch_put,
364}; 451};
365 452
453static int front_panel_get(struct snd_kcontrol *ctl,
454 struct snd_ctl_elem_value *value)
455{
456 struct oxygen *chip = ctl->private_data;
457
458 value->value.integer.value[0] =
459 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DX_FRONT_PANEL);
460 return 0;
461}
462
463static int front_panel_put(struct snd_kcontrol *ctl,
464 struct snd_ctl_elem_value *value)
465{
466 struct oxygen *chip = ctl->private_data;
467 u16 old_reg, new_reg;
468
469 spin_lock_irq(&chip->reg_lock);
470 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
471 if (value->value.integer.value[0])
472 new_reg = old_reg | GPIO_DX_FRONT_PANEL;
473 else
474 new_reg = old_reg & ~GPIO_DX_FRONT_PANEL;
475 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
476 spin_unlock_irq(&chip->reg_lock);
477 return old_reg != new_reg;
478}
479
480static const struct snd_kcontrol_new front_panel_switch = {
481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
482 .name = "Front Panel Switch",
483 .info = snd_ctl_boolean_mono_info,
484 .get = front_panel_get,
485 .put = front_panel_put,
486};
487
488static void xonar_dx_ac97_switch(struct oxygen *chip,
489 unsigned int reg, unsigned int mute)
490{
491 if (reg == AC97_LINE) {
492 spin_lock_irq(&chip->reg_lock);
493 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
494 mute ? GPIO_DX_INPUT_ROUTE : 0,
495 GPIO_DX_INPUT_ROUTE);
496 spin_unlock_irq(&chip->reg_lock);
497 }
498}
499
366static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0); 500static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0);
501static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -12700, 100, 0);
367 502
368static int xonar_control_filter(struct snd_kcontrol_new *template) 503static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
369{ 504{
370 if (!strcmp(template->name, "Master Playback Volume")) { 505 if (!strncmp(template->name, "CD Capture ", 11))
371 template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
372 template->info = pcm1796_volume_info,
373 template->tlv.p = pcm1796_db_scale;
374 } else if (!strncmp(template->name, "CD Capture ", 11)) {
375 /* CD in is actually connected to the video in pin */ 506 /* CD in is actually connected to the video in pin */
376 template->private_value ^= AC97_CD ^ AC97_VIDEO; 507 template->private_value ^= AC97_CD ^ AC97_VIDEO;
377 } else if (!strcmp(template->name, "Line Capture Volume")) { 508 return 0;
378 return 1; /* line-in bypasses the AC'97 mixer */ 509}
379 } 510
511static int xonar_dx_control_filter(struct snd_kcontrol_new *template)
512{
513 if (!strncmp(template->name, "CD Capture ", 11))
514 return 1; /* no CD input */
380 return 0; 515 return 0;
381} 516}
382 517
@@ -385,30 +520,96 @@ static int xonar_mixer_init(struct oxygen *chip)
385 return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); 520 return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
386} 521}
387 522
388static const struct oxygen_model model_xonar = { 523static int xonar_dx_mixer_init(struct oxygen *chip)
389 .shortname = "Asus AV200", 524{
390 .longname = "Asus Virtuoso 200", 525 return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
391 .chip = "AV200", 526}
392 .owner = THIS_MODULE, 527
393 .init = xonar_init, 528static const struct oxygen_model xonar_models[] = {
394 .control_filter = xonar_control_filter, 529 [MODEL_D2] = {
395 .mixer_init = xonar_mixer_init, 530 .shortname = "Xonar D2",
396 .cleanup = xonar_cleanup, 531 .longname = "Asus Virtuoso 200",
397 .set_dac_params = set_pcm1796_params, 532 .chip = "AV200",
398 .set_adc_params = set_cs5381_params, 533 .owner = THIS_MODULE,
399 .update_dac_volume = update_pcm1796_volume, 534 .init = xonar_d2_init,
400 .update_dac_mute = update_pcm1796_mute, 535 .control_filter = xonar_d2_control_filter,
401 .ac97_switch_hook = xonar_ac97_switch_hook, 536 .mixer_init = xonar_mixer_init,
402 .gpio_changed = xonar_gpio_changed, 537 .cleanup = xonar_cleanup,
403 .model_data_size = sizeof(struct xonar_data), 538 .set_dac_params = set_pcm1796_params,
404 .dac_channels = 8, 539 .set_adc_params = set_cs53x1_params,
405 .used_channels = OXYGEN_CHANNEL_B | 540 .update_dac_volume = update_pcm1796_volume,
406 OXYGEN_CHANNEL_C | 541 .update_dac_mute = update_pcm1796_mute,
407 OXYGEN_CHANNEL_SPDIF | 542 .dac_tlv = pcm1796_db_scale,
408 OXYGEN_CHANNEL_MULTICH, 543 .model_data_size = sizeof(struct xonar_data),
409 .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, 544 .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
410 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 545 PLAYBACK_1_TO_SPDIF |
411 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 546 CAPTURE_0_FROM_I2S_2 |
547 CAPTURE_1_FROM_SPDIF,
548 .dac_channels = 8,
549 .dac_volume_min = 0x0f,
550 .dac_volume_max = 0xff,
551 .misc_flags = OXYGEN_MISC_MIDI,
552 .function_flags = OXYGEN_FUNCTION_SPI |
553 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
554 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
555 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
556 },
557 [MODEL_D2X] = {
558 .shortname = "Xonar D2X",
559 .longname = "Asus Virtuoso 200",
560 .chip = "AV200",
561 .owner = THIS_MODULE,
562 .init = xonar_d2x_init,
563 .control_filter = xonar_d2_control_filter,
564 .mixer_init = xonar_mixer_init,
565 .cleanup = xonar_cleanup,
566 .set_dac_params = set_pcm1796_params,
567 .set_adc_params = set_cs53x1_params,
568 .update_dac_volume = update_pcm1796_volume,
569 .update_dac_mute = update_pcm1796_mute,
570 .gpio_changed = xonar_gpio_changed,
571 .dac_tlv = pcm1796_db_scale,
572 .model_data_size = sizeof(struct xonar_data),
573 .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
574 PLAYBACK_1_TO_SPDIF |
575 CAPTURE_0_FROM_I2S_2 |
576 CAPTURE_1_FROM_SPDIF,
577 .dac_channels = 8,
578 .dac_volume_min = 0x0f,
579 .dac_volume_max = 0xff,
580 .misc_flags = OXYGEN_MISC_MIDI,
581 .function_flags = OXYGEN_FUNCTION_SPI |
582 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
583 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
584 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
585 },
586 [MODEL_DX] = {
587 .shortname = "Xonar DX",
588 .longname = "Asus Virtuoso 100",
589 .chip = "AV200",
590 .owner = THIS_MODULE,
591 .init = xonar_dx_init,
592 .control_filter = xonar_dx_control_filter,
593 .mixer_init = xonar_dx_mixer_init,
594 .cleanup = xonar_dx_cleanup,
595 .set_dac_params = set_cs43xx_params,
596 .set_adc_params = set_cs53x1_params,
597 .update_dac_volume = update_cs43xx_volume,
598 .update_dac_mute = update_cs43xx_mute,
599 .gpio_changed = xonar_gpio_changed,
600 .ac97_switch = xonar_dx_ac97_switch,
601 .dac_tlv = cs4362a_db_scale,
602 .model_data_size = sizeof(struct xonar_data),
603 .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
604 PLAYBACK_1_TO_SPDIF |
605 CAPTURE_0_FROM_I2S_2,
606 .dac_channels = 8,
607 .dac_volume_min = 0,
608 .dac_volume_max = 127,
609 .function_flags = OXYGEN_FUNCTION_2WIRE,
610 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
611 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
612 },
412}; 613};
413 614
414static int __devinit xonar_probe(struct pci_dev *pci, 615static int __devinit xonar_probe(struct pci_dev *pci,
@@ -423,7 +624,8 @@ static int __devinit xonar_probe(struct pci_dev *pci,
423 ++dev; 624 ++dev;
424 return -ENOENT; 625 return -ENOENT;
425 } 626 }
426 err = oxygen_pci_probe(pci, index[dev], id[dev], 1, &model_xonar); 627 err = oxygen_pci_probe(pci, index[dev], id[dev],
628 &xonar_models[pci_id->driver_data]);
427 if (err >= 0) 629 if (err >= 0)
428 ++dev; 630 ++dev;
429 return err; 631 return err;