Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * card driver for models with CS4398/CS4362A DACs (Xonar D1/DX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Xonar D1/DX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * -----------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * CMI8788:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *   I²C <-> CS4398 (addr 1001111) (front)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *       <-> CS4362A (addr 0011000) (surround, center/LFE, back)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *   GPI 0 <- external power present (DX only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *   GPIO 0 -> enable output to speakers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *   GPIO 1 -> route output to front panel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *   GPIO 2 -> M0 of CS5361
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *   GPIO 3 -> M1 of CS5361
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *   GPIO 6 -> ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *   GPIO 7 -> ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *   GPIO 8 -> route input jack to line-in (0) or mic-in (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * CM9780:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *   LINE_OUT -> input of ADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *   AUX_IN  <- aux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *   MIC_IN  <- mic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *   FMIC_IN <- front mic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *   GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <sound/ac97_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include "xonar.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include "cm9780.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include "cs4398.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include "cs4362a.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define GPI_EXT_POWER		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define GPIO_D1_OUTPUT_ENABLE	0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define GPIO_D1_FRONT_PANEL	0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define GPIO_D1_MAGIC		0x00c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define GPIO_D1_INPUT_ROUTE	0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define I2C_DEVICE_CS4398	0x9e	/* 10011, AD1=1, AD0=1, /W=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define I2C_DEVICE_CS4362A	0x30	/* 001100, AD0=0, /W=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) struct xonar_cs43xx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	struct xonar_generic generic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	u8 cs4398_regs[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	u8 cs4362a_regs[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (reg < ARRAY_SIZE(data->cs4398_regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		data->cs4398_regs[reg] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static void cs4398_write_cached(struct oxygen *chip, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (value != data->cs4398_regs[reg])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		cs4398_write(chip, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (reg < ARRAY_SIZE(data->cs4362a_regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		data->cs4362a_regs[reg] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) static void cs4362a_write_cached(struct oxygen *chip, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (value != data->cs4362a_regs[reg])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		cs4362a_write(chip, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void cs43xx_registers_init(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	/* set CPEN (control port mode) and power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	/* configure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	cs4398_write(chip, 2, data->cs4398_regs[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	cs4398_write(chip, 4, data->cs4398_regs[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	cs4398_write(chip, 5, data->cs4398_regs[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	cs4398_write(chip, 6, data->cs4398_regs[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	cs4398_write(chip, 7, data->cs4398_regs[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		      CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	cs4362a_write(chip, 0x04, data->cs4362a_regs[0x04]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	cs4362a_write(chip, 0x05, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	for (i = 6; i <= 14; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		cs4362a_write(chip, i, data->cs4362a_regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	/* clear power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	cs4398_write(chip, 8, CS4398_CPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	cs4362a_write(chip, 0x01, CS4362A_CPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void xonar_d1_init(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	data->generic.anti_pop_delay = 800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	data->cs4398_regs[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	data->cs4398_regs[4] = CS4398_MUTEP_LOW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		CS4398_MUTE_B | CS4398_MUTE_A | CS4398_PAMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	data->cs4398_regs[5] = 60 * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	data->cs4398_regs[6] = 60 * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	data->cs4398_regs[7] = CS4398_RMP_DN | CS4398_RMP_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		CS4398_ZERO_CROSS | CS4398_SOFT_RAMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	data->cs4362a_regs[4] = CS4362A_RMP_DN | CS4362A_DEM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	data->cs4362a_regs[6] = CS4362A_FM_SINGLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	data->cs4362a_regs[7] = 60 | CS4362A_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	data->cs4362a_regs[8] = 60 | CS4362A_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	data->cs4362a_regs[9] = data->cs4362a_regs[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	data->cs4362a_regs[10] = 60 | CS4362A_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	data->cs4362a_regs[11] = 60 | CS4362A_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	data->cs4362a_regs[12] = data->cs4362a_regs[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	data->cs4362a_regs[13] = 60 | CS4362A_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	data->cs4362a_regs[14] = 60 | CS4362A_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		       OXYGEN_2WIRE_LENGTH_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		       OXYGEN_2WIRE_INTERRUPT_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		       OXYGEN_2WIRE_SPEED_FAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	cs43xx_registers_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			  GPIO_D1_FRONT_PANEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			  GPIO_D1_MAGIC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			  GPIO_D1_INPUT_ROUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			    GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	xonar_init_cs53x1(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	xonar_enable_output(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	snd_component_add(chip->card, "CS4398");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	snd_component_add(chip->card, "CS4362A");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	snd_component_add(chip->card, "CS5361");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static void xonar_dx_init(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	data->generic.ext_power_reg = OXYGEN_GPI_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	data->generic.ext_power_bit = GPI_EXT_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	xonar_init_ext_power(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	xonar_d1_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void xonar_d1_cleanup(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	xonar_disable_output(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static void xonar_d1_suspend(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	xonar_d1_cleanup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static void xonar_d1_resume(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	cs43xx_registers_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	xonar_enable_output(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static void set_cs43xx_params(struct oxygen *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			      struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	u8 cs4398_fm, cs4362a_fm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (params_rate(params) <= 50000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		cs4398_fm = CS4398_FM_SINGLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		cs4362a_fm = CS4362A_FM_SINGLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	} else if (params_rate(params) <= 100000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		cs4398_fm = CS4398_FM_DOUBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		cs4362a_fm = CS4362A_FM_DOUBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		cs4398_fm = CS4398_FM_QUAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		cs4362a_fm = CS4362A_FM_QUAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	cs4398_fm |= CS4398_DEM_NONE | CS4398_DIF_LJUST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	cs4398_write_cached(chip, 2, cs4398_fm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	cs4362a_fm |= data->cs4362a_regs[6] & ~CS4362A_FM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	cs4362a_write_cached(chip, 6, cs4362a_fm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	cs4362a_write_cached(chip, 12, cs4362a_fm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	cs4362a_fm &= CS4362A_FM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	cs4362a_fm |= data->cs4362a_regs[9] & ~CS4362A_FM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	cs4362a_write_cached(chip, 9, cs4362a_fm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static void update_cs4362a_volumes(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	u8 mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	mute = chip->dac_mute ? CS4362A_MUTE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	for (i = 0; i < 6; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		cs4362a_write_cached(chip, 7 + i + i / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				     (127 - chip->dac_volume[2 + i]) | mute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static void update_cs43xx_volume(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	cs4398_write_cached(chip, 5, (127 - chip->dac_volume[0]) * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	cs4398_write_cached(chip, 6, (127 - chip->dac_volume[1]) * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	update_cs4362a_volumes(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static void update_cs43xx_mute(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (chip->dac_mute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		reg |= CS4398_MUTE_B | CS4398_MUTE_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	cs4398_write_cached(chip, 4, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	update_cs4362a_volumes(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	reg = data->cs4362a_regs[9] & ~CS4362A_ATAPI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (mixed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		reg |= CS4362A_ATAPI_B_LR | CS4362A_ATAPI_A_LR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		reg |= CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	cs4362a_write_cached(chip, 9, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static const struct snd_kcontrol_new front_panel_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	.name = "Front Panel Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	.info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	.get = xonar_gpio_bit_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	.put = xonar_gpio_bit_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	.private_value = GPIO_D1_FRONT_PANEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int rolloff_info(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	static const char *const names[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		"Fast Roll-off", "Slow Roll-off"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	return snd_ctl_enum_info(info, 1, 2, names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int rolloff_get(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		       struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	value->value.enumerated.item[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		(data->cs4398_regs[7] & CS4398_FILT_SEL) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int rolloff_put(struct snd_kcontrol *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		       struct snd_ctl_elem_value *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	struct oxygen *chip = ctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	int changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	reg = data->cs4398_regs[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (value->value.enumerated.item[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		reg |= CS4398_FILT_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		reg &= ~CS4398_FILT_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	changed = reg != data->cs4398_regs[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		cs4398_write(chip, 7, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		if (reg & CS4398_FILT_SEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			reg = data->cs4362a_regs[0x04] | CS4362A_FILT_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			reg = data->cs4362a_regs[0x04] & ~CS4362A_FILT_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		cs4362a_write(chip, 0x04, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static const struct snd_kcontrol_new rolloff_control = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	.name = "DAC Filter Playback Enum",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	.info = rolloff_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	.get = rolloff_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	.put = rolloff_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 					  unsigned int reg, unsigned int mute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (reg == AC97_LINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 				      mute ? GPIO_D1_INPUT_ROUTE : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 				      GPIO_D1_INPUT_ROUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static int xonar_d1_mixer_init(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	err = snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static void dump_cs4362a_registers(struct xonar_cs43xx *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 				   struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	snd_iprintf(buffer, "\nCS4362A:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	for (i = 1; i <= 14; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static void dump_d1_registers(struct oxygen *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			      struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	struct xonar_cs43xx *data = chip->model_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	snd_iprintf(buffer, "\nCS4398: 7?");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	for (i = 2; i < 8; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	dump_cs4362a_registers(data, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static const struct oxygen_model model_xonar_d1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	.longname = "Asus Virtuoso 100",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	.chip = "AV200",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	.init = xonar_d1_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	.mixer_init = xonar_d1_mixer_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	.cleanup = xonar_d1_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	.suspend = xonar_d1_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	.resume = xonar_d1_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	.set_dac_params = set_cs43xx_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	.set_adc_params = xonar_set_cs53x1_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	.update_dac_volume = update_cs43xx_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	.update_dac_mute = update_cs43xx_mute,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	.update_center_lfe_mix = update_cs43xx_center_lfe_mix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	.ac97_switch = xonar_d1_line_mic_ac97_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	.dump_registers = dump_d1_registers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	.dac_tlv = cs4362a_db_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	.model_data_size = sizeof(struct xonar_cs43xx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	.device_config = PLAYBACK_0_TO_I2S |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			 PLAYBACK_1_TO_SPDIF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			 CAPTURE_0_FROM_I2S_2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			 CAPTURE_1_FROM_SPDIF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			 AC97_FMIC_SWITCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	.dac_channels_pcm = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	.dac_channels_mixer = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	.dac_volume_min = 127 - 60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	.dac_volume_max = 127,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	.function_flags = OXYGEN_FUNCTION_2WIRE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	.dac_mclks = OXYGEN_MCLKS(256, 128, 128),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	.adc_mclks = OXYGEN_MCLKS(256, 128, 128),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int get_xonar_cs43xx_model(struct oxygen *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			   const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	switch (id->subdevice) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	case 0x834f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		chip->model = model_xonar_d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		chip->model.shortname = "Xonar D1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	case 0x8275:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	case 0x8327:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		chip->model = model_xonar_d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		chip->model.shortname = "Xonar DX";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		chip->model.init = xonar_dx_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }