diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 549 |
1 files changed, 452 insertions, 97 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 14829210ef0b..45b4a8d70e08 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <sound/asoundef.h> | 29 | #include <sound/asoundef.h> |
30 | #include <sound/tlv.h> | 30 | #include <sound/tlv.h> |
31 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
32 | #include <sound/jack.h> | ||
32 | #include "hda_local.h" | 33 | #include "hda_local.h" |
33 | #include "hda_beep.h" | 34 | #include "hda_beep.h" |
34 | #include <sound/hda_hwdep.h> | 35 | #include <sound/hda_hwdep.h> |
@@ -306,6 +307,12 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, | |||
306 | } | 307 | } |
307 | EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); | 308 | EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); |
308 | 309 | ||
310 | static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | ||
311 | hda_nid_t *conn_list, int max_conns); | ||
312 | static bool add_conn_list(struct snd_array *array, hda_nid_t nid); | ||
313 | static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, | ||
314 | hda_nid_t *src, int len); | ||
315 | |||
309 | /** | 316 | /** |
310 | * snd_hda_get_connections - get connection list | 317 | * snd_hda_get_connections - get connection list |
311 | * @codec: the HDA codec | 318 | * @codec: the HDA codec |
@@ -319,7 +326,44 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); | |||
319 | * Returns the number of connections, or a negative error code. | 326 | * Returns the number of connections, or a negative error code. |
320 | */ | 327 | */ |
321 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | 328 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, |
322 | hda_nid_t *conn_list, int max_conns) | 329 | hda_nid_t *conn_list, int max_conns) |
330 | { | ||
331 | struct snd_array *array = &codec->conn_lists; | ||
332 | int i, len, old_used; | ||
333 | hda_nid_t list[HDA_MAX_CONNECTIONS]; | ||
334 | |||
335 | /* look up the cached results */ | ||
336 | for (i = 0; i < array->used; ) { | ||
337 | hda_nid_t *p = snd_array_elem(array, i); | ||
338 | len = p[1]; | ||
339 | if (nid == *p) | ||
340 | return copy_conn_list(nid, conn_list, max_conns, | ||
341 | p + 2, len); | ||
342 | i += len + 2; | ||
343 | } | ||
344 | |||
345 | len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS); | ||
346 | if (len < 0) | ||
347 | return len; | ||
348 | |||
349 | /* add to the cache */ | ||
350 | old_used = array->used; | ||
351 | if (!add_conn_list(array, nid) || !add_conn_list(array, len)) | ||
352 | goto error_add; | ||
353 | for (i = 0; i < len; i++) | ||
354 | if (!add_conn_list(array, list[i])) | ||
355 | goto error_add; | ||
356 | |||
357 | return copy_conn_list(nid, conn_list, max_conns, list, len); | ||
358 | |||
359 | error_add: | ||
360 | array->used = old_used; | ||
361 | return -ENOMEM; | ||
362 | } | ||
363 | EXPORT_SYMBOL_HDA(snd_hda_get_connections); | ||
364 | |||
365 | static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | ||
366 | hda_nid_t *conn_list, int max_conns) | ||
323 | { | 367 | { |
324 | unsigned int parm; | 368 | unsigned int parm; |
325 | int i, conn_len, conns; | 369 | int i, conn_len, conns; |
@@ -416,8 +460,28 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
416 | } | 460 | } |
417 | return conns; | 461 | return conns; |
418 | } | 462 | } |
419 | EXPORT_SYMBOL_HDA(snd_hda_get_connections); | ||
420 | 463 | ||
464 | static bool add_conn_list(struct snd_array *array, hda_nid_t nid) | ||
465 | { | ||
466 | hda_nid_t *p = snd_array_new(array); | ||
467 | if (!p) | ||
468 | return false; | ||
469 | *p = nid; | ||
470 | return true; | ||
471 | } | ||
472 | |||
473 | static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, | ||
474 | hda_nid_t *src, int len) | ||
475 | { | ||
476 | if (len > max_dst) { | ||
477 | snd_printk(KERN_ERR "hda_codec: " | ||
478 | "Too many connections %d for NID 0x%x\n", | ||
479 | len, nid); | ||
480 | return -EINVAL; | ||
481 | } | ||
482 | memcpy(dst, src, len * sizeof(hda_nid_t)); | ||
483 | return len; | ||
484 | } | ||
421 | 485 | ||
422 | /** | 486 | /** |
423 | * snd_hda_queue_unsol_event - add an unsolicited event to queue | 487 | * snd_hda_queue_unsol_event - add an unsolicited event to queue |
@@ -936,6 +1000,7 @@ void snd_hda_shutup_pins(struct hda_codec *codec) | |||
936 | } | 1000 | } |
937 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); | 1001 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); |
938 | 1002 | ||
1003 | #ifdef SND_HDA_NEEDS_RESUME | ||
939 | /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ | 1004 | /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ |
940 | static void restore_shutup_pins(struct hda_codec *codec) | 1005 | static void restore_shutup_pins(struct hda_codec *codec) |
941 | { | 1006 | { |
@@ -952,6 +1017,7 @@ static void restore_shutup_pins(struct hda_codec *codec) | |||
952 | } | 1017 | } |
953 | codec->pins_shutup = 0; | 1018 | codec->pins_shutup = 0; |
954 | } | 1019 | } |
1020 | #endif | ||
955 | 1021 | ||
956 | static void init_hda_cache(struct hda_cache_rec *cache, | 1022 | static void init_hda_cache(struct hda_cache_rec *cache, |
957 | unsigned int record_size); | 1023 | unsigned int record_size); |
@@ -1016,6 +1082,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1016 | list_del(&codec->list); | 1082 | list_del(&codec->list); |
1017 | snd_array_free(&codec->mixers); | 1083 | snd_array_free(&codec->mixers); |
1018 | snd_array_free(&codec->nids); | 1084 | snd_array_free(&codec->nids); |
1085 | snd_array_free(&codec->conn_lists); | ||
1019 | codec->bus->caddr_tbl[codec->addr] = NULL; | 1086 | codec->bus->caddr_tbl[codec->addr] = NULL; |
1020 | if (codec->patch_ops.free) | 1087 | if (codec->patch_ops.free) |
1021 | codec->patch_ops.free(codec); | 1088 | codec->patch_ops.free(codec); |
@@ -1076,6 +1143,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1076 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); | 1143 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); |
1077 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); | 1144 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); |
1078 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); | 1145 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); |
1146 | snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); | ||
1079 | if (codec->bus->modelname) { | 1147 | if (codec->bus->modelname) { |
1080 | codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); | 1148 | codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); |
1081 | if (!codec->modelname) { | 1149 | if (!codec->modelname) { |
@@ -1216,6 +1284,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1216 | struct hda_codec *c; | 1284 | struct hda_codec *c; |
1217 | struct hda_cvt_setup *p; | 1285 | struct hda_cvt_setup *p; |
1218 | unsigned int oldval, newval; | 1286 | unsigned int oldval, newval; |
1287 | int type; | ||
1219 | int i; | 1288 | int i; |
1220 | 1289 | ||
1221 | if (!nid) | 1290 | if (!nid) |
@@ -1254,10 +1323,12 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1254 | p->dirty = 0; | 1323 | p->dirty = 0; |
1255 | 1324 | ||
1256 | /* make other inactive cvts with the same stream-tag dirty */ | 1325 | /* make other inactive cvts with the same stream-tag dirty */ |
1326 | type = get_wcaps_type(get_wcaps(codec, nid)); | ||
1257 | list_for_each_entry(c, &codec->bus->codec_list, list) { | 1327 | list_for_each_entry(c, &codec->bus->codec_list, list) { |
1258 | for (i = 0; i < c->cvt_setups.used; i++) { | 1328 | for (i = 0; i < c->cvt_setups.used; i++) { |
1259 | p = snd_array_elem(&c->cvt_setups, i); | 1329 | p = snd_array_elem(&c->cvt_setups, i); |
1260 | if (!p->active && p->stream_tag == stream_tag) | 1330 | if (!p->active && p->stream_tag == stream_tag && |
1331 | get_wcaps_type(get_wcaps(codec, p->nid)) == type) | ||
1261 | p->dirty = 1; | 1332 | p->dirty = 1; |
1262 | } | 1333 | } |
1263 | } | 1334 | } |
@@ -1281,6 +1352,9 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1281 | if (!nid) | 1352 | if (!nid) |
1282 | return; | 1353 | return; |
1283 | 1354 | ||
1355 | if (codec->no_sticky_stream) | ||
1356 | do_now = 1; | ||
1357 | |||
1284 | snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); | 1358 | snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); |
1285 | p = get_hda_cvt_setup(codec, nid); | 1359 | p = get_hda_cvt_setup(codec, nid); |
1286 | if (p) { | 1360 | if (p) { |
@@ -1322,6 +1396,7 @@ static void purify_inactive_streams(struct hda_codec *codec) | |||
1322 | } | 1396 | } |
1323 | } | 1397 | } |
1324 | 1398 | ||
1399 | #ifdef SND_HDA_NEEDS_RESUME | ||
1325 | /* clean up all streams; called from suspend */ | 1400 | /* clean up all streams; called from suspend */ |
1326 | static void hda_cleanup_all_streams(struct hda_codec *codec) | 1401 | static void hda_cleanup_all_streams(struct hda_codec *codec) |
1327 | { | 1402 | { |
@@ -1333,6 +1408,7 @@ static void hda_cleanup_all_streams(struct hda_codec *codec) | |||
1333 | really_cleanup_stream(codec, p); | 1408 | really_cleanup_stream(codec, p); |
1334 | } | 1409 | } |
1335 | } | 1410 | } |
1411 | #endif | ||
1336 | 1412 | ||
1337 | /* | 1413 | /* |
1338 | * amp access functions | 1414 | * amp access functions |
@@ -1831,6 +1907,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
1831 | hda_nid_t nid = get_amp_nid(kcontrol); | 1907 | hda_nid_t nid = get_amp_nid(kcontrol); |
1832 | int dir = get_amp_direction(kcontrol); | 1908 | int dir = get_amp_direction(kcontrol); |
1833 | unsigned int ofs = get_amp_offset(kcontrol); | 1909 | unsigned int ofs = get_amp_offset(kcontrol); |
1910 | bool min_mute = get_amp_min_mute(kcontrol); | ||
1834 | u32 caps, val1, val2; | 1911 | u32 caps, val1, val2; |
1835 | 1912 | ||
1836 | if (size < 4 * sizeof(unsigned int)) | 1913 | if (size < 4 * sizeof(unsigned int)) |
@@ -1841,6 +1918,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
1841 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); | 1918 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); |
1842 | val1 += ofs; | 1919 | val1 += ofs; |
1843 | val1 = ((int)val1) * ((int)val2); | 1920 | val1 = ((int)val1) * ((int)val2); |
1921 | if (min_mute) | ||
1922 | val2 |= TLV_DB_SCALE_MUTE; | ||
1844 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) | 1923 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) |
1845 | return -EFAULT; | 1924 | return -EFAULT; |
1846 | if (put_user(2 * sizeof(unsigned int), _tlv + 1)) | 1925 | if (put_user(2 * sizeof(unsigned int), _tlv + 1)) |
@@ -1910,6 +1989,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, | |||
1910 | } | 1989 | } |
1911 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | 1990 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); |
1912 | 1991 | ||
1992 | static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name) | ||
1993 | { | ||
1994 | int idx; | ||
1995 | for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */ | ||
1996 | if (!_snd_hda_find_mixer_ctl(codec, name, idx)) | ||
1997 | return idx; | ||
1998 | } | ||
1999 | return -EBUSY; | ||
2000 | } | ||
2001 | |||
1913 | /** | 2002 | /** |
1914 | * snd_hda_ctl_add - Add a control element and assign to the codec | 2003 | * snd_hda_ctl_add - Add a control element and assign to the codec |
1915 | * @codec: HD-audio codec | 2004 | * @codec: HD-audio codec |
@@ -2115,10 +2204,10 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2115 | * This function returns zero if successful or a negative error code. | 2204 | * This function returns zero if successful or a negative error code. |
2116 | */ | 2205 | */ |
2117 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | 2206 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, |
2118 | unsigned int *tlv, const char **slaves) | 2207 | unsigned int *tlv, const char * const *slaves) |
2119 | { | 2208 | { |
2120 | struct snd_kcontrol *kctl; | 2209 | struct snd_kcontrol *kctl; |
2121 | const char **s; | 2210 | const char * const *s; |
2122 | int err; | 2211 | int err; |
2123 | 2212 | ||
2124 | for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) | 2213 | for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) |
@@ -2228,10 +2317,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | |||
2228 | change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, | 2317 | change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, |
2229 | HDA_AMP_MUTE, | 2318 | HDA_AMP_MUTE, |
2230 | *valp ? 0 : HDA_AMP_MUTE); | 2319 | *valp ? 0 : HDA_AMP_MUTE); |
2231 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2320 | hda_call_check_power_status(codec, nid); |
2232 | if (codec->patch_ops.check_power_status) | ||
2233 | codec->patch_ops.check_power_status(codec, nid); | ||
2234 | #endif | ||
2235 | snd_hda_power_down(codec); | 2321 | snd_hda_power_down(codec); |
2236 | return change; | 2322 | return change; |
2237 | } | 2323 | } |
@@ -2535,7 +2621,7 @@ static unsigned int convert_to_spdif_status(unsigned short val) | |||
2535 | static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, | 2621 | static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, |
2536 | int verb, int val) | 2622 | int verb, int val) |
2537 | { | 2623 | { |
2538 | hda_nid_t *d; | 2624 | const hda_nid_t *d; |
2539 | 2625 | ||
2540 | snd_hda_codec_write_cache(codec, nid, 0, verb, val); | 2626 | snd_hda_codec_write_cache(codec, nid, 0, verb, val); |
2541 | d = codec->slave_dig_outs; | 2627 | d = codec->slave_dig_outs; |
@@ -2648,8 +2734,6 @@ static struct snd_kcontrol_new dig_mixes[] = { | |||
2648 | { } /* end */ | 2734 | { } /* end */ |
2649 | }; | 2735 | }; |
2650 | 2736 | ||
2651 | #define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */ | ||
2652 | |||
2653 | /** | 2737 | /** |
2654 | * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls | 2738 | * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls |
2655 | * @codec: the HDA codec | 2739 | * @codec: the HDA codec |
@@ -2667,12 +2751,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
2667 | struct snd_kcontrol_new *dig_mix; | 2751 | struct snd_kcontrol_new *dig_mix; |
2668 | int idx; | 2752 | int idx; |
2669 | 2753 | ||
2670 | for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { | 2754 | idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); |
2671 | if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", | 2755 | if (idx < 0) { |
2672 | idx)) | ||
2673 | break; | ||
2674 | } | ||
2675 | if (idx >= SPDIF_MAX_IDX) { | ||
2676 | printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); | 2756 | printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); |
2677 | return -EBUSY; | 2757 | return -EBUSY; |
2678 | } | 2758 | } |
@@ -2823,12 +2903,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
2823 | struct snd_kcontrol_new *dig_mix; | 2903 | struct snd_kcontrol_new *dig_mix; |
2824 | int idx; | 2904 | int idx; |
2825 | 2905 | ||
2826 | for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { | 2906 | idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch"); |
2827 | if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", | 2907 | if (idx < 0) { |
2828 | idx)) | ||
2829 | break; | ||
2830 | } | ||
2831 | if (idx >= SPDIF_MAX_IDX) { | ||
2832 | printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); | 2908 | printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); |
2833 | return -EBUSY; | 2909 | return -EBUSY; |
2834 | } | 2910 | } |
@@ -3654,7 +3730,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec) | |||
3654 | * with the proper parameters for set up. | 3730 | * with the proper parameters for set up. |
3655 | * ops.cleanup should be called in hw_free for clean up of streams. | 3731 | * ops.cleanup should be called in hw_free for clean up of streams. |
3656 | * | 3732 | * |
3657 | * This function returns 0 if successfull, or a negative error code. | 3733 | * This function returns 0 if successful, or a negative error code. |
3658 | */ | 3734 | */ |
3659 | int __devinit snd_hda_build_pcms(struct hda_bus *bus) | 3735 | int __devinit snd_hda_build_pcms(struct hda_bus *bus) |
3660 | { | 3736 | { |
@@ -3683,7 +3759,7 @@ EXPORT_SYMBOL_HDA(snd_hda_build_pcms); | |||
3683 | * If no entries are matching, the function returns a negative value. | 3759 | * If no entries are matching, the function returns a negative value. |
3684 | */ | 3760 | */ |
3685 | int snd_hda_check_board_config(struct hda_codec *codec, | 3761 | int snd_hda_check_board_config(struct hda_codec *codec, |
3686 | int num_configs, const char **models, | 3762 | int num_configs, const char * const *models, |
3687 | const struct snd_pci_quirk *tbl) | 3763 | const struct snd_pci_quirk *tbl) |
3688 | { | 3764 | { |
3689 | if (codec->modelname && models) { | 3765 | if (codec->modelname && models) { |
@@ -3747,7 +3823,7 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config); | |||
3747 | * If no entries are matching, the function returns a negative value. | 3823 | * If no entries are matching, the function returns a negative value. |
3748 | */ | 3824 | */ |
3749 | int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, | 3825 | int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, |
3750 | int num_configs, const char **models, | 3826 | int num_configs, const char * const *models, |
3751 | const struct snd_pci_quirk *tbl) | 3827 | const struct snd_pci_quirk *tbl) |
3752 | { | 3828 | { |
3753 | const struct snd_pci_quirk *q; | 3829 | const struct snd_pci_quirk *q; |
@@ -3796,27 +3872,39 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config); | |||
3796 | * | 3872 | * |
3797 | * Returns 0 if successful, or a negative error code. | 3873 | * Returns 0 if successful, or a negative error code. |
3798 | */ | 3874 | */ |
3799 | int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | 3875 | int snd_hda_add_new_ctls(struct hda_codec *codec, |
3876 | const struct snd_kcontrol_new *knew) | ||
3800 | { | 3877 | { |
3801 | int err; | 3878 | int err; |
3802 | 3879 | ||
3803 | for (; knew->name; knew++) { | 3880 | for (; knew->name; knew++) { |
3804 | struct snd_kcontrol *kctl; | 3881 | struct snd_kcontrol *kctl; |
3882 | int addr = 0, idx = 0; | ||
3805 | if (knew->iface == -1) /* skip this codec private value */ | 3883 | if (knew->iface == -1) /* skip this codec private value */ |
3806 | continue; | 3884 | continue; |
3807 | kctl = snd_ctl_new1(knew, codec); | 3885 | for (;;) { |
3808 | if (!kctl) | ||
3809 | return -ENOMEM; | ||
3810 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
3811 | if (err < 0) { | ||
3812 | if (!codec->addr) | ||
3813 | return err; | ||
3814 | kctl = snd_ctl_new1(knew, codec); | 3886 | kctl = snd_ctl_new1(knew, codec); |
3815 | if (!kctl) | 3887 | if (!kctl) |
3816 | return -ENOMEM; | 3888 | return -ENOMEM; |
3817 | kctl->id.device = codec->addr; | 3889 | if (addr > 0) |
3890 | kctl->id.device = addr; | ||
3891 | if (idx > 0) | ||
3892 | kctl->id.index = idx; | ||
3818 | err = snd_hda_ctl_add(codec, 0, kctl); | 3893 | err = snd_hda_ctl_add(codec, 0, kctl); |
3819 | if (err < 0) | 3894 | if (!err) |
3895 | break; | ||
3896 | /* try first with another device index corresponding to | ||
3897 | * the codec addr; if it still fails (or it's the | ||
3898 | * primary codec), then try another control index | ||
3899 | */ | ||
3900 | if (!addr && codec->addr) | ||
3901 | addr = codec->addr; | ||
3902 | else if (!idx && !knew->index) { | ||
3903 | idx = find_empty_mixer_ctl_idx(codec, | ||
3904 | knew->name); | ||
3905 | if (idx <= 0) | ||
3906 | return err; | ||
3907 | } else | ||
3820 | return err; | 3908 | return err; |
3821 | } | 3909 | } |
3822 | } | 3910 | } |
@@ -3928,7 +4016,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, | |||
3928 | struct hda_loopback_check *check, | 4016 | struct hda_loopback_check *check, |
3929 | hda_nid_t nid) | 4017 | hda_nid_t nid) |
3930 | { | 4018 | { |
3931 | struct hda_amp_list *p; | 4019 | const struct hda_amp_list *p; |
3932 | int ch, v; | 4020 | int ch, v; |
3933 | 4021 | ||
3934 | if (!check->amplist) | 4022 | if (!check->amplist) |
@@ -4096,7 +4184,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, | |||
4096 | -1); | 4184 | -1); |
4097 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | 4185 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); |
4098 | if (codec->slave_dig_outs) { | 4186 | if (codec->slave_dig_outs) { |
4099 | hda_nid_t *d; | 4187 | const hda_nid_t *d; |
4100 | for (d = codec->slave_dig_outs; *d; d++) | 4188 | for (d = codec->slave_dig_outs; *d; d++) |
4101 | snd_hda_codec_setup_stream(codec, *d, stream_tag, 0, | 4189 | snd_hda_codec_setup_stream(codec, *d, stream_tag, 0, |
4102 | format); | 4190 | format); |
@@ -4111,7 +4199,7 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) | |||
4111 | { | 4199 | { |
4112 | snd_hda_codec_cleanup_stream(codec, nid); | 4200 | snd_hda_codec_cleanup_stream(codec, nid); |
4113 | if (codec->slave_dig_outs) { | 4201 | if (codec->slave_dig_outs) { |
4114 | hda_nid_t *d; | 4202 | const hda_nid_t *d; |
4115 | for (d = codec->slave_dig_outs; *d; d++) | 4203 | for (d = codec->slave_dig_outs; *d; d++) |
4116 | snd_hda_codec_cleanup_stream(codec, *d); | 4204 | snd_hda_codec_cleanup_stream(codec, *d); |
4117 | } | 4205 | } |
@@ -4258,7 +4346,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, | |||
4258 | unsigned int format, | 4346 | unsigned int format, |
4259 | struct snd_pcm_substream *substream) | 4347 | struct snd_pcm_substream *substream) |
4260 | { | 4348 | { |
4261 | hda_nid_t *nids = mout->dac_nids; | 4349 | const hda_nid_t *nids = mout->dac_nids; |
4262 | int chs = substream->runtime->channels; | 4350 | int chs = substream->runtime->channels; |
4263 | int i; | 4351 | int i; |
4264 | 4352 | ||
@@ -4313,7 +4401,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare); | |||
4313 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, | 4401 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, |
4314 | struct hda_multi_out *mout) | 4402 | struct hda_multi_out *mout) |
4315 | { | 4403 | { |
4316 | hda_nid_t *nids = mout->dac_nids; | 4404 | const hda_nid_t *nids = mout->dac_nids; |
4317 | int i; | 4405 | int i; |
4318 | 4406 | ||
4319 | for (i = 0; i < mout->num_dacs; i++) | 4407 | for (i = 0; i < mout->num_dacs; i++) |
@@ -4338,7 +4426,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); | |||
4338 | * Helper for automatic pin configuration | 4426 | * Helper for automatic pin configuration |
4339 | */ | 4427 | */ |
4340 | 4428 | ||
4341 | static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) | 4429 | static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list) |
4342 | { | 4430 | { |
4343 | for (; *list; list++) | 4431 | for (; *list; list++) |
4344 | if (*list == nid) | 4432 | if (*list == nid) |
@@ -4372,6 +4460,34 @@ static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences, | |||
4372 | } | 4460 | } |
4373 | 4461 | ||
4374 | 4462 | ||
4463 | /* add the found input-pin to the cfg->inputs[] table */ | ||
4464 | static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid, | ||
4465 | int type) | ||
4466 | { | ||
4467 | if (cfg->num_inputs < AUTO_CFG_MAX_INS) { | ||
4468 | cfg->inputs[cfg->num_inputs].pin = nid; | ||
4469 | cfg->inputs[cfg->num_inputs].type = type; | ||
4470 | cfg->num_inputs++; | ||
4471 | } | ||
4472 | } | ||
4473 | |||
4474 | /* sort inputs in the order of AUTO_PIN_* type */ | ||
4475 | static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg) | ||
4476 | { | ||
4477 | int i, j; | ||
4478 | |||
4479 | for (i = 0; i < cfg->num_inputs; i++) { | ||
4480 | for (j = i + 1; j < cfg->num_inputs; j++) { | ||
4481 | if (cfg->inputs[i].type > cfg->inputs[j].type) { | ||
4482 | struct auto_pin_cfg_item tmp; | ||
4483 | tmp = cfg->inputs[i]; | ||
4484 | cfg->inputs[i] = cfg->inputs[j]; | ||
4485 | cfg->inputs[j] = tmp; | ||
4486 | } | ||
4487 | } | ||
4488 | } | ||
4489 | } | ||
4490 | |||
4375 | /* | 4491 | /* |
4376 | * Parse all pin widgets and store the useful pin nids to cfg | 4492 | * Parse all pin widgets and store the useful pin nids to cfg |
4377 | * | 4493 | * |
@@ -4385,19 +4501,20 @@ static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences, | |||
4385 | * output, i.e. to line_out_pins[0]. So, line_outs is always positive | 4501 | * output, i.e. to line_out_pins[0]. So, line_outs is always positive |
4386 | * if any analog output exists. | 4502 | * if any analog output exists. |
4387 | * | 4503 | * |
4388 | * The analog input pins are assigned to input_pins array. | 4504 | * The analog input pins are assigned to inputs array. |
4389 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, | 4505 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, |
4390 | * respectively. | 4506 | * respectively. |
4391 | */ | 4507 | */ |
4392 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, | 4508 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, |
4393 | struct auto_pin_cfg *cfg, | 4509 | struct auto_pin_cfg *cfg, |
4394 | hda_nid_t *ignore_nids) | 4510 | const hda_nid_t *ignore_nids) |
4395 | { | 4511 | { |
4396 | hda_nid_t nid, end_nid; | 4512 | hda_nid_t nid, end_nid; |
4397 | short seq, assoc_line_out, assoc_speaker; | 4513 | short seq, assoc_line_out, assoc_speaker; |
4398 | short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; | 4514 | short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; |
4399 | short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; | 4515 | short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; |
4400 | short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; | 4516 | short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; |
4517 | int i; | ||
4401 | 4518 | ||
4402 | memset(cfg, 0, sizeof(*cfg)); | 4519 | memset(cfg, 0, sizeof(*cfg)); |
4403 | 4520 | ||
@@ -4468,33 +4585,17 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4468 | sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; | 4585 | sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; |
4469 | cfg->hp_outs++; | 4586 | cfg->hp_outs++; |
4470 | break; | 4587 | break; |
4471 | case AC_JACK_MIC_IN: { | 4588 | case AC_JACK_MIC_IN: |
4472 | int preferred, alt; | 4589 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_MIC); |
4473 | if (loc == AC_JACK_LOC_FRONT || | ||
4474 | (loc & 0x30) == AC_JACK_LOC_INTERNAL) { | ||
4475 | preferred = AUTO_PIN_FRONT_MIC; | ||
4476 | alt = AUTO_PIN_MIC; | ||
4477 | } else { | ||
4478 | preferred = AUTO_PIN_MIC; | ||
4479 | alt = AUTO_PIN_FRONT_MIC; | ||
4480 | } | ||
4481 | if (!cfg->input_pins[preferred]) | ||
4482 | cfg->input_pins[preferred] = nid; | ||
4483 | else if (!cfg->input_pins[alt]) | ||
4484 | cfg->input_pins[alt] = nid; | ||
4485 | break; | 4590 | break; |
4486 | } | ||
4487 | case AC_JACK_LINE_IN: | 4591 | case AC_JACK_LINE_IN: |
4488 | if (loc == AC_JACK_LOC_FRONT) | 4592 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_LINE_IN); |
4489 | cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid; | ||
4490 | else | ||
4491 | cfg->input_pins[AUTO_PIN_LINE] = nid; | ||
4492 | break; | 4593 | break; |
4493 | case AC_JACK_CD: | 4594 | case AC_JACK_CD: |
4494 | cfg->input_pins[AUTO_PIN_CD] = nid; | 4595 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_CD); |
4495 | break; | 4596 | break; |
4496 | case AC_JACK_AUX: | 4597 | case AC_JACK_AUX: |
4497 | cfg->input_pins[AUTO_PIN_AUX] = nid; | 4598 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_AUX); |
4498 | break; | 4599 | break; |
4499 | case AC_JACK_SPDIF_OUT: | 4600 | case AC_JACK_SPDIF_OUT: |
4500 | case AC_JACK_DIG_OTHER_OUT: | 4601 | case AC_JACK_DIG_OTHER_OUT: |
@@ -4539,6 +4640,11 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4539 | memmove(sequences_hp + i, sequences_hp + i + 1, | 4640 | memmove(sequences_hp + i, sequences_hp + i + 1, |
4540 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); | 4641 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); |
4541 | } | 4642 | } |
4643 | memset(cfg->hp_pins + cfg->hp_outs, 0, | ||
4644 | sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs)); | ||
4645 | if (!cfg->hp_outs) | ||
4646 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
4647 | |||
4542 | } | 4648 | } |
4543 | 4649 | ||
4544 | /* sort by sequence */ | 4650 | /* sort by sequence */ |
@@ -4549,21 +4655,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4549 | sort_pins_by_sequence(cfg->hp_pins, sequences_hp, | 4655 | sort_pins_by_sequence(cfg->hp_pins, sequences_hp, |
4550 | cfg->hp_outs); | 4656 | cfg->hp_outs); |
4551 | 4657 | ||
4552 | /* if we have only one mic, make it AUTO_PIN_MIC */ | ||
4553 | if (!cfg->input_pins[AUTO_PIN_MIC] && | ||
4554 | cfg->input_pins[AUTO_PIN_FRONT_MIC]) { | ||
4555 | cfg->input_pins[AUTO_PIN_MIC] = | ||
4556 | cfg->input_pins[AUTO_PIN_FRONT_MIC]; | ||
4557 | cfg->input_pins[AUTO_PIN_FRONT_MIC] = 0; | ||
4558 | } | ||
4559 | /* ditto for line-in */ | ||
4560 | if (!cfg->input_pins[AUTO_PIN_LINE] && | ||
4561 | cfg->input_pins[AUTO_PIN_FRONT_LINE]) { | ||
4562 | cfg->input_pins[AUTO_PIN_LINE] = | ||
4563 | cfg->input_pins[AUTO_PIN_FRONT_LINE]; | ||
4564 | cfg->input_pins[AUTO_PIN_FRONT_LINE] = 0; | ||
4565 | } | ||
4566 | |||
4567 | /* | 4658 | /* |
4568 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin | 4659 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin |
4569 | * as a primary output | 4660 | * as a primary output |
@@ -4602,13 +4693,18 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4602 | break; | 4693 | break; |
4603 | } | 4694 | } |
4604 | 4695 | ||
4696 | sort_autocfg_input_pins(cfg); | ||
4697 | |||
4605 | /* | 4698 | /* |
4606 | * debug prints of the parsed results | 4699 | * debug prints of the parsed results |
4607 | */ | 4700 | */ |
4608 | snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | 4701 | snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n", |
4609 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], | 4702 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], |
4610 | cfg->line_out_pins[2], cfg->line_out_pins[3], | 4703 | cfg->line_out_pins[2], cfg->line_out_pins[3], |
4611 | cfg->line_out_pins[4]); | 4704 | cfg->line_out_pins[4], |
4705 | cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" : | ||
4706 | (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ? | ||
4707 | "speaker" : "line")); | ||
4612 | snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | 4708 | snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", |
4613 | cfg->speaker_outs, cfg->speaker_pins[0], | 4709 | cfg->speaker_outs, cfg->speaker_pins[0], |
4614 | cfg->speaker_pins[1], cfg->speaker_pins[2], | 4710 | cfg->speaker_pins[1], cfg->speaker_pins[2], |
@@ -4621,14 +4717,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4621 | if (cfg->dig_outs) | 4717 | if (cfg->dig_outs) |
4622 | snd_printd(" dig-out=0x%x/0x%x\n", | 4718 | snd_printd(" dig-out=0x%x/0x%x\n", |
4623 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); | 4719 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); |
4624 | snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," | 4720 | snd_printd(" inputs:"); |
4625 | " cd=0x%x, aux=0x%x\n", | 4721 | for (i = 0; i < cfg->num_inputs; i++) { |
4626 | cfg->input_pins[AUTO_PIN_MIC], | 4722 | snd_printd(" %s=0x%x", |
4627 | cfg->input_pins[AUTO_PIN_FRONT_MIC], | 4723 | hda_get_autocfg_input_label(codec, cfg, i), |
4628 | cfg->input_pins[AUTO_PIN_LINE], | 4724 | cfg->inputs[i].pin); |
4629 | cfg->input_pins[AUTO_PIN_FRONT_LINE], | 4725 | } |
4630 | cfg->input_pins[AUTO_PIN_CD], | 4726 | snd_printd("\n"); |
4631 | cfg->input_pins[AUTO_PIN_AUX]); | ||
4632 | if (cfg->dig_in_pin) | 4727 | if (cfg->dig_in_pin) |
4633 | snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); | 4728 | snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); |
4634 | 4729 | ||
@@ -4636,11 +4731,165 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4636 | } | 4731 | } |
4637 | EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config); | 4732 | EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config); |
4638 | 4733 | ||
4639 | /* labels for input pins */ | 4734 | int snd_hda_get_input_pin_attr(unsigned int def_conf) |
4640 | const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { | 4735 | { |
4641 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" | 4736 | unsigned int loc = get_defcfg_location(def_conf); |
4642 | }; | 4737 | unsigned int conn = get_defcfg_connect(def_conf); |
4643 | EXPORT_SYMBOL_HDA(auto_pin_cfg_labels); | 4738 | if (conn == AC_JACK_PORT_NONE) |
4739 | return INPUT_PIN_ATTR_UNUSED; | ||
4740 | /* Windows may claim the internal mic to be BOTH, too */ | ||
4741 | if (conn == AC_JACK_PORT_FIXED || conn == AC_JACK_PORT_BOTH) | ||
4742 | return INPUT_PIN_ATTR_INT; | ||
4743 | if ((loc & 0x30) == AC_JACK_LOC_INTERNAL) | ||
4744 | return INPUT_PIN_ATTR_INT; | ||
4745 | if ((loc & 0x30) == AC_JACK_LOC_SEPARATE) | ||
4746 | return INPUT_PIN_ATTR_DOCK; | ||
4747 | if (loc == AC_JACK_LOC_REAR) | ||
4748 | return INPUT_PIN_ATTR_REAR; | ||
4749 | if (loc == AC_JACK_LOC_FRONT) | ||
4750 | return INPUT_PIN_ATTR_FRONT; | ||
4751 | return INPUT_PIN_ATTR_NORMAL; | ||
4752 | } | ||
4753 | EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); | ||
4754 | |||
4755 | /** | ||
4756 | * hda_get_input_pin_label - Give a label for the given input pin | ||
4757 | * | ||
4758 | * When check_location is true, the function checks the pin location | ||
4759 | * for mic and line-in pins, and set an appropriate prefix like "Front", | ||
4760 | * "Rear", "Internal". | ||
4761 | */ | ||
4762 | |||
4763 | const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, | ||
4764 | int check_location) | ||
4765 | { | ||
4766 | unsigned int def_conf; | ||
4767 | static const char * const mic_names[] = { | ||
4768 | "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic", | ||
4769 | }; | ||
4770 | int attr; | ||
4771 | |||
4772 | def_conf = snd_hda_codec_get_pincfg(codec, pin); | ||
4773 | |||
4774 | switch (get_defcfg_device(def_conf)) { | ||
4775 | case AC_JACK_MIC_IN: | ||
4776 | if (!check_location) | ||
4777 | return "Mic"; | ||
4778 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
4779 | if (!attr) | ||
4780 | return "None"; | ||
4781 | return mic_names[attr - 1]; | ||
4782 | case AC_JACK_LINE_IN: | ||
4783 | if (!check_location) | ||
4784 | return "Line"; | ||
4785 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
4786 | if (!attr) | ||
4787 | return "None"; | ||
4788 | if (attr == INPUT_PIN_ATTR_DOCK) | ||
4789 | return "Dock Line"; | ||
4790 | return "Line"; | ||
4791 | case AC_JACK_AUX: | ||
4792 | return "Aux"; | ||
4793 | case AC_JACK_CD: | ||
4794 | return "CD"; | ||
4795 | case AC_JACK_SPDIF_IN: | ||
4796 | return "SPDIF In"; | ||
4797 | case AC_JACK_DIG_OTHER_IN: | ||
4798 | return "Digital In"; | ||
4799 | default: | ||
4800 | return "Misc"; | ||
4801 | } | ||
4802 | } | ||
4803 | EXPORT_SYMBOL_HDA(hda_get_input_pin_label); | ||
4804 | |||
4805 | /* Check whether the location prefix needs to be added to the label. | ||
4806 | * If all mic-jacks are in the same location (e.g. rear panel), we don't | ||
4807 | * have to put "Front" prefix to each label. In such a case, returns false. | ||
4808 | */ | ||
4809 | static int check_mic_location_need(struct hda_codec *codec, | ||
4810 | const struct auto_pin_cfg *cfg, | ||
4811 | int input) | ||
4812 | { | ||
4813 | unsigned int defc; | ||
4814 | int i, attr, attr2; | ||
4815 | |||
4816 | defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin); | ||
4817 | attr = snd_hda_get_input_pin_attr(defc); | ||
4818 | /* for internal or docking mics, we need locations */ | ||
4819 | if (attr <= INPUT_PIN_ATTR_NORMAL) | ||
4820 | return 1; | ||
4821 | |||
4822 | attr = 0; | ||
4823 | for (i = 0; i < cfg->num_inputs; i++) { | ||
4824 | defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin); | ||
4825 | attr2 = snd_hda_get_input_pin_attr(defc); | ||
4826 | if (attr2 >= INPUT_PIN_ATTR_NORMAL) { | ||
4827 | if (attr && attr != attr2) | ||
4828 | return 1; /* different locations found */ | ||
4829 | attr = attr2; | ||
4830 | } | ||
4831 | } | ||
4832 | return 0; | ||
4833 | } | ||
4834 | |||
4835 | /** | ||
4836 | * hda_get_autocfg_input_label - Get a label for the given input | ||
4837 | * | ||
4838 | * Get a label for the given input pin defined by the autocfg item. | ||
4839 | * Unlike hda_get_input_pin_label(), this function checks all inputs | ||
4840 | * defined in autocfg and avoids the redundant mic/line prefix as much as | ||
4841 | * possible. | ||
4842 | */ | ||
4843 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, | ||
4844 | const struct auto_pin_cfg *cfg, | ||
4845 | int input) | ||
4846 | { | ||
4847 | int type = cfg->inputs[input].type; | ||
4848 | int has_multiple_pins = 0; | ||
4849 | |||
4850 | if ((input > 0 && cfg->inputs[input - 1].type == type) || | ||
4851 | (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type)) | ||
4852 | has_multiple_pins = 1; | ||
4853 | if (has_multiple_pins && type == AUTO_PIN_MIC) | ||
4854 | has_multiple_pins &= check_mic_location_need(codec, cfg, input); | ||
4855 | return hda_get_input_pin_label(codec, cfg->inputs[input].pin, | ||
4856 | has_multiple_pins); | ||
4857 | } | ||
4858 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); | ||
4859 | |||
4860 | /** | ||
4861 | * snd_hda_add_imux_item - Add an item to input_mux | ||
4862 | * | ||
4863 | * When the same label is used already in the existing items, the number | ||
4864 | * suffix is appended to the label. This label index number is stored | ||
4865 | * to type_idx when non-NULL pointer is given. | ||
4866 | */ | ||
4867 | int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, | ||
4868 | int index, int *type_idx) | ||
4869 | { | ||
4870 | int i, label_idx = 0; | ||
4871 | if (imux->num_items >= HDA_MAX_NUM_INPUTS) { | ||
4872 | snd_printd(KERN_ERR "hda_codec: Too many imux items!\n"); | ||
4873 | return -EINVAL; | ||
4874 | } | ||
4875 | for (i = 0; i < imux->num_items; i++) { | ||
4876 | if (!strncmp(label, imux->items[i].label, strlen(label))) | ||
4877 | label_idx++; | ||
4878 | } | ||
4879 | if (type_idx) | ||
4880 | *type_idx = label_idx; | ||
4881 | if (label_idx > 0) | ||
4882 | snprintf(imux->items[imux->num_items].label, | ||
4883 | sizeof(imux->items[imux->num_items].label), | ||
4884 | "%s %d", label, label_idx); | ||
4885 | else | ||
4886 | strlcpy(imux->items[imux->num_items].label, label, | ||
4887 | sizeof(imux->items[imux->num_items].label)); | ||
4888 | imux->items[imux->num_items].index = index; | ||
4889 | imux->num_items++; | ||
4890 | return 0; | ||
4891 | } | ||
4892 | EXPORT_SYMBOL_HDA(snd_hda_add_imux_item); | ||
4644 | 4893 | ||
4645 | 4894 | ||
4646 | #ifdef CONFIG_PM | 4895 | #ifdef CONFIG_PM |
@@ -4675,7 +4924,7 @@ EXPORT_SYMBOL_HDA(snd_hda_suspend); | |||
4675 | * | 4924 | * |
4676 | * Returns 0 if successful. | 4925 | * Returns 0 if successful. |
4677 | * | 4926 | * |
4678 | * This fucntion is defined only when POWER_SAVE isn't set. | 4927 | * This function is defined only when POWER_SAVE isn't set. |
4679 | * In the power-save mode, the codec is resumed dynamically. | 4928 | * In the power-save mode, the codec is resumed dynamically. |
4680 | */ | 4929 | */ |
4681 | int snd_hda_resume(struct hda_bus *bus) | 4930 | int snd_hda_resume(struct hda_bus *bus) |
@@ -4784,5 +5033,111 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen) | |||
4784 | } | 5033 | } |
4785 | EXPORT_SYMBOL_HDA(snd_print_pcm_bits); | 5034 | EXPORT_SYMBOL_HDA(snd_print_pcm_bits); |
4786 | 5035 | ||
5036 | #ifdef CONFIG_SND_HDA_INPUT_JACK | ||
5037 | /* | ||
5038 | * Input-jack notification support | ||
5039 | */ | ||
5040 | struct hda_jack_item { | ||
5041 | hda_nid_t nid; | ||
5042 | int type; | ||
5043 | struct snd_jack *jack; | ||
5044 | }; | ||
5045 | |||
5046 | static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, | ||
5047 | int type) | ||
5048 | { | ||
5049 | switch (type) { | ||
5050 | case SND_JACK_HEADPHONE: | ||
5051 | return "Headphone"; | ||
5052 | case SND_JACK_MICROPHONE: | ||
5053 | return "Mic"; | ||
5054 | case SND_JACK_LINEOUT: | ||
5055 | return "Line-out"; | ||
5056 | case SND_JACK_HEADSET: | ||
5057 | return "Headset"; | ||
5058 | case SND_JACK_VIDEOOUT: | ||
5059 | return "HDMI/DP"; | ||
5060 | default: | ||
5061 | return "Misc"; | ||
5062 | } | ||
5063 | } | ||
5064 | |||
5065 | static void hda_free_jack_priv(struct snd_jack *jack) | ||
5066 | { | ||
5067 | struct hda_jack_item *jacks = jack->private_data; | ||
5068 | jacks->nid = 0; | ||
5069 | jacks->jack = NULL; | ||
5070 | } | ||
5071 | |||
5072 | int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, | ||
5073 | const char *name) | ||
5074 | { | ||
5075 | struct hda_jack_item *jack; | ||
5076 | int err; | ||
5077 | |||
5078 | snd_array_init(&codec->jacks, sizeof(*jack), 32); | ||
5079 | jack = snd_array_new(&codec->jacks); | ||
5080 | if (!jack) | ||
5081 | return -ENOMEM; | ||
5082 | |||
5083 | jack->nid = nid; | ||
5084 | jack->type = type; | ||
5085 | if (!name) | ||
5086 | name = get_jack_default_name(codec, nid, type); | ||
5087 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); | ||
5088 | if (err < 0) { | ||
5089 | jack->nid = 0; | ||
5090 | return err; | ||
5091 | } | ||
5092 | jack->jack->private_data = jack; | ||
5093 | jack->jack->private_free = hda_free_jack_priv; | ||
5094 | return 0; | ||
5095 | } | ||
5096 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_add); | ||
5097 | |||
5098 | void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) | ||
5099 | { | ||
5100 | struct hda_jack_item *jacks = codec->jacks.list; | ||
5101 | int i; | ||
5102 | |||
5103 | if (!jacks) | ||
5104 | return; | ||
5105 | |||
5106 | for (i = 0; i < codec->jacks.used; i++, jacks++) { | ||
5107 | unsigned int pin_ctl; | ||
5108 | unsigned int present; | ||
5109 | int type; | ||
5110 | |||
5111 | if (jacks->nid != nid) | ||
5112 | continue; | ||
5113 | present = snd_hda_jack_detect(codec, nid); | ||
5114 | type = jacks->type; | ||
5115 | if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) { | ||
5116 | pin_ctl = snd_hda_codec_read(codec, nid, 0, | ||
5117 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5118 | type = (pin_ctl & AC_PINCTL_HP_EN) ? | ||
5119 | SND_JACK_HEADPHONE : SND_JACK_LINEOUT; | ||
5120 | } | ||
5121 | snd_jack_report(jacks->jack, present ? type : 0); | ||
5122 | } | ||
5123 | } | ||
5124 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_report); | ||
5125 | |||
5126 | /* free jack instances manually when clearing/reconfiguring */ | ||
5127 | void snd_hda_input_jack_free(struct hda_codec *codec) | ||
5128 | { | ||
5129 | if (!codec->bus->shutdown && codec->jacks.list) { | ||
5130 | struct hda_jack_item *jacks = codec->jacks.list; | ||
5131 | int i; | ||
5132 | for (i = 0; i < codec->jacks.used; i++, jacks++) { | ||
5133 | if (jacks->jack) | ||
5134 | snd_device_free(codec->bus->card, jacks->jack); | ||
5135 | } | ||
5136 | } | ||
5137 | snd_array_free(&codec->jacks); | ||
5138 | } | ||
5139 | EXPORT_SYMBOL_HDA(snd_hda_input_jack_free); | ||
5140 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | ||
5141 | |||
4787 | MODULE_DESCRIPTION("HDA codec core"); | 5142 | MODULE_DESCRIPTION("HDA codec core"); |
4788 | MODULE_LICENSE("GPL"); | 5143 | MODULE_LICENSE("GPL"); |