xref: /linux/include/sound/hda_regmap.h (revision 5e56bcea5017b7b7808df60f21ef01738b6e1a25)
14d75faa0STakashi Iwai /*
24d75faa0STakashi Iwai  * HD-audio regmap helpers
34d75faa0STakashi Iwai  */
44d75faa0STakashi Iwai 
54d75faa0STakashi Iwai #ifndef __SOUND_HDA_REGMAP_H
64d75faa0STakashi Iwai #define __SOUND_HDA_REGMAP_H
74d75faa0STakashi Iwai 
84d75faa0STakashi Iwai #include <linux/regmap.h>
94d75faa0STakashi Iwai #include <sound/core.h>
104d75faa0STakashi Iwai #include <sound/hdaudio.h>
114d75faa0STakashi Iwai 
124d75faa0STakashi Iwai int snd_hdac_regmap_init(struct hdac_device *codec);
134d75faa0STakashi Iwai void snd_hdac_regmap_exit(struct hdac_device *codec);
14*5e56bceaSTakashi Iwai int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
15*5e56bceaSTakashi Iwai 				    unsigned int verb);
164d75faa0STakashi Iwai int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
174d75faa0STakashi Iwai 			     unsigned int *val);
184d75faa0STakashi Iwai int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
194d75faa0STakashi Iwai 			      unsigned int val);
204d75faa0STakashi Iwai int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
214d75faa0STakashi Iwai 			       unsigned int mask, unsigned int val);
224d75faa0STakashi Iwai 
234d75faa0STakashi Iwai /**
244d75faa0STakashi Iwai  * snd_hdac_regmap_encode_verb - encode the verb to a pseudo register
254d75faa0STakashi Iwai  * @nid: widget NID
264d75faa0STakashi Iwai  * @verb: codec verb
274d75faa0STakashi Iwai  *
284d75faa0STakashi Iwai  * Returns an encoded pseudo register.
294d75faa0STakashi Iwai  */
304d75faa0STakashi Iwai #define snd_hdac_regmap_encode_verb(nid, verb)		\
314d75faa0STakashi Iwai 	(((verb) << 8) | 0x80000 | ((unsigned int)(nid) << 20))
324d75faa0STakashi Iwai 
334d75faa0STakashi Iwai /**
344d75faa0STakashi Iwai  * snd_hdac_regmap_encode_amp - encode the AMP verb to a pseudo register
354d75faa0STakashi Iwai  * @nid: widget NID
364d75faa0STakashi Iwai  * @ch: channel (left = 0, right = 1)
374d75faa0STakashi Iwai  * @dir: direction (#HDA_INPUT, #HDA_OUTPUT)
384d75faa0STakashi Iwai  * @idx: input index value
394d75faa0STakashi Iwai  *
404d75faa0STakashi Iwai  * Returns an encoded pseudo register.
414d75faa0STakashi Iwai  */
424d75faa0STakashi Iwai #define snd_hdac_regmap_encode_amp(nid, ch, dir, idx)			\
434d75faa0STakashi Iwai 	(snd_hdac_regmap_encode_verb(nid, AC_VERB_GET_AMP_GAIN_MUTE) |	\
444d75faa0STakashi Iwai 	 ((ch) ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT) |			\
454d75faa0STakashi Iwai 	 ((dir) == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT) | \
464d75faa0STakashi Iwai 	 (idx))
474d75faa0STakashi Iwai 
484d75faa0STakashi Iwai /**
494d75faa0STakashi Iwai  * snd_hdac_regmap_write - Write a verb with caching
504d75faa0STakashi Iwai  * @nid: codec NID
514d75faa0STakashi Iwai  * @reg: verb to write
524d75faa0STakashi Iwai  * @val: value to write
534d75faa0STakashi Iwai  *
544d75faa0STakashi Iwai  * For writing an amp value, use snd_hda_regmap_amp_update().
554d75faa0STakashi Iwai  */
564d75faa0STakashi Iwai static inline int
574d75faa0STakashi Iwai snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
584d75faa0STakashi Iwai 		      unsigned int verb, unsigned int val)
594d75faa0STakashi Iwai {
604d75faa0STakashi Iwai 	unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
614d75faa0STakashi Iwai 
624d75faa0STakashi Iwai 	return snd_hdac_regmap_write_raw(codec, cmd, val);
634d75faa0STakashi Iwai }
644d75faa0STakashi Iwai 
654d75faa0STakashi Iwai /**
664d75faa0STakashi Iwai  * snd_hda_regmap_update - Update a verb value with caching
674d75faa0STakashi Iwai  * @nid: codec NID
684d75faa0STakashi Iwai  * @verb: verb to update
694d75faa0STakashi Iwai  * @mask: bit mask to update
704d75faa0STakashi Iwai  * @val: value to update
714d75faa0STakashi Iwai  *
724d75faa0STakashi Iwai  * For updating an amp value, use snd_hda_regmap_amp_update().
734d75faa0STakashi Iwai  */
744d75faa0STakashi Iwai static inline int
754d75faa0STakashi Iwai snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid,
764d75faa0STakashi Iwai 		       unsigned int verb, unsigned int mask,
774d75faa0STakashi Iwai 		       unsigned int val)
784d75faa0STakashi Iwai {
794d75faa0STakashi Iwai 	unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
804d75faa0STakashi Iwai 
814d75faa0STakashi Iwai 	return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
824d75faa0STakashi Iwai }
834d75faa0STakashi Iwai 
844d75faa0STakashi Iwai /**
854d75faa0STakashi Iwai  * snd_hda_regmap_read - Read a verb with caching
864d75faa0STakashi Iwai  * @nid: codec NID
874d75faa0STakashi Iwai  * @verb: verb to read
884d75faa0STakashi Iwai  * @val: pointer to store the value
894d75faa0STakashi Iwai  *
904d75faa0STakashi Iwai  * For reading an amp value, use snd_hda_regmap_get_amp().
914d75faa0STakashi Iwai  */
924d75faa0STakashi Iwai static inline int
934d75faa0STakashi Iwai snd_hdac_regmap_read(struct hdac_device *codec, hda_nid_t nid,
944d75faa0STakashi Iwai 		     unsigned int verb, unsigned int *val)
954d75faa0STakashi Iwai {
964d75faa0STakashi Iwai 	unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
974d75faa0STakashi Iwai 
984d75faa0STakashi Iwai 	return snd_hdac_regmap_read_raw(codec, cmd, val);
994d75faa0STakashi Iwai }
1004d75faa0STakashi Iwai 
1014d75faa0STakashi Iwai /**
1024d75faa0STakashi Iwai  * snd_hdac_regmap_get_amp - Read AMP value
1034d75faa0STakashi Iwai  * @codec: HD-audio codec
1044d75faa0STakashi Iwai  * @nid: NID to read the AMP value
1054d75faa0STakashi Iwai  * @ch: channel (left=0 or right=1)
1064d75faa0STakashi Iwai  * @direction: #HDA_INPUT or #HDA_OUTPUT
1074d75faa0STakashi Iwai  * @index: the index value (only for input direction)
1084d75faa0STakashi Iwai  * @val: the pointer to store the value
1094d75faa0STakashi Iwai  *
1104d75faa0STakashi Iwai  * Read AMP value.  The volume is between 0 to 0x7f, 0x80 = mute bit.
1114d75faa0STakashi Iwai  * Returns the value or a negative error.
1124d75faa0STakashi Iwai  */
1134d75faa0STakashi Iwai static inline int
1144d75faa0STakashi Iwai snd_hdac_regmap_get_amp(struct hdac_device *codec, hda_nid_t nid,
1154d75faa0STakashi Iwai 			int ch, int dir, int idx)
1164d75faa0STakashi Iwai {
1174d75faa0STakashi Iwai 	unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
1184d75faa0STakashi Iwai 	int err, val;
1194d75faa0STakashi Iwai 
1204d75faa0STakashi Iwai 	err = snd_hdac_regmap_read_raw(codec, cmd, &val);
1214d75faa0STakashi Iwai 	return err < 0 ? err : val;
1224d75faa0STakashi Iwai }
1234d75faa0STakashi Iwai 
1244d75faa0STakashi Iwai /**
1254d75faa0STakashi Iwai  * snd_hdac_regmap_update_amp - update the AMP value
1264d75faa0STakashi Iwai  * @codec: HD-audio codec
1274d75faa0STakashi Iwai  * @nid: NID to read the AMP value
1284d75faa0STakashi Iwai  * @ch: channel (left=0 or right=1)
1294d75faa0STakashi Iwai  * @direction: #HDA_INPUT or #HDA_OUTPUT
1304d75faa0STakashi Iwai  * @idx: the index value (only for input direction)
1314d75faa0STakashi Iwai  * @mask: bit mask to set
1324d75faa0STakashi Iwai  * @val: the bits value to set
1334d75faa0STakashi Iwai  *
1344d75faa0STakashi Iwai  * Update the AMP value with a bit mask.
1354d75faa0STakashi Iwai  * Returns 0 if the value is unchanged, 1 if changed, or a negative error.
1364d75faa0STakashi Iwai  */
1374d75faa0STakashi Iwai static inline int
1384d75faa0STakashi Iwai snd_hdac_regmap_update_amp(struct hdac_device *codec, hda_nid_t nid,
1394d75faa0STakashi Iwai 			   int ch, int dir, int idx, int mask, int val)
1404d75faa0STakashi Iwai {
1414d75faa0STakashi Iwai 	unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
1424d75faa0STakashi Iwai 
1434d75faa0STakashi Iwai 	return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
1444d75faa0STakashi Iwai }
1454d75faa0STakashi Iwai 
1464d75faa0STakashi Iwai #endif /* __SOUND_HDA_REGMAP_H */
147