summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xina260.c107
1 files changed, 32 insertions, 75 deletions
diff --git a/ina260.c b/ina260.c
index e77f377..030d424 100755
--- a/ina260.c
+++ b/ina260.c
@@ -29,21 +29,24 @@ static struct regmap_config ina260_regmap_config = {
static ssize_t _attr##_show(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
unsigned int rvalue; \
+ int err; \
struct client_data *cdata=dev_get_drvdata(dev); \
- if(regmap_read(cdata->regmap, (_reg), &rvalue)) \
- return -1; \
+ err = regmap_read(cdata->regmap, (_reg), &rvalue); \
+ if(err>0) \
+ return err; \
return sprintf(buf, "%x\n", rvalue); \
}
#define INA260_REG_STORE(_attr,_reg) \
static ssize_t _attr##_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
{ \
- int uvalue; \
+ int uvalue, err; \
struct client_data *cdata=dev_get_drvdata(dev); \
if(kstrtoint(buf, 0,&uvalue)) \
return -EINVAL; \
- if(regmap_write(cdata->regmap, (_reg), uvalue)) \
- return -1; \
+ err = regmap_write(cdata->regmap, (_reg), uvalue); \
+ if(err>0) \
+ return err; \
return count; \
}
@@ -58,7 +61,6 @@ static ssize_t _attr##_store(struct device *dev, struct device_attribute *attr,
// Data attached to i2c clients
struct client_data {
struct i2c_client *client;
- unsigned char reg; // Slave selected register
struct regmap *regmap;
};
@@ -68,60 +70,40 @@ static const struct i2c_device_id ina260_ids[] = {
};
MODULE_DEVICE_TABLE(i2c,ina260_ids);
-/**
- * @brief Read from ina260 registers
- *
- * @param cdata client data to use to communicate
- * @param reg register to read
- * @param value register content output
- * @return int 0 on success, 1 on communication errors
- */
-static int ina260_read_register(struct client_data* cdata, unsigned char reg, unsigned int *value){
- return regmap_read(cdata->regmap, reg, value);
-}
-
-/**
- * @brief Write to ina260 registers
- *
- * @param cdata client data to use to communicate
- * @param reg register to write to
- * @param value value to write in @a reg
- * @return int 0 on success, 1 on communication errors
- */
-static int ina260_write_register(struct client_data* cdata, unsigned char reg, int value){
- return regmap_write(cdata->regmap, reg, value);
-}
-
static int ina260_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{
- int rvalue;
+ int rvalue, reg, err;
struct client_data *cdata=dev_get_drvdata(dev);
- if(type == hwmon_power){
- if(regmap_read(cdata->regmap, INA260_REG_POWER, &rvalue))
- return -1;
+ switch(type){
+ case hwmon_power:
+ reg=INA260_REG_POWER;
+ break;
+ case hwmon_curr:
+ reg=INA260_REG_CURRENT;
+ break;
+ case hwmon_in:
+ reg=INA260_REG_VOLTAGE;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ err=regmap_read(cdata->regmap, reg, &rvalue);
+ if(err<0){
+ return err;
+ } else if(type == hwmon_power) {
*val=10*rvalue*1000;
- } else if (type == hwmon_curr){
- if(regmap_read(cdata->regmap, INA260_REG_CURRENT, &rvalue))
- return -1;
- *val=((rvalue*25/100) + rvalue)*100+(rvalue*25%100);
- *val/=100;
- } else if (type == hwmon_in){
- if(regmap_read(cdata->regmap, INA260_REG_VOLTAGE, &rvalue))
- return -1;
-
- *val=((rvalue*25/100) + rvalue)*100+(rvalue*25%100);
- *val/=100; // Skip remainder here
+ } else{
+ *val=div_u64(rvalue*25,100)+rvalue;
}
-
- return 0;
+ return 0;
}
static int ina260_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{
- return 0;
+ return -EOPNOTSUPP;
}
INA260_REG_SHOW(configuration,INA260_REG_CONFIGURATION)
@@ -187,24 +169,6 @@ static const struct attribute_group registers_group = {
.name = "registers"
};
-
-/**
- * @brief Compare on ina260 register to a supplied value
- *
- * @param client i2c client to use for communications
- * @param reg register to use for comparison
- * @param value register expected value
- * @return int 0 if register contains value and 1 otherwise
- */
-static int ina260_probe_register(struct i2c_client *client, unsigned char reg, int value){
- unsigned char bytes[2];
- if(i2c_master_send(client,&reg,1)<0)
- return 1;
- if(i2c_master_recv(client,bytes,2)<0)
- return 1;
- return ((bytes[0]<<8) | bytes[1])!=value;
-}
-
const struct attribute_group *extra_groups[] = {
&registers_group,
NULL
@@ -214,17 +178,10 @@ static int ina260_probe_new(struct i2c_client *client){
struct client_data *p;
struct device *hwmon_dev;
- // Attempt device discovery:
- if(ina260_probe_register(client,INA260_REG_MANUFACTURER,0x5449) ||
- ina260_probe_register(client,INA260_REG_DIE,0x2270)){
- printk("ina260 probe fails bus=%d address=0x%02x\n",client->adapter->nr,client->addr);
- return 1;
- }
// Initialize client data:
- printk("ina260 detected bus=%d address=0x%02x\n",client->adapter->nr,client->addr);
+ printk("Adding ina260 [bus=%d address=0x%02x]\n",client->adapter->nr,client->addr);
p=kzalloc(sizeof(struct client_data),GFP_KERNEL);
p->client=client;
- p->reg=INA260_REG_DIE; // Maintain cache coherence
p->regmap = devm_regmap_init_i2c(client, &ina260_regmap_config);
hwmon_dev=hwmon_device_register_with_info(&client->dev,client->name,p,
@@ -238,7 +195,7 @@ static int ina260_remove(struct i2c_client *client){
struct client_data *p=i2c_get_clientdata(client);
kfree(p);
hwmon_device_unregister(&client->dev);
- printk("ina260 removed bus=%d address=0x%02x\n",client->adapter->nr,client->addr);
+ printk("Removing ina260 [bus=%d address=0x%02x]\n",client->adapter->nr,client->addr);
return 0;
}