linux/drivers/hwmon/ina2xx.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for Texas Instruments INA219, INA226 power monitor chips
 *
 * INA219:
 * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
 * Datasheet: https://www.ti.com/product/ina219
 *
 * INA220:
 * Bi-Directional Current/Power Monitor with I2C Interface
 * Datasheet: https://www.ti.com/product/ina220
 *
 * INA226:
 * Bi-Directional Current/Power Monitor with I2C Interface
 * Datasheet: https://www.ti.com/product/ina226
 *
 * INA230:
 * Bi-directional Current/Power Monitor with I2C Interface
 * Datasheet: https://www.ti.com/product/ina230
 *
 * Copyright (C) 2012 Lothar Felten <[email protected]>
 * Thanks to Jan Volkering
 */

#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/util_macros.h>

/* common register definitions */
#define INA2XX_CONFIG
#define INA2XX_SHUNT_VOLTAGE
#define INA2XX_BUS_VOLTAGE
#define INA2XX_POWER
#define INA2XX_CURRENT
#define INA2XX_CALIBRATION

/* INA226 register definitions */
#define INA226_MASK_ENABLE
#define INA226_ALERT_LIMIT
#define INA226_DIE_ID

#define INA2XX_MAX_REGISTERS

/* settings - depend on use case */
#define INA219_CONFIG_DEFAULT
#define INA226_CONFIG_DEFAULT

/* worst case is 68.10 ms (~14.6Hz, ina219) */
#define INA2XX_CONVERSION_RATE
#define INA2XX_MAX_DELAY

#define INA2XX_RSHUNT_DEFAULT

/* bit mask for reading the averaging setting in the configuration register */
#define INA226_AVG_RD_MASK

#define INA226_READ_AVG(reg)

#define INA226_ALERT_LATCH_ENABLE
#define INA226_ALERT_POLARITY

/* bit number of alert functions in Mask/Enable Register */
#define INA226_SHUNT_OVER_VOLTAGE_MASK
#define INA226_SHUNT_UNDER_VOLTAGE_MASK
#define INA226_BUS_OVER_VOLTAGE_MASK
#define INA226_BUS_UNDER_VOLTAGE_MASK
#define INA226_POWER_OVER_LIMIT_MASK

/* bit mask for alert config bits of Mask/Enable Register */
#define INA226_ALERT_CONFIG_MASK
#define INA226_ALERT_FUNCTION_FLAG

/*
 * Both bus voltage and shunt voltage conversion times for ina226 are set
 * to 0b0100 on POR, which translates to 2200 microseconds in total.
 */
#define INA226_TOTAL_CONV_TIME_DEFAULT

static bool ina2xx_writeable_reg(struct device *dev, unsigned int reg)
{}

static bool ina2xx_volatile_reg(struct device *dev, unsigned int reg)
{}

static const struct regmap_config ina2xx_regmap_config =;

enum ina2xx_ids {};

struct ina2xx_config {};

struct ina2xx_data {};

static const struct ina2xx_config ina2xx_config[] =;

/*
 * Available averaging rates for ina226. The indices correspond with
 * the bit values expected by the chip (according to the ina226 datasheet,
 * table 3 AVG bit settings, found at
 * https://www.ti.com/lit/ds/symlink/ina226.pdf.
 */
static const int ina226_avg_tab[] =;

static int ina226_reg_to_interval(u16 config)
{}

/*
 * Return the new, shifted AVG field value of CONFIG register,
 * to use with regmap_update_bits
 */
static u16 ina226_interval_to_reg(long interval)
{}

static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
			    unsigned int regval)
{}

/*
 * Read and convert register value from chip. If the register value is 0,
 * check if the chip has been power cycled or reset. If so, re-initialize it.
 */
static int ina2xx_read_init(struct device *dev, int reg, long *val)
{}

/*
 * Turns alert limit values into register values.
 * Opposite of the formula in ina2xx_get_value().
 */
static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, long val)
{}

static int ina226_alert_limit_read(struct ina2xx_data *data, u32 mask, int reg, long *val)
{}

static int ina226_alert_limit_write(struct ina2xx_data *data, u32 mask, int reg, long val)
{}

static int ina2xx_chip_read(struct device *dev, u32 attr, long *val)
{}

static int ina226_alert_read(struct regmap *regmap, u32 mask, long *val)
{}

static int ina2xx_in_read(struct device *dev, u32 attr, int channel, long *val)
{}

static int ina2xx_power_read(struct device *dev, u32 attr, long *val)
{}

static int ina2xx_curr_read(struct device *dev, u32 attr, long *val)
{}

static int ina2xx_read(struct device *dev, enum hwmon_sensor_types type,
		       u32 attr, int channel, long *val)
{}

static int ina2xx_chip_write(struct device *dev, u32 attr, long val)
{}

static int ina2xx_in_write(struct device *dev, u32 attr, int channel, long val)
{}

static int ina2xx_power_write(struct device *dev, u32 attr, long val)
{}

static int ina2xx_curr_write(struct device *dev, u32 attr, long val)
{}

static int ina2xx_write(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long val)
{}

static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type,
				 u32 attr, int channel)
{}

static const struct hwmon_channel_info * const ina2xx_info[] =;

static const struct hwmon_ops ina2xx_hwmon_ops =;

static const struct hwmon_chip_info ina2xx_chip_info =;

/* shunt resistance */

/*
 * In order to keep calibration register value fixed, the product
 * of current_lsb and shunt_resistor should also be fixed and equal
 * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order
 * to keep the scale.
 */
static int ina2xx_set_shunt(struct ina2xx_data *data, unsigned long val)
{}

static ssize_t shunt_resistor_show(struct device *dev,
				   struct device_attribute *da, char *buf)
{}

static ssize_t shunt_resistor_store(struct device *dev,
				    struct device_attribute *da,
				    const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(shunt_resistor);

/* pointers to created device attributes */
static struct attribute *ina2xx_attrs[] =;
ATTRIBUTE_GROUPS();

/*
 * Initialize chip
 */
static int ina2xx_init(struct device *dev, struct ina2xx_data *data)
{}

static int ina2xx_probe(struct i2c_client *client)
{}

static const struct i2c_device_id ina2xx_id[] =;
MODULE_DEVICE_TABLE(i2c, ina2xx_id);

static const struct of_device_id __maybe_unused ina2xx_of_match[] =;
MODULE_DEVICE_TABLE(of, ina2xx_of_match);

static struct i2c_driver ina2xx_driver =;

module_i2c_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();