1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * card driver for models with PCM1796 DACs (Xonar D2/D2X/HDAV1.3/ST/STX) |
4 | * |
5 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> |
6 | */ |
7 | |
8 | /* |
9 | * Xonar D2/D2X |
10 | * ------------ |
11 | * |
12 | * CMI8788: |
13 | * |
14 | * SPI 0 -> 1st PCM1796 (front) |
15 | * SPI 1 -> 2nd PCM1796 (surround) |
16 | * SPI 2 -> 3rd PCM1796 (center/LFE) |
17 | * SPI 4 -> 4th PCM1796 (back) |
18 | * |
19 | * GPIO 2 -> M0 of CS5381 |
20 | * GPIO 3 -> M1 of CS5381 |
21 | * GPIO 5 <- external power present (D2X only) |
22 | * GPIO 7 -> ALT |
23 | * GPIO 8 -> enable output to speakers |
24 | * |
25 | * CM9780: |
26 | * |
27 | * LINE_OUT -> input of ADC |
28 | * |
29 | * AUX_IN <- aux |
30 | * VIDEO_IN <- CD |
31 | * FMIC_IN <- mic |
32 | * |
33 | * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input |
34 | */ |
35 | |
36 | /* |
37 | * Xonar HDAV1.3 (Deluxe) |
38 | * ---------------------- |
39 | * |
40 | * CMI8788: |
41 | * |
42 | * I²C <-> PCM1796 (addr 1001100) (front) |
43 | * |
44 | * GPI 0 <- external power present |
45 | * |
46 | * GPIO 0 -> enable HDMI (0) or speaker (1) output |
47 | * GPIO 2 -> M0 of CS5381 |
48 | * GPIO 3 -> M1 of CS5381 |
49 | * GPIO 4 <- daughterboard detection |
50 | * GPIO 5 <- daughterboard detection |
51 | * GPIO 6 -> ? |
52 | * GPIO 7 -> ? |
53 | * GPIO 8 -> route input jack to line-in (0) or mic-in (1) |
54 | * |
55 | * UART <-> HDMI controller |
56 | * |
57 | * CM9780: |
58 | * |
59 | * LINE_OUT -> input of ADC |
60 | * |
61 | * AUX_IN <- aux |
62 | * CD_IN <- CD |
63 | * MIC_IN <- mic |
64 | * |
65 | * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input |
66 | * |
67 | * no daughterboard |
68 | * ---------------- |
69 | * |
70 | * GPIO 4 <- 1 |
71 | * |
72 | * H6 daughterboard |
73 | * ---------------- |
74 | * |
75 | * GPIO 4 <- 0 |
76 | * GPIO 5 <- 0 |
77 | * |
78 | * I²C <-> PCM1796 (addr 1001101) (surround) |
79 | * <-> PCM1796 (addr 1001110) (center/LFE) |
80 | * <-> PCM1796 (addr 1001111) (back) |
81 | * |
82 | * unknown daughterboard |
83 | * --------------------- |
84 | * |
85 | * GPIO 4 <- 0 |
86 | * GPIO 5 <- 1 |
87 | * |
88 | * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back) |
89 | */ |
90 | |
91 | /* |
92 | * Xonar Essence ST (Deluxe)/STX (II) |
93 | * ---------------------------------- |
94 | * |
95 | * CMI8788: |
96 | * |
97 | * I²C <-> PCM1792A (addr 1001100) |
98 | * <-> CS2000 (addr 1001110) (ST only) |
99 | * |
100 | * ADC1 MCLK -> REF_CLK of CS2000 (ST only) |
101 | * |
102 | * GPI 0 <- external power present (STX only) |
103 | * |
104 | * GPIO 0 -> enable output to speakers |
105 | * GPIO 1 -> route HP to front panel (0) or rear jack (1) |
106 | * GPIO 2 -> M0 of CS5381 |
107 | * GPIO 3 -> M1 of CS5381 |
108 | * GPIO 4 <- daughterboard detection |
109 | * GPIO 5 <- daughterboard detection |
110 | * GPIO 6 -> ? |
111 | * GPIO 7 -> route output to speaker jacks (0) or HP (1) |
112 | * GPIO 8 -> route input jack to line-in (0) or mic-in (1) |
113 | * |
114 | * PCM1792A: |
115 | * |
116 | * SCK <- CLK_OUT of CS2000 (ST only) |
117 | * |
118 | * CM9780: |
119 | * |
120 | * LINE_OUT -> input of ADC |
121 | * |
122 | * AUX_IN <- aux |
123 | * MIC_IN <- mic |
124 | * |
125 | * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input |
126 | * |
127 | * H6 daughterboard |
128 | * ---------------- |
129 | * |
130 | * GPIO 4 <- 0 |
131 | * GPIO 5 <- 0 |
132 | */ |
133 | |
134 | /* |
135 | * Xonar Xense |
136 | * ----------- |
137 | * |
138 | * CMI8788: |
139 | * |
140 | * I²C <-> PCM1796 (addr 1001100) (front) |
141 | * <-> CS4362A (addr 0011000) (surround, center/LFE, back) |
142 | * <-> CS2000 (addr 1001110) |
143 | * |
144 | * ADC1 MCLK -> REF_CLK of CS2000 |
145 | * |
146 | * GPI 0 <- external power present |
147 | * |
148 | * GPIO 0 -> enable output |
149 | * GPIO 1 -> route HP to front panel (0) or rear jack (1) |
150 | * GPIO 2 -> M0 of CS5381 |
151 | * GPIO 3 -> M1 of CS5381 |
152 | * GPIO 4 -> enable output |
153 | * GPIO 5 -> enable output |
154 | * GPIO 6 -> ? |
155 | * GPIO 7 -> route output to HP (0) or speaker (1) |
156 | * GPIO 8 -> route input jack to mic-in (0) or line-in (1) |
157 | * |
158 | * CM9780: |
159 | * |
160 | * LINE_OUT -> input of ADC |
161 | * |
162 | * AUX_IN <- aux |
163 | * VIDEO_IN <- ? |
164 | * FMIC_IN <- mic |
165 | * |
166 | * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input |
167 | * GPO 1 -> route mic-in from input jack (0) or front panel header (1) |
168 | */ |
169 | |
170 | #include <linux/pci.h> |
171 | #include <linux/delay.h> |
172 | #include <linux/mutex.h> |
173 | #include <sound/ac97_codec.h> |
174 | #include <sound/control.h> |
175 | #include <sound/core.h> |
176 | #include <sound/info.h> |
177 | #include <sound/pcm.h> |
178 | #include <sound/pcm_params.h> |
179 | #include <sound/tlv.h> |
180 | #include "xonar.h" |
181 | #include "cm9780.h" |
182 | #include "pcm1796.h" |
183 | #include "cs2000.h" |
184 | |
185 | |
186 | #define GPIO_D2X_EXT_POWER 0x0020 |
187 | #define GPIO_D2_ALT 0x0080 |
188 | #define GPIO_D2_OUTPUT_ENABLE 0x0100 |
189 | |
190 | #define GPI_EXT_POWER 0x01 |
191 | #define GPIO_INPUT_ROUTE 0x0100 |
192 | |
193 | #define GPIO_HDAV_OUTPUT_ENABLE 0x0001 |
194 | #define GPIO_HDAV_MAGIC 0x00c0 |
195 | |
196 | #define GPIO_DB_MASK 0x0030 |
197 | #define GPIO_DB_H6 0x0000 |
198 | |
199 | #define GPIO_ST_OUTPUT_ENABLE 0x0001 |
200 | #define GPIO_ST_HP_REAR 0x0002 |
201 | #define GPIO_ST_MAGIC 0x0040 |
202 | #define GPIO_ST_HP 0x0080 |
203 | |
204 | #define GPIO_XENSE_OUTPUT_ENABLE (0x0001 | 0x0010 | 0x0020) |
205 | #define GPIO_XENSE_SPEAKERS 0x0080 |
206 | |
207 | #define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */ |
208 | #define I2C_DEVICE_CS2000 0x9c /* 100111, 0, /W=0 */ |
209 | |
210 | #define PCM1796_REG_BASE 16 |
211 | |
212 | |
213 | struct xonar_pcm179x { |
214 | struct xonar_generic generic; |
215 | unsigned int dacs; |
216 | u8 pcm1796_regs[4][5]; |
217 | unsigned int current_rate; |
218 | bool h6; |
219 | bool hp_active; |
220 | s8 hp_gain_offset; |
221 | bool has_cs2000; |
222 | u8 cs2000_regs[0x1f]; |
223 | bool broken_i2c; |
224 | }; |
225 | |
226 | struct xonar_hdav { |
227 | struct xonar_pcm179x pcm179x; |
228 | struct xonar_hdmi hdmi; |
229 | }; |
230 | |
231 | |
232 | static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, |
233 | u8 reg, u8 value) |
234 | { |
235 | /* maps ALSA channel pair number to SPI output */ |
236 | static const u8 codec_map[4] = { |
237 | 0, 1, 2, 4 |
238 | }; |
239 | oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | |
240 | OXYGEN_SPI_DATA_LENGTH_2 | |
241 | OXYGEN_SPI_CLOCK_160 | |
242 | (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | |
243 | OXYGEN_SPI_CEN_LATCH_CLOCK_HI, |
244 | data: (reg << 8) | value); |
245 | } |
246 | |
247 | static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec, |
248 | u8 reg, u8 value) |
249 | { |
250 | oxygen_write_i2c(chip, I2C_DEVICE_PCM1796(codec), map: reg, data: value); |
251 | } |
252 | |
253 | static void pcm1796_write(struct oxygen *chip, unsigned int codec, |
254 | u8 reg, u8 value) |
255 | { |
256 | struct xonar_pcm179x *data = chip->model_data; |
257 | |
258 | if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) == |
259 | OXYGEN_FUNCTION_SPI) |
260 | pcm1796_write_spi(chip, codec, reg, value); |
261 | else |
262 | pcm1796_write_i2c(chip, codec, reg, value); |
263 | if ((unsigned int)(reg - PCM1796_REG_BASE) |
264 | < ARRAY_SIZE(data->pcm1796_regs[codec])) |
265 | data->pcm1796_regs[codec][reg - PCM1796_REG_BASE] = value; |
266 | } |
267 | |
268 | static void pcm1796_write_cached(struct oxygen *chip, unsigned int codec, |
269 | u8 reg, u8 value) |
270 | { |
271 | struct xonar_pcm179x *data = chip->model_data; |
272 | |
273 | if (value != data->pcm1796_regs[codec][reg - PCM1796_REG_BASE]) |
274 | pcm1796_write(chip, codec, reg, value); |
275 | } |
276 | |
277 | static void cs2000_write(struct oxygen *chip, u8 reg, u8 value) |
278 | { |
279 | struct xonar_pcm179x *data = chip->model_data; |
280 | |
281 | oxygen_write_i2c(chip, I2C_DEVICE_CS2000, map: reg, data: value); |
282 | data->cs2000_regs[reg] = value; |
283 | } |
284 | |
285 | static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value) |
286 | { |
287 | struct xonar_pcm179x *data = chip->model_data; |
288 | |
289 | if (value != data->cs2000_regs[reg]) |
290 | cs2000_write(chip, reg, value); |
291 | } |
292 | |
293 | static void pcm1796_registers_init(struct oxygen *chip) |
294 | { |
295 | struct xonar_pcm179x *data = chip->model_data; |
296 | unsigned int i; |
297 | s8 gain_offset; |
298 | |
299 | msleep(msecs: 1); |
300 | gain_offset = data->hp_active ? data->hp_gain_offset : 0; |
301 | for (i = 0; i < data->dacs; ++i) { |
302 | /* set ATLD before ATL/ATR */ |
303 | pcm1796_write(chip, codec: i, reg: 18, |
304 | value: data->pcm1796_regs[0][18 - PCM1796_REG_BASE]); |
305 | pcm1796_write(chip, codec: i, reg: 16, value: chip->dac_volume[i * 2] |
306 | + gain_offset); |
307 | pcm1796_write(chip, codec: i, reg: 17, value: chip->dac_volume[i * 2 + 1] |
308 | + gain_offset); |
309 | pcm1796_write(chip, codec: i, reg: 19, |
310 | value: data->pcm1796_regs[0][19 - PCM1796_REG_BASE]); |
311 | pcm1796_write(chip, codec: i, reg: 20, |
312 | value: data->pcm1796_regs[0][20 - PCM1796_REG_BASE]); |
313 | pcm1796_write(chip, codec: i, reg: 21, value: 0); |
314 | gain_offset = 0; |
315 | } |
316 | } |
317 | |
318 | static void pcm1796_init(struct oxygen *chip) |
319 | { |
320 | struct xonar_pcm179x *data = chip->model_data; |
321 | |
322 | data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = |
323 | PCM1796_FMT_24_I2S | PCM1796_ATLD; |
324 | if (!data->broken_i2c) |
325 | data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE; |
326 | data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = |
327 | PCM1796_FLT_SHARP | PCM1796_ATS_1; |
328 | data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = |
329 | data->h6 ? PCM1796_OS_64 : PCM1796_OS_128; |
330 | pcm1796_registers_init(chip); |
331 | data->current_rate = 48000; |
332 | } |
333 | |
334 | static void xonar_d2_init(struct oxygen *chip) |
335 | { |
336 | struct xonar_pcm179x *data = chip->model_data; |
337 | |
338 | data->generic.anti_pop_delay = 300; |
339 | data->generic.output_enable_bit = GPIO_D2_OUTPUT_ENABLE; |
340 | data->dacs = 4; |
341 | |
342 | pcm1796_init(chip); |
343 | |
344 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT); |
345 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT); |
346 | |
347 | oxygen_ac97_set_bits(chip, codec: 0, CM9780_JACK, CM9780_FMIC2MIC); |
348 | |
349 | xonar_init_cs53x1(chip); |
350 | xonar_enable_output(chip); |
351 | |
352 | snd_component_add(card: chip->card, component: "PCM1796" ); |
353 | snd_component_add(card: chip->card, component: "CS5381" ); |
354 | } |
355 | |
356 | static void xonar_d2x_init(struct oxygen *chip) |
357 | { |
358 | struct xonar_pcm179x *data = chip->model_data; |
359 | |
360 | data->generic.ext_power_reg = OXYGEN_GPIO_DATA; |
361 | data->generic.ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK; |
362 | data->generic.ext_power_bit = GPIO_D2X_EXT_POWER; |
363 | oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER); |
364 | xonar_init_ext_power(chip); |
365 | xonar_d2_init(chip); |
366 | } |
367 | |
368 | static void xonar_hdav_init(struct oxygen *chip) |
369 | { |
370 | struct xonar_hdav *data = chip->model_data; |
371 | |
372 | oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, |
373 | OXYGEN_2WIRE_LENGTH_8 | |
374 | OXYGEN_2WIRE_INTERRUPT_MASK | |
375 | OXYGEN_2WIRE_SPEED_STANDARD); |
376 | |
377 | data->pcm179x.generic.anti_pop_delay = 100; |
378 | data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE; |
379 | data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA; |
380 | data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; |
381 | data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER; |
382 | data->pcm179x.dacs = chip->model.dac_channels_mixer / 2; |
383 | data->pcm179x.h6 = chip->model.dac_channels_mixer > 2; |
384 | |
385 | pcm1796_init(chip); |
386 | |
387 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, |
388 | GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE); |
389 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE); |
390 | |
391 | xonar_init_cs53x1(chip); |
392 | xonar_init_ext_power(chip); |
393 | xonar_hdmi_init(chip, data: &data->hdmi); |
394 | xonar_enable_output(chip); |
395 | |
396 | snd_component_add(card: chip->card, component: "PCM1796" ); |
397 | snd_component_add(card: chip->card, component: "CS5381" ); |
398 | } |
399 | |
400 | static void xonar_st_init_i2c(struct oxygen *chip) |
401 | { |
402 | oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, |
403 | OXYGEN_2WIRE_LENGTH_8 | |
404 | OXYGEN_2WIRE_INTERRUPT_MASK | |
405 | OXYGEN_2WIRE_SPEED_STANDARD); |
406 | } |
407 | |
408 | static void xonar_st_init_common(struct oxygen *chip) |
409 | { |
410 | struct xonar_pcm179x *data = chip->model_data; |
411 | |
412 | data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; |
413 | data->dacs = chip->model.dac_channels_mixer / 2; |
414 | data->h6 = chip->model.dac_channels_mixer > 2; |
415 | data->hp_gain_offset = 2*-18; |
416 | |
417 | pcm1796_init(chip); |
418 | |
419 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, |
420 | GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | |
421 | GPIO_ST_MAGIC | GPIO_ST_HP); |
422 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, |
423 | GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); |
424 | |
425 | xonar_init_cs53x1(chip); |
426 | xonar_enable_output(chip); |
427 | |
428 | snd_component_add(card: chip->card, component: "PCM1792A" ); |
429 | snd_component_add(card: chip->card, component: "CS5381" ); |
430 | } |
431 | |
432 | static void cs2000_registers_init(struct oxygen *chip) |
433 | { |
434 | struct xonar_pcm179x *data = chip->model_data; |
435 | |
436 | cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_FREEZE); |
437 | cs2000_write(chip, CS2000_DEV_CTRL, value: 0); |
438 | cs2000_write(chip, CS2000_DEV_CFG_1, |
439 | CS2000_R_MOD_SEL_1 | |
440 | (0 << CS2000_R_SEL_SHIFT) | |
441 | CS2000_AUX_OUT_SRC_REF_CLK | |
442 | CS2000_EN_DEV_CFG_1); |
443 | cs2000_write(chip, CS2000_DEV_CFG_2, |
444 | value: (0 << CS2000_LOCK_CLK_SHIFT) | |
445 | CS2000_FRAC_N_SRC_STATIC); |
446 | cs2000_write(chip, CS2000_RATIO_0 + 0, value: 0x00); /* 1.0 */ |
447 | cs2000_write(chip, CS2000_RATIO_0 + 1, value: 0x10); |
448 | cs2000_write(chip, CS2000_RATIO_0 + 2, value: 0x00); |
449 | cs2000_write(chip, CS2000_RATIO_0 + 3, value: 0x00); |
450 | cs2000_write(chip, CS2000_FUN_CFG_1, |
451 | value: data->cs2000_regs[CS2000_FUN_CFG_1]); |
452 | cs2000_write(chip, CS2000_FUN_CFG_2, value: 0); |
453 | cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2); |
454 | msleep(msecs: 3); /* PLL lock delay */ |
455 | } |
456 | |
457 | static void xonar_st_init(struct oxygen *chip) |
458 | { |
459 | struct xonar_pcm179x *data = chip->model_data; |
460 | |
461 | data->generic.anti_pop_delay = 100; |
462 | data->h6 = chip->model.dac_channels_mixer > 2; |
463 | data->has_cs2000 = true; |
464 | data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1; |
465 | data->broken_i2c = true; |
466 | |
467 | oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, |
468 | OXYGEN_RATE_48000 | |
469 | OXYGEN_I2S_FORMAT_I2S | |
470 | OXYGEN_I2S_MCLK(data->h6 ? MCLK_256 : MCLK_512) | |
471 | OXYGEN_I2S_BITS_16 | |
472 | OXYGEN_I2S_MASTER | |
473 | OXYGEN_I2S_BCLK_64); |
474 | |
475 | xonar_st_init_i2c(chip); |
476 | cs2000_registers_init(chip); |
477 | xonar_st_init_common(chip); |
478 | |
479 | snd_component_add(card: chip->card, component: "CS2000" ); |
480 | } |
481 | |
482 | static void xonar_stx_init(struct oxygen *chip) |
483 | { |
484 | struct xonar_pcm179x *data = chip->model_data; |
485 | |
486 | xonar_st_init_i2c(chip); |
487 | data->generic.anti_pop_delay = 800; |
488 | data->generic.ext_power_reg = OXYGEN_GPI_DATA; |
489 | data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; |
490 | data->generic.ext_power_bit = GPI_EXT_POWER; |
491 | xonar_init_ext_power(chip); |
492 | xonar_st_init_common(chip); |
493 | } |
494 | |
495 | static void xonar_xense_init(struct oxygen *chip) |
496 | { |
497 | struct xonar_pcm179x *data = chip->model_data; |
498 | |
499 | data->generic.ext_power_reg = OXYGEN_GPI_DATA; |
500 | data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; |
501 | data->generic.ext_power_bit = GPI_EXT_POWER; |
502 | xonar_init_ext_power(chip); |
503 | |
504 | data->generic.anti_pop_delay = 100; |
505 | data->has_cs2000 = true; |
506 | data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1; |
507 | |
508 | oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, |
509 | OXYGEN_RATE_48000 | |
510 | OXYGEN_I2S_FORMAT_I2S | |
511 | OXYGEN_I2S_MCLK(MCLK_512) | |
512 | OXYGEN_I2S_BITS_16 | |
513 | OXYGEN_I2S_MASTER | |
514 | OXYGEN_I2S_BCLK_64); |
515 | |
516 | xonar_st_init_i2c(chip); |
517 | cs2000_registers_init(chip); |
518 | |
519 | data->generic.output_enable_bit = GPIO_XENSE_OUTPUT_ENABLE; |
520 | data->dacs = 1; |
521 | data->hp_gain_offset = 2*-18; |
522 | |
523 | pcm1796_init(chip); |
524 | |
525 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, |
526 | GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | |
527 | GPIO_ST_MAGIC | GPIO_XENSE_SPEAKERS); |
528 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, |
529 | GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | |
530 | GPIO_XENSE_SPEAKERS); |
531 | |
532 | xonar_init_cs53x1(chip); |
533 | xonar_enable_output(chip); |
534 | |
535 | snd_component_add(card: chip->card, component: "PCM1796" ); |
536 | snd_component_add(card: chip->card, component: "CS5381" ); |
537 | snd_component_add(card: chip->card, component: "CS2000" ); |
538 | } |
539 | |
540 | static void xonar_d2_cleanup(struct oxygen *chip) |
541 | { |
542 | xonar_disable_output(chip); |
543 | } |
544 | |
545 | static void xonar_hdav_cleanup(struct oxygen *chip) |
546 | { |
547 | xonar_hdmi_cleanup(chip); |
548 | xonar_disable_output(chip); |
549 | msleep(msecs: 2); |
550 | } |
551 | |
552 | static void xonar_st_cleanup(struct oxygen *chip) |
553 | { |
554 | xonar_disable_output(chip); |
555 | } |
556 | |
557 | static void xonar_d2_suspend(struct oxygen *chip) |
558 | { |
559 | xonar_d2_cleanup(chip); |
560 | } |
561 | |
562 | static void xonar_hdav_suspend(struct oxygen *chip) |
563 | { |
564 | xonar_hdav_cleanup(chip); |
565 | } |
566 | |
567 | static void xonar_st_suspend(struct oxygen *chip) |
568 | { |
569 | xonar_st_cleanup(chip); |
570 | } |
571 | |
572 | static void xonar_d2_resume(struct oxygen *chip) |
573 | { |
574 | pcm1796_registers_init(chip); |
575 | xonar_enable_output(chip); |
576 | } |
577 | |
578 | static void xonar_hdav_resume(struct oxygen *chip) |
579 | { |
580 | struct xonar_hdav *data = chip->model_data; |
581 | |
582 | pcm1796_registers_init(chip); |
583 | xonar_hdmi_resume(chip, hdmi: &data->hdmi); |
584 | xonar_enable_output(chip); |
585 | } |
586 | |
587 | static void xonar_stx_resume(struct oxygen *chip) |
588 | { |
589 | pcm1796_registers_init(chip); |
590 | xonar_enable_output(chip); |
591 | } |
592 | |
593 | static void xonar_st_resume(struct oxygen *chip) |
594 | { |
595 | cs2000_registers_init(chip); |
596 | xonar_stx_resume(chip); |
597 | } |
598 | |
599 | static void update_pcm1796_oversampling(struct oxygen *chip) |
600 | { |
601 | struct xonar_pcm179x *data = chip->model_data; |
602 | unsigned int i; |
603 | u8 reg; |
604 | |
605 | if (data->current_rate <= 48000 && !data->h6) |
606 | reg = PCM1796_OS_128; |
607 | else |
608 | reg = PCM1796_OS_64; |
609 | for (i = 0; i < data->dacs; ++i) |
610 | pcm1796_write_cached(chip, codec: i, reg: 20, value: reg); |
611 | } |
612 | |
613 | static void update_pcm1796_deemph(struct oxygen *chip) |
614 | { |
615 | struct xonar_pcm179x *data = chip->model_data; |
616 | unsigned int i; |
617 | u8 reg; |
618 | |
619 | reg = data->pcm1796_regs[0][18 - PCM1796_REG_BASE] & ~PCM1796_DMF_MASK; |
620 | if (data->current_rate == 48000) |
621 | reg |= PCM1796_DMF_48; |
622 | else if (data->current_rate == 44100) |
623 | reg |= PCM1796_DMF_441; |
624 | else if (data->current_rate == 32000) |
625 | reg |= PCM1796_DMF_32; |
626 | for (i = 0; i < data->dacs; ++i) |
627 | pcm1796_write_cached(chip, codec: i, reg: 18, value: reg); |
628 | } |
629 | |
630 | static void set_pcm1796_params(struct oxygen *chip, |
631 | struct snd_pcm_hw_params *params) |
632 | { |
633 | struct xonar_pcm179x *data = chip->model_data; |
634 | |
635 | msleep(msecs: 1); |
636 | data->current_rate = params_rate(p: params); |
637 | update_pcm1796_oversampling(chip); |
638 | update_pcm1796_deemph(chip); |
639 | } |
640 | |
641 | static void update_pcm1796_volume(struct oxygen *chip) |
642 | { |
643 | struct xonar_pcm179x *data = chip->model_data; |
644 | unsigned int i; |
645 | s8 gain_offset; |
646 | |
647 | gain_offset = data->hp_active ? data->hp_gain_offset : 0; |
648 | for (i = 0; i < data->dacs; ++i) { |
649 | pcm1796_write_cached(chip, codec: i, reg: 16, value: chip->dac_volume[i * 2] |
650 | + gain_offset); |
651 | pcm1796_write_cached(chip, codec: i, reg: 17, value: chip->dac_volume[i * 2 + 1] |
652 | + gain_offset); |
653 | gain_offset = 0; |
654 | } |
655 | } |
656 | |
657 | static void update_pcm1796_mute(struct oxygen *chip) |
658 | { |
659 | struct xonar_pcm179x *data = chip->model_data; |
660 | unsigned int i; |
661 | u8 value; |
662 | |
663 | value = data->pcm1796_regs[0][18 - PCM1796_REG_BASE]; |
664 | if (chip->dac_mute) |
665 | value |= PCM1796_MUTE; |
666 | else |
667 | value &= ~PCM1796_MUTE; |
668 | for (i = 0; i < data->dacs; ++i) |
669 | pcm1796_write_cached(chip, codec: i, reg: 18, value); |
670 | } |
671 | |
672 | static void update_cs2000_rate(struct oxygen *chip, unsigned int rate) |
673 | { |
674 | struct xonar_pcm179x *data = chip->model_data; |
675 | u8 rate_mclk, reg; |
676 | |
677 | switch (rate) { |
678 | case 32000: |
679 | case 64000: |
680 | rate_mclk = OXYGEN_RATE_32000; |
681 | break; |
682 | case 44100: |
683 | case 88200: |
684 | case 176400: |
685 | rate_mclk = OXYGEN_RATE_44100; |
686 | break; |
687 | default: |
688 | case 48000: |
689 | case 96000: |
690 | case 192000: |
691 | rate_mclk = OXYGEN_RATE_48000; |
692 | break; |
693 | } |
694 | |
695 | if (rate <= 96000 && (rate > 48000 || data->h6)) { |
696 | rate_mclk |= OXYGEN_I2S_MCLK(MCLK_256); |
697 | reg = CS2000_REF_CLK_DIV_1; |
698 | } else { |
699 | rate_mclk |= OXYGEN_I2S_MCLK(MCLK_512); |
700 | reg = CS2000_REF_CLK_DIV_2; |
701 | } |
702 | |
703 | oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, value: rate_mclk, |
704 | OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); |
705 | cs2000_write_cached(chip, CS2000_FUN_CFG_1, value: reg); |
706 | msleep(msecs: 3); /* PLL lock delay */ |
707 | } |
708 | |
709 | static void set_st_params(struct oxygen *chip, |
710 | struct snd_pcm_hw_params *params) |
711 | { |
712 | update_cs2000_rate(chip, rate: params_rate(p: params)); |
713 | set_pcm1796_params(chip, params); |
714 | } |
715 | |
716 | static void set_hdav_params(struct oxygen *chip, |
717 | struct snd_pcm_hw_params *params) |
718 | { |
719 | struct xonar_hdav *data = chip->model_data; |
720 | |
721 | set_pcm1796_params(chip, params); |
722 | xonar_set_hdmi_params(chip, hdmi: &data->hdmi, params); |
723 | } |
724 | |
725 | static const struct snd_kcontrol_new alt_switch = { |
726 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
727 | .name = "Analog Loopback Switch" , |
728 | .info = snd_ctl_boolean_mono_info, |
729 | .get = xonar_gpio_bit_switch_get, |
730 | .put = xonar_gpio_bit_switch_put, |
731 | .private_value = GPIO_D2_ALT, |
732 | }; |
733 | |
734 | static int rolloff_info(struct snd_kcontrol *ctl, |
735 | struct snd_ctl_elem_info *info) |
736 | { |
737 | static const char *const names[2] = { |
738 | "Sharp Roll-off" , "Slow Roll-off" |
739 | }; |
740 | |
741 | return snd_ctl_enum_info(info, channels: 1, items: 2, names); |
742 | } |
743 | |
744 | static int rolloff_get(struct snd_kcontrol *ctl, |
745 | struct snd_ctl_elem_value *value) |
746 | { |
747 | struct oxygen *chip = ctl->private_data; |
748 | struct xonar_pcm179x *data = chip->model_data; |
749 | |
750 | value->value.enumerated.item[0] = |
751 | (data->pcm1796_regs[0][19 - PCM1796_REG_BASE] & |
752 | PCM1796_FLT_MASK) != PCM1796_FLT_SHARP; |
753 | return 0; |
754 | } |
755 | |
756 | static int rolloff_put(struct snd_kcontrol *ctl, |
757 | struct snd_ctl_elem_value *value) |
758 | { |
759 | struct oxygen *chip = ctl->private_data; |
760 | struct xonar_pcm179x *data = chip->model_data; |
761 | unsigned int i; |
762 | int changed; |
763 | u8 reg; |
764 | |
765 | mutex_lock(&chip->mutex); |
766 | reg = data->pcm1796_regs[0][19 - PCM1796_REG_BASE]; |
767 | reg &= ~PCM1796_FLT_MASK; |
768 | if (!value->value.enumerated.item[0]) |
769 | reg |= PCM1796_FLT_SHARP; |
770 | else |
771 | reg |= PCM1796_FLT_SLOW; |
772 | changed = reg != data->pcm1796_regs[0][19 - PCM1796_REG_BASE]; |
773 | if (changed) { |
774 | for (i = 0; i < data->dacs; ++i) |
775 | pcm1796_write(chip, codec: i, reg: 19, value: reg); |
776 | } |
777 | mutex_unlock(lock: &chip->mutex); |
778 | return changed; |
779 | } |
780 | |
781 | static const struct snd_kcontrol_new rolloff_control = { |
782 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
783 | .name = "DAC Filter Playback Enum" , |
784 | .info = rolloff_info, |
785 | .get = rolloff_get, |
786 | .put = rolloff_put, |
787 | }; |
788 | |
789 | static int deemph_get(struct snd_kcontrol *ctl, |
790 | struct snd_ctl_elem_value *value) |
791 | { |
792 | struct oxygen *chip = ctl->private_data; |
793 | struct xonar_pcm179x *data = chip->model_data; |
794 | |
795 | value->value.integer.value[0] = |
796 | !!(data->pcm1796_regs[0][18 - PCM1796_REG_BASE] & PCM1796_DME); |
797 | return 0; |
798 | } |
799 | |
800 | static int deemph_put(struct snd_kcontrol *ctl, |
801 | struct snd_ctl_elem_value *value) |
802 | { |
803 | struct oxygen *chip = ctl->private_data; |
804 | struct xonar_pcm179x *data = chip->model_data; |
805 | unsigned int i; |
806 | int changed; |
807 | u8 reg; |
808 | |
809 | mutex_lock(&chip->mutex); |
810 | reg = data->pcm1796_regs[0][18 - PCM1796_REG_BASE]; |
811 | if (!value->value.integer.value[0]) |
812 | reg &= ~PCM1796_DME; |
813 | else |
814 | reg |= PCM1796_DME; |
815 | changed = reg != data->pcm1796_regs[0][18 - PCM1796_REG_BASE]; |
816 | if (changed) { |
817 | for (i = 0; i < data->dacs; ++i) |
818 | pcm1796_write(chip, codec: i, reg: 18, value: reg); |
819 | } |
820 | mutex_unlock(lock: &chip->mutex); |
821 | return changed; |
822 | } |
823 | |
824 | static const struct snd_kcontrol_new deemph_control = { |
825 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
826 | .name = "De-emphasis Playback Switch" , |
827 | .info = snd_ctl_boolean_mono_info, |
828 | .get = deemph_get, |
829 | .put = deemph_put, |
830 | }; |
831 | |
832 | static const struct snd_kcontrol_new hdav_hdmi_control = { |
833 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
834 | .name = "HDMI Playback Switch" , |
835 | .info = snd_ctl_boolean_mono_info, |
836 | .get = xonar_gpio_bit_switch_get, |
837 | .put = xonar_gpio_bit_switch_put, |
838 | .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT, |
839 | }; |
840 | |
841 | static int st_output_switch_info(struct snd_kcontrol *ctl, |
842 | struct snd_ctl_elem_info *info) |
843 | { |
844 | static const char *const names[3] = { |
845 | "Speakers" , "Headphones" , "FP Headphones" |
846 | }; |
847 | |
848 | return snd_ctl_enum_info(info, channels: 1, items: 3, names); |
849 | } |
850 | |
851 | static int st_output_switch_get(struct snd_kcontrol *ctl, |
852 | struct snd_ctl_elem_value *value) |
853 | { |
854 | struct oxygen *chip = ctl->private_data; |
855 | u16 gpio; |
856 | |
857 | gpio = oxygen_read16(chip, OXYGEN_GPIO_DATA); |
858 | if (!(gpio & GPIO_ST_HP)) |
859 | value->value.enumerated.item[0] = 0; |
860 | else if (gpio & GPIO_ST_HP_REAR) |
861 | value->value.enumerated.item[0] = 1; |
862 | else |
863 | value->value.enumerated.item[0] = 2; |
864 | return 0; |
865 | } |
866 | |
867 | |
868 | static int st_output_switch_put(struct snd_kcontrol *ctl, |
869 | struct snd_ctl_elem_value *value) |
870 | { |
871 | struct oxygen *chip = ctl->private_data; |
872 | struct xonar_pcm179x *data = chip->model_data; |
873 | u16 gpio_old, gpio; |
874 | |
875 | mutex_lock(&chip->mutex); |
876 | gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA); |
877 | gpio = gpio_old; |
878 | switch (value->value.enumerated.item[0]) { |
879 | case 0: |
880 | gpio &= ~(GPIO_ST_HP | GPIO_ST_HP_REAR); |
881 | break; |
882 | case 1: |
883 | gpio |= GPIO_ST_HP | GPIO_ST_HP_REAR; |
884 | break; |
885 | case 2: |
886 | gpio = (gpio | GPIO_ST_HP) & ~GPIO_ST_HP_REAR; |
887 | break; |
888 | } |
889 | oxygen_write16(chip, OXYGEN_GPIO_DATA, value: gpio); |
890 | data->hp_active = gpio & GPIO_ST_HP; |
891 | update_pcm1796_volume(chip); |
892 | mutex_unlock(lock: &chip->mutex); |
893 | return gpio != gpio_old; |
894 | } |
895 | |
896 | static int st_hp_volume_offset_info(struct snd_kcontrol *ctl, |
897 | struct snd_ctl_elem_info *info) |
898 | { |
899 | static const char *const names[4] = { |
900 | "< 32 ohms" , "32-64 ohms" , "64-300 ohms" , "300-600 ohms" |
901 | }; |
902 | |
903 | return snd_ctl_enum_info(info, channels: 1, items: 4, names); |
904 | } |
905 | |
906 | static int st_hp_volume_offset_get(struct snd_kcontrol *ctl, |
907 | struct snd_ctl_elem_value *value) |
908 | { |
909 | struct oxygen *chip = ctl->private_data; |
910 | struct xonar_pcm179x *data = chip->model_data; |
911 | |
912 | mutex_lock(&chip->mutex); |
913 | if (data->hp_gain_offset < 2*-12) |
914 | value->value.enumerated.item[0] = 0; |
915 | else if (data->hp_gain_offset < 2*-6) |
916 | value->value.enumerated.item[0] = 1; |
917 | else if (data->hp_gain_offset < 0) |
918 | value->value.enumerated.item[0] = 2; |
919 | else |
920 | value->value.enumerated.item[0] = 3; |
921 | mutex_unlock(lock: &chip->mutex); |
922 | return 0; |
923 | } |
924 | |
925 | |
926 | static int st_hp_volume_offset_put(struct snd_kcontrol *ctl, |
927 | struct snd_ctl_elem_value *value) |
928 | { |
929 | static const s8 offsets[] = { 2*-18, 2*-12, 2*-6, 0 }; |
930 | struct oxygen *chip = ctl->private_data; |
931 | struct xonar_pcm179x *data = chip->model_data; |
932 | s8 offset; |
933 | int changed; |
934 | |
935 | if (value->value.enumerated.item[0] > 3) |
936 | return -EINVAL; |
937 | offset = offsets[value->value.enumerated.item[0]]; |
938 | mutex_lock(&chip->mutex); |
939 | changed = offset != data->hp_gain_offset; |
940 | if (changed) { |
941 | data->hp_gain_offset = offset; |
942 | update_pcm1796_volume(chip); |
943 | } |
944 | mutex_unlock(lock: &chip->mutex); |
945 | return changed; |
946 | } |
947 | |
948 | static const struct snd_kcontrol_new st_controls[] = { |
949 | { |
950 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
951 | .name = "Analog Output" , |
952 | .info = st_output_switch_info, |
953 | .get = st_output_switch_get, |
954 | .put = st_output_switch_put, |
955 | }, |
956 | { |
957 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
958 | .name = "Headphones Impedance Playback Enum" , |
959 | .info = st_hp_volume_offset_info, |
960 | .get = st_hp_volume_offset_get, |
961 | .put = st_hp_volume_offset_put, |
962 | }, |
963 | }; |
964 | |
965 | static int xense_output_switch_get(struct snd_kcontrol *ctl, |
966 | struct snd_ctl_elem_value *value) |
967 | { |
968 | struct oxygen *chip = ctl->private_data; |
969 | u16 gpio; |
970 | |
971 | gpio = oxygen_read16(chip, OXYGEN_GPIO_DATA); |
972 | if (gpio & GPIO_XENSE_SPEAKERS) |
973 | value->value.enumerated.item[0] = 0; |
974 | else if (!(gpio & GPIO_XENSE_SPEAKERS) && (gpio & GPIO_ST_HP_REAR)) |
975 | value->value.enumerated.item[0] = 1; |
976 | else |
977 | value->value.enumerated.item[0] = 2; |
978 | return 0; |
979 | } |
980 | |
981 | static int xense_output_switch_put(struct snd_kcontrol *ctl, |
982 | struct snd_ctl_elem_value *value) |
983 | { |
984 | struct oxygen *chip = ctl->private_data; |
985 | struct xonar_pcm179x *data = chip->model_data; |
986 | u16 gpio_old, gpio; |
987 | |
988 | mutex_lock(&chip->mutex); |
989 | gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA); |
990 | gpio = gpio_old; |
991 | switch (value->value.enumerated.item[0]) { |
992 | case 0: |
993 | gpio |= GPIO_XENSE_SPEAKERS | GPIO_ST_HP_REAR; |
994 | break; |
995 | case 1: |
996 | gpio = (gpio | GPIO_ST_HP_REAR) & ~GPIO_XENSE_SPEAKERS; |
997 | break; |
998 | case 2: |
999 | gpio &= ~(GPIO_XENSE_SPEAKERS | GPIO_ST_HP_REAR); |
1000 | break; |
1001 | } |
1002 | oxygen_write16(chip, OXYGEN_GPIO_DATA, value: gpio); |
1003 | data->hp_active = !(gpio & GPIO_XENSE_SPEAKERS); |
1004 | update_pcm1796_volume(chip); |
1005 | mutex_unlock(lock: &chip->mutex); |
1006 | return gpio != gpio_old; |
1007 | } |
1008 | |
1009 | static const struct snd_kcontrol_new xense_controls[] = { |
1010 | { |
1011 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1012 | .name = "Analog Output" , |
1013 | .info = st_output_switch_info, |
1014 | .get = xense_output_switch_get, |
1015 | .put = xense_output_switch_put, |
1016 | }, |
1017 | { |
1018 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1019 | .name = "Headphones Impedance Playback Enum" , |
1020 | .info = st_hp_volume_offset_info, |
1021 | .get = st_hp_volume_offset_get, |
1022 | .put = st_hp_volume_offset_put, |
1023 | }, |
1024 | }; |
1025 | |
1026 | static void xonar_line_mic_ac97_switch(struct oxygen *chip, |
1027 | unsigned int reg, unsigned int mute) |
1028 | { |
1029 | if (reg == AC97_LINE) { |
1030 | spin_lock_irq(lock: &chip->reg_lock); |
1031 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, |
1032 | value: mute ? GPIO_INPUT_ROUTE : 0, |
1033 | GPIO_INPUT_ROUTE); |
1034 | spin_unlock_irq(lock: &chip->reg_lock); |
1035 | } |
1036 | } |
1037 | |
1038 | static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -6000, 50, 0); |
1039 | |
1040 | static int xonar_d2_control_filter(struct snd_kcontrol_new *template) |
1041 | { |
1042 | if (!strncmp(template->name, "CD Capture " , 11)) |
1043 | /* CD in is actually connected to the video in pin */ |
1044 | template->private_value ^= AC97_CD ^ AC97_VIDEO; |
1045 | return 0; |
1046 | } |
1047 | |
1048 | static int xonar_st_h6_control_filter(struct snd_kcontrol_new *template) |
1049 | { |
1050 | if (!strncmp(template->name, "Master Playback " , 16)) |
1051 | /* no volume/mute, as I²C to the third DAC does not work */ |
1052 | return 1; |
1053 | return 0; |
1054 | } |
1055 | |
1056 | static int add_pcm1796_controls(struct oxygen *chip) |
1057 | { |
1058 | struct xonar_pcm179x *data = chip->model_data; |
1059 | int err; |
1060 | |
1061 | if (!data->broken_i2c) { |
1062 | err = snd_ctl_add(card: chip->card, |
1063 | kcontrol: snd_ctl_new1(kcontrolnew: &rolloff_control, private_data: chip)); |
1064 | if (err < 0) |
1065 | return err; |
1066 | err = snd_ctl_add(card: chip->card, |
1067 | kcontrol: snd_ctl_new1(kcontrolnew: &deemph_control, private_data: chip)); |
1068 | if (err < 0) |
1069 | return err; |
1070 | } |
1071 | return 0; |
1072 | } |
1073 | |
1074 | static int xonar_d2_mixer_init(struct oxygen *chip) |
1075 | { |
1076 | int err; |
1077 | |
1078 | err = snd_ctl_add(card: chip->card, kcontrol: snd_ctl_new1(kcontrolnew: &alt_switch, private_data: chip)); |
1079 | if (err < 0) |
1080 | return err; |
1081 | err = add_pcm1796_controls(chip); |
1082 | if (err < 0) |
1083 | return err; |
1084 | return 0; |
1085 | } |
1086 | |
1087 | static int xonar_hdav_mixer_init(struct oxygen *chip) |
1088 | { |
1089 | int err; |
1090 | |
1091 | err = snd_ctl_add(card: chip->card, kcontrol: snd_ctl_new1(kcontrolnew: &hdav_hdmi_control, private_data: chip)); |
1092 | if (err < 0) |
1093 | return err; |
1094 | err = add_pcm1796_controls(chip); |
1095 | if (err < 0) |
1096 | return err; |
1097 | return 0; |
1098 | } |
1099 | |
1100 | static int xonar_st_mixer_init(struct oxygen *chip) |
1101 | { |
1102 | unsigned int i; |
1103 | int err; |
1104 | |
1105 | for (i = 0; i < ARRAY_SIZE(st_controls); ++i) { |
1106 | err = snd_ctl_add(card: chip->card, |
1107 | kcontrol: snd_ctl_new1(kcontrolnew: &st_controls[i], private_data: chip)); |
1108 | if (err < 0) |
1109 | return err; |
1110 | } |
1111 | err = add_pcm1796_controls(chip); |
1112 | if (err < 0) |
1113 | return err; |
1114 | return 0; |
1115 | } |
1116 | |
1117 | static int xonar_xense_mixer_init(struct oxygen *chip) |
1118 | { |
1119 | unsigned int i; |
1120 | int err; |
1121 | |
1122 | for (i = 0; i < ARRAY_SIZE(xense_controls); ++i) { |
1123 | err = snd_ctl_add(card: chip->card, |
1124 | kcontrol: snd_ctl_new1(kcontrolnew: &xense_controls[i], private_data: chip)); |
1125 | if (err < 0) |
1126 | return err; |
1127 | } |
1128 | err = add_pcm1796_controls(chip); |
1129 | if (err < 0) |
1130 | return err; |
1131 | return 0; |
1132 | } |
1133 | |
1134 | static void dump_pcm1796_registers(struct oxygen *chip, |
1135 | struct snd_info_buffer *buffer) |
1136 | { |
1137 | struct xonar_pcm179x *data = chip->model_data; |
1138 | unsigned int dac, i; |
1139 | |
1140 | for (dac = 0; dac < data->dacs; ++dac) { |
1141 | snd_iprintf(buffer, "\nPCM1796 %u:" , dac + 1); |
1142 | for (i = 0; i < 5; ++i) |
1143 | snd_iprintf(buffer, " %02x" , |
1144 | data->pcm1796_regs[dac][i]); |
1145 | } |
1146 | snd_iprintf(buffer, "\n" ); |
1147 | } |
1148 | |
1149 | static void dump_cs2000_registers(struct oxygen *chip, |
1150 | struct snd_info_buffer *buffer) |
1151 | { |
1152 | struct xonar_pcm179x *data = chip->model_data; |
1153 | unsigned int i; |
1154 | |
1155 | if (data->has_cs2000) { |
1156 | snd_iprintf(buffer, "\nCS2000:\n00: " ); |
1157 | for (i = 1; i < 0x10; ++i) |
1158 | snd_iprintf(buffer, " %02x" , data->cs2000_regs[i]); |
1159 | snd_iprintf(buffer, "\n10:" ); |
1160 | for (i = 0x10; i < 0x1f; ++i) |
1161 | snd_iprintf(buffer, " %02x" , data->cs2000_regs[i]); |
1162 | snd_iprintf(buffer, "\n" ); |
1163 | } |
1164 | } |
1165 | |
1166 | static void dump_st_registers(struct oxygen *chip, |
1167 | struct snd_info_buffer *buffer) |
1168 | { |
1169 | dump_pcm1796_registers(chip, buffer); |
1170 | dump_cs2000_registers(chip, buffer); |
1171 | } |
1172 | |
1173 | static const struct oxygen_model model_xonar_d2 = { |
1174 | .longname = "Asus Virtuoso 200" , |
1175 | .chip = "AV200" , |
1176 | .init = xonar_d2_init, |
1177 | .control_filter = xonar_d2_control_filter, |
1178 | .mixer_init = xonar_d2_mixer_init, |
1179 | .cleanup = xonar_d2_cleanup, |
1180 | .suspend = xonar_d2_suspend, |
1181 | .resume = xonar_d2_resume, |
1182 | .set_dac_params = set_pcm1796_params, |
1183 | .set_adc_params = xonar_set_cs53x1_params, |
1184 | .update_dac_volume = update_pcm1796_volume, |
1185 | .update_dac_mute = update_pcm1796_mute, |
1186 | .dump_registers = dump_pcm1796_registers, |
1187 | .dac_tlv = pcm1796_db_scale, |
1188 | .model_data_size = sizeof(struct xonar_pcm179x), |
1189 | .device_config = PLAYBACK_0_TO_I2S | |
1190 | PLAYBACK_1_TO_SPDIF | |
1191 | CAPTURE_0_FROM_I2S_2 | |
1192 | CAPTURE_1_FROM_SPDIF | |
1193 | MIDI_OUTPUT | |
1194 | MIDI_INPUT | |
1195 | AC97_CD_INPUT, |
1196 | .dac_channels_pcm = 8, |
1197 | .dac_channels_mixer = 8, |
1198 | .dac_volume_min = 255 - 2*60, |
1199 | .dac_volume_max = 255, |
1200 | .misc_flags = OXYGEN_MISC_MIDI, |
1201 | .function_flags = OXYGEN_FUNCTION_SPI | |
1202 | OXYGEN_FUNCTION_ENABLE_SPI_4_5, |
1203 | .dac_mclks = OXYGEN_MCLKS(512, 128, 128), |
1204 | .adc_mclks = OXYGEN_MCLKS(256, 128, 128), |
1205 | .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, |
1206 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
1207 | }; |
1208 | |
1209 | static const struct oxygen_model model_xonar_hdav = { |
1210 | .longname = "Asus Virtuoso 200" , |
1211 | .chip = "AV200" , |
1212 | .init = xonar_hdav_init, |
1213 | .mixer_init = xonar_hdav_mixer_init, |
1214 | .cleanup = xonar_hdav_cleanup, |
1215 | .suspend = xonar_hdav_suspend, |
1216 | .resume = xonar_hdav_resume, |
1217 | .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter, |
1218 | .set_dac_params = set_hdav_params, |
1219 | .set_adc_params = xonar_set_cs53x1_params, |
1220 | .update_dac_volume = update_pcm1796_volume, |
1221 | .update_dac_mute = update_pcm1796_mute, |
1222 | .uart_input = xonar_hdmi_uart_input, |
1223 | .ac97_switch = xonar_line_mic_ac97_switch, |
1224 | .dump_registers = dump_pcm1796_registers, |
1225 | .dac_tlv = pcm1796_db_scale, |
1226 | .model_data_size = sizeof(struct xonar_hdav), |
1227 | .device_config = PLAYBACK_0_TO_I2S | |
1228 | PLAYBACK_1_TO_SPDIF | |
1229 | CAPTURE_0_FROM_I2S_2 | |
1230 | CAPTURE_1_FROM_SPDIF, |
1231 | .dac_channels_pcm = 8, |
1232 | .dac_channels_mixer = 2, |
1233 | .dac_volume_min = 255 - 2*60, |
1234 | .dac_volume_max = 255, |
1235 | .misc_flags = OXYGEN_MISC_MIDI, |
1236 | .function_flags = OXYGEN_FUNCTION_2WIRE, |
1237 | .dac_mclks = OXYGEN_MCLKS(512, 128, 128), |
1238 | .adc_mclks = OXYGEN_MCLKS(256, 128, 128), |
1239 | .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, |
1240 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
1241 | }; |
1242 | |
1243 | static const struct oxygen_model model_xonar_st = { |
1244 | .longname = "Asus Virtuoso 100" , |
1245 | .chip = "AV200" , |
1246 | .init = xonar_st_init, |
1247 | .mixer_init = xonar_st_mixer_init, |
1248 | .cleanup = xonar_st_cleanup, |
1249 | .suspend = xonar_st_suspend, |
1250 | .resume = xonar_st_resume, |
1251 | .set_dac_params = set_st_params, |
1252 | .set_adc_params = xonar_set_cs53x1_params, |
1253 | .update_dac_volume = update_pcm1796_volume, |
1254 | .update_dac_mute = update_pcm1796_mute, |
1255 | .ac97_switch = xonar_line_mic_ac97_switch, |
1256 | .dump_registers = dump_st_registers, |
1257 | .dac_tlv = pcm1796_db_scale, |
1258 | .model_data_size = sizeof(struct xonar_pcm179x), |
1259 | .device_config = PLAYBACK_0_TO_I2S | |
1260 | PLAYBACK_1_TO_SPDIF | |
1261 | CAPTURE_0_FROM_I2S_2 | |
1262 | CAPTURE_1_FROM_SPDIF | |
1263 | AC97_FMIC_SWITCH, |
1264 | .dac_channels_pcm = 2, |
1265 | .dac_channels_mixer = 2, |
1266 | .dac_volume_min = 255 - 2*60, |
1267 | .dac_volume_max = 255, |
1268 | .function_flags = OXYGEN_FUNCTION_2WIRE, |
1269 | .dac_mclks = OXYGEN_MCLKS(512, 128, 128), |
1270 | .adc_mclks = OXYGEN_MCLKS(256, 128, 128), |
1271 | .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, |
1272 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
1273 | }; |
1274 | |
1275 | int get_xonar_pcm179x_model(struct oxygen *chip, |
1276 | const struct pci_device_id *id) |
1277 | { |
1278 | switch (id->subdevice) { |
1279 | case 0x8269: |
1280 | chip->model = model_xonar_d2; |
1281 | chip->model.shortname = "Xonar D2" ; |
1282 | break; |
1283 | case 0x82b7: |
1284 | chip->model = model_xonar_d2; |
1285 | chip->model.shortname = "Xonar D2X" ; |
1286 | chip->model.init = xonar_d2x_init; |
1287 | break; |
1288 | case 0x8314: |
1289 | chip->model = model_xonar_hdav; |
1290 | oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK); |
1291 | switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) { |
1292 | default: |
1293 | chip->model.shortname = "Xonar HDAV1.3" ; |
1294 | break; |
1295 | case GPIO_DB_H6: |
1296 | chip->model.shortname = "Xonar HDAV1.3+H6" ; |
1297 | chip->model.dac_channels_mixer = 8; |
1298 | chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); |
1299 | break; |
1300 | } |
1301 | break; |
1302 | case 0x835d: |
1303 | chip->model = model_xonar_st; |
1304 | oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK); |
1305 | switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) { |
1306 | default: |
1307 | chip->model.shortname = "Xonar ST" ; |
1308 | break; |
1309 | case GPIO_DB_H6: |
1310 | chip->model.shortname = "Xonar ST+H6" ; |
1311 | chip->model.control_filter = xonar_st_h6_control_filter; |
1312 | chip->model.dac_channels_pcm = 8; |
1313 | chip->model.dac_channels_mixer = 8; |
1314 | chip->model.dac_volume_min = 255; |
1315 | chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); |
1316 | break; |
1317 | } |
1318 | break; |
1319 | case 0x835c: |
1320 | chip->model = model_xonar_st; |
1321 | chip->model.shortname = "Xonar STX" ; |
1322 | chip->model.init = xonar_stx_init; |
1323 | chip->model.resume = xonar_stx_resume; |
1324 | chip->model.set_dac_params = set_pcm1796_params; |
1325 | break; |
1326 | case 0x85f4: |
1327 | chip->model = model_xonar_st; |
1328 | oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK); |
1329 | switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) { |
1330 | default: |
1331 | chip->model.shortname = "Xonar STX II" ; |
1332 | break; |
1333 | case GPIO_DB_H6: |
1334 | chip->model.shortname = "Xonar STX II+H6" ; |
1335 | chip->model.dac_channels_pcm = 8; |
1336 | chip->model.dac_channels_mixer = 8; |
1337 | chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); |
1338 | break; |
1339 | } |
1340 | chip->model.init = xonar_stx_init; |
1341 | chip->model.resume = xonar_stx_resume; |
1342 | chip->model.set_dac_params = set_pcm1796_params; |
1343 | break; |
1344 | case 0x8428: |
1345 | chip->model = model_xonar_st; |
1346 | chip->model.shortname = "Xonar Xense" ; |
1347 | chip->model.chip = "AV100" ; |
1348 | chip->model.init = xonar_xense_init; |
1349 | chip->model.mixer_init = xonar_xense_mixer_init; |
1350 | break; |
1351 | default: |
1352 | return -EINVAL; |
1353 | } |
1354 | return 0; |
1355 | } |
1356 | |