root/drivers/media/rc/ttusbir.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ttusbir_brightness_get
  2. ttusbir_set_led
  3. ttusbir_brightness_set
  4. ttusbir_bulk_complete
  5. ttusbir_process_ir_data
  6. ttusbir_urb_complete
  7. ttusbir_probe
  8. ttusbir_disconnect
  9. ttusbir_suspend
  10. ttusbir_resume

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * TechnoTrend USB IR Receiver
   4  *
   5  * Copyright (C) 2012 Sean Young <sean@mess.org>
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/usb.h>
  10 #include <linux/usb/input.h>
  11 #include <linux/slab.h>
  12 #include <linux/leds.h>
  13 #include <media/rc-core.h>
  14 
  15 #define DRIVER_NAME     "ttusbir"
  16 #define DRIVER_DESC     "TechnoTrend USB IR Receiver"
  17 /*
  18  * The Windows driver uses 8 URBS, the original lirc drivers has a
  19  * configurable amount (2 default, 4 max). This device generates about 125
  20  * messages per second (!), whether IR is idle or not.
  21  */
  22 #define NUM_URBS        4
  23 #define NS_PER_BYTE     62500
  24 #define NS_PER_BIT      (NS_PER_BYTE/8)
  25 
  26 struct ttusbir {
  27         struct rc_dev *rc;
  28         struct device *dev;
  29         struct usb_device *udev;
  30 
  31         struct urb *urb[NUM_URBS];
  32 
  33         struct led_classdev led;
  34         struct urb *bulk_urb;
  35         uint8_t bulk_buffer[5];
  36         int bulk_out_endp, iso_in_endp;
  37         bool led_on, is_led_on;
  38         atomic_t led_complete;
  39 
  40         char phys[64];
  41 };
  42 
  43 static enum led_brightness ttusbir_brightness_get(struct led_classdev *led_dev)
  44 {
  45         struct ttusbir *tt = container_of(led_dev, struct ttusbir, led);
  46 
  47         return tt->led_on ? LED_FULL : LED_OFF;
  48 }
  49 
  50 static void ttusbir_set_led(struct ttusbir *tt)
  51 {
  52         int ret;
  53 
  54         smp_mb();
  55 
  56         if (tt->led_on != tt->is_led_on && tt->udev &&
  57                                 atomic_add_unless(&tt->led_complete, 1, 1)) {
  58                 tt->bulk_buffer[4] = tt->is_led_on = tt->led_on;
  59                 ret = usb_submit_urb(tt->bulk_urb, GFP_ATOMIC);
  60                 if (ret) {
  61                         dev_warn(tt->dev, "failed to submit bulk urb: %d\n",
  62                                                                         ret);
  63                         atomic_dec(&tt->led_complete);
  64                 }
  65         }
  66 }
  67 
  68 static void ttusbir_brightness_set(struct led_classdev *led_dev, enum
  69                                                 led_brightness brightness)
  70 {
  71         struct ttusbir *tt = container_of(led_dev, struct ttusbir, led);
  72 
  73         tt->led_on = brightness != LED_OFF;
  74 
  75         ttusbir_set_led(tt);
  76 }
  77 
  78 /*
  79  * The urb cannot be reused until the urb completes
  80  */
  81 static void ttusbir_bulk_complete(struct urb *urb)
  82 {
  83         struct ttusbir *tt = urb->context;
  84 
  85         atomic_dec(&tt->led_complete);
  86 
  87         switch (urb->status) {
  88         case 0:
  89                 break;
  90         case -ECONNRESET:
  91         case -ENOENT:
  92         case -ESHUTDOWN:
  93                 usb_unlink_urb(urb);
  94                 return;
  95         case -EPIPE:
  96         default:
  97                 dev_dbg(tt->dev, "Error: urb status = %d\n", urb->status);
  98                 break;
  99         }
 100 
 101         ttusbir_set_led(tt);
 102 }
 103 
 104 /*
 105  * The data is one bit per sample, a set bit signifying silence and samples
 106  * being MSB first. Bit 0 can contain garbage so take it to be whatever
 107  * bit 1 is, so we don't have unexpected edges.
 108  */
 109 static void ttusbir_process_ir_data(struct ttusbir *tt, uint8_t *buf)
 110 {
 111         struct ir_raw_event rawir = {};
 112         unsigned i, v, b;
 113         bool event = false;
 114 
 115         for (i = 0; i < 128; i++) {
 116                 v = buf[i] & 0xfe;
 117                 switch (v) {
 118                 case 0xfe:
 119                         rawir.pulse = false;
 120                         rawir.duration = NS_PER_BYTE;
 121                         if (ir_raw_event_store_with_filter(tt->rc, &rawir))
 122                                 event = true;
 123                         break;
 124                 case 0:
 125                         rawir.pulse = true;
 126                         rawir.duration = NS_PER_BYTE;
 127                         if (ir_raw_event_store_with_filter(tt->rc, &rawir))
 128                                 event = true;
 129                         break;
 130                 default:
 131                         /* one edge per byte */
 132                         if (v & 2) {
 133                                 b = ffz(v | 1);
 134                                 rawir.pulse = true;
 135                         } else {
 136                                 b = ffs(v) - 1;
 137                                 rawir.pulse = false;
 138                         }
 139 
 140                         rawir.duration = NS_PER_BIT * (8 - b);
 141                         if (ir_raw_event_store_with_filter(tt->rc, &rawir))
 142                                 event = true;
 143 
 144                         rawir.pulse = !rawir.pulse;
 145                         rawir.duration = NS_PER_BIT * b;
 146                         if (ir_raw_event_store_with_filter(tt->rc, &rawir))
 147                                 event = true;
 148                         break;
 149                 }
 150         }
 151 
 152         /* don't wakeup when there's nothing to do */
 153         if (event)
 154                 ir_raw_event_handle(tt->rc);
 155 }
 156 
 157 static void ttusbir_urb_complete(struct urb *urb)
 158 {
 159         struct ttusbir *tt = urb->context;
 160         int rc;
 161 
 162         switch (urb->status) {
 163         case 0:
 164                 ttusbir_process_ir_data(tt, urb->transfer_buffer);
 165                 break;
 166         case -ECONNRESET:
 167         case -ENOENT:
 168         case -ESHUTDOWN:
 169                 usb_unlink_urb(urb);
 170                 return;
 171         case -EPIPE:
 172         default:
 173                 dev_dbg(tt->dev, "Error: urb status = %d\n", urb->status);
 174                 break;
 175         }
 176 
 177         rc = usb_submit_urb(urb, GFP_ATOMIC);
 178         if (rc && rc != -ENODEV)
 179                 dev_warn(tt->dev, "failed to resubmit urb: %d\n", rc);
 180 }
 181 
 182 static int ttusbir_probe(struct usb_interface *intf,
 183                          const struct usb_device_id *id)
 184 {
 185         struct ttusbir *tt;
 186         struct usb_interface_descriptor *idesc;
 187         struct usb_endpoint_descriptor *desc;
 188         struct rc_dev *rc;
 189         int i, j, ret;
 190         int altsetting = -1;
 191 
 192         tt = kzalloc(sizeof(*tt), GFP_KERNEL);
 193         rc = rc_allocate_device(RC_DRIVER_IR_RAW);
 194         if (!tt || !rc) {
 195                 ret = -ENOMEM;
 196                 goto out;
 197         }
 198 
 199         /* find the correct alt setting */
 200         for (i = 0; i < intf->num_altsetting && altsetting == -1; i++) {
 201                 int max_packet, bulk_out_endp = -1, iso_in_endp = -1;
 202 
 203                 idesc = &intf->altsetting[i].desc;
 204 
 205                 for (j = 0; j < idesc->bNumEndpoints; j++) {
 206                         desc = &intf->altsetting[i].endpoint[j].desc;
 207                         max_packet = le16_to_cpu(desc->wMaxPacketSize);
 208                         if (usb_endpoint_dir_in(desc) &&
 209                                         usb_endpoint_xfer_isoc(desc) &&
 210                                         max_packet == 0x10)
 211                                 iso_in_endp = j;
 212                         else if (usb_endpoint_dir_out(desc) &&
 213                                         usb_endpoint_xfer_bulk(desc) &&
 214                                         max_packet == 0x20)
 215                                 bulk_out_endp = j;
 216 
 217                         if (bulk_out_endp != -1 && iso_in_endp != -1) {
 218                                 tt->bulk_out_endp = bulk_out_endp;
 219                                 tt->iso_in_endp = iso_in_endp;
 220                                 altsetting = i;
 221                                 break;
 222                         }
 223                 }
 224         }
 225 
 226         if (altsetting == -1) {
 227                 dev_err(&intf->dev, "cannot find expected altsetting\n");
 228                 ret = -ENODEV;
 229                 goto out;
 230         }
 231 
 232         tt->dev = &intf->dev;
 233         tt->udev = interface_to_usbdev(intf);
 234         tt->rc = rc;
 235 
 236         ret = usb_set_interface(tt->udev, 0, altsetting);
 237         if (ret)
 238                 goto out;
 239 
 240         for (i = 0; i < NUM_URBS; i++) {
 241                 struct urb *urb = usb_alloc_urb(8, GFP_KERNEL);
 242                 void *buffer;
 243 
 244                 if (!urb) {
 245                         ret = -ENOMEM;
 246                         goto out;
 247                 }
 248 
 249                 urb->dev = tt->udev;
 250                 urb->context = tt;
 251                 urb->pipe = usb_rcvisocpipe(tt->udev, tt->iso_in_endp);
 252                 urb->interval = 1;
 253                 buffer = usb_alloc_coherent(tt->udev, 128, GFP_KERNEL,
 254                                                 &urb->transfer_dma);
 255                 if (!buffer) {
 256                         usb_free_urb(urb);
 257                         ret = -ENOMEM;
 258                         goto out;
 259                 }
 260                 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP | URB_ISO_ASAP;
 261                 urb->transfer_buffer = buffer;
 262                 urb->complete = ttusbir_urb_complete;
 263                 urb->number_of_packets = 8;
 264                 urb->transfer_buffer_length = 128;
 265 
 266                 for (j = 0; j < 8; j++) {
 267                         urb->iso_frame_desc[j].offset = j * 16;
 268                         urb->iso_frame_desc[j].length = 16;
 269                 }
 270 
 271                 tt->urb[i] = urb;
 272         }
 273 
 274         tt->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
 275         if (!tt->bulk_urb) {
 276                 ret = -ENOMEM;
 277                 goto out;
 278         }
 279 
 280         tt->bulk_buffer[0] = 0xaa;
 281         tt->bulk_buffer[1] = 0x01;
 282         tt->bulk_buffer[2] = 0x05;
 283         tt->bulk_buffer[3] = 0x01;
 284 
 285         usb_fill_bulk_urb(tt->bulk_urb, tt->udev, usb_sndbulkpipe(tt->udev,
 286                 tt->bulk_out_endp), tt->bulk_buffer, sizeof(tt->bulk_buffer),
 287                                                 ttusbir_bulk_complete, tt);
 288 
 289         tt->led.name = "ttusbir:green:power";
 290         tt->led.default_trigger = "rc-feedback";
 291         tt->led.brightness_set = ttusbir_brightness_set;
 292         tt->led.brightness_get = ttusbir_brightness_get;
 293         tt->is_led_on = tt->led_on = true;
 294         atomic_set(&tt->led_complete, 0);
 295         ret = led_classdev_register(&intf->dev, &tt->led);
 296         if (ret)
 297                 goto out;
 298 
 299         usb_make_path(tt->udev, tt->phys, sizeof(tt->phys));
 300 
 301         rc->device_name = DRIVER_DESC;
 302         rc->input_phys = tt->phys;
 303         usb_to_input_id(tt->udev, &rc->input_id);
 304         rc->dev.parent = &intf->dev;
 305         rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
 306         rc->priv = tt;
 307         rc->driver_name = DRIVER_NAME;
 308         rc->map_name = RC_MAP_TT_1500;
 309         rc->min_timeout = 1;
 310         rc->timeout = IR_DEFAULT_TIMEOUT;
 311         rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
 312 
 313         /*
 314          * The precision is NS_PER_BIT, but since every 8th bit can be
 315          * overwritten with garbage the accuracy is at best 2 * NS_PER_BIT.
 316          */
 317         rc->rx_resolution = NS_PER_BIT;
 318 
 319         ret = rc_register_device(rc);
 320         if (ret) {
 321                 dev_err(&intf->dev, "failed to register rc device %d\n", ret);
 322                 goto out2;
 323         }
 324 
 325         usb_set_intfdata(intf, tt);
 326 
 327         for (i = 0; i < NUM_URBS; i++) {
 328                 ret = usb_submit_urb(tt->urb[i], GFP_KERNEL);
 329                 if (ret) {
 330                         dev_err(tt->dev, "failed to submit urb %d\n", ret);
 331                         goto out3;
 332                 }
 333         }
 334 
 335         return 0;
 336 out3:
 337         rc_unregister_device(rc);
 338         rc = NULL;
 339 out2:
 340         led_classdev_unregister(&tt->led);
 341 out:
 342         if (tt) {
 343                 for (i = 0; i < NUM_URBS && tt->urb[i]; i++) {
 344                         struct urb *urb = tt->urb[i];
 345 
 346                         usb_kill_urb(urb);
 347                         usb_free_coherent(tt->udev, 128, urb->transfer_buffer,
 348                                                         urb->transfer_dma);
 349                         usb_free_urb(urb);
 350                 }
 351                 usb_kill_urb(tt->bulk_urb);
 352                 usb_free_urb(tt->bulk_urb);
 353                 kfree(tt);
 354         }
 355         rc_free_device(rc);
 356 
 357         return ret;
 358 }
 359 
 360 static void ttusbir_disconnect(struct usb_interface *intf)
 361 {
 362         struct ttusbir *tt = usb_get_intfdata(intf);
 363         struct usb_device *udev = tt->udev;
 364         int i;
 365 
 366         tt->udev = NULL;
 367 
 368         rc_unregister_device(tt->rc);
 369         led_classdev_unregister(&tt->led);
 370         for (i = 0; i < NUM_URBS; i++) {
 371                 usb_kill_urb(tt->urb[i]);
 372                 usb_free_coherent(udev, 128, tt->urb[i]->transfer_buffer,
 373                                                 tt->urb[i]->transfer_dma);
 374                 usb_free_urb(tt->urb[i]);
 375         }
 376         usb_kill_urb(tt->bulk_urb);
 377         usb_free_urb(tt->bulk_urb);
 378         usb_set_intfdata(intf, NULL);
 379         kfree(tt);
 380 }
 381 
 382 static int ttusbir_suspend(struct usb_interface *intf, pm_message_t message)
 383 {
 384         struct ttusbir *tt = usb_get_intfdata(intf);
 385         int i;
 386 
 387         for (i = 0; i < NUM_URBS; i++)
 388                 usb_kill_urb(tt->urb[i]);
 389 
 390         led_classdev_suspend(&tt->led);
 391         usb_kill_urb(tt->bulk_urb);
 392 
 393         return 0;
 394 }
 395 
 396 static int ttusbir_resume(struct usb_interface *intf)
 397 {
 398         struct ttusbir *tt = usb_get_intfdata(intf);
 399         int i, rc;
 400 
 401         tt->is_led_on = true;
 402         led_classdev_resume(&tt->led);
 403 
 404         for (i = 0; i < NUM_URBS; i++) {
 405                 rc = usb_submit_urb(tt->urb[i], GFP_KERNEL);
 406                 if (rc) {
 407                         dev_warn(tt->dev, "failed to submit urb: %d\n", rc);
 408                         break;
 409                 }
 410         }
 411 
 412         return rc;
 413 }
 414 
 415 static const struct usb_device_id ttusbir_table[] = {
 416         { USB_DEVICE(0x0b48, 0x2003) },
 417         { }
 418 };
 419 
 420 static struct usb_driver ttusbir_driver = {
 421         .name = DRIVER_NAME,
 422         .id_table = ttusbir_table,
 423         .probe = ttusbir_probe,
 424         .suspend = ttusbir_suspend,
 425         .resume = ttusbir_resume,
 426         .reset_resume = ttusbir_resume,
 427         .disconnect = ttusbir_disconnect,
 428 };
 429 
 430 module_usb_driver(ttusbir_driver);
 431 
 432 MODULE_DESCRIPTION(DRIVER_DESC);
 433 MODULE_AUTHOR("Sean Young <sean@mess.org>");
 434 MODULE_LICENSE("GPL");
 435 MODULE_DEVICE_TABLE(usb, ttusbir_table);
 436 

/* [<][>][^][v][top][bottom][index][help] */