21 #include <linux/device.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
26 #include <linux/slab.h>
30 #define DRIVER_NAME "iguanair"
61 #define CMD_GET_VERSION 0x01
62 #define CMD_GET_BUFSIZE 0x11
63 #define CMD_GET_FEATURES 0x10
65 #define CMD_EXECUTE 0x1f
66 #define CMD_RX_OVERFLOW 0x31
67 #define CMD_TX_OVERFLOW 0x32
68 #define CMD_RECEIVER_ON 0x12
69 #define CMD_RECEIVER_OFF 0x14
74 #define MAX_IN_PACKET 8u
75 #define MAX_OUT_PACKET (sizeof(struct send_packet) + BUF_SIZE)
77 #define RX_RESOLUTION 21333
94 static void process_ir_data(
struct iguanair *
ir,
unsigned len)
96 if (len >= 4 && ir->
buf_in[0] == 0 && ir->
buf_in[1] == 0) {
126 ir_raw_event_reset(ir->
rc);
133 }
else if (len >= 7) {
138 init_ir_raw_event(&rawir);
140 for (i = 0; i < 7; i++) {
141 if (ir->
buf_in[i] == 0x80) {
145 rawir.pulse = (ir->
buf_in[
i] & 0x80) == 0;
146 rawir.duration = ((ir->
buf_in[
i] & 0x7f) + 1) *
159 static void iguanair_rx(
struct urb *
urb)
173 switch (urb->status) {
175 process_ir_data(ir, urb->actual_length);
184 dev_dbg(ir->
dev,
"Error: urb status = %d\n", urb->status);
190 dev_warn(ir->
dev,
"failed to resubmit urb: %d\n", rc);
193 static void iguanair_irq_out(
struct urb *urb)
198 dev_dbg(ir->
dev,
"Error: out urb status = %d\n", urb->status);
201 static int iguanair_send(
struct iguanair *ir,
unsigned size)
218 static int iguanair_get_features(
struct iguanair *ir)
222 ir->
packet->header.start = 0;
226 rc = iguanair_send(ir,
sizeof(ir->
packet->header));
243 rc = iguanair_send(ir,
sizeof(ir->
packet->header));
250 dev_info(ir->
dev,
"buffer size %u larger than expected\n",
257 rc = iguanair_send(ir,
sizeof(ir->
packet->header));
271 ir->
packet->header.start = 0;
276 ir_raw_event_reset(ir->
rc);
278 rc = iguanair_send(ir,
sizeof(ir->
packet->header));
293 if (carrier < 25000 || carrier > 150000)
307 switch (cycles & 3) {
322 fours = (cycles - sevens * 7) / 4;
325 ir->
packet->busy7 = (4 - sevens) * 2;
326 ir->
packet->busy4 = 110 - fours;
342 ir->
packet->channels = mask << 4;
348 static int iguanair_tx(
struct rc_dev *dev,
unsigned *txbuf,
unsigned count)
358 for (i = space = size = 0; i <
count; i++) {
361 if (size + bytes > ir->
bufsize) {
365 while (periods > 127) {
366 ir->
packet->payload[size++] = 127 | space;
370 ir->
packet->payload[size++] = periods | space;
379 ir->
packet->header.start = 0;
386 rc = iguanair_send(ir,
sizeof(*ir->
packet) + size);
394 return rc ? rc :
count;
404 rc = iguanair_receiver(ir,
true);
413 static void iguanair_close(
struct rc_dev *rdev)
420 rc = iguanair_receiver(ir,
false);
423 dev_warn(ir->
dev,
"failed to disable receiver: %d\n", rc);
431 struct usb_device *
udev = interface_to_usbdev(intf);
434 int ret, pipein, pipeout;
435 struct usb_host_interface *idesc;
456 idesc = intf->altsetting;
458 if (idesc->desc.bNumEndpoints < 2) {
464 ir->
dev = &intf->dev;
469 pipeout = usb_sndintpipe(udev,
470 idesc->endpoint[1].desc.bEndpointAddress);
472 iguanair_irq_out, ir, 1);
474 ir->
urb_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
476 pipein = usb_rcvintpipe(udev, idesc->endpoint[0].desc.bEndpointAddress);
480 ir->
urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
484 dev_warn(&intf->dev,
"failed to submit urb: %d\n", ret);
488 ret = iguanair_get_features(ir);
493 "IguanaWorks USB IR Transceiver version 0x%04x", ir->
version);
500 rc->
dev.parent = &intf->dev;
504 rc->
open = iguanair_open;
505 rc->
close = iguanair_close;
508 rc->
tx_ir = iguanair_tx;
514 iguanair_set_tx_carrier(rc, 38000);
518 dev_err(&intf->dev,
"failed to register rc device %d", ret);
522 usb_set_intfdata(intf, ir);
543 struct iguanair *ir = usb_get_intfdata(intf);
546 usb_set_intfdata(intf,
NULL);
558 struct iguanair *ir = usb_get_intfdata(intf);
564 rc = iguanair_receiver(ir,
false);
566 dev_warn(ir->
dev,
"failed to disable receiver for suspend\n");
579 struct iguanair *ir = usb_get_intfdata(intf);
586 dev_warn(&intf->dev,
"failed to submit urb: %d\n", rc);
589 rc = iguanair_receiver(ir,
true);
591 dev_warn(ir->
dev,
"failed to enable receiver after resume\n");
600 { USB_DEVICE(0x1781, 0x0938) },
604 static struct usb_driver iguanair_driver = {
606 .probe = iguanair_probe,
608 .suspend = iguanair_suspend,
609 .resume = iguanair_resume,
610 .reset_resume = iguanair_resume,
611 .id_table = iguanair_table,