blob: b395a4ccc7259f4953a47efe96855ea1d14988a1 [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
Sathish Ambley4149e842012-03-23 11:53:55 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#include <linux/bitmap.h>
14#include <linux/bitops.h>
Rohit Vaswanie50680c2012-06-13 18:26:18 +053015#include <linux/delay.h>
Sathish Ambley4149e842012-03-23 11:53:55 -070016#include <linux/gpio.h>
17#include <linux/init.h>
18#include <linux/io.h>
19#include <linux/irq.h>
20
21#include <mach/msm_iomap.h>
22#include <mach/gpiomux.h>
23#include "gpio-msm-common.h"
24
25/* Bits of interest in the GPIO_IN_OUT register.
26 */
27enum {
28 GPIO_IN_BIT = 0,
29 GPIO_OUT_BIT = 1
30};
31
32/* Bits of interest in the GPIO_INTR_STATUS register.
33 */
34enum {
35 INTR_STATUS_BIT = 0,
36};
37
38/* Bits of interest in the GPIO_CFG register.
39 */
40enum {
41 GPIO_OE_BIT = 9,
42};
43
44/* Bits of interest in the GPIO_INTR_CFG register.
45 */
46enum {
47 INTR_ENABLE_BIT = 0,
48 INTR_POL_CTL_BIT = 1,
49 INTR_DECT_CTL_BIT = 2,
50 INTR_RAW_STATUS_EN_BIT = 4,
51 INTR_TARGET_PROC_BIT = 5,
52 INTR_DIR_CONN_EN_BIT = 8,
53};
54
55/*
56 * There is no 'DC_POLARITY_LO' because the GIC is incapable
57 * of asserting on falling edge or level-low conditions. Even though
58 * the registers allow for low-polarity inputs, the case can never arise.
59 */
60enum {
61 DC_GPIO_SEL_BIT = 0,
62 DC_POLARITY_BIT = 8,
63};
64
65/*
66 * When a GPIO triggers, two separate decisions are made, controlled
67 * by two separate flags.
68 *
69 * - First, INTR_RAW_STATUS_EN controls whether or not the GPIO_INTR_STATUS
70 * register for that GPIO will be updated to reflect the triggering of that
71 * gpio. If this bit is 0, this register will not be updated.
72 * - Second, INTR_ENABLE controls whether an interrupt is triggered.
73 *
74 * If INTR_ENABLE is set and INTR_RAW_STATUS_EN is NOT set, an interrupt
75 * can be triggered but the status register will not reflect it.
76 */
77#define INTR_RAW_STATUS_EN BIT(INTR_RAW_STATUS_EN_BIT)
78#define INTR_ENABLE BIT(INTR_ENABLE_BIT)
79#define INTR_POL_CTL_HI BIT(INTR_POL_CTL_BIT)
80#define INTR_DIR_CONN_EN BIT(INTR_DIR_CONN_EN_BIT)
81#define DC_POLARITY_HI BIT(DC_POLARITY_BIT)
82
83#define INTR_TARGET_PROC_APPS (4 << INTR_TARGET_PROC_BIT)
84#define INTR_TARGET_PROC_NONE (7 << INTR_TARGET_PROC_BIT)
85
86#define INTR_DECT_CTL_LEVEL (0 << INTR_DECT_CTL_BIT)
87#define INTR_DECT_CTL_POS_EDGE (1 << INTR_DECT_CTL_BIT)
88#define INTR_DECT_CTL_NEG_EDGE (2 << INTR_DECT_CTL_BIT)
89#define INTR_DECT_CTL_DUAL_EDGE (3 << INTR_DECT_CTL_BIT)
90#define INTR_DECT_CTL_MASK (3 << INTR_DECT_CTL_BIT)
91
92#define GPIO_CONFIG(gpio) (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
93#define GPIO_IN_OUT(gpio) (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
94#define GPIO_INTR_CFG(gpio) (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
95#define GPIO_INTR_STATUS(gpio) (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
96#define GPIO_DIR_CONN_INTR(intr) (MSM_TLMM_BASE + 0x2800 + (0x04 * (intr)))
97
98static inline void set_gpio_bits(unsigned n, void __iomem *reg)
99{
100 __raw_writel(__raw_readl(reg) | n, reg);
101}
102
103static inline void clr_gpio_bits(unsigned n, void __iomem *reg)
104{
105 __raw_writel(__raw_readl(reg) & ~n, reg);
106}
107
108unsigned __msm_gpio_get_inout(unsigned gpio)
109{
110 return __raw_readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN_BIT);
111}
112
113void __msm_gpio_set_inout(unsigned gpio, unsigned val)
114{
115 __raw_writel(val ? BIT(GPIO_OUT_BIT) : 0, GPIO_IN_OUT(gpio));
116}
117
118void __msm_gpio_set_config_direction(unsigned gpio, int input, int val)
119{
120 if (input) {
121 clr_gpio_bits(BIT(GPIO_OE_BIT), GPIO_CONFIG(gpio));
122 } else {
123 __msm_gpio_set_inout(gpio, val);
124 set_gpio_bits(BIT(GPIO_OE_BIT), GPIO_CONFIG(gpio));
125 }
126}
127
128void __msm_gpio_set_polarity(unsigned gpio, unsigned val)
129{
130 if (val)
131 clr_gpio_bits(INTR_POL_CTL_HI, GPIO_INTR_CFG(gpio));
132 else
133 set_gpio_bits(INTR_POL_CTL_HI, GPIO_INTR_CFG(gpio));
134}
135
136unsigned __msm_gpio_get_intr_status(unsigned gpio)
137{
138 return __raw_readl(GPIO_INTR_STATUS(gpio)) &
139 BIT(INTR_STATUS_BIT);
140}
141
142void __msm_gpio_set_intr_status(unsigned gpio)
143{
Rohit Vaswani75aaf2f2012-07-25 16:47:35 -0700144 __raw_writel(0, GPIO_INTR_STATUS(gpio));
Sathish Ambley4149e842012-03-23 11:53:55 -0700145}
146
147unsigned __msm_gpio_get_intr_config(unsigned gpio)
148{
149 return __raw_readl(GPIO_INTR_CFG(gpio));
150}
151
152void __msm_gpio_set_intr_cfg_enable(unsigned gpio, unsigned val)
153{
154 unsigned cfg;
155
156 cfg = __raw_readl(GPIO_INTR_CFG(gpio));
157 if (val) {
Rohit Vaswaniea45a492012-08-03 11:47:42 -0700158 cfg &= ~INTR_DIR_CONN_EN;
159 cfg |= INTR_ENABLE;
Sathish Ambley4149e842012-03-23 11:53:55 -0700160 } else {
Rohit Vaswaniea45a492012-08-03 11:47:42 -0700161 cfg &= ~INTR_ENABLE;
Sathish Ambley4149e842012-03-23 11:53:55 -0700162 }
163 __raw_writel(cfg, GPIO_INTR_CFG(gpio));
164}
165
Rohit Vaswanif4f36582012-08-28 11:49:11 -0700166unsigned __msm_gpio_get_intr_cfg_enable(unsigned gpio)
167{
168 return __msm_gpio_get_intr_config(gpio) & INTR_ENABLE;
169}
170
Sathish Ambley4149e842012-03-23 11:53:55 -0700171void __msm_gpio_set_intr_cfg_type(unsigned gpio, unsigned type)
172{
173 unsigned cfg;
174
Rohit Vaswaniea45a492012-08-03 11:47:42 -0700175 /* RAW_STATUS_EN is left on for all gpio irqs. Due to the
176 * internal circuitry of TLMM, toggling the RAW_STATUS
177 * could cause the INTR_STATUS to be set for EDGE interrupts.
178 */
Rohit Vaswani5b1f7012012-08-13 21:09:22 -0700179 cfg = INTR_RAW_STATUS_EN | INTR_TARGET_PROC_APPS;
Rohit Vaswaniea45a492012-08-03 11:47:42 -0700180 __raw_writel(cfg, GPIO_INTR_CFG(gpio));
Sathish Ambley4149e842012-03-23 11:53:55 -0700181 cfg &= ~INTR_DECT_CTL_MASK;
182 if (type == IRQ_TYPE_EDGE_RISING)
183 cfg |= INTR_DECT_CTL_POS_EDGE;
184 else if (type == IRQ_TYPE_EDGE_FALLING)
185 cfg |= INTR_DECT_CTL_NEG_EDGE;
186 else if (type == IRQ_TYPE_EDGE_BOTH)
187 cfg |= INTR_DECT_CTL_DUAL_EDGE;
188 else
189 cfg |= INTR_DECT_CTL_LEVEL;
190
Rohit Vaswani54ce8562012-08-13 21:10:57 -0700191 if (type & IRQ_TYPE_LEVEL_LOW)
Sathish Ambley4149e842012-03-23 11:53:55 -0700192 cfg &= ~INTR_POL_CTL_HI;
Rohit Vaswani54ce8562012-08-13 21:10:57 -0700193 else
194 cfg |= INTR_POL_CTL_HI;
Sathish Ambley4149e842012-03-23 11:53:55 -0700195
196 __raw_writel(cfg, GPIO_INTR_CFG(gpio));
Rohit Vaswanie50680c2012-06-13 18:26:18 +0530197 /* Sometimes it might take a little while to update
198 * the interrupt status after the RAW_STATUS is enabled
Rohit Vaswaniea45a492012-08-03 11:47:42 -0700199 * We clear the interrupt status before enabling the
200 * interrupt in the unmask call-back.
Rohit Vaswanie50680c2012-06-13 18:26:18 +0530201 */
202 udelay(5);
Sathish Ambley4149e842012-03-23 11:53:55 -0700203}
204
205void __gpio_tlmm_config(unsigned config)
206{
207 unsigned flags;
208 unsigned gpio = GPIO_PIN(config);
209
210 flags = ((GPIO_DIR(config) << 9) & (0x1 << 9)) |
211 ((GPIO_DRVSTR(config) << 6) & (0x7 << 6)) |
212 ((GPIO_FUNC(config) << 2) & (0xf << 2)) |
213 ((GPIO_PULL(config) & 0x3));
214 __raw_writel(flags, GPIO_CONFIG(gpio));
215}
216
217void __msm_gpio_install_direct_irq(unsigned gpio, unsigned irq,
218 unsigned int input_polarity)
219{
220 unsigned cfg;
221
222 set_gpio_bits(BIT(GPIO_OE_BIT), GPIO_CONFIG(gpio));
223 cfg = __raw_readl(GPIO_INTR_CFG(gpio));
224 cfg &= ~(INTR_TARGET_PROC_NONE | INTR_RAW_STATUS_EN | INTR_ENABLE);
225 cfg |= INTR_TARGET_PROC_APPS | INTR_DIR_CONN_EN;
226 __raw_writel(cfg, GPIO_INTR_CFG(gpio));
227
228 cfg = gpio;
229 if (input_polarity)
230 cfg |= DC_POLARITY_HI;
231 __raw_writel(cfg, GPIO_DIR_CONN_INTR(irq));
232}