brintos

brintos / linux-shallow public Read only

0
0
Text · 6.4 KiB · 37287b0 Raw
254 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Rockchip RK805/RK808/RK816/RK817/RK818 Core (I2C) driver4 *5 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd6 * Copyright (C) 2016 PHYTEC Messtechnik GmbH7 *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, but40	 *   we don't use that feature.  It's better to cache.41	 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since42	 *   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, but67	 * 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, but97	 *   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");254