hda_regmap.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * HD-audio regmap helpers
  3. */
  4. #ifndef __SOUND_HDA_REGMAP_H
  5. #define __SOUND_HDA_REGMAP_H
  6. #include <linux/regmap.h>
  7. #include <sound/core.h>
  8. #include <sound/hdaudio.h>
  9. #define AC_AMP_FAKE_MUTE 0x10 /* fake mute bit set to amp verbs */
  10. int snd_hdac_regmap_init(struct hdac_device *codec);
  11. void snd_hdac_regmap_exit(struct hdac_device *codec);
  12. int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
  13. unsigned int verb);
  14. int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
  15. unsigned int *val);
  16. int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
  17. unsigned int val);
  18. int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
  19. unsigned int mask, unsigned int val);
  20. /**
  21. * snd_hdac_regmap_encode_verb - encode the verb to a pseudo register
  22. * @nid: widget NID
  23. * @verb: codec verb
  24. *
  25. * Returns an encoded pseudo register.
  26. */
  27. #define snd_hdac_regmap_encode_verb(nid, verb) \
  28. (((verb) << 8) | 0x80000 | ((unsigned int)(nid) << 20))
  29. /**
  30. * snd_hdac_regmap_encode_amp - encode the AMP verb to a pseudo register
  31. * @nid: widget NID
  32. * @ch: channel (left = 0, right = 1)
  33. * @dir: direction (#HDA_INPUT, #HDA_OUTPUT)
  34. * @idx: input index value
  35. *
  36. * Returns an encoded pseudo register.
  37. */
  38. #define snd_hdac_regmap_encode_amp(nid, ch, dir, idx) \
  39. (snd_hdac_regmap_encode_verb(nid, AC_VERB_GET_AMP_GAIN_MUTE) | \
  40. ((ch) ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT) | \
  41. ((dir) == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT) | \
  42. (idx))
  43. /**
  44. * snd_hdac_regmap_encode_amp_stereo - encode a pseudo register for stereo AMPs
  45. * @nid: widget NID
  46. * @dir: direction (#HDA_INPUT, #HDA_OUTPUT)
  47. * @idx: input index value
  48. *
  49. * Returns an encoded pseudo register.
  50. */
  51. #define snd_hdac_regmap_encode_amp_stereo(nid, dir, idx) \
  52. (snd_hdac_regmap_encode_verb(nid, AC_VERB_GET_AMP_GAIN_MUTE) | \
  53. AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT | /* both bits set! */ \
  54. ((dir) == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT) | \
  55. (idx))
  56. /**
  57. * snd_hdac_regmap_write - Write a verb with caching
  58. * @nid: codec NID
  59. * @reg: verb to write
  60. * @val: value to write
  61. *
  62. * For writing an amp value, use snd_hda_regmap_amp_update().
  63. */
  64. static inline int
  65. snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
  66. unsigned int verb, unsigned int val)
  67. {
  68. unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
  69. return snd_hdac_regmap_write_raw(codec, cmd, val);
  70. }
  71. /**
  72. * snd_hda_regmap_update - Update a verb value with caching
  73. * @nid: codec NID
  74. * @verb: verb to update
  75. * @mask: bit mask to update
  76. * @val: value to update
  77. *
  78. * For updating an amp value, use snd_hda_regmap_amp_update().
  79. */
  80. static inline int
  81. snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid,
  82. unsigned int verb, unsigned int mask,
  83. unsigned int val)
  84. {
  85. unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
  86. return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
  87. }
  88. /**
  89. * snd_hda_regmap_read - Read a verb with caching
  90. * @nid: codec NID
  91. * @verb: verb to read
  92. * @val: pointer to store the value
  93. *
  94. * For reading an amp value, use snd_hda_regmap_get_amp().
  95. */
  96. static inline int
  97. snd_hdac_regmap_read(struct hdac_device *codec, hda_nid_t nid,
  98. unsigned int verb, unsigned int *val)
  99. {
  100. unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
  101. return snd_hdac_regmap_read_raw(codec, cmd, val);
  102. }
  103. /**
  104. * snd_hdac_regmap_get_amp - Read AMP value
  105. * @codec: HD-audio codec
  106. * @nid: NID to read the AMP value
  107. * @ch: channel (left=0 or right=1)
  108. * @direction: #HDA_INPUT or #HDA_OUTPUT
  109. * @index: the index value (only for input direction)
  110. * @val: the pointer to store the value
  111. *
  112. * Read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
  113. * Returns the value or a negative error.
  114. */
  115. static inline int
  116. snd_hdac_regmap_get_amp(struct hdac_device *codec, hda_nid_t nid,
  117. int ch, int dir, int idx)
  118. {
  119. unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
  120. int err, val;
  121. err = snd_hdac_regmap_read_raw(codec, cmd, &val);
  122. return err < 0 ? err : val;
  123. }
  124. /**
  125. * snd_hdac_regmap_update_amp - update the AMP value
  126. * @codec: HD-audio codec
  127. * @nid: NID to read the AMP value
  128. * @ch: channel (left=0 or right=1)
  129. * @direction: #HDA_INPUT or #HDA_OUTPUT
  130. * @idx: the index value (only for input direction)
  131. * @mask: bit mask to set
  132. * @val: the bits value to set
  133. *
  134. * Update the AMP value with a bit mask.
  135. * Returns 0 if the value is unchanged, 1 if changed, or a negative error.
  136. */
  137. static inline int
  138. snd_hdac_regmap_update_amp(struct hdac_device *codec, hda_nid_t nid,
  139. int ch, int dir, int idx, int mask, int val)
  140. {
  141. unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
  142. return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
  143. }
  144. /**
  145. * snd_hdac_regmap_get_amp_stereo - Read stereo AMP values
  146. * @codec: HD-audio codec
  147. * @nid: NID to read the AMP value
  148. * @ch: channel (left=0 or right=1)
  149. * @direction: #HDA_INPUT or #HDA_OUTPUT
  150. * @index: the index value (only for input direction)
  151. * @val: the pointer to store the value
  152. *
  153. * Read stereo AMP values. The lower byte is left, the upper byte is right.
  154. * Returns the value or a negative error.
  155. */
  156. static inline int
  157. snd_hdac_regmap_get_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
  158. int dir, int idx)
  159. {
  160. unsigned int cmd = snd_hdac_regmap_encode_amp_stereo(nid, dir, idx);
  161. int err, val;
  162. err = snd_hdac_regmap_read_raw(codec, cmd, &val);
  163. return err < 0 ? err : val;
  164. }
  165. /**
  166. * snd_hdac_regmap_update_amp_stereo - update the stereo AMP value
  167. * @codec: HD-audio codec
  168. * @nid: NID to read the AMP value
  169. * @direction: #HDA_INPUT or #HDA_OUTPUT
  170. * @idx: the index value (only for input direction)
  171. * @mask: bit mask to set
  172. * @val: the bits value to set
  173. *
  174. * Update the stereo AMP value with a bit mask.
  175. * The lower byte is left, the upper byte is right.
  176. * Returns 0 if the value is unchanged, 1 if changed, or a negative error.
  177. */
  178. static inline int
  179. snd_hdac_regmap_update_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
  180. int dir, int idx, int mask, int val)
  181. {
  182. unsigned int cmd = snd_hdac_regmap_encode_amp_stereo(nid, dir, idx);
  183. return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
  184. }
  185. /**
  186. * snd_hdac_regmap_sync_node - sync the widget node attributes
  187. * @codec: HD-audio codec
  188. * @nid: NID to sync
  189. */
  190. static inline void
  191. snd_hdac_regmap_sync_node(struct hdac_device *codec, hda_nid_t nid)
  192. {
  193. regcache_mark_dirty(codec->regmap);
  194. regcache_sync_region(codec->regmap, nid << 20, ((nid + 1) << 20) - 1);
  195. }
  196. #endif /* __SOUND_HDA_REGMAP_H */