On 07/12/2017 02:12 AM, Ladislav Michl wrote:
> On Tue, Jul 11, 2017 at 10:59:11PM +0200, Ladislav Michl wrote:
>> On Tue, Jul 11, 2017 at 07:07:32PM +0300, Dragos Bogdan wrote:
>>> The only difference between the already supported LTC2943 and LTC2944 is 
>>> the operating range (3.6V - 20V compared to 3.6V - 60V).
>> Please wrap commit message correctly.
>>
>>> Signed-off-by: Dragos Bogdan <[email protected]>
>>> ---
>>> Changes in v2:
>>> - Fix the voltage and current conversion.
>> That's better :-) However it conflicts with LTC2942 patch. I can fix
> Well, still not good enough. You overlooked different temperature
> computing formula. For a bug, see bellow.

The Full-Scale Temperature is 510 K (as it is displayed in the Electrical
Characteristics section) for both LTC2943 and LTC2944 parts, so the same
computing formula is valid.

For LTC2944, the 500 K value used in the Applications Information section
is an error that will be fixed in the next version of the datasheet.

>
>> this and extend LTC2942 patch serie to add LTC2944. Okay to proceed
>> or do you want to take care about this yourself? Also it is nice to
> I'll provide patchset myself, it is mostly done now. I'd appreciate
> if you could test it on your device.
>
>> Cc driver author (done now).
>>
>>      ladis
>>
>>>  .../devicetree/bindings/power/supply/ltc2941.txt   | 10 ++---
>>>  drivers/power/supply/ltc2941-battery-gauge.c       | 46 
>>> +++++++++++++++++-----
>>>  2 files changed, 41 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt 
>>> b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
>>> index a9d7aa60558b..ed0f02846d10 100644
>>> --- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt
>>> +++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
>>> @@ -1,9 +1,9 @@
>>> -binding for LTC2941 and LTC2943 battery gauges
>>> +binding for LTC2941, LTC2943 and LTC2944 battery gauges
>>>  
>>> -Both the LTC2941 and LTC2943 measure battery capacity.
>>> -The LTC2943 is compatible with the LTC2941, it adds voltage and
>>> -temperature monitoring, and uses a slightly different conversion
>>> -formula for the charge counter.
>>> +All the LTC2941, LTC2943 and LTC2944 measure battery capacity.
>>> +The LTC2943 and LTC2944 are compatible with the LTC2941, they add voltage 
>>> and
>>> +temperature monitoring, and use a slightly different conversion formula 
>>> for the
>>> +charge counter.
>>>  
>>>  Required properties:
>>>  - compatible: Should contain "lltc,ltc2941" or "lltc,ltc2943" which also
>>> diff --git a/drivers/power/supply/ltc2941-battery-gauge.c 
>>> b/drivers/power/supply/ltc2941-battery-gauge.c
>>> index 7efb908f4451..4c979b1a022b 100644
>>> --- a/drivers/power/supply/ltc2941-battery-gauge.c
>>> +++ b/drivers/power/supply/ltc2941-battery-gauge.c
>>> @@ -1,5 +1,5 @@
>>>  /*
>>> - * I2C client/driver for the Linear Technology LTC2941 and LTC2943
>>> + * I2C client/driver for the Linear Technology LTC2941, LTC2943 and LTC2944
>>>   * Battery Gas Gauge IC
>>>   *
>>>   * Copyright (C) 2014 Topic Embedded Systems
>>> @@ -57,6 +57,12 @@ enum ltc294x_reg {
>>>  #define LTC2941_NUM_REGS   0x08
>>>  #define LTC2943_NUM_REGS   0x18
>>>  
>>> +enum ltc294x_id {
>>> +   LTC2941_ID,
>>> +   LTC2943_ID,
>>> +   LTC2944_ID,
>>> +};
>>> +
>>>  struct ltc294x_info {
>>>     struct i2c_client *client;      /* I2C Client pointer */
>>>     struct power_supply *supply;    /* Supply pointer */
>>> @@ -66,6 +72,7 @@ struct ltc294x_info {
>>>     int charge;     /* Last charge register content */
>>>     int r_sense;    /* mOhm */
>>>     int Qlsb;       /* nAh */
>>> +   enum ltc294x_id id;
>>>  };
>>>  
>>>  static inline int convert_bin_to_uAh(
>>> @@ -145,7 +152,7 @@ static int ltc294x_reset(const struct ltc294x_info 
>>> *info, int prescaler_exp)
>>>  
>>>     control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
>>>                             LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
>>> -   /* Put the 2943 into "monitor" mode, so it measures every 10 sec */
>>> +   /* Put the 2943/4 into "monitor" mode, so it measures every 10 sec */
>>>     if (info->num_regs == LTC2943_NUM_REGS)
>>>             control |= LTC2943_REG_CONTROL_MODE_SCAN;
>>>  
>>> @@ -248,11 +255,16 @@ static int ltc294x_get_voltage(const struct 
>>> ltc294x_info *info, int *val)
>>>     int ret;
>>>     u8 datar[2];
>>>     u32 value;
>>> +   u32 full_scale;
>>>  
>>>     ret = ltc294x_read_regs(info->client,
>>>             LTC294X_REG_VOLTAGE_MSB, &datar[0], 2);
>>>     value = (datar[0] << 8) | datar[1];
>>> -   *val = ((value * 23600) / 0xFFFF) * 1000; /* in uV */
>>> +   if (info->id == LTC2944_ID)
>>> +           full_scale = 70800;
>>> +   else
>>> +           full_scale = 23600;
>>> +   *val = ((value * full_scale) / 0xFFFF) * 1000; /* in uV */
> Here result of 14bit ADC conversion is stored in 16bit register with
> lowest two bits being zero. Multiplying that with 70800 will overflow
> 32bit unsigned integer.
>
>>>     return ret;
>>>  }
>>>  
>>> @@ -261,15 +273,20 @@ static int ltc294x_get_current(const struct 
>>> ltc294x_info *info, int *val)
>>>     int ret;
>>>     u8 datar[2];
>>>     s32 value;
>>> +   u32 full_scale;
>>>  
>>>     ret = ltc294x_read_regs(info->client,
>>>             LTC294X_REG_CURRENT_MSB, &datar[0], 2);
>>>     value = (datar[0] << 8) | datar[1];
>>>     value -= 0x7FFF;
>>> +   if (info->id == LTC2944_ID)
>>> +           full_scale = 64000;
>>> +   else
>>> +           full_scale = 60000;
>>>     /* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
>>>      * the formula below keeps everything in s32 range while preserving
>>>      * enough digits */
>>> -   *val = 1000 * ((60000 * value) / (info->r_sense * 0x7FFF)); /* in uA */
>>> +   *val = 1000 * ((full_scale * value) / (info->r_sense * 0x7FFF)); /* in 
>>> uA */
>>>     return ret;
>>>  }
>>>  
>>> @@ -388,7 +405,11 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
>>>  
>>>     np = of_node_get(client->dev.of_node);
>>>  
>>> -   info->num_regs = (unsigned long)of_device_get_match_data(&client->dev);
>>> +   info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev);
>>> +   if (info->id == LTC2941_ID)
>>> +           info->num_regs = LTC2941_NUM_REGS;
>>> +   else
>>> +           info->num_regs = LTC2943_NUM_REGS;
>>>     info->supply_desc.name = np->name;
>>>  
>>>     /* r_sense can be negative, when sense+ is connected to the battery
>>> @@ -492,8 +513,9 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, 
>>> ltc294x_suspend, ltc294x_resume);
>>>  
>>>  
>>>  static const struct i2c_device_id ltc294x_i2c_id[] = {
>>> -   {"ltc2941", LTC2941_NUM_REGS},
>>> -   {"ltc2943", LTC2943_NUM_REGS},
>>> +   {"ltc2941", LTC2941_ID},
>>> +   {"ltc2943", LTC2943_ID},
>>> +   {"ltc2944", LTC2944_ID},
>>>     { },
>>>  };
>>>  MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
>>> @@ -501,11 +523,15 @@ MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
>>>  static const struct of_device_id ltc294x_i2c_of_match[] = {
>>>     {
>>>             .compatible = "lltc,ltc2941",
>>> -           .data = (void *)LTC2941_NUM_REGS
>>> +           .data = (void *)LTC2941_ID
>>>     },
>>>     {
>>>             .compatible = "lltc,ltc2943",
>>> -           .data = (void *)LTC2943_NUM_REGS
>>> +           .data = (void *)LTC2943_ID
>>> +   },
>>> +   {
>>> +           .compatible = "lltc,ltc2944",
>>> +           .data = (void *)LTC2944_ID
>>>     },
>>>     { },
>>>  };
>>> @@ -525,5 +551,5 @@ module_i2c_driver(ltc294x_driver);
>>>  
>>>  MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
>>>  MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
>>> -MODULE_DESCRIPTION("LTC2941/LTC2943 Battery Gas Gauge IC driver");
>>> +MODULE_DESCRIPTION("LTC2941/LTC2943/LTC2944 Battery Gas Gauge IC driver");
>>>  MODULE_LICENSE("GPL");
>>> -- 
>>> 2.11.0
>

Reply via email to