aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c7df01b72ca..af989f660cc 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -44,6 +44,7 @@ struct hda_vendor_id {
44/* codec vendor labels */ 44/* codec vendor labels */
45static struct hda_vendor_id hda_vendor_ids[] = { 45static struct hda_vendor_id hda_vendor_ids[] = {
46 { 0x1002, "ATI" }, 46 { 0x1002, "ATI" },
47 { 0x1013, "Cirrus Logic" },
47 { 0x1057, "Motorola" }, 48 { 0x1057, "Motorola" },
48 { 0x1095, "Silicon Image" }, 49 { 0x1095, "Silicon Image" },
49 { 0x10de, "Nvidia" }, 50 { 0x10de, "Nvidia" },
@@ -150,7 +151,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
150{ 151{
151 u32 val; 152 u32 val;
152 153
153 val = (u32)(codec->addr & 0x0f) << 28; 154 if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
155 (verb & ~0xfff) || (parm & ~0xffff)) {
156 printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
157 codec->addr, direct, nid, verb, parm);
158 return ~0;
159 }
160
161 val = (u32)codec->addr << 28;
154 val |= (u32)direct << 27; 162 val |= (u32)direct << 27;
155 val |= (u32)nid << 20; 163 val |= (u32)nid << 20;
156 val |= verb << 8; 164 val |= verb << 8;
@@ -167,6 +175,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
167 struct hda_bus *bus = codec->bus; 175 struct hda_bus *bus = codec->bus;
168 int err; 176 int err;
169 177
178 if (cmd == ~0)
179 return -1;
180
170 if (res) 181 if (res)
171 *res = -1; 182 *res = -1;
172 again: 183 again:
@@ -291,11 +302,20 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
291 unsigned int parm; 302 unsigned int parm;
292 int i, conn_len, conns; 303 int i, conn_len, conns;
293 unsigned int shift, num_elems, mask; 304 unsigned int shift, num_elems, mask;
305 unsigned int wcaps;
294 hda_nid_t prev_nid; 306 hda_nid_t prev_nid;
295 307
296 if (snd_BUG_ON(!conn_list || max_conns <= 0)) 308 if (snd_BUG_ON(!conn_list || max_conns <= 0))
297 return -EINVAL; 309 return -EINVAL;
298 310
311 wcaps = get_wcaps(codec, nid);
312 if (!(wcaps & AC_WCAP_CONN_LIST) &&
313 get_wcaps_type(wcaps) != AC_WID_VOL_KNB) {
314 snd_printk(KERN_WARNING "hda_codec: "
315 "connection list not available for 0x%x\n", nid);
316 return -EINVAL;
317 }
318
299 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 319 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
300 if (parm & AC_CLIST_LONG) { 320 if (parm & AC_CLIST_LONG) {
301 /* long form */ 321 /* long form */
@@ -316,6 +336,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
316 /* single connection */ 336 /* single connection */
317 parm = snd_hda_codec_read(codec, nid, 0, 337 parm = snd_hda_codec_read(codec, nid, 0,
318 AC_VERB_GET_CONNECT_LIST, 0); 338 AC_VERB_GET_CONNECT_LIST, 0);
339 if (parm == -1 && codec->bus->rirb_error)
340 return -EIO;
319 conn_list[0] = parm & mask; 341 conn_list[0] = parm & mask;
320 return 1; 342 return 1;
321 } 343 }
@@ -327,9 +349,12 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
327 int range_val; 349 int range_val;
328 hda_nid_t val, n; 350 hda_nid_t val, n;
329 351
330 if (i % num_elems == 0) 352 if (i % num_elems == 0) {
331 parm = snd_hda_codec_read(codec, nid, 0, 353 parm = snd_hda_codec_read(codec, nid, 0,
332 AC_VERB_GET_CONNECT_LIST, i); 354 AC_VERB_GET_CONNECT_LIST, i);
355 if (parm == -1 && codec->bus->rirb_error)
356 return -EIO;
357 }
333 range_val = !!(parm & (1 << (shift-1))); /* ranges */ 358 range_val = !!(parm & (1 << (shift-1))); /* ranges */
334 val = parm & mask; 359 val = parm & mask;
335 if (val == 0) { 360 if (val == 0) {
@@ -727,8 +752,7 @@ static int read_pin_defaults(struct hda_codec *codec)
727 for (i = 0; i < codec->num_nodes; i++, nid++) { 752 for (i = 0; i < codec->num_nodes; i++, nid++) {
728 struct hda_pincfg *pin; 753 struct hda_pincfg *pin;
729 unsigned int wcaps = get_wcaps(codec, nid); 754 unsigned int wcaps = get_wcaps(codec, nid);
730 unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> 755 unsigned int wid_type = get_wcaps_type(wcaps);
731 AC_WCAP_TYPE_SHIFT;
732 if (wid_type != AC_WID_PIN) 756 if (wid_type != AC_WID_PIN)
733 continue; 757 continue;
734 pin = snd_array_new(&codec->init_pins); 758 pin = snd_array_new(&codec->init_pins);
@@ -891,7 +915,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
891 * Returns 0 if successful, or a negative error code. 915 * Returns 0 if successful, or a negative error code.
892 */ 916 */
893int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 917int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
894 int do_init, struct hda_codec **codecp) 918 struct hda_codec **codecp)
895{ 919{
896 struct hda_codec *codec; 920 struct hda_codec *codec;
897 char component[31]; 921 char component[31];
@@ -984,11 +1008,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
984 codec->afg ? codec->afg : codec->mfg, 1008 codec->afg ? codec->afg : codec->mfg,
985 AC_PWRST_D0); 1009 AC_PWRST_D0);
986 1010
987 if (do_init) {
988 err = snd_hda_codec_configure(codec);
989 if (err < 0)
990 goto error;
991 }
992 snd_hda_codec_proc_new(codec); 1011 snd_hda_codec_proc_new(codec);
993 1012
994 snd_hda_create_hwdep(codec); 1013 snd_hda_create_hwdep(codec);
@@ -1042,6 +1061,7 @@ int snd_hda_codec_configure(struct hda_codec *codec)
1042 err = init_unsol_queue(codec->bus); 1061 err = init_unsol_queue(codec->bus);
1043 return err; 1062 return err;
1044} 1063}
1064EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
1045 1065
1046/** 1066/**
1047 * snd_hda_codec_setup_stream - set up the codec for streaming 1067 * snd_hda_codec_setup_stream - set up the codec for streaming
@@ -2356,16 +2376,20 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2356 hda_nid_t nid; 2376 hda_nid_t nid;
2357 int i; 2377 int i;
2358 2378
2359 snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, 2379 /* this delay seems necessary to avoid click noise at power-down */
2380 if (power_state == AC_PWRST_D3)
2381 msleep(100);
2382 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
2360 power_state); 2383 power_state);
2361 msleep(10); /* partial workaround for "azx_get_response timeout" */ 2384 /* partial workaround for "azx_get_response timeout" */
2385 if (power_state == AC_PWRST_D0)
2386 msleep(10);
2362 2387
2363 nid = codec->start_nid; 2388 nid = codec->start_nid;
2364 for (i = 0; i < codec->num_nodes; i++, nid++) { 2389 for (i = 0; i < codec->num_nodes; i++, nid++) {
2365 unsigned int wcaps = get_wcaps(codec, nid); 2390 unsigned int wcaps = get_wcaps(codec, nid);
2366 if (wcaps & AC_WCAP_POWER) { 2391 if (wcaps & AC_WCAP_POWER) {
2367 unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> 2392 unsigned int wid_type = get_wcaps_type(wcaps);
2368 AC_WCAP_TYPE_SHIFT;
2369 if (power_state == AC_PWRST_D3 && 2393 if (power_state == AC_PWRST_D3 &&
2370 wid_type == AC_WID_PIN) { 2394 wid_type == AC_WID_PIN) {
2371 unsigned int pincap; 2395 unsigned int pincap;
@@ -2573,7 +2597,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2573 case 20: 2597 case 20:
2574 case 24: 2598 case 24:
2575 case 32: 2599 case 32:
2576 if (maxbps >= 32) 2600 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
2577 val |= 0x40; 2601 val |= 0x40;
2578 else if (maxbps >= 24) 2602 else if (maxbps >= 24)
2579 val |= 0x30; 2603 val |= 0x30;
@@ -2700,11 +2724,12 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2700 bps = 20; 2724 bps = 20;
2701 } 2725 }
2702 } 2726 }
2703 else if (streams == AC_SUPFMT_FLOAT32) { 2727 if (streams & AC_SUPFMT_FLOAT32) {
2704 /* should be exclusive */
2705 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; 2728 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
2706 bps = 32; 2729 if (!bps)
2707 } else if (streams == AC_SUPFMT_AC3) { 2730 bps = 32;
2731 }
2732 if (streams == AC_SUPFMT_AC3) {
2708 /* should be exclusive */ 2733 /* should be exclusive */
2709 /* temporary hack: we have still no proper support 2734 /* temporary hack: we have still no proper support
2710 * for the direct AC3 stream... 2735 * for the direct AC3 stream...
@@ -3102,7 +3127,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
3102 tbl = q; 3127 tbl = q;
3103 3128
3104 if (tbl->value >= 0 && tbl->value < num_configs) { 3129 if (tbl->value >= 0 && tbl->value < num_configs) {
3105#ifdef CONFIG_SND_DEBUG_DETECT 3130#ifdef CONFIG_SND_DEBUG_VERBOSE
3106 char tmp[10]; 3131 char tmp[10];
3107 const char *model = NULL; 3132 const char *model = NULL;
3108 if (models) 3133 if (models)
@@ -3655,8 +3680,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
3655 end_nid = codec->start_nid + codec->num_nodes; 3680 end_nid = codec->start_nid + codec->num_nodes;
3656 for (nid = codec->start_nid; nid < end_nid; nid++) { 3681 for (nid = codec->start_nid; nid < end_nid; nid++) {
3657 unsigned int wid_caps = get_wcaps(codec, nid); 3682 unsigned int wid_caps = get_wcaps(codec, nid);
3658 unsigned int wid_type = 3683 unsigned int wid_type = get_wcaps_type(wid_caps);
3659 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3660 unsigned int def_conf; 3684 unsigned int def_conf;
3661 short assoc, loc; 3685 short assoc, loc;
3662 3686