2018-08-29 17:49:14 +03:00
// SPDX-License-Identifier: GPL-2.0
2011-06-09 23:50:19 +04:00
/*
2016-01-25 18:43:47 +03:00
* GPIO driver for TI TPS65912x PMICs
2011-06-09 23:50:19 +04:00
*
2016-01-25 18:43:47 +03:00
* Copyright ( C ) 2015 Texas Instruments Incorporated - http : //www.ti.com/
* Andrew F . Davis < afd @ ti . com >
2011-06-09 23:50:19 +04:00
*
2016-01-25 18:43:47 +03:00
* Based on the Arizona GPIO driver and the previous TPS65912 driver by
* Margarita Olaya Cabrera < magi @ slimlogic . co . uk >
2011-06-09 23:50:19 +04:00
*/
2018-08-29 17:45:30 +03:00
# include <linux/gpio/driver.h>
2016-01-25 18:43:47 +03:00
# include <linux/module.h>
2011-06-09 23:50:19 +04:00
# include <linux/platform_device.h>
2016-01-25 18:43:47 +03:00
2011-06-09 23:50:19 +04:00
# include <linux/mfd/tps65912.h>
2016-01-25 18:43:47 +03:00
struct tps65912_gpio {
2011-06-09 23:50:19 +04:00
struct gpio_chip gpio_chip ;
2016-01-25 18:43:47 +03:00
struct tps65912 * tps ;
2011-06-09 23:50:19 +04:00
} ;
2016-01-25 18:43:47 +03:00
static int tps65912_gpio_get_direction ( struct gpio_chip * gc ,
unsigned offset )
2011-06-09 23:50:19 +04:00
{
2016-01-25 18:43:47 +03:00
struct tps65912_gpio * gpio = gpiochip_get_data ( gc ) ;
2011-06-09 23:50:19 +04:00
2016-01-25 18:43:47 +03:00
int ret , val ;
2011-06-09 23:50:19 +04:00
2016-01-25 18:43:47 +03:00
ret = regmap_read ( gpio - > tps - > regmap , TPS65912_GPIO1 + offset , & val ) ;
if ( ret )
return ret ;
2011-06-09 23:50:19 +04:00
2016-01-25 18:43:47 +03:00
if ( val & GPIO_CFG_MASK )
2018-08-29 17:45:30 +03:00
return 0 ;
2016-01-25 18:43:47 +03:00
else
2018-08-29 17:45:30 +03:00
return 1 ;
2011-06-09 23:50:19 +04:00
}
2016-01-25 18:43:47 +03:00
static int tps65912_gpio_direction_input ( struct gpio_chip * gc , unsigned offset )
2011-06-09 23:50:19 +04:00
{
2016-01-25 18:43:47 +03:00
struct tps65912_gpio * gpio = gpiochip_get_data ( gc ) ;
2011-06-09 23:50:19 +04:00
2016-01-25 18:43:47 +03:00
return regmap_update_bits ( gpio - > tps - > regmap , TPS65912_GPIO1 + offset ,
GPIO_CFG_MASK , 0 ) ;
2011-06-09 23:50:19 +04:00
}
2016-01-25 18:43:47 +03:00
static int tps65912_gpio_direction_output ( struct gpio_chip * gc ,
unsigned offset , int value )
2011-06-09 23:50:19 +04:00
{
2016-01-25 18:43:47 +03:00
struct tps65912_gpio * gpio = gpiochip_get_data ( gc ) ;
2011-06-09 23:50:19 +04:00
/* Set the initial value */
2016-01-25 18:43:47 +03:00
regmap_update_bits ( gpio - > tps - > regmap , TPS65912_GPIO1 + offset ,
GPIO_SET_MASK , value ? GPIO_SET_MASK : 0 ) ;
2011-06-09 23:50:19 +04:00
2016-01-25 18:43:47 +03:00
return regmap_update_bits ( gpio - > tps - > regmap , TPS65912_GPIO1 + offset ,
GPIO_CFG_MASK , GPIO_CFG_MASK ) ;
2011-06-09 23:50:19 +04:00
}
2016-01-25 18:43:47 +03:00
static int tps65912_gpio_get ( struct gpio_chip * gc , unsigned offset )
2011-06-09 23:50:19 +04:00
{
2016-01-25 18:43:47 +03:00
struct tps65912_gpio * gpio = gpiochip_get_data ( gc ) ;
int ret , val ;
ret = regmap_read ( gpio - > tps - > regmap , TPS65912_GPIO1 + offset , & val ) ;
if ( ret )
return ret ;
2011-06-09 23:50:19 +04:00
2016-01-25 18:43:47 +03:00
if ( val & GPIO_STS_MASK )
return 1 ;
return 0 ;
}
static void tps65912_gpio_set ( struct gpio_chip * gc , unsigned offset ,
int value )
{
struct tps65912_gpio * gpio = gpiochip_get_data ( gc ) ;
regmap_update_bits ( gpio - > tps - > regmap , TPS65912_GPIO1 + offset ,
GPIO_SET_MASK , value ? GPIO_SET_MASK : 0 ) ;
2011-06-09 23:50:19 +04:00
}
2016-09-11 15:14:37 +03:00
static const struct gpio_chip template_chip = {
2016-01-25 18:43:47 +03:00
. label = " tps65912-gpio " ,
2011-06-09 23:50:19 +04:00
. owner = THIS_MODULE ,
2016-01-25 18:43:47 +03:00
. get_direction = tps65912_gpio_get_direction ,
. direction_input = tps65912_gpio_direction_input ,
. direction_output = tps65912_gpio_direction_output ,
2011-06-09 23:50:19 +04:00
. get = tps65912_gpio_get ,
. set = tps65912_gpio_set ,
. base = - 1 ,
2016-01-25 18:43:47 +03:00
. ngpio = 5 ,
. can_sleep = true ,
2011-06-09 23:50:19 +04:00
} ;
2012-11-19 22:22:34 +04:00
static int tps65912_gpio_probe ( struct platform_device * pdev )
2011-06-09 23:50:19 +04:00
{
2016-01-25 18:43:47 +03:00
struct tps65912 * tps = dev_get_drvdata ( pdev - > dev . parent ) ;
struct tps65912_gpio * gpio ;
2011-06-09 23:50:19 +04:00
int ret ;
2016-01-25 18:43:47 +03:00
gpio = devm_kzalloc ( & pdev - > dev , sizeof ( * gpio ) , GFP_KERNEL ) ;
if ( ! gpio )
2011-06-09 23:50:19 +04:00
return - ENOMEM ;
2016-01-25 18:43:47 +03:00
gpio - > tps = dev_get_drvdata ( pdev - > dev . parent ) ;
gpio - > gpio_chip = template_chip ;
gpio - > gpio_chip . parent = tps - > dev ;
2011-06-09 23:50:19 +04:00
2016-03-09 18:02:52 +03:00
ret = devm_gpiochip_add_data ( & pdev - > dev , & gpio - > gpio_chip ,
gpio ) ;
2011-06-09 23:50:19 +04:00
if ( ret < 0 ) {
2016-01-25 18:43:47 +03:00
dev_err ( & pdev - > dev , " Could not register gpiochip, %d \n " , ret ) ;
2012-09-01 13:44:27 +04:00
return ret ;
2011-06-09 23:50:19 +04:00
}
2016-01-25 18:43:47 +03:00
platform_set_drvdata ( pdev , gpio ) ;
2011-06-09 23:50:19 +04:00
2016-01-25 18:43:47 +03:00
return 0 ;
2011-06-09 23:50:19 +04:00
}
2016-01-25 18:43:47 +03:00
static const struct platform_device_id tps65912_gpio_id_table [ ] = {
{ " tps65912-gpio " , } ,
{ /* sentinel */ }
} ;
MODULE_DEVICE_TABLE ( platform , tps65912_gpio_id_table ) ;
2011-06-09 23:50:19 +04:00
static struct platform_driver tps65912_gpio_driver = {
. driver = {
. name = " tps65912-gpio " ,
} ,
. probe = tps65912_gpio_probe ,
2016-01-25 18:43:47 +03:00
. id_table = tps65912_gpio_id_table ,
2011-06-09 23:50:19 +04:00
} ;
2016-01-25 18:43:47 +03:00
module_platform_driver ( tps65912_gpio_driver ) ;
2011-06-09 23:50:19 +04:00
2016-01-25 18:43:47 +03:00
MODULE_AUTHOR ( " Andrew F. Davis <afd@ti.com> " ) ;
MODULE_DESCRIPTION ( " TPS65912 GPIO driver " ) ;
2011-06-09 23:50:19 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;