Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * act8865-regulator.c - Voltage regulation for active-semi ACT88xx PMUs
0004  *
0005  * http://www.active-semi.com/products/power-management-units/act88xx/
0006  *
0007  * Copyright (C) 2013 Atmel Corporation
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/init.h>
0012 #include <linux/i2c.h>
0013 #include <linux/err.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regulator/driver.h>
0016 #include <linux/regulator/act8865.h>
0017 #include <linux/of.h>
0018 #include <linux/of_device.h>
0019 #include <linux/power_supply.h>
0020 #include <linux/regulator/of_regulator.h>
0021 #include <linux/regmap.h>
0022 #include <dt-bindings/regulator/active-semi,8865-regulator.h>
0023 
0024 /*
0025  * ACT8600 Global Register Map.
0026  */
0027 #define ACT8600_SYS_MODE    0x00
0028 #define ACT8600_SYS_CTRL    0x01
0029 #define ACT8600_DCDC1_VSET  0x10
0030 #define ACT8600_DCDC1_CTRL  0x12
0031 #define ACT8600_DCDC2_VSET  0x20
0032 #define ACT8600_DCDC2_CTRL  0x22
0033 #define ACT8600_DCDC3_VSET  0x30
0034 #define ACT8600_DCDC3_CTRL  0x32
0035 #define ACT8600_SUDCDC4_VSET    0x40
0036 #define ACT8600_SUDCDC4_CTRL    0x41
0037 #define ACT8600_LDO5_VSET   0x50
0038 #define ACT8600_LDO5_CTRL   0x51
0039 #define ACT8600_LDO6_VSET   0x60
0040 #define ACT8600_LDO6_CTRL   0x61
0041 #define ACT8600_LDO7_VSET   0x70
0042 #define ACT8600_LDO7_CTRL   0x71
0043 #define ACT8600_LDO8_VSET   0x80
0044 #define ACT8600_LDO8_CTRL   0x81
0045 #define ACT8600_LDO910_CTRL 0x91
0046 #define ACT8600_APCH0       0xA1
0047 #define ACT8600_APCH1       0xA8
0048 #define ACT8600_APCH2       0xA9
0049 #define ACT8600_APCH_STAT   0xAA
0050 #define ACT8600_OTG0        0xB0
0051 #define ACT8600_OTG1        0xB2
0052 
0053 /*
0054  * ACT8846 Global Register Map.
0055  */
0056 #define ACT8846_SYS0        0x00
0057 #define ACT8846_SYS1        0x01
0058 #define ACT8846_REG1_VSET   0x10
0059 #define ACT8846_REG1_CTRL   0x12
0060 #define ACT8846_REG2_VSET0  0x20
0061 #define ACT8846_REG2_VSET1  0x21
0062 #define ACT8846_REG2_CTRL   0x22
0063 #define ACT8846_REG3_VSET0  0x30
0064 #define ACT8846_REG3_VSET1  0x31
0065 #define ACT8846_REG3_CTRL   0x32
0066 #define ACT8846_REG4_VSET0  0x40
0067 #define ACT8846_REG4_VSET1  0x41
0068 #define ACT8846_REG4_CTRL   0x42
0069 #define ACT8846_REG5_VSET   0x50
0070 #define ACT8846_REG5_CTRL   0x51
0071 #define ACT8846_REG6_VSET   0x58
0072 #define ACT8846_REG6_CTRL   0x59
0073 #define ACT8846_REG7_VSET   0x60
0074 #define ACT8846_REG7_CTRL   0x61
0075 #define ACT8846_REG8_VSET   0x68
0076 #define ACT8846_REG8_CTRL   0x69
0077 #define ACT8846_REG9_VSET   0x70
0078 #define ACT8846_REG9_CTRL   0x71
0079 #define ACT8846_REG10_VSET  0x80
0080 #define ACT8846_REG10_CTRL  0x81
0081 #define ACT8846_REG11_VSET  0x90
0082 #define ACT8846_REG11_CTRL  0x91
0083 #define ACT8846_REG12_VSET  0xa0
0084 #define ACT8846_REG12_CTRL  0xa1
0085 #define ACT8846_REG13_CTRL  0xb1
0086 #define ACT8846_GLB_OFF_CTRL    0xc3
0087 #define ACT8846_OFF_SYSMASK 0x18
0088 
0089 /*
0090  * ACT8865 Global Register Map.
0091  */
0092 #define ACT8865_SYS_MODE    0x00
0093 #define ACT8865_SYS_CTRL    0x01
0094 #define ACT8865_SYS_UNLK_REGS   0x0b
0095 #define ACT8865_DCDC1_VSET1 0x20
0096 #define ACT8865_DCDC1_VSET2 0x21
0097 #define ACT8865_DCDC1_CTRL  0x22
0098 #define ACT8865_DCDC1_SUS   0x24
0099 #define ACT8865_DCDC2_VSET1 0x30
0100 #define ACT8865_DCDC2_VSET2 0x31
0101 #define ACT8865_DCDC2_CTRL  0x32
0102 #define ACT8865_DCDC2_SUS   0x34
0103 #define ACT8865_DCDC3_VSET1 0x40
0104 #define ACT8865_DCDC3_VSET2 0x41
0105 #define ACT8865_DCDC3_CTRL  0x42
0106 #define ACT8865_DCDC3_SUS   0x44
0107 #define ACT8865_LDO1_VSET   0x50
0108 #define ACT8865_LDO1_CTRL   0x51
0109 #define ACT8865_LDO1_SUS    0x52
0110 #define ACT8865_LDO2_VSET   0x54
0111 #define ACT8865_LDO2_CTRL   0x55
0112 #define ACT8865_LDO2_SUS    0x56
0113 #define ACT8865_LDO3_VSET   0x60
0114 #define ACT8865_LDO3_CTRL   0x61
0115 #define ACT8865_LDO3_SUS    0x62
0116 #define ACT8865_LDO4_VSET   0x64
0117 #define ACT8865_LDO4_CTRL   0x65
0118 #define ACT8865_LDO4_SUS    0x66
0119 #define ACT8865_MSTROFF     0x20
0120 
0121 /*
0122  * Field Definitions.
0123  */
0124 #define ACT8865_ENA     0x80    /* ON - [7] */
0125 #define ACT8865_DIS     0x40    /* DIS - [6] */
0126 
0127 #define ACT8865_VSEL_MASK   0x3F    /* VSET - [5:0] */
0128 
0129 
0130 #define ACT8600_LDO10_ENA       0x40    /* ON - [6] */
0131 #define ACT8600_SUDCDC_VSEL_MASK    0xFF    /* SUDCDC VSET - [7:0] */
0132 
0133 #define ACT8600_APCH_CHG_ACIN       BIT(7)
0134 #define ACT8600_APCH_CHG_USB        BIT(6)
0135 #define ACT8600_APCH_CSTATE0        BIT(5)
0136 #define ACT8600_APCH_CSTATE1        BIT(4)
0137 
0138 /*
0139  * ACT8865 voltage number
0140  */
0141 #define ACT8865_VOLTAGE_NUM 64
0142 #define ACT8600_SUDCDC_VOLTAGE_NUM  256
0143 
0144 struct act8865 {
0145     struct regmap *regmap;
0146     int off_reg;
0147     int off_mask;
0148 };
0149 
0150 static const struct regmap_range act8600_reg_ranges[] = {
0151     regmap_reg_range(0x00, 0x01),
0152     regmap_reg_range(0x10, 0x10),
0153     regmap_reg_range(0x12, 0x12),
0154     regmap_reg_range(0x20, 0x20),
0155     regmap_reg_range(0x22, 0x22),
0156     regmap_reg_range(0x30, 0x30),
0157     regmap_reg_range(0x32, 0x32),
0158     regmap_reg_range(0x40, 0x41),
0159     regmap_reg_range(0x50, 0x51),
0160     regmap_reg_range(0x60, 0x61),
0161     regmap_reg_range(0x70, 0x71),
0162     regmap_reg_range(0x80, 0x81),
0163     regmap_reg_range(0x91, 0x91),
0164     regmap_reg_range(0xA1, 0xA1),
0165     regmap_reg_range(0xA8, 0xAA),
0166     regmap_reg_range(0xB0, 0xB0),
0167     regmap_reg_range(0xB2, 0xB2),
0168     regmap_reg_range(0xC1, 0xC1),
0169 };
0170 
0171 static const struct regmap_range act8600_reg_ro_ranges[] = {
0172     regmap_reg_range(0xAA, 0xAA),
0173     regmap_reg_range(0xC1, 0xC1),
0174 };
0175 
0176 static const struct regmap_range act8600_reg_volatile_ranges[] = {
0177     regmap_reg_range(0x00, 0x01),
0178     regmap_reg_range(0x12, 0x12),
0179     regmap_reg_range(0x22, 0x22),
0180     regmap_reg_range(0x32, 0x32),
0181     regmap_reg_range(0x41, 0x41),
0182     regmap_reg_range(0x51, 0x51),
0183     regmap_reg_range(0x61, 0x61),
0184     regmap_reg_range(0x71, 0x71),
0185     regmap_reg_range(0x81, 0x81),
0186     regmap_reg_range(0xA8, 0xA8),
0187     regmap_reg_range(0xAA, 0xAA),
0188     regmap_reg_range(0xB0, 0xB0),
0189     regmap_reg_range(0xC1, 0xC1),
0190 };
0191 
0192 static const struct regmap_access_table act8600_write_ranges_table = {
0193     .yes_ranges = act8600_reg_ranges,
0194     .n_yes_ranges   = ARRAY_SIZE(act8600_reg_ranges),
0195     .no_ranges  = act8600_reg_ro_ranges,
0196     .n_no_ranges    = ARRAY_SIZE(act8600_reg_ro_ranges),
0197 };
0198 
0199 static const struct regmap_access_table act8600_read_ranges_table = {
0200     .yes_ranges = act8600_reg_ranges,
0201     .n_yes_ranges   = ARRAY_SIZE(act8600_reg_ranges),
0202 };
0203 
0204 static const struct regmap_access_table act8600_volatile_ranges_table = {
0205     .yes_ranges = act8600_reg_volatile_ranges,
0206     .n_yes_ranges   = ARRAY_SIZE(act8600_reg_volatile_ranges),
0207 };
0208 
0209 static const struct regmap_config act8600_regmap_config = {
0210     .reg_bits = 8,
0211     .val_bits = 8,
0212     .max_register = 0xFF,
0213     .wr_table = &act8600_write_ranges_table,
0214     .rd_table = &act8600_read_ranges_table,
0215     .volatile_table = &act8600_volatile_ranges_table,
0216 };
0217 
0218 static const struct regmap_config act8865_regmap_config = {
0219     .reg_bits = 8,
0220     .val_bits = 8,
0221 };
0222 
0223 static const struct linear_range act8865_voltage_ranges[] = {
0224     REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000),
0225     REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000),
0226     REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
0227 };
0228 
0229 static const struct linear_range act8600_sudcdc_voltage_ranges[] = {
0230     REGULATOR_LINEAR_RANGE(3000000, 0, 63, 0),
0231     REGULATOR_LINEAR_RANGE(3000000, 64, 159, 100000),
0232     REGULATOR_LINEAR_RANGE(12600000, 160, 191, 200000),
0233     REGULATOR_LINEAR_RANGE(19000000, 192, 247, 400000),
0234     REGULATOR_LINEAR_RANGE(41400000, 248, 255, 0),
0235 };
0236 
0237 static int act8865_set_suspend_state(struct regulator_dev *rdev, bool enable)
0238 {
0239     struct regmap *regmap = rdev->regmap;
0240     int id = rdev->desc->id, reg, val;
0241 
0242     switch (id) {
0243     case ACT8865_ID_DCDC1:
0244         reg = ACT8865_DCDC1_SUS;
0245         val = 0xa8;
0246         break;
0247     case ACT8865_ID_DCDC2:
0248         reg = ACT8865_DCDC2_SUS;
0249         val = 0xa8;
0250         break;
0251     case ACT8865_ID_DCDC3:
0252         reg = ACT8865_DCDC3_SUS;
0253         val = 0xa8;
0254         break;
0255     case ACT8865_ID_LDO1:
0256         reg = ACT8865_LDO1_SUS;
0257         val = 0xe8;
0258         break;
0259     case ACT8865_ID_LDO2:
0260         reg = ACT8865_LDO2_SUS;
0261         val = 0xe8;
0262         break;
0263     case ACT8865_ID_LDO3:
0264         reg = ACT8865_LDO3_SUS;
0265         val = 0xe8;
0266         break;
0267     case ACT8865_ID_LDO4:
0268         reg = ACT8865_LDO4_SUS;
0269         val = 0xe8;
0270         break;
0271     default:
0272         return -EINVAL;
0273     }
0274 
0275     if (enable)
0276         val |= BIT(4);
0277 
0278     /*
0279      * Ask the PMIC to enable/disable this output when entering hibernate
0280      * mode.
0281      */
0282     return regmap_write(regmap, reg, val);
0283 }
0284 
0285 static int act8865_set_suspend_enable(struct regulator_dev *rdev)
0286 {
0287     return act8865_set_suspend_state(rdev, true);
0288 }
0289 
0290 static int act8865_set_suspend_disable(struct regulator_dev *rdev)
0291 {
0292     return act8865_set_suspend_state(rdev, false);
0293 }
0294 
0295 static unsigned int act8865_of_map_mode(unsigned int mode)
0296 {
0297     switch (mode) {
0298     case ACT8865_REGULATOR_MODE_FIXED:
0299         return REGULATOR_MODE_FAST;
0300     case ACT8865_REGULATOR_MODE_NORMAL:
0301         return REGULATOR_MODE_NORMAL;
0302     case ACT8865_REGULATOR_MODE_LOWPOWER:
0303         return REGULATOR_MODE_STANDBY;
0304     default:
0305         return REGULATOR_MODE_INVALID;
0306     }
0307 }
0308 
0309 static int act8865_set_mode(struct regulator_dev *rdev, unsigned int mode)
0310 {
0311     struct regmap *regmap = rdev->regmap;
0312     int id = rdev_get_id(rdev);
0313     int reg, val = 0;
0314 
0315     switch (id) {
0316     case ACT8865_ID_DCDC1:
0317         reg = ACT8865_DCDC1_CTRL;
0318         break;
0319     case ACT8865_ID_DCDC2:
0320         reg = ACT8865_DCDC2_CTRL;
0321         break;
0322     case ACT8865_ID_DCDC3:
0323         reg = ACT8865_DCDC3_CTRL;
0324         break;
0325     case ACT8865_ID_LDO1:
0326         reg = ACT8865_LDO1_CTRL;
0327         break;
0328     case ACT8865_ID_LDO2:
0329         reg = ACT8865_LDO2_CTRL;
0330         break;
0331     case ACT8865_ID_LDO3:
0332         reg = ACT8865_LDO3_CTRL;
0333         break;
0334     case ACT8865_ID_LDO4:
0335         reg = ACT8865_LDO4_CTRL;
0336         break;
0337     default:
0338         return -EINVAL;
0339     }
0340 
0341     switch (mode) {
0342     case REGULATOR_MODE_FAST:
0343     case REGULATOR_MODE_NORMAL:
0344         if (id <= ACT8865_ID_DCDC3)
0345             val = BIT(5);
0346         break;
0347     case REGULATOR_MODE_STANDBY:
0348         if (id > ACT8865_ID_DCDC3)
0349             val = BIT(5);
0350         break;
0351     default:
0352         return -EINVAL;
0353     }
0354 
0355     return regmap_update_bits(regmap, reg, BIT(5), val);
0356 }
0357 
0358 static unsigned int act8865_get_mode(struct regulator_dev *rdev)
0359 {
0360     struct regmap *regmap = rdev->regmap;
0361     int id = rdev_get_id(rdev);
0362     int reg, ret, val = 0;
0363 
0364     switch (id) {
0365     case ACT8865_ID_DCDC1:
0366         reg = ACT8865_DCDC1_CTRL;
0367         break;
0368     case ACT8865_ID_DCDC2:
0369         reg = ACT8865_DCDC2_CTRL;
0370         break;
0371     case ACT8865_ID_DCDC3:
0372         reg = ACT8865_DCDC3_CTRL;
0373         break;
0374     case ACT8865_ID_LDO1:
0375         reg = ACT8865_LDO1_CTRL;
0376         break;
0377     case ACT8865_ID_LDO2:
0378         reg = ACT8865_LDO2_CTRL;
0379         break;
0380     case ACT8865_ID_LDO3:
0381         reg = ACT8865_LDO3_CTRL;
0382         break;
0383     case ACT8865_ID_LDO4:
0384         reg = ACT8865_LDO4_CTRL;
0385         break;
0386     default:
0387         return -EINVAL;
0388     }
0389 
0390     ret = regmap_read(regmap, reg, &val);
0391     if (ret)
0392         return ret;
0393 
0394     if (id <= ACT8865_ID_DCDC3 && (val & BIT(5)))
0395         return REGULATOR_MODE_FAST;
0396     else if (id > ACT8865_ID_DCDC3 && !(val & BIT(5)))
0397         return REGULATOR_MODE_NORMAL;
0398     else
0399         return REGULATOR_MODE_STANDBY;
0400 }
0401 
0402 static const struct regulator_ops act8865_ops = {
0403     .list_voltage       = regulator_list_voltage_linear_range,
0404     .map_voltage        = regulator_map_voltage_linear_range,
0405     .get_voltage_sel    = regulator_get_voltage_sel_regmap,
0406     .set_voltage_sel    = regulator_set_voltage_sel_regmap,
0407     .enable         = regulator_enable_regmap,
0408     .disable        = regulator_disable_regmap,
0409     .set_mode       = act8865_set_mode,
0410     .get_mode       = act8865_get_mode,
0411     .is_enabled     = regulator_is_enabled_regmap,
0412     .set_suspend_enable = act8865_set_suspend_enable,
0413     .set_suspend_disable    = act8865_set_suspend_disable,
0414 };
0415 
0416 static const struct regulator_ops act8865_ldo_ops = {
0417     .list_voltage       = regulator_list_voltage_linear_range,
0418     .map_voltage        = regulator_map_voltage_linear_range,
0419     .get_voltage_sel    = regulator_get_voltage_sel_regmap,
0420     .set_voltage_sel    = regulator_set_voltage_sel_regmap,
0421     .enable         = regulator_enable_regmap,
0422     .disable        = regulator_disable_regmap,
0423     .set_mode       = act8865_set_mode,
0424     .get_mode       = act8865_get_mode,
0425     .is_enabled     = regulator_is_enabled_regmap,
0426     .set_suspend_enable = act8865_set_suspend_enable,
0427     .set_suspend_disable    = act8865_set_suspend_disable,
0428     .set_pull_down      = regulator_set_pull_down_regmap,
0429 };
0430 
0431 static const struct regulator_ops act8865_fixed_ldo_ops = {
0432     .enable         = regulator_enable_regmap,
0433     .disable        = regulator_disable_regmap,
0434     .is_enabled     = regulator_is_enabled_regmap,
0435 };
0436 
0437 #define ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, _ops) \
0438     [_family##_ID_##_id] = {                    \
0439         .name           = _name,            \
0440         .of_match       = of_match_ptr(_name),      \
0441         .of_map_mode        = act8865_of_map_mode,      \
0442         .regulators_node    = of_match_ptr("regulators"),   \
0443         .supply_name        = _supply,          \
0444         .id         = _family##_ID_##_id,       \
0445         .type           = REGULATOR_VOLTAGE,        \
0446         .ops            = _ops,             \
0447         .n_voltages     = ACT8865_VOLTAGE_NUM,      \
0448         .linear_ranges      = act8865_voltage_ranges,   \
0449         .n_linear_ranges    = ARRAY_SIZE(act8865_voltage_ranges), \
0450         .vsel_reg       = _family##_##_id##_##_vsel_reg, \
0451         .vsel_mask      = ACT8865_VSEL_MASK,        \
0452         .enable_reg     = _family##_##_id##_CTRL,   \
0453         .enable_mask        = ACT8865_ENA,          \
0454         .pull_down_reg      = _family##_##_id##_CTRL,   \
0455         .pull_down_mask     = ACT8865_DIS,          \
0456         .owner          = THIS_MODULE,          \
0457     }
0458 
0459 #define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply) \
0460     ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, &act8865_ops)
0461 
0462 #define ACT88xx_LDO(_name, _family, _id, _vsel_reg, _supply) \
0463     ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, &act8865_ldo_ops)
0464 
0465 static const struct regulator_desc act8600_regulators[] = {
0466     ACT88xx_REG("DCDC1", ACT8600, DCDC1, VSET, "vp1"),
0467     ACT88xx_REG("DCDC2", ACT8600, DCDC2, VSET, "vp2"),
0468     ACT88xx_REG("DCDC3", ACT8600, DCDC3, VSET, "vp3"),
0469     {
0470         .name = "SUDCDC_REG4",
0471         .of_match = of_match_ptr("SUDCDC_REG4"),
0472         .regulators_node = of_match_ptr("regulators"),
0473         .id = ACT8600_ID_SUDCDC4,
0474         .ops = &act8865_ops,
0475         .type = REGULATOR_VOLTAGE,
0476         .n_voltages = ACT8600_SUDCDC_VOLTAGE_NUM,
0477         .linear_ranges = act8600_sudcdc_voltage_ranges,
0478         .n_linear_ranges = ARRAY_SIZE(act8600_sudcdc_voltage_ranges),
0479         .vsel_reg = ACT8600_SUDCDC4_VSET,
0480         .vsel_mask = ACT8600_SUDCDC_VSEL_MASK,
0481         .enable_reg = ACT8600_SUDCDC4_CTRL,
0482         .enable_mask = ACT8865_ENA,
0483         .owner = THIS_MODULE,
0484     },
0485     ACT88xx_REG("LDO5", ACT8600, LDO5, VSET, "inl"),
0486     ACT88xx_REG("LDO6", ACT8600, LDO6, VSET, "inl"),
0487     ACT88xx_REG("LDO7", ACT8600, LDO7, VSET, "inl"),
0488     ACT88xx_REG("LDO8", ACT8600, LDO8, VSET, "inl"),
0489     {
0490         .name = "LDO_REG9",
0491         .of_match = of_match_ptr("LDO_REG9"),
0492         .regulators_node = of_match_ptr("regulators"),
0493         .id = ACT8600_ID_LDO9,
0494         .ops = &act8865_fixed_ldo_ops,
0495         .type = REGULATOR_VOLTAGE,
0496         .n_voltages = 1,
0497         .fixed_uV = 3300000,
0498         .enable_reg = ACT8600_LDO910_CTRL,
0499         .enable_mask = ACT8865_ENA,
0500         .owner = THIS_MODULE,
0501     },
0502     {
0503         .name = "LDO_REG10",
0504         .of_match = of_match_ptr("LDO_REG10"),
0505         .regulators_node = of_match_ptr("regulators"),
0506         .id = ACT8600_ID_LDO10,
0507         .ops = &act8865_fixed_ldo_ops,
0508         .type = REGULATOR_VOLTAGE,
0509         .n_voltages = 1,
0510         .fixed_uV = 1200000,
0511         .enable_reg = ACT8600_LDO910_CTRL,
0512         .enable_mask = ACT8600_LDO10_ENA,
0513         .owner = THIS_MODULE,
0514     },
0515 };
0516 
0517 static const struct regulator_desc act8846_regulators[] = {
0518     ACT88xx_REG("REG1", ACT8846, REG1, VSET, "vp1"),
0519     ACT88xx_REG("REG2", ACT8846, REG2, VSET0, "vp2"),
0520     ACT88xx_REG("REG3", ACT8846, REG3, VSET0, "vp3"),
0521     ACT88xx_REG("REG4", ACT8846, REG4, VSET0, "vp4"),
0522     ACT88xx_REG("REG5", ACT8846, REG5, VSET, "inl1"),
0523     ACT88xx_REG("REG6", ACT8846, REG6, VSET, "inl1"),
0524     ACT88xx_REG("REG7", ACT8846, REG7, VSET, "inl1"),
0525     ACT88xx_REG("REG8", ACT8846, REG8, VSET, "inl2"),
0526     ACT88xx_REG("REG9", ACT8846, REG9, VSET, "inl2"),
0527     ACT88xx_REG("REG10", ACT8846, REG10, VSET, "inl3"),
0528     ACT88xx_REG("REG11", ACT8846, REG11, VSET, "inl3"),
0529     ACT88xx_REG("REG12", ACT8846, REG12, VSET, "inl3"),
0530 };
0531 
0532 static const struct regulator_desc act8865_regulators[] = {
0533     ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1, "vp1"),
0534     ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1, "vp2"),
0535     ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1, "vp3"),
0536     ACT88xx_LDO("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
0537     ACT88xx_LDO("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
0538     ACT88xx_LDO("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
0539     ACT88xx_LDO("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
0540 };
0541 
0542 static const struct regulator_desc act8865_alt_regulators[] = {
0543     ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET2, "vp1"),
0544     ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET2, "vp2"),
0545     ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET2, "vp3"),
0546     ACT88xx_LDO("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
0547     ACT88xx_LDO("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
0548     ACT88xx_LDO("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
0549     ACT88xx_LDO("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
0550 };
0551 
0552 #ifdef CONFIG_OF
0553 static const struct of_device_id act8865_dt_ids[] = {
0554     { .compatible = "active-semi,act8600", .data = (void *)ACT8600 },
0555     { .compatible = "active-semi,act8846", .data = (void *)ACT8846 },
0556     { .compatible = "active-semi,act8865", .data = (void *)ACT8865 },
0557     { }
0558 };
0559 MODULE_DEVICE_TABLE(of, act8865_dt_ids);
0560 #endif
0561 
0562 static struct act8865_regulator_data *act8865_get_regulator_data(
0563         int id, struct act8865_platform_data *pdata)
0564 {
0565     int i;
0566 
0567     for (i = 0; i < pdata->num_regulators; i++) {
0568         if (pdata->regulators[i].id == id)
0569             return &pdata->regulators[i];
0570     }
0571 
0572     return NULL;
0573 }
0574 
0575 static struct i2c_client *act8865_i2c_client;
0576 static void act8865_power_off(void)
0577 {
0578     struct act8865 *act8865;
0579 
0580     act8865 = i2c_get_clientdata(act8865_i2c_client);
0581     regmap_write(act8865->regmap, act8865->off_reg, act8865->off_mask);
0582     while (1);
0583 }
0584 
0585 static int act8600_charger_get_status(struct regmap *map)
0586 {
0587     unsigned int val;
0588     int ret;
0589     u8 state0, state1;
0590 
0591     ret = regmap_read(map, ACT8600_APCH_STAT, &val);
0592     if (ret < 0)
0593         return ret;
0594 
0595     state0 = val & ACT8600_APCH_CSTATE0;
0596     state1 = val & ACT8600_APCH_CSTATE1;
0597 
0598     if (state0 && !state1)
0599         return POWER_SUPPLY_STATUS_CHARGING;
0600     if (!state0 && state1)
0601         return POWER_SUPPLY_STATUS_NOT_CHARGING;
0602     if (!state0 && !state1)
0603         return POWER_SUPPLY_STATUS_DISCHARGING;
0604 
0605     return POWER_SUPPLY_STATUS_UNKNOWN;
0606 }
0607 
0608 static int act8600_charger_get_property(struct power_supply *psy,
0609         enum power_supply_property psp, union power_supply_propval *val)
0610 {
0611     struct regmap *map = power_supply_get_drvdata(psy);
0612     int ret;
0613 
0614     switch (psp) {
0615     case POWER_SUPPLY_PROP_STATUS:
0616         ret = act8600_charger_get_status(map);
0617         if (ret < 0)
0618             return ret;
0619 
0620         val->intval = ret;
0621         break;
0622     default:
0623         return -EINVAL;
0624     }
0625 
0626     return 0;
0627 }
0628 
0629 static enum power_supply_property act8600_charger_properties[] = {
0630     POWER_SUPPLY_PROP_STATUS,
0631 };
0632 
0633 static const struct power_supply_desc act8600_charger_desc = {
0634     .name = "act8600-charger",
0635     .type = POWER_SUPPLY_TYPE_BATTERY,
0636     .properties = act8600_charger_properties,
0637     .num_properties = ARRAY_SIZE(act8600_charger_properties),
0638     .get_property = act8600_charger_get_property,
0639 };
0640 
0641 static int act8600_charger_probe(struct device *dev, struct regmap *regmap)
0642 {
0643     struct power_supply *charger;
0644     struct power_supply_config cfg = {
0645         .drv_data = regmap,
0646         .of_node = dev->of_node,
0647     };
0648 
0649     charger = devm_power_supply_register(dev, &act8600_charger_desc, &cfg);
0650 
0651     return PTR_ERR_OR_ZERO(charger);
0652 }
0653 
0654 static int act8865_pmic_probe(struct i2c_client *client,
0655                   const struct i2c_device_id *i2c_id)
0656 {
0657     const struct regulator_desc *regulators;
0658     struct act8865_platform_data *pdata = NULL;
0659     struct device *dev = &client->dev;
0660     int i, ret, num_regulators;
0661     struct act8865 *act8865;
0662     const struct regmap_config *regmap_config;
0663     unsigned long type;
0664     int off_reg, off_mask;
0665     int voltage_select = 0;
0666 
0667     if (dev->of_node) {
0668         const struct of_device_id *id;
0669 
0670         id = of_match_device(of_match_ptr(act8865_dt_ids), dev);
0671         if (!id)
0672             return -ENODEV;
0673 
0674         type = (unsigned long) id->data;
0675 
0676         voltage_select = !!of_get_property(dev->of_node,
0677                            "active-semi,vsel-high",
0678                            NULL);
0679     } else {
0680         type = i2c_id->driver_data;
0681         pdata = dev_get_platdata(dev);
0682     }
0683 
0684     switch (type) {
0685     case ACT8600:
0686         regulators = act8600_regulators;
0687         num_regulators = ARRAY_SIZE(act8600_regulators);
0688         regmap_config = &act8600_regmap_config;
0689         off_reg = -1;
0690         off_mask = -1;
0691         break;
0692     case ACT8846:
0693         regulators = act8846_regulators;
0694         num_regulators = ARRAY_SIZE(act8846_regulators);
0695         regmap_config = &act8865_regmap_config;
0696         off_reg = ACT8846_GLB_OFF_CTRL;
0697         off_mask = ACT8846_OFF_SYSMASK;
0698         break;
0699     case ACT8865:
0700         if (voltage_select) {
0701             regulators = act8865_alt_regulators;
0702             num_regulators = ARRAY_SIZE(act8865_alt_regulators);
0703         } else {
0704             regulators = act8865_regulators;
0705             num_regulators = ARRAY_SIZE(act8865_regulators);
0706         }
0707         regmap_config = &act8865_regmap_config;
0708         off_reg = ACT8865_SYS_CTRL;
0709         off_mask = ACT8865_MSTROFF;
0710         break;
0711     default:
0712         dev_err(dev, "invalid device id %lu\n", type);
0713         return -EINVAL;
0714     }
0715 
0716     act8865 = devm_kzalloc(dev, sizeof(struct act8865), GFP_KERNEL);
0717     if (!act8865)
0718         return -ENOMEM;
0719 
0720     act8865->regmap = devm_regmap_init_i2c(client, regmap_config);
0721     if (IS_ERR(act8865->regmap)) {
0722         ret = PTR_ERR(act8865->regmap);
0723         dev_err(dev, "Failed to allocate register map: %d\n", ret);
0724         return ret;
0725     }
0726 
0727     if (of_device_is_system_power_controller(dev->of_node)) {
0728         if (!pm_power_off && (off_reg > 0)) {
0729             act8865_i2c_client = client;
0730             act8865->off_reg = off_reg;
0731             act8865->off_mask = off_mask;
0732             pm_power_off = act8865_power_off;
0733         } else {
0734             dev_err(dev, "Failed to set poweroff capability, already defined\n");
0735         }
0736     }
0737 
0738     /* Finally register devices */
0739     for (i = 0; i < num_regulators; i++) {
0740         const struct regulator_desc *desc = &regulators[i];
0741         struct regulator_config config = { };
0742         struct regulator_dev *rdev;
0743 
0744         config.dev = dev;
0745         config.driver_data = act8865;
0746         config.regmap = act8865->regmap;
0747 
0748         if (pdata) {
0749             struct act8865_regulator_data *rdata;
0750 
0751             rdata = act8865_get_regulator_data(desc->id, pdata);
0752             if (rdata) {
0753                 config.init_data = rdata->init_data;
0754                 config.of_node = rdata->of_node;
0755             }
0756         }
0757 
0758         rdev = devm_regulator_register(dev, desc, &config);
0759         if (IS_ERR(rdev)) {
0760             dev_err(dev, "failed to register %s\n", desc->name);
0761             return PTR_ERR(rdev);
0762         }
0763     }
0764 
0765     if (type == ACT8600) {
0766         ret = act8600_charger_probe(dev, act8865->regmap);
0767         if (ret < 0) {
0768             if (ret != -EPROBE_DEFER)
0769                 dev_err(dev, "Failed to probe charger");
0770             return ret;
0771         }
0772     }
0773 
0774     i2c_set_clientdata(client, act8865);
0775 
0776     /* Unlock expert registers for ACT8865. */
0777     return type != ACT8865 ? 0 : regmap_write(act8865->regmap,
0778                           ACT8865_SYS_UNLK_REGS, 0xef);
0779 }
0780 
0781 static const struct i2c_device_id act8865_ids[] = {
0782     { .name = "act8600", .driver_data = ACT8600 },
0783     { .name = "act8846", .driver_data = ACT8846 },
0784     { .name = "act8865", .driver_data = ACT8865 },
0785     { },
0786 };
0787 MODULE_DEVICE_TABLE(i2c, act8865_ids);
0788 
0789 static struct i2c_driver act8865_pmic_driver = {
0790     .driver = {
0791         .name   = "act8865",
0792     },
0793     .probe      = act8865_pmic_probe,
0794     .id_table   = act8865_ids,
0795 };
0796 
0797 module_i2c_driver(act8865_pmic_driver);
0798 
0799 MODULE_DESCRIPTION("active-semi act88xx voltage regulator driver");
0800 MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
0801 MODULE_LICENSE("GPL v2");