Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:rehar:lirc
lirc-imontouch
lirc-imontouch-0.2.4.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File lirc-imontouch-0.2.4.patch of Package lirc-imontouch
diff -Naur lirc-0.8.5pre2/configure.ac lirc-0.8.5pre2-imontouch-0.2.4/configure.ac --- lirc-0.8.5pre2/configure.ac 2009-03-31 14:23:00.000000000 -0500 +++ lirc-0.8.5pre2-imontouch-0.2.4/configure.ac 2009-04-18 18:12:08.000000000 -0500 @@ -164,6 +164,7 @@ (lirc_dev lirc_igorplugusb) \ (lirc_dev lirc_ttusbir) \ (lirc_dev lirc_imon) \ + (lirc_dev lirc_imontouch) \ (lirc_dev lirc_it87) \ (lirc_dev lirc_ite8709) \ (lirc_dev lirc_mceusb) \ @@ -442,7 +443,7 @@ hercules_smarttv_stereo, i2cuser, igorplugusb, iguanaIR, imon, imon_24g, imon_knob, imon_lcd, imon_pad, imon_rsc, - irdeo, irdeo_remote, irlink, irman, irreal, + imontouch, irdeo, irdeo_remote, irlink, irman, irreal, it87, ite8709, knc_one, kworld, leadtek_0007, leadtek_0010, leadtek_pvr2000, livedrive_midi, livedrive_seq, logitech, @@ -599,6 +600,8 @@ ;; lirc_dev-lirc_imon) ;; + lirc_dev-lirc_imontouch) + ;; lirc_dev-lirc_it87) ;; lirc_dev-lirc_ite8709) @@ -1008,6 +1011,10 @@ lircd_conf="imon/lircd.conf.imon" fi +if test "$driver" = "imontouch"; then + lirc_driver="lirc_dev lirc_imontouch" + lircd_conf="imon/lircd.conf.imon" +fi if test "$driver" = "imon_24g"; then lirc_driver="lirc_dev lirc_imon" lircd_conf="imon/lircd.conf.imon-2.4g" @@ -1495,6 +1502,7 @@ lirc_i2c \ lirc_igorplugusb \ lirc_imon \ + lirc_imontouch \ lirc_it87 \ lirc_ite8709 \ lirc_mceusb \ @@ -1771,6 +1779,7 @@ drivers/lirc_igorplugusb/Makefile drivers/lirc_ttusbir/Makefile drivers/lirc_imon/Makefile + drivers/lirc_imontouch/Makefile drivers/lirc_it87/Makefile drivers/lirc_ite8709/Makefile drivers/lirc_mceusb/Makefile diff -Naur lirc-0.8.5pre2/drivers/lirc_imon/lirc_imon.c lirc-0.8.5pre2-imontouch-0.2.4/drivers/lirc_imon/lirc_imon.c --- lirc-0.8.5pre2/drivers/lirc_imon/lirc_imon.c 2009-03-08 14:46:55.000000000 -0500 +++ lirc-0.8.5pre2-imontouch-0.2.4/drivers/lirc_imon/lirc_imon.c 2009-04-18 18:12:08.000000000 -0500 @@ -181,8 +181,6 @@ { USB_DEVICE(0x15c2, 0xffda) }, /* iMON USB Control Board (IR & LCD) *and* iMON Knob (IR only) */ { USB_DEVICE(0x15c2, 0xffdc) }, - /* iMON USB Control Board (IR & LCD) */ - { USB_DEVICE(0x15c2, 0x0034) }, /* iMON USB Control Board (IR & VFD) */ { USB_DEVICE(0x15c2, 0x0036) }, /* iMON USB Control Board (IR & LCD) */ @@ -204,7 +202,6 @@ static struct usb_device_id display_proto_6p_list[] = { { USB_DEVICE(0x15c2, 0xffda) }, { USB_DEVICE(0x15c2, 0xffdc) }, - { USB_DEVICE(0x15c2, 0x0034) }, { USB_DEVICE(0x15c2, 0x0036) }, { USB_DEVICE(0x15c2, 0x0038) }, { USB_DEVICE(0x15c2, 0x0041) }, @@ -219,7 +216,6 @@ /* newer iMON models use control endpoints */ static struct usb_device_id ctl_ep_device_list[] = { - { USB_DEVICE(0x15c2, 0x0034) }, { USB_DEVICE(0x15c2, 0x0036) }, { USB_DEVICE(0x15c2, 0x0038) }, { USB_DEVICE(0x15c2, 0x0041) }, @@ -233,7 +229,6 @@ /* iMON LCD models use a different write op */ static struct usb_device_id lcd_device_list[] = { { USB_DEVICE(0x15c2, 0xffdc) }, - { USB_DEVICE(0x15c2, 0x0034) }, { USB_DEVICE(0x15c2, 0x0038) }, { USB_DEVICE(0x15c2, 0x0045) }, {} @@ -248,7 +243,6 @@ /* Newer iMON models decode the signal onboard */ static struct usb_device_id ir_onboard_decode_list[] = { { USB_DEVICE(0x15c2, 0xffdc) }, - { USB_DEVICE(0x15c2, 0x0034) }, { USB_DEVICE(0x15c2, 0x0036) }, { USB_DEVICE(0x15c2, 0x0038) }, { USB_DEVICE(0x15c2, 0x0041) }, diff -Naur lirc-0.8.5pre2/drivers/lirc_imontouch/lirc_imontouch.c lirc-0.8.5pre2-imontouch-0.2.4/drivers/lirc_imontouch/lirc_imontouch.c --- lirc-0.8.5pre2/drivers/lirc_imontouch/lirc_imontouch.c 1969-12-31 18:00:00.000000000 -0600 +++ lirc-0.8.5pre2-imontouch-0.2.4/drivers/lirc_imontouch/lirc_imontouch.c 2009-04-18 18:18:59.000000000 -0500 @@ -0,0 +1,813 @@ +/* + lirc_imontouch - LIRC plugin and input device driver for the Soundgraph iMON Touch LCD and remote control + Copyright (C) 2008 Rene Harder (rehar@saweb.de) + based on lirc_imon by Venky Raju(dev@venky.ws) http://www.venky.ws/projects/imon + + lirc_imontouch 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 3 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <linux/version.h> + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + + +#include <linux/autoconf.h> + +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/input.h> +#include <linux/usb/input.h> +#include <linux/timer.h> + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include <asm/uaccess.h> +#else +#include <linux/uaccess.h> +#endif + +#include <linux/usb.h> + +#include <drivers/kcompat.h> +#include <drivers/lirc.h> +#include <drivers/lirc_dev/lirc_dev.h> + +#define MOD_AUTHOR "Rene Harder <rehar@saweb.de>" +#define MOD_DESC "Driver for Soundgraph iMON Touch LCD and Remote Control iMON PAD" +#define MOD_NAME "lirc_imontouch" +#define MOD_VERSION "0.2.4" + +#define BUF_CHUNK_SIZE 8 +#define BUF_SIZE 128 + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) +#define BIT_MASK(nr) BIT(nr) +#define BIT_WORD(nr) LONG(nr) +#endif + +#define TRUE 1 +#define FALSE 0 + +/*Prototypes*/ + +static int imontouch_probe(struct usb_interface *interface, const struct usb_device_id *id); +static void imontouch_disconnect(struct usb_interface *interface); + +static void usb_rx_callback_intf0(struct urb *urb); +static void usb_rx_callback_intf1(struct urb *urb); + + +static int lircdev_open(void *data); +static void lircdev_close(void *data); + +/*Module init and exit */ +static int __init imontouch_init(void); +static void __exit imontouch_exit(void); +struct mutex lock; + +/* Globals*/ + + +struct imontouch_context { + struct usb_device *dev_intf0; /*display has two USB interfaces*/ + struct usb_device *dev_intf1; + int lirc_isopen; /* LIRC port open */ + int lirc_isassociating; /* LIRC port open for association */ + int dev_present_intf0; /* USB interface 0 presence */ + int dev_present_intf1; /* USB interface 1 presence */ + struct mutex lock; /* to lock this object */ + + + struct lirc_driver *driver; + struct usb_endpoint_descriptor *rx_endpoint_intf0, *rx_endpoint_intf1; + struct urb *rx_urb_intf0, *rx_urb_intf1; + + unsigned char usb_rx_buf[8]; + + struct rx_data { + int count; /* length of 0 or 1 sequence */ + int prev_bit; /* logic level of sequence */ + int initial_space; /* initial space flag */ + } rx; + struct input_dev *mouse; + struct input_dev *touch; + int is_mouse; + int touch_x; + int touch_y; + char name[128]; + char phys[64]; + char touch_name[128]; + char touch_phys[64]; + struct timer_list timer; +}; + +#define LOCK_CONTEXT mutex_lock(&context->lock) +#define UNLOCK_CONTEXT mutex_unlock(&context->lock) +#define LOCK_DRIVER mutex_lock(&lock) +#define UNLOCK_DRIVER mutex_unlock(&lock) +#define TOUCH_TIMEOUT (HZ/30) + +static struct usb_device_id imontouch_usb_id_table[] = { + /*SoundGraph iMON Touch LCD 7" */ + { USB_DEVICE(0x15c2, 0x0034) }, + /*SoundGraph iMON Touch LCD 4.3" */ + { USB_DEVICE(0x15c2, 0x0035) }, + {} +}; + +/* USB Device data */ +static struct usb_driver imontouch_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = MOD_NAME, + .probe = imontouch_probe, + .disconnect = imontouch_disconnect, + .id_table = imontouch_usb_id_table, +}; + +static int debug; +static int use_lirc; +static int touch_passthrough; +static int mouse; + +/* Module */ + +MODULE_AUTHOR(MOD_AUTHOR); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, imontouch_usb_id_table); + +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)"); + +/*module_param(use_lirc, int, 1); +MODULE_PARM_DESC(use_lirc, "Use LIRC device as output for RC and Touchscreen: 0=no, 1=yes(default: yes) (not yet active");*/ + +module_param(touch_passthrough, int, 0); +MODULE_PARM_DESC(touch_passthrough, "passtrough the raw touchscreen data, otherwise make a lower resolution matrix for LIRC: 0=no, 1=yes (raw touchscreen data) default:no"); + +module_param(mouse, int, 0); +MODULE_PARM_DESC(mouse, "Use the PAD on the remote as mouse pointer after probing the device: 1=yes, 0=no (default: no)"); + + +static inline void delete_context(struct imontouch_context *context) +{ + + lirc_buffer_free(context->driver->rbuf); + kfree(context->driver->rbuf); + kfree(context->driver); + kfree(context); + kfree(context->mouse); + kfree(context->touch); + + if (debug) + printk(KERN_INFO "%s: context deleted\n", __FUNCTION__); +} +static inline void deregister_from_lirc(struct imontouch_context *context) +{ + int retval; + int minor = context->driver->minor; + + retval = lirc_unregister_driver(minor); + if (retval) + printk(KERN_ERR "%s: unable to deregister from lirc(%d)\n", + __FUNCTION__, retval); + else + printk(KERN_INFO "%s: Deregistered iMON driver(minor:%d)\n", __FUNCTION__, minor); + +} + +static inline void incoming_lirc_packet(struct imontouch_context *context, struct urb *urb, int intf){ + int len = urb->actual_length; + unsigned char *buf = urb->transfer_buffer; + char rel_x, rel_y; + + if(!context->is_mouse){ + /* generated PAD key codes: + Mouse_N 0x69 02 81 B7 00 68 1401 + Mouse_S 0x68 82 91 B7 00 68 1401 + Mouse_W 0x6A 82 81 B7 00 68 1401 + Mouse_E 0x68 8A 81 B7 00 68 1401 + mouse buttons : + MouseRightClick 0x68 84 81 B7 00 68 1401 + MouseLeftClick 0x68 83 81 B7 00 68 1401 + */ + if(buf[0] & 0x01 && !buf[1] && len==5){ + rel_x=buf[2]; + rel_y=buf[3]; + len=8; + if (abs(abs(rel_x) - abs(rel_y)) < 10) + return; + if(rel_x >= 14) + {buf[0]=0x68; buf[1]=0x8A;buf[2]=0x1B;buf[3]=0xb7;buf[4]=0x00;buf[5]=0x68;buf[6]=0x14;buf[7]=0x01;} + else if (rel_x <= -14) + {buf[0]=0x6a; buf[1]=0x82;buf[2]=0x81;buf[3]=0xB7;buf[4]=0x00;buf[5]=0x68;buf[6]=0x14;buf[7]=0x01;} + else if (rel_y >= 14) + {buf[0]=0x68; buf[1]=0x82;buf[2]=0x91;buf[3]=0xB7;buf[4]=0x00;buf[5]=0x68;buf[6]=0x14;buf[7]=0x01;} + else if (rel_y <= -14) + {buf[0]=0x69; buf[1]=0x02;buf[2]=0x81;buf[3]=0x70;buf[4]=0x00;buf[5]=0x68;buf[6]=0x14;buf[7]=0x01;} + + }else if (buf[0] & 0x01 && buf[1]==0x01 && len==5){ //left mouse click + len=8; + buf[0]=0x68; buf[1]=0x83;buf[2]=0x81;buf[3]=0xB7;buf[4]=0x00;buf[5]=0x68;buf[6]=0x14;buf[7]=0x01; + }else if (buf[0] & 0x01 && buf[1]==0x02 && len==5){ //right mouse click + len=8; + buf[0]=0x68; buf[1]=0x84;buf[2]=0x81;buf[3]=0xB7;buf[4]=0x00;buf[5]=0x68;buf[6]=0x14;buf[7]=0x01; + } + + } + if (len == 5) { + buf[5]=0x00; + buf[6]=0x00; + buf[7]=0x00; + len=8; + } + if (len != 8) { + printk(KERN_WARNING "%s: invalid incoming packet size(%d)\n", + __FUNCTION__, len); + return; + } + if (!buf[1] && !buf[2] && !buf[3] && !buf[4] && !buf[5] && !buf[6] && !buf[7] && !intf ) + return; + if (((buf[2]>>6) & 0x01) && intf && (buf[7] != 0x86)) + return; + if((buf[6]==0x14 || buf[6]==0x03) && buf[7]==0x86 && intf){ /*handle touchscreen, generate button events for LIRC, in lower resolution */ + if (!touch_passthrough){ + /*generate higher resolution touchscreen to generate button events (256 buttons) + buf[0]=buf[0]>>4; buf[1]=0x00;buf[2]=buf[2]>>4;buf[3]=0x00;buf[4]=0x00;buf[5]=0x00;buf[6]=0x14;buf[7]=0xff; */ + + /*generate lower resolution touchscreen to generate button events (64 buttons)*/ + buf[0]=buf[0]>>5; buf[1]=0x00;buf[2]=buf[2]>>5;buf[3]=0x00;buf[4]=0x00;buf[5]=0x00;buf[6]=0x14;buf[7]=0xff; + } + } + lirc_buffer_write(context->driver->rbuf, buf); + wake_up(&context->driver->rbuf->wait_poll); + return; + + +} + +static void display_timeout(struct imontouch_context *context){ + struct input_dev *touch=NULL; + + touch = context->touch; + if (!context->touch) /*no touchscreen input generated, something went wrong*/ + return; + input_report_abs(touch, ABS_X, context->touch_x); + input_report_abs(touch, ABS_Y, context->touch_y); + input_report_key(touch, BTN_TOUCH, 0x00); + input_sync(touch); +} + +static void usb_rx_callback_intf0(struct urb *urb){ + struct imontouch_context *context; + unsigned char *buf = urb->transfer_buffer; + char rel_x, rel_y; + int len = urb->actual_length; + struct input_dev *mouse=NULL; + int i; + + if (len == 5) { + buf[5]=0x00; + buf[6]=0x00; + buf[7]=0x00; + len=8; + } + if (len != 8) { + printk(KERN_WARNING "%s: invalid incoming packet size(%d)\n", + __FUNCTION__, len); + return; + } + if(debug){ + printk(KERN_INFO "lirc_imontouch %s incomming packet: ",__FUNCTION__ ); + for(i=0;i<8;i++) + { + printk("%02x ",buf[i]); + } + printk("\n"); + } + if (!urb) + return; + + context = (struct imontouch_context *) urb->context; + + if (!context){ + + goto exit; + } + mouse = context->mouse; + + if (!context->mouse){ /*no mouse input generated, something went wrong*/ + + goto exit; + } + switch (urb->status){ + + case -ENOENT: /* usb unlink*/ + if(debug) printk(KERN_WARNING "%s: usb unlink\n",__FUNCTION__); + + return; + case 0: + + + if(buf[0] & 0x01 && context->is_mouse){ /* handle iIMON PAD to generate mouse events*/ + + input_report_key(mouse, BTN_LEFT, buf[1] & 0x01); + input_report_key(mouse, BTN_RIGHT, buf[1] >> 2 & 0x01); + rel_x=buf[2]; + rel_y=buf[3]; + + input_report_rel(mouse, REL_X, rel_x); + input_report_rel(mouse, REL_Y, rel_y); + input_sync(mouse); + }else{ + if (context->lirc_isopen) + incoming_lirc_packet(context, urb,0); + + + } + break; + default : + printk(KERN_WARNING "%s unknown urb status\n", __FUNCTION__); + break; + } +exit: + usb_submit_urb(context->rx_urb_intf1, GFP_ATOMIC); + usb_submit_urb(context->rx_urb_intf0, GFP_ATOMIC); + +} + +static void usb_rx_callback_intf1(struct urb *urb){ + struct imontouch_context *context; + unsigned char *buf = urb->transfer_buffer; + int len = urb->actual_length; + struct input_dev *touch=NULL; + int i; + + if (len != 8) { + printk(KERN_WARNING "%s: invalid incoming packet size(%d)\n", + __FUNCTION__, len); + return; + } + if(debug){ + printk("lirc_imontouch %s incomming packet: ",__FUNCTION__ ); + for(i=0;i<8;i++) + { + printk("%02x ",buf[i]); + } + printk("\n"); + } + if (!urb) + return; + + context = (struct imontouch_context *) urb->context; + if (!context){ + + goto exit; + } + touch = context->touch; + if (!context->touch){ /*no touchscreen input generated, something went wrong*/ + + goto exit; + } + + switch (urb->status){ + + case -ENOENT: /* usb unlink*/ + if(debug) printk(KERN_WARNING "%s: usb unlink\n",__FUNCTION__); + + return; + case 0: + + if(buf[0] ==0x29 && buf[1]==0x91 && (buf[2]==0x35 || buf[2]==0x15) && buf[3]==0xb7 && !buf[4] && !buf[5] &&(buf[6]==0x14 || buf[6]==0x03) && buf[7]==0x01 ){ /*switch mouse/keyboard*/ + context->is_mouse= (~context->is_mouse) & 0x01; + if(debug) + printk(KERN_INFO "%s: toggle mouse %d\n",__FUNCTION__,context->is_mouse); + + goto exit; + + } + + if((buf[6]==0x14 || buf[6]==0x03) && buf[7]==0x86){ /*handle touchscreen, map to input device */ + + mod_timer(&context->timer,jiffies+TOUCH_TIMEOUT); + + context->touch_x=buf[0]<<4 | (buf[1]>>4); + context->touch_y=0xfff-((buf[2]<<4) | (buf[1]&0xf)); + + input_report_abs(touch, ABS_X, context->touch_x); + input_report_abs(touch, ABS_Y, context->touch_y); + input_report_key(touch, BTN_TOUCH, 0x01); + input_sync(touch); + } + if (context->lirc_isopen) + incoming_lirc_packet(context, urb,1); + + + break; + default : + printk(KERN_WARNING "%s: unknown urb status\n", __FUNCTION__); + break; + } +exit: + usb_submit_urb(context->rx_urb_intf1, GFP_ATOMIC); + usb_submit_urb(context->rx_urb_intf0, GFP_ATOMIC); + +} + + +static int imontouch_probe(struct usb_interface *interface, const struct usb_device_id *id){ + + struct usb_device *dev = NULL; + struct usb_host_interface *iface_desc = NULL; + struct urb *rx_urb = NULL; + struct lirc_driver *driver = NULL; + struct lirc_buffer *rbuf = NULL; + struct usb_interface *first_if; + int ifnum; + int err; + int lirc_minor=-1; + int retval; + int minor_first_intf=-1; + int num_endpoints; + int alloc_status; + struct imontouch_context *context = NULL; + struct imontouch_context *first_if_context=NULL; + + dev = usb_get_dev(interface_to_usbdev(interface)); + iface_desc = interface->cur_altsetting; + num_endpoints = iface_desc->desc.bNumEndpoints; + ifnum=iface_desc->desc.bInterfaceNumber; + printk(KERN_INFO "%s: found iIMON device, %d. interface\n", __FUNCTION__, ifnum); + + alloc_status=0; + if(!ifnum) + first_if=usb_ifnum_to_if(dev,1); + else + first_if=usb_ifnum_to_if(dev,0); + + LOCK_DRIVER; + + first_if_context=(struct imontouch_context *)usb_get_intfdata(first_if); + + if(!first_if_context){ + printk(KERN_INFO "%s: first usb interface not yet registered\n", __FUNCTION__); + + context = kzalloc(sizeof(struct imontouch_context), GFP_KERNEL); + if (!context) { + printk(KERN_ERR "%s: kzalloc failed for context\n", __FUNCTION__); + alloc_status = 1; + goto alloc_status_switch; + } + driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); + if (!driver) { + printk(KERN_ERR "%s: kzalloc failed for lirc_driver\n", __FUNCTION__); + alloc_status = 2; + goto alloc_status_switch; + } + rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + printk(KERN_ERR "%s: kzalloc failed for lirc_buffer\n", __FUNCTION__); + alloc_status = 3; + goto alloc_status_switch; + } + if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { + printk(KERN_ERR "%s: lirc_buffer_init failed", __FUNCTION__); + alloc_status = 4; + goto alloc_status_switch; + } + + rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rx_urb) { + printk(KERN_ERR "%s: usb_alloc_urb failed for IR urb\n", __FUNCTION__); + alloc_status = 5; + goto alloc_status_switch; + } + + + memset(context, 0, sizeof(struct imontouch_context)); + mutex_init(&context->lock); + + memset(driver, 0, sizeof(struct lirc_driver)); + + strcpy(driver->name, MOD_NAME); + driver->minor = -1; + driver->code_length = 64; + driver->sample_rate = 0; + driver->features = LIRC_CAN_REC_LIRCCODE; + driver->data = context; + driver->rbuf = rbuf; + driver->set_use_inc = lircdev_open; + driver->set_use_dec = lircdev_close; + context->lirc_isopen=0; + driver->owner = THIS_MODULE; + LOCK_CONTEXT; + context->driver = driver; + context->is_mouse=mouse; + init_timer(&context->timer); + context->timer.data=(unsigned long)context; + context->timer.function=display_timeout; + + lirc_minor = lirc_register_driver(driver); + if (lirc_minor < 0) { + printk(KERN_ERR "%s: lirc_register_driver failed\n", __FUNCTION__); + alloc_status = 5; + UNLOCK_CONTEXT; + goto alloc_status_switch; + } else + printk(KERN_INFO "%s: Registered imontouch driver(minor:%d)\n",__FUNCTION__, lirc_minor); + + driver->minor = lirc_minor; + UNLOCK_CONTEXT; + + + + }else{ + if(first_if_context->driver){ + minor_first_intf=first_if_context->driver->minor; + printk(KERN_INFO "%s: driver dectected, LIRC minor: %d\n", __FUNCTION__,minor_first_intf); + + rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rx_urb) { + printk(KERN_ERR "%s: usb_alloc_urb failed for urb\n", __FUNCTION__); + alloc_status = 5; + goto alloc_status_switch; + } + + context=first_if_context; + + } + } + + printk(KERN_INFO "%s: imontouch device connected, minor %d\n", __FUNCTION__, context->driver->minor); + LOCK_CONTEXT; + if(!ifnum) { + context->dev_intf0 = dev; + context->dev_present_intf0 = TRUE; + context->rx_urb_intf0 = rx_urb; + context->rx_endpoint_intf0= &iface_desc->endpoint[0].desc; + + + usb_fill_int_urb(rx_urb, context->dev_intf0, usb_rcvintpipe(context->dev_intf0, context->rx_endpoint_intf0->bEndpointAddress), context->usb_rx_buf, sizeof(context->usb_rx_buf),usb_rx_callback_intf0, context, context->rx_endpoint_intf0->bInterval); + retval = usb_submit_urb(context->rx_urb_intf0, GFP_KERNEL); + context->mouse= input_allocate_device(); + snprintf(context->name, sizeof(context->name), "iMON PAD IR Mouse %04x:%04x", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); + usb_make_path(dev, context->phys, sizeof(context->phys)); + strlcat(context->phys, "/input0", sizeof(context->phys)); + + context->mouse->phys=context->phys; + context->mouse->name=context->name; + context->mouse->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + context->mouse->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); + context->mouse->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + context->mouse->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); + context->mouse->relbit[0] |= BIT_MASK(REL_WHEEL); + + usb_to_input_id(dev, &context->mouse->id); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) + context->mouse->private = context; + context->mouse->cdev.dev = &interface->dev; +#else + input_set_drvdata(context->mouse, context); + context->mouse->dev.parent = &interface->dev; +#endif + input_register_device(context->mouse); + + + + }else{ + context->dev_intf1 = dev; + context->dev_present_intf1 = TRUE; + context->rx_urb_intf1 = rx_urb; + context->rx_endpoint_intf1= &iface_desc->endpoint[0].desc; + + usb_fill_int_urb(rx_urb, context->dev_intf1, usb_rcvintpipe(context->dev_intf1, context->rx_endpoint_intf1->bEndpointAddress), context->usb_rx_buf, sizeof(context->usb_rx_buf),usb_rx_callback_intf1, context, context->rx_endpoint_intf1->bInterval); + retval = usb_submit_urb(context->rx_urb_intf1, GFP_KERNEL); + + context->touch= input_allocate_device(); + snprintf(context->touch_name, sizeof(context->touch_name), "USB Touchscreen %04x:%04x", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); + usb_make_path(dev, context->touch_phys, sizeof(context->touch_phys)); + strlcat(context->touch_phys, "/input1", sizeof(context->touch_phys)); + + context->touch->phys=context->touch_phys; + context->touch->name=context->touch_name; + context->touch->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + context->touch->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_set_abs_params(context->touch, ABS_X, 0x00, 0xfff, 0, 0); + input_set_abs_params(context->touch, ABS_Y, 0x00, 0xfff, 0, 0); + + usb_to_input_id(dev, &context->touch->id); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) + context->touch->private = context; + context->touch->cdev.dev = &interface->dev; +#else + input_set_drvdata(context->touch, context); + context->touch->dev.parent = &interface->dev; +#endif + err=input_register_device(context->touch); + + if (err) { + printk(KERN_ERR "%s: input_register touchscreen failed, err: %d\n", __FUNCTION__, err); + + } + } + //context->rx_endpoint = rx_endpoint; + + if (retval) + printk(KERN_ERR "%s: usb_submit_urb failed for module probe (%d)\n", + __FUNCTION__, retval); + + + + usb_set_intfdata(interface, context); + + UNLOCK_CONTEXT; + +alloc_status_switch: + + switch (alloc_status) { + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(driver); + case 2: + kfree(context); + context = NULL; + case 1: + retval = -ENOMEM; + case 0: + ; + } + + +UNLOCK_DRIVER; +return 0; +} + + +static void imontouch_disconnect(struct usb_interface *interface){ + struct imontouch_context *context; + int ifnum; + /* prevent races with ir_open()/vfd_open() */ + LOCK_DRIVER; + + + context = usb_get_intfdata(interface); + ifnum=interface->cur_altsetting->desc.bInterfaceNumber; + LOCK_CONTEXT; + + + if(!ifnum){ + + context->dev_present_intf0 = FALSE; + usb_kill_urb(context->rx_urb_intf0); + input_unregister_device (context->mouse); + if (context->dev_present_intf1){ + if(debug) + printk(KERN_INFO "%s: interface 1 still activated\n", __FUNCTION__); + + UNLOCK_CONTEXT; + + }else{ + /* De-register from lirc_dev if IR port is not open */ + if (!context->lirc_isopen) + deregister_from_lirc(context); + + del_timer_sync(&context->timer); + UNLOCK_CONTEXT; + + printk(KERN_INFO "%s: imontouch device disconnected\n", __FUNCTION__); + } + }else{ + + context->dev_present_intf1 = FALSE; + usb_kill_urb(context->rx_urb_intf1); + input_unregister_device (context->touch); + if (context->dev_present_intf0){ + if(debug) + printk(KERN_INFO "%s: interface 0 still activated\n", __FUNCTION__); + UNLOCK_CONTEXT; + + }else{ + /* De-register from lirc_dev if IR port is not open */ + if (!context->lirc_isopen) + deregister_from_lirc(context); + + del_timer_sync(&context->timer); + UNLOCK_CONTEXT; + + printk(KERN_INFO "%s: imontouch device disconnected\n", __FUNCTION__); + } + + + + + + } + + + usb_set_intfdata(interface, NULL); + UNLOCK_DRIVER; + +} + +static int lircdev_open(void *data){ + struct imontouch_context *context; + int retval = 0; + + LOCK_DRIVER; + context = (struct imontouch_context *) data; + LOCK_CONTEXT; + + if (context->lirc_isopen) { + printk(KERN_ERR "%s: LIRC port is already open\n", __FUNCTION__); + retval = -EBUSY; + goto exit; + } + /* initial IR protocol decode variables */ + context->rx.count = 0; + context->rx.initial_space = 1; + context->rx.prev_bit = 0; + MOD_INC_USE_COUNT; + context->lirc_isopen = TRUE; + printk(KERN_INFO "%s: LIRC port opened\n", __FUNCTION__); + + +exit: + UNLOCK_CONTEXT; + UNLOCK_DRIVER; + return retval; + + +}; +static void lircdev_close(void *data){ +struct imontouch_context *context; + + context = (struct imontouch_context *) data; + if (!context) { + printk(KERN_ERR "%s: no context for device\n", __FUNCTION__); + return; + } + LOCK_CONTEXT; + context->lirc_isopen = FALSE; + printk(KERN_INFO "%s: LIRC port closed\n", __FUNCTION__); + MOD_DEC_USE_COUNT; + + + if (!context->dev_present_intf0 & !context->dev_present_intf1) { + /* Device disconnected while LIRC port was + * still open. Driver was not deregistered + * at disconnect time, so do it now. */ + usb_kill_urb(context->rx_urb_intf1); + input_unregister_device (context->touch); + usb_kill_urb(context->rx_urb_intf0); + input_unregister_device (context->mouse); + deregister_from_lirc(context); + } + + + UNLOCK_CONTEXT; + return; + +}; + +static int __init imontouch_init(void) +{ + int resource; + + printk(KERN_INFO MOD_DESC ", v" MOD_VERSION "\n"); + printk(KERN_INFO MOD_AUTHOR "\n"); + mutex_init(&lock); + resource = usb_register(&imontouch_driver); + if (resource) { + printk(KERN_ERR "%s: usb register failed(%d)\n", __FUNCTION__, resource); + return -ENODEV; + } + return 0; +} + +static void __exit imontouch_exit(void) +{ + usb_deregister(&imontouch_driver); + printk(KERN_INFO "%s: module removed.\n", __FUNCTION__); +} + + +module_init(imontouch_init); +module_exit(imontouch_exit); diff -Naur lirc-0.8.5pre2/drivers/lirc_imontouch/Makefile.am lirc-0.8.5pre2-imontouch-0.2.4/drivers/lirc_imontouch/Makefile.am --- lirc-0.8.5pre2/drivers/lirc_imontouch/Makefile.am 1969-12-31 18:00:00.000000000 -0600 +++ lirc-0.8.5pre2-imontouch-0.2.4/drivers/lirc_imontouch/Makefile.am 2009-04-18 18:12:08.000000000 -0500 @@ -0,0 +1,13 @@ +## $Id: Makefile.am,v 1.1 2005/01/26 20:07:28 lirc Exp $ + +## Process this file with automake to produce Makefile.in + +## this is so that Automake includes the C compiling definitions, and +## includes the source files in the distribution. +EXTRA_PROGRAMS = automake_dummy +automake_dummy_SOURCES = lirc_imontouch.c + +## there is no *just* object file support in automake. This is close enough +module_DATA = lirc_imontouch.o + +include ../Makefile.common diff -Naur lirc-0.8.5pre2/drivers/Makefile.am lirc-0.8.5pre2-imontouch-0.2.4/drivers/Makefile.am --- lirc-0.8.5pre2/drivers/Makefile.am 2009-03-01 13:22:39.000000000 -0600 +++ lirc-0.8.5pre2-imontouch-0.2.4/drivers/Makefile.am 2009-04-18 18:12:08.000000000 -0500 @@ -15,6 +15,7 @@ lirc_i2c \ lirc_igorplugusb \ lirc_imon \ + lirc_imontouch \ lirc_it87 \ lirc_ite8709 \ lirc_mceusb \ diff -Naur lirc-0.8.5pre2/setup.data lirc-0.8.5pre2-imontouch-0.2.4/setup.data --- lirc-0.8.5pre2/setup.data 2009-03-01 13:22:39.000000000 -0600 +++ lirc-0.8.5pre2-imontouch-0.2.4/setup.data 2009-04-18 18:12:08.000000000 -0500 @@ -136,6 +136,7 @@ alsa_usb: "Sound Blaster Extigy/Audigy 2 NX (ALSA snd-usb-audio)" imon_24g: "Soundgraph iMON 2.4G DT & LT" imon: "Soundgraph iMON MultiMedian IR/VFD" + imontouch: "Soundgraph iMON Touch LCD" imon_lcd: "Soundgraph iMON IR/LCD" imon_knob: "Soundgraph iMON Knob" imon_pad: "Soundgraph iMON PAD IR/VFD" @@ -228,6 +229,7 @@ igorplugusb \ iguanaIR \ imon \ + imontouch \ imon_lcd \ imon_24g \ imon_knob \ @@ -301,6 +303,7 @@ igorplugusb \ iguanaIR \ imon \ + imontouch \ imon_lcd \ imon_24g \ imon_knob \
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor