aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/oxygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/oxygen/oxygen.c')
-rw-r--r--sound/pci/oxygen/oxygen.c43
1 files changed, 38 insertions, 5 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 98a8eb3c92f7..5e258b26f044 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -70,6 +70,7 @@ enum {
70 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 70 MODEL_MERIDIAN, /* AuzenTech X-Meridian */
71 MODEL_CLARO, /* HT-Omega Claro */ 71 MODEL_CLARO, /* HT-Omega Claro */
72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */ 72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */
73 MODEL_HIFIER, /* TempoTec HiFier Fantasia */
73}; 74};
74 75
75static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { 76static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
@@ -81,6 +82,8 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, 82 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF }, 83 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF },
83 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, 84 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
85 { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER },
86 { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER },
84 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 87 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
85 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 88 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
86 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, 89 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
@@ -98,6 +101,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
98#define GPIO_CLARO_HP 0x0100 101#define GPIO_CLARO_HP 0x0100
99 102
100struct generic_data { 103struct generic_data {
104 unsigned int dacs;
101 u8 ak4396_regs[4][5]; 105 u8 ak4396_regs[4][5];
102 u16 wm8785_regs[3]; 106 u16 wm8785_regs[3];
103}; 107};
@@ -148,7 +152,7 @@ static void ak4396_registers_init(struct oxygen *chip)
148 struct generic_data *data = chip->model_data; 152 struct generic_data *data = chip->model_data;
149 unsigned int i; 153 unsigned int i;
150 154
151 for (i = 0; i < 4; ++i) { 155 for (i = 0; i < data->dacs; ++i) {
152 ak4396_write(chip, i, AK4396_CONTROL_1, 156 ak4396_write(chip, i, AK4396_CONTROL_1,
153 AK4396_DIF_24_MSB | AK4396_RSTN); 157 AK4396_DIF_24_MSB | AK4396_RSTN);
154 ak4396_write(chip, i, AK4396_CONTROL_2, 158 ak4396_write(chip, i, AK4396_CONTROL_2,
@@ -166,6 +170,7 @@ static void ak4396_init(struct oxygen *chip)
166{ 170{
167 struct generic_data *data = chip->model_data; 171 struct generic_data *data = chip->model_data;
168 172
173 data->dacs = chip->model.dac_channels / 2;
169 data->ak4396_regs[0][AK4396_CONTROL_2] = 174 data->ak4396_regs[0][AK4396_CONTROL_2] =
170 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 175 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
171 ak4396_registers_init(chip); 176 ak4396_registers_init(chip);
@@ -232,6 +237,12 @@ static void claro_halo_init(struct oxygen *chip)
232 claro_enable_hp(chip); 237 claro_enable_hp(chip);
233} 238}
234 239
240static void hifier_init(struct oxygen *chip)
241{
242 ak4396_init(chip);
243 snd_component_add(chip->card, "CS5340");
244}
245
235static void generic_cleanup(struct oxygen *chip) 246static void generic_cleanup(struct oxygen *chip)
236{ 247{
237} 248}
@@ -268,6 +279,11 @@ static void claro_resume(struct oxygen *chip)
268 claro_enable_hp(chip); 279 claro_enable_hp(chip);
269} 280}
270 281
282static void stereo_resume(struct oxygen *chip)
283{
284 ak4396_registers_init(chip);
285}
286
271static void set_ak4396_params(struct oxygen *chip, 287static void set_ak4396_params(struct oxygen *chip,
272 struct snd_pcm_hw_params *params) 288 struct snd_pcm_hw_params *params)
273{ 289{
@@ -286,7 +302,7 @@ static void set_ak4396_params(struct oxygen *chip,
286 msleep(1); /* wait for the new MCLK to become stable */ 302 msleep(1); /* wait for the new MCLK to become stable */
287 303
288 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { 304 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
289 for (i = 0; i < 4; ++i) { 305 for (i = 0; i < data->dacs; ++i) {
290 ak4396_write(chip, i, AK4396_CONTROL_1, 306 ak4396_write(chip, i, AK4396_CONTROL_1,
291 AK4396_DIF_24_MSB); 307 AK4396_DIF_24_MSB);
292 ak4396_write(chip, i, AK4396_CONTROL_2, value); 308 ak4396_write(chip, i, AK4396_CONTROL_2, value);
@@ -298,9 +314,10 @@ static void set_ak4396_params(struct oxygen *chip,
298 314
299static void update_ak4396_volume(struct oxygen *chip) 315static void update_ak4396_volume(struct oxygen *chip)
300{ 316{
317 struct generic_data *data = chip->model_data;
301 unsigned int i; 318 unsigned int i;
302 319
303 for (i = 0; i < 4; ++i) { 320 for (i = 0; i < data->dacs; ++i) {
304 ak4396_write_cached(chip, i, AK4396_LCH_ATT, 321 ak4396_write_cached(chip, i, AK4396_LCH_ATT,
305 chip->dac_volume[i * 2]); 322 chip->dac_volume[i * 2]);
306 ak4396_write_cached(chip, i, AK4396_RCH_ATT, 323 ak4396_write_cached(chip, i, AK4396_RCH_ATT,
@@ -317,7 +334,7 @@ static void update_ak4396_mute(struct oxygen *chip)
317 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; 334 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
318 if (chip->dac_mute) 335 if (chip->dac_mute)
319 value |= AK4396_SMUTE; 336 value |= AK4396_SMUTE;
320 for (i = 0; i < 4; ++i) 337 for (i = 0; i < data->dacs; ++i)
321 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); 338 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
322} 339}
323 340
@@ -356,6 +373,10 @@ static void set_ak5385_params(struct oxygen *chip,
356 value, GPIO_AK5385_DFS_MASK); 373 value, GPIO_AK5385_DFS_MASK);
357} 374}
358 375
376static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params)
377{
378}
379
359static int rolloff_info(struct snd_kcontrol *ctl, 380static int rolloff_info(struct snd_kcontrol *ctl,
360 struct snd_ctl_elem_info *info) 381 struct snd_ctl_elem_info *info)
361{ 382{
@@ -400,7 +421,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
400 reg &= ~AK4396_SLOW; 421 reg &= ~AK4396_SLOW;
401 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2]; 422 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
402 if (changed) { 423 if (changed) {
403 for (i = 0; i < 4; ++i) 424 for (i = 0; i < data->dacs; ++i)
404 ak4396_write(chip, i, AK4396_CONTROL_2, reg); 425 ak4396_write(chip, i, AK4396_CONTROL_2, reg);
405 } 426 }
406 mutex_unlock(&chip->mutex); 427 mutex_unlock(&chip->mutex);
@@ -550,6 +571,18 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
550 CAPTURE_0_FROM_I2S_2 | 571 CAPTURE_0_FROM_I2S_2 |
551 CAPTURE_1_FROM_SPDIF; 572 CAPTURE_1_FROM_SPDIF;
552 break; 573 break;
574 case MODEL_HIFIER:
575 chip->model.shortname = "C-Media CMI8787";
576 chip->model.chip = "CMI8787";
577 chip->model.init = hifier_init;
578 chip->model.resume = stereo_resume;
579 chip->model.mixer_init = generic_mixer_init;
580 chip->model.set_adc_params = set_no_params;
581 chip->model.device_config = PLAYBACK_0_TO_I2S |
582 PLAYBACK_1_TO_SPDIF |
583 CAPTURE_0_FROM_I2S_1;
584 chip->model.dac_channels = 2;
585 break;
553 } 586 }
554 if (id->driver_data == MODEL_MERIDIAN || 587 if (id->driver_data == MODEL_MERIDIAN ||
555 id->driver_data == MODEL_CLARO_HALO) { 588 id->driver_data == MODEL_CLARO_HALO) {