[Gta04-owner] Replicant-4.2 for GTA04

Dr. H. Nikolaus Schaller hns at goldelico.com
Mon Mar 24 17:52:50 CET 2014


Am 24.03.2014 um 17:28 schrieb Alexandre Roumiantsev:

> Hello
> 
>> Can you please send a patch of your bq27x00_battery.c changes, so we
>> can have a look at it and our kernel devs can push it upstream, if it
>> fixes a problem? 
> Here
> https://drive.google.com/file/d/0B-rRgKAzYyoBbXZHLVUyUTBWMW8/edit?usp=sharing
> is my version of bq27x00_battery.c. But it is too experimental and should
> used only for comparison. It is too far to be a regular patch. 
>> I cannot test your binary image, as I cannot see any
>> battery problem with my device. Can somebody who still has battery
>> problems on Replicant, which are not related to corroded battery pads,
>> old uboot or uncalibrated battery please try this image and report the
>> findings?
> I would like to get some feedback from somebody, who has GTA04 subj about 
> battery status display behavior, to have more info then only from my own unit. 
> For me, the battery behavior in new experimental build is more suitable. 
> I repeat that battery technical detail is new for me and I would like that
> somebody, who knows technical well give explanation why old version of driver 
> looks better then new one.

Hi Alexandre,
I have tried to make a diff (relative to 3.12.7) myself, but it appears that you are based on an older kernel?
And the one we use includes support for bq27425?

I.e. a git diff (or plain diff).

That makes it much easier to find out *what* you have changed and comment on it.
Git provides so many tools to make code inspection, communication and discussion easier so that we should use them...

So could you please provide a patch?

Or please describe in words what you have changed and why or it is really difficult to comment on it.

> 
> Best regards, Alexandre.

BR as well,
Nikolaus



Here the result of my manual attempt to do a diff relative to 3.12.7:

25d24
<  * http://www.ti.com/product/bq27425-g1
51c50
< #define BQ27x00_REG_NAC			0x0C /* Nominal available capacity */
---
> #define BQ27x00_REG_NAC			0x0C /* Nominal available capaciy */
54,55c53
< #define BQ27x00_REG_AE			0x22 /* Available energy */
< #define BQ27x00_POWER_AVG		0x24
---
> #define BQ27x00_REG_AE			0x22 /* Available enery */
59,61c57
< #define BQ27000_FLAG_EDVF		BIT(0) /* Final End-of-Discharge-Voltage flag */
< #define BQ27000_FLAG_EDV1		BIT(1) /* First End-of-Discharge-Voltage flag */
< #define BQ27000_FLAG_CI			BIT(4) /* Capacity Inaccurate flag */
---
> #define BQ27000_FLAG_CHGS		BIT(7)
63d58
< #define BQ27000_FLAG_CHGS		BIT(7) /* Charge state flag */
70,71d64
< #define BQ27500_FLAG_SOCF		BIT(1) /* State-of-Charge threshold final */
< #define BQ27500_FLAG_SOC1		BIT(2) /* State-of-Charge threshold 1 */
73,77d65
< #define BQ27500_FLAG_OTC		BIT(15)
< 
< /* bq27425 register addresses are same as bq27x00 addresses minus 4 */
< #define BQ27425_REG_OFFSET		0x04
< #define BQ27425_REG_SOC			0x18 /* Register address plus offset */
82d69
< #define BQ27x00_POWER_CONSTANT		(256 * 29200 / 1000)
89c76
< enum bq27x00_chip { BQ27000, BQ27500, BQ27425};
---
> enum bq27x00_chip { BQ27000, BQ27500 };
99d85
< 	int energy;
101,102c87,88
< 	int power_avg;
< 	int health;
---
> 
> 	int current_now;
129d114
< 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
140,141d124
< 	POWER_SUPPLY_PROP_POWER_AVG,
< 	POWER_SUPPLY_PROP_HEALTH,
144,158c127
< static enum power_supply_property bq27425_battery_props[] = {
< 	POWER_SUPPLY_PROP_STATUS,
< 	POWER_SUPPLY_PROP_PRESENT,
< 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
< 	POWER_SUPPLY_PROP_CURRENT_NOW,
< 	POWER_SUPPLY_PROP_CAPACITY,
< 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
< 	POWER_SUPPLY_PROP_TEMP,
< 	POWER_SUPPLY_PROP_TECHNOLOGY,
< 	POWER_SUPPLY_PROP_CHARGE_FULL,
< 	POWER_SUPPLY_PROP_CHARGE_NOW,
< 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
< };
< 
< static unsigned int poll_interval = 360;
---
> static unsigned int poll_interval = 60;
170,171d138
< 	if (di->chip == BQ27425)
< 		return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
176,187d142
<  * Higher versions of the chip like BQ27425 and BQ27500
<  * differ from BQ27000 and BQ27200 in calculation of certain
<  * parameters. Hence we need to check for the chip type.
<  */
< static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di)
< {
< 	if (di->chip == BQ27425 || di->chip == BQ27500)
< 		return true;
< 	return false;
< }
< 
< /*
197,198d151
< 	else if (di->chip == BQ27425)
< 		rsoc = bq27x00_read(di, BQ27425_REG_SOC, false);
203c156
< 		dev_dbg(di->dev, "error reading relative State-of-Charge\n");
---
> 		dev_err(di->dev, "error reading relative State-of-Charge\n");
218,219c171
< 		dev_dbg(di->dev, "error reading charge register %02x: %d\n",
< 			reg, charge);
---
> 		dev_err(di->dev, "error reading nominal available capacity\n");
223c175
< 	if (bq27xxx_is_chip_version_higher(di))
---
> 	if (di->chip == BQ27500)
237,244d188
< 	int flags;
< 	bool is_bq27500 = di->chip == BQ27500;
< 	bool is_higher = bq27xxx_is_chip_version_higher(di);
< 
< 	flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
< 	if (flags >= 0 && !is_higher && (flags & BQ27000_FLAG_CI))
< 		return -ENODATA;
< 
265c209
< 	if (bq27xxx_is_chip_version_higher(di))
---
> 	if (di->chip == BQ27500)
271c215
< 		dev_dbg(di->dev, "error reading initial last measured discharge\n");
---
> 		dev_err(di->dev, "error reading initial last measured discharge\n");
275c219
< 	if (bq27xxx_is_chip_version_higher(di))
---
> 	if (di->chip == BQ27500)
284,325d227
<  * Return the battery Available energy in µWh
<  * Or < 0 if something fails.
<  */
< static int bq27x00_battery_read_energy(struct bq27x00_device_info *di)
< {
< 	int ae;
< 
< 	ae = bq27x00_read(di, BQ27x00_REG_AE, false);
< 	if (ae < 0) {
< 		dev_dbg(di->dev, "error reading available energy\n");
< 		return ae;
< 	}
< 
< 	if (di->chip == BQ27500)
< 		ae *= 1000;
< 	else
< 		ae = ae * 29200 / BQ27000_RS;
< 
< 	return ae;
< }
< 
< /*
<  * Return the battery temperature in tenths of degree Kelvin
<  * Or < 0 if something fails.
<  */
< static int bq27x00_battery_read_temperature(struct bq27x00_device_info *di)
< {
< 	int temp;
< 
< 	temp = bq27x00_read(di, BQ27x00_REG_TEMP, false);
< 	if (temp < 0) {
< 		dev_err(di->dev, "error reading temperature\n");
< 		return temp;
< 	}
< 
< 	if (!bq27xxx_is_chip_version_higher(di))
< 		temp = 5 * temp / 2;
< 
< 	return temp;
< }
< 
< /*
350,351c252
< 		dev_dbg(di->dev, "error reading time register %02x: %d\n",
< 			reg, tval);
---
> 		dev_err(di->dev, "error reading register %02x: %d\n", reg, tval);
361,414d261
< /*
<  * Read a power avg register.
<  * Return < 0 if something fails.
<  */
< static int bq27x00_battery_read_pwr_avg(struct bq27x00_device_info *di, u8 reg)
< {
< 	int tval;
< 
< 	tval = bq27x00_read(di, reg, false);
< 	if (tval < 0) {
< 		dev_err(di->dev, "error reading power avg rgister  %02x: %d\n",
< 			reg, tval);
< 		return tval;
< 	}
< 
< 	if (di->chip == BQ27500)
< 		return tval;
< 	else
< 		return (tval * BQ27x00_POWER_CONSTANT) / BQ27000_RS;
< }
< 
< /*
<  * Read flag register.
<  * Return < 0 if something fails.
<  */
< static int bq27x00_battery_read_health(struct bq27x00_device_info *di)
< {
< 	int tval;
< 
< 	tval = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
< 	if (tval < 0) {
< 		dev_err(di->dev, "error reading flag register:%d\n", tval);
< 		return tval;
< 	}
< 
< 	if ((di->chip == BQ27500)) {
< 		if (tval & BQ27500_FLAG_SOCF)
< 			tval = POWER_SUPPLY_HEALTH_DEAD;
< 		else if (tval & BQ27500_FLAG_OTC)
< 			tval = POWER_SUPPLY_HEALTH_OVERHEAT;
< 		else
< 			tval = POWER_SUPPLY_HEALTH_GOOD;
< 		return tval;
< 	} else {
< 		if (tval & BQ27000_FLAG_EDV1)
< 			tval = POWER_SUPPLY_HEALTH_DEAD;
< 		else
< 			tval = POWER_SUPPLY_HEALTH_GOOD;
< 		return tval;
< 	}
< 
< 	return -1;
< }
< 
419d265
< 	bool is_bq27425 = di->chip == BQ27425;
422,425c268
< 	cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
< 	if ((cache.flags & 0xff) == 0xff)
< 		/* read error */
< 		cache.flags = -1;
---
> 	cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500);
427,458c270,279
< 		if (!is_bq27500 && !is_bq27425
< 				&& (cache.flags & BQ27000_FLAG_CI)) {
< 			dev_dbg(di->dev, "battery is not calibrated! ignoring capacity values\n");
< 			cache.capacity = -ENODATA;
< 			cache.energy = -ENODATA;
< 			cache.time_to_empty = -ENODATA;
< 			cache.time_to_empty_avg = -ENODATA;
< 			cache.time_to_full = -ENODATA;
< 			cache.charge_full = -ENODATA;
< 			cache.health = -ENODATA;
< 		} else {
< 			cache.capacity = bq27x00_battery_read_rsoc(di);
< 			if (!is_bq27425) {
< 				cache.energy = bq27x00_battery_read_energy(di);
< 				cache.time_to_empty =
< 					bq27x00_battery_read_time(di,
< 							BQ27x00_REG_TTE);
< 				cache.time_to_empty_avg =
< 					bq27x00_battery_read_time(di,
< 							BQ27x00_REG_TTECP);
< 				cache.time_to_full =
< 					bq27x00_battery_read_time(di,
< 							BQ27x00_REG_TTF);
< 			}
< 			cache.charge_full = bq27x00_battery_read_lmd(di);
< 			cache.health = bq27x00_battery_read_health(di);
< 		}
< 		cache.temperature = bq27x00_battery_read_temperature(di);
< 		if (!is_bq27425)
< 			cache.cycle_count = bq27x00_battery_read_cyct(di);
< 		cache.power_avg =
< 			bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG);
---
> 		cache.capacity = bq27x00_battery_read_rsoc(di);
> 		cache.temperature = bq27x00_read(di, BQ27x00_REG_TEMP, false);
> 		cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE);
> 		cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP);
> 		cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF);
> 		cache.charge_full = bq27x00_battery_read_lmd(di);
> 		cache.cycle_count = bq27x00_battery_read_cyct(di);
> 
> 		if (!is_bq27500)
> 			cache.current_now = bq27x00_read(di, BQ27x00_REG_AI, false);
464a286,287
> 	/* Ignore current_now which is a snapshot of the current battery state
> 	 * and is likely to be different even between two consecutive reads */
467,472c290,291
< 	if (is_bq27500)
< 		flags_changed &= BQ27500_FLAGS_IMPORTANT;
< 	else
< 		flags_changed &= BQ27000_FLAGS_IMPORTANT;
< 	if (flags_changed)
< 		power_supply_changed(&di->bat);
---
> 
> 	power_supply_changed(&di->bat);
490a310,328
> 
> /*
>  * Return the battery temperature in tenths of degree Celsius
>  * Or < 0 if something fails.
>  */
> static int bq27x00_battery_temperature(struct bq27x00_device_info *di,
> 	union power_supply_propval *val)
> {
> 	if (di->cache.temperature < 0)
> 		return di->cache.temperature;
> 
> 	if (di->chip == BQ27500)
> 		val->intval = di->cache.temperature - 2731;
> 	else
> 		val->intval = ((di->cache.temperature * 5) - 5463) / 2;
> 
> 	return 0;
> }
> 
500d337
< 	int flags;
502,504c339,344
< 	curr = bq27x00_read(di, BQ27x00_REG_AI, false);
< 	if (curr < 0) {
< 		dev_err(di->dev, "error reading current\n");
---
> 	if (di->chip == BQ27500)
> 	    curr = bq27x00_read(di, BQ27x00_REG_AI, false);
> 	else
> 	    curr = di->cache.current_now;
> 
> 	if (curr < 0)
506d345
< 	}
508c347
< 	if (bq27xxx_is_chip_version_higher(di)) {
---
> 	if (di->chip == BQ27500) {
512,513c351
< 		flags = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
< 		if (flags & BQ27000_FLAG_CHGS) {
---
> 		if (di->cache.flags & BQ27000_FLAG_CHGS) {
529c367
< 	if (bq27xxx_is_chip_version_higher(di)) {
---
> 	if (di->chip == BQ27500) {
552c390,394
< static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di,
---
> /*
>  * Return the battery Voltage in milivolts
>  * Or < 0 if something fails.
>  */
> static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
555c397
< 	int level;
---
> 	int volt;
557,575c399,401
< 	if (bq27xxx_is_chip_version_higher(di)) {
< 		if (di->cache.flags & BQ27500_FLAG_FC)
< 			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
< 		else if (di->cache.flags & BQ27500_FLAG_SOC1)
< 			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
< 		else if (di->cache.flags & BQ27500_FLAG_SOCF)
< 			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
< 		else
< 			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
< 	} else {
< 		if (di->cache.flags & BQ27000_FLAG_FC)
< 			level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
< 		else if (di->cache.flags & BQ27000_FLAG_EDV1)
< 			level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
< 		else if (di->cache.flags & BQ27000_FLAG_EDVF)
< 			level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
< 		else
< 			level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
< 	}
---
> 	volt = bq27x00_read(di, BQ27x00_REG_VOLT, false);
> 	if (volt < 0)
> 		return volt;
577c403
< 	val->intval = level;
---
> 	val->intval = volt * 1000;
583c409
<  * Return the battery Voltage in millivolts
---
>  * Return the battery Available energy in µWh
586c412
< static int bq27x00_battery_voltage(struct bq27x00_device_info *di,
---
> static int bq27x00_battery_energy(struct bq27x00_device_info *di,
589c415
< 	int volt;
---
> 	int ae;
591,594c417,420
< 	volt = bq27x00_read(di, BQ27x00_REG_VOLT, false);
< 	if (volt < 0) {
< 		dev_err(di->dev, "error reading voltage\n");
< 		return volt;
---
> 	ae = bq27x00_read(di, BQ27x00_REG_AE, false);
> 	if (ae < 0) {
> 		dev_err(di->dev, "error reading available energy\n");
> 		return ae;
597c423,428
< 	val->intval = volt * 1000;
---
> 	if (di->chip == BQ27500)
> 		ae *= 1000;
> 	else
> 		ae = ae * 29200 / BQ27000_RS;
> 
> 	val->intval = ae;
601a433
> 
649,651d480
< 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
< 		ret = bq27x00_battery_capacity_level(di, val);
< 		break;
653,655c482
< 		ret = bq27x00_simple_value(di->cache.temperature, val);
< 		if (ret == 0)
< 			val->intval -= 2731;
---
> 		ret = bq27x00_battery_temperature(di, val);
682,688c509
< 		ret = bq27x00_simple_value(di->cache.energy, val);
< 		break;
< 	case POWER_SUPPLY_PROP_POWER_AVG:
< 		ret = bq27x00_simple_value(di->cache.power_avg, val);
< 		break;
< 	case POWER_SUPPLY_PROP_HEALTH:
< 		ret = bq27x00_simple_value(di->cache.health, val);
---
> 		ret = bq27x00_battery_energy(di, val);
710,716c531,532
< 	if (di->chip == BQ27425) {
< 		di->bat.properties = bq27425_battery_props;
< 		di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props);
< 	} else {
< 		di->bat.properties = bq27x00_battery_props;
< 		di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
< 	}
---
> 	di->bat.properties = bq27x00_battery_props;
> 	di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
738,745d553
< 	/*
< 	 * power_supply_unregister call bq27x00_battery_get_property which
< 	 * call bq27x00_battery_poll.
< 	 * Make sure that bq27x00_battery_poll will not call
< 	 * schedule_delayed_work again after unregister (which cause OOPS).
< 	 */
< 	poll_interval = 0;
< 
805a614,616
> 	retval = idr_pre_get(&battery_id, GFP_KERNEL);
> 	if (retval == 0)
> 		return -ENOMEM;
807c618
< 	num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL);
---
> 	retval = idr_get_new(&battery_id, client, &num);
809,810c620,621
< 	if (num < 0)
< 		return num;
---
> 	if (retval < 0)
> 		return retval;
832,833c643
< 	retval = bq27x00_powersupply_init(di);
< 	if (retval)
---
> 	if (bq27x00_powersupply_init(di))
872d681
< 	{ "bq27425", BQ27425 },
980a790
> 	platform_set_drvdata(pdev, NULL);
991a802
> 	platform_set_drvdata(pdev, NULL);



More information about the Gta04-owner mailing list