You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(135) |
Nov
(123) |
Dec
(83) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(244) |
Feb
(72) |
Mar
(221) |
Apr
(91) |
May
(104) |
Jun
(93) |
Jul
(78) |
Aug
(1) |
Sep
(1) |
Oct
(29) |
Nov
(98) |
Dec
(20) |
| 2003 |
Jan
|
Feb
(21) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(18) |
Sep
(18) |
Oct
(23) |
Nov
(12) |
Dec
(6) |
| 2004 |
Jan
(2) |
Feb
(32) |
Mar
|
Apr
(12) |
May
(11) |
Jun
(11) |
Jul
|
Aug
(9) |
Sep
|
Oct
(15) |
Nov
|
Dec
|
| 2005 |
Jan
|
Feb
(2) |
Mar
(11) |
Apr
(6) |
May
(1) |
Jun
(9) |
Jul
(7) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2006 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2007 |
Jan
|
Feb
(2) |
Mar
|
Apr
(25) |
May
(2) |
Jun
|
Jul
(5) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2008 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2009 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(13) |
Oct
|
Nov
(2) |
Dec
(2) |
| 2011 |
Jan
|
Feb
|
Mar
(10) |
Apr
(10) |
May
(1) |
Jun
(6) |
Jul
|
Aug
(2) |
Sep
(5) |
Oct
|
Nov
|
Dec
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:54:12
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input
In directory usw-pr-cvs1:/tmp/cvs-serv3778
Modified Files:
evdev.c input.c joydev.c keybdev.c mousedev.c tsdev.c
Log Message:
Updating ...
Index: evdev.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/evdev.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
Index: input.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/input.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -d -r1.49 -r1.50
--- input.c 2002/01/20 03:54:46 1.49
+++ input.c 2002/01/24 19:54:08 1.50
@@ -146,6 +146,8 @@
if (code > MSC_MAX || !test_bit(code, dev->mscbit))
return;
+
+ if (dev->event) dev->event(dev, type, code, value);
break;
Index: joydev.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/joydev.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- joydev.c 2002/01/20 03:54:46 1.39
+++ joydev.c 2002/01/24 19:54:08 1.40
@@ -29,6 +29,7 @@
#include <asm/io.h>
#include <asm/system.h>
+#include <asm/segment.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/joystick.h>
Index: keybdev.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/keybdev.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- keybdev.c 2002/01/10 19:31:36 1.17
+++ keybdev.c 2002/01/24 19:54:08 1.18
@@ -35,6 +35,10 @@
#include <linux/module.h>
#include <linux/kbd_kern.h>
+MODULE_AUTHOR("Vojtech Pavlik <vo...@uc...>");
+MODULE_DESCRIPTION("Input core to console keyboard binding");
+MODULE_LICENSE("GPL");
+
char keybdev_name[] = "keyboard";
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(__alpha__) || \
@@ -150,6 +154,7 @@
#endif /* CONFIG_X86 || CONFIG_IA64 || __alpha__ || __mips__ || CONFIG_PPC */
+
static struct input_handler keybdev_handler;
void keybdev_ledfunc(unsigned int led)
@@ -165,6 +170,23 @@
}
}
+/* Tell the user who may be running in X and not see the console that we have
+ panic'ed. This is to distingush panics from "real" lockups.
+ Could in theory send the panic message as morse, but that is left as an
+ exercise for the reader. */
+
+void panic_blink(void)
+{
+ static unsigned long last_jiffie;
+ static char led;
+ /* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is different. */
+ if (jiffies - last_jiffie > HZ/2) {
+ led ^= 0x01 | 0x04;
+ keybdev_ledfunc(led);
+ last_jiffie = jiffies;
+ }
+}
+
void keybdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int down)
{
if (type != EV_KEY) return;
@@ -239,8 +261,4 @@
module_init(keybdev_init);
module_exit(keybdev_exit);
-
-MODULE_AUTHOR("Vojtech Pavlik <vo...@uc...>");
-MODULE_DESCRIPTION("Input core to console keyboard binding");
-MODULE_LICENSE("GPL");
Index: mousedev.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/mousedev.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
Index: tsdev.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/tsdev.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:52:59
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/serio In directory usw-pr-cvs1:/tmp/cvs-serv3262 Modified Files: serport_old.c Log Message: Update. Index: serport_old.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/serio/serport_old.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- serport_old.c 2002/01/22 20:45:17 1.9 +++ serport_old.c 2002/01/24 19:52:57 1.10 @@ -100,7 +100,7 @@ for (i = 0; ttyname[i] != 0 && ttyname[i] != '/'; i++); ttyname[i] = 0; - sprintf(serport->phys, "%s%d/serio0", ttyname, MINOR(tty->device) - tty->driver.minor_start); + sprintf(serport->phys, "%s%d/serio0", ttyname, minor(tty->device) - tty->driver.minor_start); serport->serio.name = serport_name; serport->serio.phys = serport->phys; @@ -166,9 +166,9 @@ char name[32]; #ifdef CONFIG_DEVFS_FS - sprintf(name, tty->driver.name, MINOR(tty->device) - tty->driver.minor_start); + sprintf(name, tty->driver.name, minor(tty->device) - tty->driver.minor_start); #else - sprintf(name, "%s%d", tty->driver.name, MINOR(tty->device) - tty->driver.minor_start); + sprintf(name, "%s%d", tty->driver.name, minor(tty->device) - tty->driver.minor_start); #endif serio_register_port(&serport->serio); |
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:51:30
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/usb
In directory usw-pr-cvs1:/tmp/cvs-serv2610/linux/drivers/usb
Modified Files:
hid-core.c hid-debug.h hid-input.c hid.h usbkbd.c usbmouse.c
wacom.c
Log Message:
Moving, updating to latest versions.
Index: hid-core.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/hid-core.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- hid-core.c 2002/01/22 20:56:42 1.37
+++ hid-core.c 2002/01/24 19:51:26 1.38
@@ -43,7 +43,6 @@
#undef DEBUG_DATA
#include <linux/usb.h>
-#include "usbpath.h"
#include "hid.h"
#ifdef CONFIG_USB_HIDDEV
@@ -204,27 +203,12 @@
return -1;
}
-#if 0 /* Old code, could be right in some way, but generates superfluous fields */
- if (HID_MAIN_ITEM_VARIABLE & ~flags) { /* ARRAY */
- if (parser->global.logical_maximum <= parser->global.logical_minimum) {
- dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
- return -1;
- }
- usages = parser->local.usage_index;
- /* Hint: we can assume usages < MAX_USAGE here */
- } else { /* VARIABLE */
- usages = parser->global.report_count;
- }
-#else
if (parser->global.logical_maximum <= parser->global.logical_minimum) {
dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
return -1;
}
usages = parser->local.usage_index;
- dbg("add_field: usage_index: %d, report_count: %d", parser->global.report_count, parser->local.usage_index);
-#endif
-
offset = report->size;
report->size += parser->global.report_size * parser->global.report_count;
@@ -338,7 +322,7 @@
return 0;
case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
- parser->global.unit_exponent = item_udata(item);
+ parser->global.unit_exponent = item_sdata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_UNIT:
@@ -761,7 +745,6 @@
#endif
}
-
/*
* Analyse a received field, and fetch the data from it. The field
* content is stored for next report processing (we do differential
@@ -869,13 +852,13 @@
}
/*
- * Interrupt input handler.
+ * Input interrupt completion handler.
*/
-static void hid_irq(struct urb *urb)
+static void hid_irq_in(struct urb *urb)
{
if (urb->status) {
- dbg("nonzero status in irq %d", urb->status);
+ dbg("nonzero status in input irq %d", urb->status);
return;
}
@@ -925,7 +908,8 @@
hid_dump_input(field->usage + offset, value);
if (offset >= field->report_count) {
- dbg("offset exceeds report_count");
+ dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count);
+ hid_dump_field(field, 8);
return -1;
}
if (field->logical_minimum < 0) {
@@ -962,6 +946,63 @@
return -1;
}
+/*
+ * Find a report with a specified HID usage.
+ */
+
+int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type)
+{
+ struct hid_report_enum *report_enum = hid->report_enum + type;
+ struct list_head *list = report_enum->report_list.next;
+ int i, j;
+
+ while (list != &report_enum->report_list) {
+ *report = (struct hid_report *) list;
+ list = list->next;
+ for (i = 0; i < (*report)->maxfield; i++) {
+ struct hid_field *field = (*report)->field[i];
+ for (j = 0; j < field->maxusage; j++)
+ if (field->logical == wanted_usage)
+ return j;
+ }
+ }
+ return -1;
+}
+
+int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field)
+{
+ int i, j;
+
+ for (i = 0; i < report->maxfield; i++) {
+ *field = report->field[i];
+ for (j = 0; j < (*field)->maxusage; j++)
+ if ((*field)->usage[j].hid == wanted_usage)
+ return j;
+ }
+
+ return -1;
+}
+
+static int hid_submit_out(struct hid_device *hid)
+{
+ struct hid_report *report;
+
+ report = hid->out[hid->outtail];
+
+ hid_output_report(report, hid->outbuf);
+ hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1;
+ hid->urbout->dev = hid->dev;
+
+ dbg("submitting out urb");
+
+ if (usb_submit_urb(hid->urbout)) {
+ err("usb_submit_urb(out) failed");
+ return -1;
+ }
+
+ return 0;
+}
+
static int hid_submit_ctrl(struct hid_device *hid)
{
struct hid_report *report;
@@ -970,22 +1011,22 @@
report = hid->ctrl[hid->ctrltail].report;
dir = hid->ctrl[hid->ctrltail].dir;
- if (!dir)
+ if (dir == USB_DIR_OUT)
hid_output_report(report, hid->ctrlbuf);
- hid->urbctrl.transfer_buffer_length = ((report->size - 1) >> 3) + 1 + ((report->id > 0) && dir);
- hid->urbctrl.pipe = dir ? usb_rcvctrlpipe(hid->dev, 0) : usb_sndctrlpipe(hid->dev, 0);
- hid->urbctrl.dev = hid->dev;
-
- hid->dr.wLength = cpu_to_le16(hid->urbctrl.transfer_buffer_length);
- hid->dr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
- hid->dr.bRequest = dir ? HID_REQ_GET_REPORT : HID_REQ_SET_REPORT;
- hid->dr.wIndex = cpu_to_le16(hid->ifnum);
- hid->dr.wValue = ((report->type + 1) << 8) | report->id;
+ hid->urbctrl->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + ((report->id > 0) && (dir != USB_DIR_OUT));
+ hid->urbctrl->pipe = (dir == USB_DIR_OUT) ? usb_sndctrlpipe(hid->dev, 0) : usb_rcvctrlpipe(hid->dev, 0);
+ hid->urbctrl->dev = hid->dev;
+ hid->cr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
+ hid->cr.bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
+ hid->cr.wValue = ((report->type + 1) << 8) | report->id;
+ hid->cr.wIndex = cpu_to_le16(hid->ifnum);
+ hid->cr.wLength = cpu_to_le16(hid->urbctrl->transfer_buffer_length);
+
dbg("submitting ctrl urb");
- if (usb_submit_urb(&hid->urbctrl)) {
+ if (usb_submit_urb(hid->urbctrl)) {
err("usb_submit_urb(ctrl) failed");
return -1;
}
@@ -993,14 +1034,49 @@
return 0;
}
+/*
+ * Output interrupt completion handler.
+ */
+
+static void hid_irq_out(struct urb *urb)
+{
+ struct hid_device *hid = urb->context;
+ unsigned long flags;
+
+ if (urb->status)
+ warn("output irq status %d received", urb->status);
+
+ spin_lock_irqsave(&hid->outlock, flags);
+
+ hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
+
+ if (hid->outhead != hid->outtail) {
+ hid_submit_out(hid);
+ return;
+ }
+
+ clear_bit(HID_OUT_RUNNING, &hid->iofl);
+
+ spin_unlock_irqrestore(&hid->outlock, flags);
+
+ wake_up(&hid->wait);
+}
+
+/*
+ * Control pipe completion handler.
+ */
+
static void hid_ctrl(struct urb *urb)
{
struct hid_device *hid = urb->context;
+ unsigned long flags;
if (urb->status)
warn("ctrl urb status %d received", urb->status);
- if (hid->ctrl[hid->ctrltail].dir)
+ spin_lock_irqsave(&hid->ctrllock, flags);
+
+ if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN)
hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb);
hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
@@ -1010,14 +1086,42 @@
return;
}
+ clear_bit(HID_CTRL_RUNNING, &hid->iofl);
+
+ spin_unlock_irqrestore(&hid->ctrllock, flags);
+
wake_up(&hid->wait);
}
void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
{
int head;
+ unsigned long flags;
+ if (dir == USB_DIR_OUT && hid->urbout) {
+
+ spin_lock_irqsave(&hid->outlock, flags);
+
+ if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) {
+ spin_unlock_irqrestore(&hid->outlock, flags);
+ warn("output queue full");
+ return;
+ }
+
+ hid->out[hid->outhead] = report;
+ hid->outhead = head;
+
+ if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl))
+ hid_submit_out(hid);
+
+ spin_unlock_irqrestore(&hid->outlock, flags);
+ return;
+ }
+
+ spin_lock_irqsave(&hid->ctrllock, flags);
+
if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) {
+ spin_unlock_irqrestore(&hid->ctrllock, flags);
warn("control queue full");
return;
}
@@ -1026,10 +1130,35 @@
hid->ctrl[hid->ctrlhead].dir = dir;
hid->ctrlhead = head;
- if (hid->urbctrl.status != -EINPROGRESS)
+ if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl))
hid_submit_ctrl(hid);
+
+ spin_unlock_irqrestore(&hid->ctrllock, flags);
}
+int hid_wait_io(struct hid_device *hid)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ int timeout = 10*HZ;
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&hid->wait, &wait);
+
+ while (timeout && test_bit(HID_CTRL_RUNNING, &hid->iofl) &&
+ test_bit(HID_OUT_RUNNING, &hid->iofl))
+ timeout = schedule_timeout(timeout);
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&hid->wait, &wait);
+
+ if (!timeout) {
+ dbg("timeout waiting for ctrl or out queue to clear");
+ return -1;
+ }
+
+ return 0;
+}
+
static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
unsigned char type, void *buf, int size)
{
@@ -1043,9 +1172,9 @@
if (hid->open++)
return 0;
- hid->urb.dev = hid->dev;
+ hid->urbin->dev = hid->dev;
- if (usb_submit_urb(&hid->urb))
+ if (usb_submit_urb(hid->urbin))
return -EIO;
return 0;
@@ -1054,7 +1183,7 @@
void hid_close(struct hid_device *hid)
{
if (!--hid->open)
- usb_unlink_urb(&hid->urb);
+ usb_unlink_urb(hid->urbin);
}
/*
@@ -1063,26 +1192,14 @@
void hid_init_reports(struct hid_device *hid)
{
- DECLARE_WAITQUEUE(wait, current);
struct hid_report_enum *report_enum;
struct hid_report *report;
struct list_head *list;
- int len, timeout = 10*HZ;
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&hid->wait, &wait);
-
report_enum = hid->report_enum + HID_INPUT_REPORT;
list = report_enum->report_list.next;
while (list != &report_enum->report_list) {
report = (struct hid_report *) list;
- len = ((report->size - 1) >> 3) + 1 + report_enum->numbered;
- if (len > hid->urb.transfer_buffer_length) {
- hid->urb.transfer_buffer_length = len < 32 ? len : 32;
- }
-#if 0
- usb_set_idle(hid->dev, hid->ifnum, 0, report->id); /*** FIXME mixing sync & async ***/
-#endif
hid_submit_report(hid, report, USB_DIR_IN);
list = list->next;
}
@@ -1095,20 +1212,30 @@
list = list->next;
}
- while (timeout && (hid->ctrlhead != hid->ctrltail))
- timeout = schedule_timeout(timeout);
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&hid->wait, &wait);
+ if (hid_wait_io(hid)) {
+ warn("timeout initializing reports\n");
+ return;
+ }
- if (!timeout)
- dbg("timeout waiting for ctrl queue to clear");
+ report_enum = hid->report_enum + HID_INPUT_REPORT;
+ list = report_enum->report_list.next;
+ while (list != &report_enum->report_list) {
+ report = (struct hid_report *) list;
+ usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+ 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id,
+ hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+ list = list->next;
+ }
}
#define USB_VENDOR_ID_WACOM 0x056a
#define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010
#define USB_DEVICE_ID_WACOM_INTUOS 0x0020
+#define USB_VENDOR_ID_GRIFFIN 0x077d
+#define USB_DEVICE_ID_POWERMATE 0x0410
+#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
+
struct hid_blacklist {
__u16 idVendor;
__u16 idProduct;
@@ -1119,6 +1246,8 @@
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2},
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3},
{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4},
+ { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE },
+ { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB },
{ 0, 0 }
};
@@ -1179,23 +1308,32 @@
if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */
continue;
- if (!(endpoint->bEndpointAddress & 0x80)) /* Not an input endpoint */
- continue;
-
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
-
- FILL_INT_URB(&hid->urb, dev, pipe, hid->buffer, 0, hid_irq, hid, endpoint->bInterval);
-
- break;
+ if (endpoint->bEndpointAddress & USB_DIR_IN) {
+ if (hid->urbin)
+ continue;
+ if (!(hid->urbin = usb_alloc_urb(0)))
+ goto fail;
+ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+ FILL_INT_URB(hid->urbin, dev, pipe, hid->inbuf, 0, hid_irq_in, hid, endpoint->bInterval);
+ } else {
+ if (hid->urbout)
+ continue;
+ if (!(hid->urbout = usb_alloc_urb(0)))
+ goto fail;
+ pipe = usb_sndbulkpipe(dev, endpoint->bEndpointAddress); /* FIXME should we use sndint here? */
+ FILL_BULK_URB(hid->urbout, dev, pipe, hid->outbuf, 0, hid_irq_out, hid);
+ }
}
- if (n == interface->bNumEndpoints) {
- dbg("couldn't find an input interrupt endpoint");
- hid_free_device(hid);
- return NULL;
+ if (!hid->urbin) {
+ err("couldn't find an input interrupt endpoint");
+ goto fail;
}
init_waitqueue_head(&hid->wait);
+
+ hid->outlock = SPIN_LOCK_UNLOCKED;
+ hid->ctrllock = SPIN_LOCK_UNLOCKED;
hid->version = hdesc->bcdHID;
hid->country = hdesc->bCountryCode;
@@ -1205,7 +1343,7 @@
hid->name[0] = 0;
if (!(buf = kmalloc(64, GFP_KERNEL)))
- return NULL;
+ goto fail;
if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) {
strcat(hid->name, buf);
@@ -1222,9 +1360,19 @@
kfree(buf);
- FILL_CONTROL_URB(&hid->urbctrl, dev, 0, (void*) &hid->dr, hid->ctrlbuf, 1, hid_ctrl, hid);
+ hid->urbctrl = usb_alloc_urb(0);
+ FILL_CONTROL_URB(hid->urbctrl, dev, 0, (void*) &hid->cr, hid->ctrlbuf, 1, hid_ctrl, hid);
return hid;
+
+fail:
+
+ hid_free_device(hid);
+ if (hid->urbin) usb_free_urb(hid->urbin);
+ if (hid->urbout) usb_free_urb(hid->urbout);
+ if (hid->urbctrl) usb_free_urb(hid->urbctrl);
+
+ return NULL;
}
static void* hid_probe(struct usb_device *dev, unsigned int ifnum,
@@ -1284,7 +1432,14 @@
struct hid_device *hid = ptr;
dbg("cleanup called");
- usb_unlink_urb(&hid->urb);
+ usb_unlink_urb(hid->urbin);
+ usb_unlink_urb(hid->urbout);
+ usb_unlink_urb(hid->urbctrl);
+
+ usb_free_urb(hid->urbin);
+ usb_free_urb(hid->urbctrl);
+ if (hid->urbout)
+ usb_free_urb(hid->urbout);
if (hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(hid);
Index: hid-debug.h
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/hid-debug.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- hid-debug.h 2002/01/22 20:56:57 1.9
+++ hid-debug.h 2002/01/24 19:51:26 1.10
@@ -34,6 +34,7 @@
};
static struct hid_usage_entry hid_usage_table[] = {
+ { 0, 0, "Undefined" },
{ 1, 0, "GenericDesktop" },
{0, 0x01, "Pointer"},
{0, 0x02, "Mouse"},
@@ -85,6 +86,7 @@
{ 7, 0, "Keyboard" },
{ 8, 0, "LED" },
{ 9, 0, "Button" },
+ { 10, 0, "Ordinal" },
{ 12, 0, "Hotkey" },
{ 13, 0, "Digitizers" },
{0, 0x01, "Digitizer"},
@@ -110,6 +112,112 @@
{0, 0x45, "Eraser"},
{0, 0x46, "TabletPick"},
{ 15, 0, "PhysicalInterfaceDevice" },
+ {0, 0x00, "Undefined"},
+ {0, 0x01, "Physical_Interface_Device"},
+ {0, 0x20, "Normal"},
+ {0, 0x21, "Set_Effect_Report"},
+ {0, 0x22, "Effect_Block_Index"},
+ {0, 0x23, "Parameter_Block_Offset"},
+ {0, 0x24, "ROM_Flag"},
+ {0, 0x25, "Effect_Type"},
+ {0, 0x26, "ET_Constant_Force"},
+ {0, 0x27, "ET_Ramp"},
+ {0, 0x28, "ET_Custom_Force_Data"},
+ {0, 0x30, "ET_Square"},
+ {0, 0x31, "ET_Sine"},
+ {0, 0x32, "ET_Triangle"},
+ {0, 0x33, "ET_Sawtooth_Up"},
+ {0, 0x34, "ET_Sawtooth_Down"},
+ {0, 0x40, "ET_Spring"},
+ {0, 0x41, "ET_Damper"},
+ {0, 0x42, "ET_Inertia"},
+ {0, 0x43, "ET_Friction"},
+ {0, 0x50, "Duration"},
+ {0, 0x51, "Sample_Period"},
+ {0, 0x52, "Gain"},
+ {0, 0x53, "Trigger_Button"},
+ {0, 0x54, "Trigger_Repeat_Interval"},
+ {0, 0x55, "Axes_Enable"},
+ {0, 0x56, "Direction_Enable"},
+ {0, 0x57, "Direction"},
+ {0, 0x58, "Type_Specific_Block_Offset"},
+ {0, 0x59, "Block_Type"},
+ {0, 0x5A, "Set_Envelope_Report"},
+ {0, 0x5B, "Attack_Level"},
+ {0, 0x5C, "Attack_Time"},
+ {0, 0x5D, "Fade_Level"},
+ {0, 0x5E, "Fade_Time"},
+ {0, 0x5F, "Set_Condition_Report"},
+ {0, 0x60, "CP_Offset"},
+ {0, 0x61, "Positive_Coefficient"},
+ {0, 0x62, "Negative_Coefficient"},
+ {0, 0x63, "Positive_Saturation"},
+ {0, 0x64, "Negative_Saturation"},
+ {0, 0x65, "Dead_Band"},
+ {0, 0x66, "Download_Force_Sample"},
+ {0, 0x67, "Isoch_Custom_Force_Enable"},
+ {0, 0x68, "Custom_Force_Data_Report"},
+ {0, 0x69, "Custom_Force_Data"},
+ {0, 0x6A, "Custom_Force_Vendor_Defined_Data"},
+ {0, 0x6B, "Set_Custom_Force_Report"},
+ {0, 0x6C, "Custom_Force_Data_Offset"},
+ {0, 0x6D, "Sample_Count"},
+ {0, 0x6E, "Set_Periodic_Report"},
+ {0, 0x6F, "Offset"},
+ {0, 0x70, "Magnitude"},
+ {0, 0x71, "Phase"},
+ {0, 0x72, "Period"},
+ {0, 0x73, "Set_Constant_Force_Report"},
+ {0, 0x74, "Set_Ramp_Force_Report"},
+ {0, 0x75, "Ramp_Start"},
+ {0, 0x76, "Ramp_End"},
+ {0, 0x77, "Effect_Operation_Report"},
+ {0, 0x78, "Effect_Operation"},
+ {0, 0x79, "Op_Effect_Start"},
+ {0, 0x7A, "Op_Effect_Start_Solo"},
+ {0, 0x7B, "Op_Effect_Stop"},
+ {0, 0x7C, "Loop_Count"},
+ {0, 0x7D, "Device_Gain_Report"},
+ {0, 0x7E, "Device_Gain"},
+ {0, 0x7F, "PID_Pool_Report"},
+ {0, 0x80, "RAM_Pool_Size"},
+ {0, 0x81, "ROM_Pool_Size"},
+ {0, 0x82, "ROM_Effect_Block_Count"},
+ {0, 0x83, "Simultaneous_Effects_Max"},
+ {0, 0x84, "Pool_Alignment"},
+ {0, 0x85, "PID_Pool_Move_Report"},
+ {0, 0x86, "Move_Source"},
+ {0, 0x87, "Move_Destination"},
+ {0, 0x88, "Move_Length"},
+ {0, 0x89, "PID_Block_Load_Report"},
+ {0, 0x8B, "Block_Load_Status"},
+ {0, 0x8C, "Block_Load_Success"},
+ {0, 0x8D, "Block_Load_Full"},
+ {0, 0x8E, "Block_Load_Error"},
+ {0, 0x8F, "Block_Handle"},
+ {0, 0x90, "PID_Block_Free_Report"},
+ {0, 0x91, "Type_Specific_Block_Handle"},
+ {0, 0x92, "PID_State_Report"},
+ {0, 0x94, "Effect_Playing"},
+ {0, 0x95, "PID_Device_Control_Report"},
+ {0, 0x96, "PID_Device_Control"},
+ {0, 0x97, "DC_Enable_Actuators"},
+ {0, 0x98, "DC_Disable_Actuators"},
+ {0, 0x99, "DC_Stop_All_Effects"},
+ {0, 0x9A, "DC_Device_Reset"},
+ {0, 0x9B, "DC_Device_Pause"},
+ {0, 0x9C, "DC_Device_Continue"},
+ {0, 0x9F, "Device_Paused"},
+ {0, 0xA0, "Actuators_Enabled"},
+ {0, 0xA4, "Safety_Switch"},
+ {0, 0xA5, "Actuator_Override_Switch"},
+ {0, 0xA6, "Actuator_Power"},
+ {0, 0xA7, "Start_Delay"},
+ {0, 0xA8, "Parameter_Block_Size"},
+ {0, 0xA9, "Device_Managed_Pool"},
+ {0, 0xAA, "Shared_Parameter_Blocks"},
+ {0, 0xAB, "Create_New_Effect_Report"},
+ {0, 0xAC, "RAM_Pool_Available"},
{ 0, 0, NULL }
};
@@ -174,7 +282,50 @@
tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent);
}
if (field->unit) {
- tab(n); printk("Unit(%u)\n", field->unit);
+ char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
+ char *units[5][8] = {
+ { "None", "None", "None", "None", "None", "None", "None", "None" },
+ { "None", "Centimeter", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
+ { "None", "Radians", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
+ { "None", "Inch", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" },
+ { "None", "Degrees", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }
+ };
+
+ int i;
+ int sys;
+ __u32 data = field->unit;
+
+ /* First nibble tells us which system we're in. */
+ sys = data & 0xf;
+ data >>= 4;
+
+ if(sys > 4) {
+ tab(n); printk("Unit(Invalid)\n");
+ }
+ else {
+ int earlier_unit = 0;
+
+ tab(n); printk("Unit(%s : ", systems[sys]);
+
+ for (i=1 ; i<sizeof(__u32)*2 ; i++) {
+ char nibble = data & 0xf;
+ data >>= 4;
+ if (nibble != 0) {
+ if(earlier_unit++ > 0)
+ printk("*");
+ printk("%s", units[sys][i]);
+ if(nibble != 1) {
+ /* This is a _signed_ nibble(!) */
+
+ int val = nibble & 0x7;
+ if(nibble & 0x08)
+ val = -((0x7 & ~val) +1);
+ printk("^%d", val);
+ }
+ }
+ }
+ printk(")\n");
+ }
}
tab(n); printk("Report Size(%u)\n", field->report_size);
tab(n); printk("Report Count(%u)\n", field->report_count);
Index: hid-input.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/hid-input.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
Index: hid.h
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/hid.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- hid.h 2002/01/22 20:57:23 1.26
+++ hid.h 2002/01/24 19:51:26 1.27
@@ -175,6 +175,7 @@
#define HID_UP_KEYBOARD 0x00070000
#define HID_UP_LED 0x00080000
#define HID_UP_BUTTON 0x00090000
+#define HID_UP_ORDINAL 0x000a0000
#define HID_UP_CONSUMER 0x000c0000
#define HID_UP_DIGITIZER 0x000d0000
#define HID_UP_PID 0x000f0000
@@ -215,7 +216,7 @@
__s32 logical_maximum;
__s32 physical_minimum;
__s32 physical_maximum;
- unsigned unit_exponent;
+ __s32 unit_exponent;
unsigned unit;
unsigned report_id;
unsigned report_size;
@@ -272,7 +273,7 @@
__s32 logical_maximum;
__s32 physical_minimum;
__s32 physical_maximum;
- unsigned unit_exponent;
+ __s32 unit_exponent;
unsigned unit;
struct hid_report *report; /* associated report */
};
@@ -299,6 +300,7 @@
#define HID_BUFFER_SIZE 32
#define HID_CONTROL_FIFO_SIZE 64
+#define HID_OUTPUT_FIFO_SIZE 64
struct hid_control_fifo {
unsigned char dir;
@@ -308,6 +310,9 @@
#define HID_CLAIMED_INPUT 1
#define HID_CLAIMED_HIDDEV 2
+#define HID_CTRL_RUNNING 1
+#define HID_OUT_RUNNING 2
+
struct hid_device { /* device report descriptor */
__u8 *rdesc;
unsigned rsize;
@@ -320,15 +325,24 @@
struct usb_device *dev; /* USB device */
int ifnum; /* USB interface number */
- struct urb urb; /* USB URB structure */
- char buffer[HID_BUFFER_SIZE]; /* Rx buffer */
+ unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
- struct urb urbctrl; /* Control URB */
- struct usb_ctrlrequest dr; /* Control devrquest struct */
+ struct urb *urbin; /* Input URB */
+ char inbuf[HID_BUFFER_SIZE]; /* Input buffer */
+
+ struct urb *urbctrl; /* Control URB */
+ struct usb_ctrlrequest cr; /* Control request struct */
struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */
unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
char ctrlbuf[HID_BUFFER_SIZE]; /* Control buffer */
+ spinlock_t ctrllock; /* Control fifo spinlock */
+ struct urb *urbout; /* Output URB */
+ struct hid_report *out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
+ unsigned char outhead, outtail; /* Output pipe fifo head & tail */
+ char outbuf[HID_BUFFER_SIZE]; /* Output buffer */
+ spinlock_t outlock; /* Output fifo spinlock */
+
unsigned claimed; /* Claimed by hidinput, hiddev? */
unsigned quirks; /* Various quirks the device can pull on us */
@@ -381,6 +395,7 @@
#else
#define hid_dump_input(a,b) do { } while (0)
#define hid_dump_device(c) do { } while (0)
+#define hid_dump_field(a,b) do { } while (0)
#endif
#endif
Index: usbkbd.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/usbkbd.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- usbkbd.c 2002/01/22 20:59:16 1.30
+++ usbkbd.c 2002/01/24 19:51:26 1.31
@@ -4,8 +4,6 @@
* Copyright (c) 1999-2001 Vojtech Pavlik
*
* USB HIDBP Keyboard support
- *
- * Sponsored by SuSE
*/
/*
@@ -24,8 +22,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vo...@su...>, or by paper mail:
- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
+ * e-mail - mail your message to <vo...@uc...>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>
@@ -35,19 +33,17 @@
#include <linux/init.h>
#include <linux/usb.h>
-#define _HID_BOOT_PROTOCOL
-#include "hid.h"
-
/*
* Version Information
*/
#define DRIVER_VERSION ""
-#define DRIVER_AUTHOR "Vojtech Pavlik <vo...@su...>"
+#define DRIVER_AUTHOR "Vojtech Pavlik <vo...@uc...>"
#define DRIVER_DESC "USB HID Boot Protocol keyboard driver"
+#define DRIVER_LICENSE "GPL"
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_LICENSE("GPL");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
static unsigned char usb_kbd_keycode[256] = {
0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
@@ -74,9 +70,10 @@
unsigned char new[8];
unsigned char old[8];
struct urb irq, led;
- struct usb_ctrlrequest dr;
+ struct usb_ctrlrequest cr;
unsigned char leds, newleds;
char name[128];
+ char phys[64];
int open;
};
@@ -181,6 +178,7 @@
struct usb_endpoint_descriptor *endpoint;
struct usb_kbd *kbd;
int i, pipe, maxp;
+ char path[64];
char *buf;
iface = &dev->actconfig->interface[ifnum];
@@ -195,9 +193,6 @@
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- hid_set_protocol(dev, interface->bInterfaceNumber, 0);
- hid_set_idle(dev, interface->bInterfaceNumber, 0, 0);
-
if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL;
memset(kbd, 0, sizeof(struct usb_kbd));
@@ -218,13 +213,17 @@
FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp,
usb_kbd_irq, kbd, endpoint->bInterval);
- kbd->dr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- kbd->dr.bRequest = HID_REQ_SET_REPORT;
- kbd->dr.wValue = 0x200;
- kbd->dr.wIndex = interface->bInterfaceNumber;
- kbd->dr.wLength = 1;
+ kbd->cr.bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+ kbd->cr.bRequest = 0x09;
+ kbd->cr.wValue = 0x200;
+ kbd->cr.wIndex = interface->bInterfaceNumber;
+ kbd->cr.wLength = 1;
+
+ usb_make_path(dev, path, 64);
+ sprintf(kbd->phys, "%s/input0", path);
kbd->dev.name = kbd->name;
+ kbd->dev.phys = kbd->phys;
kbd->dev.idbus = BUS_USB;
kbd->dev.idvendor = dev->descriptor.idVendor;
kbd->dev.idproduct = dev->descriptor.idProduct;
@@ -249,12 +248,11 @@
kfree(buf);
FILL_CONTROL_URB(&kbd->led, dev, usb_sndctrlpipe(dev, 0),
- (void*) &kbd->dr, &kbd->leds, 1, usb_kbd_led, kbd);
+ (void*) &kbd->cr, &kbd->leds, 1, usb_kbd_led, kbd);
input_register_device(&kbd->dev);
- printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
- kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum);
+ printk(KERN_INFO "input: %s on %s\n", kbd->name, path);
return kbd;
}
Index: usbmouse.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/usbmouse.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- usbmouse.c 2002/01/22 20:59:30 1.16
+++ usbmouse.c 2002/01/24 19:51:26 1.17
@@ -32,7 +32,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb.h>
-#include "usbpath.h"
/*
* Version Information
Index: wacom.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/wacom.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- wacom.c 2002/01/22 21:00:01 1.29
+++ wacom.c 2002/01/24 19:51:26 1.30
@@ -65,7 +65,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb.h>
-#include "usbpath.h"
/*
* Version Information
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:51:29
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/gameport
In directory usw-pr-cvs1:/tmp/cvs-serv2610/linux/drivers/input/gameport
Modified Files:
vortex.c
Log Message:
Moving, updating to latest versions.
Index: vortex.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/input/gameport/vortex.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- vortex.c 2002/01/22 20:41:45 1.3
+++ vortex.c 2002/01/24 19:51:25 1.4
@@ -46,6 +46,9 @@
MODULE_DESCRIPTION("Aureal Vortex and Vortex2 gameport driver");
MODULE_LICENSE("GPL");
+#define VORTEX_GCR 0x0c /* Gameport control register */
+#define VORTEX_LEG 0x08 /* Legacy port location */
+#define VORTEX_AXD 0x10 /* Axes start */
#define VORTEX_DATA_WAIT 20 /* 20 ms */
struct vortex {
@@ -90,7 +93,7 @@
switch (mode) {
case GAMEPORT_MODE_COOKED:
writeb(0x40, vortex->io + VORTEX_GCR);
- wait_ms(PCIGAME_DATA_WAIT);
+ wait_ms(VORTEX_DATA_WAIT);
return 0;
case GAMEPORT_MODE_RAW:
writeb(0x00, vortex->io + VORTEX_GCR);
@@ -157,8 +160,8 @@
}
static struct pci_device_id vortex_id_table[] __devinitdata =
-{{ 0x12eb, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x1100c },
- { 0x12eb, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x2880c },
+{{ 0x12eb, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x11000 },
+ { 0x12eb, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x28800 },
{ 0 }};
static struct pci_driver vortex_driver = {
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:51:29
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/macintosh
In directory usw-pr-cvs1:/tmp/cvs-serv2610/linux/drivers/macintosh
Added Files:
adbhid.c mac_hid.c
Log Message:
Moving, updating to latest versions.
--- NEW FILE: adbhid.c ---
/*
* drivers/input/adbhid.c
*
* ADB HID driver for Power Macintosh computers.
*
* Adapted from drivers/macintosh/mac_keyb.c by Franz Sirl
* (see that file for its authors and contributors).
*
* Copyright (C) 2000 Franz Sirl.
*
* Adapted to ADB changes and support for more devices by
* Benjamin Herrenschmidt. Adapted from code in MkLinux
* and reworked.
*
* Supported devices:
*
* - Standard 1 button mouse
* - All standard Apple Extended protocol (handler ID 4)
* - mouseman and trackman mice & trackballs
* - PowerBook Trackpad (default setup: enable tapping)
* - MicroSpeed mouse & trackball (needs testing)
* - CH Products Trackball Pro (needs testing)
* - Contour Design (Contour Mouse)
* - Hunter digital (NoHandsMouse)
* - Kensignton TurboMouse 5 (needs testing)
* - Mouse Systems A3 mice and trackballs <ai...@ku...>
* - MacAlly 2-buttons mouse (needs testing) <po...@de...>
*
* To do:
*
* Improve Kensington support.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/input.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
MODULE_AUTHOR("Franz Sirl <Fra...@la...>");
#define KEYB_KEYREG 0 /* register # for key up/down data */
#define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
#define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */
static int adb_message_handler(struct notifier_block *, unsigned long, void *);
static struct notifier_block adbhid_adb_notifier = {
notifier_call: adb_message_handler,
};
unsigned char adb_to_linux_keycodes[128] = {
30, 31, 32, 33, 35, 34, 44, 45, 46, 47, 86, 48, 16, 17, 18, 19,
21, 20, 2, 3, 4, 5, 7, 6, 13, 10, 8, 12, 9, 11, 27, 24,
22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43, 51, 53, 49, 50, 52,
15, 57, 41, 14, 96, 1, 29,125, 42, 58, 56,105,106,108,103, 0,
0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 98, 96, 0, 74, 0,
0,117, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73,183,181,124,
63, 64, 65, 61, 66, 67,191, 87,190, 99, 0, 70, 0, 68,101, 88,
0,119,110,102,104,111, 62,107, 60,109, 59, 54,100, 97,116,116
};
struct adbhid {
struct input_dev input;
int id;
int default_id;
int original_handler_id;
int current_handler_id;
int mouse_kind;
unsigned char *keycode;
char name[64];
char phys[32];
};
static struct adbhid *adbhid[16] = { 0 };
static void adbhid_probe(void);
static void adbhid_input_keycode(int, int, int);
static void leds_done(struct adb_request *);
static void init_trackpad(int id);
static void init_trackball(int id);
static void init_turbomouse(int id);
static void init_microspeed(int id);
static void init_ms_a3(int id);
static struct adb_ids keyboard_ids;
static struct adb_ids mouse_ids;
static struct adb_ids buttons_ids;
/* Kind of keyboard, see Apple technote 1152 */
#define ADB_KEYBOARD_UNKNOWN 0
#define ADB_KEYBOARD_ANSI 0x0100
#define ADB_KEYBOARD_ISO 0x0200
#define ADB_KEYBOARD_JIS 0x0300
/* Kind of mouse */
#define ADBMOUSE_STANDARD_100 0 /* Standard 100cpi mouse (handler 1) */
#define ADBMOUSE_STANDARD_200 1 /* Standard 200cpi mouse (handler 2) */
#define ADBMOUSE_EXTENDED 2 /* Apple Extended mouse (handler 4) */
#define ADBMOUSE_TRACKBALL 3 /* TrackBall (handler 4) */
#define ADBMOUSE_TRACKPAD 4 /* Apple's PowerBook trackpad (handler 4) */
#define ADBMOUSE_TURBOMOUSE5 5 /* Turbomouse 5 (previously req. mousehack) */
#define ADBMOUSE_MICROSPEED 6 /* Microspeed mouse (&trackball ?), MacPoint */
#define ADBMOUSE_TRACKBALLPRO 7 /* Trackball Pro (special buttons) */
#define ADBMOUSE_MS_A3 8 /* Mouse systems A3 trackball (handler 3) */
#define ADBMOUSE_MACALLY2 9 /* MacAlly 2-button mouse */
static void
adbhid_keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll)
{
int id = (data[0] >> 4) & 0x0f;
if (!adbhid[id]) {
printk(KERN_ERR "ADB HID on ID %d not yet registered, packet %#02x, %#02x, %#02x, %#02x\n",
id, data[0], data[1], data[2], data[3]);
return;
}
/* first check this is from register 0 */
if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
return; /* ignore it */
#if 0
/* How will this be handled now? */
kbd_pt_regs = regs;
#endif
adbhid_input_keycode(id, data[1], 0);
if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
adbhid_input_keycode(id, data[2], 0);
}
static void
adbhid_input_keycode(int id, int keycode, int repeat)
{
int up_flag;
up_flag = (keycode & 0x80);
keycode &= 0x7f;
switch (keycode) {
case 0x39: /* Generate down/up events for CapsLock everytime. */
input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 1);
input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 0);
return;
case 0x3f: /* ignore Powerbook Fn key */
return;
}
if (adbhid[id]->keycode[keycode])
input_report_key(&adbhid[id]->input,
adbhid[id]->keycode[keycode], !up_flag);
else
printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode,
up_flag ? "released" : "pressed");
}
static void
adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
{
int id = (data[0] >> 4) & 0x0f;
if (!adbhid[id]) {
printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id);
return;
}
/*
Handler 1 -- 100cpi original Apple mouse protocol.
Handler 2 -- 200cpi original Apple mouse protocol.
For Apple's standard one-button mouse protocol the data array will
contain the following values:
BITS COMMENTS
data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
data[1] = bxxx xxxx First button and x-axis motion.
data[2] = byyy yyyy Second button and y-axis motion.
Handler 4 -- Apple Extended mouse protocol.
For Apple's 3-button mouse protocol the data array will contain the
following values:
BITS COMMENTS
data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
data[1] = bxxx xxxx Left button and x-axis motion.
data[2] = byyy yyyy Second button and y-axis motion.
data[3] = byyy bxxx Third button and fourth button. Y is additional
high bits of y-axis motion. XY is additional
high bits of x-axis motion.
MacAlly 2-button mouse protocol.
For MacAlly 2-button mouse protocol the data array will contain the
following values:
BITS COMMENTS
data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
data[1] = bxxx xxxx Left button and x-axis motion.
data[2] = byyy yyyy Right button and y-axis motion.
data[3] = ???? ???? unknown
data[4] = ???? ???? unknown
*/
/* If it's a trackpad, we alias the second button to the first.
NOTE: Apple sends an ADB flush command to the trackpad when
the first (the real) button is released. We could do
this here using async flush requests.
*/
switch (adbhid[id]->mouse_kind)
{
case ADBMOUSE_TRACKPAD:
data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80);
data[2] = data[2] | 0x80;
break;
case ADBMOUSE_MICROSPEED:
data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
data[3] = (data[3] & 0x77) | ((data[3] & 0x04) << 5)
| (data[3] & 0x08);
break;
case ADBMOUSE_TRACKBALLPRO:
data[1] = (data[1] & 0x7f) | (((data[3] & 0x04) << 5)
& ((data[3] & 0x08) << 4));
data[2] = (data[2] & 0x7f) | ((data[3] & 0x01) << 7);
data[3] = (data[3] & 0x77) | ((data[3] & 0x02) << 6);
break;
case ADBMOUSE_MS_A3:
data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
data[3] = ((data[3] & 0x04) << 5);
break;
case ADBMOUSE_MACALLY2:
data[3] = (data[2] & 0x80) ? 0x80 : 0x00;
data[2] |= 0x80; /* Right button is mapped as button 3 */
nb=4;
break;
}
input_report_key(&adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1));
input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
if (nb >= 4)
input_report_key(&adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1));
input_report_rel(&adbhid[id]->input, REL_X,
((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ));
input_report_rel(&adbhid[id]->input, REL_Y,
((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 ));
}
static void
adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
{
int id = (data[0] >> 4) & 0x0f;
if (!adbhid[id]) {
printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id);
return;
}
switch (adbhid[id]->original_handler_id) {
default:
case 0x02: /* Adjustable keyboard button device */
printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
data[0], data[1], data[2], data[3]);
break;
case 0x1f: /* Powerbook button device */
{
#ifdef CONFIG_PMAC_BACKLIGHT
int backlight = get_backlight_level();
/*
* XXX: Where is the contrast control for the passive?
* -- Cort
*/
switch (data[1]) {
case 0x8: /* mute */
break;
case 0x7: /* contrast decrease */
break;
case 0x6: /* contrast increase */
break;
case 0xa: /* brightness decrease */
if (backlight < 0)
break;
if (backlight > BACKLIGHT_OFF)
set_backlight_level(backlight-1);
else
set_backlight_level(BACKLIGHT_OFF);
break;
case 0x9: /* brightness increase */
if (backlight < 0)
break;
if (backlight < BACKLIGHT_MAX)
set_backlight_level(backlight+1);
else
set_backlight_level(BACKLIGHT_MAX);
break;
}
#endif /* CONFIG_PMAC_BACKLIGHT */
}
break;
}
}
static struct adb_request led_request;
static int leds_pending[16];
static int pending_devs[16];
static int pending_led_start=0;
static int pending_led_end=0;
static void real_leds(unsigned char leds, int device)
{
if (led_request.complete) {
adb_request(&led_request, leds_done, 0, 3,
ADB_WRITEREG(device, KEYB_LEDREG), 0xff,
~leds);
} else {
if (!(leds_pending[device] & 0x100)) {
pending_devs[pending_led_end] = device;
pending_led_end++;
pending_led_end = (pending_led_end < 16) ? pending_led_end : 0;
}
leds_pending[device] = leds | 0x100;
}
}
/*
* Event callback from the input module. Events that change the state of
* the hardware are processed here.
*/
static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
struct adbhid *adbhid = dev->private;
unsigned char leds;
switch (type) {
case EV_LED:
leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0)
| (test_bit(LED_NUML, dev->led) ? 1 : 0)
| (test_bit(LED_CAPSL, dev->led) ? 2 : 0);
real_leds(leds, adbhid->id);
return 0;
}
return -1;
}
static void leds_done(struct adb_request *req)
{
int leds,device;
if (pending_led_start != pending_led_end) {
device = pending_devs[pending_led_start];
leds = leds_pending[device] & 0xff;
leds_pending[device] = 0;
pending_led_start++;
pending_led_start = (pending_led_start < 16) ? pending_led_start : 0;
real_leds(leds,device);
}
}
static int
adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
{
unsigned long flags;
switch (code) {
case ADB_MSG_PRE_RESET:
case ADB_MSG_POWERDOWN:
/* Stop the repeat timer. Autopoll is already off at this point */
save_flags(flags);
cli();
{
int i;
for (i = 1; i < 16; i++) {
if (adbhid[i])
del_timer(&adbhid[i]->input.timer);
}
}
restore_flags(flags);
/* Stop pending led requests */
while(!led_request.complete)
adb_poll();
break;
case ADB_MSG_POST_RESET:
adbhid_probe();
break;
}
return NOTIFY_DONE;
}
static void
adbhid_input_register(int id, int default_id, int original_handler_id,
int current_handler_id, int mouse_kind)
{
int i;
if (adbhid[id]) {
printk(KERN_ERR "Trying to reregister ADB HID on ID %d\n", id);
return;
}
if (!(adbhid[id] = kmalloc(sizeof(struct adbhid), GFP_KERNEL)))
return;
memset(adbhid[id], 0, sizeof(struct adbhid));
sprintf(adbhid[id]->phys, "adb%d:%d.%02x/input0", id, default_id, original_handler_id);
adbhid[id]->id = default_id;
adbhid[id]->original_handler_id = original_handler_id;
adbhid[id]->current_handler_id = current_handler_id;
adbhid[id]->mouse_kind = mouse_kind;
adbhid[id]->input.private = adbhid[id];
adbhid[id]->input.name = adbhid[id]->name;
adbhid[id]->input.phys = adbhid[id]->phys;
adbhid[id]->input.idbus = BUS_ADB;
adbhid[id]->input.idvendor = 0x0001;
adbhid[id]->input.idproduct = (id << 12) | (default_id << 8) | original_handler_id;
adbhid[id]->input.idversion = 0x0100;
switch (default_id) {
case ADB_KEYBOARD:
if (!(adbhid[id]->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL))) {
kfree(adbhid[id]);
return;
}
sprintf(adbhid[id]->name, "ADB keyboard");
memcpy(adbhid[id]->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
printk(KERN_INFO "Detected ADB keyboard, type ");
switch (original_handler_id) {
default:
printk("<unknown>.\n");
adbhid[id]->input.idversion = ADB_KEYBOARD_UNKNOWN;
break;
case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
case 0xC0: case 0xC3: case 0xC6:
printk("ANSI.\n");
adbhid[id]->input.idversion = ADB_KEYBOARD_ANSI;
break;
case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
case 0xC4: case 0xC7:
printk("ISO, swapping keys.\n");
adbhid[id]->input.idversion = ADB_KEYBOARD_ISO;
i = adbhid[id]->keycode[10];
adbhid[id]->keycode[10] = adbhid[id]->keycode[50];
adbhid[id]->keycode[50] = i;
break;
case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
printk("JIS.\n");
adbhid[id]->input.idversion = ADB_KEYBOARD_JIS;
break;
}
for (i = 0; i < 128; i++)
if (adbhid[id]->keycode[i])
set_bit(adbhid[id]->keycode[i], adbhid[id]->input.keybit);
adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
adbhid[id]->input.ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
adbhid[id]->input.event = adbhid_kbd_event;
adbhid[id]->input.keycodemax = 127;
adbhid[id]->input.keycodesize = 1;
break;
case ADB_MOUSE:
sprintf(adbhid[id]->name, "ADB mouse");
adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
adbhid[id]->input.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
adbhid[id]->input.relbit[0] = BIT(REL_X) | BIT(REL_Y);
break;
case ADB_MISC:
switch (original_handler_id) {
case 0x02: /* Adjustable keyboard button device */
sprintf(adbhid[id]->name, "ADB adjustable keyboard buttons");
break;
case 0x1f: /* Powerbook button device */
sprintf(adbhid[id]->name, "ADB Powerbook buttons");
break;
}
if (adbhid[id]->name[0])
break;
/* else fall through */
default:
printk(KERN_INFO "Trying to register unknown ADB device to input layer.\n");
kfree(adbhid[id]);
return;
}
adbhid[id]->input.keycode = adbhid[id]->keycode;
input_register_device(&adbhid[id]->input);
printk(KERN_INFO "input: %s on adb%d:%d.%02x\n",
adbhid[id]->name, id, default_id, original_handler_id);
if (default_id == ADB_KEYBOARD) {
/* HACK WARNING!! This should go away as soon there is an utility
* to control that for event devices.
*/
adbhid[id]->input.rep[REP_DELAY] = HZ/2; /* input layer default: HZ/4 */
adbhid[id]->input.rep[REP_PERIOD] = HZ/15; /* input layer default: HZ/33 */
}
}
static void adbhid_input_unregister(int id)
{
input_unregister_device(&adbhid[id]->input);
if (adbhid[id]->keycode)
kfree(adbhid[id]->keycode);
kfree(adbhid[id]);
adbhid[id] = 0;
}
static void
adbhid_probe(void)
{
struct adb_request req;
int i, default_id, org_handler_id, cur_handler_id;
for (i = 1; i < 16; i++) {
if (adbhid[i])
adbhid_input_unregister(i);
}
adb_register(ADB_MOUSE, 0, &mouse_ids, adbhid_mouse_input);
adb_register(ADB_KEYBOARD, 0, &keyboard_ids, adbhid_keyboard_input);
adb_register(ADB_MISC, 0, &buttons_ids, adbhid_buttons_input);
for (i = 0; i < keyboard_ids.nids; i++) {
int id = keyboard_ids.id[i];
adb_get_infos(id, &default_id, &org_handler_id);
/* turn off all leds */
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id, KEYB_LEDREG), 0xff, 0xff);
/* Enable full feature set of the keyboard
->get it to send separate codes for left and right shift,
control, option keys */
#if 0 /* handler 5 doesn't send separate codes for R modifiers */
if (adb_try_handler_change(id, 5))
printk("ADB keyboard at %d, handler set to 5\n", id);
else
#endif
if (adb_try_handler_change(id, 3))
printk("ADB keyboard at %d, handler set to 3\n", id);
else
printk("ADB keyboard at %d, handler 1\n", id);
adb_get_infos(id, &default_id, &cur_handler_id);
adbhid_input_register(id, default_id, org_handler_id, cur_handler_id, 0);
}
for (i = 0; i < buttons_ids.nids; i++) {
int id = buttons_ids.id[i];
adb_get_infos(id, &default_id, &org_handler_id);
adbhid_input_register(id, default_id, org_handler_id, org_handler_id, 0);
}
/* Try to switch all mice to handler 4, or 2 for three-button
mode and full resolution. */
for (i = 0; i < mouse_ids.nids; i++) {
int id = mouse_ids.id[i];
int mouse_kind;
adb_get_infos(id, &default_id, &org_handler_id);
if (adb_try_handler_change(id, 4)) {
printk("ADB mouse at %d, handler set to 4", id);
mouse_kind = ADBMOUSE_EXTENDED;
}
else if (adb_try_handler_change(id, 0x2F)) {
printk("ADB mouse at %d, handler set to 0x2F", id);
mouse_kind = ADBMOUSE_MICROSPEED;
}
else if (adb_try_handler_change(id, 0x42)) {
printk("ADB mouse at %d, handler set to 0x42", id);
mouse_kind = ADBMOUSE_TRACKBALLPRO;
}
else if (adb_try_handler_change(id, 0x66)) {
printk("ADB mouse at %d, handler set to 0x66", id);
mouse_kind = ADBMOUSE_MICROSPEED;
}
else if (adb_try_handler_change(id, 0x5F)) {
printk("ADB mouse at %d, handler set to 0x5F", id);
mouse_kind = ADBMOUSE_MICROSPEED;
}
else if (adb_try_handler_change(id, 3)) {
printk("ADB mouse at %d, handler set to 3", id);
mouse_kind = ADBMOUSE_MS_A3;
}
else if (adb_try_handler_change(id, 2)) {
printk("ADB mouse at %d, handler set to 2", id);
mouse_kind = ADBMOUSE_STANDARD_200;
}
else {
printk("ADB mouse at %d, handler 1", id);
mouse_kind = ADBMOUSE_STANDARD_100;
}
if ((mouse_kind == ADBMOUSE_TRACKBALLPRO)
|| (mouse_kind == ADBMOUSE_MICROSPEED)) {
init_microspeed(id);
} else if (mouse_kind == ADBMOUSE_MS_A3) {
init_ms_a3(id);
} else if (mouse_kind == ADBMOUSE_EXTENDED) {
/*
* Register 1 is usually used for device
* identification. Here, we try to identify
* a known device and call the appropriate
* init function.
*/
adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
ADB_READREG(id, 1));
if ((req.reply_len) &&
(req.reply[1] == 0x9a) && ((req.reply[2] == 0x21)
|| (req.reply[2] == 0x20))) {
mouse_kind = ADBMOUSE_TRACKBALL;
init_trackball(id);
}
else if ((req.reply_len >= 4) &&
(req.reply[1] == 0x74) && (req.reply[2] == 0x70) &&
(req.reply[3] == 0x61) && (req.reply[4] == 0x64)) {
mouse_kind = ADBMOUSE_TRACKPAD;
init_trackpad(id);
}
else if ((req.reply_len >= 4) &&
(req.reply[1] == 0x4b) && (req.reply[2] == 0x4d) &&
(req.reply[3] == 0x4c) && (req.reply[4] == 0x31)) {
mouse_kind = ADBMOUSE_TURBOMOUSE5;
init_turbomouse(id);
}
else if ((req.reply_len == 9) &&
(req.reply[1] == 0x4b) && (req.reply[2] == 0x4f) &&
(req.reply[3] == 0x49) && (req.reply[4] == 0x54)) {
if (adb_try_handler_change(id, 0x42)) {
printk("\nADB MacAlly 2-button mouse at %d, handler set to 0x42", id);
mouse_kind = ADBMOUSE_MACALLY2;
}
}
}
printk("\n");
adb_get_infos(id, &default_id, &cur_handler_id);
adbhid_input_register(id, default_id, org_handler_id,
cur_handler_id, mouse_kind);
}
}
static void
init_trackpad(int id)
{
struct adb_request req;
unsigned char r1_buffer[8];
printk(" (trackpad)");
adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
ADB_READREG(id,1));
if (req.reply_len < 8)
printk("bad length for reg. 1\n");
else
{
memcpy(r1_buffer, &req.reply[1], 8);
adb_request(&req, NULL, ADBREQ_SYNC, 9,
ADB_WRITEREG(id,1),
r1_buffer[0],
r1_buffer[1],
r1_buffer[2],
r1_buffer[3],
r1_buffer[4],
r1_buffer[5],
0x0d, /*r1_buffer[6],*/
r1_buffer[7]);
adb_request(&req, NULL, ADBREQ_SYNC, 9,
ADB_WRITEREG(id,2),
0x99,
0x94,
0x19,
0xff,
0xb2,
0x8a,
0x1b,
0x50);
adb_request(&req, NULL, ADBREQ_SYNC, 9,
ADB_WRITEREG(id,1),
r1_buffer[0],
r1_buffer[1],
r1_buffer[2],
r1_buffer[3],
r1_buffer[4],
r1_buffer[5],
0x03, /*r1_buffer[6],*/
r1_buffer[7]);
}
}
static void
init_trackball(int id)
{
struct adb_request req;
printk(" (trackman/mouseman)");
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id,1), 00,0x81);
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id,1), 01,0x81);
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id,1), 02,0x81);
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id,1), 03,0x38);
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id,1), 00,0x81);
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id,1), 01,0x81);
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id,1), 02,0x81);
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id,1), 03,0x38);
}
static void
init_turbomouse(int id)
{
struct adb_request req;
printk(" (TurboMouse 5)");
adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
adb_request(&req, NULL, ADBREQ_SYNC, 9,
ADB_WRITEREG(3,2),
0xe7,
0x8c,
0,
0,
0,
0xff,
0xff,
0x94);
adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
adb_request(&req, NULL, ADBREQ_SYNC, 9,
ADB_WRITEREG(3,2),
0xa5,
0x14,
0,
0,
0x69,
0xff,
0xff,
0x27);
}
static void
init_microspeed(int id)
{
struct adb_request req;
printk(" (Microspeed/MacPoint or compatible)");
adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
/* This will initialize mice using the Microspeed, MacPoint and
other compatible firmware. Bit 12 enables extended protocol.
Register 1 Listen (4 Bytes)
0 - 3 Button is mouse (set also for double clicking!!!)
4 - 7 Button is locking (affects change speed also)
8 - 11 Button changes speed
12 1 = Extended mouse mode, 0 = normal mouse mode
13 - 15 unused 0
16 - 23 normal speed
24 - 31 changed speed
Register 1 talk holds version and product identification information.
Register 1 Talk (4 Bytes):
0 - 7 Product code
8 - 23 undefined, reserved
24 - 31 Version number
Speed 0 is max. 1 to 255 set speed in increments of 1/256 of max.
*/
adb_request(&req, NULL, ADBREQ_SYNC, 5,
ADB_WRITEREG(id,1),
0x20, /* alt speed = 0x20 (rather slow) */
0x00, /* norm speed = 0x00 (fastest) */
0x10, /* extended protocol, no speed change */
0x07); /* all buttons enabled as mouse buttons, no locking */
adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
}
static void
init_ms_a3(int id)
{
struct adb_request req;
printk(" (Mouse Systems A3 Mouse, or compatible)");
adb_request(&req, NULL, ADBREQ_SYNC, 3,
ADB_WRITEREG(id, 0x2),
0x00,
0x07);
adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
}
static int __init adbhid_init(void)
{
if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
return 0;
led_request.complete = 1;
adbhid_probe();
notifier_chain_register(&adb_client_list, &adbhid_adb_notifier);
return 0;
}
static void __exit adbhid_exit(void)
{
}
module_init(adbhid_init);
module_exit(adbhid_exit);
--- NEW FILE: mac_hid.c ---
/*
* drivers/macintosh/mac_hid.c
*
* HID support stuff for Macintosh computers.
*
* Copyright (C) 2000, 2001 Franz Sirl.
*
* This stuff should really be handled in userspace.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
#include <linux/input.h>
static struct input_dev emumousebtn;
static void emumousebtn_input_register(void);
static int mouse_emulate_buttons = 0;
static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */
static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
static int mouse_last_keycode = 0;
#if defined(CONFIG_SYSCTL)
/* file(s) in /proc/sys/dev/mac_hid */
ctl_table mac_hid_files[] =
{
{
DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
"mouse_button_emulation", &mouse_emulate_buttons, sizeof(int),
0644, NULL, &proc_dointvec
},
{
DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
"mouse_button2_keycode", &mouse_button2_keycode, sizeof(int),
0644, NULL, &proc_dointvec
},
{
DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
"mouse_button3_keycode", &mouse_button3_keycode, sizeof(int),
0644, NULL, &proc_dointvec
},
{ 0 }
};
/* dir in /proc/sys/dev */
ctl_table mac_hid_dir[] =
{
{ DEV_MAC_HID, "mac_hid", NULL, 0, 0555, mac_hid_files },
{ 0 }
};
/* /proc/sys/dev itself, in case that is not there yet */
ctl_table mac_hid_root_dir[] =
{
{ CTL_DEV, "dev", NULL, 0, 0555, mac_hid_dir },
{ 0 }
};
static struct ctl_table_header *mac_hid_sysctl_header;
#endif /* endif CONFIG_SYSCTL */
int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
{
switch (caller) {
case 1:
/* Called from keyboard.c */
if (mouse_emulate_buttons
&& (keycode == mouse_button2_keycode
|| keycode == mouse_button3_keycode)) {
if (mouse_emulate_buttons == 1) {
input_report_key(&emumousebtn,
keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
down);
return 1;
}
mouse_last_keycode = down ? keycode : 0;
}
break;
}
return 0;
}
static void emumousebtn_input_register(void)
{
emumousebtn.name = "Macintosh mouse button emulation";
emumousebtn.phys = "machid/input0"; /* FIXME */
emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y);
emumousebtn.idbus = BUS_ADB;
emumousebtn.idvendor = 0x0001;
emumousebtn.idproduct = 0x0001;
emumousebtn.idversion = 0x0100;
input_register_device(&emumousebtn);
}
static int __init mac_hid_init(void)
{
emumousebtn_input_register();
#if defined(CONFIG_SYSCTL)
mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1);
#endif /* CONFIG_SYSCTL */
return(0);
}
static void __exit mac_hid_exit(void)
{
}
module_init(mac_hid_init);
module_exit(mac_hid_exit);
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:51:29
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/sound
In directory usw-pr-cvs1:/tmp/cvs-serv2610/linux/drivers/sound
Modified Files:
es1370.c es1371.c trident.c
Log Message:
Moving, updating to latest versions.
Index: es1370.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/sound/es1370.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- es1370.c 2002/01/03 15:33:39 1.1
+++ es1370.c 2002/01/24 19:51:26 1.2
@@ -1024,7 +1024,7 @@
static int es1370_open_mixdev(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ unsigned int minor = minor(inode->i_rdev);
struct list_head *list;
struct es1370_state *s;
@@ -1368,7 +1368,7 @@
ret = -EINVAL;
goto out;
}
- if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) {
+ if (remap_page_range(vma, vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) {
ret = -EAGAIN;
goto out;
}
@@ -1724,7 +1724,7 @@
static int es1370_open(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ unsigned int minor = minor(inode->i_rdev);
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
struct list_head *list;
@@ -1940,7 +1940,7 @@
if (size > (PAGE_SIZE << s->dma_dac1.buforder))
goto out;
ret = -EAGAIN;
- if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot))
+ if (remap_page_range(vma, vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot))
goto out;
s->dma_dac1.mapped = 1;
ret = 0;
@@ -2160,7 +2160,7 @@
static int es1370_open_dac(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ unsigned int minor = minor(inode->i_rdev);
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
struct list_head *list;
@@ -2403,7 +2403,7 @@
static int es1370_midi_open(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ unsigned int minor = minor(inode->i_rdev);
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
struct list_head *list;
@@ -2479,12 +2479,8 @@
break;
if (signal_pending(current))
break;
- if (file->f_flags & O_NONBLOCK) {
- remove_wait_queue(&s->midi.owait, &wait);
- set_current_state(TASK_RUNNING);
- unlock_kernel();
- return -EBUSY;
- }
+ if (file->f_flags & O_NONBLOCK)
+ break;
tmo = (count * HZ) / 3100;
if (!schedule_timeout(tmo ? : 1) && tmo)
DBG(printk(KERN_DEBUG "es1370: midi timed out??\n");)
Index: es1371.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/sound/es1371.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- es1371.c 2002/01/03 15:33:39 1.1
+++ es1371.c 2002/01/24 19:51:26 1.2
@@ -1207,7 +1207,7 @@
static int es1371_open_mixdev(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
struct list_head *list;
struct es1371_state *s;
@@ -1556,7 +1556,7 @@
ret = -EINVAL;
goto out;
}
- if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) {
+ if (remap_page_range(vma, vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) {
ret = -EAGAIN;
goto out;
}
@@ -1907,7 +1907,7 @@
static int es1371_open(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
struct list_head *list;
@@ -2125,7 +2125,7 @@
if (size > (PAGE_SIZE << s->dma_dac1.buforder))
goto out;
ret = -EAGAIN;
- if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot))
+ if (remap_page_range(vma, vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot))
goto out;
s->dma_dac1.mapped = 1;
ret = 0;
@@ -2336,7 +2336,7 @@
static int es1371_open_dac(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
struct list_head *list;
@@ -2578,7 +2578,7 @@
static int es1371_midi_open(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
struct list_head *list;
@@ -2654,10 +2654,7 @@
if (signal_pending(current))
break;
if (file->f_flags & O_NONBLOCK) {
- remove_wait_queue(&s->midi.owait, &wait);
- set_current_state(TASK_RUNNING);
- unlock_kernel();
- return -EBUSY;
+ break;
}
tmo = (count * HZ) / 3100;
if (!schedule_timeout(tmo ? : 1) && tmo)
@@ -2842,8 +2839,8 @@
printk(KERN_ERR PFX "irq %u in use\n", s->irq);
goto err_irq;
}
- printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n"
- KERN_INFO PFX "features: joystick 0x%x\n", s->rev, s->io, s->irq, joystick[devindex]);
+ printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u joystick %#x\n",
+ s->rev, s->io, s->irq, s->gameport.io);
/* register devices */
if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1))<0))
goto err_dev1;
@@ -3048,7 +3045,7 @@
#ifndef MODULE
-/* format is: es1371=[spdif,[nomic,[amplifier]]] */
+/* format is: es1371=[spdif,[nomix,[amplifier]]] */
static int __init es1371_setup(char *str)
{
@@ -3059,8 +3056,8 @@
(void)
((get_option(&str, &spdif[nr_dev]) == 2)
- && (get_option(&str, &nomic[nr_dev]) == 2)
- && (get_option(&str, &lifier)));
+ && (get_option(&str, &nomix[nr_dev]) == 2)
+ && (get_option(&str, &lifier[nr_dev])));
nr_dev++;
return 1;
Index: trident.c
===================================================================
RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/sound/trident.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- trident.c 2002/01/03 15:33:39 1.1
+++ trident.c 2002/01/24 19:51:26 1.2
@@ -191,6 +191,7 @@
#define TRIDENT_STATE_MAGIC 0x63657373 /* "cess" */
#define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */
+#define ALI_DMA_MASK 0xffffffff /* ALI Tridents lack the 30-bit limitation */
#define NR_HW_CH 32
@@ -647,13 +648,21 @@
static void trident_free_pcm_channel(struct trident_card *card, unsigned int channel)
{
int bank;
+ unsigned char b;
if (channel < 31 || channel > 63)
return;
+ if (card->pci_id == PCI_DEVICE_ID_TRIDENT_4DWAVE_DX ||
+ card->pci_id == PCI_DEVICE_ID_TRIDENT_4DWAVE_NX) {
+ b = inb (TRID_REG(card, T4D_REC_CH));
+ if ((b & ~0x80) == channel)
+ outb(0x0, TRID_REG(card, T4D_REC_CH));
+ }
+
bank = channel >> 5;
channel = channel & 0x1f;
-
+
card->banks[bank].bitmap &= ~(1 << (channel));
}
@@ -2072,7 +2081,7 @@
if (size > (PAGE_SIZE << dmabuf->buforder))
goto out;
ret = -EAGAIN;
- if (remap_page_range(vma->vm_start, virt_to_phys(dmabuf->rawbuf),
+ if (remap_page_range(vma, vma->vm_start, virt_to_phys(dmabuf->rawbuf),
size, vma->vm_page_prot))
goto out;
dmabuf->mapped = 1;
@@ -2554,7 +2563,7 @@
static int trident_open(struct inode *inode, struct file *file)
{
int i = 0;
- int minor = MINOR(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
struct trident_card *card = devs;
struct trident_state *state = NULL;
struct dmabuf *dmabuf = NULL;
@@ -3749,7 +3758,7 @@
static int trident_open_mixdev(struct inode *inode, struct file *file)
{
int i = 0;
- int minor = MINOR(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
struct trident_card *card = devs;
for (card = devs; card != NULL; card = card->next)
@@ -3996,13 +4005,20 @@
u16 temp;
struct pci_dev *pci_dev_m1533 = NULL;
int rc = -ENODEV;
+ u64 dma_mask;
if (pci_enable_device(pci_dev))
goto out;
- if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) {
+ if (pci_dev->device == PCI_DEVICE_ID_ALI_5451)
+ dma_mask = ALI_DMA_MASK;
+ else
+ dma_mask = TRIDENT_DMA_MASK;
+ if (pci_set_dma_mask(pci_dev, dma_mask)) {
printk(KERN_ERR "trident: architecture does not support"
- " 30bit PCI busmaster DMA\n");
+ " %s PCI busmaster DMA\n",
+ pci_dev->device == PCI_DEVICE_ID_ALI_5451 ?
+ "32-bit" : "30-bit");
goto out;
}
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
@@ -4038,11 +4054,11 @@
card->banks[BANK_B].bitmap = 0UL;
card->gameport.driver = card;
- card->gameport.fuzz = 64;
+ card->gameport.fuzz = 64;
card->gameport.read = trident_game_read;
card->gameport.trigger = trident_game_trigger;
- card->gameport.cooked_read = trident_game_cooked_read;
- card->gameport.open = trident_game_open;
+ card->gameport.cooked_read = trident_game_cooked_read;
+ card->gameport.open = trident_game_open;
init_MUTEX(&card->open_sem);
spin_lock_init(&card->lock);
@@ -4174,7 +4190,7 @@
}
rc = 0;
pci_set_drvdata(pci_dev, card);
-
+
/* Enable Address Engine Interrupts */
trident_enable_loop_interrupts(card);
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:51:29
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/touchscreen
In directory usw-pr-cvs1:/tmp/cvs-serv2610/linux/drivers/input/touchscreen
Added Files:
anakin_ts.c
Log Message:
Moving, updating to latest versions.
--- NEW FILE: anakin_ts.c ---
/*
* linux/drivers/input/anakin_ts.c
*
* Copyright (c) 2001 "Crazy" James Simmons jsi...@tr...
*
* Sponsored by Transvirtual Technology.
*
* Based on work by : Tak-Shing Chan <ch...@al...>
*
* Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Changelog:
* 18-Apr-2001 TTC Created
* 24-Jun-2001 JAS Ported to new input api
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/input.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
/*
* TSBUF_SIZE must be a power of two
*/
#define TSBUF_SIZE 256
#define ANAKIN_TS_ON 1
#define ANAKIN_TS_OFF 0
#define NEXT(index) (((index) + 1) & (TSBUF_SIZE - 1))
static struct input_dev anakin_ts_dev;
static unsigned short buffer[TSBUF_SIZE][4];
static int head, tail, xscale, xtrans, yscale, ytrans;
static char *anakin_ts_name = "Anakin TouchScreen";
static char *anakin_ts_phys[32];
/*
* Interrupt handler
*/
static void
anakin_ts_handler(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned int status = __raw_readl(IO_BASE + IO_CONTROLLER + 0x24);
/*
if (NEXT(head) != tail) {
*
* iPAQ format (u16 pressure, x, y, millisecs)
*
switch (status >> 20 & 3) {
case 0:
return;
case 2:
buffer[head][0] = 0;
break;
default:
buffer[head][0] = 0x7f;
}
buffer[head][1] = status >> 2 & 0xff;
buffer[head][2] = status >> 12 & 0xff;
buffer[head][3] = jiffies;
while (head != tail && count >= sizeof data) {
data[0] = buffer[tail][0];
data[1] = (xscale * buffer[tail][1] >> 8) + xtrans;
data[2] = (yscale * buffer[tail][2] >> 8) + ytrans;
data[3] = buffer[tail][3];
__copy_to_user(buf, data, sizeof data);
tail = NEXT(tail);
count -= sizeof data;
buf += sizeof data;
written += sizeof data;
}
input_report_key(&anakin_ts_dev, BTN_TOUCH, value);
input_report_abs(&anakin_ts_dev, ABS_X, value);
input_report_abs(&anakin_ts_dev, ABS_Y, value);
head = NEXT(head);
}
*/
}
static int anakin_ts_open(struct input_dev *dev)
{
__raw_writel(ANAKIN_TS_ON, IO_BASE + IO_CONTROLLER + 8);
return 0;
}
static void anakin_ts_close(struct input_dev *dev)
{
__raw_writel(ANAKIN_TS_OFF, IO_BASE + IO_CONTROLLER + 8);
}
/*
* Initialization and exit routines
*/
static int __init anakin_ts_init(void)
{
int retval;
if ((retval = request_irq(IRQ_TOUCHSCREEN, anakin_ts_handler,
SA_INTERRUPT, "anakints", 0))) {
printk("anakints: failed to get IRQ\n");
return retval;
}
__raw_writel(ANAKIN_TS_ON, IO_BASE + IO_CONTROLLER + 8);
printk("Anakin touchscreen driver initialized\n");
head = tail = 0;
/*
* TODO: get rid of these hardcoded values
*/
xscale = -439; /* 256 * Xsize / (Xout - Xoff) */
xtrans = 415; /* -Xoff * Xsize / (Xout - Xoff) */
yscale = -283; /* 256 * Ysize / (Yout - Yoff) */
ytrans = 257; /* -Yoff * Ysize / (Yout - Yoff) */
anakin_ts_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
anakin_ts_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
anakin_ts_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
anakin_ts_dev.absmax[ABS_X] = 0x1ff;
anakin_ts_dev.absmax[ABS_Y] = 0x0ff;
anakin_ts_dev.open = anakin_ts_open;
anakin_ts_dev.close = anakin_ts_close;
sprintf(anakin_ts_phys, "isa%04x/input0", IO_BASE);
anakin_ts_dev.name = anakin_ts_name;
anakin_ts_dev.phys = anakin_ts_phys;
anakin_ts_dev.idbus = BUS_ISA;
anakin_ts_dev.idvendor = 0x0003;
anakin_ts_dev.idproduct = 0x0001;
anakin_ts_dev.idversion = 0x0100;
input_register_device(&anakin_ts_dev);
printk(KERN_INFO "input: %s at %#x irq %d\n",
anakin_ts_name, IO_BASE, IRQ_TOUCHSCREEN);
return 0;
}
static void __exit anakin_ts_exit(void)
{
input_unregister_device(&anakin_ts_dev);
__raw_writel(ANAKIN_TS_OFF, IO_BASE + IO_CONTROLLER + 8);
free_irq(IRQ_TOUCHSCREEN, 0);
}
module_init(anakin_ts_init);
module_exit(anakin_ts_exit);
MODULE_AUTHOR("James Simmons <jsi...@tr...>");
MODULE_DESCRIPTION("Anakin touchscreen driver");
MODULE_SUPPORTED_DEVICE("touchscreen/anakin");
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:51:29
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input In directory usw-pr-cvs1:/tmp/cvs-serv2610/linux/drivers/input Removed Files: adbhid.c anakin_ts.c arckbd.c cerf_keyb.c hphil.c mac_hid.c Log Message: Moving, updating to latest versions. --- adbhid.c DELETED --- --- anakin_ts.c DELETED --- --- arckbd.c DELETED --- --- cerf_keyb.c DELETED --- --- hphil.c DELETED --- --- mac_hid.c DELETED --- |
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:51:29
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/keyboard
In directory usw-pr-cvs1:/tmp/cvs-serv2610/linux/drivers/input/keyboard
Added Files:
arckbd.c cerf_keyb.c
Log Message:
Moving, updating to latest versions.
--- NEW FILE: arckbd.c ---
/*
* linux/arch/arm/drivers/char1/keyb_arc.c
*
* Acorn keyboard driver for ARM Linux.
*
* The Acorn keyboard appears to have a ***very*** buggy reset protocol -
* every reset behaves differently. We try to get round this by attempting
* a few things...
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/ptrace.h>
#include <linux/signal.h>
#include <linux/timer.h>
#include <linux/random.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/bitops.h>
#include <asm/keyboard.h>
#include <asm/irq.h>
#include <asm/ioc.h>
#include <asm/hardware.h>
#include "../../char/busmouse.h"
extern void kbd_reset_kdown(void);
#define VERSION 108
#define KBD_REPORT_ERR
#define KBD_REPORT_UNKN
#include <asm/io.h>
#include <asm/system.h>
static char kbd_txval[4];
static unsigned char kbd_txhead, kbd_txtail;
#define KBD_INCTXPTR(ptr) ((ptr) = ((ptr) + 1) & 3)
static int kbd_id = -1;
static DECLARE_WAIT_QUEUE_HEAD(kbd_waitq);
#ifdef CONFIG_KBDMOUSE
static int mousedev;
#endif
/*
* Protocol codes to send the keyboard.
*/
#define HRST 0xff /* reset keyboard */
#define RAK1 0xfe /* reset response */
#define RAK2 0xfd /* reset response */
#define BACK 0x3f /* Ack for first keyboard pair */
#define SMAK 0x33 /* Last data byte ack (key scanning + mouse movement scanning) */
#define MACK 0x32 /* Last data byte ack (mouse movement scanning) */
#define SACK 0x31 /* Last data byte ack (key scanning) */
#define NACK 0x30 /* Last data byte ack (no scanning, mouse data) */
#define RQMP 0x22 /* Request mouse data */
#define PRST 0x21 /* nothing */
#define RQID 0x20 /* Request ID */
#define UP_FLAG 1
#ifdef CONFIG_MAGIC_SYSRQ
unsigned char a5kkbd_sysrq_xlate[] =
{
27, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
'`', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '0', '-', '=', '£', 127, 0,
0, 0, 0, '/', '*', '#', 9, 'q',
'w', 'e', 'r', 't', 'y', 'u', 'i', 'o',
'p', '[', ']', '\\', 22, 23, 25, '7',
'8', '9', '-', 0, 'a', 's', 'd', 'f',
'g', 'h', 'j', 'k', 'l', ';', '\'', 13,
'4', '5', '6', '+', 0, 0, 'z', 'x',
'c', 'v', 'b', 'n', 'm', ',', '.', '/',
0, 0, '1', '2', '3', 0, 0, ' ',
0, 0, 0, 0, 0, '0', '.', 10,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
#endif
/*
* This array converts the scancode that we get from the keyboard to the
* real rows/columns on the A5000 keyboard. This might be keyboard specific...
*
* It is these values that we use to maintain the key down array. That way, we
* should pick up on the ghost key presses (which is what happens when you press
* three keys, and the keyboard thinks you have pressed four!)
*
* Row 8 (0x80+c) is actually a column with one key per row. It is isolated from
* the other keys, and can't cause these problems (its used for shift, ctrl, alt etc).
*
* Illegal scancodes are denoted by an 0xff (in other words, we don't know about
* them, and can't process them for ghosts). This does however, cause problems with
* autorepeat processing...
*/
static unsigned char scancode_2_colrow[256] = {
0x01, 0x42, 0x32, 0x33, 0x43, 0x56, 0x5a, 0x6c, 0x7c, 0x5c, 0x5b, 0x6b, 0x7b, 0x84, 0x70, 0x60,
0x11, 0x51, 0x62, 0x63, 0x44, 0x54, 0x55, 0x45, 0x46, 0x4a, 0x3c, 0x4b, 0x59, 0x49, 0x69, 0x79,
0x83, 0x40, 0x30, 0x3b, 0x39, 0x38, 0x31, 0x61, 0x72, 0x73, 0x64, 0x74, 0x75, 0x65, 0x66, 0x6a,
0x1c, 0x2c, 0x7a, 0x36, 0x48, 0x68, 0x78, 0x20, 0x2b, 0x29, 0x28, 0x81, 0x71, 0x22, 0x23, 0x34,
0x24, 0x25, 0x35, 0x26, 0x3a, 0x0c, 0x2a, 0x76, 0x10, 0x1b, 0x19, 0x18, 0x82, 0xff, 0x21, 0x12,
0x13, 0x14, 0x04, 0x05, 0x15, 0x16, 0x1a, 0x0a, 0x85, 0x77, 0x00, 0x0b, 0x09, 0x02, 0x80, 0x03,
0x87, 0x86, 0x06, 0x17, 0x27, 0x07, 0x37, 0x08, 0xff,
};
#define BITS_PER_SHORT (8*sizeof(unsigned short))
static unsigned short ghost_down[128/BITS_PER_SHORT];
static void a5kkbd_key(unsigned int keycode, unsigned int up_flag)
{
unsigned int real_keycode;
if (keycode > 0x72) {
#ifdef KBD_REPORT_UNKN
printk ("kbd: unknown scancode 0x%04x\n", keycode);
#endif
return;
}
if (keycode >= 0x70) {
#ifdef CONFIG_KBDMOUSE
if (mousedev >= 0)
switch (keycode) {
case 0x70: /* Left mouse button */
busmouse_add_buttons(mousedev, 4, up_flag ? 4 : 0);
break;
case 0x71: /* Middle mouse button */
busmouse_add_buttons(mousedev, 2, up_flag ? 2 : 0);
break;
case 0x72:/* Right mouse button */
busmouse_add_buttons(mousedev, 1, up_flag ? 1 : 0);
break;
}
#endif
return;
}
/*
* We have to work out if we accept this key press as a real key, or
* if it is a ghost. IE. If you press three keys, the keyboard will think
* that you've pressed a fourth: (@ = key down, # = ghost)
*
* 0 1 2 3 4 5 6 7
* | | | | | | | |
* 0-+-+-+-+-+-+-+-+-
* | | | | | | | |
* 1-+-@-+-+-+-@-+-+-
* | | | | | | | |
* 2-+-+-+-+-+-+-+-+-
* | | | | | | | |
* 3-+-@-+-+-+-#-+-+-
* | | | | | | | |
*
* This is what happens when you have a matrix keyboard...
*/
real_keycode = scancode_2_colrow[keycode];
if ((real_keycode & 0x80) == 0) {
int rr, kc = (real_keycode >> 4) & 7;
int cc;
unsigned short res, kdownkc;
kdownkc = ghost_down[kc] | (1 << (real_keycode & 15));
for (rr = 0; rr < 128/BITS_PER_SHORT; rr++)
if (rr != kc && (res = ghost_down[rr] & kdownkc)) {
/*
* we have found a second row with at least one key pressed in the
* same column.
*/
for (cc = 0; res; res >>= 1)
cc += (res & 1);
if (cc > 1)
return; /* ignore it */
}
if (up_flag)
clear_bit (real_keycode, ghost_down);
else
set_bit (real_keycode, ghost_down);
}
handle_scancode(keycode, !up_flag);
}
static inline void a5kkbd_sendbyte(unsigned char val)
{
kbd_txval[kbd_txhead] = val;
KBD_INCTXPTR(kbd_txhead);
enable_irq(IRQ_KEYBOARDTX);
}
static inline void a5kkbd_reset(void)
{
int i;
for (i = 0; i < NR_SCANCODES/BITS_PER_SHORT; i++)
ghost_down[i] = 0;
kbd_reset_kdown();
}
void a5kkbd_leds(unsigned char leds)
{
leds = ((leds & (1<<VC_SCROLLOCK))?4:0) | ((leds & (1<<VC_NUMLOCK))?2:0) |
((leds & (1<<VC_CAPSLOCK))?1:0);
a5kkbd_sendbyte(leds);
}
/* Keyboard states:
* 0 initial reset condition, receive HRST, send RRAK1
* 1 Sent RAK1, wait for RAK1, send RRAK2
* 2 Sent RAK2, wait for RAK2, send SMAK or RQID
* 3 Sent RQID, expect KBID, send SMAK
* 4 Sent SMAK, wait for anything
* 5 Wait for second keyboard nibble for key pressed
* 6 Wait for second keyboard nibble for key released
* 7 Wait for second part of mouse data
*
* This function returns 1 when we successfully enter the IDLE state
* (and hence need to do some keyboard processing).
*/
#define KBD_INITRST 0
#define KBD_RAK1 1
#define KBD_RAK2 2
#define KBD_ID 3
#define KBD_IDLE 4
#define KBD_KEYDOWN 5
#define KBD_KEYUP 6
#define KBD_MOUSE 7
static int handle_rawcode(unsigned int keyval)
{
static signed char kbd_mousedx = 0;
signed char kbd_mousedy;
static unsigned char kbd_state = KBD_INITRST;
static unsigned char kbd_keyhigh = 0;
if (keyval == HRST && kbd_state != KBD_INITRST && kbd_state != KBD_ID) {
a5kkbd_sendbyte (HRST);
a5kkbd_reset ();
kbd_state = KBD_INITRST;
} else switch(kbd_state) {
case KBD_INITRST: /* hard reset - sent HRST */
if (keyval == HRST) {
a5kkbd_sendbyte (RAK1);
kbd_state = KBD_RAK1;
} else if (keyval == RAK1) {
/* Some A5000 keyboards are very fussy and don't follow Acorn's
* specs - this appears to fix them, but them it might stop
* them from being initialised.
* fix by Philip Blundell
*/
printk(KERN_DEBUG "keyboard sent early RAK1 -- ignored\n");
} else
goto kbd_wontreset;
break;
case KBD_RAK1: /* sent RAK1 - expect RAK1 and send RAK2 */
if (keyval == RAK1) {
a5kkbd_sendbyte (RAK2);
kbd_state = KBD_RAK2;
} else
goto kbd_wontreset;
break;
case KBD_RAK2: /* Sent RAK2 - expect RAK2 and send either RQID or SMAK */
if (keyval == RAK2) {
if (kbd_id == -1) {
a5kkbd_sendbyte (NACK);
a5kkbd_sendbyte (RQID);
kbd_state = KBD_ID;
} else {
a5kkbd_sendbyte (SMAK);
kbd_state = KBD_IDLE;
}
} else
goto kbd_wontreset;
break;
case KBD_ID: /* Sent RQID - expect KBID */
if (keyval == HRST) {
kbd_id = -2;
a5kkbd_reset ();
a5kkbd_sendbyte (HRST);
kbd_state = KBD_INITRST;
wake_up (&kbd_waitq);
} else if ((keyval & 0xc0) == 0x80) {
kbd_id = keyval & 0x3f;
a5kkbd_sendbyte (SMAK);
kbd_state = KBD_IDLE;
wake_up (&kbd_waitq);
}
break;
case KBD_IDLE: /* Send SMAK, ready for any reply */
switch (keyval & 0xf0) {
default: /* 0x00 - 0x7f */
kbd_mousedx = keyval & 0x40 ? keyval|0x80 : keyval;
kbd_state = KBD_MOUSE;
a5kkbd_sendbyte (BACK);
break;
case 0x80:
case 0x90:
case 0xa0:
case 0xb0:
if (kbd_id == -1)
kbd_id = keyval & 0x3f;
break;
case 0xc0:
kbd_keyhigh = keyval;
kbd_state = KBD_KEYDOWN;
a5kkbd_sendbyte (BACK);
break;
case 0xd0:
kbd_keyhigh = keyval;
kbd_state = KBD_KEYUP;
a5kkbd_sendbyte (BACK);
break;
case 0xe0:
case 0xf0:
goto kbd_error;
}
break;
case KBD_KEYDOWN:
if ((keyval & 0xf0) != 0xc0)
goto kbd_error;
else {
kbd_state = KBD_IDLE;
a5kkbd_sendbyte (SMAK);
if (((kbd_keyhigh ^ keyval) & 0xf0) == 0)
a5kkbd_key ((keyval & 0x0f) | ((kbd_keyhigh << 4) & 0xf0), 0);
}
break;
case KBD_KEYUP:
if ((keyval & 0xf0) != 0xd0)
goto kbd_error;
else {
kbd_state = KBD_IDLE;
a5kkbd_sendbyte (SMAK);
if (((kbd_keyhigh ^ keyval) & 0xf0) == 0)
a5kkbd_key ((keyval & 0x0f) | ((kbd_keyhigh << 4) & 0xf0), UP_FLAG);
}
break;
case KBD_MOUSE:
if (keyval & 0x80)
goto kbd_error;
else {
kbd_state = KBD_IDLE;
a5kkbd_sendbyte (SMAK);
kbd_mousedy = (char)(keyval & 0x40 ? keyval | 0x80 : keyval);
#ifdef CONFIG_KBDMOUSE
if (mousedev >= 0)
busmouse_add_movement(mousedev, (int)kbd_mousedx, (int)kbd_mousedy);
#endif
}
}
return kbd_state == KBD_IDLE ? 1 : 0;
kbd_wontreset:
#ifdef KBD_REPORT_ERR
printk ("kbd: keyboard won't reset (kbdstate %d, keyval %02X)\n",
kbd_state, keyval);
#endif
mdelay(1);
inb(IOC_KARTRX);
a5kkbd_sendbyte (HRST);
kbd_state = KBD_INITRST;
return 0;
kbd_error:
#ifdef KBD_REPORT_ERR
printk ("kbd: keyboard out of sync - resetting\n");
#endif
a5kkbd_sendbyte (HRST);
kbd_state = KBD_INITRST;
return 0;
}
static void a5kkbd_rx(int irq, void *dev_id, struct pt_regs *regs)
{
kbd_pt_regs = regs;
if (handle_rawcode(inb(IOC_KARTRX)))
mark_bh (KEYBOARD_BH);
}
static void a5kkbd_tx(int irq, void *dev_id, struct pt_regs *regs)
{
outb (kbd_txval[kbd_txtail], IOC_KARTTX);
KBD_INCTXPTR(kbd_txtail);
if (kbd_txtail == kbd_txhead)
disable_irq(irq);
}
#ifdef CONFIG_KBDMOUSE
static struct busmouse a5kkbd_mouse = {
6, "kbdmouse", NULL, NULL, 7
};
#endif
void __init a5kkbd_init_hw (void)
{
unsigned long flags;
save_flags_cli (flags);
if (request_irq (IRQ_KEYBOARDTX, a5kkbd_tx, 0, "keyboard", NULL) != 0)
panic("Could not allocate keyboard transmit IRQ!");
disable_irq (IRQ_KEYBOARDTX);
if (request_irq (IRQ_KEYBOARDRX, a5kkbd_rx, 0, "keyboard", NULL) != 0)
panic("Could not allocate keyboard receive IRQ!");
(void)inb(IOC_KARTRX);
restore_flags (flags);
a5kkbd_sendbyte (HRST); /* send HRST (expect HRST) */
/* wait 1s for keyboard to initialise */
interruptible_sleep_on_timeout(&kbd_waitq, HZ);
#ifdef CONFIG_KBDMOUSE
mousedev = register_busmouse(&a5kkbd_mouse);
if (mousedev < 0)
printk(KERN_ERR "Unable to register mouse driver\n");
#endif
printk (KERN_INFO "Keyboard driver v%d.%02d. (", VERSION/100, VERSION%100);
if (kbd_id != -1)
printk ("id=%d ", kbd_id);
printk ("English)\n");
}
--- NEW FILE: cerf_keyb.c ---
/*
cerf_keyb.c: This is the end. Daniel is writing a device driver!!!
*/
#include <linux/config.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <linux/signal.h>
#include <linux/init.h>
#include <linux/kbd_ll.h>
#include <linux/delay.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/kbd_kern.h>
#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <asm/keyboard.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/io.h>
#define KBD_REPORT_UNKN
#define KBD_REPORT_ERR /* Report keyboard errors */
#define KBD_REPORT_UNKN /* Report unknown scan codes */
#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
#define KBD_NO_DATA (-1) /* No data */
#define KBD_REPEAT_START (0x20)
#define KBD_REPEAT_CONTINUE (0x05)
#define KBD_KEY_DOWN_MAX (0x10)
#define UINT_LEN (20)
#define SC_LIM (69)
#define KBD_ROWS (5)
#define KBD_COLUMNS (8)
#define KBD_KEYUP (0x80)
#define KBD_MODESCAN (0x7f)
#define KBD_CAPSSCAN (0x3a)
#define KBD_SHIFTSCAN (0x2a)
#define KBD_NUMCURSCAN (0x7c)
#define KBD_CTRLSCAN (0x1d)
#define KBD_ALTSCAN (0x38)
#define KBD_UP_OFF (0)
#define KBD_UP_ON (1)
#define KBD_DOWN (2)
#define KBD_DOWN_HOLD (3)
static unsigned char handle_kbd_event(void);
static unsigned char kbd_read_input(void);
static void column_set(unsigned int column);
static int scancodes(unsigned char codeval[KBD_ROWS][KBD_COLUMNS]);
static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
static struct timer_list kbd_timer;
static short mode_ena = 0;
static short numcur_ena = 0;
static short shift_ena = 0;
#define E0_KPENTER 96
#define E0_RCTRL 97
#define E0_KPSLASH 98
#define E0_PRSCR 99
#define E0_RALT 100
#define E0_BREAK 101 /* (control-pause) */
#define E0_HOME 102
#define E0_UP 103
#define E0_PGUP 104
#define E0_LEFT 105
#define E0_RIGHT 106
#define E0_END 107
#define E0_DOWN 108
#define E0_PGDN 109
#define E0_INS 110
#define E0_DEL 111
#define E1_PAUSE 119
#define E0_MACRO 112
#define E0_F13 113
#define E0_F14 114
#define E0_HELP 115
#define E0_DO 116
#define E0_F17 117
#define E0_KPMINPLUS 118
#define E0_OK 124
#define E0_MSLW 125
#define E0_MSRW 126
#define E0_MSTM 127
static unsigned char e0_keys[128] = {
0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
};
static unsigned char cerf_normal_map[KBD_ROWS][KBD_COLUMNS] = {
{KBD_ALTSCAN, KBD_MODESCAN, 0x1e, 0x30, 0x2e, 0x20, 0x00, 0x00},
{0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x00},
{0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x00},
{0x1f, 0x14, 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x00},
{0x2c, KBD_SHIFTSCAN, KBD_CTRLSCAN, 0x39, KBD_NUMCURSCAN, 0x2b, 0x1c, 0x00}
};
static unsigned char cerf_mode_map[KBD_ROWS][KBD_COLUMNS] = {
{0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00},
{0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x00}, //
{0x0d, 0x0c, 0x37, 0x35, 0x0d, 0x48, 0x28, 0x00},
{0x01, 0x33, 0x34, 0x00, 0x4b, 0x27, 0x4d, 0x00}, //
{0x0f, 0x00, KBD_CAPSSCAN, 0x0e, 0x00, 0x50, 0x00, 0x00}
};
static unsigned char cerf_numcur_map[KBD_ROWS][KBD_COLUMNS] = {
{0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00},
{0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x00},
{0x0d, 0x0c, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x4d, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00}
};
static void column_set(unsigned int column)
{
if (column < 0)
{
CERF_PDA_CPLD_UnSet(CERF_PDA_CPLD_KEYPAD_A, 0xFF, 0xFF);
CERF_PDA_CPLD_UnSet(CERF_PDA_CPLD_KEYPAD_B, 0xFF, 0xFF);
}
else
{
if(column < 4)
{
CERF_PDA_CPLD_Set(CERF_PDA_CPLD_KEYPAD_A, 1 << (column % 4), 0xFF);
CERF_PDA_CPLD_UnSet(CERF_PDA_CPLD_KEYPAD_B, 0xFF, 0xFF);
}
else
{
CERF_PDA_CPLD_UnSet(CERF_PDA_CPLD_KEYPAD_A, 0xFF, 0xFF);
CERF_PDA_CPLD_Set(CERF_PDA_CPLD_KEYPAD_B, 1 << (column % 4), 0xFF);
}
}
}
static int scancodes(unsigned char codeval[KBD_ROWS][KBD_COLUMNS])
{
int i, j;
for(i = 0; i < KBD_COLUMNS; i++)
{
column_set(i);
udelay(50);
for(j = 0; j < KBD_ROWS; j++)
{
if(mode_ena)
codeval[j][i] = (GPLR & (1 << (20 + j)))?(cerf_mode_map[j][i]?cerf_mode_map[j][i]:cerf_normal_map[j][i]):0;
else if(numcur_ena)
codeval[j][i] = (GPLR & (1 << (20 + j)))?(cerf_numcur_map[j][i]?cerf_numcur_map[j][i]:cerf_normal_map[j][i]):0;
else
codeval[j][i] = (GPLR & (1 << (20 + j)))?cerf_normal_map[j][i]:0;
}
}
column_set(-1);
return 0;
}
static unsigned char kbd_read_input(void)
{
int i, j, k, l;
unsigned char prev;
static unsigned char count = 0;
static unsigned char oldcodes[KBD_ROWS][KBD_COLUMNS]={{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}};
unsigned char inputcode[KBD_ROWS][KBD_COLUMNS];
memset(inputcode, 0, sizeof(unsigned char) * (KBD_ROWS * KBD_COLUMNS));
scancodes(inputcode);
for(i = 0; i < KBD_COLUMNS; i++)
{
for(j = 0; j < KBD_ROWS; j++)
{
// if(oldcodes[j][i] == 0xe0)
// oldcodes[j][i] =
if(oldcodes[j][i] != inputcode[j][i])
{
// Value of the key before entering this function
prev = oldcodes[j][i];
// KEYUP
if(inputcode[j][i] == 0 && oldcodes[j][i] != 0 && !(oldcodes[j][i] & KBD_KEYUP))
{
oldcodes[j][i] |= KBD_KEYUP;
if(mode_ena == KBD_UP_ON)
mode_ena = KBD_UP_OFF;
if(prev == KBD_MODESCAN)
if(mode_ena == KBD_DOWN_HOLD)
mode_ena = KBD_UP_OFF;
else if(mode_ena == KBD_DOWN)
mode_ena = KBD_UP_ON;
if(mode_ena == KBD_DOWN)
mode_ena = KBD_DOWN_HOLD;
}
// RESET KEYUP
else if(oldcodes[j][i] & KBD_KEYUP)
oldcodes[j][i] = 0;
// KEY DOWN
else
{
oldcodes[j][i] = inputcode[j][i];
// Parse out mode modifiers before the keyboard interpreter can touch them
if(inputcode[j][i] == KBD_MODESCAN)
{
if(!mode_ena)
mode_ena = KBD_DOWN;
continue;
}
if(inputcode[j][i] == KBD_NUMCURSCAN)
{
numcur_ena = numcur_ena?0:1;
continue;
}
}
//printk("Modified: (%#x,%#x), ipv:%#x, To: (%#.2x), From: (%#.2x), Flags:%d,%d,%d\r\n", j, i, inputcode[j][i], oldcodes[j][i], prev, mode_ena, shift_ena, numcur_ena);
return oldcodes[j][i];
}
}
}
return (unsigned char)(KBD_NO_DATA);
}
int cerf_kbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode)
{
static int prev_scancode;
if (scancode == 0xe0 || scancode == 0xe1) {
prev_scancode = scancode;
return 0;
}
if (scancode == 0x00 || scancode == 0xff) {
prev_scancode = 0;
return 0;
}
scancode &= 0x7f;
if (prev_scancode) {
if (prev_scancode != 0xe0) {
if (prev_scancode == 0xe1 && scancode == 0x1d) {
prev_scancode = 0x100;
return 0;
} else if (prev_scancode == 0x100 && scancode == 0x45) {
prev_scancode = 0;
} else {
#ifdef KBD_REPORT_UNKN
if (!raw_mode)
printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
#endif
prev_scancode = 0;
return 0;
}
} else {
prev_scancode = 0;
if (scancode == 0x2a || scancode == 0x36)
return 0;
else {
#ifdef KBD_REPORT_UNKN
if (!raw_mode)
printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
scancode);
#endif
return 0;
}
}
} else
*keycode = scancode;
return 1;
}
static inline void handle_keyboard_event(unsigned char scancode)
{
if(scancode != (unsigned char)(KBD_NO_DATA))
{
#ifdef CONFIG_VT
handle_scancode(scancode, !(scancode & KBD_KEYUP));
#endif
tasklet_schedule(&keyboard_tasklet);
}
}
static unsigned char handle_kbd_event(void)
{
unsigned char scancode;
scancode = kbd_read_input();
handle_keyboard_event(scancode);
return 0;
}
/* Handle the automatic interrupts handled by the timer */
static void keyboard_interrupt(unsigned long foo)
{
spin_lock_irq(&kbd_controller_lock);
handle_kbd_event();
spin_unlock_irq(&kbd_controller_lock);
kbd_timer.expires = 8 + jiffies;
kbd_timer.data = 0x00000000;
kbd_timer.function = (void(*)(unsigned long))&keyboard_interrupt;
add_timer(&kbd_timer);
}
void cerf_leds(unsigned char leds)
{
}
char cerf_unexpected_up(unsigned char keycode)
{
return 0;
}
int cerf_getkeycode(unsigned int scancode)
{
return 0;
}
int cerf_setkeycode(unsigned int scancode, unsigned int keycode)
{
return 0;
}
void cerf_kbd_init_hw(void)
{
printk("Starting Cerf PDA Keyboard Driver... ");
k_setkeycode = cerf_setkeycode;
k_getkeycode = cerf_getkeycode;
k_translate = cerf_kbd_translate;
k_unexpected_up = cerf_unexpected_up;
k_leds = cerf_leds;
GPDR &= ~(GPIO_GPIO(20) | GPIO_GPIO(21) | GPIO_GPIO(22) | GPIO_GPIO(23) | GPIO_GPIO(24));
kbd_timer.expires = 40 + jiffies;
kbd_timer.data = 0x00000000;
kbd_timer.function = (void(*)(unsigned long))&keyboard_interrupt;
add_timer(&kbd_timer);
printk("Done\r\n");
}
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:26:40
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/mouse In directory usw-pr-cvs1:/tmp/cvs-serv27479/mouse Removed Files: gunze.c Log Message: Moving files ... --- gunze.c DELETED --- |
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:26:40
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/keyboard
In directory usw-pr-cvs1:/tmp/cvs-serv27479/keyboard
Added Files:
apollokbd.c
Log Message:
Moving files ...
--- NEW FILE: apollokbd.c ---
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/keyboard.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/random.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/apollohw.h>
#include <asm/uaccess.h>
#include "busmouse.h"
/* extern void handle_scancode(unsigned char,int ); */
#define DNKEY_CAPS 0x7e
#define BREAK_FLAG 0x80
#define DNKEY_REPEAT_DELAY 50
#define DNKEY_CTRL 0x43
#define DNKEY_LSHIFT 0x5e
#define DNKEY_RSHIFT 0x6a
#define DNKEY_REPT 0x5d
#define DNKEY_REPEAT 0x7f
#define DNKEY_LALT 0x75
#define DNKEY_RALT 0x77
#define APOLLO_KEYB_CMD_ENTRIES 16
#define APOLLO_KBD_MODE_KEYB 0x01
#define APOLLO_KBD_MODE_MOUSE 0x02
#define APOLLO_KBD_MODE_CHANGE 0xff
static u_char keyb_cmds[APOLLO_KEYB_CMD_ENTRIES];
static short keyb_cmd_read=0, keyb_cmd_write=0;
static int keyb_cmd_transmit=0;
static int msedev;
static unsigned int kbd_mode=APOLLO_KBD_MODE_KEYB;
#if 0
static void debug_keyb_timer_handler(unsigned long ignored);
static u_char debug_buf1[4096],debug_buf2[4096],*debug_buf=&debug_buf1[0];
static u_char *shadow_buf=&debug_buf2[0];
static short debug_buf_count=0;
static int debug_buf_overrun=0,debug_timer_running=0;
static unsigned long debug_buffer_updated=0;
static struct timer_list debug_keyb_timer = { NULL, NULL, 0, 0,
debug_keyb_timer_handler };
#endif
static u_short dnplain_map[NR_KEYS] __initdata = {
/* ins del del F1 F2 F3 F4
mark line char */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
/* F5 F6 F7 F8 F9 F0 Again Read */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
/* Edit Exit Hold Copy Paste Grow ESC */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf01b,
/* 1 2 3 4 5 6 7 8 */
0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 0xf038,
/* 9 0 - = ` Back |<--
Space */
0xf039, 0xf030, 0xf02d, 0xf03d, 0xf060, 0xf07f, 0xf200, 0xf200,
/* Shell -->| Tab q w e
Cmd */
0xf200, 0xf200, 0xf200, 0xf200, 0xf009, 0xfb71, 0xfb77, 0xfb65,
/* r t y u i o p [ */
0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, 0xfb6f, 0xfb70, 0xf05b,
/* ] Del 7 8 9 + */
0xf05d, 0xf200, 0xf200, 0xf200, 0xf307, 0xf308, 0xf300, 0xf30a,
/* [<--] Up [-->] Ctrl a s */
0xf200, 0xf600, 0xf200, 0xf702, 0xf200, 0xf200, 0xfb61, 0xfb73,
/* d f g h j k l ; */
0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
/* ' Return \ 4 5 6 */
0xf027, 0xf200, 0xf201, 0xf05c, 0xf200, 0xf304, 0xf305, 0xf306,
/* - <-- Next --> Rept Shift
Window */
0xf30b, 0xf601, 0xf200, 0xf602, 0xf200, 0xf200, 0xf700, 0xf200,
/* z x c v b n m , */
0xfb7a, 0xfb78, 0xfb63, 0xfb76, 0xfb62, 0xfb6e, 0xfb6d, 0xf02c,
/* . / Shift Pop 1 2 */
0xf02e, 0xf02f, 0xf700, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302,
/* 3 PgUp Down PgDn Alt Space Alt */
0xf303, 0xf200, 0xf118, 0xf603, 0xf119, 0xf703, 0xf020, 0xf701,
/* 0 . Enter */
0xf200, 0xf300, 0xf200, 0xf310, 0xf30e, 0xf200, 0xf700, 0xf200,
};
static u_short dnshift_map[NR_KEYS] __initdata = {
/* ins del del F1 F2 F3 F4
mark line char */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
/* F5 F6 F7 F8 F9 F0 Again Read */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
/* Save Abort Help Cut Undo Grow ESC */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf01b,
/* ! @ # $ % ^ & * */
0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026, 0xf02a,
/* ( ) _ + ~ Back |<--
Space */
0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07e, 0xf07f, 0xf200, 0xf200,
/* Shell -->| Tab Q W E
Cmd */
0xf200, 0xf200, 0xf200, 0xf200, 0xf009, 0xfb51, 0xfb57, 0xfb45,
/* R T Y U I O P { */
0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, 0xfb4f, 0xfb50, 0xf07b,
/* } Del 7 8 9 + */
0xf07d, 0xf200, 0xf200, 0xf200, 0xf307, 0xf308, 0xf300, 0xf30a,
/* [<--] Up [-->] Ctrl A S */
0xf200, 0xf600, 0xf200, 0xf702, 0xf200, 0xf200, 0xfb41, 0xfb53,
/* D F G H J K L : */
0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
/* " Return | 4 5 6 */
0xf022, 0xf200, 0xf201, 0xf07c, 0xf200, 0xf304, 0xf305, 0xf306,
/* - <-- Next --> Rept Shift
Window */
0xf30b, 0xf601, 0xf200, 0xf602, 0xf200, 0xf200, 0xf700, 0xf200,
/* Z X C V B N M < */
0xfb5a, 0xfb58, 0xfb43, 0xfb56, 0xfb42, 0xfb4e, 0xfb4d, 0xf03c,
/* > ? Shift Pop 1 2 */
0xf03e, 0xf03f, 0xf700, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302,
/* 3 PgUp Down PgDn Alt Space Alt */
0xf303, 0xf200, 0xf118, 0xf603, 0xf119, 0xf703, 0xf020, 0xf701,
/* 0 . Enter */
0xf200, 0xf300, 0xf200, 0xf310, 0xf30e, 0xf200, 0xf708, 0xf200,
};
static u_short dnctrl_map[NR_KEYS] __initdata = {
/* ins del del F1 F2 F3 F4
mark line char */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
/* F5 F6 F7 F8 F9 F0 Again Read */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
/* Save Abort Help Cut Undo Grow ESC */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf01b,
/* ! @ # $ % ^ & * */
0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 0xf07f,
/* ( ) _ + ~ Back |<--
Space */
0xf200, 0xf200, 0xf01f, 0xf200, 0xf01c, 0xf200, 0xf200, 0xf200,
/* Shell -->| Tab Q W E
Cmd */
0xf200, 0xf200, 0xf200, 0xf200, 0xf009, 0xf011, 0xf017, 0xf005,
/* R T Y U I O P { */
0xf012, 0xf014, 0xf019, 0xf015, 0xf009, 0xf00f, 0xf010, 0xf01b,
/* } Del 7 8 9 + */
0xf01d, 0xf200, 0xf200, 0xf200, 0xf307, 0xf308, 0xf300, 0xf30a,
/* [<--] Up [-->] Ctrl A S */
0xf200, 0xf600, 0xf200, 0xf702, 0xf200, 0xf200, 0xfb01, 0xfb53,
/* D F G H J K L : */
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
/* " Return | 4 5 6 */
0xf200, 0xf200, 0xf201, 0xf01c, 0xf200, 0xf304, 0xf305, 0xf306,
/* - <-- Next --> Rept Shift
Window */
0xf30b, 0xf601, 0xf200, 0xf602, 0xf200, 0xf200, 0xf704, 0xf200,
/* Z X C V B N M < */
0xf01a, 0xf018, 0xf003, 0xf016, 0xf002, 0xf00e, 0xf01d, 0xf03c,
/* > ? Shift Pop 1 2 */
0xf03e, 0xf03f, 0xf705, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302,
/* 3 PgUp Down PgDn Alt Space Alt */
0xf303, 0xf200, 0xf118, 0xf603, 0xf119, 0xf703, 0xf020, 0xf701,
/* 0 . Enter */
0xf200, 0xf300, 0xf200, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200,
};
static u_short dnalt_map[NR_KEYS] __initdata = {
/* ins del del F1 F2 F3 F4
mark line char */
0xf200, 0xf200, 0xf200, 0xf200, 0xf500, 0xf501, 0xf502, 0xf503,
/* F5 F6 F7 F8 F9 F0 Again Read */
0xf504, 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf200, 0xf200,
/* Edit Exit Hold Copy Paste Grow ESC */
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf01b,
/* 1 2 3 4 5 6 7 8 */
0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, 0xf837, 0xf838,
/* 9 0 - = ` Back |<--
Space */
0xf839, 0xf830, 0xf82d, 0xf83d, 0xf860, 0xf87f, 0xf200, 0xf200,
/* Shell -->| Tab q w e
Cmd */
0xf200, 0xf200, 0xf200, 0xf200, 0xf809, 0xf871, 0xf877, 0xf865,
/* r t y u i o p [ */
0xf872, 0xf874, 0xf879, 0xf875, 0xf869, 0xf86f, 0xf870, 0xf85b,
/* ] Del 7 8 9 + */
0xf05d, 0xf200, 0xf200, 0xf200, 0xf307, 0xf308, 0xf300, 0xf30a,
/* [<--] Up [-->] Ctrl a s */
0xf200, 0xf600, 0xf200, 0xf702, 0xf200, 0xf200, 0xf861, 0xf873,
/* d f g h j k l ; */
0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf03b,
/* ' Return \ 4 5 6 */
0xf027, 0xf200, 0xf201, 0xf05c, 0xf200, 0xf304, 0xf305, 0xf306,
/* - <-- Next --> Rept Shift
Window */
0xf30b, 0xf601, 0xf200, 0xf602, 0xf200, 0xf200, 0xf704, 0xf200,
/* z x c v b n m , */
0xf87a, 0xf878, 0xf863, 0xf876, 0xf862, 0xf86e, 0xf86d, 0xf82c,
/* . / Shift Pop 1 2 */
0xf82e, 0xf82f, 0xf705, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302,
/* 3 PgUp Down PgDn Alt Space Alt */
0xf303, 0xf200, 0xf118, 0xf603, 0xf119, 0xf703, 0xf820, 0xf701,
/* 0 . Enter */
0xf200, 0xf300, 0xf200, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200,
};
static u_short dnaltgr_map[NR_KEYS] __initdata = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
};
static u_short dnshift_ctrl_map[NR_KEYS] __initdata = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
};
static u_short dnctrl_alt_map[NR_KEYS] __initdata = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
};
#if 0
static void debug_keyb_timer_handler(unsigned long ignored) {
unsigned long flags;
u_char *swap;
short length,i;
if (time_after(jiffies, debug_buffer_updated + 100)) {
save_flags(flags);
cli();
length=debug_buf_count;
swap=debug_buf;
debug_buf=shadow_buf;
shadow_buf=swap;
debug_buf_count=0;
debug_timer_running=0;
restore_flags(flags);
for(i=1;length;length--,i++)
printk("%02x%c",*(swap++), (i % 25) ? ' ' : '\n');
printk("\n");
}
else {
debug_keyb_timer.expires=jiffies+10;
add_timer(&debug_keyb_timer);
}
}
#endif
static void dn_keyb_process_key_event(unsigned char scancode) {
static unsigned char lastscancode;
unsigned char prev_scancode=lastscancode;
static unsigned int lastkeypress;
lastscancode=scancode;
/* printk("scan: %02x, lastscan: %02X, prev_scancode: %02X\n",scancode,lastscancode,prev_scancode); */
if(prev_scancode==APOLLO_KBD_MODE_CHANGE) {
kbd_mode=scancode;
/* printk("modechange: %d\n",scancode); */
}
else if((scancode & (~BREAK_FLAG)) == DNKEY_CAPS) {
/* printk("handle_scancode: %02x\n",DNKEY_CAPS); */
handle_scancode(DNKEY_CAPS, 1);
/* printk("handle_scancode: %02x\n",BREAK_FLAG | DNKEY_CAPS); */
handle_scancode(DNKEY_CAPS, 0);
}
else if( (scancode == DNKEY_REPEAT) && (prev_scancode < 0x7e) &&
!(prev_scancode==DNKEY_CTRL || prev_scancode==DNKEY_LSHIFT ||
prev_scancode==DNKEY_RSHIFT || prev_scancode==DNKEY_REPT ||
prev_scancode==DNKEY_LALT || prev_scancode==DNKEY_RALT)) {
if (time_after(jiffies, lastkeypress + DNKEY_REPEAT_DELAY)) {
/* printk("handle_scancode: %02x\n",prev_scancode); */
handle_scancode(prev_scancode, 1);
}
lastscancode=prev_scancode;
}
else {
/* printk("handle_scancode: %02x\n",scancode); */
handle_scancode(scancode & ~BREAK_FLAG, !(scancode & BREAK_FLAG));
lastkeypress=jiffies;
}
}
static void dn_keyb_process_mouse_event(unsigned char mouse_data) {
static short mouse_byte_count=0;
static u_char mouse_packet[3];
short mouse_buttons;
mouse_packet[mouse_byte_count++]=mouse_data;
if(mouse_byte_count==3) {
if(mouse_packet[0]==APOLLO_KBD_MODE_CHANGE) {
kbd_mode=mouse_packet[1];
mouse_byte_count=0;
/* printk("modechange: %d\n",mouse_packet[1]); */
if(kbd_mode==APOLLO_KBD_MODE_KEYB)
dn_keyb_process_key_event(mouse_packet[2]);
}
if((mouse_packet[0] & 0x8f) == 0x80) {
if(mouse_update_allowed) {
mouse_ready=1;
mouse_buttons=(mouse_packet[0] >> 4) & 0x7;
mouse_dx+=mouse_packet[1] == 0xff ? 0 : (signed char)mouse_packet[1];
mouse_dy+=mouse_packet[2] == 0xff ? 0 : (signed char)mouse_packet[2];
wake_up_interruptible(&mouse_wait);
if (mouse_dx < -2048)
mouse_dx = -2048;
else
if (mouse_dx > 2048)
mouse_dx = 2048;
if (mouse_dy < -2048)
mouse_dy = -2048;
else
if (mouse_dy > 2048)
mouse_dy = 2048;
if (mouse_fasyncptr)
kill_fasync(mouse_fasyncptr, SIGIO, POLL_IN);
}
mouse_byte_count=0;
/* printk("mouse: %d, %d, %x\n",mouse_x,mouse_y,buttons); */
}
}
}
static void dn_keyb_int(int irq, void *dummy, struct pt_regs *fp) {
unsigned char data;
unsigned long flags;
int scn2681_ints;
do {
scn2681_ints=sio01.isr_imr & 3;
if(scn2681_ints & 2) {
data=sio01.rhra_thra;
#if 0
if(debug_buf_count<4096) {
debug_buf[debug_buf_count++]=data;
debug_buffer_updated=jiffies;
if(!debug_timer_running) {
debug_keyb_timer.expires=jiffies+10;
add_timer(&debug_keyb_timer);
debug_timer_running=1;
}
}
else
debug_buf_overrun=1;
#endif
if(sio01.sra_csra & 0x10) {
printk("whaa overrun !\n");
continue;
}
if(kbd_mode==APOLLO_KBD_MODE_KEYB)
dn_keyb_process_key_event(data);
else
dn_keyb_process_mouse_event(data);
}
if(scn2681_ints & 1) {
save_flags(flags);
cli();
if(keyb_cmd_write!=keyb_cmd_read) {
sio01.rhra_thra=keyb_cmds[keyb_cmd_read++];
if(keyb_cmd_read==APOLLO_KEYB_CMD_ENTRIES)
keyb_cmd_read=0;
keyb_cmd_transmit=1;
}
else {
keyb_cmd_transmit=0;
sio01.BRGtest_cra=9;
}
restore_flags(flags);
}
} while(scn2681_ints) ;
}
void write_keyb_cmd(u_short length, u_char *cmd) {
unsigned long flags;
if((keyb_cmd_write==keyb_cmd_read) && keyb_cmd_transmit)
return;
save_flags(flags);
cli();
for(;length;length--) {
keyb_cmds[keyb_cmd_write++]=*(cmd++);
if(keyb_cmd_write==keyb_cmd_read)
return;
if(keyb_cmd_write==APOLLO_KEYB_CMD_ENTRIES)
keyb_cmd_write=0;
}
if(!keyb_cmd_transmit) {
sio01.BRGtest_cra=5;
}
restore_flags(flags);
}
static int release_mouse(struct inode * inode, struct file * file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static int open_mouse(struct inode * inode, struct file * file)
{
MOD_INC_USE_COUNT;
return 0;
}
static struct busmouse apollo_mouse = {
APOLLO_MOUSE_MINOR, "apollomouse", open_mouse, release_mouse,7
};
int __init dn_keyb_init(void){
/* printk("dn_keyb_init\n"); */
memcpy(key_maps[0], dnplain_map, sizeof(plain_map));
memcpy(key_maps[1], dnshift_map, sizeof(plain_map));
memcpy(key_maps[2], dnaltgr_map, sizeof(plain_map));
memcpy(key_maps[4], dnctrl_map, sizeof(plain_map));
memcpy(key_maps[5], dnshift_ctrl_map, sizeof(plain_map));
memcpy(key_maps[8], dnalt_map, sizeof(plain_map));
memcpy(key_maps[12], dnctrl_alt_map, sizeof(plain_map));
msedev=register_busmouse(&apollo_mouse);
if (msedev < 0)
printk(KERN_WARNING "Unable to install Apollo mouse driver.\n");
else
printk(KERN_INFO "Apollo mouse installed.\n");
/* program UpDownMode */
while(!(sio01.sra_csra & 0x4));
sio01.rhra_thra=0xff;
while(!(sio01.sra_csra & 0x4));
sio01.rhra_thra=0x1;
request_irq(1, dn_keyb_int,0,NULL,NULL);
/* enable receive int on DUART */
sio01.isr_imr=3;
return 0;
}
int dn_dummy_kbdrate(struct kbd_repeat *k) {
printk("dn_dummy_kbdrate\n");
return 0;
}
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:26:40
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input In directory usw-pr-cvs1:/tmp/cvs-serv27479 Removed Files: amikbd.c apollokbd.c hid-core.c hid-debug.h hid-input.c hid.h hiddev.c ns558.c usbkbd.c usbmouse.c usbpath.h wacom.c Log Message: Moving files ... --- amikbd.c DELETED --- --- apollokbd.c DELETED --- --- hid-core.c DELETED --- --- hid-debug.h DELETED --- --- hid-input.c DELETED --- --- hid.h DELETED --- --- hiddev.c DELETED --- --- ns558.c DELETED --- --- usbkbd.c DELETED --- --- usbmouse.c DELETED --- --- usbpath.h DELETED --- --- wacom.c DELETED --- |
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:24:55
|
Update of /cvsroot/linuxconsole/ruby/utils In directory usw-pr-cvs1:/tmp/cvs-serv26905 Added Files: cvmove Log Message: Tool for moving files in the CVS without losing revision number. --- NEW FILE: cvmove --- #!/bin/bash mv $1 $2 cvs remove $1 cd $2 cvs add $1 cvs commit -r 1.`expr \`grep \\\\$Id: cvmove,v 1.1 2002/01/24 19:24:52 vojtech Exp $1 | sed -e "s/^.*,v 1\.//" | sed -e "s/200.*\\\\$//"\` + 1` -m Moved. $1 |
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:23:24
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/gameport
In directory usw-pr-cvs1:/tmp/cvs-serv26594
Modified Files:
Tag: 1.43
ns558.c
Log Message:
Moved.
--- NEW FILE: ns558.c ---
/*
* $Id: ns558.c,v 1.43 2002/01/24 19:23:21 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
* Copyright (c) 1999 Brian Gerst
*/
/*
* NS558 based standard IBM game port driver for Linux
*/
/*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vo...@uc...>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <asm/io.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/slab.h>
#include <linux/isapnp.h>
MODULE_AUTHOR("Vojtech Pavlik <vo...@uc...>");
MODULE_DESCRIPTION("Classic gameport (ISA/PnP) driver");
MODULE_LICENSE("GPL");
#define NS558_ISA 1
#define NS558_PNP 2
static int ns558_isa_portlist[] = { 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209,
0x20b, 0x20c, 0x20e, 0x20f, 0x211, 0x219, 0x101, 0 };
struct ns558 {
int type;
int size;
struct pci_dev *dev;
struct ns558 *next;
struct gameport gameport;
char phys[32];
char name[32];
};
static struct ns558 *ns558;
/*
* ns558_isa_probe() tries to find an isa gameport at the
* specified address, and also checks for mirrors.
* A joystick must be attached for this to work.
*/
static struct ns558* ns558_isa_probe(int io, struct ns558 *next)
{
int i, j, b;
unsigned char c, u, v;
struct ns558 *port;
/*
* No one should be using this address.
*/
if (check_region(io, 1))
return next;
/*
* We must not be able to write arbitrary values to the port.
* The lower two axis bits must be 1 after a write.
*/
c = inb(io);
outb(~c & ~3, io);
if (~(u = v = inb(io)) & 3) {
outb(c, io);
return next;
}
/*
* After a trigger, there must be at least some bits changing.
*/
for (i = 0; i < 1000; i++) v &= inb(io);
if (u == v) {
outb(c, io);
return next;
}
wait_ms(3);
/*
* After some time (4ms) the axes shouldn't change anymore.
*/
u = inb(io);
for (i = 0; i < 1000; i++)
if ((u ^ inb(io)) & 0xf) {
outb(c, io);
return next;
}
/*
* And now find the number of mirrors of the port.
*/
for (i = 1; i < 5; i++) {
if (check_region(io & (-1 << i), (1 << i))) /* Don't disturb anyone */
break;
outb(0xff, io & (-1 << i));
for (j = b = 0; j < 1000; j++)
if (inb(io & (-1 << i)) != inb((io & (-1 << i)) + (1 << i) - 1)) b++;
wait_ms(3);
if (b > 300) /* We allow 30% difference */
break;
}
i--;
if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) {
printk(KERN_ERR "ns558: Memory allocation failed.\n");
return next;
}
memset(port, 0, sizeof(struct ns558));
port->next = next;
port->type = NS558_ISA;
port->size = (1 << i);
port->gameport.io = io & (-1 << i);
port->gameport.phys = port->phys;
port->gameport.name = port->name;
port->gameport.idbus = BUS_ISA;
sprintf(port->phys, "isa%04x/gameport0", io & (-1 << i));
sprintf(port->name, "NS558 ISA");
request_region(port->gameport.io, (1 << i), "ns558-isa");
gameport_register_port(&port->gameport);
printk(KERN_INFO "gameport: NS558 ISA at %#x", port->gameport.io);
if (port->size > 1) printk(" size %d", port->size);
printk(" speed %d kHz\n", port->gameport.speed);
return port;
}
#ifdef __ISAPNP__
#define NS558_DEVICE(a,b,c,d)\
card_vendor: ISAPNP_ANY_ID, card_device: ISAPNP_ANY_ID,\
vendor: ISAPNP_VENDOR(a,b,c), function: ISAPNP_DEVICE(d)
static struct isapnp_device_id pnp_devids[] = {
{ NS558_DEVICE('@','P','@',0x0001) }, /* ALS 100 */
{ NS558_DEVICE('@','P','@',0x0020) }, /* ALS 200 */
{ NS558_DEVICE('@','P','@',0x1001) }, /* ALS 100+ */
{ NS558_DEVICE('@','P','@',0x2001) }, /* ALS 120 */
{ NS558_DEVICE('A','S','B',0x16fd) }, /* AdLib NSC16 */
{ NS558_DEVICE('A','Z','T',0x3001) }, /* AZT1008 */
{ NS558_DEVICE('C','D','C',0x0001) }, /* Opl3-SAx */
{ NS558_DEVICE('C','S','C',0x0001) }, /* CS4232 */
{ NS558_DEVICE('C','S','C',0x000f) }, /* CS4236 */
{ NS558_DEVICE('C','S','C',0x0101) }, /* CS4327 */
{ NS558_DEVICE('C','T','L',0x7001) }, /* SB16 */
{ NS558_DEVICE('C','T','L',0x7002) }, /* AWE64 */
{ NS558_DEVICE('C','T','L',0x7005) }, /* Vibra16 */
{ NS558_DEVICE('E','N','S',0x2020) }, /* SoundscapeVIVO */
{ NS558_DEVICE('E','S','S',0x0001) }, /* ES1869 */
{ NS558_DEVICE('E','S','S',0x0005) }, /* ES1878 */
{ NS558_DEVICE('E','S','S',0x6880) }, /* ES688 */
{ NS558_DEVICE('I','B','M',0x0012) }, /* CS4232 */
{ NS558_DEVICE('O','P','T',0x0001) }, /* OPTi Audio16 */
{ NS558_DEVICE('Y','M','H',0x0006) }, /* Opl3-SA */
{ NS558_DEVICE('Y','M','H',0x0022) }, /* Opl3-SAx */
{ NS558_DEVICE('P','N','P',0xb02f) }, /* Generic */
{ 0, },
};
MODULE_DEVICE_TABLE(isapnp, pnp_devids);
static struct ns558* ns558_pnp_probe(struct pci_dev *dev, struct ns558 *next)
{
int ioport, iolen;
struct ns558 *port;
if (dev->prepare && dev->prepare(dev) < 0)
return next;
if (!(dev->resource[0].flags & IORESOURCE_IO)) {
printk(KERN_WARNING "ns558: No i/o ports on a gameport? Weird\n");
return next;
}
if (dev->activate && dev->activate(dev) < 0) {
printk(KERN_ERR "ns558: PnP resource allocation failed\n");
return next;
}
ioport = pci_resource_start(dev, 0);
iolen = pci_resource_len(dev, 0);
if (!request_region(ioport, iolen, "ns558-pnp"))
goto deactivate;
if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) {
printk(KERN_ERR "ns558: Memory allocation failed.\n");
goto deactivate;
}
memset(port, 0, sizeof(struct ns558));
port->next = next;
port->type = NS558_PNP;
port->size = iolen;
port->dev = dev;
port->gameport.io = ioport;
port->gameport.phys = port->phys;
port->gameport.name = port->name;
port->gameport.idbus = BUS_ISAPNP;
port->gameport.idvendor = dev->vendor;
port->gameport.idproduct = dev->device;
port->gameport.idversion = 0x100;
sprintf(port->phys, "isapnp%d.%d/gameport0", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
sprintf(port->name, "%s", dev->name[0] ? dev->name : "NS558 PnP Gameport");
gameport_register_port(&port->gameport);
printk(KERN_INFO "gameport: NS558 PnP at isapnp%d.%d io %#x",
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), port->gameport.io);
if (iolen > 1) printk(" size %d", iolen);
printk(" speed %d kHz\n", port->gameport.speed);
return port;
deactivate:
if (dev->deactivate)
dev->deactivate(dev);
return next;
}
#endif
int __init ns558_init(void)
{
int i = 0;
#ifdef __ISAPNP__
struct isapnp_device_id *devid;
struct pci_dev *dev = NULL;
#endif
/*
* Probe for ISA ports.
*/
while (ns558_isa_portlist[i])
ns558 = ns558_isa_probe(ns558_isa_portlist[i++], ns558);
/*
* Probe for PnP ports.
*/
#ifdef __ISAPNP__
for (devid = pnp_devids; devid->vendor; devid++) {
while ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, dev))) {
ns558 = ns558_pnp_probe(dev, ns558);
}
}
#endif
return ns558 ? 0 : -ENODEV;
}
void __exit ns558_exit(void)
{
struct ns558 *next, *port = ns558;
while (port) {
gameport_unregister_port(&port->gameport);
switch (port->type) {
#ifdef __ISAPNP__
case NS558_PNP:
if (port->dev->deactivate)
port->dev->deactivate(port->dev);
/* fall through */
#endif
case NS558_ISA:
release_region(port->gameport.io, port->size);
break;
default:
break;
}
next = port->next;
kfree(port);
port = next;
}
}
module_init(ns558_init);
module_exit(ns558_exit);
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:22:49
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/keyboard
In directory usw-pr-cvs1:/tmp/cvs-serv26415
Added Files:
Tag: 1.10
amikbd.c
Log Message:
Moved.
--- NEW FILE: amikbd.c ---
/*
* $Id: amikbd.c,v 1.10 2002/01/24 19:22:46 vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* Based on the work of:
* Hamish Macdonald
*/
/*
* Amiga keyboard driver for Linux/m68k
*/
/*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vo...@uc...>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>
#include <asm/irq.h>
MODULE_AUTHOR("Vojtech Pavlik <vo...@uc...>");
MODULE_DESCRIPTION("Amiga keyboard driver");
MODULE_LICENSE("GPL");
static unsigned char amikbd_keycode[0x78] = {
0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 43, 0, 82,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 79, 80, 81,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 0, 0, 75, 76, 77,
0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 0, 83, 71, 72, 73,
57, 14, 15, 96, 28, 1,111, 0, 0, 0, 74, 0,103,108,106,105,
59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 98, 55, 78, 87,
42, 54, 58, 29, 56,100
}
static char *amikbd_messages[] = {
KERN_ALERT "amikbd: Ctrl-Amiga-Amiga reset warning!!\n",
KERN_WARNING "amikbd: keyboard lost sync\n",
KERN_WARNING "amikbd: keyboard buffer overflow\n",
KERN_WARNING "amikbd: keyboard controller failure\n",
KERN_ERR "amikbd: keyboard selftest failure\n",
KERN_INFO "amikbd: initiate power-up key stream\n",
KERN_INFO "amikbd: terminate power-up key stream\n",
KERN_WARNING "amikbd: keyboard interrupt\n"
};
static struct input_dev amikbd_dev;
static char *amikbd_name = "Amiga keyboard";
static char *amikbd_phys = "amikbd/input0";
static void amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
unsigned char scancode, down;
scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */
ciaa.cra |= 0x40; /* switch SP pin to output for handshake */
udelay(85); /* wait until 85 us have expired */
ciaa.cra &= ~0x40; /* switch CIA serial port to input mode */
scancode = scancode >> 1; /* lowest bit is release bit */
down = scancode & 1;
if (scancode < 0x78) { /* scancodes < 0x78 are keys */
scancode = amikbd_keycode[scancode];
if (scancode == KEY_CAPS) { /* CapsLock is a toggle switch key on Amiga */
input_report_key(&amikbd_dev, scancode, 1);
input_report_key(&amikbd_dev, scancode, 0);
return;
}
input_report_key(&amikbd_dev, scancode, down);
return;
}
printk(amikbd_messages[scancode]); /* scancodes >= 0x78 are error codes */
}
static int __init amikbd_init(void)
{
int i;
if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
return -EIO;
amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
amikbd_dev.keycode = amikbd_keycode;
for (i = 0; i < 0x78; i++)
if (amikbd_keycode[i])
set_bit(amikbd_keycode[i], amikbd_dev.keybit);
ciaa.cra &= ~0x41; /* serial data in, turn off TA */
request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", NULL);
amikbd_dev.name = amikbd_name;
amikbd_dev.phys = amikbd_phys;
amikbd_dev.idbus = BUS_AMIGA;
amikbd_dev.idvendor = 0x0001;
amikbd_dev.idproduct = 0x0001;
amikbd_dev.idversion = 0x0100;
input_register_device(&amikbd_dev);
printk(KERN_INFO "input: %s\n", amikbd_name);
return 0;
}
static void __exit amikbd_exit(void)
{
input_unregister_device(&amikbd_dev);
free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt);
}
module_init(amikbd_init);
module_exit(amikbd_exit);
|
|
From: Vojtech P. <vo...@us...> - 2002-01-24 19:21:37
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/input/touchscreen
In directory usw-pr-cvs1:/tmp/cvs-serv26099
Added Files:
Tag: 1.14
gunze.c
Log Message:
Moved.
--- NEW FILE: gunze.c ---
/*
* $Id: gunze.c,v 1.14 2002/01/24 19:21:32 vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik
*/
/*
* Gunze AHL-51S touchscreen driver for Linux
*/
/*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vo...@uc...>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>
MODULE_AUTHOR("Vojtech Pavlik <vo...@uc...>");
MODULE_DESCRIPTION("Gunze AHL-51S touchscreen driver");
MODULE_LICENSE("GPL");
/*
* Definitions & global arrays.
*/
#define GUNZE_MAX_LENGTH 10
static char *gunze_name = "Gunze AHL-51S TouchScreen";
/*
* Per-touchscreen data.
*/
struct gunze {
struct input_dev dev;
struct serio *serio;
int idx;
unsigned char data[GUNZE_MAX_LENGTH];
char phys[32];
};
static void gunze_process_packet(struct gunze* gunze)
{
struct input_dev *dev = &gunze->dev;
if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' ||
(gunze->data[0] != 'T' && gunze->data[0] != 'R')) {
gunze->data[10] = 0;
printk(KERN_WARNING "gunze.c: bad packet: >%s<\n", gunze->data);
return;
}
input_report_abs(dev, ABS_X, simple_strtoul(gunze->data + 1, NULL, 10) * 4);
input_report_abs(dev, ABS_Y, 3072 - simple_strtoul(gunze->data + 6, NULL, 10) * 3);
input_report_key(dev, BTN_TOUCH, gunze->data[0] == 'T');
}
static void gunze_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
{
struct gunze* gunze = serio->private;
if (data == '\r') {
gunze_process_packet(gunze);
gunze->idx = 0;
} else {
if (gunze->idx < GUNZE_MAX_LENGTH)
gunze->data[gunze->idx++] = data;
}
}
/*
* gunze_disconnect() is the opposite of gunze_connect()
*/
static void gunze_disconnect(struct serio *serio)
{
struct gunze* gunze = serio->private;
input_unregister_device(&gunze->dev);
serio_close(serio);
kfree(gunze);
}
/*
* gunze_connect() is the routine that is called when someone adds a
* new serio device. It looks whether it was registered as a Gunze touchscreen
* and if yes, registers it as an input device.
*/
static void gunze_connect(struct serio *serio, struct serio_dev *dev)
{
struct gunze *gunze;
if (serio->type != (SERIO_RS232 | SERIO_GUNZE))
return;
if (!(gunze = kmalloc(sizeof(struct gunze), GFP_KERNEL)))
return;
memset(gunze, 0, sizeof(struct gunze));
gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
gunze->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
gunze->dev.absmin[ABS_X] = 96; gunze->dev.absmin[ABS_Y] = 72;
gunze->dev.absmax[ABS_X] = 4000; gunze->dev.absmax[ABS_Y] = 3000;
gunze->serio = serio;
serio->private = gunze;
sprintf(gunze->phys, "%s/input0", serio->phys);
gunze->dev.private = gunze;
gunze->dev.name = gunze_name;
gunze->dev.phys = gunze->phys;
gunze->dev.idbus = BUS_RS232;
gunze->dev.idvendor = SERIO_GUNZE;
gunze->dev.idproduct = 0x0051;
gunze->dev.idversion = 0x0100;
if (serio_open(serio, dev)) {
kfree(gunze);
return;
}
input_register_device(&gunze->dev);
printk(KERN_INFO "input: %s on %s\n", gunze_name, serio->phys);
}
/*
* The serio device structure.
*/
static struct serio_dev gunze_dev = {
interrupt: gunze_interrupt,
connect: gunze_connect,
disconnect: gunze_disconnect,
};
/*
* The functions for inserting/removing us as a module.
*/
int __init gunze_init(void)
{
serio_register_device(&gunze_dev);
return 0;
}
void __exit gunze_exit(void)
{
serio_unregister_device(&gunze_dev);
}
module_init(gunze_init);
module_exit(gunze_exit);
|
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:04
|
Update of /cvsroot/linuxconsole/ruby/linux/include/asm-sparc64 In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/asm-sparc64 Removed Files: page.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- page.h DELETED --- |
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:04
|
Update of /cvsroot/linuxconsole/ruby/linux/include/asm-sparc In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/asm-sparc Removed Files: page.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- page.h DELETED --- |
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:04
|
Update of /cvsroot/linuxconsole/ruby/linux/include/asm-sh In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/asm-sh Removed Files: page.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- page.h DELETED --- |
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:03
|
Update of /cvsroot/linuxconsole/ruby/linux/include/linux In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/linux Removed Files: kernel.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- kernel.h DELETED --- |
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:03
|
Update of /cvsroot/linuxconsole/ruby/linux/include/asm-ppc In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/asm-ppc Removed Files: page.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- page.h DELETED --- |
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:02
|
Update of /cvsroot/linuxconsole/ruby/linux/include/asm-parisc In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/asm-parisc Removed Files: page.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- page.h DELETED --- |
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:02
|
Update of /cvsroot/linuxconsole/ruby/linux/include/asm-m68k In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/asm-m68k Removed Files: page.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- page.h DELETED --- |
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:02
|
Update of /cvsroot/linuxconsole/ruby/linux/include/asm-ia64 In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/asm-ia64 Removed Files: page.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- page.h DELETED --- |
|
From: James S. <jsi...@us...> - 2002-01-24 18:49:02
|
Update of /cvsroot/linuxconsole/ruby/linux/include/asm-mips In directory usw-pr-cvs1:/tmp/cvs-serv15926/include/asm-mips Removed Files: page.h Log Message: Got ride of the do_BUG thing. Unfortunely the bust_spinlock code is not generic enough. --- page.h DELETED --- |