0001
0002
0003
0004
0005 #include <linux/module.h>
0006 #include <linux/usb.h>
0007 #include <linux/usb/input.h>
0008 #include <media/rc-core.h>
0009
0010
0011 #define BIT_DURATION 250
0012
0013 struct imon {
0014 struct device *dev;
0015 struct urb *ir_urb;
0016 struct rc_dev *rcdev;
0017 __be64 *ir_buf;
0018 char phys[64];
0019 };
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 static void imon_ir_data(struct imon *imon)
0030 {
0031 struct ir_raw_event rawir = {};
0032 u64 data = be64_to_cpup(imon->ir_buf);
0033 u8 packet_no = data & 0xff;
0034 int offset = 40;
0035 int bit;
0036
0037 if (packet_no == 0xff)
0038 return;
0039
0040 dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf);
0041
0042
0043
0044
0045
0046 data >>= 24;
0047
0048 do {
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 rawir.pulse = !rawir.pulse;
0061 bit = fls64(data & (BIT_ULL(offset) - 1));
0062 if (bit < offset) {
0063 dev_dbg(imon->dev, "%s: %d bits",
0064 rawir.pulse ? "pulse" : "space", offset - bit);
0065 rawir.duration = (offset - bit) * BIT_DURATION;
0066 ir_raw_event_store_with_filter(imon->rcdev, &rawir);
0067
0068 offset = bit;
0069 }
0070
0071 data = ~data;
0072 } while (offset > 0);
0073
0074 if (packet_no == 0x0a && !imon->rcdev->idle) {
0075 ir_raw_event_set_idle(imon->rcdev, true);
0076 ir_raw_event_handle(imon->rcdev);
0077 }
0078 }
0079
0080 static void imon_ir_rx(struct urb *urb)
0081 {
0082 struct imon *imon = urb->context;
0083 int ret;
0084
0085 switch (urb->status) {
0086 case 0:
0087 imon_ir_data(imon);
0088 break;
0089 case -ECONNRESET:
0090 case -ENOENT:
0091 case -ESHUTDOWN:
0092 usb_unlink_urb(urb);
0093 return;
0094 case -EPIPE:
0095 default:
0096 dev_dbg(imon->dev, "error: urb status = %d", urb->status);
0097 break;
0098 }
0099
0100 ret = usb_submit_urb(urb, GFP_ATOMIC);
0101 if (ret && ret != -ENODEV)
0102 dev_warn(imon->dev, "failed to resubmit urb: %d", ret);
0103 }
0104
0105 static int imon_probe(struct usb_interface *intf,
0106 const struct usb_device_id *id)
0107 {
0108 struct usb_endpoint_descriptor *ir_ep = NULL;
0109 struct usb_host_interface *idesc;
0110 struct usb_device *udev;
0111 struct rc_dev *rcdev;
0112 struct imon *imon;
0113 int i, ret;
0114
0115 udev = interface_to_usbdev(intf);
0116 idesc = intf->cur_altsetting;
0117
0118 for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
0119 struct usb_endpoint_descriptor *ep = &idesc->endpoint[i].desc;
0120
0121 if (usb_endpoint_is_int_in(ep)) {
0122 ir_ep = ep;
0123 break;
0124 }
0125 }
0126
0127 if (!ir_ep) {
0128 dev_err(&intf->dev, "IR endpoint missing");
0129 return -ENODEV;
0130 }
0131
0132 imon = devm_kmalloc(&intf->dev, sizeof(*imon), GFP_KERNEL);
0133 if (!imon)
0134 return -ENOMEM;
0135
0136 imon->ir_urb = usb_alloc_urb(0, GFP_KERNEL);
0137 if (!imon->ir_urb)
0138 return -ENOMEM;
0139
0140 imon->ir_buf = kmalloc(sizeof(__be64), GFP_KERNEL);
0141 if (!imon->ir_buf) {
0142 ret = -ENOMEM;
0143 goto free_urb;
0144 }
0145
0146 imon->dev = &intf->dev;
0147 usb_fill_int_urb(imon->ir_urb, udev,
0148 usb_rcvintpipe(udev, ir_ep->bEndpointAddress),
0149 imon->ir_buf, sizeof(__be64),
0150 imon_ir_rx, imon, ir_ep->bInterval);
0151
0152 rcdev = devm_rc_allocate_device(&intf->dev, RC_DRIVER_IR_RAW);
0153 if (!rcdev) {
0154 ret = -ENOMEM;
0155 goto free_urb;
0156 }
0157
0158 usb_make_path(udev, imon->phys, sizeof(imon->phys));
0159
0160 rcdev->device_name = "iMON Station";
0161 rcdev->driver_name = KBUILD_MODNAME;
0162 rcdev->input_phys = imon->phys;
0163 usb_to_input_id(udev, &rcdev->input_id);
0164 rcdev->dev.parent = &intf->dev;
0165 rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
0166 rcdev->map_name = RC_MAP_IMON_RSC;
0167 rcdev->rx_resolution = BIT_DURATION;
0168 rcdev->priv = imon;
0169
0170 ret = devm_rc_register_device(&intf->dev, rcdev);
0171 if (ret)
0172 goto free_urb;
0173
0174 imon->rcdev = rcdev;
0175
0176 ret = usb_submit_urb(imon->ir_urb, GFP_KERNEL);
0177 if (ret)
0178 goto free_urb;
0179
0180 usb_set_intfdata(intf, imon);
0181
0182 return 0;
0183
0184 free_urb:
0185 usb_free_urb(imon->ir_urb);
0186 kfree(imon->ir_buf);
0187 return ret;
0188 }
0189
0190 static void imon_disconnect(struct usb_interface *intf)
0191 {
0192 struct imon *imon = usb_get_intfdata(intf);
0193
0194 usb_kill_urb(imon->ir_urb);
0195 usb_free_urb(imon->ir_urb);
0196 kfree(imon->ir_buf);
0197 }
0198
0199 static const struct usb_device_id imon_table[] = {
0200
0201 { USB_DEVICE(0x04e8, 0xff30) },
0202 {}
0203 };
0204
0205 static struct usb_driver imon_driver = {
0206 .name = KBUILD_MODNAME,
0207 .probe = imon_probe,
0208 .disconnect = imon_disconnect,
0209 .id_table = imon_table
0210 };
0211
0212 module_usb_driver(imon_driver);
0213
0214 MODULE_DESCRIPTION("Early raw iMON IR devices");
0215 MODULE_AUTHOR("Sean Young <sean@mess.org>");
0216 MODULE_LICENSE("GPL");
0217 MODULE_DEVICE_TABLE(usb, imon_table);