ALSA: hda - Add widget sysfs tree
[firefly-linux-kernel-4.4.55.git] / include / sound / hdaudio.h
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 */
12 typedef u16 hda_nid_t;
13
14 struct hdac_bus;
15 struct hdac_device;
16 struct hdac_driver;
17 struct hdac_widget_tree;
18
19 /*
20  * exported bus type
21  */
22 extern struct bus_type snd_hda_bus_type;
23
24 /*
25  * HD-audio codec base device
26  */
27 struct hdac_device {
28         struct device dev;
29         int type;
30         struct hdac_bus *bus;
31         unsigned int addr;              /* codec address */
32         struct list_head list;          /* list point for bus codec_list */
33
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 */
57
58         /* sysfs */
59         struct hdac_widget_tree *widgets;
60 };
61
62 /* device/driver type used for matching */
63 enum {
64         HDA_DEV_CORE,
65         HDA_DEV_LEGACY,
66 };
67
68 /* direction */
69 enum {
70         HDA_INPUT, HDA_OUTPUT
71 };
72
73 #define dev_to_hdac_dev(_dev)   container_of(_dev, struct hdac_device, dev)
74
75 int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
76                          const char *name, unsigned int addr);
77 void snd_hdac_device_exit(struct hdac_device *dev);
78 int snd_hdac_device_register(struct hdac_device *codec);
79 void snd_hdac_device_unregister(struct hdac_device *codec);
80
81 int snd_hdac_refresh_widgets(struct hdac_device *codec);
82
83 unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
84                                unsigned int verb, unsigned int parm);
85 int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
86                   unsigned int verb, unsigned int parm, unsigned int *res);
87 int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm);
88 int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
89                              hda_nid_t *conn_list, int max_conns);
90 int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
91                            hda_nid_t *start_id);
92
93 #ifdef CONFIG_PM
94 void snd_hdac_power_up(struct hdac_device *codec);
95 void snd_hdac_power_down(struct hdac_device *codec);
96 #else
97 static inline void snd_hdac_power_up(struct hdac_device *codec) {}
98 static inline void snd_hdac_power_down(struct hdac_device *codec) {}
99 #endif
100
101 /*
102  * HD-audio codec base driver
103  */
104 struct hdac_driver {
105         struct device_driver driver;
106         int type;
107         int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
108         void (*unsol_event)(struct hdac_device *dev, unsigned int event);
109 };
110
111 #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
112
113 /*
114  * HD-audio bus base driver
115  */
116 struct 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
126 struct 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
152 int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
153                       const struct hdac_bus_ops *ops);
154 void snd_hdac_bus_exit(struct hdac_bus *bus);
155 int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
156                            unsigned int cmd, unsigned int *res);
157 int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
158                                     unsigned int cmd, unsigned int *res);
159 void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
160
161 int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec);
162 void snd_hdac_bus_remove_device(struct hdac_bus *bus,
163                                 struct hdac_device *codec);
164
165 static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
166 {
167         set_bit(codec->addr, &codec->bus->codec_powered);
168 }
169
170 static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
171 {
172         clear_bit(codec->addr, &codec->bus->codec_powered);
173 }
174
175 #endif /* __SOUND_HDAUDIO_H */