// 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 <jdelvare@suse.de> * * 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. * * This driver also supports NCT7716, NCT7717 and NCT7718 from Nuvoton. * The NCT7716 is similar to NCT7717 but has one more address support. * * 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.
*/
/* The maximum number of channels currently supported */ #define MAX_CHANNELS 3
/* * 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, NCT7718 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. * NCT7716 can have address 0x48 or 0x49. * NCT7717 has address 0x48. * SA56004 can have address 0x48 through 0x4F.
*/
/* * temperature register index
*/ enum lm90_temp_reg_index {
LOCAL_LOW = 0,
LOCAL_HIGH,
LOCAL_CRIT,
REMOTE_CRIT,
LOCAL_EMERG, /* max6659 and max6695/96 */
REMOTE_EMERG, /* max6659 and max6695/96 */
REMOTE2_CRIT, /* max6695/96 only */
REMOTE2_EMERG, /* max6695/96 only */
REMOTE_TEMP,
REMOTE_LOW,
REMOTE_HIGH,
REMOTE_OFFSET, /* except max6646, max6657/58/59, and max6695/96 */
LOCAL_TEMP,
REMOTE2_TEMP, /* max6695/96 only */
REMOTE2_LOW, /* max6695/96 only */
REMOTE2_HIGH, /* max6695/96 only */
REMOTE2_OFFSET,
TEMP_REG_NUM
};
/* * Client data (each client gets its own)
*/
struct lm90_data { struct i2c_client *client; struct device *hwmon_dev;
u32 chip_config[2];
u32 channel_config[MAX_CHANNELS + 1]; constchar *channel_label[MAX_CHANNELS]; struct hwmon_channel_info chip_info; struct hwmon_channel_info temp_info; conststruct hwmon_channel_info *info[3]; struct hwmon_chip_info chip; struct mutex update_lock; struct delayed_work alert_work; struct work_struct report_work; bool valid; /* true if register values are valid */ bool alarms_valid; /* true if status register values are valid */ unsignedlong last_updated; /* in jiffies */ unsignedlong alarms_updated; /* in jiffies */ int kind;
u32 flags;
unsignedint update_interval; /* in milliseconds */
u8 config; /* Current configuration register value */
u8 config_orig; /* Original configuration register value */
u8 convrate_orig; /* Original conversion rate register value */
u8 resolution; /* temperature resolution in bit */
u16 alert_alarms; /* Which alarm bits trigger ALERT# */ /* Upper 8 bits for max6695/96 */
u8 max_convrate; /* Maximum conversion rate */
u8 reg_status2; /* 2nd status register (optional) */
u8 reg_local_ext; /* local extension register offset */
u8 reg_remote_ext; /* remote temperature low byte */
u8 faultqueue_mask; /* fault queue mask */
u8 faultqueue_depth; /* fault queue mask */
/* registers values */
u16 temp[TEMP_REG_NUM];
u8 temp_hyst;
u8 conalert;
u16 reported_alarms; /* alarms reported as sysfs/udev events */
u16 current_alarms; /* current alarms, reported by chip */
u16 alarms; /* alarms not yet reported to user */
};
/* * Support functions
*/
/* * If the chip supports PEC but not on write byte transactions, we need * to explicitly ask for a transaction without PEC.
*/ staticinline s32 lm90_write_no_pec(struct i2c_client *client, u8 value)
{ return i2c_smbus_xfer(client->adapter, client->addr,
client->flags & ~I2C_CLIENT_PEC,
I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
}
/* * 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.
*/ staticint lm90_read_reg(struct i2c_client *client, u8 reg)
{ struct lm90_data *data = i2c_get_clientdata(client); bool partial_pec = (client->flags & I2C_CLIENT_PEC) &&
(data->flags & LM90_HAVE_PARTIAL_PEC); int err;
if (partial_pec) {
err = lm90_write_no_pec(client, reg); if (err) return err; return i2c_smbus_read_byte(client);
} return i2c_smbus_read_byte_data(client, 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)
{ if (reg >= LM90_REG_CONFIG1 && reg <= LM90_REG_REMOTE_LOWH) return reg + 6; return reg;
}
/* * Write into LM90 register. * Convert register address to write address if needed, then execute the * operation.
*/ staticint lm90_write_reg(struct i2c_client *client, u8 reg, u8 val)
{ return i2c_smbus_write_byte_data(client, lm90_write_reg_addr(reg), val);
}
/* * Write into 16-bit LM90 register. * Convert register addresses to write address if needed, then execute the * operation.
*/ staticint lm90_write16(struct i2c_client *client, u8 regh, u8 regl, u16 val)
{ int ret;
ret = lm90_write_reg(client, regh, val >> 8); if (ret < 0 || !regl) return ret; return lm90_write_reg(client, regl, val & 0xff);
}
oldh = lm90_read_reg(client, regh); if (oldh < 0) return oldh;
if (!regl) return oldh << 8;
l = lm90_read_reg(client, regl); if (l < 0) return l;
if (!is_volatile) return (oldh << 8) | l;
/* * For volatile registers we have to use a trick. * We have to read two registers to have the sensor temperature, * but we have to beware a conversion could occur between the * readings. The datasheet says we should either use * the one-shot conversion register, which we don't want to do * (disables hardware monitoring) or monitor the busy bit, which is * impossible (we can't read the values and monitor that bit at the * exact same time). So the solution used here is to read the high * the high byte again. If the new high byte matches the old one, * then we have a valid reading. Otherwise we have to read the low * byte again, and now we believe we have a correct reading.
*/
newh = lm90_read_reg(client, regh); if (newh < 0) return newh; if (oldh != newh) {
l = lm90_read_reg(client, regl); if (l < 0) return l;
} return (newh << 8) | l;
}
staticint lm90_update_confreg(struct lm90_data *data, u8 config)
{ if (data->config != config) { int err;
/* * 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.
*/ staticint lm90_select_remote_channel(struct lm90_data *data, bool second)
{
u8 config = data->config & ~0x08;
if (second)
config |= 0x08;
return lm90_update_confreg(data, config);
}
staticint lm90_write_convrate(struct lm90_data *data, int val)
{
u8 config = data->config; int err;
/* Save config and pause conversion */ if (data->flags & LM90_PAUSE_FOR_CONFIG) {
err = lm90_update_confreg(data, config | 0x40); if (err < 0) return err;
}
/* Set conv rate */
err = lm90_write_reg(data->client, LM90_REG_CONVRATE, val);
/* Revert change to config */
lm90_update_confreg(data, config);
return err;
}
/* * Set conversion rate. * client->update_lock must be held when calling this function (unless we are * in detection or initialization steps).
*/ staticint lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, unsignedint interval)
{ unsignedint update_interval; int i, err;
if (data->flags & LM90_HAVE_OFFSET) {
val = lm90_read16(client, LM90_REG_REMOTE_OFFSH,
LM90_REG_REMOTE_OFFSL, false); if (val < 0) return val;
data->temp[REMOTE_OFFSET] = val;
}
if (data->flags & LM90_HAVE_EMERGENCY) {
val = lm90_read_reg(client, MAX6659_REG_LOCAL_EMERG); if (val < 0) return val;
data->temp[LOCAL_EMERG] = val << 8;
val = lm90_read_reg(client, MAX6659_REG_REMOTE_EMERG); if (val < 0) return val;
data->temp[REMOTE_EMERG] = val << 8;
}
if (data->flags & LM90_HAVE_TEMP3) {
val = lm90_select_remote_channel(data, true); if (val < 0) return val;
val = lm90_read_reg(client, LM90_REG_REMOTE_CRIT); if (val < 0) return val;
data->temp[REMOTE2_CRIT] = val << 8;
if (data->flags & LM90_HAVE_EMERGENCY) {
val = lm90_read_reg(client, MAX6659_REG_REMOTE_EMERG); if (val < 0) return val;
data->temp[REMOTE2_EMERG] = val << 8;
}
val = lm90_read_reg(client, LM90_REG_REMOTE_LOWH); if (val < 0) return val;
data->temp[REMOTE2_LOW] = val << 8;
val = lm90_read_reg(client, LM90_REG_REMOTE_HIGHH); if (val < 0) return val;
data->temp[REMOTE2_HIGH] = val << 8;
if (data->flags & LM90_HAVE_OFFSET) {
val = lm90_read16(client, LM90_REG_REMOTE_OFFSH,
LM90_REG_REMOTE_OFFSL, false); if (val < 0) return val;
data->temp[REMOTE2_OFFSET] = val;
}
val = lm90_read_reg(client, LM90_REG_STATUS); if (val < 0) return val;
alarms = val & ~LM90_STATUS_BUSY;
if (data->reg_status2) {
val = lm90_read_reg(client, data->reg_status2); if (val < 0) return val;
alarms |= val << 8;
} /* * If the update is forced (called from interrupt or alert * handler) and alarm data is valid, the alarms may have been * updated after the last update interval, and the status * register may still be cleared. Only add additional alarms * in this case. Alarms will be cleared later if appropriate.
*/ if (force && data->alarms_valid)
data->current_alarms |= alarms; else
data->current_alarms = alarms;
data->alarms |= alarms;
if (force || check_enable)
schedule_work(&data->report_work);
/* * Re-enable ALERT# output if it was originally enabled, relevant * alarms are all clear, and alerts are currently disabled. * Otherwise (re)schedule worker if needed.
*/ if (check_enable) { if (!(data->current_alarms & data->alert_alarms)) {
dev_dbg(&client->dev, "Re-enabling ALERT#\n");
lm90_update_confreg(data, data->config & ~0x80); /* * We may have been called from the update handler. * If so, the worker, if scheduled, is no longer * needed. Cancel it. Don't synchronize because * it may already be running.
*/
cancel_delayed_work(&data->alert_work);
} else {
schedule_delayed_work(&data->alert_work,
max_t(int, HZ, msecs_to_jiffies(data->update_interval)));
}
}
data->alarms_updated = jiffies;
data->alarms_valid = true;
} return 0;
}
staticint lm90_update_alarms(struct lm90_data *data, bool force)
{ int err;
staticint lm90_temp_get_resolution(struct lm90_data *data, int index)
{ switch (index) { case REMOTE_TEMP: if (data->reg_remote_ext) return data->resolution; return 8; case REMOTE_OFFSET: case REMOTE2_OFFSET: case REMOTE2_TEMP: return data->resolution; case LOCAL_TEMP: if (data->reg_local_ext) return data->resolution; return 8; case REMOTE_LOW: case REMOTE_HIGH: case REMOTE2_LOW: case REMOTE2_HIGH: if (data->flags & LM90_HAVE_REM_LIMIT_EXT) return data->resolution; return 8; default: return 8;
}
}
staticint lm90_temp_from_reg(u32 flags, u16 regval, u8 resolution)
{ int val;
if (flags & LM90_HAVE_EXTENDED_TEMP)
val = regval - 0x4000; elseif (flags & (LM90_HAVE_UNSIGNED_TEMP | LM90_HAVE_EXT_UNSIGNED))
val = regval; else
val = (s16)regval;
if (channel && (data->flags & LM90_HAVE_REM_LIMIT_EXT)) { if (index == REMOTE_LOW || index == REMOTE2_LOW)
regl = LM90_REG_REMOTE_LOWL; elseif (index == REMOTE_HIGH || index == REMOTE2_HIGH)
regl = LM90_REG_REMOTE_HIGHL;
}
/* +16 degrees offset for remote temperature on LM99 */ if (data->kind == lm99 && channel) { /* prevent integer underflow */
val = max(val, -128000l);
val -= 16000;
}
static umode_t lm90_temp_is_visible(constvoid *data, u32 attr, int channel)
{ switch (attr) { case hwmon_temp_input: case hwmon_temp_min_alarm: case hwmon_temp_max_alarm: case hwmon_temp_crit_alarm: case hwmon_temp_emergency_alarm: case hwmon_temp_emergency_hyst: case hwmon_temp_fault: case hwmon_temp_label: return 0444; case hwmon_temp_min: case hwmon_temp_max: case hwmon_temp_crit: case hwmon_temp_emergency: case hwmon_temp_offset: return 0644; case hwmon_temp_crit_hyst: if (channel == 0) return 0644; return 0444; default: return 0;
}
}
staticint lm90_chip_read(struct device *dev, u32 attr, int channel, long *val)
{ struct lm90_data *data = dev_get_drvdata(dev); int err;
mutex_lock(&data->update_lock);
err = lm90_update_device(dev);
mutex_unlock(&data->update_lock); if (err) return err;
switch (attr) { case hwmon_chip_update_interval:
*val = data->update_interval; break; case hwmon_chip_alarms:
*val = data->alarms; break; case hwmon_chip_temp_samples: if (data->faultqueue_mask) {
*val = (data->config & data->faultqueue_mask) ?
data->faultqueue_depth : 1;
} else { switch (data->conalert & 0x0e) { case 0x0: default:
*val = 1; break; case 0x2:
*val = 2; break; case 0x6:
*val = 3; break; case 0xe:
*val = 4; break;
}
} break; default: return -EOPNOTSUPP;
}
return 0;
}
staticint lm90_chip_write(struct device *dev, u32 attr, int channel, long val)
{ struct lm90_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; int err;
mutex_lock(&data->update_lock);
err = lm90_update_device(dev); if (err) goto error;
staticconstchar *lm90_detect_lm84(struct i2c_client *client)
{ staticconst u8 regs[] = {
LM90_REG_STATUS, LM90_REG_LOCAL_TEMP, LM90_REG_LOCAL_HIGH,
LM90_REG_REMOTE_TEMPH, LM90_REG_REMOTE_HIGHH
}; int status = i2c_smbus_read_byte_data(client, LM90_REG_STATUS); int reg1, reg2, reg3, reg4; bool nonzero = false;
u8 ff = 0xff; int i;
if (status < 0 || (status & 0xab)) return NULL;
/* * For LM84, undefined registers return the most recent value. * Repeat several times, each time checking against a different * (presumably) existing register.
*/ for (i = 0; i < ARRAY_SIZE(regs); i++) {
reg1 = i2c_smbus_read_byte_data(client, regs[i]);
reg2 = i2c_smbus_read_byte_data(client, LM90_REG_REMOTE_TEMPL);
reg3 = i2c_smbus_read_byte_data(client, LM90_REG_LOCAL_LOW);
reg4 = i2c_smbus_read_byte_data(client, LM90_REG_REMOTE_LOWH);
if (reg1 < 0) return NULL;
/* If any register has a different value, this is not an LM84 */ if (reg2 != reg1 || reg3 != reg1 || reg4 != reg1) return NULL;
nonzero |= reg1 || reg2 || reg3 || reg4;
ff &= reg1;
} /* * If all registers always returned 0 or 0xff, all bets are off, * and we can not make any predictions about the chip type.
*/ return nonzero && ff != 0xff ? "lm84" : NULL;
}
staticconstchar *lm90_detect_max1617(struct i2c_client *client, int config1)
{ int status = i2c_smbus_read_byte_data(client, LM90_REG_STATUS); int llo, rlo, lhi, rhi;
if (status < 0 || (status & 0x03)) return NULL;
if (config1 & 0x3f) return NULL;
/* * Fail if unsupported registers return anything but 0xff. * The calling code already checked man_id and chip_id. * A byte read operation repeats the most recent read operation * and should also return 0xff.
*/ if (i2c_smbus_read_byte_data(client, LM90_REG_REMOTE_TEMPL) != 0xff ||
i2c_smbus_read_byte_data(client, MAX6657_REG_LOCAL_TEMPL) != 0xff ||
i2c_smbus_read_byte_data(client, LM90_REG_REMOTE_LOWL) != 0xff ||
i2c_smbus_read_byte(client) != 0xff) return NULL;
/* * A byte read operation repeats the most recent read and should * return the same value.
*/ if (i2c_smbus_read_byte(client) != rhi) return NULL;
/* * The following two checks are marginal since the checked values * are strictly speaking valid.
*/
/* fail for negative high limits; this also catches read errors */ if ((s8)lhi < 0 || (s8)rhi < 0) return NULL;
/* fail if low limits are larger than or equal to high limits */ if ((s8)llo >= lhi || (s8)rlo >= rhi) return NULL;
if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { /* * Word read operations return 0xff in second byte
*/ if (i2c_smbus_read_word_data(client, LM90_REG_REMOTE_TEMPL) !=
0xffff) return NULL; if (i2c_smbus_read_word_data(client, LM90_REG_CONFIG1) !=
(config1 | 0xff00)) return NULL; if (i2c_smbus_read_word_data(client, LM90_REG_LOCAL_HIGH) !=
(lhi | 0xff00)) return NULL;
}
return"max1617";
}
staticconstchar *lm90_detect_national(struct i2c_client *client, int chip_id, int config1, int convrate)
{ int config2 = i2c_smbus_read_byte_data(client, LM90_REG_CONFIG2); int address = client->addr; constchar *name = NULL;
if (address != 0x4c && address != 0x4d) return NULL;
switch (chip_id & 0xf0) { case 0x10: /* LM86 */ if (address == 0x4c)
name = "lm86"; break; case 0x20: /* LM90 */ if (address == 0x4c)
name = "lm90"; break; case 0x30: /* LM89/LM99 */
name = "lm99"; /* detect LM89 as LM99 */ break; default: break;
}
return name;
}
staticconstchar *lm90_detect_on(struct i2c_client *client, int chip_id, int config1, int convrate)
{ int address = client->addr; constchar *name = NULL;
staticconstchar *lm90_detect_analog(struct i2c_client *client, bool common_address, int chip_id, int config1, int convrate)
{ int status = i2c_smbus_read_byte_data(client, LM90_REG_STATUS); int config2 = i2c_smbus_read_byte_data(client, ADT7481_REG_CONFIG2); int man_id2 = i2c_smbus_read_byte_data(client, ADT7481_REG_MAN_ID); int chip_id2 = i2c_smbus_read_byte_data(client, ADT7481_REG_CHIP_ID); int address = client->addr; constchar *name = NULL;
/* * The following chips should be detected by this function. Known * register values are listed. Registers 0x3d .. 0x3e are undocumented * for most of the chips, yet appear to return a well defined value. * Register 0xff is undocumented for some of the chips. Register 0x3f * is undocumented for all chips, but also returns a well defined value. * Values are as reported from real chips unless mentioned otherwise. * The code below checks values for registers 0x3d, 0x3e, and 0xff, * but not for register 0x3f. * * Chip Register * 3d 3e 3f fe ff Notes * ---------------------------------------------------------- * adm1020 00 00 00 41 39 * adm1021 00 00 00 41 03 * adm1021a 00 00 00 41 3c * adm1023 00 00 00 41 3c same as adm1021a * adm1032 00 00 00 41 42 * * adt7421 21 41 04 41 04 * adt7461 00 00 00 41 51 * adt7461a 61 41 05 41 57 * adt7481 81 41 02 41 62 * adt7482 - - - 41 65 datasheet * 82 41 05 41 75 real chip * adt7483 83 41 04 41 94 * * nct72 61 41 07 41 55 * nct210 00 00 00 41 3f * nct214 61 41 08 41 5a * nct1008 - - - 41 57 datasheet rev. 3 * 61 41 06 41 54 real chip * * nvt210 - - - 41 - datasheet * nvt211 - - - 41 - datasheet
*/ switch (chip_id) { case 0x00 ... 0x03: /* ADM1021 */ case 0x05 ... 0x0f: if (man_id2 == 0x00 && chip_id2 == 0x00 && common_address &&
!(status & 0x03) && !(config1 & 0x3f) && !(convrate & 0xf8))
name = "adm1021"; break; case 0x04: /* ADT7421 (undocumented) */ if (man_id2 == 0x41 && chip_id2 == 0x21 &&
(address == 0x4c || address == 0x4d) &&
(config1 & 0x0b) == 0x08 && convrate <= 0x0a)
name = "adt7421"; break; case 0x30 ... 0x38: /* ADM1021A, ADM1023 */ case 0x3a ... 0x3e: /* * ADM1021A and compatible chips will be mis-detected as * ADM1023. Chips labeled 'ADM1021A' and 'ADM1023' were both * found to have a Chip ID of 0x3c. * ADM1021A does not officially support low byte registers * (0x12 .. 0x14), but a chip labeled ADM1021A does support it. * Official support for the temperature offset high byte * register (0x11) was added to revision F of the ADM1021A * datasheet. * It is currently unknown if there is a means to distinguish * ADM1021A from ADM1023, and/or if revisions of ADM1021A exist * which differ in functionality from ADM1023.
*/ if (man_id2 == 0x00 && chip_id2 == 0x00 && common_address &&
!(status & 0x03) && !(config1 & 0x3f) && !(convrate & 0xf8))
name = "adm1023"; break; case 0x39: /* ADM1020 (undocumented) */ if (man_id2 == 0x00 && chip_id2 == 0x00 &&
(address == 0x4c || address == 0x4d || address == 0x4e) &&
!(status & 0x03) && !(config1 & 0x3f) && !(convrate & 0xf8))
name = "adm1020"; break; case 0x3f: /* NCT210 */ if (man_id2 == 0x00 && chip_id2 == 0x00 && common_address &&
!(status & 0x03) && !(config1 & 0x3f) && !(convrate & 0xf8))
name = "nct210"; break; case 0x40 ... 0x4f: /* ADM1032 */ if (man_id2 == 0x00 && chip_id2 == 0x00 &&
(address == 0x4c || address == 0x4d) && !(config1 & 0x3f) &&
convrate <= 0x0a)
name = "adm1032"; break; case 0x51: /* ADT7461 */ if (man_id2 == 0x00 && chip_id2 == 0x00 &&
(address == 0x4c || address == 0x4d) && !(config1 & 0x1b) &&
convrate <= 0x0a)
name = "adt7461"; break; case 0x54: /* NCT1008 */ if (man_id2 == 0x41 && chip_id2 == 0x61 &&
(address == 0x4c || address == 0x4d) && !(config1 & 0x1b) &&
convrate <= 0x0a)
name = "nct1008"; break; case 0x55: /* NCT72 */ if (man_id2 == 0x41 && chip_id2 == 0x61 &&
(address == 0x4c || address == 0x4d) && !(config1 & 0x1b) &&
convrate <= 0x0a)
name = "nct72"; break; case 0x57: /* ADT7461A, NCT1008 (datasheet rev. 3) */ if (man_id2 == 0x41 && chip_id2 == 0x61 &&
(address == 0x4c || address == 0x4d) && !(config1 & 0x1b) &&
convrate <= 0x0a)
name = "adt7461a"; break; case 0x5a: /* NCT214 */ if (man_id2 == 0x41 && chip_id2 == 0x61 &&
common_address && !(config1 & 0x1b) && convrate <= 0x0a)
name = "nct214"; break; case 0x62: /* ADT7481, undocumented */ if (man_id2 == 0x41 && chip_id2 == 0x81 &&
(address == 0x4b || address == 0x4c) && !(config1 & 0x10) &&
!(config2 & 0x7f) && (convrate & 0x0f) <= 0x0b) {
name = "adt7481";
} break; case 0x65: /* ADT7482, datasheet */ case 0x75: /* ADT7482, real chip */ if (man_id2 == 0x41 && chip_id2 == 0x82 &&
address == 0x4c && !(config1 & 0x10) && !(config2 & 0x7f) &&
convrate <= 0x0a)
name = "adt7482"; break; case 0x94: /* ADT7483 */ if (man_id2 == 0x41 && chip_id2 == 0x83 &&
common_address &&
((address >= 0x18 && address <= 0x1a) ||
(address >= 0x29 && address <= 0x2b) ||
(address >= 0x4c && address <= 0x4e)) &&
!(config1 & 0x10) && !(config2 & 0x7f) && convrate <= 0x0a)
name = "adt7483a"; break; default: break;
}
return name;
}
staticconstchar *lm90_detect_maxim(struct i2c_client *client, bool common_address, int chip_id, int config1, int convrate)
{ int man_id, emerg, emerg2, status2; int address = client->addr; constchar *name = NULL;
switch (chip_id) { case 0x01: if (!common_address) break;
/* * We read MAX6659_REG_REMOTE_EMERG twice, and re-read * LM90_REG_MAN_ID in between. If MAX6659_REG_REMOTE_EMERG * exists, both readings will reflect the same value. Otherwise, * the readings will be different.
*/
emerg = i2c_smbus_read_byte_data(client,
MAX6659_REG_REMOTE_EMERG);
man_id = i2c_smbus_read_byte_data(client,
LM90_REG_MAN_ID);
emerg2 = i2c_smbus_read_byte_data(client,
MAX6659_REG_REMOTE_EMERG);
status2 = i2c_smbus_read_byte_data(client,
MAX6696_REG_STATUS2); if (emerg < 0 || man_id < 0 || emerg2 < 0 || status2 < 0) return NULL;
/* * Even though MAX6695 and MAX6696 do not have a chip ID * register, reading it returns 0x01. Bit 4 of the config1 * register is unused and should return zero when read. Bit 0 of * the status2 register is unused and should return zero when * read. * * MAX6695 and MAX6696 have an additional set of temperature * limit registers. We can detect those chips by checking if * one of those registers exists.
*/ if (!(config1 & 0x10) && !(status2 & 0x01) && emerg == emerg2 &&
convrate <= 0x07)
name = "max6696"; /* * The chip_id register of the MAX6680 and MAX6681 holds the * revision of the chip. The lowest bit of the config1 register * is unused and should return zero when read, so should the * second to last bit of config1 (software reset). Register * address 0x12 (LM90_REG_REMOTE_OFFSL) exists for this chip and * should differ from emerg2, and emerg2 should match man_id * since it does not exist.
*/ elseif (!(config1 & 0x03) && convrate <= 0x07 &&
emerg2 == man_id && emerg2 != status2)
name = "max6680"; /* * MAX1617A does not have any extended registers (register * address 0x10 or higher) except for manufacturer and * device ID registers. Unlike other chips of this series, * unsupported registers were observed to return a fixed value * of 0x01. * Note: Multiple chips with different markings labeled as * "MAX1617" (no "A") were observed to report manufacturer ID * 0x4d and device ID 0x01. It is unknown if other variants of * MAX1617/MAX617A with different behavior exist. The detection * code below works for those chips.
*/ elseif (!(config1 & 0x03f) && convrate <= 0x07 &&
emerg == 0x01 && emerg2 == 0x01 && status2 == 0x01)
name = "max1617"; break; case 0x08: /* * The chip_id of the MAX6654 holds the revision of the chip. * The lowest 3 bits of the config1 register are unused and * should return zero when read.
*/ if (common_address && !(config1 & 0x07) && convrate <= 0x07)
name = "max6654"; break; case 0x09: /* * The chip_id of the MAX6690 holds the revision of the chip. * The lowest 3 bits of the config1 register are unused and * should return zero when read. * Note that MAX6654 and MAX6690 are practically the same chips. * The only diference is the rated accuracy. Rev. 1 of the * MAX6690 datasheet lists a chip ID of 0x08, and a chip labeled * MAX6654 was observed to have a chip ID of 0x09.
*/ if (common_address && !(config1 & 0x07) && convrate <= 0x07)
name = "max6690"; break; case 0x4d: /* * MAX6642, MAX6657, MAX6658 and MAX6659 do NOT have a chip_id * register. Reading from that address will return the last * read value, which in our case is those of the man_id * register, or 0x4d. * MAX6642 does not have a conversion rate register, nor low * limit registers. Reading from those registers returns the * last read value. * * For MAX6657, MAX6658 and MAX6659, the config1 register lacks * a low nibble, so the value will be those of the previous
--> --------------------
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.