1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Rockchip RK801/RK805/RK808/RK816/RK817/RK818 Core (I2C) driver 4 * 5 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 6 * Copyright (C) 2016 PHYTEC Messtechnik GmbH 7 * 8 * Author: Chris Zhong <zyw@rock-chips.com> 9 * Author: Zhang Qing <zhangqing@rock-chips.com> 10 * Author: Wadim Egorov <w.egorov@phytec.de> 11 */ 12 13 #include <linux/i2c.h> 14 #include <linux/mfd/rk808.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/regmap.h> 18 19 struct rk8xx_i2c_platform_data { 20 const struct regmap_config *regmap_cfg; 21 int variant; 22 }; 23 24 static bool rk801_is_volatile_reg(struct device *dev, unsigned int reg) 25 { 26 switch (reg) { 27 case RK801_SYS_STS_REG: 28 case RK801_INT_STS0_REG: 29 case RK801_SYS_CFG0_REG: 30 case RK801_SYS_CFG1_REG: 31 case RK801_SYS_CFG2_REG: 32 case RK801_SYS_CFG3_REG: 33 case RK801_SYS_CFG4_REG: 34 case RK801_SLEEP_CFG_REG: 35 return true; 36 } 37 38 return false; 39 } 40 41 static bool rk806_is_volatile_reg(struct device *dev, unsigned int reg) 42 { 43 switch (reg) { 44 case RK806_POWER_EN0 ... RK806_POWER_EN5: 45 case RK806_DVS_START_CTRL ... RK806_INT_MSK1: 46 return true; 47 } 48 49 return false; 50 } 51 52 static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg) 53 { 54 /* 55 * Notes: 56 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but 57 * we don't use that feature. It's better to cache. 58 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since 59 * bits are cleared in case when we shutoff anyway, but better safe. 60 */ 61 62 switch (reg) { 63 case RK808_SECONDS_REG ... RK808_WEEKS_REG: 64 case RK808_RTC_STATUS_REG: 65 case RK808_VB_MON_REG: 66 case RK808_THERMAL_REG: 67 case RK808_DCDC_UV_STS_REG: 68 case RK808_LDO_UV_STS_REG: 69 case RK808_DCDC_PG_REG: 70 case RK808_LDO_PG_REG: 71 case RK808_DEVCTRL_REG: 72 case RK808_INT_STS_REG1: 73 case RK808_INT_STS_REG2: 74 return true; 75 } 76 77 return false; 78 } 79 80 static bool rk816_is_volatile_reg(struct device *dev, unsigned int reg) 81 { 82 /* 83 * Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but 84 * we don't use that feature. It's better to cache. 85 */ 86 87 switch (reg) { 88 case RK808_SECONDS_REG ... RK808_WEEKS_REG: 89 case RK808_RTC_STATUS_REG: 90 case RK808_VB_MON_REG: 91 case RK808_THERMAL_REG: 92 case RK816_DCDC_EN_REG1: 93 case RK816_DCDC_EN_REG2: 94 case RK816_INT_STS_REG1: 95 case RK816_INT_STS_REG2: 96 case RK816_INT_STS_REG3: 97 case RK808_DEVCTRL_REG: 98 case RK816_SUP_STS_REG: 99 case RK816_GGSTS_REG: 100 case RK816_ZERO_CUR_ADC_REGH: 101 case RK816_ZERO_CUR_ADC_REGL: 102 case RK816_GASCNT_REG(0) ... RK816_BAT_VOL_REGL: 103 return true; 104 } 105 106 return false; 107 } 108 109 static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg) 110 { 111 /* 112 * Notes: 113 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but 114 * we don't use that feature. It's better to cache. 115 */ 116 117 switch (reg) { 118 case RK817_SECONDS_REG ... RK817_WEEKS_REG: 119 case RK817_RTC_STATUS_REG: 120 case RK817_CODEC_DTOP_LPT_SRST: 121 case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0: 122 case RK817_PMIC_CHRG_STS: 123 case RK817_PMIC_CHRG_OUT: 124 case RK817_PMIC_CHRG_IN: 125 case RK817_INT_STS_REG0: 126 case RK817_INT_STS_REG1: 127 case RK817_INT_STS_REG2: 128 case RK817_SYS_STS: 129 return true; 130 } 131 132 return false; 133 } 134 135 136 static const struct regmap_config rk818_regmap_config = { 137 .reg_bits = 8, 138 .val_bits = 8, 139 .max_register = RK818_USB_CTRL_REG, 140 .cache_type = REGCACHE_MAPLE, 141 .volatile_reg = rk808_is_volatile_reg, 142 }; 143 144 static const struct regmap_config rk801_regmap_config = { 145 .reg_bits = 8, 146 .val_bits = 8, 147 .max_register = RK801_SYS_CFG3_OTP_REG, 148 .cache_type = REGCACHE_RBTREE, 149 .volatile_reg = rk801_is_volatile_reg, 150 }; 151 152 static const struct regmap_config rk805_regmap_config = { 153 .reg_bits = 8, 154 .val_bits = 8, 155 .max_register = RK805_OFF_SOURCE_REG, 156 .cache_type = REGCACHE_MAPLE, 157 .volatile_reg = rk808_is_volatile_reg, 158 }; 159 160 static const struct regmap_config rk806_regmap_config = { 161 .reg_bits = 8, 162 .val_bits = 8, 163 .max_register = RK806_BUCK_RSERVE_REG5, 164 .cache_type = REGCACHE_MAPLE, 165 .volatile_reg = rk806_is_volatile_reg, 166 }; 167 168 static const struct regmap_config rk808_regmap_config = { 169 .reg_bits = 8, 170 .val_bits = 8, 171 .max_register = RK808_IO_POL_REG, 172 .cache_type = REGCACHE_MAPLE, 173 .volatile_reg = rk808_is_volatile_reg, 174 }; 175 176 static const struct regmap_config rk816_regmap_config = { 177 .reg_bits = 8, 178 .val_bits = 8, 179 .max_register = RK816_DATA_REG(18), 180 .cache_type = REGCACHE_MAPLE, 181 .volatile_reg = rk816_is_volatile_reg, 182 }; 183 184 static const struct regmap_config rk817_regmap_config = { 185 .reg_bits = 8, 186 .val_bits = 8, 187 .max_register = RK817_GPIO_INT_CFG, 188 .cache_type = REGCACHE_NONE, 189 .volatile_reg = rk817_is_volatile_reg, 190 }; 191 192 static const struct rk8xx_i2c_platform_data rk801_data = { 193 .regmap_cfg = &rk801_regmap_config, 194 .variant = RK801_ID, 195 }; 196 197 static const struct rk8xx_i2c_platform_data rk805_data = { 198 .regmap_cfg = &rk805_regmap_config, 199 .variant = RK805_ID, 200 }; 201 202 static const struct rk8xx_i2c_platform_data rk806_data = { 203 .regmap_cfg = &rk806_regmap_config, 204 .variant = RK806_ID, 205 }; 206 207 static const struct rk8xx_i2c_platform_data rk808_data = { 208 .regmap_cfg = &rk808_regmap_config, 209 .variant = RK808_ID, 210 }; 211 212 static const struct rk8xx_i2c_platform_data rk809_data = { 213 .regmap_cfg = &rk817_regmap_config, 214 .variant = RK809_ID, 215 }; 216 217 static const struct rk8xx_i2c_platform_data rk816_data = { 218 .regmap_cfg = &rk816_regmap_config, 219 .variant = RK816_ID, 220 }; 221 222 static const struct rk8xx_i2c_platform_data rk817_data = { 223 .regmap_cfg = &rk817_regmap_config, 224 .variant = RK817_ID, 225 }; 226 227 static const struct rk8xx_i2c_platform_data rk818_data = { 228 .regmap_cfg = &rk818_regmap_config, 229 .variant = RK818_ID, 230 }; 231 232 static int rk8xx_i2c_probe(struct i2c_client *client) 233 { 234 const struct rk8xx_i2c_platform_data *data; 235 struct regmap *regmap; 236 237 data = device_get_match_data(&client->dev); 238 if (!data) 239 return -ENODEV; 240 241 regmap = devm_regmap_init_i2c(client, data->regmap_cfg); 242 if (IS_ERR(regmap)) 243 return dev_err_probe(&client->dev, PTR_ERR(regmap), 244 "regmap initialization failed\n"); 245 246 return rk8xx_probe(&client->dev, data->variant, client->irq, regmap); 247 } 248 249 static void rk8xx_i2c_shutdown(struct i2c_client *client) 250 { 251 rk8xx_shutdown(&client->dev); 252 } 253 254 static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); 255 256 static const struct of_device_id rk8xx_i2c_of_match[] = { 257 { .compatible = "rockchip,rk801", .data = &rk801_data }, 258 { .compatible = "rockchip,rk805", .data = &rk805_data }, 259 { .compatible = "rockchip,rk806", .data = &rk806_data }, 260 { .compatible = "rockchip,rk808", .data = &rk808_data }, 261 { .compatible = "rockchip,rk809", .data = &rk809_data }, 262 { .compatible = "rockchip,rk816", .data = &rk816_data }, 263 { .compatible = "rockchip,rk817", .data = &rk817_data }, 264 { .compatible = "rockchip,rk818", .data = &rk818_data }, 265 { }, 266 }; 267 MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match); 268 269 static struct i2c_driver rk8xx_i2c_driver = { 270 .driver = { 271 .name = "rk8xx-i2c", 272 .of_match_table = rk8xx_i2c_of_match, 273 .pm = &rk8xx_i2c_pm_ops, 274 }, 275 .probe = rk8xx_i2c_probe, 276 .shutdown = rk8xx_i2c_shutdown, 277 }; 278 module_i2c_driver(rk8xx_i2c_driver); 279 280 MODULE_LICENSE("GPL"); 281 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 282 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); 283 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); 284 MODULE_DESCRIPTION("RK8xx I2C PMIC driver"); 285