2 * TI TPS6586x GPIO driver
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5 * Author: Laxman dewangan <ldewangan@nvidia.com>
8 * Copyright (c) 2010 CompuLab Ltd.
9 * Mike Rapoport <mike@compulab.co.il>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms and conditions of the GNU General Public License,
13 * version 2, as published by the Free Software Foundation.
15 * This program is distributed in the hope it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/errno.h>
25 #include <linux/gpio.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/mfd/tps6586x.h>
29 #include <linux/of_device.h>
30 #include <linux/platform_device.h>
32 /* GPIO control registers */
33 #define TPS6586X_GPIOSET1 0x5d
34 #define TPS6586X_GPIOSET2 0x5e
36 struct tps6586x_gpio
{
37 struct gpio_chip gpio_chip
;
38 struct device
*parent
;
41 static inline struct tps6586x_gpio
*to_tps6586x_gpio(struct gpio_chip
*chip
)
43 return container_of(chip
, struct tps6586x_gpio
, gpio_chip
);
46 static int tps6586x_gpio_get(struct gpio_chip
*gc
, unsigned offset
)
48 struct tps6586x_gpio
*tps6586x_gpio
= to_tps6586x_gpio(gc
);
52 ret
= tps6586x_read(tps6586x_gpio
->parent
, TPS6586X_GPIOSET2
, &val
);
56 return !!(val
& (1 << offset
));
59 static void tps6586x_gpio_set(struct gpio_chip
*gc
, unsigned offset
,
62 struct tps6586x_gpio
*tps6586x_gpio
= to_tps6586x_gpio(gc
);
64 tps6586x_update(tps6586x_gpio
->parent
, TPS6586X_GPIOSET2
,
65 value
<< offset
, 1 << offset
);
68 static int tps6586x_gpio_output(struct gpio_chip
*gc
, unsigned offset
,
71 struct tps6586x_gpio
*tps6586x_gpio
= to_tps6586x_gpio(gc
);
74 tps6586x_gpio_set(gc
, offset
, value
);
76 val
= 0x1 << (offset
* 2);
77 mask
= 0x3 << (offset
* 2);
79 return tps6586x_update(tps6586x_gpio
->parent
, TPS6586X_GPIOSET1
,
83 static int tps6586x_gpio_to_irq(struct gpio_chip
*gc
, unsigned offset
)
85 struct tps6586x_gpio
*tps6586x_gpio
= to_tps6586x_gpio(gc
);
87 return tps6586x_irq_get_virq(tps6586x_gpio
->parent
,
88 TPS6586X_INT_PLDO_0
+ offset
);
91 static int tps6586x_gpio_probe(struct platform_device
*pdev
)
93 struct tps6586x_platform_data
*pdata
;
94 struct tps6586x_gpio
*tps6586x_gpio
;
97 pdata
= dev_get_platdata(pdev
->dev
.parent
);
98 tps6586x_gpio
= devm_kzalloc(&pdev
->dev
,
99 sizeof(*tps6586x_gpio
), GFP_KERNEL
);
100 if (!tps6586x_gpio
) {
101 dev_err(&pdev
->dev
, "Could not allocate tps6586x_gpio\n");
105 tps6586x_gpio
->parent
= pdev
->dev
.parent
;
107 tps6586x_gpio
->gpio_chip
.owner
= THIS_MODULE
;
108 tps6586x_gpio
->gpio_chip
.label
= pdev
->name
;
109 tps6586x_gpio
->gpio_chip
.dev
= &pdev
->dev
;
110 tps6586x_gpio
->gpio_chip
.ngpio
= 4;
111 tps6586x_gpio
->gpio_chip
.can_sleep
= true;
113 /* FIXME: add handling of GPIOs as dedicated inputs */
114 tps6586x_gpio
->gpio_chip
.direction_output
= tps6586x_gpio_output
;
115 tps6586x_gpio
->gpio_chip
.set
= tps6586x_gpio_set
;
116 tps6586x_gpio
->gpio_chip
.get
= tps6586x_gpio_get
;
117 tps6586x_gpio
->gpio_chip
.to_irq
= tps6586x_gpio_to_irq
;
119 #ifdef CONFIG_OF_GPIO
120 tps6586x_gpio
->gpio_chip
.of_node
= pdev
->dev
.parent
->of_node
;
122 if (pdata
&& pdata
->gpio_base
)
123 tps6586x_gpio
->gpio_chip
.base
= pdata
->gpio_base
;
125 tps6586x_gpio
->gpio_chip
.base
= -1;
127 ret
= gpiochip_add(&tps6586x_gpio
->gpio_chip
);
129 dev_err(&pdev
->dev
, "Could not register gpiochip, %d\n", ret
);
133 platform_set_drvdata(pdev
, tps6586x_gpio
);
138 static int tps6586x_gpio_remove(struct platform_device
*pdev
)
140 struct tps6586x_gpio
*tps6586x_gpio
= platform_get_drvdata(pdev
);
142 return gpiochip_remove(&tps6586x_gpio
->gpio_chip
);
145 static struct platform_driver tps6586x_gpio_driver
= {
146 .driver
.name
= "tps6586x-gpio",
147 .driver
.owner
= THIS_MODULE
,
148 .probe
= tps6586x_gpio_probe
,
149 .remove
= tps6586x_gpio_remove
,
152 static int __init
tps6586x_gpio_init(void)
154 return platform_driver_register(&tps6586x_gpio_driver
);
156 subsys_initcall(tps6586x_gpio_init
);
158 static void __exit
tps6586x_gpio_exit(void)
160 platform_driver_unregister(&tps6586x_gpio_driver
);
162 module_exit(tps6586x_gpio_exit
);
164 MODULE_ALIAS("platform:tps6586x-gpio");
165 MODULE_DESCRIPTION("GPIO interface for TPS6586X PMIC");
166 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
167 MODULE_LICENSE("GPL");