diff options
Diffstat (limited to 'sound')
| -rw-r--r-- | sound/core/control.c | 4 | ||||
| -rw-r--r-- | sound/core/hwdep.c | 9 | ||||
| -rw-r--r-- | sound/pci/hda/hda_hwdep.c | 2 | ||||
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 4 | ||||
| -rw-r--r-- | sound/pci/hda/hda_local.h | 7 | ||||
| -rw-r--r-- | sound/pci/hda/patch_hdmi.c | 5 | ||||
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 29 | ||||
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 67 | ||||
| -rw-r--r-- | sound/pci/hda/patch_via.c | 5 | ||||
| -rw-r--r-- | sound/pci/intel8x0.c | 29 | ||||
| -rw-r--r-- | sound/pci/rme9652/hdsp.c | 2 | ||||
| -rw-r--r-- | sound/pci/rme9652/hdspm.c | 42 | ||||
| -rw-r--r-- | sound/soc/codecs/tlv320aic23.c | 1 | ||||
| -rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 1 | ||||
| -rw-r--r-- | sound/soc/codecs/wm5100.c | 12 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8711.c | 4 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8904.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8940.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8962.c | 30 | ||||
| -rw-r--r-- | sound/soc/samsung/ac97.c | 10 | ||||
| -rw-r--r-- | sound/soc/samsung/dma.c | 148 | ||||
| -rw-r--r-- | sound/soc/samsung/dma.h | 4 | ||||
| -rw-r--r-- | sound/usb/misc/ua101.c | 28 |
23 files changed, 251 insertions, 196 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 978fe1a8e9f0..59edb12dd542 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
| @@ -1081,12 +1081,12 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue) | |||
| 1081 | char *names, *p; | 1081 | char *names, *p; |
| 1082 | size_t buf_len, name_len; | 1082 | size_t buf_len, name_len; |
| 1083 | unsigned int i; | 1083 | unsigned int i; |
| 1084 | const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr; | ||
| 1084 | 1085 | ||
| 1085 | if (ue->info.value.enumerated.names_length > 64 * 1024) | 1086 | if (ue->info.value.enumerated.names_length > 64 * 1024) |
| 1086 | return -EINVAL; | 1087 | return -EINVAL; |
| 1087 | 1088 | ||
| 1088 | names = memdup_user( | 1089 | names = memdup_user((const void __user *)user_ptrval, |
| 1089 | (const void __user *)ue->info.value.enumerated.names_ptr, | ||
| 1090 | ue->info.value.enumerated.names_length); | 1090 | ue->info.value.enumerated.names_length); |
| 1091 | if (IS_ERR(names)) | 1091 | if (IS_ERR(names)) |
| 1092 | return PTR_ERR(names); | 1092 | return PTR_ERR(names); |
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index a70ee7f1ed98..031e215b6dde 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c | |||
| @@ -272,7 +272,14 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, | |||
| 272 | if (get_user(device, (int __user *)arg)) | 272 | if (get_user(device, (int __user *)arg)) |
| 273 | return -EFAULT; | 273 | return -EFAULT; |
| 274 | mutex_lock(®ister_mutex); | 274 | mutex_lock(®ister_mutex); |
| 275 | device = device < 0 ? 0 : device + 1; | 275 | |
| 276 | if (device < 0) | ||
| 277 | device = 0; | ||
| 278 | else if (device < SNDRV_MINOR_HWDEPS) | ||
| 279 | device++; | ||
| 280 | else | ||
| 281 | device = SNDRV_MINOR_HWDEPS; | ||
| 282 | |||
| 276 | while (device < SNDRV_MINOR_HWDEPS) { | 283 | while (device < SNDRV_MINOR_HWDEPS) { |
| 277 | if (snd_hwdep_search(card, device)) | 284 | if (snd_hwdep_search(card, device)) |
| 278 | break; | 285 | break; |
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 72e5885007cc..7e7d0788ddcf 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
| @@ -756,8 +756,6 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw) | |||
| 756 | } | 756 | } |
| 757 | if (!fw->size) | 757 | if (!fw->size) |
| 758 | return 0; | 758 | return 0; |
| 759 | if (size < fw->size) | ||
| 760 | size = fw->size; | ||
| 761 | 759 | ||
| 762 | for (len = 0; len < fw->size; len++) { | 760 | for (len = 0; len < fw->size; len++) { |
| 763 | if (!*p) | 761 | if (!*p) |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index bd7fc99af187..096507d2ca9a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -3063,12 +3063,12 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
| 3063 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 3063 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
| 3064 | .class_mask = 0xffffff, | 3064 | .class_mask = 0xffffff, |
| 3065 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | | 3065 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | |
| 3066 | AZX_DCAPS_RIRB_PRE_DELAY }, | 3066 | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, |
| 3067 | #else | 3067 | #else |
| 3068 | /* this entry seems still valid -- i.e. without emu20kx chip */ | 3068 | /* this entry seems still valid -- i.e. without emu20kx chip */ |
| 3069 | { PCI_DEVICE(0x1102, 0x0009), | 3069 | { PCI_DEVICE(0x1102, 0x0009), |
| 3070 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | | 3070 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | |
| 3071 | AZX_DCAPS_RIRB_PRE_DELAY }, | 3071 | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, |
| 3072 | #endif | 3072 | #endif |
| 3073 | /* Vortex86MX */ | 3073 | /* Vortex86MX */ |
| 3074 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, | 3074 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 81e12c0ed0a2..dcbea0da0fa2 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
| @@ -442,6 +442,8 @@ struct auto_pin_cfg { | |||
| 442 | (cfg & AC_DEFCFG_SEQUENCE) | 442 | (cfg & AC_DEFCFG_SEQUENCE) |
| 443 | #define get_defcfg_device(cfg) \ | 443 | #define get_defcfg_device(cfg) \ |
| 444 | ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | 444 | ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) |
| 445 | #define get_defcfg_misc(cfg) \ | ||
| 446 | ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) | ||
| 445 | 447 | ||
| 446 | /* bit-flags for snd_hda_parse_pin_def_config() behavior */ | 448 | /* bit-flags for snd_hda_parse_pin_def_config() behavior */ |
| 447 | #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ | 449 | #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ |
| @@ -509,6 +511,11 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | |||
| 509 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) |
| 510 | { | 512 | { |
| 511 | return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && | 513 | return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && |
| 514 | /* disable MISC_NO_PRESENCE check because it may break too | ||
| 515 | * many devices | ||
| 516 | */ | ||
| 517 | /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & | ||
| 518 | AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ | ||
| 512 | (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); | 519 | (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); |
| 513 | } | 520 | } |
| 514 | 521 | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 342540128fb8..aac3bfacda3f 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -1006,7 +1006,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | |||
| 1006 | unsigned int caps, config; | 1006 | unsigned int caps, config; |
| 1007 | int pin_idx; | 1007 | int pin_idx; |
| 1008 | struct hdmi_spec_per_pin *per_pin; | 1008 | struct hdmi_spec_per_pin *per_pin; |
| 1009 | struct hdmi_eld *eld; | ||
| 1010 | int err; | 1009 | int err; |
| 1011 | 1010 | ||
| 1012 | caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP); | 1011 | caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP); |
| @@ -1023,7 +1022,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | |||
| 1023 | 1022 | ||
| 1024 | pin_idx = spec->num_pins; | 1023 | pin_idx = spec->num_pins; |
| 1025 | per_pin = &spec->pins[pin_idx]; | 1024 | per_pin = &spec->pins[pin_idx]; |
| 1026 | eld = &per_pin->sink_eld; | ||
| 1027 | 1025 | ||
| 1028 | per_pin->pin_nid = pin_nid; | 1026 | per_pin->pin_nid = pin_nid; |
| 1029 | 1027 | ||
| @@ -1576,7 +1574,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 1576 | struct snd_pcm_substream *substream) | 1574 | struct snd_pcm_substream *substream) |
| 1577 | { | 1575 | { |
| 1578 | int chs; | 1576 | int chs; |
| 1579 | unsigned int dataDCC1, dataDCC2, channel_id; | 1577 | unsigned int dataDCC2, channel_id; |
| 1580 | int i; | 1578 | int i; |
| 1581 | struct hdmi_spec *spec = codec->spec; | 1579 | struct hdmi_spec *spec = codec->spec; |
| 1582 | struct hda_spdif_out *spdif = | 1580 | struct hda_spdif_out *spdif = |
| @@ -1586,7 +1584,6 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 1586 | 1584 | ||
| 1587 | chs = substream->runtime->channels; | 1585 | chs = substream->runtime->channels; |
| 1588 | 1586 | ||
| 1589 | dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT; | ||
| 1590 | dataDCC2 = 0x2; | 1587 | dataDCC2 = 0x2; |
| 1591 | 1588 | ||
| 1592 | /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ | 1589 | /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8f93b97559a5..9693059dec84 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -1604,27 +1604,29 @@ static void alc_auto_init_digital(struct hda_codec *codec) | |||
| 1604 | static void alc_auto_parse_digital(struct hda_codec *codec) | 1604 | static void alc_auto_parse_digital(struct hda_codec *codec) |
| 1605 | { | 1605 | { |
| 1606 | struct alc_spec *spec = codec->spec; | 1606 | struct alc_spec *spec = codec->spec; |
| 1607 | int i, err; | 1607 | int i, err, nums; |
| 1608 | hda_nid_t dig_nid; | 1608 | hda_nid_t dig_nid; |
| 1609 | 1609 | ||
| 1610 | /* support multiple SPDIFs; the secondary is set up as a slave */ | 1610 | /* support multiple SPDIFs; the secondary is set up as a slave */ |
| 1611 | nums = 0; | ||
| 1611 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | 1612 | for (i = 0; i < spec->autocfg.dig_outs; i++) { |
| 1612 | hda_nid_t conn[4]; | 1613 | hda_nid_t conn[4]; |
| 1613 | err = snd_hda_get_connections(codec, | 1614 | err = snd_hda_get_connections(codec, |
| 1614 | spec->autocfg.dig_out_pins[i], | 1615 | spec->autocfg.dig_out_pins[i], |
| 1615 | conn, ARRAY_SIZE(conn)); | 1616 | conn, ARRAY_SIZE(conn)); |
| 1616 | if (err < 0) | 1617 | if (err <= 0) |
| 1617 | continue; | 1618 | continue; |
| 1618 | dig_nid = conn[0]; /* assume the first element is audio-out */ | 1619 | dig_nid = conn[0]; /* assume the first element is audio-out */ |
| 1619 | if (!i) { | 1620 | if (!nums) { |
| 1620 | spec->multiout.dig_out_nid = dig_nid; | 1621 | spec->multiout.dig_out_nid = dig_nid; |
| 1621 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | 1622 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; |
| 1622 | } else { | 1623 | } else { |
| 1623 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | 1624 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; |
| 1624 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | 1625 | if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) |
| 1625 | break; | 1626 | break; |
| 1626 | spec->slave_dig_outs[i - 1] = dig_nid; | 1627 | spec->slave_dig_outs[nums - 1] = dig_nid; |
| 1627 | } | 1628 | } |
| 1629 | nums++; | ||
| 1628 | } | 1630 | } |
| 1629 | 1631 | ||
| 1630 | if (spec->autocfg.dig_in_pin) { | 1632 | if (spec->autocfg.dig_in_pin) { |
| @@ -2270,6 +2272,7 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
| 2270 | struct alc_spec *spec = codec->spec; | 2272 | struct alc_spec *spec = codec->spec; |
| 2271 | struct hda_pcm *info = spec->pcm_rec; | 2273 | struct hda_pcm *info = spec->pcm_rec; |
| 2272 | const struct hda_pcm_stream *p; | 2274 | const struct hda_pcm_stream *p; |
| 2275 | bool have_multi_adcs; | ||
| 2273 | int i; | 2276 | int i; |
| 2274 | 2277 | ||
| 2275 | codec->num_pcms = 1; | 2278 | codec->num_pcms = 1; |
| @@ -2348,8 +2351,11 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
| 2348 | /* If the use of more than one ADC is requested for the current | 2351 | /* If the use of more than one ADC is requested for the current |
| 2349 | * model, configure a second analog capture-only PCM. | 2352 | * model, configure a second analog capture-only PCM. |
| 2350 | */ | 2353 | */ |
| 2354 | have_multi_adcs = (spec->num_adc_nids > 1) && | ||
| 2355 | !spec->dyn_adc_switch && !spec->auto_mic && | ||
| 2356 | (!spec->input_mux || spec->input_mux->num_items > 1); | ||
| 2351 | /* Additional Analaog capture for index #2 */ | 2357 | /* Additional Analaog capture for index #2 */ |
| 2352 | if (spec->alt_dac_nid || spec->num_adc_nids > 1) { | 2358 | if (spec->alt_dac_nid || have_multi_adcs) { |
| 2353 | codec->num_pcms = 3; | 2359 | codec->num_pcms = 3; |
| 2354 | info = spec->pcm_rec + 2; | 2360 | info = spec->pcm_rec + 2; |
| 2355 | info->name = spec->stream_name_analog; | 2361 | info->name = spec->stream_name_analog; |
| @@ -2365,7 +2371,7 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
| 2365 | alc_pcm_null_stream; | 2371 | alc_pcm_null_stream; |
| 2366 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; | 2372 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; |
| 2367 | } | 2373 | } |
| 2368 | if (spec->num_adc_nids > 1) { | 2374 | if (have_multi_adcs) { |
| 2369 | p = spec->stream_analog_alt_capture; | 2375 | p = spec->stream_analog_alt_capture; |
| 2370 | if (!p) | 2376 | if (!p) |
| 2371 | p = &alc_pcm_analog_alt_capture; | 2377 | p = &alc_pcm_analog_alt_capture; |
| @@ -2657,7 +2663,6 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) | |||
| 2657 | hda_nid_t *adc_nids = spec->private_adc_nids; | 2663 | hda_nid_t *adc_nids = spec->private_adc_nids; |
| 2658 | hda_nid_t *cap_nids = spec->private_capsrc_nids; | 2664 | hda_nid_t *cap_nids = spec->private_capsrc_nids; |
| 2659 | int max_nums = ARRAY_SIZE(spec->private_adc_nids); | 2665 | int max_nums = ARRAY_SIZE(spec->private_adc_nids); |
| 2660 | bool indep_capsrc = false; | ||
| 2661 | int i, nums = 0; | 2666 | int i, nums = 0; |
| 2662 | 2667 | ||
| 2663 | nid = codec->start_nid; | 2668 | nid = codec->start_nid; |
| @@ -2679,13 +2684,11 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) | |||
| 2679 | break; | 2684 | break; |
| 2680 | if (type == AC_WID_AUD_SEL) { | 2685 | if (type == AC_WID_AUD_SEL) { |
| 2681 | cap_nids[nums] = src; | 2686 | cap_nids[nums] = src; |
| 2682 | indep_capsrc = true; | ||
| 2683 | break; | 2687 | break; |
| 2684 | } | 2688 | } |
| 2685 | n = snd_hda_get_conn_list(codec, src, &list); | 2689 | n = snd_hda_get_conn_list(codec, src, &list); |
| 2686 | if (n > 1) { | 2690 | if (n > 1) { |
| 2687 | cap_nids[nums] = src; | 2691 | cap_nids[nums] = src; |
| 2688 | indep_capsrc = true; | ||
| 2689 | break; | 2692 | break; |
| 2690 | } else if (n != 1) | 2693 | } else if (n != 1) |
| 2691 | break; | 2694 | break; |
| @@ -3326,6 +3329,12 @@ static void alc_auto_set_output_and_unmute(struct hda_codec *codec, | |||
| 3326 | if (nid) | 3329 | if (nid) |
| 3327 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 3330 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
| 3328 | AMP_OUT_ZERO); | 3331 | AMP_OUT_ZERO); |
| 3332 | |||
| 3333 | /* unmute DAC if it's not assigned to a mixer */ | ||
| 3334 | nid = alc_look_for_out_mute_nid(codec, pin, dac); | ||
| 3335 | if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT)) | ||
| 3336 | snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
| 3337 | AMP_OUT_ZERO); | ||
| 3329 | } | 3338 | } |
| 3330 | 3339 | ||
| 3331 | static void alc_auto_init_multi_out(struct hda_codec *codec) | 3340 | static void alc_auto_init_multi_out(struct hda_codec *codec) |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 59a52a430f24..de4c36027cbe 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -3791,9 +3791,10 @@ static int is_dual_headphones(struct hda_codec *codec) | |||
| 3791 | } | 3791 | } |
| 3792 | 3792 | ||
| 3793 | 3793 | ||
| 3794 | static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) | 3794 | static int stac92xx_parse_auto_config(struct hda_codec *codec) |
| 3795 | { | 3795 | { |
| 3796 | struct sigmatel_spec *spec = codec->spec; | 3796 | struct sigmatel_spec *spec = codec->spec; |
| 3797 | hda_nid_t dig_out = 0, dig_in = 0; | ||
| 3797 | int hp_swap = 0; | 3798 | int hp_swap = 0; |
| 3798 | int i, err; | 3799 | int i, err; |
| 3799 | 3800 | ||
| @@ -3976,6 +3977,22 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
| 3976 | if (spec->multiout.max_channels > 2) | 3977 | if (spec->multiout.max_channels > 2) |
| 3977 | spec->surr_switch = 1; | 3978 | spec->surr_switch = 1; |
| 3978 | 3979 | ||
| 3980 | /* find digital out and in converters */ | ||
| 3981 | for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) { | ||
| 3982 | unsigned int wid_caps = get_wcaps(codec, i); | ||
| 3983 | if (wid_caps & AC_WCAP_DIGITAL) { | ||
| 3984 | switch (get_wcaps_type(wid_caps)) { | ||
| 3985 | case AC_WID_AUD_OUT: | ||
| 3986 | if (!dig_out) | ||
| 3987 | dig_out = i; | ||
| 3988 | break; | ||
| 3989 | case AC_WID_AUD_IN: | ||
| 3990 | if (!dig_in) | ||
| 3991 | dig_in = i; | ||
| 3992 | break; | ||
| 3993 | } | ||
| 3994 | } | ||
| 3995 | } | ||
| 3979 | if (spec->autocfg.dig_outs) | 3996 | if (spec->autocfg.dig_outs) |
| 3980 | spec->multiout.dig_out_nid = dig_out; | 3997 | spec->multiout.dig_out_nid = dig_out; |
| 3981 | if (dig_in && spec->autocfg.dig_in_pin) | 3998 | if (dig_in && spec->autocfg.dig_in_pin) |
| @@ -5279,7 +5296,7 @@ static int patch_stac925x(struct hda_codec *codec) | |||
| 5279 | spec->capvols = stac925x_capvols; | 5296 | spec->capvols = stac925x_capvols; |
| 5280 | spec->capsws = stac925x_capsws; | 5297 | spec->capsws = stac925x_capsws; |
| 5281 | 5298 | ||
| 5282 | err = stac92xx_parse_auto_config(codec, 0x8, 0x7); | 5299 | err = stac92xx_parse_auto_config(codec); |
| 5283 | if (!err) { | 5300 | if (!err) { |
| 5284 | if (spec->board_config < 0) { | 5301 | if (spec->board_config < 0) { |
| 5285 | printk(KERN_WARNING "hda_codec: No auto-config is " | 5302 | printk(KERN_WARNING "hda_codec: No auto-config is " |
| @@ -5420,7 +5437,7 @@ again: | |||
| 5420 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); | 5437 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); |
| 5421 | spec->pwr_nids = stac92hd73xx_pwr_nids; | 5438 | spec->pwr_nids = stac92hd73xx_pwr_nids; |
| 5422 | 5439 | ||
| 5423 | err = stac92xx_parse_auto_config(codec, 0x25, 0x27); | 5440 | err = stac92xx_parse_auto_config(codec); |
| 5424 | 5441 | ||
| 5425 | if (!err) { | 5442 | if (!err) { |
| 5426 | if (spec->board_config < 0) { | 5443 | if (spec->board_config < 0) { |
| @@ -5629,26 +5646,8 @@ again: | |||
| 5629 | stac92xx_set_config_regs(codec, | 5646 | stac92xx_set_config_regs(codec, |
| 5630 | stac92hd83xxx_brd_tbl[spec->board_config]); | 5647 | stac92hd83xxx_brd_tbl[spec->board_config]); |
| 5631 | 5648 | ||
| 5632 | switch (codec->vendor_id) { | 5649 | if (spec->board_config != STAC_92HD83XXX_PWR_REF) |
| 5633 | case 0x111d76d1: | ||
| 5634 | case 0x111d76d9: | ||
| 5635 | case 0x111d76df: | ||
| 5636 | case 0x111d76e5: | ||
| 5637 | case 0x111d7666: | ||
| 5638 | case 0x111d7667: | ||
| 5639 | case 0x111d7668: | ||
| 5640 | case 0x111d7669: | ||
| 5641 | case 0x111d76e3: | ||
| 5642 | case 0x111d7604: | ||
| 5643 | case 0x111d76d4: | ||
| 5644 | case 0x111d7605: | ||
| 5645 | case 0x111d76d5: | ||
| 5646 | case 0x111d76e7: | ||
| 5647 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) | ||
| 5648 | break; | ||
| 5649 | spec->num_pwrs = 0; | 5650 | spec->num_pwrs = 0; |
| 5650 | break; | ||
| 5651 | } | ||
| 5652 | 5651 | ||
| 5653 | codec->patch_ops = stac92xx_patch_ops; | 5652 | codec->patch_ops = stac92xx_patch_ops; |
| 5654 | 5653 | ||
| @@ -5675,7 +5674,7 @@ again: | |||
| 5675 | } | 5674 | } |
| 5676 | #endif | 5675 | #endif |
| 5677 | 5676 | ||
| 5678 | err = stac92xx_parse_auto_config(codec, 0x1d, 0); | 5677 | err = stac92xx_parse_auto_config(codec); |
| 5679 | if (!err) { | 5678 | if (!err) { |
| 5680 | if (spec->board_config < 0) { | 5679 | if (spec->board_config < 0) { |
| 5681 | printk(KERN_WARNING "hda_codec: No auto-config is " | 5680 | printk(KERN_WARNING "hda_codec: No auto-config is " |
| @@ -5996,7 +5995,7 @@ again: | |||
| 5996 | 5995 | ||
| 5997 | spec->multiout.dac_nids = spec->dac_nids; | 5996 | spec->multiout.dac_nids = spec->dac_nids; |
| 5998 | 5997 | ||
| 5999 | err = stac92xx_parse_auto_config(codec, 0x21, 0); | 5998 | err = stac92xx_parse_auto_config(codec); |
| 6000 | if (!err) { | 5999 | if (!err) { |
| 6001 | if (spec->board_config < 0) { | 6000 | if (spec->board_config < 0) { |
| 6002 | printk(KERN_WARNING "hda_codec: No auto-config is " | 6001 | printk(KERN_WARNING "hda_codec: No auto-config is " |
| @@ -6105,7 +6104,7 @@ static int patch_stac922x(struct hda_codec *codec) | |||
| 6105 | 6104 | ||
| 6106 | spec->multiout.dac_nids = spec->dac_nids; | 6105 | spec->multiout.dac_nids = spec->dac_nids; |
| 6107 | 6106 | ||
| 6108 | err = stac92xx_parse_auto_config(codec, 0x08, 0x09); | 6107 | err = stac92xx_parse_auto_config(codec); |
| 6109 | if (!err) { | 6108 | if (!err) { |
| 6110 | if (spec->board_config < 0) { | 6109 | if (spec->board_config < 0) { |
| 6111 | printk(KERN_WARNING "hda_codec: No auto-config is " | 6110 | printk(KERN_WARNING "hda_codec: No auto-config is " |
| @@ -6230,7 +6229,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
| 6230 | spec->aloopback_shift = 0; | 6229 | spec->aloopback_shift = 0; |
| 6231 | spec->eapd_switch = 1; | 6230 | spec->eapd_switch = 1; |
| 6232 | 6231 | ||
| 6233 | err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); | 6232 | err = stac92xx_parse_auto_config(codec); |
| 6234 | if (!err) { | 6233 | if (!err) { |
| 6235 | if (spec->board_config < 0) { | 6234 | if (spec->board_config < 0) { |
| 6236 | printk(KERN_WARNING "hda_codec: No auto-config is " | 6235 | printk(KERN_WARNING "hda_codec: No auto-config is " |
| @@ -6355,7 +6354,7 @@ static int patch_stac9205(struct hda_codec *codec) | |||
| 6355 | break; | 6354 | break; |
| 6356 | } | 6355 | } |
| 6357 | 6356 | ||
| 6358 | err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); | 6357 | err = stac92xx_parse_auto_config(codec); |
| 6359 | if (!err) { | 6358 | if (!err) { |
| 6360 | if (spec->board_config < 0) { | 6359 | if (spec->board_config < 0) { |
| 6361 | printk(KERN_WARNING "hda_codec: No auto-config is " | 6360 | printk(KERN_WARNING "hda_codec: No auto-config is " |
| @@ -6460,7 +6459,7 @@ static int patch_stac9872(struct hda_codec *codec) | |||
| 6460 | spec->capvols = stac9872_capvols; | 6459 | spec->capvols = stac9872_capvols; |
| 6461 | spec->capsws = stac9872_capsws; | 6460 | spec->capsws = stac9872_capsws; |
| 6462 | 6461 | ||
| 6463 | err = stac92xx_parse_auto_config(codec, 0x10, 0x12); | 6462 | err = stac92xx_parse_auto_config(codec); |
| 6464 | if (err < 0) { | 6463 | if (err < 0) { |
| 6465 | stac92xx_free(codec); | 6464 | stac92xx_free(codec); |
| 6466 | return -EINVAL; | 6465 | return -EINVAL; |
| @@ -6565,6 +6564,18 @@ static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
| 6565 | { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, | 6564 | { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, |
| 6566 | { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, | 6565 | { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, |
| 6567 | { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, | 6566 | { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, |
| 6567 | { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx}, | ||
| 6568 | { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx}, | ||
| 6569 | { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx}, | ||
| 6570 | { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx}, | ||
| 6571 | { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx}, | ||
| 6572 | { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx}, | ||
| 6573 | { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx}, | ||
| 6574 | { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx}, | ||
| 6575 | { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx}, | ||
| 6576 | { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx}, | ||
| 6577 | { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx}, | ||
| 6578 | { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx}, | ||
| 6568 | {} /* terminator */ | 6579 | {} /* terminator */ |
| 6569 | }; | 6580 | }; |
| 6570 | 6581 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 417d62ad3b96..0b020a93a8ed 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
| @@ -3700,13 +3700,8 @@ static const struct hda_verb vt1812_init_verbs[] = { | |||
| 3700 | static void set_widgets_power_state_vt1812(struct hda_codec *codec) | 3700 | static void set_widgets_power_state_vt1812(struct hda_codec *codec) |
| 3701 | { | 3701 | { |
| 3702 | struct via_spec *spec = codec->spec; | 3702 | struct via_spec *spec = codec->spec; |
| 3703 | int imux_is_smixer = | ||
| 3704 | snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; | ||
| 3705 | unsigned int parm; | 3703 | unsigned int parm; |
| 3706 | unsigned int present; | 3704 | unsigned int present; |
| 3707 | /* MUX10 (1eh) = stereo mixer */ | ||
| 3708 | imux_is_smixer = | ||
| 3709 | snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; | ||
| 3710 | /* inputs */ | 3705 | /* inputs */ |
| 3711 | /* PW 5/6/7 (29h/2ah/2bh) */ | 3706 | /* PW 5/6/7 (29h/2ah/2bh) */ |
| 3712 | parm = AC_PWRST_D3; | 3707 | parm = AC_PWRST_D3; |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 6a5b387b97fd..45b2055f5a76 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
| @@ -42,6 +42,12 @@ | |||
| 42 | #include <asm/pgtable.h> | 42 | #include <asm/pgtable.h> |
| 43 | #include <asm/cacheflush.h> | 43 | #include <asm/cacheflush.h> |
| 44 | 44 | ||
| 45 | #ifdef CONFIG_KVM_GUEST | ||
| 46 | #include <linux/kvm_para.h> | ||
| 47 | #else | ||
| 48 | #define kvm_para_available() (0) | ||
| 49 | #endif | ||
| 50 | |||
| 45 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | 51 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
| 46 | MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455"); | 52 | MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455"); |
| 47 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
| @@ -77,6 +83,7 @@ static int buggy_semaphore; | |||
| 77 | static int buggy_irq = -1; /* auto-check */ | 83 | static int buggy_irq = -1; /* auto-check */ |
| 78 | static int xbox; | 84 | static int xbox; |
| 79 | static int spdif_aclink = -1; | 85 | static int spdif_aclink = -1; |
| 86 | static int inside_vm = -1; | ||
| 80 | 87 | ||
| 81 | module_param(index, int, 0444); | 88 | module_param(index, int, 0444); |
| 82 | MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); | 89 | MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); |
| @@ -94,6 +101,8 @@ module_param(xbox, bool, 0444); | |||
| 94 | MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); | 101 | MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); |
| 95 | module_param(spdif_aclink, int, 0444); | 102 | module_param(spdif_aclink, int, 0444); |
| 96 | MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); | 103 | MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); |
| 104 | module_param(inside_vm, bool, 0444); | ||
| 105 | MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization."); | ||
| 97 | 106 | ||
| 98 | /* just for backward compatibility */ | 107 | /* just for backward compatibility */ |
| 99 | static int enable; | 108 | static int enable; |
| @@ -400,6 +409,7 @@ struct intel8x0 { | |||
| 400 | unsigned buggy_irq: 1; /* workaround for buggy mobos */ | 409 | unsigned buggy_irq: 1; /* workaround for buggy mobos */ |
| 401 | unsigned xbox: 1; /* workaround for Xbox AC'97 detection */ | 410 | unsigned xbox: 1; /* workaround for Xbox AC'97 detection */ |
| 402 | unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */ | 411 | unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */ |
| 412 | unsigned inside_vm: 1; /* enable VM optimization */ | ||
| 403 | 413 | ||
| 404 | int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ | 414 | int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ |
| 405 | unsigned int sdm_saved; /* SDM reg value */ | 415 | unsigned int sdm_saved; /* SDM reg value */ |
| @@ -1065,8 +1075,11 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs | |||
| 1065 | udelay(10); | 1075 | udelay(10); |
| 1066 | continue; | 1076 | continue; |
| 1067 | } | 1077 | } |
| 1068 | if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && | 1078 | if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) |
| 1069 | ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | 1079 | continue; |
| 1080 | if (chip->inside_vm) | ||
| 1081 | break; | ||
| 1082 | if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | ||
| 1070 | break; | 1083 | break; |
| 1071 | } while (timeout--); | 1084 | } while (timeout--); |
| 1072 | ptr = ichdev->last_pos; | 1085 | ptr = ichdev->last_pos; |
| @@ -2984,6 +2997,10 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, | |||
| 2984 | if (xbox) | 2997 | if (xbox) |
| 2985 | chip->xbox = 1; | 2998 | chip->xbox = 1; |
| 2986 | 2999 | ||
| 3000 | chip->inside_vm = inside_vm; | ||
| 3001 | if (inside_vm) | ||
| 3002 | printk(KERN_INFO "intel8x0: enable KVM optimization\n"); | ||
| 3003 | |||
| 2987 | if (pci->vendor == PCI_VENDOR_ID_INTEL && | 3004 | if (pci->vendor == PCI_VENDOR_ID_INTEL && |
| 2988 | pci->device == PCI_DEVICE_ID_INTEL_440MX) | 3005 | pci->device == PCI_DEVICE_ID_INTEL_440MX) |
| 2989 | chip->fix_nocache = 1; /* enable workaround */ | 3006 | chip->fix_nocache = 1; /* enable workaround */ |
| @@ -3226,6 +3243,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | |||
| 3226 | buggy_irq = 0; | 3243 | buggy_irq = 0; |
| 3227 | } | 3244 | } |
| 3228 | 3245 | ||
| 3246 | if (inside_vm < 0) { | ||
| 3247 | /* detect KVM and Parallels virtual environments */ | ||
| 3248 | inside_vm = kvm_para_available(); | ||
| 3249 | #if defined(__i386__) || defined(__x86_64__) | ||
| 3250 | inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
| 3251 | #endif | ||
| 3252 | } | ||
| 3253 | |||
| 3229 | if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, | 3254 | if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, |
| 3230 | &chip)) < 0) { | 3255 | &chip)) < 0) { |
| 3231 | snd_card_free(card); | 3256 | snd_card_free(card); |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 1c6d1e1c27c1..f74220292254 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
| @@ -151,7 +151,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); | |||
| 151 | #define HDSP_PROGRAM 0x020 | 151 | #define HDSP_PROGRAM 0x020 |
| 152 | #define HDSP_CONFIG_MODE_0 0x040 | 152 | #define HDSP_CONFIG_MODE_0 0x040 |
| 153 | #define HDSP_CONFIG_MODE_1 0x080 | 153 | #define HDSP_CONFIG_MODE_1 0x080 |
| 154 | #define HDSP_VERSION_BIT 0x100 | 154 | #define HDSP_VERSION_BIT (0x100 | HDSP_S_LOAD) |
| 155 | #define HDSP_BIGENDIAN_MODE 0x200 | 155 | #define HDSP_BIGENDIAN_MODE 0x200 |
| 156 | #define HDSP_RD_MULTIPLE 0x400 | 156 | #define HDSP_RD_MULTIPLE 0x400 |
| 157 | #define HDSP_9652_ENABLE_MIXER 0x800 | 157 | #define HDSP_9652_ENABLE_MIXER 0x800 |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 6e2f7ef7ddb1..15a6c3b9bc9a 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
| @@ -520,16 +520,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
| 520 | #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) | 520 | #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) |
| 521 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) | 521 | #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) |
| 522 | 522 | ||
| 523 | /* revisions >= 230 indicate AES32 card */ | ||
| 524 | #define HDSPM_MADI_ANCIENT_REV 204 | ||
| 525 | #define HDSPM_MADI_OLD_REV 207 | ||
| 526 | #define HDSPM_MADI_REV 210 | ||
| 527 | #define HDSPM_RAYDAT_REV 211 | 523 | #define HDSPM_RAYDAT_REV 211 |
| 528 | #define HDSPM_AIO_REV 212 | 524 | #define HDSPM_AIO_REV 212 |
| 529 | #define HDSPM_MADIFACE_REV 213 | 525 | #define HDSPM_MADIFACE_REV 213 |
| 530 | #define HDSPM_AES_REV 240 | ||
| 531 | #define HDSPM_AES32_REV 234 | ||
| 532 | #define HDSPM_AES32_OLD_REV 233 | ||
| 533 | 526 | ||
| 534 | /* speed factor modes */ | 527 | /* speed factor modes */ |
| 535 | #define HDSPM_SPEED_SINGLE 0 | 528 | #define HDSPM_SPEED_SINGLE 0 |
| @@ -6253,7 +6246,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, | |||
| 6253 | status.card_specific.madi.madi_input = | 6246 | status.card_specific.madi.madi_input = |
| 6254 | (statusregister & HDSPM_AB_int) ? 1 : 0; | 6247 | (statusregister & HDSPM_AB_int) ? 1 : 0; |
| 6255 | status.card_specific.madi.channel_format = | 6248 | status.card_specific.madi.channel_format = |
| 6256 | (statusregister & HDSPM_TX_64ch) ? 1 : 0; | 6249 | (statusregister & HDSPM_RX_64ch) ? 1 : 0; |
| 6257 | /* TODO: Mac driver sets it when f_s>48kHz */ | 6250 | /* TODO: Mac driver sets it when f_s>48kHz */ |
| 6258 | status.card_specific.madi.frame_format = 0; | 6251 | status.card_specific.madi.frame_format = 0; |
| 6259 | 6252 | ||
| @@ -6503,13 +6496,6 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
| 6503 | strcpy(card->driver, "HDSPM"); | 6496 | strcpy(card->driver, "HDSPM"); |
| 6504 | 6497 | ||
| 6505 | switch (hdspm->firmware_rev) { | 6498 | switch (hdspm->firmware_rev) { |
| 6506 | case HDSPM_MADI_REV: | ||
| 6507 | case HDSPM_MADI_OLD_REV: | ||
| 6508 | case HDSPM_MADI_ANCIENT_REV: | ||
| 6509 | hdspm->io_type = MADI; | ||
| 6510 | hdspm->card_name = "RME MADI"; | ||
| 6511 | hdspm->midiPorts = 3; | ||
| 6512 | break; | ||
| 6513 | case HDSPM_RAYDAT_REV: | 6499 | case HDSPM_RAYDAT_REV: |
| 6514 | hdspm->io_type = RayDAT; | 6500 | hdspm->io_type = RayDAT; |
| 6515 | hdspm->card_name = "RME RayDAT"; | 6501 | hdspm->card_name = "RME RayDAT"; |
| @@ -6525,17 +6511,25 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
| 6525 | hdspm->card_name = "RME MADIface"; | 6511 | hdspm->card_name = "RME MADIface"; |
| 6526 | hdspm->midiPorts = 1; | 6512 | hdspm->midiPorts = 1; |
| 6527 | break; | 6513 | break; |
| 6528 | case HDSPM_AES_REV: | ||
| 6529 | case HDSPM_AES32_REV: | ||
| 6530 | case HDSPM_AES32_OLD_REV: | ||
| 6531 | hdspm->io_type = AES32; | ||
| 6532 | hdspm->card_name = "RME AES32"; | ||
| 6533 | hdspm->midiPorts = 2; | ||
| 6534 | break; | ||
| 6535 | default: | 6514 | default: |
| 6536 | snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n", | 6515 | if ((hdspm->firmware_rev == 0xf0) || |
| 6516 | ((hdspm->firmware_rev >= 0xe6) && | ||
| 6517 | (hdspm->firmware_rev <= 0xea))) { | ||
| 6518 | hdspm->io_type = AES32; | ||
| 6519 | hdspm->card_name = "RME AES32"; | ||
| 6520 | hdspm->midiPorts = 2; | ||
| 6521 | } else if ((hdspm->firmware_rev == 0xd5) || | ||
| 6522 | ((hdspm->firmware_rev >= 0xc8) && | ||
| 6523 | (hdspm->firmware_rev <= 0xcf))) { | ||
| 6524 | hdspm->io_type = MADI; | ||
| 6525 | hdspm->card_name = "RME MADI"; | ||
| 6526 | hdspm->midiPorts = 3; | ||
| 6527 | } else { | ||
| 6528 | snd_printk(KERN_ERR | ||
| 6529 | "HDSPM: unknown firmware revision %x\n", | ||
| 6537 | hdspm->firmware_rev); | 6530 | hdspm->firmware_rev); |
| 6538 | return -ENODEV; | 6531 | return -ENODEV; |
| 6532 | } | ||
| 6539 | } | 6533 | } |
| 6540 | 6534 | ||
| 6541 | err = pci_enable_device(pci); | 6535 | err = pci_enable_device(pci); |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index ab27dbcd1262..336de8f69a02 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
| @@ -430,6 +430,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 430 | iface_reg |= TLV320AIC23_MS_MASTER; | 430 | iface_reg |= TLV320AIC23_MS_MASTER; |
| 431 | break; | 431 | break; |
| 432 | case SND_SOC_DAIFMT_CBS_CFS: | 432 | case SND_SOC_DAIFMT_CBS_CFS: |
| 433 | iface_reg &= ~TLV320AIC23_MS_MASTER; | ||
| 433 | break; | 434 | break; |
| 434 | default: | 435 | default: |
| 435 | return -EINVAL; | 436 | return -EINVAL; |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 7a49390bc30d..87d5ef188e29 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
| @@ -1023,6 +1023,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 1023 | break; | 1023 | break; |
| 1024 | case SND_SOC_DAIFMT_CBS_CFS: | 1024 | case SND_SOC_DAIFMT_CBS_CFS: |
| 1025 | aic3x->master = 0; | 1025 | aic3x->master = 0; |
| 1026 | iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER); | ||
| 1026 | break; | 1027 | break; |
| 1027 | default: | 1028 | default: |
| 1028 | return -EINVAL; | 1029 | return -EINVAL; |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 5d88c99aaea6..42d9039a49e9 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
| @@ -2361,13 +2361,17 @@ static int wm5100_gpio_direction_out(struct gpio_chip *chip, | |||
| 2361 | { | 2361 | { |
| 2362 | struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); | 2362 | struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); |
| 2363 | struct snd_soc_codec *codec = wm5100->codec; | 2363 | struct snd_soc_codec *codec = wm5100->codec; |
| 2364 | int val; | 2364 | int val, ret; |
| 2365 | 2365 | ||
| 2366 | val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT); | 2366 | val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT); |
| 2367 | 2367 | ||
| 2368 | return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, | 2368 | ret = snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, |
| 2369 | WM5100_GP1_FN_MASK | WM5100_GP1_DIR | | 2369 | WM5100_GP1_FN_MASK | WM5100_GP1_DIR | |
| 2370 | WM5100_GP1_LVL, val); | 2370 | WM5100_GP1_LVL, val); |
| 2371 | if (ret < 0) | ||
| 2372 | return ret; | ||
| 2373 | else | ||
| 2374 | return 0; | ||
| 2371 | } | 2375 | } |
| 2372 | 2376 | ||
| 2373 | static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset) | 2377 | static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset) |
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 8d0347cf0e9a..076bdb9930a1 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c | |||
| @@ -151,7 +151,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream, | |||
| 151 | { | 151 | { |
| 152 | struct snd_soc_codec *codec = dai->codec; | 152 | struct snd_soc_codec *codec = dai->codec; |
| 153 | struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); | 153 | struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); |
| 154 | u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc; | 154 | u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfff3; |
| 155 | int i = get_coeff(wm8711->sysclk, params_rate(params)); | 155 | int i = get_coeff(wm8711->sysclk, params_rate(params)); |
| 156 | u16 srate = (coeff_div[i].sr << 2) | | 156 | u16 srate = (coeff_div[i].sr << 2) | |
| 157 | (coeff_div[i].bosr << 1) | coeff_div[i].usb; | 157 | (coeff_div[i].bosr << 1) | coeff_div[i].usb; |
| @@ -232,7 +232,7 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 232 | unsigned int fmt) | 232 | unsigned int fmt) |
| 233 | { | 233 | { |
| 234 | struct snd_soc_codec *codec = codec_dai->codec; | 234 | struct snd_soc_codec *codec = codec_dai->codec; |
| 235 | u16 iface = 0; | 235 | u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0x000c; |
| 236 | 236 | ||
| 237 | /* set master/slave audio interface */ | 237 | /* set master/slave audio interface */ |
| 238 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 238 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 9fc8f4c0a9a9..285ef87e6704 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
| @@ -867,7 +867,7 @@ SOC_ENUM("Right Capture Mode", rin_mode), | |||
| 867 | SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0, | 867 | SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0, |
| 868 | WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0), | 868 | WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0), |
| 869 | SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0, | 869 | SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0, |
| 870 | WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0), | 870 | WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 1), |
| 871 | 871 | ||
| 872 | SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), | 872 | SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), |
| 873 | SOC_ENUM("High Pass Filter Mode", hpf_mode), | 873 | SOC_ENUM("High Pass Filter Mode", hpf_mode), |
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index dc5cb3150857..de9ec9b8b7d9 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
| @@ -621,7 +621,7 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
| 621 | 621 | ||
| 622 | switch (div_id) { | 622 | switch (div_id) { |
| 623 | case WM8940_BCLKDIV: | 623 | case WM8940_BCLKDIV: |
| 624 | reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFEF3; | 624 | reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3; |
| 625 | ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2)); | 625 | ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2)); |
| 626 | break; | 626 | break; |
| 627 | case WM8940_MCLKDIV: | 627 | case WM8940_MCLKDIV: |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index f60dfa16545e..91d3c6dbeba3 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
| @@ -1961,7 +1961,13 @@ static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int re | |||
| 1961 | 1961 | ||
| 1962 | static int wm8962_reset(struct snd_soc_codec *codec) | 1962 | static int wm8962_reset(struct snd_soc_codec *codec) |
| 1963 | { | 1963 | { |
| 1964 | return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); | 1964 | int ret; |
| 1965 | |||
| 1966 | ret = snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); | ||
| 1967 | if (ret != 0) | ||
| 1968 | return ret; | ||
| 1969 | |||
| 1970 | return snd_soc_write(codec, WM8962_PLL_SOFTWARE_RESET, 0); | ||
| 1965 | } | 1971 | } |
| 1966 | 1972 | ||
| 1967 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); | 1973 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); |
| @@ -2360,15 +2366,14 @@ static int sysclk_event(struct snd_soc_dapm_widget *w, | |||
| 2360 | 2366 | ||
| 2361 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, | 2367 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, |
| 2362 | WM8962_FLL_ENA, WM8962_FLL_ENA); | 2368 | WM8962_FLL_ENA, WM8962_FLL_ENA); |
| 2363 | if (wm8962->irq) { | 2369 | |
| 2364 | timeout = msecs_to_jiffies(5); | 2370 | timeout = msecs_to_jiffies(5); |
| 2365 | timeout = wait_for_completion_timeout(&wm8962->fll_lock, | 2371 | timeout = wait_for_completion_timeout(&wm8962->fll_lock, |
| 2366 | timeout); | 2372 | timeout); |
| 2367 | 2373 | ||
| 2368 | if (timeout == 0) | 2374 | if (wm8962->irq && timeout == 0) |
| 2369 | dev_err(codec->dev, | 2375 | dev_err(codec->dev, |
| 2370 | "Timed out starting FLL\n"); | 2376 | "Timed out starting FLL\n"); |
| 2371 | } | ||
| 2372 | } | 2377 | } |
| 2373 | break; | 2378 | break; |
| 2374 | 2379 | ||
| @@ -4029,6 +4034,11 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
| 4029 | snd_soc_update_bits(codec, WM8962_CLOCKING2, | 4034 | snd_soc_update_bits(codec, WM8962_CLOCKING2, |
| 4030 | WM8962_CLKREG_OVD, WM8962_CLKREG_OVD); | 4035 | WM8962_CLKREG_OVD, WM8962_CLKREG_OVD); |
| 4031 | 4036 | ||
| 4037 | /* Ensure that the oscillator and PLLs are disabled */ | ||
| 4038 | snd_soc_update_bits(codec, WM8962_PLL2, | ||
| 4039 | WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, | ||
| 4040 | 0); | ||
| 4041 | |||
| 4032 | regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); | 4042 | regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); |
| 4033 | 4043 | ||
| 4034 | if (pdata) { | 4044 | if (pdata) { |
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index b5e922f469d5..bad91b4584f9 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
| @@ -271,7 +271,10 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, | |||
| 271 | 271 | ||
| 272 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 272 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
| 273 | 273 | ||
| 274 | s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); | 274 | if (!dma_data->ops) |
| 275 | dma_data->ops = samsung_dma_get_ops(); | ||
| 276 | |||
| 277 | dma_data->ops->started(dma_data->channel); | ||
| 275 | 278 | ||
| 276 | return 0; | 279 | return 0; |
| 277 | } | 280 | } |
| @@ -317,7 +320,10 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, | |||
| 317 | 320 | ||
| 318 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 321 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
| 319 | 322 | ||
| 320 | s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); | 323 | if (!dma_data->ops) |
| 324 | dma_data->ops = samsung_dma_get_ops(); | ||
| 325 | |||
| 326 | dma_data->ops->started(dma_data->channel); | ||
| 321 | 327 | ||
| 322 | return 0; | 328 | return 0; |
| 323 | } | 329 | } |
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index 9465588b02f2..2d622b635e68 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c | |||
| @@ -54,7 +54,6 @@ struct runtime_data { | |||
| 54 | spinlock_t lock; | 54 | spinlock_t lock; |
| 55 | int state; | 55 | int state; |
| 56 | unsigned int dma_loaded; | 56 | unsigned int dma_loaded; |
| 57 | unsigned int dma_limit; | ||
| 58 | unsigned int dma_period; | 57 | unsigned int dma_period; |
| 59 | dma_addr_t dma_start; | 58 | dma_addr_t dma_start; |
| 60 | dma_addr_t dma_pos; | 59 | dma_addr_t dma_pos; |
| @@ -62,77 +61,79 @@ struct runtime_data { | |||
| 62 | struct s3c_dma_params *params; | 61 | struct s3c_dma_params *params; |
| 63 | }; | 62 | }; |
| 64 | 63 | ||
| 64 | static void audio_buffdone(void *data); | ||
| 65 | |||
| 65 | /* dma_enqueue | 66 | /* dma_enqueue |
| 66 | * | 67 | * |
| 67 | * place a dma buffer onto the queue for the dma system | 68 | * place a dma buffer onto the queue for the dma system |
| 68 | * to handle. | 69 | * to handle. |
| 69 | */ | 70 | */ |
| 70 | static void dma_enqueue(struct snd_pcm_substream *substream) | 71 | static void dma_enqueue(struct snd_pcm_substream *substream) |
| 71 | { | 72 | { |
| 72 | struct runtime_data *prtd = substream->runtime->private_data; | 73 | struct runtime_data *prtd = substream->runtime->private_data; |
| 73 | dma_addr_t pos = prtd->dma_pos; | 74 | dma_addr_t pos = prtd->dma_pos; |
| 74 | unsigned int limit; | 75 | unsigned int limit; |
| 75 | int ret; | 76 | struct samsung_dma_prep_info dma_info; |
| 76 | 77 | ||
| 77 | pr_debug("Entered %s\n", __func__); | 78 | pr_debug("Entered %s\n", __func__); |
| 78 | 79 | ||
| 79 | if (s3c_dma_has_circular()) | 80 | limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; |
| 80 | limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; | ||
| 81 | else | ||
| 82 | limit = prtd->dma_limit; | ||
| 83 | 81 | ||
| 84 | pr_debug("%s: loaded %d, limit %d\n", | 82 | pr_debug("%s: loaded %d, limit %d\n", |
| 85 | __func__, prtd->dma_loaded, limit); | 83 | __func__, prtd->dma_loaded, limit); |
| 86 | 84 | ||
| 87 | while (prtd->dma_loaded < limit) { | 85 | dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); |
| 88 | unsigned long len = prtd->dma_period; | 86 | dma_info.direction = |
| 87 | (substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
| 88 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 89 | dma_info.fp = audio_buffdone; | ||
| 90 | dma_info.fp_param = substream; | ||
| 91 | dma_info.period = prtd->dma_period; | ||
| 92 | dma_info.len = prtd->dma_period*limit; | ||
| 89 | 93 | ||
| 94 | while (prtd->dma_loaded < limit) { | ||
| 90 | pr_debug("dma_loaded: %d\n", prtd->dma_loaded); | 95 | pr_debug("dma_loaded: %d\n", prtd->dma_loaded); |
| 91 | 96 | ||
| 92 | if ((pos + len) > prtd->dma_end) { | 97 | if ((pos + dma_info.period) > prtd->dma_end) { |
| 93 | len = prtd->dma_end - pos; | 98 | dma_info.period = prtd->dma_end - pos; |
| 94 | pr_debug("%s: corrected dma len %ld\n", __func__, len); | 99 | pr_debug("%s: corrected dma len %ld\n", |
| 100 | __func__, dma_info.period); | ||
| 95 | } | 101 | } |
| 96 | 102 | ||
| 97 | ret = s3c2410_dma_enqueue(prtd->params->channel, | 103 | dma_info.buf = pos; |
| 98 | substream, pos, len); | 104 | prtd->params->ops->prepare(prtd->params->ch, &dma_info); |
| 99 | 105 | ||
| 100 | if (ret == 0) { | 106 | prtd->dma_loaded++; |
| 101 | prtd->dma_loaded++; | 107 | pos += prtd->dma_period; |
| 102 | pos += prtd->dma_period; | 108 | if (pos >= prtd->dma_end) |
| 103 | if (pos >= prtd->dma_end) | 109 | pos = prtd->dma_start; |
| 104 | pos = prtd->dma_start; | ||
| 105 | } else | ||
| 106 | break; | ||
| 107 | } | 110 | } |
| 108 | 111 | ||
| 109 | prtd->dma_pos = pos; | 112 | prtd->dma_pos = pos; |
| 110 | } | 113 | } |
| 111 | 114 | ||
| 112 | static void audio_buffdone(struct s3c2410_dma_chan *channel, | 115 | static void audio_buffdone(void *data) |
| 113 | void *dev_id, int size, | ||
| 114 | enum s3c2410_dma_buffresult result) | ||
| 115 | { | 116 | { |
| 116 | struct snd_pcm_substream *substream = dev_id; | 117 | struct snd_pcm_substream *substream = data; |
| 117 | struct runtime_data *prtd; | 118 | struct runtime_data *prtd = substream->runtime->private_data; |
| 118 | 119 | ||
| 119 | pr_debug("Entered %s\n", __func__); | 120 | pr_debug("Entered %s\n", __func__); |
| 120 | 121 | ||
| 121 | if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) | 122 | if (prtd->state & ST_RUNNING) { |
| 122 | return; | 123 | prtd->dma_pos += prtd->dma_period; |
| 123 | 124 | if (prtd->dma_pos >= prtd->dma_end) | |
| 124 | prtd = substream->runtime->private_data; | 125 | prtd->dma_pos = prtd->dma_start; |
| 125 | 126 | ||
| 126 | if (substream) | 127 | if (substream) |
| 127 | snd_pcm_period_elapsed(substream); | 128 | snd_pcm_period_elapsed(substream); |
| 128 | 129 | ||
| 129 | spin_lock(&prtd->lock); | 130 | spin_lock(&prtd->lock); |
| 130 | if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { | 131 | if (!samsung_dma_has_circular()) { |
| 131 | prtd->dma_loaded--; | 132 | prtd->dma_loaded--; |
| 132 | dma_enqueue(substream); | 133 | dma_enqueue(substream); |
| 134 | } | ||
| 135 | spin_unlock(&prtd->lock); | ||
| 133 | } | 136 | } |
| 134 | |||
| 135 | spin_unlock(&prtd->lock); | ||
| 136 | } | 137 | } |
| 137 | 138 | ||
| 138 | static int dma_hw_params(struct snd_pcm_substream *substream, | 139 | static int dma_hw_params(struct snd_pcm_substream *substream, |
| @@ -144,8 +145,7 @@ static int dma_hw_params(struct snd_pcm_substream *substream, | |||
| 144 | unsigned long totbytes = params_buffer_bytes(params); | 145 | unsigned long totbytes = params_buffer_bytes(params); |
| 145 | struct s3c_dma_params *dma = | 146 | struct s3c_dma_params *dma = |
| 146 | snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 147 | snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
| 147 | int ret = 0; | 148 | struct samsung_dma_info dma_info; |
| 148 | |||
| 149 | 149 | ||
| 150 | pr_debug("Entered %s\n", __func__); | 150 | pr_debug("Entered %s\n", __func__); |
| 151 | 151 | ||
| @@ -163,30 +163,26 @@ static int dma_hw_params(struct snd_pcm_substream *substream, | |||
| 163 | pr_debug("params %p, client %p, channel %d\n", prtd->params, | 163 | pr_debug("params %p, client %p, channel %d\n", prtd->params, |
| 164 | prtd->params->client, prtd->params->channel); | 164 | prtd->params->client, prtd->params->channel); |
| 165 | 165 | ||
| 166 | ret = s3c2410_dma_request(prtd->params->channel, | 166 | prtd->params->ops = samsung_dma_get_ops(); |
| 167 | prtd->params->client, NULL); | 167 | |
| 168 | 168 | dma_info.cap = (samsung_dma_has_circular() ? | |
| 169 | if (ret < 0) { | 169 | DMA_CYCLIC : DMA_SLAVE); |
| 170 | printk(KERN_ERR "failed to get dma channel\n"); | 170 | dma_info.client = prtd->params->client; |
| 171 | return ret; | 171 | dma_info.direction = |
| 172 | } | 172 | (substream->stream == SNDRV_PCM_STREAM_PLAYBACK |
| 173 | 173 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | |
| 174 | /* use the circular buffering if we have it available. */ | 174 | dma_info.width = prtd->params->dma_size; |
| 175 | if (s3c_dma_has_circular()) | 175 | dma_info.fifo = prtd->params->dma_addr; |
| 176 | s3c2410_dma_setflags(prtd->params->channel, | 176 | prtd->params->ch = prtd->params->ops->request( |
| 177 | S3C2410_DMAF_CIRCULAR); | 177 | prtd->params->channel, &dma_info); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | s3c2410_dma_set_buffdone_fn(prtd->params->channel, | ||
| 181 | audio_buffdone); | ||
| 182 | |||
| 183 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 180 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
| 184 | 181 | ||
| 185 | runtime->dma_bytes = totbytes; | 182 | runtime->dma_bytes = totbytes; |
| 186 | 183 | ||
| 187 | spin_lock_irq(&prtd->lock); | 184 | spin_lock_irq(&prtd->lock); |
| 188 | prtd->dma_loaded = 0; | 185 | prtd->dma_loaded = 0; |
| 189 | prtd->dma_limit = runtime->hw.periods_min; | ||
| 190 | prtd->dma_period = params_period_bytes(params); | 186 | prtd->dma_period = params_period_bytes(params); |
| 191 | prtd->dma_start = runtime->dma_addr; | 187 | prtd->dma_start = runtime->dma_addr; |
| 192 | prtd->dma_pos = prtd->dma_start; | 188 | prtd->dma_pos = prtd->dma_start; |
| @@ -202,11 +198,12 @@ static int dma_hw_free(struct snd_pcm_substream *substream) | |||
| 202 | 198 | ||
| 203 | pr_debug("Entered %s\n", __func__); | 199 | pr_debug("Entered %s\n", __func__); |
| 204 | 200 | ||
| 205 | /* TODO - do we need to ensure DMA flushed */ | ||
| 206 | snd_pcm_set_runtime_buffer(substream, NULL); | 201 | snd_pcm_set_runtime_buffer(substream, NULL); |
| 207 | 202 | ||
| 208 | if (prtd->params) { | 203 | if (prtd->params) { |
| 209 | s3c2410_dma_free(prtd->params->channel, prtd->params->client); | 204 | prtd->params->ops->flush(prtd->params->ch); |
| 205 | prtd->params->ops->release(prtd->params->ch, | ||
| 206 | prtd->params->client); | ||
| 210 | prtd->params = NULL; | 207 | prtd->params = NULL; |
| 211 | } | 208 | } |
| 212 | 209 | ||
| @@ -225,23 +222,9 @@ static int dma_prepare(struct snd_pcm_substream *substream) | |||
| 225 | if (!prtd->params) | 222 | if (!prtd->params) |
| 226 | return 0; | 223 | return 0; |
| 227 | 224 | ||
| 228 | /* channel needs configuring for mem=>device, increment memory addr, | ||
| 229 | * sync to pclk, half-word transfers to the IIS-FIFO. */ | ||
| 230 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 231 | s3c2410_dma_devconfig(prtd->params->channel, | ||
| 232 | S3C2410_DMASRC_MEM, | ||
| 233 | prtd->params->dma_addr); | ||
| 234 | } else { | ||
| 235 | s3c2410_dma_devconfig(prtd->params->channel, | ||
| 236 | S3C2410_DMASRC_HW, | ||
| 237 | prtd->params->dma_addr); | ||
| 238 | } | ||
| 239 | |||
| 240 | s3c2410_dma_config(prtd->params->channel, | ||
| 241 | prtd->params->dma_size); | ||
| 242 | |||
| 243 | /* flush the DMA channel */ | 225 | /* flush the DMA channel */ |
| 244 | s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); | 226 | prtd->params->ops->flush(prtd->params->ch); |
| 227 | |||
| 245 | prtd->dma_loaded = 0; | 228 | prtd->dma_loaded = 0; |
| 246 | prtd->dma_pos = prtd->dma_start; | 229 | prtd->dma_pos = prtd->dma_start; |
| 247 | 230 | ||
| @@ -265,14 +248,14 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd) | |||
| 265 | case SNDRV_PCM_TRIGGER_RESUME: | 248 | case SNDRV_PCM_TRIGGER_RESUME: |
| 266 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 249 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 267 | prtd->state |= ST_RUNNING; | 250 | prtd->state |= ST_RUNNING; |
| 268 | s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); | 251 | prtd->params->ops->trigger(prtd->params->ch); |
| 269 | break; | 252 | break; |
| 270 | 253 | ||
| 271 | case SNDRV_PCM_TRIGGER_STOP: | 254 | case SNDRV_PCM_TRIGGER_STOP: |
| 272 | case SNDRV_PCM_TRIGGER_SUSPEND: | 255 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 273 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 256 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 274 | prtd->state &= ~ST_RUNNING; | 257 | prtd->state &= ~ST_RUNNING; |
| 275 | s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); | 258 | prtd->params->ops->stop(prtd->params->ch); |
| 276 | break; | 259 | break; |
| 277 | 260 | ||
| 278 | default: | 261 | default: |
| @@ -291,21 +274,12 @@ dma_pointer(struct snd_pcm_substream *substream) | |||
| 291 | struct snd_pcm_runtime *runtime = substream->runtime; | 274 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 292 | struct runtime_data *prtd = runtime->private_data; | 275 | struct runtime_data *prtd = runtime->private_data; |
| 293 | unsigned long res; | 276 | unsigned long res; |
| 294 | dma_addr_t src, dst; | ||
| 295 | 277 | ||
| 296 | pr_debug("Entered %s\n", __func__); | 278 | pr_debug("Entered %s\n", __func__); |
| 297 | 279 | ||
| 298 | spin_lock(&prtd->lock); | 280 | res = prtd->dma_pos - prtd->dma_start; |
| 299 | s3c2410_dma_getposition(prtd->params->channel, &src, &dst); | ||
| 300 | |||
| 301 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
| 302 | res = dst - prtd->dma_start; | ||
| 303 | else | ||
| 304 | res = src - prtd->dma_start; | ||
| 305 | |||
| 306 | spin_unlock(&prtd->lock); | ||
| 307 | 281 | ||
| 308 | pr_debug("Pointer %x %x\n", src, dst); | 282 | pr_debug("Pointer offset: %lu\n", res); |
| 309 | 283 | ||
| 310 | /* we seem to be getting the odd error from the pcm library due | 284 | /* we seem to be getting the odd error from the pcm library due |
| 311 | * to out-of-bounds pointers. this is maybe due to the dma engine | 285 | * to out-of-bounds pointers. this is maybe due to the dma engine |
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index c50659269a40..7d1ead77ef21 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | 6 | * Free Software Foundation; either version 2 of the License, or (at your |
| 7 | * option) any later version. | 7 | * option) any later version. |
| 8 | * | 8 | * |
| 9 | * ALSA PCM interface for the Samsung S3C24xx CPU | 9 | * ALSA PCM interface for the Samsung SoC |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #ifndef _S3C_AUDIO_H | 12 | #ifndef _S3C_AUDIO_H |
| @@ -17,6 +17,8 @@ struct s3c_dma_params { | |||
| 17 | int channel; /* Channel ID */ | 17 | int channel; /* Channel ID */ |
| 18 | dma_addr_t dma_addr; | 18 | dma_addr_t dma_addr; |
| 19 | int dma_size; /* Size of the DMA transfer */ | 19 | int dma_size; /* Size of the DMA transfer */ |
| 20 | unsigned ch; | ||
| 21 | struct samsung_dma_ops *ops; | ||
| 20 | }; | 22 | }; |
| 21 | 23 | ||
| 22 | #endif | 24 | #endif |
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index 67bec7612442..c0609c210303 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c | |||
| @@ -459,7 +459,8 @@ static void kill_stream_urbs(struct ua101_stream *stream) | |||
| 459 | unsigned int i; | 459 | unsigned int i; |
| 460 | 460 | ||
| 461 | for (i = 0; i < stream->queue_length; ++i) | 461 | for (i = 0; i < stream->queue_length; ++i) |
| 462 | usb_kill_urb(&stream->urbs[i]->urb); | 462 | if (stream->urbs[i]) |
| 463 | usb_kill_urb(&stream->urbs[i]->urb); | ||
| 463 | } | 464 | } |
| 464 | 465 | ||
| 465 | static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index) | 466 | static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index) |
| @@ -484,6 +485,9 @@ static void disable_iso_interface(struct ua101 *ua, unsigned int intf_index) | |||
| 484 | { | 485 | { |
| 485 | struct usb_host_interface *alts; | 486 | struct usb_host_interface *alts; |
| 486 | 487 | ||
| 488 | if (!ua->intf[intf_index]) | ||
| 489 | return; | ||
| 490 | |||
| 487 | alts = ua->intf[intf_index]->cur_altsetting; | 491 | alts = ua->intf[intf_index]->cur_altsetting; |
| 488 | if (alts->desc.bAlternateSetting != 0) { | 492 | if (alts->desc.bAlternateSetting != 0) { |
| 489 | int err = usb_set_interface(ua->dev, | 493 | int err = usb_set_interface(ua->dev, |
| @@ -1144,27 +1148,37 @@ static void free_stream_urbs(struct ua101_stream *stream) | |||
| 1144 | { | 1148 | { |
| 1145 | unsigned int i; | 1149 | unsigned int i; |
| 1146 | 1150 | ||
| 1147 | for (i = 0; i < stream->queue_length; ++i) | 1151 | for (i = 0; i < stream->queue_length; ++i) { |
| 1148 | kfree(stream->urbs[i]); | 1152 | kfree(stream->urbs[i]); |
| 1153 | stream->urbs[i] = NULL; | ||
| 1154 | } | ||
| 1149 | } | 1155 | } |
| 1150 | 1156 | ||
| 1151 | static void free_usb_related_resources(struct ua101 *ua, | 1157 | static void free_usb_related_resources(struct ua101 *ua, |
| 1152 | struct usb_interface *interface) | 1158 | struct usb_interface *interface) |
| 1153 | { | 1159 | { |
| 1154 | unsigned int i; | 1160 | unsigned int i; |
| 1161 | struct usb_interface *intf; | ||
| 1155 | 1162 | ||
| 1163 | mutex_lock(&ua->mutex); | ||
| 1156 | free_stream_urbs(&ua->capture); | 1164 | free_stream_urbs(&ua->capture); |
| 1157 | free_stream_urbs(&ua->playback); | 1165 | free_stream_urbs(&ua->playback); |
| 1166 | mutex_unlock(&ua->mutex); | ||
| 1158 | free_stream_buffers(ua, &ua->capture); | 1167 | free_stream_buffers(ua, &ua->capture); |
| 1159 | free_stream_buffers(ua, &ua->playback); | 1168 | free_stream_buffers(ua, &ua->playback); |
| 1160 | 1169 | ||
| 1161 | for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) | 1170 | for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) { |
| 1162 | if (ua->intf[i]) { | 1171 | mutex_lock(&ua->mutex); |
| 1163 | usb_set_intfdata(ua->intf[i], NULL); | 1172 | intf = ua->intf[i]; |
| 1164 | if (ua->intf[i] != interface) | 1173 | ua->intf[i] = NULL; |
| 1174 | mutex_unlock(&ua->mutex); | ||
| 1175 | if (intf) { | ||
| 1176 | usb_set_intfdata(intf, NULL); | ||
| 1177 | if (intf != interface) | ||
| 1165 | usb_driver_release_interface(&ua101_driver, | 1178 | usb_driver_release_interface(&ua101_driver, |
| 1166 | ua->intf[i]); | 1179 | intf); |
| 1167 | } | 1180 | } |
| 1181 | } | ||
| 1168 | } | 1182 | } |
| 1169 | 1183 | ||
| 1170 | static void ua101_card_free(struct snd_card *card) | 1184 | static void ua101_card_free(struct snd_card *card) |
