diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 11:34:25 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 11:34:25 -0800 |
commit | 460dc1eecf37263c8e3b17685ef236f0d236facb (patch) | |
tree | 1d20e367cefccddb969b48afaab140b8125cea4e /sound/pci/hda/hda_hwdep.c | |
parent | 024e4ec1856d57bb78c06ec903d29dcf716f5f47 (diff) | |
parent | b531f81b0d70ffbe8d70500512483227cc532608 (diff) |
Merge tag 'sound-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"The biggest change in this update is the unification of HD-audio codec
parsers. Now the HD-audio codec is parsed in a generic parser code
which is invoked by each HD-audio codec driver.
Some background information is found in David Henningsson's blog
entry:
http://voices.canonical.com/david.henningsson/2013/01/18/upcoming-changes-to-the-intel-hda-drivers/
Other than that, some random updates/fixes like USB-audio and a bunch
of small AoC updates as usual.
Highlights:
- Unification of HD-audio parser code (aka generic parser)
- Support of new Intel HD-audio controller, new IDT codecs
- Fixes for HD-audio HDMI audio hotplug
- Haswell HDMI audio fixup
- Support of Creative CA0132 DSP code
- A few fixes of HDSP driver
- USB-audio fix for Roland A-PRO, M-Audio FT C600
- Support PM for aloop driver (and fixes Oops)
- Compress API updates for gapless playback support
For ASoC part:
- Support for a wider range of hardware in the compressed stream code
- The ability to mute capture streams as well as playback streams
while inactive
- DT support for AK4642, FSI, Samsung I2S and WM8962
- AC'97 support for Tegra
- New driver for max98090, replacing the stub which was there
- A new driver from Dialog
Note that due to dependencies, DTification of DMA support for Samsung
platforms (used only by the and I2S driver and SPI) is merged here as
well."
Fix up trivial conflict in drivers/spi/spi-s3c64xx.c due to removed code
being changed.
* tag 'sound-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (453 commits)
ALSA: usb: Fix Processing Unit Descriptor parsers
ALSA: hda - hdmi: Notify userspace when ELD control changes
ALSA: hda - hdmi: Protect ELD buffer
ALSA: hda - hdmi: Refactor hdmi_eld into parsed_hdmi_eld
ALSA: hda - hdmi: Do not expose eld data when eld is invalid
ALSA: hda - hdmi: ELD shouldn't be valid after unplug
ALSA: hda - Fix the silent speaker output on Fujitsu S7020 laptop
ALSA: hda - add quirks for mute LED on two HP machines
ALSA: usb/quirks, fix out-of-bounds access
ASoC: codecs: Add da7213 codec
ALSA: au88x0 - Define channel map for au88x0
ALSA: compress: add support for gapless playback
ALSA: hda - Remove speaker clicks on CX20549
ALSA: hda - Disable runtime PM for Intel 5 Series/3400
ALSA: hda - Increase badness for missing multi-io
ASoC: arizona: Automatically manage input mutes
ALSA: hda - Fix broken workaround for HDMI/SPDIF conflicts
ALSA: hda/ca0132 - Add missing \n to debug prints
ALSA: hda/ca0132 - Fix type of INVALID_CHIP_ADDRESS
ALSA: hda - update documentation for no-primary-hp fixup
...
Diffstat (limited to 'sound/pci/hda/hda_hwdep.c')
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 87 |
1 files changed, 69 insertions, 18 deletions
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index a5c9411bb36..ce67608734b 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -148,6 +148,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec) hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; #endif + mutex_init(&codec->user_mutex); snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32); snd_array_init(&codec->hints, sizeof(struct hda_hint), 32); snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16); @@ -346,12 +347,14 @@ static ssize_t init_verbs_show(struct device *dev, struct snd_hwdep *hwdep = dev_get_drvdata(dev); struct hda_codec *codec = hwdep->private_data; int i, len = 0; + mutex_lock(&codec->user_mutex); for (i = 0; i < codec->init_verbs.used; i++) { struct hda_verb *v = snd_array_elem(&codec->init_verbs, i); len += snprintf(buf + len, PAGE_SIZE - len, "0x%02x 0x%03x 0x%04x\n", v->nid, v->verb, v->param); } + mutex_unlock(&codec->user_mutex); return len; } @@ -364,12 +367,16 @@ static int parse_init_verbs(struct hda_codec *codec, const char *buf) return -EINVAL; if (!nid || !verb) return -EINVAL; + mutex_lock(&codec->user_mutex); v = snd_array_new(&codec->init_verbs); - if (!v) + if (!v) { + mutex_unlock(&codec->user_mutex); return -ENOMEM; + } v->nid = nid; v->verb = verb; v->param = param; + mutex_unlock(&codec->user_mutex); return 0; } @@ -392,11 +399,13 @@ static ssize_t hints_show(struct device *dev, struct snd_hwdep *hwdep = dev_get_drvdata(dev); struct hda_codec *codec = hwdep->private_data; int i, len = 0; + mutex_lock(&codec->user_mutex); for (i = 0; i < codec->hints.used; i++) { struct hda_hint *hint = snd_array_elem(&codec->hints, i); len += snprintf(buf + len, PAGE_SIZE - len, "%s = %s\n", hint->key, hint->val); } + mutex_unlock(&codec->user_mutex); return len; } @@ -431,6 +440,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf) { char *key, *val; struct hda_hint *hint; + int err = 0; buf = skip_spaces(buf); if (!*buf || *buf == '#' || *buf == '\n') @@ -450,26 +460,31 @@ static int parse_hints(struct hda_codec *codec, const char *buf) val = skip_spaces(val); remove_trail_spaces(key); remove_trail_spaces(val); + mutex_lock(&codec->user_mutex); hint = get_hint(codec, key); if (hint) { /* replace */ kfree(hint->key); hint->key = key; hint->val = val; - return 0; + goto unlock; } /* allocate a new hint entry */ if (codec->hints.used >= MAX_HINTS) hint = NULL; else hint = snd_array_new(&codec->hints); - if (!hint) { - kfree(key); - return -ENOMEM; + if (hint) { + hint->key = key; + hint->val = val; + } else { + err = -ENOMEM; } - hint->key = key; - hint->val = val; - return 0; + unlock: + mutex_unlock(&codec->user_mutex); + if (err) + kfree(key); + return err; } static ssize_t hints_store(struct device *dev, @@ -489,11 +504,13 @@ static ssize_t pin_configs_show(struct hda_codec *codec, char *buf) { int i, len = 0; + mutex_lock(&codec->user_mutex); for (i = 0; i < list->used; i++) { struct hda_pincfg *pin = snd_array_elem(list, i); len += sprintf(buf + len, "0x%02x 0x%08x\n", pin->nid, pin->cfg); } + mutex_unlock(&codec->user_mutex); return len; } @@ -528,13 +545,16 @@ static ssize_t driver_pin_configs_show(struct device *dev, static int parse_user_pin_configs(struct hda_codec *codec, const char *buf) { - int nid, cfg; + int nid, cfg, err; if (sscanf(buf, "%i %i", &nid, &cfg) != 2) return -EINVAL; if (!nid) return -EINVAL; - return snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg); + mutex_lock(&codec->user_mutex); + err = snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg); + mutex_unlock(&codec->user_mutex); + return err; } static ssize_t user_pin_configs_store(struct device *dev, @@ -600,19 +620,50 @@ EXPORT_SYMBOL_HDA(snd_hda_get_hint); int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) { - const char *p = snd_hda_get_hint(codec, key); + const char *p; + int ret; + + mutex_lock(&codec->user_mutex); + p = snd_hda_get_hint(codec, key); if (!p || !*p) - return -ENOENT; - switch (toupper(*p)) { - case 'T': /* true */ - case 'Y': /* yes */ - case '1': - return 1; + ret = -ENOENT; + else { + switch (toupper(*p)) { + case 'T': /* true */ + case 'Y': /* yes */ + case '1': + ret = 1; + break; + default: + ret = 0; + break; + } } - return 0; + mutex_unlock(&codec->user_mutex); + return ret; } EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); +int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp) +{ + const char *p; + unsigned long val; + int ret; + + mutex_lock(&codec->user_mutex); + p = snd_hda_get_hint(codec, key); + if (!p) + ret = -ENOENT; + else if (strict_strtoul(p, 0, &val)) + ret = -EINVAL; + else { + *valp = val; + ret = 0; + } + mutex_unlock(&codec->user_mutex); + return ret; +} +EXPORT_SYMBOL_HDA(snd_hda_get_int_hint); #endif /* CONFIG_SND_HDA_RECONFIG */ #ifdef CONFIG_SND_HDA_PATCH_LOADER |