1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Rockchip RK808/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 rk817_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 */ 59 60 switch (reg) { 61 case RK817_SECONDS_REG ... RK817_WEEKS_REG: 62 case RK817_RTC_STATUS_REG: 63 case RK817_CODEC_DTOP_LPT_SRST: 64 case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0: 65 case RK817_PMIC_CHRG_STS: 66 case RK817_PMIC_CHRG_OUT: 67 case RK817_PMIC_CHRG_IN: 68 case RK817_INT_STS_REG0: 69 case RK817_INT_STS_REG1: 70 case RK817_INT_STS_REG2: 71 case RK817_SYS_STS: 72 return true; 73 } 74 75 return false; 76 } 77 78 79 static const struct regmap_config rk818_regmap_config = { 80 .reg_bits = 8, 81 .val_bits = 8, 82 .max_register = RK818_USB_CTRL_REG, 83 .cache_type = REGCACHE_MAPLE, 84 .volatile_reg = rk808_is_volatile_reg, 85 }; 86 87 static const struct regmap_config rk805_regmap_config = { 88 .reg_bits = 8, 89 .val_bits = 8, 90 .max_register = RK805_OFF_SOURCE_REG, 91 .cache_type = REGCACHE_MAPLE, 92 .volatile_reg = rk808_is_volatile_reg, 93 }; 94 95 static const struct regmap_config rk808_regmap_config = { 96 .reg_bits = 8, 97 .val_bits = 8, 98 .max_register = RK808_IO_POL_REG, 99 .cache_type = REGCACHE_MAPLE, 100 .volatile_reg = rk808_is_volatile_reg, 101 }; 102 103 static const struct regmap_config rk817_regmap_config = { 104 .reg_bits = 8, 105 .val_bits = 8, 106 .max_register = RK817_GPIO_INT_CFG, 107 .cache_type = REGCACHE_NONE, 108 .volatile_reg = rk817_is_volatile_reg, 109 }; 110 111 static const struct rk8xx_i2c_platform_data rk805_data = { 112 .regmap_cfg = &rk805_regmap_config, 113 .variant = RK805_ID, 114 }; 115 116 static const struct rk8xx_i2c_platform_data rk808_data = { 117 .regmap_cfg = &rk808_regmap_config, 118 .variant = RK808_ID, 119 }; 120 121 static const struct rk8xx_i2c_platform_data rk809_data = { 122 .regmap_cfg = &rk817_regmap_config, 123 .variant = RK809_ID, 124 }; 125 126 static const struct rk8xx_i2c_platform_data rk817_data = { 127 .regmap_cfg = &rk817_regmap_config, 128 .variant = RK817_ID, 129 }; 130 131 static const struct rk8xx_i2c_platform_data rk818_data = { 132 .regmap_cfg = &rk818_regmap_config, 133 .variant = RK818_ID, 134 }; 135 136 static int rk8xx_i2c_probe(struct i2c_client *client) 137 { 138 const struct rk8xx_i2c_platform_data *data; 139 struct regmap *regmap; 140 141 data = device_get_match_data(&client->dev); 142 if (!data) 143 return -ENODEV; 144 145 regmap = devm_regmap_init_i2c(client, data->regmap_cfg); 146 if (IS_ERR(regmap)) 147 return dev_err_probe(&client->dev, PTR_ERR(regmap), 148 "regmap initialization failed\n"); 149 150 return rk8xx_probe(&client->dev, data->variant, client->irq, regmap); 151 } 152 153 static void rk8xx_i2c_shutdown(struct i2c_client *client) 154 { 155 rk8xx_shutdown(&client->dev); 156 } 157 158 static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); 159 160 static const struct of_device_id rk8xx_i2c_of_match[] = { 161 { .compatible = "rockchip,rk805", .data = &rk805_data }, 162 { .compatible = "rockchip,rk808", .data = &rk808_data }, 163 { .compatible = "rockchip,rk809", .data = &rk809_data }, 164 { .compatible = "rockchip,rk817", .data = &rk817_data }, 165 { .compatible = "rockchip,rk818", .data = &rk818_data }, 166 { }, 167 }; 168 MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match); 169 170 static struct i2c_driver rk8xx_i2c_driver = { 171 .driver = { 172 .name = "rk8xx-i2c", 173 .of_match_table = rk8xx_i2c_of_match, 174 .pm = &rk8xx_i2c_pm_ops, 175 }, 176 .probe = rk8xx_i2c_probe, 177 .shutdown = rk8xx_i2c_shutdown, 178 }; 179 module_i2c_driver(rk8xx_i2c_driver); 180 181 MODULE_LICENSE("GPL"); 182 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 183 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); 184 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); 185 MODULE_DESCRIPTION("RK8xx I2C PMIC driver"); 186