mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
ODROID-XU3: add Hardkernel INA231 driver
Change-Id: I27f0fd585e58da786d0e34dfcf35fb6b9c1be36b
This commit is contained in:
65
arch/arm/boot/dts/exynos5422-odroidxu3.dts
Normal file → Executable file
65
arch/arm/boot/dts/exynos5422-odroidxu3.dts
Normal file → Executable file
@@ -20,35 +20,60 @@
|
||||
compatible = "hardkernel,odroid-xu3", "samsung,exynos5800", "samsung,exynos5";
|
||||
};
|
||||
|
||||
/*
|
||||
i2c0 INA231 Sensors
|
||||
|
||||
- drivers/hardkernel/ina231.h
|
||||
|
||||
config = INA231_CONFIG(VSH_CT(eVSH_CT_8244uS) | \
|
||||
VBUS_CT(eVBUS_CT_8244uS) | \
|
||||
AVG_BIT(eAVG_16) | \
|
||||
eSHUNT_BUS_VOLT_CONTINUOUS),
|
||||
update_period = CONVERSION_DELAY(eVSH_CON_8244uS, eVBUS_CON_8244uS, eAVG_CON_16),
|
||||
*/
|
||||
|
||||
&i2c_0 {
|
||||
status = "okay";
|
||||
|
||||
/* A15 cluster: VDD_ARM */
|
||||
ina231@40 {
|
||||
compatible = "ti,ina231";
|
||||
clock-frequency = <400000>;
|
||||
ina231@40 {
|
||||
compatible = "hardkernel,INA231";
|
||||
reg = <0x40>;
|
||||
shunt-resistor = <10000>;
|
||||
sensor-name = "sensor_arm";
|
||||
enable = <0>;
|
||||
max_A = <9>;
|
||||
shunt_R_mohm = <10>;
|
||||
config = <0x45FF>;
|
||||
update_period = <263808>;
|
||||
};
|
||||
|
||||
/* memory: VDD_MEM */
|
||||
ina231@41 {
|
||||
compatible = "ti,ina231";
|
||||
ina231@41 {
|
||||
compatible = "hardkernel,INA231";
|
||||
reg = <0x41>;
|
||||
shunt-resistor = <10000>;
|
||||
sensor-name = "sensor_mem";
|
||||
enable = <0>;
|
||||
max_A = <3>;
|
||||
shunt_R_mohm = <10>;
|
||||
config = <0x45FF>;
|
||||
update_period = <263808>;
|
||||
};
|
||||
|
||||
/* GPU: VDD_G3D */
|
||||
ina231@44 {
|
||||
compatible = "ti,ina231";
|
||||
ina231@44 {
|
||||
compatible = "hardkernel,INA231";
|
||||
reg = <0x44>;
|
||||
shunt-resistor = <10000>;
|
||||
sensor-name = "sensor_g3d";
|
||||
enable = <0>;
|
||||
max_A = <5>;
|
||||
shunt_R_mohm = <10>;
|
||||
config = <0x45FF>;
|
||||
update_period = <263808>;
|
||||
};
|
||||
|
||||
/* A7 cluster: VDD_KFC */
|
||||
ina231@45 {
|
||||
compatible = "ti,ina231";
|
||||
ina231@45 {
|
||||
compatible = "hardkernel,INA231";
|
||||
reg = <0x45>;
|
||||
shunt-resistor = <10000>;
|
||||
sensor-name = "sensor_kfc";
|
||||
enable = <0>;
|
||||
max_A = <2>;
|
||||
shunt_R_mohm = <10>;
|
||||
config = <0x45FF>;
|
||||
update_period = <263808>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -202,4 +202,6 @@ source "drivers/hwtracing/intel_th/Kconfig"
|
||||
|
||||
source "drivers/fpga/Kconfig"
|
||||
|
||||
# Hardkernel Specific drivers
|
||||
source "drivers/hardkernel/Kconfig"
|
||||
endmenu
|
||||
|
||||
@@ -173,3 +173,6 @@ obj-$(CONFIG_STM) += hwtracing/stm/
|
||||
obj-$(CONFIG_ANDROID) += android/
|
||||
obj-$(CONFIG_NVMEM) += nvmem/
|
||||
obj-$(CONFIG_FPGA) += fpga/
|
||||
|
||||
# Hardkernel Specific drivers
|
||||
obj-y += hardkernel/
|
||||
|
||||
10
drivers/hardkernel/Kconfig
Executable file
10
drivers/hardkernel/Kconfig
Executable file
@@ -0,0 +1,10 @@
|
||||
menu "ODROID Specific Hardware"
|
||||
|
||||
config ODROID_EXYNOS5_SP
|
||||
tristate "Enable the INA231 Sensor on ODROID-EXYNOS5"
|
||||
depends on I2C && ARCH_EXYNOS5
|
||||
default n
|
||||
---help---
|
||||
Enables the INA231 Sensor on ODROID-EXYNOS5
|
||||
endmenu
|
||||
|
||||
2
drivers/hardkernel/Makefile
Executable file
2
drivers/hardkernel/Makefile
Executable file
@@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_ODROID_EXYNOS5_SP) += ina231-sensor.o
|
||||
ina231-sensor-y := ina231-misc.o ina231-sysfs.o ina231-i2c.o
|
||||
341
drivers/hardkernel/ina231-i2c.c
Executable file
341
drivers/hardkernel/ina231-i2c.c
Executable file
@@ -0,0 +1,341 @@
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//
|
||||
//
|
||||
// I2C INA231(Sensor) driver
|
||||
// 2013.07.17
|
||||
//
|
||||
//
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#include "ina231.h"
|
||||
#include "ina231-misc.h"
|
||||
#include "ina231-sysfs.h"
|
||||
|
||||
//#define DEBUG_INA231
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//
|
||||
// function prototype
|
||||
//
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static void __exit ina231_i2c_exit (void);
|
||||
static int __init ina231_i2c_init (void);
|
||||
static int ina231_i2c_remove (struct i2c_client *client);
|
||||
static int ina231_i2c_probe (struct i2c_client *client, const struct i2c_device_id *id);
|
||||
static void ina231_work (struct work_struct *work);
|
||||
int ina231_i2c_read (struct i2c_client *client, unsigned char cmd);
|
||||
int ina231_i2c_write (struct i2c_client *client, unsigned char cmd, unsigned short data);
|
||||
void ina231_i2c_enable (struct ina231_sensor *sensor);
|
||||
|
||||
static enum hrtimer_restart ina231_timer (struct hrtimer *timer);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
int ina231_i2c_read(struct i2c_client *client, unsigned char cmd)
|
||||
{
|
||||
struct i2c_msg msg[2];
|
||||
int ret;
|
||||
|
||||
unsigned char buf[2];
|
||||
|
||||
memset(msg, 0x00, sizeof(msg));
|
||||
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].len = 1;
|
||||
msg[0].buf = &cmd;
|
||||
|
||||
msg[1].addr = client->addr;
|
||||
msg[1].flags = I2C_M_RD;
|
||||
msg[1].len = 2;
|
||||
msg[1].buf = &buf[0];
|
||||
|
||||
if ((ret = i2c_transfer(client->adapter, msg, 2)) != 2) {
|
||||
dev_err(&client->dev, "I2C read error: (%d) reg: 0x%X \n", ret, cmd);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = ((buf[0] << 8) | buf[1]) & 0xFFFF;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
int ina231_i2c_write(struct i2c_client *client, unsigned char cmd, unsigned short data)
|
||||
{
|
||||
int ret;
|
||||
unsigned char block_data[3];
|
||||
|
||||
memset(block_data, 0x00, sizeof(block_data));
|
||||
|
||||
block_data[0] = cmd;
|
||||
block_data[1] = (data >> 8) & 0xFF;
|
||||
block_data[2] = (data ) & 0xFF;
|
||||
|
||||
if ((ret = i2c_master_send(client, block_data, 3)) < 0) {
|
||||
dev_err(&client->dev, "I2C write error: (%d) reg: 0x%X \n", ret, cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
void ina231_i2c_enable(struct ina231_sensor *sensor)
|
||||
{
|
||||
hrtimer_start(&sensor->timer,
|
||||
ktime_set(sensor->timer_sec, sensor->timer_nsec),
|
||||
HRTIMER_MODE_REL);
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static void ina231_work (struct work_struct *work)
|
||||
{
|
||||
struct ina231_sensor *sensor = container_of(work, struct ina231_sensor, work);
|
||||
|
||||
if (sensor->pd->enable) {
|
||||
sensor->reg_bus_volt = ina231_i2c_read(sensor->client, REG_BUS_VOLT);
|
||||
sensor->reg_current = ina231_i2c_read(sensor->client, REG_CURRENT );
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
sensor->cur_uV = sensor->reg_bus_volt * FIX_uV_LSB;
|
||||
sensor->cur_uA = sensor->reg_current * sensor->cur_lsb_uA;
|
||||
sensor->cur_uW = (sensor->cur_uV / 1000 ) * (sensor->cur_uA / 1000);
|
||||
|
||||
if ((sensor->cur_uV > sensor->max_uV) || (sensor->cur_uA > sensor->cur_uA)) {
|
||||
sensor->max_uV = sensor->cur_uV;
|
||||
sensor->max_uA = sensor->cur_uA;
|
||||
sensor->max_uW = sensor->cur_uW;
|
||||
}
|
||||
mutex_unlock(&sensor->mutex);
|
||||
}
|
||||
else {
|
||||
sensor->cur_uV = 0;
|
||||
sensor->cur_uA = 0;
|
||||
sensor->cur_uW = 0;
|
||||
}
|
||||
|
||||
#if defined(DEBUG_INA231)
|
||||
printk("%s : BUS Voltage = %06d uV, %1d.%06d V\n",
|
||||
sensor->pd->name, sensor->cur_uV,
|
||||
sensor->cur_uV/1000000,
|
||||
sensor->cur_uV%1000000);
|
||||
printk("%s : Curent = %06d uA, %1d.%06d A\n",
|
||||
sensor->pd->name, sensor->cur_uA,
|
||||
sensor->cur_uA/1000000,
|
||||
sensor->cur_uA%1000000);
|
||||
printk("%s : Powert = %06d uW, %1d.%06d W\n",
|
||||
sensor->pd->name, sensor->cur_uW,
|
||||
sensor->cur_uW/1000000,
|
||||
sensor->cur_uW%1000000);
|
||||
#endif
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static enum hrtimer_restart ina231_timer(struct hrtimer *timer)
|
||||
{
|
||||
struct ina231_sensor *sensor = container_of(timer, struct ina231_sensor, timer);
|
||||
|
||||
queue_work(sensor->wq, &sensor->work);
|
||||
|
||||
if (sensor->pd->enable) ina231_i2c_enable(sensor);
|
||||
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#ifdef CONFIG_OF
|
||||
static int ina231_i2c_dt_parse(struct i2c_client *client, struct ina231_sensor *sensor)
|
||||
{
|
||||
struct device_node *sensor_np = client->dev.of_node;
|
||||
const char *sensor_name;
|
||||
unsigned int rdata;
|
||||
|
||||
if (!(sensor->pd = devm_kzalloc(&client->dev, sizeof(struct ina231_pd),
|
||||
GFP_KERNEL))) {
|
||||
dev_err(&client->dev, "INA231 Sensor platform data struct malloc error!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (of_property_read_string(sensor_np, "sensor-name", &sensor_name))
|
||||
return -1;
|
||||
sensor->pd->name = (unsigned char *)sensor_name;
|
||||
|
||||
if (of_property_read_u32(sensor_np, "enable", &rdata))
|
||||
return -1;
|
||||
sensor->pd->enable = rdata;
|
||||
|
||||
if (of_property_read_u32(sensor_np, "max_A", &rdata))
|
||||
return -1;
|
||||
sensor->pd->max_A = rdata;
|
||||
|
||||
if (of_property_read_u32(sensor_np, "shunt_R_mohm", &rdata))
|
||||
return -1;
|
||||
sensor->pd->shunt_R_mohm = rdata;
|
||||
|
||||
if (of_property_read_u32(sensor_np, "config", &rdata))
|
||||
return -1;
|
||||
sensor->pd->config = rdata;
|
||||
|
||||
if (of_property_read_u32(sensor_np, "update_period", &rdata))
|
||||
return -1;
|
||||
sensor->pd->update_period = rdata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // CONFIG_OF
|
||||
static int ina231_i2c_dt_parse(struct i2c_client *client, struct ina231_sensor *sensor)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static int ina231_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
int rc = 0;
|
||||
struct ina231_sensor *sensor;
|
||||
|
||||
if (!(sensor = devm_kzalloc(&client->dev, sizeof(struct ina231_sensor),
|
||||
GFP_KERNEL))) {
|
||||
dev_err(&client->dev, "INA231 Sensor struct malloc error!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
// mutex init
|
||||
mutex_init(&sensor->mutex);
|
||||
|
||||
sensor->client = client;
|
||||
|
||||
if (client->dev.of_node) {
|
||||
if(ina231_i2c_dt_parse(client, sensor) < 0)
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
sensor->pd = client->dev.platform_data;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, sensor);
|
||||
|
||||
// Calculate current lsb value
|
||||
sensor->cur_lsb_uA = sensor->pd->max_A * 1000000 / 32768;
|
||||
// Calculate register value
|
||||
sensor->reg_calibration = 5120000 / (sensor->cur_lsb_uA * sensor->pd->shunt_R_mohm);
|
||||
|
||||
if ((rc = ina231_i2c_write(sensor->client, REG_CONFIG, sensor->pd->config)) < 0)
|
||||
goto out;
|
||||
if ((rc = ina231_i2c_write(sensor->client, REG_CALIBRATION, sensor->reg_calibration)) < 0)
|
||||
goto out;
|
||||
if ((rc = ina231_i2c_write(sensor->client, REG_ALERT_EN, 0x0000)) < 0)
|
||||
goto out;
|
||||
if ((rc = ina231_i2c_write(sensor->client, REG_ALERT_LIMIT, 0x0000)) < 0)
|
||||
goto out;
|
||||
|
||||
if ((rc = ina231_i2c_read(sensor->client, REG_CONFIG)) != sensor->pd->config)
|
||||
goto out;
|
||||
if ((rc = ina231_i2c_read(sensor->client, REG_CALIBRATION)) != sensor->reg_calibration )
|
||||
goto out;
|
||||
if ((rc = ina231_i2c_read(sensor->client, REG_ALERT_EN)) != 0x0000)
|
||||
goto out;
|
||||
if ((rc = ina231_i2c_read(sensor->client, REG_ALERT_LIMIT)) != 0x0000)
|
||||
goto out;
|
||||
|
||||
// misc driver probe
|
||||
if (ina231_misc_probe(sensor) < 0)
|
||||
goto out;
|
||||
|
||||
// sysfs probe
|
||||
if (ina231_sysfs_create(&client->dev) < 0)
|
||||
goto out;
|
||||
|
||||
// timer run for sensor data receive
|
||||
INIT_WORK(&sensor->work, ina231_work);
|
||||
if ((sensor->wq = create_singlethread_workqueue("ina231_wq")) == NULL) goto out;
|
||||
|
||||
hrtimer_init(&sensor->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
sensor->timer_sec = sensor->pd->update_period / 1000000;
|
||||
sensor->timer_nsec = sensor->pd->update_period % 1000000;
|
||||
sensor->timer_nsec = sensor->timer_nsec * 1000;
|
||||
sensor->timer.function = ina231_timer;
|
||||
|
||||
if (sensor->pd->enable) ina231_i2c_enable(sensor);
|
||||
|
||||
// display register message
|
||||
rc = 0;
|
||||
dev_info(&client->dev, "============= Probe INA231 : %s ============= \n",
|
||||
sensor->pd->name);
|
||||
dev_info(&client->dev, "SENSOR ENABLE : %s\n" ,
|
||||
sensor->pd->enable ? "true" : "false");
|
||||
dev_info(&client->dev, "REG CONFIG : 0x%04X\n" ,
|
||||
sensor->pd->config );
|
||||
dev_info(&client->dev, "REG CALIBRATION : 0x%04X\n" ,
|
||||
sensor->reg_calibration );
|
||||
dev_info(&client->dev, "SHUNT Resister : %d mOhm\n",
|
||||
sensor->pd->shunt_R_mohm );
|
||||
dev_info(&client->dev, "MAX Current : %d A\n" ,
|
||||
sensor->pd->max_A );
|
||||
dev_info(&client->dev, "Current LSB uA : %d uA\n" ,
|
||||
sensor->cur_lsb_uA );
|
||||
dev_info(&client->dev, "Conversion Time : %d us\n" ,
|
||||
sensor->pd->update_period );
|
||||
dev_info(&client->dev, "=====================================================\n");
|
||||
|
||||
return 0;
|
||||
out:
|
||||
dev_err(&client->dev, "============= Probe INA231 Fail! : %s (0x%04X) ============= \n",
|
||||
sensor->pd->name, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static int ina231_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(&client->dev);
|
||||
|
||||
// removed sysfs entry
|
||||
ina231_sysfs_remove(&client->dev);
|
||||
// removed misc drv
|
||||
ina231_misc_remove(&client->dev);
|
||||
// timer
|
||||
if (sensor->pd->enable) hrtimer_cancel(&sensor->timer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static const struct i2c_device_id ina231_id[] = {
|
||||
{ INA231_I2C_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, ina231_id);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static struct i2c_driver ina231_i2c_driver = {
|
||||
.driver = {
|
||||
.name = INA231_I2C_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ina231_i2c_probe,
|
||||
.remove = ina231_i2c_remove,
|
||||
.id_table = ina231_id,
|
||||
};
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static int __init ina231_i2c_init(void)
|
||||
{
|
||||
return i2c_add_driver(&ina231_i2c_driver);
|
||||
}
|
||||
module_init(ina231_i2c_init);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static void __exit ina231_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&ina231_i2c_driver);
|
||||
}
|
||||
module_exit(ina231_i2c_exit);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
24
drivers/hardkernel/ina231-i2c.h
Executable file
24
drivers/hardkernel/ina231-i2c.h
Executable file
@@ -0,0 +1,24 @@
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
//
|
||||
//
|
||||
//
|
||||
// I2C INA231(Sensor) driver
|
||||
// 2013.07.17
|
||||
//
|
||||
//
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
#ifndef _INA231_I2C_H_
|
||||
#define _INA231_I2C_H_
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
// extern function define
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
extern void ina231_i2c_enable (struct ina231_sensor *sensor);
|
||||
extern int ina231_i2c_read (struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len);
|
||||
extern int ina231_i2c_write (struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len);
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
#endif /* _INA231_I2C_H_ */
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
175
drivers/hardkernel/ina231-misc.c
Executable file
175
drivers/hardkernel/ina231-misc.c
Executable file
@@ -0,0 +1,175 @@
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//
|
||||
//
|
||||
// I2C INA231(Sensor) driver
|
||||
// 2013.07.17
|
||||
//
|
||||
//
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#include <linux/input.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/miscdevice.h>
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#include "ina231.h"
|
||||
#include "ina231-i2c.h"
|
||||
#include "ina231-misc.h"
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
// Global Sensor struct (sensor struct save for ioctl)
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
struct global_sensor {
|
||||
struct ina231_sensor *p;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
LIST_HEAD(SensorList);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//
|
||||
// function prototype
|
||||
//
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static int ina231_misc_open (struct inode *inode, struct file *file);
|
||||
static long ina231_misc_ioctl (struct file *file, unsigned int cmd, unsigned long arg);
|
||||
void ina231_misc_remove (struct device *dev);
|
||||
int ina231_misc_probe (struct ina231_sensor *sensor);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static const struct file_operations ina231_misc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ina231_misc_open,
|
||||
.unlocked_ioctl = ina231_misc_ioctl,
|
||||
};
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static long ina231_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct ina231_sensor *sensor = (struct ina231_sensor *)file->private_data;
|
||||
struct ina231_iocreg *iocreg = (struct ina231_iocreg *)arg;
|
||||
|
||||
switch (cmd) {
|
||||
// Get regisger
|
||||
case INA231_IOCGREG:
|
||||
iocreg->enable = sensor->pd->enable;
|
||||
if (sensor->pd->enable) {
|
||||
mutex_lock(&sensor->mutex);
|
||||
iocreg->cur_uV = sensor->cur_uV;
|
||||
iocreg->cur_uA = sensor->cur_uA;
|
||||
iocreg->cur_uW = sensor->cur_uW;
|
||||
mutex_unlock(&sensor->mutex);
|
||||
}
|
||||
else {
|
||||
iocreg->cur_uV = 0;
|
||||
iocreg->cur_uA = 0;
|
||||
iocreg->cur_uW = 0;
|
||||
}
|
||||
break;
|
||||
// Set status
|
||||
case INA231_IOCSSTATUS:
|
||||
if (sensor->pd->enable != iocreg->enable) {
|
||||
sensor->pd->enable = iocreg->enable;
|
||||
if (sensor->pd->enable) ina231_i2c_enable(sensor);
|
||||
}
|
||||
break;
|
||||
// Set status
|
||||
case INA231_IOCGSTATUS:
|
||||
iocreg->enable = sensor->pd->enable;
|
||||
memset(iocreg->name, 0x00, sizeof(iocreg->name));
|
||||
memcpy(iocreg->name, sensor->pd->name, sizeof(iocreg->name));
|
||||
break;
|
||||
default :
|
||||
printk("%s : unknown message!!\n", __func__);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static int ina231_misc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct global_sensor *gsensor;
|
||||
struct list_head *list_head;
|
||||
|
||||
printk("%s : %d\n", __func__, iminor(inode));
|
||||
|
||||
list_for_each(list_head, &SensorList)
|
||||
{
|
||||
gsensor = list_entry(list_head, struct global_sensor, list);
|
||||
|
||||
if (gsensor->p->misc->minor == iminor(inode)) {
|
||||
printk("find match sensor struct : name = %s\n",
|
||||
gsensor->p->pd->name);
|
||||
file->private_data = gsensor->p;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
int ina231_misc_probe(struct ina231_sensor *sensor)
|
||||
{
|
||||
int rc;
|
||||
struct miscdevice *pmisc;
|
||||
struct global_sensor *gsensor;
|
||||
|
||||
if (!(pmisc = devm_kzalloc(&sensor->client->dev,
|
||||
sizeof(struct miscdevice),
|
||||
GFP_KERNEL))) {
|
||||
printk("INA231 Sensor misc struct malloc error!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pmisc->minor = MISC_DYNAMIC_MINOR;
|
||||
pmisc->name = sensor->pd->name;
|
||||
pmisc->fops = &ina231_misc_fops;
|
||||
pmisc->mode = S_IWUGO | S_IRUGO;
|
||||
|
||||
sensor->misc = pmisc;
|
||||
|
||||
if ((rc = misc_register(sensor->misc)) < 0) {
|
||||
printk("%s : INA231 misc register fail!\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if(!(gsensor = (struct global_sensor *)devm_kzalloc(&sensor->client->dev,
|
||||
sizeof(struct global_sensor),
|
||||
GFP_KERNEL))) {
|
||||
printk("%s : INA231 global sensor malloc error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
else {
|
||||
gsensor->p = sensor;
|
||||
list_add(&gsensor->list, &SensorList);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
void ina231_misc_remove(struct device *dev)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
struct list_head *list_head;
|
||||
struct global_sensor *gsensor;
|
||||
|
||||
misc_deregister(sensor->misc);
|
||||
|
||||
list_for_each(list_head, &SensorList)
|
||||
{
|
||||
gsensor = list_entry(list_head, struct global_sensor, list);
|
||||
}
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
MODULE_AUTHOR("HardKernel Co., Ltd.");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("INA231 Current Sensor Driver");
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
33
drivers/hardkernel/ina231-misc.h
Executable file
33
drivers/hardkernel/ina231-misc.h
Executable file
@@ -0,0 +1,33 @@
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
//
|
||||
//
|
||||
//
|
||||
// I2C INA231(Sensor) driver
|
||||
// 2013.07.17
|
||||
//
|
||||
//
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
#ifndef _INA231_MISC_H_
|
||||
#define _INA231_MISC_H_
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
struct ina231_iocreg {
|
||||
unsigned char name[20];
|
||||
unsigned int enable;
|
||||
unsigned int cur_uV;
|
||||
unsigned int cur_uA;
|
||||
unsigned int cur_uW;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define INA231_IOCGREG _IOR('i', 1, struct ina231_iocreg *)
|
||||
#define INA231_IOCSSTATUS _IOW('i', 2, struct ina231_iocreg *)
|
||||
#define INA231_IOCGSTATUS _IOR('i', 3, struct ina231_iocreg *)
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
extern void ina231_misc_remove (struct device *dev);
|
||||
extern int ina231_misc_probe (struct ina231_sensor *sensor);
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
#endif // _INA231_MISC_H_
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
236
drivers/hardkernel/ina231-sysfs.c
Executable file
236
drivers/hardkernel/ina231-sysfs.c
Executable file
@@ -0,0 +1,236 @@
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//
|
||||
//
|
||||
// I2C INA231(Sensor) driver
|
||||
// 2013.07.17
|
||||
//
|
||||
//
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#include "ina231.h"
|
||||
#include "ina231-i2c.h"
|
||||
#include "ina231-misc.h"
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//
|
||||
// sysfs function prototype define
|
||||
//
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_name
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static DEVICE_ATTR(sensor_name, 0660, show_name, NULL);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_power
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static DEVICE_ATTR(sensor_W, 0660, show_power, NULL);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_current
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static DEVICE_ATTR(sensor_A, 0660, show_current, NULL);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_voltage
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static DEVICE_ATTR(sensor_V, 0660, show_voltage, NULL);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_max_power
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static DEVICE_ATTR(sensor_maxW, 0660, show_max_power, NULL);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_max_current
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static DEVICE_ATTR(sensor_maxA, 0660, show_max_current, NULL);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_max_voltage
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static DEVICE_ATTR(sensor_maxV, 0660, show_max_voltage, NULL);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_enable
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static ssize_t set_enable
|
||||
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
|
||||
static DEVICE_ATTR(enable, 0660, show_enable, set_enable);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_period
|
||||
(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
static DEVICE_ATTR(update_period, 0660, show_period, NULL);
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static struct attribute *ina231_sysfs_entries[] = {
|
||||
&dev_attr_sensor_name.attr,
|
||||
&dev_attr_sensor_W.attr,
|
||||
&dev_attr_sensor_A.attr,
|
||||
&dev_attr_sensor_V.attr,
|
||||
&dev_attr_sensor_maxW.attr,
|
||||
&dev_attr_sensor_maxA.attr,
|
||||
&dev_attr_sensor_maxV.attr,
|
||||
&dev_attr_enable.attr,
|
||||
&dev_attr_update_period.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group ina231_attr_group = {
|
||||
.name = NULL,
|
||||
.attrs = ina231_sysfs_entries,
|
||||
};
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_name
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "%s\n", sensor->pd->name);
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_power
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
unsigned int value;
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
value = sensor->cur_uW;
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
return sprintf(buf, "%d.%06d\n", (value/1000000), (value%1000000));
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_max_power
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
unsigned int value;
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
value = sensor->max_uW;
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
return sprintf(buf, "%d.%06d\n", (value/1000000), (value%1000000));
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_current
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
unsigned int value;
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
value = sensor->cur_uA;
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
return sprintf(buf, "%d.%06d\n", (value/1000000), (value%1000000));
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_max_current
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
unsigned int value;
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
value = sensor->max_uA;
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
return sprintf(buf, "%d.%06d\n", (value/1000000), (value%1000000));
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_voltage
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
unsigned int value;
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
value = sensor->cur_uV;
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
return sprintf(buf, "%d.%06d\n", (value/1000000), (value%1000000));
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_max_voltage
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
unsigned int value;
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
value = sensor->max_uV;
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
return sprintf(buf, "%d.%06d\n", (value/1000000), (value%1000000));
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_enable
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", sensor->pd->enable);
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t set_enable
|
||||
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
|
||||
if (simple_strtol(buf, NULL, 10) != 0) {
|
||||
if (!sensor->pd->enable) {
|
||||
sensor->pd->enable = 1;
|
||||
ina231_i2c_enable(sensor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (sensor->pd->enable) {
|
||||
sensor->pd->enable = 0;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
static ssize_t show_period
|
||||
(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ina231_sensor *sensor = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "%d usec\n", sensor->pd->update_period);
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
int ina231_sysfs_create (struct device *dev)
|
||||
{
|
||||
return sysfs_create_group(&dev->kobj, &ina231_attr_group);
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
void ina231_sysfs_remove (struct device *dev)
|
||||
{
|
||||
sysfs_remove_group(&dev->kobj, &ina231_attr_group);
|
||||
}
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
23
drivers/hardkernel/ina231-sysfs.h
Executable file
23
drivers/hardkernel/ina231-sysfs.h
Executable file
@@ -0,0 +1,23 @@
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
//
|
||||
//
|
||||
//
|
||||
// I2C INA231(Sensor) driver
|
||||
// 2013.07.17
|
||||
//
|
||||
//
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
#ifndef _INA231_SYSFS_H_
|
||||
#define _INA231_SYSFS_H_
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
// extern function define
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
extern int ina231_sysfs_create (struct device *dev);
|
||||
extern void ina231_sysfs_remove (struct device *dev);
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
#endif /* _INA231_SYSFS_H_ */
|
||||
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
//[*]--------------------------------------------------------------------------------------------------[*]
|
||||
170
drivers/hardkernel/ina231.h
Executable file
170
drivers/hardkernel/ina231.h
Executable file
@@ -0,0 +1,170 @@
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//
|
||||
//
|
||||
// I2C INA231 Sensor driver (platform data struct)
|
||||
// 2013.07.17
|
||||
//
|
||||
//
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#ifndef __INA231_H__
|
||||
#define __INA231_H__
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#define INA231_I2C_NAME "INA231"
|
||||
|
||||
struct i2c_client;
|
||||
struct misc_dev;
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
// INA231 Register define
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#define REG_CONFIG 0x00 // R/W
|
||||
#define REG_SHUNT_VOLT 0x01 // R
|
||||
#define REG_BUS_VOLT 0x02 // R
|
||||
#define REG_POWER 0x03 // R
|
||||
#define REG_CURRENT 0x04 // R
|
||||
#define REG_CALIBRATION 0x05 // R/W
|
||||
#define REG_ALERT_EN 0x06 // R/W
|
||||
#define REG_ALERT_LIMIT 0x07 // R/W
|
||||
|
||||
#define FIX_uV_LSB 1250 // fix lsb value 0.00125 V
|
||||
|
||||
// ex) CONVERSION_DELAY(eVBUS_CT_140uS, eVSH_CT_150uS, eAVG_1); return uSec
|
||||
#define CONVERSION_DELAY(x, y, z) ((x + y) * z)
|
||||
|
||||
#define INA231_CONFIG(x) ((0x4000 | x) & 0xFFFF)
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
enum {
|
||||
eAVG_CON_1 = 1,
|
||||
eAVG_CON_4 = 4,
|
||||
eAVG_CON_16 = 16,
|
||||
eAVG_CON_64 = 64,
|
||||
eAVG_CON_128 = 128,
|
||||
eAVG_CON_256 = 256,
|
||||
eAVG_CON_512 = 512,
|
||||
eAVG_CON_1024 = 1024,
|
||||
};
|
||||
|
||||
enum {
|
||||
eAVG_1 = 0,
|
||||
eAVG_4,
|
||||
eAVG_16,
|
||||
eAVG_64,
|
||||
eAVG_128,
|
||||
eAVG_256,
|
||||
eAVG_512,
|
||||
eAVG_1024,
|
||||
};
|
||||
|
||||
#define AVG_BIT(x) (x << 9)
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
enum {
|
||||
eVBUS_CON_140uS = 140,
|
||||
eVBUS_CON_204uS = 204,
|
||||
eVBUS_CON_332uS = 332,
|
||||
eVBUS_CON_588uS = 588,
|
||||
eVBUS_CON_1100uS = 1100,
|
||||
eVBUS_CON_2116uS = 2116,
|
||||
eVBUS_CON_4156uS = 4156,
|
||||
eVBUS_CON_8244uS = 8244,
|
||||
};
|
||||
|
||||
enum {
|
||||
eVBUS_CT_140uS = 0,
|
||||
eVBUS_CT_204uS,
|
||||
eVBUS_CT_332uS,
|
||||
eVBUS_CT_588uS,
|
||||
eVBUS_CT_1100uS,
|
||||
eVBUS_CT_2116uS,
|
||||
eVBUS_CT_4156uS,
|
||||
eVBUS_CT_8244uS,
|
||||
};
|
||||
|
||||
#define VBUS_CT(x) (x << 6)
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
enum {
|
||||
eVSH_CON_140uS = 140,
|
||||
eVSH_CON_204uS = 204,
|
||||
eVSH_CON_332uS = 332,
|
||||
eVSH_CON_588uS = 588,
|
||||
eVSH_CON_1100uS = 1100,
|
||||
eVSH_CON_2116uS = 2116,
|
||||
eVSH_CON_4156uS = 4156,
|
||||
eVSH_CON_8244uS = 8244,
|
||||
};
|
||||
|
||||
enum {
|
||||
eVSH_CT_140uS = 0,
|
||||
eVSH_CT_204uS,
|
||||
eVSH_CT_332uS,
|
||||
eVSH_CT_588uS,
|
||||
eVSH_CT_1100uS,
|
||||
eVSH_CT_2116uS,
|
||||
eVSH_CT_4156uS,
|
||||
eVSH_CT_8244uS,
|
||||
};
|
||||
|
||||
#define VSH_CT(x) (x << 3)
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
enum {
|
||||
ePOWER_DOWN1 = 0,
|
||||
eSHUNT_VOLT_TRIGGER,
|
||||
eBUS_VOLT_TRIGGER,
|
||||
eSHUNT_BUS_VOLT_TRIGGER,
|
||||
ePOWER_DOWN2,
|
||||
eSHUNT_VOLT_CONTINUOUS,
|
||||
eBUS_VOLT_CONTINUOUS,
|
||||
eSHUNT_BUS_VOLT_CONTINUOUS,
|
||||
};
|
||||
|
||||
#define MODE_SET(x) (x)
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
struct ina231_pd {
|
||||
unsigned char *name;
|
||||
unsigned short config;
|
||||
unsigned int max_A;
|
||||
unsigned int shunt_R_mohm; // unit = m ohm
|
||||
unsigned int update_period; // unit = usec
|
||||
unsigned int enable;
|
||||
};
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
struct ina231_sensor {
|
||||
struct i2c_client *client;
|
||||
struct ina231_pd *pd;
|
||||
struct miscdevice *misc;
|
||||
|
||||
unsigned short reg_calibration;
|
||||
unsigned short reg_bus_volt;
|
||||
unsigned short reg_current;
|
||||
|
||||
unsigned int cur_lsb_uA;
|
||||
|
||||
unsigned int cur_uA;
|
||||
unsigned int cur_uV;
|
||||
unsigned int cur_uW;
|
||||
|
||||
unsigned int max_uA;
|
||||
unsigned int max_uV;
|
||||
unsigned int max_uW;
|
||||
|
||||
struct hrtimer timer;
|
||||
unsigned int timer_sec, timer_nsec;
|
||||
struct work_struct work;
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
struct mutex mutex;
|
||||
|
||||
#if defined(CONFIG_HAS_EARLYSUSPEND)
|
||||
struct early_suspend power;
|
||||
#endif
|
||||
};
|
||||
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
#endif // INA231
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
//[*]------------------------------------------------------------------------[*]
|
||||
Reference in New Issue
Block a user