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; - *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 + 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; } - - return 0; + err=regmap_read(cdata->regmap, reg, &rvalue); + if(err<0){ + return err; + } else if(type == hwmon_power) { + *val=10*rvalue*1000; + } else{ + *val=div_u64(rvalue*25,100)+rvalue; + } + 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,®,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[] = { ®isters_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; }