0001
0002
0003
0004
0005
0006 #ifndef __SOUND_HDA_REGMAP_H
0007 #define __SOUND_HDA_REGMAP_H
0008
0009 #include <linux/regmap.h>
0010 #include <sound/core.h>
0011 #include <sound/hdaudio.h>
0012
0013 #define AC_AMP_FAKE_MUTE 0x10
0014
0015 int snd_hdac_regmap_init(struct hdac_device *codec);
0016 void snd_hdac_regmap_exit(struct hdac_device *codec);
0017 int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
0018 unsigned int verb);
0019 int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
0020 unsigned int *val);
0021 int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec,
0022 unsigned int reg, unsigned int *val);
0023 int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
0024 unsigned int val);
0025 int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
0026 unsigned int mask, unsigned int val);
0027 int snd_hdac_regmap_update_raw_once(struct hdac_device *codec, unsigned int reg,
0028 unsigned int mask, unsigned int val);
0029 void snd_hdac_regmap_sync(struct hdac_device *codec);
0030
0031
0032
0033
0034
0035
0036
0037
0038 #define snd_hdac_regmap_encode_verb(nid, verb) \
0039 (((verb) << 8) | 0x80000 | ((unsigned int)(nid) << 20))
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #define snd_hdac_regmap_encode_amp(nid, ch, dir, idx) \
0051 (snd_hdac_regmap_encode_verb(nid, AC_VERB_GET_AMP_GAIN_MUTE) | \
0052 ((ch) ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT) | \
0053 ((dir) == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT) | \
0054 (idx))
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 #define snd_hdac_regmap_encode_amp_stereo(nid, dir, idx) \
0065 (snd_hdac_regmap_encode_verb(nid, AC_VERB_GET_AMP_GAIN_MUTE) | \
0066 AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT | \
0067 ((dir) == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT) | \
0068 (idx))
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 static inline int
0079 snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
0080 unsigned int verb, unsigned int val)
0081 {
0082 unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
0083
0084 return snd_hdac_regmap_write_raw(codec, cmd, val);
0085 }
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 static inline int
0097 snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid,
0098 unsigned int verb, unsigned int mask,
0099 unsigned int val)
0100 {
0101 unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
0102
0103 return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
0104 }
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 static inline int
0115 snd_hdac_regmap_read(struct hdac_device *codec, hda_nid_t nid,
0116 unsigned int verb, unsigned int *val)
0117 {
0118 unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
0119
0120 return snd_hdac_regmap_read_raw(codec, cmd, val);
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 static inline int
0136 snd_hdac_regmap_get_amp(struct hdac_device *codec, hda_nid_t nid,
0137 int ch, int dir, int idx)
0138 {
0139 unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
0140 int err, val;
0141
0142 err = snd_hdac_regmap_read_raw(codec, cmd, &val);
0143 return err < 0 ? err : val;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 static inline int
0160 snd_hdac_regmap_update_amp(struct hdac_device *codec, hda_nid_t nid,
0161 int ch, int dir, int idx, int mask, int val)
0162 {
0163 unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
0164
0165 return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 static inline int
0181 snd_hdac_regmap_get_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
0182 int dir, int idx)
0183 {
0184 unsigned int cmd = snd_hdac_regmap_encode_amp_stereo(nid, dir, idx);
0185 int err, val;
0186
0187 err = snd_hdac_regmap_read_raw(codec, cmd, &val);
0188 return err < 0 ? err : val;
0189 }
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 static inline int
0205 snd_hdac_regmap_update_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
0206 int dir, int idx, int mask, int val)
0207 {
0208 unsigned int cmd = snd_hdac_regmap_encode_amp_stereo(nid, dir, idx);
0209
0210 return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
0211 }
0212
0213
0214
0215
0216
0217
0218 static inline void
0219 snd_hdac_regmap_sync_node(struct hdac_device *codec, hda_nid_t nid)
0220 {
0221 regcache_mark_dirty(codec->regmap);
0222 regcache_sync_region(codec->regmap, nid << 20, ((nid + 1) << 20) - 1);
0223 }
0224
0225 #endif