linux/drivers/hwmon/lm90.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
 *          monitoring
 * Copyright (C) 2003-2010  Jean Delvare <[email protected]>
 *
 * Based on the lm83 driver. The LM90 is a sensor chip made by National
 * Semiconductor. It reports up to two temperatures (its own plus up to
 * one external one) with a 0.125 deg resolution (1 deg for local
 * temperature) and a 3-4 deg accuracy.
 *
 * This driver also supports the LM89 and LM99, two other sensor chips
 * made by National Semiconductor. Both have an increased remote
 * temperature measurement accuracy (1 degree), and the LM99
 * additionally shifts remote temperatures (measured and limits) by 16
 * degrees, which allows for higher temperatures measurement.
 * Note that there is no way to differentiate between both chips.
 * When device is auto-detected, the driver will assume an LM99.
 *
 * This driver also supports the LM86, another sensor chip made by
 * National Semiconductor. It is exactly similar to the LM90 except it
 * has a higher accuracy.
 *
 * This driver also supports the ADM1032, a sensor chip made by Analog
 * Devices. That chip is similar to the LM90, with a few differences
 * that are not handled by this driver. Among others, it has a higher
 * accuracy than the LM90, much like the LM86 does.
 *
 * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor
 * chips made by Maxim. These chips are similar to the LM86.
 * Note that there is no easy way to differentiate between the three
 * variants. We use the device address to detect MAX6659, which will result
 * in a detection as max6657 if it is on address 0x4c. The extra address
 * and features of the MAX6659 are only supported if the chip is configured
 * explicitly as max6659, or if its address is not 0x4c.
 * These chips lack the remote temperature offset feature.
 *
 * This driver also supports the MAX6654 chip made by Maxim. This chip can be
 * at 9 different addresses, similar to MAX6680/MAX6681. The MAX6654 is similar
 * to MAX6657/MAX6658/MAX6659, but does not support critical temperature
 * limits. Extended range is available by setting the configuration register
 * accordingly, and is done during initialization. Extended precision is only
 * available at conversion rates of 1 Hz and slower. Note that extended
 * precision is not enabled by default, as this driver initializes all chips
 * to 2 Hz by design. The driver also supports MAX6690, which is practically
 * identical to MAX6654.
 *
 * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and
 * MAX6692 chips made by Maxim.  These are again similar to the LM86,
 * but they use unsigned temperature values and can report temperatures
 * from 0 to 145 degrees.
 *
 * This driver also supports the MAX6680 and MAX6681, two other sensor
 * chips made by Maxim. These are quite similar to the other Maxim
 * chips. The MAX6680 and MAX6681 only differ in the pinout so they can
 * be treated identically.
 *
 * This driver also supports the MAX6695 and MAX6696, two other sensor
 * chips made by Maxim. These are also quite similar to other Maxim
 * chips, but support three temperature sensors instead of two. MAX6695
 * and MAX6696 only differ in the pinout so they can be treated identically.
 *
 * This driver also supports ADT7461 and ADT7461A from Analog Devices as well as
 * NCT1008 from ON Semiconductor. The chips are supported in both compatibility
 * and extended mode. They are mostly compatible with LM90 except for a data
 * format difference for the temperature value registers.
 *
 * This driver also supports ADT7481, ADT7482, and ADT7483 from Analog Devices
 * / ON Semiconductor. The chips are similar to ADT7461 but support two external
 * temperature sensors.
 *
 * This driver also supports NCT72, NCT214, and NCT218 from ON Semiconductor.
 * The chips are similar to ADT7461/ADT7461A but have full PEC support
 * (undocumented).
 *
 * This driver also supports the SA56004 from Philips. This device is
 * pin-compatible with the LM86, the ED/EDP parts are also address-compatible.
 *
 * This driver also supports the G781 from GMT. This device is compatible
 * with the ADM1032.
 *
 * This driver also supports TMP451 and TMP461 from Texas Instruments.
 * Those devices are supported in both compatibility and extended mode.
 * They are mostly compatible with ADT7461 except for local temperature
 * low byte register and max conversion rate.
 *
 * This driver also supports MAX1617 and various clones such as G767
 * and NE1617. Such clones will be detected as MAX1617.
 *
 * This driver also supports NE1618 from Philips. It is similar to NE1617
 * but supports 11 bit external temperature values.
 *
 * Since the LM90 was the first chipset supported by this driver, most
 * comments will refer to this chipset, but are actually general and
 * concern all supported chipsets, unless mentioned otherwise.
 */

#include <linux/bits.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/hwmon.h>
#include <linux/kstrtox.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

/* The maximum number of channels currently supported */
#define MAX_CHANNELS

/*
 * Addresses to scan
 * Address is fully defined internally and cannot be changed except for
 * MAX6659, MAX6680 and MAX6681.
 * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, ADT7461A, MAX6649,
 * MAX6657, MAX6658, NCT1008 and W83L771 have address 0x4c.
 * ADM1032-2, ADT7461-2, ADT7461A-2, LM89-1, LM99-1, MAX6646, and NCT1008D
 * have address 0x4d.
 * MAX6647 has address 0x4e.
 * MAX6659 can have address 0x4c, 0x4d or 0x4e.
 * MAX6654, MAX6680, and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29,
 * 0x2a, 0x2b, 0x4c, 0x4d or 0x4e.
 * SA56004 can have address 0x48 through 0x4F.
 */

static const unsigned short normal_i2c[] =;

enum chips {};

/*
 * The LM90 registers
 */

#define LM90_REG_MAN_ID
#define LM90_REG_CHIP_ID
#define LM90_REG_CONFIG1
#define LM90_REG_CONFIG2
#define LM90_REG_CONVRATE
#define LM90_REG_STATUS
#define LM90_REG_LOCAL_TEMP
#define LM90_REG_LOCAL_HIGH
#define LM90_REG_LOCAL_LOW
#define LM90_REG_LOCAL_CRIT
#define LM90_REG_REMOTE_TEMPH
#define LM90_REG_REMOTE_TEMPL
#define LM90_REG_REMOTE_OFFSH
#define LM90_REG_REMOTE_OFFSL
#define LM90_REG_REMOTE_HIGHH
#define LM90_REG_REMOTE_HIGHL
#define LM90_REG_REMOTE_LOWH
#define LM90_REG_REMOTE_LOWL
#define LM90_REG_REMOTE_CRIT
#define LM90_REG_TCRIT_HYST

/* MAX6646/6647/6649/6654/6657/6658/6659/6695/6696 registers */

#define MAX6657_REG_LOCAL_TEMPL
#define MAX6696_REG_STATUS2
#define MAX6659_REG_REMOTE_EMERG
#define MAX6659_REG_LOCAL_EMERG

/*  SA56004 registers */

#define SA56004_REG_LOCAL_TEMPL

#define LM90_MAX_CONVRATE_MS

/* TMP451/TMP461 registers */
#define TMP451_REG_LOCAL_TEMPL
#define TMP451_REG_CONALERT

#define TMP461_REG_CHEN
#define TMP461_REG_DFC

/* ADT7481 registers */
#define ADT7481_REG_STATUS2
#define ADT7481_REG_CONFIG2

#define ADT7481_REG_MAN_ID
#define ADT7481_REG_CHIP_ID

/* Device features */
#define LM90_HAVE_EXTENDED_TEMP
#define LM90_HAVE_OFFSET
#define LM90_HAVE_UNSIGNED_TEMP
#define LM90_HAVE_REM_LIMIT_EXT
#define LM90_HAVE_EMERGENCY
#define LM90_HAVE_EMERGENCY_ALARM
#define LM90_HAVE_TEMP3
#define LM90_HAVE_BROKEN_ALERT
#define LM90_PAUSE_FOR_CONFIG
#define LM90_HAVE_CRIT
#define LM90_HAVE_CRIT_ALRM_SWP
#define LM90_HAVE_PEC
#define LM90_HAVE_PARTIAL_PEC
#define LM90_HAVE_ALARMS
#define LM90_HAVE_EXT_UNSIGNED
#define LM90_HAVE_LOW
#define LM90_HAVE_CONVRATE
#define LM90_HAVE_REMOTE_EXT
#define LM90_HAVE_FAULTQUEUE

/* LM90 status */
#define LM90_STATUS_LTHRM
#define LM90_STATUS_RTHRM
#define LM90_STATUS_ROPEN
#define LM90_STATUS_RLOW
#define LM90_STATUS_RHIGH
#define LM90_STATUS_LLOW
#define LM90_STATUS_LHIGH
#define LM90_STATUS_BUSY

/* MAX6695/6696 and ADT7481 2nd status register */
#define MAX6696_STATUS2_R2THRM
#define MAX6696_STATUS2_R2OPEN
#define MAX6696_STATUS2_R2LOW
#define MAX6696_STATUS2_R2HIGH
#define MAX6696_STATUS2_ROT2
#define MAX6696_STATUS2_R2OT2
#define MAX6696_STATUS2_LOT2

/*
 * Driver data (common to all clients)
 */

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

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

/*
 * chip type specific parameters
 */
struct lm90_params {};

static const struct lm90_params lm90_params[] =;

/*
 * temperature register index
 */
enum lm90_temp_reg_index {};

/*
 * Client data (each client gets its own)
 */

struct lm90_data {};

/*
 * Support functions
 */

/*
 * If the chip supports PEC but not on write byte transactions, we need
 * to explicitly ask for a transaction without PEC.
 */
static inline s32 lm90_write_no_pec(struct i2c_client *client, u8 value)
{}

/*
 * It is assumed that client->update_lock is held (unless we are in
 * detection or initialization steps). This matters when PEC is enabled
 * for chips with partial PEC support, because we don't want the address
 * pointer to change between the write byte and the read byte transactions.
 */
static int lm90_read_reg(struct i2c_client *client, u8 reg)
{}

/*
 * Return register write address
 *
 * The write address for registers 0x03 .. 0x08 is the read address plus 6.
 * For other registers the write address matches the read address.
 */
static u8 lm90_write_reg_addr(u8 reg)
{}

/*
 * Write into LM90 register.
 * Convert register address to write address if needed, then execute the
 * operation.
 */
static int lm90_write_reg(struct i2c_client *client, u8 reg, u8 val)
{}

/*
 * Write into 16-bit LM90 register.
 * Convert register addresses to write address if needed, then execute the
 * operation.
 */
static int lm90_write16(struct i2c_client *client, u8 regh, u8 regl, u16 val)
{}

static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl,
		       bool is_volatile)
{}

static int lm90_update_confreg(struct lm90_data *data, u8 config)
{}

/*
 * client->update_lock must be held when calling this function (unless we are
 * in detection or initialization steps), and while a remote channel other
 * than channel 0 is selected. Also, calling code must make sure to re-select
 * external channel 0 before releasing the lock. This is necessary because
 * various registers have different meanings as a result of selecting a
 * non-default remote channel.
 */
static int lm90_select_remote_channel(struct lm90_data *data, bool second)
{}

static int lm90_write_convrate(struct lm90_data *data, int val)
{}

/*
 * Set conversion rate.
 * client->update_lock must be held when calling this function (unless we are
 * in detection or initialization steps).
 */
static int lm90_set_convrate(struct i2c_client *client, struct lm90_data *data,
			     unsigned int interval)
{}

static int lm90_set_faultqueue(struct i2c_client *client,
			       struct lm90_data *data, int val)
{}

static int lm90_update_limits(struct device *dev)
{}

static void lm90_report_alarms(struct work_struct *work)
{}

static int lm90_update_alarms_locked(struct lm90_data *data, bool force)
{}

static int lm90_update_alarms(struct lm90_data *data, bool force)
{}

static void lm90_alert_work(struct work_struct *__work)
{}

static int lm90_update_device(struct device *dev)
{}

static int lm90_temp_get_resolution(struct lm90_data *data, int index)
{}

static int lm90_temp_from_reg(u32 flags, u16 regval, u8 resolution)
{}

static int lm90_get_temp(struct lm90_data *data, int index, int channel)
{}

static u16 lm90_temp_to_reg(u32 flags, long val, u8 resolution)
{}

static int lm90_set_temp(struct lm90_data *data, int index, int channel, long val)
{}

static int lm90_get_temphyst(struct lm90_data *data, int index, int channel)
{}

static int lm90_set_temphyst(struct lm90_data *data, long val)
{}

static int lm90_get_temp_offset(struct lm90_data *data, int index)
{}

static int lm90_set_temp_offset(struct lm90_data *data, int index, int channel, long val)
{}

static const u8 lm90_temp_index[MAX_CHANNELS] =;

static const u8 lm90_temp_min_index[MAX_CHANNELS] =;

static const u8 lm90_temp_max_index[MAX_CHANNELS] =;

static const u8 lm90_temp_crit_index[MAX_CHANNELS] =;

static const u8 lm90_temp_emerg_index[MAX_CHANNELS] =;

static const s8 lm90_temp_offset_index[MAX_CHANNELS] =;

static const u16 lm90_min_alarm_bits[MAX_CHANNELS] =;
static const u16 lm90_max_alarm_bits[MAX_CHANNELS] =;
static const u16 lm90_crit_alarm_bits[MAX_CHANNELS] =;
static const u16 lm90_crit_alarm_bits_swapped[MAX_CHANNELS] =;
static const u16 lm90_emergency_alarm_bits[MAX_CHANNELS] =;
static const u16 lm90_fault_bits[MAX_CHANNELS] =;

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

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

static umode_t lm90_temp_is_visible(const void *data, u32 attr, int channel)
{}

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

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

static umode_t lm90_chip_is_visible(const void *data, u32 attr, int channel)
{}

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

static int lm90_read_string(struct device *dev, enum hwmon_sensor_types type,
			    u32 attr, int channel, const char **str)
{}

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

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

static const char *lm90_detect_lm84(struct i2c_client *client)
{}

static const char *lm90_detect_max1617(struct i2c_client *client, int config1)
{}

static const char *lm90_detect_national(struct i2c_client *client, int chip_id,
					int config1, int convrate)
{}

static const char *lm90_detect_on(struct i2c_client *client, int chip_id, int config1,
				  int convrate)
{}

static const char *lm90_detect_analog(struct i2c_client *client, bool common_address,
				      int chip_id, int config1, int convrate)
{}

static const char *lm90_detect_maxim(struct i2c_client *client, bool common_address,
				     int chip_id, int config1, int convrate)
{}

static const char *lm90_detect_nuvoton(struct i2c_client *client, int chip_id,
				       int config1, int convrate)
{}

static const char *lm90_detect_nxp(struct i2c_client *client, bool common_address,
				   int chip_id, int config1, int convrate)
{}

static const char *lm90_detect_gmt(struct i2c_client *client, int chip_id,
				   int config1, int convrate)
{}

static const char *lm90_detect_ti49(struct i2c_client *client, bool common_address,
				    int chip_id, int config1, int convrate)
{}

static const char *lm90_detect_ti(struct i2c_client *client, int chip_id,
				  int config1, int convrate)
{}

/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info)
{}

static void lm90_restore_conf(void *_data)
{}

static int lm90_init_client(struct i2c_client *client, struct lm90_data *data)
{}

static bool lm90_is_tripped(struct i2c_client *client)
{}

static irqreturn_t lm90_irq_thread(int irq, void *dev_id)
{}

static int lm90_probe_channel_from_dt(struct i2c_client *client,
				      struct device_node *child,
				      struct lm90_data *data)
{}

static int lm90_parse_dt_channel_info(struct i2c_client *client,
				      struct lm90_data *data)
{}

static const struct hwmon_ops lm90_ops =;

static int lm90_probe(struct i2c_client *client)
{}

static void lm90_alert(struct i2c_client *client, enum i2c_alert_protocol type,
		       unsigned int flag)
{}

static int lm90_suspend(struct device *dev)
{}

static int lm90_resume(struct device *dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(lm90_pm_ops, lm90_suspend, lm90_resume);

static struct i2c_driver lm90_driver =;

module_i2c_driver();

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