File Index
Files and directories
Sign in
FILE

cmedia.c

File preview with syntax highlighting.

linux-6.19.14/sound/hda/codecs/cmedia.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Universal codec driver for Intel High Definition Audio Codec
  4 *
  5 * HD audio codec driver for C-Media CMI9880
  6 *
  7 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
  8 */
  9
 10#include <linux/init.h>
 11#include <linux/slab.h>
 12#include <linux/module.h>
 13#include <sound/core.h>
 14#include <sound/hda_codec.h>
 15#include "hda_local.h"
 16#include "hda_auto_parser.h"
 17#include "hda_jack.h"
 18#include "generic.h"
 19
 20static int cmedia_probe(struct hda_codec *codec, const struct hda_device_id *id)
 21{
 22	struct hda_gen_spec *spec;
 23	struct auto_pin_cfg *cfg;
 24	bool is_cmi8888 = id->vendor_id == 0x13f68888;
 25	int err;
 26
 27	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 28	if (spec == NULL)
 29		return -ENOMEM;
 30
 31	codec->spec = spec;
 32	cfg = &spec->autocfg;
 33	snd_hda_gen_spec_init(spec);
 34
 35	if (is_cmi8888) {
 36		/* mask NID 0x10 from the playback volume selection;
 37		 * it's a headphone boost volume handled manually below
 38		 */
 39		spec->out_vol_mask = (1ULL << 0x10);
 40	}
 41
 42	err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
 43	if (err < 0)
 44		goto error;
 45	err = snd_hda_gen_parse_auto_config(codec, cfg);
 46	if (err < 0)
 47		goto error;
 48
 49	err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
 50	if (err < 0)
 51		goto error;
 52	err = snd_hda_gen_parse_auto_config(codec, cfg);
 53	if (err < 0)
 54		goto error;
 55
 56	if (is_cmi8888) {
 57		if (get_defcfg_device(snd_hda_codec_get_pincfg(codec, 0x10)) ==
 58		    AC_JACK_HP_OUT) {
 59			static const struct snd_kcontrol_new amp_kctl =
 60				HDA_CODEC_VOLUME("Headphone Amp Playback Volume",
 61						 0x10, 0, HDA_OUTPUT);
 62			if (!snd_hda_gen_add_kctl(spec, NULL, &amp_kctl)) {
 63				err = -ENOMEM;
 64				goto error;
 65			}
 66		}
 67	}
 68
 69	return 0;
 70
 71 error:
 72	snd_hda_gen_remove(codec);
 73	return err;
 74}
 75
 76static const struct hda_codec_ops cmedia_codec_ops = {
 77	.probe = cmedia_probe,
 78	.remove = snd_hda_gen_remove,
 79	.build_controls = snd_hda_gen_build_controls,
 80	.build_pcms = snd_hda_gen_build_pcms,
 81	.init = snd_hda_gen_init,
 82	.unsol_event = snd_hda_jack_unsol_event,
 83	.check_power_status = snd_hda_gen_check_power_status,
 84	.stream_pm = snd_hda_gen_stream_pm,
 85};
 86
 87/*
 88 * driver entries
 89 */
 90static const struct hda_device_id snd_hda_id_cmedia[] = {
 91	HDA_CODEC_ID(0x13f68888, "CMI8888"),
 92	HDA_CODEC_ID(0x13f69880, "CMI9880"),
 93	HDA_CODEC_ID(0x434d4980, "CMI9880"),
 94	{} /* terminator */
 95};
 96MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cmedia);
 97
 98MODULE_LICENSE("GPL");
 99MODULE_DESCRIPTION("C-Media HD-audio codec");
100
101static struct hda_codec_driver cmedia_driver = {
102	.id = snd_hda_id_cmedia,
103	.ops = &cmedia_codec_ops,
104};
105
106module_hda_codec_driver(cmedia_driver);
~/ Read-only file preview.