1356 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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/D2X10 * ------------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 CS538120 * GPIO 3 -> M1 of CS538121 * GPIO 5 <- external power present (D2X only)22 * GPIO 7 -> ALT23 * GPIO 8 -> enable output to speakers24 *25 * CM9780:26 *27 * LINE_OUT -> input of ADC28 *29 * AUX_IN <- aux30 * VIDEO_IN <- CD31 * FMIC_IN <- mic32 *33 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input34 */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 present45 *46 * GPIO 0 -> enable HDMI (0) or speaker (1) output47 * GPIO 2 -> M0 of CS538148 * GPIO 3 -> M1 of CS538149 * GPIO 4 <- daughterboard detection50 * GPIO 5 <- daughterboard detection51 * GPIO 6 -> ?52 * GPIO 7 -> ?53 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)54 *55 * UART <-> HDMI controller56 *57 * CM9780:58 *59 * LINE_OUT -> input of ADC60 *61 * AUX_IN <- aux62 * CD_IN <- CD63 * MIC_IN <- mic64 *65 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input66 *67 * no daughterboard68 * ----------------69 *70 * GPIO 4 <- 171 *72 * H6 daughterboard73 * ----------------74 *75 * GPIO 4 <- 076 * GPIO 5 <- 077 *78 * I²C <-> PCM1796 (addr 1001101) (surround)79 * <-> PCM1796 (addr 1001110) (center/LFE)80 * <-> PCM1796 (addr 1001111) (back)81 *82 * unknown daughterboard83 * ---------------------84 *85 * GPIO 4 <- 086 * GPIO 5 <- 187 *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 speakers105 * GPIO 1 -> route HP to front panel (0) or rear jack (1)106 * GPIO 2 -> M0 of CS5381107 * GPIO 3 -> M1 of CS5381108 * GPIO 4 <- daughterboard detection109 * GPIO 5 <- daughterboard detection110 * 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 ADC121 *122 * AUX_IN <- aux123 * MIC_IN <- mic124 *125 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input126 *127 * H6 daughterboard128 * ----------------129 *130 * GPIO 4 <- 0131 * GPIO 5 <- 0132 */133 134/*135 * Xonar Xense136 * -----------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 CS2000145 *146 * GPI 0 <- external power present147 *148 * GPIO 0 -> enable output149 * GPIO 1 -> route HP to front panel (0) or rear jack (1)150 * GPIO 2 -> M0 of CS5381151 * GPIO 3 -> M1 of CS5381152 * GPIO 4 -> enable output153 * GPIO 5 -> enable output154 * 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 ADC161 *162 * AUX_IN <- aux163 * VIDEO_IN <- ?164 * FMIC_IN <- mic165 *166 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input167 * 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 0x0020187#define GPIO_D2_ALT 0x0080188#define GPIO_D2_OUTPUT_ENABLE 0x0100189 190#define GPI_EXT_POWER 0x01191#define GPIO_INPUT_ROUTE 0x0100192 193#define GPIO_HDAV_OUTPUT_ENABLE 0x0001194#define GPIO_HDAV_MAGIC 0x00c0195 196#define GPIO_DB_MASK 0x0030197#define GPIO_DB_H6 0x0000198 199#define GPIO_ST_OUTPUT_ENABLE 0x0001200#define GPIO_ST_HP_REAR 0x0002201#define GPIO_ST_MAGIC 0x0040202#define GPIO_ST_HP 0x0080203 204#define GPIO_XENSE_OUTPUT_ENABLE (0x0001 | 0x0010 | 0x0020)205#define GPIO_XENSE_SPEAKERS 0x0080206 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 16211 212 213struct 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 226struct xonar_hdav {227 struct xonar_pcm179x pcm179x;228 struct xonar_hdmi hdmi;229};230 231 232static 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, 4238 };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 (reg << 8) | value);245}246 247static 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), reg, value);251}252 253static 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 else262 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 268static 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 277static 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, reg, value);282 data->cs2000_regs[reg] = value;283}284 285static 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 293static 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(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, i, 18,304 data->pcm1796_regs[0][18 - PCM1796_REG_BASE]);305 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]306 + gain_offset);307 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]308 + gain_offset);309 pcm1796_write(chip, i, 19,310 data->pcm1796_regs[0][19 - PCM1796_REG_BASE]);311 pcm1796_write(chip, i, 20,312 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]);313 pcm1796_write(chip, i, 21, 0);314 gain_offset = 0;315 }316}317 318static 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 334static 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, 0, CM9780_JACK, CM9780_FMIC2MIC);348 349 xonar_init_cs53x1(chip);350 xonar_enable_output(chip);351 352 snd_component_add(chip->card, "PCM1796");353 snd_component_add(chip->card, "CS5381");354}355 356static 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 368static 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->hdmi);394 xonar_enable_output(chip);395 396 snd_component_add(chip->card, "PCM1796");397 snd_component_add(chip->card, "CS5381");398}399 400static 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 408static 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(chip->card, "PCM1792A");429 snd_component_add(chip->card, "CS5381");430}431 432static 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, 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 (0 << CS2000_LOCK_CLK_SHIFT) |445 CS2000_FRAC_N_SRC_STATIC);446 cs2000_write(chip, CS2000_RATIO_0 + 0, 0x00); /* 1.0 */447 cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10);448 cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00);449 cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00);450 cs2000_write(chip, CS2000_FUN_CFG_1,451 data->cs2000_regs[CS2000_FUN_CFG_1]);452 cs2000_write(chip, CS2000_FUN_CFG_2, 0);453 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2);454 msleep(3); /* PLL lock delay */455}456 457static 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(chip->card, "CS2000");480}481 482static 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 495static 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(chip->card, "PCM1796");536 snd_component_add(chip->card, "CS5381");537 snd_component_add(chip->card, "CS2000");538}539 540static void xonar_d2_cleanup(struct oxygen *chip)541{542 xonar_disable_output(chip);543}544 545static void xonar_hdav_cleanup(struct oxygen *chip)546{547 xonar_hdmi_cleanup(chip);548 xonar_disable_output(chip);549 msleep(2);550}551 552static void xonar_st_cleanup(struct oxygen *chip)553{554 xonar_disable_output(chip);555}556 557static void xonar_d2_suspend(struct oxygen *chip)558{559 xonar_d2_cleanup(chip);560}561 562static void xonar_hdav_suspend(struct oxygen *chip)563{564 xonar_hdav_cleanup(chip);565}566 567static void xonar_st_suspend(struct oxygen *chip)568{569 xonar_st_cleanup(chip);570}571 572static void xonar_d2_resume(struct oxygen *chip)573{574 pcm1796_registers_init(chip);575 xonar_enable_output(chip);576}577 578static 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, &data->hdmi);584 xonar_enable_output(chip);585}586 587static void xonar_stx_resume(struct oxygen *chip)588{589 pcm1796_registers_init(chip);590 xonar_enable_output(chip);591}592 593static void xonar_st_resume(struct oxygen *chip)594{595 cs2000_registers_init(chip);596 xonar_stx_resume(chip);597}598 599static 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 else608 reg = PCM1796_OS_64;609 for (i = 0; i < data->dacs; ++i)610 pcm1796_write_cached(chip, i, 20, reg);611}612 613static 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, i, 18, reg);628}629 630static 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(1);636 data->current_rate = params_rate(params);637 update_pcm1796_oversampling(chip);638 update_pcm1796_deemph(chip);639}640 641static 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, i, 16, chip->dac_volume[i * 2]650 + gain_offset);651 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1]652 + gain_offset);653 gain_offset = 0;654 }655}656 657static 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 else667 value &= ~PCM1796_MUTE;668 for (i = 0; i < data->dacs; ++i)669 pcm1796_write_cached(chip, i, 18, value);670}671 672static 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, rate_mclk,704 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);705 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg);706 msleep(3); /* PLL lock delay */707}708 709static void set_st_params(struct oxygen *chip,710 struct snd_pcm_hw_params *params)711{712 update_cs2000_rate(chip, params_rate(params));713 set_pcm1796_params(chip, params);714}715 716static 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, &data->hdmi, params);723}724 725static 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 734static 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, 1, 2, names);742}743 744static 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 756static 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 else771 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, i, 19, reg);776 }777 mutex_unlock(&chip->mutex);778 return changed;779}780 781static 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 789static 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 800static 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 else814 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, i, 18, reg);819 }820 mutex_unlock(&chip->mutex);821 return changed;822}823 824static 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 832static 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 841static 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, 1, 3, names);849}850 851static 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 else863 value->value.enumerated.item[0] = 2;864 return 0;865}866 867 868static 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, gpio);890 data->hp_active = gpio & GPIO_ST_HP;891 update_pcm1796_volume(chip);892 mutex_unlock(&chip->mutex);893 return gpio != gpio_old;894}895 896static 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, 1, 4, names);904}905 906static 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 else920 value->value.enumerated.item[0] = 3;921 mutex_unlock(&chip->mutex);922 return 0;923}924 925 926static 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(&chip->mutex);945 return changed;946}947 948static 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 965static 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 else977 value->value.enumerated.item[0] = 2;978 return 0;979}980 981static 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, gpio);1003 data->hp_active = !(gpio & GPIO_XENSE_SPEAKERS);1004 update_pcm1796_volume(chip);1005 mutex_unlock(&chip->mutex);1006 return gpio != gpio_old;1007}1008 1009static 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 1026static 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(&chip->reg_lock);1031 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,1032 mute ? GPIO_INPUT_ROUTE : 0,1033 GPIO_INPUT_ROUTE);1034 spin_unlock_irq(&chip->reg_lock);1035 }1036}1037 1038static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -6000, 50, 0);1039 1040static 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 1048static 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 1056static 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(chip->card,1063 snd_ctl_new1(&rolloff_control, chip));1064 if (err < 0)1065 return err;1066 err = snd_ctl_add(chip->card,1067 snd_ctl_new1(&deemph_control, chip));1068 if (err < 0)1069 return err;1070 }1071 return 0;1072}1073 1074static int xonar_d2_mixer_init(struct oxygen *chip)1075{1076 int err;1077 1078 err = snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, 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 1087static int xonar_hdav_mixer_init(struct oxygen *chip)1088{1089 int err;1090 1091 err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, 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 1100static 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(chip->card,1107 snd_ctl_new1(&st_controls[i], 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 1117static 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(chip->card,1124 snd_ctl_new1(&xense_controls[i], 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 1134static 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 1149static 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 1166static 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 1173static 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 1209static 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 1243static 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 1275int 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