Commit dce2079b authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Add snd_hda_get_conn_list() helper function

Add a new helper function snd_hda_get_conn_list().
Unlike snd_hda_get_connections(), this function doesn't copy the
connection-list but gives the raw pointer for the cached list.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 2e925dde
...@@ -311,35 +311,35 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); ...@@ -311,35 +311,35 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
hda_nid_t *conn_list, int max_conns); hda_nid_t *conn_list, int max_conns);
static bool add_conn_list(struct snd_array *array, hda_nid_t nid); static bool add_conn_list(struct snd_array *array, hda_nid_t nid);
static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst,
hda_nid_t *src, int len);
/** /**
* snd_hda_get_connections - get connection list * snd_hda_get_connections - get connection list
* @codec: the HDA codec * @codec: the HDA codec
* @nid: NID to parse * @nid: NID to parse
* @conn_list: connection list array * @listp: the pointer to store NID list
* @max_conns: max. number of connections to store
* *
* Parses the connection list of the given widget and stores the list * Parses the connection list of the given widget and stores the list
* of NIDs. * of NIDs.
* *
* Returns the number of connections, or a negative error code. * Returns the number of connections, or a negative error code.
*/ */
int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
hda_nid_t *conn_list, int max_conns) const hda_nid_t **listp)
{ {
struct snd_array *array = &codec->conn_lists; struct snd_array *array = &codec->conn_lists;
int i, len, old_used; int i, len, old_used;
hda_nid_t list[HDA_MAX_CONNECTIONS]; hda_nid_t list[HDA_MAX_CONNECTIONS];
hda_nid_t *p;
/* look up the cached results */ /* look up the cached results */
for (i = 0; i < array->used; ) { for (i = 0; i < array->used; ) {
hda_nid_t *p = snd_array_elem(array, i); p = snd_array_elem(array, i);
len = p[1]; len = p[1];
if (nid == *p) if (nid == *p) {
return copy_conn_list(nid, conn_list, max_conns, if (listp)
p + 2, len); *listp = p + 2;
return len;
}
i += len + 2; i += len + 2;
} }
...@@ -355,12 +355,46 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, ...@@ -355,12 +355,46 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
if (!add_conn_list(array, list[i])) if (!add_conn_list(array, list[i]))
goto error_add; goto error_add;
return copy_conn_list(nid, conn_list, max_conns, list, len); p = snd_array_elem(array, old_used);
if (listp)
*listp = p + 2;
return len;
error_add: error_add:
array->used = old_used; array->used = old_used;
return -ENOMEM; return -ENOMEM;
} }
EXPORT_SYMBOL_HDA(snd_hda_get_conn_list);
/**
* snd_hda_get_connections - copy connection list
* @codec: the HDA codec
* @nid: NID to parse
* @conn_list: connection list array
* @max_conns: max. number of connections to store
*
* Parses the connection list of the given widget and stores the list
* of NIDs.
*
* Returns the number of connections, or a negative error code.
*/
int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
hda_nid_t *conn_list, int max_conns)
{
const hda_nid_t *list;
int len = snd_hda_get_conn_list(codec, nid, &list);
if (len <= 0)
return len;
if (len > max_conns) {
snd_printk(KERN_ERR "hda_codec: "
"Too many connections %d for NID 0x%x\n",
len, nid);
return -EINVAL;
}
memcpy(conn_list, list, len * sizeof(hda_nid_t));
return len;
}
EXPORT_SYMBOL_HDA(snd_hda_get_connections); EXPORT_SYMBOL_HDA(snd_hda_get_connections);
static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
...@@ -471,19 +505,6 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid) ...@@ -471,19 +505,6 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
return true; return true;
} }
static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst,
hda_nid_t *src, int len)
{
if (len > max_dst) {
snd_printk(KERN_ERR "hda_codec: "
"Too many connections %d for NID 0x%x\n",
len, nid);
return -EINVAL;
}
memcpy(dst, src, len * sizeof(hda_nid_t));
return len;
}
/** /**
* snd_hda_queue_unsol_event - add an unsolicited event to queue * snd_hda_queue_unsol_event - add an unsolicited event to queue
* @bus: the BUS * @bus: the BUS
......
...@@ -903,6 +903,8 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, ...@@ -903,6 +903,8 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
hda_nid_t *start_id); hda_nid_t *start_id);
int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
hda_nid_t *conn_list, int max_conns); 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_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
u32 *ratesp, u64 *formatsp, unsigned int *bpsp); u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment