| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- * Copyright (c) 2012 Guenter Roeck <linux@roeck-us.net>
- *
- * based on max1668.c
- * Copyright (c) 2011 David George <david.george@ska.ac.za>
- */
- #include <linux/bitfield.h>
- #include <linux/bits.h>
- #include <linux/err.h>
- #include <linux/hwmon.h>
- #include <linux/i2c.h>
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/regmap.h>
- #include <linux/slab.h>
- enum chips { max6581, max6602, max6622, max6636, max6689, max6693, max6694,
- max6697, max6698, max6699 };
- /* Report local sensor as temp1 */
- static const u8 MAX6697_REG_TEMP[] = {
- 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08 };
- static const u8 MAX6697_REG_TEMP_EXT[] = {
- 0x57, 0x09, 0x52, 0x53, 0x54, 0x55, 0x56, 0 };
- static const u8 MAX6697_REG_MAX[] = {
- 0x17, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x18 };
- static const u8 MAX6697_REG_CRIT[] = {
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 };
- #define MAX6697_REG_MIN 0x30
- /*
- * Map device tree / internal register bit map to chip bit map.
- * Applies to alert register and over-temperature register.
- */
- #define MAX6697_EXTERNAL_MASK_DT GENMASK(7, 1)
- #define MAX6697_LOCAL_MASK_DT BIT(0)
- #define MAX6697_EXTERNAL_MASK_CHIP GENMASK(6, 0)
- #define MAX6697_LOCAL_MASK_CHIP BIT(7)
- /* alert - local channel is in bit 6 */
- #define MAX6697_ALERT_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \
- (((reg) & 0x01) << 6) | ((reg) & 0x80))
- /* over-temperature - local channel is in bit 7 */
- #define MAX6697_OVERT_MAP_BITS(reg) \
- (FIELD_PREP(MAX6697_EXTERNAL_MASK_CHIP, FIELD_GET(MAX6697_EXTERNAL_MASK_DT, reg)) | \
- FIELD_PREP(MAX6697_LOCAL_MASK_CHIP, FIELD_GET(MAX6697_LOCAL_MASK_DT, reg)))
- #define MAX6697_REG_STAT_ALARM 0x44
- #define MAX6697_REG_STAT_CRIT 0x45
- #define MAX6697_REG_STAT_FAULT 0x46
- #define MAX6697_REG_STAT_MIN_ALARM 0x47
- #define MAX6697_REG_CONFIG 0x41
- #define MAX6581_CONF_EXTENDED BIT(1)
- #define MAX6693_CONF_BETA BIT(2)
- #define MAX6697_CONF_RESISTANCE BIT(3)
- #define MAX6697_CONF_TIMEOUT BIT(5)
- #define MAX6697_REG_ALERT_MASK 0x42
- #define MAX6697_REG_OVERT_MASK 0x43
- #define MAX6581_REG_RESISTANCE 0x4a
- #define MAX6581_REG_IDEALITY 0x4b
- #define MAX6581_REG_IDEALITY_SELECT 0x4c
- #define MAX6581_REG_OFFSET 0x4d
- #define MAX6581_REG_OFFSET_SELECT 0x4e
- #define MAX6581_OFFSET_MIN -31750
- #define MAX6581_OFFSET_MAX 31750
- #define MAX6697_CONV_TIME 156 /* ms per channel, worst case */
- struct max6697_chip_data {
- int channels;
- u32 have_ext;
- u32 have_crit;
- u32 have_fault;
- u8 valid_conf;
- };
- struct max6697_data {
- struct regmap *regmap;
- enum chips type;
- const struct max6697_chip_data *chip;
- int temp_offset; /* in degrees C */
- #define MAX6697_TEMP_INPUT 0
- #define MAX6697_TEMP_EXT 1
- #define MAX6697_TEMP_MAX 2
- #define MAX6697_TEMP_CRIT 3
- u32 alarms;
- };
- static const struct max6697_chip_data max6697_chip_data[] = {
- [max6581] = {
- .channels = 8,
- .have_crit = 0xff,
- .have_ext = 0x7f,
- .have_fault = 0xfe,
- .valid_conf = MAX6581_CONF_EXTENDED | MAX6697_CONF_TIMEOUT,
- },
- [max6602] = {
- .channels = 5,
- .have_crit = 0x12,
- .have_ext = 0x02,
- .have_fault = 0x1e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
- },
- [max6622] = {
- .channels = 5,
- .have_crit = 0x12,
- .have_ext = 0x02,
- .have_fault = 0x1e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
- },
- [max6636] = {
- .channels = 7,
- .have_crit = 0x72,
- .have_ext = 0x02,
- .have_fault = 0x7e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
- },
- [max6689] = {
- .channels = 7,
- .have_crit = 0x72,
- .have_ext = 0x02,
- .have_fault = 0x7e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
- },
- [max6693] = {
- .channels = 7,
- .have_crit = 0x72,
- .have_ext = 0x02,
- .have_fault = 0x7e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6693_CONF_BETA |
- MAX6697_CONF_TIMEOUT,
- },
- [max6694] = {
- .channels = 5,
- .have_crit = 0x12,
- .have_ext = 0x02,
- .have_fault = 0x1e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6693_CONF_BETA |
- MAX6697_CONF_TIMEOUT,
- },
- [max6697] = {
- .channels = 7,
- .have_crit = 0x72,
- .have_ext = 0x02,
- .have_fault = 0x7e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
- },
- [max6698] = {
- .channels = 7,
- .have_crit = 0x72,
- .have_ext = 0x02,
- .have_fault = 0x0e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
- },
- [max6699] = {
- .channels = 5,
- .have_crit = 0x12,
- .have_ext = 0x02,
- .have_fault = 0x1e,
- .valid_conf = MAX6697_CONF_RESISTANCE | MAX6697_CONF_TIMEOUT,
- },
- };
- static int max6697_alarm_channel_map(int channel)
- {
- switch (channel) {
- case 0:
- return 6;
- case 7:
- return 7;
- default:
- return channel - 1;
- }
- }
- static int max6697_read(struct device *dev, enum hwmon_sensor_types type,
- u32 attr, int channel, long *val)
- {
- unsigned int offset_regs[2] = { MAX6581_REG_OFFSET_SELECT, MAX6581_REG_OFFSET };
- unsigned int temp_regs[2] = { MAX6697_REG_TEMP[channel],
- MAX6697_REG_TEMP_EXT[channel] };
- struct max6697_data *data = dev_get_drvdata(dev);
- struct regmap *regmap = data->regmap;
- u8 regdata[2] = { };
- u32 regval;
- int ret;
- switch (attr) {
- case hwmon_temp_input:
- ret = regmap_multi_reg_read(regmap, temp_regs, regdata,
- data->chip->have_ext & BIT(channel) ? 2 : 1);
- if (ret)
- return ret;
- *val = (((regdata[0] - data->temp_offset) << 3) | (regdata[1] >> 5)) * 125;
- break;
- case hwmon_temp_max:
- ret = regmap_read(regmap, MAX6697_REG_MAX[channel], ®val);
- if (ret)
- return ret;
- *val = ((int)regval - data->temp_offset) * 1000;
- break;
- case hwmon_temp_crit:
- ret = regmap_read(regmap, MAX6697_REG_CRIT[channel], ®val);
- if (ret)
- return ret;
- *val = ((int)regval - data->temp_offset) * 1000;
- break;
- case hwmon_temp_min:
- ret = regmap_read(regmap, MAX6697_REG_MIN, ®val);
- if (ret)
- return ret;
- *val = ((int)regval - data->temp_offset) * 1000;
- break;
- case hwmon_temp_offset:
- ret = regmap_multi_reg_read(regmap, offset_regs, regdata, 2);
- if (ret)
- return ret;
- if (!(regdata[0] & BIT(channel - 1)))
- regdata[1] = 0;
- *val = sign_extend32(regdata[1], 7) * 250;
- break;
- case hwmon_temp_fault:
- ret = regmap_read(regmap, MAX6697_REG_STAT_FAULT, ®val);
- if (ret)
- return ret;
- if (data->type == max6581)
- *val = !!(regval & BIT(channel - 1));
- else
- *val = !!(regval & BIT(channel));
- break;
- case hwmon_temp_crit_alarm:
- ret = regmap_read(regmap, MAX6697_REG_STAT_CRIT, ®val);
- if (ret)
- return ret;
- /*
- * In the MAX6581 datasheet revision 0 to 3, the local channel
- * overtemperature status is reported in bit 6 of register 0x45,
- * and the overtemperature status for remote channel 7 is
- * reported in bit 7. In Revision 4 and later, the local channel
- * overtemperature status is reported in bit 7, and the remote
- * channel 7 overtemperature status is reported in bit 6. A real
- * chip was found to match the functionality documented in
- * Revision 4 and later.
- */
- *val = !!(regval & BIT(channel ? channel - 1 : 7));
- break;
- case hwmon_temp_max_alarm:
- ret = regmap_read(regmap, MAX6697_REG_STAT_ALARM, ®val);
- if (ret)
- return ret;
- *val = !!(regval & BIT(max6697_alarm_channel_map(channel)));
- break;
- case hwmon_temp_min_alarm:
- ret = regmap_read(regmap, MAX6697_REG_STAT_MIN_ALARM, ®val);
- if (ret)
- return ret;
- *val = !!(regval & BIT(max6697_alarm_channel_map(channel)));
- break;
- default:
- return -EOPNOTSUPP;
- }
- return 0;
- }
- static int max6697_write(struct device *dev, enum hwmon_sensor_types type,
- u32 attr, int channel, long val)
- {
- struct max6697_data *data = dev_get_drvdata(dev);
- struct regmap *regmap = data->regmap;
- int ret;
- switch (attr) {
- case hwmon_temp_max:
- val = clamp_val(val, -1000000, 1000000); /* prevent underflow */
- val = DIV_ROUND_CLOSEST(val, 1000) + data->temp_offset;
- val = clamp_val(val, 0, data->type == max6581 ? 255 : 127);
- return regmap_write(regmap, MAX6697_REG_MAX[channel], val);
- case hwmon_temp_crit:
- val = clamp_val(val, -1000000, 1000000); /* prevent underflow */
- val = DIV_ROUND_CLOSEST(val, 1000) + data->temp_offset;
- val = clamp_val(val, 0, data->type == max6581 ? 255 : 127);
- return regmap_write(regmap, MAX6697_REG_CRIT[channel], val);
- case hwmon_temp_min:
- val = clamp_val(val, -1000000, 1000000); /* prevent underflow */
- val = DIV_ROUND_CLOSEST(val, 1000) + data->temp_offset;
- val = clamp_val(val, 0, 255);
- return regmap_write(regmap, MAX6697_REG_MIN, val);
- case hwmon_temp_offset:
- val = clamp_val(val, MAX6581_OFFSET_MIN, MAX6581_OFFSET_MAX);
- val = DIV_ROUND_CLOSEST(val, 250);
- if (!val) { /* disable this (and only this) channel */
- ret = regmap_clear_bits(regmap, MAX6581_REG_OFFSET_SELECT,
- BIT(channel - 1));
- } else {
- /* enable channel and update offset */
- ret = regmap_set_bits(regmap, MAX6581_REG_OFFSET_SELECT,
- BIT(channel - 1));
- if (ret)
- return ret;
- ret = regmap_write(regmap, MAX6581_REG_OFFSET, val);
- }
- return ret;
- default:
- return -EOPNOTSUPP;
- }
- }
- static umode_t max6697_is_visible(const void *_data, enum hwmon_sensor_types type,
- u32 attr, int channel)
- {
- const struct max6697_data *data = _data;
- const struct max6697_chip_data *chip = data->chip;
- if (channel >= chip->channels)
- return 0;
- switch (attr) {
- case hwmon_temp_max:
- return 0644;
- case hwmon_temp_input:
- case hwmon_temp_max_alarm:
- return 0444;
- case hwmon_temp_min:
- if (data->type == max6581)
- return channel ? 0444 : 0644;
- break;
- case hwmon_temp_min_alarm:
- if (data->type == max6581)
- return 0444;
- break;
- case hwmon_temp_crit:
- if (chip->have_crit & BIT(channel))
- return 0644;
- break;
- case hwmon_temp_crit_alarm:
- if (chip->have_crit & BIT(channel))
- return 0444;
- break;
- case hwmon_temp_fault:
- if (chip->have_fault & BIT(channel))
- return 0444;
- break;
- case hwmon_temp_offset:
- if (data->type == max6581 && channel)
- return 0644;
- break;
- default:
- break;
- }
- return 0;
- }
- /* Return 0 if detection is successful, -ENODEV otherwise */
- static const struct hwmon_channel_info * const max6697_info[] = {
- HWMON_CHANNEL_INFO(temp,
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_MIN | HWMON_T_MIN_ALARM |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM,
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |
- HWMON_T_MIN | HWMON_T_MIN_ALARM |
- HWMON_T_FAULT | HWMON_T_OFFSET,
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |
- HWMON_T_MIN | HWMON_T_MIN_ALARM |
- HWMON_T_FAULT | HWMON_T_OFFSET,
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |
- HWMON_T_MIN | HWMON_T_MIN_ALARM |
- HWMON_T_FAULT | HWMON_T_OFFSET,
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |
- HWMON_T_MIN | HWMON_T_MIN_ALARM |
- HWMON_T_FAULT | HWMON_T_OFFSET,
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |
- HWMON_T_MIN | HWMON_T_MIN_ALARM |
- HWMON_T_FAULT | HWMON_T_OFFSET,
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |
- HWMON_T_MIN | HWMON_T_MIN_ALARM |
- HWMON_T_FAULT | HWMON_T_OFFSET,
- HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |
- HWMON_T_MIN | HWMON_T_MIN_ALARM |
- HWMON_T_FAULT | HWMON_T_OFFSET),
- NULL
- };
- static const struct hwmon_ops max6697_hwmon_ops = {
- .is_visible = max6697_is_visible,
- .read = max6697_read,
- .write = max6697_write,
- };
- static const struct hwmon_chip_info max6697_chip_info = {
- .ops = &max6697_hwmon_ops,
- .info = max6697_info,
- };
- static int max6697_config_of(struct device_node *node, struct max6697_data *data)
- {
- const struct max6697_chip_data *chip = data->chip;
- struct regmap *regmap = data->regmap;
- int ret, confreg;
- u32 vals[2];
- confreg = 0;
- if (of_property_read_bool(node, "smbus-timeout-disable") &&
- (chip->valid_conf & MAX6697_CONF_TIMEOUT)) {
- confreg |= MAX6697_CONF_TIMEOUT;
- }
- if (of_property_read_bool(node, "extended-range-enable") &&
- (chip->valid_conf & MAX6581_CONF_EXTENDED)) {
- confreg |= MAX6581_CONF_EXTENDED;
- data->temp_offset = 64;
- }
- if (of_property_read_bool(node, "beta-compensation-enable") &&
- (chip->valid_conf & MAX6693_CONF_BETA)) {
- confreg |= MAX6693_CONF_BETA;
- }
- if (of_property_read_u32(node, "alert-mask", vals))
- vals[0] = 0;
- ret = regmap_write(regmap, MAX6697_REG_ALERT_MASK,
- MAX6697_ALERT_MAP_BITS(vals[0]));
- if (ret)
- return ret;
- if (of_property_read_u32(node, "over-temperature-mask", vals))
- vals[0] = 0;
- ret = regmap_write(regmap, MAX6697_REG_OVERT_MASK,
- MAX6697_OVERT_MAP_BITS(vals[0]));
- if (ret)
- return ret;
- if (data->type != max6581) {
- if (of_property_read_bool(node, "resistance-cancellation") &&
- chip->valid_conf & MAX6697_CONF_RESISTANCE) {
- confreg |= MAX6697_CONF_RESISTANCE;
- }
- } else {
- if (of_property_read_u32(node, "resistance-cancellation", &vals[0])) {
- if (of_property_read_bool(node, "resistance-cancellation"))
- vals[0] = 0xfe;
- else
- vals[0] = 0;
- }
- vals[0] &= 0xfe;
- ret = regmap_write(regmap, MAX6581_REG_RESISTANCE, vals[0] >> 1);
- if (ret < 0)
- return ret;
- if (of_property_read_u32_array(node, "transistor-ideality", vals, 2)) {
- vals[0] = 0;
- vals[1] = 0;
- }
- ret = regmap_write(regmap, MAX6581_REG_IDEALITY, vals[1]);
- if (ret < 0)
- return ret;
- ret = regmap_write(regmap, MAX6581_REG_IDEALITY_SELECT,
- (vals[0] & 0xfe) >> 1);
- if (ret < 0)
- return ret;
- }
- return regmap_write(regmap, MAX6697_REG_CONFIG, confreg);
- }
- static int max6697_init_chip(struct device_node *np, struct max6697_data *data)
- {
- unsigned int reg;
- int ret;
- /*
- * Don't touch configuration if there is no devicetree configuration.
- * If that is the case, use the current chip configuration.
- */
- if (!np) {
- struct regmap *regmap = data->regmap;
- ret = regmap_read(regmap, MAX6697_REG_CONFIG, ®);
- if (ret < 0)
- return ret;
- if (data->type == max6581) {
- if (reg & MAX6581_CONF_EXTENDED)
- data->temp_offset = 64;
- ret = regmap_read(regmap, MAX6581_REG_RESISTANCE, ®);
- }
- } else {
- ret = max6697_config_of(np, data);
- }
- return ret;
- }
- static bool max6697_volatile_reg(struct device *dev, unsigned int reg)
- {
- switch (reg) {
- case 0x00 ... 0x09: /* temperature high bytes */
- case 0x44 ... 0x47: /* status */
- case 0x51 ... 0x58: /* temperature low bytes */
- return true;
- default:
- return false;
- }
- }
- static bool max6697_writeable_reg(struct device *dev, unsigned int reg)
- {
- return reg != 0x0a && reg != 0x0f && !max6697_volatile_reg(dev, reg);
- }
- static const struct regmap_config max6697_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 0x58,
- .writeable_reg = max6697_writeable_reg,
- .volatile_reg = max6697_volatile_reg,
- .cache_type = REGCACHE_MAPLE,
- };
- static int max6697_probe(struct i2c_client *client)
- {
- struct device *dev = &client->dev;
- struct max6697_data *data;
- struct device *hwmon_dev;
- struct regmap *regmap;
- int err;
- regmap = devm_regmap_init_i2c(client, &max6697_regmap_config);
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
- data = devm_kzalloc(dev, sizeof(struct max6697_data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
- data->regmap = regmap;
- data->type = (uintptr_t)i2c_get_match_data(client);
- data->chip = &max6697_chip_data[data->type];
- err = max6697_init_chip(client->dev.of_node, data);
- if (err)
- return err;
- hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
- &max6697_chip_info, NULL);
- return PTR_ERR_OR_ZERO(hwmon_dev);
- }
- static const struct i2c_device_id max6697_id[] = {
- { "max6581", max6581 },
- { "max6602", max6602 },
- { "max6622", max6622 },
- { "max6636", max6636 },
- { "max6689", max6689 },
- { "max6693", max6693 },
- { "max6694", max6694 },
- { "max6697", max6697 },
- { "max6698", max6698 },
- { "max6699", max6699 },
- { }
- };
- MODULE_DEVICE_TABLE(i2c, max6697_id);
- static const struct of_device_id __maybe_unused max6697_of_match[] = {
- {
- .compatible = "maxim,max6581",
- .data = (void *)max6581
- },
- {
- .compatible = "maxim,max6602",
- .data = (void *)max6602
- },
- {
- .compatible = "maxim,max6622",
- .data = (void *)max6622
- },
- {
- .compatible = "maxim,max6636",
- .data = (void *)max6636
- },
- {
- .compatible = "maxim,max6689",
- .data = (void *)max6689
- },
- {
- .compatible = "maxim,max6693",
- .data = (void *)max6693
- },
- {
- .compatible = "maxim,max6694",
- .data = (void *)max6694
- },
- {
- .compatible = "maxim,max6697",
- .data = (void *)max6697
- },
- {
- .compatible = "maxim,max6698",
- .data = (void *)max6698
- },
- {
- .compatible = "maxim,max6699",
- .data = (void *)max6699
- },
- { },
- };
- MODULE_DEVICE_TABLE(of, max6697_of_match);
- static struct i2c_driver max6697_driver = {
- .driver = {
- .name = "max6697",
- .of_match_table = of_match_ptr(max6697_of_match),
- },
- .probe = max6697_probe,
- .id_table = max6697_id,
- };
- module_i2c_driver(max6697_driver);
- MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
- MODULE_DESCRIPTION("MAX6697 temperature sensor driver");
- MODULE_LICENSE("GPL");
|