summaryrefslogtreecommitdiffstats
path: root/sound/hda/hdac_device.c
diff options
context:
space:
mode:
authorTakashi Iwai2015-04-04 12:15:32 +0200
committerTakashi Iwai2015-04-04 12:16:30 +0200
commit664bc5c55923712a8aabd2a390ed7477325e32df (patch)
tree6382fd31d0fab7699fb2ff6b0501275700dd5b85 /sound/hda/hdac_device.c
parentALSA: hda - Fix subsystem ID read regression (diff)
parentALSA: hda - Set use_single_rw flag for regmap (diff)
downloadkernel-qcow2-linux-664bc5c55923712a8aabd2a390ed7477325e32df.tar.gz
kernel-qcow2-linux-664bc5c55923712a8aabd2a390ed7477325e32df.tar.xz
kernel-qcow2-linux-664bc5c55923712a8aabd2a390ed7477325e32df.zip
Merge branch 'topic/hda-regmap' into for-next
This merges the support of regmap in HD-audio infrastructure. Many in-house cache codes in HD-audio driver are relaced with the more standard regmap base now. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/hda/hdac_device.c')
-rw-r--r--sound/hda/hdac_device.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index 53b6b95ff8cd..d4a0e723af2c 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -9,6 +9,7 @@
#include <linux/export.h>
#include <linux/pm_runtime.h>
#include <sound/hdaudio.h>
+#include <sound/hda_regmap.h>
#include "local.h"
static void setup_fg_nodes(struct hdac_device *codec);
@@ -234,7 +235,22 @@ int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
EXPORT_SYMBOL_GPL(snd_hdac_read);
/**
- * snd_hdac_read_parm - read a codec parameter
+ * _snd_hdac_read_parm - read a parmeter
+ *
+ * This function returns zero or an error unlike snd_hdac_read_parm().
+ */
+int _snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm,
+ unsigned int *res)
+{
+ unsigned int cmd;
+
+ cmd = snd_hdac_regmap_encode_verb(nid, AC_VERB_PARAMETERS) | parm;
+ return snd_hdac_regmap_read_raw(codec, cmd, res);
+}
+EXPORT_SYMBOL_GPL(_snd_hdac_read_parm);
+
+/**
+ * snd_hdac_read_parm_uncached - read a codec parameter without caching
* @codec: the codec object
* @nid: NID to read a parameter
* @parm: parameter to read
@@ -242,15 +258,42 @@ EXPORT_SYMBOL_GPL(snd_hdac_read);
* Returns -1 for error. If you need to distinguish the error more
* strictly, use snd_hdac_read() directly.
*/
-int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm)
+int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
+ int parm)
{
int val;
- if (snd_hdac_read(codec, nid, AC_VERB_PARAMETERS, parm, &val))
- return -1;
+ if (codec->regmap)
+ regcache_cache_bypass(codec->regmap, true);
+ val = snd_hdac_read_parm(codec, nid, parm);
+ if (codec->regmap)
+ regcache_cache_bypass(codec->regmap, false);
return val;
}
-EXPORT_SYMBOL_GPL(snd_hdac_read_parm);
+EXPORT_SYMBOL_GPL(snd_hdac_read_parm_uncached);
+
+/**
+ * snd_hdac_override_parm - override read-only parameters
+ * @codec: the codec object
+ * @nid: NID for the parameter
+ * @parm: the parameter to change
+ * @val: the parameter value to overwrite
+ */
+int snd_hdac_override_parm(struct hdac_device *codec, hda_nid_t nid,
+ unsigned int parm, unsigned int val)
+{
+ unsigned int verb = (AC_VERB_PARAMETERS << 8) | (nid << 20) | parm;
+ int err;
+
+ if (!codec->regmap)
+ return -EINVAL;
+
+ codec->caps_overwriting = true;
+ err = snd_hdac_regmap_write_raw(codec, verb, val);
+ codec->caps_overwriting = false;
+ return err;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_override_parm);
/**
* snd_hdac_get_sub_nodes - get start NID and number of subtree nodes
@@ -259,13 +302,14 @@ EXPORT_SYMBOL_GPL(snd_hdac_read_parm);
* @start_id: the pointer to store the starting NID
*
* Returns the number of subtree nodes or zero if not found.
+ * This function reads parameters always without caching.
*/
int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
hda_nid_t *start_id)
{
unsigned int parm;
- parm = snd_hdac_read_parm(codec, nid, AC_PAR_NODE_COUNT);
+ parm = snd_hdac_read_parm_uncached(codec, nid, AC_PAR_NODE_COUNT);
if (parm == -1) {
*start_id = 0;
return 0;