rk29_phone: fix heatset main mic Call Features
[firefly-linux-kernel-4.4.55.git] / drivers / gpio / tps65910-gpio.c
1 /*
2  * tps65910_gpio.c -- access to GPIOs on TPS65910x chips
3  *
4  * Copyright (C) 2010 Mistral solutions Pvt Ltd <www.mistralsolutions.com>
5  *
6  * Based on twl4030-gpio.c
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  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/interrupt.h>
26 #include <linux/kthread.h>
27 #include <linux/irq.h>
28 #include <linux/gpio.h>
29 #include <linux/platform_device.h>
30 #include <linux/slab.h>
31
32 #include <linux/i2c/tps65910.h>
33
34 static int gpio_tps65910_remove(struct platform_device *pdev);
35
36 /*
37  * The GPIO "subchip" supports 1 GPIOs which can be configured as
38  * inputs or outputs, with pullups or pulldowns on each pin.  Each
39  * GPIO can trigger interrupts on either or both edges.
40  */
41
42
43 /* Data structures */
44 static struct gpio_chip tps65910_gpiochip;
45 static DEFINE_MUTEX(gpio_lock);
46 static unsigned int gpio_usage_count;
47 static struct work_struct  gpio_work;
48 static struct mutex work_lock;
49 /*
50  * To configure TPS65910 GPIO registers
51  */
52 static inline int gpio_tps65910_write(u8 address, u8 data)
53 {
54         return tps65910_i2c_write_u8(TPS65910_I2C_ID0, data, address);
55 }
56
57
58 /*
59  * To read a TPS65910 GPIO module register
60  */
61 static inline int gpio_tps65910_read(u8 address)
62 {
63         u8 data;
64         int ret = 0;
65
66         ret = tps65910_i2c_read_u8(TPS65910_I2C_ID0, &data, address);
67         return (ret < 0) ? ret : data;
68 }
69
70 static int tps65910_request(struct gpio_chip *chip, unsigned offset)
71 {
72         int status = 0;
73
74         mutex_lock(&gpio_lock);
75
76         /* initialize TPS65910 GPIO */
77         /* By default the GPIO_CKSYNC signal is GPIO */
78         if (!gpio_usage_count)
79                 gpio_usage_count++;
80
81         mutex_unlock(&gpio_lock);
82         return status;
83 }
84
85 static void tps65910_free(struct gpio_chip *chip, unsigned offset)
86 {
87         mutex_lock(&gpio_lock);
88
89         /* on last use, switch off GPIO module */
90         if (!gpio_usage_count)
91                 gpio_usage_count--;
92
93         mutex_unlock(&gpio_lock);
94 }
95
96 static int tps65910_direction_in(struct gpio_chip *chip, unsigned offset)
97 {
98         /* Configure TPS65910 GPIO as input */
99         u8 val;
100
101         mutex_lock(&gpio_lock);
102
103         val = gpio_tps65910_read(TPS65910_REG_GPIO0);
104
105         val &= ~(TPS65910_GPIO_CFG_OUTPUT);
106
107         val = gpio_tps65910_read(TPS65910_REG_GPIO0);
108
109         mutex_unlock(&gpio_lock);
110
111         return 0;
112 }
113
114 static int tps65910_get(struct gpio_chip *chip, unsigned offset)
115 {
116         int status = 0;
117
118         mutex_lock(&gpio_lock);
119
120         status = gpio_tps65910_read(TPS65910_REG_GPIO0);
121
122         mutex_unlock(&gpio_lock);
123         if (status & 0x01)
124                 return 1;
125         else
126                 return 0;
127 }
128 static
129 int tps65910_direction_out(struct gpio_chip *chip, unsigned offset, int value)
130 {
131         /* Configure TPS65910 GPIO as input */
132         u8 val;
133         u32 ret;
134         mutex_lock(&gpio_lock);
135         val = gpio_tps65910_read(TPS65910_REG_GPIO0);
136
137         val |= TPS65910_GPIO_CFG_OUTPUT;
138
139         ret = gpio_tps65910_write(TPS65910_REG_GPIO0, val);
140         mutex_unlock(&gpio_lock);
141
142         if (ret != 0)
143                 return -EIO;
144         return 0;
145 }
146
147 static void tps65910_set(struct gpio_chip *chip, unsigned offset, int value)
148 {
149         int val = 0;
150         u32 ret;
151
152         mutex_lock(&gpio_lock);
153         val = gpio_tps65910_read(TPS65910_REG_GPIO0);
154
155         if (value == 1)
156                 val |= 0x01;
157         else
158                 val &= 0xFE;
159
160         ret = gpio_tps65910_write(TPS65910_REG_GPIO0, val);
161
162         mutex_unlock(&gpio_lock);
163 }
164
165
166
167 static void tps65910_gpio_set_debounce(u8 debounce)
168 {
169         u8 val;
170
171         mutex_lock(&gpio_lock);
172
173         val = gpio_tps65910_read(TPS65910_REG_GPIO0);
174
175         if (debounce == TPS65910_DEBOUNCE_91_5_MS)
176                 val = (0<<4);
177         else if (debounce == TPS65910_DEBOUNCE_150_MS)
178                 val = (1<<4);
179         else
180                 printk(KERN_ERR "Invalid argument to %s\n", __func__);
181
182         gpio_tps65910_write(TPS65910_REG_GPIO0, val);
183
184         mutex_unlock(&gpio_lock);
185 }
186 EXPORT_SYMBOL(tps65910_gpio_set_debounce);
187
188
189 static void tps65910_gpio_pullup_enable(void)
190 {
191         u8 val;
192         u32 ret;
193
194         mutex_lock(&gpio_lock);
195
196         val = gpio_tps65910_read(TPS65910_REG_GPIO0);
197
198         val = (1<<3);
199
200         ret = gpio_tps65910_write(TPS65910_REG_GPIO0, val);
201
202         mutex_unlock(&gpio_lock);
203
204         if (ret != 0)
205                 printk(KERN_ERR "Error writing to TPS65910_REG_GPIO0 in %s \n",
206                                 __func__);
207 }
208 EXPORT_SYMBOL(tps65910_gpio_pullup_enable);
209
210 static void tps65910_gpio_pullup_disable(void)
211 {
212         u8 val;
213         u32 ret;
214
215         mutex_lock(&gpio_lock);
216
217         val = gpio_tps65910_read(TPS65910_REG_GPIO0);
218
219         val = (0<<3);
220
221         ret = gpio_tps65910_write(TPS65910_REG_GPIO0, val);
222
223         mutex_unlock(&gpio_lock);
224 }
225 EXPORT_SYMBOL(tps65910_gpio_pullup_disable);
226
227 static void tps65910_gpio_work(struct work_struct *work)
228 {
229
230         /* Read the status register and take action  */
231         u8 status2;
232         int err;
233         mutex_lock(&work_lock);
234         err =  tps65910_i2c_read_u8(TPS65910_I2C_ID0, &status2,
235                         TPS65910_REG_INT_STS);
236         if (!err) {
237                 switch (status2) {
238                 case TPS65910_GPIO_F_IT:
239                         printk(KERN_NOTICE "Received TPS65910 GPIO falling \
240                                 edge interrupt \n");
241                         /* Clear interrupt */
242                         tps65910_i2c_write_u8(TPS65910_I2C_ID0, status2,
243                                         TPS65910_REG_INT_STS);
244                         /* Add code accroding to board requirment */
245                         break;
246                 case TPS65910_GPIO_R_IT:
247                         printk(KERN_NOTICE "Received TPS65910 GPIO Raising \
248                                  edge interrupt \n");
249                         /* Clear interrupt */
250                         tps65910_i2c_write_u8(TPS65910_I2C_ID0, status2,
251                                         TPS65910_REG_INT_STS);
252                         /* Add code accroding to board requirment */
253                         break;
254                 }
255         } else {
256                 printk(KERN_ERR"Could not read TPS65910_REG_INT_STS\n");
257         }
258
259         mutex_unlock(&work_lock);
260
261 }
262
263
264
265 static irqreturn_t tps65910_gpio_isr(int irq, void *_tps65910)
266 {
267         /* Disable IRQ, schedule work, enable IRQ and  acknowledge */
268         disable_irq(irq);
269         (void) schedule_work(&gpio_work);
270         enable_irq(irq);
271         return IRQ_HANDLED;
272 }
273
274
275 static struct gpio_chip tps65910_gpiochip = {
276         .label                  = "tps65910",
277         .owner                  = THIS_MODULE,
278         .request                = tps65910_request,
279         .free                   = tps65910_free,
280         .direction_input        = tps65910_direction_in,
281         .get                    = tps65910_get,
282         .direction_output       = tps65910_direction_out,
283         .set                    = tps65910_set,
284 };
285
286
287 static int __devinit gpio_tps65910_probe(struct platform_device *pdev)
288 {
289         int ret = -1;
290         int status = 0;
291
292         struct tps65910_gpio *pdata = pdev->dev.platform_data;
293
294         if (pdata->gpio_mode == TPS65910_GPIO_AS_IRQ) {
295
296                 if (pdata->irq_num) {
297                         status = request_irq(pdata->irq_num, tps65910_gpio_isr,
298                                         IRQF_SHARED, "tps65910_gpio", pdev);
299                         if (status < 0) {
300                                 pr_err("tps65910: could not claim irq%d: %d\n",
301                                         pdata->irq_num, status);
302                         }
303
304                 }
305
306                 INIT_WORK(&gpio_work, tps65910_gpio_work);
307                 mutex_init(&work_lock);
308
309                 tps65910_gpiochip.ngpio = TPS65910_GPIO_MAX;
310                 tps65910_gpiochip.dev = &pdev->dev;
311
312                 ret = gpiochip_add(&tps65910_gpiochip);
313
314                 if (ret < 0) {
315                         dev_err(&pdev->dev, "could not register gpiochip \
316                                  %d\n", ret);
317                         tps65910_gpiochip.ngpio = 0;
318                         gpio_tps65910_remove(pdev);
319                         return -ENODEV;
320                 }
321                 if (pdata->gpio_setup)
322                         pdata->gpio_setup(pdata);
323         }
324         return ret;
325 }
326
327 static int gpio_tps65910_remove(struct platform_device *pdev)
328 {
329         struct tps65910_gpio *pdata = pdev->dev.platform_data;
330         int status;
331
332         if (pdata->gpio_taredown)
333                 pdata->gpio_taredown(pdata);
334         if (pdata->gpio_mode == TPS65910_GPIO_AS_IRQ)
335                 free_irq(pdata->irq_num, NULL);
336
337         status = gpiochip_remove(&tps65910_gpiochip);
338         if (status < 0)
339                 return status;
340         return 0;
341 }
342
343 static struct platform_driver gpio_tps65910_driver = {
344         .driver.name    = "tps65910_gpio",
345         .driver.owner   = THIS_MODULE,
346         .probe          = gpio_tps65910_probe,
347         .remove         = gpio_tps65910_remove,
348 };
349
350 static int __init gpio_tps65910_init(void)
351 {
352         return platform_driver_register(&gpio_tps65910_driver);
353 }
354 subsys_initcall(gpio_tps65910_init);
355
356 static void __exit gpio_tps65910_exit(void)
357 {
358         platform_driver_unregister(&gpio_tps65910_driver);
359 }
360 module_exit(gpio_tps65910_exit);
361
362 MODULE_AUTHOR("Mistral Solutions Pvt Ltd.");
363 MODULE_DESCRIPTION("GPIO interface for TPS65910");
364 MODULE_LICENSE("GPL");