1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#ifndef __LINUX_HSI_H__
24#define __LINUX_HSI_H__
25
26#include <linux/device.h>
27#include <linux/mutex.h>
28#include <linux/scatterlist.h>
29#include <linux/list.h>
30#include <linux/module.h>
31#include <linux/notifier.h>
32
33
34#define HSI_MSG_READ 0
35#define HSI_MSG_WRITE 1
36
37
38enum {
39 HSI_MODE_STREAM = 1,
40 HSI_MODE_FRAME,
41};
42
43enum {
44 HSI_FLOW_SYNC,
45 HSI_FLOW_PIPE,
46};
47
48enum {
49 HSI_ARB_RR,
50 HSI_ARB_PRIO,
51};
52
53#define HSI_MAX_CHANNELS 16
54
55
56enum {
57 HSI_STATUS_COMPLETED,
58 HSI_STATUS_PENDING,
59 HSI_STATUS_PROCEEDING,
60 HSI_STATUS_QUEUED,
61 HSI_STATUS_ERROR,
62};
63
64
65enum {
66 HSI_EVENT_START_RX,
67 HSI_EVENT_STOP_RX,
68};
69
70
71
72
73
74
75
76
77
78struct hsi_config {
79 unsigned int mode;
80 unsigned int channels;
81 unsigned int speed;
82 union {
83 unsigned int flow;
84 unsigned int arb_mode;
85 };
86};
87
88
89
90
91
92
93
94
95
96
97
98struct hsi_board_info {
99 const char *name;
100 unsigned int hsi_id;
101 unsigned int port;
102 struct hsi_config tx_cfg;
103 struct hsi_config rx_cfg;
104 void *platform_data;
105 struct dev_archdata *archdata;
106};
107
108#ifdef CONFIG_HSI_BOARDINFO
109extern int hsi_register_board_info(struct hsi_board_info const *info,
110 unsigned int len);
111#else
112static inline int hsi_register_board_info(struct hsi_board_info const *info,
113 unsigned int len)
114{
115 return 0;
116}
117#endif
118
119
120
121
122
123
124
125
126
127
128struct hsi_client {
129 struct device device;
130 struct hsi_config tx_cfg;
131 struct hsi_config rx_cfg;
132
133 void (*ehandler)(struct hsi_client *, unsigned long);
134 unsigned int pclaimed:1;
135 struct notifier_block nb;
136};
137
138#define to_hsi_client(dev) container_of(dev, struct hsi_client, device)
139
140static inline void hsi_client_set_drvdata(struct hsi_client *cl, void *data)
141{
142 dev_set_drvdata(&cl->device, data);
143}
144
145static inline void *hsi_client_drvdata(struct hsi_client *cl)
146{
147 return dev_get_drvdata(&cl->device);
148}
149
150int hsi_register_port_event(struct hsi_client *cl,
151 void (*handler)(struct hsi_client *, unsigned long));
152int hsi_unregister_port_event(struct hsi_client *cl);
153
154
155
156
157
158struct hsi_client_driver {
159 struct device_driver driver;
160};
161
162#define to_hsi_client_driver(drv) container_of(drv, struct hsi_client_driver,\
163 driver)
164
165int hsi_register_client_driver(struct hsi_client_driver *drv);
166
167static inline void hsi_unregister_client_driver(struct hsi_client_driver *drv)
168{
169 driver_unregister(&drv->driver);
170}
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187struct hsi_msg {
188 struct list_head link;
189 struct hsi_client *cl;
190 struct sg_table sgt;
191 void *context;
192
193 void (*complete)(struct hsi_msg *msg);
194 void (*destructor)(struct hsi_msg *msg);
195
196 int status;
197 unsigned int actual_len;
198 unsigned int channel;
199 unsigned int ttype:1;
200 unsigned int break_frame:1;
201};
202
203struct hsi_msg *hsi_alloc_msg(unsigned int n_frag, gfp_t flags);
204void hsi_free_msg(struct hsi_msg *msg);
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223struct hsi_port {
224 struct device device;
225 struct hsi_config tx_cfg;
226 struct hsi_config rx_cfg;
227 unsigned int num;
228 unsigned int shared:1;
229 int claimed;
230 struct mutex lock;
231 int (*async)(struct hsi_msg *msg);
232 int (*setup)(struct hsi_client *cl);
233 int (*flush)(struct hsi_client *cl);
234 int (*start_tx)(struct hsi_client *cl);
235 int (*stop_tx)(struct hsi_client *cl);
236 int (*release)(struct hsi_client *cl);
237
238 struct atomic_notifier_head n_head;
239};
240
241#define to_hsi_port(dev) container_of(dev, struct hsi_port, device)
242#define hsi_get_port(cl) to_hsi_port((cl)->device.parent)
243
244int hsi_event(struct hsi_port *port, unsigned long event);
245int hsi_claim_port(struct hsi_client *cl, unsigned int share);
246void hsi_release_port(struct hsi_client *cl);
247
248static inline int hsi_port_claimed(struct hsi_client *cl)
249{
250 return cl->pclaimed;
251}
252
253static inline void hsi_port_set_drvdata(struct hsi_port *port, void *data)
254{
255 dev_set_drvdata(&port->device, data);
256}
257
258static inline void *hsi_port_drvdata(struct hsi_port *port)
259{
260 return dev_get_drvdata(&port->device);
261}
262
263
264
265
266
267
268
269
270
271struct hsi_controller {
272 struct device device;
273 struct module *owner;
274 unsigned int id;
275 unsigned int num_ports;
276 struct hsi_port **port;
277};
278
279#define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device)
280
281struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags);
282void hsi_put_controller(struct hsi_controller *hsi);
283int hsi_register_controller(struct hsi_controller *hsi);
284void hsi_unregister_controller(struct hsi_controller *hsi);
285
286static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi,
287 void *data)
288{
289 dev_set_drvdata(&hsi->device, data);
290}
291
292static inline void *hsi_controller_drvdata(struct hsi_controller *hsi)
293{
294 return dev_get_drvdata(&hsi->device);
295}
296
297static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi,
298 unsigned int num)
299{
300 return (num < hsi->num_ports) ? hsi->port[num] : NULL;
301}
302
303
304
305
306int hsi_async(struct hsi_client *cl, struct hsi_msg *msg);
307
308
309
310
311
312
313
314static inline unsigned int hsi_id(struct hsi_client *cl)
315{
316 return to_hsi_controller(cl->device.parent->parent)->id;
317}
318
319
320
321
322
323
324
325static inline unsigned int hsi_port_id(struct hsi_client *cl)
326{
327 return to_hsi_port(cl->device.parent)->num;
328}
329
330
331
332
333
334
335
336
337
338
339static inline int hsi_setup(struct hsi_client *cl)
340{
341 if (!hsi_port_claimed(cl))
342 return -EACCES;
343 return hsi_get_port(cl)->setup(cl);
344}
345
346
347
348
349
350
351
352
353
354
355static inline int hsi_flush(struct hsi_client *cl)
356{
357 if (!hsi_port_claimed(cl))
358 return -EACCES;
359 return hsi_get_port(cl)->flush(cl);
360}
361
362
363
364
365
366
367
368
369static inline int hsi_async_read(struct hsi_client *cl, struct hsi_msg *msg)
370{
371 msg->ttype = HSI_MSG_READ;
372 return hsi_async(cl, msg);
373}
374
375
376
377
378
379
380
381
382static inline int hsi_async_write(struct hsi_client *cl, struct hsi_msg *msg)
383{
384 msg->ttype = HSI_MSG_WRITE;
385 return hsi_async(cl, msg);
386}
387
388
389
390
391
392
393
394static inline int hsi_start_tx(struct hsi_client *cl)
395{
396 if (!hsi_port_claimed(cl))
397 return -EACCES;
398 return hsi_get_port(cl)->start_tx(cl);
399}
400
401
402
403
404
405
406
407static inline int hsi_stop_tx(struct hsi_client *cl)
408{
409 if (!hsi_port_claimed(cl))
410 return -EACCES;
411 return hsi_get_port(cl)->stop_tx(cl);
412}
413#endif
414