aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/imon.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2010-09-15 14:42:07 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:06:07 -0400
commiteaf2bcc923ed6c56da8f856e7dc380321433fbda (patch)
tree6797e607a284ede12de80a3ba7582bb458c19c3d /drivers/media/IR/imon.c
parentee08940531193ccce680ca3c2f17ecc497c4bb67 (diff)
V4L/DVB: imon: split mouse events to a separate input dev
This is a stab at separating the mouse (and front panel/knob) events out to a separate input device. This is necessary in preparation for the next patch which makes the rc-core input dev opaque to rc drivers. I can't verify the correctness of the patch beyond the fact that it compiles without warnings. The driver has resisted most of my attempts at understanding it properly...for example, the double calls to le64_to_cpu() and be64_to_cpu() which are applied in imon_incoming_packet() and imon_panel_key_lookup() would amount to a bswab64() call, irregardless of the cpu endianness, and I think the code wouldn't have worked on a big-endian machine... - Minor alterations to apply with minimal core IR changes - Use timer for imon keys too, since its entirely possible for the receiver to miss release codes (either by way of another key being pressed while the first is held or by the remote pointing away from the recevier when the key is release. yes, I know, its ugly). - Bump driver version number, since this is a fairly significant change (for the much much better). Tested successfully w/an imon knob receiver. Signed-off-by: David Härdeman <david@hardeman.nu> Signed-off-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/imon.c')
-rw-r--r--drivers/media/IR/imon.c273
1 files changed, 160 insertions, 113 deletions
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
index c185422ef28c..d36fe7239782 100644
--- a/drivers/media/IR/imon.c
+++ b/drivers/media/IR/imon.c
@@ -44,7 +44,7 @@
44#define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" 44#define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
45#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" 45#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display"
46#define MOD_NAME "imon" 46#define MOD_NAME "imon"
47#define MOD_VERSION "0.9.1" 47#define MOD_VERSION "0.9.2"
48 48
49#define DISPLAY_MINOR_BASE 144 49#define DISPLAY_MINOR_BASE 144
50#define DEVICE_NAME "lcd%d" 50#define DEVICE_NAME "lcd%d"
@@ -121,21 +121,25 @@ struct imon_context {
121 u16 vendor; /* usb vendor ID */ 121 u16 vendor; /* usb vendor ID */
122 u16 product; /* usb product ID */ 122 u16 product; /* usb product ID */
123 123
124 struct input_dev *idev; /* input device for remote */ 124 struct input_dev *rdev; /* input device for remote */
125 struct input_dev *idev; /* input device for panel & IR mouse */
125 struct input_dev *touch; /* input device for touchscreen */ 126 struct input_dev *touch; /* input device for touchscreen */
126 127
127 u32 kc; /* current input keycode */ 128 u32 kc; /* current input keycode */
128 u32 last_keycode; /* last reported input keycode */ 129 u32 last_keycode; /* last reported input keycode */
130 u32 rc_scancode; /* the computed remote scancode */
131 u8 rc_toggle; /* the computed remote toggle bit */
129 u64 ir_type; /* iMON or MCE (RC6) IR protocol? */ 132 u64 ir_type; /* iMON or MCE (RC6) IR protocol? */
130 u8 mce_toggle_bit; /* last mce toggle bit */
131 bool release_code; /* some keys send a release code */ 133 bool release_code; /* some keys send a release code */
132 134
133 u8 display_type; /* store the display type */ 135 u8 display_type; /* store the display type */
134 bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */ 136 bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */
135 137
138 char name_rdev[128]; /* rc input device name */
139 char phys_rdev[64]; /* rc input device phys path */
140
136 char name_idev[128]; /* input device name */ 141 char name_idev[128]; /* input device name */
137 char phys_idev[64]; /* input device phys path */ 142 char phys_idev[64]; /* input device phys path */
138 struct timer_list itimer; /* input device timer, need for rc6 */
139 143
140 char name_touch[128]; /* touch screen name */ 144 char name_touch[128]; /* touch screen name */
141 char phys_touch[64]; /* touch screen phys path */ 145 char phys_touch[64]; /* touch screen phys path */
@@ -956,17 +960,6 @@ static void usb_tx_callback(struct urb *urb)
956} 960}
957 961
958/** 962/**
959 * mce/rc6 keypresses have no distinct release code, use timer
960 */
961static void imon_mce_timeout(unsigned long data)
962{
963 struct imon_context *ictx = (struct imon_context *)data;
964
965 input_report_key(ictx->idev, ictx->last_keycode, 0);
966 input_sync(ictx->idev);
967}
968
969/**
970 * report touchscreen input 963 * report touchscreen input
971 */ 964 */
972static void imon_touch_display_timeout(unsigned long data) 965static void imon_touch_display_timeout(unsigned long data)
@@ -1006,9 +999,6 @@ int imon_ir_change_protocol(void *priv, u64 ir_type)
1006 dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); 999 dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
1007 ir_proto_packet[0] = 0x01; 1000 ir_proto_packet[0] = 0x01;
1008 pad_mouse = false; 1001 pad_mouse = false;
1009 init_timer(&ictx->itimer);
1010 ictx->itimer.data = (unsigned long)ictx;
1011 ictx->itimer.function = imon_mce_timeout;
1012 break; 1002 break;
1013 case IR_TYPE_UNKNOWN: 1003 case IR_TYPE_UNKNOWN:
1014 case IR_TYPE_OTHER: 1004 case IR_TYPE_OTHER:
@@ -1147,20 +1137,21 @@ static int stabilize(int a, int b, u16 timeout, u16 threshold)
1147 return result; 1137 return result;
1148} 1138}
1149 1139
1150static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 hw_code) 1140static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 scancode)
1151{ 1141{
1152 u32 scancode = be32_to_cpu(hw_code);
1153 u32 keycode; 1142 u32 keycode;
1154 u32 release; 1143 u32 release;
1155 bool is_release_code = false; 1144 bool is_release_code = false;
1156 1145
1157 /* Look for the initial press of a button */ 1146 /* Look for the initial press of a button */
1158 keycode = ir_g_keycode_from_table(ictx->idev, scancode); 1147 keycode = ir_g_keycode_from_table(ictx->rdev, scancode);
1148 ictx->rc_toggle = 0x0;
1149 ictx->rc_scancode = scancode;
1159 1150
1160 /* Look for the release of a button */ 1151 /* Look for the release of a button */
1161 if (keycode == KEY_RESERVED) { 1152 if (keycode == KEY_RESERVED) {
1162 release = scancode & ~0x4000; 1153 release = scancode & ~0x4000;
1163 keycode = ir_g_keycode_from_table(ictx->idev, release); 1154 keycode = ir_g_keycode_from_table(ictx->rdev, release);
1164 if (keycode != KEY_RESERVED) 1155 if (keycode != KEY_RESERVED)
1165 is_release_code = true; 1156 is_release_code = true;
1166 } 1157 }
@@ -1170,9 +1161,8 @@ static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 hw_code)
1170 return keycode; 1161 return keycode;
1171} 1162}
1172 1163
1173static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 hw_code) 1164static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode)
1174{ 1165{
1175 u32 scancode = be32_to_cpu(hw_code);
1176 u32 keycode; 1166 u32 keycode;
1177 1167
1178#define MCE_KEY_MASK 0x7000 1168#define MCE_KEY_MASK 0x7000
@@ -1186,18 +1176,21 @@ static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 hw_code)
1186 * but we can't or them into all codes, as some keys are decoded in 1176 * but we can't or them into all codes, as some keys are decoded in
1187 * a different way w/o the same use of the toggle bit... 1177 * a different way w/o the same use of the toggle bit...
1188 */ 1178 */
1189 if ((scancode >> 24) & 0x80) 1179 if (scancode & 0x80000000)
1190 scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT; 1180 scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT;
1191 1181
1192 keycode = ir_g_keycode_from_table(ictx->idev, scancode); 1182 ictx->rc_scancode = scancode;
1183 keycode = ir_g_keycode_from_table(ictx->rdev, scancode);
1184
1185 /* not used in mce mode, but make sure we know its false */
1186 ictx->release_code = false;
1193 1187
1194 return keycode; 1188 return keycode;
1195} 1189}
1196 1190
1197static u32 imon_panel_key_lookup(u64 hw_code) 1191static u32 imon_panel_key_lookup(u64 code)
1198{ 1192{
1199 int i; 1193 int i;
1200 u64 code = be64_to_cpu(hw_code);
1201 u32 keycode = KEY_RESERVED; 1194 u32 keycode = KEY_RESERVED;
1202 1195
1203 for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) { 1196 for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
@@ -1284,8 +1277,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
1284 int dir = 0; 1277 int dir = 0;
1285 char rel_x = 0x00, rel_y = 0x00; 1278 char rel_x = 0x00, rel_y = 0x00;
1286 u16 timeout, threshold; 1279 u16 timeout, threshold;
1287 u64 temp_key; 1280 u32 scancode = KEY_RESERVED;
1288 u32 remote_key;
1289 1281
1290 /* 1282 /*
1291 * The imon directional pad functions more like a touchpad. Bytes 3 & 4 1283 * The imon directional pad functions more like a touchpad. Bytes 3 & 4
@@ -1314,21 +1306,27 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
1314 } 1306 }
1315 buf[2] = dir & 0xFF; 1307 buf[2] = dir & 0xFF;
1316 buf[3] = (dir >> 8) & 0xFF; 1308 buf[3] = (dir >> 8) & 0xFF;
1317 memcpy(&temp_key, buf, sizeof(temp_key)); 1309 scancode = be32_to_cpu(*((u32 *)buf));
1318 remote_key = (u32) (le64_to_cpu(temp_key)
1319 & 0xffffffff);
1320 ictx->kc = imon_remote_key_lookup(ictx,
1321 remote_key);
1322 } 1310 }
1323 } else { 1311 } else {
1312 /*
1313 * Hack alert: instead of using keycodes, we have
1314 * to use hard-coded scancodes here...
1315 */
1324 if (abs(rel_y) > abs(rel_x)) { 1316 if (abs(rel_y) > abs(rel_x)) {
1325 buf[2] = (rel_y > 0) ? 0x7F : 0x80; 1317 buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1326 buf[3] = 0; 1318 buf[3] = 0;
1327 ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP; 1319 if (rel_y > 0)
1320 scancode = 0x01007f00; /* KEY_DOWN */
1321 else
1322 scancode = 0x01008000; /* KEY_UP */
1328 } else { 1323 } else {
1329 buf[2] = 0; 1324 buf[2] = 0;
1330 buf[3] = (rel_x > 0) ? 0x7F : 0x80; 1325 buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1331 ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT; 1326 if (rel_x > 0)
1327 scancode = 0x0100007f; /* KEY_RIGHT */
1328 else
1329 scancode = 0x01000080; /* KEY_LEFT */
1332 } 1330 }
1333 } 1331 }
1334 1332
@@ -1370,29 +1368,43 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
1370 } 1368 }
1371 buf[2] = dir & 0xFF; 1369 buf[2] = dir & 0xFF;
1372 buf[3] = (dir >> 8) & 0xFF; 1370 buf[3] = (dir >> 8) & 0xFF;
1373 memcpy(&temp_key, buf, sizeof(temp_key)); 1371 scancode = be32_to_cpu(*((u32 *)buf));
1374 remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff);
1375 ictx->kc = imon_remote_key_lookup(ictx, remote_key);
1376 } else { 1372 } else {
1373 /*
1374 * Hack alert: instead of using keycodes, we have
1375 * to use hard-coded scancodes here...
1376 */
1377 if (abs(rel_y) > abs(rel_x)) { 1377 if (abs(rel_y) > abs(rel_x)) {
1378 buf[2] = (rel_y > 0) ? 0x7F : 0x80; 1378 buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1379 buf[3] = 0; 1379 buf[3] = 0;
1380 ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP; 1380 if (rel_y > 0)
1381 scancode = 0x01007f00; /* KEY_DOWN */
1382 else
1383 scancode = 0x01008000; /* KEY_UP */
1381 } else { 1384 } else {
1382 buf[2] = 0; 1385 buf[2] = 0;
1383 buf[3] = (rel_x > 0) ? 0x7F : 0x80; 1386 buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1384 ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT; 1387 if (rel_x > 0)
1388 scancode = 0x0100007f; /* KEY_RIGHT */
1389 else
1390 scancode = 0x01000080; /* KEY_LEFT */
1385 } 1391 }
1386 } 1392 }
1387 } 1393 }
1394
1395 if (scancode)
1396 ictx->kc = imon_remote_key_lookup(ictx, scancode);
1388} 1397}
1389 1398
1399/**
1400 * figure out if these is a press or a release. We don't actually
1401 * care about repeats, as those will be auto-generated within the IR
1402 * subsystem for repeating scancodes.
1403 */
1390static int imon_parse_press_type(struct imon_context *ictx, 1404static int imon_parse_press_type(struct imon_context *ictx,
1391 unsigned char *buf, u8 ktype) 1405 unsigned char *buf, u8 ktype)
1392{ 1406{
1393 int press_type = 0; 1407 int press_type = 0;
1394 int rep_delay = ictx->idev->rep[REP_DELAY];
1395 int rep_period = ictx->idev->rep[REP_PERIOD];
1396 1408
1397 /* key release of 0x02XXXXXX key */ 1409 /* key release of 0x02XXXXXX key */
1398 if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00) 1410 if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00)
@@ -1408,22 +1420,10 @@ static int imon_parse_press_type(struct imon_context *ictx,
1408 buf[2] == 0x81 && buf[3] == 0xb7) 1420 buf[2] == 0x81 && buf[3] == 0xb7)
1409 ictx->kc = ictx->last_keycode; 1421 ictx->kc = ictx->last_keycode;
1410 1422
1411 /* mce-specific button handling */ 1423 /* mce-specific button handling, no keyup events */
1412 else if (ktype == IMON_KEY_MCE) { 1424 else if (ktype == IMON_KEY_MCE) {
1413 /* initial press */ 1425 ictx->rc_toggle = buf[2];
1414 if (ictx->kc != ictx->last_keycode 1426 press_type = 1;
1415 || buf[2] != ictx->mce_toggle_bit) {
1416 ictx->last_keycode = ictx->kc;
1417 ictx->mce_toggle_bit = buf[2];
1418 press_type = 1;
1419 mod_timer(&ictx->itimer,
1420 jiffies + msecs_to_jiffies(rep_delay));
1421 /* repeat */
1422 } else {
1423 press_type = 2;
1424 mod_timer(&ictx->itimer,
1425 jiffies + msecs_to_jiffies(rep_period));
1426 }
1427 1427
1428 /* incoherent or irrelevant data */ 1428 /* incoherent or irrelevant data */
1429 } else if (ictx->kc == KEY_RESERVED) 1429 } else if (ictx->kc == KEY_RESERVED)
@@ -1452,36 +1452,38 @@ static void imon_incoming_packet(struct imon_context *ictx,
1452 u32 kc; 1452 u32 kc;
1453 bool norelease = false; 1453 bool norelease = false;
1454 int i; 1454 int i;
1455 u64 temp_key; 1455 u64 scancode;
1456 u64 panel_key = 0;
1457 u32 remote_key = 0;
1458 struct input_dev *idev = NULL; 1456 struct input_dev *idev = NULL;
1457 struct ir_input_dev *irdev = NULL;
1459 int press_type = 0; 1458 int press_type = 0;
1460 int msec; 1459 int msec;
1461 struct timeval t; 1460 struct timeval t;
1462 static struct timeval prev_time = { 0, 0 }; 1461 static struct timeval prev_time = { 0, 0 };
1463 u8 ktype = IMON_KEY_IMON; 1462 u8 ktype;
1464 1463
1465 idev = ictx->idev; 1464 idev = ictx->idev;
1465 irdev = input_get_drvdata(idev);
1466 1466
1467 /* filter out junk data on the older 0xffdc imon devices */ 1467 /* filter out junk data on the older 0xffdc imon devices */
1468 if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff)) 1468 if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff))
1469 return; 1469 return;
1470 1470
1471 /* Figure out what key was pressed */ 1471 /* Figure out what key was pressed */
1472 memcpy(&temp_key, buf, sizeof(temp_key));
1473 if (len == 8 && buf[7] == 0xee) { 1472 if (len == 8 && buf[7] == 0xee) {
1473 scancode = be64_to_cpu(*((u64 *)buf));
1474 ktype = IMON_KEY_PANEL; 1474 ktype = IMON_KEY_PANEL;
1475 panel_key = le64_to_cpu(temp_key); 1475 kc = imon_panel_key_lookup(scancode);
1476 kc = imon_panel_key_lookup(panel_key);
1477 } else { 1476 } else {
1478 remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff); 1477 scancode = be32_to_cpu(*((u32 *)buf));
1479 if (ictx->ir_type == IR_TYPE_RC6) { 1478 if (ictx->ir_type == IR_TYPE_RC6) {
1479 ktype = IMON_KEY_IMON;
1480 if (buf[0] == 0x80) 1480 if (buf[0] == 0x80)
1481 ktype = IMON_KEY_MCE; 1481 ktype = IMON_KEY_MCE;
1482 kc = imon_mce_key_lookup(ictx, remote_key); 1482 kc = imon_mce_key_lookup(ictx, scancode);
1483 } else 1483 } else {
1484 kc = imon_remote_key_lookup(ictx, remote_key); 1484 ktype = IMON_KEY_IMON;
1485 kc = imon_remote_key_lookup(ictx, scancode);
1486 }
1485 } 1487 }
1486 1488
1487 /* keyboard/mouse mode toggle button */ 1489 /* keyboard/mouse mode toggle button */
@@ -1504,6 +1506,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
1504 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 && 1506 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 &&
1505 buf[7] == 0x86) { 1507 buf[7] == 0x86) {
1506 imon_touch_event(ictx, buf); 1508 imon_touch_event(ictx, buf);
1509 return;
1507 1510
1508 /* look for mouse events with pad in mouse mode */ 1511 /* look for mouse events with pad in mouse mode */
1509 } else if (ictx->pad_mouse) { 1512 } else if (ictx->pad_mouse) {
@@ -1534,9 +1537,20 @@ static void imon_incoming_packet(struct imon_context *ictx,
1534 if (ictx->kc == KEY_UNKNOWN) 1537 if (ictx->kc == KEY_UNKNOWN)
1535 goto unknown_key; 1538 goto unknown_key;
1536 1539
1537 /* KEY_MUTE repeats from MCE and knob need to be suppressed */ 1540 if (ktype != IMON_KEY_PANEL) {
1538 if ((ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) 1541 if (press_type == 0)
1539 && (buf[7] == 0xee || ktype == IMON_KEY_MCE)) { 1542 ir_keyup(irdev);
1543 else {
1544 ir_keydown(ictx->rdev, ictx->rc_scancode,
1545 ictx->rc_toggle);
1546 ictx->last_keycode = ictx->kc;
1547 }
1548 return;
1549 }
1550
1551 /* Only panel type events left to process now */
1552 /* KEY_MUTE repeats from knob need to be suppressed */
1553 if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
1540 do_gettimeofday(&t); 1554 do_gettimeofday(&t);
1541 msec = tv2int(&t, &prev_time); 1555 msec = tv2int(&t, &prev_time);
1542 prev_time = t; 1556 prev_time = t;
@@ -1547,11 +1561,9 @@ static void imon_incoming_packet(struct imon_context *ictx,
1547 input_report_key(idev, ictx->kc, press_type); 1561 input_report_key(idev, ictx->kc, press_type);
1548 input_sync(idev); 1562 input_sync(idev);
1549 1563
1550 /* panel keys and some remote keys don't generate a release */ 1564 /* panel keys don't generate a release */
1551 if (panel_key || norelease) { 1565 input_report_key(idev, ictx->kc, 0);
1552 input_report_key(idev, ictx->kc, 0); 1566 input_sync(idev);
1553 input_sync(idev);
1554 }
1555 1567
1556 ictx->last_keycode = ictx->kc; 1568 ictx->last_keycode = ictx->kc;
1557 1569
@@ -1559,8 +1571,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
1559 1571
1560unknown_key: 1572unknown_key:
1561 dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__, 1573 dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__,
1562 (panel_key ? be64_to_cpu(panel_key) : 1574 (long long)scancode);
1563 be32_to_cpu(remote_key)));
1564 return; 1575 return;
1565 1576
1566not_input_data: 1577not_input_data:
@@ -1651,31 +1662,71 @@ static void usb_rx_callback_intf1(struct urb *urb)
1651 usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC); 1662 usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
1652} 1663}
1653 1664
1665static struct input_dev *imon_init_rdev(struct imon_context *ictx)
1666{
1667 struct input_dev *rdev;
1668 struct ir_dev_props *props;
1669 int ret;
1670
1671 rdev = input_allocate_device();
1672 props = kzalloc(sizeof(*props), GFP_KERNEL);
1673 if (!rdev || !props) {
1674 dev_err(ictx->dev, "remote control dev allocation failed\n");
1675 goto out;
1676 }
1677
1678 snprintf(ictx->name_rdev, sizeof(ictx->name_rdev),
1679 "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product);
1680 usb_make_path(ictx->usbdev_intf0, ictx->phys_rdev,
1681 sizeof(ictx->phys_rdev));
1682 strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev));
1683
1684 rdev->name = ictx->name_rdev;
1685 rdev->phys = ictx->phys_rdev;
1686 usb_to_input_id(ictx->usbdev_intf0, &rdev->id);
1687 rdev->dev.parent = ictx->dev;
1688 rdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
1689 input_set_drvdata(rdev, ictx);
1690
1691 props->priv = ictx;
1692 props->driver_type = RC_DRIVER_SCANCODE;
1693 props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */
1694 props->change_protocol = imon_ir_change_protocol;
1695 ictx->props = props;
1696
1697 ret = ir_input_register(rdev, RC_MAP_IMON_PAD, props, MOD_NAME);
1698 if (ret < 0) {
1699 dev_err(ictx->dev, "remote input dev register failed\n");
1700 goto out;
1701 }
1702
1703 return rdev;
1704
1705out:
1706 kfree(props);
1707 input_free_device(rdev);
1708 return NULL;
1709}
1710
1654static struct input_dev *imon_init_idev(struct imon_context *ictx) 1711static struct input_dev *imon_init_idev(struct imon_context *ictx)
1655{ 1712{
1656 struct input_dev *idev; 1713 struct input_dev *idev;
1657 struct ir_dev_props *props;
1658 int ret, i; 1714 int ret, i;
1659 1715
1660 idev = input_allocate_device(); 1716 idev = input_allocate_device();
1661 if (!idev) { 1717 if (!idev) {
1662 dev_err(ictx->dev, "remote input dev allocation failed\n"); 1718 dev_err(ictx->dev, "input dev allocation failed\n");
1663 goto idev_alloc_failed; 1719 goto out;
1664 }
1665
1666 props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
1667 if (!props) {
1668 dev_err(ictx->dev, "remote ir dev props allocation failed\n");
1669 goto props_alloc_failed;
1670 } 1720 }
1671 1721
1672 snprintf(ictx->name_idev, sizeof(ictx->name_idev), 1722 snprintf(ictx->name_idev, sizeof(ictx->name_idev),
1673 "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product); 1723 "iMON Panel, Knob and Mouse(%04x:%04x)",
1724 ictx->vendor, ictx->product);
1674 idev->name = ictx->name_idev; 1725 idev->name = ictx->name_idev;
1675 1726
1676 usb_make_path(ictx->usbdev_intf0, ictx->phys_idev, 1727 usb_make_path(ictx->usbdev_intf0, ictx->phys_idev,
1677 sizeof(ictx->phys_idev)); 1728 sizeof(ictx->phys_idev));
1678 strlcat(ictx->phys_idev, "/input0", sizeof(ictx->phys_idev)); 1729 strlcat(ictx->phys_idev, "/input1", sizeof(ictx->phys_idev));
1679 idev->phys = ictx->phys_idev; 1730 idev->phys = ictx->phys_idev;
1680 1731
1681 idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL); 1732 idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
@@ -1691,30 +1742,20 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx)
1691 __set_bit(kc, idev->keybit); 1742 __set_bit(kc, idev->keybit);
1692 } 1743 }
1693 1744
1694 props->priv = ictx;
1695 props->driver_type = RC_DRIVER_SCANCODE;
1696 /* IR_TYPE_OTHER maps to iMON PAD remote, IR_TYPE_RC6 to MCE remote */
1697 props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6;
1698 props->change_protocol = imon_ir_change_protocol;
1699 ictx->props = props;
1700
1701 usb_to_input_id(ictx->usbdev_intf0, &idev->id); 1745 usb_to_input_id(ictx->usbdev_intf0, &idev->id);
1702 idev->dev.parent = ictx->dev; 1746 idev->dev.parent = ictx->dev;
1747 input_set_drvdata(idev, ictx);
1703 1748
1704 ret = ir_input_register(idev, RC_MAP_IMON_PAD, props, MOD_NAME); 1749 ret = input_register_device(idev);
1705 if (ret < 0) { 1750 if (ret < 0) {
1706 dev_err(ictx->dev, "remote input dev register failed\n"); 1751 dev_err(ictx->dev, "input dev register failed\n");
1707 goto idev_register_failed; 1752 goto out;
1708 } 1753 }
1709 1754
1710 return idev; 1755 return idev;
1711 1756
1712idev_register_failed: 1757out:
1713 kfree(props);
1714props_alloc_failed:
1715 input_free_device(idev); 1758 input_free_device(idev);
1716idev_alloc_failed:
1717
1718 return NULL; 1759 return NULL;
1719} 1760}
1720 1761
@@ -1736,7 +1777,7 @@ static struct input_dev *imon_init_touch(struct imon_context *ictx)
1736 1777
1737 usb_make_path(ictx->usbdev_intf1, ictx->phys_touch, 1778 usb_make_path(ictx->usbdev_intf1, ictx->phys_touch,
1738 sizeof(ictx->phys_touch)); 1779 sizeof(ictx->phys_touch));
1739 strlcat(ictx->phys_touch, "/input1", sizeof(ictx->phys_touch)); 1780 strlcat(ictx->phys_touch, "/input2", sizeof(ictx->phys_touch));
1740 touch->phys = ictx->phys_touch; 1781 touch->phys = ictx->phys_touch;
1741 1782
1742 touch->evbit[0] = 1783 touch->evbit[0] =
@@ -1911,6 +1952,12 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
1911 goto idev_setup_failed; 1952 goto idev_setup_failed;
1912 } 1953 }
1913 1954
1955 ictx->rdev = imon_init_rdev(ictx);
1956 if (!ictx->rdev) {
1957 dev_err(dev, "%s: rc device setup failed\n", __func__);
1958 goto rdev_setup_failed;
1959 }
1960
1914 usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0, 1961 usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
1915 usb_rcvintpipe(ictx->usbdev_intf0, 1962 usb_rcvintpipe(ictx->usbdev_intf0,
1916 ictx->rx_endpoint_intf0->bEndpointAddress), 1963 ictx->rx_endpoint_intf0->bEndpointAddress),
@@ -1928,7 +1975,9 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
1928 return ictx; 1975 return ictx;
1929 1976
1930urb_submit_failed: 1977urb_submit_failed:
1931 ir_input_unregister(ictx->idev); 1978 ir_input_unregister(ictx->rdev);
1979rdev_setup_failed:
1980 input_unregister_device(ictx->idev);
1932idev_setup_failed: 1981idev_setup_failed:
1933find_endpoint_failed: 1982find_endpoint_failed:
1934 mutex_unlock(&ictx->lock); 1983 mutex_unlock(&ictx->lock);
@@ -2289,7 +2338,8 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
2289 if (ifnum == 0) { 2338 if (ifnum == 0) {
2290 ictx->dev_present_intf0 = false; 2339 ictx->dev_present_intf0 = false;
2291 usb_kill_urb(ictx->rx_urb_intf0); 2340 usb_kill_urb(ictx->rx_urb_intf0);
2292 ir_input_unregister(ictx->idev); 2341 input_unregister_device(ictx->idev);
2342 ir_input_unregister(ictx->rdev);
2293 if (ictx->display_supported) { 2343 if (ictx->display_supported) {
2294 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) 2344 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
2295 usb_deregister_dev(interface, &imon_lcd_class); 2345 usb_deregister_dev(interface, &imon_lcd_class);
@@ -2309,11 +2359,8 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
2309 mutex_unlock(&ictx->lock); 2359 mutex_unlock(&ictx->lock);
2310 if (!ictx->display_isopen) 2360 if (!ictx->display_isopen)
2311 free_imon_context(ictx); 2361 free_imon_context(ictx);
2312 } else { 2362 } else
2313 if (ictx->ir_type == IR_TYPE_RC6)
2314 del_timer_sync(&ictx->itimer);
2315 mutex_unlock(&ictx->lock); 2363 mutex_unlock(&ictx->lock);
2316 }
2317 2364
2318 mutex_unlock(&driver_lock); 2365 mutex_unlock(&driver_lock);
2319 2366