diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/Kconfig | 2 | ||||
-rw-r--r-- | sound/core/control.c | 4 | ||||
-rw-r--r-- | sound/core/hwdep.c | 9 | ||||
-rw-r--r-- | sound/firewire/cmp.c | 2 | ||||
-rw-r--r-- | sound/mips/Kconfig | 2 | ||||
-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/au1x/Kconfig | 2 | ||||
-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 |
27 files changed, 255 insertions, 200 deletions
diff --git a/sound/Kconfig b/sound/Kconfig index 1fef141ef8e7..261a03c8a209 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -59,7 +59,7 @@ config SOUND_OSS_CORE_PRECLAIM source "sound/oss/dmasound/Kconfig" -if !M68K +if !M68K && !UML menuconfig SND tristate "Advanced Linux Sound Architecture" diff --git a/sound/core/control.c b/sound/core/control.c index 49721f5a2ee7..819a5c579a39 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1082,12 +1082,12 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue) char *names, *p; size_t buf_len, name_len; unsigned int i; + const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr; if (ue->info.value.enumerated.names_length > 64 * 1024) return -EINVAL; - names = memdup_user( - (const void __user *)ue->info.value.enumerated.names_ptr, + names = memdup_user((const void __user *)user_ptrval, ue->info.value.enumerated.names_length); if (IS_ERR(names)) return PTR_ERR(names); diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index c7ceb28d885d..75ea16f35b1a 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -273,7 +273,14 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)arg)) return -EFAULT; mutex_lock(®ister_mutex); - device = device < 0 ? 0 : device + 1; + + if (device < 0) + device = 0; + else if (device < SNDRV_MINOR_HWDEPS) + device++; + else + device = SNDRV_MINOR_HWDEPS; + while (device < SNDRV_MINOR_HWDEPS) { if (snd_hwdep_search(card, device)) break; diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c index 14cacbc655dd..76294f2ae47f 100644 --- a/sound/firewire/cmp.c +++ b/sound/firewire/cmp.c @@ -32,7 +32,7 @@ enum bus_reset_handling { SUCCEED_ON_BUS_RESET, }; -static __attribute__((format(printf, 2, 3))) +static __printf(2, 3) void cmp_error(struct cmp_connection *c, const char *fmt, ...) { va_list va; diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig index 77dd0a13aecc..d2f615ab177a 100644 --- a/sound/mips/Kconfig +++ b/sound/mips/Kconfig @@ -24,7 +24,7 @@ config SND_SGI_HAL2 config SND_AU1X00 tristate "Au1x00 AC97 Port Driver (DEPRECATED)" - depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500 + depends on MIPS_ALCHEMY select SND_PCM select SND_AC97_CODEC help diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index a6d54595bb7b..6b2efb8cb1f9 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -757,8 +757,6 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw) } if (!fw->size) return 0; - if (size < fw->size) - size = fw->size; for (len = 0; len < fw->size; len++) { 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) = { .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | - AZX_DCAPS_RIRB_PRE_DELAY }, + AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, #else /* this entry seems still valid -- i.e. without emu20kx chip */ { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | - AZX_DCAPS_RIRB_PRE_DELAY }, + AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, #endif /* Vortex86MX */ { 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 { (cfg & AC_DEFCFG_SEQUENCE) #define get_defcfg_device(cfg) \ ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) +#define get_defcfg_misc(cfg) \ + ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) /* bit-flags for snd_hda_parse_pin_def_config() behavior */ #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); static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && + /* disable MISC_NO_PRESENCE check because it may break too + * many devices + */ + /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & + AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); } diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index e577f93cdda7..81b7b791b3c3 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) unsigned int caps, config; int pin_idx; struct hdmi_spec_per_pin *per_pin; - struct hdmi_eld *eld; int err; 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) pin_idx = spec->num_pins; per_pin = &spec->pins[pin_idx]; - eld = &per_pin->sink_eld; per_pin->pin_nid = pin_nid; @@ -1576,7 +1574,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) { int chs; - unsigned int dataDCC1, dataDCC2, channel_id; + unsigned int dataDCC2, channel_id; int i; struct hdmi_spec *spec = codec->spec; struct hda_spdif_out *spdif = @@ -1586,7 +1584,6 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, chs = substream->runtime->channels; - dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT; dataDCC2 = 0x2; /* 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 fca4e6daa9e2..a24e068a021b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1605,27 +1605,29 @@ static void alc_auto_init_digital(struct hda_codec *codec) static void alc_auto_parse_digital(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - int i, err; + int i, err, nums; hda_nid_t dig_nid; /* support multiple SPDIFs; the secondary is set up as a slave */ + nums = 0; for (i = 0; i < spec->autocfg.dig_outs; i++) { hda_nid_t conn[4]; err = snd_hda_get_connections(codec, spec->autocfg.dig_out_pins[i], conn, ARRAY_SIZE(conn)); - if (err < 0) + if (err <= 0) continue; dig_nid = conn[0]; /* assume the first element is audio-out */ - if (!i) { + if (!nums) { spec->multiout.dig_out_nid = dig_nid; spec->dig_out_type = spec->autocfg.dig_out_type[0]; } else { spec->multiout.slave_dig_outs = spec->slave_dig_outs; - if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) + if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) break; - spec->slave_dig_outs[i - 1] = dig_nid; + spec->slave_dig_outs[nums - 1] = dig_nid; } + nums++; } if (spec->autocfg.dig_in_pin) { @@ -2271,6 +2273,7 @@ static int alc_build_pcms(struct hda_codec *codec) struct alc_spec *spec = codec->spec; struct hda_pcm *info = spec->pcm_rec; const struct hda_pcm_stream *p; + bool have_multi_adcs; int i; codec->num_pcms = 1; @@ -2349,8 +2352,11 @@ static int alc_build_pcms(struct hda_codec *codec) /* If the use of more than one ADC is requested for the current * model, configure a second analog capture-only PCM. */ + have_multi_adcs = (spec->num_adc_nids > 1) && + !spec->dyn_adc_switch && !spec->auto_mic && + (!spec->input_mux || spec->input_mux->num_items > 1); /* Additional Analaog capture for index #2 */ - if (spec->alt_dac_nid || spec->num_adc_nids > 1) { + if (spec->alt_dac_nid || have_multi_adcs) { codec->num_pcms = 3; info = spec->pcm_rec + 2; info->name = spec->stream_name_analog; @@ -2366,7 +2372,7 @@ static int alc_build_pcms(struct hda_codec *codec) alc_pcm_null_stream; info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; } - if (spec->num_adc_nids > 1) { + if (have_multi_adcs) { p = spec->stream_analog_alt_capture; if (!p) p = &alc_pcm_analog_alt_capture; @@ -2658,7 +2664,6 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) hda_nid_t *adc_nids = spec->private_adc_nids; hda_nid_t *cap_nids = spec->private_capsrc_nids; int max_nums = ARRAY_SIZE(spec->private_adc_nids); - bool indep_capsrc = false; int i, nums = 0; nid = codec->start_nid; @@ -2680,13 +2685,11 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) break; if (type == AC_WID_AUD_SEL) { cap_nids[nums] = src; - indep_capsrc = true; break; } n = snd_hda_get_conn_list(codec, src, &list); if (n > 1) { cap_nids[nums] = src; - indep_capsrc = true; break; } else if (n != 1) break; @@ -3327,6 +3330,12 @@ static void alc_auto_set_output_and_unmute(struct hda_codec *codec, if (nid) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); + + /* unmute DAC if it's not assigned to a mixer */ + nid = alc_look_for_out_mute_nid(codec, pin, dac); + if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT)) + snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_ZERO); } 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 4b17f8621c79..4e715fefebef 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3792,9 +3792,10 @@ static int is_dual_headphones(struct hda_codec *codec) } -static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) +static int stac92xx_parse_auto_config(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; + hda_nid_t dig_out = 0, dig_in = 0; int hp_swap = 0; int i, err; @@ -3977,6 +3978,22 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if (spec->multiout.max_channels > 2) spec->surr_switch = 1; + /* find digital out and in converters */ + for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) { + unsigned int wid_caps = get_wcaps(codec, i); + if (wid_caps & AC_WCAP_DIGITAL) { + switch (get_wcaps_type(wid_caps)) { + case AC_WID_AUD_OUT: + if (!dig_out) + dig_out = i; + break; + case AC_WID_AUD_IN: + if (!dig_in) + dig_in = i; + break; + } + } + } if (spec->autocfg.dig_outs) spec->multiout.dig_out_nid = dig_out; if (dig_in && spec->autocfg.dig_in_pin) @@ -5280,7 +5297,7 @@ static int patch_stac925x(struct hda_codec *codec) spec->capvols = stac925x_capvols; spec->capsws = stac925x_capsws; - err = stac92xx_parse_auto_config(codec, 0x8, 0x7); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -5421,7 +5438,7 @@ again: spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); spec->pwr_nids = stac92hd73xx_pwr_nids; - err = stac92xx_parse_auto_config(codec, 0x25, 0x27); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { @@ -5630,26 +5647,8 @@ again: stac92xx_set_config_regs(codec, stac92hd83xxx_brd_tbl[spec->board_config]); - switch (codec->vendor_id) { - case 0x111d76d1: - case 0x111d76d9: - case 0x111d76df: - case 0x111d76e5: - case 0x111d7666: - case 0x111d7667: - case 0x111d7668: - case 0x111d7669: - case 0x111d76e3: - case 0x111d7604: - case 0x111d76d4: - case 0x111d7605: - case 0x111d76d5: - case 0x111d76e7: - if (spec->board_config == STAC_92HD83XXX_PWR_REF) - break; + if (spec->board_config != STAC_92HD83XXX_PWR_REF) spec->num_pwrs = 0; - break; - } codec->patch_ops = stac92xx_patch_ops; @@ -5676,7 +5675,7 @@ again: } #endif - err = stac92xx_parse_auto_config(codec, 0x1d, 0); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -5997,7 +5996,7 @@ again: spec->multiout.dac_nids = spec->dac_nids; - err = stac92xx_parse_auto_config(codec, 0x21, 0); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6106,7 +6105,7 @@ static int patch_stac922x(struct hda_codec *codec) spec->multiout.dac_nids = spec->dac_nids; - err = stac92xx_parse_auto_config(codec, 0x08, 0x09); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6231,7 +6230,7 @@ static int patch_stac927x(struct hda_codec *codec) spec->aloopback_shift = 0; spec->eapd_switch = 1; - err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6356,7 +6355,7 @@ static int patch_stac9205(struct hda_codec *codec) break; } - err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6461,7 +6460,7 @@ static int patch_stac9872(struct hda_codec *codec) spec->capvols = stac9872_capvols; spec->capsws = stac9872_capsws; - err = stac92xx_parse_auto_config(codec, 0x10, 0x12); + err = stac92xx_parse_auto_config(codec); if (err < 0) { stac92xx_free(codec); return -EINVAL; @@ -6566,6 +6565,18 @@ static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx}, {} /* terminator */ }; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 7aa7dcc206e2..431c0d417eeb 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -3701,13 +3701,8 @@ static const struct hda_verb vt1812_init_verbs[] = { static void set_widgets_power_state_vt1812(struct hda_codec *codec) { struct via_spec *spec = codec->spec; - int imux_is_smixer = - snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; unsigned int parm; unsigned int present; - /* MUX10 (1eh) = stereo mixer */ - imux_is_smixer = - snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; /* inputs */ /* PW 5/6/7 (29h/2ah/2bh) */ parm = AC_PWRST_D3; diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 4a1618da48a4..29e312597f20 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -42,6 +42,12 @@ #include <asm/pgtable.h> #include <asm/cacheflush.h> +#ifdef CONFIG_KVM_GUEST +#include <linux/kvm_para.h> +#else +#define kvm_para_available() (0) +#endif + MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455"); MODULE_LICENSE("GPL"); @@ -77,6 +83,7 @@ static int buggy_semaphore; static int buggy_irq = -1; /* auto-check */ static int xbox; static int spdif_aclink = -1; +static int inside_vm = -1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); @@ -94,6 +101,8 @@ module_param(xbox, bool, 0444); MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); module_param(spdif_aclink, int, 0444); MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); +module_param(inside_vm, bool, 0444); +MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization."); /* just for backward compatibility */ static int enable; @@ -400,6 +409,7 @@ struct intel8x0 { unsigned buggy_irq: 1; /* workaround for buggy mobos */ unsigned xbox: 1; /* workaround for Xbox AC'97 detection */ unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */ + unsigned inside_vm: 1; /* enable VM optimization */ int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ 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 udelay(10); continue; } - if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && - ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) + if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) + continue; + if (chip->inside_vm) + break; + if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) break; } while (timeout--); ptr = ichdev->last_pos; @@ -2984,6 +2997,10 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, if (xbox) chip->xbox = 1; + chip->inside_vm = inside_vm; + if (inside_vm) + printk(KERN_INFO "intel8x0: enable KVM optimization\n"); + if (pci->vendor == PCI_VENDOR_ID_INTEL && pci->device == PCI_DEVICE_ID_INTEL_440MX) chip->fix_nocache = 1; /* enable workaround */ @@ -3226,6 +3243,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, buggy_irq = 0; } + if (inside_vm < 0) { + /* detect KVM and Parallels virtual environments */ + inside_vm = kvm_para_available(); +#if defined(__i386__) || defined(__x86_64__) + inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); +#endif + } + if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) { snd_card_free(card); diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 5542bfff6604..f2a3758dac52 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -151,7 +151,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); #define HDSP_PROGRAM 0x020 #define HDSP_CONFIG_MODE_0 0x040 #define HDSP_CONFIG_MODE_1 0x080 -#define HDSP_VERSION_BIT 0x100 +#define HDSP_VERSION_BIT (0x100 | HDSP_S_LOAD) #define HDSP_BIGENDIAN_MODE 0x200 #define HDSP_RD_MULTIPLE 0x400 #define HDSP_9652_ENABLE_MIXER 0x800 diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index a4e1cccd4473..e760adad9523 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -520,16 +520,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) -/* revisions >= 230 indicate AES32 card */ -#define HDSPM_MADI_ANCIENT_REV 204 -#define HDSPM_MADI_OLD_REV 207 -#define HDSPM_MADI_REV 210 #define HDSPM_RAYDAT_REV 211 #define HDSPM_AIO_REV 212 #define HDSPM_MADIFACE_REV 213 -#define HDSPM_AES_REV 240 -#define HDSPM_AES32_REV 234 -#define HDSPM_AES32_OLD_REV 233 /* speed factor modes */ #define HDSPM_SPEED_SINGLE 0 @@ -6253,7 +6246,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, status.card_specific.madi.madi_input = (statusregister & HDSPM_AB_int) ? 1 : 0; status.card_specific.madi.channel_format = - (statusregister & HDSPM_TX_64ch) ? 1 : 0; + (statusregister & HDSPM_RX_64ch) ? 1 : 0; /* TODO: Mac driver sets it when f_s>48kHz */ status.card_specific.madi.frame_format = 0; @@ -6503,13 +6496,6 @@ static int __devinit snd_hdspm_create(struct snd_card *card, strcpy(card->driver, "HDSPM"); switch (hdspm->firmware_rev) { - case HDSPM_MADI_REV: - case HDSPM_MADI_OLD_REV: - case HDSPM_MADI_ANCIENT_REV: - hdspm->io_type = MADI; - hdspm->card_name = "RME MADI"; - hdspm->midiPorts = 3; - break; case HDSPM_RAYDAT_REV: hdspm->io_type = RayDAT; hdspm->card_name = "RME RayDAT"; @@ -6525,17 +6511,25 @@ static int __devinit snd_hdspm_create(struct snd_card *card, hdspm->card_name = "RME MADIface"; hdspm->midiPorts = 1; break; - case HDSPM_AES_REV: - case HDSPM_AES32_REV: - case HDSPM_AES32_OLD_REV: - hdspm->io_type = AES32; - hdspm->card_name = "RME AES32"; - hdspm->midiPorts = 2; - break; default: - snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n", + if ((hdspm->firmware_rev == 0xf0) || + ((hdspm->firmware_rev >= 0xe6) && + (hdspm->firmware_rev <= 0xea))) { + hdspm->io_type = AES32; + hdspm->card_name = "RME AES32"; + hdspm->midiPorts = 2; + } else if ((hdspm->firmware_rev == 0xd5) || + ((hdspm->firmware_rev >= 0xc8) && + (hdspm->firmware_rev <= 0xcf))) { + hdspm->io_type = MADI; + hdspm->card_name = "RME MADI"; + hdspm->midiPorts = 3; + } else { + snd_printk(KERN_ERR + "HDSPM: unknown firmware revision %x\n", hdspm->firmware_rev); - return -ENODEV; + return -ENODEV; + } } err = pci_enable_device(pci); diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig index 6d592546e8fc..e908a8123110 100644 --- a/sound/soc/au1x/Kconfig +++ b/sound/soc/au1x/Kconfig @@ -3,7 +3,7 @@ ## config SND_SOC_AU1XPSC tristate "SoC Audio for Au1200/Au1250/Au1550" - depends on SOC_AU1200 || SOC_AU1550 + depends on MIPS_ALCHEMY help This option enables support for the Programmable Serial Controllers in AC97 and I2S mode, and the Descriptor-Based DMA 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, iface_reg |= TLV320AIC23_MS_MASTER; break; case SND_SOC_DAIFMT_CBS_CFS: + iface_reg &= ~TLV320AIC23_MS_MASTER; break; default: 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, break; case SND_SOC_DAIFMT_CBS_CFS: aic3x->master = 0; + iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER); break; default: 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, { struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); struct snd_soc_codec *codec = wm5100->codec; - int val; + int val, ret; val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT); - return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, - WM5100_GP1_FN_MASK | WM5100_GP1_DIR | - WM5100_GP1_LVL, val); + ret = snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, + WM5100_GP1_FN_MASK | WM5100_GP1_DIR | + WM5100_GP1_LVL, val); + if (ret < 0) + return ret; + else + return 0; } 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, { struct snd_soc_codec *codec = dai->codec; struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); - u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc; + u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfff3; int i = get_coeff(wm8711->sysclk, params_rate(params)); u16 srate = (coeff_div[i].sr << 2) | (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, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; - u16 iface = 0; + u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0x000c; /* set master/slave audio interface */ 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), SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0, WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0), SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0, - WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0), + WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 1), SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), 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, switch (div_id) { case WM8940_BCLKDIV: - reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFEF3; + reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3; ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2)); break; 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 static int wm8962_reset(struct snd_soc_codec *codec) { - return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); + int ret; + + ret = snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); + if (ret != 0) + return ret; + + return snd_soc_write(codec, WM8962_PLL_SOFTWARE_RESET, 0); } 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, snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, WM8962_FLL_ENA); - if (wm8962->irq) { - timeout = msecs_to_jiffies(5); - timeout = wait_for_completion_timeout(&wm8962->fll_lock, - timeout); - - if (timeout == 0) - dev_err(codec->dev, - "Timed out starting FLL\n"); - } + + timeout = msecs_to_jiffies(5); + timeout = wait_for_completion_timeout(&wm8962->fll_lock, + timeout); + + if (wm8962->irq && timeout == 0) + dev_err(codec->dev, + "Timed out starting FLL\n"); } break; @@ -4029,6 +4034,11 @@ static int wm8962_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_CLKREG_OVD, WM8962_CLKREG_OVD); + /* Ensure that the oscillator and PLLs are disabled */ + snd_soc_update_bits(codec, WM8962_PLL2, + WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, + 0); + regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); if (pdata) { diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 31a224573b68..16521e3ffc0c 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -272,7 +272,10 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); + if (!dma_data->ops) + dma_data->ops = samsung_dma_get_ops(); + + dma_data->ops->started(dma_data->channel); return 0; } @@ -318,7 +321,10 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); + if (!dma_data->ops) + dma_data->ops = samsung_dma_get_ops(); + + dma_data->ops->started(dma_data->channel); return 0; } diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index 8351a7131e5c..a68b26441784 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -55,7 +55,6 @@ struct runtime_data { spinlock_t lock; int state; unsigned int dma_loaded; - unsigned int dma_limit; unsigned int dma_period; dma_addr_t dma_start; dma_addr_t dma_pos; @@ -63,77 +62,79 @@ struct runtime_data { struct s3c_dma_params *params; }; +static void audio_buffdone(void *data); + /* dma_enqueue * * place a dma buffer onto the queue for the dma system * to handle. -*/ + */ static void dma_enqueue(struct snd_pcm_substream *substream) { struct runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; unsigned int limit; - int ret; + struct samsung_dma_prep_info dma_info; pr_debug("Entered %s\n", __func__); - if (s3c_dma_has_circular()) - limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; - else - limit = prtd->dma_limit; + limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; pr_debug("%s: loaded %d, limit %d\n", __func__, prtd->dma_loaded, limit); - while (prtd->dma_loaded < limit) { - unsigned long len = prtd->dma_period; + dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE); + dma_info.direction = + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK + ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + dma_info.fp = audio_buffdone; + dma_info.fp_param = substream; + dma_info.period = prtd->dma_period; + dma_info.len = prtd->dma_period*limit; + while (prtd->dma_loaded < limit) { pr_debug("dma_loaded: %d\n", prtd->dma_loaded); - if ((pos + len) > prtd->dma_end) { - len = prtd->dma_end - pos; - pr_debug("%s: corrected dma len %ld\n", __func__, len); + if ((pos + dma_info.period) > prtd->dma_end) { + dma_info.period = prtd->dma_end - pos; + pr_debug("%s: corrected dma len %ld\n", + __func__, dma_info.period); } - ret = s3c2410_dma_enqueue(prtd->params->channel, - substream, pos, len); + dma_info.buf = pos; + prtd->params->ops->prepare(prtd->params->ch, &dma_info); - if (ret == 0) { - prtd->dma_loaded++; - pos += prtd->dma_period; - if (pos >= prtd->dma_end) - pos = prtd->dma_start; - } else - break; + prtd->dma_loaded++; + pos += prtd->dma_period; + if (pos >= prtd->dma_end) + pos = prtd->dma_start; } prtd->dma_pos = pos; } -static void audio_buffdone(struct s3c2410_dma_chan *channel, - void *dev_id, int size, - enum s3c2410_dma_buffresult result) +static void audio_buffdone(void *data) { - struct snd_pcm_substream *substream = dev_id; - struct runtime_data *prtd; + struct snd_pcm_substream *substream = data; + struct runtime_data *prtd = substream->runtime->private_data; pr_debug("Entered %s\n", __func__); - if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) - return; - - prtd = substream->runtime->private_data; + if (prtd->state & ST_RUNNING) { + prtd->dma_pos += prtd->dma_period; + if (prtd->dma_pos >= prtd->dma_end) + prtd->dma_pos = prtd->dma_start; - if (substream) - snd_pcm_period_elapsed(substream); + if (substream) + snd_pcm_period_elapsed(substream); - spin_lock(&prtd->lock); - if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { - prtd->dma_loaded--; - dma_enqueue(substream); + spin_lock(&prtd->lock); + if (!samsung_dma_has_circular()) { + prtd->dma_loaded--; + dma_enqueue(substream); + } + spin_unlock(&prtd->lock); } - - spin_unlock(&prtd->lock); } static int dma_hw_params(struct snd_pcm_substream *substream, @@ -145,8 +146,7 @@ static int dma_hw_params(struct snd_pcm_substream *substream, unsigned long totbytes = params_buffer_bytes(params); struct s3c_dma_params *dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - int ret = 0; - + struct samsung_dma_info dma_info; pr_debug("Entered %s\n", __func__); @@ -164,30 +164,26 @@ static int dma_hw_params(struct snd_pcm_substream *substream, pr_debug("params %p, client %p, channel %d\n", prtd->params, prtd->params->client, prtd->params->channel); - ret = s3c2410_dma_request(prtd->params->channel, - prtd->params->client, NULL); - - if (ret < 0) { - printk(KERN_ERR "failed to get dma channel\n"); - return ret; - } - - /* use the circular buffering if we have it available. */ - if (s3c_dma_has_circular()) - s3c2410_dma_setflags(prtd->params->channel, - S3C2410_DMAF_CIRCULAR); + prtd->params->ops = samsung_dma_get_ops(); + + dma_info.cap = (samsung_dma_has_circular() ? + DMA_CYCLIC : DMA_SLAVE); + dma_info.client = prtd->params->client; + dma_info.direction = + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK + ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + dma_info.width = prtd->params->dma_size; + dma_info.fifo = prtd->params->dma_addr; + prtd->params->ch = prtd->params->ops->request( + prtd->params->channel, &dma_info); } - s3c2410_dma_set_buffdone_fn(prtd->params->channel, - audio_buffdone); - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = totbytes; spin_lock_irq(&prtd->lock); prtd->dma_loaded = 0; - prtd->dma_limit = runtime->hw.periods_min; prtd->dma_period = params_period_bytes(params); prtd->dma_start = runtime->dma_addr; prtd->dma_pos = prtd->dma_start; @@ -203,11 +199,12 @@ static int dma_hw_free(struct snd_pcm_substream *substream) pr_debug("Entered %s\n", __func__); - /* TODO - do we need to ensure DMA flushed */ snd_pcm_set_runtime_buffer(substream, NULL); if (prtd->params) { - s3c2410_dma_free(prtd->params->channel, prtd->params->client); + prtd->params->ops->flush(prtd->params->ch); + prtd->params->ops->release(prtd->params->ch, + prtd->params->client); prtd->params = NULL; } @@ -226,23 +223,9 @@ static int dma_prepare(struct snd_pcm_substream *substream) if (!prtd->params) return 0; - /* channel needs configuring for mem=>device, increment memory addr, - * sync to pclk, half-word transfers to the IIS-FIFO. */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - s3c2410_dma_devconfig(prtd->params->channel, - S3C2410_DMASRC_MEM, - prtd->params->dma_addr); - } else { - s3c2410_dma_devconfig(prtd->params->channel, - S3C2410_DMASRC_HW, - prtd->params->dma_addr); - } - - s3c2410_dma_config(prtd->params->channel, - prtd->params->dma_size); - /* flush the DMA channel */ - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); + prtd->params->ops->flush(prtd->params->ch); + prtd->dma_loaded = 0; prtd->dma_pos = prtd->dma_start; @@ -266,14 +249,14 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: prtd->state |= ST_RUNNING; - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); + prtd->params->ops->trigger(prtd->params->ch); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: prtd->state &= ~ST_RUNNING; - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); + prtd->params->ops->stop(prtd->params->ch); break; default: @@ -292,21 +275,12 @@ dma_pointer(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct runtime_data *prtd = runtime->private_data; unsigned long res; - dma_addr_t src, dst; pr_debug("Entered %s\n", __func__); - spin_lock(&prtd->lock); - s3c2410_dma_getposition(prtd->params->channel, &src, &dst); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - res = dst - prtd->dma_start; - else - res = src - prtd->dma_start; - - spin_unlock(&prtd->lock); + res = prtd->dma_pos - prtd->dma_start; - pr_debug("Pointer %x %x\n", src, dst); + pr_debug("Pointer offset: %lu\n", res); /* we seem to be getting the odd error from the pcm library due * 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 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - * ALSA PCM interface for the Samsung S3C24xx CPU + * ALSA PCM interface for the Samsung SoC */ #ifndef _S3C_AUDIO_H @@ -17,6 +17,8 @@ struct s3c_dma_params { int channel; /* Channel ID */ dma_addr_t dma_addr; int dma_size; /* Size of the DMA transfer */ + unsigned ch; + struct samsung_dma_ops *ops; }; #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) unsigned int i; for (i = 0; i < stream->queue_length; ++i) - usb_kill_urb(&stream->urbs[i]->urb); + if (stream->urbs[i]) + usb_kill_urb(&stream->urbs[i]->urb); } 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) { struct usb_host_interface *alts; + if (!ua->intf[intf_index]) + return; + alts = ua->intf[intf_index]->cur_altsetting; if (alts->desc.bAlternateSetting != 0) { int err = usb_set_interface(ua->dev, @@ -1144,27 +1148,37 @@ static void free_stream_urbs(struct ua101_stream *stream) { unsigned int i; - for (i = 0; i < stream->queue_length; ++i) + for (i = 0; i < stream->queue_length; ++i) { kfree(stream->urbs[i]); + stream->urbs[i] = NULL; + } } static void free_usb_related_resources(struct ua101 *ua, struct usb_interface *interface) { unsigned int i; + struct usb_interface *intf; + mutex_lock(&ua->mutex); free_stream_urbs(&ua->capture); free_stream_urbs(&ua->playback); + mutex_unlock(&ua->mutex); free_stream_buffers(ua, &ua->capture); free_stream_buffers(ua, &ua->playback); - for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) - if (ua->intf[i]) { - usb_set_intfdata(ua->intf[i], NULL); - if (ua->intf[i] != interface) + for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) { + mutex_lock(&ua->mutex); + intf = ua->intf[i]; + ua->intf[i] = NULL; + mutex_unlock(&ua->mutex); + if (intf) { + usb_set_intfdata(intf, NULL); + if (intf != interface) usb_driver_release_interface(&ua101_driver, - ua->intf[i]); + intf); } + } } static void ua101_card_free(struct snd_card *card) |