Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.18-rc6 253 lines 6.5 kB view raw
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 19struct rk8xx_i2c_platform_data { 20 const struct regmap_config *regmap_cfg; 21 int variant; 22}; 23 24static bool rk806_is_volatile_reg(struct device *dev, unsigned int reg) 25{ 26 switch (reg) { 27 case RK806_POWER_EN0 ... RK806_POWER_EN5: 28 case RK806_DVS_START_CTRL ... RK806_INT_MSK1: 29 return true; 30 } 31 32 return false; 33} 34 35static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg) 36{ 37 /* 38 * Notes: 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. 43 */ 44 45 switch (reg) { 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: 57 return true; 58 } 59 60 return false; 61} 62 63static bool rk816_is_volatile_reg(struct device *dev, unsigned int reg) 64{ 65 /* 66 * Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but 67 * we don't use that feature. It's better to cache. 68 */ 69 70 switch (reg) { 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: 82 case RK816_GGSTS_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: 86 return true; 87 } 88 89 return false; 90} 91 92static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg) 93{ 94 /* 95 * Notes: 96 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but 97 * we don't use that feature. It's better to cache. 98 */ 99 100 switch (reg) { 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: 111 case RK817_SYS_STS: 112 return true; 113 } 114 115 return false; 116} 117 118 119static const struct regmap_config rk818_regmap_config = { 120 .reg_bits = 8, 121 .val_bits = 8, 122 .max_register = RK818_USB_CTRL_REG, 123 .cache_type = REGCACHE_MAPLE, 124 .volatile_reg = rk808_is_volatile_reg, 125}; 126 127static const struct regmap_config rk805_regmap_config = { 128 .reg_bits = 8, 129 .val_bits = 8, 130 .max_register = RK805_OFF_SOURCE_REG, 131 .cache_type = REGCACHE_MAPLE, 132 .volatile_reg = rk808_is_volatile_reg, 133}; 134 135static const struct regmap_config rk806_regmap_config = { 136 .reg_bits = 8, 137 .val_bits = 8, 138 .max_register = RK806_BUCK_RSERVE_REG5, 139 .cache_type = REGCACHE_MAPLE, 140 .volatile_reg = rk806_is_volatile_reg, 141}; 142 143static const struct regmap_config rk808_regmap_config = { 144 .reg_bits = 8, 145 .val_bits = 8, 146 .max_register = RK808_IO_POL_REG, 147 .cache_type = REGCACHE_MAPLE, 148 .volatile_reg = rk808_is_volatile_reg, 149}; 150 151static const struct regmap_config rk816_regmap_config = { 152 .reg_bits = 8, 153 .val_bits = 8, 154 .max_register = RK816_DATA_REG(18), 155 .cache_type = REGCACHE_MAPLE, 156 .volatile_reg = rk816_is_volatile_reg, 157}; 158 159static const struct regmap_config rk817_regmap_config = { 160 .reg_bits = 8, 161 .val_bits = 8, 162 .max_register = RK817_GPIO_INT_CFG, 163 .cache_type = REGCACHE_NONE, 164 .volatile_reg = rk817_is_volatile_reg, 165}; 166 167static const struct rk8xx_i2c_platform_data rk805_data = { 168 .regmap_cfg = &rk805_regmap_config, 169 .variant = RK805_ID, 170}; 171 172static const struct rk8xx_i2c_platform_data rk806_data = { 173 .regmap_cfg = &rk806_regmap_config, 174 .variant = RK806_ID, 175}; 176 177static const struct rk8xx_i2c_platform_data rk808_data = { 178 .regmap_cfg = &rk808_regmap_config, 179 .variant = RK808_ID, 180}; 181 182static const struct rk8xx_i2c_platform_data rk809_data = { 183 .regmap_cfg = &rk817_regmap_config, 184 .variant = RK809_ID, 185}; 186 187static const struct rk8xx_i2c_platform_data rk816_data = { 188 .regmap_cfg = &rk816_regmap_config, 189 .variant = RK816_ID, 190}; 191 192static const struct rk8xx_i2c_platform_data rk817_data = { 193 .regmap_cfg = &rk817_regmap_config, 194 .variant = RK817_ID, 195}; 196 197static const struct rk8xx_i2c_platform_data rk818_data = { 198 .regmap_cfg = &rk818_regmap_config, 199 .variant = RK818_ID, 200}; 201 202static int rk8xx_i2c_probe(struct i2c_client *client) 203{ 204 const struct rk8xx_i2c_platform_data *data; 205 struct regmap *regmap; 206 207 data = device_get_match_data(&client->dev); 208 if (!data) 209 return -ENODEV; 210 211 regmap = devm_regmap_init_i2c(client, data->regmap_cfg); 212 if (IS_ERR(regmap)) 213 return dev_err_probe(&client->dev, PTR_ERR(regmap), 214 "regmap initialization failed\n"); 215 216 return rk8xx_probe(&client->dev, data->variant, client->irq, regmap); 217} 218 219static void rk8xx_i2c_shutdown(struct i2c_client *client) 220{ 221 rk8xx_shutdown(&client->dev); 222} 223 224static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); 225 226static 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 }, 234 { }, 235}; 236MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match); 237 238static struct i2c_driver rk8xx_i2c_driver = { 239 .driver = { 240 .name = "rk8xx-i2c", 241 .of_match_table = rk8xx_i2c_of_match, 242 .pm = &rk8xx_i2c_pm_ops, 243 }, 244 .probe = rk8xx_i2c_probe, 245 .shutdown = rk8xx_i2c_shutdown, 246}; 247module_i2c_driver(rk8xx_i2c_driver); 248 249MODULE_LICENSE("GPL"); 250MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 251MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); 252MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); 253MODULE_DESCRIPTION("RK8xx I2C PMIC driver");