aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/oxygen')
-rw-r--r--sound/pci/oxygen/oxygen.h1
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c33
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c6
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c39
4 files changed, 58 insertions, 21 deletions
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index bd615dbffadb..2ac3b3c8253f 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -84,6 +84,7 @@ struct oxygen_model {
84 struct snd_pcm_hw_params *params); 84 struct snd_pcm_hw_params *params);
85 void (*update_dac_volume)(struct oxygen *chip); 85 void (*update_dac_volume)(struct oxygen *chip);
86 void (*update_dac_mute)(struct oxygen *chip); 86 void (*update_dac_mute)(struct oxygen *chip);
87 void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed);
87 void (*gpio_changed)(struct oxygen *chip); 88 void (*gpio_changed)(struct oxygen *chip);
88 void (*uart_input)(struct oxygen *chip); 89 void (*uart_input)(struct oxygen *chip);
89 void (*ac97_switch)(struct oxygen *chip, 90 void (*ac97_switch)(struct oxygen *chip,
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index e8e911a86c8e..5dfb5fb73381 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -99,11 +99,15 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
99 99
100static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 100static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
101{ 101{
102 static const char *const names[3] = { 102 static const char *const names[5] = {
103 "Front", "Front+Surround", "Front+Surround+Back" 103 "Front",
104 "Front+Surround",
105 "Front+Surround+Back",
106 "Front+Surround+Center/LFE",
107 "Front+Surround+Center/LFE+Back",
104 }; 108 };
105 struct oxygen *chip = ctl->private_data; 109 struct oxygen *chip = ctl->private_data;
106 unsigned int count = 2 + (chip->model.dac_channels == 8); 110 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3;
107 111
108 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 112 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
109 info->count = 1; 113 info->count = 1;
@@ -127,7 +131,7 @@ static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
127void oxygen_update_dac_routing(struct oxygen *chip) 131void oxygen_update_dac_routing(struct oxygen *chip)
128{ 132{
129 /* DAC 0: front, DAC 1: surround, DAC 2: center/LFE, DAC 3: back */ 133 /* DAC 0: front, DAC 1: surround, DAC 2: center/LFE, DAC 3: back */
130 static const unsigned int reg_values[3] = { 134 static const unsigned int reg_values[5] = {
131 /* stereo -> front */ 135 /* stereo -> front */
132 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) | 136 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
133 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) | 137 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
@@ -143,6 +147,16 @@ void oxygen_update_dac_routing(struct oxygen *chip)
143 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) | 147 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
144 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) | 148 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
145 (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT), 149 (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
150 /* stereo -> front+surround+center/LFE */
151 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
152 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
153 (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
154 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
155 /* stereo -> front+surround+center/LFE+back */
156 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
157 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
158 (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
159 (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
146 }; 160 };
147 u8 channels; 161 u8 channels;
148 unsigned int reg_value; 162 unsigned int reg_value;
@@ -167,22 +181,23 @@ void oxygen_update_dac_routing(struct oxygen *chip)
167 OXYGEN_PLAY_DAC1_SOURCE_MASK | 181 OXYGEN_PLAY_DAC1_SOURCE_MASK |
168 OXYGEN_PLAY_DAC2_SOURCE_MASK | 182 OXYGEN_PLAY_DAC2_SOURCE_MASK |
169 OXYGEN_PLAY_DAC3_SOURCE_MASK); 183 OXYGEN_PLAY_DAC3_SOURCE_MASK);
184 if (chip->model.update_center_lfe_mix)
185 chip->model.update_center_lfe_mix(chip, chip->dac_routing > 2);
170} 186}
171 187
172static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 188static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
173{ 189{
174 struct oxygen *chip = ctl->private_data; 190 struct oxygen *chip = ctl->private_data;
175 unsigned int count = 2 + (chip->model.dac_channels == 8); 191 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3;
176 int changed; 192 int changed;
177 193
194 if (value->value.enumerated.item[0] >= count)
195 return -EINVAL;
178 mutex_lock(&chip->mutex); 196 mutex_lock(&chip->mutex);
179 changed = value->value.enumerated.item[0] != chip->dac_routing; 197 changed = value->value.enumerated.item[0] != chip->dac_routing;
180 if (changed) { 198 if (changed) {
181 chip->dac_routing = min(value->value.enumerated.item[0], 199 chip->dac_routing = value->value.enumerated.item[0];
182 count - 1);
183 spin_lock_irq(&chip->reg_lock);
184 oxygen_update_dac_routing(chip); 200 oxygen_update_dac_routing(chip);
185 spin_unlock_irq(&chip->reg_lock);
186 } 201 }
187 mutex_unlock(&chip->mutex); 202 mutex_unlock(&chip->mutex);
188 return changed; 203 return changed;
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index ef2345d82b86..1e98333366df 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -435,6 +435,7 @@ static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
435 if (err < 0) 435 if (err < 0)
436 return err; 436 return err;
437 437
438 mutex_lock(&chip->mutex);
438 spin_lock_irq(&chip->reg_lock); 439 spin_lock_irq(&chip->reg_lock);
439 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, 440 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
440 OXYGEN_SPDIF_OUT_ENABLE); 441 OXYGEN_SPDIF_OUT_ENABLE);
@@ -446,6 +447,7 @@ static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
446 OXYGEN_SPDIF_OUT_RATE_MASK); 447 OXYGEN_SPDIF_OUT_RATE_MASK);
447 oxygen_update_spdif_source(chip); 448 oxygen_update_spdif_source(chip);
448 spin_unlock_irq(&chip->reg_lock); 449 spin_unlock_irq(&chip->reg_lock);
450 mutex_unlock(&chip->mutex);
449 return 0; 451 return 0;
450} 452}
451 453
@@ -459,6 +461,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
459 if (err < 0) 461 if (err < 0)
460 return err; 462 return err;
461 463
464 mutex_lock(&chip->mutex);
462 spin_lock_irq(&chip->reg_lock); 465 spin_lock_irq(&chip->reg_lock);
463 oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS, 466 oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS,
464 oxygen_play_channels(hw_params), 467 oxygen_play_channels(hw_params),
@@ -475,12 +478,11 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
475 OXYGEN_I2S_FORMAT_MASK | 478 OXYGEN_I2S_FORMAT_MASK |
476 OXYGEN_I2S_MCLK_MASK | 479 OXYGEN_I2S_MCLK_MASK |
477 OXYGEN_I2S_BITS_MASK); 480 OXYGEN_I2S_BITS_MASK);
478 oxygen_update_dac_routing(chip);
479 oxygen_update_spdif_source(chip); 481 oxygen_update_spdif_source(chip);
480 spin_unlock_irq(&chip->reg_lock); 482 spin_unlock_irq(&chip->reg_lock);
481 483
482 mutex_lock(&chip->mutex);
483 chip->model.set_dac_params(chip, hw_params); 484 chip->model.set_dac_params(chip, hw_params);
485 oxygen_update_dac_routing(chip);
484 mutex_unlock(&chip->mutex); 486 mutex_unlock(&chip->mutex);
485 return 0; 487 return 0;
486} 488}
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),