Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e5e4389 authored by Marek Belisko's avatar Marek Belisko Committed by Sebastian Reichel
Browse files

power: twl4030-madc-battery: Convert to iio consumer.



Because of added iio error handling private data allocation was converted
to managed to simplify code.

Signed-off-by: default avatarMarek Belisko <marek@goldelico.com>
Reviewed-By: default avatarSebastian Reichel <sre@debian.org>
Signed-off-by: default avatarSebastian Reichel <sre@kernel.org>
parent 0db739fa
Loading
Loading
Loading
Loading
+61 −35
Original line number Original line Diff line number Diff line
@@ -19,10 +19,14 @@
#include <linux/sort.h>
#include <linux/sort.h>
#include <linux/i2c/twl4030-madc.h>
#include <linux/i2c/twl4030-madc.h>
#include <linux/power/twl4030_madc_battery.h>
#include <linux/power/twl4030_madc_battery.h>
#include <linux/iio/consumer.h>


struct twl4030_madc_battery {
struct twl4030_madc_battery {
	struct power_supply *psy;
	struct power_supply *psy;
	struct twl4030_madc_bat_platform_data *pdata;
	struct twl4030_madc_bat_platform_data *pdata;
	struct iio_channel *channel_temp;
	struct iio_channel *channel_ichg;
	struct iio_channel *channel_vbat;
};
};


static enum power_supply_property twl4030_madc_bat_props[] = {
static enum power_supply_property twl4030_madc_bat_props[] = {
@@ -38,43 +42,34 @@ static enum power_supply_property twl4030_madc_bat_props[] = {
	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
};
};


static int madc_read(int index)
static int madc_read(struct iio_channel *channel)
{
{
	struct twl4030_madc_request req;
	int val, err;
	int val;
	err = iio_read_channel_processed(channel, &val);

	if (err < 0)
	req.channels = index;
		return err;
	req.method = TWL4030_MADC_SW2;
	req.type = TWL4030_MADC_WAIT;
	req.do_avg = 0;
	req.raw = false;
	req.func_cb = NULL;

	val = twl4030_madc_conversion(&req);
	if (val < 0)
		return val;


	return req.rbuf[ffs(index) - 1];
	return val;
}
}


static int twl4030_madc_bat_get_charging_status(void)
static int twl4030_madc_bat_get_charging_status(struct twl4030_madc_battery *bt)
{
{
	return (madc_read(TWL4030_MADC_ICHG) > 0) ? 1 : 0;
	return (madc_read(bt->channel_ichg) > 0) ? 1 : 0;
}
}


static int twl4030_madc_bat_get_voltage(void)
static int twl4030_madc_bat_get_voltage(struct twl4030_madc_battery *bt)
{
{
	return madc_read(TWL4030_MADC_VBAT);
	return madc_read(bt->channel_vbat);
}
}


static int twl4030_madc_bat_get_current(void)
static int twl4030_madc_bat_get_current(struct twl4030_madc_battery *bt)
{
{
	return madc_read(TWL4030_MADC_ICHG) * 1000;
	return madc_read(bt->channel_ichg) * 1000;
}
}


static int twl4030_madc_bat_get_temp(void)
static int twl4030_madc_bat_get_temp(struct twl4030_madc_battery *bt)
{
{
	return madc_read(TWL4030_MADC_BTEMP) * 10;
	return madc_read(bt->channel_temp) * 10;
}
}


static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat,
static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat,
@@ -84,7 +79,7 @@ static int twl4030_madc_bat_voltscale(struct twl4030_madc_battery *bat,
	int i, res = 0;
	int i, res = 0;


	/* choose charging curve */
	/* choose charging curve */
	if (twl4030_madc_bat_get_charging_status())
	if (twl4030_madc_bat_get_charging_status(bat))
		calibration = bat->pdata->charging;
		calibration = bat->pdata->charging;
	else
	else
		calibration = bat->pdata->discharging;
		calibration = bat->pdata->discharging;
@@ -118,23 +113,23 @@ static int twl4030_madc_bat_get_property(struct power_supply *psy,
	switch (psp) {
	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
	case POWER_SUPPLY_PROP_STATUS:
		if (twl4030_madc_bat_voltscale(bat,
		if (twl4030_madc_bat_voltscale(bat,
				twl4030_madc_bat_get_voltage()) > 95)
				twl4030_madc_bat_get_voltage(bat)) > 95)
			val->intval = POWER_SUPPLY_STATUS_FULL;
			val->intval = POWER_SUPPLY_STATUS_FULL;
		else {
		else {
			if (twl4030_madc_bat_get_charging_status())
			if (twl4030_madc_bat_get_charging_status(bat))
				val->intval = POWER_SUPPLY_STATUS_CHARGING;
				val->intval = POWER_SUPPLY_STATUS_CHARGING;
			else
			else
				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
		}
		}
		break;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = twl4030_madc_bat_get_voltage() * 1000;
		val->intval = twl4030_madc_bat_get_voltage(bat) * 1000;
		break;
		break;
	case POWER_SUPPLY_PROP_TECHNOLOGY:
	case POWER_SUPPLY_PROP_TECHNOLOGY:
		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
		break;
		break;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		val->intval = twl4030_madc_bat_get_current();
		val->intval = twl4030_madc_bat_get_current(bat);
		break;
		break;
	case POWER_SUPPLY_PROP_PRESENT:
	case POWER_SUPPLY_PROP_PRESENT:
		/* assume battery is always present */
		/* assume battery is always present */
@@ -142,23 +137,23 @@ static int twl4030_madc_bat_get_property(struct power_supply *psy,
		break;
		break;
	case POWER_SUPPLY_PROP_CHARGE_NOW: {
	case POWER_SUPPLY_PROP_CHARGE_NOW: {
			int percent = twl4030_madc_bat_voltscale(bat,
			int percent = twl4030_madc_bat_voltscale(bat,
					twl4030_madc_bat_get_voltage());
					twl4030_madc_bat_get_voltage(bat));
			val->intval = (percent * bat->pdata->capacity) / 100;
			val->intval = (percent * bat->pdata->capacity) / 100;
			break;
			break;
		}
		}
	case POWER_SUPPLY_PROP_CAPACITY:
	case POWER_SUPPLY_PROP_CAPACITY:
		val->intval = twl4030_madc_bat_voltscale(bat,
		val->intval = twl4030_madc_bat_voltscale(bat,
					twl4030_madc_bat_get_voltage());
					twl4030_madc_bat_get_voltage(bat));
		break;
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL:
	case POWER_SUPPLY_PROP_CHARGE_FULL:
		val->intval = bat->pdata->capacity;
		val->intval = bat->pdata->capacity;
		break;
		break;
	case POWER_SUPPLY_PROP_TEMP:
	case POWER_SUPPLY_PROP_TEMP:
		val->intval = twl4030_madc_bat_get_temp();
		val->intval = twl4030_madc_bat_get_temp(bat);
		break;
		break;
	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: {
	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: {
			int percent = twl4030_madc_bat_voltscale(bat,
			int percent = twl4030_madc_bat_voltscale(bat,
					twl4030_madc_bat_get_voltage());
					twl4030_madc_bat_get_voltage(bat));
			/* in mAh */
			/* in mAh */
			int chg = (percent * (bat->pdata->capacity/1000))/100;
			int chg = (percent * (bat->pdata->capacity/1000))/100;


@@ -201,10 +196,29 @@ static int twl4030_madc_battery_probe(struct platform_device *pdev)
	struct power_supply_config psy_cfg = {};
	struct power_supply_config psy_cfg = {};
	int ret = 0;
	int ret = 0;


	twl4030_madc_bat = kzalloc(sizeof(*twl4030_madc_bat), GFP_KERNEL);
	twl4030_madc_bat = devm_kzalloc(&pdev->dev, sizeof(*twl4030_madc_bat),
				GFP_KERNEL);
	if (!twl4030_madc_bat)
	if (!twl4030_madc_bat)
		return -ENOMEM;
		return -ENOMEM;


	twl4030_madc_bat->channel_temp = iio_channel_get(&pdev->dev, "temp");
	if (IS_ERR(twl4030_madc_bat->channel_temp)) {
		ret = PTR_ERR(twl4030_madc_bat->channel_temp);
		goto err;
	}

	twl4030_madc_bat->channel_ichg = iio_channel_get(&pdev->dev, "ichg");
	if (IS_ERR(twl4030_madc_bat->channel_ichg)) {
		ret = PTR_ERR(twl4030_madc_bat->channel_ichg);
		goto err_temp;
	}

	twl4030_madc_bat->channel_vbat = iio_channel_get(&pdev->dev, "vbat");
	if (IS_ERR(twl4030_madc_bat->channel_vbat)) {
		ret = PTR_ERR(twl4030_madc_bat->channel_vbat);
		goto err_ichg;
	}

	/* sort charging and discharging calibration data */
	/* sort charging and discharging calibration data */
	sort(pdata->charging, pdata->charging_size,
	sort(pdata->charging, pdata->charging_size,
		sizeof(struct twl4030_madc_bat_calibration),
		sizeof(struct twl4030_madc_bat_calibration),
@@ -221,9 +235,18 @@ static int twl4030_madc_battery_probe(struct platform_device *pdev)
						      &psy_cfg);
						      &psy_cfg);
	if (IS_ERR(twl4030_madc_bat->psy)) {
	if (IS_ERR(twl4030_madc_bat->psy)) {
		ret = PTR_ERR(twl4030_madc_bat->psy);
		ret = PTR_ERR(twl4030_madc_bat->psy);
		kfree(twl4030_madc_bat);
		goto err_vbat;
	}
	}


	return 0;

err_vbat:
	iio_channel_release(twl4030_madc_bat->channel_vbat);
err_ichg:
	iio_channel_release(twl4030_madc_bat->channel_ichg);
err_temp:
	iio_channel_release(twl4030_madc_bat->channel_temp);
err:
	return ret;
	return ret;
}
}


@@ -232,7 +255,10 @@ static int twl4030_madc_battery_remove(struct platform_device *pdev)
	struct twl4030_madc_battery *bat = platform_get_drvdata(pdev);
	struct twl4030_madc_battery *bat = platform_get_drvdata(pdev);


	power_supply_unregister(bat->psy);
	power_supply_unregister(bat->psy);
	kfree(bat);

	iio_channel_release(bat->channel_vbat);
	iio_channel_release(bat->channel_ichg);
	iio_channel_release(bat->channel_temp);


	return 0;
	return 0;
}
}