2023-05-04 20:36:09 +03:00
// SPDX-License-Identifier: GPL-2.0-only
/*
* Rockchip RK808 / RK818 Core ( I2C ) driver
*
* Copyright ( c ) 2014 , Fuzhou Rockchip Electronics Co . , Ltd
* Copyright ( C ) 2016 PHYTEC Messtechnik GmbH
*
* Author : Chris Zhong < zyw @ rock - chips . com >
* Author : Zhang Qing < zhangqing @ rock - chips . com >
* Author : Wadim Egorov < w . egorov @ phytec . de >
*/
# include <linux/i2c.h>
# include <linux/mfd/rk808.h>
# include <linux/module.h>
# include <linux/of.h>
# include <linux/regmap.h>
2023-05-04 20:36:10 +03:00
struct rk8xx_i2c_platform_data {
const struct regmap_config * regmap_cfg ;
int variant ;
} ;
2023-05-04 20:36:09 +03:00
static bool rk808_is_volatile_reg ( struct device * dev , unsigned int reg )
{
/*
* Notes :
* - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile , but
* we don ' t use that feature . It ' s better to cache .
* - It ' s unlikely we care that RK808_DEVCTRL_REG is volatile since
* bits are cleared in case when we shutoff anyway , but better safe .
*/
switch ( reg ) {
case RK808_SECONDS_REG . . . RK808_WEEKS_REG :
case RK808_RTC_STATUS_REG :
case RK808_VB_MON_REG :
case RK808_THERMAL_REG :
case RK808_DCDC_UV_STS_REG :
case RK808_LDO_UV_STS_REG :
case RK808_DCDC_PG_REG :
case RK808_LDO_PG_REG :
case RK808_DEVCTRL_REG :
case RK808_INT_STS_REG1 :
case RK808_INT_STS_REG2 :
return true ;
}
return false ;
}
static bool rk817_is_volatile_reg ( struct device * dev , unsigned int reg )
{
/*
* Notes :
* - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile , but
* we don ' t use that feature . It ' s better to cache .
*/
switch ( reg ) {
case RK817_SECONDS_REG . . . RK817_WEEKS_REG :
case RK817_RTC_STATUS_REG :
case RK817_CODEC_DTOP_LPT_SRST :
case RK817_GAS_GAUGE_ADC_CONFIG0 . . . RK817_GAS_GAUGE_CUR_ADC_K0 :
case RK817_PMIC_CHRG_STS :
case RK817_PMIC_CHRG_OUT :
case RK817_PMIC_CHRG_IN :
case RK817_INT_STS_REG0 :
case RK817_INT_STS_REG1 :
case RK817_INT_STS_REG2 :
case RK817_SYS_STS :
return true ;
}
return false ;
}
static const struct regmap_config rk818_regmap_config = {
. reg_bits = 8 ,
. val_bits = 8 ,
. max_register = RK818_USB_CTRL_REG ,
. cache_type = REGCACHE_RBTREE ,
. volatile_reg = rk808_is_volatile_reg ,
} ;
static const struct regmap_config rk805_regmap_config = {
. reg_bits = 8 ,
. val_bits = 8 ,
. max_register = RK805_OFF_SOURCE_REG ,
. cache_type = REGCACHE_RBTREE ,
. volatile_reg = rk808_is_volatile_reg ,
} ;
static const struct regmap_config rk808_regmap_config = {
. reg_bits = 8 ,
. val_bits = 8 ,
. max_register = RK808_IO_POL_REG ,
. cache_type = REGCACHE_RBTREE ,
. volatile_reg = rk808_is_volatile_reg ,
} ;
static const struct regmap_config rk817_regmap_config = {
. reg_bits = 8 ,
. val_bits = 8 ,
. max_register = RK817_GPIO_INT_CFG ,
. cache_type = REGCACHE_NONE ,
. volatile_reg = rk817_is_volatile_reg ,
} ;
2023-05-04 20:36:10 +03:00
static const struct rk8xx_i2c_platform_data rk805_data = {
. regmap_cfg = & rk805_regmap_config ,
. variant = RK805_ID ,
} ;
static const struct rk8xx_i2c_platform_data rk808_data = {
. regmap_cfg = & rk808_regmap_config ,
. variant = RK808_ID ,
} ;
2023-05-04 20:36:09 +03:00
2023-05-04 20:36:10 +03:00
static const struct rk8xx_i2c_platform_data rk809_data = {
. regmap_cfg = & rk817_regmap_config ,
. variant = RK809_ID ,
} ;
2023-05-04 20:36:09 +03:00
2023-05-04 20:36:10 +03:00
static const struct rk8xx_i2c_platform_data rk817_data = {
. regmap_cfg = & rk817_regmap_config ,
. variant = RK817_ID ,
} ;
2023-05-04 20:36:09 +03:00
2023-05-04 20:36:10 +03:00
static const struct rk8xx_i2c_platform_data rk818_data = {
. regmap_cfg = & rk818_regmap_config ,
. variant = RK818_ID ,
} ;
2023-05-04 20:36:09 +03:00
static int rk8xx_i2c_probe ( struct i2c_client * client )
{
2023-05-04 20:36:10 +03:00
const struct rk8xx_i2c_platform_data * data ;
2023-05-04 20:36:09 +03:00
struct regmap * regmap ;
2023-05-04 20:36:10 +03:00
data = device_get_match_data ( & client - > dev ) ;
if ( ! data )
return - ENODEV ;
2023-05-04 20:36:09 +03:00
2023-05-04 20:36:10 +03:00
regmap = devm_regmap_init_i2c ( client , data - > regmap_cfg ) ;
2023-05-04 20:36:09 +03:00
if ( IS_ERR ( regmap ) )
return dev_err_probe ( & client - > dev , PTR_ERR ( regmap ) ,
" regmap initialization failed \n " ) ;
2023-05-04 20:36:10 +03:00
return rk8xx_probe ( & client - > dev , data - > variant , client - > irq , regmap ) ;
2023-05-04 20:36:09 +03:00
}
static void rk8xx_i2c_shutdown ( struct i2c_client * client )
{
rk8xx_shutdown ( & client - > dev ) ;
}
static SIMPLE_DEV_PM_OPS ( rk8xx_i2c_pm_ops , rk8xx_suspend , rk8xx_resume ) ;
static const struct of_device_id rk8xx_i2c_of_match [ ] = {
2023-05-04 20:36:10 +03:00
{ . compatible = " rockchip,rk805 " , . data = & rk805_data } ,
{ . compatible = " rockchip,rk808 " , . data = & rk808_data } ,
{ . compatible = " rockchip,rk809 " , . data = & rk809_data } ,
{ . compatible = " rockchip,rk817 " , . data = & rk817_data } ,
{ . compatible = " rockchip,rk818 " , . data = & rk818_data } ,
2023-05-04 20:36:09 +03:00
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , rk8xx_i2c_of_match ) ;
static struct i2c_driver rk8xx_i2c_driver = {
. driver = {
. name = " rk8xx-i2c " ,
. of_match_table = rk8xx_i2c_of_match ,
. pm = & rk8xx_i2c_pm_ops ,
} ,
2023-05-15 21:27:52 +03:00
. probe = rk8xx_i2c_probe ,
2023-05-04 20:36:09 +03:00
. shutdown = rk8xx_i2c_shutdown ,
} ;
module_i2c_driver ( rk8xx_i2c_driver ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Chris Zhong <zyw@rock-chips.com> " ) ;
MODULE_AUTHOR ( " Zhang Qing <zhangqing@rock-chips.com> " ) ;
MODULE_AUTHOR ( " Wadim Egorov <w.egorov@phytec.de> " ) ;
MODULE_DESCRIPTION ( " RK8xx I2C PMIC driver " ) ;