File Index
Files and directories
Sign in
FILE

st_rc.c

File preview with syntax highlighting.

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