ALSA: hda - Add regmap support
[linux-2.6-block.git] / include / sound / hda_regmap.h
CommitLineData
4d75faa0
TI
1/*
2 * HD-audio regmap helpers
3 */
4
5#ifndef __SOUND_HDA_REGMAP_H
6#define __SOUND_HDA_REGMAP_H
7
8#include <linux/regmap.h>
9#include <sound/core.h>
10#include <sound/hdaudio.h>
11
12int snd_hdac_regmap_init(struct hdac_device *codec);
13void snd_hdac_regmap_exit(struct hdac_device *codec);
14
15int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
16 unsigned int *val);
17int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
18 unsigned int val);
19int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
20 unsigned int mask, unsigned int val);
21
22/**
23 * snd_hdac_regmap_encode_verb - encode the verb to a pseudo register
24 * @nid: widget NID
25 * @verb: codec verb
26 *
27 * Returns an encoded pseudo register.
28 */
29#define snd_hdac_regmap_encode_verb(nid, verb) \
30 (((verb) << 8) | 0x80000 | ((unsigned int)(nid) << 20))
31
32/**
33 * snd_hdac_regmap_encode_amp - encode the AMP verb to a pseudo register
34 * @nid: widget NID
35 * @ch: channel (left = 0, right = 1)
36 * @dir: direction (#HDA_INPUT, #HDA_OUTPUT)
37 * @idx: input index value
38 *
39 * Returns an encoded pseudo register.
40 */
41#define snd_hdac_regmap_encode_amp(nid, ch, dir, idx) \
42 (snd_hdac_regmap_encode_verb(nid, AC_VERB_GET_AMP_GAIN_MUTE) | \
43 ((ch) ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT) | \
44 ((dir) == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT) | \
45 (idx))
46
47/**
48 * snd_hdac_regmap_write - Write a verb with caching
49 * @nid: codec NID
50 * @reg: verb to write
51 * @val: value to write
52 *
53 * For writing an amp value, use snd_hda_regmap_amp_update().
54 */
55static inline int
56snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
57 unsigned int verb, unsigned int val)
58{
59 unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
60
61 return snd_hdac_regmap_write_raw(codec, cmd, val);
62}
63
64/**
65 * snd_hda_regmap_update - Update a verb value with caching
66 * @nid: codec NID
67 * @verb: verb to update
68 * @mask: bit mask to update
69 * @val: value to update
70 *
71 * For updating an amp value, use snd_hda_regmap_amp_update().
72 */
73static inline int
74snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid,
75 unsigned int verb, unsigned int mask,
76 unsigned int val)
77{
78 unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
79
80 return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
81}
82
83/**
84 * snd_hda_regmap_read - Read a verb with caching
85 * @nid: codec NID
86 * @verb: verb to read
87 * @val: pointer to store the value
88 *
89 * For reading an amp value, use snd_hda_regmap_get_amp().
90 */
91static inline int
92snd_hdac_regmap_read(struct hdac_device *codec, hda_nid_t nid,
93 unsigned int verb, unsigned int *val)
94{
95 unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
96
97 return snd_hdac_regmap_read_raw(codec, cmd, val);
98}
99
100/**
101 * snd_hdac_regmap_get_amp - Read AMP value
102 * @codec: HD-audio codec
103 * @nid: NID to read the AMP value
104 * @ch: channel (left=0 or right=1)
105 * @direction: #HDA_INPUT or #HDA_OUTPUT
106 * @index: the index value (only for input direction)
107 * @val: the pointer to store the value
108 *
109 * Read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
110 * Returns the value or a negative error.
111 */
112static inline int
113snd_hdac_regmap_get_amp(struct hdac_device *codec, hda_nid_t nid,
114 int ch, int dir, int idx)
115{
116 unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
117 int err, val;
118
119 err = snd_hdac_regmap_read_raw(codec, cmd, &val);
120 return err < 0 ? err : val;
121}
122
123/**
124 * snd_hdac_regmap_update_amp - update the AMP value
125 * @codec: HD-audio codec
126 * @nid: NID to read the AMP value
127 * @ch: channel (left=0 or right=1)
128 * @direction: #HDA_INPUT or #HDA_OUTPUT
129 * @idx: the index value (only for input direction)
130 * @mask: bit mask to set
131 * @val: the bits value to set
132 *
133 * Update the AMP value with a bit mask.
134 * Returns 0 if the value is unchanged, 1 if changed, or a negative error.
135 */
136static inline int
137snd_hdac_regmap_update_amp(struct hdac_device *codec, hda_nid_t nid,
138 int ch, int dir, int idx, int mask, int val)
139{
140 unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
141
142 return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
143}
144
145#endif /* __SOUND_HDA_REGMAP_H */