1
2
3
4
5
6
7
8
9#ifndef _LINUX_LIRC_DEV_H
10#define _LINUX_LIRC_DEV_H
11
12#define MAX_IRCTL_DEVICES 8
13#define BUFLEN 16
14
15#define mod(n, div) ((n) % (div))
16
17#include <linux/slab.h>
18#include <linux/fs.h>
19#include <linux/ioctl.h>
20#include <linux/poll.h>
21#include <linux/kfifo.h>
22#include <media/lirc.h>
23
24struct lirc_buffer {
25 wait_queue_head_t wait_poll;
26 spinlock_t fifo_lock;
27 unsigned int chunk_size;
28 unsigned int size;
29
30
31 struct kfifo fifo;
32};
33
34static inline void lirc_buffer_clear(struct lirc_buffer *buf)
35{
36 unsigned long flags;
37
38 if (kfifo_initialized(&buf->fifo)) {
39 spin_lock_irqsave(&buf->fifo_lock, flags);
40 kfifo_reset(&buf->fifo);
41 spin_unlock_irqrestore(&buf->fifo_lock, flags);
42 } else
43 WARN(1, "calling %s on an uninitialized lirc_buffer\n",
44 __func__);
45}
46
47static inline int lirc_buffer_init(struct lirc_buffer *buf,
48 unsigned int chunk_size,
49 unsigned int size)
50{
51 int ret;
52
53 init_waitqueue_head(&buf->wait_poll);
54 spin_lock_init(&buf->fifo_lock);
55 buf->chunk_size = chunk_size;
56 buf->size = size;
57 ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL);
58
59 return ret;
60}
61
62static inline void lirc_buffer_free(struct lirc_buffer *buf)
63{
64 if (kfifo_initialized(&buf->fifo)) {
65 kfifo_free(&buf->fifo);
66 } else
67 WARN(1, "calling %s on an uninitialized lirc_buffer\n",
68 __func__);
69}
70
71static inline int lirc_buffer_len(struct lirc_buffer *buf)
72{
73 int len;
74 unsigned long flags;
75
76 spin_lock_irqsave(&buf->fifo_lock, flags);
77 len = kfifo_len(&buf->fifo);
78 spin_unlock_irqrestore(&buf->fifo_lock, flags);
79
80 return len;
81}
82
83static inline int lirc_buffer_full(struct lirc_buffer *buf)
84{
85 return lirc_buffer_len(buf) == buf->size * buf->chunk_size;
86}
87
88static inline int lirc_buffer_empty(struct lirc_buffer *buf)
89{
90 return !lirc_buffer_len(buf);
91}
92
93static inline int lirc_buffer_available(struct lirc_buffer *buf)
94{
95 return buf->size - (lirc_buffer_len(buf) / buf->chunk_size);
96}
97
98static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf,
99 unsigned char *dest)
100{
101 unsigned int ret = 0;
102
103 if (lirc_buffer_len(buf) >= buf->chunk_size)
104 ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size,
105 &buf->fifo_lock);
106 return ret;
107
108}
109
110static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
111 unsigned char *orig)
112{
113 unsigned int ret;
114
115 ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size,
116 &buf->fifo_lock);
117
118 return ret;
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
186struct lirc_driver {
187 char name[40];
188 int minor;
189 __u32 code_length;
190 unsigned int buffer_size;
191 int sample_rate;
192 __u32 features;
193
194 unsigned int chunk_size;
195
196 void *data;
197 int min_timeout;
198 int max_timeout;
199 int (*add_to_buf)(void *data, struct lirc_buffer *buf);
200 struct lirc_buffer *rbuf;
201 int (*set_use_inc)(void *data);
202 void (*set_use_dec)(void *data);
203 struct rc_dev *rdev;
204 const struct file_operations *fops;
205 struct device *dev;
206 struct module *owner;
207};
208
209
210
211
212
213
214
215extern int lirc_register_driver(struct lirc_driver *d);
216
217
218
219extern int lirc_unregister_driver(int minor);
220
221
222
223
224void *lirc_get_pdata(struct file *file);
225
226
227
228
229int lirc_dev_fop_open(struct inode *inode, struct file *file);
230int lirc_dev_fop_close(struct inode *inode, struct file *file);
231unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait);
232long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
233ssize_t lirc_dev_fop_read(struct file *file, char __user *buffer, size_t length,
234 loff_t *ppos);
235ssize_t lirc_dev_fop_write(struct file *file, const char __user *buffer,
236 size_t length, loff_t *ppos);
237
238#endif
239