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 long timeout;
 100        unsigned int symbol, mark = 0;
 101        struct st_rc_device *dev = data;
 102        int last_symbol = 0;
 103        u32 status, int_status;
 104        DEFINE_IR_RAW_EVENT(ev);
 105
 106        if (dev->irq_wake)
 107                pm_wakeup_event(dev->dev, 0);
 108
 109        /* FIXME: is 10ms good enough ? */
 110        timeout = jiffies +  msecs_to_jiffies(10);
 111        do {
 112                status  = readl(dev->rx_base + IRB_RX_STATUS);
 113                if (!(status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW)))
 114                        break;
 115
 116                int_status = readl(dev->rx_base + IRB_RX_INT_STATUS);
 117                if (unlikely(int_status & IRB_RX_OVERRUN_INT)) {
 118                        /* discard the entire collection in case of errors!  */
 119                        ir_raw_event_reset(dev->rdev);
 120                        dev_info(dev->dev, "IR RX overrun\n");
 121                        writel(IRB_RX_OVERRUN_INT,
 122                                        dev->rx_base + IRB_RX_INT_CLEAR);
 123                        continue;
 124                }
 125
 126                symbol = readl(dev->rx_base + IRB_RX_SYS);
 127                mark = readl(dev->rx_base + IRB_RX_ON);
 128
 129                if (symbol == IRB_TIMEOUT)
 130                        last_symbol = 1;
 131
 132                 /* Ignore any noise */
 133                if ((mark > 2) && (symbol > 1)) {
 134                        symbol -= mark;
 135                        if (dev->overclocking) { /* adjustments to timings */
 136                                symbol *= dev->sample_mult;
 137                                symbol /= dev->sample_div;
 138                                mark *= dev->sample_mult;
 139                                mark /= dev->sample_div;
 140                        }
 141
 142                        ev.duration = US_TO_NS(mark);
 143                        ev.pulse = true;
 144                        ir_raw_event_store(dev->rdev, &ev);
 145
 146                        if (!last_symbol) {
 147                                ev.duration = US_TO_NS(symbol);
 148                                ev.pulse = false;
 149                                ir_raw_event_store(dev->rdev, &ev);
 150                        } else  {
 151                                st_rc_send_lirc_timeout(dev->rdev);
 152                        }
 153
 154                }
 155                last_symbol = 0;
 156        } while (time_is_after_jiffies(timeout));
 157
 158        writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_CLEAR);
 159
 160        /* Empty software fifo */
 161        ir_raw_event_handle(dev->rdev);
 162        return IRQ_HANDLED;
 163}
 164
 165static void st_rc_hardware_init(struct st_rc_device *dev)
 166{
 167        int baseclock, freqdiff;
 168        unsigned int rx_max_symbol_per = MAX_SYMB_TIME;
 169        unsigned int rx_sampling_freq_div;
 170
 171        /* Enable the IP */
 172        reset_control_deassert(dev->rstc);
 173
 174        clk_prepare_enable(dev->sys_clock);
 175        baseclock = clk_get_rate(dev->sys_clock);
 176
 177        /* IRB input pins are inverted internally from high to low. */
 178        writel(1, dev->rx_base + IRB_RX_POLARITY_INV);
 179
 180        rx_sampling_freq_div = baseclock / IRB_SAMPLE_FREQ;
 181        writel(rx_sampling_freq_div, dev->base + IRB_SAMPLE_RATE_COMM);
 182
 183        freqdiff = baseclock - (rx_sampling_freq_div * IRB_SAMPLE_FREQ);
 184        if (freqdiff) { /* over clocking, workout the adjustment factors */
 185                dev->overclocking = true;
 186                dev->sample_mult = 1000;
 187                dev->sample_div = baseclock / (10000 * rx_sampling_freq_div);
 188                rx_max_symbol_per = (rx_max_symbol_per * 1000)/dev->sample_div;
 189        }
 190
 191        writel(rx_max_symbol_per, dev->rx_base + IRB_MAX_SYM_PERIOD);
 192}
 193
 194static int st_rc_remove(struct platform_device *pdev)
 195{
 196        struct st_rc_device *rc_dev = platform_get_drvdata(pdev);
 197
 198        dev_pm_clear_wake_irq(&pdev->dev);
 199        device_init_wakeup(&pdev->dev, false);
 200        clk_disable_unprepare(rc_dev->sys_clock);
 201        rc_unregister_device(rc_dev->rdev);
 202        return 0;
 203}
 204
 205static int st_rc_open(struct rc_dev *rdev)
 206{
 207        struct st_rc_device *dev = rdev->priv;
 208        unsigned long flags;
 209        local_irq_save(flags);
 210        /* enable interrupts and receiver */
 211        writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_EN);
 212        writel(0x01, dev->rx_base + IRB_RX_EN);
 213        local_irq_restore(flags);
 214
 215        return 0;
 216}
 217
 218static void st_rc_close(struct rc_dev *rdev)
 219{
 220        struct st_rc_device *dev = rdev->priv;
 221        /* disable interrupts and receiver */
 222        writel(0x00, dev->rx_base + IRB_RX_EN);
 223        writel(0x00, dev->rx_base + IRB_RX_INT_EN);
 224}
 225
 226static int st_rc_probe(struct platform_device *pdev)
 227{
 228        int ret = -EINVAL;
 229        struct rc_dev *rdev;
 230        struct device *dev = &pdev->dev;
 231        struct resource *res;
 232        struct st_rc_device *rc_dev;
 233        struct device_node *np = pdev->dev.of_node;
 234        const char *rx_mode;
 235
 236        rc_dev = devm_kzalloc(dev, sizeof(struct st_rc_device), GFP_KERNEL);
 237
 238        if (!rc_dev)
 239                return -ENOMEM;
 240
 241        rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
 242
 243        if (!rdev)
 244                return -ENOMEM;
 245
 246        if (np && !of_property_read_string(np, "rx-mode", &rx_mode)) {
 247
 248                if (!strcmp(rx_mode, "uhf")) {
 249                        rc_dev->rxuhfmode = true;
 250                } else if (!strcmp(rx_mode, "infrared")) {
 251                        rc_dev->rxuhfmode = false;
 252                } else {
 253                        dev_err(dev, "Unsupported rx mode [%s]\n", rx_mode);
 254                        goto err;
 255                }
 256
 257        } else {
 258                goto err;
 259        }
 260
 261        rc_dev->sys_clock = devm_clk_get(dev, NULL);
 262        if (IS_ERR(rc_dev->sys_clock)) {
 263                dev_err(dev, "System clock not found\n");
 264                ret = PTR_ERR(rc_dev->sys_clock);
 265                goto err;
 266        }
 267
 268        rc_dev->irq = platform_get_irq(pdev, 0);
 269        if (rc_dev->irq < 0) {
 270                ret = rc_dev->irq;
 271                goto err;
 272        }
 273
 274        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 275
 276        rc_dev->base = devm_ioremap_resource(dev, res);
 277        if (IS_ERR(rc_dev->base)) {
 278                ret = PTR_ERR(rc_dev->base);
 279                goto err;
 280        }
 281
 282        if (rc_dev->rxuhfmode)
 283                rc_dev->rx_base = rc_dev->base + 0x40;
 284        else
 285                rc_dev->rx_base = rc_dev->base;
 286
 287        rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL);
 288        if (IS_ERR(rc_dev->rstc)) {
 289                ret = PTR_ERR(rc_dev->rstc);
 290                goto err;
 291        }
 292
 293        rc_dev->dev = dev;
 294        platform_set_drvdata(pdev, rc_dev);
 295        st_rc_hardware_init(rc_dev);
 296
 297        rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
 298        /* rx sampling rate is 10Mhz */
 299        rdev->rx_resolution = 100;
 300        rdev->timeout = US_TO_NS(MAX_SYMB_TIME);
 301        rdev->priv = rc_dev;
 302        rdev->open = st_rc_open;
 303        rdev->close = st_rc_close;
 304        rdev->driver_name = IR_ST_NAME;
 305        rdev->map_name = RC_MAP_EMPTY;
 306        rdev->device_name = "ST Remote Control Receiver";
 307
 308        ret = rc_register_device(rdev);
 309        if (ret < 0)
 310                goto clkerr;
 311
 312        rc_dev->rdev = rdev;
 313        if (devm_request_irq(dev, rc_dev->irq, st_rc_rx_interrupt,
 314                             0, IR_ST_NAME, rc_dev) < 0) {
 315                dev_err(dev, "IRQ %d register failed\n", rc_dev->irq);
 316                ret = -EINVAL;
 317                goto rcerr;
 318        }
 319
 320        /* enable wake via this device */
 321        device_init_wakeup(dev, true);
 322        dev_pm_set_wake_irq(dev, rc_dev->irq);
 323
 324        /*
 325         * for LIRC_MODE_MODE2 or LIRC_MODE_PULSE or LIRC_MODE_RAW
 326         * lircd expects a long space first before a signal train to sync.
 327         */
 328        st_rc_send_lirc_timeout(rdev);
 329
 330        dev_info(dev, "setup in %s mode\n", rc_dev->rxuhfmode ? "UHF" : "IR");
 331
 332        return ret;
 333rcerr:
 334        rc_unregister_device(rdev);
 335        rdev = NULL;
 336clkerr:
 337        clk_disable_unprepare(rc_dev->sys_clock);
 338err:
 339        rc_free_device(rdev);
 340        dev_err(dev, "Unable to register device (%d)\n", ret);
 341        return ret;
 342}
 343
 344#ifdef CONFIG_PM_SLEEP
 345static int st_rc_suspend(struct device *dev)
 346{
 347        struct st_rc_device *rc_dev = dev_get_drvdata(dev);
 348
 349        if (device_may_wakeup(dev)) {
 350                if (!enable_irq_wake(rc_dev->irq))
 351                        rc_dev->irq_wake = 1;
 352                else
 353                        return -EINVAL;
 354        } else {
 355                pinctrl_pm_select_sleep_state(dev);
 356                writel(0x00, rc_dev->rx_base + IRB_RX_EN);
 357                writel(0x00, rc_dev->rx_base + IRB_RX_INT_EN);
 358                clk_disable_unprepare(rc_dev->sys_clock);
 359                reset_control_assert(rc_dev->rstc);
 360        }
 361
 362        return 0;
 363}
 364
 365static int st_rc_resume(struct device *dev)
 366{
 367        struct st_rc_device *rc_dev = dev_get_drvdata(dev);
 368        struct rc_dev   *rdev = rc_dev->rdev;
 369
 370        if (rc_dev->irq_wake) {
 371                disable_irq_wake(rc_dev->irq);
 372                rc_dev->irq_wake = 0;
 373        } else {
 374                pinctrl_pm_select_default_state(dev);
 375                st_rc_hardware_init(rc_dev);
 376                if (rdev->users) {
 377                        writel(IRB_RX_INTS, rc_dev->rx_base + IRB_RX_INT_EN);
 378                        writel(0x01, rc_dev->rx_base + IRB_RX_EN);
 379                }
 380        }
 381
 382        return 0;
 383}
 384
 385#endif
 386
 387static SIMPLE_DEV_PM_OPS(st_rc_pm_ops, st_rc_suspend, st_rc_resume);
 388
 389#ifdef CONFIG_OF
 390static const struct of_device_id st_rc_match[] = {
 391        { .compatible = "st,comms-irb", },
 392        {},
 393};
 394
 395MODULE_DEVICE_TABLE(of, st_rc_match);
 396#endif
 397
 398static struct platform_driver st_rc_driver = {
 399        .driver = {
 400                .name = IR_ST_NAME,
 401                .of_match_table = of_match_ptr(st_rc_match),
 402                .pm     = &st_rc_pm_ops,
 403        },
 404        .probe = st_rc_probe,
 405        .remove = st_rc_remove,
 406};
 407
 408module_platform_driver(st_rc_driver);
 409
 410MODULE_DESCRIPTION("RC Transceiver driver for STMicroelectronics platforms");
 411MODULE_AUTHOR("STMicroelectronics (R&D) Ltd");
 412MODULE_LICENSE("GPL");
 413