at v4.15 5.2 kB view raw
1/* 2 * LIRC base driver 3 * 4 * by Artur Lipowski <alipowski@interia.pl> 5 * This code is licensed under GNU GPL 6 * 7 */ 8 9#ifndef _LINUX_LIRC_DEV_H 10#define _LINUX_LIRC_DEV_H 11 12#define BUFLEN 16 13 14#include <linux/slab.h> 15#include <linux/fs.h> 16#include <linux/ioctl.h> 17#include <linux/poll.h> 18#include <linux/kfifo.h> 19#include <media/lirc.h> 20#include <linux/device.h> 21#include <linux/cdev.h> 22 23struct lirc_buffer { 24 wait_queue_head_t wait_poll; 25 spinlock_t fifo_lock; 26 unsigned int chunk_size; 27 unsigned int size; /* in chunks */ 28 /* Using chunks instead of bytes pretends to simplify boundary checking 29 * And should allow for some performance fine tunning later */ 30 struct kfifo fifo; 31}; 32 33static inline void lirc_buffer_clear(struct lirc_buffer *buf) 34{ 35 unsigned long flags; 36 37 if (kfifo_initialized(&buf->fifo)) { 38 spin_lock_irqsave(&buf->fifo_lock, flags); 39 kfifo_reset(&buf->fifo); 40 spin_unlock_irqrestore(&buf->fifo_lock, flags); 41 } else 42 WARN(1, "calling %s on an uninitialized lirc_buffer\n", 43 __func__); 44} 45 46static inline int lirc_buffer_init(struct lirc_buffer *buf, 47 unsigned int chunk_size, 48 unsigned int size) 49{ 50 int ret; 51 52 init_waitqueue_head(&buf->wait_poll); 53 spin_lock_init(&buf->fifo_lock); 54 buf->chunk_size = chunk_size; 55 buf->size = size; 56 ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL); 57 58 return ret; 59} 60 61static inline void lirc_buffer_free(struct lirc_buffer *buf) 62{ 63 if (kfifo_initialized(&buf->fifo)) { 64 kfifo_free(&buf->fifo); 65 } else 66 WARN(1, "calling %s on an uninitialized lirc_buffer\n", 67 __func__); 68} 69 70static inline int lirc_buffer_len(struct lirc_buffer *buf) 71{ 72 int len; 73 unsigned long flags; 74 75 spin_lock_irqsave(&buf->fifo_lock, flags); 76 len = kfifo_len(&buf->fifo); 77 spin_unlock_irqrestore(&buf->fifo_lock, flags); 78 79 return len; 80} 81 82static inline int lirc_buffer_full(struct lirc_buffer *buf) 83{ 84 return lirc_buffer_len(buf) == buf->size * buf->chunk_size; 85} 86 87static inline int lirc_buffer_empty(struct lirc_buffer *buf) 88{ 89 return !lirc_buffer_len(buf); 90} 91 92static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf, 93 unsigned char *dest) 94{ 95 unsigned int ret = 0; 96 97 if (lirc_buffer_len(buf) >= buf->chunk_size) 98 ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size, 99 &buf->fifo_lock); 100 return ret; 101 102} 103 104static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf, 105 unsigned char *orig) 106{ 107 unsigned int ret; 108 109 ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size, 110 &buf->fifo_lock); 111 112 return ret; 113} 114 115/** 116 * struct lirc_dev - represents a LIRC device 117 * 118 * @name: used for logging 119 * @minor: the minor device (/dev/lircX) number for the device 120 * @code_length: length of a remote control key code expressed in bits 121 * @features: lirc compatible hardware features, like LIRC_MODE_RAW, 122 * LIRC_CAN\_\*, as defined at include/media/lirc.h. 123 * @buffer_size: Number of FIFO buffers with @chunk_size size. 124 * Only used if @rbuf is NULL. 125 * @chunk_size: Size of each FIFO buffer. 126 * Only used if @rbuf is NULL. 127 * @data: private per-driver data 128 * @buf: if %NULL, lirc_dev will allocate and manage the buffer, 129 * otherwise allocated by the caller which will 130 * have to write to the buffer by other means, like irq's 131 * (see also lirc_serial.c). 132 * @buf_internal: whether lirc_dev has allocated the read buffer or not 133 * @rdev: &struct rc_dev associated with the device 134 * @fops: &struct file_operations for the device 135 * @owner: the module owning this struct 136 * @attached: if the device is still live 137 * @open: open count for the device's chardev 138 * @mutex: serialises file_operations calls 139 * @dev: &struct device assigned to the device 140 * @cdev: &struct cdev assigned to the device 141 */ 142struct lirc_dev { 143 char name[40]; 144 unsigned int minor; 145 __u32 code_length; 146 __u32 features; 147 148 unsigned int buffer_size; /* in chunks holding one code each */ 149 unsigned int chunk_size; 150 struct lirc_buffer *buf; 151 bool buf_internal; 152 153 void *data; 154 struct rc_dev *rdev; 155 const struct file_operations *fops; 156 struct module *owner; 157 158 bool attached; 159 int open; 160 161 struct mutex mutex; /* protect from simultaneous accesses */ 162 163 struct device dev; 164 struct cdev cdev; 165}; 166 167struct lirc_dev *lirc_allocate_device(void); 168 169void lirc_free_device(struct lirc_dev *d); 170 171int lirc_register_device(struct lirc_dev *d); 172 173void lirc_unregister_device(struct lirc_dev *d); 174 175/* Must be called in the open fop before lirc_get_pdata() can be used */ 176void lirc_init_pdata(struct inode *inode, struct file *file); 177 178/* Returns the private data stored in the lirc_dev 179 * associated with the given device file pointer. 180 */ 181void *lirc_get_pdata(struct file *file); 182 183/* default file operations 184 * used by drivers if they override only some operations 185 */ 186int lirc_dev_fop_open(struct inode *inode, struct file *file); 187int lirc_dev_fop_close(struct inode *inode, struct file *file); 188unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait); 189long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 190ssize_t lirc_dev_fop_read(struct file *file, char __user *buffer, size_t length, 191 loff_t *ppos); 192#endif