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

mfd: Add Ricoh RN5T618 PMIC core driver

Ricoh RN5T618 is a power management IC which integrates 3 step-down
DCDC converters, 7 low-dropout regulators, a Li-ion battery charger,
fuel gauge, ADC, GPIOs and a watchdog timer.

This commit adds a MFD core driver to support the I2C communication
with the device.

Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Beniamino Galvani and committed by
Lee Jones
9bb9e29c 6ac734d2

+374
+11
drivers/mfd/Kconfig
··· 597 597 Additional drivers must be enabled in order to use the 598 598 different functionality of the device. 599 599 600 + config MFD_RN5T618 601 + tristate "Ricoh RN5T5618 PMIC" 602 + depends on I2C 603 + select MFD_CORE 604 + select REGMAP_I2C 605 + help 606 + Say yes here to add support for the Ricoh RN5T618 PMIC. This 607 + driver provides common support for accessing the device, 608 + additional drivers must be enabled in order to use the 609 + functionality of the device. 610 + 600 611 config MFD_SEC_CORE 601 612 bool "SAMSUNG Electronics PMIC Series Support" 602 613 depends on I2C=y
+1
drivers/mfd/Makefile
··· 160 160 obj-$(CONFIG_MFD_PALMAS) += palmas.o 161 161 obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o 162 162 obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o 163 + obj-$(CONFIG_MFD_RN5T618) += rn5t618.o 163 164 obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o 164 165 obj-$(CONFIG_MFD_SYSCON) += syscon.o 165 166 obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
+134
drivers/mfd/rn5t618.c
··· 1 + /* 2 + * MFD core driver for Ricoh RN5T618 PMIC 3 + * 4 + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * version 2 as published by the Free Software Foundation. 9 + * 10 + * You should have received a copy of the GNU General Public License 11 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 12 + */ 13 + 14 + #include <linux/i2c.h> 15 + #include <linux/mfd/core.h> 16 + #include <linux/mfd/rn5t618.h> 17 + #include <linux/module.h> 18 + #include <linux/regmap.h> 19 + 20 + static const struct mfd_cell rn5t618_cells[] = { 21 + { .name = "rn5t618-regulator" }, 22 + { .name = "rn5t618-wdt" }, 23 + }; 24 + 25 + static bool rn5t618_volatile_reg(struct device *dev, unsigned int reg) 26 + { 27 + switch (reg) { 28 + case RN5T618_WATCHDOGCNT: 29 + case RN5T618_DCIRQ: 30 + case RN5T618_ILIMDATAH ... RN5T618_AIN0DATAL: 31 + case RN5T618_IR_ADC1 ... RN5T618_IR_ADC3: 32 + case RN5T618_IR_GPR: 33 + case RN5T618_IR_GPF: 34 + case RN5T618_MON_IOIN: 35 + case RN5T618_INTMON: 36 + return true; 37 + default: 38 + return false; 39 + } 40 + } 41 + 42 + static const struct regmap_config rn5t618_regmap_config = { 43 + .reg_bits = 8, 44 + .val_bits = 8, 45 + .volatile_reg = rn5t618_volatile_reg, 46 + .max_register = RN5T618_MAX_REG, 47 + .cache_type = REGCACHE_RBTREE, 48 + }; 49 + 50 + static struct rn5t618 *rn5t618_pm_power_off; 51 + 52 + static void rn5t618_power_off(void) 53 + { 54 + /* disable automatic repower-on */ 55 + regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_REPCNT, 56 + RN5T618_REPCNT_REPWRON, 0); 57 + /* start power-off sequence */ 58 + regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_SLPCNT, 59 + RN5T618_SLPCNT_SWPWROFF, RN5T618_SLPCNT_SWPWROFF); 60 + } 61 + 62 + static int rn5t618_i2c_probe(struct i2c_client *i2c, 63 + const struct i2c_device_id *id) 64 + { 65 + struct rn5t618 *priv; 66 + int ret; 67 + 68 + priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); 69 + if (!priv) 70 + return -ENOMEM; 71 + 72 + i2c_set_clientdata(i2c, priv); 73 + 74 + priv->regmap = devm_regmap_init_i2c(i2c, &rn5t618_regmap_config); 75 + if (IS_ERR(priv->regmap)) { 76 + ret = PTR_ERR(priv->regmap); 77 + dev_err(&i2c->dev, "regmap init failed: %d\n", ret); 78 + return ret; 79 + } 80 + 81 + ret = mfd_add_devices(&i2c->dev, -1, rn5t618_cells, 82 + ARRAY_SIZE(rn5t618_cells), NULL, 0, NULL); 83 + if (ret) { 84 + dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret); 85 + return ret; 86 + } 87 + 88 + if (!pm_power_off) { 89 + rn5t618_pm_power_off = priv; 90 + pm_power_off = rn5t618_power_off; 91 + } 92 + 93 + return 0; 94 + } 95 + 96 + static int rn5t618_i2c_remove(struct i2c_client *i2c) 97 + { 98 + struct rn5t618 *priv = i2c_get_clientdata(i2c); 99 + 100 + if (priv == rn5t618_pm_power_off) { 101 + rn5t618_pm_power_off = NULL; 102 + pm_power_off = NULL; 103 + } 104 + 105 + mfd_remove_devices(&i2c->dev); 106 + return 0; 107 + } 108 + 109 + static const struct of_device_id rn5t618_of_match[] = { 110 + { .compatible = "ricoh,rn5t618" }, 111 + { } 112 + }; 113 + MODULE_DEVICE_TABLE(of, rn5t618_of_match); 114 + 115 + static const struct i2c_device_id rn5t618_i2c_id[] = { 116 + { } 117 + }; 118 + MODULE_DEVICE_TABLE(i2c, rn5t618_i2c_id); 119 + 120 + static struct i2c_driver rn5t618_i2c_driver = { 121 + .driver = { 122 + .name = "rn5t618", 123 + .of_match_table = of_match_ptr(rn5t618_of_match), 124 + }, 125 + .probe = rn5t618_i2c_probe, 126 + .remove = rn5t618_i2c_remove, 127 + .id_table = rn5t618_i2c_id, 128 + }; 129 + 130 + module_i2c_driver(rn5t618_i2c_driver); 131 + 132 + MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); 133 + MODULE_DESCRIPTION("Ricoh RN5T618 MFD driver"); 134 + MODULE_LICENSE("GPL v2");
+228
include/linux/mfd/rn5t618.h
··· 1 + /* 2 + * MFD core driver for Ricoh RN5T618 PMIC 3 + * 4 + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * version 2 as published by the Free Software Foundation. 9 + * 10 + * You should have received a copy of the GNU General Public License 11 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 12 + */ 13 + 14 + #ifndef __LINUX_MFD_RN5T618_H 15 + #define __LINUX_MFD_RN5T618_H 16 + 17 + #include <linux/regmap.h> 18 + 19 + #define RN5T618_LSIVER 0x00 20 + #define RN5T618_OTPVER 0x01 21 + #define RN5T618_IODAC 0x02 22 + #define RN5T618_VINDAC 0x03 23 + #define RN5T618_CPUCNT 0x06 24 + #define RN5T618_PSWR 0x07 25 + #define RN5T618_PONHIS 0x09 26 + #define RN5T618_POFFHIS 0x0a 27 + #define RN5T618_WATCHDOG 0x0b 28 + #define RN5T618_WATCHDOGCNT 0x0c 29 + #define RN5T618_PWRFUNC 0x0d 30 + #define RN5T618_SLPCNT 0x0e 31 + #define RN5T618_REPCNT 0x0f 32 + #define RN5T618_PWRONTIMSET 0x10 33 + #define RN5T618_NOETIMSETCNT 0x11 34 + #define RN5T618_PWRIREN 0x12 35 + #define RN5T618_PWRIRQ 0x13 36 + #define RN5T618_PWRMON 0x14 37 + #define RN5T618_PWRIRSEL 0x15 38 + #define RN5T618_DC1_SLOT 0x16 39 + #define RN5T618_DC2_SLOT 0x17 40 + #define RN5T618_DC3_SLOT 0x18 41 + #define RN5T618_LDO1_SLOT 0x1b 42 + #define RN5T618_LDO2_SLOT 0x1c 43 + #define RN5T618_LDO3_SLOT 0x1d 44 + #define RN5T618_LDO4_SLOT 0x1e 45 + #define RN5T618_LDO5_SLOT 0x1f 46 + #define RN5T618_PSO0_SLOT 0x25 47 + #define RN5T618_PSO1_SLOT 0x26 48 + #define RN5T618_PSO2_SLOT 0x27 49 + #define RN5T618_PSO3_SLOT 0x28 50 + #define RN5T618_LDORTC1_SLOT 0x2a 51 + #define RN5T618_DC1CTL 0x2c 52 + #define RN5T618_DC1CTL2 0x2d 53 + #define RN5T618_DC2CTL 0x2e 54 + #define RN5T618_DC2CTL2 0x2f 55 + #define RN5T618_DC3CTL 0x30 56 + #define RN5T618_DC3CTL2 0x31 57 + #define RN5T618_DC1DAC 0x36 58 + #define RN5T618_DC2DAC 0x37 59 + #define RN5T618_DC3DAC 0x38 60 + #define RN5T618_DC1DAC_SLP 0x3b 61 + #define RN5T618_DC2DAC_SLP 0x3c 62 + #define RN5T618_DC3DAC_SLP 0x3d 63 + #define RN5T618_DCIREN 0x40 64 + #define RN5T618_DCIRQ 0x41 65 + #define RN5T618_DCIRMON 0x42 66 + #define RN5T618_LDOEN1 0x44 67 + #define RN5T618_LDOEN2 0x45 68 + #define RN5T618_LDODIS 0x46 69 + #define RN5T618_LDO1DAC 0x4c 70 + #define RN5T618_LDO2DAC 0x4d 71 + #define RN5T618_LDO3DAC 0x4e 72 + #define RN5T618_LDO4DAC 0x4f 73 + #define RN5T618_LDO5DAC 0x50 74 + #define RN5T618_LDORTCDAC 0x56 75 + #define RN5T618_LDORTC2DAC 0x57 76 + #define RN5T618_LDO1DAC_SLP 0x58 77 + #define RN5T618_LDO2DAC_SLP 0x59 78 + #define RN5T618_LDO3DAC_SLP 0x5a 79 + #define RN5T618_LDO4DAC_SLP 0x5b 80 + #define RN5T618_LDO5DAC_SLP 0x5c 81 + #define RN5T618_ADCCNT1 0x64 82 + #define RN5T618_ADCCNT2 0x65 83 + #define RN5T618_ADCCNT3 0x66 84 + #define RN5T618_ILIMDATAH 0x68 85 + #define RN5T618_ILIMDATAL 0x69 86 + #define RN5T618_VBATDATAH 0x6a 87 + #define RN5T618_VBATDATAL 0x6b 88 + #define RN5T618_VADPDATAH 0x6c 89 + #define RN5T618_VADPDATAL 0x6d 90 + #define RN5T618_VUSBDATAH 0x6e 91 + #define RN5T618_VUSBDATAL 0x6f 92 + #define RN5T618_VSYSDATAH 0x70 93 + #define RN5T618_VSYSDATAL 0x71 94 + #define RN5T618_VTHMDATAH 0x72 95 + #define RN5T618_VTHMDATAL 0x73 96 + #define RN5T618_AIN1DATAH 0x74 97 + #define RN5T618_AIN1DATAL 0x75 98 + #define RN5T618_AIN0DATAH 0x76 99 + #define RN5T618_AIN0DATAL 0x77 100 + #define RN5T618_ILIMTHL 0x78 101 + #define RN5T618_ILIMTHH 0x79 102 + #define RN5T618_VBATTHL 0x7a 103 + #define RN5T618_VBATTHH 0x7b 104 + #define RN5T618_VADPTHL 0x7c 105 + #define RN5T618_VADPTHH 0x7d 106 + #define RN5T618_VUSBTHL 0x7e 107 + #define RN5T618_VUSBTHH 0x7f 108 + #define RN5T618_VSYSTHL 0x80 109 + #define RN5T618_VSYSTHH 0x81 110 + #define RN5T618_VTHMTHL 0x82 111 + #define RN5T618_VTHMTHH 0x83 112 + #define RN5T618_AIN1THL 0x84 113 + #define RN5T618_AIN1THH 0x85 114 + #define RN5T618_AIN0THL 0x86 115 + #define RN5T618_AIN0THH 0x87 116 + #define RN5T618_EN_ADCIR1 0x88 117 + #define RN5T618_EN_ADCIR2 0x89 118 + #define RN5T618_EN_ADCIR3 0x8a 119 + #define RN5T618_IR_ADC1 0x8c 120 + #define RN5T618_IR_ADC2 0x8d 121 + #define RN5T618_IR_ADC3 0x8e 122 + #define RN5T618_IOSEL 0x90 123 + #define RN5T618_IOOUT 0x91 124 + #define RN5T618_GPEDGE1 0x92 125 + #define RN5T618_GPEDGE2 0x93 126 + #define RN5T618_EN_GPIR 0x94 127 + #define RN5T618_IR_GPR 0x95 128 + #define RN5T618_IR_GPF 0x96 129 + #define RN5T618_MON_IOIN 0x97 130 + #define RN5T618_GPLED_FUNC 0x98 131 + #define RN5T618_INTPOL 0x9c 132 + #define RN5T618_INTEN 0x9d 133 + #define RN5T618_INTMON 0x9e 134 + #define RN5T618_PREVINDAC 0xb0 135 + #define RN5T618_BATDAC 0xb1 136 + #define RN5T618_CHGCTL1 0xb3 137 + #define RN5T618_CHGCTL2 0xb4 138 + #define RN5T618_VSYSSET 0xb5 139 + #define RN5T618_REGISET1 0xb6 140 + #define RN5T618_REGISET2 0xb7 141 + #define RN5T618_CHGISET 0xb8 142 + #define RN5T618_TIMSET 0xb9 143 + #define RN5T618_BATSET1 0xba 144 + #define RN5T618_BATSET2 0xbb 145 + #define RN5T618_DIESET 0xbc 146 + #define RN5T618_CHGSTATE 0xbd 147 + #define RN5T618_CHGCTRL_IRFMASK 0xbe 148 + #define RN5T618_CHGSTAT_IRFMASK1 0xbf 149 + #define RN5T618_CHGSTAT_IRFMASK2 0xc0 150 + #define RN5T618_CHGERR_IRFMASK 0xc1 151 + #define RN5T618_CHGCTRL_IRR 0xc2 152 + #define RN5T618_CHGSTAT_IRR1 0xc3 153 + #define RN5T618_CHGSTAT_IRR2 0xc4 154 + #define RN5T618_CHGERR_IRR 0xc5 155 + #define RN5T618_CHGCTRL_MONI 0xc6 156 + #define RN5T618_CHGSTAT_MONI1 0xc7 157 + #define RN5T618_CHGSTAT_MONI2 0xc8 158 + #define RN5T618_CHGERR_MONI 0xc9 159 + #define RN5T618_CHGCTRL_DETMOD1 0xca 160 + #define RN5T618_CHGCTRL_DETMOD2 0xcb 161 + #define RN5T618_CHGSTAT_DETMOD1 0xcc 162 + #define RN5T618_CHGSTAT_DETMOD2 0xcd 163 + #define RN5T618_CHGSTAT_DETMOD3 0xce 164 + #define RN5T618_CHGERR_DETMOD1 0xcf 165 + #define RN5T618_CHGERR_DETMOD2 0xd0 166 + #define RN5T618_CHGOSCCTL 0xd4 167 + #define RN5T618_CHGOSCSCORESET1 0xd5 168 + #define RN5T618_CHGOSCSCORESET2 0xd6 169 + #define RN5T618_CHGOSCSCORESET3 0xd7 170 + #define RN5T618_CHGOSCFREQSET1 0xd8 171 + #define RN5T618_CHGOSCFREQSET2 0xd9 172 + #define RN5T618_CONTROL 0xe0 173 + #define RN5T618_SOC 0xe1 174 + #define RN5T618_RE_CAP_H 0xe2 175 + #define RN5T618_RE_CAP_L 0xe3 176 + #define RN5T618_FA_CAP_H 0xe4 177 + #define RN5T618_FA_CAP_L 0xe5 178 + #define RN5T618_AGE 0xe6 179 + #define RN5T618_TT_EMPTY_H 0xe7 180 + #define RN5T618_TT_EMPTY_L 0xe8 181 + #define RN5T618_TT_FULL_H 0xe9 182 + #define RN5T618_TT_FULL_L 0xea 183 + #define RN5T618_VOLTAGE_1 0xeb 184 + #define RN5T618_VOLTAGE_0 0xec 185 + #define RN5T618_TEMP_1 0xed 186 + #define RN5T618_TEMP_0 0xee 187 + #define RN5T618_CC_CTRL 0xef 188 + #define RN5T618_CC_COUNT2 0xf0 189 + #define RN5T618_CC_COUNT1 0xf1 190 + #define RN5T618_CC_COUNT0 0xf2 191 + #define RN5T618_CC_SUMREG3 0xf3 192 + #define RN5T618_CC_SUMREG2 0xf4 193 + #define RN5T618_CC_SUMREG1 0xf5 194 + #define RN5T618_CC_SUMREG0 0xf6 195 + #define RN5T618_CC_OFFREG1 0xf7 196 + #define RN5T618_CC_OFFREG0 0xf8 197 + #define RN5T618_CC_GAINREG1 0xf9 198 + #define RN5T618_CC_GAINREG0 0xfa 199 + #define RN5T618_CC_AVEREG1 0xfb 200 + #define RN5T618_CC_AVEREG0 0xfc 201 + #define RN5T618_MAX_REG 0xfc 202 + 203 + #define RN5T618_REPCNT_REPWRON BIT(0) 204 + #define RN5T618_SLPCNT_SWPWROFF BIT(0) 205 + #define RN5T618_WATCHDOG_WDOGEN BIT(2) 206 + #define RN5T618_WATCHDOG_WDOGTIM_M (BIT(0) | BIT(1)) 207 + #define RN5T618_WATCHDOG_WDOGTIM_S 0 208 + #define RN5T618_PWRIRQ_IR_WDOG BIT(6) 209 + 210 + enum { 211 + RN5T618_DCDC1, 212 + RN5T618_DCDC2, 213 + RN5T618_DCDC3, 214 + RN5T618_LDO1, 215 + RN5T618_LDO2, 216 + RN5T618_LDO3, 217 + RN5T618_LDO4, 218 + RN5T618_LDO5, 219 + RN5T618_LDORTC1, 220 + RN5T618_LDORTC2, 221 + RN5T618_REG_NUM, 222 + }; 223 + 224 + struct rn5t618 { 225 + struct regmap *regmap; 226 + }; 227 + 228 + #endif /* __LINUX_MFD_RN5T618_H */