Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1/*
  2 * linux/arch/arm/mach-w90x900/gpio.c
  3 *
  4 * Generic nuc900 GPIO handling
  5 *
  6 *  Wan ZongShun <mcuos.com@gmail.com>
  7 *
  8 * This program is free software; you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License version 2 as
 10 * published by the Free Software Foundation.
 11 */
 12
 13#include <linux/clk.h>
 14#include <linux/errno.h>
 15#include <linux/interrupt.h>
 16#include <linux/irq.h>
 17#include <linux/debugfs.h>
 18#include <linux/seq_file.h>
 19#include <linux/kernel.h>
 20#include <linux/list.h>
 21#include <linux/module.h>
 22#include <linux/io.h>
 23#include <linux/gpio/driver.h>
 24
 25#include <mach/hardware.h>
 26
 27#define GPIO_BASE 		(W90X900_VA_GPIO)
 28#define GPIO_DIR		(0x04)
 29#define GPIO_OUT		(0x08)
 30#define GPIO_IN			(0x0C)
 31#define GROUPINERV		(0x10)
 32#define GPIO_GPIO(Nb)		(0x00000001 << (Nb))
 33
 34#define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio)			\
 35	{								\
 36		.chip = {						\
 37			.label		  = name,			\
 38			.direction_input  = nuc900_dir_input,		\
 39			.direction_output = nuc900_dir_output,		\
 40			.get		  = nuc900_gpio_get,		\
 41			.set		  = nuc900_gpio_set,		\
 42			.base		  = base_gpio,			\
 43			.ngpio		  = nr_gpio,			\
 44		}							\
 45	}
 46
 47struct nuc900_gpio_chip {
 48	struct gpio_chip	chip;
 49	void __iomem		*regbase;	/* Base of group register*/
 50	spinlock_t 		gpio_lock;
 51};
 52
 53static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
 54{
 55	struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
 56	void __iomem *pio = nuc900_gpio->regbase + GPIO_IN;
 57	unsigned int regval;
 58
 59	regval = __raw_readl(pio);
 60	regval &= GPIO_GPIO(offset);
 61
 62	return (regval != 0);
 63}
 64
 65static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
 66{
 67	struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
 68	void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT;
 69	unsigned int regval;
 70	unsigned long flags;
 71
 72	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
 73
 74	regval = __raw_readl(pio);
 75
 76	if (val)
 77		regval |= GPIO_GPIO(offset);
 78	else
 79		regval &= ~GPIO_GPIO(offset);
 80
 81	__raw_writel(regval, pio);
 82
 83	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
 84}
 85
 86static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
 87{
 88	struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
 89	void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
 90	unsigned int regval;
 91	unsigned long flags;
 92
 93	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
 94
 95	regval = __raw_readl(pio);
 96	regval &= ~GPIO_GPIO(offset);
 97	__raw_writel(regval, pio);
 98
 99	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
100
101	return 0;
102}
103
104static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val)
105{
106	struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
107	void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT;
108	void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
109	unsigned int regval;
110	unsigned long flags;
111
112	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
113
114	regval = __raw_readl(pio);
115	regval |= GPIO_GPIO(offset);
116	__raw_writel(regval, pio);
117
118	regval = __raw_readl(outreg);
119
120	if (val)
121		regval |= GPIO_GPIO(offset);
122	else
123		regval &= ~GPIO_GPIO(offset);
124
125	__raw_writel(regval, outreg);
126
127	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
128
129	return 0;
130}
131
132static struct nuc900_gpio_chip nuc900_gpio[] = {
133	NUC900_GPIO_CHIP("GROUPC", 0, 16),
134	NUC900_GPIO_CHIP("GROUPD", 16, 10),
135	NUC900_GPIO_CHIP("GROUPE", 26, 14),
136	NUC900_GPIO_CHIP("GROUPF", 40, 10),
137	NUC900_GPIO_CHIP("GROUPG", 50, 17),
138	NUC900_GPIO_CHIP("GROUPH", 67, 8),
139	NUC900_GPIO_CHIP("GROUPI", 75, 17),
140};
141
142void __init nuc900_init_gpio(int nr_group)
143{
144	unsigned	i;
145	struct nuc900_gpio_chip *gpio_chip;
146
147	for (i = 0; i < nr_group; i++) {
148		gpio_chip = &nuc900_gpio[i];
149		spin_lock_init(&gpio_chip->gpio_lock);
150		gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
151		gpiochip_add_data(&gpio_chip->chip, gpio_chip);
152	}
153}