X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=include%2Fmedia%2Fir-core.h;h=ad1303f20e002d0484a056d432ca24d11a41e2f8;hb=e40b1127f994a427568319d1be9b9e5ab1f58dd1;hp=39df3cf9e8452ca3440c60835f12a89fa7bcf71b;hpb=9ce50c1a5faad80cf6100ea4e8970416ee3b8b59;p=safe%2Fjmp%2Flinux-2.6 diff --git a/include/media/ir-core.h b/include/media/ir-core.h index 39df3cf..ad1303f 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h @@ -16,64 +16,46 @@ #ifndef _IR_CORE #define _IR_CORE -#include #include #include #include #include +#include extern int ir_core_debug; #define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \ printk(KERN_DEBUG "%s: " fmt , __func__, ## arg) -#define IR_TYPE_UNKNOWN 0 -#define IR_TYPE_RC5 (1 << 0) /* Philips RC5 protocol */ -#define IR_TYPE_PD (1 << 1) /* Pulse distance encoded IR */ -#define IR_TYPE_NEC (1 << 2) -#define IR_TYPE_OTHER (((u64)1) << 63l) - -enum raw_event_type { - IR_SPACE = (1 << 0), - IR_PULSE = (1 << 1), - IR_START_EVENT = (1 << 2), - IR_STOP_EVENT = (1 << 3), -}; - -struct ir_scancode { - u16 scancode; - u32 keycode; -}; - -struct ir_scancode_table { - struct ir_scancode *scan; - int size; - u64 ir_type; - char *name; - spinlock_t lock; -}; - -struct rc_keymap { - struct list_head list; - struct ir_scancode_table map; +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 */ }; +/** + * struct ir_dev_props - Allow caller drivers to set special properties + * @driver_type: specifies if the driver or hardware have already a decoder, + * or if it needs to use the IR raw event decoders to produce a scancode + * @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 + * @priv: driver-specific data, to be used on the callbacks + * @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. + */ struct ir_dev_props { - unsigned long allowed_protos; - void *priv; - int (*change_protocol)(void *priv, u64 ir_type); - int (*open)(void *priv); - void (*close)(void *priv); -}; - -struct ir_raw_event { - struct timespec delta; /* Time spent before event */ - enum raw_event_type type; /* event type */ -}; - -struct ir_raw_event_ctrl { - struct kfifo kfifo; /* fifo for the pulse/space events */ - struct timespec last_event; /* when last event occurred */ - struct timer_list timer_keyup; /* timer for key release */ + enum rc_driver_type driver_type; + unsigned long allowed_protos; + u32 scanmask; + void *priv; + int (*change_protocol)(void *priv, u64 ir_type); + int (*open)(void *priv); + void (*close)(void *priv); }; struct ir_input_dev { @@ -83,79 +65,84 @@ struct ir_input_dev { unsigned long devno; /* device number */ const struct ir_dev_props *props; /* Device properties */ struct ir_raw_event_ctrl *raw; /* for raw pulse/space events */ + struct input_dev *input_dev; /* the input device associated with this device */ /* key info - needed by IR keycode handlers */ - u32 keycode; /* linux key code */ - int keypressed; /* current state */ + spinlock_t keylock; /* protects the below members */ + bool keypressed; /* current state */ + unsigned long keyup_jiffies; /* when should the current keypress be released? */ + struct timer_list timer_keyup; /* timer for releasing a keypress */ + u32 last_keycode; /* keycode of last command */ + u32 last_scancode; /* scancode of last command */ + u8 last_toggle; /* toggle of last command */ }; -struct ir_raw_handler { - struct list_head list; - - int (*decode)(struct input_dev *input_dev, - struct ir_raw_event *evs, - int len); - int (*raw_register)(struct input_dev *input_dev); - int (*raw_unregister)(struct input_dev *input_dev); +enum raw_event_type { + IR_SPACE = (1 << 0), + IR_PULSE = (1 << 1), + IR_START_EVENT = (1 << 2), + IR_STOP_EVENT = (1 << 3), }; #define to_ir_input_dev(_attr) container_of(_attr, struct ir_input_dev, attr) -#define IR_KEYTABLE(a) \ -ir_codes_ ## a ## _table +/* From ir-keytable.c */ +int __ir_input_register(struct input_dev *dev, + const struct ir_scancode_table *ir_codes, + const struct ir_dev_props *props, + const char *driver_name); -#define DECLARE_IR_KEYTABLE(a) \ -extern struct ir_scancode_table IR_KEYTABLE(a) +static inline int ir_input_register(struct input_dev *dev, + const char *map_name, + const struct ir_dev_props *props, + const char *driver_name) { + struct ir_scancode_table *ir_codes; + struct ir_input_dev *ir_dev; + int rc; -#define DEFINE_IR_KEYTABLE(tabname, type) \ -struct ir_scancode_table IR_KEYTABLE(tabname) = { \ - .scan = tabname, \ - .size = ARRAY_SIZE(tabname), \ - .ir_type = type, \ - .name = #tabname, \ -}; \ -EXPORT_SYMBOL_GPL(IR_KEYTABLE(tabname)) + if (!map_name) + return -EINVAL; -#define DEFINE_LEGACY_IR_KEYTABLE(tabname) \ - DEFINE_IR_KEYTABLE(tabname, IR_TYPE_UNKNOWN) + ir_codes = get_rc_map(map_name); + if (!ir_codes) + return -EINVAL; -/* Routines from ir-keytable.c */ + rc = __ir_input_register(dev, ir_codes, props, driver_name); + if (rc < 0) + return -EINVAL; -u32 ir_g_keycode_from_table(struct input_dev *input_dev, - u32 scancode); -void ir_keyup(struct input_dev *dev); -void ir_keydown(struct input_dev *dev, int scancode); -int ir_input_register(struct input_dev *dev, - const struct ir_scancode_table *ir_codes, - const struct ir_dev_props *props, - const char *driver_name); -void ir_input_unregister(struct input_dev *input_dev); + ir_dev = input_get_drvdata(dev); -/* Routines from rc-map.c */ + if (!rc && ir_dev->props && ir_dev->props->change_protocol) + rc = ir_dev->props->change_protocol(ir_dev->props->priv, + ir_codes->ir_type); -int ir_register_map(struct rc_keymap *map); -void ir_unregister_map(struct rc_keymap *map); -struct ir_scancode_table *get_rc_map(const char *name); + return rc; +} -/* Routines from ir-sysfs.c */ +void ir_input_unregister(struct input_dev *input_dev); -int ir_register_class(struct input_dev *input_dev); -void ir_unregister_class(struct input_dev *input_dev); +void ir_repeat(struct input_dev *dev); +void ir_keydown(struct input_dev *dev, int scancode, u8 toggle); +u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode); -/* Routines from ir-raw-event.c */ -int ir_raw_event_register(struct input_dev *input_dev); -void ir_raw_event_unregister(struct input_dev *input_dev); -int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type); -int ir_raw_event_handle(struct input_dev *input_dev); -int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); -void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); -void ir_raw_init(void); +/* From ir-raw-event.c */ + +struct ir_raw_event { + unsigned pulse:1; + unsigned duration:31; +}; -/* from ir-nec-decoder.c */ -#ifdef CONFIG_IR_NEC_DECODER_MODULE -#define load_nec_decode() request_module("ir-nec-decoder") -#else -#define load_nec_decode() 0 -#endif +#define IR_MAX_DURATION 0x7FFFFFFF /* a bit more than 2 seconds */ + +void ir_raw_event_handle(struct input_dev *input_dev); +int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev); +int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type); +static inline void ir_raw_event_reset(struct input_dev *input_dev) +{ + struct ir_raw_event ev = { .pulse = false, .duration = 0 }; + ir_raw_event_store(input_dev, &ev); + ir_raw_event_handle(input_dev); +} #endif /* _IR_CORE */