1 // SPDX-License-Identifier: GPL-2.0-only
3 * Rockchip RK805/RK808/RK816/RK817/RK818 Core (I2C) driver
5 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
6 * Copyright (C) 2016 PHYTEC Messtechnik GmbH
8 * Author: Chris Zhong <zyw@rock-chips.com>
9 * Author: Zhang Qing <zhangqing@rock-chips.com>
10 * Author: Wadim Egorov <w.egorov@phytec.de>
13 #include <linux/i2c.h>
14 #include <linux/mfd/rk808.h>
15 #include <linux/module.h>
17 #include <linux/regmap.h>
19 struct rk8xx_i2c_platform_data
{
20 const struct regmap_config
*regmap_cfg
;
24 static bool rk806_is_volatile_reg(struct device
*dev
, unsigned int reg
)
27 case RK806_POWER_EN0
... RK806_POWER_EN5
:
28 case RK806_DVS_START_CTRL
... RK806_INT_MSK1
:
35 static bool rk808_is_volatile_reg(struct device
*dev
, unsigned int reg
)
39 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
40 * we don't use that feature. It's better to cache.
41 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
42 * bits are cleared in case when we shutoff anyway, but better safe.
46 case RK808_SECONDS_REG
... RK808_WEEKS_REG
:
47 case RK808_RTC_STATUS_REG
:
48 case RK808_VB_MON_REG
:
49 case RK808_THERMAL_REG
:
50 case RK808_DCDC_UV_STS_REG
:
51 case RK808_LDO_UV_STS_REG
:
52 case RK808_DCDC_PG_REG
:
53 case RK808_LDO_PG_REG
:
54 case RK808_DEVCTRL_REG
:
55 case RK808_INT_STS_REG1
:
56 case RK808_INT_STS_REG2
:
63 static bool rk816_is_volatile_reg(struct device
*dev
, unsigned int reg
)
66 * Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
67 * we don't use that feature. It's better to cache.
71 case RK808_SECONDS_REG
... RK808_WEEKS_REG
:
72 case RK808_RTC_STATUS_REG
:
73 case RK808_VB_MON_REG
:
74 case RK808_THERMAL_REG
:
75 case RK816_DCDC_EN_REG1
:
76 case RK816_DCDC_EN_REG2
:
77 case RK816_INT_STS_REG1
:
78 case RK816_INT_STS_REG2
:
79 case RK816_INT_STS_REG3
:
80 case RK808_DEVCTRL_REG
:
81 case RK816_SUP_STS_REG
:
83 case RK816_ZERO_CUR_ADC_REGH
:
84 case RK816_ZERO_CUR_ADC_REGL
:
85 case RK816_GASCNT_REG(0) ... RK816_BAT_VOL_REGL
:
92 static bool rk817_is_volatile_reg(struct device
*dev
, unsigned int reg
)
96 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
97 * we don't use that feature. It's better to cache.
101 case RK817_SECONDS_REG
... RK817_WEEKS_REG
:
102 case RK817_RTC_STATUS_REG
:
103 case RK817_CODEC_DTOP_LPT_SRST
:
104 case RK817_GAS_GAUGE_ADC_CONFIG0
... RK817_GAS_GAUGE_CUR_ADC_K0
:
105 case RK817_PMIC_CHRG_STS
:
106 case RK817_PMIC_CHRG_OUT
:
107 case RK817_PMIC_CHRG_IN
:
108 case RK817_INT_STS_REG0
:
109 case RK817_INT_STS_REG1
:
110 case RK817_INT_STS_REG2
:
119 static const struct regmap_config rk818_regmap_config
= {
122 .max_register
= RK818_USB_CTRL_REG
,
123 .cache_type
= REGCACHE_MAPLE
,
124 .volatile_reg
= rk808_is_volatile_reg
,
127 static const struct regmap_config rk805_regmap_config
= {
130 .max_register
= RK805_OFF_SOURCE_REG
,
131 .cache_type
= REGCACHE_MAPLE
,
132 .volatile_reg
= rk808_is_volatile_reg
,
135 static const struct regmap_config rk806_regmap_config
= {
138 .max_register
= RK806_BUCK_RSERVE_REG5
,
139 .cache_type
= REGCACHE_MAPLE
,
140 .volatile_reg
= rk806_is_volatile_reg
,
143 static const struct regmap_config rk808_regmap_config
= {
146 .max_register
= RK808_IO_POL_REG
,
147 .cache_type
= REGCACHE_MAPLE
,
148 .volatile_reg
= rk808_is_volatile_reg
,
151 static const struct regmap_config rk816_regmap_config
= {
154 .max_register
= RK816_DATA_REG(18),
155 .cache_type
= REGCACHE_MAPLE
,
156 .volatile_reg
= rk816_is_volatile_reg
,
159 static const struct regmap_config rk817_regmap_config
= {
162 .max_register
= RK817_GPIO_INT_CFG
,
163 .cache_type
= REGCACHE_NONE
,
164 .volatile_reg
= rk817_is_volatile_reg
,
167 static const struct rk8xx_i2c_platform_data rk805_data
= {
168 .regmap_cfg
= &rk805_regmap_config
,
172 static const struct rk8xx_i2c_platform_data rk806_data
= {
173 .regmap_cfg
= &rk806_regmap_config
,
177 static const struct rk8xx_i2c_platform_data rk808_data
= {
178 .regmap_cfg
= &rk808_regmap_config
,
182 static const struct rk8xx_i2c_platform_data rk809_data
= {
183 .regmap_cfg
= &rk817_regmap_config
,
187 static const struct rk8xx_i2c_platform_data rk816_data
= {
188 .regmap_cfg
= &rk816_regmap_config
,
192 static const struct rk8xx_i2c_platform_data rk817_data
= {
193 .regmap_cfg
= &rk817_regmap_config
,
197 static const struct rk8xx_i2c_platform_data rk818_data
= {
198 .regmap_cfg
= &rk818_regmap_config
,
202 static int rk8xx_i2c_probe(struct i2c_client
*client
)
204 const struct rk8xx_i2c_platform_data
*data
;
205 struct regmap
*regmap
;
207 data
= device_get_match_data(&client
->dev
);
211 regmap
= devm_regmap_init_i2c(client
, data
->regmap_cfg
);
213 return dev_err_probe(&client
->dev
, PTR_ERR(regmap
),
214 "regmap initialization failed\n");
216 return rk8xx_probe(&client
->dev
, data
->variant
, client
->irq
, regmap
);
219 static void rk8xx_i2c_shutdown(struct i2c_client
*client
)
221 rk8xx_shutdown(&client
->dev
);
224 static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops
, rk8xx_suspend
, rk8xx_resume
);
226 static const struct of_device_id rk8xx_i2c_of_match
[] = {
227 { .compatible
= "rockchip,rk805", .data
= &rk805_data
},
228 { .compatible
= "rockchip,rk806", .data
= &rk806_data
},
229 { .compatible
= "rockchip,rk808", .data
= &rk808_data
},
230 { .compatible
= "rockchip,rk809", .data
= &rk809_data
},
231 { .compatible
= "rockchip,rk816", .data
= &rk816_data
},
232 { .compatible
= "rockchip,rk817", .data
= &rk817_data
},
233 { .compatible
= "rockchip,rk818", .data
= &rk818_data
},
236 MODULE_DEVICE_TABLE(of
, rk8xx_i2c_of_match
);
238 static struct i2c_driver rk8xx_i2c_driver
= {
241 .of_match_table
= rk8xx_i2c_of_match
,
242 .pm
= &rk8xx_i2c_pm_ops
,
244 .probe
= rk8xx_i2c_probe
,
245 .shutdown
= rk8xx_i2c_shutdown
,
247 module_i2c_driver(rk8xx_i2c_driver
);
249 MODULE_LICENSE("GPL");
250 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
251 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
252 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
253 MODULE_DESCRIPTION("RK8xx I2C PMIC driver");