commit 14f62fd6287ec340ce99c8eb0c68d00970d98684
parent dd72b52f7253ea4ad1e0070985709272435a9a99
Author: nanocodebug <nanocodebug@gmail.com>
Date: Tue, 21 Jun 2022 23:21:09 -0700
cleanup and fixes
Diffstat:
1 file changed, 84 insertions(+), 71 deletions(-)
diff --git a/reform2-lpc-driver/src/reform2-lpc.c b/reform2-lpc-driver/src/reform2-lpc.c
@@ -5,22 +5,22 @@
#include <linux/delay.h>
#include <linux/power_supply.h>
-static int spiProbe(struct spi_device *spi);
-static void spiRemove(struct spi_device *spi);
+static int lpcProbe(struct spi_device *spi);
+static void lpcRemove(struct spi_device *spi);
static ssize_t showStatus(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t showCells(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t showFirmware(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t showCapacity(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t lpcCommand(struct device *dev, char command, uint8_t arg1, uint8_t *response);
-static int bat_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val);
+static int getBatProperty(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val);
-typedef struct t_private_data
+typedef struct lpc_driver_data
{
struct spi_device *spi;
struct power_supply *bat;
struct mutex lock;
-} T_PRIVATE_DATA;
+} lpc_driver_data;
static DEVICE_ATTR(status, 0444, showStatus, NULL);
static DEVICE_ATTR(cells, 0444, showCells, NULL);
@@ -37,28 +37,29 @@ static struct spi_board_info g_spi_board_info = {
static enum power_supply_property bat_props[] = {
POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_TECHNOLOGY, // lifepo4
- POWER_SUPPLY_PROP_VOLTAGE_NOW, // uV
- POWER_SUPPLY_PROP_CURRENT_NOW, // uA
- POWER_SUPPLY_PROP_CAPACITY, // percent
- POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, //uAh hardcoded to 1800 atm, param 2
- POWER_SUPPLY_PROP_CHARGE_NOW, //uAh capacity_accu_ampsecs param 0
- POWER_SUPPLY_PROP_CHARGE_EMPTY, // uAh param 1
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CHARGE_NOW,
+ POWER_SUPPLY_PROP_CHARGE_EMPTY,
};
static struct power_supply_desc bat_desc = {
.name = "8xlifepo4",
.properties = bat_props,
.num_properties = ARRAY_SIZE(bat_props),
- .get_property = bat_get_property,
+ .get_property = getBatProperty,
.type = POWER_SUPPLY_TYPE_BATTERY,
};
-static int spiProbe(struct spi_device *spi)
+static int lpcProbe(struct spi_device *spi)
{
- T_PRIVATE_DATA *data;
- int ret;
+ struct lpc_driver_data *data;
struct power_supply_config psy_cfg = {};
+ int ret;
printk(KERN_INFO "%s: probing ...\n", "reform2-lpc");
@@ -73,7 +74,7 @@ static int spiProbe(struct spi_device *spi)
return -ENODEV;
}
- data = kzalloc(sizeof(T_PRIVATE_DATA), GFP_KERNEL);
+ data = kzalloc(sizeof(struct lpc_driver_data), GFP_KERNEL);
if (data == NULL)
{
printk(KERN_ERR "%s: kzalloc failed\n", __func__);
@@ -118,12 +119,12 @@ static int spiProbe(struct spi_device *spi)
return PTR_ERR(data->bat);
}
- return 0;
+ return ret;
}
-static void spiRemove(struct spi_device *spi)
+static void lpcRemove(struct spi_device *spi)
{
- T_PRIVATE_DATA *data = (T_PRIVATE_DATA *)spi_get_drvdata(spi);
+ struct lpc_driver_data *data = (struct lpc_driver_data *)spi_get_drvdata(spi);
printk(KERN_INFO "%s: removing ... \n", "reform2-lpc");
@@ -139,36 +140,38 @@ static void spiRemove(struct spi_device *spi)
static ssize_t showStatus(struct device *dev, struct device_attribute *attr, char *buf)
{
- uint8_t statusResult[8];
- int ret = 0;
+ uint8_t buffer[8];
int16_t voltage;
int16_t amps;
uint8_t percentage;
uint8_t status;
+ int ret = 0;
- ret = lpcCommand(dev, 'q', 0, statusResult);
+ ret = lpcCommand(dev, 'q', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
}
- voltage = (int16_t)statusResult[0] | ((int16_t)statusResult[1] << 8);
- amps = (int16_t)statusResult[2] | ((int16_t)statusResult[3] << 8);
- percentage = statusResult[4];
- status = statusResult[5];
+ voltage = (int16_t)buffer[0] | ((int16_t)buffer[1] << 8);
+ amps = (int16_t)buffer[2] | ((int16_t)buffer[3] << 8);
+ percentage = buffer[4];
+ status = buffer[5];
return snprintf(buf, PAGE_SIZE, "%d.%d %d.%d %2d%% %d",
- voltage / 1000, voltage % 1000, amps / 1000, abs(amps % 1000), percentage, status);
+ voltage / 1000, voltage % 1000,
+ amps / 1000, abs(amps % 1000),
+ percentage, status);
}
static ssize_t showCells(struct device *dev, struct device_attribute *attr, char *buf)
{
- uint8_t statusResult[8];
+ uint8_t buffer[8];
uint16_t cells[8];
- int ret = 0;
ssize_t wroteChars = 0;
-
- ret = lpcCommand(dev, 'v', 0, statusResult);
+ int ret = 0;
+
+ ret = lpcCommand(dev, 'v', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
@@ -176,10 +179,10 @@ static ssize_t showCells(struct device *dev, struct device_attribute *attr, char
for(uint8_t s = 0; s < 4; s++)
{
- cells[s] = statusResult[s*2] | statusResult[(s*2)+1] << 8;
+ cells[s] = buffer[s*2] | buffer[(s*2)+1] << 8;
}
- ret = lpcCommand(dev, 'v', 1, statusResult);
+ ret = lpcCommand(dev, 'v', 1, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
@@ -187,7 +190,7 @@ static ssize_t showCells(struct device *dev, struct device_attribute *attr, char
for(uint8_t s = 0; s < 4; s++)
{
- cells[s+4] = statusResult[s*2] | statusResult[(s*2)+1] << 8;
+ cells[s+4] = buffer[s*2] | buffer[(s*2)+1] << 8;
}
for(uint8_t s = 0; s < 8; s++)
@@ -215,7 +218,6 @@ static ssize_t showFirmware(struct device *dev, struct device_attribute *attr, c
uint8_t str3[9];
int ret = 0;
-
ret = lpcCommand(dev, 'f', 0, str1);
if (ret)
{
@@ -245,24 +247,23 @@ static ssize_t showCapacity(struct device *dev, struct device_attribute *attr, c
{
uint8_t buffer[8];
int ret = 0;
- uint16_t cap_accu, cap_min, cap_max;
+ uint16_t cap_accu_mah, cap_min_mah, cap_max_mah;
ret = lpcCommand(dev, 'c', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
}
- // units in mAh
- cap_accu = buffer[0] | (buffer[1] << 8);
- cap_min = buffer[2] | (buffer[3] << 8);
- cap_max = buffer[4] | (buffer[5] << 8);
+ cap_accu_mah = buffer[0] | (buffer[1] << 8);
+ cap_min_mah = buffer[2] | (buffer[3] << 8);
+ cap_max_mah = buffer[4] | (buffer[5] << 8);
- return snprintf(buf, PAGE_SIZE, "%d %d %d", cap_accu, cap_min, cap_max);
+ return snprintf(buf, PAGE_SIZE, "%d %d %d", cap_accu_mah, cap_min_mah, cap_max_mah);
}
static ssize_t lpcCommand(struct device *dev, char command, uint8_t arg1, uint8_t *responseBuffer)
{
- T_PRIVATE_DATA *data = (T_PRIVATE_DATA *)dev_get_drvdata(dev);
+ struct lpc_driver_data *data = (struct lpc_driver_data *)dev_get_drvdata(dev);
uint8_t commandBuffer[4] = {0xB5, command, arg1, 0x0};
int ret = 0;
@@ -273,6 +274,7 @@ static ssize_t lpcCommand(struct device *dev, char command, uint8_t arg1, uint8_
{
printk(KERN_INFO "%s: spi_write failed\n", __func__);
}
+ // todo, replace with wait timer?
mdelay(70);
ret = spi_read(data->spi, responseBuffer, 8);
@@ -280,26 +282,28 @@ static ssize_t lpcCommand(struct device *dev, char command, uint8_t arg1, uint8_
{
printk(KERN_INFO "%s: spi_read failed\n", __func__);
}
+ // todo, replace with wait timer?
mdelay(70);
mutex_unlock(&data->lock);
return ret;
}
-static int bat_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
+static int getBatProperty(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
{
int ret = 0;
uint8_t buffer[8];
- T_PRIVATE_DATA *data;
+ struct lpc_driver_data *data;
struct device *dev;
- int16_t temp = 0;
+ int16_t amp;
- data = (T_PRIVATE_DATA *)power_supply_get_drvdata(psy);
+ data = (struct lpc_driver_data *)power_supply_get_drvdata(psy);
dev = &(data->spi->dev);
- switch (psp) {
+ switch (psp)
+ {
case POWER_SUPPLY_PROP_STATUS:
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
ret = lpcCommand(dev, 'q', 0, buffer);
@@ -307,14 +311,14 @@ static int bat_get_property(struct power_supply *psy,
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
}
- temp = (int16_t)buffer[2] | ((int16_t)buffer[3] << 8);
- if(temp < 0)
+ amp = (int16_t)buffer[2] | ((int16_t)buffer[3] << 8);
+ if (amp < 0)
{
val->intval = POWER_SUPPLY_STATUS_CHARGING;
}
- else if(temp == 0)
+ else if (amp == 0)
{
- if(buffer[4] == 100)
+ if (buffer[4] == 100)
{
val->intval = POWER_SUPPLY_STATUS_FULL;
}
@@ -325,60 +329,82 @@ static int bat_get_property(struct power_supply *psy,
}
else
{
- val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
}
break;
+
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
break;
+
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = lpcCommand(dev, 'q', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
+ ret = -EINVAL;
}
val->intval = (buffer[0] | buffer[1] << 8) * 1000;
break;
+
case POWER_SUPPLY_PROP_CURRENT_NOW:
ret = lpcCommand(dev, 'q', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
+ ret = -EINVAL;
}
- val->intval = (buffer[2] | buffer[3] << 8) * 1000;
+ amp = (int16_t)buffer[2] | ((int16_t)buffer[3] << 8);
+ // negative current, battery is charging
+ // reporting a negative value is out of spec
+ if(amp < 0)
+ {
+ amp = 0;
+ }
+ val->intval = amp * 1000;
break;
+
case POWER_SUPPLY_PROP_CAPACITY:
ret = lpcCommand(dev, 'q', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
+ ret = -EINVAL;
}
val->intval = buffer[4];
break;
+
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
ret = lpcCommand(dev, 'c', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
+ ret = -EINVAL;
}
val->intval = (buffer[4] | buffer[5] << 8) * 1000;
break;
+
case POWER_SUPPLY_PROP_CHARGE_NOW:
ret = lpcCommand(dev, 'c', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
+ ret = -EINVAL;
}
val->intval = (buffer[0] | buffer[1] << 8) * 1000;
break;
+
case POWER_SUPPLY_PROP_CHARGE_EMPTY:
ret = lpcCommand(dev, 'c', 0, buffer);
if (ret)
{
printk(KERN_INFO "%s: lpcCommand failed\n", __func__);
+ ret = -EINVAL;
}
val->intval = (buffer[2] | buffer[3] << 8) * 1000;
break;
+
default:
val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
ret = -EINVAL;
@@ -387,33 +413,20 @@ static int bat_get_property(struct power_supply *psy,
return ret;
}
-// enum state_t {
-// ST_CHARGE, -- charging
-// ST_OVERVOLTED, -- charging? full? balancing
-// ST_COOLDOWN, -- charging? full? balancing
-// ST_UNDERVOLTED, -- cells under voltage, discharging?
-// ST_MISSING, -- cells missing
-// ST_FULLY_CHARGED, -- full charged
-// ST_POWERSAVE -- deep sleep of lpc
-// };
-
static const struct of_device_id of_tis_spi_match[] = {
{.compatible = "mntre,lpc11u24", .data = 0},
- {.compatible = "mntre,lpc-reform2", .data = 0},
{}};
MODULE_DEVICE_TABLE(of, of_tis_spi_match);
static struct spi_device_id g_spi_dev_id_list[] = {
- /* device name, device id */
{ "lpc11u24", 0 },
- { "lpc-reform2", 0 },
{ },
};
MODULE_DEVICE_TABLE(spi, g_spi_dev_id_list);
static struct spi_driver g_spi_driver = {
- .probe = spiProbe,
- .remove = spiRemove,
+ .probe = lpcProbe,
+ .remove = lpcRemove,
.driver = {
.of_match_table = of_match_ptr(of_tis_spi_match),
.owner = THIS_MODULE,