0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
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
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
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
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
0297
0298
0299
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
0328
0329
0330
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
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
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
0496
0497
0498
0499
0500
0501
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);