aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@brturbo.com.br>2005-11-09 00:37:32 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:18 -0500
commitd5e5265315770bda46c50ecaa64e2b9790f2064c (patch)
tree5c92fa1125dee3f766bd06f18840ce78bf0cd861 /drivers
parentda45a2a5b96afd7188c058a55eb2917d6524c0cf (diff)
[PATCH] v4l: 784: several improvement on i2c ir handling for em2820
- Several Improvement on I2C IR handling for em2820: - moved Pinnacle IR table (ir_codes_em2820) to em2820-input.c - IR struct renamed and moved to a header file. - New file to handle em2820-specific IR. - Some cleanups. - attach now detects I2C IR and calls em2820-specific IR code - IR compat code moved to compat.h - New header with struct IR_i2c there, to allow it to be used by board-specific input handlers. - Some improvements at em28xx board detection: - Board detection message improved to show interface and class. - Now it doesn't touch audio interfaces. Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c43
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c150
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c15
-rw-r--r--drivers/media/video/em28xx/em28xx.h20
-rw-r--r--drivers/media/video/ir-kbd-i2c.c238
6 files changed, 280 insertions, 189 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 91c70ebd0ea4..919520f89975 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -143,7 +143,7 @@ struct em2820_board em2820_boards[] = {
143 .tuner_type = TUNER_PHILIPS_PAL, 143 .tuner_type = TUNER_PHILIPS_PAL,
144 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE, 144 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
145 .has_tuner = 1, 145 .has_tuner = 1,
146 .decoder = EM2820_SAA7114, 146 .decoder = EM2820_SAA7114,
147 .input = {{ 147 .input = {{
148 .type = EM2820_VMUX_TELEVISION, 148 .type = EM2820_VMUX_TELEVISION,
149 .vmux = 2, 149 .vmux = 2,
@@ -250,6 +250,7 @@ void em2820_card_setup(struct em2820 *dev)
250 struct tveeprom tv; 250 struct tveeprom tv;
251#ifdef CONFIG_MODULES 251#ifdef CONFIG_MODULES
252 request_module("tveeprom"); 252 request_module("tveeprom");
253 request_module("ir-kbd-i2c");
253#endif 254#endif
254 /* Call first TVeeprom */ 255 /* Call first TVeeprom */
255 256
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index a7b6f678f979..f6bfc038777e 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -26,10 +26,10 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/usb.h> 27#include <linux/usb.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <media/tuner.h>
30#include <linux/video_decoder.h> 29#include <linux/video_decoder.h>
31 30
32#include "em2820.h" 31#include "em2820.h"
32#include <media/tuner.h>
33 33
34/* ----------------------------------------------------------- */ 34/* ----------------------------------------------------------- */
35 35
@@ -41,14 +41,11 @@ static unsigned int i2c_debug = 0;
41module_param(i2c_debug, int, 0644); 41module_param(i2c_debug, int, 0644);
42MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); 42MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
43 43
44#define dprintk(fmt, args...) if (i2c_debug) do {\ 44#define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\
45 printk(KERN_DEBUG "%s: %s: " fmt "\n",\
46 dev->name, __FUNCTION__ , ##args); } while (0)
47#define dprintk1(fmt, args...) if (i2c_debug) do{ \
48 printk(KERN_DEBUG "%s: %s: " fmt, \
49 dev->name, __FUNCTION__ , ##args); } while (0)
50#define dprintk2(fmt, args...) if (i2c_debug) do {\
51 printk(fmt , ##args); } while (0) 45 printk(fmt , ##args); } while (0)
46#define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
47 printk(KERN_DEBUG "%s at %s: " fmt, \
48 dev->name, __FUNCTION__ , ##args); } while (0)
52 49
53/* 50/*
54 * em2800_i2c_send_max4() 51 * em2800_i2c_send_max4()
@@ -238,7 +235,7 @@ static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap,
238 return 0; 235 return 0;
239 for (i = 0; i < num; i++) { 236 for (i = 0; i < num; i++) {
240 addr = msgs[i].addr << 1; 237 addr = msgs[i].addr << 1;
241 dprintk1("%s %s addr=%x len=%d:", 238 dprintk2(2,"%s %s addr=%x len=%d:",
242 (msgs[i].flags & I2C_M_RD) ? "read" : "write", 239 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
243 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); 240 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
244 if (!msgs[i].len) { /* no len: check only for device presence */ 241 if (!msgs[i].len) { /* no len: check only for device presence */
@@ -247,7 +244,7 @@ static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap,
247 else 244 else
248 rc = em2820_i2c_check_for_device(dev, addr); 245 rc = em2820_i2c_check_for_device(dev, addr);
249 if (rc < 0) { 246 if (rc < 0) {
250 dprintk2(" no device\n"); 247 dprintk2(2," no device\n");
251 return rc; 248 return rc;
252 } 249 }
253 250
@@ -261,14 +258,14 @@ static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap,
261 rc = em2820_i2c_recv_bytes(dev, addr, 258 rc = em2820_i2c_recv_bytes(dev, addr,
262 msgs[i].buf, 259 msgs[i].buf,
263 msgs[i].len); 260 msgs[i].len);
264 if (i2c_debug) { 261 if (i2c_debug>=2) {
265 for (byte = 0; byte < msgs[i].len; byte++) { 262 for (byte = 0; byte < msgs[i].len; byte++) {
266 printk(" %02x", msgs[i].buf[byte]); 263 printk(" %02x", msgs[i].buf[byte]);
267 } 264 }
268 } 265 }
269 } else { 266 } else {
270 /* write bytes */ 267 /* write bytes */
271 if (i2c_debug) { 268 if (i2c_debug>=2) {
272 for (byte = 0; byte < msgs[i].len; byte++) 269 for (byte = 0; byte < msgs[i].len; byte++)
273 printk(" %02x", msgs[i].buf[byte]); 270 printk(" %02x", msgs[i].buf[byte]);
274 } 271 }
@@ -284,13 +281,13 @@ static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap,
284 if (rc < 0) 281 if (rc < 0)
285 goto err; 282 goto err;
286 } 283 }
287 if (i2c_debug) 284 if (i2c_debug>=2)
288 printk("\n"); 285 printk("\n");
289 } 286 }
290 287
291 return num; 288 return num;
292 err: 289 err:
293 dprintk2(" ERROR: %i\n", rc); 290 dprintk2(2," ERROR: %i\n", rc);
294 return rc; 291 return rc;
295} 292}
296 293
@@ -436,26 +433,34 @@ static int attach_inform(struct i2c_client *client)
436{ 433{
437 struct em2820 *dev = client->adapter->algo_data; 434 struct em2820 *dev = client->adapter->algo_data;
438 435
439 dprintk("address %x", client->addr << 1);
440 switch (client->addr << 1) { 436 switch (client->addr << 1) {
441 case 0x86: 437 case 0x86:
442 em2820_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); 438 em2820_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
443 break; 439 break;
444 case 0x4a: 440 case 0x4a:
445 dprintk1("attach_inform: saa7113 detected.\n"); 441 dprintk1(1,"attach_inform: saa7113 detected.\n");
446 break; 442 break;
447 case 0xa0: 443 case 0xa0:
448 dprintk1("attach_inform: eeprom detected.\n"); 444 dprintk1(1,"attach_inform: eeprom detected.\n");
445 break;
446 case 0x60:
447 case 0x8e:
448 {
449 struct IR_i2c *ir = i2c_get_clientdata(client);
450 dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys);
451 em2820_set_ir(dev,ir);
449 break; 452 break;
453 }
450 case 0x80: 454 case 0x80:
451 case 0x88: 455 case 0x88:
452 dprintk1("attach_inform: msp34xx detected.\n"); 456 dprintk1(1,"attach_inform: msp34xx detected.\n");
453 break; 457 break;
454 case 0xb8: 458 case 0xb8:
455 case 0xba: 459 case 0xba:
456 dprintk1("attach_inform: tvp5150 detected.\n"); 460 dprintk1(1,"attach_inform: tvp5150 detected.\n");
457 break; 461 break;
458 default: 462 default:
463 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1);
459 dev->tuner_addr = client->addr; 464 dev->tuner_addr = client->addr;
460 em2820_set_tuner(-1, client); 465 em2820_set_tuner(-1, client);
461 } 466 }
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
new file mode 100644
index 000000000000..d6b3e15a0350
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -0,0 +1,150 @@
1/*
2 *
3 * handle saa7134 IR remotes via linux kernel input layer.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/sched.h>
26#include <linux/interrupt.h>
27#include <linux/input.h>
28#include <linux/usb.h>
29
30#include "em2820.h"
31
32static unsigned int disable_ir = 0;
33module_param(disable_ir, int, 0444);
34MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
35
36static unsigned int ir_debug = 0;
37module_param(ir_debug, int, 0644);
38MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
39
40#define dprintk(fmt, arg...) if (ir_debug) \
41 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
42
43/* ---------------------------------------------------------------------- */
44
45static IR_KEYTAB_TYPE ir_codes_em_pinnacle[IR_KEYTAB_SIZE] = {
46 [ 0 ] = KEY_CHANNEL,
47 [ 1 ] = KEY_SELECT,
48 [ 2 ] = KEY_MUTE,
49 [ 3 ] = KEY_POWER,
50 [ 4 ] = KEY_KP1,
51 [ 5 ] = KEY_KP2,
52 [ 6 ] = KEY_KP3,
53 [ 7 ] = KEY_CHANNELUP,
54 [ 8 ] = KEY_KP4,
55 [ 9 ] = KEY_KP5,
56 [ 10 ] = KEY_KP6,
57
58 [ 11 ] = KEY_CHANNELDOWN,
59 [ 12 ] = KEY_KP7,
60 [ 13 ] = KEY_KP8,
61 [ 14 ] = KEY_KP9,
62 [ 15 ] = KEY_VOLUMEUP,
63 [ 16 ] = KEY_KP0,
64 [ 17 ] = KEY_MENU,
65 [ 18 ] = KEY_PRINT,
66
67 [ 19 ] = KEY_VOLUMEDOWN,
68 [ 21 ] = KEY_PAUSE,
69 [ 23 ] = KEY_RECORD,
70 [ 24 ] = KEY_REWIND,
71 [ 25 ] = KEY_PLAY,
72 [ 27 ] = KEY_BACKSPACE,
73 [ 29 ] = KEY_STOP,
74 [ 31 ] = KEY_ZOOM,
75};
76
77/* ----------------------------------------------------------------------- */
78
79static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
80{
81 unsigned char buf[2];
82 unsigned char code;
83
84 /* poll IR chip */
85 if (2 != i2c_master_recv(&ir->c,buf,2))
86 return -EIO;
87
88 /* Does eliminate repeated parity code */
89 if (buf[1]==0xff)
90 return 0;
91
92 /* avoid fast reapeating */
93 if (buf[1]==ir->old)
94 return 0;
95 ir->old=buf[1];
96
97 /* Rearranges bits to the right order */
98 code= ((buf[0]&0x01)<<5) | /* 0010 0000 */
99 ((buf[0]&0x02)<<3) | /* 0001 0000 */
100 ((buf[0]&0x04)<<1) | /* 0000 1000 */
101 ((buf[0]&0x08)>>1) | /* 0000 0100 */
102 ((buf[0]&0x10)>>3) | /* 0000 0010 */
103 ((buf[0]&0x20)>>5); /* 0000 0001 */
104
105 dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]);
106
107 /* return key */
108 *ir_key = code;
109 *ir_raw = code;
110 return 1;
111}
112
113/* ----------------------------------------------------------------------- */
114void em2820_set_ir(struct em2820 * dev,struct IR_i2c *ir)
115{
116 if (disable_ir)
117 return ;
118
119 /* detect & configure */
120 switch (dev->model) {
121 case (EM2800_BOARD_UNKNOWN):
122 break;
123 case (EM2820_BOARD_UNKNOWN):
124 break;
125 case (EM2820_BOARD_TERRATEC_CINERGY_250):
126 break;
127 case (EM2820_BOARD_PINNACLE_USB_2):
128 ir->ir_codes = ir_codes_em_pinnacle;
129 break;
130 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
131 ir->ir_codes = ir_codes_hauppauge_new;
132 ir->get_key = get_key_em_haup;
133 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppage)");
134 break;
135 case (EM2820_BOARD_MSI_VOX_USB_2):
136 break;
137 case (EM2800_BOARD_TERRATEC_CINERGY_200):
138 break;
139 case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
140 break;
141 case (EM2800_BOARD_KWORLD_USB2800):
142 break;
143 }
144}
145
146/* ----------------------------------------------------------------------
147 * Local variables:
148 * c-basic-offset: 8
149 * End:
150 */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index d3a959b9ee64..f3fc44b352b4 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -28,10 +28,10 @@
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/usb.h> 29#include <linux/usb.h>
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <media/tuner.h>
32#include <linux/video_decoder.h> 31#include <linux/video_decoder.h>
33 32
34#include "em2820.h" 33#include "em2820.h"
34#include <media/tuner.h>
35 35
36#define DRIVER_AUTHOR "Markus Rechberger <mrechberger@gmail.com>, " \ 36#define DRIVER_AUTHOR "Markus Rechberger <mrechberger@gmail.com>, " \
37 "Ludovico Cavedon <cavedon@sssup.it>, " \ 37 "Ludovico Cavedon <cavedon@sssup.it>, " \
@@ -1699,15 +1699,22 @@ static int em2820_usb_probe(struct usb_interface *interface,
1699 struct usb_device *udev; 1699 struct usb_device *udev;
1700 struct em2820 *dev = NULL; 1700 struct em2820 *dev = NULL;
1701 int retval = -ENODEV; 1701 int retval = -ENODEV;
1702 int model,i,nr; 1702 int model,i,nr,ifnum;
1703 1703
1704 udev = usb_get_dev(interface_to_usbdev(interface)); 1704 udev = usb_get_dev(interface_to_usbdev(interface));
1705 endpoint = &interface->cur_altsetting->endpoint[1].desc; 1705 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1706
1707 em2820_err(DRIVER_NAME " new device (%04x:%04x): interface %i, class %i\n",
1708 udev->descriptor.idVendor,udev->descriptor.idProduct,
1709 ifnum,
1710 interface->altsetting[0].desc.bInterfaceClass);
1706 1711
1707 /* Don't register audio interfaces */ 1712 /* Don't register audio interfaces */
1708 if (interface->altsetting[1].desc.bInterfaceClass == USB_CLASS_AUDIO) 1713 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO)
1709 return -ENODEV; 1714 return -ENODEV;
1710 1715
1716 endpoint = &interface->cur_altsetting->endpoint[1].desc;
1717
1711 /* check if the the device has the iso in endpoint at the correct place */ 1718 /* check if the the device has the iso in endpoint at the correct place */
1712 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 1719 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1713 USB_ENDPOINT_XFER_ISOC) { 1720 USB_ENDPOINT_XFER_ISOC) {
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 4115938a1731..31b23f0db051 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -27,6 +27,7 @@
27 27
28#include <linux/videodev.h> 28#include <linux/videodev.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <media/ir-kbd-i2c.h>
30 31
31/* Boards supported by driver */ 32/* Boards supported by driver */
32 33
@@ -53,19 +54,12 @@
53/* number of buffers for isoc transfers */ 54/* number of buffers for isoc transfers */
54#define EM2820_NUM_BUFS 5 55#define EM2820_NUM_BUFS 5
55 56
56/* number of packets for each buffer */ 57/* number of packets for each buffer
57// windows requests only 40 packets .. so we better do the same 58 windows requests only 40 packets .. so we better do the same
58// this is what I found out for all alternate numbers there! 59 this is what I found out for all alternate numbers there!
59 60 */
60#define EM2820_NUM_PACKETS 40 61#define EM2820_NUM_PACKETS 40
61 62
62/* packet size for each packet */
63/* no longer needed: read from endpoint descriptor */
64//#define EM2820_MAX_PACKET_SIZE 3072 //7
65//#define EM2820_MAX_PACKET_SIZE 2892 //6
66//#define EM2820_MAX_PACKET_SIZE 2580 //5
67//#define EM2820_MAX_PACKET_SIZE 1448 //2
68
69/* default alternate; 0 means choose the best */ 63/* default alternate; 0 means choose the best */
70#define EM2820_PINOUT 0 64#define EM2820_PINOUT 0
71#define EM2820_MAX_ALT 7 65#define EM2820_MAX_ALT 7
@@ -292,6 +286,10 @@ void em2820_i2c_call_clients(struct em2820 *dev, unsigned int cmd, void *arg);
292int em2820_i2c_register(struct em2820 *dev); 286int em2820_i2c_register(struct em2820 *dev);
293int em2820_i2c_unregister(struct em2820 *dev); 287int em2820_i2c_unregister(struct em2820 *dev);
294 288
289/* Provided by em2820-input.c */
290
291void em2820_set_ir(struct em2820 * dev,struct IR_i2c *ir);
292
295/* Provided by em2820-core.c */ 293/* Provided by em2820-core.c */
296 294
297void em2820_print_ioctl(char *name, unsigned int cmd); 295void em2820_print_ioctl(char *name, unsigned int cmd);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index aec710f4effc..8cc3f8ab2f3a 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -41,101 +41,71 @@
41#include <linux/workqueue.h> 41#include <linux/workqueue.h>
42#include <asm/semaphore.h> 42#include <asm/semaphore.h>
43#include <media/ir-common.h> 43#include <media/ir-common.h>
44 44#include <media/ir-kbd-i2c.h>
45static IR_KEYTAB_TYPE ir_codes_em2820[IR_KEYTAB_SIZE] = {
46 [ 0x01 ] = KEY_CHANNEL,
47 [ 0x02 ] = KEY_SELECT,
48 [ 0x03 ] = KEY_MUTE,
49 [ 0x04 ] = KEY_POWER,
50 [ 0x05 ] = KEY_KP1,
51 [ 0x06 ] = KEY_KP2,
52 [ 0x07 ] = KEY_KP3,
53 [ 0x08 ] = KEY_CHANNELUP,
54 [ 0x09 ] = KEY_KP4,
55 [ 0x0a ] = KEY_KP5,
56 [ 0x0b ] = KEY_KP6,
57 [ 0x0c ] = KEY_CHANNELDOWN,
58 [ 0x0d ] = KEY_KP7,
59 [ 0x0e ] = KEY_KP8,
60 [ 0x0f ] = KEY_KP9,
61 [ 0x10 ] = KEY_VOLUMEUP,
62 [ 0x11 ] = KEY_KP0,
63 [ 0x12 ] = KEY_MENU,
64 [ 0x13 ] = KEY_PRINT,
65 [ 0x14 ] = KEY_VOLUMEDOWN,
66 [ 0x16 ] = KEY_PAUSE,
67 [ 0x18 ] = KEY_RECORD,
68 [ 0x19 ] = KEY_REWIND,
69 [ 0x1a ] = KEY_PLAY,
70 [ 0x1b ] = KEY_FORWARD,
71 [ 0x1c ] = KEY_BACKSPACE,
72 [ 0x1e ] = KEY_STOP,
73 [ 0x40 ] = KEY_ZOOM,
74};
75 45
76/* Mark Phalan <phalanm@o2.ie> */ 46/* Mark Phalan <phalanm@o2.ie> */
77static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { 47static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
78 [ 0x00 ] = KEY_KP0, 48 [ 0 ] = KEY_KP0,
79 [ 0x01 ] = KEY_KP1, 49 [ 1 ] = KEY_KP1,
80 [ 0x02 ] = KEY_KP2, 50 [ 2 ] = KEY_KP2,
81 [ 0x03 ] = KEY_KP3, 51 [ 3 ] = KEY_KP3,
82 [ 0x04 ] = KEY_KP4, 52 [ 4 ] = KEY_KP4,
83 [ 0x05 ] = KEY_KP5, 53 [ 5 ] = KEY_KP5,
84 [ 0x06 ] = KEY_KP6, 54 [ 6 ] = KEY_KP6,
85 [ 0x07 ] = KEY_KP7, 55 [ 7 ] = KEY_KP7,
86 [ 0x08 ] = KEY_KP8, 56 [ 8 ] = KEY_KP8,
87 [ 0x09 ] = KEY_KP9, 57 [ 9 ] = KEY_KP9,
88 58
89 [ 0x12 ] = KEY_POWER, 59 [ 18 ] = KEY_POWER,
90 [ 0x10 ] = KEY_MUTE, 60 [ 16 ] = KEY_MUTE,
91 [ 0x1f ] = KEY_VOLUMEDOWN, 61 [ 31 ] = KEY_VOLUMEDOWN,
92 [ 0x1b ] = KEY_VOLUMEUP, 62 [ 27 ] = KEY_VOLUMEUP,
93 [ 0x1a ] = KEY_CHANNELUP, 63 [ 26 ] = KEY_CHANNELUP,
94 [ 0x1e ] = KEY_CHANNELDOWN, 64 [ 30 ] = KEY_CHANNELDOWN,
95 [ 0x0e ] = KEY_PAGEUP, 65 [ 14 ] = KEY_PAGEUP,
96 [ 0x1d ] = KEY_PAGEDOWN, 66 [ 29 ] = KEY_PAGEDOWN,
97 [ 0x13 ] = KEY_SOUND, 67 [ 19 ] = KEY_SOUND,
98 68
99 [ 0x18 ] = KEY_KPPLUSMINUS, /* CH +/- */ 69 [ 24 ] = KEY_KPPLUSMINUS, /* CH +/- */
100 [ 0x16 ] = KEY_SUBTITLE, /* CC */ 70 [ 22 ] = KEY_SUBTITLE, /* CC */
101 [ 0x0d ] = KEY_TEXT, /* TTX */ 71 [ 13 ] = KEY_TEXT, /* TTX */
102 [ 0x0b ] = KEY_TV, /* AIR/CBL */ 72 [ 11 ] = KEY_TV, /* AIR/CBL */
103 [ 0x11 ] = KEY_PC, /* PC/TV */ 73 [ 17 ] = KEY_PC, /* PC/TV */
104 [ 0x17 ] = KEY_OK, /* CH RTN */ 74 [ 23 ] = KEY_OK, /* CH RTN */
105 [ 0x19 ] = KEY_MODE, /* FUNC */ 75 [ 25 ] = KEY_MODE, /* FUNC */
106 [ 0x0c ] = KEY_SEARCH, /* AUTOSCAN */ 76 [ 12 ] = KEY_SEARCH, /* AUTOSCAN */
107 77
108 /* Not sure what to do with these ones! */ 78 /* Not sure what to do with these ones! */
109 [ 0x0f ] = KEY_SELECT, /* SOURCE */ 79 [ 15 ] = KEY_SELECT, /* SOURCE */
110 [ 0x0a ] = KEY_KPPLUS, /* +100 */ 80 [ 10 ] = KEY_KPPLUS, /* +100 */
111 [ 0x14 ] = KEY_KPEQUAL, /* SYNC */ 81 [ 20 ] = KEY_KPEQUAL, /* SYNC */
112 [ 0x1c ] = KEY_MEDIA, /* PC/TV */ 82 [ 28 ] = KEY_MEDIA, /* PC/TV */
113}; 83};
114 84
115static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { 85static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
116 [ 0x03 ] = KEY_POWER, 86 [ 0x3 ] = KEY_POWER,
117 [ 0x6f ] = KEY_MUTE, 87 [ 0x6f ] = KEY_MUTE,
118 [ 0x10 ] = KEY_BACKSPACE, /* Recall */ 88 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
119 89
120 [ 0x11 ] = KEY_KP0, 90 [ 0x11 ] = KEY_KP0,
121 [ 0x04 ] = KEY_KP1, 91 [ 0x4 ] = KEY_KP1,
122 [ 0x05 ] = KEY_KP2, 92 [ 0x5 ] = KEY_KP2,
123 [ 0x06 ] = KEY_KP3, 93 [ 0x6 ] = KEY_KP3,
124 [ 0x08 ] = KEY_KP4, 94 [ 0x8 ] = KEY_KP4,
125 [ 0x09 ] = KEY_KP5, 95 [ 0x9 ] = KEY_KP5,
126 [ 0x0a ] = KEY_KP6, 96 [ 0xa ] = KEY_KP6,
127 [ 0x0c ] = KEY_KP7, 97 [ 0xc ] = KEY_KP7,
128 [ 0x0d ] = KEY_KP8, 98 [ 0xd ] = KEY_KP8,
129 [ 0x0e ] = KEY_KP9, 99 [ 0xe ] = KEY_KP9,
130 [ 0x12 ] = KEY_KPDOT, /* 100+ */ 100 [ 0x12 ] = KEY_KPDOT, /* 100+ */
131 101
132 [ 0x07 ] = KEY_VOLUMEUP, 102 [ 0x7 ] = KEY_VOLUMEUP,
133 [ 0x0b ] = KEY_VOLUMEDOWN, 103 [ 0xb ] = KEY_VOLUMEDOWN,
134 [ 0x1a ] = KEY_KPPLUS, 104 [ 0x1a ] = KEY_KPPLUS,
135 [ 0x18 ] = KEY_KPMINUS, 105 [ 0x18 ] = KEY_KPMINUS,
136 [ 0x15 ] = KEY_UP, 106 [ 0x15 ] = KEY_UP,
137 [ 0x1d ] = KEY_DOWN, 107 [ 0x1d ] = KEY_DOWN,
138 [ 0x0f ] = KEY_CHANNELUP, 108 [ 0xf ] = KEY_CHANNELUP,
139 [ 0x13 ] = KEY_CHANNELDOWN, 109 [ 0x13 ] = KEY_CHANNELDOWN,
140 [ 0x48 ] = KEY_ZOOM, 110 [ 0x48 ] = KEY_ZOOM,
141 111
@@ -152,17 +122,6 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
152 122
153}; 123};
154 124
155struct IR {
156 struct i2c_client c;
157 struct input_dev *input;
158 struct ir_input_state ir;
159
160 struct work_struct work;
161 struct timer_list timer;
162 char phys[32];
163 int (*get_key)(struct IR*, u32*, u32*);
164};
165
166/* ----------------------------------------------------------------------- */ 125/* ----------------------------------------------------------------------- */
167/* insmod parameters */ 126/* insmod parameters */
168 127
@@ -173,12 +132,9 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
173#define dprintk(level, fmt, arg...) if (debug >= level) \ 132#define dprintk(level, fmt, arg...) if (debug >= level) \
174 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg) 133 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
175 134
176#define IR_PINNACLE_REMOTE 0x01
177#define IR_TERRATEC_REMOTE 0x02
178
179/* ----------------------------------------------------------------------- */ 135/* ----------------------------------------------------------------------- */
180 136
181static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) 137static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
182{ 138{
183 unsigned char buf[3]; 139 unsigned char buf[3];
184 int start, toggle, dev, code; 140 int start, toggle, dev, code;
@@ -205,7 +161,7 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
205 return 1; 161 return 1;
206} 162}
207 163
208static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) 164static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
209{ 165{
210 unsigned char b; 166 unsigned char b;
211 167
@@ -219,7 +175,7 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
219 return 1; 175 return 1;
220} 176}
221 177
222static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) 178static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
223{ 179{
224 unsigned char b; 180 unsigned char b;
225 181
@@ -239,7 +195,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
239 return 1; 195 return 1;
240} 196}
241 197
242static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) 198static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
243{ 199{
244 unsigned char b; 200 unsigned char b;
245 201
@@ -267,7 +223,7 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
267 return 1; 223 return 1;
268} 224}
269 225
270static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw) 226static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
271{ 227{
272 unsigned char b; 228 unsigned char b;
273 229
@@ -289,10 +245,9 @@ static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
289 *ir_raw = b; 245 *ir_raw = b;
290 return 1; 246 return 1;
291} 247}
292
293/* ----------------------------------------------------------------------- */ 248/* ----------------------------------------------------------------------- */
294 249
295static void ir_key_poll(struct IR *ir) 250static void ir_key_poll(struct IR_i2c *ir)
296{ 251{
297 static u32 ir_key, ir_raw; 252 static u32 ir_key, ir_raw;
298 int rc; 253 int rc;
@@ -313,13 +268,13 @@ static void ir_key_poll(struct IR *ir)
313 268
314static void ir_timer(unsigned long data) 269static void ir_timer(unsigned long data)
315{ 270{
316 struct IR *ir = (struct IR*)data; 271 struct IR_i2c *ir = (struct IR_i2c*)data;
317 schedule_work(&ir->work); 272 schedule_work(&ir->work);
318} 273}
319 274
320static void ir_work(void *data) 275static void ir_work(void *data)
321{ 276{
322 struct IR *ir = data; 277 struct IR_i2c *ir = data;
323 ir_key_poll(ir); 278 ir_key_poll(ir);
324 mod_timer(&ir->timer, jiffies+HZ/10); 279 mod_timer(&ir->timer, jiffies+HZ/10);
325} 280}
@@ -351,10 +306,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
351 IR_KEYTAB_TYPE *ir_codes = NULL; 306 IR_KEYTAB_TYPE *ir_codes = NULL;
352 char *name; 307 char *name;
353 int ir_type; 308 int ir_type;
354 struct IR *ir; 309 struct IR_i2c *ir;
355 struct input_dev *input_dev; 310 struct input_dev *input_dev;
356 311
357 ir = kzalloc(sizeof(struct IR), GFP_KERNEL); 312 ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
358 input_dev = input_allocate_device(); 313 input_dev = input_allocate_device();
359 if (!ir || !input_dev) { 314 if (!ir || !input_dev) {
360 kfree(ir); 315 kfree(ir);
@@ -390,36 +345,18 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
390 ir_codes = ir_codes_rc5_tv; 345 ir_codes = ir_codes_rc5_tv;
391 break; 346 break;
392 case 0x30: 347 case 0x30:
393 switch(kind){ 348 name = "KNC One";
394 case IR_TERRATEC_REMOTE: 349 ir->get_key = get_key_knc1;
395 name = "Terratec IR"; 350 ir_type = IR_TYPE_OTHER;
396 ir->get_key = get_key_knc1; 351 ir_codes = ir_codes_empty;
397 ir_type = IR_TYPE_OTHER;
398 ir_codes = ir_codes_em2820;
399 break;
400 default:
401 name = "KNC One";
402 ir->get_key = get_key_knc1;
403 ir_type = IR_TYPE_OTHER;
404 ir_codes = ir_codes_empty;
405 }
406 break; 352 break;
407 case 0x47:
408 case 0x7a: 353 case 0x7a:
409 switch(kind){ 354 name = "Purple TV";
410 case IR_PINNACLE_REMOTE: 355 ir->get_key = get_key_purpletv;
411 name = "Pinnacle IR Remote"; 356 ir_type = IR_TYPE_OTHER;
412 ir->get_key = get_key_purpletv; 357 ir_codes = ir_codes_purpletv;
413 ir_type = IR_TYPE_OTHER;
414 ir_codes = ir_codes_em2820;
415 break;
416 default:
417 name = "Purple TV";
418 ir->get_key = get_key_purpletv;
419 ir_type = IR_TYPE_OTHER;
420 ir_codes = ir_codes_purpletv;
421 }
422 break; 358 break;
359
423 default: 360 default:
424 /* shouldn't happen */ 361 /* shouldn't happen */
425 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr); 362 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
@@ -427,12 +364,18 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
427 return -1; 364 return -1;
428 } 365 }
429 366
430 /* register i2c device */ 367 /* Sets name and its physical addr */
431 i2c_attach_client(&ir->c);
432 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); 368 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
433 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", 369 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
434 ir->c.adapter->dev.bus_id, 370 ir->c.adapter->dev.bus_id,
435 ir->c.dev.bus_id); 371 ir->c.dev.bus_id);
372 ir->ir_codes=ir_codes;
373
374 /* register i2c device
375 * At device register, IR codes may be changed to be
376 * board dependent.
377 */
378 i2c_attach_client(&ir->c);
436 379
437 /* init + register input device */ 380 /* init + register input device */
438 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 381 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
@@ -440,6 +383,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
440 input_dev->name = ir->c.name; 383 input_dev->name = ir->c.name;
441 input_dev->phys = ir->phys; 384 input_dev->phys = ir->phys;
442 385
386 /* register event device */
443 input_register_device(ir->input); 387 input_register_device(ir->input);
444 388
445 /* start polling via eventd */ 389 /* start polling via eventd */
@@ -454,7 +398,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
454 398
455static int ir_detach(struct i2c_client *client) 399static int ir_detach(struct i2c_client *client)
456{ 400{
457 struct IR *ir = i2c_get_clientdata(client); 401 struct IR_i2c *ir = i2c_get_clientdata(client);
458 402
459 /* kill outstanding polls */ 403 /* kill outstanding polls */
460 del_timer(&ir->timer); 404 del_timer(&ir->timer);
@@ -483,11 +427,9 @@ static int ir_probe(struct i2c_adapter *adap)
483 427
484 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; 428 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
485 static const int probe_saa7134[] = { 0x7a, -1 }; 429 static const int probe_saa7134[] = { 0x7a, -1 };
486 static const int probe_em2820[] = { 0x47, 0x30, -1 }; 430 static const int probe_em2820[] = { 0x30, 0x47, -1 };
487 const int *probe = NULL; 431 const int *probe = NULL;
488 int attached = 0; 432 struct i2c_client c; char buf; int i,rc;
489
490 struct i2c_client c; unsigned char buf; int i,rc;
491 433
492 switch (adap->id) { 434 switch (adap->id) {
493 case I2C_HW_B_BT848: 435 case I2C_HW_B_BT848:
@@ -505,27 +447,15 @@ static int ir_probe(struct i2c_adapter *adap)
505 447
506 memset(&c,0,sizeof(c)); 448 memset(&c,0,sizeof(c));
507 c.adapter = adap; 449 c.adapter = adap;
508 for (i = 0; -1 != probe[i] && attached != 1; i++) { 450 for (i = 0; -1 != probe[i]; i++) {
509 c.addr = probe[i]; 451 c.addr = probe[i];
510 rc = i2c_master_recv(&c,&buf,1); 452 rc = i2c_master_recv(&c,&buf,0);
511 dprintk(1,"probe 0x%02x @ %s: %s\n", 453 dprintk(1,"probe 0x%02x @ %s: %s\n",
512 probe[i], adap->name, 454 probe[i], adap->name,
513 (1 == rc) ? "yes" : "no"); 455 (0 == rc) ? "yes" : "no");
514 switch(adap->id){ 456 if (0 == rc) {
515 case I2C_HW_B_BT848: 457 ir_attach(adap,probe[i],0,0);
516 case I2C_HW_SAA7134: 458 break;
517 if (1 == rc) {
518 ir_attach(adap,probe[i],0,0);
519 attached=1;
520 break;
521 }
522 case I2C_HW_B_EM2820:
523 /* windows logs are needed for fixing the pinnacle device */
524 if (1 == rc && 0xff == buf){
525 ir_attach(adap,probe[i],0,IR_TERRATEC_REMOTE);
526 attached=1;
527 }
528 break;
529 } 459 }
530 } 460 }
531 return 0; 461 return 0;