mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
hwmon: Add support for ltc2947
The ltc2947 is a high precision power and energy monitor with an internal sense resistor supporting up to +/- 30A. Three internal no Latency ADCs ensure accurate measurement of voltage and current, while high-bandwidth analog multiplication of voltage and current provides accurate power measurement in a wide range of applications. Internal or external clocking options enable precise charge and energy measurements. Signed-off-by: Nuno Sá <nuno.sa@analog.com> Link: https://lore.kernel.org/r/20191021154115.319073-1-nuno.sa@analog.com [groeck: Removed unnecessary checks when reading temperature and energy; PAGE{0,1} -> LTC2947_PAGE_{0,1}] Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
2057bdfb71
commit
9f90fd652b
@ -90,6 +90,7 @@ Hardware Monitoring Kernel Drivers
|
||||
lm95245
|
||||
lochnagar
|
||||
ltc2945
|
||||
ltc2947
|
||||
ltc2978
|
||||
ltc2990
|
||||
ltc3815
|
||||
|
100
Documentation/hwmon/ltc2947.rst
Normal file
100
Documentation/hwmon/ltc2947.rst
Normal file
@ -0,0 +1,100 @@
|
||||
Kernel drivers ltc2947-i2c and ltc2947-spi
|
||||
==========================================
|
||||
|
||||
Supported chips:
|
||||
|
||||
* Analog Devices LTC2947
|
||||
|
||||
Prefix: 'ltc2947'
|
||||
|
||||
Addresses scanned: -
|
||||
|
||||
Datasheet:
|
||||
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/LTC2947.pdf
|
||||
|
||||
Author: Nuno Sá <nuno.sa@analog.com>
|
||||
|
||||
Description
|
||||
___________
|
||||
|
||||
The LTC2947 is a high precision power and energy monitor that measures current,
|
||||
voltage, power, temperature, charge and energy. The device supports both SPI
|
||||
and I2C depending on the chip configuration.
|
||||
The device also measures accumulated quantities as energy. It has two banks of
|
||||
register's to read/set energy related values. These banks can be configured
|
||||
independently to have setups like: energy1 accumulates always and enrgy2 only
|
||||
accumulates if current is positive (to check battery charging efficiency for
|
||||
example). The device also supports a GPIO pin that can be configured as output
|
||||
to control a fan as a function of measured temperature. Then, the GPIO becomes
|
||||
active as soon as a temperature reading is higher than a defined threshold. The
|
||||
temp2 channel is used to control this thresholds and to read the respective
|
||||
alarms.
|
||||
|
||||
Sysfs entries
|
||||
_____________
|
||||
|
||||
The following attributes are supported. Limits are read-write, reset_history
|
||||
is write-only and all the other attributes are read-only.
|
||||
|
||||
======================= ==========================================
|
||||
in0_input VP-VM voltage (mV).
|
||||
in0_min Undervoltage threshold
|
||||
in0_max Overvoltage threshold
|
||||
in0_lowest Lowest measured voltage
|
||||
in0_highest Highest measured voltage
|
||||
in0_reset_history Write 1 to reset in1 history
|
||||
in0_min_alarm Undervoltage alarm
|
||||
in0_max_alarm Overvoltage alarm
|
||||
in0_label Channel label (VP-VM)
|
||||
|
||||
in1_input DVCC voltage (mV)
|
||||
in1_min Undervoltage threshold
|
||||
in1_max Overvoltage threshold
|
||||
in1_lowest Lowest measured voltage
|
||||
in1_highest Highest measured voltage
|
||||
in1_reset_history Write 1 to reset in2 history
|
||||
in1_min_alarm Undervoltage alarm
|
||||
in1_max_alarm Overvoltage alarm
|
||||
in1_label Channel label (DVCC)
|
||||
|
||||
curr1_input IP-IM Sense current (mA)
|
||||
curr1_min Undercurrent threshold
|
||||
curr1_max Overcurrent threshold
|
||||
curr1_lowest Lowest measured current
|
||||
curr1_highest Highest measured current
|
||||
curr1_reset_history Write 1 to reset curr1 history
|
||||
curr1_min_alarm Undercurrent alarm
|
||||
curr1_max_alarm Overcurrent alarm
|
||||
curr1_label Channel label (IP-IM)
|
||||
|
||||
power1_input Power (in uW)
|
||||
power1_min Low power threshold
|
||||
power1_max High power threshold
|
||||
power1_input_lowest Historical minimum power use
|
||||
power1_input_highest Historical maximum power use
|
||||
power1_reset_history Write 1 to reset power1 history
|
||||
power1_min_alarm Low power alarm
|
||||
power1_max_alarm High power alarm
|
||||
power1_label Channel label (Power)
|
||||
|
||||
temp1_input Chip Temperature (in milliC)
|
||||
temp1_min Low temperature threshold
|
||||
temp1_max High temperature threshold
|
||||
temp1_input_lowest Historical minimum temperature use
|
||||
temp1_input_highest Historical maximum temperature use
|
||||
temp1_reset_history Write 1 to reset temp1 history
|
||||
temp1_min_alarm Low temperature alarm
|
||||
temp1_max_alarm High temperature alarm
|
||||
temp1_label Channel label (Ambient)
|
||||
|
||||
temp2_min Low temperature threshold for fan control
|
||||
temp2_max High temperature threshold for fan control
|
||||
temp2_min_alarm Low temperature fan control alarm
|
||||
temp2_max_alarm High temperature fan control alarm
|
||||
temp2_label Channel label (TEMPFAN)
|
||||
|
||||
energy1_input Measured energy over time (in microJoule)
|
||||
|
||||
energy2_input Measured energy over time (in microJoule)
|
||||
======================= ==========================================
|
10
MAINTAINERS
10
MAINTAINERS
@ -9630,6 +9630,16 @@ S: Maintained
|
||||
F: Documentation/hwmon/ltc4261.rst
|
||||
F: drivers/hwmon/ltc4261.c
|
||||
|
||||
LTC2947 HARDWARE MONITOR DRIVER
|
||||
M: Nuno Sá <nuno.sa@analog.com>
|
||||
W: http://ez.analog.com/community/linux-device-drivers
|
||||
L: linux-hwmon@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/hwmon/ltc2947-core.c
|
||||
F: drivers/hwmon/ltc2947-spi.c
|
||||
F: drivers/hwmon/ltc2947-i2c.c
|
||||
F: drivers/hwmon/ltc2947.h
|
||||
|
||||
LTC4306 I2C MULTIPLEXER DRIVER
|
||||
M: Michael Hennerich <michael.hennerich@analog.com>
|
||||
W: http://ez.analog.com/community/linux-device-drivers
|
||||
|
@ -726,6 +726,33 @@ config SENSORS_LTC2945
|
||||
This driver can also be built as a module. If so, the module will
|
||||
be called ltc2945.
|
||||
|
||||
config SENSORS_LTC2947
|
||||
tristate
|
||||
|
||||
config SENSORS_LTC2947_I2C
|
||||
tristate "Analog Devices LTC2947 High Precision Power and Energy Monitor over I2C"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
select SENSORS_LTC2947
|
||||
help
|
||||
If you say yes here you get support for Linear Technology LTC2947
|
||||
I2C High Precision Power and Energy Monitor
|
||||
|
||||
This driver can also be built as a module. If so, the module will
|
||||
be called ltc2947-i2c.
|
||||
|
||||
config SENSORS_LTC2947_SPI
|
||||
tristate "Analog Devices LTC2947 High Precision Power and Energy Monitor over SPI"
|
||||
depends on SPI_MASTER
|
||||
select REGMAP_SPI
|
||||
select SENSORS_LTC2947
|
||||
help
|
||||
If you say yes here you get support for Linear Technology LTC2947
|
||||
SPI High Precision Power and Energy Monitor
|
||||
|
||||
This driver can also be built as a module. If so, the module will
|
||||
be called ltc2947-spi.
|
||||
|
||||
config SENSORS_LTC2990
|
||||
tristate "Linear Technology LTC2990"
|
||||
depends on I2C
|
||||
|
@ -106,6 +106,9 @@ obj-$(CONFIG_SENSORS_LM95234) += lm95234.o
|
||||
obj-$(CONFIG_SENSORS_LM95241) += lm95241.o
|
||||
obj-$(CONFIG_SENSORS_LM95245) += lm95245.o
|
||||
obj-$(CONFIG_SENSORS_LTC2945) += ltc2945.o
|
||||
obj-$(CONFIG_SENSORS_LTC2947) += ltc2947-core.o
|
||||
obj-$(CONFIG_SENSORS_LTC2947_I2C) += ltc2947-i2c.o
|
||||
obj-$(CONFIG_SENSORS_LTC2947_SPI) += ltc2947-spi.o
|
||||
obj-$(CONFIG_SENSORS_LTC2990) += ltc2990.o
|
||||
obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o
|
||||
obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o
|
||||
|
1183
drivers/hwmon/ltc2947-core.c
Normal file
1183
drivers/hwmon/ltc2947-core.c
Normal file
File diff suppressed because it is too large
Load Diff
49
drivers/hwmon/ltc2947-i2c.c
Normal file
49
drivers/hwmon/ltc2947-i2c.c
Normal file
@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Analog Devices LTC2947 high precision power and energy monitor over I2C
|
||||
*
|
||||
* Copyright 2019 Analog Devices Inc.
|
||||
*/
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "ltc2947.h"
|
||||
|
||||
static const struct regmap_config ltc2947_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static int ltc2947_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct regmap *map;
|
||||
|
||||
map = devm_regmap_init_i2c(i2c, <c2947_regmap_config);
|
||||
if (IS_ERR(map))
|
||||
return PTR_ERR(map);
|
||||
|
||||
return ltc2947_core_probe(map, i2c->name);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ltc2947_id[] = {
|
||||
{"ltc2947", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ltc2947_id);
|
||||
|
||||
static struct i2c_driver ltc2947_driver = {
|
||||
.driver = {
|
||||
.name = "ltc2947",
|
||||
.of_match_table = ltc2947_of_match,
|
||||
.pm = <c2947_pm_ops,
|
||||
},
|
||||
.probe = ltc2947_probe,
|
||||
.id_table = ltc2947_id,
|
||||
};
|
||||
module_i2c_driver(ltc2947_driver);
|
||||
|
||||
MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
|
||||
MODULE_DESCRIPTION("LTC2947 I2C power and energy monitor driver");
|
||||
MODULE_LICENSE("GPL");
|
50
drivers/hwmon/ltc2947-spi.c
Normal file
50
drivers/hwmon/ltc2947-spi.c
Normal file
@ -0,0 +1,50 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Analog Devices LTC2947 high precision power and energy monitor over SPI
|
||||
*
|
||||
* Copyright 2019 Analog Devices Inc.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include "ltc2947.h"
|
||||
|
||||
static const struct regmap_config ltc2947_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.read_flag_mask = BIT(0),
|
||||
};
|
||||
|
||||
static int ltc2947_probe(struct spi_device *spi)
|
||||
{
|
||||
struct regmap *map;
|
||||
|
||||
map = devm_regmap_init_spi(spi, <c2947_regmap_config);
|
||||
if (IS_ERR(map))
|
||||
return PTR_ERR(map);
|
||||
|
||||
return ltc2947_core_probe(map, spi_get_device_id(spi)->name);
|
||||
}
|
||||
|
||||
static const struct spi_device_id ltc2947_id[] = {
|
||||
{"ltc2947", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ltc2947_id);
|
||||
|
||||
static struct spi_driver ltc2947_driver = {
|
||||
.driver = {
|
||||
.name = "ltc2947",
|
||||
.of_match_table = ltc2947_of_match,
|
||||
.pm = <c2947_pm_ops,
|
||||
},
|
||||
.probe = ltc2947_probe,
|
||||
.id_table = ltc2947_id,
|
||||
};
|
||||
module_spi_driver(ltc2947_driver);
|
||||
|
||||
MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
|
||||
MODULE_DESCRIPTION("LTC2947 SPI power and energy monitor driver");
|
||||
MODULE_LICENSE("GPL");
|
12
drivers/hwmon/ltc2947.h
Normal file
12
drivers/hwmon/ltc2947.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LINUX_LTC2947_H
|
||||
#define _LINUX_LTC2947_H
|
||||
|
||||
struct regmap;
|
||||
|
||||
extern const struct of_device_id ltc2947_of_match[];
|
||||
extern const struct dev_pm_ops ltc2947_pm_ops;
|
||||
|
||||
int ltc2947_core_probe(struct regmap *map, const char *name);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user