1 /* 2 * Jack-detection handling for HD-audio 3 * 4 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> 5 * 6 * This driver is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12 #include <linux/init.h> 13 #include <linux/slab.h> 14 #include <linux/export.h> 15 #include <sound/core.h> 16 #include <sound/control.h> 17 #include <sound/jack.h> 18 #include "hda_codec.h" 19 #include "hda_local.h" 20 #include "hda_jack.h" 21 22 bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) 23 { 24 if (codec->no_jack_detect) 25 return false; 26 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) 27 return false; 28 if (!codec->ignore_misc_bit && 29 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & 30 AC_DEFCFG_MISC_NO_PRESENCE)) 31 return false; 32 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) 33 return false; 34 return true; 35 } 36 EXPORT_SYMBOL_HDA(is_jack_detectable); 37 38 /* execute pin sense measurement */ 39 static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) 40 { 41 u32 pincap; 42 43 if (!codec->no_trigger_sense) { 44 pincap = snd_hda_query_pin_caps(codec, nid); 45 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ 46 snd_hda_codec_read(codec, nid, 0, 47 AC_VERB_SET_PIN_SENSE, 0); 48 } 49 return snd_hda_codec_read(codec, nid, 0, 50 AC_VERB_GET_PIN_SENSE, 0); 51 } 52 53 /** 54 * snd_hda_jack_tbl_get - query the jack-table entry for the given NID 55 */ 56 struct hda_jack_tbl * 57 snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) 58 { 59 struct hda_jack_tbl *jack = codec->jacktbl.list; 60 int i; 61 62 if (!nid || !jack) 63 return NULL; 64 for (i = 0; i < codec->jacktbl.used; i++, jack++) 65 if (jack->nid == nid) 66 return jack; 67 return NULL; 68 } 69 EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get); 70 71 /** 72 * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag 73 */ 74 struct hda_jack_tbl * 75 snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) 76 { 77 struct hda_jack_tbl *jack = codec->jacktbl.list; 78 int i; 79 80 if (!tag || !jack) 81 return NULL; 82 for (i = 0; i < codec->jacktbl.used; i++, jack++) 83 if (jack->tag == tag) 84 return jack; 85 return NULL; 86 } 87 EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag); 88 89 /** 90 * snd_hda_jack_tbl_new - create a jack-table entry for the given NID 91 */ 92 struct hda_jack_tbl * 93 snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) 94 { 95 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 96 if (jack) 97 return jack; 98 snd_array_init(&codec->jacktbl, sizeof(*jack), 16); 99 jack = snd_array_new(&codec->jacktbl); 100 if (!jack) 101 return NULL; 102 jack->nid = nid; 103 jack->jack_dirty = 1; 104 jack->tag = codec->jacktbl.used; 105 return jack; 106 } 107 EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_new); 108 109 void snd_hda_jack_tbl_clear(struct hda_codec *codec) 110 { 111 #ifdef CONFIG_SND_HDA_INPUT_JACK 112 /* free jack instances manually when clearing/reconfiguring */ 113 if (!codec->bus->shutdown && codec->jacktbl.list) { 114 struct hda_jack_tbl *jack = codec->jacktbl.list; 115 int i; 116 for (i = 0; i < codec->jacktbl.used; i++, jack++) { 117 if (jack->jack) 118 snd_device_free(codec->bus->card, jack->jack); 119 } 120 } 121 #endif 122 snd_array_free(&codec->jacktbl); 123 } 124 125 /* update the cached value and notification flag if needed */ 126 static void jack_detect_update(struct hda_codec *codec, 127 struct hda_jack_tbl *jack) 128 { 129 if (jack->jack_dirty || !jack->jack_detect) { 130 jack->pin_sense = read_pin_sense(codec, jack->nid); 131 jack->jack_dirty = 0; 132 } 133 } 134 135 /** 136 * snd_hda_set_dirty_all - Mark all the cached as dirty 137 * 138 * This function sets the dirty flag to all entries of jack table. 139 * It's called from the resume path in hda_codec.c. 140 */ 141 void snd_hda_jack_set_dirty_all(struct hda_codec *codec) 142 { 143 struct hda_jack_tbl *jack = codec->jacktbl.list; 144 int i; 145 146 for (i = 0; i < codec->jacktbl.used; i++, jack++) 147 if (jack->nid) 148 jack->jack_dirty = 1; 149 } 150 EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all); 151 152 /** 153 * snd_hda_pin_sense - execute pin sense measurement 154 * @codec: the CODEC to sense 155 * @nid: the pin NID to sense 156 * 157 * Execute necessary pin sense measurement and return its Presence Detect, 158 * Impedance, ELD Valid etc. status bits. 159 */ 160 u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) 161 { 162 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 163 if (jack) { 164 jack_detect_update(codec, jack); 165 return jack->pin_sense; 166 } 167 return read_pin_sense(codec, nid); 168 } 169 EXPORT_SYMBOL_HDA(snd_hda_pin_sense); 170 171 #define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE) 172 173 /** 174 * snd_hda_jack_detect - query pin Presence Detect status 175 * @codec: the CODEC to sense 176 * @nid: the pin NID to sense 177 * 178 * Query and return the pin's Presence Detect status. 179 */ 180 int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 181 { 182 u32 sense = snd_hda_pin_sense(codec, nid); 183 return get_jack_plug_state(sense); 184 } 185 EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 186 187 /** 188 * snd_hda_jack_detect_enable - enable the jack-detection 189 */ 190 int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, 191 unsigned char action) 192 { 193 struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid); 194 if (!jack) 195 return -ENOMEM; 196 if (jack->jack_detect) 197 return 0; /* already registered */ 198 jack->jack_detect = 1; 199 if (action) 200 jack->action = action; 201 return snd_hda_codec_write_cache(codec, nid, 0, 202 AC_VERB_SET_UNSOLICITED_ENABLE, 203 AC_USRSP_EN | jack->tag); 204 } 205 EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable); 206 207 /** 208 * snd_hda_jack_report_sync - sync the states of all jacks and report if changed 209 */ 210 void snd_hda_jack_report_sync(struct hda_codec *codec) 211 { 212 struct hda_jack_tbl *jack = codec->jacktbl.list; 213 int i, state; 214 215 for (i = 0; i < codec->jacktbl.used; i++, jack++) 216 if (jack->nid) { 217 jack_detect_update(codec, jack); 218 if (!jack->kctl) 219 continue; 220 state = get_jack_plug_state(jack->pin_sense); 221 snd_kctl_jack_report(codec->bus->card, jack->kctl, state); 222 #ifdef CONFIG_SND_HDA_INPUT_JACK 223 if (jack->jack) 224 snd_jack_report(jack->jack, 225 state ? jack->type : 0); 226 #endif 227 } 228 } 229 EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync); 230 231 #ifdef CONFIG_SND_HDA_INPUT_JACK 232 /* guess the jack type from the pin-config */ 233 static int get_input_jack_type(struct hda_codec *codec, hda_nid_t nid) 234 { 235 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); 236 switch (get_defcfg_device(def_conf)) { 237 case AC_JACK_LINE_OUT: 238 case AC_JACK_SPEAKER: 239 return SND_JACK_LINEOUT; 240 case AC_JACK_HP_OUT: 241 return SND_JACK_HEADPHONE; 242 case AC_JACK_SPDIF_OUT: 243 case AC_JACK_DIG_OTHER_OUT: 244 return SND_JACK_AVOUT; 245 case AC_JACK_MIC_IN: 246 return SND_JACK_MICROPHONE; 247 default: 248 return SND_JACK_LINEIN; 249 } 250 } 251 252 static void hda_free_jack_priv(struct snd_jack *jack) 253 { 254 struct hda_jack_tbl *jacks = jack->private_data; 255 jacks->nid = 0; 256 jacks->jack = NULL; 257 } 258 #endif 259 260 /** 261 * snd_hda_jack_add_kctl - Add a kctl for the given pin 262 * 263 * This assigns a jack-detection kctl to the given pin. The kcontrol 264 * will have the given name and index. 265 */ 266 int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 267 const char *name, int idx) 268 { 269 struct hda_jack_tbl *jack; 270 struct snd_kcontrol *kctl; 271 int err, state; 272 273 jack = snd_hda_jack_tbl_new(codec, nid); 274 if (!jack) 275 return 0; 276 if (jack->kctl) 277 return 0; /* already created */ 278 kctl = snd_kctl_jack_new(name, idx, codec); 279 if (!kctl) 280 return -ENOMEM; 281 err = snd_hda_ctl_add(codec, nid, kctl); 282 if (err < 0) 283 return err; 284 jack->kctl = kctl; 285 state = snd_hda_jack_detect(codec, nid); 286 snd_kctl_jack_report(codec->bus->card, kctl, state); 287 #ifdef CONFIG_SND_HDA_INPUT_JACK 288 jack->type = get_input_jack_type(codec, nid); 289 err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); 290 if (err < 0) 291 return err; 292 jack->jack->private_data = jack; 293 jack->jack->private_free = hda_free_jack_priv; 294 snd_jack_report(jack->jack, state ? jack->type : 0); 295 #endif 296 return 0; 297 } 298 EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); 299 300 static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, 301 const struct auto_pin_cfg *cfg, 302 char *lastname, int *lastidx) 303 { 304 unsigned int def_conf, conn; 305 char name[44]; 306 int idx, err; 307 308 if (!nid) 309 return 0; 310 if (!is_jack_detectable(codec, nid)) 311 return 0; 312 def_conf = snd_hda_codec_get_pincfg(codec, nid); 313 conn = get_defcfg_connect(def_conf); 314 if (conn != AC_JACK_PORT_COMPLEX) 315 return 0; 316 317 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); 318 if (!strcmp(name, lastname) && idx == *lastidx) 319 idx++; 320 strncpy(lastname, name, 44); 321 *lastidx = idx; 322 err = snd_hda_jack_add_kctl(codec, nid, name, idx); 323 if (err < 0) 324 return err; 325 return snd_hda_jack_detect_enable(codec, nid, 0); 326 } 327 328 /** 329 * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg 330 */ 331 int snd_hda_jack_add_kctls(struct hda_codec *codec, 332 const struct auto_pin_cfg *cfg) 333 { 334 const hda_nid_t *p; 335 int i, err, lastidx = 0; 336 char lastname[44] = ""; 337 338 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { 339 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 340 if (err < 0) 341 return err; 342 } 343 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { 344 if (*p == *cfg->line_out_pins) /* might be duplicated */ 345 break; 346 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 347 if (err < 0) 348 return err; 349 } 350 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { 351 if (*p == *cfg->line_out_pins) /* might be duplicated */ 352 break; 353 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 354 if (err < 0) 355 return err; 356 } 357 for (i = 0; i < cfg->num_inputs; i++) { 358 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); 359 if (err < 0) 360 return err; 361 } 362 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { 363 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 364 if (err < 0) 365 return err; 366 } 367 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); 368 if (err < 0) 369 return err; 370 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); 371 if (err < 0) 372 return err; 373 return 0; 374 } 375 EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls); 376