/* Callback for data arriving from the PowerMate over the USB interrupt pipe */ static void powermate_irq(struct urb *urb, struct pt_regs *regs) { struct powermate_device *pm = urb->context; int retval; switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } /* handle updates to device state */ input_regs(&pm->input, regs); input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01); input_report_rel(&pm->input, REL_DIAL, pm->data[1]); input_sync(&pm->input); exit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, retval); }
static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs) { char dx, dy; unsigned char buttons; outb(LOGIBM_READ_X_LOW, LOGIBM_CONTROL_PORT); dx = (inb(LOGIBM_DATA_PORT) & 0xf); outb(LOGIBM_READ_X_HIGH, LOGIBM_CONTROL_PORT); dx |= (inb(LOGIBM_DATA_PORT) & 0xf) << 4; outb(LOGIBM_READ_Y_LOW, LOGIBM_CONTROL_PORT); dy = (inb(LOGIBM_DATA_PORT) & 0xf); outb(LOGIBM_READ_Y_HIGH, LOGIBM_CONTROL_PORT); buttons = inb(LOGIBM_DATA_PORT); dy |= (buttons & 0xf) << 4; buttons = ~buttons >> 5; input_regs(logibm_dev, regs); input_report_rel(logibm_dev, REL_X, dx); input_report_rel(logibm_dev, REL_Y, dy); input_report_key(logibm_dev, BTN_RIGHT, buttons & 1); input_report_key(logibm_dev, BTN_MIDDLE, buttons & 2); input_report_key(logibm_dev, BTN_LEFT, buttons & 4); input_sync(logibm_dev); outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT); return IRQ_HANDLED; }
static irqreturn_t 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 */ down = !(scancode & 1); /* lowest bit is release bit */ scancode >>= 1; if (scancode < 0x78) { /* scancodes < 0x78 are keys */ scancode = amikbd_keycode[scancode]; input_regs(amikbd_dev, fp); if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ input_report_key(amikbd_dev, scancode, 1); input_report_key(amikbd_dev, scancode, 0); } else { input_report_key(amikbd_dev, scancode, down); } input_sync(amikbd_dev); } else /* scancodes >= 0x78 are error codes */ printk(amikbd_messages[scancode - 0x78]); return IRQ_HANDLED; }
static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char buttons; outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); input_regs(inport_dev, regs); outb(INPORT_REG_X, INPORT_CONTROL_PORT); input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT)); outb(INPORT_REG_Y, INPORT_CONTROL_PORT); input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT)); outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT); buttons = inb(INPORT_DATA_PORT); input_report_key(inport_dev, BTN_MIDDLE, buttons & 1); input_report_key(inport_dev, BTN_LEFT, buttons & 2); input_report_key(inport_dev, BTN_RIGHT, buttons & 4); outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); input_sync(inport_dev); return IRQ_HANDLED; }
static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { unsigned char *packet = psmouse->packet; struct input_dev *dev = psmouse->dev; if (psmouse->pktcnt != 3) return PSMOUSE_GOOD_DATA; input_regs(dev, regs); /* calculate X and Y */ if ((packet[0] & 0x08) == 0x00) { input_report_abs(dev, ABS_X, (packet[1] | ((packet[0] & 0x30) << 4))); input_report_abs(dev, ABS_Y, 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); } else { input_report_rel(dev, REL_X, ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); input_report_rel(dev, REL_Y, -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); } input_report_key(dev, BTN_LEFT, packet[0] & 0x01); input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); input_report_key(dev, BTN_TOUCH, packet[0] & 0x04); input_sync(dev); return PSMOUSE_FULL_PACKET; }
static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs) { struct input_dev *dev = &psmouse->dev; unsigned char *packet = psmouse->packet; input_regs(dev, regs); /* * The PS2++ protocol is a little bit complex */ if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) ps2pp_process_packet(psmouse); /* * Scroll wheel on IntelliMice, scroll buttons on NetMice */ if (psmouse->type == PSMOUSE_IMPS || psmouse->type == PSMOUSE_GENPS) input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]); /* * Scroll wheel and buttons on IntelliMouse Explorer */ if (psmouse->type == PSMOUSE_IMEX) { input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); }
static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs) { int value = inb_p(pc110pad_io); int handshake = inb_p(pc110pad_io + 2); outb_p(handshake | 1, pc110pad_io + 2); outb_p(handshake & ~1, pc110pad_io + 2); inb_p(0x64); pc110pad_data[pc110pad_count++] = value; if (pc110pad_count < 3) return IRQ_HANDLED; input_regs(pc110pad_dev, regs); input_report_key(pc110pad_dev, BTN_TOUCH, pc110pad_data[0] & 0x01); input_report_abs(pc110pad_dev, ABS_X, pc110pad_data[1] | ((pc110pad_data[0] << 3) & 0x80) | ((pc110pad_data[0] << 1) & 0x100)); input_report_abs(pc110pad_dev, ABS_Y, pc110pad_data[2] | ((pc110pad_data[0] << 4) & 0x80)); input_sync(pc110pad_dev); pc110pad_count = 0; return IRQ_HANDLED; }
static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value) { input_regs(dev, regs); if (value == 3) { input_report_key(dev, code, 1); input_sync(dev); input_report_key(dev, code, 0); } else input_event(dev, EV_KEY, code, value); input_sync(dev); }
void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs) { struct input_dev *dev = &iforce->dev; int i; static int being_used = 0; if (being_used) printk(KERN_WARNING "iforce-packets.c: re-entrant call to iforce_process %d\n", being_used); being_used++; #ifdef CONFIG_JOYSTICK_IFORCE_232 if (HI(iforce->expect_packet) == HI(cmd)) { iforce->expect_packet = 0; iforce->ecmd = cmd; memcpy(iforce->edata, data, IFORCE_MAX_LENGTH); wake_up(&iforce->wait); } #endif if (!iforce->type) { being_used--; return; } switch (HI(cmd)) { case 0x01: /* joystick position data */ case 0x03: /* wheel position data */ input_regs(dev, regs); if (HI(cmd) == 1) { input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0])); input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2])); input_report_abs(dev, ABS_THROTTLE, 255 - data[4]); if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit)) input_report_abs(dev, ABS_RUDDER, (__s8)data[7]); } else { input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0])); input_report_abs(dev, ABS_GAS, 255 - data[2]); input_report_abs(dev, ABS_BRAKE, 255 - data[3]); } input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x); input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y); for (i = 0; iforce->type->btn[i] >= 0; i++) input_report_key(dev, iforce->type->btn[i], data[(i >> 3) + 5] & (1 << (i & 7))); /* If there are untouched bits left, interpret them as the second hat */ if (i <= 8) { int btns = data[6]; if (test_bit(ABS_HAT1X, dev->absbit)) { if (btns & 8) input_report_abs(dev, ABS_HAT1X, -1); else if (btns & 2) input_report_abs(dev, ABS_HAT1X, 1); else input_report_abs(dev, ABS_HAT1X, 0); } if (test_bit(ABS_HAT1Y, dev->absbit)) { if (btns & 1) input_report_abs(dev, ABS_HAT1Y, -1); else if (btns & 4) input_report_abs(dev, ABS_HAT1Y, 1); else input_report_abs(dev, ABS_HAT1Y, 0); } } input_sync(dev); break; case 0x02: /* status report */ input_regs(dev, regs); input_report_key(dev, BTN_DEAD, data[0] & 0x02); input_sync(dev); /* Check if an effect was just started or stopped */ i = data[1] & 0x7f; if (data[1] & 0x80) { if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { /* Report play event */ input_report_ff_status(dev, i, FF_STATUS_PLAYING); } } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { /* Report stop event */ input_report_ff_status(dev, i, FF_STATUS_STOPPED); } if (LO(cmd) > 3) { int j; for (j=3; j<LO(cmd); j+=2) { mark_core_as_ready(iforce, data[j] | (data[j+1]<<8)); } } break; } being_used--; }