| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * IguanaWorks USB IR Transceiver support |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * 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 | 6 | */ |
|---|
| 16 | 7 | |
|---|
| 17 | 8 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 23 | 14 | #include <linux/completion.h> |
|---|
| 24 | 15 | #include <media/rc-core.h> |
|---|
| 25 | 16 | |
|---|
| 26 | | -#define DRIVER_NAME "iguanair" |
|---|
| 27 | 17 | #define BUF_SIZE 152 |
|---|
| 28 | 18 | |
|---|
| 29 | 19 | struct iguanair { |
|---|
| .. | .. |
|---|
| 35 | 25 | uint16_t version; |
|---|
| 36 | 26 | uint8_t bufsize; |
|---|
| 37 | 27 | uint8_t cycle_overhead; |
|---|
| 38 | | - |
|---|
| 39 | | - struct mutex lock; |
|---|
| 40 | 28 | |
|---|
| 41 | 29 | /* receiver support */ |
|---|
| 42 | 30 | bool receiver_on; |
|---|
| .. | .. |
|---|
| 71 | 59 | #define MAX_IN_PACKET 8u |
|---|
| 72 | 60 | #define MAX_OUT_PACKET (sizeof(struct send_packet) + BUF_SIZE) |
|---|
| 73 | 61 | #define TIMEOUT 1000 |
|---|
| 74 | | -#define RX_RESOLUTION 21333 |
|---|
| 62 | +#define RX_RESOLUTION 21 |
|---|
| 75 | 63 | |
|---|
| 76 | 64 | struct packet { |
|---|
| 77 | 65 | uint16_t start; |
|---|
| .. | .. |
|---|
| 85 | 73 | uint8_t channels; |
|---|
| 86 | 74 | uint8_t busy7; |
|---|
| 87 | 75 | uint8_t busy4; |
|---|
| 88 | | - uint8_t payload[0]; |
|---|
| 76 | + uint8_t payload[]; |
|---|
| 89 | 77 | }; |
|---|
| 90 | 78 | |
|---|
| 91 | 79 | static void process_ir_data(struct iguanair *ir, unsigned len) |
|---|
| .. | .. |
|---|
| 113 | 101 | break; |
|---|
| 114 | 102 | case CMD_TX_OVERFLOW: |
|---|
| 115 | 103 | ir->tx_overflow = true; |
|---|
| 116 | | - /* fall through */ |
|---|
| 104 | + fallthrough; |
|---|
| 117 | 105 | case CMD_RECEIVER_OFF: |
|---|
| 118 | 106 | case CMD_RECEIVER_ON: |
|---|
| 119 | 107 | case CMD_SEND: |
|---|
| .. | .. |
|---|
| 129 | 117 | break; |
|---|
| 130 | 118 | } |
|---|
| 131 | 119 | } else if (len >= 7) { |
|---|
| 132 | | - DEFINE_IR_RAW_EVENT(rawir); |
|---|
| 120 | + struct ir_raw_event rawir = {}; |
|---|
| 133 | 121 | unsigned i; |
|---|
| 134 | 122 | bool event = false; |
|---|
| 135 | | - |
|---|
| 136 | | - init_ir_raw_event(&rawir); |
|---|
| 137 | 123 | |
|---|
| 138 | 124 | for (i = 0; i < 7; i++) { |
|---|
| 139 | 125 | if (ir->buf_in[i] == 0x80) { |
|---|
| 140 | 126 | rawir.pulse = false; |
|---|
| 141 | | - rawir.duration = US_TO_NS(21845); |
|---|
| 127 | + rawir.duration = 21845; |
|---|
| 142 | 128 | } else { |
|---|
| 143 | 129 | rawir.pulse = (ir->buf_in[i] & 0x80) == 0; |
|---|
| 144 | 130 | rawir.duration = ((ir->buf_in[i] & 0x7f) + 1) * |
|---|
| .. | .. |
|---|
| 295 | 281 | if (carrier < 25000 || carrier > 150000) |
|---|
| 296 | 282 | return -EINVAL; |
|---|
| 297 | 283 | |
|---|
| 298 | | - mutex_lock(&ir->lock); |
|---|
| 299 | | - |
|---|
| 300 | 284 | if (carrier != ir->carrier) { |
|---|
| 301 | 285 | uint32_t cycles, fours, sevens; |
|---|
| 302 | 286 | |
|---|
| .. | .. |
|---|
| 325 | 309 | ir->packet->busy4 = 110 - fours; |
|---|
| 326 | 310 | } |
|---|
| 327 | 311 | |
|---|
| 328 | | - mutex_unlock(&ir->lock); |
|---|
| 329 | | - |
|---|
| 330 | 312 | return 0; |
|---|
| 331 | 313 | } |
|---|
| 332 | 314 | |
|---|
| .. | .. |
|---|
| 337 | 319 | if (mask > 15) |
|---|
| 338 | 320 | return 4; |
|---|
| 339 | 321 | |
|---|
| 340 | | - mutex_lock(&ir->lock); |
|---|
| 341 | 322 | ir->packet->channels = mask << 4; |
|---|
| 342 | | - mutex_unlock(&ir->lock); |
|---|
| 343 | 323 | |
|---|
| 344 | 324 | return 0; |
|---|
| 345 | 325 | } |
|---|
| .. | .. |
|---|
| 349 | 329 | struct iguanair *ir = dev->priv; |
|---|
| 350 | 330 | unsigned int i, size, p, periods; |
|---|
| 351 | 331 | int rc; |
|---|
| 352 | | - |
|---|
| 353 | | - mutex_lock(&ir->lock); |
|---|
| 354 | 332 | |
|---|
| 355 | 333 | /* convert from us to carrier periods */ |
|---|
| 356 | 334 | for (i = size = 0; i < count; i++) { |
|---|
| .. | .. |
|---|
| 379 | 357 | rc = -EOVERFLOW; |
|---|
| 380 | 358 | |
|---|
| 381 | 359 | out: |
|---|
| 382 | | - mutex_unlock(&ir->lock); |
|---|
| 383 | | - |
|---|
| 384 | 360 | return rc ? rc : count; |
|---|
| 385 | 361 | } |
|---|
| 386 | 362 | |
|---|
| .. | .. |
|---|
| 389 | 365 | struct iguanair *ir = rdev->priv; |
|---|
| 390 | 366 | int rc; |
|---|
| 391 | 367 | |
|---|
| 392 | | - mutex_lock(&ir->lock); |
|---|
| 393 | | - |
|---|
| 394 | 368 | rc = iguanair_receiver(ir, true); |
|---|
| 395 | 369 | if (rc == 0) |
|---|
| 396 | 370 | ir->receiver_on = true; |
|---|
| 397 | | - |
|---|
| 398 | | - mutex_unlock(&ir->lock); |
|---|
| 399 | 371 | |
|---|
| 400 | 372 | return rc; |
|---|
| 401 | 373 | } |
|---|
| .. | .. |
|---|
| 405 | 377 | struct iguanair *ir = rdev->priv; |
|---|
| 406 | 378 | int rc; |
|---|
| 407 | 379 | |
|---|
| 408 | | - mutex_lock(&ir->lock); |
|---|
| 409 | | - |
|---|
| 410 | 380 | rc = iguanair_receiver(ir, false); |
|---|
| 411 | 381 | ir->receiver_on = false; |
|---|
| 412 | 382 | if (rc && rc != -ENODEV) |
|---|
| 413 | 383 | dev_warn(ir->dev, "failed to disable receiver: %d\n", rc); |
|---|
| 414 | | - |
|---|
| 415 | | - mutex_unlock(&ir->lock); |
|---|
| 416 | 384 | } |
|---|
| 417 | 385 | |
|---|
| 418 | 386 | static int iguanair_probe(struct usb_interface *intf, |
|---|
| .. | .. |
|---|
| 452 | 420 | ir->rc = rc; |
|---|
| 453 | 421 | ir->dev = &intf->dev; |
|---|
| 454 | 422 | ir->udev = udev; |
|---|
| 455 | | - mutex_init(&ir->lock); |
|---|
| 456 | 423 | |
|---|
| 457 | 424 | init_completion(&ir->completion); |
|---|
| 458 | 425 | pipeout = usb_sndintpipe(udev, |
|---|
| .. | .. |
|---|
| 494 | 461 | rc->s_tx_mask = iguanair_set_tx_mask; |
|---|
| 495 | 462 | rc->s_tx_carrier = iguanair_set_tx_carrier; |
|---|
| 496 | 463 | rc->tx_ir = iguanair_tx; |
|---|
| 497 | | - rc->driver_name = DRIVER_NAME; |
|---|
| 464 | + rc->driver_name = KBUILD_MODNAME; |
|---|
| 498 | 465 | rc->map_name = RC_MAP_RC6_MCE; |
|---|
| 499 | 466 | rc->min_timeout = 1; |
|---|
| 500 | 467 | rc->timeout = IR_DEFAULT_TIMEOUT; |
|---|
| .. | .. |
|---|
| 549 | 516 | struct iguanair *ir = usb_get_intfdata(intf); |
|---|
| 550 | 517 | int rc = 0; |
|---|
| 551 | 518 | |
|---|
| 552 | | - mutex_lock(&ir->lock); |
|---|
| 553 | | - |
|---|
| 554 | 519 | if (ir->receiver_on) { |
|---|
| 555 | 520 | rc = iguanair_receiver(ir, false); |
|---|
| 556 | 521 | if (rc) |
|---|
| .. | .. |
|---|
| 560 | 525 | usb_kill_urb(ir->urb_in); |
|---|
| 561 | 526 | usb_kill_urb(ir->urb_out); |
|---|
| 562 | 527 | |
|---|
| 563 | | - mutex_unlock(&ir->lock); |
|---|
| 564 | | - |
|---|
| 565 | 528 | return rc; |
|---|
| 566 | 529 | } |
|---|
| 567 | 530 | |
|---|
| 568 | 531 | static int iguanair_resume(struct usb_interface *intf) |
|---|
| 569 | 532 | { |
|---|
| 570 | 533 | struct iguanair *ir = usb_get_intfdata(intf); |
|---|
| 571 | | - int rc = 0; |
|---|
| 572 | | - |
|---|
| 573 | | - mutex_lock(&ir->lock); |
|---|
| 534 | + int rc; |
|---|
| 574 | 535 | |
|---|
| 575 | 536 | rc = usb_submit_urb(ir->urb_in, GFP_KERNEL); |
|---|
| 576 | 537 | if (rc) |
|---|
| .. | .. |
|---|
| 582 | 543 | dev_warn(ir->dev, "failed to enable receiver after resume\n"); |
|---|
| 583 | 544 | } |
|---|
| 584 | 545 | |
|---|
| 585 | | - mutex_unlock(&ir->lock); |
|---|
| 586 | | - |
|---|
| 587 | 546 | return rc; |
|---|
| 588 | 547 | } |
|---|
| 589 | 548 | |
|---|
| .. | .. |
|---|
| 593 | 552 | }; |
|---|
| 594 | 553 | |
|---|
| 595 | 554 | static struct usb_driver iguanair_driver = { |
|---|
| 596 | | - .name = DRIVER_NAME, |
|---|
| 555 | + .name = KBUILD_MODNAME, |
|---|
| 597 | 556 | .probe = iguanair_probe, |
|---|
| 598 | 557 | .disconnect = iguanair_disconnect, |
|---|
| 599 | 558 | .suspend = iguanair_suspend, |
|---|