xref: /linux/include/sound/hdaudio.h (revision 3256be6537751f65c76b3ecfbb4e667f87525a2f)
1e3d280fcSTakashi Iwai /*
2e3d280fcSTakashi Iwai  * HD-audio core stuff
3e3d280fcSTakashi Iwai  */
4e3d280fcSTakashi Iwai 
5e3d280fcSTakashi Iwai #ifndef __SOUND_HDAUDIO_H
6e3d280fcSTakashi Iwai #define __SOUND_HDAUDIO_H
7e3d280fcSTakashi Iwai 
8e3d280fcSTakashi Iwai #include <linux/device.h>
9d068ebc2STakashi Iwai #include <sound/hda_verbs.h>
10d068ebc2STakashi Iwai 
117639a06cSTakashi Iwai /* codec node id */
127639a06cSTakashi Iwai typedef u16 hda_nid_t;
137639a06cSTakashi Iwai 
14d068ebc2STakashi Iwai struct hdac_bus;
15d068ebc2STakashi Iwai struct hdac_device;
16d068ebc2STakashi Iwai struct hdac_driver;
17*3256be65STakashi Iwai struct hdac_widget_tree;
18e3d280fcSTakashi Iwai 
19e3d280fcSTakashi Iwai /*
20e3d280fcSTakashi Iwai  * exported bus type
21e3d280fcSTakashi Iwai  */
22e3d280fcSTakashi Iwai extern struct bus_type snd_hda_bus_type;
23e3d280fcSTakashi Iwai 
24e3d280fcSTakashi Iwai /*
25e3d280fcSTakashi Iwai  * HD-audio codec base device
26e3d280fcSTakashi Iwai  */
27e3d280fcSTakashi Iwai struct hdac_device {
28e3d280fcSTakashi Iwai 	struct device dev;
29e3d280fcSTakashi Iwai 	int type;
30d068ebc2STakashi Iwai 	struct hdac_bus *bus;
31d068ebc2STakashi Iwai 	unsigned int addr;		/* codec address */
32d068ebc2STakashi Iwai 	struct list_head list;		/* list point for bus codec_list */
337639a06cSTakashi Iwai 
347639a06cSTakashi Iwai 	hda_nid_t afg;			/* AFG node id */
357639a06cSTakashi Iwai 	hda_nid_t mfg;			/* MFG node id */
367639a06cSTakashi Iwai 
377639a06cSTakashi Iwai 	/* ids */
387639a06cSTakashi Iwai 	unsigned int vendor_id;
397639a06cSTakashi Iwai 	unsigned int subsystem_id;
407639a06cSTakashi Iwai 	unsigned int revision_id;
417639a06cSTakashi Iwai 	unsigned int afg_function_id;
427639a06cSTakashi Iwai 	unsigned int mfg_function_id;
437639a06cSTakashi Iwai 	unsigned int afg_unsol:1;
447639a06cSTakashi Iwai 	unsigned int mfg_unsol:1;
457639a06cSTakashi Iwai 
467639a06cSTakashi Iwai 	unsigned int power_caps;	/* FG power caps */
477639a06cSTakashi Iwai 
487639a06cSTakashi Iwai 	const char *vendor_name;	/* codec vendor name */
497639a06cSTakashi Iwai 	const char *chip_name;		/* codec chip name */
507639a06cSTakashi Iwai 
517639a06cSTakashi Iwai 	/* widgets */
527639a06cSTakashi Iwai 	unsigned int num_nodes;
537639a06cSTakashi Iwai 	hda_nid_t start_nid, end_nid;
547639a06cSTakashi Iwai 
557639a06cSTakashi Iwai 	/* misc flags */
567639a06cSTakashi Iwai 	atomic_t in_pm;		/* suspend/resume being performed */
57*3256be65STakashi Iwai 
58*3256be65STakashi Iwai 	/* sysfs */
59*3256be65STakashi Iwai 	struct hdac_widget_tree *widgets;
60e3d280fcSTakashi Iwai };
61e3d280fcSTakashi Iwai 
62e3d280fcSTakashi Iwai /* device/driver type used for matching */
63e3d280fcSTakashi Iwai enum {
64e3d280fcSTakashi Iwai 	HDA_DEV_CORE,
65e3d280fcSTakashi Iwai 	HDA_DEV_LEGACY,
66e3d280fcSTakashi Iwai };
67e3d280fcSTakashi Iwai 
687639a06cSTakashi Iwai /* direction */
697639a06cSTakashi Iwai enum {
707639a06cSTakashi Iwai 	HDA_INPUT, HDA_OUTPUT
717639a06cSTakashi Iwai };
727639a06cSTakashi Iwai 
73e3d280fcSTakashi Iwai #define dev_to_hdac_dev(_dev)	container_of(_dev, struct hdac_device, dev)
74e3d280fcSTakashi Iwai 
757639a06cSTakashi Iwai int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
767639a06cSTakashi Iwai 			 const char *name, unsigned int addr);
777639a06cSTakashi Iwai void snd_hdac_device_exit(struct hdac_device *dev);
78*3256be65STakashi Iwai int snd_hdac_device_register(struct hdac_device *codec);
79*3256be65STakashi Iwai void snd_hdac_device_unregister(struct hdac_device *codec);
807639a06cSTakashi Iwai 
817639a06cSTakashi Iwai int snd_hdac_refresh_widgets(struct hdac_device *codec);
827639a06cSTakashi Iwai 
837639a06cSTakashi Iwai unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
847639a06cSTakashi Iwai 			       unsigned int verb, unsigned int parm);
857639a06cSTakashi Iwai int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
867639a06cSTakashi Iwai 		  unsigned int verb, unsigned int parm, unsigned int *res);
877639a06cSTakashi Iwai int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm);
887639a06cSTakashi Iwai int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
897639a06cSTakashi Iwai 			     hda_nid_t *conn_list, int max_conns);
907639a06cSTakashi Iwai int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
917639a06cSTakashi Iwai 			   hda_nid_t *start_id);
927639a06cSTakashi Iwai 
937639a06cSTakashi Iwai #ifdef CONFIG_PM
947639a06cSTakashi Iwai void snd_hdac_power_up(struct hdac_device *codec);
957639a06cSTakashi Iwai void snd_hdac_power_down(struct hdac_device *codec);
967639a06cSTakashi Iwai #else
977639a06cSTakashi Iwai static inline void snd_hdac_power_up(struct hdac_device *codec) {}
987639a06cSTakashi Iwai static inline void snd_hdac_power_down(struct hdac_device *codec) {}
997639a06cSTakashi Iwai #endif
1007639a06cSTakashi Iwai 
101e3d280fcSTakashi Iwai /*
102e3d280fcSTakashi Iwai  * HD-audio codec base driver
103e3d280fcSTakashi Iwai  */
104e3d280fcSTakashi Iwai struct hdac_driver {
105e3d280fcSTakashi Iwai 	struct device_driver driver;
106e3d280fcSTakashi Iwai 	int type;
107e3d280fcSTakashi Iwai 	int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
108d068ebc2STakashi Iwai 	void (*unsol_event)(struct hdac_device *dev, unsigned int event);
109e3d280fcSTakashi Iwai };
110e3d280fcSTakashi Iwai 
111e3d280fcSTakashi Iwai #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
112e3d280fcSTakashi Iwai 
113d068ebc2STakashi Iwai /*
114d068ebc2STakashi Iwai  * HD-audio bus base driver
115d068ebc2STakashi Iwai  */
116d068ebc2STakashi Iwai struct hdac_bus_ops {
117d068ebc2STakashi Iwai 	/* send a single command */
118d068ebc2STakashi Iwai 	int (*command)(struct hdac_bus *bus, unsigned int cmd);
119d068ebc2STakashi Iwai 	/* get a response from the last command */
120d068ebc2STakashi Iwai 	int (*get_response)(struct hdac_bus *bus, unsigned int addr,
121d068ebc2STakashi Iwai 			    unsigned int *res);
122d068ebc2STakashi Iwai };
123d068ebc2STakashi Iwai 
124d068ebc2STakashi Iwai #define HDA_UNSOL_QUEUE_SIZE	64
125d068ebc2STakashi Iwai 
126d068ebc2STakashi Iwai struct hdac_bus {
127d068ebc2STakashi Iwai 	struct device *dev;
128d068ebc2STakashi Iwai 	const struct hdac_bus_ops *ops;
129d068ebc2STakashi Iwai 
130d068ebc2STakashi Iwai 	/* codec linked list */
131d068ebc2STakashi Iwai 	struct list_head codec_list;
132d068ebc2STakashi Iwai 	unsigned int num_codecs;
133d068ebc2STakashi Iwai 
134d068ebc2STakashi Iwai 	/* link caddr -> codec */
135d068ebc2STakashi Iwai 	struct hdac_device *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
136d068ebc2STakashi Iwai 
137d068ebc2STakashi Iwai 	/* unsolicited event queue */
138d068ebc2STakashi Iwai 	u32 unsol_queue[HDA_UNSOL_QUEUE_SIZE * 2]; /* ring buffer */
139d068ebc2STakashi Iwai 	unsigned int unsol_rp, unsol_wp;
140d068ebc2STakashi Iwai 	struct work_struct unsol_work;
141d068ebc2STakashi Iwai 
142d068ebc2STakashi Iwai 	/* bit flags of powered codecs */
143d068ebc2STakashi Iwai 	unsigned long codec_powered;
144d068ebc2STakashi Iwai 
145d068ebc2STakashi Iwai 	/* flags */
146d068ebc2STakashi Iwai 	bool sync_write:1;		/* sync after verb write */
147d068ebc2STakashi Iwai 
148d068ebc2STakashi Iwai 	/* locks */
149d068ebc2STakashi Iwai 	struct mutex cmd_mutex;
150d068ebc2STakashi Iwai };
151d068ebc2STakashi Iwai 
152d068ebc2STakashi Iwai int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
153d068ebc2STakashi Iwai 		      const struct hdac_bus_ops *ops);
154d068ebc2STakashi Iwai void snd_hdac_bus_exit(struct hdac_bus *bus);
155d068ebc2STakashi Iwai int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
156d068ebc2STakashi Iwai 			   unsigned int cmd, unsigned int *res);
157d068ebc2STakashi Iwai int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
158d068ebc2STakashi Iwai 				    unsigned int cmd, unsigned int *res);
159d068ebc2STakashi Iwai void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
160d068ebc2STakashi Iwai 
161d068ebc2STakashi Iwai int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec);
162d068ebc2STakashi Iwai void snd_hdac_bus_remove_device(struct hdac_bus *bus,
163d068ebc2STakashi Iwai 				struct hdac_device *codec);
164d068ebc2STakashi Iwai 
1657639a06cSTakashi Iwai static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
1667639a06cSTakashi Iwai {
1677639a06cSTakashi Iwai 	set_bit(codec->addr, &codec->bus->codec_powered);
1687639a06cSTakashi Iwai }
1697639a06cSTakashi Iwai 
1707639a06cSTakashi Iwai static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
1717639a06cSTakashi Iwai {
1727639a06cSTakashi Iwai 	clear_bit(codec->addr, &codec->bus->codec_powered);
1737639a06cSTakashi Iwai }
1747639a06cSTakashi Iwai 
175e3d280fcSTakashi Iwai #endif /* __SOUND_HDAUDIO_H */
176