aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBibek Basu <bibek.basu@stericsson.com>2011-02-09 00:32:35 -0500
committerLinus Walleij <linus.walleij@linaro.org>2011-03-28 02:47:17 -0400
commit0cb3fcd72cc3e6dd88f0e769746d294e5e6bafa9 (patch)
treeed04e6b37c1c92eb1e9b0aed99cc98a3b6193fc7
parent18bcd0c8cb7d85a9063b88ec810dc1cdc0974518 (diff)
gpio: driver for 42 AB8500 GPIO pins
To get rid of port expanders, the free GPIOs of ab8500 can be used. There are 42 GPIO pins. Out of which 16 are interrupt capable.This patch implements 16 virtual IRQ mapped to 16 interrupt capable AB8500 GPIOs. Signed-off-by: Bibek Basu <bibek.basu@stericsson.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> [Renamed header file as per MFD structure] Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/Kconfig5
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/ab8500-gpio.c522
-rw-r--r--drivers/mfd/ab8500-core.c14
-rw-r--r--drivers/mfd/ab8500-i2c.c2
-rw-r--r--include/linux/mfd/ab8500.h41
-rw-r--r--include/linux/mfd/ab8500/gpio.h21
7 files changed, 605 insertions, 1 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d8d0cda2641..d3743204a7e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -414,4 +414,9 @@ config GPIO_JANZ_TTL
414 This driver provides support for driving the pins in output 414 This driver provides support for driving the pins in output
415 mode only. Input mode is not supported. 415 mode only. Input mode is not supported.
416 416
417config AB8500_GPIO
418 bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
419 depends on AB8500_CORE
420 help
421 Select this to enable the AB8500 IC GPIO driver
417endif 422endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 3351cf87b0e..becef595435 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o
42obj-$(CONFIG_GPIO_SX150X) += sx150x.o 42obj-$(CONFIG_GPIO_SX150X) += sx150x.o
43obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o 43obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o
44obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o 44obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o
45obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o
diff --git a/drivers/gpio/ab8500-gpio.c b/drivers/gpio/ab8500-gpio.c
new file mode 100644
index 00000000000..e7b834d054b
--- /dev/null
+++ b/drivers/gpio/ab8500-gpio.c
@@ -0,0 +1,522 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2011
3 *
4 * Author: BIBEK BASU <bibek.basu@stericsson.com>
5 * License terms: GNU General Public License (GPL) version 2
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/slab.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/gpio.h>
20#include <linux/irq.h>
21#include <linux/interrupt.h>
22#include <linux/mfd/ab8500.h>
23#include <linux/mfd/abx500.h>
24#include <linux/mfd/ab8500/gpio.h>
25
26/*
27 * GPIO registers offset
28 * Bank: 0x10
29 */
30#define AB8500_GPIO_SEL1_REG 0x00
31#define AB8500_GPIO_SEL2_REG 0x01
32#define AB8500_GPIO_SEL3_REG 0x02
33#define AB8500_GPIO_SEL4_REG 0x03
34#define AB8500_GPIO_SEL5_REG 0x04
35#define AB8500_GPIO_SEL6_REG 0x05
36
37#define AB8500_GPIO_DIR1_REG 0x10
38#define AB8500_GPIO_DIR2_REG 0x11
39#define AB8500_GPIO_DIR3_REG 0x12
40#define AB8500_GPIO_DIR4_REG 0x13
41#define AB8500_GPIO_DIR5_REG 0x14
42#define AB8500_GPIO_DIR6_REG 0x15
43
44#define AB8500_GPIO_OUT1_REG 0x20
45#define AB8500_GPIO_OUT2_REG 0x21
46#define AB8500_GPIO_OUT3_REG 0x22
47#define AB8500_GPIO_OUT4_REG 0x23
48#define AB8500_GPIO_OUT5_REG 0x24
49#define AB8500_GPIO_OUT6_REG 0x25
50
51#define AB8500_GPIO_PUD1_REG 0x30
52#define AB8500_GPIO_PUD2_REG 0x31
53#define AB8500_GPIO_PUD3_REG 0x32
54#define AB8500_GPIO_PUD4_REG 0x33
55#define AB8500_GPIO_PUD5_REG 0x34
56#define AB8500_GPIO_PUD6_REG 0x35
57
58#define AB8500_GPIO_IN1_REG 0x40
59#define AB8500_GPIO_IN2_REG 0x41
60#define AB8500_GPIO_IN3_REG 0x42
61#define AB8500_GPIO_IN4_REG 0x43
62#define AB8500_GPIO_IN5_REG 0x44
63#define AB8500_GPIO_IN6_REG 0x45
64#define AB8500_GPIO_ALTFUN_REG 0x45
65#define ALTFUN_REG_INDEX 6
66#define AB8500_NUM_GPIO 42
67#define AB8500_NUM_VIR_GPIO_IRQ 16
68
69enum ab8500_gpio_action {
70 NONE,
71 STARTUP,
72 SHUTDOWN,
73 MASK,
74 UNMASK
75};
76
77struct ab8500_gpio {
78 struct gpio_chip chip;
79 struct ab8500 *parent;
80 struct device *dev;
81 struct mutex lock;
82 u32 irq_base;
83 enum ab8500_gpio_action irq_action;
84 u16 rising;
85 u16 falling;
86};
87/**
88 * to_ab8500_gpio() - get the pointer to ab8500_gpio
89 * @chip: Member of the structure ab8500_gpio
90 */
91static inline struct ab8500_gpio *to_ab8500_gpio(struct gpio_chip *chip)
92{
93 return container_of(chip, struct ab8500_gpio, chip);
94}
95
96static int ab8500_gpio_set_bits(struct gpio_chip *chip, u8 reg,
97 unsigned offset, int val)
98{
99 struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
100 u8 pos = offset % 8;
101 int ret;
102
103 reg = reg + (offset / 8);
104 ret = abx500_mask_and_set_register_interruptible(ab8500_gpio->dev,
105 AB8500_MISC, reg, 1 << pos, val << pos);
106 if (ret < 0)
107 dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
108 return ret;
109}
110/**
111 * ab8500_gpio_get() - Get the particular GPIO value
112 * @chip: Gpio device
113 * @offset: GPIO number to read
114 */
115static int ab8500_gpio_get(struct gpio_chip *chip, unsigned offset)
116{
117 struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
118 u8 mask = 1 << (offset % 8);
119 u8 reg = AB8500_GPIO_OUT1_REG + (offset / 8);
120 int ret;
121 u8 data;
122 ret = abx500_get_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
123 reg, &data);
124 if (ret < 0) {
125 dev_err(ab8500_gpio->dev, "%s read failed\n", __func__);
126 return ret;
127 }
128 return (data & mask) >> (offset % 8);
129}
130
131static void ab8500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
132{
133 struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
134 int ret;
135 /* Write the data */
136 ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, 1);
137 if (ret < 0)
138 dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
139}
140
141static int ab8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
142 int val)
143{
144 int ret;
145 /* set direction as output */
146 ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1);
147 if (ret < 0)
148 return ret;
149 /* disable pull down */
150 ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1);
151 if (ret < 0)
152 return ret;
153 /* set the output as 1 or 0 */
154 return ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
155
156}
157
158static int ab8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
159{
160 /* set the register as input */
161 return ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 0);
162}
163
164static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
165{
166 /*
167 * Only some GPIOs are interrupt capable, and they are
168 * organized in discontiguous clusters:
169 *
170 * GPIO6 to GPIO13
171 * GPIO24 and GPIO25
172 * GPIO36 to GPIO41
173 */
174 static struct ab8500_gpio_irq_cluster {
175 int start;
176 int end;
177 } clusters[] = {
178 {.start = 6, .end = 13},
179 {.start = 24, .end = 25},
180 {.start = 36, .end = 41},