11// SPDX-License-Identifier: GPL-2.0
22/*
3- * GPIO driver for TI TPS65215/TPS65219 PMICs
3+ * GPIO driver for TI TPS65214/ TPS65215/TPS65219 PMICs
44 *
55 * Copyright (C) 2022, 2025 Texas Instruments Incorporated - http://www.ti.com/
66 */
1313#include <linux/regmap.h>
1414
1515#define TPS65219_GPIO0_DIR_MASK BIT(3)
16+ #define TPS65214_GPIO0_DIR_MASK BIT(1)
1617#define TPS6521X_GPIO0_OFFSET 2
1718#define TPS6521X_GPIO0_IDX 0
1819
1920/*
21+ * TPS65214 GPIO mapping
22+ * Linux gpio offset 0 -> GPIO (pin16) -> bit_offset 2
23+ * Linux gpio offset 1 -> GPO1 (pin9 ) -> bit_offset 0
24+ *
2025 * TPS65215 & TPS65219 GPIO mapping
2126 * Linux gpio offset 0 -> GPIO (pin16) -> bit_offset 2
2227 * Linux gpio offset 1 -> GPO1 (pin8 ) -> bit_offset 0
2328 * Linux gpio offset 2 -> GPO2 (pin17) -> bit_offset 1
2429 */
2530
2631struct tps65219_gpio {
32+ int (* change_dir )(struct gpio_chip * gc , unsigned int offset , unsigned int dir );
2733 struct gpio_chip gpio_chip ;
2834 struct tps65219 * tps ;
2935};
3036
37+ static int tps65214_gpio_get_direction (struct gpio_chip * gc , unsigned int offset )
38+ {
39+ struct tps65219_gpio * gpio = gpiochip_get_data (gc );
40+ int ret , val ;
41+
42+ if (offset != TPS6521X_GPIO0_IDX )
43+ return GPIO_LINE_DIRECTION_OUT ;
44+
45+ ret = regmap_read (gpio -> tps -> regmap , TPS65219_REG_GENERAL_CONFIG , & val );
46+ if (ret )
47+ return ret ;
48+
49+ return !(val & TPS65214_GPIO0_DIR_MASK );
50+ }
51+
3152static int tps65219_gpio_get_direction (struct gpio_chip * gc , unsigned int offset )
3253{
3354 struct tps65219_gpio * gpio = gpiochip_get_data (gc );
@@ -118,6 +139,33 @@ static int tps65219_gpio_change_direction(struct gpio_chip *gc, unsigned int off
118139 return - ENOTSUPP ;
119140}
120141
142+ static int tps65214_gpio_change_direction (struct gpio_chip * gc , unsigned int offset ,
143+ unsigned int direction )
144+ {
145+ struct tps65219_gpio * gpio = gpiochip_get_data (gc );
146+ struct device * dev = gpio -> tps -> dev ;
147+ int val , ret ;
148+
149+ /**
150+ * Verified if GPIO or GPO in parent function
151+ * Masked value: 0 = GPIO, 1 = VSEL
152+ */
153+ ret = regmap_read (gpio -> tps -> regmap , TPS65219_REG_MFP_1_CONFIG , & val );
154+ if (ret )
155+ return ret ;
156+
157+ ret = !!(val & BIT (TPS65219_GPIO0_DIR_MASK ));
158+ if (ret )
159+ dev_err (dev , "GPIO%d configured as VSEL, not GPIO\n" , offset );
160+
161+ ret = regmap_update_bits (gpio -> tps -> regmap , TPS65219_REG_GENERAL_CONFIG ,
162+ TPS65214_GPIO0_DIR_MASK , direction );
163+ if (ret )
164+ dev_err (dev , "Fail to change direction to %u for GPIO%d.\n" , direction , offset );
165+
166+ return ret ;
167+ }
168+
121169static int tps65219_gpio_direction_input (struct gpio_chip * gc , unsigned int offset )
122170{
123171 struct tps65219_gpio * gpio = gpiochip_get_data (gc );
@@ -131,21 +179,36 @@ static int tps65219_gpio_direction_input(struct gpio_chip *gc, unsigned int offs
131179 if (tps65219_gpio_get_direction (gc , offset ) == GPIO_LINE_DIRECTION_IN )
132180 return 0 ;
133181
134- return tps65219_gpio_change_direction (gc , offset , GPIO_LINE_DIRECTION_IN );
182+ return gpio -> change_dir (gc , offset , GPIO_LINE_DIRECTION_IN );
135183}
136184
137185static int tps65219_gpio_direction_output (struct gpio_chip * gc , unsigned int offset , int value )
138186{
187+ struct tps65219_gpio * gpio = gpiochip_get_data (gc );
188+
139189 tps65219_gpio_set (gc , offset , value );
140190 if (offset != TPS6521X_GPIO0_IDX )
141191 return 0 ;
142192
143193 if (tps65219_gpio_get_direction (gc , offset ) == GPIO_LINE_DIRECTION_OUT )
144194 return 0 ;
145195
146- return tps65219_gpio_change_direction (gc , offset , GPIO_LINE_DIRECTION_OUT );
196+ return gpio -> change_dir (gc , offset , GPIO_LINE_DIRECTION_OUT );
147197}
148198
199+ static const struct gpio_chip tps65214_template_chip = {
200+ .label = "tps65214-gpio" ,
201+ .owner = THIS_MODULE ,
202+ .get_direction = tps65214_gpio_get_direction ,
203+ .direction_input = tps65219_gpio_direction_input ,
204+ .direction_output = tps65219_gpio_direction_output ,
205+ .get = tps65219_gpio_get ,
206+ .set_rv = tps65219_gpio_set ,
207+ .base = -1 ,
208+ .ngpio = 2 ,
209+ .can_sleep = true,
210+ };
211+
149212static const struct gpio_chip tps65219_template_chip = {
150213 .label = "tps65219-gpio" ,
151214 .owner = THIS_MODULE ,
@@ -161,29 +224,46 @@ static const struct gpio_chip tps65219_template_chip = {
161224
162225static int tps65219_gpio_probe (struct platform_device * pdev )
163226{
227+ enum pmic_id chip = platform_get_device_id (pdev )-> driver_data ;
164228 struct tps65219 * tps = dev_get_drvdata (pdev -> dev .parent );
165229 struct tps65219_gpio * gpio ;
166230
167231 gpio = devm_kzalloc (& pdev -> dev , sizeof (* gpio ), GFP_KERNEL );
168232 if (!gpio )
169233 return - ENOMEM ;
170234
235+ if (chip == TPS65214 ) {
236+ gpio -> gpio_chip = tps65214_template_chip ;
237+ gpio -> change_dir = tps65214_gpio_change_direction ;
238+ } else if (chip == TPS65219 ) {
239+ gpio -> gpio_chip = tps65219_template_chip ;
240+ gpio -> change_dir = tps65219_gpio_change_direction ;
241+ } else {
242+ return - ENODATA ;
243+ }
244+
171245 gpio -> tps = tps ;
172- gpio -> gpio_chip = tps65219_template_chip ;
173246 gpio -> gpio_chip .parent = tps -> dev ;
174247
175248 return devm_gpiochip_add_data (& pdev -> dev , & gpio -> gpio_chip , gpio );
176249}
177250
251+ static const struct platform_device_id tps6521x_gpio_id_table [] = {
252+ { "tps65214-gpio" , TPS65214 },
253+ { "tps65219-gpio" , TPS65219 },
254+ { /* sentinel */ }
255+ };
256+ MODULE_DEVICE_TABLE (platform , tps6521x_gpio_id_table );
257+
178258static struct platform_driver tps65219_gpio_driver = {
179259 .driver = {
180260 .name = "tps65219-gpio" ,
181261 },
182262 .probe = tps65219_gpio_probe ,
263+ .id_table = tps6521x_gpio_id_table ,
183264};
184265module_platform_driver (tps65219_gpio_driver );
185266
186- MODULE_ALIAS ("platform:tps65219-gpio" );
187267MODULE_AUTHOR ("Jonathan Cormier <jcormier@criticallink.com>" );
188- MODULE_DESCRIPTION ("TPS65215/TPS65219 GPIO driver" );
268+ MODULE_DESCRIPTION ("TPS65214/ TPS65215/TPS65219 GPIO driver" );
189269MODULE_LICENSE ("GPL" );
0 commit comments