root/drivers/media/rc/serial_ir.c

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

DEFINITIONS

This source file includes following definitions.
  1. sinp
  2. soutp
  3. on
  4. off
  5. send_pulse_irdeo
  6. send_space_irdeo
  7. send_pulse_homebrew_softcarrier
  8. send_pulse_homebrew
  9. send_space_homebrew
  10. frbwrite
  11. serial_ir_irq_handler
  12. hardware_init_port
  13. serial_ir_timeout
  14. serial_ir_probe
  15. serial_ir_open
  16. serial_ir_close
  17. serial_ir_tx
  18. serial_ir_tx_duty_cycle
  19. serial_ir_tx_carrier
  20. serial_ir_suspend
  21. serial_ir_resume
  22. serial_ir_init
  23. serial_ir_exit
  24. serial_ir_init_module
  25. serial_ir_exit_module

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * serial_ir.c
   4  *
   5  * serial_ir - Device driver that records pulse- and pause-lengths
   6  *             (space-lengths) between DDCD event on a serial port.
   7  *
   8  * Copyright (C) 1996,97 Ralph Metzler <rjkm@thp.uni-koeln.de>
   9  * Copyright (C) 1998 Trent Piepho <xyzzy@u.washington.edu>
  10  * Copyright (C) 1998 Ben Pfaff <blp@gnu.org>
  11  * Copyright (C) 1999 Christoph Bartelmus <lirc@bartelmus.de>
  12  * Copyright (C) 2007 Andrei Tanas <andrei@tanas.ca> (suspend/resume support)
  13  * Copyright (C) 2016 Sean Young <sean@mess.org> (port to rc-core)
  14  */
  15 
  16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  17 
  18 #include <linux/module.h>
  19 #include <linux/errno.h>
  20 #include <linux/interrupt.h>
  21 #include <linux/kernel.h>
  22 #include <linux/serial_reg.h>
  23 #include <linux/types.h>
  24 #include <linux/delay.h>
  25 #include <linux/platform_device.h>
  26 #include <linux/spinlock.h>
  27 #include <media/rc-core.h>
  28 
  29 struct serial_ir_hw {
  30         int signal_pin;
  31         int signal_pin_change;
  32         u8 on;
  33         u8 off;
  34         unsigned set_send_carrier:1;
  35         unsigned set_duty_cycle:1;
  36         void (*send_pulse)(unsigned int length, ktime_t edge);
  37         void (*send_space)(void);
  38         spinlock_t lock;
  39 };
  40 
  41 #define IR_HOMEBREW     0
  42 #define IR_IRDEO        1
  43 #define IR_IRDEO_REMOTE 2
  44 #define IR_ANIMAX       3
  45 #define IR_IGOR         4
  46 
  47 /* module parameters */
  48 static int type;
  49 static int io;
  50 static int irq;
  51 static ulong iommap;
  52 static int ioshift;
  53 static bool softcarrier = true;
  54 static bool share_irq;
  55 static int sense = -1;  /* -1 = auto, 0 = active high, 1 = active low */
  56 static bool txsense;    /* 0 = active high, 1 = active low */
  57 
  58 /* forward declarations */
  59 static void send_pulse_irdeo(unsigned int length, ktime_t edge);
  60 static void send_space_irdeo(void);
  61 #ifdef CONFIG_IR_SERIAL_TRANSMITTER
  62 static void send_pulse_homebrew(unsigned int length, ktime_t edge);
  63 static void send_space_homebrew(void);
  64 #endif
  65 
  66 static struct serial_ir_hw hardware[] = {
  67         [IR_HOMEBREW] = {
  68                 .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_HOMEBREW].lock),
  69                 .signal_pin        = UART_MSR_DCD,
  70                 .signal_pin_change = UART_MSR_DDCD,
  71                 .on  = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR),
  72                 .off = (UART_MCR_RTS | UART_MCR_OUT2),
  73 #ifdef CONFIG_IR_SERIAL_TRANSMITTER
  74                 .send_pulse = send_pulse_homebrew,
  75                 .send_space = send_space_homebrew,
  76                 .set_send_carrier = true,
  77                 .set_duty_cycle = true,
  78 #endif
  79         },
  80 
  81         [IR_IRDEO] = {
  82                 .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IRDEO].lock),
  83                 .signal_pin        = UART_MSR_DSR,
  84                 .signal_pin_change = UART_MSR_DDSR,
  85                 .on  = UART_MCR_OUT2,
  86                 .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2),
  87                 .send_pulse = send_pulse_irdeo,
  88                 .send_space = send_space_irdeo,
  89                 .set_duty_cycle = true,
  90         },
  91 
  92         [IR_IRDEO_REMOTE] = {
  93                 .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IRDEO_REMOTE].lock),
  94                 .signal_pin        = UART_MSR_DSR,
  95                 .signal_pin_change = UART_MSR_DDSR,
  96                 .on  = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2),
  97                 .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2),
  98                 .send_pulse = send_pulse_irdeo,
  99                 .send_space = send_space_irdeo,
 100                 .set_duty_cycle = true,
 101         },
 102 
 103         [IR_ANIMAX] = {
 104                 .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_ANIMAX].lock),
 105                 .signal_pin        = UART_MSR_DCD,
 106                 .signal_pin_change = UART_MSR_DDCD,
 107                 .on  = 0,
 108                 .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2),
 109         },
 110 
 111         [IR_IGOR] = {
 112                 .lock = __SPIN_LOCK_UNLOCKED(hardware[IR_IGOR].lock),
 113                 .signal_pin        = UART_MSR_DSR,
 114                 .signal_pin_change = UART_MSR_DDSR,
 115                 .on  = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR),
 116                 .off = (UART_MCR_RTS | UART_MCR_OUT2),
 117 #ifdef CONFIG_IR_SERIAL_TRANSMITTER
 118                 .send_pulse = send_pulse_homebrew,
 119                 .send_space = send_space_homebrew,
 120                 .set_send_carrier = true,
 121                 .set_duty_cycle = true,
 122 #endif
 123         },
 124 };
 125 
 126 #define RS_ISR_PASS_LIMIT 256
 127 
 128 struct serial_ir {
 129         ktime_t lastkt;
 130         struct rc_dev *rcdev;
 131         struct platform_device *pdev;
 132         struct timer_list timeout_timer;
 133 
 134         unsigned int carrier;
 135         unsigned int duty_cycle;
 136 };
 137 
 138 static struct serial_ir serial_ir;
 139 
 140 /* fetch serial input packet (1 byte) from register offset */
 141 static u8 sinp(int offset)
 142 {
 143         if (iommap)
 144                 /* the register is memory-mapped */
 145                 offset <<= ioshift;
 146 
 147         return inb(io + offset);
 148 }
 149 
 150 /* write serial output packet (1 byte) of value to register offset */
 151 static void soutp(int offset, u8 value)
 152 {
 153         if (iommap)
 154                 /* the register is memory-mapped */
 155                 offset <<= ioshift;
 156 
 157         outb(value, io + offset);
 158 }
 159 
 160 static void on(void)
 161 {
 162         if (txsense)
 163                 soutp(UART_MCR, hardware[type].off);
 164         else
 165                 soutp(UART_MCR, hardware[type].on);
 166 }
 167 
 168 static void off(void)
 169 {
 170         if (txsense)
 171                 soutp(UART_MCR, hardware[type].on);
 172         else
 173                 soutp(UART_MCR, hardware[type].off);
 174 }
 175 
 176 static void send_pulse_irdeo(unsigned int length, ktime_t target)
 177 {
 178         long rawbits;
 179         int i;
 180         unsigned char output;
 181         unsigned char chunk, shifted;
 182 
 183         /* how many bits have to be sent ? */
 184         rawbits = length * 1152 / 10000;
 185         if (serial_ir.duty_cycle > 50)
 186                 chunk = 3;
 187         else
 188                 chunk = 1;
 189         for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) {
 190                 shifted = chunk << (i * 3);
 191                 shifted >>= 1;
 192                 output &= (~shifted);
 193                 i++;
 194                 if (i == 3) {
 195                         soutp(UART_TX, output);
 196                         while (!(sinp(UART_LSR) & UART_LSR_THRE))
 197                                 ;
 198                         output = 0x7f;
 199                         i = 0;
 200                 }
 201         }
 202         if (i != 0) {
 203                 soutp(UART_TX, output);
 204                 while (!(sinp(UART_LSR) & UART_LSR_TEMT))
 205                         ;
 206         }
 207 }
 208 
 209 static void send_space_irdeo(void)
 210 {
 211 }
 212 
 213 #ifdef CONFIG_IR_SERIAL_TRANSMITTER
 214 static void send_pulse_homebrew_softcarrier(unsigned int length, ktime_t edge)
 215 {
 216         ktime_t now, target = ktime_add_us(edge, length);
 217         /*
 218          * delta should never exceed 4 seconds and on m68k
 219          * ndelay(s64) does not compile; so use s32 rather than s64.
 220          */
 221         s32 delta;
 222         unsigned int pulse, space;
 223 
 224         /* Ensure the dividend fits into 32 bit */
 225         pulse = DIV_ROUND_CLOSEST(serial_ir.duty_cycle * (NSEC_PER_SEC / 100),
 226                                   serial_ir.carrier);
 227         space = DIV_ROUND_CLOSEST((100 - serial_ir.duty_cycle) *
 228                                   (NSEC_PER_SEC / 100), serial_ir.carrier);
 229 
 230         for (;;) {
 231                 now = ktime_get();
 232                 if (ktime_compare(now, target) >= 0)
 233                         break;
 234                 on();
 235                 edge = ktime_add_ns(edge, pulse);
 236                 delta = ktime_to_ns(ktime_sub(edge, now));
 237                 if (delta > 0)
 238                         ndelay(delta);
 239                 now = ktime_get();
 240                 off();
 241                 if (ktime_compare(now, target) >= 0)
 242                         break;
 243                 edge = ktime_add_ns(edge, space);
 244                 delta = ktime_to_ns(ktime_sub(edge, now));
 245                 if (delta > 0)
 246                         ndelay(delta);
 247         }
 248 }
 249 
 250 static void send_pulse_homebrew(unsigned int length, ktime_t edge)
 251 {
 252         if (softcarrier)
 253                 send_pulse_homebrew_softcarrier(length, edge);
 254         else
 255                 on();
 256 }
 257 
 258 static void send_space_homebrew(void)
 259 {
 260         off();
 261 }
 262 #endif
 263 
 264 static void frbwrite(unsigned int l, bool is_pulse)
 265 {
 266         /* simple noise filter */
 267         static unsigned int ptr, pulse, space;
 268         struct ir_raw_event ev = {};
 269 
 270         if (ptr > 0 && is_pulse) {
 271                 pulse += l;
 272                 if (pulse > 250000) {
 273                         ev.duration = space;
 274                         ev.pulse = false;
 275                         ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
 276                         ev.duration = pulse;
 277                         ev.pulse = true;
 278                         ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
 279                         ptr = 0;
 280                         pulse = 0;
 281                 }
 282                 return;
 283         }
 284         if (!is_pulse) {
 285                 if (ptr == 0) {
 286                         if (l > 20000000) {
 287                                 space = l;
 288                                 ptr++;
 289                                 return;
 290                         }
 291                 } else {
 292                         if (l > 20000000) {
 293                                 space += pulse;
 294                                 if (space > IR_MAX_DURATION)
 295                                         space = IR_MAX_DURATION;
 296                                 space += l;
 297                                 if (space > IR_MAX_DURATION)
 298                                         space = IR_MAX_DURATION;
 299                                 pulse = 0;
 300                                 return;
 301                         }
 302 
 303                         ev.duration = space;
 304                         ev.pulse = false;
 305                         ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
 306                         ev.duration = pulse;
 307                         ev.pulse = true;
 308                         ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
 309                         ptr = 0;
 310                         pulse = 0;
 311                 }
 312         }
 313 
 314         ev.duration = l;
 315         ev.pulse = is_pulse;
 316         ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
 317 }
 318 
 319 static irqreturn_t serial_ir_irq_handler(int i, void *blah)
 320 {
 321         ktime_t kt;
 322         int counter, dcd;
 323         u8 status;
 324         ktime_t delkt;
 325         unsigned int data;
 326         static int last_dcd = -1;
 327 
 328         if ((sinp(UART_IIR) & UART_IIR_NO_INT)) {
 329                 /* not our interrupt */
 330                 return IRQ_NONE;
 331         }
 332 
 333         counter = 0;
 334         do {
 335                 counter++;
 336                 status = sinp(UART_MSR);
 337                 if (counter > RS_ISR_PASS_LIMIT) {
 338                         dev_err(&serial_ir.pdev->dev, "Trapped in interrupt");
 339                         break;
 340                 }
 341                 if ((status & hardware[type].signal_pin_change) &&
 342                     sense != -1) {
 343                         /* get current time */
 344                         kt = ktime_get();
 345 
 346                         /*
 347                          * The driver needs to know if your receiver is
 348                          * active high or active low, or the space/pulse
 349                          * sense could be inverted.
 350                          */
 351 
 352                         /* calc time since last interrupt in nanoseconds */
 353                         dcd = (status & hardware[type].signal_pin) ? 1 : 0;
 354 
 355                         if (dcd == last_dcd) {
 356                                 dev_err(&serial_ir.pdev->dev,
 357                                         "ignoring spike: %d %d %lldns %lldns\n",
 358                                         dcd, sense, ktime_to_ns(kt),
 359                                         ktime_to_ns(serial_ir.lastkt));
 360                                 continue;
 361                         }
 362 
 363                         delkt = ktime_sub(kt, serial_ir.lastkt);
 364                         if (ktime_compare(delkt, ktime_set(15, 0)) > 0) {
 365                                 data = IR_MAX_DURATION; /* really long time */
 366                                 if (!(dcd ^ sense)) {
 367                                         /* sanity check */
 368                                         dev_err(&serial_ir.pdev->dev,
 369                                                 "dcd unexpected: %d %d %lldns %lldns\n",
 370                                                 dcd, sense, ktime_to_ns(kt),
 371                                                 ktime_to_ns(serial_ir.lastkt));
 372                                         /*
 373                                          * detecting pulse while this
 374                                          * MUST be a space!
 375                                          */
 376                                         sense = sense ? 0 : 1;
 377                                 }
 378                         } else {
 379                                 data = ktime_to_ns(delkt);
 380                         }
 381                         frbwrite(data, !(dcd ^ sense));
 382                         serial_ir.lastkt = kt;
 383                         last_dcd = dcd;
 384                 }
 385         } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */
 386 
 387         mod_timer(&serial_ir.timeout_timer,
 388                   jiffies + nsecs_to_jiffies(serial_ir.rcdev->timeout));
 389 
 390         ir_raw_event_handle(serial_ir.rcdev);
 391 
 392         return IRQ_HANDLED;
 393 }
 394 
 395 static int hardware_init_port(void)
 396 {
 397         u8 scratch, scratch2, scratch3;
 398 
 399         /*
 400          * This is a simple port existence test, borrowed from the autoconfig
 401          * function in drivers/tty/serial/8250/8250_port.c
 402          */
 403         scratch = sinp(UART_IER);
 404         soutp(UART_IER, 0);
 405 #ifdef __i386__
 406         outb(0xff, 0x080);
 407 #endif
 408         scratch2 = sinp(UART_IER) & 0x0f;
 409         soutp(UART_IER, 0x0f);
 410 #ifdef __i386__
 411         outb(0x00, 0x080);
 412 #endif
 413         scratch3 = sinp(UART_IER) & 0x0f;
 414         soutp(UART_IER, scratch);
 415         if (scratch2 != 0 || scratch3 != 0x0f) {
 416                 /* we fail, there's nothing here */
 417                 pr_err("port existence test failed, cannot continue\n");
 418                 return -ENODEV;
 419         }
 420 
 421         /* Set DLAB 0. */
 422         soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
 423 
 424         /* First of all, disable all interrupts */
 425         soutp(UART_IER, sinp(UART_IER) &
 426               (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI)));
 427 
 428         /* Clear registers. */
 429         sinp(UART_LSR);
 430         sinp(UART_RX);
 431         sinp(UART_IIR);
 432         sinp(UART_MSR);
 433 
 434         /* Set line for power source */
 435         off();
 436 
 437         /* Clear registers again to be sure. */
 438         sinp(UART_LSR);
 439         sinp(UART_RX);
 440         sinp(UART_IIR);
 441         sinp(UART_MSR);
 442 
 443         switch (type) {
 444         case IR_IRDEO:
 445         case IR_IRDEO_REMOTE:
 446                 /* setup port to 7N1 @ 115200 Baud */
 447                 /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */
 448 
 449                 /* Set DLAB 1. */
 450                 soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
 451                 /* Set divisor to 1 => 115200 Baud */
 452                 soutp(UART_DLM, 0);
 453                 soutp(UART_DLL, 1);
 454                 /* Set DLAB 0 +  7N1 */
 455                 soutp(UART_LCR, UART_LCR_WLEN7);
 456                 /* THR interrupt already disabled at this point */
 457                 break;
 458         default:
 459                 break;
 460         }
 461 
 462         return 0;
 463 }
 464 
 465 static void serial_ir_timeout(struct timer_list *unused)
 466 {
 467         struct ir_raw_event ev = {
 468                 .timeout = true,
 469                 .duration = serial_ir.rcdev->timeout
 470         };
 471         ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
 472         ir_raw_event_handle(serial_ir.rcdev);
 473 }
 474 
 475 /* Needed by serial_ir_probe() */
 476 static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
 477                         unsigned int count);
 478 static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle);
 479 static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier);
 480 static int serial_ir_open(struct rc_dev *rcdev);
 481 static void serial_ir_close(struct rc_dev *rcdev);
 482 
 483 static int serial_ir_probe(struct platform_device *dev)
 484 {
 485         struct rc_dev *rcdev;
 486         int i, nlow, nhigh, result;
 487 
 488         rcdev = devm_rc_allocate_device(&dev->dev, RC_DRIVER_IR_RAW);
 489         if (!rcdev)
 490                 return -ENOMEM;
 491 
 492         if (hardware[type].send_pulse && hardware[type].send_space)
 493                 rcdev->tx_ir = serial_ir_tx;
 494         if (hardware[type].set_send_carrier)
 495                 rcdev->s_tx_carrier = serial_ir_tx_carrier;
 496         if (hardware[type].set_duty_cycle)
 497                 rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle;
 498 
 499         switch (type) {
 500         case IR_HOMEBREW:
 501                 rcdev->device_name = "Serial IR type home-brew";
 502                 break;
 503         case IR_IRDEO:
 504                 rcdev->device_name = "Serial IR type IRdeo";
 505                 break;
 506         case IR_IRDEO_REMOTE:
 507                 rcdev->device_name = "Serial IR type IRdeo remote";
 508                 break;
 509         case IR_ANIMAX:
 510                 rcdev->device_name = "Serial IR type AnimaX";
 511                 break;
 512         case IR_IGOR:
 513                 rcdev->device_name = "Serial IR type IgorPlug";
 514                 break;
 515         }
 516 
 517         rcdev->input_phys = KBUILD_MODNAME "/input0";
 518         rcdev->input_id.bustype = BUS_HOST;
 519         rcdev->input_id.vendor = 0x0001;
 520         rcdev->input_id.product = 0x0001;
 521         rcdev->input_id.version = 0x0100;
 522         rcdev->open = serial_ir_open;
 523         rcdev->close = serial_ir_close;
 524         rcdev->dev.parent = &serial_ir.pdev->dev;
 525         rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
 526         rcdev->driver_name = KBUILD_MODNAME;
 527         rcdev->map_name = RC_MAP_RC6_MCE;
 528         rcdev->min_timeout = 1;
 529         rcdev->timeout = IR_DEFAULT_TIMEOUT;
 530         rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
 531         rcdev->rx_resolution = 250000;
 532 
 533         serial_ir.rcdev = rcdev;
 534 
 535         timer_setup(&serial_ir.timeout_timer, serial_ir_timeout, 0);
 536 
 537         result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler,
 538                                   share_irq ? IRQF_SHARED : 0,
 539                                   KBUILD_MODNAME, &hardware);
 540         if (result < 0) {
 541                 if (result == -EBUSY)
 542                         dev_err(&dev->dev, "IRQ %d busy\n", irq);
 543                 else if (result == -EINVAL)
 544                         dev_err(&dev->dev, "Bad irq number or handler\n");
 545                 return result;
 546         }
 547 
 548         /* Reserve io region. */
 549         if ((iommap &&
 550              (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift,
 551                                       KBUILD_MODNAME) == NULL)) ||
 552              (!iommap && (devm_request_region(&dev->dev, io, 8,
 553                           KBUILD_MODNAME) == NULL))) {
 554                 dev_err(&dev->dev, "port %04x already in use\n", io);
 555                 dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n");
 556                 dev_warn(&dev->dev,
 557                          "or compile the serial port driver as module and\n");
 558                 dev_warn(&dev->dev, "make sure this module is loaded first\n");
 559                 return -EBUSY;
 560         }
 561 
 562         result = hardware_init_port();
 563         if (result < 0)
 564                 return result;
 565 
 566         /* Initialize pulse/space widths */
 567         serial_ir.duty_cycle = 50;
 568         serial_ir.carrier = 38000;
 569 
 570         /* If pin is high, then this must be an active low receiver. */
 571         if (sense == -1) {
 572                 /* wait 1/2 sec for the power supply */
 573                 msleep(500);
 574 
 575                 /*
 576                  * probe 9 times every 0.04s, collect "votes" for
 577                  * active high/low
 578                  */
 579                 nlow = 0;
 580                 nhigh = 0;
 581                 for (i = 0; i < 9; i++) {
 582                         if (sinp(UART_MSR) & hardware[type].signal_pin)
 583                                 nlow++;
 584                         else
 585                                 nhigh++;
 586                         msleep(40);
 587                 }
 588                 sense = nlow >= nhigh ? 1 : 0;
 589                 dev_info(&dev->dev, "auto-detected active %s receiver\n",
 590                          sense ? "low" : "high");
 591         } else
 592                 dev_info(&dev->dev, "Manually using active %s receiver\n",
 593                          sense ? "low" : "high");
 594 
 595         dev_dbg(&dev->dev, "Interrupt %d, port %04x obtained\n", irq, io);
 596 
 597         return devm_rc_register_device(&dev->dev, rcdev);
 598 }
 599 
 600 static int serial_ir_open(struct rc_dev *rcdev)
 601 {
 602         unsigned long flags;
 603 
 604         /* initialize timestamp */
 605         serial_ir.lastkt = ktime_get();
 606 
 607         spin_lock_irqsave(&hardware[type].lock, flags);
 608 
 609         /* Set DLAB 0. */
 610         soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
 611 
 612         soutp(UART_IER, sinp(UART_IER) | UART_IER_MSI);
 613 
 614         spin_unlock_irqrestore(&hardware[type].lock, flags);
 615 
 616         return 0;
 617 }
 618 
 619 static void serial_ir_close(struct rc_dev *rcdev)
 620 {
 621         unsigned long flags;
 622 
 623         spin_lock_irqsave(&hardware[type].lock, flags);
 624 
 625         /* Set DLAB 0. */
 626         soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
 627 
 628         /* First of all, disable all interrupts */
 629         soutp(UART_IER, sinp(UART_IER) &
 630               (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI)));
 631         spin_unlock_irqrestore(&hardware[type].lock, flags);
 632 }
 633 
 634 static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
 635                         unsigned int count)
 636 {
 637         unsigned long flags;
 638         ktime_t edge;
 639         s64 delta;
 640         int i;
 641 
 642         spin_lock_irqsave(&hardware[type].lock, flags);
 643         if (type == IR_IRDEO) {
 644                 /* DTR, RTS down */
 645                 on();
 646         }
 647 
 648         edge = ktime_get();
 649         for (i = 0; i < count; i++) {
 650                 if (i % 2)
 651                         hardware[type].send_space();
 652                 else
 653                         hardware[type].send_pulse(txbuf[i], edge);
 654 
 655                 edge = ktime_add_us(edge, txbuf[i]);
 656                 delta = ktime_us_delta(edge, ktime_get());
 657                 if (delta > 25) {
 658                         spin_unlock_irqrestore(&hardware[type].lock, flags);
 659                         usleep_range(delta - 25, delta + 25);
 660                         spin_lock_irqsave(&hardware[type].lock, flags);
 661                 } else if (delta > 0) {
 662                         udelay(delta);
 663                 }
 664         }
 665         off();
 666         spin_unlock_irqrestore(&hardware[type].lock, flags);
 667         return count;
 668 }
 669 
 670 static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle)
 671 {
 672         serial_ir.duty_cycle = cycle;
 673         return 0;
 674 }
 675 
 676 static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier)
 677 {
 678         if (carrier > 500000 || carrier < 20000)
 679                 return -EINVAL;
 680 
 681         serial_ir.carrier = carrier;
 682         return 0;
 683 }
 684 
 685 static int serial_ir_suspend(struct platform_device *dev,
 686                              pm_message_t state)
 687 {
 688         /* Set DLAB 0. */
 689         soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
 690 
 691         /* Disable all interrupts */
 692         soutp(UART_IER, sinp(UART_IER) &
 693               (~(UART_IER_MSI | UART_IER_RLSI | UART_IER_THRI | UART_IER_RDI)));
 694 
 695         /* Clear registers. */
 696         sinp(UART_LSR);
 697         sinp(UART_RX);
 698         sinp(UART_IIR);
 699         sinp(UART_MSR);
 700 
 701         return 0;
 702 }
 703 
 704 static int serial_ir_resume(struct platform_device *dev)
 705 {
 706         unsigned long flags;
 707         int result;
 708 
 709         result = hardware_init_port();
 710         if (result < 0)
 711                 return result;
 712 
 713         spin_lock_irqsave(&hardware[type].lock, flags);
 714         /* Enable Interrupt */
 715         serial_ir.lastkt = ktime_get();
 716         soutp(UART_IER, sinp(UART_IER) | UART_IER_MSI);
 717         off();
 718 
 719         spin_unlock_irqrestore(&hardware[type].lock, flags);
 720 
 721         return 0;
 722 }
 723 
 724 static struct platform_driver serial_ir_driver = {
 725         .probe          = serial_ir_probe,
 726         .suspend        = serial_ir_suspend,
 727         .resume         = serial_ir_resume,
 728         .driver         = {
 729                 .name   = "serial_ir",
 730         },
 731 };
 732 
 733 static int __init serial_ir_init(void)
 734 {
 735         int result;
 736 
 737         result = platform_driver_register(&serial_ir_driver);
 738         if (result)
 739                 return result;
 740 
 741         serial_ir.pdev = platform_device_alloc("serial_ir", 0);
 742         if (!serial_ir.pdev) {
 743                 result = -ENOMEM;
 744                 goto exit_driver_unregister;
 745         }
 746 
 747         result = platform_device_add(serial_ir.pdev);
 748         if (result)
 749                 goto exit_device_put;
 750 
 751         return 0;
 752 
 753 exit_device_put:
 754         platform_device_put(serial_ir.pdev);
 755 exit_driver_unregister:
 756         platform_driver_unregister(&serial_ir_driver);
 757         return result;
 758 }
 759 
 760 static void serial_ir_exit(void)
 761 {
 762         platform_device_unregister(serial_ir.pdev);
 763         platform_driver_unregister(&serial_ir_driver);
 764 }
 765 
 766 static int __init serial_ir_init_module(void)
 767 {
 768         switch (type) {
 769         case IR_HOMEBREW:
 770         case IR_IRDEO:
 771         case IR_IRDEO_REMOTE:
 772         case IR_ANIMAX:
 773         case IR_IGOR:
 774                 /* if nothing specified, use ttyS0/com1 and irq 4 */
 775                 io = io ? io : 0x3f8;
 776                 irq = irq ? irq : 4;
 777                 break;
 778         default:
 779                 return -EINVAL;
 780         }
 781         if (!softcarrier) {
 782                 switch (type) {
 783                 case IR_HOMEBREW:
 784                 case IR_IGOR:
 785                         hardware[type].set_send_carrier = false;
 786                         hardware[type].set_duty_cycle = false;
 787                         break;
 788                 }
 789         }
 790 
 791         /* make sure sense is either -1, 0, or 1 */
 792         if (sense != -1)
 793                 sense = !!sense;
 794 
 795         return serial_ir_init();
 796 }
 797 
 798 static void __exit serial_ir_exit_module(void)
 799 {
 800         del_timer_sync(&serial_ir.timeout_timer);
 801         serial_ir_exit();
 802 }
 803 
 804 module_init(serial_ir_init_module);
 805 module_exit(serial_ir_exit_module);
 806 
 807 MODULE_DESCRIPTION("Infra-red receiver driver for serial ports.");
 808 MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, Christoph Bartelmus, Andrei Tanas");
 809 MODULE_LICENSE("GPL");
 810 
 811 module_param(type, int, 0444);
 812 MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo, 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug");
 813 
 814 module_param_hw(io, int, ioport, 0444);
 815 MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
 816 
 817 /* some architectures (e.g. intel xscale) have memory mapped registers */
 818 module_param_hw(iommap, ulong, other, 0444);
 819 MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O (0 = no memory mapped io)");
 820 
 821 /*
 822  * some architectures (e.g. intel xscale) align the 8bit serial registers
 823  * on 32bit word boundaries.
 824  * See linux-kernel/drivers/tty/serial/8250/8250.c serial_in()/out()
 825  */
 826 module_param_hw(ioshift, int, other, 0444);
 827 MODULE_PARM_DESC(ioshift, "shift I/O register offset (0 = no shift)");
 828 
 829 module_param_hw(irq, int, irq, 0444);
 830 MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
 831 
 832 module_param_hw(share_irq, bool, other, 0444);
 833 MODULE_PARM_DESC(share_irq, "Share interrupts (0 = off, 1 = on)");
 834 
 835 module_param(sense, int, 0444);
 836 MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit (0 = active high, 1 = active low )");
 837 
 838 #ifdef CONFIG_IR_SERIAL_TRANSMITTER
 839 module_param(txsense, bool, 0444);
 840 MODULE_PARM_DESC(txsense, "Sense of transmitter circuit (0 = active high, 1 = active low )");
 841 #endif
 842 
 843 module_param(softcarrier, bool, 0444);
 844 MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");

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