2009-12-11 14:34:07 +03:00
/*
* Remote Controller core header
*
2010-03-25 02:47:53 +03:00
* Copyright ( C ) 2009 - 2010 by Mauro Carvalho Chehab < mchehab @ redhat . com >
*
2009-12-11 14:34:07 +03:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*/
# ifndef _IR_CORE
# define _IR_CORE
# include <linux/spinlock.h>
2010-03-21 02:59:44 +03:00
# include <linux/kfifo.h>
# include <linux/time.h>
2010-03-21 19:00:55 +03:00
# include <linux/timer.h>
2010-04-03 03:01:00 +04:00
# include <media/rc-map.h>
2009-12-11 14:34:07 +03:00
extern int ir_core_debug ;
# define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \
printk ( KERN_DEBUG " %s: " fmt , __func__ , # # arg )
2010-04-07 06:21:46 +04:00
enum rc_driver_type {
RC_DRIVER_SCANCODE = 0 , /* Driver or hardware generates a scancode */
RC_DRIVER_IR_RAW , /* Needs a Infra-Red pulse/space decoder */
} ;
2010-04-04 21:06:55 +04:00
/**
2010-10-29 23:08:23 +04:00
* struct rc_dev - represents a remote control device
* @ dev : driver model ' s view of this device
* @ input_name : name of the input child device
* @ input_phys : physical path to the input child device
* @ input_id : id of the input child device ( struct input_id )
* @ driver_name : name of the hardware driver which registered this device
* @ map_name : name of the default keymap
* @ rc_tab : current scan / key table
* @ devno : unique remote control device number
* @ raw : additional data for raw pulse / space devices
* @ input_dev : the input child device used to communicate events to userspace
* @ driver_type : specifies if protocol decoding is done in hardware or software
* @ idle : used to keep track of RX state
2010-04-04 21:06:55 +04:00
* @ allowed_protos : bitmask with the supported IR_TYPE_ * protocols
* @ scanmask : some hardware decoders are not capable of providing the full
* scancode to the application . As this is a hardware limit , we can ' t do
* anything with it . Yet , as the same keycode table can be used with other
* devices , a mask is provided to allow its usage . Drivers should generally
* leave this field in blank
2010-10-29 23:08:23 +04:00
* @ priv : driver - specific data
* @ keylock : protects the remaining members of the struct
* @ keypressed : whether a key is currently pressed
* @ keyup_jiffies : time ( in jiffies ) when the current keypress should be released
* @ timer_keyup : timer for releasing a keypress
* @ last_keycode : keycode of last keypress
* @ last_scancode : scancode of last keypress
* @ last_toggle : toggle value of last command
2010-07-31 18:59:22 +04:00
* @ timeout : optional time after which device stops sending data
* @ min_timeout : minimum timeout supported by device
* @ max_timeout : maximum timeout supported by device
2010-07-31 18:59:23 +04:00
* @ rx_resolution : resolution ( in ns ) of input sampler
* @ tx_resolution : resolution ( in ns ) of output sampler
2010-04-04 21:06:55 +04:00
* @ change_protocol : allow changing the protocol used on hardware decoders
* @ open : callback to allow drivers to enable polling / irq when IR input device
* is opened .
* @ close : callback to allow drivers to disable polling / irq when IR input device
* is opened .
2010-06-17 00:55:25 +04:00
* @ s_tx_mask : set transmitter mask ( for devices with multiple tx outputs )
* @ s_tx_carrier : set transmit carrier frequency
2010-07-31 18:59:23 +04:00
* @ s_tx_duty_cycle : set transmit duty cycle ( 0 % - 100 % )
* @ s_rx_carrier : inform driver about carrier it is expected to handle
2010-06-17 00:55:25 +04:00
* @ tx_ir : transmit IR
2010-10-29 23:08:23 +04:00
* @ s_idle : enable / disable hardware idle mode , upon which ,
* device doesn ' t interrupt host until it sees IR pulses
2010-07-31 18:59:23 +04:00
* @ s_learning_mode : enable wide band receiver used for learning
2010-10-17 02:56:28 +04:00
* @ s_carrier_report : enable carrier reports
2010-04-04 21:06:55 +04:00
*/
2010-10-29 23:08:23 +04:00
struct rc_dev {
struct device dev ;
const char * input_name ;
const char * input_phys ;
struct input_id input_id ;
char * driver_name ;
const char * map_name ;
struct ir_scancode_table rc_tab ;
unsigned long devno ;
struct ir_raw_event_ctrl * raw ;
struct input_dev * input_dev ;
enum rc_driver_type driver_type ;
2010-07-31 18:59:22 +04:00
bool idle ;
2010-10-29 23:08:23 +04:00
u64 allowed_protos ;
u32 scanmask ;
void * priv ;
spinlock_t keylock ;
bool keypressed ;
unsigned long keyup_jiffies ;
struct timer_list timer_keyup ;
u32 last_keycode ;
u32 last_scancode ;
u8 last_toggle ;
u32 timeout ;
u32 min_timeout ;
u32 max_timeout ;
u32 rx_resolution ;
u32 tx_resolution ;
int ( * change_protocol ) ( struct rc_dev * dev , u64 ir_type ) ;
int ( * open ) ( struct rc_dev * dev ) ;
void ( * close ) ( struct rc_dev * dev ) ;
int ( * s_tx_mask ) ( struct rc_dev * dev , u32 mask ) ;
int ( * s_tx_carrier ) ( struct rc_dev * dev , u32 carrier ) ;
int ( * s_tx_duty_cycle ) ( struct rc_dev * dev , u32 duty_cycle ) ;
int ( * s_rx_carrier_range ) ( struct rc_dev * dev , u32 min , u32 max ) ;
int ( * tx_ir ) ( struct rc_dev * dev , int * txbuf , u32 n ) ;
void ( * s_idle ) ( struct rc_dev * dev , bool enable ) ;
int ( * s_learning_mode ) ( struct rc_dev * dev , int enable ) ;
int ( * s_carrier_report ) ( struct rc_dev * dev , int enable ) ;
2009-12-11 15:44:23 +03:00
} ;
2010-03-21 02:59:44 +03:00
2010-04-08 22:10:27 +04:00
enum raw_event_type {
IR_SPACE = ( 1 < < 0 ) ,
IR_PULSE = ( 1 < < 1 ) ,
IR_START_EVENT = ( 1 < < 2 ) ,
IR_STOP_EVENT = ( 1 < < 3 ) ,
2010-03-25 02:47:53 +03:00
} ;
2010-10-29 23:08:23 +04:00
# define to_rc_dev(d) container_of(d, struct rc_dev, dev)
2010-07-31 18:59:21 +04:00
2010-04-02 20:18:42 +04:00
2010-10-29 23:08:23 +04:00
void ir_repeat ( struct rc_dev * dev ) ;
void ir_keydown ( struct rc_dev * dev , int scancode , u8 toggle ) ;
void ir_keydown_notimeout ( struct rc_dev * dev , int scancode , u8 toggle ) ;
void ir_keyup ( struct rc_dev * dev ) ;
u32 ir_g_keycode_from_table ( struct rc_dev * dev , u32 scancode ) ;
2009-12-13 22:00:08 +03:00
2010-04-08 22:10:27 +04:00
/* From ir-raw-event.c */
2010-04-16 01:46:00 +04:00
struct ir_raw_event {
2010-10-17 02:56:28 +04:00
union {
u32 duration ;
struct {
u32 carrier ;
u8 duty_cycle ;
} ;
} ;
unsigned pulse : 1 ;
unsigned reset : 1 ;
unsigned timeout : 1 ;
unsigned carrier_report : 1 ;
2010-04-16 01:46:00 +04:00
} ;
2010-10-17 02:56:28 +04:00
# define DEFINE_IR_RAW_EVENT(event) \
struct ir_raw_event event = { \
{ . duration = 0 } , \
. pulse = 0 , \
. reset = 0 , \
. timeout = 0 , \
. carrier_report = 0 }
static inline void init_ir_raw_event ( struct ir_raw_event * ev )
{
memset ( ev , 0 , sizeof ( * ev ) ) ;
}
# define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */
2010-04-16 01:46:00 +04:00
2010-10-29 23:08:23 +04:00
struct rc_dev * rc_allocate_device ( void ) ;
void rc_free_device ( struct rc_dev * dev ) ;
int rc_register_device ( struct rc_dev * dev ) ;
void rc_unregister_device ( struct rc_dev * dev ) ;
void ir_raw_event_handle ( struct rc_dev * dev ) ;
int ir_raw_event_store ( struct rc_dev * dev , struct ir_raw_event * ev ) ;
int ir_raw_event_store_edge ( struct rc_dev * dev , enum raw_event_type type ) ;
int ir_raw_event_store_with_filter ( struct rc_dev * dev ,
2010-07-31 18:59:22 +04:00
struct ir_raw_event * ev ) ;
2010-10-29 23:08:23 +04:00
void ir_raw_event_set_idle ( struct rc_dev * dev , bool idle ) ;
2010-07-31 18:59:22 +04:00
2010-10-29 23:08:23 +04:00
static inline void ir_raw_event_reset ( struct rc_dev * dev )
2010-04-16 01:46:00 +04:00
{
2010-10-17 02:56:28 +04:00
DEFINE_IR_RAW_EVENT ( ev ) ;
ev . reset = true ;
2010-10-29 23:08:23 +04:00
ir_raw_event_store ( dev , & ev ) ;
ir_raw_event_handle ( dev ) ;
2010-04-16 01:46:00 +04:00
}
2010-04-08 20:10:00 +04:00
2010-10-29 23:08:12 +04:00
/* extract mask bits out of data and pack them into the result */
static inline u32 ir_extract_bits ( u32 data , u32 mask )
{
u32 vbit = 1 , value = 0 ;
do {
if ( mask & 1 ) {
if ( data & 1 )
value | = vbit ;
vbit < < = 1 ;
}
data > > = 1 ;
} while ( mask > > = 1 ) ;
return value ;
}
2010-03-25 02:47:53 +03:00
# endif /* _IR_CORE */