1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Rockchip 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 rk808_is_volatile_reg(struct device *dev, unsigned int reg) 25 { 26 /* 27 * Notes: 28 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but 29 * we don't use that feature. It's better to cache. 30 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since 31 * bits are cleared in case when we shutoff anyway, but better safe. 32 */ 33 34 switch (reg) { 35 case RK808_SECONDS_REG ... RK808_WEEKS_REG: 36 case RK808_RTC_STATUS_REG: 37 case RK808_VB_MON_REG: 38 case RK808_THERMAL_REG: 39 case RK808_DCDC_UV_STS_REG: 40 case RK808_LDO_UV_STS_REG: 41 case RK808_DCDC_PG_REG: 42 case RK808_LDO_PG_REG: 43 case RK808_DEVCTRL_REG: 44 case RK808_INT_STS_REG1: 45 case RK808_INT_STS_REG2: 46 return true; 47 } 48 49 return false; 50 } 51 52 static bool rk816_is_volatile_reg(struct device *dev, unsigned int reg) 53 { 54 /* 55 * Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but 56 * we don't use that feature. It's better to cache. 57 */ 58 59 switch (reg) { 60 case RK808_SECONDS_REG ... RK808_WEEKS_REG: 61 case RK808_RTC_STATUS_REG: 62 case RK808_VB_MON_REG: 63 case RK808_THERMAL_REG: 64 case RK816_DCDC_EN_REG1: 65 case RK816_DCDC_EN_REG2: 66 case RK816_INT_STS_REG1: 67 case RK816_INT_STS_REG2: 68 case RK816_INT_STS_REG3: 69 case RK808_DEVCTRL_REG: 70 case RK816_SUP_STS_REG: 71 case RK816_GGSTS_REG: 72 case RK816_ZERO_CUR_ADC_REGH: 73 case RK816_ZERO_CUR_ADC_REGL: 74 case RK816_GASCNT_REG(0) ... RK816_BAT_VOL_REGL: 75 return true; 76 } 77 78 return false; 79 } 80 81 static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg) 82 { 83 /* 84 * Notes: 85 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but 86 * we don't use that feature. It's better to cache. 87 */ 88 89 switch (reg) { 90 case RK817_SECONDS_REG ... RK817_WEEKS_REG: 91 case RK817_RTC_STATUS_REG: 92 case RK817_CODEC_DTOP_LPT_SRST: 93 case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0: 94 case RK817_PMIC_CHRG_STS: 95 case RK817_PMIC_CHRG_OUT: 96 case RK817_PMIC_CHRG_IN: 97 case RK817_INT_STS_REG0: 98 case RK817_INT_STS_REG1: 99 case RK817_INT_STS_REG2: 100 case RK817_SYS_STS: 101 return true; 102 } 103 104 return false; 105 } 106 107 108 static const struct regmap_config rk818_regmap_config = { 109 .reg_bits = 8, 110 .val_bits = 8, 111 .max_register = RK818_USB_CTRL_REG, 112 .cache_type = REGCACHE_MAPLE, 113 .volatile_reg = rk808_is_volatile_reg, 114 }; 115 116 static const struct regmap_config rk805_regmap_config = { 117 .reg_bits = 8, 118 .val_bits = 8, 119 .max_register = RK805_OFF_SOURCE_REG, 120 .cache_type = REGCACHE_MAPLE, 121 .volatile_reg = rk808_is_volatile_reg, 122 }; 123 124 static const struct regmap_config rk808_regmap_config = { 125 .reg_bits = 8, 126 .val_bits = 8, 127 .max_register = RK808_IO_POL_REG, 128 .cache_type = REGCACHE_MAPLE, 129 .volatile_reg = rk808_is_volatile_reg, 130 }; 131 132 static const struct regmap_config rk816_regmap_config = { 133 .reg_bits = 8, 134 .val_bits = 8, 135 .max_register = RK816_DATA_REG(18), 136 .cache_type = REGCACHE_MAPLE, 137 .volatile_reg = rk816_is_volatile_reg, 138 }; 139 140 static const struct regmap_config rk817_regmap_config = { 141 .reg_bits = 8, 142 .val_bits = 8, 143 .max_register = RK817_GPIO_INT_CFG, 144 .cache_type = REGCACHE_NONE, 145 .volatile_reg = rk817_is_volatile_reg, 146 }; 147 148 static const struct rk8xx_i2c_platform_data rk805_data = { 149 .regmap_cfg = &rk805_regmap_config, 150 .variant = RK805_ID, 151 }; 152 153 static const struct rk8xx_i2c_platform_data rk808_data = { 154 .regmap_cfg = &rk808_regmap_config, 155 .variant = RK808_ID, 156 }; 157 158 static const struct rk8xx_i2c_platform_data rk809_data = { 159 .regmap_cfg = &rk817_regmap_config, 160 .variant = RK809_ID, 161 }; 162 163 static const struct rk8xx_i2c_platform_data rk816_data = { 164 .regmap_cfg = &rk816_regmap_config, 165 .variant = RK816_ID, 166 }; 167 168 static const struct rk8xx_i2c_platform_data rk817_data = { 169 .regmap_cfg = &rk817_regmap_config, 170 .variant = RK817_ID, 171 }; 172 173 static const struct rk8xx_i2c_platform_data rk818_data = { 174 .regmap_cfg = &rk818_regmap_config, 175 .variant = RK818_ID, 176 }; 177 178 static int rk8xx_i2c_probe(struct i2c_client *client) 179 { 180 const struct rk8xx_i2c_platform_data *data; 181 struct regmap *regmap; 182 183 data = device_get_match_data(&client->dev); 184 if (!data) 185 return -ENODEV; 186 187 regmap = devm_regmap_init_i2c(client, data->regmap_cfg); 188 if (IS_ERR(regmap)) 189 return dev_err_probe(&client->dev, PTR_ERR(regmap), 190 "regmap initialization failed\n"); 191 192 return rk8xx_probe(&client->dev, data->variant, client->irq, regmap); 193 } 194 195 static void rk8xx_i2c_shutdown(struct i2c_client *client) 196 { 197 rk8xx_shutdown(&client->dev); 198 } 199 200 static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); 201 202 static const struct of_device_id rk8xx_i2c_of_match[] = { 203 { .compatible = "rockchip,rk805", .data = &rk805_data }, 204 { .compatible = "rockchip,rk808", .data = &rk808_data }, 205 { .compatible = "rockchip,rk809", .data = &rk809_data }, 206 { .compatible = "rockchip,rk816", .data = &rk816_data }, 207 { .compatible = "rockchip,rk817", .data = &rk817_data }, 208 { .compatible = "rockchip,rk818", .data = &rk818_data }, 209 { }, 210 }; 211 MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match); 212 213 static struct i2c_driver rk8xx_i2c_driver = { 214 .driver = { 215 .name = "rk8xx-i2c", 216 .of_match_table = rk8xx_i2c_of_match, 217 .pm = &rk8xx_i2c_pm_ops, 218 }, 219 .probe = rk8xx_i2c_probe, 220 .shutdown = rk8xx_i2c_shutdown, 221 }; 222 module_i2c_driver(rk8xx_i2c_driver); 223 224 MODULE_LICENSE("GPL"); 225 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 226 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); 227 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); 228 MODULE_DESCRIPTION("RK8xx I2C PMIC driver"); 229