root/drivers/power/supply/max8997_charger.c

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

DEFINITIONS

This source file includes following definitions.
  1. max8997_battery_get_property
  2. max8997_battery_probe
  3. max8997_battery_init
  4. max8997_battery_cleanup

   1 // SPDX-License-Identifier: GPL-2.0+
   2 //
   3 // max8997_charger.c - Power supply consumer driver for the Maxim 8997/8966
   4 //
   5 //  Copyright (C) 2011 Samsung Electronics
   6 //  MyungJoo Ham <myungjoo.ham@samsung.com>
   7 
   8 #include <linux/err.h>
   9 #include <linux/module.h>
  10 #include <linux/slab.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/power_supply.h>
  13 #include <linux/mfd/max8997.h>
  14 #include <linux/mfd/max8997-private.h>
  15 
  16 struct charger_data {
  17         struct device *dev;
  18         struct max8997_dev *iodev;
  19         struct power_supply *battery;
  20 };
  21 
  22 static enum power_supply_property max8997_battery_props[] = {
  23         POWER_SUPPLY_PROP_STATUS, /* "FULL" or "NOT FULL" only. */
  24         POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */
  25         POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */
  26 };
  27 
  28 /* Note that the charger control is done by a current regulator "CHARGER" */
  29 static int max8997_battery_get_property(struct power_supply *psy,
  30                 enum power_supply_property psp,
  31                 union power_supply_propval *val)
  32 {
  33         struct charger_data *charger = power_supply_get_drvdata(psy);
  34         struct i2c_client *i2c = charger->iodev->i2c;
  35         int ret;
  36         u8 reg;
  37 
  38         switch (psp) {
  39         case POWER_SUPPLY_PROP_STATUS:
  40                 val->intval = 0;
  41                 ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, &reg);
  42                 if (ret)
  43                         return ret;
  44                 if ((reg & (1 << 0)) == 0x1)
  45                         val->intval = POWER_SUPPLY_STATUS_FULL;
  46 
  47                 break;
  48         case POWER_SUPPLY_PROP_PRESENT:
  49                 val->intval = 0;
  50                 ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, &reg);
  51                 if (ret)
  52                         return ret;
  53                 if ((reg & (1 << 2)) == 0x0)
  54                         val->intval = 1;
  55 
  56                 break;
  57         case POWER_SUPPLY_PROP_ONLINE:
  58                 val->intval = 0;
  59                 ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, &reg);
  60                 if (ret)
  61                         return ret;
  62                 /* DCINOK */
  63                 if (reg & (1 << 1))
  64                         val->intval = 1;
  65 
  66                 break;
  67         default:
  68                 return -EINVAL;
  69         }
  70 
  71         return 0;
  72 }
  73 
  74 static const struct power_supply_desc max8997_battery_desc = {
  75         .name           = "max8997_pmic",
  76         .type           = POWER_SUPPLY_TYPE_BATTERY,
  77         .get_property   = max8997_battery_get_property,
  78         .properties     = max8997_battery_props,
  79         .num_properties = ARRAY_SIZE(max8997_battery_props),
  80 };
  81 
  82 static int max8997_battery_probe(struct platform_device *pdev)
  83 {
  84         int ret = 0;
  85         struct charger_data *charger;
  86         struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
  87         struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
  88         struct power_supply_config psy_cfg = {};
  89 
  90         if (!pdata)
  91                 return -EINVAL;
  92 
  93         if (pdata->eoc_mA) {
  94                 int val = (pdata->eoc_mA - 50) / 10;
  95                 if (val < 0)
  96                         val = 0;
  97                 if (val > 0xf)
  98                         val = 0xf;
  99 
 100                 ret = max8997_update_reg(iodev->i2c,
 101                                 MAX8997_REG_MBCCTRL5, val, 0xf);
 102                 if (ret < 0) {
 103                         dev_err(&pdev->dev, "Cannot use i2c bus.\n");
 104                         return ret;
 105                 }
 106         }
 107 
 108         switch (pdata->timeout) {
 109         case 5:
 110                 ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
 111                                 0x2 << 4, 0x7 << 4);
 112                 break;
 113         case 6:
 114                 ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
 115                                 0x3 << 4, 0x7 << 4);
 116                 break;
 117         case 7:
 118                 ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
 119                                 0x4 << 4, 0x7 << 4);
 120                 break;
 121         case 0:
 122                 ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1,
 123                                 0x7 << 4, 0x7 << 4);
 124                 break;
 125         default:
 126                 dev_err(&pdev->dev, "incorrect timeout value (%d)\n",
 127                                 pdata->timeout);
 128                 return -EINVAL;
 129         }
 130         if (ret < 0) {
 131                 dev_err(&pdev->dev, "Cannot use i2c bus.\n");
 132                 return ret;
 133         }
 134 
 135         charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
 136         if (!charger)
 137                 return -ENOMEM;
 138 
 139         platform_set_drvdata(pdev, charger);
 140 
 141 
 142         charger->dev = &pdev->dev;
 143         charger->iodev = iodev;
 144 
 145         psy_cfg.drv_data = charger;
 146 
 147         charger->battery = devm_power_supply_register(&pdev->dev,
 148                                                  &max8997_battery_desc,
 149                                                  &psy_cfg);
 150         if (IS_ERR(charger->battery)) {
 151                 dev_err(&pdev->dev, "failed: power supply register\n");
 152                 return PTR_ERR(charger->battery);
 153         }
 154 
 155         return 0;
 156 }
 157 
 158 static const struct platform_device_id max8997_battery_id[] = {
 159         { "max8997-battery", 0 },
 160         { }
 161 };
 162 MODULE_DEVICE_TABLE(platform, max8997_battery_id);
 163 
 164 static struct platform_driver max8997_battery_driver = {
 165         .driver = {
 166                 .name = "max8997-battery",
 167         },
 168         .probe = max8997_battery_probe,
 169         .id_table = max8997_battery_id,
 170 };
 171 
 172 static int __init max8997_battery_init(void)
 173 {
 174         return platform_driver_register(&max8997_battery_driver);
 175 }
 176 subsys_initcall(max8997_battery_init);
 177 
 178 static void __exit max8997_battery_cleanup(void)
 179 {
 180         platform_driver_unregister(&max8997_battery_driver);
 181 }
 182 module_exit(max8997_battery_cleanup);
 183 
 184 MODULE_DESCRIPTION("MAXIM 8997/8966 battery control driver");
 185 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
 186 MODULE_LICENSE("GPL");

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