linux/drivers/media/rc/st_rc.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 STMicroelectronics Limited
   3 * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 */
  10#include <linux/kernel.h>
  11#include <linux/clk.h>
  12#include <linux/interrupt.h>
  13#include <linux/module.h>
  14#include <linux/of.h>
  15#include <linux/platform_device.h>
  16#include <linux/reset.h>
  17#include <media/rc-core.h>
  18#include <linux/pinctrl/consumer.h>
  19#include <linux/pm_wakeirq.h>
  20
  21struct st_rc_device {
  22        struct device                   *dev;
  23        int                             irq;
  24        int                             irq_wake;
  25        struct clk                      *sys_clock;
  26        void __iomem                    *base;  /* Register base address */
  27        void __iomem                    *rx_base;/* RX Register base address */
  28        struct rc_dev                   *rdev;
  29        bool                            overclocking;
  30        int                             sample_mult;
  31        int                             sample_div;
  32        bool                            rxuhfmode;
  33        struct  reset_control           *rstc;
  34};
  35
  36/* Registers */
  37#define IRB_SAMPLE_RATE_COMM    0x64    /* sample freq divisor*/
  38#define IRB_CLOCK_SEL           0x70    /* clock select       */
  39#define IRB_CLOCK_SEL_STATUS    0x74    /* clock status       */
  40/* IRB IR/UHF receiver registers */
  41#define IRB_RX_ON               0x40    /* pulse time capture */
  42#define IRB_RX_SYS              0X44    /* sym period capture */
  43#define IRB_RX_INT_EN           0x48    /* IRQ enable (R/W)   */
  44#define IRB_RX_INT_STATUS       0x4c    /* IRQ status (R/W)   */
  45#define IRB_RX_EN               0x50    /* Receive enable     */
  46#define IRB_MAX_SYM_PERIOD      0x54    /* max sym value      */
  47#define IRB_RX_INT_CLEAR        0x58    /* overrun status     */
  48#define IRB_RX_STATUS           0x6c    /* receive status     */
  49#define IRB_RX_NOISE_SUPPR      0x5c    /* noise suppression  */
  50#define IRB_RX_POLARITY_INV     0x68    /* polarity inverter  */
  51
  52/**
  53 * IRQ set: Enable full FIFO                 1  -> bit  3;
  54 *          Enable overrun IRQ               1  -> bit  2;
  55 *          Enable last symbol IRQ           1  -> bit  1:
  56 *          Enable RX interrupt              1  -> bit  0;
  57 */
  58#define IRB_RX_INTS             0x0f
  59#define IRB_RX_OVERRUN_INT      0x04
  60 /* maximum symbol period (microsecs),timeout to detect end of symbol train */
  61#define MAX_SYMB_TIME           0x5000
  62#define IRB_SAMPLE_FREQ         10000000
  63#define IRB_FIFO_NOT_EMPTY      0xff00
  64#define IRB_OVERFLOW            0x4
  65#define IRB_TIMEOUT             0xffff
  66#define IR_ST_NAME "st-rc"
  67
  68static void st_rc_send_lirc_timeout(struct rc_dev *rdev)
  69{
  70        DEFINE_IR_RAW_EVENT(ev);
  71        ev.timeout = true;
  72        ir_raw_event_store(rdev, &ev);
  73}
  74
  75/**
  76 * RX graphical example to better understand the difference between ST IR block
  77 * output and standard definition used by LIRC (and most of the world!)
  78 *
  79 *           mark                                     mark
  80 *      |-IRB_RX_ON-|                            |-IRB_RX_ON-|
  81 *      ___  ___  ___                            ___  ___  ___             _
  82 *      | |  | |  | |                            | |  | |  | |             |
  83 *      | |  | |  | |         space 0            | |  | |  | |   space 1   |
  84 * _____| |__| |__| |____________________________| |__| |__| |_____________|
  85 *
  86 *      |--------------- IRB_RX_SYS -------------|------ IRB_RX_SYS -------|
  87 *
  88 *      |------------- encoding bit 0 -----------|---- encoding bit 1 -----|
  89 *
  90 * ST hardware returns mark (IRB_RX_ON) and total symbol time (IRB_RX_SYS), so
  91 * convert to standard mark/space we have to calculate space=(IRB_RX_SYS-mark)
  92 * The mark time represents the amount of time the carrier (usually 36-40kHz)
  93 * is detected.The above examples shows Pulse Width Modulation encoding where
  94 * bit 0 is represented by space>mark.
  95 */
  96
  97static irqreturn_t st_rc_rx_interrupt(int irq, void *data)
  98{
  99        unsigned int symbol, mark = 0;
 100        struct st_rc_device *dev = data;
 101        int last_symbol = 0;
 102        u32 status;
 103        DEFINE_IR_RAW_EVENT(ev);
 104
 105        if (dev->irq_wake)
 106                pm_wakeup_event(dev->dev, 0);
 107
 108        status  = readl(dev->rx_base + IRB_RX_STATUS);
 109
 110        while (status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW)) {
 111                u32 int_status = readl(dev->rx_base + IRB_RX_INT_STATUS);
 112                if (unlikely(int_status & IRB_RX_OVERRUN_INT)) {
 113                        /* discard the entire collection in case of errors!  */
 114                        ir_raw_event_reset(dev->rdev);
 115                        dev_info(dev->dev, "IR RX overrun\n");
 116                        writel(IRB_RX_OVERRUN_INT,
 117                                        dev->rx_base + IRB_RX_INT_CLEAR);
 118                        continue;
 119                }
 120
 121                symbol = readl(dev->rx_base + IRB_RX_SYS);
 122                mark = readl(dev->rx_base + IRB_RX_ON);
 123
 124                if (symbol == IRB_TIMEOUT)
 125                        last_symbol = 1;
 126
 127                 /* Ignore any noise */
 128                if ((mark > 2) && (symbol > 1)) {
 129                        symbol -= mark;
 130                        if (dev->overclocking) { /* adjustments to timings */
 131                                symbol *= dev->sample_mult;
 132                                symbol /= dev->sample_div;
 133                                mark *= dev->sample_mult;
 134                                mark /= dev->sample_div;
 135                        }
 136
 137                        ev.duration = US_TO_NS(mark);
 138                        ev.pulse = true;
 139                        ir_raw_event_store(dev->rdev, &ev);
 140
 141                        if (!last_symbol) {
 142                                ev.duration = US_TO_NS(symbol);
 143                                ev.pulse = false;
 144                                ir_raw_event_store(dev->rdev, &ev);
 145                        } else  {
 146                                st_rc_send_lirc_timeout(dev->rdev);
 147                        }
 148
 149                }
 150                last_symbol = 0;
 151                status  = readl(dev->rx_base + IRB_RX_STATUS);
 152        }
 153
 154        writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_CLEAR);
 155
 156        /* Empty software fifo */
 157        ir_raw_event_handle(dev->rdev);
 158        return IRQ_HANDLED;
 159}
 160
 161static void st_rc_hardware_init(struct st_rc_device *dev)
 162{
 163        int baseclock, freqdiff;
 164        unsigned int rx_max_symbol_per = MAX_SYMB_TIME;
 165        unsigned int rx_sampling_freq_div;
 166
 167        /* Enable the IP */
 168        if (dev->rstc)
 169                reset_control_deassert(dev->rstc);
 170
 171        clk_prepare_enable(dev->sys_clock);
 172        baseclock = clk_get_rate(dev->sys_clock);
 173
 174        /* IRB input pins are inverted internally from high to low. */
 175        writel(1, dev->rx_base + IRB_RX_POLARITY_INV);
 176
 177        rx_sampling_freq_div = baseclock / IRB_SAMPLE_FREQ;
 178        writel(rx_sampling_freq_div, dev->base + IRB_SAMPLE_RATE_COMM);
 179
 180        freqdiff = baseclock - (rx_sampling_freq_div * IRB_SAMPLE_FREQ);
 181        if (freqdiff) { /* over clocking, workout the adjustment factors */
 182                dev->overclocking = true;
 183                dev->sample_mult = 1000;
 184                dev->sample_div = baseclock / (10000 * rx_sampling_freq_div);
 185                rx_max_symbol_per = (rx_max_symbol_per * 1000)/dev->sample_div;
 186        }
 187
 188        writel(rx_max_symbol_per, dev->rx_base + IRB_MAX_SYM_PERIOD);
 189}
 190
 191static int st_rc_remove(struct platform_device *pdev)
 192{
 193        struct st_rc_device *rc_dev = platform_get_drvdata(pdev);
 194
 195        dev_pm_clear_wake_irq(&pdev->dev);
 196        device_init_wakeup(&pdev->dev, false);
 197        clk_disable_unprepare(rc_dev->sys_clock);
 198        rc_unregister_device(rc_dev->rdev);
 199        return 0;
 200}
 201
 202static int st_rc_open(struct rc_dev *rdev)
 203{
 204        struct st_rc_device *dev = rdev->priv;
 205        unsigned long flags;
 206        local_irq_save(flags);
 207        /* enable interrupts and receiver */
 208        writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_EN);
 209        writel(0x01, dev->rx_base + IRB_RX_EN);
 210        local_irq_restore(flags);
 211
 212        return 0;
 213}
 214
 215static void st_rc_close(struct rc_dev *rdev)
 216{
 217        struct st_rc_device *dev = rdev->priv;
 218        /* disable interrupts and receiver */
 219        writel(0x00, dev->rx_base + IRB_RX_EN);
 220        writel(0x00, dev->rx_base + IRB_RX_INT_EN);
 221}
 222
 223static int st_rc_probe(struct platform_device *pdev)
 224{
 225        int ret = -EINVAL;
 226        struct rc_dev *rdev;
 227        struct device *dev = &pdev->dev;
 228        struct resource *res;
 229        struct st_rc_device *rc_dev;
 230        struct device_node *np = pdev->dev.of_node;
 231        const char *rx_mode;
 232
 233        rc_dev = devm_kzalloc(dev, sizeof(struct st_rc_device), GFP_KERNEL);
 234
 235        if (!rc_dev)
 236                return -ENOMEM;
 237
 238        rdev = rc_allocate_device();
 239
 240        if (!rdev)
 241                return -ENOMEM;
 242
 243        if (np && !of_property_read_string(np, "rx-mode", &rx_mode)) {
 244
 245                if (!strcmp(rx_mode, "uhf")) {
 246                        rc_dev->rxuhfmode = true;
 247                } else if (!strcmp(rx_mode, "infrared")) {
 248                        rc_dev->rxuhfmode = false;
 249                } else {
 250                        dev_err(dev, "Unsupported rx mode [%s]\n", rx_mode);
 251                        goto err;
 252                }
 253
 254        } else {
 255                goto err;
 256        }
 257
 258        rc_dev->sys_clock = devm_clk_get(dev, NULL);
 259        if (IS_ERR(rc_dev->sys_clock)) {
 260                dev_err(dev, "System clock not found\n");
 261                ret = PTR_ERR(rc_dev->sys_clock);
 262                goto err;
 263        }
 264
 265        rc_dev->irq = platform_get_irq(pdev, 0);
 266        if (rc_dev->irq < 0) {
 267                ret = rc_dev->irq;
 268                goto err;
 269        }
 270
 271        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 272
 273        rc_dev->base = devm_ioremap_resource(dev, res);
 274        if (IS_ERR(rc_dev->base)) {
 275                ret = PTR_ERR(rc_dev->base);
 276                goto err;
 277        }
 278
 279        if (rc_dev->rxuhfmode)
 280                rc_dev->rx_base = rc_dev->base + 0x40;
 281        else
 282                rc_dev->rx_base = rc_dev->base;
 283
 284
 285        rc_dev->rstc = reset_control_get_optional(dev, NULL);
 286        if (IS_ERR(rc_dev->rstc))
 287                rc_dev->rstc = NULL;
 288
 289        rc_dev->dev = dev;
 290        platform_set_drvdata(pdev, rc_dev);
 291        st_rc_hardware_init(rc_dev);
 292
 293        rdev->driver_type = RC_DRIVER_IR_RAW;
 294        rdev->allowed_protocols = RC_BIT_ALL;
 295        /* rx sampling rate is 10Mhz */
 296        rdev->rx_resolution = 100;
 297        rdev->timeout = US_TO_NS(MAX_SYMB_TIME);
 298        rdev->priv = rc_dev;
 299        rdev->open = st_rc_open;
 300        rdev->close = st_rc_close;
 301        rdev->driver_name = IR_ST_NAME;
 302        rdev->map_name = RC_MAP_LIRC;
 303        rdev->input_name = "ST Remote Control Receiver";
 304
 305        ret = rc_register_device(rdev);
 306        if (ret < 0)
 307                goto clkerr;
 308
 309        rc_dev->rdev = rdev;
 310        if (devm_request_irq(dev, rc_dev->irq, st_rc_rx_interrupt,
 311                             0, IR_ST_NAME, rc_dev) < 0) {
 312                dev_err(dev, "IRQ %d register failed\n", rc_dev->irq);
 313                ret = -EINVAL;
 314                goto rcerr;
 315        }
 316
 317        /* enable wake via this device */
 318        device_init_wakeup(dev, true);
 319        dev_pm_set_wake_irq(dev, rc_dev->irq);
 320
 321        /**
 322         * for LIRC_MODE_MODE2 or LIRC_MODE_PULSE or LIRC_MODE_RAW
 323         * lircd expects a long space first before a signal train to sync.
 324         */
 325        st_rc_send_lirc_timeout(rdev);
 326
 327        dev_info(dev, "setup in %s mode\n", rc_dev->rxuhfmode ? "UHF" : "IR");
 328
 329        return ret;
 330rcerr:
 331        rc_unregister_device(rdev);
 332        rdev = NULL;
 333clkerr:
 334        clk_disable_unprepare(rc_dev->sys_clock);
 335err:
 336        rc_free_device(rdev);
 337        dev_err(dev, "Unable to register device (%d)\n", ret);
 338        return ret;
 339}
 340
 341#ifdef CONFIG_PM_SLEEP
 342static int st_rc_suspend(struct device *dev)
 343{
 344        struct st_rc_device *rc_dev = dev_get_drvdata(dev);
 345
 346        if (device_may_wakeup(dev)) {
 347                if (!enable_irq_wake(rc_dev->irq))
 348                        rc_dev->irq_wake = 1;
 349                else
 350                        return -EINVAL;
 351        } else {
 352                pinctrl_pm_select_sleep_state(dev);
 353                writel(0x00, rc_dev->rx_base + IRB_RX_EN);
 354                writel(0x00, rc_dev->rx_base + IRB_RX_INT_EN);
 355                clk_disable_unprepare(rc_dev->sys_clock);
 356                if (rc_dev->rstc)
 357                        reset_control_assert(rc_dev->rstc);
 358        }
 359
 360        return 0;
 361}
 362
 363static int st_rc_resume(struct device *dev)
 364{
 365        struct st_rc_device *rc_dev = dev_get_drvdata(dev);
 366        struct rc_dev   *rdev = rc_dev->rdev;
 367
 368        if (rc_dev->irq_wake) {
 369                disable_irq_wake(rc_dev->irq);
 370                rc_dev->irq_wake = 0;
 371        } else {
 372                pinctrl_pm_select_default_state(dev);
 373                st_rc_hardware_init(rc_dev);
 374                if (rdev->users) {
 375                        writel(IRB_RX_INTS, rc_dev->rx_base + IRB_RX_INT_EN);
 376                        writel(0x01, rc_dev->rx_base + IRB_RX_EN);
 377                }
 378        }
 379
 380        return 0;
 381}
 382
 383#endif
 384
 385static SIMPLE_DEV_PM_OPS(st_rc_pm_ops, st_rc_suspend, st_rc_resume);
 386
 387#ifdef CONFIG_OF
 388static const struct of_device_id st_rc_match[] = {
 389        { .compatible = "st,comms-irb", },
 390        {},
 391};
 392
 393MODULE_DEVICE_TABLE(of, st_rc_match);
 394#endif
 395
 396static struct platform_driver st_rc_driver = {
 397        .driver = {
 398                .name = IR_ST_NAME,
 399                .of_match_table = of_match_ptr(st_rc_match),
 400                .pm     = &st_rc_pm_ops,
 401        },
 402        .probe = st_rc_probe,
 403        .remove = st_rc_remove,
 404};
 405
 406module_platform_driver(st_rc_driver);
 407
 408MODULE_DESCRIPTION("RC Transceiver driver for STMicroelectronics platforms");
 409MODULE_AUTHOR("STMicroelectronics (R&D) Ltd");
 410MODULE_LICENSE("GPL");
 411