PM / devfreq: rk3399_dmc: rename driver and internals to rockchip
[firefly-linux-kernel-4.4.55.git] / drivers / gpio / gpio-rt5025.c
1 /*
2  *  drivers/gpio/rt5025-gpio.c
3  *  Driver foo Richtek RT5025 PMIC GPIO
4  *
5  *  Copyright (C) 2014 Richtek Technologh Corp.
6  *  cy_huang <cy_huang@richtek.com>
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 version 2 as
10  * published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  */
13
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/err.h>
18 #include <linux/gpio.h>
19 #include <linux/i2c.h>
20 #include <linux/platform_device.h>
21 #include <linux/of.h>
22
23 #include <linux/mfd/rt5025.h>
24 #include <linux/mfd/rt5025-gpio.h>
25
26 struct rt5025_gpio_info {
27         struct i2c_client *i2c;
28         unsigned gpio_base;
29         unsigned irq_base;
30         int ngpio;
31         struct gpio_chip gpio_chip;
32 };
33
34 static inline int find_rt5025_gpioreg(unsigned off, int *gpio_reg)
35 {
36         int ret = 0;
37
38         switch (off) {
39         case 0:
40         case 1:
41         case 2:
42                 *gpio_reg = RT5025_REG_GPIO0 + off;
43                 break;
44         default:
45                 ret = -EINVAL;
46         }
47         return ret;
48 }
49
50 static int rt5025_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
51 {
52         struct rt5025_gpio_info *gi = dev_get_drvdata(chip->dev);
53         int gpio_reg = 0;
54         int ret = 0;
55
56         ret = find_rt5025_gpioreg(offset , &gpio_reg);
57         if (ret < 0) {
58                 dev_err(chip->dev, "not a valid gpio index\n");
59                 return ret;
60         }
61
62         ret = rt5025_clr_bits(gi->i2c, gpio_reg, RT5025_GPIO_DIRMASK);
63         if (ret < 0) {
64                 dev_err(chip->dev, "set gpio input fail\n");
65                 return ret;
66         }
67
68         return 0;
69 }
70
71 static int rt5025_gpio_direction_output(struct gpio_chip *chip,
72         unsigned offset, int value)
73 {
74         struct rt5025_gpio_info *gi = dev_get_drvdata(chip->dev);
75         int gpio_reg = 0;
76         int ret = 0;
77
78         ret = find_rt5025_gpioreg(offset, &gpio_reg);
79         if (ret < 0) {
80                 dev_err(chip->dev, "not a valid gpio index\n");
81                 return ret;
82         }
83
84         ret = rt5025_clr_bits(gi->i2c, gpio_reg, RT5025_GPIO_DIRSHIFT);
85         if (ret < 0) {
86                 dev_err(chip->dev, "clr gpio direction fail\n");
87                 return ret;
88         }
89
90         ret = rt5025_set_bits(gi->i2c, gpio_reg,
91                 RT5025_GPIO_OUTPUT<<RT5025_GPIO_DIRSHIFT);
92         if (ret < 0) {
93                 dev_err(chip->dev, "set gpio output dir fail\n");
94                 return ret;
95         }
96
97         if (value)
98                 ret = rt5025_set_bits(gi->i2c, gpio_reg,
99                 RT5025_GPIO_OVALUEMASK);
100         else
101                 ret = rt5025_clr_bits(gi->i2c, gpio_reg,
102                 RT5025_GPIO_OVALUEMASK);
103
104         if (ret < 0) {
105                 dev_err(chip->dev, "set gpio output value fail\n");
106                 return ret;
107         }
108
109         return 0;
110 }
111
112 static int rt5025_gpio_get_value(struct gpio_chip *chip, unsigned offset)
113 {
114         struct rt5025_gpio_info *gi = dev_get_drvdata(chip->dev);
115         int gpio_reg = 0;
116         int ret = 0;
117
118         ret = find_rt5025_gpioreg(offset, &gpio_reg);
119         if (ret < 0) {
120                 dev_err(chip->dev, "not a valid gpio index\n");
121                 return ret;
122         }
123
124         ret = rt5025_reg_read(gi->i2c, gpio_reg);
125         if (ret < 0) {
126                 dev_err(chip->dev, "read gpio register fail\n");
127                 return ret;
128         }
129
130         return (ret&RT5025_GPIO_IVALUEMASK)?1 : 0;
131 }
132
133 static void rt5025_gpio_set_value(struct gpio_chip *chip,
134         unsigned offset, int value)
135 {
136         struct rt5025_gpio_info *gi = dev_get_drvdata(chip->dev);
137         int gpio_reg = 0;
138         int ret = 0;
139
140         ret = find_rt5025_gpioreg(offset, &gpio_reg);
141         if (ret < 0) {
142                 dev_err(chip->dev, "not a valid gpio index\n");
143                 return;
144         }
145
146         if (value)
147                 ret = rt5025_set_bits(gi->i2c, gpio_reg,
148                 RT5025_GPIO_OVALUEMASK);
149         else
150                 ret = rt5025_clr_bits(gi->i2c, gpio_reg,
151                 RT5025_GPIO_OVALUEMASK);
152
153         if (ret < 0)
154                 dev_err(chip->dev, "read gpio register fail\n");
155 }
156
157 static int rt_parse_dt(struct rt5025_gpio_info *gi, struct device *dev)
158 {
159         #ifdef CONFIG_OF
160         struct device_node *np = dev->of_node;
161
162         of_property_read_u32(np, "rt,ngpio", &gi->ngpio);
163         #endif /* #ifdef CONFIG_OF */
164         return 0;
165 }
166
167 static int rt_parse_pdata(struct rt5025_gpio_info *gi, struct device *dev)
168 {
169         struct rt5025_gpio_data *gpio_pdata = dev->platform_data;
170
171         gi->ngpio = gpio_pdata->ngpio;
172         return 0;
173 }
174
175 static int rt5025_gpio_probe(struct platform_device *pdev)
176 {
177         struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
178         struct rt5025_platform_data *pdata = (pdev->dev.parent)->platform_data;
179         struct rt5025_gpio_info *gi;
180         bool use_dt = pdev->dev.of_node;
181         int rc = 0;
182
183         gi = devm_kzalloc(&pdev->dev, sizeof(*gi), GFP_KERNEL);
184         if (!gi)
185                 return -ENOMEM;
186
187
188         gi->i2c = chip->i2c;
189         if (use_dt) {
190                 rt_parse_dt(gi, &pdev->dev);
191         } else {
192                 if (!pdata) {
193                         rc = -EINVAL;
194                         goto out_dev;
195                 }
196                 pdev->dev.platform_data = pdata->gpio_pdata;
197                 rt_parse_pdata(gi, &pdev->dev);
198         }
199
200         gi->gpio_chip.direction_input  = rt5025_gpio_direction_input;
201         gi->gpio_chip.direction_output = rt5025_gpio_direction_output;
202         gi->gpio_chip.get = rt5025_gpio_get_value;
203         gi->gpio_chip.set = rt5025_gpio_set_value;
204         gi->gpio_chip.can_sleep = 0;
205
206         gi->gpio_chip.base = -1;
207         gi->gpio_chip.ngpio = gi->ngpio;
208         gi->gpio_chip.label = pdev->name;
209         gi->gpio_chip.dev = &pdev->dev;
210         gi->gpio_chip.owner = THIS_MODULE;
211
212         rc = gpiochip_add(&gi->gpio_chip);
213         if (rc)
214                 goto out_dev;
215
216         platform_set_drvdata(pdev, gi);
217         dev_info(&pdev->dev, "driver successfully loaded\n");
218         return rc;
219 out_dev:
220         return rc;
221 }
222
223 static int rt5025_gpio_remove(struct platform_device *pdev)
224 {
225         int rc = 0;
226         struct rt5025_gpio_info *gi = platform_get_drvdata(pdev);
227
228         rc = gpiochip_remove(&gi->gpio_chip);
229         dev_info(&pdev->dev, "\n");
230         return 0;
231 }
232
233 static struct of_device_id rt_match_table[] = {
234         { .compatible = "rt,rt5025-gpio",},
235         {},
236 };
237
238 static struct platform_driver rt5025_gpio_driver = {
239         .driver = {
240                 .name = RT5025_DEV_NAME "-gpio",
241                 .owner = THIS_MODULE,
242                 .of_match_table = rt_match_table,
243         },
244         .probe = rt5025_gpio_probe,
245         .remove = rt5025_gpio_remove,
246 };
247
248 static int rt5025_gpio_init(void)
249 {
250         return platform_driver_register(&rt5025_gpio_driver);
251 }
252 fs_initcall_sync(rt5025_gpio_init);
253
254 static void rt5025_gpio_exit(void)
255 {
256         platform_driver_unregister(&rt5025_gpio_driver);
257 }
258 module_exit(rt5025_gpio_exit);
259
260 MODULE_LICENSE("GPL");
261 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com>");
262 MODULE_DESCRIPTION("GPIO driver for RT5025");
263 MODULE_ALIAS("platform:" RT5025_DEV_NAME "-gpio");
264 MODULE_VERSION(RT5025_DRV_VER);