aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-05-11 12:18:27 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-05-20 11:27:04 -0400
commit10bbc48d7a045c022a54f637c0c6b72f0e38b519 (patch)
treee01f9375a4c6c8be210bf3ccc5568d010a434799 /drivers/gpio
parentaa4603a0a7663b10e645b32cc808aac00bc390a3 (diff)
gpio: Convert tps65910 to a platform driver
Make the gpio-tps65910 as platform driver and register this from tps65910 core driver as mfd sub device. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-tps65910.c140
1 files changed, 102 insertions, 38 deletions
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c
index bc155f2509ba..af6dc837ffca 100644
--- a/drivers/gpio/gpio-tps65910.c
+++ b/drivers/gpio/gpio-tps65910.c
@@ -18,11 +18,23 @@
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h>
21#include <linux/mfd/tps65910.h> 22#include <linux/mfd/tps65910.h>
22 23
24struct tps65910_gpio {
25 struct gpio_chip gpio_chip;
26 struct tps65910 *tps65910;
27};
28
29static inline struct tps65910_gpio *to_tps65910_gpio(struct gpio_chip *chip)
30{
31 return container_of(chip, struct tps65910_gpio, gpio_chip);
32}
33
23static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) 34static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
24{ 35{
25 struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); 36 struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
37 struct tps65910 *tps65910 = tps65910_gpio->tps65910;
26 unsigned int val; 38 unsigned int val;
27 39
28 tps65910_reg_read(tps65910, TPS65910_GPIO0 + offset, &val); 40 tps65910_reg_read(tps65910, TPS65910_GPIO0 + offset, &val);
@@ -36,7 +48,8 @@ static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
36static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset, 48static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset,
37 int value) 49 int value)
38{ 50{
39 struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); 51 struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
52 struct tps65910 *tps65910 = tps65910_gpio->tps65910;
40 53
41 if (value) 54 if (value)
42 tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset, 55 tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset,
@@ -49,7 +62,8 @@ static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset,
49static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, 62static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
50 int value) 63 int value)
51{ 64{
52 struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); 65 struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
66 struct tps65910 *tps65910 = tps65910_gpio->tps65910;
53 67
54 /* Set the initial value */ 68 /* Set the initial value */
55 tps65910_gpio_set(gc, offset, value); 69 tps65910_gpio_set(gc, offset, value);
@@ -60,59 +74,109 @@ static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
60 74
61static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) 75static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
62{ 76{
63 struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); 77 struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
78 struct tps65910 *tps65910 = tps65910_gpio->tps65910;
64 79
65 return tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset, 80 return tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset,
66 GPIO_CFG_MASK); 81 GPIO_CFG_MASK);
67} 82}
68 83
69void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) 84static int __devinit tps65910_gpio_probe(struct platform_device *pdev)
70{ 85{
86 struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
87 struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
88 struct tps65910_gpio *tps65910_gpio;
71 int ret; 89 int ret;
72 struct tps65910_board *board_data; 90 int i;
91
92 tps65910_gpio = devm_kzalloc(&pdev->dev,
93 sizeof(*tps65910_gpio), GFP_KERNEL);
94 if (!tps65910_gpio) {
95 dev_err(&pdev->dev, "Could not allocate tps65910_gpio\n");
96 return -ENOMEM;
97 }
73 98
74 if (!gpio_base) 99 tps65910_gpio->tps65910 = tps65910;
75 return;
76 100
77 tps65910->gpio.owner = THIS_MODULE; 101 tps65910_gpio->gpio_chip.owner = THIS_MODULE;
78 tps65910->gpio.label = tps65910->i2c_client->name; 102 tps65910_gpio->gpio_chip.label = tps65910->i2c_client->name;
79 tps65910->gpio.dev = tps65910->dev;
80 tps65910->gpio.base = gpio_base;
81 103
82 switch(tps65910_chip_id(tps65910)) { 104 switch(tps65910_chip_id(tps65910)) {
83 case TPS65910: 105 case TPS65910:
84 tps65910->gpio.ngpio = TPS65910_NUM_GPIO; 106 tps65910_gpio->gpio_chip.ngpio = TPS65910_NUM_GPIO;
85 break; 107 break;
86 case TPS65911: 108 case TPS65911:
87 tps65910->gpio.ngpio = TPS65911_NUM_GPIO; 109 tps65910_gpio->gpio_chip.ngpio = TPS65911_NUM_GPIO;
88 break; 110 break;
89 default: 111 default:
90 return; 112 return -EINVAL;
91 } 113 }
92 tps65910->gpio.can_sleep = 1; 114 tps65910_gpio->gpio_chip.can_sleep = 1;
93 115 tps65910_gpio->gpio_chip.direction_input = tps65910_gpio_input;
94 tps65910->gpio.direction_input = tps65910_gpio_input; 116 tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output;
95 tps65910->gpio.direction_output = tps65910_gpio_output; 117 tps65910_gpio->gpio_chip.set = tps65910_gpio_set;
96 tps65910->gpio.set = tps65910_gpio_set; 118 tps65910_gpio->gpio_chip.get = tps65910_gpio_get;
97 tps65910->gpio.get = tps65910_gpio_get; 119 tps65910_gpio->gpio_chip.dev = &pdev->dev;
98 120 if (pdata && pdata->gpio_base)
99 /* Configure sleep control for gpios */ 121 tps65910_gpio->gpio_chip.base = pdata->gpio_base;
100 board_data = dev_get_platdata(tps65910->dev); 122 else
101 if (board_data) { 123 tps65910_gpio->gpio_chip.base = -1;
102 int i; 124
103 for (i = 0; i < tps65910->gpio.ngpio; ++i) { 125 if (!pdata)
104 if (board_data->en_gpio_sleep[i]) { 126 goto skip_init;
105 ret = tps65910_reg_set_bits(tps65910, 127
106 TPS65910_GPIO0 + i, GPIO_SLEEP_MASK); 128 /* Configure sleep control for gpios if provided */
107 if (ret < 0) 129 for (i = 0; i < tps65910_gpio->gpio_chip.ngpio; ++i) {
108 dev_warn(tps65910->dev, 130 if (!pdata->en_gpio_sleep[i])
109 "GPIO Sleep setting failed\n"); 131 continue;
110 } 132
111 } 133 ret = tps65910_reg_set_bits(tps65910,
134 TPS65910_GPIO0 + i, GPIO_SLEEP_MASK);
135 if (ret < 0)
136 dev_warn(tps65910->dev,
137 "GPIO Sleep setting failed with err %d\n", ret);
138 }
139
140skip_init:
141 ret = gpiochip_add(&tps65910_gpio->gpio_chip);
142 if (ret < 0) {
143 dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
144 return ret;
112 } 145 }
113 146
114 ret = gpiochip_add(&tps65910->gpio); 147 platform_set_drvdata(pdev, tps65910_gpio);
115 148
116 if (ret) 149 return ret;
117 dev_warn(tps65910->dev, "GPIO registration failed: %d\n", ret);
118} 150}
151
152static int __devexit tps65910_gpio_remove(struct platform_device *pdev)
153{
154 struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev);
155
156 return gpiochip_remove(&tps65910_gpio->gpio_chip);
157}
158
159static struct platform_driver tps65910_gpio_driver = {
160 .driver.name = "tps65910-gpio",
161 .driver.owner = THIS_MODULE,
162 .probe = tps65910_gpio_probe,
163 .remove = __devexit_p(tps65910_gpio_remove),
164};
165
166static int __init tps65910_gpio_init(void)
167{
168 return platform_driver_register(&tps65910_gpio_driver);
169}
170subsys_initcall(tps65910_gpio_init);
171
172static void __exit tps65910_gpio_exit(void)
173{
174 platform_driver_unregister(&tps65910_gpio_driver);
175}
176module_exit(tps65910_gpio_exit);
177
178MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
179MODULE_AUTHOR("Jorge Eduardo Candelaria jedu@slimlogic.co.uk>");
180MODULE_DESCRIPTION("GPIO interface for TPS65910/TPS6511 PMICs");
181MODULE_LICENSE("GPL v2");
182MODULE_ALIAS("platform:tps65910-gpio");