mirror of
https://gitlab.com/manzerbredes/ina260-sysfs-driver.git
synced 2025-04-19 04:09:45 +00:00
Minor changes
This commit is contained in:
parent
e2e40a7305
commit
b5382a57fd
1 changed files with 33 additions and 76 deletions
109
ina260.c
109
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) \
|
static ssize_t _attr##_show(struct device *dev, struct device_attribute *attr, char *buf) \
|
||||||
{ \
|
{ \
|
||||||
unsigned int rvalue; \
|
unsigned int rvalue; \
|
||||||
|
int err; \
|
||||||
struct client_data *cdata=dev_get_drvdata(dev); \
|
struct client_data *cdata=dev_get_drvdata(dev); \
|
||||||
if(regmap_read(cdata->regmap, (_reg), &rvalue)) \
|
err = regmap_read(cdata->regmap, (_reg), &rvalue); \
|
||||||
return -1; \
|
if(err>0) \
|
||||||
|
return err; \
|
||||||
return sprintf(buf, "%x\n", rvalue); \
|
return sprintf(buf, "%x\n", rvalue); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INA260_REG_STORE(_attr,_reg) \
|
#define INA260_REG_STORE(_attr,_reg) \
|
||||||
static ssize_t _attr##_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
|
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); \
|
struct client_data *cdata=dev_get_drvdata(dev); \
|
||||||
if(kstrtoint(buf, 0,&uvalue)) \
|
if(kstrtoint(buf, 0,&uvalue)) \
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
if(regmap_write(cdata->regmap, (_reg), uvalue)) \
|
err = regmap_write(cdata->regmap, (_reg), uvalue); \
|
||||||
return -1; \
|
if(err>0) \
|
||||||
|
return err; \
|
||||||
return count; \
|
return count; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +61,6 @@ static ssize_t _attr##_store(struct device *dev, struct device_attribute *attr,
|
||||||
// Data attached to i2c clients
|
// Data attached to i2c clients
|
||||||
struct client_data {
|
struct client_data {
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
unsigned char reg; // Slave selected register
|
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,60 +70,40 @@ static const struct i2c_device_id ina260_ids[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(i2c,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,
|
static int ina260_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
||||||
u32 attr, int channel, long *val)
|
u32 attr, int channel, long *val)
|
||||||
{
|
{
|
||||||
int rvalue;
|
int rvalue, reg, err;
|
||||||
struct client_data *cdata=dev_get_drvdata(dev);
|
struct client_data *cdata=dev_get_drvdata(dev);
|
||||||
if(type == hwmon_power){
|
switch(type){
|
||||||
if(regmap_read(cdata->regmap, INA260_REG_POWER, &rvalue))
|
case hwmon_power:
|
||||||
return -1;
|
reg=INA260_REG_POWER;
|
||||||
*val=10*rvalue*1000;
|
break;
|
||||||
} else if (type == hwmon_curr){
|
case hwmon_curr:
|
||||||
if(regmap_read(cdata->regmap, INA260_REG_CURRENT, &rvalue))
|
reg=INA260_REG_CURRENT;
|
||||||
return -1;
|
break;
|
||||||
*val=((rvalue*25/100) + rvalue)*100+(rvalue*25%100);
|
case hwmon_in:
|
||||||
*val/=100;
|
reg=INA260_REG_VOLTAGE;
|
||||||
} else if (type == hwmon_in){
|
break;
|
||||||
if(regmap_read(cdata->regmap, INA260_REG_VOLTAGE, &rvalue))
|
default:
|
||||||
return -1;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
*val=((rvalue*25/100) + rvalue)*100+(rvalue*25%100);
|
|
||||||
*val/=100; // Skip remainder here
|
|
||||||
}
|
}
|
||||||
|
err=regmap_read(cdata->regmap, reg, &rvalue);
|
||||||
return 0;
|
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,
|
static int ina260_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
|
||||||
u32 attr, int channel, long val)
|
u32 attr, int channel, long val)
|
||||||
{
|
{
|
||||||
return 0;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
INA260_REG_SHOW(configuration,INA260_REG_CONFIGURATION)
|
INA260_REG_SHOW(configuration,INA260_REG_CONFIGURATION)
|
||||||
|
@ -187,24 +169,6 @@ static const struct attribute_group registers_group = {
|
||||||
.name = "registers"
|
.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[] = {
|
const struct attribute_group *extra_groups[] = {
|
||||||
®isters_group,
|
®isters_group,
|
||||||
NULL
|
NULL
|
||||||
|
@ -214,17 +178,10 @@ static int ina260_probe_new(struct i2c_client *client){
|
||||||
struct client_data *p;
|
struct client_data *p;
|
||||||
struct device *hwmon_dev;
|
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:
|
// 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=kzalloc(sizeof(struct client_data),GFP_KERNEL);
|
||||||
p->client=client;
|
p->client=client;
|
||||||
p->reg=INA260_REG_DIE; // Maintain cache coherence
|
|
||||||
p->regmap = devm_regmap_init_i2c(client, &ina260_regmap_config);
|
p->regmap = devm_regmap_init_i2c(client, &ina260_regmap_config);
|
||||||
|
|
||||||
hwmon_dev=hwmon_device_register_with_info(&client->dev,client->name,p,
|
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);
|
struct client_data *p=i2c_get_clientdata(client);
|
||||||
kfree(p);
|
kfree(p);
|
||||||
hwmon_device_unregister(&client->dev);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue