Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * TQ-Systems TQMx86 PLD GPIO driver
  4 *
  5 * Based on vendor driver by:
  6 *   Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
  7 */
  8
  9#include <linux/bitmap.h>
 10#include <linux/bitops.h>
 11#include <linux/errno.h>
 12#include <linux/gpio/driver.h>
 13#include <linux/init.h>
 14#include <linux/interrupt.h>
 15#include <linux/kernel.h>
 16#include <linux/module.h>
 17#include <linux/platform_device.h>
 18#include <linux/pm_runtime.h>
 19#include <linux/seq_file.h>
 20#include <linux/slab.h>
 21
 22#define TQMX86_NGPIO	8
 23#define TQMX86_NGPO	4	/* 0-3 - output */
 24#define TQMX86_NGPI	4	/* 4-7 - input */
 25#define TQMX86_DIR_INPUT_MASK	0xf0	/* 0-3 - output, 4-7 - input */
 26
 27#define TQMX86_GPIODD	0	/* GPIO Data Direction Register */
 28#define TQMX86_GPIOD	1	/* GPIO Data Register */
 29#define TQMX86_GPIIC	3	/* GPI Interrupt Configuration Register */
 30#define TQMX86_GPIIS	4	/* GPI Interrupt Status Register */
 31
 32#define TQMX86_GPII_NONE	0
 33#define TQMX86_GPII_FALLING	BIT(0)
 34#define TQMX86_GPII_RISING	BIT(1)
 35/* Stored in irq_type as a trigger type, but not actually valid as a register
 36 * value, so the name doesn't use "GPII"
 37 */
 38#define TQMX86_INT_BOTH		(BIT(0) | BIT(1))
 39#define TQMX86_GPII_MASK	(BIT(0) | BIT(1))
 40#define TQMX86_GPII_BITS	2
 41/* Stored in irq_type with GPII bits */
 42#define TQMX86_INT_UNMASKED	BIT(2)
 43
 44struct tqmx86_gpio_data {
 45	struct gpio_chip	chip;
 46	void __iomem		*io_base;
 47	int			irq;
 48	/* Lock must be held for accessing output and irq_type fields */
 49	raw_spinlock_t		spinlock;
 50	DECLARE_BITMAP(output, TQMX86_NGPIO);
 51	u8			irq_type[TQMX86_NGPI];
 52};
 53
 54static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg)
 55{
 56	return ioread8(gd->io_base + reg);
 57}
 58
 59static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val,
 60			      unsigned int reg)
 61{
 62	iowrite8(val, gd->io_base + reg);
 63}
 64
 65static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset)
 66{
 67	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 68
 69	return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset));
 70}
 71
 72static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
 73			    int value)
 74{
 75	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 76	unsigned long flags;
 77
 78	raw_spin_lock_irqsave(&gpio->spinlock, flags);
 79	__assign_bit(offset, gpio->output, value);
 80	tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
 81	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 82}
 83
 84static int tqmx86_gpio_direction_input(struct gpio_chip *chip,
 85				       unsigned int offset)
 86{
 87	/* Direction cannot be changed. Validate is an input. */
 88	if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
 89		return 0;
 90	else
 91		return -EINVAL;
 92}
 93
 94static int tqmx86_gpio_direction_output(struct gpio_chip *chip,
 95					unsigned int offset,
 96					int value)
 97{
 98	/* Direction cannot be changed, validate is an output */
 99	if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
100		return -EINVAL;
101
102	tqmx86_gpio_set(chip, offset, value);
103	return 0;
104}
105
106static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
107				     unsigned int offset)
108{
109	if (TQMX86_DIR_INPUT_MASK & BIT(offset))
110		return GPIO_LINE_DIRECTION_IN;
111
112	return GPIO_LINE_DIRECTION_OUT;
113}
114
115static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset)
116	__must_hold(&gpio->spinlock)
117{
118	u8 type = TQMX86_GPII_NONE, gpiic;
119
120	if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) {
121		type = gpio->irq_type[offset] & TQMX86_GPII_MASK;
122
123		if (type == TQMX86_INT_BOTH)
124			type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO)
125				? TQMX86_GPII_FALLING
126				: TQMX86_GPII_RISING;
127	}
128
129	gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
130	gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS));
131	gpiic |= type << (offset * TQMX86_GPII_BITS);
132	tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
133}
134
135static void tqmx86_gpio_irq_mask(struct irq_data *data)
136{
137	unsigned int offset = (data->hwirq - TQMX86_NGPO);
138	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
139		irq_data_get_irq_chip_data(data));
140	unsigned long flags;
141
142	raw_spin_lock_irqsave(&gpio->spinlock, flags);
143	gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED;
144	tqmx86_gpio_irq_config(gpio, offset);
145	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
146
147	gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data));
148}
149
150static void tqmx86_gpio_irq_unmask(struct irq_data *data)
151{
152	unsigned int offset = (data->hwirq - TQMX86_NGPO);
153	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
154		irq_data_get_irq_chip_data(data));
155	unsigned long flags;
156
157	gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));
158
159	raw_spin_lock_irqsave(&gpio->spinlock, flags);
160	gpio->irq_type[offset] |= TQMX86_INT_UNMASKED;
161	tqmx86_gpio_irq_config(gpio, offset);
162	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
163}
164
165static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
166{
167	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
168		irq_data_get_irq_chip_data(data));
169	unsigned int offset = (data->hwirq - TQMX86_NGPO);
170	unsigned int edge_type = type & IRQF_TRIGGER_MASK;
171	unsigned long flags;
172	u8 new_type;
173
174	switch (edge_type) {
175	case IRQ_TYPE_EDGE_RISING:
176		new_type = TQMX86_GPII_RISING;
177		break;
178	case IRQ_TYPE_EDGE_FALLING:
179		new_type = TQMX86_GPII_FALLING;
180		break;
181	case IRQ_TYPE_EDGE_BOTH:
182		new_type = TQMX86_INT_BOTH;
183		break;
184	default:
185		return -EINVAL; /* not supported */
186	}
187
188	raw_spin_lock_irqsave(&gpio->spinlock, flags);
189	gpio->irq_type[offset] &= ~TQMX86_GPII_MASK;
190	gpio->irq_type[offset] |= new_type;
191	tqmx86_gpio_irq_config(gpio, offset);
192	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
193
194	return 0;
195}
196
197static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
198{
199	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
200	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
201	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
202	unsigned long irq_bits, flags;
203	int i;
204	u8 irq_status;
205
206	chained_irq_enter(irq_chip, desc);
207
208	irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
209	tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
210
211	irq_bits = irq_status;
212
213	raw_spin_lock_irqsave(&gpio->spinlock, flags);
214	for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
215		/*
216		 * Edge-both triggers are implemented by flipping the edge
217		 * trigger after each interrupt, as the controller only supports
218		 * either rising or falling edge triggers, but not both.
219		 *
220		 * Internally, the TQMx86 GPIO controller has separate status
221		 * registers for rising and falling edge interrupts. GPIIC
222		 * configures which bits from which register are visible in the
223		 * interrupt status register GPIIS and defines what triggers the
224		 * parent IRQ line. Writing to GPIIS always clears both rising
225		 * and falling interrupt flags internally, regardless of the
226		 * currently configured trigger.
227		 *
228		 * In consequence, we can cleanly implement the edge-both
229		 * trigger in software by first clearing the interrupt and then
230		 * setting the new trigger based on the current GPIO input in
231		 * tqmx86_gpio_irq_config() - even if an edge arrives between
232		 * reading the input and setting the trigger, we will have a new
233		 * interrupt pending.
234		 */
235		if ((gpio->irq_type[i] & TQMX86_GPII_MASK) == TQMX86_INT_BOTH)
236			tqmx86_gpio_irq_config(gpio, i);
237	}
238	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
239
240	for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
241		generic_handle_domain_irq(gpio->chip.irq.domain,
242					  i + TQMX86_NGPO);
243
244	chained_irq_exit(irq_chip, desc);
245}
246
247/* Minimal runtime PM is needed by the IRQ subsystem */
248static int __maybe_unused tqmx86_gpio_runtime_suspend(struct device *dev)
249{
250	return 0;
251}
252
253static int __maybe_unused tqmx86_gpio_runtime_resume(struct device *dev)
254{
255	return 0;
256}
257
258static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {
259	SET_RUNTIME_PM_OPS(tqmx86_gpio_runtime_suspend,
260			   tqmx86_gpio_runtime_resume, NULL)
261};
262
263static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
264				       unsigned long *valid_mask,
265				       unsigned int ngpios)
266{
267	/* Only GPIOs 4-7 are valid for interrupts. Clear the others */
268	clear_bit(0, valid_mask);
269	clear_bit(1, valid_mask);
270	clear_bit(2, valid_mask);
271	clear_bit(3, valid_mask);
272}
273
274static void tqmx86_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
275{
276	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
277
278	seq_puts(p, gc->label);
279}
280
281static const struct irq_chip tqmx86_gpio_irq_chip = {
282	.irq_mask = tqmx86_gpio_irq_mask,
283	.irq_unmask = tqmx86_gpio_irq_unmask,
284	.irq_set_type = tqmx86_gpio_irq_set_type,
285	.irq_print_chip = tqmx86_gpio_irq_print_chip,
286	.flags = IRQCHIP_IMMUTABLE,
287	GPIOCHIP_IRQ_RESOURCE_HELPERS,
288};
289
290static int tqmx86_gpio_probe(struct platform_device *pdev)
291{
292	struct device *dev = &pdev->dev;
293	struct tqmx86_gpio_data *gpio;
294	struct gpio_chip *chip;
295	struct gpio_irq_chip *girq;
296	void __iomem *io_base;
297	struct resource *res;
298	int ret, irq;
299
300	irq = platform_get_irq_optional(pdev, 0);
301	if (irq < 0 && irq != -ENXIO)
302		return irq;
303
304	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
305	if (!res) {
306		dev_err(&pdev->dev, "Cannot get I/O\n");
307		return -ENODEV;
308	}
309
310	io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));
311	if (!io_base)
312		return -ENOMEM;
313
314	gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
315	if (!gpio)
316		return -ENOMEM;
317
318	raw_spin_lock_init(&gpio->spinlock);
319	gpio->io_base = io_base;
320
321	tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
322
323	/*
324	 * Reading the previous output state is not possible with TQMx86 hardware.
325	 * Initialize all outputs to 0 to have a defined state that matches the
326	 * shadow register.
327	 */
328	tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD);
329
330	chip = &gpio->chip;
331	chip->label = "gpio-tqmx86";
332	chip->owner = THIS_MODULE;
333	chip->can_sleep = false;
334	chip->base = -1;
335	chip->direction_input = tqmx86_gpio_direction_input;
336	chip->direction_output = tqmx86_gpio_direction_output;
337	chip->get_direction = tqmx86_gpio_get_direction;
338	chip->get = tqmx86_gpio_get;
339	chip->set = tqmx86_gpio_set;
340	chip->ngpio = TQMX86_NGPIO;
341	chip->parent = pdev->dev.parent;
342
343	pm_runtime_enable(&pdev->dev);
344
345	if (irq > 0) {
346		u8 irq_status;
347
348		/* Mask all interrupts */
349		tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
350
351		/* Clear all pending interrupts */
352		irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
353		tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
354
355		girq = &chip->irq;
356		gpio_irq_chip_set_chip(girq, &tqmx86_gpio_irq_chip);
357		girq->parent_handler = tqmx86_gpio_irq_handler;
358		girq->num_parents = 1;
359		girq->parents = devm_kcalloc(&pdev->dev, 1,
360					     sizeof(*girq->parents),
361					     GFP_KERNEL);
362		if (!girq->parents) {
363			ret = -ENOMEM;
364			goto out_pm_dis;
365		}
366		girq->parents[0] = irq;
367		girq->default_type = IRQ_TYPE_NONE;
368		girq->handler = handle_simple_irq;
369		girq->init_valid_mask = tqmx86_init_irq_valid_mask;
370
371		irq_domain_set_pm_device(girq->domain, dev);
372	}
373
374	ret = devm_gpiochip_add_data(dev, chip, gpio);
375	if (ret) {
376		dev_err(dev, "Could not register GPIO chip\n");
377		goto out_pm_dis;
378	}
379
380	dev_info(dev, "GPIO functionality initialized with %d pins\n",
381		 chip->ngpio);
382
383	return 0;
384
385out_pm_dis:
386	pm_runtime_disable(&pdev->dev);
387
388	return ret;
389}
390
391static struct platform_driver tqmx86_gpio_driver = {
392	.driver = {
393		.name = "tqmx86-gpio",
394		.pm = &tqmx86_gpio_dev_pm_ops,
395	},
396	.probe		= tqmx86_gpio_probe,
397};
398
399module_platform_driver(tqmx86_gpio_driver);
400
401MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver");
402MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
403MODULE_LICENSE("GPL");
404MODULE_ALIAS("platform:tqmx86-gpio");