aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/xonar_cs43xx.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-09-28 05:16:41 -0400
committerTakashi Iwai <tiwai@suse.de>2009-09-28 05:54:11 -0400
commit3d8bb454c4fbe18cea1adfd4183a4a9ef5f0ef04 (patch)
tree77cc05fe4547c3945940d20002e41a48acaa0db6 /sound/pci/oxygen/xonar_cs43xx.c
parent75919d7c057be888c7cd7b192fad02182260b04a (diff)
sound: oxygen: add stereo upmixing to center/LFE channels
Add the possibility to route a mix of the two channels of stereo data to the center and LFE outputs. This is implemented only for models where the DACs support this, i.e., for the Xonar D1 and DX. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen/xonar_cs43xx.c')
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index 8fb5797577dd..0fa05ed6681d 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -67,6 +67,7 @@ struct xonar_cs43xx {
67 struct xonar_generic generic; 67 struct xonar_generic generic;
68 u8 cs4398_fm; 68 u8 cs4398_fm;
69 u8 cs4362a_fm; 69 u8 cs4362a_fm;
70 u8 cs4362a_fm_c;
70}; 71};
71 72
72static void cs4398_write(struct oxygen *chip, u8 reg, u8 value) 73static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
@@ -128,7 +129,7 @@ static void cs43xx_init(struct oxygen *chip)
128 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE); 129 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
129 cs4362a_write(chip, 0x05, 0); 130 cs4362a_write(chip, 0x05, 0);
130 cs4362a_write(chip, 0x06, data->cs4362a_fm); 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 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
133 update_cs43xx_volume(chip); 134 update_cs43xx_volume(chip);
134 update_cs43xx_mute(chip); 135 update_cs43xx_mute(chip);
@@ -146,6 +147,7 @@ static void xonar_d1_init(struct oxygen *chip)
146 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; 147 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
147 data->cs4362a_fm = CS4362A_FM_SINGLE | 148 data->cs4362a_fm = CS4362A_FM_SINGLE |
148 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; 149 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
150 data->cs4362a_fm_c = data->cs4362a_fm;
149 151
150 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 152 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
151 OXYGEN_2WIRE_LENGTH_8 | 153 OXYGEN_2WIRE_LENGTH_8 |
@@ -202,25 +204,41 @@ static void set_cs43xx_params(struct oxygen *chip,
202 struct snd_pcm_hw_params *params) 204 struct snd_pcm_hw_params *params)
203{ 205{
204 struct xonar_cs43xx *data = chip->model_data; 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 cs4398_fm = CS4398_FM_SINGLE;
210 data->cs4362a_fm |= CS4362A_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 cs4398_fm = CS4398_FM_DOUBLE;
213 data->cs4362a_fm |= CS4362A_FM_DOUBLE; 214 cs4362a_fm = CS4362A_FM_DOUBLE;
214 } else { 215 } else {
215 data->cs4398_fm |= CS4398_FM_QUAD; 216 cs4398_fm = CS4398_FM_QUAD;
216 data->cs4362a_fm |= CS4362A_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); 224 cs4398_write(chip, 2, data->cs4398_fm);
219 cs4362a_write(chip, 0x06, data->cs4362a_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); 227 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
222} 228}
223 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 = { 242static const struct snd_kcontrol_new front_panel_switch = {
225 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
226 .name = "Front Panel Switch", 244 .name = "Front Panel Switch",
@@ -269,6 +287,7 @@ static const struct oxygen_model model_xonar_d1 = {
269 .set_adc_params = xonar_set_cs53x1_params, 287 .set_adc_params = xonar_set_cs53x1_params,
270 .update_dac_volume = update_cs43xx_volume, 288 .update_dac_volume = update_cs43xx_volume,
271 .update_dac_mute = update_cs43xx_mute, 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, 291 .ac97_switch = xonar_d1_line_mic_ac97_switch,
273 .dac_tlv = cs4362a_db_scale, 292 .dac_tlv = cs4362a_db_scale,
274 .model_data_size = sizeof(struct xonar_cs43xx), 293 .model_data_size = sizeof(struct xonar_cs43xx),