📄 ati_remote.c
字号:
{ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; unsigned long now = jiffies; int acc; if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) { acc = 1; ati_remote->acc_jiffies = now; } else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125))) acc = accel[0]; else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250))) acc = accel[1]; else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500))) acc = accel[2]; else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000))) acc = accel[3]; else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500))) acc = accel[4]; else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000))) acc = accel[5]; else acc = accel[6]; return acc;}/* * ati_remote_report_input */static void ati_remote_input_report(struct urb *urb){ struct ati_remote *ati_remote = urb->context; unsigned char *data= ati_remote->inbuf; struct input_dev *dev = ati_remote->idev; int index, acc; int remote_num; /* Deal with strange looking inputs */ if ( (urb->actual_length != 4) || (data[0] != 0x14) || ((data[3] & 0x0f) != 0x00) ) { ati_remote_dump(data, urb->actual_length); return; } /* Mask unwanted remote channels. */ /* note: remote_num is 0-based, channel 1 on remote == 0 here */ remote_num = (data[3] >> 4) & 0x0f; if (channel_mask & (1 << (remote_num + 1))) { dbginfo(&ati_remote->interface->dev, "Masked input from channel 0x%02x: data %02x,%02x, mask= 0x%02lx\n", remote_num, data[1], data[2], channel_mask); return; } /* Look up event code index in translation table */ index = ati_remote_event_lookup(remote_num, data[1], data[2]); if (index < 0) { dev_warn(&ati_remote->interface->dev, "Unknown input from channel 0x%02x: data %02x,%02x\n", remote_num, data[1], data[2]); return; } dbginfo(&ati_remote->interface->dev, "channel 0x%02x; data %02x,%02x; index %d; keycode %d\n", remote_num, data[1], data[2], index, ati_remote_tbl[index].code); if (ati_remote_tbl[index].kind == KIND_LITERAL) { input_event(dev, ati_remote_tbl[index].type, ati_remote_tbl[index].code, ati_remote_tbl[index].value); input_sync(dev); ati_remote->old_jiffies = jiffies; return; } if (ati_remote_tbl[index].kind == KIND_FILTERED) { unsigned long now = jiffies; /* Filter duplicate events which happen "too close" together. */ if (ati_remote->old_data[0] == data[1] && ati_remote->old_data[1] == data[2] && time_before(now, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) { ati_remote->repeat_count++; } else { ati_remote->repeat_count = 0; ati_remote->first_jiffies = now; } ati_remote->old_data[0] = data[1]; ati_remote->old_data[1] = data[2]; ati_remote->old_jiffies = now; /* Ensure we skip at least the 4 first duplicate events (generated * by a single keypress), and continue skipping until repeat_delay * msecs have passed */ if (ati_remote->repeat_count > 0 && (ati_remote->repeat_count < 5 || time_before(now, ati_remote->first_jiffies + msecs_to_jiffies(repeat_delay)))) return; input_event(dev, ati_remote_tbl[index].type, ati_remote_tbl[index].code, 1); input_sync(dev); input_event(dev, ati_remote_tbl[index].type, ati_remote_tbl[index].code, 0); input_sync(dev); } else { /* * Other event kinds are from the directional control pad, and have an * acceleration factor applied to them. Without this acceleration, the * control pad is mostly unusable. */ acc = ati_remote_compute_accel(ati_remote); switch (ati_remote_tbl[index].kind) { case KIND_ACCEL: input_event(dev, ati_remote_tbl[index].type, ati_remote_tbl[index].code, ati_remote_tbl[index].value * acc); break; case KIND_LU: input_report_rel(dev, REL_X, -acc); input_report_rel(dev, REL_Y, -acc); break; case KIND_RU: input_report_rel(dev, REL_X, acc); input_report_rel(dev, REL_Y, -acc); break; case KIND_LD: input_report_rel(dev, REL_X, -acc); input_report_rel(dev, REL_Y, acc); break; case KIND_RD: input_report_rel(dev, REL_X, acc); input_report_rel(dev, REL_Y, acc); break; default: dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", ati_remote_tbl[index].kind); } input_sync(dev); ati_remote->old_jiffies = jiffies; ati_remote->old_data[0] = data[1]; ati_remote->old_data[1] = data[2]; }}/* * ati_remote_irq_in */static void ati_remote_irq_in(struct urb *urb){ struct ati_remote *ati_remote = urb->context; int retval; switch (urb->status) { case 0: /* success */ ati_remote_input_report(urb); break; case -ECONNRESET: /* unlink */ case -ENOENT: case -ESHUTDOWN: dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n", __FUNCTION__); return; default: /* error */ dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n", __FUNCTION__, urb->status); } retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n", __FUNCTION__, retval);}/* * ati_remote_alloc_buffers */static int ati_remote_alloc_buffers(struct usb_device *udev, struct ati_remote *ati_remote){ ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC, &ati_remote->inbuf_dma); if (!ati_remote->inbuf) return -1; ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC, &ati_remote->outbuf_dma); if (!ati_remote->outbuf) return -1; ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); if (!ati_remote->irq_urb) return -1; ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!ati_remote->out_urb) return -1; return 0;}/* * ati_remote_free_buffers */static void ati_remote_free_buffers(struct ati_remote *ati_remote){ usb_free_urb(ati_remote->irq_urb); usb_free_urb(ati_remote->out_urb); usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, ati_remote->inbuf, ati_remote->inbuf_dma); usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, ati_remote->outbuf, ati_remote->outbuf_dma);}static void ati_remote_input_init(struct ati_remote *ati_remote){ struct input_dev *idev = ati_remote->idev; int i; idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) if (ati_remote_tbl[i].type == EV_KEY) set_bit(ati_remote_tbl[i].code, idev->keybit); input_set_drvdata(idev, ati_remote); idev->open = ati_remote_open; idev->close = ati_remote_close; idev->name = ati_remote->name; idev->phys = ati_remote->phys; usb_to_input_id(ati_remote->udev, &idev->id); idev->dev.parent = &ati_remote->udev->dev;}static int ati_remote_initialize(struct ati_remote *ati_remote){ struct usb_device *udev = ati_remote->udev; int pipe, maxp; init_waitqueue_head(&ati_remote->wait); /* Set up irq_urb */ pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf, maxp, ati_remote_irq_in, ati_remote, ati_remote->endpoint_in->bInterval); ati_remote->irq_urb->transfer_dma = ati_remote->inbuf_dma; ati_remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* Set up out_urb */ pipe = usb_sndintpipe(udev, ati_remote->endpoint_out->bEndpointAddress); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf, maxp, ati_remote_irq_out, ati_remote, ati_remote->endpoint_out->bInterval); ati_remote->out_urb->transfer_dma = ati_remote->outbuf_dma; ati_remote->out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* send initialization strings */ if ((ati_remote_sendpacket(ati_remote, 0x8004, init1)) || (ati_remote_sendpacket(ati_remote, 0x8007, init2))) { dev_err(&ati_remote->interface->dev, "Initializing ati_remote hardware failed.\n"); return -EIO; } return 0;}/* * ati_remote_probe */static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id){ struct usb_device *udev = interface_to_usbdev(interface); struct usb_host_interface *iface_host = interface->cur_altsetting; struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; struct ati_remote *ati_remote; struct input_dev *input_dev; int err = -ENOMEM; if (iface_host->desc.bNumEndpoints != 2) { err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__); return -ENODEV; } endpoint_in = &iface_host->endpoint[0].desc; endpoint_out = &iface_host->endpoint[1].desc; if (!usb_endpoint_is_int_in(endpoint_in)) { err("%s: Unexpected endpoint_in\n", __FUNCTION__); return -ENODEV; } if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { err("%s: endpoint_in message size==0? \n", __FUNCTION__); return -ENODEV; } ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL); input_dev = input_allocate_device(); if (!ati_remote || !input_dev) goto fail1; /* Allocate URB buffers, URBs */ if (ati_remote_alloc_buffers(udev, ati_remote)) goto fail2; ati_remote->endpoint_in = endpoint_in; ati_remote->endpoint_out = endpoint_out; ati_remote->udev = udev; ati_remote->idev = input_dev; ati_remote->interface = interface; usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); if (udev->manufacturer) strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); if (udev->product) snprintf(ati_remote->name, sizeof(ati_remote->name), "%s %s", ati_remote->name, udev->product); if (!strlen(ati_remote->name)) snprintf(ati_remote->name, sizeof(ati_remote->name), DRIVER_DESC "(%04x,%04x)", le16_to_cpu(ati_remote->udev->descriptor.idVendor), le16_to_cpu(ati_remote->udev->descriptor.idProduct)); ati_remote_input_init(ati_remote); /* Device Hardware Initialization - fills in ati_remote->idev from udev. */ err = ati_remote_initialize(ati_remote); if (err) goto fail3; /* Set up and register input device */ err = input_register_device(ati_remote->idev); if (err) goto fail3; usb_set_intfdata(interface, ati_remote); return 0; fail3: usb_kill_urb(ati_remote->irq_urb); usb_kill_urb(ati_remote->out_urb); fail2: ati_remote_free_buffers(ati_remote); fail1: input_free_device(input_dev); kfree(ati_remote); return err;}/* * ati_remote_disconnect */static void ati_remote_disconnect(struct usb_interface *interface){ struct ati_remote *ati_remote; ati_remote = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); if (!ati_remote) { warn("%s - null device?\n", __FUNCTION__); return; } usb_kill_urb(ati_remote->irq_urb); usb_kill_urb(ati_remote->out_urb); input_unregister_device(ati_remote->idev); ati_remote_free_buffers(ati_remote); kfree(ati_remote);}/* * ati_remote_init */static int __init ati_remote_init(void){ int result; result = usb_register(&ati_remote_driver); if (result) err("usb_register error #%d\n", result); else info("Registered USB driver " DRIVER_DESC " v. " DRIVER_VERSION); return result;}/* * ati_remote_exit */static void __exit ati_remote_exit(void){ usb_deregister(&ati_remote_driver);}/* * module specification */module_init(ati_remote_init);module_exit(ati_remote_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -