generic-adc-battery.c (10760B)
1/* 2 * Generic battery driver code using IIO 3 * Copyright (C) 2012, Anish Kumar <anish198519851985@gmail.com> 4 * based on jz4740-battery.c 5 * based on s3c_adc_battery.c 6 * 7 * This file is subject to the terms and conditions of the GNU General Public 8 * License. See the file COPYING in the main directory of this archive for 9 * more details. 10 * 11 */ 12#include <linux/interrupt.h> 13#include <linux/platform_device.h> 14#include <linux/power_supply.h> 15#include <linux/gpio/consumer.h> 16#include <linux/err.h> 17#include <linux/timer.h> 18#include <linux/jiffies.h> 19#include <linux/errno.h> 20#include <linux/init.h> 21#include <linux/module.h> 22#include <linux/slab.h> 23#include <linux/iio/consumer.h> 24#include <linux/iio/types.h> 25#include <linux/power/generic-adc-battery.h> 26 27#define JITTER_DEFAULT 10 /* hope 10ms is enough */ 28 29enum gab_chan_type { 30 GAB_VOLTAGE = 0, 31 GAB_CURRENT, 32 GAB_POWER, 33 GAB_MAX_CHAN_TYPE 34}; 35 36/* 37 * gab_chan_name suggests the standard channel names for commonly used 38 * channel types. 39 */ 40static const char *const gab_chan_name[] = { 41 [GAB_VOLTAGE] = "voltage", 42 [GAB_CURRENT] = "current", 43 [GAB_POWER] = "power", 44}; 45 46struct gab { 47 struct power_supply *psy; 48 struct power_supply_desc psy_desc; 49 struct iio_channel *channel[GAB_MAX_CHAN_TYPE]; 50 struct gab_platform_data *pdata; 51 struct delayed_work bat_work; 52 int level; 53 int status; 54 bool cable_plugged; 55 struct gpio_desc *charge_finished; 56}; 57 58static struct gab *to_generic_bat(struct power_supply *psy) 59{ 60 return power_supply_get_drvdata(psy); 61} 62 63static void gab_ext_power_changed(struct power_supply *psy) 64{ 65 struct gab *adc_bat = to_generic_bat(psy); 66 67 schedule_delayed_work(&adc_bat->bat_work, msecs_to_jiffies(0)); 68} 69 70static const enum power_supply_property gab_props[] = { 71 POWER_SUPPLY_PROP_STATUS, 72 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 73 POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN, 74 POWER_SUPPLY_PROP_CHARGE_NOW, 75 POWER_SUPPLY_PROP_VOLTAGE_NOW, 76 POWER_SUPPLY_PROP_CURRENT_NOW, 77 POWER_SUPPLY_PROP_TECHNOLOGY, 78 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 79 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 80 POWER_SUPPLY_PROP_MODEL_NAME, 81}; 82 83/* 84 * This properties are set based on the received platform data and this 85 * should correspond one-to-one with enum chan_type. 86 */ 87static const enum power_supply_property gab_dyn_props[] = { 88 POWER_SUPPLY_PROP_VOLTAGE_NOW, 89 POWER_SUPPLY_PROP_CURRENT_NOW, 90 POWER_SUPPLY_PROP_POWER_NOW, 91}; 92 93static bool gab_charge_finished(struct gab *adc_bat) 94{ 95 if (!adc_bat->charge_finished) 96 return false; 97 return gpiod_get_value(adc_bat->charge_finished); 98} 99 100static int gab_get_status(struct gab *adc_bat) 101{ 102 struct gab_platform_data *pdata = adc_bat->pdata; 103 struct power_supply_info *bat_info; 104 105 bat_info = &pdata->battery_info; 106 if (adc_bat->level == bat_info->charge_full_design) 107 return POWER_SUPPLY_STATUS_FULL; 108 return adc_bat->status; 109} 110 111static enum gab_chan_type gab_prop_to_chan(enum power_supply_property psp) 112{ 113 switch (psp) { 114 case POWER_SUPPLY_PROP_POWER_NOW: 115 return GAB_POWER; 116 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 117 return GAB_VOLTAGE; 118 case POWER_SUPPLY_PROP_CURRENT_NOW: 119 return GAB_CURRENT; 120 default: 121 WARN_ON(1); 122 break; 123 } 124 return GAB_POWER; 125} 126 127static int read_channel(struct gab *adc_bat, enum power_supply_property psp, 128 int *result) 129{ 130 int ret; 131 int chan_index; 132 133 chan_index = gab_prop_to_chan(psp); 134 ret = iio_read_channel_processed(adc_bat->channel[chan_index], 135 result); 136 if (ret < 0) 137 pr_err("read channel error\n"); 138 return ret; 139} 140 141static int gab_get_property(struct power_supply *psy, 142 enum power_supply_property psp, union power_supply_propval *val) 143{ 144 struct gab *adc_bat; 145 struct gab_platform_data *pdata; 146 struct power_supply_info *bat_info; 147 int result = 0; 148 int ret = 0; 149 150 adc_bat = to_generic_bat(psy); 151 if (!adc_bat) { 152 dev_err(&psy->dev, "no battery infos ?!\n"); 153 return -EINVAL; 154 } 155 pdata = adc_bat->pdata; 156 bat_info = &pdata->battery_info; 157 158 switch (psp) { 159 case POWER_SUPPLY_PROP_STATUS: 160 val->intval = gab_get_status(adc_bat); 161 break; 162 case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: 163 val->intval = 0; 164 break; 165 case POWER_SUPPLY_PROP_CHARGE_NOW: 166 val->intval = pdata->cal_charge(result); 167 break; 168 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 169 case POWER_SUPPLY_PROP_CURRENT_NOW: 170 case POWER_SUPPLY_PROP_POWER_NOW: 171 ret = read_channel(adc_bat, psp, &result); 172 if (ret < 0) 173 goto err; 174 val->intval = result; 175 break; 176 case POWER_SUPPLY_PROP_TECHNOLOGY: 177 val->intval = bat_info->technology; 178 break; 179 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 180 val->intval = bat_info->voltage_min_design; 181 break; 182 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 183 val->intval = bat_info->voltage_max_design; 184 break; 185 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 186 val->intval = bat_info->charge_full_design; 187 break; 188 case POWER_SUPPLY_PROP_MODEL_NAME: 189 val->strval = bat_info->name; 190 break; 191 default: 192 return -EINVAL; 193 } 194err: 195 return ret; 196} 197 198static void gab_work(struct work_struct *work) 199{ 200 struct gab *adc_bat; 201 struct delayed_work *delayed_work; 202 bool is_plugged; 203 int status; 204 205 delayed_work = to_delayed_work(work); 206 adc_bat = container_of(delayed_work, struct gab, bat_work); 207 status = adc_bat->status; 208 209 is_plugged = power_supply_am_i_supplied(adc_bat->psy); 210 adc_bat->cable_plugged = is_plugged; 211 212 if (!is_plugged) 213 adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING; 214 else if (gab_charge_finished(adc_bat)) 215 adc_bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING; 216 else 217 adc_bat->status = POWER_SUPPLY_STATUS_CHARGING; 218 219 if (status != adc_bat->status) 220 power_supply_changed(adc_bat->psy); 221} 222 223static irqreturn_t gab_charged(int irq, void *dev_id) 224{ 225 struct gab *adc_bat = dev_id; 226 struct gab_platform_data *pdata = adc_bat->pdata; 227 int delay; 228 229 delay = pdata->jitter_delay ? pdata->jitter_delay : JITTER_DEFAULT; 230 schedule_delayed_work(&adc_bat->bat_work, 231 msecs_to_jiffies(delay)); 232 return IRQ_HANDLED; 233} 234 235static int gab_probe(struct platform_device *pdev) 236{ 237 struct gab *adc_bat; 238 struct power_supply_desc *psy_desc; 239 struct power_supply_config psy_cfg = {}; 240 struct gab_platform_data *pdata = pdev->dev.platform_data; 241 enum power_supply_property *properties; 242 int ret = 0; 243 int chan; 244 int index = ARRAY_SIZE(gab_props); 245 bool any = false; 246 247 adc_bat = devm_kzalloc(&pdev->dev, sizeof(*adc_bat), GFP_KERNEL); 248 if (!adc_bat) { 249 dev_err(&pdev->dev, "failed to allocate memory\n"); 250 return -ENOMEM; 251 } 252 253 psy_cfg.drv_data = adc_bat; 254 psy_desc = &adc_bat->psy_desc; 255 psy_desc->name = pdata->battery_info.name; 256 257 /* bootup default values for the battery */ 258 adc_bat->cable_plugged = false; 259 adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING; 260 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; 261 psy_desc->get_property = gab_get_property; 262 psy_desc->external_power_changed = gab_ext_power_changed; 263 adc_bat->pdata = pdata; 264 265 /* 266 * copying the static properties and allocating extra memory for holding 267 * the extra configurable properties received from platform data. 268 */ 269 properties = kcalloc(ARRAY_SIZE(gab_props) + 270 ARRAY_SIZE(gab_chan_name), 271 sizeof(*properties), 272 GFP_KERNEL); 273 if (!properties) { 274 ret = -ENOMEM; 275 goto first_mem_fail; 276 } 277 278 memcpy(properties, gab_props, sizeof(gab_props)); 279 280 /* 281 * getting channel from iio and copying the battery properties 282 * based on the channel supported by consumer device. 283 */ 284 for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) { 285 adc_bat->channel[chan] = iio_channel_get(&pdev->dev, 286 gab_chan_name[chan]); 287 if (IS_ERR(adc_bat->channel[chan])) { 288 ret = PTR_ERR(adc_bat->channel[chan]); 289 adc_bat->channel[chan] = NULL; 290 } else { 291 /* copying properties for supported channels only */ 292 int index2; 293 294 for (index2 = 0; index2 < index; index2++) { 295 if (properties[index2] == gab_dyn_props[chan]) 296 break; /* already known */ 297 } 298 if (index2 == index) /* really new */ 299 properties[index++] = gab_dyn_props[chan]; 300 any = true; 301 } 302 } 303 304 /* none of the channels are supported so let's bail out */ 305 if (!any) { 306 ret = -ENODEV; 307 goto second_mem_fail; 308 } 309 310 /* 311 * Total number of properties is equal to static properties 312 * plus the dynamic properties.Some properties may not be set 313 * as come channels may be not be supported by the device.So 314 * we need to take care of that. 315 */ 316 psy_desc->properties = properties; 317 psy_desc->num_properties = index; 318 319 adc_bat->psy = power_supply_register(&pdev->dev, psy_desc, &psy_cfg); 320 if (IS_ERR(adc_bat->psy)) { 321 ret = PTR_ERR(adc_bat->psy); 322 goto err_reg_fail; 323 } 324 325 INIT_DELAYED_WORK(&adc_bat->bat_work, gab_work); 326 327 adc_bat->charge_finished = devm_gpiod_get_optional(&pdev->dev, 328 "charged", GPIOD_IN); 329 if (adc_bat->charge_finished) { 330 int irq; 331 332 irq = gpiod_to_irq(adc_bat->charge_finished); 333 ret = request_any_context_irq(irq, gab_charged, 334 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 335 "battery charged", adc_bat); 336 if (ret < 0) 337 goto gpio_req_fail; 338 } 339 340 platform_set_drvdata(pdev, adc_bat); 341 342 /* Schedule timer to check current status */ 343 schedule_delayed_work(&adc_bat->bat_work, 344 msecs_to_jiffies(0)); 345 return 0; 346 347gpio_req_fail: 348 power_supply_unregister(adc_bat->psy); 349err_reg_fail: 350 for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) { 351 if (adc_bat->channel[chan]) 352 iio_channel_release(adc_bat->channel[chan]); 353 } 354second_mem_fail: 355 kfree(properties); 356first_mem_fail: 357 return ret; 358} 359 360static int gab_remove(struct platform_device *pdev) 361{ 362 int chan; 363 struct gab *adc_bat = platform_get_drvdata(pdev); 364 365 power_supply_unregister(adc_bat->psy); 366 367 if (adc_bat->charge_finished) 368 free_irq(gpiod_to_irq(adc_bat->charge_finished), adc_bat); 369 370 for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) { 371 if (adc_bat->channel[chan]) 372 iio_channel_release(adc_bat->channel[chan]); 373 } 374 375 kfree(adc_bat->psy_desc.properties); 376 cancel_delayed_work_sync(&adc_bat->bat_work); 377 return 0; 378} 379 380static int __maybe_unused gab_suspend(struct device *dev) 381{ 382 struct gab *adc_bat = dev_get_drvdata(dev); 383 384 cancel_delayed_work_sync(&adc_bat->bat_work); 385 adc_bat->status = POWER_SUPPLY_STATUS_UNKNOWN; 386 return 0; 387} 388 389static int __maybe_unused gab_resume(struct device *dev) 390{ 391 struct gab *adc_bat = dev_get_drvdata(dev); 392 struct gab_platform_data *pdata = adc_bat->pdata; 393 int delay; 394 395 delay = pdata->jitter_delay ? pdata->jitter_delay : JITTER_DEFAULT; 396 397 /* Schedule timer to check current status */ 398 schedule_delayed_work(&adc_bat->bat_work, 399 msecs_to_jiffies(delay)); 400 return 0; 401} 402 403static SIMPLE_DEV_PM_OPS(gab_pm_ops, gab_suspend, gab_resume); 404 405static struct platform_driver gab_driver = { 406 .driver = { 407 .name = "generic-adc-battery", 408 .pm = &gab_pm_ops, 409 }, 410 .probe = gab_probe, 411 .remove = gab_remove, 412}; 413module_platform_driver(gab_driver); 414 415MODULE_AUTHOR("anish kumar <anish198519851985@gmail.com>"); 416MODULE_DESCRIPTION("generic battery driver using IIO"); 417MODULE_LICENSE("GPL");