1 // SPDX-License-Identifier: GPL-2.0
3 * TI TPS6586x GPIO driver
5 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
6 * Author: Laxman dewangan <ldewangan@nvidia.com>
9 * Copyright (c) 2010 CompuLab Ltd.
10 * Mike Rapoport <mike@compulab.co.il>
13 #include <linux/errno.h>
14 #include <linux/gpio/driver.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/mfd/tps6586x.h>
18 #include <linux/of_device.h>
19 #include <linux/platform_device.h>
21 /* GPIO control registers */
22 #define TPS6586X_GPIOSET1 0x5d
23 #define TPS6586X_GPIOSET2 0x5e
25 struct tps6586x_gpio
{
26 struct gpio_chip gpio_chip
;
27 struct device
*parent
;
30 static int tps6586x_gpio_get(struct gpio_chip
*gc
, unsigned offset
)
32 struct tps6586x_gpio
*tps6586x_gpio
= gpiochip_get_data(gc
);
36 ret
= tps6586x_read(tps6586x_gpio
->parent
, TPS6586X_GPIOSET2
, &val
);
40 return !!(val
& (1 << offset
));
43 static void tps6586x_gpio_set(struct gpio_chip
*gc
, unsigned offset
,
46 struct tps6586x_gpio
*tps6586x_gpio
= gpiochip_get_data(gc
);
48 tps6586x_update(tps6586x_gpio
->parent
, TPS6586X_GPIOSET2
,
49 value
<< offset
, 1 << offset
);
52 static int tps6586x_gpio_output(struct gpio_chip
*gc
, unsigned offset
,
55 struct tps6586x_gpio
*tps6586x_gpio
= gpiochip_get_data(gc
);
58 tps6586x_gpio_set(gc
, offset
, value
);
60 val
= 0x1 << (offset
* 2);
61 mask
= 0x3 << (offset
* 2);
63 return tps6586x_update(tps6586x_gpio
->parent
, TPS6586X_GPIOSET1
,
67 static int tps6586x_gpio_to_irq(struct gpio_chip
*gc
, unsigned offset
)
69 struct tps6586x_gpio
*tps6586x_gpio
= gpiochip_get_data(gc
);
71 return tps6586x_irq_get_virq(tps6586x_gpio
->parent
,
72 TPS6586X_INT_PLDO_0
+ offset
);
75 static int tps6586x_gpio_probe(struct platform_device
*pdev
)
77 struct tps6586x_platform_data
*pdata
;
78 struct tps6586x_gpio
*tps6586x_gpio
;
81 pdata
= dev_get_platdata(pdev
->dev
.parent
);
82 tps6586x_gpio
= devm_kzalloc(&pdev
->dev
,
83 sizeof(*tps6586x_gpio
), GFP_KERNEL
);
87 tps6586x_gpio
->parent
= pdev
->dev
.parent
;
89 tps6586x_gpio
->gpio_chip
.owner
= THIS_MODULE
;
90 tps6586x_gpio
->gpio_chip
.label
= pdev
->name
;
91 tps6586x_gpio
->gpio_chip
.parent
= &pdev
->dev
;
92 tps6586x_gpio
->gpio_chip
.ngpio
= 4;
93 tps6586x_gpio
->gpio_chip
.can_sleep
= true;
95 /* FIXME: add handling of GPIOs as dedicated inputs */
96 tps6586x_gpio
->gpio_chip
.direction_output
= tps6586x_gpio_output
;
97 tps6586x_gpio
->gpio_chip
.set
= tps6586x_gpio_set
;
98 tps6586x_gpio
->gpio_chip
.get
= tps6586x_gpio_get
;
99 tps6586x_gpio
->gpio_chip
.to_irq
= tps6586x_gpio_to_irq
;
101 #ifdef CONFIG_OF_GPIO
102 tps6586x_gpio
->gpio_chip
.of_node
= pdev
->dev
.parent
->of_node
;
104 if (pdata
&& pdata
->gpio_base
)
105 tps6586x_gpio
->gpio_chip
.base
= pdata
->gpio_base
;
107 tps6586x_gpio
->gpio_chip
.base
= -1;
109 ret
= devm_gpiochip_add_data(&pdev
->dev
, &tps6586x_gpio
->gpio_chip
,
112 dev_err(&pdev
->dev
, "Could not register gpiochip, %d\n", ret
);
116 platform_set_drvdata(pdev
, tps6586x_gpio
);
121 static struct platform_driver tps6586x_gpio_driver
= {
122 .driver
.name
= "tps6586x-gpio",
123 .probe
= tps6586x_gpio_probe
,
126 static int __init
tps6586x_gpio_init(void)
128 return platform_driver_register(&tps6586x_gpio_driver
);
130 subsys_initcall(tps6586x_gpio_init
);