2005-04-16 15:20:36 -07:00
/*
*
* keyboard input driver for i2c IR remote controls
*
* Copyright ( c ) 2000 - 2003 Gerd Knorr < kraxel @ bytesex . org >
* modified for PixelView ( BT878P + W / FM ) by
* Michal Kochanowicz < mkochano @ pld . org . pl >
* Christoph Bartelmus < lirc @ bartelmus . de >
* modified for KNC ONE TV Station / Anubis Typhoon TView Tuner by
* Ulrich Mueller < ulrich . mueller42 @ web . de >
2005-11-08 21:37:21 -08:00
* modified for em2820 based USB TV tuners by
* Markus Rechberger < mrechberger @ gmail . com >
2007-08-24 01:02:32 -03:00
* modified for DViCO Fusion HDTV 5 RT GOLD by
* Chaogui Zhang < czhang1974 @ gmail . com >
2008-10-13 08:37:06 -03:00
* modified for MSI TV @ nywhere Plus by
* Henry Wong < henry @ stuffedcow . net >
* Mark Schultz < n9xmj @ yahoo . com >
* Brian Rogers < brian_rogers @ comcast . net >
2009-02-12 03:43:11 -03:00
* modified for AVerMedia Cardbus by
* Oldrich Jedlicka < oldium . pro @ seznam . cz >
2005-04-16 15:20:36 -07: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 ; either version 2 of the License , or
* ( at your option ) any later version .
*
* 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 .
*
*/
2016-09-19 19:21:23 -03:00
# include <asm/unaligned.h>
2005-04-16 15:20:36 -07:00
# include <linux/module.h>
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/string.h>
# include <linux/timer.h>
# include <linux/delay.h>
# include <linux/errno.h>
# include <linux/slab.h>
# include <linux/i2c.h>
# include <linux/workqueue.h>
2005-12-12 00:37:28 -08:00
2010-11-17 13:28:38 -03:00
# include <media/rc-core.h>
2015-11-10 12:01:44 -02:00
# include <media/i2c/ir-kbd-i2c.h>
2005-11-08 21:37:21 -08:00
2005-04-16 15:20:36 -07:00
2017-08-07 16:20:58 -04:00
static int get_key_haup_common ( struct IR_i2c * ir , enum rc_proto * protocol ,
u32 * scancode , u8 * ptoggle , int size )
2005-04-16 15:20:36 -07:00
{
2007-06-25 14:34:06 -03:00
unsigned char buf [ 6 ] ;
2016-09-19 19:21:23 -03:00
int start , range , toggle , dev , code , ircode , vendor ;
2005-04-16 15:20:36 -07:00
/* poll IR chip */
2009-05-13 16:48:50 -03:00
if ( size ! = i2c_master_recv ( ir - > c , buf , size ) )
2005-04-16 15:20:36 -07:00
return - EIO ;
2016-09-19 19:21:23 -03:00
if ( buf [ 0 ] & 0x80 ) {
int offset = ( size = = 6 ) ? 3 : 0 ;
2005-04-16 15:20:36 -07:00
2016-09-19 19:21:23 -03:00
/* split rc5 data block ... */
start = ( buf [ offset ] > > 7 ) & 1 ;
range = ( buf [ offset ] > > 6 ) & 1 ;
toggle = ( buf [ offset ] > > 5 ) & 1 ;
dev = buf [ offset ] & 0x1f ;
code = ( buf [ offset + 1 ] > > 2 ) & 0x3f ;
2014-04-03 20:31:25 -03:00
2016-09-19 19:21:23 -03:00
/* rc5 has two start bits
* the first bit must be one
* the second bit defines the command range :
* 1 = 0 - 63 , 0 = 64 - 127
*/
if ( ! start )
/* no key pressed */
return 0 ;
2008-09-22 00:54:59 -03:00
2016-09-19 19:21:23 -03:00
/* filter out invalid key presses */
ircode = ( start < < 12 ) | ( toggle < < 11 ) | ( dev < < 6 ) | code ;
if ( ( ircode & 0x1fff ) = = 0x1fff )
return 0 ;
2006-09-26 16:39:00 -03:00
2016-09-19 19:21:23 -03:00
if ( ! range )
code + = 64 ;
2005-04-16 15:20:36 -07:00
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev ,
" ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d \n " ,
2016-09-19 19:21:23 -03:00
start , range , toggle , dev , code ) ;
2017-08-07 16:20:58 -04:00
* protocol = RC_PROTO_RC5 ;
2016-09-19 19:21:23 -03:00
* scancode = RC_SCANCODE_RC5 ( dev , code ) ;
* ptoggle = toggle ;
return 1 ;
} else if ( size = = 6 & & ( buf [ 0 ] & 0x40 ) ) {
code = buf [ 4 ] ;
dev = buf [ 3 ] ;
vendor = get_unaligned_be16 ( buf + 1 ) ;
if ( vendor = = 0x800f ) {
* ptoggle = ( dev & 0x80 ) ! = 0 ;
2017-08-07 16:20:58 -04:00
* protocol = RC_PROTO_RC6_MCE ;
2016-09-19 19:21:23 -03:00
dev & = 0x7f ;
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev ,
" ir hauppauge (rc6-mce): t%d vendor=%d dev=%d code=%d \n " ,
* ptoggle , vendor , dev , code ) ;
2016-09-19 19:21:23 -03:00
} else {
* ptoggle = 0 ;
2017-08-07 16:20:58 -04:00
* protocol = RC_PROTO_RC6_6A_32 ;
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev ,
" ir hauppauge (rc6-6a-32): vendor=%d dev=%d code=%d \n " ,
vendor , dev , code ) ;
2016-09-19 19:21:23 -03:00
}
* scancode = RC_SCANCODE_RC6_6A ( vendor , dev , code ) ;
return 1 ;
}
return 0 ;
2005-04-16 15:20:36 -07:00
}
2017-08-07 16:20:58 -04:00
static int get_key_haup ( struct IR_i2c * ir , enum rc_proto * protocol ,
2014-04-03 20:31:25 -03:00
u32 * scancode , u8 * toggle )
2007-06-25 14:34:06 -03:00
{
2016-09-19 19:21:23 -03:00
return get_key_haup_common ( ir , protocol , scancode , toggle , 3 ) ;
2007-06-25 14:34:06 -03:00
}
2017-08-07 16:20:58 -04:00
static int get_key_haup_xvr ( struct IR_i2c * ir , enum rc_proto * protocol ,
2014-04-03 20:31:25 -03:00
u32 * scancode , u8 * toggle )
2007-06-25 14:34:06 -03:00
{
2011-01-20 18:31:18 -03:00
int ret ;
unsigned char buf [ 1 ] = { 0 } ;
/*
* This is the same apparent " are you ready? " poll command observed
* watching Windows driver traffic and implemented in lirc_zilog . With
* this added , we get far saner remote behavior with z8 chips on usb
* connected devices , even with the default polling interval of 100 ms .
*/
ret = i2c_master_send ( ir - > c , buf , 1 ) ;
if ( ret ! = 1 )
return ( ret < 0 ) ? ret : - EINVAL ;
2016-09-19 19:21:23 -03:00
return get_key_haup_common ( ir , protocol , scancode , toggle , 6 ) ;
2007-06-25 14:34:06 -03:00
}
2017-08-07 16:20:58 -04:00
static int get_key_pixelview ( struct IR_i2c * ir , enum rc_proto * protocol ,
2014-04-03 20:31:25 -03:00
u32 * scancode , u8 * toggle )
2005-04-16 15:20:36 -07:00
{
2005-11-08 21:37:43 -08:00
unsigned char b ;
2005-04-16 15:20:36 -07:00
/* poll IR chip */
2009-05-13 16:48:50 -03:00
if ( 1 ! = i2c_master_recv ( ir - > c , & b , 1 ) ) {
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " read error \n " ) ;
2005-04-16 15:20:36 -07:00
return - EIO ;
}
2014-04-03 20:31:25 -03:00
2017-08-07 16:20:58 -04:00
* protocol = RC_PROTO_OTHER ;
2014-04-03 20:31:25 -03:00
* scancode = b ;
* toggle = 0 ;
2005-04-16 15:20:36 -07:00
return 1 ;
}
2017-08-07 16:20:58 -04:00
static int get_key_fusionhdtv ( struct IR_i2c * ir , enum rc_proto * protocol ,
2014-04-03 20:31:25 -03:00
u32 * scancode , u8 * toggle )
2007-08-24 01:02:32 -03:00
{
unsigned char buf [ 4 ] ;
/* poll IR chip */
2009-05-13 16:48:50 -03:00
if ( 4 ! = i2c_master_recv ( ir - > c , buf , 4 ) ) {
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " read error \n " ) ;
2007-08-24 01:02:32 -03:00
return - EIO ;
}
2017-10-18 10:00:50 -04:00
if ( buf [ 0 ] ! = 0 | | buf [ 1 ] ! = 0 | | buf [ 2 ] ! = 0 | | buf [ 3 ] ! = 0 )
dev_dbg ( & ir - > rc - > dev , " %s: %*ph \n " , __func__ , 4 , buf ) ;
2007-08-24 01:02:32 -03:00
/* no key pressed or signal from other ir remote */
if ( buf [ 0 ] ! = 0x1 | | buf [ 1 ] ! = 0xfe )
return 0 ;
2017-08-07 16:20:58 -04:00
* protocol = RC_PROTO_UNKNOWN ;
2014-04-03 20:31:25 -03:00
* scancode = buf [ 2 ] ;
* toggle = 0 ;
2007-08-24 01:02:32 -03:00
return 1 ;
}
2017-08-07 16:20:58 -04:00
static int get_key_knc1 ( struct IR_i2c * ir , enum rc_proto * protocol ,
2014-04-03 20:31:25 -03:00
u32 * scancode , u8 * toggle )
2005-04-16 15:20:36 -07:00
{
unsigned char b ;
/* poll IR chip */
2009-05-13 16:48:50 -03:00
if ( 1 ! = i2c_master_recv ( ir - > c , & b , 1 ) ) {
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " read error \n " ) ;
2005-04-16 15:20:36 -07:00
return - EIO ;
}
/* it seems that 0xFE indicates that a button is still hold
2005-11-08 21:37:36 -08:00
down , while 0xff indicates that no button is hold
down . 0xfe sequences are sometimes interrupted by 0xFF */
2005-04-16 15:20:36 -07:00
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " key %02x \n " , b ) ;
2005-04-16 15:20:36 -07:00
2005-11-08 21:37:36 -08:00
if ( b = = 0xff )
2005-04-16 15:20:36 -07:00
return 0 ;
2005-11-08 21:37:36 -08:00
if ( b = = 0xfe )
2005-04-16 15:20:36 -07:00
/* keep old data */
return 1 ;
2017-08-07 16:20:58 -04:00
* protocol = RC_PROTO_UNKNOWN ;
2014-04-03 20:31:25 -03:00
* scancode = b ;
* toggle = 0 ;
2005-04-16 15:20:36 -07:00
return 1 ;
}
2017-08-07 16:20:58 -04:00
static int get_key_avermedia_cardbus ( struct IR_i2c * ir , enum rc_proto * protocol ,
2014-04-03 20:31:25 -03:00
u32 * scancode , u8 * toggle )
2009-02-12 03:43:11 -03:00
{
unsigned char subaddr , key , keygroup ;
2009-05-13 16:48:50 -03:00
struct i2c_msg msg [ ] = { { . addr = ir - > c - > addr , . flags = 0 ,
2009-02-12 03:43:11 -03:00
. buf = & subaddr , . len = 1 } ,
2009-05-13 16:48:50 -03:00
{ . addr = ir - > c - > addr , . flags = I2C_M_RD ,
2009-02-12 03:43:11 -03:00
. buf = & key , . len = 1 } } ;
subaddr = 0x0d ;
2009-05-13 16:48:50 -03:00
if ( 2 ! = i2c_transfer ( ir - > c - > adapter , msg , 2 ) ) {
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " read error \n " ) ;
2009-02-12 03:43:11 -03:00
return - EIO ;
}
if ( key = = 0xff )
return 0 ;
subaddr = 0x0b ;
msg [ 1 ] . buf = & keygroup ;
2009-05-13 16:48:50 -03:00
if ( 2 ! = i2c_transfer ( ir - > c - > adapter , msg , 2 ) ) {
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " read error \n " ) ;
2009-02-12 03:43:11 -03:00
return - EIO ;
}
if ( keygroup = = 0xff )
return 0 ;
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " read key 0x%02x/0x%02x \n " , key , keygroup ) ;
2013-04-06 14:28:16 -03:00
if ( keygroup < 2 | | keygroup > 4 ) {
2017-10-18 10:00:50 -04:00
dev_warn ( & ir - > rc - > dev , " warning: invalid key group 0x%02x for key 0x%02x \n " ,
keygroup , key ) ;
2009-02-12 03:43:11 -03:00
}
key | = ( keygroup & 1 ) < < 6 ;
2017-08-07 16:20:58 -04:00
* protocol = RC_PROTO_UNKNOWN ;
2014-04-03 20:31:25 -03:00
* scancode = key ;
if ( ir - > c - > addr = = 0x41 ) /* AVerMedia EM78P153 */
* scancode | = keygroup < < 8 ;
* toggle = 0 ;
2009-02-12 03:43:11 -03:00
return 1 ;
}
2005-04-16 15:20:36 -07:00
/* ----------------------------------------------------------------------- */
2012-01-09 22:28:13 -02:00
static int ir_key_poll ( struct IR_i2c * ir )
2005-04-16 15:20:36 -07:00
{
2017-08-07 16:20:58 -04:00
enum rc_proto protocol ;
2014-04-03 20:31:25 -03:00
u32 scancode ;
u8 toggle ;
2005-04-16 15:20:36 -07:00
int rc ;
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " %s \n " , __func__ ) ;
2014-04-03 20:31:25 -03:00
rc = ir - > get_key ( ir , & protocol , & scancode , & toggle ) ;
2005-04-16 15:20:36 -07:00
if ( rc < 0 ) {
2017-10-18 10:00:50 -04:00
dev_warn ( & ir - > rc - > dev , " error %d \n " , rc ) ;
2012-01-09 22:28:13 -02:00
return rc ;
2005-04-16 15:20:36 -07:00
}
2011-01-12 13:50:01 -03:00
if ( rc ) {
2017-10-18 10:00:50 -04:00
dev_dbg ( & ir - > rc - > dev , " %s: proto = 0x%04x, scancode = 0x%08x \n " ,
2014-04-03 20:31:30 -03:00
__func__ , protocol , scancode ) ;
rc_keydown ( ir - > rc , protocol , scancode , toggle ) ;
2011-01-12 13:50:01 -03:00
}
2012-01-09 22:28:13 -02:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
2006-11-22 14:57:56 +00:00
static void ir_work ( struct work_struct * work )
2005-04-16 15:20:36 -07:00
{
2012-01-09 22:28:13 -02:00
int rc ;
2009-03-07 07:43:43 -03:00
struct IR_i2c * ir = container_of ( work , struct IR_i2c , work . work ) ;
2007-05-21 11:51:11 -03:00
2012-01-09 22:28:13 -02:00
rc = ir_key_poll ( ir ) ;
if ( rc = = - ENODEV ) {
rc_unregister_device ( ir - > rc ) ;
ir - > rc = NULL ;
return ;
}
2010-09-23 01:23:10 -03:00
schedule_delayed_work ( & ir - > work , msecs_to_jiffies ( ir - > polling_interval ) ) ;
2005-04-16 15:20:36 -07:00
}
/* ----------------------------------------------------------------------- */
2009-05-13 16:48:50 -03:00
static int ir_probe ( struct i2c_client * client , const struct i2c_device_id * id )
2005-04-16 15:20:36 -07:00
{
2010-04-02 20:01:00 -03:00
char * ir_codes = NULL ;
2009-05-13 16:50:11 -03:00
const char * name = NULL ;
2017-08-07 16:20:58 -04:00
u64 rc_proto = RC_PROTO_BIT_UNKNOWN ;
2005-12-12 00:37:27 -08:00
struct IR_i2c * ir ;
2010-11-12 09:02:40 -03:00
struct rc_dev * rc = NULL ;
2009-05-13 16:48:50 -03:00
struct i2c_adapter * adap = client - > adapter ;
unsigned short addr = client - > addr ;
2006-11-20 10:23:04 -03:00
int err ;
2005-04-16 15:20:36 -07:00
2013-05-02 08:29:43 -03:00
ir = devm_kzalloc ( & client - > dev , sizeof ( * ir ) , GFP_KERNEL ) ;
2010-11-12 09:02:40 -03:00
if ( ! ir )
return - ENOMEM ;
2005-09-15 02:01:53 -05:00
2009-05-13 16:48:50 -03:00
ir - > c = client ;
2010-09-23 01:23:10 -03:00
ir - > polling_interval = DEFAULT_POLLING_INTERVAL ;
2009-05-13 16:48:50 -03:00
i2c_set_clientdata ( client , ir ) ;
2006-01-09 15:25:21 -02:00
2005-04-16 15:20:36 -07:00
switch ( addr ) {
case 0x64 :
name = " Pixelview " ;
ir - > get_key = get_key_pixelview ;
2017-08-07 16:20:58 -04:00
rc_proto = RC_PROTO_BIT_OTHER ;
2010-04-02 20:01:00 -03:00
ir_codes = RC_MAP_EMPTY ;
2005-04-16 15:20:36 -07:00
break ;
case 0x18 :
2009-11-13 05:48:24 -03:00
case 0x1f :
2005-04-16 15:20:36 -07:00
case 0x1a :
name = " Hauppauge " ;
ir - > get_key = get_key_haup ;
2017-08-07 16:20:58 -04:00
rc_proto = RC_PROTO_BIT_RC5 ;
2011-01-24 22:23:08 -03:00
ir_codes = RC_MAP_HAUPPAUGE ;
2005-04-16 15:20:36 -07:00
break ;
case 0x30 :
2005-11-08 21:37:32 -08:00
name = " KNC One " ;
ir - > get_key = get_key_knc1 ;
2017-08-07 16:20:58 -04:00
rc_proto = RC_PROTO_BIT_OTHER ;
2010-04-02 20:01:00 -03:00
ir_codes = RC_MAP_EMPTY ;
2005-04-16 15:20:36 -07:00
break ;
2007-08-24 01:02:32 -03:00
case 0x6b :
2007-08-24 01:07:12 -03:00
name = " FusionHDTV " ;
ir - > get_key = get_key_fusionhdtv ;
2017-08-07 16:20:58 -04:00
rc_proto = RC_PROTO_BIT_UNKNOWN ;
2010-04-02 20:01:00 -03:00
ir_codes = RC_MAP_FUSIONHDTV_MCE ;
2007-08-24 01:02:32 -03:00
break ;
2009-02-12 03:43:11 -03:00
case 0x40 :
name = " AVerMedia Cardbus remote " ;
ir - > get_key = get_key_avermedia_cardbus ;
2017-08-07 16:20:58 -04:00
rc_proto = RC_PROTO_BIT_OTHER ;
2010-04-02 20:01:00 -03:00
ir_codes = RC_MAP_AVERMEDIA_CARDBUS ;
2009-02-12 03:43:11 -03:00
break ;
2013-04-06 14:28:16 -03:00
case 0x41 :
name = " AVerMedia EM78P153 " ;
ir - > get_key = get_key_avermedia_cardbus ;
2017-08-07 16:20:58 -04:00
rc_proto = RC_PROTO_BIT_OTHER ;
2013-04-06 14:28:16 -03:00
/* RM-KV remote, seems to be same as RM-K6 */
ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6 ;
break ;
2011-01-16 15:45:32 -03:00
case 0x71 :
name = " Hauppauge/Zilog Z8 " ;
ir - > get_key = get_key_haup_xvr ;
2017-08-07 16:20:58 -04:00
rc_proto = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
RC_PROTO_BIT_RC6_6A_32 ;
2011-01-24 22:23:08 -03:00
ir_codes = RC_MAP_HAUPPAUGE ;
2011-01-16 15:45:32 -03:00
break ;
2005-04-16 15:20:36 -07:00
}
2009-05-13 16:49:32 -03:00
/* Let the caller override settings */
if ( client - > dev . platform_data ) {
const struct IR_i2c_init_data * init_data =
client - > dev . platform_data ;
ir_codes = init_data - > ir_codes ;
2010-11-12 09:02:40 -03:00
rc = init_data - > rc_dev ;
2009-05-13 16:49:32 -03:00
name = init_data - > name ;
2009-07-28 11:44:05 -03:00
if ( init_data - > type )
2017-08-07 16:20:58 -04:00
rc_proto = init_data - > type ;
2009-07-28 11:44:05 -03:00
2010-09-23 01:23:10 -03:00
if ( init_data - > polling_interval )
ir - > polling_interval = init_data - > polling_interval ;
2009-07-28 11:44:05 -03:00
switch ( init_data - > internal_get_key_func ) {
case IR_KBD_GET_KEY_CUSTOM :
/* The bridge driver provided us its own function */
ir - > get_key = init_data - > get_key ;
break ;
case IR_KBD_GET_KEY_PIXELVIEW :
ir - > get_key = get_key_pixelview ;
break ;
case IR_KBD_GET_KEY_HAUP :
ir - > get_key = get_key_haup ;
break ;
case IR_KBD_GET_KEY_KNC1 :
ir - > get_key = get_key_knc1 ;
break ;
case IR_KBD_GET_KEY_FUSIONHDTV :
ir - > get_key = get_key_fusionhdtv ;
break ;
case IR_KBD_GET_KEY_HAUP_XVR :
ir - > get_key = get_key_haup_xvr ;
break ;
case IR_KBD_GET_KEY_AVERMEDIA_CARDBUS :
ir - > get_key = get_key_avermedia_cardbus ;
break ;
}
2009-05-13 16:49:32 -03:00
}
2010-11-12 09:02:40 -03:00
if ( ! rc ) {
/*
2013-10-20 21:34:01 -03:00
* If platform_data doesn ' t specify rc_dev , initialize it
2010-11-12 09:02:40 -03:00
* internally
*/
2016-12-16 06:50:58 -02:00
rc = rc_allocate_device ( RC_DRIVER_SCANCODE ) ;
2013-05-02 08:29:43 -03:00
if ( ! rc )
return - ENOMEM ;
2010-11-12 09:02:40 -03:00
}
ir - > rc = rc ;
2009-05-13 16:50:11 -03:00
/* Make sure we are all setup before going on */
2017-08-07 16:20:58 -04:00
if ( ! name | | ! ir - > get_key | | ! rc_proto | | ! ir_codes ) {
2017-10-18 10:00:50 -04:00
dev_warn ( & client - > dev , " Unsupported device at address 0x%02x \n " ,
addr ) ;
2009-05-13 16:50:11 -03:00
err = - ENODEV ;
goto err_out_free ;
}
2006-11-20 10:23:04 -03:00
ir - > ir_codes = ir_codes ;
2005-11-08 21:37:32 -08:00
2017-10-18 09:39:12 -04:00
snprintf ( ir - > phys , sizeof ( ir - > phys ) , " %s/%s " , dev_name ( & adap - > dev ) ,
2009-05-13 16:48:50 -03:00
dev_name ( & client - > dev ) ) ;
2005-11-08 21:37:56 -08:00
2010-11-12 09:02:40 -03:00
/*
* Initialize input_dev fields
* It doesn ' t make sense to allow overriding them via platform_data
*/
2010-10-29 16:08:23 -03:00
rc - > input_id . bustype = BUS_I2C ;
rc - > input_phys = ir - > phys ;
2017-10-18 09:39:12 -04:00
rc - > device_name = name ;
rc - > dev . parent = & client - > dev ;
2010-11-12 09:02:40 -03:00
/*
* Initialize the other fields of rc_dev
*/
rc - > map_name = ir - > ir_codes ;
2017-08-07 16:20:58 -04:00
rc - > allowed_protocols = rc_proto ;
2010-11-12 09:02:40 -03:00
if ( ! rc - > driver_name )
2017-10-18 10:00:50 -04:00
rc - > driver_name = KBUILD_MODNAME ;
2005-09-15 02:01:53 -05:00
2010-10-29 16:08:23 -03:00
err = rc_register_device ( rc ) ;
2006-11-20 10:23:04 -03:00
if ( err )
2009-05-13 16:48:50 -03:00
goto err_out_free ;
2006-11-20 10:23:04 -03:00
2005-04-16 15:20:36 -07:00
/* start polling via eventd */
2009-03-07 07:43:43 -03:00
INIT_DELAYED_WORK ( & ir - > work , ir_work ) ;
schedule_delayed_work ( & ir - > work , 0 ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
2006-11-20 10:23:04 -03:00
err_out_free :
2010-11-12 09:02:40 -03:00
/* Only frees rc if it were allocated internally */
2010-10-29 16:08:23 -03:00
rc_free_device ( rc ) ;
2006-11-20 10:23:04 -03:00
return err ;
2005-04-16 15:20:36 -07:00
}
2009-05-13 16:48:50 -03:00
static int ir_remove ( struct i2c_client * client )
2005-04-16 15:20:36 -07:00
{
2005-11-08 21:37:43 -08:00
struct IR_i2c * ir = i2c_get_clientdata ( client ) ;
2005-04-16 15:20:36 -07:00
/* kill outstanding polls */
2009-03-07 07:43:43 -03:00
cancel_delayed_work_sync ( & ir - > work ) ;
2005-04-16 15:20:36 -07:00
2009-05-13 16:48:50 -03:00
/* unregister device */
2014-11-20 07:13:16 -03:00
rc_unregister_device ( ir - > rc ) ;
2005-04-16 15:20:36 -07:00
/* free memory */
return 0 ;
}
2009-05-13 16:48:50 -03:00
static const struct i2c_device_id ir_kbd_id [ ] = {
/* Generic entry for any IR receiver */
{ " ir_video " , 0 } ,
2009-07-28 11:50:14 -03:00
/* IR device specific entries should be added here */
{ " ir_rx_z8f0811_haup " , 0 } ,
2010-12-28 22:47:46 -03:00
{ " ir_rx_z8f0811_hdpvr " , 0 } ,
2009-05-13 16:48:50 -03:00
{ }
} ;
2009-02-12 03:43:11 -03:00
2012-02-12 06:56:32 -03:00
static struct i2c_driver ir_kbd_driver = {
2009-05-13 16:48:50 -03:00
. driver = {
. name = " ir-kbd-i2c " ,
} ,
. probe = ir_probe ,
. remove = ir_remove ,
. id_table = ir_kbd_id ,
} ;
2005-04-16 15:20:36 -07:00
2012-02-12 06:56:32 -03:00
module_i2c_driver ( ir_kbd_driver ) ;
2005-04-16 15:20:36 -07:00
/* ----------------------------------------------------------------------- */
MODULE_AUTHOR ( " Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller " ) ;
MODULE_DESCRIPTION ( " input driver for i2c IR remote controls " ) ;
MODULE_LICENSE ( " GPL " ) ;