Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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