Blame view

arch/arm/mach-w90x900/gpio.c 3.77 KB
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
1
  /*
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
2
   * linux/arch/arm/mach-w90x900/gpio.c
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
3
   *
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
4
   * Generic nuc900 GPIO handling
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
   *
   *  Wan ZongShun <mcuos.com@gmail.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
  
  #include <linux/clk.h>
  #include <linux/errno.h>
  #include <linux/interrupt.h>
  #include <linux/irq.h>
  #include <linux/debugfs.h>
  #include <linux/seq_file.h>
  #include <linux/kernel.h>
  #include <linux/list.h>
  #include <linux/module.h>
  #include <linux/io.h>
  #include <linux/gpio.h>
  
  #include <mach/hardware.h>
  
  #define GPIO_BASE 		(W90X900_VA_GPIO)
  #define GPIO_DIR		(0x04)
  #define GPIO_OUT		(0x08)
  #define GPIO_IN			(0x0C)
  #define GROUPINERV		(0x10)
  #define GPIO_GPIO(Nb)		(0x00000001 << (Nb))
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
33
  #define to_nuc900_gpio_chip(c) container_of(c, struct nuc900_gpio_chip, chip)
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
34

35c9221ac   wanzongshun   ARM: 5682/1: Add ...
35
  #define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio)			\
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
36
37
38
  	{								\
  		.chip = {						\
  			.label		  = name,			\
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
39
40
41
42
  			.direction_input  = nuc900_dir_input,		\
  			.direction_output = nuc900_dir_output,		\
  			.get		  = nuc900_gpio_get,		\
  			.set		  = nuc900_gpio_set,		\
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
43
44
45
46
  			.base		  = base_gpio,			\
  			.ngpio		  = nr_gpio,			\
  		}							\
  	}
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
47
  struct nuc900_gpio_chip {
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
48
49
50
51
  	struct gpio_chip	chip;
  	void __iomem		*regbase;	/* Base of group register*/
  	spinlock_t 		gpio_lock;
  };
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
52
  static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
53
  {
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
54
55
  	struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
  	void __iomem *pio = nuc900_gpio->regbase + GPIO_IN;
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
56
57
58
59
60
61
62
  	unsigned int regval;
  
  	regval = __raw_readl(pio);
  	regval &= GPIO_GPIO(offset);
  
  	return (regval != 0);
  }
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
63
  static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
64
  {
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
65
66
  	struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
  	void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT;
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
67
68
  	unsigned int regval;
  	unsigned long flags;
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
69
  	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
70
71
72
73
74
75
76
77
78
  
  	regval = __raw_readl(pio);
  
  	if (val)
  		regval |= GPIO_GPIO(offset);
  	else
  		regval &= ~GPIO_GPIO(offset);
  
  	__raw_writel(regval, pio);
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
79
  	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
80
  }
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
81
  static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
82
  {
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
83
84
  	struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
  	void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
85
86
  	unsigned int regval;
  	unsigned long flags;
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
87
  	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
88
89
90
91
  
  	regval = __raw_readl(pio);
  	regval &= ~GPIO_GPIO(offset);
  	__raw_writel(regval, pio);
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
92
  	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
93
94
95
  
  	return 0;
  }
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
96
  static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val)
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
97
  {
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
98
99
100
  	struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
  	void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT;
  	void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
101
102
  	unsigned int regval;
  	unsigned long flags;
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
103
  	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
104
105
106
107
108
109
110
111
112
113
114
115
116
  
  	regval = __raw_readl(pio);
  	regval |= GPIO_GPIO(offset);
  	__raw_writel(regval, pio);
  
  	regval = __raw_readl(outreg);
  
  	if (val)
  		regval |= GPIO_GPIO(offset);
  	else
  		regval &= ~GPIO_GPIO(offset);
  
  	__raw_writel(regval, outreg);
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
117
  	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
118
119
120
  
  	return 0;
  }
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
121
122
123
124
125
126
127
128
  static struct nuc900_gpio_chip nuc900_gpio[] = {
  	NUC900_GPIO_CHIP("GROUPC", 0, 16),
  	NUC900_GPIO_CHIP("GROUPD", 16, 10),
  	NUC900_GPIO_CHIP("GROUPE", 26, 14),
  	NUC900_GPIO_CHIP("GROUPF", 40, 10),
  	NUC900_GPIO_CHIP("GROUPG", 50, 17),
  	NUC900_GPIO_CHIP("GROUPH", 67, 8),
  	NUC900_GPIO_CHIP("GROUPI", 75, 17),
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
129
  };
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
130
  void __init nuc900_init_gpio(int nr_group)
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
131
132
  {
  	unsigned	i;
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
133
  	struct nuc900_gpio_chip *gpio_chip;
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
134
135
  
  	for (i = 0; i < nr_group; i++) {
35c9221ac   wanzongshun   ARM: 5682/1: Add ...
136
  		gpio_chip = &nuc900_gpio[i];
c52d3d688   wanzongshun   [ARM] 5548/1: Add...
137
138
139
140
141
  		spin_lock_init(&gpio_chip->gpio_lock);
  		gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
  		gpiochip_add(&gpio_chip->chip);
  	}
  }