2010-07-03 01:06:57 -03:00
/*
* LIRC base driver
*
* by Artur Lipowski < alipowski @ interia . pl >
* This code is licensed under GNU GPL
*
*/
# ifndef _LINUX_LIRC_DEV_H
# define _LINUX_LIRC_DEV_H
# define BUFLEN 16
# include <linux/slab.h>
# include <linux/fs.h>
# include <linux/ioctl.h>
# include <linux/poll.h>
# include <linux/kfifo.h>
# include <media/lirc.h>
2017-06-25 09:32:36 -03:00
# include <linux/device.h>
# include <linux/cdev.h>
2010-07-03 01:06:57 -03:00
struct lirc_buffer {
wait_queue_head_t wait_poll ;
spinlock_t fifo_lock ;
unsigned int chunk_size ;
unsigned int size ; /* in chunks */
/* Using chunks instead of bytes pretends to simplify boundary checking
* And should allow for some performance fine tunning later */
struct kfifo fifo ;
} ;
static inline void lirc_buffer_clear ( struct lirc_buffer * buf )
{
unsigned long flags ;
2014-10-28 18:51:01 -03:00
if ( kfifo_initialized ( & buf - > fifo ) ) {
2010-07-03 01:06:57 -03:00
spin_lock_irqsave ( & buf - > fifo_lock , flags ) ;
kfifo_reset ( & buf - > fifo ) ;
spin_unlock_irqrestore ( & buf - > fifo_lock , flags ) ;
} else
WARN ( 1 , " calling %s on an uninitialized lirc_buffer \n " ,
__func__ ) ;
}
static inline int lirc_buffer_init ( struct lirc_buffer * buf ,
unsigned int chunk_size ,
unsigned int size )
{
int ret ;
init_waitqueue_head ( & buf - > wait_poll ) ;
spin_lock_init ( & buf - > fifo_lock ) ;
buf - > chunk_size = chunk_size ;
buf - > size = size ;
ret = kfifo_alloc ( & buf - > fifo , size * chunk_size , GFP_KERNEL ) ;
return ret ;
}
static inline void lirc_buffer_free ( struct lirc_buffer * buf )
{
2014-10-28 18:51:01 -03:00
if ( kfifo_initialized ( & buf - > fifo ) ) {
2010-07-03 01:06:57 -03:00
kfifo_free ( & buf - > fifo ) ;
} else
WARN ( 1 , " calling %s on an uninitialized lirc_buffer \n " ,
__func__ ) ;
}
static inline int lirc_buffer_len ( struct lirc_buffer * buf )
{
int len ;
unsigned long flags ;
spin_lock_irqsave ( & buf - > fifo_lock , flags ) ;
len = kfifo_len ( & buf - > fifo ) ;
spin_unlock_irqrestore ( & buf - > fifo_lock , flags ) ;
return len ;
}
static inline int lirc_buffer_full ( struct lirc_buffer * buf )
{
return lirc_buffer_len ( buf ) = = buf - > size * buf - > chunk_size ;
}
static inline int lirc_buffer_empty ( struct lirc_buffer * buf )
{
return ! lirc_buffer_len ( buf ) ;
}
static inline unsigned int lirc_buffer_read ( struct lirc_buffer * buf ,
unsigned char * dest )
{
unsigned int ret = 0 ;
if ( lirc_buffer_len ( buf ) > = buf - > chunk_size )
ret = kfifo_out_locked ( & buf - > fifo , dest , buf - > chunk_size ,
& buf - > fifo_lock ) ;
return ret ;
}
static inline unsigned int lirc_buffer_write ( struct lirc_buffer * buf ,
unsigned char * orig )
{
unsigned int ret ;
ret = kfifo_in_locked ( & buf - > fifo , orig , buf - > chunk_size ,
& buf - > fifo_lock ) ;
return ret ;
}
2015-10-05 13:35:37 -03:00
/**
2017-09-21 16:13:34 -03:00
* struct lirc_dev - represents a LIRC device
2015-10-05 13:35:37 -03:00
*
2017-09-21 16:13:34 -03:00
* @ name : used for logging
* @ minor : the minor device ( / dev / lircX ) number for the device
* @ code_length : length of a remote control key code expressed in bits
2015-10-05 13:35:37 -03:00
* @ features : lirc compatible hardware features , like LIRC_MODE_RAW ,
2016-07-17 09:16:57 -03:00
* LIRC_CAN \ _ \ * , as defined at include / media / lirc . h .
2017-06-25 09:31:45 -03:00
* @ buffer_size : Number of FIFO buffers with @ chunk_size size .
* Only used if @ rbuf is NULL .
2015-10-05 13:35:37 -03:00
* @ chunk_size : Size of each FIFO buffer .
2017-06-25 09:31:45 -03:00
* Only used if @ rbuf is NULL .
2017-09-21 16:13:34 -03:00
* @ data : private per - driver data
2017-06-25 09:32:36 -03:00
* @ buf : if % NULL , lirc_dev will allocate and manage the buffer ,
* otherwise allocated by the caller which will
2015-10-05 13:35:37 -03:00
* have to write to the buffer by other means , like irq ' s
* ( see also lirc_serial . c ) .
2017-06-25 09:32:36 -03:00
* @ buf_internal : whether lirc_dev has allocated the read buffer or not
2017-09-21 16:13:34 -03:00
* @ rdev : & struct rc_dev associated with the device
* @ fops : & struct file_operations for the device
2015-10-05 13:35:37 -03:00
* @ owner : the module owning this struct
2017-06-25 09:32:36 -03:00
* @ attached : if the device is still live
* @ open : open count for the device ' s chardev
* @ mutex : serialises file_operations calls
* @ dev : & struct device assigned to the device
* @ cdev : & struct cdev assigned to the device
2015-10-05 13:35:37 -03:00
*/
2017-09-21 16:13:34 -03:00
struct lirc_dev {
2010-07-03 01:06:57 -03:00
char name [ 40 ] ;
2017-06-25 09:31:24 -03:00
unsigned int minor ;
2010-10-08 17:24:21 -03:00
__u32 code_length ;
__u32 features ;
2010-07-03 01:06:57 -03:00
2017-06-25 09:31:45 -03:00
unsigned int buffer_size ; /* in chunks holding one code each */
2010-07-03 01:06:57 -03:00
unsigned int chunk_size ;
2017-06-25 09:32:36 -03:00
struct lirc_buffer * buf ;
bool buf_internal ;
2010-07-03 01:06:57 -03:00
void * data ;
[media] media: lirc: Allow lirc dev to talk to rc device
The use case is simple, if any rc device has allowed protocols =
RC_TYPE_LIRC and map_name = RC_MAP_LIRC set, the driver open will be never
called. The reason for this is, all of the key maps except lirc have some
KEYS in there map, so during rc_register_device process these keys are
matched against the input drivers and open is performed, so for the case
of RC_MAP_EMPTY, a vt/keyboard is matched and the driver open is
performed.
In case of lirc, there is no match and result is that there is no open
performed, however the lirc-dev will go ahead and create a /dev/lirc0
node. Now when lircd/mode2 opens this device, no data is available
because the driver was never opened.
Other case pointed by Sean Young, As rc device gets opened via the
input interface. If the input device is never opened (e.g. embedded with
no console) then the rc open is never called and lirc will not work
either. So that's another case.
lirc_dev seems to have no link with actual rc device w.r.t open/close.
This patch adds rc_dev pointer to lirc_driver structure for cases like
this, so that it can do the open/close of the real driver in accordance
to lircd/mode2 open/close.
Without this patch its impossible to open a rc device which has
RC_TYPE_LIRC ad RC_MAP_LIRC set.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2013-07-22 04:23:07 -03:00
struct rc_dev * rdev ;
2010-09-30 16:55:07 -03:00
const struct file_operations * fops ;
2010-07-03 01:06:57 -03:00
struct module * owner ;
2017-06-25 09:32:36 -03:00
bool attached ;
int open ;
struct mutex mutex ; /* protect from simultaneous accesses */
struct device dev ;
struct cdev cdev ;
2010-07-03 01:06:57 -03:00
} ;
2017-06-25 09:32:15 -03:00
struct lirc_dev * lirc_allocate_device ( void ) ;
void lirc_free_device ( struct lirc_dev * d ) ;
2017-09-21 16:13:34 -03:00
int lirc_register_device ( struct lirc_dev * d ) ;
2010-07-03 01:06:57 -03:00
2017-09-21 16:13:34 -03:00
void lirc_unregister_device ( struct lirc_dev * d ) ;
2010-07-03 01:06:57 -03:00
2017-06-25 09:31:40 -03:00
/* Must be called in the open fop before lirc_get_pdata() can be used */
void lirc_init_pdata ( struct inode * inode , struct file * file ) ;
2017-09-21 16:13:34 -03:00
/* Returns the private data stored in the lirc_dev
2010-07-03 01:06:57 -03:00
* associated with the given device file pointer .
*/
void * lirc_get_pdata ( struct file * file ) ;
/* default file operations
* used by drivers if they override only some operations
*/
int lirc_dev_fop_open ( struct inode * inode , struct file * file ) ;
int lirc_dev_fop_close ( struct inode * inode , struct file * file ) ;
unsigned int lirc_dev_fop_poll ( struct file * file , poll_table * wait ) ;
2010-08-02 15:43:35 -03:00
long lirc_dev_fop_ioctl ( struct file * file , unsigned int cmd , unsigned long arg ) ;
2010-11-17 02:13:39 -03:00
ssize_t lirc_dev_fop_read ( struct file * file , char __user * buffer , size_t length ,
2010-07-03 01:06:57 -03:00
loff_t * ppos ) ;
# endif