summaryrefslogtreecommitdiffstats
path: root/package/lqtapi/src/include/linux/tapi/tapi.h
blob: 410655d4c98a14b46400c3e3c238696a8a11ecf7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#ifndef __LINUX_TAPI_H__
#define __LINUX_TAPI_H__

#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/mutex.h>

#include <linux/input.h>

#include <asm/atomic.h>
#include <linux/list.h>

#include <linux/cdev.h>

#include <linux/skbuff.h>
#include <linux/wait.h>

#include <linux/tapi/tapi-event.h>

struct tapi_device;

struct tapi_char_device {
	struct tapi_device *tdev;
	struct device dev;
	struct cdev cdev;
};

static inline struct tapi_char_device *cdev_to_tapi_char_device(struct cdev *cdev)
{
	return container_of(cdev, struct tapi_char_device, cdev);
}

int tapi_char_device_register(struct tapi_device *tdev,
	struct tapi_char_device *tchrdev, const struct file_operations *fops);


struct tapi_endpoint {
	unsigned int id;
	void *data;
};

static inline void tapi_endpoint_set_data(struct tapi_endpoint *ep, void *data)
{
	ep->data = data;
}

static inline void *tapi_endpoint_get_data(struct tapi_endpoint *ep)
{
	return ep->data;
}

struct tapi_port {
	unsigned int id;
	struct tapi_endpoint ep;
	struct input_dev *input;
	struct tapi_char_device chrdev;
};

struct tapi_stream {
	unsigned int id;
	struct list_head head;
	struct tapi_endpoint ep;

	struct sk_buff_head recv_queue;
	wait_queue_head_t recv_wait;
	struct sk_buff_head send_queue;
};

struct tapi_link {
	unsigned int id;
	struct list_head head;
};

enum tapi_codec {
	TAPI_CODEC_L16,
};

struct tapi_stream_config {
	enum tapi_codec codec;
	unsigned int buffer_size;
};

struct tapi_ops {
	int (*send_dtmf_events)(struct tapi_device *, struct tapi_port *port,
		struct tapi_dtmf_event *, size_t num_events, unsigned int dealy);
	int (*send_dtmf_event)(struct tapi_device *, struct tapi_port *port,
		struct tapi_dtmf_event *);
	int (*ring)(struct tapi_device *, struct tapi_port *port, bool ring);

	struct tapi_stream *(*stream_alloc)(struct tapi_device *);
	void (*stream_free)(struct tapi_device *, struct tapi_stream *);
	int (*stream_configure)(struct tapi_device *, struct tapi_stream *,
		struct tapi_stream_config *);
	int (*stream_start)(struct tapi_device *, struct tapi_stream *);
	int (*stream_stop)(struct tapi_device *, struct tapi_stream *);
	int (*stream_send)(struct tapi_device *, struct tapi_stream *,
		struct sk_buff *);

	struct tapi_link *(*link_alloc)(struct tapi_device *,
		struct tapi_endpoint *ep1, struct tapi_endpoint *ep2);
	void (*link_free)(struct tapi_device *, struct tapi_link *);
	int (*link_enable)(struct tapi_device *, struct tapi_link *);
	int (*link_disable)(struct tapi_device *, struct tapi_link *);

	int (*sync)(struct tapi_device *);
};

int tapi_stream_recv(struct tapi_device *, struct tapi_stream *, struct sk_buff *);

struct tapi_device {
	unsigned int id;

	const struct tapi_ops *ops;
	unsigned int num_ports;

	struct device dev;

	struct mutex lock;

	struct tapi_port *ports;
	struct list_head streams;
	struct list_head links;
	atomic_t stream_id;
	atomic_t link_id;

	struct tapi_char_device stream_dev;
	struct tapi_char_device control_dev;
};

static inline struct tapi_device *dev_to_tapi(struct device *dev)
{
	return container_of(dev, struct tapi_device, dev);
}

static inline struct tapi_stream *tapi_stream_from_id(struct tapi_device *tdev,
	unsigned int id)
{
	struct tapi_stream *stream;

	mutex_lock(&tdev->lock);

	list_for_each_entry(stream, &tdev->streams, head) {
		if (stream->id == id)
			goto out;
	}
	stream = NULL;

out:
	mutex_unlock(&tdev->lock);
	return stream;
}

struct tapi_link *tapi_link_alloc(struct tapi_device *, struct tapi_endpoint *,
	struct tapi_endpoint *);
void tapi_link_free(struct tapi_device *, struct tapi_link *);

struct tapi_stream *tapi_stream_alloc(struct tapi_device *tdev);
void tapi_stream_free(struct tapi_device *tdev, struct tapi_stream *stream);

static inline int tapi_sync(struct tapi_device *tdev)
{
	if (!tdev->ops || !tdev->ops->sync)
		return 0;

	return tdev->ops->sync(tdev);
}

static inline int tapi_link_enable(struct tapi_device *tdev,
	struct tapi_link *link)
{
	if (!tdev->ops || !tdev->ops->link_enable)
		return 0;

	return tdev->ops->link_enable(tdev, link);
}

static inline int tapi_link_disable(struct tapi_device *tdev,
	struct tapi_link *link)
{
	if (!tdev->ops || !tdev->ops->link_disable)
		return 0;

	return tdev->ops->link_disable(tdev, link);
}

static inline int tapi_port_send_dtmf(struct tapi_device *tdev,
	struct tapi_port *port,	struct tapi_dtmf_event *dtmf)
{
	if (!tdev->ops || !tdev->ops->send_dtmf_event)
		return -ENOSYS;

	return tdev->ops->send_dtmf_event(tdev, port, dtmf);
}

static inline int tapi_port_set_ring(struct tapi_device *tdev,
	struct tapi_port *port, bool ring)
{
	if (!tdev->ops || !tdev->ops->ring)
		return -ENOSYS;

	return tdev->ops->ring(tdev, port, ring);
}

static inline int tapi_stream_start(struct tapi_device *tdev,
struct tapi_stream *stream)
{
	if (!tdev->ops || !tdev->ops->stream_start)
		return -ENOSYS;

	return tdev->ops->stream_start(tdev, stream);
}

static inline int tapi_stream_stop(struct tapi_device *tdev,
struct tapi_stream *stream)
{
	if (!tdev->ops || !tdev->ops->stream_stop)
		return -ENOSYS;

	return tdev->ops->stream_stop(tdev, stream);
}

int tapi_device_register(struct tapi_device *tdev, const char *name,
	struct device *parent);
void tapi_device_unregister(struct tapi_device *tdev);

struct tapi_sysfs_port;

struct tapi_sysfs_port *tapi_port_alloc(struct tapi_device *tdev, unsigned int id);
void tapi_port_delete(struct tapi_sysfs_port *);

#endif