xonar_cs43xx.c (65c3ac885ce9852852b895a4a62212f62cb5f2e9) xonar_cs43xx.c (3d8bb454c4fbe18cea1adfd4183a4a9ef5f0ef04)
1/*
2 * card driver for models with CS4398/CS4362A DACs (Xonar D1/DX)
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.

--- 53 unchanged lines hidden (view full) ---

62
63#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
64#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
65
66struct xonar_cs43xx {
67 struct xonar_generic generic;
68 u8 cs4398_fm;
69 u8 cs4362a_fm;
1/*
2 * card driver for models with CS4398/CS4362A DACs (Xonar D1/DX)
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.

--- 53 unchanged lines hidden (view full) ---

62
63#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
64#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
65
66struct xonar_cs43xx {
67 struct xonar_generic generic;
68 u8 cs4398_fm;
69 u8 cs4362a_fm;
70 u8 cs4362a_fm_c;
70};
71
72static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
73{
74 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
75}
76
77static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)

--- 45 unchanged lines hidden (view full) ---

123 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP |
124 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
125 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
126 cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
127 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
128 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
129 cs4362a_write(chip, 0x05, 0);
130 cs4362a_write(chip, 0x06, data->cs4362a_fm);
71};
72
73static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
74{
75 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
76}
77
78static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)

--- 45 unchanged lines hidden (view full) ---

124 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP |
125 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
126 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
127 cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
128 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
129 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
130 cs4362a_write(chip, 0x05, 0);
131 cs4362a_write(chip, 0x06, data->cs4362a_fm);
131 cs4362a_write(chip, 0x09, data->cs4362a_fm);
132 cs4362a_write(chip, 0x09, data->cs4362a_fm_c);
132 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
133 update_cs43xx_volume(chip);
134 update_cs43xx_mute(chip);
135 /* clear power down */
136 cs4398_write(chip, 8, CS4398_CPEN);
137 cs4362a_write(chip, 0x01, CS4362A_CPEN);
138}
139
140static void xonar_d1_init(struct oxygen *chip)
141{
142 struct xonar_cs43xx *data = chip->model_data;
143
144 data->generic.anti_pop_delay = 800;
145 data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE;
146 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
147 data->cs4362a_fm = CS4362A_FM_SINGLE |
148 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
133 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
134 update_cs43xx_volume(chip);
135 update_cs43xx_mute(chip);
136 /* clear power down */
137 cs4398_write(chip, 8, CS4398_CPEN);
138 cs4362a_write(chip, 0x01, CS4362A_CPEN);
139}
140
141static void xonar_d1_init(struct oxygen *chip)
142{
143 struct xonar_cs43xx *data = chip->model_data;
144
145 data->generic.anti_pop_delay = 800;
146 data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE;
147 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
148 data->cs4362a_fm = CS4362A_FM_SINGLE |
149 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
150 data->cs4362a_fm_c = data->cs4362a_fm;
149
150 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
151 OXYGEN_2WIRE_LENGTH_8 |
152 OXYGEN_2WIRE_INTERRUPT_MASK |
153 OXYGEN_2WIRE_SPEED_FAST);
154
155 cs43xx_init(chip);
156

--- 40 unchanged lines hidden (view full) ---

197 cs43xx_init(chip);
198 xonar_enable_output(chip);
199}
200
201static void set_cs43xx_params(struct oxygen *chip,
202 struct snd_pcm_hw_params *params)
203{
204 struct xonar_cs43xx *data = chip->model_data;
151
152 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
153 OXYGEN_2WIRE_LENGTH_8 |
154 OXYGEN_2WIRE_INTERRUPT_MASK |
155 OXYGEN_2WIRE_SPEED_FAST);
156
157 cs43xx_init(chip);
158

--- 40 unchanged lines hidden (view full) ---

199 cs43xx_init(chip);
200 xonar_enable_output(chip);
201}
202
203static void set_cs43xx_params(struct oxygen *chip,
204 struct snd_pcm_hw_params *params)
205{
206 struct xonar_cs43xx *data = chip->model_data;
207 u8 cs4398_fm, cs4362a_fm;
205
208
206 data->cs4398_fm = CS4398_DEM_NONE | CS4398_DIF_LJUST;
207 data->cs4362a_fm = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
208 if (params_rate(params) <= 50000) {
209 if (params_rate(params) <= 50000) {
209 data->cs4398_fm |= CS4398_FM_SINGLE;
210 data->cs4362a_fm |= CS4362A_FM_SINGLE;
210 cs4398_fm = CS4398_FM_SINGLE;
211 cs4362a_fm = CS4362A_FM_SINGLE;
211 } else if (params_rate(params) <= 100000) {
212 } else if (params_rate(params) <= 100000) {
212 data->cs4398_fm |= CS4398_FM_DOUBLE;
213 data->cs4362a_fm |= CS4362A_FM_DOUBLE;
213 cs4398_fm = CS4398_FM_DOUBLE;
214 cs4362a_fm = CS4362A_FM_DOUBLE;
214 } else {
215 } else {
215 data->cs4398_fm |= CS4398_FM_QUAD;
216 data->cs4362a_fm |= CS4362A_FM_QUAD;
216 cs4398_fm = CS4398_FM_QUAD;
217 cs4362a_fm = CS4362A_FM_QUAD;
217 }
218 }
219 data->cs4398_fm = CS4398_DEM_NONE | CS4398_DIF_LJUST | cs4398_fm;
220 data->cs4362a_fm =
221 (data->cs4362a_fm & ~CS4362A_FM_MASK) | cs4362a_fm;
222 data->cs4362a_fm_c =
223 (data->cs4362a_fm_c & ~CS4362A_FM_MASK) | cs4362a_fm;
218 cs4398_write(chip, 2, data->cs4398_fm);
219 cs4362a_write(chip, 0x06, data->cs4362a_fm);
224 cs4398_write(chip, 2, data->cs4398_fm);
225 cs4362a_write(chip, 0x06, data->cs4362a_fm);
220 cs4362a_write(chip, 0x09, data->cs4362a_fm);
226 cs4362a_write(chip, 0x09, data->cs4362a_fm_c);
221 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
222}
223
227 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
228}
229
230static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
231{
232 struct xonar_cs43xx *data = chip->model_data;
233
234 data->cs4362a_fm_c &= ~CS4362A_ATAPI_MASK;
235 if (mixed)
236 data->cs4362a_fm_c |= CS4362A_ATAPI_B_LR | CS4362A_ATAPI_A_LR;
237 else
238 data->cs4362a_fm_c |= CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
239 cs4362a_write(chip, 0x09, data->cs4362a_fm_c);
240}
241
224static const struct snd_kcontrol_new front_panel_switch = {
225 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
226 .name = "Front Panel Switch",
227 .info = snd_ctl_boolean_mono_info,
228 .get = xonar_gpio_bit_switch_get,
229 .put = xonar_gpio_bit_switch_put,
230 .private_value = GPIO_D1_FRONT_PANEL,
231};

--- 32 unchanged lines hidden (view full) ---

264 .mixer_init = xonar_d1_mixer_init,
265 .cleanup = xonar_d1_cleanup,
266 .suspend = xonar_d1_suspend,
267 .resume = xonar_d1_resume,
268 .set_dac_params = set_cs43xx_params,
269 .set_adc_params = xonar_set_cs53x1_params,
270 .update_dac_volume = update_cs43xx_volume,
271 .update_dac_mute = update_cs43xx_mute,
242static const struct snd_kcontrol_new front_panel_switch = {
243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
244 .name = "Front Panel Switch",
245 .info = snd_ctl_boolean_mono_info,
246 .get = xonar_gpio_bit_switch_get,
247 .put = xonar_gpio_bit_switch_put,
248 .private_value = GPIO_D1_FRONT_PANEL,
249};

--- 32 unchanged lines hidden (view full) ---

282 .mixer_init = xonar_d1_mixer_init,
283 .cleanup = xonar_d1_cleanup,
284 .suspend = xonar_d1_suspend,
285 .resume = xonar_d1_resume,
286 .set_dac_params = set_cs43xx_params,
287 .set_adc_params = xonar_set_cs53x1_params,
288 .update_dac_volume = update_cs43xx_volume,
289 .update_dac_mute = update_cs43xx_mute,
290 .update_center_lfe_mix = update_cs43xx_center_lfe_mix,
272 .ac97_switch = xonar_d1_line_mic_ac97_switch,
273 .dac_tlv = cs4362a_db_scale,
274 .model_data_size = sizeof(struct xonar_cs43xx),
275 .device_config = PLAYBACK_0_TO_I2S |
276 PLAYBACK_1_TO_SPDIF |
277 CAPTURE_0_FROM_I2S_2,
278 .dac_channels = 8,
279 .dac_volume_min = 127 - 60,

--- 25 unchanged lines hidden ---
291 .ac97_switch = xonar_d1_line_mic_ac97_switch,
292 .dac_tlv = cs4362a_db_scale,
293 .model_data_size = sizeof(struct xonar_cs43xx),
294 .device_config = PLAYBACK_0_TO_I2S |
295 PLAYBACK_1_TO_SPDIF |
296 CAPTURE_0_FROM_I2S_2,
297 .dac_channels = 8,
298 .dac_volume_min = 127 - 60,

--- 25 unchanged lines hidden ---