diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-02-26 06:29:03 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-03-23 08:19:41 -0400 |
commit | 5e56bcea5017b7b7808df60f21ef01738b6e1a25 (patch) | |
tree | bf841e780837f867d8e842928440537e1eb465cc /sound/hda | |
parent | faa75f8a2edf005a5caf43be4875ffeeb9bcb498 (diff) |
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 933907b16457..486ef720cbff 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) | |||
60 | { | 60 | { |
61 | struct hdac_device *codec = dev_to_hdac_dev(dev); | 61 | struct hdac_device *codec = dev_to_hdac_dev(dev); |
62 | unsigned int verb = get_verb(reg); | 62 | unsigned int verb = get_verb(reg); |
63 | int i; | ||
64 | |||
65 | for (i = 0; i < codec->vendor_verbs.used; i++) { | ||
66 | unsigned int *v = snd_array_elem(&codec->vendor_verbs, i); | ||
67 | if (verb == *v) | ||
68 | return true; | ||
69 | } | ||
63 | 70 | ||
64 | if (codec->caps_overwriting) | 71 | if (codec->caps_overwriting) |
65 | return true; | 72 | return true; |
@@ -200,6 +207,7 @@ int snd_hdac_regmap_init(struct hdac_device *codec) | |||
200 | if (IS_ERR(regmap)) | 207 | if (IS_ERR(regmap)) |
201 | return PTR_ERR(regmap); | 208 | return PTR_ERR(regmap); |
202 | codec->regmap = regmap; | 209 | codec->regmap = regmap; |
210 | snd_array_init(&codec->vendor_verbs, sizeof(unsigned int), 8); | ||
203 | return 0; | 211 | return 0; |
204 | } | 212 | } |
205 | EXPORT_SYMBOL_GPL(snd_hdac_regmap_init); | 213 | EXPORT_SYMBOL_GPL(snd_hdac_regmap_init); |
@@ -209,10 +217,30 @@ void snd_hdac_regmap_exit(struct hdac_device *codec) | |||
209 | if (codec->regmap) { | 217 | if (codec->regmap) { |
210 | regmap_exit(codec->regmap); | 218 | regmap_exit(codec->regmap); |
211 | codec->regmap = NULL; | 219 | codec->regmap = NULL; |
220 | snd_array_free(&codec->vendor_verbs); | ||
212 | } | 221 | } |
213 | } | 222 | } |
214 | EXPORT_SYMBOL_GPL(snd_hdac_regmap_exit); | 223 | EXPORT_SYMBOL_GPL(snd_hdac_regmap_exit); |
215 | 224 | ||
225 | /** | ||
226 | * snd_hdac_regmap_add_vendor_verb - add a vendor-specific verb to regmap | ||
227 | * @codec: the codec object | ||
228 | * @verb: verb to allow accessing via regmap | ||
229 | * | ||
230 | * Returns zero for success or a negative error code. | ||
231 | */ | ||
232 | int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec, | ||
233 | unsigned int verb) | ||
234 | { | ||
235 | unsigned int *p = snd_array_new(&codec->vendor_verbs); | ||
236 | |||
237 | if (!p) | ||
238 | return -ENOMEM; | ||
239 | *p = verb; | ||
240 | return 0; | ||
241 | } | ||
242 | EXPORT_SYMBOL_GPL(snd_hdac_regmap_add_vendor_verb); | ||
243 | |||
216 | /* | 244 | /* |
217 | * helper functions | 245 | * helper functions |
218 | */ | 246 | */ |