xref: /openbmc/linux/drivers/media/rc/iguanair.c (revision 95e9fd10)
1 /*
2  * IguanaWorks USB IR Transceiver support
3  *
4  * Copyright (C) 2012 Sean Young <sean@mess.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 #include <linux/device.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/usb.h>
25 #include <linux/usb/input.h>
26 #include <linux/slab.h>
27 #include <linux/completion.h>
28 #include <media/rc-core.h>
29 
30 #define DRIVER_NAME "iguanair"
31 
32 struct iguanair {
33 	struct rc_dev *rc;
34 
35 	struct device *dev;
36 	struct usb_device *udev;
37 
38 	int pipe_in, pipe_out;
39 	uint8_t bufsize;
40 	uint8_t version[2];
41 
42 	struct mutex lock;
43 
44 	/* receiver support */
45 	bool receiver_on;
46 	dma_addr_t dma_in;
47 	uint8_t *buf_in;
48 	struct urb *urb_in;
49 	struct completion completion;
50 
51 	/* transmit support */
52 	bool tx_overflow;
53 	uint32_t carrier;
54 	uint8_t cycle_overhead;
55 	uint8_t channels;
56 	uint8_t busy4;
57 	uint8_t busy7;
58 
59 	char name[64];
60 	char phys[64];
61 };
62 
63 #define CMD_GET_VERSION		0x01
64 #define CMD_GET_BUFSIZE		0x11
65 #define CMD_GET_FEATURES	0x10
66 #define CMD_SEND		0x15
67 #define CMD_EXECUTE		0x1f
68 #define CMD_RX_OVERFLOW		0x31
69 #define CMD_TX_OVERFLOW		0x32
70 #define CMD_RECEIVER_ON		0x12
71 #define CMD_RECEIVER_OFF	0x14
72 
73 #define DIR_IN			0xdc
74 #define DIR_OUT			0xcd
75 
76 #define MAX_PACKET_SIZE		8u
77 #define TIMEOUT			1000
78 
79 struct packet {
80 	uint16_t start;
81 	uint8_t direction;
82 	uint8_t cmd;
83 };
84 
85 struct response_packet {
86 	struct packet header;
87 	uint8_t data[4];
88 };
89 
90 struct send_packet {
91 	struct packet header;
92 	uint8_t length;
93 	uint8_t channels;
94 	uint8_t busy7;
95 	uint8_t busy4;
96 	uint8_t payload[0];
97 };
98 
99 static void process_ir_data(struct iguanair *ir, unsigned len)
100 {
101 	if (len >= 4 && ir->buf_in[0] == 0 && ir->buf_in[1] == 0) {
102 		switch (ir->buf_in[3]) {
103 		case CMD_TX_OVERFLOW:
104 			ir->tx_overflow = true;
105 		case CMD_RECEIVER_OFF:
106 		case CMD_RECEIVER_ON:
107 		case CMD_SEND:
108 			complete(&ir->completion);
109 			break;
110 		case CMD_RX_OVERFLOW:
111 			dev_warn(ir->dev, "receive overflow\n");
112 			break;
113 		default:
114 			dev_warn(ir->dev, "control code %02x received\n",
115 							ir->buf_in[3]);
116 			break;
117 		}
118 	} else if (len >= 7) {
119 		DEFINE_IR_RAW_EVENT(rawir);
120 		unsigned i;
121 
122 		init_ir_raw_event(&rawir);
123 
124 		for (i = 0; i < 7; i++) {
125 			if (ir->buf_in[i] == 0x80) {
126 				rawir.pulse = false;
127 				rawir.duration = US_TO_NS(21845);
128 			} else {
129 				rawir.pulse = (ir->buf_in[i] & 0x80) == 0;
130 				rawir.duration = ((ir->buf_in[i] & 0x7f) + 1) *
131 									 21330;
132 			}
133 
134 			ir_raw_event_store_with_filter(ir->rc, &rawir);
135 		}
136 
137 		ir_raw_event_handle(ir->rc);
138 	}
139 }
140 
141 static void iguanair_rx(struct urb *urb)
142 {
143 	struct iguanair *ir;
144 
145 	if (!urb)
146 		return;
147 
148 	ir = urb->context;
149 	if (!ir) {
150 		usb_unlink_urb(urb);
151 		return;
152 	}
153 
154 	switch (urb->status) {
155 	case 0:
156 		process_ir_data(ir, urb->actual_length);
157 		break;
158 	case -ECONNRESET:
159 	case -ENOENT:
160 	case -ESHUTDOWN:
161 		usb_unlink_urb(urb);
162 		return;
163 	case -EPIPE:
164 	default:
165 		dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
166 		break;
167 	}
168 
169 	usb_submit_urb(urb, GFP_ATOMIC);
170 }
171 
172 static int iguanair_send(struct iguanair *ir, void *data, unsigned size,
173 			struct response_packet *response, unsigned *res_len)
174 {
175 	unsigned offset, len;
176 	int rc, transferred;
177 
178 	for (offset = 0; offset < size; offset += MAX_PACKET_SIZE) {
179 		len = min(size - offset, MAX_PACKET_SIZE);
180 
181 		if (ir->tx_overflow)
182 			return -EOVERFLOW;
183 
184 		rc = usb_interrupt_msg(ir->udev, ir->pipe_out, data + offset,
185 						len, &transferred, TIMEOUT);
186 		if (rc)
187 			return rc;
188 
189 		if (transferred != len)
190 			return -EIO;
191 	}
192 
193 	if (response) {
194 		rc = usb_interrupt_msg(ir->udev, ir->pipe_in, response,
195 					sizeof(*response), res_len, TIMEOUT);
196 	}
197 
198 	return rc;
199 }
200 
201 static int iguanair_get_features(struct iguanair *ir)
202 {
203 	struct packet packet;
204 	struct response_packet response;
205 	int rc, len;
206 
207 	packet.start = 0;
208 	packet.direction = DIR_OUT;
209 	packet.cmd = CMD_GET_VERSION;
210 
211 	rc = iguanair_send(ir, &packet, sizeof(packet), &response, &len);
212 	if (rc) {
213 		dev_info(ir->dev, "failed to get version\n");
214 		goto out;
215 	}
216 
217 	if (len != 6) {
218 		dev_info(ir->dev, "failed to get version\n");
219 		rc = -EIO;
220 		goto out;
221 	}
222 
223 	ir->version[0] = response.data[0];
224 	ir->version[1] = response.data[1];
225 	ir->bufsize = 150;
226 	ir->cycle_overhead = 65;
227 
228 	packet.cmd = CMD_GET_BUFSIZE;
229 
230 	rc = iguanair_send(ir, &packet, sizeof(packet), &response, &len);
231 	if (rc) {
232 		dev_info(ir->dev, "failed to get buffer size\n");
233 		goto out;
234 	}
235 
236 	if (len != 5) {
237 		dev_info(ir->dev, "failed to get buffer size\n");
238 		rc = -EIO;
239 		goto out;
240 	}
241 
242 	ir->bufsize = response.data[0];
243 
244 	if (ir->version[0] == 0 || ir->version[1] == 0)
245 		goto out;
246 
247 	packet.cmd = CMD_GET_FEATURES;
248 
249 	rc = iguanair_send(ir, &packet, sizeof(packet), &response, &len);
250 	if (rc) {
251 		dev_info(ir->dev, "failed to get features\n");
252 		goto out;
253 	}
254 
255 	if (len < 5) {
256 		dev_info(ir->dev, "failed to get features\n");
257 		rc = -EIO;
258 		goto out;
259 	}
260 
261 	if (len > 5 && ir->version[0] >= 4)
262 		ir->cycle_overhead = response.data[1];
263 
264 out:
265 	return rc;
266 }
267 
268 static int iguanair_receiver(struct iguanair *ir, bool enable)
269 {
270 	struct packet packet = { 0, DIR_OUT, enable ?
271 				CMD_RECEIVER_ON : CMD_RECEIVER_OFF };
272 	int rc;
273 
274 	INIT_COMPLETION(ir->completion);
275 
276 	rc = iguanair_send(ir, &packet, sizeof(packet), NULL, NULL);
277 	if (rc)
278 		return rc;
279 
280 	wait_for_completion_timeout(&ir->completion, TIMEOUT);
281 
282 	return 0;
283 }
284 
285 /*
286  * The iguana ir creates the carrier by busy spinning after each pulse or
287  * space. This is counted in CPU cycles, with the CPU running at 24MHz. It is
288  * broken down into 7-cycles and 4-cyles delays, with a preference for
289  * 4-cycle delays.
290  */
291 static int iguanair_set_tx_carrier(struct rc_dev *dev, uint32_t carrier)
292 {
293 	struct iguanair *ir = dev->priv;
294 
295 	if (carrier < 25000 || carrier > 150000)
296 		return -EINVAL;
297 
298 	mutex_lock(&ir->lock);
299 
300 	if (carrier != ir->carrier) {
301 		uint32_t cycles, fours, sevens;
302 
303 		ir->carrier = carrier;
304 
305 		cycles = DIV_ROUND_CLOSEST(24000000, carrier * 2) -
306 							ir->cycle_overhead;
307 
308 		/*  make up the the remainer of 4-cycle blocks */
309 		switch (cycles & 3) {
310 		case 0:
311 			sevens = 0;
312 			break;
313 		case 1:
314 			sevens = 3;
315 			break;
316 		case 2:
317 			sevens = 2;
318 			break;
319 		case 3:
320 			sevens = 1;
321 			break;
322 		}
323 
324 		fours = (cycles - sevens * 7) / 4;
325 
326 		/* magic happens here */
327 		ir->busy7 = (4 - sevens) * 2;
328 		ir->busy4 = 110 - fours;
329 	}
330 
331 	mutex_unlock(&ir->lock);
332 
333 	return carrier;
334 }
335 
336 static int iguanair_set_tx_mask(struct rc_dev *dev, uint32_t mask)
337 {
338 	struct iguanair *ir = dev->priv;
339 
340 	if (mask > 15)
341 		return 4;
342 
343 	mutex_lock(&ir->lock);
344 	ir->channels = mask;
345 	mutex_unlock(&ir->lock);
346 
347 	return 0;
348 }
349 
350 static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
351 {
352 	struct iguanair *ir = dev->priv;
353 	uint8_t space, *payload;
354 	unsigned i, size, rc;
355 	struct send_packet *packet;
356 
357 	mutex_lock(&ir->lock);
358 
359 	/* convert from us to carrier periods */
360 	for (i = size = 0; i < count; i++) {
361 		txbuf[i] = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
362 		size += (txbuf[i] + 126) / 127;
363 	}
364 
365 	packet = kmalloc(sizeof(*packet) + size, GFP_KERNEL);
366 	if (!packet) {
367 		rc = -ENOMEM;
368 		goto out;
369 	}
370 
371 	if (size > ir->bufsize) {
372 		rc = -E2BIG;
373 		goto out;
374 	}
375 
376 	packet->header.start = 0;
377 	packet->header.direction = DIR_OUT;
378 	packet->header.cmd = CMD_SEND;
379 	packet->length = size;
380 	packet->channels = ir->channels << 4;
381 	packet->busy7 = ir->busy7;
382 	packet->busy4 = ir->busy4;
383 
384 	space = 0;
385 	payload = packet->payload;
386 
387 	for (i = 0; i < count; i++) {
388 		unsigned periods = txbuf[i];
389 
390 		while (periods > 127) {
391 			*payload++ = 127 | space;
392 			periods -= 127;
393 		}
394 
395 		*payload++ = periods | space;
396 		space ^= 0x80;
397 	}
398 
399 	if (ir->receiver_on) {
400 		rc = iguanair_receiver(ir, false);
401 		if (rc) {
402 			dev_warn(ir->dev, "disable receiver before transmit failed\n");
403 			goto out;
404 		}
405 	}
406 
407 	ir->tx_overflow = false;
408 
409 	INIT_COMPLETION(ir->completion);
410 
411 	rc = iguanair_send(ir, packet, size + 8, NULL, NULL);
412 
413 	if (rc == 0) {
414 		wait_for_completion_timeout(&ir->completion, TIMEOUT);
415 		if (ir->tx_overflow)
416 			rc = -EOVERFLOW;
417 	}
418 
419 	ir->tx_overflow = false;
420 
421 	if (ir->receiver_on) {
422 		if (iguanair_receiver(ir, true))
423 			dev_warn(ir->dev, "re-enable receiver after transmit failed\n");
424 	}
425 
426 out:
427 	mutex_unlock(&ir->lock);
428 	kfree(packet);
429 
430 	return rc;
431 }
432 
433 static int iguanair_open(struct rc_dev *rdev)
434 {
435 	struct iguanair *ir = rdev->priv;
436 	int rc;
437 
438 	mutex_lock(&ir->lock);
439 
440 	usb_submit_urb(ir->urb_in, GFP_KERNEL);
441 
442 	BUG_ON(ir->receiver_on);
443 
444 	rc = iguanair_receiver(ir, true);
445 	if (rc == 0)
446 		ir->receiver_on = true;
447 
448 	mutex_unlock(&ir->lock);
449 
450 	return rc;
451 }
452 
453 static void iguanair_close(struct rc_dev *rdev)
454 {
455 	struct iguanair *ir = rdev->priv;
456 	int rc;
457 
458 	mutex_lock(&ir->lock);
459 
460 	rc = iguanair_receiver(ir, false);
461 	ir->receiver_on = false;
462 	if (rc)
463 		dev_warn(ir->dev, "failed to disable receiver: %d\n", rc);
464 
465 	usb_kill_urb(ir->urb_in);
466 
467 	mutex_unlock(&ir->lock);
468 }
469 
470 static int __devinit iguanair_probe(struct usb_interface *intf,
471 						const struct usb_device_id *id)
472 {
473 	struct usb_device *udev = interface_to_usbdev(intf);
474 	struct iguanair *ir;
475 	struct rc_dev *rc;
476 	int ret;
477 	struct usb_host_interface *idesc;
478 
479 	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
480 	rc = rc_allocate_device();
481 	if (!ir || !rc) {
482 		ret = ENOMEM;
483 		goto out;
484 	}
485 
486 	ir->buf_in = usb_alloc_coherent(udev, MAX_PACKET_SIZE, GFP_ATOMIC,
487 								&ir->dma_in);
488 	ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
489 
490 	if (!ir->buf_in || !ir->urb_in) {
491 		ret = ENOMEM;
492 		goto out;
493 	}
494 
495 	idesc = intf->altsetting;
496 
497 	if (idesc->desc.bNumEndpoints < 2) {
498 		ret = -ENODEV;
499 		goto out;
500 	}
501 
502 	ir->rc = rc;
503 	ir->dev = &intf->dev;
504 	ir->udev = udev;
505 	ir->pipe_in = usb_rcvintpipe(udev,
506 				idesc->endpoint[0].desc.bEndpointAddress);
507 	ir->pipe_out = usb_sndintpipe(udev,
508 				idesc->endpoint[1].desc.bEndpointAddress);
509 	mutex_init(&ir->lock);
510 	init_completion(&ir->completion);
511 
512 	ret = iguanair_get_features(ir);
513 	if (ret) {
514 		dev_warn(&intf->dev, "failed to get device features");
515 		goto out;
516 	}
517 
518 	usb_fill_int_urb(ir->urb_in, ir->udev, ir->pipe_in, ir->buf_in,
519 		MAX_PACKET_SIZE, iguanair_rx, ir,
520 		idesc->endpoint[0].desc.bInterval);
521 	ir->urb_in->transfer_dma = ir->dma_in;
522 	ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
523 
524 	snprintf(ir->name, sizeof(ir->name),
525 		"IguanaWorks USB IR Transceiver version %d.%d",
526 		ir->version[0], ir->version[1]);
527 
528 	usb_make_path(ir->udev, ir->phys, sizeof(ir->phys));
529 
530 	rc->input_name = ir->name;
531 	rc->input_phys = ir->phys;
532 	usb_to_input_id(ir->udev, &rc->input_id);
533 	rc->dev.parent = &intf->dev;
534 	rc->driver_type = RC_DRIVER_IR_RAW;
535 	rc->allowed_protos = RC_TYPE_ALL;
536 	rc->priv = ir;
537 	rc->open = iguanair_open;
538 	rc->close = iguanair_close;
539 	rc->s_tx_mask = iguanair_set_tx_mask;
540 	rc->s_tx_carrier = iguanair_set_tx_carrier;
541 	rc->tx_ir = iguanair_tx;
542 	rc->driver_name = DRIVER_NAME;
543 	rc->map_name = RC_MAP_EMPTY;
544 
545 	iguanair_set_tx_carrier(rc, 38000);
546 
547 	ret = rc_register_device(rc);
548 	if (ret < 0) {
549 		dev_err(&intf->dev, "failed to register rc device %d", ret);
550 		goto out;
551 	}
552 
553 	usb_set_intfdata(intf, ir);
554 
555 	dev_info(&intf->dev, "Registered %s", ir->name);
556 
557 	return 0;
558 out:
559 	if (ir) {
560 		usb_free_urb(ir->urb_in);
561 		usb_free_coherent(udev, MAX_PACKET_SIZE, ir->buf_in,
562 								ir->dma_in);
563 	}
564 	rc_free_device(rc);
565 	kfree(ir);
566 	return ret;
567 }
568 
569 static void __devexit iguanair_disconnect(struct usb_interface *intf)
570 {
571 	struct iguanair *ir = usb_get_intfdata(intf);
572 
573 	usb_set_intfdata(intf, NULL);
574 
575 	usb_kill_urb(ir->urb_in);
576 	usb_free_urb(ir->urb_in);
577 	usb_free_coherent(ir->udev, MAX_PACKET_SIZE, ir->buf_in, ir->dma_in);
578 	rc_unregister_device(ir->rc);
579 	kfree(ir);
580 }
581 
582 static int iguanair_suspend(struct usb_interface *intf, pm_message_t message)
583 {
584 	struct iguanair *ir = usb_get_intfdata(intf);
585 	int rc = 0;
586 
587 	mutex_lock(&ir->lock);
588 
589 	if (ir->receiver_on) {
590 		rc = iguanair_receiver(ir, false);
591 		if (rc)
592 			dev_warn(ir->dev, "failed to disable receiver for suspend\n");
593 	}
594 
595 	mutex_unlock(&ir->lock);
596 
597 	return rc;
598 }
599 
600 static int iguanair_resume(struct usb_interface *intf)
601 {
602 	struct iguanair *ir = usb_get_intfdata(intf);
603 	int rc = 0;
604 
605 	mutex_lock(&ir->lock);
606 
607 	if (ir->receiver_on) {
608 		rc = iguanair_receiver(ir, true);
609 		if (rc)
610 			dev_warn(ir->dev, "failed to enable receiver after resume\n");
611 	}
612 
613 	mutex_unlock(&ir->lock);
614 
615 	return rc;
616 }
617 
618 static const struct usb_device_id iguanair_table[] = {
619 	{ USB_DEVICE(0x1781, 0x0938) },
620 	{ }
621 };
622 
623 static struct usb_driver iguanair_driver = {
624 	.name =	DRIVER_NAME,
625 	.probe = iguanair_probe,
626 	.disconnect = __devexit_p(iguanair_disconnect),
627 	.suspend = iguanair_suspend,
628 	.resume = iguanair_resume,
629 	.reset_resume = iguanair_resume,
630 	.id_table = iguanair_table
631 };
632 
633 module_usb_driver(iguanair_driver);
634 
635 MODULE_DESCRIPTION("IguanaWorks USB IR Transceiver");
636 MODULE_AUTHOR("Sean Young <sean@mess.org>");
637 MODULE_LICENSE("GPL");
638 MODULE_DEVICE_TABLE(usb, iguanair_table);
639 
640