diff options
Diffstat (limited to 'sound')
29 files changed, 286 insertions, 129 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 303ac04ff6e4..a3b2a6479246 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -451,13 +451,11 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, snd_pcm_timer_resolution_change(substream); runtime->status->state = SNDRV_PCM_STATE_SETUP; - if (substream->latency_pm_qos_req) { - pm_qos_remove_request(substream->latency_pm_qos_req); - substream->latency_pm_qos_req = NULL; - } + if (pm_qos_request_active(&substream->latency_pm_qos_req)) + pm_qos_remove_request(&substream->latency_pm_qos_req); if ((usecs = period_to_usecs(runtime)) >= 0) - substream->latency_pm_qos_req = pm_qos_add_request( - PM_QOS_CPU_DMA_LATENCY, usecs); + pm_qos_add_request(&substream->latency_pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, usecs); return 0; _error: /* hardware might be unuseable from this time, @@ -512,8 +510,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) if (substream->ops->hw_free) result = substream->ops->hw_free(substream); runtime->status->state = SNDRV_PCM_STATE_OPEN; - pm_qos_remove_request(substream->latency_pm_qos_req); - substream->latency_pm_qos_req = NULL; + pm_qos_remove_request(&substream->latency_pm_qos_req); return result; } diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 84714a65e5c8..c290cee4cee8 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig @@ -155,7 +155,7 @@ config SND_ML403_AC97CR select SND_AC97_CODEC help Say Y here to include support for the - opb_ac97_controller_ref_v1_00_a ip core found in Xilinx' ML403 + opb_ac97_controller_ref_v1_00_a ip core found in Xilinx's ML403 reference design. To compile this driver as a module, choose M here: the module diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index e89991ea3543..3b4413448226 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -941,11 +941,11 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao, } -static long outstream_get_space_available(struct hpi_hostbuffer_status +static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status) { - return status->size_in_bytes - ((long)(status->host_index) - - (long)(status->dSP_index)); + return status->size_in_bytes - (status->host_index - + status->dSP_index); } static void outstream_write(struct hpi_adapter_obj *pao, @@ -954,7 +954,7 @@ static void outstream_write(struct hpi_adapter_obj *pao, struct hpi_hw_obj *phw = pao->priv; struct bus_master_interface *interface = phw->p_interface_buffer; struct hpi_hostbuffer_status *status; - long space_available; + u32 space_available; if (!phw->outstream_host_buffer_size[phm->obj_index]) { /* there is no BBM buffer, write via message */ @@ -1007,7 +1007,7 @@ static void outstream_write(struct hpi_adapter_obj *pao, } space_available = outstream_get_space_available(status); - if (space_available < (long)phm->u.d.u.data.data_size) { + if (space_available < phm->u.d.u.data.data_size) { phr->error = HPI_ERROR_INVALID_DATASIZE; return; } @@ -1018,7 +1018,7 @@ static void outstream_write(struct hpi_adapter_obj *pao, && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm-> obj_index])) { u8 *p_bbm_data; - long l_first_write; + u32 l_first_write; u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data; if (hpios_locked_mem_get_virt_addr(&phw-> @@ -1248,9 +1248,9 @@ static void instream_start(struct hpi_adapter_obj *pao, hw_message(pao, phm, phr); } -static long instream_get_bytes_available(struct hpi_hostbuffer_status *status) +static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status) { - return (long)(status->dSP_index) - (long)(status->host_index); + return status->dSP_index - status->host_index; } static void instream_read(struct hpi_adapter_obj *pao, @@ -1259,9 +1259,9 @@ static void instream_read(struct hpi_adapter_obj *pao, struct hpi_hw_obj *phw = pao->priv; struct bus_master_interface *interface = phw->p_interface_buffer; struct hpi_hostbuffer_status *status; - long data_available; + u32 data_available; u8 *p_bbm_data; - long l_first_read; + u32 l_first_read; u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data; if (!phw->instream_host_buffer_size[phm->obj_index]) { @@ -1272,7 +1272,7 @@ static void instream_read(struct hpi_adapter_obj *pao, status = &interface->instream_host_buffer_status[phm->obj_index]; data_available = instream_get_bytes_available(status); - if (data_available < (long)phm->u.d.u.data.data_size) { + if (data_available < phm->u.d.u.data.data_size) { phr->error = HPI_ERROR_INVALID_DATASIZE; return; } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a3d638c8c1fd..ba2098d20ccc 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -784,6 +784,9 @@ static int read_pin_defaults(struct hda_codec *codec) pin->nid = nid; pin->cfg = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); + pin->ctrl = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, + 0); } return 0; } @@ -912,15 +915,38 @@ static void restore_pincfgs(struct hda_codec *codec) void snd_hda_shutup_pins(struct hda_codec *codec) { int i; + /* don't shut up pins when unloading the driver; otherwise it breaks + * the default pin setup at the next load of the driver + */ + if (codec->bus->shutdown) + return; for (i = 0; i < codec->init_pins.used; i++) { struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); /* use read here for syncing after issuing each verb */ snd_hda_codec_read(codec, pin->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0); } + codec->pins_shutup = 1; } EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); +/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ +static void restore_shutup_pins(struct hda_codec *codec) +{ + int i; + if (!codec->pins_shutup) + return; + if (codec->bus->shutdown) + return; + for (i = 0; i < codec->init_pins.used; i++) { + struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); + snd_hda_codec_write(codec, pin->nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + pin->ctrl); + } + codec->pins_shutup = 0; +} + static void init_hda_cache(struct hda_cache_rec *cache, unsigned int record_size); static void free_hda_cache(struct hda_cache_rec *cache); @@ -2907,6 +2933,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); restore_pincfgs(codec); /* restore all current pin configs */ + restore_shutup_pins(codec); hda_exec_init_verbs(codec); if (codec->patch_ops.resume) codec->patch_ops.resume(codec); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 49e939e7e5cd..5991d14e1ec0 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -821,6 +821,7 @@ struct hda_codec { unsigned int pin_amp_workaround:1; /* pin out-amp takes index * (e.g. Conexant codecs) */ + unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ @@ -897,7 +898,9 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec); /* the struct for codec->pin_configs */ struct hda_pincfg { hda_nid_t nid; - unsigned int cfg; + unsigned char ctrl; /* current pin control value */ + unsigned char pad; /* reserved */ + unsigned int cfg; /* default configuration */ }; unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid); diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 86067ee78632..2fc53961054e 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -52,6 +52,10 @@ struct hdmi_spec { */ struct hda_multi_out multiout; unsigned int codec_type; + + /* misc flags */ + /* PD bit indicates only the update, not the current state */ + unsigned int old_pin_detect:1; }; @@ -616,6 +620,9 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, * Unsolicited events */ +static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, + struct hdmi_eld *eld); + static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) { struct hdmi_spec *spec = codec->spec; @@ -632,6 +639,12 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) if (index < 0) return; + if (spec->old_pin_detect) { + if (pind) + hdmi_present_sense(codec, tag, &spec->sink_eld[index]); + pind = spec->sink_eld[index].monitor_present; + } + spec->sink_eld[index].monitor_present = pind; spec->sink_eld[index].eld_valid = eldv; diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 3c10c0b149f4..b0652acee9b2 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -478,6 +478,7 @@ static int patch_nvhdmi_8ch_89(struct hda_codec *codec) codec->spec = spec; spec->codec_type = HDA_CODEC_NVIDIA_MCP89; + spec->old_pin_detect = 1; if (hdmi_parse_codec(codec) < 0) { codec->spec = NULL; @@ -508,6 +509,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) spec->multiout.max_channels = 8; spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; spec->codec_type = HDA_CODEC_NVIDIA_MCP7X; + spec->old_pin_detect = 1; codec->patch_ops = nvhdmi_patch_ops_8ch_7x; @@ -528,6 +530,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) spec->multiout.max_channels = 2; spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; spec->codec_type = HDA_CODEC_NVIDIA_MCP7X; + spec->old_pin_detect = 1; codec->patch_ops = nvhdmi_patch_ops_2ch; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fc767b6b4785..596ea2f12cf6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1267,6 +1267,8 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec) unsigned nid = 0; struct alc_spec *spec = codec->spec; + spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ + ass = codec->subsystem_id & 0xffff; if (ass != codec->bus->pci->subsystem_device && (ass & 1)) goto do_sku; @@ -2547,7 +2549,7 @@ static struct snd_kcontrol_new alc_beep_mixer[] = { static int alc_build_controls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - struct snd_kcontrol *kctl; + struct snd_kcontrol *kctl = NULL; struct snd_kcontrol_new *knew; int i, j, err; unsigned int u; @@ -2619,16 +2621,18 @@ static int alc_build_controls(struct hda_codec *codec) } /* assign Capture Source enums to NID */ - kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); - if (!kctl) - kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); - for (i = 0; kctl && i < kctl->count; i++) { - hda_nid_t *nids = spec->capsrc_nids; - if (!nids) - nids = spec->adc_nids; - err = snd_hda_add_nid(codec, kctl, i, nids[i]); - if (err < 0) - return err; + if (spec->capsrc_nids || spec->adc_nids) { + kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); + if (!kctl) + kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); + for (i = 0; kctl && i < kctl->count; i++) { + hda_nid_t *nids = spec->capsrc_nids; + if (!nids) + nids = spec->adc_nids; + err = snd_hda_add_nid(codec, kctl, i, nids[i]); + if (err < 0) + return err; + } } if (spec->cap_mixer) { const char *kname = kctl ? kctl->id.name : NULL; @@ -5176,8 +5180,24 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, #ifdef CONFIG_SND_HDA_INPUT_BEEP #define set_beep_amp(spec, nid, idx, dir) \ ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) + +static struct snd_pci_quirk beep_white_list[] = { + SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), + {} +}; + +static inline int has_cdefine_beep(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + const struct snd_pci_quirk *q; + q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); + if (q) + return q->value; + return spec->cdefine.enable_pcbeep; +} #else #define set_beep_amp(spec, nid, idx, dir) /* NOP */ +#define has_cdefine_beep(codec) 0 #endif /* @@ -6948,7 +6968,7 @@ static struct hda_input_mux mb5_capture_source = { .num_items = 3, .items = { { "Mic", 0x1 }, - { "Line", 0x2 }, + { "Line", 0x7 }, { "CD", 0x4 }, }, }; @@ -7469,8 +7489,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), + HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), @@ -7853,10 +7873,9 @@ static struct hda_verb alc885_mb5_init_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, { } }; @@ -9485,6 +9504,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), + SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, * so apparently no perfect solution yet */ @@ -10562,10 +10582,12 @@ static int patch_alc882(struct hda_codec *codec) } } - err = snd_hda_attach_beep_device(codec, 0x1); - if (err < 0) { - alc_free(codec); - return err; + if (has_cdefine_beep(codec)) { + err = snd_hda_attach_beep_device(codec, 0x1); + if (err < 0) { + alc_free(codec); + return err; + } } if (board_config != ALC882_AUTO) @@ -10615,7 +10637,7 @@ static int patch_alc882(struct hda_codec *codec) set_capture_mixer(codec); - if (spec->cdefine.enable_pcbeep) + if (has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); if (board_config == ALC882_AUTO) @@ -12431,7 +12453,7 @@ static int patch_alc262(struct hda_codec *codec) } } - if (!spec->no_analog) { + if (!spec->no_analog && has_cdefine_beep(codec)) { err = snd_hda_attach_beep_device(codec, 0x1); if (err < 0) { alc_free(codec); @@ -12482,7 +12504,7 @@ static int patch_alc262(struct hda_codec *codec) } if (!spec->cap_mixer && !spec->no_analog) set_capture_mixer(codec); - if (!spec->no_analog && spec->cdefine.enable_pcbeep) + if (!spec->no_analog && has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); spec->vmaster_nid = 0x0c; @@ -14454,10 +14476,12 @@ static int patch_alc269(struct hda_codec *codec) } } - err = snd_hda_attach_beep_device(codec, 0x1); - if (err < 0) { - alc_free(codec); - return err; + if (has_cdefine_beep(codec)) { + err = snd_hda_attach_beep_device(codec, 0x1); + if (err < 0) { + alc_free(codec); + return err; + } } if (board_config != ALC269_AUTO) @@ -14490,7 +14514,7 @@ static int patch_alc269(struct hda_codec *codec) if (!spec->cap_mixer) set_capture_mixer(codec); - if (spec->cdefine.enable_pcbeep) + if (has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); if (board_config == ALC269_AUTO) @@ -18687,10 +18711,12 @@ static int patch_alc662(struct hda_codec *codec) } } - err = snd_hda_attach_beep_device(codec, 0x1); - if (err < 0) { - alc_free(codec); - return err; + if (has_cdefine_beep(codec)) { + err = snd_hda_attach_beep_device(codec, 0x1); + if (err < 0) { + alc_free(codec); + return err; + } } if (board_config != ALC662_AUTO) @@ -18712,7 +18738,7 @@ static int patch_alc662(struct hda_codec *codec) if (!spec->cap_mixer) set_capture_mixer(codec); - if (spec->cdefine.enable_pcbeep) { + if (has_cdefine_beep(codec)) { switch (codec->vendor_id) { case 0x10ec0662: set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 6d943f6f6b70..2870a4fdc130 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -1055,7 +1055,7 @@ static int snd_trident_capture_prepare(struct snd_pcm_substream *substream) spin_lock_irq(&trident->reg_lock); - // Initilize the channel and set channel Mode + // Initialize the channel and set channel Mode outb(0, TRID_REG(trident, LEGACY_DMAR15)); // Set DMA channel operation mode register diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 495be6e71931..24454c98d0ee 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -300,7 +300,7 @@ struct snd_soc_dai au1xpsc_i2s_dai = { }; EXPORT_SYMBOL(au1xpsc_i2s_dai); -static int __init au1xpsc_i2s_drvprobe(struct platform_device *pdev) +static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) { struct resource *r; unsigned long sel; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 31ac5538fe7e..5da30eb6ad00 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -83,8 +83,8 @@ config SND_SOC_ALL_CODECS config SND_SOC_WM_HUBS tristate - default y if SND_SOC_WM8993=y - default m if SND_SOC_WM8993=m + default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y + default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m config SND_SOC_AC97_CODEC tristate diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index 1072621e93fd..9d1df2628136 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -127,6 +127,8 @@ static __devinit int wm8727_platform_probe(struct platform_device *pdev) goto err_codec; } + return 0; + err_codec: snd_soc_unregister_codec(codec); err: diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 7e4a627b4c7e..4e212ed62ea6 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -94,7 +94,6 @@ SOC_DAPM_SINGLE("Bypass Switch", WM8776_OUTMUX, 2, 1, 0), static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AUX"), -SND_SOC_DAPM_INPUT("AUX"), SND_SOC_DAPM_INPUT("AIN1"), SND_SOC_DAPM_INPUT("AIN2"), diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 0417dae32e6f..19ad590ca0b3 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -885,7 +885,6 @@ static int wm8988_register(struct wm8988_priv *wm8988, ret = snd_soc_register_dai(&wm8988_dai); if (ret != 0) { dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); goto err_codec; } diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 79f0f4ad242c..d3955096d872 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -612,7 +612,6 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) NUMDMA_MASK); mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); - mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); } if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { @@ -623,7 +622,6 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) NUMDMA_MASK); mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); - mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); } } diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 22208b373fb9..e1ec6d91ea38 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h @@ -73,7 +73,7 @@ struct psc_dma { }; /* Utility for retrieving psc_dma_stream structure from a substream */ -inline struct psc_dma_stream * +static inline struct psc_dma_stream * to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma) { if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 6a2764ee8203..3a501062c244 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -46,7 +46,7 @@ struct mpc8610_hpcd_data { }; /** - * mpc8610_hpcd_machine_probe: initalize the board + * mpc8610_hpcd_machine_probe: initialize the board * * This function is called when platform_device_add() is called. It is used * to initialize the board-specific hardware. diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 80b4fee2442b..4fd13d0791b8 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -23,7 +23,7 @@ * between pcm data and GPIO status data changes. Our FIQ handler is not * able to handle this, hence this driver only works with 48000Hz sampling * rate. - * Reading and writing AC97 registers is another challange. The core + * Reading and writing AC97 registers is another challenge. The core * provides us status bits when the read register is updated with *another* * value. When we read the same register two times (and the register still * contains the same value) these status bits are not set. We work diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 3396a0db06ba..ec4acac49ebd 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -683,20 +683,15 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, /* clock inversion (CKG2) */ data = 0; - switch (SH_FSI_INVERSION_MASK & flags) { - case SH_FSI_LRM_INV: - data = 1 << 12; - break; - case SH_FSI_BRM_INV: - data = 1 << 8; - break; - case SH_FSI_LRS_INV: - data = 1 << 4; - break; - case SH_FSI_BRS_INV: - data = 1 << 0; - break; - } + if (SH_FSI_LRM_INV & flags) + data |= 1 << 12; + if (SH_FSI_BRM_INV & flags) + data |= 1 << 8; + if (SH_FSI_LRS_INV & flags) + data |= 1 << 4; + if (SH_FSI_BRS_INV & flags) + data |= 1 << 0; + fsi_reg_write(fsi, CKG2, data); /* do fmt, di fmt */ @@ -726,15 +721,15 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, break; case SH_FSI_FMT_TDM: msg = "TDM"; - data = CR_FMT(CR_TDM) | (fsi->chan - 1); fsi->chan = is_play ? SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); + data = CR_FMT(CR_TDM) | (fsi->chan - 1); break; case SH_FSI_FMT_TDM_DELAY: msg = "TDM Delay"; - data = CR_FMT(CR_TDM_D) | (fsi->chan - 1); fsi->chan = is_play ? SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); + data = CR_FMT(CR_TDM_D) | (fsi->chan - 1); break; default: dev_err(dai->dev, "unknown format.\n"); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 998569d60330..e048e0910099 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1307,7 +1307,7 @@ cpu_dai_err: } /* - * Attempt to initialise any uninitalised cards. Must be called with + * Attempt to initialise any uninitialised cards. Must be called with * client_mutex. */ static void snd_soc_instantiate_cards(void) diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 71221fd20944..9eb1a4e0363b 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1010,7 +1010,7 @@ static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_de struct snd_amd7930 *amd; int err, irq; - irq = op->irqs[0]; + irq = op->archdata.irqs[0]; if (dev_num >= SNDRV_CARDS) return -ENODEV; @@ -1075,7 +1075,7 @@ static struct of_platform_driver amd7930_sbus_driver = { static int __init amd7930_init(void) { - return of_register_driver(&amd7930_sbus_driver, &of_bus_type); + return of_register_platform_driver(&amd7930_sbus_driver); } static void __exit amd7930_exit(void) @@ -1092,7 +1092,7 @@ static void __exit amd7930_exit(void) amd7930_list = NULL; - of_unregister_driver(&amd7930_sbus_driver); + of_unregister_platform_driver(&amd7930_sbus_driver); } module_init(amd7930_init); diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index fb4c6f2f29e5..68570ee2c9bb 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1832,14 +1832,14 @@ static int __devinit snd_cs4231_sbus_create(struct snd_card *card, chip->c_dma.request = sbus_dma_request; chip->c_dma.address = sbus_dma_addr; - if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt, + if (request_irq(op->archdata.irqs[0], snd_cs4231_sbus_interrupt, IRQF_SHARED, "cs4231", chip)) { snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n", - dev, op->irqs[0]); + dev, op->archdata.irqs[0]); snd_cs4231_sbus_free(chip); return -EBUSY; } - chip->irq[0] = op->irqs[0]; + chip->irq[0] = op->archdata.irqs[0]; if (snd_cs4231_probe(chip) < 0) { snd_cs4231_sbus_free(chip); @@ -1870,7 +1870,7 @@ static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_dev card->shortname, rp->flags & 0xffL, (unsigned long long)rp->start, - op->irqs[0]); + op->archdata.irqs[0]); err = snd_cs4231_sbus_create(card, op, dev); if (err < 0) { @@ -1979,12 +1979,12 @@ static int __devinit snd_cs4231_ebus_create(struct snd_card *card, chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; chip->c_dma.ebus_info.client_cookie = chip; - chip->c_dma.ebus_info.irq = op->irqs[0]; + chip->c_dma.ebus_info.irq = op->archdata.irqs[0]; strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; chip->p_dma.ebus_info.client_cookie = chip; - chip->p_dma.ebus_info.irq = op->irqs[1]; + chip->p_dma.ebus_info.irq = op->archdata.irqs[1]; chip->p_dma.prepare = _ebus_dma_prepare; chip->p_dma.enable = _ebus_dma_enable; @@ -2060,7 +2060,7 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev sprintf(card->longname, "%s at 0x%llx, irq %d", card->shortname, op->resource[0].start, - op->irqs[0]); + op->archdata.irqs[0]); err = snd_cs4231_ebus_create(card, op, dev); if (err < 0) { @@ -2120,12 +2120,12 @@ static struct of_platform_driver cs4231_driver = { static int __init cs4231_init(void) { - return of_register_driver(&cs4231_driver, &of_bus_type); + return of_register_platform_driver(&cs4231_driver); } static void __exit cs4231_exit(void) { - of_unregister_driver(&cs4231_driver); + of_unregister_platform_driver(&cs4231_driver); } module_init(cs4231_init); diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 1557bf132e73..c421901c48d0 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2608,7 +2608,7 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id return -ENOENT; } - irq = op->irqs[0]; + irq = op->archdata.irqs[0]; if (irq <= 0) { printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev); return -ENODEV; @@ -2699,12 +2699,12 @@ static struct of_platform_driver dbri_sbus_driver = { /* Probe for the dbri chip and then attach the driver. */ static int __init dbri_init(void) { - return of_register_driver(&dbri_sbus_driver, &of_bus_type); + return of_register_platform_driver(&dbri_sbus_driver); } static void __exit dbri_exit(void) { - of_unregister_driver(&dbri_sbus_driver); + of_unregister_platform_driver(&dbri_sbus_driver); } module_init(dbri_init); diff --git a/sound/usb/clock.c b/sound/usb/clock.c index b7aadd614c70..b5855114667e 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -103,7 +103,8 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - UAC2_CX_CLOCK_SELECTOR << 8, selector_id << 8, + UAC2_CX_CLOCK_SELECTOR << 8, + snd_usb_ctrl_intf(chip) | (selector_id << 8), &buf, sizeof(buf), 1000); if (ret < 0) @@ -120,7 +121,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_CLOCK_VALID << 8, source_id << 8, + UAC2_CS_CONTROL_CLOCK_VALID << 8, + snd_usb_ctrl_intf(chip) | (source_id << 8), &data, sizeof(data), 1000); if (err < 0) { @@ -269,7 +271,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, data[3] = rate >> 24; if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, - UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), data, sizeof(data), 1000)) < 0) { snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", dev->devnum, iface, fmt->altsetting, rate); @@ -278,7 +281,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), data, sizeof(data), 1000)) < 0) { snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", dev->devnum, iface, fmt->altsetting); diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 9593b91452b9..6f6596cf2b19 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -427,6 +427,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { kfree(fp->rate_table); kfree(fp); + fp = NULL; continue; } diff --git a/sound/usb/format.c b/sound/usb/format.c index 5367cd1e52d9..30364aba79cc 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -206,6 +206,60 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof } /* + * Helper function to walk the array of sample rate triplets reported by + * the device. The problem is that we need to parse whole array first to + * get to know how many sample rates we have to expect. + * Then fp->rate_table can be allocated and filled. + */ +static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, + const unsigned char *data) +{ + int i, nr_rates = 0; + + fp->rates = fp->rate_min = fp->rate_max = 0; + + for (i = 0; i < nr_triplets; i++) { + int min = combine_quad(&data[2 + 12 * i]); + int max = combine_quad(&data[6 + 12 * i]); + int res = combine_quad(&data[10 + 12 * i]); + int rate; + + if ((max < 0) || (min < 0) || (res < 0) || (max < min)) + continue; + + /* + * for ranges with res == 1, we announce a continuous sample + * rate range, and this function should return 0 for no further + * parsing. + */ + if (res == 1) { + fp->rate_min = min; + fp->rate_max = max; + fp->rates = SNDRV_PCM_RATE_CONTINUOUS; + return 0; + } + + for (rate = min; rate <= max; rate += res) { + if (fp->rate_table) + fp->rate_table[nr_rates] = rate; + if (!fp->rate_min || rate < fp->rate_min) + fp->rate_min = rate; + if (!fp->rate_max || rate > fp->rate_max) + fp->rate_max = rate; + fp->rates |= snd_pcm_rate_to_rate_bit(rate); + + nr_rates++; + + /* avoid endless loop */ + if (res == 0) + break; + } + } + + return nr_rates; +} + +/* * parse the format descriptor and stores the possible sample rates * on the audioformat table (audio class v2). */ @@ -215,13 +269,20 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, { struct usb_device *dev = chip->dev; unsigned char tmp[2], *data; - int i, nr_rates, data_size, ret = 0; + int nr_triplets, data_size, ret = 0; int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock); + if (clock < 0) { + snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", + __func__, clock); + goto err; + } + /* get the number of sample rates first by only fetching 2 bytes */ ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), tmp, sizeof(tmp), 1000); if (ret < 0) { @@ -230,8 +291,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, goto err; } - nr_rates = (tmp[1] << 8) | tmp[0]; - data_size = 2 + 12 * nr_rates; + nr_triplets = (tmp[1] << 8) | tmp[0]; + data_size = 2 + 12 * nr_triplets; data = kzalloc(data_size, GFP_KERNEL); if (!data) { ret = -ENOMEM; @@ -241,7 +302,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, /* now get the full information */ ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), data, data_size, 1000); if (ret < 0) { @@ -251,26 +313,28 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, goto err_free; } - fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); + /* Call the triplet parser, and make sure fp->rate_table is NULL. + * We just use the return value to know how many sample rates we + * will have to deal with. */ + kfree(fp->rate_table); + fp->rate_table = NULL; + fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data); + + if (fp->nr_rates == 0) { + /* SNDRV_PCM_RATE_CONTINUOUS */ + ret = 0; + goto err_free; + } + + fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); if (!fp->rate_table) { ret = -ENOMEM; goto err_free; } - fp->nr_rates = 0; - fp->rate_min = fp->rate_max = 0; - - for (i = 0; i < nr_rates; i++) { - int rate = combine_quad(&data[2 + 12 * i]); - - fp->rate_table[fp->nr_rates] = rate; - if (!fp->rate_min || rate < fp->rate_min) - fp->rate_min = rate; - if (!fp->rate_max || rate > fp->rate_max) - fp->rate_max = rate; - fp->rates |= snd_pcm_rate_to_rate_bit(rate); - fp->nr_rates++; - } + /* Call the triplet parser again, but this time, fp->rate_table is + * allocated, so the rates will be stored */ + parse_uac2_sample_rate_range(fp, nr_triplets, data); err_free: kfree(data); diff --git a/sound/usb/helper.h b/sound/usb/helper.h index a6b0e51b3a9a..09bd943c43bf 100644 --- a/sound/usb/helper.h +++ b/sound/usb/helper.h @@ -28,5 +28,9 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, #define snd_usb_get_speed(dev) ((dev)->speed) #endif +static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip) +{ + return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber; +} #endif /* __USBAUDIO_HELPER_H */ diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index a060d005e209..736d134cc03c 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -297,20 +297,27 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) { - unsigned char buf[14]; /* enough space for one range of 4 bytes */ + unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ unsigned char *val; - int ret; + int ret, size; __u8 bRequest; - bRequest = (request == UAC_GET_CUR) ? - UAC2_CS_CUR : UAC2_CS_RANGE; + if (request == UAC_GET_CUR) { + bRequest = UAC2_CS_CUR; + size = sizeof(__u16); + } else { + bRequest = UAC2_CS_RANGE; + size = sizeof(buf); + } + + memset(buf, 0, sizeof(buf)); ret = snd_usb_ctl_msg(cval->mixer->chip->dev, usb_rcvctrlpipe(cval->mixer->chip->dev, 0), bRequest, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx, cval->mixer->ctrlif | (cval->id << 8), - buf, sizeof(buf), 1000); + buf, size, 1000); if (ret < 0) { snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", @@ -318,6 +325,8 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v return ret; } + /* FIXME: how should we handle multiple triplets here? */ + switch (request) { case UAC_GET_CUR: val = buf; @@ -1098,6 +1107,19 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, } break; + case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x0991): + /* Most audio usb devices lie about volume resolution. + * Most Logitech webcams have res = 384. + * Proboly there is some logitech magic behind this number --fishor + */ + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + snd_printk(KERN_INFO + "set resolution quirk: cval->res = 384\n"); + cval->res = 384; + } + break; + } snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 456829882f40..3634cedf9306 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -636,7 +636,7 @@ static int hw_rule_period_time(struct snd_pcm_hw_params *params, min_datainterval = min(min_datainterval, fp->datainterval); } if (min_datainterval == 0xff) { - hwc_debug(" --> get emtpy\n"); + hwc_debug(" --> get empty\n"); it->empty = 1; return -EINVAL; } |