Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[sfrench/cifs-2.6.git] / arch / arm / mach-msm / board-trout-gpio.c
1 /*
2  * linux/arch/arm/mach-msm/gpio.c
3  *
4  * Copyright (C) 2005 HP Labs
5  * Copyright (C) 2008 Google, Inc.
6  * Copyright (C) 2009 Pavel Machek <pavel@ucw.cz>
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 as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/io.h>
17 #include <linux/irq.h>
18 #include <linux/gpio.h>
19
20 #include "board-trout.h"
21
22 struct msm_gpio_chip {
23         struct gpio_chip        chip;
24         void __iomem            *reg;   /* Base of register bank */
25         u8                      shadow;
26 };
27
28 #define to_msm_gpio_chip(c) container_of(c, struct msm_gpio_chip, chip)
29
30 static int msm_gpiolib_get(struct gpio_chip *chip, unsigned offset)
31 {
32         struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
33         unsigned mask = 1 << offset;
34
35         return !!(readb(msm_gpio->reg) & mask);
36 }
37
38 static void msm_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
39 {
40         struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
41         unsigned mask = 1 << offset;
42
43         if (val)
44                 msm_gpio->shadow |= mask;
45         else
46                 msm_gpio->shadow &= ~mask;
47
48         writeb(msm_gpio->shadow, msm_gpio->reg);
49 }
50
51 static int msm_gpiolib_direction_input(struct gpio_chip *chip,
52                                         unsigned offset)
53 {
54         msm_gpiolib_set(chip, offset, 0);
55         return 0;
56 }
57
58 static int msm_gpiolib_direction_output(struct gpio_chip *chip,
59                                          unsigned offset, int val)
60 {
61         msm_gpiolib_set(chip, offset, val);
62         return 0;
63 }
64
65 #define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val)           \
66         {                                                               \
67                 .chip = {                                               \
68                         .label            = name,                       \
69                         .direction_input  = msm_gpiolib_direction_input,\
70                         .direction_output = msm_gpiolib_direction_output, \
71                         .get              = msm_gpiolib_get,            \
72                         .set              = msm_gpiolib_set,            \
73                         .base             = base_gpio,                  \
74                         .ngpio            = 8,                          \
75                 },                                                      \
76                 .reg = (void *) reg_num + TROUT_CPLD_BASE,              \
77                 .shadow = shadow_val,                                   \
78         }
79
80 static struct msm_gpio_chip msm_gpio_banks[] = {
81 #if defined(CONFIG_MSM_DEBUG_UART1)
82         /* H2W pins <-> UART1 */
83         TROUT_GPIO_BANK("MISC2", 0x00,   TROUT_GPIO_MISC2_BASE, 0x40),
84 #else
85         /* H2W pins <-> UART3, Bluetooth <-> UART1 */
86         TROUT_GPIO_BANK("MISC2", 0x00,   TROUT_GPIO_MISC2_BASE, 0x80),
87 #endif
88         /* I2C pull */
89         TROUT_GPIO_BANK("MISC3", 0x02,   TROUT_GPIO_MISC3_BASE, 0x04),
90         TROUT_GPIO_BANK("MISC4", 0x04,   TROUT_GPIO_MISC4_BASE, 0),
91         /* mmdi 32k en */
92         TROUT_GPIO_BANK("MISC5", 0x06,   TROUT_GPIO_MISC5_BASE, 0x04),
93         TROUT_GPIO_BANK("INT2", 0x08,    TROUT_GPIO_INT2_BASE,  0),
94         TROUT_GPIO_BANK("MISC1", 0x0a,   TROUT_GPIO_MISC1_BASE, 0),
95         TROUT_GPIO_BANK("VIRTUAL", 0x12, TROUT_GPIO_VIRTUAL_BASE, 0),
96 };
97
98 /*
99  * Called from the processor-specific init to enable GPIO pin support.
100  */
101 int __init trout_init_gpio(void)
102 {
103         int i;
104
105         for (i = 0; i < ARRAY_SIZE(msm_gpio_banks); i++)
106                 gpiochip_add(&msm_gpio_banks[i].chip);
107
108         return 0;
109 }
110
111 postcore_initcall(trout_init_gpio);
112