1/*
2 * HD-audio core stuff
3 */
4
5#ifndef __SOUND_HDAUDIO_H
6#define __SOUND_HDAUDIO_H
7
8#include <linux/device.h>
9#include <sound/hda_verbs.h>
10
11/* codec node id */
12typedef u16 hda_nid_t;
13
14struct hdac_bus;
15struct hdac_device;
16struct hdac_driver;
17struct hdac_widget_tree;
18
19/*
20 * exported bus type
21 */
22extern struct bus_type snd_hda_bus_type;
23
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
35/*
36 * HD-audio codec base device
37 */
38struct hdac_device {
39	struct device dev;
40	int type;
41	struct hdac_bus *bus;
42	unsigned int addr;		/* codec address */
43	struct list_head list;		/* list point for bus codec_list */
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
62	/* verb exec op override */
63	int (*exec_verb)(struct hdac_device *dev, unsigned int cmd,
64			 unsigned int flags, unsigned int *res);
65
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 */
72
73	/* sysfs */
74	struct hdac_widget_tree *widgets;
75
76	/* regmap */
77	struct regmap *regmap;
78	struct snd_array vendor_verbs;
79	bool lazy_cache:1;	/* don't wake up for writes */
80	bool caps_overwriting:1; /* caps overwrite being in process */
81	bool cache_coef:1;	/* cache COEF read/write too */
82};
83
84/* device/driver type used for matching */
85enum {
86	HDA_DEV_CORE,
87	HDA_DEV_LEGACY,
88};
89
90/* direction */
91enum {
92	HDA_INPUT, HDA_OUTPUT
93};
94
95#define dev_to_hdac_dev(_dev)	container_of(_dev, struct hdac_device, dev)
96
97int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
98			 const char *name, unsigned int addr);
99void snd_hdac_device_exit(struct hdac_device *dev);
100int snd_hdac_device_register(struct hdac_device *codec);
101void snd_hdac_device_unregister(struct hdac_device *codec);
102
103int snd_hdac_refresh_widgets(struct hdac_device *codec);
104
105unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
106			       unsigned int verb, unsigned int parm);
107int snd_hdac_exec_verb(struct hdac_device *codec, unsigned int cmd,
108		       unsigned int flags, unsigned int *res);
109int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
110		  unsigned int verb, unsigned int parm, unsigned int *res);
111int _snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm,
112			unsigned int *res);
113int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
114				int parm);
115int snd_hdac_override_parm(struct hdac_device *codec, hda_nid_t nid,
116			   unsigned int parm, unsigned int val);
117int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
118			     hda_nid_t *conn_list, int max_conns);
119int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
120			   hda_nid_t *start_id);
121
122/**
123 * snd_hdac_read_parm - read a codec parameter
124 * @codec: the codec object
125 * @nid: NID to read a parameter
126 * @parm: parameter to read
127 *
128 * Returns -1 for error.  If you need to distinguish the error more
129 * strictly, use _snd_hdac_read_parm() directly.
130 */
131static inline int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid,
132				     int parm)
133{
134	unsigned int val;
135
136	return _snd_hdac_read_parm(codec, nid, parm, &val) < 0 ? -1 : val;
137}
138
139#ifdef CONFIG_PM
140int snd_hdac_power_up(struct hdac_device *codec);
141int snd_hdac_power_down(struct hdac_device *codec);
142int snd_hdac_power_up_pm(struct hdac_device *codec);
143int snd_hdac_power_down_pm(struct hdac_device *codec);
144#else
145static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
146static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
147static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
148static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
149#endif
150
151/*
152 * HD-audio codec base driver
153 */
154struct hdac_driver {
155	struct device_driver driver;
156	int type;
157	int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
158	void (*unsol_event)(struct hdac_device *dev, unsigned int event);
159};
160
161#define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
162
163/*
164 * HD-audio bus base driver
165 */
166struct hdac_bus_ops {
167	/* send a single command */
168	int (*command)(struct hdac_bus *bus, unsigned int cmd);
169	/* get a response from the last command */
170	int (*get_response)(struct hdac_bus *bus, unsigned int addr,
171			    unsigned int *res);
172};
173
174#define HDA_UNSOL_QUEUE_SIZE	64
175
176struct hdac_bus {
177	struct device *dev;
178	const struct hdac_bus_ops *ops;
179
180	/* codec linked list */
181	struct list_head codec_list;
182	unsigned int num_codecs;
183
184	/* link caddr -> codec */
185	struct hdac_device *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
186
187	/* unsolicited event queue */
188	u32 unsol_queue[HDA_UNSOL_QUEUE_SIZE * 2]; /* ring buffer */
189	unsigned int unsol_rp, unsol_wp;
190	struct work_struct unsol_work;
191
192	/* bit flags of powered codecs */
193	unsigned long codec_powered;
194
195	/* flags */
196	bool sync_write:1;		/* sync after verb write */
197
198	/* locks */
199	struct mutex cmd_mutex;
200};
201
202int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
203		      const struct hdac_bus_ops *ops);
204void snd_hdac_bus_exit(struct hdac_bus *bus);
205int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
206			   unsigned int cmd, unsigned int *res);
207int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
208				    unsigned int cmd, unsigned int *res);
209void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
210
211int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec);
212void snd_hdac_bus_remove_device(struct hdac_bus *bus,
213				struct hdac_device *codec);
214
215static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
216{
217	set_bit(codec->addr, &codec->bus->codec_powered);
218}
219
220static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
221{
222	clear_bit(codec->addr, &codec->bus->codec_powered);
223}
224
225/*
226 * generic array helpers
227 */
228void *snd_array_new(struct snd_array *array);
229void snd_array_free(struct snd_array *array);
230static inline void snd_array_init(struct snd_array *array, unsigned int size,
231				  unsigned int align)
232{
233	array->elem_size = size;
234	array->alloc_align = align;
235}
236
237static inline void *snd_array_elem(struct snd_array *array, unsigned int idx)
238{
239	return array->list + idx * array->elem_size;
240}
241
242static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
243{
244	return (unsigned long)(ptr - array->list) / array->elem_size;
245}
246
247#endif /* __SOUND_HDAUDIO_H */
248