max8998_charger.c (5393B)
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// max8998_charger.c - Power supply consumer driver for the Maxim 8998/LP3974 4// 5// Copyright (C) 2009-2010 Samsung Electronics 6// MyungJoo Ham <myungjoo.ham@samsung.com> 7 8#include <linux/err.h> 9#include <linux/module.h> 10#include <linux/mod_devicetable.h> 11#include <linux/slab.h> 12#include <linux/platform_device.h> 13#include <linux/power_supply.h> 14#include <linux/mfd/max8998.h> 15#include <linux/mfd/max8998-private.h> 16 17struct max8998_battery_data { 18 struct device *dev; 19 struct max8998_dev *iodev; 20 struct power_supply *battery; 21}; 22 23static enum power_supply_property max8998_battery_props[] = { 24 POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */ 25 POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */ 26 POWER_SUPPLY_PROP_STATUS, /* charger is charging/discharging/full */ 27}; 28 29/* Note that the charger control is done by a current regulator "CHARGER" */ 30static int max8998_battery_get_property(struct power_supply *psy, 31 enum power_supply_property psp, 32 union power_supply_propval *val) 33{ 34 struct max8998_battery_data *max8998 = power_supply_get_drvdata(psy); 35 struct i2c_client *i2c = max8998->iodev->i2c; 36 int ret; 37 u8 reg; 38 39 switch (psp) { 40 case POWER_SUPPLY_PROP_PRESENT: 41 ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, ®); 42 if (ret) 43 return ret; 44 if (reg & (1 << 4)) 45 val->intval = 0; 46 else 47 val->intval = 1; 48 break; 49 case POWER_SUPPLY_PROP_ONLINE: 50 ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, ®); 51 if (ret) 52 return ret; 53 54 if (reg & (1 << 5)) 55 val->intval = 1; 56 else 57 val->intval = 0; 58 59 break; 60 case POWER_SUPPLY_PROP_STATUS: 61 ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, ®); 62 if (ret) 63 return ret; 64 65 if (!(reg & (1 << 5))) { 66 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 67 } else { 68 if (reg & (1 << 6)) 69 val->intval = POWER_SUPPLY_STATUS_FULL; 70 else if (reg & (1 << 3)) 71 val->intval = POWER_SUPPLY_STATUS_CHARGING; 72 else 73 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 74 } 75 break; 76 default: 77 return -EINVAL; 78 } 79 80 return 0; 81} 82 83static const struct power_supply_desc max8998_battery_desc = { 84 .name = "max8998_pmic", 85 .type = POWER_SUPPLY_TYPE_BATTERY, 86 .get_property = max8998_battery_get_property, 87 .properties = max8998_battery_props, 88 .num_properties = ARRAY_SIZE(max8998_battery_props), 89}; 90 91static int max8998_battery_probe(struct platform_device *pdev) 92{ 93 struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); 94 struct max8998_platform_data *pdata = iodev->pdata; 95 struct power_supply_config psy_cfg = {}; 96 struct max8998_battery_data *max8998; 97 struct i2c_client *i2c; 98 int ret = 0; 99 100 if (!pdata) { 101 dev_err(pdev->dev.parent, "No platform init data supplied\n"); 102 return -ENODEV; 103 } 104 105 max8998 = devm_kzalloc(&pdev->dev, sizeof(struct max8998_battery_data), 106 GFP_KERNEL); 107 if (!max8998) 108 return -ENOMEM; 109 110 max8998->dev = &pdev->dev; 111 max8998->iodev = iodev; 112 platform_set_drvdata(pdev, max8998); 113 i2c = max8998->iodev->i2c; 114 115 /* Setup "End of Charge" */ 116 /* If EOC value equals 0, 117 * remain value set from bootloader or default value */ 118 if (pdata->eoc >= 10 && pdata->eoc <= 45) { 119 max8998_update_reg(i2c, MAX8998_REG_CHGR1, 120 (pdata->eoc / 5 - 2) << 5, 0x7 << 5); 121 } else if (pdata->eoc == 0) { 122 dev_dbg(max8998->dev, 123 "EOC value not set: leave it unchanged.\n"); 124 } else { 125 dev_err(max8998->dev, "Invalid EOC value\n"); 126 return -EINVAL; 127 } 128 129 /* Setup Charge Restart Level */ 130 switch (pdata->restart) { 131 case 100: 132 max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x1 << 3, 0x3 << 3); 133 break; 134 case 150: 135 max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x0 << 3, 0x3 << 3); 136 break; 137 case 200: 138 max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x2 << 3, 0x3 << 3); 139 break; 140 case -1: 141 max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x3 << 3, 0x3 << 3); 142 break; 143 case 0: 144 dev_dbg(max8998->dev, 145 "Restart Level not set: leave it unchanged.\n"); 146 break; 147 default: 148 dev_err(max8998->dev, "Invalid Restart Level\n"); 149 return -EINVAL; 150 } 151 152 /* Setup Charge Full Timeout */ 153 switch (pdata->timeout) { 154 case 5: 155 max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x0 << 4, 0x3 << 4); 156 break; 157 case 6: 158 max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x1 << 4, 0x3 << 4); 159 break; 160 case 7: 161 max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x2 << 4, 0x3 << 4); 162 break; 163 case -1: 164 max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x3 << 4, 0x3 << 4); 165 break; 166 case 0: 167 dev_dbg(max8998->dev, 168 "Full Timeout not set: leave it unchanged.\n"); 169 break; 170 default: 171 dev_err(max8998->dev, "Invalid Full Timeout value\n"); 172 return -EINVAL; 173 } 174 175 psy_cfg.drv_data = max8998; 176 177 max8998->battery = devm_power_supply_register(max8998->dev, 178 &max8998_battery_desc, 179 &psy_cfg); 180 if (IS_ERR(max8998->battery)) { 181 ret = PTR_ERR(max8998->battery); 182 dev_err(max8998->dev, "failed: power supply register: %d\n", 183 ret); 184 return ret; 185 } 186 187 return 0; 188} 189 190static const struct platform_device_id max8998_battery_id[] = { 191 { "max8998-battery", TYPE_MAX8998 }, 192 { } 193}; 194 195static struct platform_driver max8998_battery_driver = { 196 .driver = { 197 .name = "max8998-battery", 198 }, 199 .probe = max8998_battery_probe, 200 .id_table = max8998_battery_id, 201}; 202 203module_platform_driver(max8998_battery_driver); 204 205MODULE_DESCRIPTION("MAXIM 8998 battery control driver"); 206MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 207MODULE_LICENSE("GPL"); 208MODULE_ALIAS("platform:max8998-battery");