2019-05-31 01:09:32 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2017-06-13 10:28:40 +05:30
/*
2020-07-22 21:24:54 +02:00
* Copyright ( C ) 2017 Texas Instruments Incorporated - https : //www.ti.com/
2017-06-13 10:28:40 +05:30
*
* Author : Keerthy < j - keerthy @ ti . com >
*/
2021-02-26 15:28:52 +01:00
# include <linux/gpio/consumer.h>
2017-06-13 10:28:40 +05:30
# include <linux/interrupt.h>
# include <linux/mfd/core.h>
# include <linux/module.h>
# include <linux/of_device.h>
# include <linux/regmap.h>
# include <linux/mfd/lp87565.h>
static const struct regmap_config lp87565_regmap_config = {
. reg_bits = 8 ,
. val_bits = 8 ,
. max_register = LP87565_REG_MAX ,
} ;
static const struct mfd_cell lp87565_cells [ ] = {
{ . name = " lp87565-q1-regulator " , } ,
{ . name = " lp87565-q1-gpio " , } ,
} ;
static const struct of_device_id of_lp87565_match_table [ ] = {
{ . compatible = " ti,lp87565 " , } ,
2020-09-02 16:22:59 +02:00
{
. compatible = " ti,lp87524-q1 " ,
. data = ( void * ) LP87565_DEVICE_TYPE_LP87524_Q1 ,
} ,
2017-06-13 10:28:40 +05:30
{
. compatible = " ti,lp87565-q1 " ,
. data = ( void * ) LP87565_DEVICE_TYPE_LP87565_Q1 ,
} ,
2019-05-15 15:38:47 +05:30
{
. compatible = " ti,lp87561-q1 " ,
. data = ( void * ) LP87565_DEVICE_TYPE_LP87561_Q1 ,
} ,
2017-06-13 10:28:40 +05:30
{ }
} ;
MODULE_DEVICE_TABLE ( of , of_lp87565_match_table ) ;
static int lp87565_probe ( struct i2c_client * client ,
const struct i2c_device_id * ids )
{
struct lp87565 * lp87565 ;
const struct of_device_id * of_id ;
int ret ;
unsigned int otpid ;
lp87565 = devm_kzalloc ( & client - > dev , sizeof ( * lp87565 ) , GFP_KERNEL ) ;
if ( ! lp87565 )
return - ENOMEM ;
lp87565 - > dev = & client - > dev ;
lp87565 - > regmap = devm_regmap_init_i2c ( client , & lp87565_regmap_config ) ;
if ( IS_ERR ( lp87565 - > regmap ) ) {
ret = PTR_ERR ( lp87565 - > regmap ) ;
dev_err ( lp87565 - > dev ,
" Failed to initialize register map: %d \n " , ret ) ;
return ret ;
}
2021-02-26 15:28:52 +01:00
lp87565 - > reset_gpio = devm_gpiod_get_optional ( lp87565 - > dev , " reset " ,
GPIOD_OUT_LOW ) ;
if ( IS_ERR ( lp87565 - > reset_gpio ) ) {
ret = PTR_ERR ( lp87565 - > reset_gpio ) ;
if ( ret = = - EPROBE_DEFER )
return ret ;
}
if ( lp87565 - > reset_gpio ) {
gpiod_set_value_cansleep ( lp87565 - > reset_gpio , 1 ) ;
/* The minimum assertion time is undocumented, just guess */
usleep_range ( 2000 , 4000 ) ;
gpiod_set_value_cansleep ( lp87565 - > reset_gpio , 0 ) ;
/* Min 1.2 ms before first I2C transaction */
usleep_range ( 1500 , 3000 ) ;
}
2017-06-13 10:28:40 +05:30
ret = regmap_read ( lp87565 - > regmap , LP87565_REG_OTP_REV , & otpid ) ;
if ( ret ) {
dev_err ( lp87565 - > dev , " Failed to read OTP ID \n " ) ;
return ret ;
}
lp87565 - > rev = otpid & LP87565_OTP_REV_OTP_ID ;
of_id = of_match_device ( of_lp87565_match_table , & client - > dev ) ;
if ( of_id )
lp87565 - > dev_type = ( enum lp87565_device_type ) of_id - > data ;
i2c_set_clientdata ( client , lp87565 ) ;
2017-07-30 18:58:15 +08:00
return devm_mfd_add_devices ( lp87565 - > dev , PLATFORM_DEVID_AUTO ,
lp87565_cells , ARRAY_SIZE ( lp87565_cells ) ,
NULL , 0 , NULL ) ;
2017-06-13 10:28:40 +05:30
}
2021-02-26 15:28:52 +01:00
static void lp87565_shutdown ( struct i2c_client * client )
{
struct lp87565 * lp87565 = i2c_get_clientdata ( client ) ;
gpiod_set_value_cansleep ( lp87565 - > reset_gpio , 1 ) ;
}
2017-06-13 10:28:40 +05:30
static const struct i2c_device_id lp87565_id_table [ ] = {
{ " lp87565-q1 " , 0 } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( i2c , lp87565_id_table ) ;
static struct i2c_driver lp87565_driver = {
. driver = {
. name = " lp87565 " ,
. of_match_table = of_lp87565_match_table ,
} ,
. probe = lp87565_probe ,
2021-02-26 15:28:52 +01:00
. shutdown = lp87565_shutdown ,
2017-06-13 10:28:40 +05:30
. id_table = lp87565_id_table ,
} ;
module_i2c_driver ( lp87565_driver ) ;
MODULE_AUTHOR ( " J Keerthy <j-keerthy@ti.com> " ) ;
MODULE_DESCRIPTION ( " lp87565 chip family Multi-Function Device driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;