From 8d087c7600499463b7b8e3d4da4da40669cb8bfa Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Tue, 28 Jun 2011 12:45:47 +0200 Subject: [PATCH] ALSA: hda - Create snd_hda_get_conn_index() helper function Create snd_hda_get_conn_index() helper function for obtaining the connection index of the widget. Replaced the similar codes used in several codec-drivers with this common helper. Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/hda_codec.c | 42 ++++++++++++++++++++++++++++++---- sound/pci/hda/hda_codec.h | 2 ++ sound/pci/hda/patch_cirrus.c | 16 ++++--------- sound/pci/hda/patch_cmedia.c | 11 ++++----- sound/pci/hda/patch_conexant.c | 15 ++---------- sound/pci/hda/patch_realtek.c | 14 ++---------- sound/pci/hda/patch_sigmatel.c | 27 +++------------------- sound/pci/hda/patch_via.c | 40 ++++---------------------------- 8 files changed, 59 insertions(+), 108 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 26c420de91c3..7f8502388a82 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -411,11 +411,8 @@ static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, wcaps = get_wcaps(codec, nid); if (!(wcaps & AC_WCAP_CONN_LIST) && - get_wcaps_type(wcaps) != AC_WID_VOL_KNB) { - snd_printk(KERN_WARNING "hda_codec: " - "connection list not available for 0x%x\n", nid); - return -EINVAL; - } + get_wcaps_type(wcaps) != AC_WID_VOL_KNB) + return 0; parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); if (parm & AC_CLIST_LONG) { @@ -505,6 +502,41 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid) return true; } +/** + * snd_hda_get_conn_index - get the connection index of the given NID + * @codec: the HDA codec + * @mux: NID containing the list + * @nid: NID to select + * @recursive: 1 when searching NID recursively, otherwise 0 + * + * Parses the connection list of the widget @mux and checks whether the + * widget @nid is present. If it is, return the connection index. + * Otherwise it returns -1. + */ +int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, + hda_nid_t nid, int recursive) +{ + hda_nid_t conn[HDA_MAX_NUM_INPUTS]; + int i, nums; + + nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); + for (i = 0; i < nums; i++) + if (conn[i] == nid) + return i; + if (!recursive) + return -1; + if (recursive > 5) { + snd_printd("hda_codec: too deep connection for 0x%x\n", nid); + return -1; + } + recursive++; + for (i = 0; i < nums; i++) + if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0) + return i; + return -1; +} +EXPORT_SYMBOL_HDA(snd_hda_get_conn_index); + /** * snd_hda_queue_unsol_event - add an unsolicited event to queue * @bus: the BUS diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 79ef65e3ae14..10d500d2ba33 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -905,6 +905,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns); int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, const hda_nid_t **listp); +int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, + hda_nid_t nid, int recursive); int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, u32 *ratesp, u64 *formatsp, unsigned int *bpsp); diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index c7b5ca28fa77..7f93739b1e33 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -346,21 +346,15 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { - hda_nid_t pins[2]; unsigned int type; - int j, nums; + int idx; type = get_wcaps_type(get_wcaps(codec, nid)); if (type != AC_WID_AUD_IN) continue; - nums = snd_hda_get_connections(codec, nid, pins, - ARRAY_SIZE(pins)); - if (nums <= 0) - continue; - for (j = 0; j < nums; j++) { - if (pins[j] == pin) { - *idxp = j; - return nid; - } + idx = snd_hda_get_conn_index(codec, nid, pin, 0); + if (idx >= 0) { + *idxp = idx; + return nid; } } return 0; diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 9eaf99b01aec..08af4847c07a 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -403,7 +403,6 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi /* clear the table, only one c-media dac assumed here */ memset(spec->multi_init, 0, sizeof(spec->multi_init)); for (j = 0, i = 0; i < cfg->line_outs; i++) { - hda_nid_t conn[4]; nid = cfg->line_out_pins[i]; /* set as output */ spec->multi_init[j].nid = nid; @@ -416,12 +415,10 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; spec->multi_init[j].param = 0; /* find the index in connect list */ - len = snd_hda_get_connections(codec, nid, conn, 4); - for (k = 0; k < len; k++) - if (conn[k] == spec->dac_nids[i]) { - spec->multi_init[j].param = k; - break; - } + k = snd_hda_get_conn_index(codec, nid, + spec->dac_nids[i], 0); + if (k >= 0) + spec->multi_init[j].param = k; j++; } } diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 6e864276b744..40cf7f16f587 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3308,19 +3308,8 @@ static const struct hda_pcm_stream cx_auto_pcm_analog_capture = { static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; -/* get the connection index of @nid in the widget @mux */ -static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, - hda_nid_t nid) -{ - hda_nid_t conn[HDA_MAX_NUM_INPUTS]; - int i, nums; - - nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); - for (i = 0; i < nums; i++) - if (conn[i] == nid) - return i; - return -1; -} +#define get_connection_index(codec, mux, nid)\ + snd_hda_get_conn_index(codec, mux, nid, 0) /* get an unassigned DAC from the given list. * Return the nid if found and reduce the DAC list, or return zero if diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cf383ede281d..7b96dcef2c62 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1195,18 +1195,8 @@ static void alc_line_automute(struct hda_codec *codec) update_speakers(codec); } -static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, - hda_nid_t nid) -{ - hda_nid_t conn[HDA_MAX_NUM_INPUTS]; - int i, nums; - - nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); - for (i = 0; i < nums; i++) - if (conn[i] == nid) - return i; - return -1; -} +#define get_connection_index(codec, mux, nid) \ + snd_hda_get_conn_index(codec, mux, nid, 0) /* switch the current ADC according to the jack state */ static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7407095cbc78..56425a53cf1b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3408,30 +3408,9 @@ static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux, return 0; } -static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, - hda_nid_t nid) -{ - hda_nid_t conn[HDA_MAX_NUM_INPUTS]; - int i, nums; - - if (!(get_wcaps(codec, mux) & AC_WCAP_CONN_LIST)) - return -1; - - nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); - for (i = 0; i < nums; i++) - if (conn[i] == nid) - return i; - - for (i = 0; i < nums; i++) { - unsigned int wid_caps = get_wcaps(codec, conn[i]); - unsigned int wid_type = get_wcaps_type(wid_caps); - - if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX) - if (get_connection_index(codec, conn[i], nid) >= 0) - return i; - } - return -1; -} +/* look for NID recursively */ +#define get_connection_index(codec, mux, nid) \ + snd_hda_get_conn_index(codec, mux, nid, 1) /* create a volume assigned to the given pin (only if supported) */ /* return 1 if the volume control is created */ diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 997b7057a549..76142c1389d7 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -410,27 +410,8 @@ static int via_new_analog_input(struct via_spec *spec, const char *ctlname, return 0; } -/* return the index of the given widget nid as the source of mux; - * return -1 if not found; - * if num_conns is non-NULL, set the total number of connections - */ -static int __get_connection_index(struct hda_codec *codec, hda_nid_t mux, - hda_nid_t nid, int *num_conns) -{ - hda_nid_t conn[HDA_MAX_NUM_INPUTS]; - int i, nums; - - nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); - if (num_conns) - *num_conns = nums; - for (i = 0; i < nums; i++) - if (conn[i] == nid) - return i; - return -1; -} - #define get_connection_index(codec, mux, nid) \ - __get_connection_index(codec, mux, nid, NULL) + snd_hda_get_conn_index(codec, mux, nid, 0) static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, unsigned int mask) @@ -2011,23 +1992,10 @@ static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx) spec->loopback.amplist = spec->loopback_list; } -/* check whether the path from src to dst is reachable */ static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src, - hda_nid_t dst, int depth) + hda_nid_t dst) { - hda_nid_t conn[8]; - int i, nums; - - nums = snd_hda_get_connections(codec, src, conn, ARRAY_SIZE(conn)); - for (i = 0; i < nums; i++) - if (conn[i] == dst) - return true; - if (++depth > MAX_NID_PATH_DEPTH) - return false; - for (i = 0; i < nums; i++) - if (is_reachable_nid(codec, conn[i], dst, depth)) - return true; - return false; + return snd_hda_get_conn_index(codec, src, dst, 1) >= 0; } /* add the input-route to the given pin */ @@ -2046,7 +2014,7 @@ static bool add_input_route(struct hda_codec *codec, hda_nid_t pin) continue; spec->inputs[spec->num_inputs].mux_idx = idx; } else { - if (!is_reachable_nid(codec, spec->adc_nids[c], pin, 0)) + if (!is_reachable_nid(codec, spec->adc_nids[c], pin)) continue; } spec->inputs[spec->num_inputs].adc_idx = c;