mirror of https://gitee.com/openkylin/linux.git
Sound fixes for 3.9-rc6
This contains slightly more volumes than usual at this stage, mostly because of my vacation in the last week. Nothing to scare, all small and/or trivial fixes: - Fix loop path handling in ASoC DAPM - Some memory handling fixes in ASoC core - Fix spear_pcm to adapt to the updated API - HD-audio HDMI ELD handling fixes - Fix for CM6331 USB-audio SRC change bugs - Revert power_save_controller option change due to user-space usage - A few other small ASoC and HD-audio fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJRXl85AAoJEGwxgFQ9KSmkDzAQALJU/3Bn/tRJMFDwmVPYbuoi /mJ8iTBLz7uvKTnGaOIPg+vrt2SOkpcfE/bkv2d8GL/YMbXC7RY2j+37D8LYlnZQ rhUlM7VbkFsmoXR9GtgeWdZyrQSVNi7KFCfNLSNZmZAkDkopq0VzW4Ll+q4wyPWQ taZDQ0g3fnbAegiri246cb8nKH8gTzKRG16I/5N1S7fxLinQ6u5W4IPu9jHxNhiW sOyQOXwYp7CpgmqKBbjES8oncbgwSnk55YPY3Si+vfYIHy18yR9yCNyGsrGN8M0W c4oTU8EoNzGrwE4/+MSvkWwA4qYBEqRkEwS8eL2QlcyNpeZq1mROWnEa1BZz3PJ/ uw4M5GrVYFD/w95XRX/hJmenQelSV5S2EfCmxAbMQwXX9je2q9RzM0AeaORNUPYT Iy8S4+d9KBWBcLxmAASLUPTk5nl4bTPW/yy/Cb5ICQdnhHGTmKnJjQdIbP9tiiDD jfnftPUDBONRnCe24AtxQzDmj2wfikkMkQoR/nENKKR+u56zy6Le+m4zmv7OlfLX lqcWHh/Sgsg+B960GUPZSEqpDaXA5hkpXTz/foWbeu8Go0JVQTV9/+HDomrfP0VE EoRrApZf35PBSo2rqC6lyKhAp+OgWKmXoWelzCY3//4kYXl2cEK1voa5zFhgVRGD tccXSAxPyW4HsIg+4hqF =L1Ya -----END PGP SIGNATURE----- Merge tag 'sound-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "This contains slightly more volumes than usual at this stage, mostly because of my vacation in the last week. Nothing to scare, all small and/or trivial fixes: - Fix loop path handling in ASoC DAPM - Some memory handling fixes in ASoC core - Fix spear_pcm to adapt to the updated API - HD-audio HDMI ELD handling fixes - Fix for CM6331 USB-audio SRC change bugs - Revert power_save_controller option change due to user-space usage - A few other small ASoC and HD-audio fixes" * tag 'sound-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda/generic - fix uninitialized variable Revert "ALSA: hda - Allow power_save_controller option override DCAPS" ALSA: hda - fix typo in proc output ALSA: hda - Enabling Realtek ALC 671 codec ALSA: usb: Work around CM6631 sample rate change bug ALSA: hda - bug fix on HDMI ELD debug message ALSA: hda - bug fix on return value when getting HDMI ELD info ASoC: dma-sh7760: Fix compile error ASoC: core: fix invalid free of devm_ allocated data ASoC: spear_pcm: Update to new pcm_new() API ASoC:: max98090: Remove executable bit ASoC: dapm: Fix pointer dereference in is_connected_output_ep() ASoC: pcm030 audio fabric: remove __init from probe ASoC: imx-ssi: Fix occasional AC97 reset failure ASoC: core: fix possible memory leak in snd_soc_bytes_put() ASoC: wm_adsp: fix possible memory leak in wm_adsp_load_coeff() ASoC: dapm: Fix handling of loops ASoC: si476x: Add missing break for SNDRV_PCM_FORMAT_S8 switch case
This commit is contained in:
commit
8f09aacfa6
|
@ -890,9 +890,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
enable_msi - Enable Message Signaled Interrupt (MSI) (default = off)
|
||||
power_save - Automatic power-saving timeout (in second, 0 =
|
||||
disable)
|
||||
power_save_controller - Support runtime D3 of HD-audio controller
|
||||
(-1 = on for supported chip (default), false = off,
|
||||
true = force to on even for unsupported hardware)
|
||||
power_save_controller - Reset HD-audio controller in power-saving mode
|
||||
(default = on)
|
||||
align_buffer_size - Force rounding of buffer/period sizes to multiples
|
||||
of 128 bytes. This is more efficient in terms of memory
|
||||
access but isn't required by the HDA spec and prevents
|
||||
|
|
|
@ -488,6 +488,7 @@ struct snd_soc_dapm_path {
|
|||
/* status */
|
||||
u32 connect:1; /* source and sink widgets are connected */
|
||||
u32 walked:1; /* path has been walked */
|
||||
u32 walking:1; /* path is in the process of being walked */
|
||||
u32 weak:1; /* path ignored for power management */
|
||||
|
||||
int (*connected)(struct snd_soc_dapm_widget *source,
|
||||
|
|
|
@ -173,7 +173,7 @@ const char *snd_hda_get_jack_type(u32 cfg)
|
|||
"Line Out", "Speaker", "HP Out", "CD",
|
||||
"SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
|
||||
"Line In", "Aux", "Mic", "Telephony",
|
||||
"SPDIF In", "Digitial In", "Reserved", "Other"
|
||||
"SPDIF In", "Digital In", "Reserved", "Other"
|
||||
};
|
||||
|
||||
return jack_types[(cfg & AC_DEFCFG_DEVICE)
|
||||
|
|
|
@ -320,7 +320,7 @@ int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
|
|||
unsigned char *buf, int *eld_size)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int size;
|
||||
|
||||
/*
|
||||
|
|
|
@ -740,7 +740,7 @@ EXPORT_SYMBOL_HDA(snd_hda_activate_path);
|
|||
static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path)
|
||||
{
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
bool changed;
|
||||
bool changed = false;
|
||||
int i;
|
||||
|
||||
if (!spec->power_down_unused || path->active)
|
||||
|
|
|
@ -134,8 +134,8 @@ MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
|
|||
* this may give more power-saving, but will take longer time to
|
||||
* wake up.
|
||||
*/
|
||||
static int power_save_controller = -1;
|
||||
module_param(power_save_controller, bint, 0644);
|
||||
static bool power_save_controller = 1;
|
||||
module_param(power_save_controller, bool, 0644);
|
||||
MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
@ -2931,8 +2931,6 @@ static int azx_runtime_idle(struct device *dev)
|
|||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct azx *chip = card->private_data;
|
||||
|
||||
if (power_save_controller > 0)
|
||||
return 0;
|
||||
if (!power_save_controller ||
|
||||
!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
|
||||
return -EBUSY;
|
||||
|
|
|
@ -1196,7 +1196,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
|
|||
|
||||
_snd_printd(SND_PR_VERBOSE,
|
||||
"HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
|
||||
codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
|
||||
codec->addr, pin_nid, pin_eld->monitor_present, eld->eld_valid);
|
||||
|
||||
if (eld->eld_valid) {
|
||||
if (snd_hdmi_get_eld(codec, pin_nid, eld->eld_buffer,
|
||||
|
|
|
@ -3440,7 +3440,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
|
|||
const hda_nid_t *ssids;
|
||||
|
||||
if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
|
||||
codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
|
||||
codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 ||
|
||||
codec->vendor_id == 0x10ec0671)
|
||||
ssids = alc663_ssids;
|
||||
else
|
||||
ssids = alc662_ssids;
|
||||
|
@ -3894,6 +3895,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
|
|||
{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
|
||||
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
|
||||
{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
|
||||
|
|
|
@ -159,6 +159,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
|
|||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S8:
|
||||
width = SI476X_PCM_FORMAT_S8;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
width = SI476X_PCM_FORMAT_S16_LE;
|
||||
break;
|
||||
|
|
|
@ -828,7 +828,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
|
|||
&buf_list);
|
||||
if (!buf) {
|
||||
adsp_err(dsp, "Out of memory\n");
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto out_fw;
|
||||
}
|
||||
|
||||
adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
|
||||
|
@ -865,7 +866,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
|
|||
wm_adsp_buf_free(&buf_list);
|
||||
out:
|
||||
kfree(file);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wm_adsp1_init(struct wm_adsp *adsp)
|
||||
|
|
|
@ -496,6 +496,8 @@ static void imx_ssi_ac97_reset(struct snd_ac97 *ac97)
|
|||
|
||||
if (imx_ssi->ac97_reset)
|
||||
imx_ssi->ac97_reset(ac97);
|
||||
/* First read sometimes fails, do a dummy read */
|
||||
imx_ssi_ac97_read(ac97, 0);
|
||||
}
|
||||
|
||||
static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
|
||||
|
@ -504,6 +506,9 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
|
|||
|
||||
if (imx_ssi->ac97_warm_reset)
|
||||
imx_ssi->ac97_warm_reset(ac97);
|
||||
|
||||
/* First read sometimes fails, do a dummy read */
|
||||
imx_ssi_ac97_read(ac97, 0);
|
||||
}
|
||||
|
||||
struct snd_ac97_bus_ops soc_ac97_ops = {
|
||||
|
|
|
@ -51,7 +51,7 @@ static struct snd_soc_card pcm030_card = {
|
|||
.num_links = ARRAY_SIZE(pcm030_fabric_dai),
|
||||
};
|
||||
|
||||
static int __init pcm030_fabric_probe(struct platform_device *op)
|
||||
static int pcm030_fabric_probe(struct platform_device *op)
|
||||
{
|
||||
struct device_node *np = op->dev.of_node;
|
||||
struct device_node *platform_np;
|
||||
|
|
|
@ -342,8 +342,8 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_platform sh7760_soc_platform = {
|
||||
.pcm_ops = &camelot_pcm_ops,
|
||||
static struct snd_soc_platform_driver sh7760_soc_platform = {
|
||||
.ops = &camelot_pcm_ops,
|
||||
.pcm_new = camelot_pcm_new,
|
||||
.pcm_free = camelot_pcm_free,
|
||||
};
|
||||
|
|
|
@ -3140,7 +3140,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
|
|||
if (params->mask) {
|
||||
ret = regmap_read(codec->control_data, params->base, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
val &= params->mask;
|
||||
|
||||
|
@ -3158,13 +3158,15 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
|
|||
((u32 *)data)[0] |= cpu_to_be32(val);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_raw_write(codec->control_data, params->base,
|
||||
data, len);
|
||||
|
||||
out:
|
||||
kfree(data);
|
||||
|
||||
return ret;
|
||||
|
@ -4197,7 +4199,6 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||
dev_err(card->dev,
|
||||
"ASoC: Property '%s' index %d could not be read: %d\n",
|
||||
propname, 2 * i, ret);
|
||||
kfree(routes);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = of_property_read_string_index(np, propname,
|
||||
|
@ -4206,7 +4207,6 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
|||
dev_err(card->dev,
|
||||
"ASoC: Property '%s' index %d could not be read: %d\n",
|
||||
propname, (2 * i) + 1, ret);
|
||||
kfree(routes);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -831,6 +831,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
|
|||
if (path->weak)
|
||||
continue;
|
||||
|
||||
if (path->walking)
|
||||
return 1;
|
||||
|
||||
if (path->walked)
|
||||
continue;
|
||||
|
||||
|
@ -838,6 +841,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
|
|||
|
||||
if (path->sink && path->connect) {
|
||||
path->walked = 1;
|
||||
path->walking = 1;
|
||||
|
||||
/* do we need to add this widget to the list ? */
|
||||
if (list) {
|
||||
|
@ -847,11 +851,14 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
|
|||
dev_err(widget->dapm->dev,
|
||||
"ASoC: could not add widget %s\n",
|
||||
widget->name);
|
||||
path->walking = 0;
|
||||
return con;
|
||||
}
|
||||
}
|
||||
|
||||
con += is_connected_output_ep(path->sink, list);
|
||||
|
||||
path->walking = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -931,6 +938,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
|
|||
if (path->weak)
|
||||
continue;
|
||||
|
||||
if (path->walking)
|
||||
return 1;
|
||||
|
||||
if (path->walked)
|
||||
continue;
|
||||
|
||||
|
@ -938,6 +948,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
|
|||
|
||||
if (path->source && path->connect) {
|
||||
path->walked = 1;
|
||||
path->walking = 1;
|
||||
|
||||
/* do we need to add this widget to the list ? */
|
||||
if (list) {
|
||||
|
@ -947,11 +958,14 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
|
|||
dev_err(widget->dapm->dev,
|
||||
"ASoC: could not add widget %s\n",
|
||||
widget->name);
|
||||
path->walking = 0;
|
||||
return con;
|
||||
}
|
||||
}
|
||||
|
||||
con += is_connected_input_ep(path->source, list);
|
||||
|
||||
path->walking = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -149,9 +149,9 @@ static void spear_pcm_free(struct snd_pcm *pcm)
|
|||
|
||||
static u64 spear_pcm_dmamask = DMA_BIT_MASK(32);
|
||||
|
||||
static int spear_pcm_new(struct snd_card *card,
|
||||
struct snd_soc_dai *dai, struct snd_pcm *pcm)
|
||||
static int spear_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_card *card = rtd->card->snd_card;
|
||||
int ret;
|
||||
|
||||
if (!card->dev->dma_mask)
|
||||
|
@ -159,16 +159,16 @@ static int spear_pcm_new(struct snd_card *card,
|
|||
if (!card->dev->coherent_dma_mask)
|
||||
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
if (dai->driver->playback.channels_min) {
|
||||
ret = spear_pcm_preallocate_dma_buffer(pcm,
|
||||
if (rtd->cpu_dai->driver->playback.channels_min) {
|
||||
ret = spear_pcm_preallocate_dma_buffer(rtd->pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK,
|
||||
spear_pcm_hardware.buffer_bytes_max);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dai->driver->capture.channels_min) {
|
||||
ret = spear_pcm_preallocate_dma_buffer(pcm,
|
||||
if (rtd->cpu_dai->driver->capture.channels_min) {
|
||||
ret = spear_pcm_preallocate_dma_buffer(rtd->pcm,
|
||||
SNDRV_PCM_STREAM_CAPTURE,
|
||||
spear_pcm_hardware.buffer_bytes_max);
|
||||
if (ret)
|
||||
|
|
|
@ -253,7 +253,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
|
|||
{
|
||||
struct usb_device *dev = chip->dev;
|
||||
unsigned char data[4];
|
||||
int err, crate;
|
||||
int err, cur_rate, prev_rate;
|
||||
int clock = snd_usb_clock_find_source(chip, fmt->clock);
|
||||
|
||||
if (clock < 0)
|
||||
|
@ -266,6 +266,19 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
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,
|
||||
snd_usb_ctrl_intf(chip) | (clock << 8),
|
||||
data, sizeof(data));
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
|
||||
dev->devnum, iface, fmt->altsetting);
|
||||
prev_rate = 0;
|
||||
} else {
|
||||
prev_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
|
||||
}
|
||||
|
||||
data[0] = rate;
|
||||
data[1] = rate >> 8;
|
||||
data[2] = rate >> 16;
|
||||
|
@ -280,19 +293,31 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
|
|||
return err;
|
||||
}
|
||||
|
||||
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,
|
||||
snd_usb_ctrl_intf(chip) | (clock << 8),
|
||||
data, sizeof(data))) < 0) {
|
||||
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,
|
||||
snd_usb_ctrl_intf(chip) | (clock << 8),
|
||||
data, sizeof(data));
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
|
||||
dev->devnum, iface, fmt->altsetting);
|
||||
return err;
|
||||
cur_rate = 0;
|
||||
} else {
|
||||
cur_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
|
||||
}
|
||||
|
||||
crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
|
||||
if (crate != rate)
|
||||
snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
|
||||
if (cur_rate != rate) {
|
||||
snd_printd(KERN_WARNING
|
||||
"current rate %d is different from the runtime rate %d\n",
|
||||
cur_rate, rate);
|
||||
}
|
||||
|
||||
/* Some devices doesn't respond to sample rate changes while the
|
||||
* interface is active. */
|
||||
if (rate != prev_rate) {
|
||||
usb_set_interface(dev, iface, 0);
|
||||
usb_set_interface(dev, iface, fmt->altsetting);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue