hda_jack.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. #include <linux/init.h>
  12. #include <linux/slab.h>
  13. #include <sound/core.h>
  14. #include <sound/control.h>
  15. #include "hda_codec.h"
  16. #include "hda_local.h"
  17. #include "hda_jack.h"
  18. /* execute pin sense measurement */
  19. static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
  20. {
  21. u32 pincap;
  22. if (!codec->no_trigger_sense) {
  23. pincap = snd_hda_query_pin_caps(codec, nid);
  24. if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
  25. snd_hda_codec_read(codec, nid, 0,
  26. AC_VERB_SET_PIN_SENSE, 0);
  27. }
  28. return snd_hda_codec_read(codec, nid, 0,
  29. AC_VERB_GET_PIN_SENSE, 0);
  30. }
  31. /**
  32. * snd_hda_jack_tbl_get - query the jack-table entry for the given NID
  33. */
  34. struct hda_jack_tbl *
  35. snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
  36. {
  37. struct hda_jack_tbl *jack = codec->jacktbl.list;
  38. int i;
  39. if (!nid || !jack)
  40. return NULL;
  41. for (i = 0; i < codec->jacktbl.used; i++, jack++)
  42. if (jack->nid == nid)
  43. return jack;
  44. return NULL;
  45. }
  46. EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get);
  47. /**
  48. * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
  49. */
  50. struct hda_jack_tbl *
  51. snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag)
  52. {
  53. struct hda_jack_tbl *jack = codec->jacktbl.list;
  54. int i;
  55. if (!tag || !jack)
  56. return NULL;
  57. for (i = 0; i < codec->jacktbl.used; i++, jack++)
  58. if (jack->tag == tag)
  59. return jack;
  60. return NULL;
  61. }
  62. EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag);
  63. /**
  64. * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
  65. */
  66. struct hda_jack_tbl *
  67. snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
  68. {
  69. struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
  70. if (jack)
  71. return jack;
  72. snd_array_init(&codec->jacktbl, sizeof(*jack), 16);
  73. jack = snd_array_new(&codec->jacktbl);
  74. if (!jack)
  75. return NULL;
  76. jack->nid = nid;
  77. jack->jack_dirty = 1;
  78. jack->tag = codec->jacktbl.used;
  79. return jack;
  80. }
  81. void snd_hda_jack_tbl_clear(struct hda_codec *codec)
  82. {
  83. snd_array_free(&codec->jacktbl);
  84. }
  85. /* update the cached value and notification flag if needed */
  86. static void jack_detect_update(struct hda_codec *codec,
  87. struct hda_jack_tbl *jack)
  88. {
  89. if (jack->jack_dirty || !jack->jack_detect) {
  90. unsigned int val = read_pin_sense(codec, jack->nid);
  91. jack->jack_dirty = 0;
  92. if (val != jack->pin_sense) {
  93. jack->need_notify = 1;
  94. jack->pin_sense = val;
  95. }
  96. }
  97. }
  98. /**
  99. * snd_hda_set_dirty_all - Mark all the cached as dirty
  100. *
  101. * This function sets the dirty flag to all entries of jack table.
  102. * It's called from the resume path in hda_codec.c.
  103. */
  104. void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
  105. {
  106. struct hda_jack_tbl *jack = codec->jacktbl.list;
  107. int i;
  108. for (i = 0; i < codec->jacktbl.used; i++, jack++)
  109. if (jack->nid)
  110. jack->jack_dirty = 1;
  111. }
  112. EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all);
  113. /**
  114. * snd_hda_pin_sense - execute pin sense measurement
  115. * @codec: the CODEC to sense
  116. * @nid: the pin NID to sense
  117. *
  118. * Execute necessary pin sense measurement and return its Presence Detect,
  119. * Impedance, ELD Valid etc. status bits.
  120. */
  121. u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
  122. {
  123. struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
  124. if (jack) {
  125. jack_detect_update(codec, jack);
  126. return jack->pin_sense;
  127. }
  128. return read_pin_sense(codec, nid);
  129. }
  130. EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
  131. /**
  132. * snd_hda_jack_detect - query pin Presence Detect status
  133. * @codec: the CODEC to sense
  134. * @nid: the pin NID to sense
  135. *
  136. * Query and return the pin's Presence Detect status.
  137. */
  138. int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
  139. {
  140. u32 sense = snd_hda_pin_sense(codec, nid);
  141. return !!(sense & AC_PINSENSE_PRESENCE);
  142. }
  143. EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
  144. /**
  145. * snd_hda_jack_detect_enable - enable the jack-detection
  146. */
  147. int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
  148. unsigned char action)
  149. {
  150. struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
  151. if (!jack)
  152. return -ENOMEM;
  153. if (jack->jack_detect)
  154. return 0; /* already registered */
  155. jack->jack_detect = 1;
  156. if (action)
  157. jack->action = action;
  158. return snd_hda_codec_write_cache(codec, nid, 0,
  159. AC_VERB_SET_UNSOLICITED_ENABLE,
  160. AC_USRSP_EN | jack->tag);
  161. }
  162. EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
  163. /* queue the notification when needed */
  164. static void jack_detect_report(struct hda_codec *codec,
  165. struct hda_jack_tbl *jack)
  166. {
  167. jack_detect_update(codec, jack);
  168. if (jack->need_notify) {
  169. snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
  170. &jack->kctl->id);
  171. jack->need_notify = 0;
  172. }
  173. }
  174. /**
  175. * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
  176. */
  177. void snd_hda_jack_report_sync(struct hda_codec *codec)
  178. {
  179. struct hda_jack_tbl *jack = codec->jacktbl.list;
  180. int i;
  181. for (i = 0; i < codec->jacktbl.used; i++, jack++)
  182. if (jack->nid) {
  183. jack_detect_update(codec, jack);
  184. jack_detect_report(codec, jack);
  185. }
  186. }
  187. EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync);
  188. /*
  189. * jack-detection kcontrols
  190. */
  191. #define jack_detect_kctl_info snd_ctl_boolean_mono_info
  192. static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol,
  193. struct snd_ctl_elem_value *ucontrol)
  194. {
  195. struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  196. hda_nid_t nid = kcontrol->private_value;
  197. ucontrol->value.integer.value[0] = snd_hda_jack_detect(codec, nid);
  198. return 0;
  199. }
  200. static struct snd_kcontrol_new jack_detect_kctl = {
  201. /* name is filled later */
  202. .iface = SNDRV_CTL_ELEM_IFACE_CARD,
  203. .access = SNDRV_CTL_ELEM_ACCESS_READ,
  204. .info = jack_detect_kctl_info,
  205. .get = jack_detect_kctl_get,
  206. };
  207. /**
  208. * snd_hda_jack_add_kctl - Add a kctl for the given pin
  209. *
  210. * This assigns a jack-detection kctl to the given pin. The kcontrol
  211. * will have the given name and index.
  212. */
  213. int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
  214. const char *name, int idx)
  215. {
  216. struct hda_jack_tbl *jack;
  217. struct snd_kcontrol *kctl;
  218. jack = snd_hda_jack_tbl_new(codec, nid);
  219. if (!jack)
  220. return 0;
  221. if (jack->kctl)
  222. return 0; /* already created */
  223. kctl = snd_ctl_new1(&jack_detect_kctl, codec);
  224. if (!kctl)
  225. return -ENOMEM;
  226. snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name);
  227. kctl->id.index = idx;
  228. kctl->private_value = nid;
  229. if (snd_hda_ctl_add(codec, nid, kctl) < 0)
  230. return -ENOMEM;
  231. jack->kctl = kctl;
  232. return 0;
  233. }
  234. static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, int idx,
  235. const struct auto_pin_cfg *cfg)
  236. {
  237. unsigned int def_conf, conn;
  238. int err;
  239. if (!nid)
  240. return 0;
  241. if (!is_jack_detectable(codec, nid))
  242. return 0;
  243. def_conf = snd_hda_codec_get_pincfg(codec, nid);
  244. conn = get_defcfg_connect(def_conf);
  245. if (conn != AC_JACK_PORT_COMPLEX)
  246. return 0;
  247. err = snd_hda_jack_add_kctl(codec, nid,
  248. snd_hda_get_pin_label(codec, nid, cfg),
  249. idx);
  250. if (err < 0)
  251. return err;
  252. return snd_hda_jack_detect_enable(codec, nid, 0);
  253. }
  254. /**
  255. * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg
  256. */
  257. int snd_hda_jack_add_kctls(struct hda_codec *codec,
  258. const struct auto_pin_cfg *cfg)
  259. {
  260. const hda_nid_t *p;
  261. int i, err;
  262. for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
  263. err = add_jack_kctl(codec, *p, i, cfg);
  264. if (err < 0)
  265. return err;
  266. }
  267. for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
  268. if (*p == *cfg->line_out_pins) /* might be duplicated */
  269. break;
  270. err = add_jack_kctl(codec, *p, i, cfg);
  271. if (err < 0)
  272. return err;
  273. }
  274. for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
  275. if (*p == *cfg->line_out_pins) /* might be duplicated */
  276. break;
  277. err = add_jack_kctl(codec, *p, i, cfg);
  278. if (err < 0)
  279. return err;
  280. }
  281. for (i = 0; i < cfg->num_inputs; i++) {
  282. err = add_jack_kctl(codec, cfg->inputs[i].pin, 0, cfg);
  283. if (err < 0)
  284. return err;
  285. }
  286. for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
  287. err = add_jack_kctl(codec, *p, i, cfg);
  288. if (err < 0)
  289. return err;
  290. }
  291. err = add_jack_kctl(codec, cfg->dig_in_pin, 0, cfg);
  292. if (err < 0)
  293. return err;
  294. err = add_jack_kctl(codec, cfg->mono_out_pin, 0, cfg);
  295. if (err < 0)
  296. return err;
  297. return 0;
  298. }
  299. EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);