root/drivers/power/supply/adp5061.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. adp5061_get_array_index
  2. adp5061_get_status
  3. adp5061_get_input_current_limit
  4. adp5061_set_input_current_limit
  5. adp5061_set_min_voltage
  6. adp5061_get_min_voltage
  7. adp5061_get_chg_volt_lim
  8. adp5061_get_max_voltage
  9. adp5061_set_max_voltage
  10. adp5061_set_const_chg_vmax
  11. adp5061_set_const_chg_current
  12. adp5061_get_const_chg_current
  13. adp5061_get_prechg_current
  14. adp5061_set_prechg_current
  15. adp5061_get_vweak_th
  16. adp5061_set_vweak_th
  17. adp5061_get_chg_type
  18. adp5061_get_charger_status
  19. adp5061_get_battery_status
  20. adp5061_get_termination_current
  21. adp5061_set_termination_current
  22. adp5061_get_property
  23. adp5061_set_property
  24. adp5061_prop_writeable
  25. adp5061_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * ADP5061 I2C Programmable Linear Battery Charger
   4  *
   5  * Copyright 2018 Analog Devices Inc.
   6  */
   7 
   8 #include <linux/init.h>
   9 #include <linux/module.h>
  10 #include <linux/slab.h>
  11 #include <linux/i2c.h>
  12 #include <linux/delay.h>
  13 #include <linux/pm.h>
  14 #include <linux/mod_devicetable.h>
  15 #include <linux/power_supply.h>
  16 #include <linux/platform_device.h>
  17 #include <linux/of.h>
  18 #include <linux/regmap.h>
  19 
  20 /* ADP5061 registers definition */
  21 #define ADP5061_ID                      0x00
  22 #define ADP5061_REV                     0x01
  23 #define ADP5061_VINX_SET                0x02
  24 #define ADP5061_TERM_SET                0x03
  25 #define ADP5061_CHG_CURR                0x04
  26 #define ADP5061_VOLTAGE_TH              0x05
  27 #define ADP5061_TIMER_SET               0x06
  28 #define ADP5061_FUNC_SET_1              0x07
  29 #define ADP5061_FUNC_SET_2              0x08
  30 #define ADP5061_INT_EN                  0x09
  31 #define ADP5061_INT_ACT                 0x0A
  32 #define ADP5061_CHG_STATUS_1            0x0B
  33 #define ADP5061_CHG_STATUS_2            0x0C
  34 #define ADP5061_FAULT                   0x0D
  35 #define ADP5061_BATTERY_SHORT           0x10
  36 #define ADP5061_IEND                    0x11
  37 
  38 /* ADP5061_VINX_SET */
  39 #define ADP5061_VINX_SET_ILIM_MSK               GENMASK(3, 0)
  40 #define ADP5061_VINX_SET_ILIM_MODE(x)           (((x) & 0x0F) << 0)
  41 
  42 /* ADP5061_TERM_SET */
  43 #define ADP5061_TERM_SET_VTRM_MSK               GENMASK(7, 2)
  44 #define ADP5061_TERM_SET_VTRM_MODE(x)           (((x) & 0x3F) << 2)
  45 #define ADP5061_TERM_SET_CHG_VLIM_MSK           GENMASK(1, 0)
  46 #define ADP5061_TERM_SET_CHG_VLIM_MODE(x)       (((x) & 0x03) << 0)
  47 
  48 /* ADP5061_CHG_CURR */
  49 #define ADP5061_CHG_CURR_ICHG_MSK               GENMASK(6, 2)
  50 #define ADP5061_CHG_CURR_ICHG_MODE(x)           (((x) & 0x1F) << 2)
  51 #define ADP5061_CHG_CURR_ITRK_DEAD_MSK          GENMASK(1, 0)
  52 #define ADP5061_CHG_CURR_ITRK_DEAD_MODE(x)      (((x) & 0x03) << 0)
  53 
  54 /* ADP5061_VOLTAGE_TH */
  55 #define ADP5061_VOLTAGE_TH_DIS_RCH_MSK          BIT(7)
  56 #define ADP5061_VOLTAGE_TH_DIS_RCH_MODE(x)      (((x) & 0x01) << 7)
  57 #define ADP5061_VOLTAGE_TH_VRCH_MSK             GENMASK(6, 5)
  58 #define ADP5061_VOLTAGE_TH_VRCH_MODE(x)         (((x) & 0x03) << 5)
  59 #define ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK        GENMASK(4, 3)
  60 #define ADP5061_VOLTAGE_TH_VTRK_DEAD_MODE(x)    (((x) & 0x03) << 3)
  61 #define ADP5061_VOLTAGE_TH_VWEAK_MSK            GENMASK(2, 0)
  62 #define ADP5061_VOLTAGE_TH_VWEAK_MODE(x)        (((x) & 0x07) << 0)
  63 
  64 /* ADP5061_CHG_STATUS_1 */
  65 #define ADP5061_CHG_STATUS_1_VIN_OV(x)          (((x) >> 7) & 0x1)
  66 #define ADP5061_CHG_STATUS_1_VIN_OK(x)          (((x) >> 6) & 0x1)
  67 #define ADP5061_CHG_STATUS_1_VIN_ILIM(x)        (((x) >> 5) & 0x1)
  68 #define ADP5061_CHG_STATUS_1_THERM_LIM(x)       (((x) >> 4) & 0x1)
  69 #define ADP5061_CHG_STATUS_1_CHDONE(x)          (((x) >> 3) & 0x1)
  70 #define ADP5061_CHG_STATUS_1_CHG_STATUS(x)      (((x) >> 0) & 0x7)
  71 
  72 /* ADP5061_CHG_STATUS_2 */
  73 #define ADP5061_CHG_STATUS_2_THR_STATUS(x)      (((x) >> 5) & 0x7)
  74 #define ADP5061_CHG_STATUS_2_RCH_LIM_INFO(x)    (((x) >> 3) & 0x1)
  75 #define ADP5061_CHG_STATUS_2_BAT_STATUS(x)      (((x) >> 0) & 0x7)
  76 
  77 /* ADP5061_IEND */
  78 #define ADP5061_IEND_IEND_MSK                   GENMASK(7, 5)
  79 #define ADP5061_IEND_IEND_MODE(x)               (((x) & 0x07) << 5)
  80 
  81 #define ADP5061_NO_BATTERY      0x01
  82 #define ADP5061_ICHG_MAX        1300 // mA
  83 
  84 enum adp5061_chg_status {
  85         ADP5061_CHG_OFF,
  86         ADP5061_CHG_TRICKLE,
  87         ADP5061_CHG_FAST_CC,
  88         ADP5061_CHG_FAST_CV,
  89         ADP5061_CHG_COMPLETE,
  90         ADP5061_CHG_LDO_MODE,
  91         ADP5061_CHG_TIMER_EXP,
  92         ADP5061_CHG_BAT_DET,
  93 };
  94 
  95 static const int adp5061_chg_type[4] = {
  96         [ADP5061_CHG_OFF] = POWER_SUPPLY_CHARGE_TYPE_NONE,
  97         [ADP5061_CHG_TRICKLE] = POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
  98         [ADP5061_CHG_FAST_CC] = POWER_SUPPLY_CHARGE_TYPE_FAST,
  99         [ADP5061_CHG_FAST_CV] = POWER_SUPPLY_CHARGE_TYPE_FAST,
 100 };
 101 
 102 static const int adp5061_vweak_th[8] = {
 103         2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400,
 104 };
 105 
 106 static const int adp5061_prechg_current[4] = {
 107         5, 10, 20, 80,
 108 };
 109 
 110 static const int adp5061_vmin[4] = {
 111         2000, 2500, 2600, 2900,
 112 };
 113 
 114 static const int adp5061_const_chg_vmax[4] = {
 115         3200, 3400, 3700, 3800,
 116 };
 117 
 118 static const int adp5061_const_ichg[24] = {
 119         50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650,
 120         700, 750, 800, 850, 900, 950, 1000, 1050, 1100, 1200, 1300,
 121 };
 122 
 123 static const int adp5061_vmax[36] = {
 124         3800, 3820, 3840, 3860, 3880, 3900, 3920, 3940, 3960, 3980,
 125         4000, 4020, 4040, 4060, 4080, 4100, 4120, 4140, 4160, 4180,
 126         4200, 4220, 4240, 4260, 4280, 4300, 4320, 4340, 4360, 4380,
 127         4400, 4420, 4440, 4460, 4480, 4500,
 128 };
 129 
 130 static const int adp5061_in_current_lim[16] = {
 131         100, 150, 200, 250, 300, 400, 500, 600, 700,
 132         800, 900, 1000, 1200, 1500, 1800, 2100,
 133 };
 134 
 135 static const int adp5061_iend[8] = {
 136         12500, 32500, 52500, 72500, 92500, 117500, 142500, 170000,
 137 };
 138 
 139 struct adp5061_state {
 140         struct i2c_client               *client;
 141         struct regmap                   *regmap;
 142         struct power_supply             *psy;
 143 };
 144 
 145 static int adp5061_get_array_index(const int *array, u8 size, int val)
 146 {
 147         int i;
 148 
 149         for (i = 1; i < size; i++) {
 150                 if (val < array[i])
 151                         break;
 152         }
 153 
 154         return i-1;
 155 }
 156 
 157 static int adp5061_get_status(struct adp5061_state *st,
 158                               u8 *status1, u8 *status2)
 159 {
 160         u8 buf[2];
 161         int ret;
 162 
 163         /* CHG_STATUS1 and CHG_STATUS2 are adjacent regs */
 164         ret = regmap_bulk_read(st->regmap, ADP5061_CHG_STATUS_1,
 165                                &buf[0], 2);
 166         if (ret < 0)
 167                 return ret;
 168 
 169         *status1 = buf[0];
 170         *status2 = buf[1];
 171 
 172         return ret;
 173 }
 174 
 175 static int adp5061_get_input_current_limit(struct adp5061_state *st,
 176                 union power_supply_propval *val)
 177 {
 178         unsigned int regval;
 179         int mode, ret;
 180 
 181         ret = regmap_read(st->regmap, ADP5061_VINX_SET, &regval);
 182         if (ret < 0)
 183                 return ret;
 184 
 185         mode = ADP5061_VINX_SET_ILIM_MODE(regval);
 186         val->intval = adp5061_in_current_lim[mode] * 1000;
 187 
 188         return ret;
 189 }
 190 
 191 static int adp5061_set_input_current_limit(struct adp5061_state *st, int val)
 192 {
 193         int index;
 194 
 195         /* Convert from uA to mA */
 196         val /= 1000;
 197         index = adp5061_get_array_index(adp5061_in_current_lim,
 198                                         ARRAY_SIZE(adp5061_in_current_lim),
 199                                         val);
 200         if (index < 0)
 201                 return index;
 202 
 203         return regmap_update_bits(st->regmap, ADP5061_VINX_SET,
 204                                   ADP5061_VINX_SET_ILIM_MSK,
 205                                   ADP5061_VINX_SET_ILIM_MODE(index));
 206 }
 207 
 208 static int adp5061_set_min_voltage(struct adp5061_state *st, int val)
 209 {
 210         int index;
 211 
 212         /* Convert from uV to mV */
 213         val /= 1000;
 214         index = adp5061_get_array_index(adp5061_vmin,
 215                                         ARRAY_SIZE(adp5061_vmin),
 216                                         val);
 217         if (index < 0)
 218                 return index;
 219 
 220         return regmap_update_bits(st->regmap, ADP5061_VOLTAGE_TH,
 221                                   ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK,
 222                                   ADP5061_VOLTAGE_TH_VTRK_DEAD_MODE(index));
 223 }
 224 
 225 static int adp5061_get_min_voltage(struct adp5061_state *st,
 226                                    union power_supply_propval *val)
 227 {
 228         unsigned int regval;
 229         int ret;
 230 
 231         ret = regmap_read(st->regmap, ADP5061_VOLTAGE_TH, &regval);
 232         if (ret < 0)
 233                 return ret;
 234 
 235         regval = ((regval & ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK) >> 3);
 236         val->intval = adp5061_vmin[regval] * 1000;
 237 
 238         return ret;
 239 }
 240 
 241 static int adp5061_get_chg_volt_lim(struct adp5061_state *st,
 242                                     union power_supply_propval *val)
 243 {
 244         unsigned int regval;
 245         int mode, ret;
 246 
 247         ret = regmap_read(st->regmap, ADP5061_TERM_SET, &regval);
 248         if (ret < 0)
 249                 return ret;
 250 
 251         mode = ADP5061_TERM_SET_CHG_VLIM_MODE(regval);
 252         val->intval = adp5061_const_chg_vmax[mode] * 1000;
 253 
 254         return ret;
 255 }
 256 
 257 static int adp5061_get_max_voltage(struct adp5061_state *st,
 258                                    union power_supply_propval *val)
 259 {
 260         unsigned int regval;
 261         int ret;
 262 
 263         ret = regmap_read(st->regmap, ADP5061_TERM_SET, &regval);
 264         if (ret < 0)
 265                 return ret;
 266 
 267         regval = ((regval & ADP5061_TERM_SET_VTRM_MSK) >> 2) - 0x0F;
 268         if (regval >= ARRAY_SIZE(adp5061_vmax))
 269                 regval = ARRAY_SIZE(adp5061_vmax) - 1;
 270 
 271         val->intval = adp5061_vmax[regval] * 1000;
 272 
 273         return ret;
 274 }
 275 
 276 static int adp5061_set_max_voltage(struct adp5061_state *st, int val)
 277 {
 278         int vmax_index;
 279 
 280         /* Convert from uV to mV */
 281         val /= 1000;
 282         if (val > 4500)
 283                 val = 4500;
 284 
 285         vmax_index = adp5061_get_array_index(adp5061_vmax,
 286                                              ARRAY_SIZE(adp5061_vmax), val);
 287         if (vmax_index < 0)
 288                 return vmax_index;
 289 
 290         vmax_index += 0x0F;
 291 
 292         return regmap_update_bits(st->regmap, ADP5061_TERM_SET,
 293                                   ADP5061_TERM_SET_VTRM_MSK,
 294                                   ADP5061_TERM_SET_VTRM_MODE(vmax_index));
 295 }
 296 
 297 static int adp5061_set_const_chg_vmax(struct adp5061_state *st, int val)
 298 {
 299         int index;
 300 
 301         /* Convert from uV to mV */
 302         val /= 1000;
 303         index = adp5061_get_array_index(adp5061_const_chg_vmax,
 304                                         ARRAY_SIZE(adp5061_const_chg_vmax),
 305                                         val);
 306         if (index < 0)
 307                 return index;
 308 
 309         return regmap_update_bits(st->regmap, ADP5061_TERM_SET,
 310                                   ADP5061_TERM_SET_CHG_VLIM_MSK,
 311                                   ADP5061_TERM_SET_CHG_VLIM_MODE(index));
 312 }
 313 
 314 static int adp5061_set_const_chg_current(struct adp5061_state *st, int val)
 315 {
 316 
 317         int index;
 318 
 319         /* Convert from uA to mA */
 320         val /= 1000;
 321         if (val > ADP5061_ICHG_MAX)
 322                 val = ADP5061_ICHG_MAX;
 323 
 324         index = adp5061_get_array_index(adp5061_const_ichg,
 325                                         ARRAY_SIZE(adp5061_const_ichg),
 326                                         val);
 327         if (index < 0)
 328                 return index;
 329 
 330         return regmap_update_bits(st->regmap, ADP5061_CHG_CURR,
 331                                   ADP5061_CHG_CURR_ICHG_MSK,
 332                                   ADP5061_CHG_CURR_ICHG_MODE(index));
 333 }
 334 
 335 static int adp5061_get_const_chg_current(struct adp5061_state *st,
 336                 union power_supply_propval *val)
 337 {
 338         unsigned int regval;
 339         int ret;
 340 
 341         ret = regmap_read(st->regmap, ADP5061_CHG_CURR, &regval);
 342         if (ret < 0)
 343                 return ret;
 344 
 345         regval = ((regval & ADP5061_CHG_CURR_ICHG_MSK) >> 2);
 346         if (regval >= ARRAY_SIZE(adp5061_const_ichg))
 347                 regval = ARRAY_SIZE(adp5061_const_ichg) - 1;
 348 
 349         val->intval = adp5061_const_ichg[regval] * 1000;
 350 
 351         return ret;
 352 }
 353 
 354 static int adp5061_get_prechg_current(struct adp5061_state *st,
 355                                       union power_supply_propval *val)
 356 {
 357         unsigned int regval;
 358         int ret;
 359 
 360         ret = regmap_read(st->regmap, ADP5061_CHG_CURR, &regval);
 361         if (ret < 0)
 362                 return ret;
 363 
 364         regval &= ADP5061_CHG_CURR_ITRK_DEAD_MSK;
 365         val->intval = adp5061_prechg_current[regval] * 1000;
 366 
 367         return ret;
 368 }
 369 
 370 static int adp5061_set_prechg_current(struct adp5061_state *st, int val)
 371 {
 372         int index;
 373 
 374         /* Convert from uA to mA */
 375         val /= 1000;
 376         index = adp5061_get_array_index(adp5061_prechg_current,
 377                                         ARRAY_SIZE(adp5061_prechg_current),
 378                                         val);
 379         if (index < 0)
 380                 return index;
 381 
 382         return regmap_update_bits(st->regmap, ADP5061_CHG_CURR,
 383                                   ADP5061_CHG_CURR_ITRK_DEAD_MSK,
 384                                   ADP5061_CHG_CURR_ITRK_DEAD_MODE(index));
 385 }
 386 
 387 static int adp5061_get_vweak_th(struct adp5061_state *st,
 388                                 union power_supply_propval *val)
 389 {
 390         unsigned int regval;
 391         int ret;
 392 
 393         ret = regmap_read(st->regmap, ADP5061_VOLTAGE_TH, &regval);
 394         if (ret < 0)
 395                 return ret;
 396 
 397         regval &= ADP5061_VOLTAGE_TH_VWEAK_MSK;
 398         val->intval = adp5061_vweak_th[regval] * 1000;
 399 
 400         return ret;
 401 }
 402 
 403 static int adp5061_set_vweak_th(struct adp5061_state *st, int val)
 404 {
 405         int index;
 406 
 407         /* Convert from uV to mV */
 408         val /= 1000;
 409         index = adp5061_get_array_index(adp5061_vweak_th,
 410                                         ARRAY_SIZE(adp5061_vweak_th),
 411                                         val);
 412         if (index < 0)
 413                 return index;
 414 
 415         return regmap_update_bits(st->regmap, ADP5061_VOLTAGE_TH,
 416                                   ADP5061_VOLTAGE_TH_VWEAK_MSK,
 417                                   ADP5061_VOLTAGE_TH_VWEAK_MODE(index));
 418 }
 419 
 420 static int adp5061_get_chg_type(struct adp5061_state *st,
 421                                 union power_supply_propval *val)
 422 {
 423         u8 status1, status2;
 424         int chg_type, ret;
 425 
 426         ret = adp5061_get_status(st, &status1, &status2);
 427         if (ret < 0)
 428                 return ret;
 429 
 430         chg_type = adp5061_chg_type[ADP5061_CHG_STATUS_1_CHG_STATUS(status1)];
 431         if (chg_type > ADP5061_CHG_FAST_CV)
 432                 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
 433         else
 434                 val->intval = chg_type;
 435 
 436         return ret;
 437 }
 438 
 439 static int adp5061_get_charger_status(struct adp5061_state *st,
 440                                       union power_supply_propval *val)
 441 {
 442         u8 status1, status2;
 443         int ret;
 444 
 445         ret = adp5061_get_status(st, &status1, &status2);
 446         if (ret < 0)
 447                 return ret;
 448 
 449         switch (ADP5061_CHG_STATUS_1_CHG_STATUS(status1)) {
 450         case ADP5061_CHG_OFF:
 451                 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
 452                 break;
 453         case ADP5061_CHG_TRICKLE:
 454         case ADP5061_CHG_FAST_CC:
 455         case ADP5061_CHG_FAST_CV:
 456                 val->intval = POWER_SUPPLY_STATUS_CHARGING;
 457                 break;
 458         case ADP5061_CHG_COMPLETE:
 459                 val->intval = POWER_SUPPLY_STATUS_FULL;
 460                 break;
 461         case ADP5061_CHG_TIMER_EXP:
 462                 /* The battery must be discharging if there is a charge fault */
 463                 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 464                 break;
 465         default:
 466                 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
 467         }
 468 
 469         return ret;
 470 }
 471 
 472 static int adp5061_get_battery_status(struct adp5061_state *st,
 473                                       union power_supply_propval *val)
 474 {
 475         u8 status1, status2;
 476         int ret;
 477 
 478         ret = adp5061_get_status(st, &status1, &status2);
 479         if (ret < 0)
 480                 return ret;
 481 
 482         switch (ADP5061_CHG_STATUS_2_BAT_STATUS(status2)) {
 483         case 0x0: /* Battery monitor off */
 484         case 0x1: /* No battery */
 485                 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
 486                 break;
 487         case 0x2: /* VBAT < VTRK */
 488                 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
 489                 break;
 490         case 0x3: /* VTRK < VBAT_SNS < VWEAK */
 491                 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
 492                 break;
 493         case 0x4: /* VBAT_SNS > VWEAK */
 494                 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
 495                 break;
 496         }
 497 
 498         return ret;
 499 }
 500 
 501 static int adp5061_get_termination_current(struct adp5061_state *st,
 502                                            union power_supply_propval *val)
 503 {
 504         unsigned int regval;
 505         int ret;
 506 
 507         ret = regmap_read(st->regmap, ADP5061_IEND, &regval);
 508         if (ret < 0)
 509                 return ret;
 510 
 511         regval = (regval & ADP5061_IEND_IEND_MSK) >> 5;
 512         val->intval = adp5061_iend[regval];
 513 
 514         return ret;
 515 }
 516 
 517 static int adp5061_set_termination_current(struct adp5061_state *st, int val)
 518 {
 519         int index;
 520 
 521         index = adp5061_get_array_index(adp5061_iend,
 522                                         ARRAY_SIZE(adp5061_iend),
 523                                         val);
 524         if (index < 0)
 525                 return index;
 526 
 527         return regmap_update_bits(st->regmap, ADP5061_IEND,
 528                                   ADP5061_IEND_IEND_MSK,
 529                                   ADP5061_IEND_IEND_MODE(index));
 530 }
 531 
 532 static int adp5061_get_property(struct power_supply *psy,
 533                                 enum power_supply_property psp,
 534                                 union power_supply_propval *val)
 535 {
 536         struct adp5061_state *st = power_supply_get_drvdata(psy);
 537         u8 status1, status2;
 538         int mode, ret;
 539 
 540         switch (psp) {
 541         case POWER_SUPPLY_PROP_PRESENT:
 542                 ret = adp5061_get_status(st, &status1, &status2);
 543                 if (ret < 0)
 544                         return ret;
 545 
 546                 mode = ADP5061_CHG_STATUS_2_BAT_STATUS(status2);
 547                 if (mode == ADP5061_NO_BATTERY)
 548                         val->intval = 0;
 549                 else
 550                         val->intval = 1;
 551                 break;
 552         case POWER_SUPPLY_PROP_CHARGE_TYPE:
 553                 return adp5061_get_chg_type(st, val);
 554         case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
 555                 /* This property is used to indicate the input current
 556                  * limit into VINx (ILIM)
 557                  */
 558                 return adp5061_get_input_current_limit(st, val);
 559         case POWER_SUPPLY_PROP_VOLTAGE_MAX:
 560                 /* This property is used to indicate the termination
 561                  * voltage (VTRM)
 562                  */
 563                 return adp5061_get_max_voltage(st, val);
 564         case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 565                 /*
 566                  * This property is used to indicate the trickle to fast
 567                  * charge threshold (VTRK_DEAD)
 568                  */
 569                 return adp5061_get_min_voltage(st, val);
 570         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
 571                 /* This property is used to indicate the charging
 572                  * voltage limit (CHG_VLIM)
 573                  */
 574                 return adp5061_get_chg_volt_lim(st, val);
 575         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 576                 /*
 577                  * This property is used to indicate the value of the constant
 578                  * current charge (ICHG)
 579                  */
 580                 return adp5061_get_const_chg_current(st, val);
 581         case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
 582                 /*
 583                  * This property is used to indicate the value of the trickle
 584                  * and weak charge currents (ITRK_DEAD)
 585                  */
 586                 return adp5061_get_prechg_current(st, val);
 587         case POWER_SUPPLY_PROP_VOLTAGE_AVG:
 588                 /*
 589                  * This property is used to set the VWEAK threshold
 590                  * bellow this value, weak charge mode is entered
 591                  * above this value, fast chargerge mode is entered
 592                  */
 593                 return adp5061_get_vweak_th(st, val);
 594         case POWER_SUPPLY_PROP_STATUS:
 595                 /*
 596                  * Indicate the charger status in relation to power
 597                  * supply status property
 598                  */
 599                 return adp5061_get_charger_status(st, val);
 600         case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
 601                 /*
 602                  * Indicate the battery status in relation to power
 603                  * supply capacity level property
 604                  */
 605                 return adp5061_get_battery_status(st, val);
 606         case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
 607                 /* Indicate the values of the termination current */
 608                 return adp5061_get_termination_current(st, val);
 609         default:
 610                 return -EINVAL;
 611         }
 612 
 613         return 0;
 614 }
 615 
 616 static int adp5061_set_property(struct power_supply *psy,
 617                                 enum power_supply_property psp,
 618                                 const union power_supply_propval *val)
 619 {
 620         struct adp5061_state *st = power_supply_get_drvdata(psy);
 621 
 622         switch (psp) {
 623         case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
 624                 return adp5061_set_input_current_limit(st, val->intval);
 625         case POWER_SUPPLY_PROP_VOLTAGE_MAX:
 626                 return adp5061_set_max_voltage(st, val->intval);
 627         case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 628                 return adp5061_set_min_voltage(st, val->intval);
 629         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
 630                 return adp5061_set_const_chg_vmax(st, val->intval);
 631         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 632                 return adp5061_set_const_chg_current(st, val->intval);
 633         case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
 634                 return adp5061_set_prechg_current(st, val->intval);
 635         case POWER_SUPPLY_PROP_VOLTAGE_AVG:
 636                 return adp5061_set_vweak_th(st, val->intval);
 637         case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
 638                 return adp5061_set_termination_current(st, val->intval);
 639         default:
 640                 return -EINVAL;
 641         }
 642 
 643         return 0;
 644 }
 645 
 646 static int adp5061_prop_writeable(struct power_supply *psy,
 647                                   enum power_supply_property psp)
 648 {
 649         switch (psp) {
 650         case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
 651         case POWER_SUPPLY_PROP_VOLTAGE_MAX:
 652         case POWER_SUPPLY_PROP_VOLTAGE_MIN:
 653         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
 654         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 655         case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
 656         case POWER_SUPPLY_PROP_VOLTAGE_AVG:
 657         case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
 658                 return 1;
 659         default:
 660                 return 0;
 661         }
 662 }
 663 
 664 static enum power_supply_property adp5061_props[] = {
 665         POWER_SUPPLY_PROP_PRESENT,
 666         POWER_SUPPLY_PROP_CHARGE_TYPE,
 667         POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
 668         POWER_SUPPLY_PROP_VOLTAGE_MAX,
 669         POWER_SUPPLY_PROP_VOLTAGE_MIN,
 670         POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
 671         POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 672         POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
 673         POWER_SUPPLY_PROP_VOLTAGE_AVG,
 674         POWER_SUPPLY_PROP_STATUS,
 675         POWER_SUPPLY_PROP_CAPACITY_LEVEL,
 676         POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
 677 };
 678 
 679 static const struct regmap_config adp5061_regmap_config = {
 680         .reg_bits = 8,
 681         .val_bits = 8,
 682 };
 683 
 684 static const struct power_supply_desc adp5061_desc = {
 685         .name                   = "adp5061",
 686         .type                   = POWER_SUPPLY_TYPE_USB,
 687         .get_property           = adp5061_get_property,
 688         .set_property           = adp5061_set_property,
 689         .property_is_writeable  = adp5061_prop_writeable,
 690         .properties             = adp5061_props,
 691         .num_properties         = ARRAY_SIZE(adp5061_props),
 692 };
 693 
 694 static int adp5061_probe(struct i2c_client *client,
 695                          const struct i2c_device_id *id)
 696 {
 697         struct power_supply_config psy_cfg = {};
 698         struct adp5061_state *st;
 699 
 700         st = devm_kzalloc(&client->dev, sizeof(*st), GFP_KERNEL);
 701         if (!st)
 702                 return -ENOMEM;
 703 
 704         st->client = client;
 705         st->regmap = devm_regmap_init_i2c(client,
 706                                           &adp5061_regmap_config);
 707         if (IS_ERR(st->regmap)) {
 708                 dev_err(&client->dev, "Failed to initialize register map\n");
 709                 return -EINVAL;
 710         }
 711 
 712         i2c_set_clientdata(client, st);
 713         psy_cfg.drv_data = st;
 714 
 715         st->psy = devm_power_supply_register(&client->dev,
 716                                              &adp5061_desc,
 717                                              &psy_cfg);
 718 
 719         if (IS_ERR(st->psy)) {
 720                 dev_err(&client->dev, "Failed to register power supply\n");
 721                 return PTR_ERR(st->psy);
 722         }
 723 
 724         return 0;
 725 }
 726 
 727 static const struct i2c_device_id adp5061_id[] = {
 728         { "adp5061", 0},
 729         { }
 730 };
 731 MODULE_DEVICE_TABLE(i2c, adp5061_id);
 732 
 733 static struct i2c_driver adp5061_driver = {
 734         .driver = {
 735                 .name = KBUILD_MODNAME,
 736         },
 737         .probe = adp5061_probe,
 738         .id_table = adp5061_id,
 739 };
 740 module_i2c_driver(adp5061_driver);
 741 
 742 MODULE_DESCRIPTION("Analog Devices adp5061 battery charger driver");
 743 MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
 744 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */