11835a0f9STakashi Iwai /* 21835a0f9STakashi Iwai * Jack-detection handling for HD-audio 31835a0f9STakashi Iwai * 41835a0f9STakashi Iwai * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> 51835a0f9STakashi Iwai * 61835a0f9STakashi Iwai * This driver is free software; you can redistribute it and/or modify 71835a0f9STakashi Iwai * it under the terms of the GNU General Public License as published by 81835a0f9STakashi Iwai * the Free Software Foundation; either version 2 of the License, or 91835a0f9STakashi Iwai * (at your option) any later version. 101835a0f9STakashi Iwai */ 111835a0f9STakashi Iwai 121835a0f9STakashi Iwai #include <linux/init.h> 131835a0f9STakashi Iwai #include <linux/slab.h> 141835a0f9STakashi Iwai #include <sound/core.h> 15*01a61e12STakashi Iwai #include <sound/control.h> 161835a0f9STakashi Iwai #include "hda_codec.h" 171835a0f9STakashi Iwai #include "hda_local.h" 181835a0f9STakashi Iwai #include "hda_jack.h" 191835a0f9STakashi Iwai 201835a0f9STakashi Iwai /* execute pin sense measurement */ 211835a0f9STakashi Iwai static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) 221835a0f9STakashi Iwai { 231835a0f9STakashi Iwai u32 pincap; 241835a0f9STakashi Iwai 251835a0f9STakashi Iwai if (!codec->no_trigger_sense) { 261835a0f9STakashi Iwai pincap = snd_hda_query_pin_caps(codec, nid); 271835a0f9STakashi Iwai if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ 281835a0f9STakashi Iwai snd_hda_codec_read(codec, nid, 0, 291835a0f9STakashi Iwai AC_VERB_SET_PIN_SENSE, 0); 301835a0f9STakashi Iwai } 311835a0f9STakashi Iwai return snd_hda_codec_read(codec, nid, 0, 321835a0f9STakashi Iwai AC_VERB_GET_PIN_SENSE, 0); 331835a0f9STakashi Iwai } 341835a0f9STakashi Iwai 351835a0f9STakashi Iwai /** 361835a0f9STakashi Iwai * snd_hda_jack_tbl_get - query the jack-table entry for the given NID 371835a0f9STakashi Iwai */ 381835a0f9STakashi Iwai struct hda_jack_tbl * 391835a0f9STakashi Iwai snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) 401835a0f9STakashi Iwai { 411835a0f9STakashi Iwai struct hda_jack_tbl *jack = codec->jacktbl.list; 421835a0f9STakashi Iwai int i; 431835a0f9STakashi Iwai 441835a0f9STakashi Iwai if (!nid || !jack) 451835a0f9STakashi Iwai return NULL; 461835a0f9STakashi Iwai for (i = 0; i < codec->jacktbl.used; i++, jack++) 471835a0f9STakashi Iwai if (jack->nid == nid) 481835a0f9STakashi Iwai return jack; 491835a0f9STakashi Iwai return NULL; 501835a0f9STakashi Iwai } 511835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get); 521835a0f9STakashi Iwai 531835a0f9STakashi Iwai /** 541835a0f9STakashi Iwai * snd_hda_jack_tbl_new - create a jack-table entry for the given NID 551835a0f9STakashi Iwai */ 561835a0f9STakashi Iwai struct hda_jack_tbl * 571835a0f9STakashi Iwai snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) 581835a0f9STakashi Iwai { 591835a0f9STakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 601835a0f9STakashi Iwai if (jack) 611835a0f9STakashi Iwai return jack; 621835a0f9STakashi Iwai snd_array_init(&codec->jacktbl, sizeof(*jack), 16); 631835a0f9STakashi Iwai jack = snd_array_new(&codec->jacktbl); 641835a0f9STakashi Iwai if (!jack) 651835a0f9STakashi Iwai return NULL; 661835a0f9STakashi Iwai jack->nid = nid; 671835a0f9STakashi Iwai jack->jack_dirty = 1; 681835a0f9STakashi Iwai return jack; 691835a0f9STakashi Iwai } 701835a0f9STakashi Iwai 711835a0f9STakashi Iwai void snd_hda_jack_tbl_clear(struct hda_codec *codec) 721835a0f9STakashi Iwai { 731835a0f9STakashi Iwai snd_array_free(&codec->jacktbl); 741835a0f9STakashi Iwai } 751835a0f9STakashi Iwai 761835a0f9STakashi Iwai /* update the cached value and notification flag if needed */ 771835a0f9STakashi Iwai static void jack_detect_update(struct hda_codec *codec, 781835a0f9STakashi Iwai struct hda_jack_tbl *jack) 791835a0f9STakashi Iwai { 80*01a61e12STakashi Iwai if (jack->jack_dirty || !jack->jack_cachable) { 81*01a61e12STakashi Iwai unsigned int val = read_pin_sense(codec, jack->nid); 821835a0f9STakashi Iwai jack->jack_dirty = 0; 83*01a61e12STakashi Iwai if (val != jack->pin_sense) { 84*01a61e12STakashi Iwai jack->need_notify = 1; 85*01a61e12STakashi Iwai jack->pin_sense = val; 86*01a61e12STakashi Iwai } 871835a0f9STakashi Iwai } 881835a0f9STakashi Iwai } 891835a0f9STakashi Iwai 901835a0f9STakashi Iwai /** 911835a0f9STakashi Iwai * snd_hda_set_dirty_all - Mark all the cached as dirty 921835a0f9STakashi Iwai * 931835a0f9STakashi Iwai * This function sets the dirty flag to all entries of jack table. 941835a0f9STakashi Iwai * It's called from the resume path in hda_codec.c. 951835a0f9STakashi Iwai */ 961835a0f9STakashi Iwai void snd_hda_jack_set_dirty_all(struct hda_codec *codec) 971835a0f9STakashi Iwai { 981835a0f9STakashi Iwai struct hda_jack_tbl *jack = codec->jacktbl.list; 991835a0f9STakashi Iwai int i; 1001835a0f9STakashi Iwai 1011835a0f9STakashi Iwai for (i = 0; i < codec->jacktbl.used; i++, jack++) 1021835a0f9STakashi Iwai if (jack->nid) 1031835a0f9STakashi Iwai jack->jack_dirty = 1; 1041835a0f9STakashi Iwai } 1051835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all); 1061835a0f9STakashi Iwai 1071835a0f9STakashi Iwai /** 1081835a0f9STakashi Iwai * snd_hda_pin_sense - execute pin sense measurement 1091835a0f9STakashi Iwai * @codec: the CODEC to sense 1101835a0f9STakashi Iwai * @nid: the pin NID to sense 1111835a0f9STakashi Iwai * 1121835a0f9STakashi Iwai * Execute necessary pin sense measurement and return its Presence Detect, 1131835a0f9STakashi Iwai * Impedance, ELD Valid etc. status bits. 1141835a0f9STakashi Iwai */ 1151835a0f9STakashi Iwai u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) 1161835a0f9STakashi Iwai { 1171835a0f9STakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 1181835a0f9STakashi Iwai if (jack) { 1191835a0f9STakashi Iwai jack_detect_update(codec, jack); 1201835a0f9STakashi Iwai return jack->pin_sense; 1211835a0f9STakashi Iwai } 1221835a0f9STakashi Iwai return read_pin_sense(codec, nid); 1231835a0f9STakashi Iwai } 1241835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_pin_sense); 1251835a0f9STakashi Iwai 1261835a0f9STakashi Iwai /** 1271835a0f9STakashi Iwai * snd_hda_jack_detect - query pin Presence Detect status 1281835a0f9STakashi Iwai * @codec: the CODEC to sense 1291835a0f9STakashi Iwai * @nid: the pin NID to sense 1301835a0f9STakashi Iwai * 1311835a0f9STakashi Iwai * Query and return the pin's Presence Detect status. 1321835a0f9STakashi Iwai */ 1331835a0f9STakashi Iwai int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 1341835a0f9STakashi Iwai { 1351835a0f9STakashi Iwai u32 sense = snd_hda_pin_sense(codec, nid); 1361835a0f9STakashi Iwai return !!(sense & AC_PINSENSE_PRESENCE); 1371835a0f9STakashi Iwai } 1381835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 1391835a0f9STakashi Iwai 1401835a0f9STakashi Iwai /** 1411835a0f9STakashi Iwai * snd_hda_jack_detect_enable - enable the jack-detection 1421835a0f9STakashi Iwai */ 1431835a0f9STakashi Iwai int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, 1441835a0f9STakashi Iwai unsigned int tag) 1451835a0f9STakashi Iwai { 1461835a0f9STakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid); 1471835a0f9STakashi Iwai if (!jack) 1481835a0f9STakashi Iwai return -ENOMEM; 149*01a61e12STakashi Iwai if (jack->jack_cachable) 150*01a61e12STakashi Iwai return 0; /* already registered */ 151*01a61e12STakashi Iwai jack->jack_cachable = 1; 1521835a0f9STakashi Iwai return snd_hda_codec_write_cache(codec, nid, 0, 1531835a0f9STakashi Iwai AC_VERB_SET_UNSOLICITED_ENABLE, 1541835a0f9STakashi Iwai AC_USRSP_EN | tag); 1551835a0f9STakashi Iwai } 1561835a0f9STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable); 157*01a61e12STakashi Iwai 158*01a61e12STakashi Iwai /* queue the notification when needed */ 159*01a61e12STakashi Iwai static void jack_detect_report(struct hda_codec *codec, 160*01a61e12STakashi Iwai struct hda_jack_tbl *jack) 161*01a61e12STakashi Iwai { 162*01a61e12STakashi Iwai jack_detect_update(codec, jack); 163*01a61e12STakashi Iwai if (jack->need_notify) { 164*01a61e12STakashi Iwai snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, 165*01a61e12STakashi Iwai &jack->kctl->id); 166*01a61e12STakashi Iwai jack->need_notify = 0; 167*01a61e12STakashi Iwai } 168*01a61e12STakashi Iwai } 169*01a61e12STakashi Iwai 170*01a61e12STakashi Iwai /** 171*01a61e12STakashi Iwai * snd_hda_jack_report - notify kctl when the jack state was changed 172*01a61e12STakashi Iwai */ 173*01a61e12STakashi Iwai void snd_hda_jack_report(struct hda_codec *codec, hda_nid_t nid) 174*01a61e12STakashi Iwai { 175*01a61e12STakashi Iwai struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 176*01a61e12STakashi Iwai 177*01a61e12STakashi Iwai if (jack) 178*01a61e12STakashi Iwai jack_detect_report(codec, jack); 179*01a61e12STakashi Iwai } 180*01a61e12STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_report); 181*01a61e12STakashi Iwai 182*01a61e12STakashi Iwai /** 183*01a61e12STakashi Iwai * snd_hda_jack_report_sync - sync the states of all jacks and report if changed 184*01a61e12STakashi Iwai */ 185*01a61e12STakashi Iwai void snd_hda_jack_report_sync(struct hda_codec *codec) 186*01a61e12STakashi Iwai { 187*01a61e12STakashi Iwai struct hda_jack_tbl *jack = codec->jacktbl.list; 188*01a61e12STakashi Iwai int i; 189*01a61e12STakashi Iwai 190*01a61e12STakashi Iwai for (i = 0; i < codec->jacktbl.used; i++, jack++) 191*01a61e12STakashi Iwai if (jack->nid) { 192*01a61e12STakashi Iwai jack_detect_update(codec, jack); 193*01a61e12STakashi Iwai jack_detect_report(codec, jack); 194*01a61e12STakashi Iwai } 195*01a61e12STakashi Iwai } 196*01a61e12STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync); 197*01a61e12STakashi Iwai 198*01a61e12STakashi Iwai /* 199*01a61e12STakashi Iwai * jack-detection kcontrols 200*01a61e12STakashi Iwai */ 201*01a61e12STakashi Iwai 202*01a61e12STakashi Iwai #define jack_detect_kctl_info snd_ctl_boolean_mono_info 203*01a61e12STakashi Iwai 204*01a61e12STakashi Iwai static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol, 205*01a61e12STakashi Iwai struct snd_ctl_elem_value *ucontrol) 206*01a61e12STakashi Iwai { 207*01a61e12STakashi Iwai struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 208*01a61e12STakashi Iwai hda_nid_t nid = kcontrol->private_value; 209*01a61e12STakashi Iwai 210*01a61e12STakashi Iwai ucontrol->value.integer.value[0] = snd_hda_jack_detect(codec, nid); 211*01a61e12STakashi Iwai return 0; 212*01a61e12STakashi Iwai } 213*01a61e12STakashi Iwai 214*01a61e12STakashi Iwai static struct snd_kcontrol_new jack_detect_kctl = { 215*01a61e12STakashi Iwai /* name is filled later */ 216*01a61e12STakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_CARD, 217*01a61e12STakashi Iwai .access = SNDRV_CTL_ELEM_ACCESS_READ, 218*01a61e12STakashi Iwai .info = jack_detect_kctl_info, 219*01a61e12STakashi Iwai .get = jack_detect_kctl_get, 220*01a61e12STakashi Iwai }; 221*01a61e12STakashi Iwai 222*01a61e12STakashi Iwai /** 223*01a61e12STakashi Iwai * snd_hda_jack_add_kctl - Add a kctl for the given pin 224*01a61e12STakashi Iwai * 225*01a61e12STakashi Iwai * This assigns a jack-detection kctl to the given pin. The kcontrol 226*01a61e12STakashi Iwai * will have the given name and index. 227*01a61e12STakashi Iwai */ 228*01a61e12STakashi Iwai int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 229*01a61e12STakashi Iwai const char *name, int idx) 230*01a61e12STakashi Iwai { 231*01a61e12STakashi Iwai struct hda_jack_tbl *jack; 232*01a61e12STakashi Iwai struct snd_kcontrol *kctl; 233*01a61e12STakashi Iwai 234*01a61e12STakashi Iwai jack = snd_hda_jack_tbl_get(codec, nid); 235*01a61e12STakashi Iwai if (!jack) 236*01a61e12STakashi Iwai return 0; 237*01a61e12STakashi Iwai if (jack->kctl) 238*01a61e12STakashi Iwai return 0; /* already created */ 239*01a61e12STakashi Iwai kctl = snd_ctl_new1(&jack_detect_kctl, codec); 240*01a61e12STakashi Iwai if (!kctl) 241*01a61e12STakashi Iwai return -ENOMEM; 242*01a61e12STakashi Iwai snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name); 243*01a61e12STakashi Iwai kctl->id.index = idx; 244*01a61e12STakashi Iwai kctl->private_value = nid; 245*01a61e12STakashi Iwai if (snd_hda_ctl_add(codec, nid, kctl) < 0) 246*01a61e12STakashi Iwai return -ENOMEM; 247*01a61e12STakashi Iwai jack->kctl = kctl; 248*01a61e12STakashi Iwai return 0; 249*01a61e12STakashi Iwai } 250*01a61e12STakashi Iwai 251*01a61e12STakashi Iwai static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx, 252*01a61e12STakashi Iwai const struct auto_pin_cfg *cfg) 253*01a61e12STakashi Iwai { 254*01a61e12STakashi Iwai if (!nid) 255*01a61e12STakashi Iwai return 0; 256*01a61e12STakashi Iwai if (!is_jack_detectable(codec, nid)) 257*01a61e12STakashi Iwai return 0; 258*01a61e12STakashi Iwai return snd_hda_jack_add_kctl(codec, nid, 259*01a61e12STakashi Iwai snd_hda_get_pin_label(codec, nid, cfg), 260*01a61e12STakashi Iwai idx); 261*01a61e12STakashi Iwai } 262*01a61e12STakashi Iwai 263*01a61e12STakashi Iwai /** 264*01a61e12STakashi Iwai * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg 265*01a61e12STakashi Iwai * 266*01a61e12STakashi Iwai * As of now, it assigns only to the pins that enabled the detection. 267*01a61e12STakashi Iwai * Usually this is called at the end of build_controls callback. 268*01a61e12STakashi Iwai */ 269*01a61e12STakashi Iwai int snd_hda_jack_add_kctls(struct hda_codec *codec, 270*01a61e12STakashi Iwai const struct auto_pin_cfg *cfg) 271*01a61e12STakashi Iwai { 272*01a61e12STakashi Iwai const hda_nid_t *p; 273*01a61e12STakashi Iwai int i, err; 274*01a61e12STakashi Iwai 275*01a61e12STakashi Iwai for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { 276*01a61e12STakashi Iwai err = add_jack_kctl(codec, *p, i, cfg); 277*01a61e12STakashi Iwai if (err < 0) 278*01a61e12STakashi Iwai return err; 279*01a61e12STakashi Iwai } 280*01a61e12STakashi Iwai for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { 281*01a61e12STakashi Iwai if (*p == *cfg->line_out_pins) /* might be duplicated */ 282*01a61e12STakashi Iwai break; 283*01a61e12STakashi Iwai err = add_jack_kctl(codec, *p, i, cfg); 284*01a61e12STakashi Iwai if (err < 0) 285*01a61e12STakashi Iwai return err; 286*01a61e12STakashi Iwai } 287*01a61e12STakashi Iwai for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { 288*01a61e12STakashi Iwai if (*p == *cfg->line_out_pins) /* might be duplicated */ 289*01a61e12STakashi Iwai break; 290*01a61e12STakashi Iwai err = add_jack_kctl(codec, *p, i, cfg); 291*01a61e12STakashi Iwai if (err < 0) 292*01a61e12STakashi Iwai return err; 293*01a61e12STakashi Iwai } 294*01a61e12STakashi Iwai for (i = 0; i < cfg->num_inputs; i++) { 295*01a61e12STakashi Iwai err = add_jack_kctl(codec, cfg->inputs[i].pin, 0, cfg); 296*01a61e12STakashi Iwai if (err < 0) 297*01a61e12STakashi Iwai return err; 298*01a61e12STakashi Iwai } 299*01a61e12STakashi Iwai for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { 300*01a61e12STakashi Iwai err = add_jack_kctl(codec, *p, i, cfg); 301*01a61e12STakashi Iwai if (err < 0) 302*01a61e12STakashi Iwai return err; 303*01a61e12STakashi Iwai } 304*01a61e12STakashi Iwai err = add_jack_kctl(codec, cfg->dig_in_pin, 0, cfg); 305*01a61e12STakashi Iwai if (err < 0) 306*01a61e12STakashi Iwai return err; 307*01a61e12STakashi Iwai err = add_jack_kctl(codec, cfg->mono_out_pin, 0, cfg); 308*01a61e12STakashi Iwai if (err < 0) 309*01a61e12STakashi Iwai return err; 310*01a61e12STakashi Iwai return 0; 311*01a61e12STakashi Iwai } 312*01a61e12STakashi Iwai EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls); 313