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