LTC2947

LTC2947 High Precision Power and Energy Monitor Linux Driver.

Supported Devices

Evaluation Boards

Description

This is a Hardware Monitor subsystem driver. There are two driver’s (sharing the same core implementation) for the LTC2947 since the device supports both SPI and I2C interfaces. The underlying bus is abstracted in the core implementation by using regmap. The Hwmon subsystem provides a unified framework for drivers doing hardware monitoring. It exposes a set of sysfs file that should follow the sysfs-interface.

Source Code

Status

Files

Adding Linux driver support

Kernel configuration

Configure kernel with make menuconfig (alternatively use make xconfig or make qconfig).

Note

The LTC2947 SPI driver depends CONFIG_SPI and the LTC2947 I2C driver depends on CONFIG_I2C.

Linux Kernel Configuration
    Device Drivers  --->
        <*>     Hardware Monitoring support --->
            --- Hardware Monitoring support
        [--snip--]
            <*> Analog Devices LTC2947 High Precision Power and Energy Monitor over I2C
            <*> Analog Devices LTC2947 High Precision Power and Energy Monitor over SPI
        [--snip--]

Devicetree configuration

Example I2C & SPI device initialization

The LTC2947 supports both I2C and SPI interfaces, so one of the drivers can be used depending on which kind of device is instantiated. Currently, the devices can only be instantiated via device tree.

Required devicetree properties:

  • compatible: Must be always one of these:

    • adi,ltc2947

  • reg: Must be either the I2C device address or the SPI device chip select number.

Example SPI:

&spi0 {
        #address-cells = <1>;
        #size-cells = <0>;
        status = "okay";
        ltc2947_spi: ltc2947@0 {
                compatible = "adi,ltc2947";
                reg = <0>;
                spi-max-frequency = <1000000>;
        };
};

Example I2C:

&i2c0 {
        #address-cells = <1>;
        #size-cells = <0>;
        status = "okay";
        ltc2947_i2c: ltc2947@5c {
                compatible = "adi,ltc2947";
                reg = <0x5c>;
        };
};

For more supported devicetree properties take a look to dt-bindings.

Driver testing

Identify the device

root:/sys/class/hwmon/hwmon1> cat name
ltc2947

HWMON device files

Each and every HWMON device has a device folder under /sys/class/hwmon/hwmonX, where X is the hwmon device index. Under every of these directory folders there are a set of files, depending on what kind of hardware monitoring is supported (temperature, voltage). In order to determine which hwmon device corresponds to which hardware chip, the user can read the name file under /sys/class/hwmon/hwmonX/name.

root:/> cd /sys/class/hwmon/
root:/sys/class/hwmon> ls
hwmon0  hwmon1

root:/sys/class/hwmon> cd hwmon1

root:/sys/class/hwmon/hwmon1> ls -l
total 0
-r--r--r-- 1 root root 4096 Nov 16 09:25 curr1_highest
-r--r--r-- 1 root root 4096 Nov 16 09:25 curr1_input
-r--r--r-- 1 root root 4096 Nov 16 09:25 curr1_label
-r--r--r-- 1 root root 4096 Nov 16 09:25 curr1_lowest
-rw-r--r-- 1 root root 4096 Nov 16 09:25 curr1_max
-r--r--r-- 1 root root 4096 Nov 16 09:25 curr1_max_alarm
-rw-r--r-- 1 root root 4096 Nov 16 09:25 curr1_min
-r--r--r-- 1 root root 4096 Nov 16 09:25 curr1_min_alarm
--w------- 1 root root 4096 Nov 16 09:25 curr1_reset_history
lrwxrwxrwx 1 root root    0 Nov 16 09:25 device -> ../../../spi0.0
-r--r--r-- 1 root root 4096 Nov 16 09:25 energy1_input
-r--r--r-- 1 root root 4096 Nov 16 09:25 energy2_input
-r--r--r-- 1 root root 4096 Nov 16 09:25 in0_highest
-r--r--r-- 1 root root 4096 Nov 16 09:25 in0_input
-r--r--r-- 1 root root 4096 Nov 16 09:25 in0_label
-r--r--r-- 1 root root 4096 Nov 16 09:25 in0_lowest
-rw-r--r-- 1 root root 4096 Nov 16 09:25 in0_max
-r--r--r-- 1 root root 4096 Nov 16 09:25 in0_max_alarm
-rw-r--r-- 1 root root 4096 Nov 16 09:25 in0_min
-r--r--r-- 1 root root 4096 Nov 16 09:25 in0_min_alarm
--w------- 1 root root 4096 Nov 16 09:25 in0_reset_history
-r--r--r-- 1 root root 4096 Nov 16 09:25 in1_highest
-r--r--r-- 1 root root 4096 Nov 16 09:25 in1_input
-r--r--r-- 1 root root 4096 Nov 16 09:25 in1_label
-r--r--r-- 1 root root 4096 Nov 16 09:25 in1_lowest
-rw-r--r-- 1 root root 4096 Nov 16 09:25 in1_max
-r--r--r-- 1 root root 4096 Nov 16 09:25 in1_max_alarm
-rw-r--r-- 1 root root 4096 Nov 16 09:25 in1_min
-r--r--r-- 1 root root 4096 Nov 16 09:25 in1_min_alarm
--w------- 1 root root 4096 Nov 16 09:25 in1_reset_history
-r--r--r-- 1 root root 4096 Nov 16 09:21 name
lrwxrwxrwx 1 root root    0 Nov 16 09:25 of_node -> ../../../../../../../../../firmware/devicetree/base/soc/spi@7e204000/ltc2947@0
drwxr-xr-x 2 root root    0 Nov 16 09:25 power
-r--r--r-- 1 root root 4096 Nov 16 09:25 power1_input
-r--r--r-- 1 root root 4096 Nov 16 09:25 power1_input_highest
-r--r--r-- 1 root root 4096 Nov 16 09:25 power1_input_lowest
-r--r--r-- 1 root root 4096 Nov 16 09:25 power1_label
-rw-r--r-- 1 root root 4096 Nov 16 09:25 power1_max
-r--r--r-- 1 root root 4096 Nov 16 09:25 power1_max_alarm
-rw-r--r-- 1 root root 4096 Nov 16 09:25 power1_min
-r--r--r-- 1 root root 4096 Nov 16 09:25 power1_min_alarm
--w------- 1 root root 4096 Nov 16 09:25 power1_reset_history
lrwxrwxrwx 1 root root    0 Nov 16 09:25 subsystem -> ../../../../../../../../../class/hwmon
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp1_highest
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp1_input
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp1_label
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp1_lowest
-rw-r--r-- 1 root root 4096 Nov 16 09:25 temp1_max
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp1_max_alarm
-rw-r--r-- 1 root root 4096 Nov 16 09:25 temp1_min
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp1_min_alarm
--w------- 1 root root 4096 Nov 16 09:25 temp1_reset_history
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp2_label
-rw-r--r-- 1 root root 4096 Nov 16 09:25 temp2_max
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp2_max_alarm
-rw-r--r-- 1 root root 4096 Nov 16 09:25 temp2_min
-r--r--r-- 1 root root 4096 Nov 16 09:25 temp2_min_alarm
-rw-r--r-- 1 root root 4096 Nov 16 09:17 uevent
root:/sys/class/hwmon/hwmon1>

For each type of monitored value (current, power), the file will look like ${type}${channel}_${attribute} (for example in0_input or curr1_max), where ${monitored_value} can be the current value, the high threshold, etc… The channel is the index when, for example, a device can monitor more than one voltage. For more information on the files format, take a look to sysfs-interface.

Show current values

The driver exposes current in mA, voltage in mV, power in µW, temperature in m°C, and two accumulated energy readings in µJ (energy1_input and energy2_input). To get the monitored voltage:

root:/sys/class/hwmon/hwmon1> cat in0_input
4910
Show highest read value
root:/sys/class/hwmon/hwmon1> cat in0_highest
5026
Show lowest read value
root:/sys/class/hwmon/hwmon1> cat in0_lowest
4754
Show high threshold
root:/sys/class/hwmon/hwmon1> cat in0_max
5500
Show low threshold
root:/sys/class/hwmon/hwmon1> cat in0_min
4500
Show high threshold alarm
root:/sys/class/hwmon/hwmon1> cat in0_max_alarm
0
Show low threshold alarm
root:/sys/class/hwmon/hwmon1> cat in0_min_alarm
0
Show label

Some channels, support a label attribute which specifies the name of the channel being monitored.

root:/sys/class/hwmon/hwmon1> cat in1_label
DVCC
Set High threshold
root:/sys/class/hwmon/hwmon1> echo 5500 > in0_max
Set Low threshold
root:/sys/class/hwmon/hwmon1> echo 4500 > in0_min
Reset History
root:/sys/class/hwmon/hwmon1> echo 1 > in0_reset_history

More Information

HWMON pointers

Need Help?