blob: 6ed2b421e29ebfd87128576eec7a1de2076b3b19 [file] [log] [blame]
Takashi Iwaie3d280f2015-02-17 21:46:37 +01001/*
2 * HD-audio core stuff
3 */
4
5#ifndef __SOUND_HDAUDIO_H
6#define __SOUND_HDAUDIO_H
7
8#include <linux/device.h>
Takashi Iwaid068ebc2015-03-02 23:22:59 +01009#include <sound/hda_verbs.h>
10
Takashi Iwai7639a062015-03-03 10:07:24 +010011/* codec node id */
12typedef u16 hda_nid_t;
13
Takashi Iwaid068ebc2015-03-02 23:22:59 +010014struct hdac_bus;
15struct hdac_device;
16struct hdac_driver;
Takashi Iwai3256be62015-02-24 14:59:42 +010017struct hdac_widget_tree;
Takashi Iwaie3d280f2015-02-17 21:46:37 +010018
19/*
20 * exported bus type
21 */
22extern struct bus_type snd_hda_bus_type;
23
24/*
25 * HD-audio codec base device
26 */
27struct hdac_device {
28 struct device dev;
29 int type;
Takashi Iwaid068ebc2015-03-02 23:22:59 +010030 struct hdac_bus *bus;
31 unsigned int addr; /* codec address */
32 struct list_head list; /* list point for bus codec_list */
Takashi Iwai7639a062015-03-03 10:07:24 +010033
34 hda_nid_t afg; /* AFG node id */
35 hda_nid_t mfg; /* MFG node id */
36
37 /* ids */
38 unsigned int vendor_id;
39 unsigned int subsystem_id;
40 unsigned int revision_id;
41 unsigned int afg_function_id;
42 unsigned int mfg_function_id;
43 unsigned int afg_unsol:1;
44 unsigned int mfg_unsol:1;
45
46 unsigned int power_caps; /* FG power caps */
47
48 const char *vendor_name; /* codec vendor name */
49 const char *chip_name; /* codec chip name */
50
51 /* widgets */
52 unsigned int num_nodes;
53 hda_nid_t start_nid, end_nid;
54
55 /* misc flags */
56 atomic_t in_pm; /* suspend/resume being performed */
Takashi Iwai3256be62015-02-24 14:59:42 +010057
58 /* sysfs */
59 struct hdac_widget_tree *widgets;
Takashi Iwaie3d280f2015-02-17 21:46:37 +010060};
61
62/* device/driver type used for matching */
63enum {
64 HDA_DEV_CORE,
65 HDA_DEV_LEGACY,
66};
67
Takashi Iwai7639a062015-03-03 10:07:24 +010068/* direction */
69enum {
70 HDA_INPUT, HDA_OUTPUT
71};
72
Takashi Iwaie3d280f2015-02-17 21:46:37 +010073#define dev_to_hdac_dev(_dev) container_of(_dev, struct hdac_device, dev)
74
Takashi Iwai7639a062015-03-03 10:07:24 +010075int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
76 const char *name, unsigned int addr);
77void snd_hdac_device_exit(struct hdac_device *dev);
Takashi Iwai3256be62015-02-24 14:59:42 +010078int snd_hdac_device_register(struct hdac_device *codec);
79void snd_hdac_device_unregister(struct hdac_device *codec);
Takashi Iwai7639a062015-03-03 10:07:24 +010080
81int snd_hdac_refresh_widgets(struct hdac_device *codec);
82
83unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
84 unsigned int verb, unsigned int parm);
85int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
86 unsigned int verb, unsigned int parm, unsigned int *res);
87int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm);
88int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
89 hda_nid_t *conn_list, int max_conns);
90int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
91 hda_nid_t *start_id);
92
93#ifdef CONFIG_PM
94void snd_hdac_power_up(struct hdac_device *codec);
95void snd_hdac_power_down(struct hdac_device *codec);
96#else
97static inline void snd_hdac_power_up(struct hdac_device *codec) {}
98static inline void snd_hdac_power_down(struct hdac_device *codec) {}
99#endif
100
Takashi Iwaie3d280f2015-02-17 21:46:37 +0100101/*
102 * HD-audio codec base driver
103 */
104struct hdac_driver {
105 struct device_driver driver;
106 int type;
107 int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
Takashi Iwaid068ebc2015-03-02 23:22:59 +0100108 void (*unsol_event)(struct hdac_device *dev, unsigned int event);
Takashi Iwaie3d280f2015-02-17 21:46:37 +0100109};
110
111#define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
112
Takashi Iwaid068ebc2015-03-02 23:22:59 +0100113/*
114 * HD-audio bus base driver
115 */
116struct hdac_bus_ops {
117 /* send a single command */
118 int (*command)(struct hdac_bus *bus, unsigned int cmd);
119 /* get a response from the last command */
120 int (*get_response)(struct hdac_bus *bus, unsigned int addr,
121 unsigned int *res);
122};
123
124#define HDA_UNSOL_QUEUE_SIZE 64
125
126struct hdac_bus {
127 struct device *dev;
128 const struct hdac_bus_ops *ops;
129
130 /* codec linked list */
131 struct list_head codec_list;
132 unsigned int num_codecs;
133
134 /* link caddr -> codec */
135 struct hdac_device *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
136
137 /* unsolicited event queue */
138 u32 unsol_queue[HDA_UNSOL_QUEUE_SIZE * 2]; /* ring buffer */
139 unsigned int unsol_rp, unsol_wp;
140 struct work_struct unsol_work;
141
142 /* bit flags of powered codecs */
143 unsigned long codec_powered;
144
145 /* flags */
146 bool sync_write:1; /* sync after verb write */
147
148 /* locks */
149 struct mutex cmd_mutex;
150};
151
152int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
153 const struct hdac_bus_ops *ops);
154void snd_hdac_bus_exit(struct hdac_bus *bus);
155int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
156 unsigned int cmd, unsigned int *res);
157int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
158 unsigned int cmd, unsigned int *res);
159void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
160
161int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec);
162void snd_hdac_bus_remove_device(struct hdac_bus *bus,
163 struct hdac_device *codec);
164
Takashi Iwai7639a062015-03-03 10:07:24 +0100165static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
166{
167 set_bit(codec->addr, &codec->bus->codec_powered);
168}
169
170static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
171{
172 clear_bit(codec->addr, &codec->bus->codec_powered);
173}
174
Takashi Iwaie3d280f2015-02-17 21:46:37 +0100175#endif /* __SOUND_HDAUDIO_H */