diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-02-26 11:29:03 (GMT) |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-03-23 12:19:41 (GMT) |
commit | 5e56bcea5017b7b7808df60f21ef01738b6e1a25 (patch) | |
tree | bf841e780837f867d8e842928440537e1eb465cc /sound/hda | |
parent | faa75f8a2edf005a5caf43be4875ffeeb9bcb498 (diff) | |
download | linux-5e56bcea5017b7b7808df60f21ef01738b6e1a25.tar.xz |
ALSA: hda - Allow driver to add vendor-specific verbs for regmap
Codecs may have own vendor-specific verbs, and we need to allow each
driver to give such verbs for cached accesses. Here a verb can be put
into a single array and looked through it at readable and writeable
callbacks.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/hda')
-rw-r--r-- | sound/hda/hdac_regmap.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c index 933907b..486ef72 100644 --- a/sound/hda/hdac_regmap.c +++ b/sound/hda/hdac_regmap.c @@ -60,6 +60,13 @@ static bool hda_writeable_reg(struct device *dev, unsigned int reg) { struct hdac_device *codec = dev_to_hdac_dev(dev); unsigned int verb = get_verb(reg); + int i; + + for (i = 0; i < codec->vendor_verbs.used; i++) { + unsigned int *v = snd_array_elem(&codec->vendor_verbs, i); + if (verb == *v) + return true; + } if (codec->caps_overwriting) return true; @@ -200,6 +207,7 @@ int snd_hdac_regmap_init(struct hdac_device *codec) if (IS_ERR(regmap)) return PTR_ERR(regmap); codec->regmap = regmap; + snd_array_init(&codec->vendor_verbs, sizeof(unsigned int), 8); return 0; } EXPORT_SYMBOL_GPL(snd_hdac_regmap_init); @@ -209,10 +217,30 @@ void snd_hdac_regmap_exit(struct hdac_device *codec) if (codec->regmap) { regmap_exit(codec->regmap); codec->regmap = NULL; + snd_array_free(&codec->vendor_verbs); } } EXPORT_SYMBOL_GPL(snd_hdac_regmap_exit); +/** + * snd_hdac_regmap_add_vendor_verb - add a vendor-specific verb to regmap + * @codec: the codec object + * @verb: verb to allow accessing via regmap + * + * Returns zero for success or a negative error code. + */ +int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec, + unsigned int verb) +{ + unsigned int *p = snd_array_new(&codec->vendor_verbs); + + if (!p) + return -ENOMEM; + *p = verb; + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_regmap_add_vendor_verb); + /* * helper functions */ |