linux/sound/pci/hda/hda_local.h
<<
>>
Prefs
   1/*
   2 * Universal Interface for Intel High Definition Audio Codec
   3 *
   4 * Local helper functions
   5 *
   6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
   7 *
   8 *  This program is free software; you can redistribute it and/or modify it
   9 *  under the terms of the GNU General Public License as published by the Free
  10 *  Software Foundation; either version 2 of the License, or (at your option)
  11 *  any later version.
  12 *
  13 *  This program is distributed in the hope that it will be useful, but WITHOUT
  14 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  16 *  more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License along with
  19 *  this program; if not, write to the Free Software Foundation, Inc., 59
  20 *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21 */
  22
  23#ifndef __SOUND_HDA_LOCAL_H
  24#define __SOUND_HDA_LOCAL_H
  25
  26/*
  27 * for mixer controls
  28 */
  29#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
  30        ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
  31/* mono volume with index (index=0,1,...) (channel=1,2) */
  32#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
  33        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx,  \
  34          .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
  35                    SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
  36                    SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
  37          .info = snd_hda_mixer_amp_volume_info, \
  38          .get = snd_hda_mixer_amp_volume_get, \
  39          .put = snd_hda_mixer_amp_volume_put, \
  40          .tlv = { .c = snd_hda_mixer_amp_tlv },                \
  41          .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
  42/* stereo volume with index */
  43#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
  44        HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
  45/* mono volume */
  46#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
  47        HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction)
  48/* stereo volume */
  49#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
  50        HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
  51/* mono mute switch with index (index=0,1,...) (channel=1,2) */
  52#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
  53        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
  54          .info = snd_hda_mixer_amp_switch_info, \
  55          .get = snd_hda_mixer_amp_switch_get, \
  56          .put = snd_hda_mixer_amp_switch_put, \
  57          .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
  58/* stereo mute switch with index */
  59#define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
  60        HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
  61/* mono mute switch */
  62#define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
  63        HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
  64/* stereo mute switch */
  65#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
  66        HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
  67
  68int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
  69                                  struct snd_ctl_elem_info *uinfo);
  70int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
  71                                 struct snd_ctl_elem_value *ucontrol);
  72int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
  73                                 struct snd_ctl_elem_value *ucontrol);
  74int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
  75                          unsigned int size, unsigned int __user *tlv);
  76int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
  77                                  struct snd_ctl_elem_info *uinfo);
  78int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
  79                                 struct snd_ctl_elem_value *ucontrol);
  80int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
  81                                 struct snd_ctl_elem_value *ucontrol);
  82/* lowlevel accessor with caching; use carefully */
  83int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
  84                           int direction, int index);
  85int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
  86                             int direction, int idx, int mask, int val);
  87int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
  88                             int dir, int idx, int mask, int val);
  89#ifdef SND_HDA_NEEDS_RESUME
  90void snd_hda_codec_resume_amp(struct hda_codec *codec);
  91#endif
  92
  93void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
  94                             unsigned int *tlv);
  95struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
  96                                            const char *name);
  97int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
  98                        unsigned int *tlv, const char **slaves);
  99
 100/* amp value bits */
 101#define HDA_AMP_MUTE    0x80
 102#define HDA_AMP_UNMUTE  0x00
 103#define HDA_AMP_VOLMASK 0x7f
 104
 105/* mono switch binding multiple inputs */
 106#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
 107        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 108          .info = snd_hda_mixer_amp_switch_info, \
 109          .get = snd_hda_mixer_bind_switch_get, \
 110          .put = snd_hda_mixer_bind_switch_put, \
 111          .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
 112
 113/* stereo switch binding multiple inputs */
 114#define HDA_BIND_MUTE(xname,nid,indices,dir) \
 115        HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
 116
 117int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
 118                                  struct snd_ctl_elem_value *ucontrol);
 119int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
 120                                  struct snd_ctl_elem_value *ucontrol);
 121
 122/* more generic bound controls */
 123struct hda_ctl_ops {
 124        snd_kcontrol_info_t *info;
 125        snd_kcontrol_get_t *get;
 126        snd_kcontrol_put_t *put;
 127        snd_kcontrol_tlv_rw_t *tlv;
 128};
 129
 130extern struct hda_ctl_ops snd_hda_bind_vol;     /* for bind-volume with TLV */
 131extern struct hda_ctl_ops snd_hda_bind_sw;      /* for bind-switch */
 132
 133struct hda_bind_ctls {
 134        struct hda_ctl_ops *ops;
 135        long values[];
 136};
 137
 138int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
 139                                 struct snd_ctl_elem_info *uinfo);
 140int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
 141                                struct snd_ctl_elem_value *ucontrol);
 142int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
 143                                struct snd_ctl_elem_value *ucontrol);
 144int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
 145                           unsigned int size, unsigned int __user *tlv);
 146
 147#define HDA_BIND_VOL(xname, bindrec) \
 148        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
 149          .name = xname, \
 150          .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
 151                          SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
 152                          SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,\
 153          .info = snd_hda_mixer_bind_ctls_info,\
 154          .get =  snd_hda_mixer_bind_ctls_get,\
 155          .put = snd_hda_mixer_bind_ctls_put,\
 156          .tlv = { .c = snd_hda_mixer_bind_tlv },\
 157          .private_value = (long) (bindrec) }
 158#define HDA_BIND_SW(xname, bindrec) \
 159        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
 160          .name = xname, \
 161          .info = snd_hda_mixer_bind_ctls_info,\
 162          .get =  snd_hda_mixer_bind_ctls_get,\
 163          .put = snd_hda_mixer_bind_ctls_put,\
 164          .private_value = (long) (bindrec) }
 165
 166/*
 167 * SPDIF I/O
 168 */
 169int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
 170int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
 171
 172/*
 173 * input MUX helper
 174 */
 175#define HDA_MAX_NUM_INPUTS      16
 176struct hda_input_mux_item {
 177        const char *label;
 178        unsigned int index;
 179};
 180struct hda_input_mux {
 181        unsigned int num_items;
 182        struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
 183};
 184
 185int snd_hda_input_mux_info(const struct hda_input_mux *imux,
 186                           struct snd_ctl_elem_info *uinfo);
 187int snd_hda_input_mux_put(struct hda_codec *codec,
 188                          const struct hda_input_mux *imux,
 189                          struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
 190                          unsigned int *cur_val);
 191
 192/*
 193 * Channel mode helper
 194 */
 195struct hda_channel_mode {
 196        int channels;
 197        const struct hda_verb *sequence;
 198};
 199
 200int snd_hda_ch_mode_info(struct hda_codec *codec,
 201                         struct snd_ctl_elem_info *uinfo,
 202                         const struct hda_channel_mode *chmode,
 203                         int num_chmodes);
 204int snd_hda_ch_mode_get(struct hda_codec *codec,
 205                        struct snd_ctl_elem_value *ucontrol,
 206                        const struct hda_channel_mode *chmode,
 207                        int num_chmodes,
 208                        int max_channels);
 209int snd_hda_ch_mode_put(struct hda_codec *codec,
 210                        struct snd_ctl_elem_value *ucontrol,
 211                        const struct hda_channel_mode *chmode,
 212                        int num_chmodes,
 213                        int *max_channelsp);
 214
 215/*
 216 * Multi-channel / digital-out PCM helper
 217 */
 218
 219enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
 220enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
 221
 222struct hda_multi_out {
 223        int num_dacs;           /* # of DACs, must be more than 1 */
 224        hda_nid_t *dac_nids;    /* DAC list */
 225        hda_nid_t hp_nid;       /* optional DAC for HP, 0 when not exists */
 226        hda_nid_t extra_out_nid[3];     /* optional DACs, 0 when not exists */
 227        hda_nid_t dig_out_nid;  /* digital out audio widget */
 228        int max_channels;       /* currently supported analog channels */
 229        int dig_out_used;       /* current usage of digital out (HDA_DIG_XXX) */
 230        int no_share_stream;    /* don't share a stream with multiple pins */
 231        int share_spdif;        /* share SPDIF pin */
 232        /* PCM information for both analog and SPDIF DACs */
 233        unsigned int analog_rates;
 234        unsigned int analog_maxbps;
 235        u64 analog_formats;
 236        unsigned int spdif_rates;
 237        unsigned int spdif_maxbps;
 238        u64 spdif_formats;
 239};
 240
 241int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
 242                                  struct hda_multi_out *mout);
 243int snd_hda_multi_out_dig_open(struct hda_codec *codec,
 244                               struct hda_multi_out *mout);
 245int snd_hda_multi_out_dig_close(struct hda_codec *codec,
 246                                struct hda_multi_out *mout);
 247int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
 248                                  struct hda_multi_out *mout,
 249                                  unsigned int stream_tag,
 250                                  unsigned int format,
 251                                  struct snd_pcm_substream *substream);
 252int snd_hda_multi_out_analog_open(struct hda_codec *codec,
 253                                  struct hda_multi_out *mout,
 254                                  struct snd_pcm_substream *substream,
 255                                  struct hda_pcm_stream *hinfo);
 256int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
 257                                     struct hda_multi_out *mout,
 258                                     unsigned int stream_tag,
 259                                     unsigned int format,
 260                                     struct snd_pcm_substream *substream);
 261int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
 262                                     struct hda_multi_out *mout);
 263
 264/*
 265 * generic codec parser
 266 */
 267#ifdef CONFIG_SND_HDA_GENERIC
 268int snd_hda_parse_generic_codec(struct hda_codec *codec);
 269#else
 270static inline int snd_hda_parse_generic_codec(struct hda_codec *codec)
 271{
 272        return -ENODEV;
 273}
 274#endif
 275
 276/*
 277 * generic proc interface
 278 */
 279#ifdef CONFIG_PROC_FS
 280int snd_hda_codec_proc_new(struct hda_codec *codec);
 281#else
 282static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
 283#endif
 284
 285/*
 286 * Misc
 287 */
 288int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
 289                               const char **modelnames,
 290                               const struct snd_pci_quirk *pci_list);
 291int snd_hda_add_new_ctls(struct hda_codec *codec,
 292                         struct snd_kcontrol_new *knew);
 293
 294/*
 295 * unsolicited event handler
 296 */
 297
 298#define HDA_UNSOL_QUEUE_SIZE    64
 299
 300struct hda_bus_unsolicited {
 301        /* ring buffer */
 302        u32 queue[HDA_UNSOL_QUEUE_SIZE * 2];
 303        unsigned int rp, wp;
 304
 305        /* workqueue */
 306        struct work_struct work;
 307        struct hda_bus *bus;
 308};
 309
 310/*
 311 * Helper for automatic ping configuration
 312 */
 313
 314enum {
 315        AUTO_PIN_MIC,
 316        AUTO_PIN_FRONT_MIC,
 317        AUTO_PIN_LINE,
 318        AUTO_PIN_FRONT_LINE,
 319        AUTO_PIN_CD,
 320        AUTO_PIN_AUX,
 321        AUTO_PIN_LAST
 322};
 323
 324enum {
 325        AUTO_PIN_LINE_OUT,
 326        AUTO_PIN_SPEAKER_OUT,
 327        AUTO_PIN_HP_OUT
 328};
 329
 330extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
 331
 332#define AUTO_CFG_MAX_OUTS       5
 333
 334struct auto_pin_cfg {
 335        int line_outs;
 336        /* sorted in the order of Front/Surr/CLFE/Side */
 337        hda_nid_t line_out_pins[AUTO_CFG_MAX_OUTS];
 338        int speaker_outs;
 339        hda_nid_t speaker_pins[AUTO_CFG_MAX_OUTS];
 340        int hp_outs;
 341        int line_out_type;      /* AUTO_PIN_XXX_OUT */
 342        hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS];
 343        hda_nid_t input_pins[AUTO_PIN_LAST];
 344        hda_nid_t dig_out_pin;
 345        hda_nid_t dig_in_pin;
 346        hda_nid_t mono_out_pin;
 347};
 348
 349#define get_defcfg_connect(cfg) \
 350        ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
 351#define get_defcfg_association(cfg) \
 352        ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
 353#define get_defcfg_location(cfg) \
 354        ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
 355#define get_defcfg_sequence(cfg) \
 356        (cfg & AC_DEFCFG_SEQUENCE)
 357#define get_defcfg_device(cfg) \
 358        ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
 359
 360int snd_hda_parse_pin_def_config(struct hda_codec *codec,
 361                                 struct auto_pin_cfg *cfg,
 362                                 hda_nid_t *ignore_nids);
 363
 364/* amp values */
 365#define AMP_IN_MUTE(idx)        (0x7080 | ((idx)<<8))
 366#define AMP_IN_UNMUTE(idx)      (0x7000 | ((idx)<<8))
 367#define AMP_OUT_MUTE    0xb080
 368#define AMP_OUT_UNMUTE  0xb000
 369#define AMP_OUT_ZERO    0xb000
 370/* pinctl values */
 371#define PIN_IN          0x20
 372#define PIN_VREF80      0x24
 373#define PIN_VREF50      0x21
 374#define PIN_OUT         0x40
 375#define PIN_HP          0xc0
 376#define PIN_HP_AMP      0x80
 377
 378/*
 379 * get widget capabilities
 380 */
 381static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
 382{
 383        if (nid < codec->start_nid ||
 384            nid >= codec->start_nid + codec->num_nodes)
 385                return 0;
 386        return codec->wcaps[nid - codec->start_nid];
 387}
 388
 389u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
 390int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
 391                              unsigned int caps);
 392
 393/*
 394 * hwdep interface
 395 */
 396int snd_hda_create_hwdep(struct hda_codec *codec);
 397
 398/*
 399 * power-management
 400 */
 401
 402#ifdef CONFIG_SND_HDA_POWER_SAVE
 403void snd_hda_schedule_power_save(struct hda_codec *codec);
 404
 405struct hda_amp_list {
 406        hda_nid_t nid;
 407        unsigned char dir;
 408        unsigned char idx;
 409};
 410
 411struct hda_loopback_check {
 412        struct hda_amp_list *amplist;
 413        int power_on;
 414};
 415
 416int snd_hda_check_amp_list_power(struct hda_codec *codec,
 417                                 struct hda_loopback_check *check,
 418                                 hda_nid_t nid);
 419#endif /* CONFIG_SND_HDA_POWER_SAVE */
 420
 421#endif /* __SOUND_HDA_LOCAL_H */
 422
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.