Lines Matching +full:chip +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0-only
3 * C-Media CMI8788 driver for C-Media's reference design and similar models
11 * SPI 0 -> 1st AK4396 (front)
12 * SPI 1 -> 2nd AK4396 (surround)
13 * SPI 2 -> 3rd AK4396 (center/LFE)
14 * SPI 3 -> WM8785
15 * SPI 4 -> 4th AK4396 (back)
17 * GPIO 0 -> DFS0 of AK5385
18 * GPIO 1 -> DFS1 of AK5385
20 * X-Meridian models:
21 * GPIO 4 -> enable extension S/PDIF input
22 * GPIO 6 -> enable on-board S/PDIF input
25 * GPIO 6 -> S/PDIF from optical (0) or coaxial (1) input
26 * GPIO 8 -> enable headphone amplifier
30 * LINE_OUT -> input of ADC
32 * AUX_IN <- aux
33 * CD_IN <- CD
34 * MIC_IN <- mic
36 * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
57 MODULE_DESCRIPTION("C-Media CMI8788 driver");
61 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; variable
66 module_param_array(id, charp, NULL, 0444);
67 MODULE_PARM_DESC(id, "ID string");
86 /* C-Media's reference design */
102 /* Kuroutoshikou CMI8787-HG2PCI */
108 /* AuzenTech X-Meridian */
110 /* AuzenTech X-Meridian 2G */
112 /* HT-Omega Claro */
114 /* HT-Omega Claro halo */
139 static void ak4396_write(struct oxygen *chip, unsigned int codec, in ak4396_write() argument
146 struct generic_data *data = chip->model_data; in ak4396_write()
148 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | in ak4396_write()
154 data->ak4396_regs[codec][reg] = value; in ak4396_write()
157 static void ak4396_write_cached(struct oxygen *chip, unsigned int codec, in ak4396_write_cached() argument
160 struct generic_data *data = chip->model_data; in ak4396_write_cached()
162 if (value != data->ak4396_regs[codec][reg]) in ak4396_write_cached()
163 ak4396_write(chip, codec, reg, value); in ak4396_write_cached()
166 static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) in wm8785_write() argument
168 struct generic_data *data = chip->model_data; in wm8785_write()
170 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | in wm8785_write()
176 if (reg < ARRAY_SIZE(data->wm8785_regs)) in wm8785_write()
177 data->wm8785_regs[reg] = value; in wm8785_write()
180 static void ak4396_registers_init(struct oxygen *chip) in ak4396_registers_init() argument
182 struct generic_data *data = chip->model_data; in ak4396_registers_init()
185 for (i = 0; i < data->dacs; ++i) { in ak4396_registers_init()
186 ak4396_write(chip, i, AK4396_CONTROL_1, in ak4396_registers_init()
188 ak4396_write(chip, i, AK4396_CONTROL_2, in ak4396_registers_init()
189 data->ak4396_regs[0][AK4396_CONTROL_2]); in ak4396_registers_init()
190 ak4396_write(chip, i, AK4396_CONTROL_3, in ak4396_registers_init()
192 ak4396_write(chip, i, AK4396_LCH_ATT, in ak4396_registers_init()
193 chip->dac_volume[i * 2]); in ak4396_registers_init()
194 ak4396_write(chip, i, AK4396_RCH_ATT, in ak4396_registers_init()
195 chip->dac_volume[i * 2 + 1]); in ak4396_registers_init()
199 static void ak4396_init(struct oxygen *chip) in ak4396_init() argument
201 struct generic_data *data = chip->model_data; in ak4396_init()
203 data->dacs = chip->model.dac_channels_pcm / 2; in ak4396_init()
204 data->ak4396_regs[0][AK4396_CONTROL_2] = in ak4396_init()
206 ak4396_registers_init(chip); in ak4396_init()
207 snd_component_add(chip->card, "AK4396"); in ak4396_init()
210 static void ak5385_init(struct oxygen *chip) in ak5385_init() argument
212 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_AK5385_DFS_MASK); in ak5385_init()
213 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_AK5385_DFS_MASK); in ak5385_init()
214 snd_component_add(chip->card, "AK5385"); in ak5385_init()
217 static void wm8785_registers_init(struct oxygen *chip) in wm8785_registers_init() argument
219 struct generic_data *data = chip->model_data; in wm8785_registers_init()
221 wm8785_write(chip, WM8785_R7, 0); in wm8785_registers_init()
222 wm8785_write(chip, WM8785_R0, data->wm8785_regs[0]); in wm8785_registers_init()
223 wm8785_write(chip, WM8785_R2, data->wm8785_regs[2]); in wm8785_registers_init()
226 static void wm8785_init(struct oxygen *chip) in wm8785_init() argument
228 struct generic_data *data = chip->model_data; in wm8785_init()
230 data->wm8785_regs[0] = in wm8785_init()
232 data->wm8785_regs[2] = WM8785_HPFR | WM8785_HPFL; in wm8785_init()
233 wm8785_registers_init(chip); in wm8785_init()
234 snd_component_add(chip->card, "WM8785"); in wm8785_init()
237 static void generic_init(struct oxygen *chip) in generic_init() argument
239 ak4396_init(chip); in generic_init()
240 wm8785_init(chip); in generic_init()
243 static void meridian_init(struct oxygen *chip) in meridian_init() argument
245 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, in meridian_init()
247 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, in meridian_init()
249 ak4396_init(chip); in meridian_init()
250 ak5385_init(chip); in meridian_init()
253 static void claro_enable_hp(struct oxygen *chip) in claro_enable_hp() argument
256 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_HP); in claro_enable_hp()
257 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP); in claro_enable_hp()
260 static void claro_init(struct oxygen *chip) in claro_init() argument
262 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX); in claro_init()
263 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX); in claro_init()
264 ak4396_init(chip); in claro_init()
265 wm8785_init(chip); in claro_init()
266 claro_enable_hp(chip); in claro_init()
269 static void claro_halo_init(struct oxygen *chip) in claro_halo_init() argument
271 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX); in claro_halo_init()
272 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX); in claro_halo_init()
273 ak4396_init(chip); in claro_halo_init()
274 ak5385_init(chip); in claro_halo_init()
275 claro_enable_hp(chip); in claro_halo_init()
278 static void fantasia_init(struct oxygen *chip) in fantasia_init() argument
280 ak4396_init(chip); in fantasia_init()
281 snd_component_add(chip->card, "CS5340"); in fantasia_init()
284 static void stereo_output_init(struct oxygen *chip) in stereo_output_init() argument
286 ak4396_init(chip); in stereo_output_init()
289 static void generic_cleanup(struct oxygen *chip) in generic_cleanup() argument
293 static void claro_disable_hp(struct oxygen *chip) in claro_disable_hp() argument
295 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP); in claro_disable_hp()
298 static void claro_cleanup(struct oxygen *chip) in claro_cleanup() argument
300 claro_disable_hp(chip); in claro_cleanup()
303 static void claro_suspend(struct oxygen *chip) in claro_suspend() argument
305 claro_disable_hp(chip); in claro_suspend()
308 static void generic_resume(struct oxygen *chip) in generic_resume() argument
310 ak4396_registers_init(chip); in generic_resume()
311 wm8785_registers_init(chip); in generic_resume()
314 static void meridian_resume(struct oxygen *chip) in meridian_resume() argument
316 ak4396_registers_init(chip); in meridian_resume()
319 static void claro_resume(struct oxygen *chip) in claro_resume() argument
321 ak4396_registers_init(chip); in claro_resume()
322 claro_enable_hp(chip); in claro_resume()
325 static void stereo_resume(struct oxygen *chip) in stereo_resume() argument
327 ak4396_registers_init(chip); in stereo_resume()
330 static void set_ak4396_params(struct oxygen *chip, in set_ak4396_params() argument
333 struct generic_data *data = chip->model_data; in set_ak4396_params()
337 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_DFS_MASK; in set_ak4396_params()
347 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { in set_ak4396_params()
348 for (i = 0; i < data->dacs; ++i) { in set_ak4396_params()
349 ak4396_write(chip, i, AK4396_CONTROL_1, in set_ak4396_params()
351 ak4396_write(chip, i, AK4396_CONTROL_2, value); in set_ak4396_params()
352 ak4396_write(chip, i, AK4396_CONTROL_1, in set_ak4396_params()
358 static void update_ak4396_volume(struct oxygen *chip) in update_ak4396_volume() argument
360 struct generic_data *data = chip->model_data; in update_ak4396_volume()
363 for (i = 0; i < data->dacs; ++i) { in update_ak4396_volume()
364 ak4396_write_cached(chip, i, AK4396_LCH_ATT, in update_ak4396_volume()
365 chip->dac_volume[i * 2]); in update_ak4396_volume()
366 ak4396_write_cached(chip, i, AK4396_RCH_ATT, in update_ak4396_volume()
367 chip->dac_volume[i * 2 + 1]); in update_ak4396_volume()
371 static void update_ak4396_mute(struct oxygen *chip) in update_ak4396_mute() argument
373 struct generic_data *data = chip->model_data; in update_ak4396_mute()
377 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; in update_ak4396_mute()
378 if (chip->dac_mute) in update_ak4396_mute()
380 for (i = 0; i < data->dacs; ++i) in update_ak4396_mute()
381 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); in update_ak4396_mute()
384 static void set_wm8785_params(struct oxygen *chip, in set_wm8785_params() argument
387 struct generic_data *data = chip->model_data; in set_wm8785_params()
397 if (value != data->wm8785_regs[0]) { in set_wm8785_params()
398 wm8785_write(chip, WM8785_R7, 0); in set_wm8785_params()
399 wm8785_write(chip, WM8785_R0, value); in set_wm8785_params()
400 wm8785_write(chip, WM8785_R2, data->wm8785_regs[2]); in set_wm8785_params()
404 static void set_ak5385_params(struct oxygen *chip, in set_ak5385_params() argument
415 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, in set_ak5385_params()
419 static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params) in set_no_params() argument
427 "Sharp Roll-off", "Slow Roll-off" in rolloff_info()
436 struct oxygen *chip = ctl->private_data; in rolloff_get() local
437 struct generic_data *data = chip->model_data; in rolloff_get()
439 value->value.enumerated.item[0] = in rolloff_get()
440 (data->ak4396_regs[0][AK4396_CONTROL_2] & AK4396_SLOW) != 0; in rolloff_get()
447 struct oxygen *chip = ctl->private_data; in rolloff_put() local
448 struct generic_data *data = chip->model_data; in rolloff_put()
453 mutex_lock(&chip->mutex); in rolloff_put()
454 reg = data->ak4396_regs[0][AK4396_CONTROL_2]; in rolloff_put()
455 if (value->value.enumerated.item[0]) in rolloff_put()
459 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2]; in rolloff_put()
461 for (i = 0; i < data->dacs; ++i) in rolloff_put()
462 ak4396_write(chip, i, AK4396_CONTROL_2, reg); in rolloff_put()
464 mutex_unlock(&chip->mutex); in rolloff_put()
479 "None", "High-pass Filter" in hpf_info()
487 struct oxygen *chip = ctl->private_data; in hpf_get() local
488 struct generic_data *data = chip->model_data; in hpf_get()
490 value->value.enumerated.item[0] = in hpf_get()
491 (data->wm8785_regs[WM8785_R2] & WM8785_HPFR) != 0; in hpf_get()
497 struct oxygen *chip = ctl->private_data; in hpf_put() local
498 struct generic_data *data = chip->model_data; in hpf_put()
502 mutex_lock(&chip->mutex); in hpf_put()
503 reg = data->wm8785_regs[WM8785_R2] & ~(WM8785_HPFR | WM8785_HPFL); in hpf_put()
504 if (value->value.enumerated.item[0]) in hpf_put()
506 changed = reg != data->wm8785_regs[WM8785_R2]; in hpf_put()
508 wm8785_write(chip, WM8785_R2, reg); in hpf_put()
509 mutex_unlock(&chip->mutex); in hpf_put()
524 static const char *const names[2] = { "On-board", "Extension" }; in meridian_dig_source_info()
540 struct oxygen *chip = ctl->private_data; in meridian_dig_source_get() local
542 value->value.enumerated.item[0] = in meridian_dig_source_get()
543 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & in meridian_dig_source_get()
551 struct oxygen *chip = ctl->private_data; in claro_dig_source_get() local
553 value->value.enumerated.item[0] = in claro_dig_source_get()
554 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & in claro_dig_source_get()
562 struct oxygen *chip = ctl->private_data; in meridian_dig_source_put() local
566 mutex_lock(&chip->mutex); in meridian_dig_source_put()
567 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA); in meridian_dig_source_put()
569 if (value->value.enumerated.item[0] == 0) in meridian_dig_source_put()
575 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg); in meridian_dig_source_put()
576 mutex_unlock(&chip->mutex); in meridian_dig_source_put()
583 struct oxygen *chip = ctl->private_data; in claro_dig_source_put() local
587 mutex_lock(&chip->mutex); in claro_dig_source_put()
588 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA); in claro_dig_source_put()
590 if (value->value.enumerated.item[0]) in claro_dig_source_put()
594 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg); in claro_dig_source_put()
595 mutex_unlock(&chip->mutex); in claro_dig_source_put()
615 static int generic_mixer_init(struct oxygen *chip) in generic_mixer_init() argument
617 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); in generic_mixer_init()
620 static int generic_wm8785_mixer_init(struct oxygen *chip) in generic_wm8785_mixer_init() argument
624 err = generic_mixer_init(chip); in generic_wm8785_mixer_init()
627 err = snd_ctl_add(chip->card, snd_ctl_new1(&hpf_control, chip)); in generic_wm8785_mixer_init()
633 static int meridian_mixer_init(struct oxygen *chip) in meridian_mixer_init() argument
637 err = generic_mixer_init(chip); in meridian_mixer_init()
640 err = snd_ctl_add(chip->card, in meridian_mixer_init()
641 snd_ctl_new1(&meridian_dig_source_control, chip)); in meridian_mixer_init()
647 static int claro_mixer_init(struct oxygen *chip) in claro_mixer_init() argument
651 err = generic_wm8785_mixer_init(chip); in claro_mixer_init()
654 err = snd_ctl_add(chip->card, in claro_mixer_init()
655 snd_ctl_new1(&claro_dig_source_control, chip)); in claro_mixer_init()
661 static int claro_halo_mixer_init(struct oxygen *chip) in claro_halo_mixer_init() argument
665 err = generic_mixer_init(chip); in claro_halo_mixer_init()
668 err = snd_ctl_add(chip->card, in claro_halo_mixer_init()
669 snd_ctl_new1(&claro_dig_source_control, chip)); in claro_halo_mixer_init()
675 static void dump_ak4396_registers(struct oxygen *chip, in dump_ak4396_registers() argument
678 struct generic_data *data = chip->model_data; in dump_ak4396_registers()
681 for (dac = 0; dac < data->dacs; ++dac) { in dump_ak4396_registers()
684 snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]); in dump_ak4396_registers()
689 static void dump_wm8785_registers(struct oxygen *chip, in dump_wm8785_registers() argument
692 struct generic_data *data = chip->model_data; in dump_wm8785_registers()
697 snd_iprintf(buffer, " %03x", data->wm8785_regs[i]); in dump_wm8785_registers()
701 static void dump_oxygen_registers(struct oxygen *chip, in dump_oxygen_registers() argument
704 dump_ak4396_registers(chip, buffer); in dump_oxygen_registers()
705 dump_wm8785_registers(chip, buffer); in dump_oxygen_registers()
711 .shortname = "C-Media CMI8788",
712 .longname = "C-Media Oxygen HD Audio",
713 .chip = "CMI8788",
744 static int get_oxygen_model(struct oxygen *chip, in get_oxygen_model() argument
745 const struct pci_device_id *id) in get_oxygen_model() argument
748 [MODEL_MERIDIAN] = "AuzenTech X-Meridian", in get_oxygen_model()
749 [MODEL_MERIDIAN_2G] = "AuzenTech X-Meridian 2G", in get_oxygen_model()
750 [MODEL_CLARO] = "HT-Omega Claro", in get_oxygen_model()
751 [MODEL_CLARO_HALO] = "HT-Omega Claro halo", in get_oxygen_model()
754 [MODEL_HG2PCI] = "CMI8787-HG2PCI", in get_oxygen_model()
759 chip->model = model_generic; in get_oxygen_model()
760 switch (id->driver_data) { in get_oxygen_model()
763 chip->model.init = meridian_init; in get_oxygen_model()
764 chip->model.mixer_init = meridian_mixer_init; in get_oxygen_model()
765 chip->model.resume = meridian_resume; in get_oxygen_model()
766 chip->model.set_adc_params = set_ak5385_params; in get_oxygen_model()
767 chip->model.dump_registers = dump_ak4396_registers; in get_oxygen_model()
768 chip->model.device_config = PLAYBACK_0_TO_I2S | in get_oxygen_model()
772 if (id->driver_data == MODEL_MERIDIAN) in get_oxygen_model()
773 chip->model.device_config |= AC97_CD_INPUT; in get_oxygen_model()
776 chip->model.init = claro_init; in get_oxygen_model()
777 chip->model.mixer_init = claro_mixer_init; in get_oxygen_model()
778 chip->model.cleanup = claro_cleanup; in get_oxygen_model()
779 chip->model.suspend = claro_suspend; in get_oxygen_model()
780 chip->model.resume = claro_resume; in get_oxygen_model()
783 chip->model.init = claro_halo_init; in get_oxygen_model()
784 chip->model.mixer_init = claro_halo_mixer_init; in get_oxygen_model()
785 chip->model.cleanup = claro_cleanup; in get_oxygen_model()
786 chip->model.suspend = claro_suspend; in get_oxygen_model()
787 chip->model.resume = claro_resume; in get_oxygen_model()
788 chip->model.set_adc_params = set_ak5385_params; in get_oxygen_model()
789 chip->model.dump_registers = dump_ak4396_registers; in get_oxygen_model()
790 chip->model.device_config = PLAYBACK_0_TO_I2S | in get_oxygen_model()
799 chip->model.shortname = "C-Media CMI8787"; in get_oxygen_model()
800 chip->model.chip = "CMI8787"; in get_oxygen_model()
801 if (id->driver_data == MODEL_FANTASIA) in get_oxygen_model()
802 chip->model.init = fantasia_init; in get_oxygen_model()
804 chip->model.init = stereo_output_init; in get_oxygen_model()
805 chip->model.resume = stereo_resume; in get_oxygen_model()
806 chip->model.mixer_init = generic_mixer_init; in get_oxygen_model()
807 chip->model.set_adc_params = set_no_params; in get_oxygen_model()
808 chip->model.dump_registers = dump_ak4396_registers; in get_oxygen_model()
809 chip->model.device_config = PLAYBACK_0_TO_I2S | in get_oxygen_model()
811 if (id->driver_data == MODEL_FANTASIA) { in get_oxygen_model()
812 chip->model.device_config |= CAPTURE_0_FROM_I2S_1; in get_oxygen_model()
813 chip->model.adc_mclks = OXYGEN_MCLKS(256, 128, 128); in get_oxygen_model()
815 chip->model.dac_channels_pcm = 2; in get_oxygen_model()
816 chip->model.dac_channels_mixer = 2; in get_oxygen_model()
820 chip->model = model_xonar_dg; in get_oxygen_model()
823 if (id->driver_data == MODEL_MERIDIAN || in get_oxygen_model()
824 id->driver_data == MODEL_MERIDIAN_2G || in get_oxygen_model()
825 id->driver_data == MODEL_CLARO_HALO) { in get_oxygen_model()
826 chip->model.misc_flags = OXYGEN_MISC_MIDI; in get_oxygen_model()
827 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; in get_oxygen_model()
829 if (id->driver_data < ARRAY_SIZE(names) && names[id->driver_data]) in get_oxygen_model()
830 chip->model.shortname = names[id->driver_data]; in get_oxygen_model()
841 return -ENODEV; in generic_oxygen_probe()
844 return -ENOENT; in generic_oxygen_probe()
846 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE, in generic_oxygen_probe()