/* codec vendor labels */
static struct hda_vendor_id hda_vendor_ids[] = {
{ 0x1002, "ATI" },
+ { 0x1013, "Cirrus Logic" },
{ 0x1057, "Motorola" },
{ 0x1095, "Silicon Image" },
{ 0x10de, "Nvidia" },
{
u32 val;
- if ((codec->addr & ~0xf) | (direct & ~1) | (nid & ~0x7f) |
- (verb & ~0xfff) | (parm & ~0xff)) {
+ if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
+ (verb & ~0xfff) || (parm & ~0xffff)) {
printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
codec->addr, direct, nid, verb, parm);
return ~0;
unsigned int parm;
int i, conn_len, conns;
unsigned int shift, num_elems, mask;
+ unsigned int wcaps;
hda_nid_t prev_nid;
if (snd_BUG_ON(!conn_list || max_conns <= 0))
return -EINVAL;
+ 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;
+ }
+
parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
if (parm & AC_CLIST_LONG) {
/* long form */
}
range_val = !!(parm & (1 << (shift-1))); /* ranges */
val = parm & mask;
+ if (val == 0) {
+ snd_printk(KERN_WARNING "hda_codec: "
+ "invalid CONNECT_LIST verb %x[%i]:%x\n",
+ nid, i, parm);
+ return 0;
+ }
parm >>= shift;
if (range_val) {
/* ranges between the previous and this one */
for (i = 0; i < codec->num_nodes; i++, nid++) {
struct hda_pincfg *pin;
unsigned int wcaps = get_wcaps(codec, nid);
- unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >>
- AC_WCAP_TYPE_SHIFT;
+ unsigned int wid_type = get_wcaps_type(wcaps);
if (wid_type != AC_WID_PIN)
continue;
pin = snd_array_new(&codec->init_pins);
hda_nid_t nid;
int i;
- snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE,
+ /* this delay seems necessary to avoid click noise at power-down */
+ if (power_state == AC_PWRST_D3)
+ msleep(100);
+ snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
power_state);
- msleep(10); /* partial workaround for "azx_get_response timeout" */
+ /* partial workaround for "azx_get_response timeout" */
+ if (power_state == AC_PWRST_D0)
+ msleep(10);
nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++) {
unsigned int wcaps = get_wcaps(codec, nid);
if (wcaps & AC_WCAP_POWER) {
- unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >>
- AC_WCAP_TYPE_SHIFT;
+ unsigned int wid_type = get_wcaps_type(wcaps);
if (power_state == AC_PWRST_D3 &&
wid_type == AC_WID_PIN) {
unsigned int pincap;
end_nid = codec->start_nid + codec->num_nodes;
for (nid = codec->start_nid; nid < end_nid; nid++) {
unsigned int wid_caps = get_wcaps(codec, nid);
- unsigned int wid_type =
- (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+ unsigned int wid_type = get_wcaps_type(wid_caps);
unsigned int def_conf;
short assoc, loc;