Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ADP5061 I2C Programmable Linear Battery Charger
0004  *
0005  * Copyright 2018 Analog Devices Inc.
0006  */
0007 
0008 #include <linux/init.h>
0009 #include <linux/module.h>
0010 #include <linux/slab.h>
0011 #include <linux/i2c.h>
0012 #include <linux/delay.h>
0013 #include <linux/pm.h>
0014 #include <linux/mod_devicetable.h>
0015 #include <linux/power_supply.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/of.h>
0018 #include <linux/regmap.h>
0019 
0020 /* ADP5061 registers definition */
0021 #define ADP5061_ID          0x00
0022 #define ADP5061_REV         0x01
0023 #define ADP5061_VINX_SET        0x02
0024 #define ADP5061_TERM_SET        0x03
0025 #define ADP5061_CHG_CURR        0x04
0026 #define ADP5061_VOLTAGE_TH      0x05
0027 #define ADP5061_TIMER_SET       0x06
0028 #define ADP5061_FUNC_SET_1      0x07
0029 #define ADP5061_FUNC_SET_2      0x08
0030 #define ADP5061_INT_EN          0x09
0031 #define ADP5061_INT_ACT         0x0A
0032 #define ADP5061_CHG_STATUS_1        0x0B
0033 #define ADP5061_CHG_STATUS_2        0x0C
0034 #define ADP5061_FAULT           0x0D
0035 #define ADP5061_BATTERY_SHORT       0x10
0036 #define ADP5061_IEND            0x11
0037 
0038 /* ADP5061_VINX_SET */
0039 #define ADP5061_VINX_SET_ILIM_MSK       GENMASK(3, 0)
0040 #define ADP5061_VINX_SET_ILIM_MODE(x)       (((x) & 0x0F) << 0)
0041 
0042 /* ADP5061_TERM_SET */
0043 #define ADP5061_TERM_SET_VTRM_MSK       GENMASK(7, 2)
0044 #define ADP5061_TERM_SET_VTRM_MODE(x)       (((x) & 0x3F) << 2)
0045 #define ADP5061_TERM_SET_CHG_VLIM_MSK       GENMASK(1, 0)
0046 #define ADP5061_TERM_SET_CHG_VLIM_MODE(x)   (((x) & 0x03) << 0)
0047 
0048 /* ADP5061_CHG_CURR */
0049 #define ADP5061_CHG_CURR_ICHG_MSK       GENMASK(6, 2)
0050 #define ADP5061_CHG_CURR_ICHG_MODE(x)       (((x) & 0x1F) << 2)
0051 #define ADP5061_CHG_CURR_ITRK_DEAD_MSK      GENMASK(1, 0)
0052 #define ADP5061_CHG_CURR_ITRK_DEAD_MODE(x)  (((x) & 0x03) << 0)
0053 
0054 /* ADP5061_VOLTAGE_TH */
0055 #define ADP5061_VOLTAGE_TH_DIS_RCH_MSK      BIT(7)
0056 #define ADP5061_VOLTAGE_TH_DIS_RCH_MODE(x)  (((x) & 0x01) << 7)
0057 #define ADP5061_VOLTAGE_TH_VRCH_MSK     GENMASK(6, 5)
0058 #define ADP5061_VOLTAGE_TH_VRCH_MODE(x)     (((x) & 0x03) << 5)
0059 #define ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK    GENMASK(4, 3)
0060 #define ADP5061_VOLTAGE_TH_VTRK_DEAD_MODE(x)    (((x) & 0x03) << 3)
0061 #define ADP5061_VOLTAGE_TH_VWEAK_MSK        GENMASK(2, 0)
0062 #define ADP5061_VOLTAGE_TH_VWEAK_MODE(x)    (((x) & 0x07) << 0)
0063 
0064 /* ADP5061_CHG_STATUS_1 */
0065 #define ADP5061_CHG_STATUS_1_VIN_OV(x)      (((x) >> 7) & 0x1)
0066 #define ADP5061_CHG_STATUS_1_VIN_OK(x)      (((x) >> 6) & 0x1)
0067 #define ADP5061_CHG_STATUS_1_VIN_ILIM(x)    (((x) >> 5) & 0x1)
0068 #define ADP5061_CHG_STATUS_1_THERM_LIM(x)   (((x) >> 4) & 0x1)
0069 #define ADP5061_CHG_STATUS_1_CHDONE(x)      (((x) >> 3) & 0x1)
0070 #define ADP5061_CHG_STATUS_1_CHG_STATUS(x)  (((x) >> 0) & 0x7)
0071 
0072 /* ADP5061_CHG_STATUS_2 */
0073 #define ADP5061_CHG_STATUS_2_THR_STATUS(x)  (((x) >> 5) & 0x7)
0074 #define ADP5061_CHG_STATUS_2_RCH_LIM_INFO(x)    (((x) >> 3) & 0x1)
0075 #define ADP5061_CHG_STATUS_2_BAT_STATUS(x)  (((x) >> 0) & 0x7)
0076 
0077 /* ADP5061_IEND */
0078 #define ADP5061_IEND_IEND_MSK           GENMASK(7, 5)
0079 #define ADP5061_IEND_IEND_MODE(x)       (((x) & 0x07) << 5)
0080 
0081 #define ADP5061_NO_BATTERY  0x01
0082 #define ADP5061_ICHG_MAX    1300 // mA
0083 
0084 enum adp5061_chg_status {
0085     ADP5061_CHG_OFF,
0086     ADP5061_CHG_TRICKLE,
0087     ADP5061_CHG_FAST_CC,
0088     ADP5061_CHG_FAST_CV,
0089     ADP5061_CHG_COMPLETE,
0090     ADP5061_CHG_LDO_MODE,
0091     ADP5061_CHG_TIMER_EXP,
0092     ADP5061_CHG_BAT_DET,
0093 };
0094 
0095 static const int adp5061_chg_type[4] = {
0096     [ADP5061_CHG_OFF] = POWER_SUPPLY_CHARGE_TYPE_NONE,
0097     [ADP5061_CHG_TRICKLE] = POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
0098     [ADP5061_CHG_FAST_CC] = POWER_SUPPLY_CHARGE_TYPE_FAST,
0099     [ADP5061_CHG_FAST_CV] = POWER_SUPPLY_CHARGE_TYPE_FAST,
0100 };
0101 
0102 static const int adp5061_vweak_th[8] = {
0103     2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400,
0104 };
0105 
0106 static const int adp5061_prechg_current[4] = {
0107     5, 10, 20, 80,
0108 };
0109 
0110 static const int adp5061_vmin[4] = {
0111     2000, 2500, 2600, 2900,
0112 };
0113 
0114 static const int adp5061_const_chg_vmax[4] = {
0115     3200, 3400, 3700, 3800,
0116 };
0117 
0118 static const int adp5061_const_ichg[24] = {
0119     50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650,
0120     700, 750, 800, 850, 900, 950, 1000, 1050, 1100, 1200, 1300,
0121 };
0122 
0123 static const int adp5061_vmax[36] = {
0124     3800, 3820, 3840, 3860, 3880, 3900, 3920, 3940, 3960, 3980,
0125     4000, 4020, 4040, 4060, 4080, 4100, 4120, 4140, 4160, 4180,
0126     4200, 4220, 4240, 4260, 4280, 4300, 4320, 4340, 4360, 4380,
0127     4400, 4420, 4440, 4460, 4480, 4500,
0128 };
0129 
0130 static const int adp5061_in_current_lim[16] = {
0131     100, 150, 200, 250, 300, 400, 500, 600, 700,
0132     800, 900, 1000, 1200, 1500, 1800, 2100,
0133 };
0134 
0135 static const int adp5061_iend[8] = {
0136     12500, 32500, 52500, 72500, 92500, 117500, 142500, 170000,
0137 };
0138 
0139 struct adp5061_state {
0140     struct i2c_client       *client;
0141     struct regmap           *regmap;
0142     struct power_supply     *psy;
0143 };
0144 
0145 static int adp5061_get_array_index(const int *array, u8 size, int val)
0146 {
0147     int i;
0148 
0149     for (i = 1; i < size; i++) {
0150         if (val < array[i])
0151             break;
0152     }
0153 
0154     return i-1;
0155 }
0156 
0157 static int adp5061_get_status(struct adp5061_state *st,
0158                   u8 *status1, u8 *status2)
0159 {
0160     u8 buf[2];
0161     int ret;
0162 
0163     /* CHG_STATUS1 and CHG_STATUS2 are adjacent regs */
0164     ret = regmap_bulk_read(st->regmap, ADP5061_CHG_STATUS_1,
0165                    &buf[0], 2);
0166     if (ret < 0)
0167         return ret;
0168 
0169     *status1 = buf[0];
0170     *status2 = buf[1];
0171 
0172     return ret;
0173 }
0174 
0175 static int adp5061_get_input_current_limit(struct adp5061_state *st,
0176         union power_supply_propval *val)
0177 {
0178     unsigned int regval;
0179     int mode, ret;
0180 
0181     ret = regmap_read(st->regmap, ADP5061_VINX_SET, &regval);
0182     if (ret < 0)
0183         return ret;
0184 
0185     mode = ADP5061_VINX_SET_ILIM_MODE(regval);
0186     val->intval = adp5061_in_current_lim[mode] * 1000;
0187 
0188     return ret;
0189 }
0190 
0191 static int adp5061_set_input_current_limit(struct adp5061_state *st, int val)
0192 {
0193     int index;
0194 
0195     /* Convert from uA to mA */
0196     val /= 1000;
0197     index = adp5061_get_array_index(adp5061_in_current_lim,
0198                     ARRAY_SIZE(adp5061_in_current_lim),
0199                     val);
0200     if (index < 0)
0201         return index;
0202 
0203     return regmap_update_bits(st->regmap, ADP5061_VINX_SET,
0204                   ADP5061_VINX_SET_ILIM_MSK,
0205                   ADP5061_VINX_SET_ILIM_MODE(index));
0206 }
0207 
0208 static int adp5061_set_min_voltage(struct adp5061_state *st, int val)
0209 {
0210     int index;
0211 
0212     /* Convert from uV to mV */
0213     val /= 1000;
0214     index = adp5061_get_array_index(adp5061_vmin,
0215                     ARRAY_SIZE(adp5061_vmin),
0216                     val);
0217     if (index < 0)
0218         return index;
0219 
0220     return regmap_update_bits(st->regmap, ADP5061_VOLTAGE_TH,
0221                   ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK,
0222                   ADP5061_VOLTAGE_TH_VTRK_DEAD_MODE(index));
0223 }
0224 
0225 static int adp5061_get_min_voltage(struct adp5061_state *st,
0226                    union power_supply_propval *val)
0227 {
0228     unsigned int regval;
0229     int ret;
0230 
0231     ret = regmap_read(st->regmap, ADP5061_VOLTAGE_TH, &regval);
0232     if (ret < 0)
0233         return ret;
0234 
0235     regval = ((regval & ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK) >> 3);
0236     val->intval = adp5061_vmin[regval] * 1000;
0237 
0238     return ret;
0239 }
0240 
0241 static int adp5061_get_chg_volt_lim(struct adp5061_state *st,
0242                     union power_supply_propval *val)
0243 {
0244     unsigned int regval;
0245     int mode, ret;
0246 
0247     ret = regmap_read(st->regmap, ADP5061_TERM_SET, &regval);
0248     if (ret < 0)
0249         return ret;
0250 
0251     mode = ADP5061_TERM_SET_CHG_VLIM_MODE(regval);
0252     val->intval = adp5061_const_chg_vmax[mode] * 1000;
0253 
0254     return ret;
0255 }
0256 
0257 static int adp5061_get_max_voltage(struct adp5061_state *st,
0258                    union power_supply_propval *val)
0259 {
0260     unsigned int regval;
0261     int ret;
0262 
0263     ret = regmap_read(st->regmap, ADP5061_TERM_SET, &regval);
0264     if (ret < 0)
0265         return ret;
0266 
0267     regval = ((regval & ADP5061_TERM_SET_VTRM_MSK) >> 2) - 0x0F;
0268     if (regval >= ARRAY_SIZE(adp5061_vmax))
0269         regval = ARRAY_SIZE(adp5061_vmax) - 1;
0270 
0271     val->intval = adp5061_vmax[regval] * 1000;
0272 
0273     return ret;
0274 }
0275 
0276 static int adp5061_set_max_voltage(struct adp5061_state *st, int val)
0277 {
0278     int vmax_index;
0279 
0280     /* Convert from uV to mV */
0281     val /= 1000;
0282     if (val > 4500)
0283         val = 4500;
0284 
0285     vmax_index = adp5061_get_array_index(adp5061_vmax,
0286                          ARRAY_SIZE(adp5061_vmax), val);
0287     if (vmax_index < 0)
0288         return vmax_index;
0289 
0290     vmax_index += 0x0F;
0291 
0292     return regmap_update_bits(st->regmap, ADP5061_TERM_SET,
0293                   ADP5061_TERM_SET_VTRM_MSK,
0294                   ADP5061_TERM_SET_VTRM_MODE(vmax_index));
0295 }
0296 
0297 static int adp5061_set_const_chg_vmax(struct adp5061_state *st, int val)
0298 {
0299     int index;
0300 
0301     /* Convert from uV to mV */
0302     val /= 1000;
0303     index = adp5061_get_array_index(adp5061_const_chg_vmax,
0304                     ARRAY_SIZE(adp5061_const_chg_vmax),
0305                     val);
0306     if (index < 0)
0307         return index;
0308 
0309     return regmap_update_bits(st->regmap, ADP5061_TERM_SET,
0310                   ADP5061_TERM_SET_CHG_VLIM_MSK,
0311                   ADP5061_TERM_SET_CHG_VLIM_MODE(index));
0312 }
0313 
0314 static int adp5061_set_const_chg_current(struct adp5061_state *st, int val)
0315 {
0316 
0317     int index;
0318 
0319     /* Convert from uA to mA */
0320     val /= 1000;
0321     if (val > ADP5061_ICHG_MAX)
0322         val = ADP5061_ICHG_MAX;
0323 
0324     index = adp5061_get_array_index(adp5061_const_ichg,
0325                     ARRAY_SIZE(adp5061_const_ichg),
0326                     val);
0327     if (index < 0)
0328         return index;
0329 
0330     return regmap_update_bits(st->regmap, ADP5061_CHG_CURR,
0331                   ADP5061_CHG_CURR_ICHG_MSK,
0332                   ADP5061_CHG_CURR_ICHG_MODE(index));
0333 }
0334 
0335 static int adp5061_get_const_chg_current(struct adp5061_state *st,
0336         union power_supply_propval *val)
0337 {
0338     unsigned int regval;
0339     int ret;
0340 
0341     ret = regmap_read(st->regmap, ADP5061_CHG_CURR, &regval);
0342     if (ret < 0)
0343         return ret;
0344 
0345     regval = ((regval & ADP5061_CHG_CURR_ICHG_MSK) >> 2);
0346     if (regval >= ARRAY_SIZE(adp5061_const_ichg))
0347         regval = ARRAY_SIZE(adp5061_const_ichg) - 1;
0348 
0349     val->intval = adp5061_const_ichg[regval] * 1000;
0350 
0351     return ret;
0352 }
0353 
0354 static int adp5061_get_prechg_current(struct adp5061_state *st,
0355                       union power_supply_propval *val)
0356 {
0357     unsigned int regval;
0358     int ret;
0359 
0360     ret = regmap_read(st->regmap, ADP5061_CHG_CURR, &regval);
0361     if (ret < 0)
0362         return ret;
0363 
0364     regval &= ADP5061_CHG_CURR_ITRK_DEAD_MSK;
0365     val->intval = adp5061_prechg_current[regval] * 1000;
0366 
0367     return ret;
0368 }
0369 
0370 static int adp5061_set_prechg_current(struct adp5061_state *st, int val)
0371 {
0372     int index;
0373 
0374     /* Convert from uA to mA */
0375     val /= 1000;
0376     index = adp5061_get_array_index(adp5061_prechg_current,
0377                     ARRAY_SIZE(adp5061_prechg_current),
0378                     val);
0379     if (index < 0)
0380         return index;
0381 
0382     return regmap_update_bits(st->regmap, ADP5061_CHG_CURR,
0383                   ADP5061_CHG_CURR_ITRK_DEAD_MSK,
0384                   ADP5061_CHG_CURR_ITRK_DEAD_MODE(index));
0385 }
0386 
0387 static int adp5061_get_vweak_th(struct adp5061_state *st,
0388                 union power_supply_propval *val)
0389 {
0390     unsigned int regval;
0391     int ret;
0392 
0393     ret = regmap_read(st->regmap, ADP5061_VOLTAGE_TH, &regval);
0394     if (ret < 0)
0395         return ret;
0396 
0397     regval &= ADP5061_VOLTAGE_TH_VWEAK_MSK;
0398     val->intval = adp5061_vweak_th[regval] * 1000;
0399 
0400     return ret;
0401 }
0402 
0403 static int adp5061_set_vweak_th(struct adp5061_state *st, int val)
0404 {
0405     int index;
0406 
0407     /* Convert from uV to mV */
0408     val /= 1000;
0409     index = adp5061_get_array_index(adp5061_vweak_th,
0410                     ARRAY_SIZE(adp5061_vweak_th),
0411                     val);
0412     if (index < 0)
0413         return index;
0414 
0415     return regmap_update_bits(st->regmap, ADP5061_VOLTAGE_TH,
0416                   ADP5061_VOLTAGE_TH_VWEAK_MSK,
0417                   ADP5061_VOLTAGE_TH_VWEAK_MODE(index));
0418 }
0419 
0420 static int adp5061_get_chg_type(struct adp5061_state *st,
0421                 union power_supply_propval *val)
0422 {
0423     u8 status1, status2;
0424     int chg_type, ret;
0425 
0426     ret = adp5061_get_status(st, &status1, &status2);
0427     if (ret < 0)
0428         return ret;
0429 
0430     chg_type = adp5061_chg_type[ADP5061_CHG_STATUS_1_CHG_STATUS(status1)];
0431     if (chg_type > ADP5061_CHG_FAST_CV)
0432         val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
0433     else
0434         val->intval = chg_type;
0435 
0436     return ret;
0437 }
0438 
0439 static int adp5061_get_charger_status(struct adp5061_state *st,
0440                       union power_supply_propval *val)
0441 {
0442     u8 status1, status2;
0443     int ret;
0444 
0445     ret = adp5061_get_status(st, &status1, &status2);
0446     if (ret < 0)
0447         return ret;
0448 
0449     switch (ADP5061_CHG_STATUS_1_CHG_STATUS(status1)) {
0450     case ADP5061_CHG_OFF:
0451         val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
0452         break;
0453     case ADP5061_CHG_TRICKLE:
0454     case ADP5061_CHG_FAST_CC:
0455     case ADP5061_CHG_FAST_CV:
0456         val->intval = POWER_SUPPLY_STATUS_CHARGING;
0457         break;
0458     case ADP5061_CHG_COMPLETE:
0459         val->intval = POWER_SUPPLY_STATUS_FULL;
0460         break;
0461     case ADP5061_CHG_TIMER_EXP:
0462         /* The battery must be discharging if there is a charge fault */
0463         val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
0464         break;
0465     default:
0466         val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
0467     }
0468 
0469     return ret;
0470 }
0471 
0472 static int adp5061_get_battery_status(struct adp5061_state *st,
0473                       union power_supply_propval *val)
0474 {
0475     u8 status1, status2;
0476     int ret;
0477 
0478     ret = adp5061_get_status(st, &status1, &status2);
0479     if (ret < 0)
0480         return ret;
0481 
0482     switch (ADP5061_CHG_STATUS_2_BAT_STATUS(status2)) {
0483     case 0x0: /* Battery monitor off */
0484     case 0x1: /* No battery */
0485         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
0486         break;
0487     case 0x2: /* VBAT < VTRK */
0488         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
0489         break;
0490     case 0x3: /* VTRK < VBAT_SNS < VWEAK */
0491         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
0492         break;
0493     case 0x4: /* VBAT_SNS > VWEAK */
0494         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
0495         break;
0496     }
0497 
0498     return ret;
0499 }
0500 
0501 static int adp5061_get_termination_current(struct adp5061_state *st,
0502                        union power_supply_propval *val)
0503 {
0504     unsigned int regval;
0505     int ret;
0506 
0507     ret = regmap_read(st->regmap, ADP5061_IEND, &regval);
0508     if (ret < 0)
0509         return ret;
0510 
0511     regval = (regval & ADP5061_IEND_IEND_MSK) >> 5;
0512     val->intval = adp5061_iend[regval];
0513 
0514     return ret;
0515 }
0516 
0517 static int adp5061_set_termination_current(struct adp5061_state *st, int val)
0518 {
0519     int index;
0520 
0521     index = adp5061_get_array_index(adp5061_iend,
0522                     ARRAY_SIZE(adp5061_iend),
0523                     val);
0524     if (index < 0)
0525         return index;
0526 
0527     return regmap_update_bits(st->regmap, ADP5061_IEND,
0528                   ADP5061_IEND_IEND_MSK,
0529                   ADP5061_IEND_IEND_MODE(index));
0530 }
0531 
0532 static int adp5061_get_property(struct power_supply *psy,
0533                 enum power_supply_property psp,
0534                 union power_supply_propval *val)
0535 {
0536     struct adp5061_state *st = power_supply_get_drvdata(psy);
0537     u8 status1, status2;
0538     int mode, ret;
0539 
0540     switch (psp) {
0541     case POWER_SUPPLY_PROP_PRESENT:
0542         ret = adp5061_get_status(st, &status1, &status2);
0543         if (ret < 0)
0544             return ret;
0545 
0546         mode = ADP5061_CHG_STATUS_2_BAT_STATUS(status2);
0547         if (mode == ADP5061_NO_BATTERY)
0548             val->intval = 0;
0549         else
0550             val->intval = 1;
0551         break;
0552     case POWER_SUPPLY_PROP_CHARGE_TYPE:
0553         return adp5061_get_chg_type(st, val);
0554     case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
0555         /* This property is used to indicate the input current
0556          * limit into VINx (ILIM)
0557          */
0558         return adp5061_get_input_current_limit(st, val);
0559     case POWER_SUPPLY_PROP_VOLTAGE_MAX:
0560         /* This property is used to indicate the termination
0561          * voltage (VTRM)
0562          */
0563         return adp5061_get_max_voltage(st, val);
0564     case POWER_SUPPLY_PROP_VOLTAGE_MIN:
0565         /*
0566          * This property is used to indicate the trickle to fast
0567          * charge threshold (VTRK_DEAD)
0568          */
0569         return adp5061_get_min_voltage(st, val);
0570     case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
0571         /* This property is used to indicate the charging
0572          * voltage limit (CHG_VLIM)
0573          */
0574         return adp5061_get_chg_volt_lim(st, val);
0575     case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
0576         /*
0577          * This property is used to indicate the value of the constant
0578          * current charge (ICHG)
0579          */
0580         return adp5061_get_const_chg_current(st, val);
0581     case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
0582         /*
0583          * This property is used to indicate the value of the trickle
0584          * and weak charge currents (ITRK_DEAD)
0585          */
0586         return adp5061_get_prechg_current(st, val);
0587     case POWER_SUPPLY_PROP_VOLTAGE_AVG:
0588         /*
0589          * This property is used to set the VWEAK threshold
0590          * bellow this value, weak charge mode is entered
0591          * above this value, fast chargerge mode is entered
0592          */
0593         return adp5061_get_vweak_th(st, val);
0594     case POWER_SUPPLY_PROP_STATUS:
0595         /*
0596          * Indicate the charger status in relation to power
0597          * supply status property
0598          */
0599         return adp5061_get_charger_status(st, val);
0600     case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
0601         /*
0602          * Indicate the battery status in relation to power
0603          * supply capacity level property
0604          */
0605         return adp5061_get_battery_status(st, val);
0606     case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
0607         /* Indicate the values of the termination current */
0608         return adp5061_get_termination_current(st, val);
0609     default:
0610         return -EINVAL;
0611     }
0612 
0613     return 0;
0614 }
0615 
0616 static int adp5061_set_property(struct power_supply *psy,
0617                 enum power_supply_property psp,
0618                 const union power_supply_propval *val)
0619 {
0620     struct adp5061_state *st = power_supply_get_drvdata(psy);
0621 
0622     switch (psp) {
0623     case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
0624         return adp5061_set_input_current_limit(st, val->intval);
0625     case POWER_SUPPLY_PROP_VOLTAGE_MAX:
0626         return adp5061_set_max_voltage(st, val->intval);
0627     case POWER_SUPPLY_PROP_VOLTAGE_MIN:
0628         return adp5061_set_min_voltage(st, val->intval);
0629     case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
0630         return adp5061_set_const_chg_vmax(st, val->intval);
0631     case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
0632         return adp5061_set_const_chg_current(st, val->intval);
0633     case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
0634         return adp5061_set_prechg_current(st, val->intval);
0635     case POWER_SUPPLY_PROP_VOLTAGE_AVG:
0636         return adp5061_set_vweak_th(st, val->intval);
0637     case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
0638         return adp5061_set_termination_current(st, val->intval);
0639     default:
0640         return -EINVAL;
0641     }
0642 
0643     return 0;
0644 }
0645 
0646 static int adp5061_prop_writeable(struct power_supply *psy,
0647                   enum power_supply_property psp)
0648 {
0649     switch (psp) {
0650     case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
0651     case POWER_SUPPLY_PROP_VOLTAGE_MAX:
0652     case POWER_SUPPLY_PROP_VOLTAGE_MIN:
0653     case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
0654     case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
0655     case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
0656     case POWER_SUPPLY_PROP_VOLTAGE_AVG:
0657     case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
0658         return 1;
0659     default:
0660         return 0;
0661     }
0662 }
0663 
0664 static enum power_supply_property adp5061_props[] = {
0665     POWER_SUPPLY_PROP_PRESENT,
0666     POWER_SUPPLY_PROP_CHARGE_TYPE,
0667     POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
0668     POWER_SUPPLY_PROP_VOLTAGE_MAX,
0669     POWER_SUPPLY_PROP_VOLTAGE_MIN,
0670     POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
0671     POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
0672     POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
0673     POWER_SUPPLY_PROP_VOLTAGE_AVG,
0674     POWER_SUPPLY_PROP_STATUS,
0675     POWER_SUPPLY_PROP_CAPACITY_LEVEL,
0676     POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
0677 };
0678 
0679 static const struct regmap_config adp5061_regmap_config = {
0680     .reg_bits = 8,
0681     .val_bits = 8,
0682 };
0683 
0684 static const struct power_supply_desc adp5061_desc = {
0685     .name           = "adp5061",
0686     .type           = POWER_SUPPLY_TYPE_USB,
0687     .get_property       = adp5061_get_property,
0688     .set_property       = adp5061_set_property,
0689     .property_is_writeable  = adp5061_prop_writeable,
0690     .properties     = adp5061_props,
0691     .num_properties     = ARRAY_SIZE(adp5061_props),
0692 };
0693 
0694 static int adp5061_probe(struct i2c_client *client,
0695              const struct i2c_device_id *id)
0696 {
0697     struct power_supply_config psy_cfg = {};
0698     struct adp5061_state *st;
0699 
0700     st = devm_kzalloc(&client->dev, sizeof(*st), GFP_KERNEL);
0701     if (!st)
0702         return -ENOMEM;
0703 
0704     st->client = client;
0705     st->regmap = devm_regmap_init_i2c(client,
0706                       &adp5061_regmap_config);
0707     if (IS_ERR(st->regmap)) {
0708         dev_err(&client->dev, "Failed to initialize register map\n");
0709         return -EINVAL;
0710     }
0711 
0712     i2c_set_clientdata(client, st);
0713     psy_cfg.drv_data = st;
0714 
0715     st->psy = devm_power_supply_register(&client->dev,
0716                          &adp5061_desc,
0717                          &psy_cfg);
0718 
0719     if (IS_ERR(st->psy)) {
0720         dev_err(&client->dev, "Failed to register power supply\n");
0721         return PTR_ERR(st->psy);
0722     }
0723 
0724     return 0;
0725 }
0726 
0727 static const struct i2c_device_id adp5061_id[] = {
0728     { "adp5061", 0},
0729     { }
0730 };
0731 MODULE_DEVICE_TABLE(i2c, adp5061_id);
0732 
0733 static struct i2c_driver adp5061_driver = {
0734     .driver = {
0735         .name = KBUILD_MODNAME,
0736     },
0737     .probe = adp5061_probe,
0738     .id_table = adp5061_id,
0739 };
0740 module_i2c_driver(adp5061_driver);
0741 
0742 MODULE_DESCRIPTION("Analog Devices adp5061 battery charger driver");
0743 MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
0744 MODULE_LICENSE("GPL v2");