diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-11-16 05:05:55 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-11-16 05:05:55 -0500 |
commit | 8b940fc457fbf883053caf397586a61bd3cae23e (patch) | |
tree | 9d5282f2830c99faa073928ecd84a48bf0f7077c /sound | |
parent | 19723079db3ef1769803e05293314461ba81dede (diff) | |
parent | 25d7d59d1f7321be85bda175c9a1bb85ca1b5881 (diff) |
Merge branch 'fix/hda' into topic/hda
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_eld.c | 13 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 55 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 33 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 43 | ||||
-rw-r--r-- | sound/usb/quirks.c | 7 |
7 files changed, 87 insertions, 69 deletions
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 1c8ddf547a2d..7ae7578bdcc0 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -297,10 +297,18 @@ static int hdmi_update_eld(struct hdmi_eld *e, | |||
297 | buf + ELD_FIXED_BYTES + mnl + 3 * i); | 297 | buf + ELD_FIXED_BYTES + mnl + 3 * i); |
298 | } | 298 | } |
299 | 299 | ||
300 | /* | ||
301 | * HDMI sink's ELD info cannot always be retrieved for now, e.g. | ||
302 | * in console or for audio devices. Assume the highest speakers | ||
303 | * configuration, to _not_ prohibit multi-channel audio playback. | ||
304 | */ | ||
305 | if (!e->spk_alloc) | ||
306 | e->spk_alloc = 0xffff; | ||
307 | |||
308 | e->eld_valid = true; | ||
300 | return 0; | 309 | return 0; |
301 | 310 | ||
302 | out_fail: | 311 | out_fail: |
303 | e->eld_ver = 0; | ||
304 | return -EINVAL; | 312 | return -EINVAL; |
305 | } | 313 | } |
306 | 314 | ||
@@ -323,9 +331,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
323 | * ELD is valid, actual eld_size is assigned in hdmi_update_eld() | 331 | * ELD is valid, actual eld_size is assigned in hdmi_update_eld() |
324 | */ | 332 | */ |
325 | 333 | ||
326 | if (!eld->eld_valid) | ||
327 | return -ENOENT; | ||
328 | |||
329 | size = snd_hdmi_get_eld_size(codec, nid); | 334 | size = snd_hdmi_get_eld_size(codec, nid); |
330 | if (size == 0) { | 335 | if (size == 0) { |
331 | /* wfg: workaround for ASUS P5E-VM HDMI board */ | 336 | /* wfg: workaround for ASUS P5E-VM HDMI board */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 6579e0f2bb57..618ddad17236 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -653,6 +653,9 @@ struct hdmi_eld { | |||
653 | int spk_alloc; | 653 | int spk_alloc; |
654 | int sad_count; | 654 | int sad_count; |
655 | struct cea_sad sad[ELD_MAX_SAD]; | 655 | struct cea_sad sad[ELD_MAX_SAD]; |
656 | /* | ||
657 | * all fields above eld_buffer will be cleared before updating ELD | ||
658 | */ | ||
656 | char eld_buffer[ELD_MAX_SIZE]; | 659 | char eld_buffer[ELD_MAX_SIZE]; |
657 | #ifdef CONFIG_PROC_FS | 660 | #ifdef CONFIG_PROC_FS |
658 | struct snd_info_entry *proc_entry; | 661 | struct snd_info_entry *proc_entry; |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 81b7b791b3c3..9850c5b481ea 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -65,7 +65,10 @@ struct hdmi_spec_per_pin { | |||
65 | hda_nid_t pin_nid; | 65 | hda_nid_t pin_nid; |
66 | int num_mux_nids; | 66 | int num_mux_nids; |
67 | hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; | 67 | hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; |
68 | |||
69 | struct hda_codec *codec; | ||
68 | struct hdmi_eld sink_eld; | 70 | struct hdmi_eld sink_eld; |
71 | struct delayed_work work; | ||
69 | }; | 72 | }; |
70 | 73 | ||
71 | struct hdmi_spec { | 74 | struct hdmi_spec { |
@@ -745,8 +748,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, | |||
745 | * Unsolicited events | 748 | * Unsolicited events |
746 | */ | 749 | */ |
747 | 750 | ||
748 | static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | 751 | static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry); |
749 | struct hdmi_eld *eld); | ||
750 | 752 | ||
751 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | 753 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) |
752 | { | 754 | { |
@@ -755,7 +757,6 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
755 | int pd = !!(res & AC_UNSOL_RES_PD); | 757 | int pd = !!(res & AC_UNSOL_RES_PD); |
756 | int eldv = !!(res & AC_UNSOL_RES_ELDV); | 758 | int eldv = !!(res & AC_UNSOL_RES_ELDV); |
757 | int pin_idx; | 759 | int pin_idx; |
758 | struct hdmi_eld *eld; | ||
759 | 760 | ||
760 | printk(KERN_INFO | 761 | printk(KERN_INFO |
761 | "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", | 762 | "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
@@ -764,17 +765,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
764 | pin_idx = pin_nid_to_pin_index(spec, pin_nid); | 765 | pin_idx = pin_nid_to_pin_index(spec, pin_nid); |
765 | if (pin_idx < 0) | 766 | if (pin_idx < 0) |
766 | return; | 767 | return; |
767 | eld = &spec->pins[pin_idx].sink_eld; | ||
768 | |||
769 | hdmi_present_sense(codec, pin_nid, eld); | ||
770 | 768 | ||
771 | /* | 769 | hdmi_present_sense(&spec->pins[pin_idx], true); |
772 | * HDMI sink's ELD info cannot always be retrieved for now, e.g. | ||
773 | * in console or for audio devices. Assume the highest speakers | ||
774 | * configuration, to _not_ prohibit multi-channel audio playback. | ||
775 | */ | ||
776 | if (!eld->spk_alloc) | ||
777 | eld->spk_alloc = 0xffff; | ||
778 | } | 770 | } |
779 | 771 | ||
780 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | 772 | static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) |
@@ -968,9 +960,11 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) | |||
968 | return 0; | 960 | return 0; |
969 | } | 961 | } |
970 | 962 | ||
971 | static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | 963 | static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry) |
972 | struct hdmi_eld *eld) | ||
973 | { | 964 | { |
965 | struct hda_codec *codec = per_pin->codec; | ||
966 | struct hdmi_eld *eld = &per_pin->sink_eld; | ||
967 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
974 | /* | 968 | /* |
975 | * Always execute a GetPinSense verb here, even when called from | 969 | * Always execute a GetPinSense verb here, even when called from |
976 | * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited | 970 | * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited |
@@ -980,26 +974,39 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | |||
980 | * the unsolicited response to avoid custom WARs. | 974 | * the unsolicited response to avoid custom WARs. |
981 | */ | 975 | */ |
982 | int present = snd_hda_pin_sense(codec, pin_nid); | 976 | int present = snd_hda_pin_sense(codec, pin_nid); |
977 | bool eld_valid = false; | ||
983 | 978 | ||
984 | memset(eld, 0, sizeof(*eld)); | 979 | memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer)); |
985 | 980 | ||
986 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); | 981 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); |
987 | if (eld->monitor_present) | 982 | if (eld->monitor_present) |
988 | eld->eld_valid = !!(present & AC_PINSENSE_ELDV); | 983 | eld_valid = !!(present & AC_PINSENSE_ELDV); |
989 | else | ||
990 | eld->eld_valid = 0; | ||
991 | 984 | ||
992 | printk(KERN_INFO | 985 | printk(KERN_INFO |
993 | "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", | 986 | "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
994 | codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); | 987 | codec->addr, pin_nid, eld->monitor_present, eld_valid); |
995 | 988 | ||
996 | if (eld->eld_valid) | 989 | if (eld_valid) { |
997 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | 990 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) |
998 | snd_hdmi_show_eld(eld); | 991 | snd_hdmi_show_eld(eld); |
992 | else if (retry) { | ||
993 | queue_delayed_work(codec->bus->workq, | ||
994 | &per_pin->work, | ||
995 | msecs_to_jiffies(300)); | ||
996 | } | ||
997 | } | ||
999 | 998 | ||
1000 | snd_hda_input_jack_report(codec, pin_nid); | 999 | snd_hda_input_jack_report(codec, pin_nid); |
1001 | } | 1000 | } |
1002 | 1001 | ||
1002 | static void hdmi_repoll_eld(struct work_struct *work) | ||
1003 | { | ||
1004 | struct hdmi_spec_per_pin *per_pin = | ||
1005 | container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work); | ||
1006 | |||
1007 | hdmi_present_sense(per_pin, false); | ||
1008 | } | ||
1009 | |||
1003 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | 1010 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) |
1004 | { | 1011 | { |
1005 | struct hdmi_spec *spec = codec->spec; | 1012 | struct hdmi_spec *spec = codec->spec; |
@@ -1228,7 +1235,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) | |||
1228 | if (err < 0) | 1235 | if (err < 0) |
1229 | return err; | 1236 | return err; |
1230 | 1237 | ||
1231 | hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld); | 1238 | hdmi_present_sense(per_pin, false); |
1232 | return 0; | 1239 | return 0; |
1233 | } | 1240 | } |
1234 | 1241 | ||
@@ -1279,6 +1286,8 @@ static int generic_hdmi_init(struct hda_codec *codec) | |||
1279 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1286 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1280 | AC_USRSP_EN | pin_nid); | 1287 | AC_USRSP_EN | pin_nid); |
1281 | 1288 | ||
1289 | per_pin->codec = codec; | ||
1290 | INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); | ||
1282 | snd_hda_eld_proc_new(codec, eld, pin_idx); | 1291 | snd_hda_eld_proc_new(codec, eld, pin_idx); |
1283 | } | 1292 | } |
1284 | return 0; | 1293 | return 0; |
@@ -1293,10 +1302,12 @@ static void generic_hdmi_free(struct hda_codec *codec) | |||
1293 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1302 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; |
1294 | struct hdmi_eld *eld = &per_pin->sink_eld; | 1303 | struct hdmi_eld *eld = &per_pin->sink_eld; |
1295 | 1304 | ||
1305 | cancel_delayed_work(&per_pin->work); | ||
1296 | snd_hda_eld_proc_free(codec, eld); | 1306 | snd_hda_eld_proc_free(codec, eld); |
1297 | } | 1307 | } |
1298 | snd_hda_input_jack_free(codec); | 1308 | snd_hda_input_jack_free(codec); |
1299 | 1309 | ||
1310 | flush_workqueue(codec->bus->workq); | ||
1300 | kfree(spec); | 1311 | kfree(spec); |
1301 | } | 1312 | } |
1302 | 1313 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8d1b27b2f78c..14feecf2d802 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1472,7 +1472,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) | |||
1472 | switch (fix->type) { | 1472 | switch (fix->type) { |
1473 | case ALC_FIXUP_SKU: | 1473 | case ALC_FIXUP_SKU: |
1474 | if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) | 1474 | if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) |
1475 | break;; | 1475 | break; |
1476 | snd_printdd(KERN_INFO "hda_codec: %s: " | 1476 | snd_printdd(KERN_INFO "hda_codec: %s: " |
1477 | "Apply sku override for %s\n", | 1477 | "Apply sku override for %s\n", |
1478 | codec->chip_name, modelname); | 1478 | codec->chip_name, modelname); |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index edc2b7bc177c..470f6f286e81 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -227,7 +227,6 @@ struct sigmatel_spec { | |||
227 | 227 | ||
228 | /* power management */ | 228 | /* power management */ |
229 | unsigned int num_pwrs; | 229 | unsigned int num_pwrs; |
230 | const unsigned int *pwr_mapping; | ||
231 | const hda_nid_t *pwr_nids; | 230 | const hda_nid_t *pwr_nids; |
232 | const hda_nid_t *dac_list; | 231 | const hda_nid_t *dac_list; |
233 | 232 | ||
@@ -374,18 +373,15 @@ static const unsigned long stac92hd73xx_capvols[] = { | |||
374 | 373 | ||
375 | #define STAC92HD83_DAC_COUNT 3 | 374 | #define STAC92HD83_DAC_COUNT 3 |
376 | 375 | ||
377 | static const hda_nid_t stac92hd83xxx_pwr_nids[4] = { | 376 | static const hda_nid_t stac92hd83xxx_pwr_nids[7] = { |
378 | 0xa, 0xb, 0xd, 0xe, | 377 | 0x0a, 0x0b, 0x0c, 0xd, 0x0e, |
378 | 0x0f, 0x10 | ||
379 | }; | 379 | }; |
380 | 380 | ||
381 | static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { | 381 | static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { |
382 | 0x1e, 0, | 382 | 0x1e, 0, |
383 | }; | 383 | }; |
384 | 384 | ||
385 | static const unsigned int stac92hd83xxx_pwr_mapping[4] = { | ||
386 | 0x03, 0x0c, 0x20, 0x40, | ||
387 | }; | ||
388 | |||
389 | static const hda_nid_t stac92hd83xxx_dmic_nids[] = { | 385 | static const hda_nid_t stac92hd83xxx_dmic_nids[] = { |
390 | 0x11, 0x20, | 386 | 0x11, 0x20, |
391 | }; | 387 | }; |
@@ -4470,8 +4466,12 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4470 | stac_toggle_power_map(codec, nid, 1); | 4466 | stac_toggle_power_map(codec, nid, 1); |
4471 | continue; | 4467 | continue; |
4472 | } | 4468 | } |
4473 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) | 4469 | if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) { |
4474 | stac_issue_unsol_event(codec, nid); | 4470 | stac_issue_unsol_event(codec, nid); |
4471 | continue; | ||
4472 | } | ||
4473 | /* none of the above, turn the port OFF */ | ||
4474 | stac_toggle_power_map(codec, nid, 0); | ||
4475 | } | 4475 | } |
4476 | 4476 | ||
4477 | /* sync mute LED */ | 4477 | /* sync mute LED */ |
@@ -4727,11 +4727,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | |||
4727 | if (idx >= spec->num_pwrs) | 4727 | if (idx >= spec->num_pwrs) |
4728 | return; | 4728 | return; |
4729 | 4729 | ||
4730 | /* several codecs have two power down bits */ | 4730 | idx = 1 << idx; |
4731 | if (spec->pwr_mapping) | ||
4732 | idx = spec->pwr_mapping[idx]; | ||
4733 | else | ||
4734 | idx = 1 << idx; | ||
4735 | 4731 | ||
4736 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; | 4732 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; |
4737 | if (enable) | 4733 | if (enable) |
@@ -5629,9 +5625,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5629 | snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); | 5625 | snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); |
5630 | } | 5626 | } |
5631 | 5627 | ||
5632 | /* reset pin power-down; Windows may leave these bits after reboot */ | ||
5633 | snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0); | ||
5634 | snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); | ||
5635 | codec->no_trigger_sense = 1; | 5628 | codec->no_trigger_sense = 1; |
5636 | codec->spec = spec; | 5629 | codec->spec = spec; |
5637 | 5630 | ||
@@ -5641,7 +5634,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5641 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | 5634 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; |
5642 | spec->digbeep_nid = 0x21; | 5635 | spec->digbeep_nid = 0x21; |
5643 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 5636 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
5644 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | ||
5645 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 5637 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
5646 | spec->multiout.dac_nids = spec->dac_nids; | 5638 | spec->multiout.dac_nids = spec->dac_nids; |
5647 | spec->init = stac92hd83xxx_core_init; | 5639 | spec->init = stac92hd83xxx_core_init; |
@@ -5658,9 +5650,6 @@ again: | |||
5658 | stac92xx_set_config_regs(codec, | 5650 | stac92xx_set_config_regs(codec, |
5659 | stac92hd83xxx_brd_tbl[spec->board_config]); | 5651 | stac92hd83xxx_brd_tbl[spec->board_config]); |
5660 | 5652 | ||
5661 | if (spec->board_config != STAC_92HD83XXX_PWR_REF) | ||
5662 | spec->num_pwrs = 0; | ||
5663 | |||
5664 | codec->patch_ops = stac92xx_patch_ops; | 5653 | codec->patch_ops = stac92xx_patch_ops; |
5665 | 5654 | ||
5666 | if (find_mute_led_gpio(codec, 0)) | 5655 | if (find_mute_led_gpio(codec, 0)) |
@@ -5869,8 +5858,6 @@ again: | |||
5869 | (codec->revision_id & 0xf) == 1) | 5858 | (codec->revision_id & 0xf) == 1) |
5870 | spec->stream_delay = 40; /* 40 milliseconds */ | 5859 | spec->stream_delay = 40; /* 40 milliseconds */ |
5871 | 5860 | ||
5872 | /* no output amps */ | ||
5873 | spec->num_pwrs = 0; | ||
5874 | /* disable VSW */ | 5861 | /* disable VSW */ |
5875 | spec->init = stac92hd71bxx_core_init; | 5862 | spec->init = stac92hd71bxx_core_init; |
5876 | unmute_init++; | 5863 | unmute_init++; |
@@ -5885,8 +5872,6 @@ again: | |||
5885 | if ((codec->revision_id & 0xf) == 1) | 5872 | if ((codec->revision_id & 0xf) == 1) |
5886 | spec->stream_delay = 40; /* 40 milliseconds */ | 5873 | spec->stream_delay = 40; /* 40 milliseconds */ |
5887 | 5874 | ||
5888 | /* no output amps */ | ||
5889 | spec->num_pwrs = 0; | ||
5890 | /* fallthru */ | 5875 | /* fallthru */ |
5891 | default: | 5876 | default: |
5892 | spec->init = stac92hd71bxx_core_init; | 5877 | spec->init = stac92hd71bxx_core_init; |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6b73efd26991..9c982e47eb99 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -56,7 +56,7 @@ static int wm8994_retune_mobile_base[] = { | |||
56 | static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) | 56 | static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) |
57 | { | 57 | { |
58 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 58 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
59 | struct wm8994 *control = wm8994->control_data; | 59 | struct wm8994 *control = codec->control_data; |
60 | 60 | ||
61 | switch (reg) { | 61 | switch (reg) { |
62 | case WM8994_GPIO_1: | 62 | case WM8994_GPIO_1: |
@@ -3030,19 +3030,34 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3030 | { | 3030 | { |
3031 | struct wm8994_priv *wm8994 = data; | 3031 | struct wm8994_priv *wm8994 = data; |
3032 | struct snd_soc_codec *codec = wm8994->codec; | 3032 | struct snd_soc_codec *codec = wm8994->codec; |
3033 | int reg; | 3033 | int reg, count; |
3034 | 3034 | ||
3035 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); | 3035 | /* We may occasionally read a detection without an impedence |
3036 | if (reg < 0) { | 3036 | * range being provided - if that happens loop again. |
3037 | dev_err(codec->dev, "Failed to read mic detect status: %d\n", | 3037 | */ |
3038 | reg); | 3038 | count = 10; |
3039 | return IRQ_NONE; | 3039 | do { |
3040 | } | 3040 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); |
3041 | if (reg < 0) { | ||
3042 | dev_err(codec->dev, | ||
3043 | "Failed to read mic detect status: %d\n", | ||
3044 | reg); | ||
3045 | return IRQ_NONE; | ||
3046 | } | ||
3041 | 3047 | ||
3042 | if (!(reg & WM8958_MICD_VALID)) { | 3048 | if (!(reg & WM8958_MICD_VALID)) { |
3043 | dev_dbg(codec->dev, "Mic detect data not valid\n"); | 3049 | dev_dbg(codec->dev, "Mic detect data not valid\n"); |
3044 | goto out; | 3050 | goto out; |
3045 | } | 3051 | } |
3052 | |||
3053 | if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK)) | ||
3054 | break; | ||
3055 | |||
3056 | msleep(1); | ||
3057 | } while (count--); | ||
3058 | |||
3059 | if (count == 0) | ||
3060 | dev_warn(codec->dev, "No impedence range reported for jack\n"); | ||
3046 | 3061 | ||
3047 | #ifndef CONFIG_SND_SOC_WM8994_MODULE | 3062 | #ifndef CONFIG_SND_SOC_WM8994_MODULE |
3048 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3063 | trace_snd_soc_jack_irq(dev_name(codec->dev)); |
@@ -3180,9 +3195,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3180 | 3195 | ||
3181 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, | 3196 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, |
3182 | wm8994_fifo_error, "FIFO error", codec); | 3197 | wm8994_fifo_error, "FIFO error", codec); |
3183 | wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN, | 3198 | wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, |
3184 | wm8994_temp_warn, "Thermal warning", codec); | 3199 | wm8994_temp_warn, "Thermal warning", codec); |
3185 | wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT, | 3200 | wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, |
3186 | wm8994_temp_shut, "Thermal shutdown", codec); | 3201 | wm8994_temp_shut, "Thermal shutdown", codec); |
3187 | 3202 | ||
3188 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3203 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 2e5bc7344026..a3ddac0deffd 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -137,12 +137,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
137 | return -ENOMEM; | 137 | return -ENOMEM; |
138 | } | 138 | } |
139 | if (fp->nr_rates > 0) { | 139 | if (fp->nr_rates > 0) { |
140 | rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); | 140 | rate_table = kmemdup(fp->rate_table, |
141 | sizeof(int) * fp->nr_rates, GFP_KERNEL); | ||
141 | if (!rate_table) { | 142 | if (!rate_table) { |
142 | kfree(fp); | 143 | kfree(fp); |
143 | return -ENOMEM; | 144 | return -ENOMEM; |
144 | } | 145 | } |
145 | memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates); | ||
146 | fp->rate_table = rate_table; | 146 | fp->rate_table = rate_table; |
147 | } | 147 | } |
148 | 148 | ||
@@ -224,10 +224,9 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
224 | if (altsd->bNumEndpoints != 1) | 224 | if (altsd->bNumEndpoints != 1) |
225 | return -ENXIO; | 225 | return -ENXIO; |
226 | 226 | ||
227 | fp = kmalloc(sizeof(*fp), GFP_KERNEL); | 227 | fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL); |
228 | if (!fp) | 228 | if (!fp) |
229 | return -ENOMEM; | 229 | return -ENOMEM; |
230 | memcpy(fp, &ua_format, sizeof(*fp)); | ||
231 | 230 | ||
232 | fp->iface = altsd->bInterfaceNumber; | 231 | fp->iface = altsd->bInterfaceNumber; |
233 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | 232 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; |