linux/drivers/media/rc/serial_ir.c
<<
>>
Prefs
   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
  29struct 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 */
  48static int type;
  49static int io;
  50static int irq;
  51static ulong iommap;
  52static int ioshift;
  53static bool softcarrier = true;
  54static bool share_irq;
  55static int sense = -1;  /* -1 = auto, 0 = active high, 1 = active low */
  56static bool txsense;    /* 0 = active high, 1 = active low */
  57
  58/* forward declarations */
  59static void send_pulse_irdeo(unsigned int length, ktime_t edge);
  60static void send_space_irdeo(void);
  61#ifdef CONFIG_IR_SERIAL_TRANSMITTER
  62static void send_pulse_homebrew(unsigned int length, ktime_t edge);
  63static void send_space_homebrew(void);
  64#endif
  65
  66static 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
 128struct 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
 138static struct serial_ir serial_ir;
 139
 140/* fetch serial input packet (1 byte) from register offset */
 141static 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 */
 151static 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
 160static 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
 168static 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
 176static 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
 209static void send_space_irdeo(void)
 210{
 211}
 212
 213#ifdef CONFIG_IR_SERIAL_TRANSMITTER
 214static 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
 250static 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
 258static void send_space_homebrew(void)
 259{
 260        off();
 261}
 262#endif
 263
 264static 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 > 250) {
 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 > 20000) {
 287                                space = l;
 288                                ptr++;
 289                                return;
 290                        }
 291                } else {
 292                        if (l > 20000) {
 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
 319static 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_dbg(&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_us(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
 395static 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
 465static 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() */
 476static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
 477                        unsigned int count);
 478static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle);
 479static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier);
 480static int serial_ir_open(struct rc_dev *rcdev);
 481static void serial_ir_close(struct rc_dev *rcdev);
 482
 483static 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 = 250;
 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, 8UL << 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
 600static 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
 619static 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
 634static 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
 670static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle)
 671{
 672        serial_ir.duty_cycle = cycle;
 673        return 0;
 674}
 675
 676static 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
 685static 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
 704static 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
 724static 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
 733static 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
 753exit_device_put:
 754        platform_device_put(serial_ir.pdev);
 755exit_driver_unregister:
 756        platform_driver_unregister(&serial_ir_driver);
 757        return result;
 758}
 759
 760static void serial_ir_exit(void)
 761{
 762        platform_device_unregister(serial_ir.pdev);
 763        platform_driver_unregister(&serial_ir_driver);
 764}
 765
 766static 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
 798static void __exit serial_ir_exit_module(void)
 799{
 800        del_timer_sync(&serial_ir.timeout_timer);
 801        serial_ir_exit();
 802}
 803
 804module_init(serial_ir_init_module);
 805module_exit(serial_ir_exit_module);
 806
 807MODULE_DESCRIPTION("Infra-red receiver driver for serial ports.");
 808MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, Christoph Bartelmus, Andrei Tanas");
 809MODULE_LICENSE("GPL");
 810
 811module_param(type, int, 0444);
 812MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo, 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug");
 813
 814module_param_hw(io, int, ioport, 0444);
 815MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
 816
 817/* some architectures (e.g. intel xscale) have memory mapped registers */
 818module_param_hw(iommap, ulong, other, 0444);
 819MODULE_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 */
 826module_param_hw(ioshift, int, other, 0444);
 827MODULE_PARM_DESC(ioshift, "shift I/O register offset (0 = no shift)");
 828
 829module_param_hw(irq, int, irq, 0444);
 830MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
 831
 832module_param_hw(share_irq, bool, other, 0444);
 833MODULE_PARM_DESC(share_irq, "Share interrupts (0 = off, 1 = on)");
 834
 835module_param(sense, int, 0444);
 836MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit (0 = active high, 1 = active low )");
 837
 838#ifdef CONFIG_IR_SERIAL_TRANSMITTER
 839module_param(txsense, bool, 0444);
 840MODULE_PARM_DESC(txsense, "Sense of transmitter circuit (0 = active high, 1 = active low )");
 841#endif
 842
 843module_param(softcarrier, bool, 0444);
 844MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
 845