brintos

brintos / linux-shallow public Read only

0
0
Text · 11.1 KiB · 988b091 Raw
419 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2013 STMicroelectronics Limited4 * 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		0x0f56#define IRB_RX_OVERRUN_INT	0x0457 /* maximum symbol period (microsecs),timeout to detect end of symbol train */58#define MAX_SYMB_TIME		0x500059#define IRB_SAMPLE_FREQ		1000000060#define	IRB_FIFO_NOT_EMPTY	0xff0061#define IRB_OVERFLOW		0x462#define IRB_TIMEOUT		0xffff63#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 block73 * output and standard definition used by LIRC (and most of the world!)74 *75 *           mark                                     mark76 *      |-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), so87 * 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 where90 * 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	else285		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	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_RAW328	 * 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_SLEEP347static 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		else355			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#endif392 393static SIMPLE_DEV_PM_OPS(st_rc_pm_ops, st_rc_suspend, st_rc_resume);394 395#ifdef CONFIG_OF396static const struct of_device_id st_rc_match[] = {397	{ .compatible = "st,comms-irb", },398	{},399};400 401MODULE_DEVICE_TABLE(of, st_rc_match);402#endif403 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_new = 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");419