Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 
0003 /*
0004  * Infrared Toy and IR Droid RC core driver
0005  *
0006  * Copyright (C) 2020 Sean Young <sean@mess.org>
0007  *
0008  * http://dangerousprototypes.com/docs/USB_IR_Toy:_Sampling_mode
0009  *
0010  * This driver is based on the lirc driver which can be found here:
0011  * https://sourceforge.net/p/lirc/git/ci/master/tree/plugins/irtoy.c
0012  * Copyright (C) 2011 Peter Kooiman <pkooiman@gmail.com>
0013  */
0014 
0015 #include <asm/unaligned.h>
0016 #include <linux/completion.h>
0017 #include <linux/kernel.h>
0018 #include <linux/module.h>
0019 #include <linux/usb.h>
0020 #include <linux/slab.h>
0021 #include <linux/usb/input.h>
0022 
0023 #include <media/rc-core.h>
0024 
0025 static const u8 COMMAND_VERSION[] = { 'v' };
0026 // End transmit and repeat reset command so we exit sump mode
0027 static const u8 COMMAND_RESET[] = { 0xff, 0xff, 0, 0, 0, 0, 0 };
0028 static const u8 COMMAND_SMODE_ENTER[] = { 's' };
0029 static const u8 COMMAND_SMODE_EXIT[] = { 0 };
0030 static const u8 COMMAND_TXSTART[] = { 0x26, 0x24, 0x25, 0x03 };
0031 
0032 #define REPLY_XMITCOUNT 't'
0033 #define REPLY_XMITSUCCESS 'C'
0034 #define REPLY_VERSION 'V'
0035 #define REPLY_SAMPLEMODEPROTO 'S'
0036 
0037 #define TIMEOUT 500
0038 
0039 #define LEN_XMITRES 3
0040 #define LEN_VERSION 4
0041 #define LEN_SAMPLEMODEPROTO 3
0042 
0043 #define MIN_FW_VERSION 20
0044 #define UNIT_US 21
0045 #define MAX_TIMEOUT_US (UNIT_US * U16_MAX)
0046 
0047 #define MAX_PACKET 64
0048 
0049 enum state {
0050     STATE_IRDATA,
0051     STATE_COMMAND_NO_RESP,
0052     STATE_COMMAND,
0053     STATE_TX,
0054 };
0055 
0056 struct irtoy {
0057     struct device *dev;
0058     struct usb_device *usbdev;
0059 
0060     struct rc_dev *rc;
0061     struct urb *urb_in, *urb_out;
0062 
0063     u8 *in;
0064     u8 *out;
0065     struct completion command_done;
0066 
0067     bool pulse;
0068     enum state state;
0069 
0070     void *tx_buf;
0071     uint tx_len;
0072 
0073     uint emitted;
0074     uint hw_version;
0075     uint sw_version;
0076     uint proto_version;
0077 
0078     char phys[64];
0079 };
0080 
0081 static void irtoy_response(struct irtoy *irtoy, u32 len)
0082 {
0083     switch (irtoy->state) {
0084     case STATE_COMMAND:
0085         if (len == LEN_VERSION && irtoy->in[0] == REPLY_VERSION) {
0086             uint version;
0087 
0088             irtoy->in[LEN_VERSION] = 0;
0089 
0090             if (kstrtouint(irtoy->in + 1, 10, &version)) {
0091                 dev_err(irtoy->dev, "invalid version %*phN. Please make sure you are using firmware v20 or higher",
0092                     LEN_VERSION, irtoy->in);
0093                 break;
0094             }
0095 
0096             dev_dbg(irtoy->dev, "version %s\n", irtoy->in);
0097 
0098             irtoy->hw_version = version / 100;
0099             irtoy->sw_version = version % 100;
0100 
0101             irtoy->state = STATE_IRDATA;
0102             complete(&irtoy->command_done);
0103         } else if (len == LEN_SAMPLEMODEPROTO &&
0104                irtoy->in[0] == REPLY_SAMPLEMODEPROTO) {
0105             uint version;
0106 
0107             irtoy->in[LEN_SAMPLEMODEPROTO] = 0;
0108 
0109             if (kstrtouint(irtoy->in + 1, 10, &version)) {
0110                 dev_err(irtoy->dev, "invalid sample mode response %*phN",
0111                     LEN_SAMPLEMODEPROTO, irtoy->in);
0112                 return;
0113             }
0114 
0115             dev_dbg(irtoy->dev, "protocol %s\n", irtoy->in);
0116 
0117             irtoy->proto_version = version;
0118 
0119             irtoy->state = STATE_IRDATA;
0120             complete(&irtoy->command_done);
0121         } else {
0122             dev_err(irtoy->dev, "unexpected response to command: %*phN\n",
0123                 len, irtoy->in);
0124         }
0125         break;
0126     case STATE_COMMAND_NO_RESP:
0127     case STATE_IRDATA: {
0128         struct ir_raw_event rawir = { .pulse = irtoy->pulse };
0129         __be16 *in = (__be16 *)irtoy->in;
0130         int i;
0131 
0132         for (i = 0; i < len / sizeof(__be16); i++) {
0133             u16 v = be16_to_cpu(in[i]);
0134 
0135             if (v == 0xffff) {
0136                 rawir.pulse = false;
0137             } else {
0138                 rawir.duration = v * UNIT_US;
0139                 ir_raw_event_store_with_timeout(irtoy->rc,
0140                                 &rawir);
0141             }
0142 
0143             rawir.pulse = !rawir.pulse;
0144         }
0145 
0146         irtoy->pulse = rawir.pulse;
0147 
0148         ir_raw_event_handle(irtoy->rc);
0149         break;
0150     }
0151     case STATE_TX:
0152         if (irtoy->tx_len == 0) {
0153             if (len == LEN_XMITRES &&
0154                 irtoy->in[0] == REPLY_XMITCOUNT) {
0155                 u16 emitted = get_unaligned_be16(irtoy->in + 1);
0156 
0157                 dev_dbg(irtoy->dev, "emitted:%u\n", emitted);
0158 
0159                 irtoy->emitted = emitted;
0160             } else if (len == 1 &&
0161                    irtoy->in[0] == REPLY_XMITSUCCESS) {
0162                 irtoy->state = STATE_IRDATA;
0163                 complete(&irtoy->command_done);
0164             }
0165         } else {
0166             // send next part of tx buffer
0167             uint space = irtoy->in[0];
0168             uint buf_len;
0169             int err;
0170 
0171             if (len != 1 || space > MAX_PACKET || space == 0) {
0172                 dev_dbg(irtoy->dev, "packet length expected: %*phN\n",
0173                     len, irtoy->in);
0174                 break;
0175             }
0176 
0177             buf_len = min(space, irtoy->tx_len);
0178 
0179             dev_dbg(irtoy->dev, "remaining:%u sending:%u\n",
0180                 irtoy->tx_len, buf_len);
0181 
0182             memcpy(irtoy->out, irtoy->tx_buf, buf_len);
0183             irtoy->urb_out->transfer_buffer_length = buf_len;
0184             err = usb_submit_urb(irtoy->urb_out, GFP_ATOMIC);
0185             if (err != 0) {
0186                 dev_err(irtoy->dev, "fail to submit tx buf urb: %d\n",
0187                     err);
0188                 irtoy->state = STATE_IRDATA;
0189                 complete(&irtoy->command_done);
0190                 break;
0191             }
0192 
0193             irtoy->tx_buf += buf_len;
0194             irtoy->tx_len -= buf_len;
0195         }
0196         break;
0197     }
0198 }
0199 
0200 static void irtoy_out_callback(struct urb *urb)
0201 {
0202     struct irtoy *irtoy = urb->context;
0203 
0204     if (urb->status == 0) {
0205         if (irtoy->state == STATE_COMMAND_NO_RESP)
0206             complete(&irtoy->command_done);
0207     } else {
0208         dev_warn(irtoy->dev, "out urb status: %d\n", urb->status);
0209     }
0210 }
0211 
0212 static void irtoy_in_callback(struct urb *urb)
0213 {
0214     struct irtoy *irtoy = urb->context;
0215     int ret;
0216 
0217     switch (urb->status) {
0218     case 0:
0219         irtoy_response(irtoy, urb->actual_length);
0220         break;
0221     case -ECONNRESET:
0222     case -ENOENT:
0223     case -ESHUTDOWN:
0224     case -EPROTO:
0225     case -EPIPE:
0226         usb_unlink_urb(urb);
0227         return;
0228     default:
0229         dev_dbg(irtoy->dev, "in urb status: %d\n", urb->status);
0230     }
0231 
0232     ret = usb_submit_urb(urb, GFP_ATOMIC);
0233     if (ret && ret != -ENODEV)
0234         dev_warn(irtoy->dev, "failed to resubmit urb: %d\n", ret);
0235 }
0236 
0237 static int irtoy_command(struct irtoy *irtoy, const u8 *cmd, int cmd_len,
0238              enum state state)
0239 {
0240     int err;
0241 
0242     init_completion(&irtoy->command_done);
0243 
0244     irtoy->state = state;
0245 
0246     memcpy(irtoy->out, cmd, cmd_len);
0247     irtoy->urb_out->transfer_buffer_length = cmd_len;
0248 
0249     err = usb_submit_urb(irtoy->urb_out, GFP_KERNEL);
0250     if (err != 0)
0251         return err;
0252 
0253     if (!wait_for_completion_timeout(&irtoy->command_done,
0254                      msecs_to_jiffies(TIMEOUT))) {
0255         usb_kill_urb(irtoy->urb_out);
0256         return -ETIMEDOUT;
0257     }
0258 
0259     return 0;
0260 }
0261 
0262 static int irtoy_setup(struct irtoy *irtoy)
0263 {
0264     int err;
0265 
0266     err = irtoy_command(irtoy, COMMAND_RESET, sizeof(COMMAND_RESET),
0267                 STATE_COMMAND_NO_RESP);
0268     if (err != 0) {
0269         dev_err(irtoy->dev, "could not write reset command: %d\n",
0270             err);
0271         return err;
0272     }
0273 
0274     usleep_range(50, 50);
0275 
0276     // get version
0277     err = irtoy_command(irtoy, COMMAND_VERSION, sizeof(COMMAND_VERSION),
0278                 STATE_COMMAND);
0279     if (err) {
0280         dev_err(irtoy->dev, "could not write version command: %d\n",
0281             err);
0282         return err;
0283     }
0284 
0285     // enter sample mode
0286     err = irtoy_command(irtoy, COMMAND_SMODE_ENTER,
0287                 sizeof(COMMAND_SMODE_ENTER), STATE_COMMAND);
0288     if (err)
0289         dev_err(irtoy->dev, "could not write sample command: %d\n",
0290             err);
0291 
0292     return err;
0293 }
0294 
0295 /*
0296  * When sending IR, it is imperative that we send the IR data as quickly
0297  * as possible to the device, so it does not run out of IR data and
0298  * introduce gaps. Allocate the buffer here, and then feed the data from
0299  * the urb callback handler.
0300  */
0301 static int irtoy_tx(struct rc_dev *rc, uint *txbuf, uint count)
0302 {
0303     struct irtoy *irtoy = rc->priv;
0304     unsigned int i, size;
0305     __be16 *buf;
0306     int err;
0307 
0308     size = sizeof(u16) * (count + 1);
0309     buf = kmalloc(size, GFP_KERNEL);
0310     if (!buf)
0311         return -ENOMEM;
0312 
0313     for (i = 0; i < count; i++) {
0314         u16 v = DIV_ROUND_CLOSEST(txbuf[i], UNIT_US);
0315 
0316         if (!v)
0317             v = 1;
0318         buf[i] = cpu_to_be16(v);
0319     }
0320 
0321     buf[count] = cpu_to_be16(0xffff);
0322 
0323     irtoy->tx_buf = buf;
0324     irtoy->tx_len = size;
0325     irtoy->emitted = 0;
0326 
0327     // There is an issue where if the unit is receiving IR while the
0328     // first TXSTART command is sent, the device might end up hanging
0329     // with its led on. It does not respond to any command when this
0330     // happens. To work around this, re-enter sample mode.
0331     err = irtoy_command(irtoy, COMMAND_SMODE_EXIT,
0332                 sizeof(COMMAND_SMODE_EXIT), STATE_COMMAND_NO_RESP);
0333     if (err) {
0334         dev_err(irtoy->dev, "exit sample mode: %d\n", err);
0335         return err;
0336     }
0337 
0338     err = irtoy_command(irtoy, COMMAND_SMODE_ENTER,
0339                 sizeof(COMMAND_SMODE_ENTER), STATE_COMMAND);
0340     if (err) {
0341         dev_err(irtoy->dev, "enter sample mode: %d\n", err);
0342         return err;
0343     }
0344 
0345     err = irtoy_command(irtoy, COMMAND_TXSTART, sizeof(COMMAND_TXSTART),
0346                 STATE_TX);
0347     kfree(buf);
0348 
0349     if (err) {
0350         dev_err(irtoy->dev, "failed to send tx start command: %d\n",
0351             err);
0352         // not sure what state the device is in, reset it
0353         irtoy_setup(irtoy);
0354         return err;
0355     }
0356 
0357     if (size != irtoy->emitted) {
0358         dev_err(irtoy->dev, "expected %u emitted, got %u\n", size,
0359             irtoy->emitted);
0360         // not sure what state the device is in, reset it
0361         irtoy_setup(irtoy);
0362         return -EINVAL;
0363     }
0364 
0365     return count;
0366 }
0367 
0368 static int irtoy_tx_carrier(struct rc_dev *rc, uint32_t carrier)
0369 {
0370     struct irtoy *irtoy = rc->priv;
0371     u8 buf[3];
0372     int err;
0373 
0374     if (carrier < 11800)
0375         return -EINVAL;
0376 
0377     buf[0] = 0x06;
0378     buf[1] = DIV_ROUND_CLOSEST(48000000, 16 * carrier) - 1;
0379     buf[2] = 0;
0380 
0381     err = irtoy_command(irtoy, buf, sizeof(buf), STATE_COMMAND_NO_RESP);
0382     if (err)
0383         dev_err(irtoy->dev, "could not write carrier command: %d\n",
0384             err);
0385 
0386     return err;
0387 }
0388 
0389 static int irtoy_probe(struct usb_interface *intf,
0390                const struct usb_device_id *id)
0391 {
0392     struct usb_host_interface *idesc = intf->cur_altsetting;
0393     struct usb_device *usbdev = interface_to_usbdev(intf);
0394     struct usb_endpoint_descriptor *ep_in = NULL;
0395     struct usb_endpoint_descriptor *ep_out = NULL;
0396     struct usb_endpoint_descriptor *ep = NULL;
0397     struct irtoy *irtoy;
0398     struct rc_dev *rc;
0399     struct urb *urb;
0400     int i, pipe, err = -ENOMEM;
0401 
0402     for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
0403         ep = &idesc->endpoint[i].desc;
0404 
0405         if (!ep_in && usb_endpoint_is_bulk_in(ep) &&
0406             usb_endpoint_maxp(ep) == MAX_PACKET)
0407             ep_in = ep;
0408 
0409         if (!ep_out && usb_endpoint_is_bulk_out(ep) &&
0410             usb_endpoint_maxp(ep) == MAX_PACKET)
0411             ep_out = ep;
0412     }
0413 
0414     if (!ep_in || !ep_out) {
0415         dev_err(&intf->dev, "required endpoints not found\n");
0416         return -ENODEV;
0417     }
0418 
0419     irtoy = kzalloc(sizeof(*irtoy), GFP_KERNEL);
0420     if (!irtoy)
0421         return -ENOMEM;
0422 
0423     irtoy->in = kmalloc(MAX_PACKET,  GFP_KERNEL);
0424     if (!irtoy->in)
0425         goto free_irtoy;
0426 
0427     irtoy->out = kmalloc(MAX_PACKET,  GFP_KERNEL);
0428     if (!irtoy->out)
0429         goto free_irtoy;
0430 
0431     rc = rc_allocate_device(RC_DRIVER_IR_RAW);
0432     if (!rc)
0433         goto free_irtoy;
0434 
0435     urb = usb_alloc_urb(0, GFP_KERNEL);
0436     if (!urb)
0437         goto free_rcdev;
0438 
0439     pipe = usb_rcvbulkpipe(usbdev, ep_in->bEndpointAddress);
0440     usb_fill_bulk_urb(urb, usbdev, pipe, irtoy->in, MAX_PACKET,
0441               irtoy_in_callback, irtoy);
0442     irtoy->urb_in = urb;
0443 
0444     urb = usb_alloc_urb(0, GFP_KERNEL);
0445     if (!urb)
0446         goto free_rcdev;
0447 
0448     pipe = usb_sndbulkpipe(usbdev, ep_out->bEndpointAddress);
0449     usb_fill_bulk_urb(urb, usbdev, pipe, irtoy->out, MAX_PACKET,
0450               irtoy_out_callback, irtoy);
0451 
0452     irtoy->dev = &intf->dev;
0453     irtoy->usbdev = usbdev;
0454     irtoy->rc = rc;
0455     irtoy->urb_out = urb;
0456     irtoy->pulse = true;
0457 
0458     err = usb_submit_urb(irtoy->urb_in, GFP_KERNEL);
0459     if (err != 0) {
0460         dev_err(irtoy->dev, "fail to submit in urb: %d\n", err);
0461         goto free_rcdev;
0462     }
0463 
0464     err = irtoy_setup(irtoy);
0465     if (err)
0466         goto free_rcdev;
0467 
0468     dev_info(irtoy->dev, "version: hardware %u, firmware %u.%u, protocol %u",
0469          irtoy->hw_version, irtoy->sw_version / 10,
0470          irtoy->sw_version % 10, irtoy->proto_version);
0471 
0472     if (irtoy->sw_version < MIN_FW_VERSION) {
0473         dev_err(irtoy->dev, "need firmware V%02u or higher",
0474             MIN_FW_VERSION);
0475         err = -ENODEV;
0476         goto free_rcdev;
0477     }
0478 
0479     usb_make_path(usbdev, irtoy->phys, sizeof(irtoy->phys));
0480 
0481     rc->device_name = "Infrared Toy";
0482     rc->driver_name = KBUILD_MODNAME;
0483     rc->input_phys = irtoy->phys;
0484     usb_to_input_id(usbdev, &rc->input_id);
0485     rc->dev.parent = &intf->dev;
0486     rc->priv = irtoy;
0487     rc->tx_ir = irtoy_tx;
0488     rc->s_tx_carrier = irtoy_tx_carrier;
0489     rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
0490     rc->map_name = RC_MAP_RC6_MCE;
0491     rc->rx_resolution = UNIT_US;
0492     rc->timeout = IR_DEFAULT_TIMEOUT;
0493 
0494     /*
0495      * end of transmission is detected by absence of a usb packet
0496      * with more pulse/spaces. However, each usb packet sent can
0497      * contain 32 pulse/spaces, which can be quite lengthy, so there
0498      * can be a delay between usb packets. For example with nec there is a
0499      * 17ms gap between packets.
0500      *
0501      * So, make timeout a largish minimum which works with most protocols.
0502      */
0503     rc->min_timeout = MS_TO_US(40);
0504     rc->max_timeout = MAX_TIMEOUT_US;
0505 
0506     err = rc_register_device(rc);
0507     if (err)
0508         goto free_rcdev;
0509 
0510     usb_set_intfdata(intf, irtoy);
0511 
0512     return 0;
0513 
0514 free_rcdev:
0515     usb_kill_urb(irtoy->urb_out);
0516     usb_free_urb(irtoy->urb_out);
0517     usb_kill_urb(irtoy->urb_in);
0518     usb_free_urb(irtoy->urb_in);
0519     rc_free_device(rc);
0520 free_irtoy:
0521     kfree(irtoy->in);
0522     kfree(irtoy->out);
0523     kfree(irtoy);
0524     return err;
0525 }
0526 
0527 static void irtoy_disconnect(struct usb_interface *intf)
0528 {
0529     struct irtoy *ir = usb_get_intfdata(intf);
0530 
0531     rc_unregister_device(ir->rc);
0532     usb_set_intfdata(intf, NULL);
0533     usb_kill_urb(ir->urb_out);
0534     usb_free_urb(ir->urb_out);
0535     usb_kill_urb(ir->urb_in);
0536     usb_free_urb(ir->urb_in);
0537     kfree(ir->in);
0538     kfree(ir->out);
0539     kfree(ir);
0540 }
0541 
0542 static const struct usb_device_id irtoy_table[] = {
0543     { USB_DEVICE_INTERFACE_CLASS(0x04d8, 0xfd08, USB_CLASS_CDC_DATA) },
0544     { USB_DEVICE_INTERFACE_CLASS(0x04d8, 0xf58b, USB_CLASS_CDC_DATA) },
0545     { }
0546 };
0547 
0548 static struct usb_driver irtoy_driver = {
0549     .name = KBUILD_MODNAME,
0550     .probe = irtoy_probe,
0551     .disconnect = irtoy_disconnect,
0552     .id_table = irtoy_table,
0553 };
0554 
0555 module_usb_driver(irtoy_driver);
0556 
0557 MODULE_AUTHOR("Sean Young <sean@mess.org>");
0558 MODULE_DESCRIPTION("Infrared Toy and IR Droid driver");
0559 MODULE_LICENSE("GPL");
0560 MODULE_DEVICE_TABLE(usb, irtoy_table);