]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - include/sound/hdaudio.h
ALSA: hda - Move generic array helpers to core lib
[mirror_ubuntu-artful-kernel.git] / include / sound / hdaudio.h
CommitLineData
e3d280fc
TI
1/*
2 * HD-audio core stuff
3 */
4
5#ifndef __SOUND_HDAUDIO_H
6#define __SOUND_HDAUDIO_H
7
8#include <linux/device.h>
d068ebc2
TI
9#include <sound/hda_verbs.h>
10
7639a06c
TI
11/* codec node id */
12typedef u16 hda_nid_t;
13
d068ebc2
TI
14struct hdac_bus;
15struct hdac_device;
16struct hdac_driver;
3256be65 17struct hdac_widget_tree;
e3d280fc
TI
18
19/*
20 * exported bus type
21 */
22extern struct bus_type snd_hda_bus_type;
23
71fc4c7e
TI
24/*
25 * generic arrays
26 */
27struct snd_array {
28 unsigned int used;
29 unsigned int alloced;
30 unsigned int elem_size;
31 unsigned int alloc_align;
32 void *list;
33};
34
e3d280fc
TI
35/*
36 * HD-audio codec base device
37 */
38struct hdac_device {
39 struct device dev;
40 int type;
d068ebc2
TI
41 struct hdac_bus *bus;
42 unsigned int addr; /* codec address */
43 struct list_head list; /* list point for bus codec_list */
7639a06c
TI
44
45 hda_nid_t afg; /* AFG node id */
46 hda_nid_t mfg; /* MFG node id */
47
48 /* ids */
49 unsigned int vendor_id;
50 unsigned int subsystem_id;
51 unsigned int revision_id;
52 unsigned int afg_function_id;
53 unsigned int mfg_function_id;
54 unsigned int afg_unsol:1;
55 unsigned int mfg_unsol:1;
56
57 unsigned int power_caps; /* FG power caps */
58
59 const char *vendor_name; /* codec vendor name */
60 const char *chip_name; /* codec chip name */
61
05852448
TI
62 /* verb exec op override */
63 int (*exec_verb)(struct hdac_device *dev, unsigned int cmd,
64 unsigned int flags, unsigned int *res);
65
7639a06c
TI
66 /* widgets */
67 unsigned int num_nodes;
68 hda_nid_t start_nid, end_nid;
69
70 /* misc flags */
71 atomic_t in_pm; /* suspend/resume being performed */
3256be65
TI
72
73 /* sysfs */
74 struct hdac_widget_tree *widgets;
e3d280fc
TI
75};
76
77/* device/driver type used for matching */
78enum {
79 HDA_DEV_CORE,
80 HDA_DEV_LEGACY,
81};
82
7639a06c
TI
83/* direction */
84enum {
85 HDA_INPUT, HDA_OUTPUT
86};
87
e3d280fc
TI
88#define dev_to_hdac_dev(_dev) container_of(_dev, struct hdac_device, dev)
89
7639a06c
TI
90int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
91 const char *name, unsigned int addr);
92void snd_hdac_device_exit(struct hdac_device *dev);
3256be65
TI
93int snd_hdac_device_register(struct hdac_device *codec);
94void snd_hdac_device_unregister(struct hdac_device *codec);
7639a06c
TI
95
96int snd_hdac_refresh_widgets(struct hdac_device *codec);
97
98unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
99 unsigned int verb, unsigned int parm);
05852448
TI
100int snd_hdac_exec_verb(struct hdac_device *codec, unsigned int cmd,
101 unsigned int flags, unsigned int *res);
7639a06c
TI
102int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
103 unsigned int verb, unsigned int parm, unsigned int *res);
104int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm);
105int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
106 hda_nid_t *conn_list, int max_conns);
107int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
108 hda_nid_t *start_id);
109
110#ifdef CONFIG_PM
111void snd_hdac_power_up(struct hdac_device *codec);
112void snd_hdac_power_down(struct hdac_device *codec);
113#else
114static inline void snd_hdac_power_up(struct hdac_device *codec) {}
115static inline void snd_hdac_power_down(struct hdac_device *codec) {}
116#endif
117
e3d280fc
TI
118/*
119 * HD-audio codec base driver
120 */
121struct hdac_driver {
122 struct device_driver driver;
123 int type;
124 int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
d068ebc2 125 void (*unsol_event)(struct hdac_device *dev, unsigned int event);
e3d280fc
TI
126};
127
128#define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
129
d068ebc2
TI
130/*
131 * HD-audio bus base driver
132 */
133struct hdac_bus_ops {
134 /* send a single command */
135 int (*command)(struct hdac_bus *bus, unsigned int cmd);
136 /* get a response from the last command */
137 int (*get_response)(struct hdac_bus *bus, unsigned int addr,
138 unsigned int *res);
139};
140
141#define HDA_UNSOL_QUEUE_SIZE 64
142
143struct hdac_bus {
144 struct device *dev;
145 const struct hdac_bus_ops *ops;
146
147 /* codec linked list */
148 struct list_head codec_list;
149 unsigned int num_codecs;
150
151 /* link caddr -> codec */
152 struct hdac_device *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
153
154 /* unsolicited event queue */
155 u32 unsol_queue[HDA_UNSOL_QUEUE_SIZE * 2]; /* ring buffer */
156 unsigned int unsol_rp, unsol_wp;
157 struct work_struct unsol_work;
158
159 /* bit flags of powered codecs */
160 unsigned long codec_powered;
161
162 /* flags */
163 bool sync_write:1; /* sync after verb write */
164
165 /* locks */
166 struct mutex cmd_mutex;
167};
168
169int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
170 const struct hdac_bus_ops *ops);
171void snd_hdac_bus_exit(struct hdac_bus *bus);
172int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
173 unsigned int cmd, unsigned int *res);
174int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
175 unsigned int cmd, unsigned int *res);
176void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
177
178int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec);
179void snd_hdac_bus_remove_device(struct hdac_bus *bus,
180 struct hdac_device *codec);
181
7639a06c
TI
182static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
183{
184 set_bit(codec->addr, &codec->bus->codec_powered);
185}
186
187static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
188{
189 clear_bit(codec->addr, &codec->bus->codec_powered);
190}
191
71fc4c7e
TI
192/*
193 * generic array helpers
194 */
195void *snd_array_new(struct snd_array *array);
196void snd_array_free(struct snd_array *array);
197static inline void snd_array_init(struct snd_array *array, unsigned int size,
198 unsigned int align)
199{
200 array->elem_size = size;
201 array->alloc_align = align;
202}
203
204static inline void *snd_array_elem(struct snd_array *array, unsigned int idx)
205{
206 return array->list + idx * array->elem_size;
207}
208
209static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
210{
211 return (unsigned long)(ptr - array->list) / array->elem_size;
212}
213
e3d280fc 214#endif /* __SOUND_HDAUDIO_H */