linux/sound/pci/hda/patch_cmedia.c
<<
>>
Prefs
   1/*
   2 * Universal Interface for Intel High Definition Audio Codec
   3 *
   4 * HD audio interface patch for C-Media CMI9880
   5 *
   6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
   7 *
   8 *
   9 *  This driver is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License as published by
  11 *  the Free Software Foundation; either version 2 of the License, or
  12 *  (at your option) any later version.
  13 *
  14 *  This driver is distributed in the hope that it will be useful,
  15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *  GNU General Public License for more details.
  18 *
  19 *  You should have received a copy of the GNU General Public License
  20 *  along with this program; if not, write to the Free Software
  21 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  22 */
  23
  24#include <linux/init.h>
  25#include <linux/slab.h>
  26#include <linux/module.h>
  27#include <sound/core.h>
  28#include "hda_codec.h"
  29#include "hda_local.h"
  30#include "hda_auto_parser.h"
  31#include "hda_jack.h"
  32#include "hda_generic.h"
  33
  34struct cmi_spec {
  35        struct hda_gen_spec gen;
  36};
  37
  38/*
  39 * stuff for auto-parser
  40 */
  41static const struct hda_codec_ops cmi_auto_patch_ops = {
  42        .build_controls = snd_hda_gen_build_controls,
  43        .build_pcms = snd_hda_gen_build_pcms,
  44        .init = snd_hda_gen_init,
  45        .free = snd_hda_gen_free,
  46        .unsol_event = snd_hda_jack_unsol_event,
  47};
  48
  49static int patch_cmi9880(struct hda_codec *codec)
  50{
  51        struct cmi_spec *spec;
  52        struct auto_pin_cfg *cfg;
  53        int err;
  54
  55        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  56        if (spec == NULL)
  57                return -ENOMEM;
  58
  59        codec->spec = spec;
  60        codec->patch_ops = cmi_auto_patch_ops;
  61        cfg = &spec->gen.autocfg;
  62        snd_hda_gen_spec_init(&spec->gen);
  63
  64        err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
  65        if (err < 0)
  66                goto error;
  67        err = snd_hda_gen_parse_auto_config(codec, cfg);
  68        if (err < 0)
  69                goto error;
  70
  71        return 0;
  72
  73 error:
  74        snd_hda_gen_free(codec);
  75        return err;
  76}
  77
  78static int patch_cmi8888(struct hda_codec *codec)
  79{
  80        struct cmi_spec *spec;
  81        struct auto_pin_cfg *cfg;
  82        int err;
  83
  84        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  85        if (!spec)
  86                return -ENOMEM;
  87
  88        codec->spec = spec;
  89        codec->patch_ops = cmi_auto_patch_ops;
  90        cfg = &spec->gen.autocfg;
  91        snd_hda_gen_spec_init(&spec->gen);
  92
  93        /* mask NID 0x10 from the playback volume selection;
  94         * it's a headphone boost volume handled manually below
  95         */
  96        spec->gen.out_vol_mask = (1ULL << 0x10);
  97
  98        err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
  99        if (err < 0)
 100                goto error;
 101        err = snd_hda_gen_parse_auto_config(codec, cfg);
 102        if (err < 0)
 103                goto error;
 104
 105        if (get_defcfg_device(snd_hda_codec_get_pincfg(codec, 0x10)) ==
 106            AC_JACK_HP_OUT) {
 107                static const struct snd_kcontrol_new amp_kctl =
 108                        HDA_CODEC_VOLUME("Headphone Amp Playback Volume",
 109                                         0x10, 0, HDA_OUTPUT);
 110                if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &amp_kctl)) {
 111                        err = -ENOMEM;
 112                        goto error;
 113                }
 114        }
 115
 116        return 0;
 117
 118 error:
 119        snd_hda_gen_free(codec);
 120        return err;
 121}
 122
 123/*
 124 * patch entries
 125 */
 126static const struct hda_device_id snd_hda_id_cmedia[] = {
 127        HDA_CODEC_ENTRY(0x13f68888, "CMI8888", patch_cmi8888),
 128        HDA_CODEC_ENTRY(0x13f69880, "CMI9880", patch_cmi9880),
 129        HDA_CODEC_ENTRY(0x434d4980, "CMI9880", patch_cmi9880),
 130        {} /* terminator */
 131};
 132MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cmedia);
 133
 134MODULE_LICENSE("GPL");
 135MODULE_DESCRIPTION("C-Media HD-audio codec");
 136
 137static struct hda_codec_driver cmedia_driver = {
 138        .id = snd_hda_id_cmedia,
 139};
 140
 141module_hda_codec_driver(cmedia_driver);
 142