--- zzzz-none-000/linux-3.10.107/drivers/hwmon/lm85.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/hwmon/lm85.c 2021-02-04 17:41:59.000000000 +0000 @@ -5,7 +5,7 @@ * Copyright (c) 2002, 2003 Philip Pokorny * Copyright (c) 2003 Margit Schubert-While * Copyright (c) 2004 Justin Thiessen - * Copyright (C) 2007--2009 Jean Delvare + * Copyright (C) 2007--2014 Jean Delvare * * Chip details at * @@ -34,12 +34,13 @@ #include #include #include +#include /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; enum chips { - any_chip, lm85b, lm85c, + lm85, adm1027, adt7463, adt7468, emc6d100, emc6d102, emc6d103, emc6d103s }; @@ -75,9 +76,6 @@ #define LM85_COMPANY_NATIONAL 0x01 #define LM85_COMPANY_ANALOG_DEV 0x41 #define LM85_COMPANY_SMSC 0x5c -#define LM85_VERSTEP_VMASK 0xf0 -#define LM85_VERSTEP_GENERIC 0x60 -#define LM85_VERSTEP_GENERIC2 0x70 #define LM85_VERSTEP_LM85C 0x60 #define LM85_VERSTEP_LM85B 0x62 #define LM85_VERSTEP_LM96000_1 0x68 @@ -124,7 +122,6 @@ #define EMC6D102_REG_EXTEND_ADC3 0x87 #define EMC6D102_REG_EXTEND_ADC4 0x88 - /* * Conversions. Rounding and limit checking is only done on the TO_REG * variants. Note that you should be a bit careful with which arguments @@ -194,15 +191,7 @@ static int RANGE_TO_REG(long range) { - int i; - - /* Find the closest match */ - for (i = 0; i < 15; ++i) { - if (range <= (lm85_range_map[i] + lm85_range_map[i + 1]) / 2) - break; - } - - return i; + return find_closest(range, lm85_range_map, ARRAY_SIZE(lm85_range_map)); } #define RANGE_FROM_REG(val) lm85_range_map[(val) & 0x0f] @@ -213,16 +202,12 @@ static const int adm1027_freq_map[8] = { /* 1 Hz */ 11, 15, 22, 29, 35, 44, 59, 88 }; +#define FREQ_MAP_LEN 8 -static int FREQ_TO_REG(const int *map, unsigned long freq) +static int FREQ_TO_REG(const int *map, + unsigned int map_size, unsigned long freq) { - int i; - - /* Find the closest match */ - for (i = 0; i < 7; ++i) - if (freq <= (map[i] + map[i + 1]) / 2) - break; - return i; + return find_closest(freq, map, map_size); } static int FREQ_FROM_REG(const int *map, u8 reg) @@ -306,7 +291,8 @@ * The structure is dynamically allocated. */ struct lm85_data { - struct device *hwmon_dev; + struct i2c_client *client; + const struct attribute_group *groups[6]; const int *freq_map; enum chips type; @@ -337,44 +323,235 @@ struct lm85_zone zone[3]; }; -static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info); -static int lm85_probe(struct i2c_client *client, - const struct i2c_device_id *id); -static int lm85_remove(struct i2c_client *client); - -static int lm85_read_value(struct i2c_client *client, u8 reg); -static void lm85_write_value(struct i2c_client *client, u8 reg, int value); -static struct lm85_data *lm85_update_device(struct device *dev); +static int lm85_read_value(struct i2c_client *client, u8 reg) +{ + int res; + /* What size location is it? */ + switch (reg) { + case LM85_REG_FAN(0): /* Read WORD data */ + case LM85_REG_FAN(1): + case LM85_REG_FAN(2): + case LM85_REG_FAN(3): + case LM85_REG_FAN_MIN(0): + case LM85_REG_FAN_MIN(1): + case LM85_REG_FAN_MIN(2): + case LM85_REG_FAN_MIN(3): + case LM85_REG_ALARM1: /* Read both bytes at once */ + res = i2c_smbus_read_byte_data(client, reg) & 0xff; + res |= i2c_smbus_read_byte_data(client, reg + 1) << 8; + break; + default: /* Read BYTE data */ + res = i2c_smbus_read_byte_data(client, reg); + break; + } -static const struct i2c_device_id lm85_id[] = { - { "adm1027", adm1027 }, - { "adt7463", adt7463 }, - { "adt7468", adt7468 }, - { "lm85", any_chip }, - { "lm85b", lm85b }, - { "lm85c", lm85c }, - { "emc6d100", emc6d100 }, - { "emc6d101", emc6d100 }, - { "emc6d102", emc6d102 }, - { "emc6d103", emc6d103 }, - { "emc6d103s", emc6d103s }, - { } -}; -MODULE_DEVICE_TABLE(i2c, lm85_id); + return res; +} -static struct i2c_driver lm85_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "lm85", - }, - .probe = lm85_probe, - .remove = lm85_remove, - .id_table = lm85_id, - .detect = lm85_detect, - .address_list = normal_i2c, -}; +static void lm85_write_value(struct i2c_client *client, u8 reg, int value) +{ + switch (reg) { + case LM85_REG_FAN(0): /* Write WORD data */ + case LM85_REG_FAN(1): + case LM85_REG_FAN(2): + case LM85_REG_FAN(3): + case LM85_REG_FAN_MIN(0): + case LM85_REG_FAN_MIN(1): + case LM85_REG_FAN_MIN(2): + case LM85_REG_FAN_MIN(3): + /* NOTE: ALARM is read only, so not included here */ + i2c_smbus_write_byte_data(client, reg, value & 0xff); + i2c_smbus_write_byte_data(client, reg + 1, value >> 8); + break; + default: /* Write BYTE data */ + i2c_smbus_write_byte_data(client, reg, value); + break; + } +} + +static struct lm85_data *lm85_update_device(struct device *dev) +{ + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int i; + + mutex_lock(&data->update_lock); + + if (!data->valid || + time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) { + /* Things that change quickly */ + dev_dbg(&client->dev, "Reading sensor values\n"); + /* + * Have to read extended bits first to "freeze" the + * more significant bits that are read later. + * There are 2 additional resolution bits per channel and we + * have room for 4, so we shift them to the left. + */ + if (data->type == adm1027 || data->type == adt7463 || + data->type == adt7468) { + int ext1 = lm85_read_value(client, + ADM1027_REG_EXTEND_ADC1); + int ext2 = lm85_read_value(client, + ADM1027_REG_EXTEND_ADC2); + int val = (ext1 << 8) + ext2; + + for (i = 0; i <= 4; i++) + data->in_ext[i] = + ((val >> (i * 2)) & 0x03) << 2; + + for (i = 0; i <= 2; i++) + data->temp_ext[i] = + (val >> ((i + 4) * 2)) & 0x0c; + } + + data->vid = lm85_read_value(client, LM85_REG_VID); + + for (i = 0; i <= 3; ++i) { + data->in[i] = + lm85_read_value(client, LM85_REG_IN(i)); + data->fan[i] = + lm85_read_value(client, LM85_REG_FAN(i)); + } + + if (!data->has_vid5) + data->in[4] = lm85_read_value(client, LM85_REG_IN(4)); + + if (data->type == adt7468) + data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5); + + for (i = 0; i <= 2; ++i) { + data->temp[i] = + lm85_read_value(client, LM85_REG_TEMP(i)); + data->pwm[i] = + lm85_read_value(client, LM85_REG_PWM(i)); + + if (IS_ADT7468_OFF64(data)) + data->temp[i] -= 64; + } + + data->alarms = lm85_read_value(client, LM85_REG_ALARM1); + + if (data->type == emc6d100) { + /* Three more voltage sensors */ + for (i = 5; i <= 7; ++i) { + data->in[i] = lm85_read_value(client, + EMC6D100_REG_IN(i)); + } + /* More alarm bits */ + data->alarms |= lm85_read_value(client, + EMC6D100_REG_ALARM3) << 16; + } else if (data->type == emc6d102 || data->type == emc6d103 || + data->type == emc6d103s) { + /* + * Have to read LSB bits after the MSB ones because + * the reading of the MSB bits has frozen the + * LSBs (backward from the ADM1027). + */ + int ext1 = lm85_read_value(client, + EMC6D102_REG_EXTEND_ADC1); + int ext2 = lm85_read_value(client, + EMC6D102_REG_EXTEND_ADC2); + int ext3 = lm85_read_value(client, + EMC6D102_REG_EXTEND_ADC3); + int ext4 = lm85_read_value(client, + EMC6D102_REG_EXTEND_ADC4); + data->in_ext[0] = ext3 & 0x0f; + data->in_ext[1] = ext4 & 0x0f; + data->in_ext[2] = ext4 >> 4; + data->in_ext[3] = ext3 >> 4; + data->in_ext[4] = ext2 >> 4; + + data->temp_ext[0] = ext1 & 0x0f; + data->temp_ext[1] = ext2 & 0x0f; + data->temp_ext[2] = ext1 >> 4; + } + + data->last_reading = jiffies; + } /* last_reading */ + + if (!data->valid || + time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) { + /* Things that don't change often */ + dev_dbg(&client->dev, "Reading config values\n"); + + for (i = 0; i <= 3; ++i) { + data->in_min[i] = + lm85_read_value(client, LM85_REG_IN_MIN(i)); + data->in_max[i] = + lm85_read_value(client, LM85_REG_IN_MAX(i)); + data->fan_min[i] = + lm85_read_value(client, LM85_REG_FAN_MIN(i)); + } + + if (!data->has_vid5) { + data->in_min[4] = lm85_read_value(client, + LM85_REG_IN_MIN(4)); + data->in_max[4] = lm85_read_value(client, + LM85_REG_IN_MAX(4)); + } + + if (data->type == emc6d100) { + for (i = 5; i <= 7; ++i) { + data->in_min[i] = lm85_read_value(client, + EMC6D100_REG_IN_MIN(i)); + data->in_max[i] = lm85_read_value(client, + EMC6D100_REG_IN_MAX(i)); + } + } + + for (i = 0; i <= 2; ++i) { + int val; + + data->temp_min[i] = + lm85_read_value(client, LM85_REG_TEMP_MIN(i)); + data->temp_max[i] = + lm85_read_value(client, LM85_REG_TEMP_MAX(i)); + + data->autofan[i].config = + lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); + val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); + data->pwm_freq[i] = val & 0x07; + data->zone[i].range = val >> 4; + data->autofan[i].min_pwm = + lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); + data->zone[i].limit = + lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); + data->zone[i].critical = + lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); + + if (IS_ADT7468_OFF64(data)) { + data->temp_min[i] -= 64; + data->temp_max[i] -= 64; + data->zone[i].limit -= 64; + data->zone[i].critical -= 64; + } + } + + if (data->type != emc6d103s) { + i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); + data->autofan[0].min_off = (i & 0x20) != 0; + data->autofan[1].min_off = (i & 0x40) != 0; + data->autofan[2].min_off = (i & 0x80) != 0; + + i = lm85_read_value(client, LM85_REG_AFAN_HYST1); + data->zone[0].hyst = i >> 4; + data->zone[1].hyst = i & 0x0f; + + i = lm85_read_value(client, LM85_REG_AFAN_HYST2); + data->zone[2].hyst = i >> 4; + } + + data->last_config = jiffies; + } /* last_config */ + + data->valid = 1; + + mutex_unlock(&data->update_lock); + + return data; +} /* 4 Fans */ static ssize_t show_fan(struct device *dev, struct device_attribute *attr, @@ -397,8 +574,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err; @@ -521,8 +698,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err; @@ -563,8 +740,8 @@ *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u8 config; unsigned long val; int err; @@ -621,8 +798,8 @@ struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err; @@ -640,7 +817,8 @@ data->cfg5 &= ~ADT7468_HFPWM; lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5); } else { /* Low freq. mode */ - data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val); + data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, + FREQ_MAP_LEN, val); lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), (data->zone[nr].range << 4) | data->pwm_freq[nr]); @@ -688,8 +866,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; @@ -716,8 +894,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; @@ -772,8 +950,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; @@ -803,8 +981,8 @@ const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; @@ -849,8 +1027,8 @@ struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; @@ -879,8 +1057,8 @@ struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; unsigned long val; int err; @@ -908,8 +1086,8 @@ struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; u8 tmp; long val; int err; @@ -959,8 +1137,8 @@ struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; int min; long val; int err; @@ -996,8 +1174,8 @@ struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; @@ -1035,8 +1213,8 @@ struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; int min; long val; int err; @@ -1069,8 +1247,8 @@ struct device_attribute *attr, const char *buf, size_t count) { int nr = to_sensor_dev_attr(attr)->index; - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); + struct lm85_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; long val; int err; @@ -1284,7 +1462,7 @@ { struct i2c_adapter *adapter = client->adapter; int address = client->addr; - const char *type_name; + const char *type_name = NULL; int company, verstep; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { @@ -1300,16 +1478,6 @@ "Detecting device at 0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n", address, company, verstep); - /* All supported chips have the version in common */ - if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC && - (verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC2) { - dev_dbg(&adapter->dev, - "Autodetection failed: unsupported version\n"); - return -ENODEV; - } - type_name = "lm85"; - - /* Now, refine the detection */ if (company == LM85_COMPANY_NATIONAL) { switch (verstep) { case LM85_VERSTEP_LM85C: @@ -1326,6 +1494,7 @@ "Found Winbond WPCD377I, ignoring\n"); return -ENODEV; } + type_name = "lm85"; break; } } else if (company == LM85_COMPANY_ANALOG_DEV) { @@ -1360,41 +1529,28 @@ type_name = "emc6d103s"; break; } - } else { - dev_dbg(&adapter->dev, - "Autodetection failed: unknown vendor\n"); - return -ENODEV; } + if (!type_name) + return -ENODEV; + strlcpy(info->type, type_name, I2C_NAME_SIZE); return 0; } -static void lm85_remove_files(struct i2c_client *client, struct lm85_data *data) -{ - sysfs_remove_group(&client->dev.kobj, &lm85_group); - if (data->type != emc6d103s) { - sysfs_remove_group(&client->dev.kobj, &lm85_group_minctl); - sysfs_remove_group(&client->dev.kobj, &lm85_group_temp_off); - } - if (!data->has_vid5) - sysfs_remove_group(&client->dev.kobj, &lm85_group_in4); - if (data->type == emc6d100) - sysfs_remove_group(&client->dev.kobj, &lm85_group_in567); -} - -static int lm85_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lm85_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; + struct device *hwmon_dev; struct lm85_data *data; - int err; + int idx = 0; - data = devm_kzalloc(&client->dev, sizeof(struct lm85_data), GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct lm85_data), GFP_KERNEL); if (!data) return -ENOMEM; - i2c_set_clientdata(client, data); + data->client = client; data->type = id->driver_data; mutex_init(&data->update_lock); @@ -1419,20 +1575,13 @@ /* Initialize the LM85 chip */ lm85_init_client(client); - /* Register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &lm85_group); - if (err) - return err; + /* sysfs hooks */ + data->groups[idx++] = &lm85_group; /* minctl and temp_off exist on all chips except emc6d103s */ if (data->type != emc6d103s) { - err = sysfs_create_group(&client->dev.kobj, &lm85_group_minctl); - if (err) - goto err_remove_files; - err = sysfs_create_group(&client->dev.kobj, - &lm85_group_temp_off); - if (err) - goto err_remove_files; + data->groups[idx++] = &lm85_group_minctl; + data->groups[idx++] = &lm85_group_temp_off; } /* @@ -1445,271 +1594,44 @@ data->has_vid5 = true; } - if (!data->has_vid5) { - err = sysfs_create_group(&client->dev.kobj, &lm85_group_in4); - if (err) - goto err_remove_files; - } + if (!data->has_vid5) + data->groups[idx++] = &lm85_group_in4; /* The EMC6D100 has 3 additional voltage inputs */ - if (data->type == emc6d100) { - err = sysfs_create_group(&client->dev.kobj, &lm85_group_in567); - if (err) - goto err_remove_files; - } - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto err_remove_files; - } - - return 0; - - /* Error out and cleanup code */ - err_remove_files: - lm85_remove_files(client, data); - return err; -} - -static int lm85_remove(struct i2c_client *client) -{ - struct lm85_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - lm85_remove_files(client, data); - return 0; -} - - -static int lm85_read_value(struct i2c_client *client, u8 reg) -{ - int res; - - /* What size location is it? */ - switch (reg) { - case LM85_REG_FAN(0): /* Read WORD data */ - case LM85_REG_FAN(1): - case LM85_REG_FAN(2): - case LM85_REG_FAN(3): - case LM85_REG_FAN_MIN(0): - case LM85_REG_FAN_MIN(1): - case LM85_REG_FAN_MIN(2): - case LM85_REG_FAN_MIN(3): - case LM85_REG_ALARM1: /* Read both bytes at once */ - res = i2c_smbus_read_byte_data(client, reg) & 0xff; - res |= i2c_smbus_read_byte_data(client, reg + 1) << 8; - break; - default: /* Read BYTE data */ - res = i2c_smbus_read_byte_data(client, reg); - break; - } - - return res; -} + if (data->type == emc6d100) + data->groups[idx++] = &lm85_group_in567; -static void lm85_write_value(struct i2c_client *client, u8 reg, int value) -{ - switch (reg) { - case LM85_REG_FAN(0): /* Write WORD data */ - case LM85_REG_FAN(1): - case LM85_REG_FAN(2): - case LM85_REG_FAN(3): - case LM85_REG_FAN_MIN(0): - case LM85_REG_FAN_MIN(1): - case LM85_REG_FAN_MIN(2): - case LM85_REG_FAN_MIN(3): - /* NOTE: ALARM is read only, so not included here */ - i2c_smbus_write_byte_data(client, reg, value & 0xff); - i2c_smbus_write_byte_data(client, reg + 1, value >> 8); - break; - default: /* Write BYTE data */ - i2c_smbus_write_byte_data(client, reg, value); - break; - } + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + return PTR_ERR_OR_ZERO(hwmon_dev); } -static struct lm85_data *lm85_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); - int i; - - mutex_lock(&data->update_lock); - - if (!data->valid || - time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) { - /* Things that change quickly */ - dev_dbg(&client->dev, "Reading sensor values\n"); - - /* - * Have to read extended bits first to "freeze" the - * more significant bits that are read later. - * There are 2 additional resolution bits per channel and we - * have room for 4, so we shift them to the left. - */ - if (data->type == adm1027 || data->type == adt7463 || - data->type == adt7468) { - int ext1 = lm85_read_value(client, - ADM1027_REG_EXTEND_ADC1); - int ext2 = lm85_read_value(client, - ADM1027_REG_EXTEND_ADC2); - int val = (ext1 << 8) + ext2; - - for (i = 0; i <= 4; i++) - data->in_ext[i] = - ((val >> (i * 2)) & 0x03) << 2; - - for (i = 0; i <= 2; i++) - data->temp_ext[i] = - (val >> ((i + 4) * 2)) & 0x0c; - } - - data->vid = lm85_read_value(client, LM85_REG_VID); - - for (i = 0; i <= 3; ++i) { - data->in[i] = - lm85_read_value(client, LM85_REG_IN(i)); - data->fan[i] = - lm85_read_value(client, LM85_REG_FAN(i)); - } - - if (!data->has_vid5) - data->in[4] = lm85_read_value(client, LM85_REG_IN(4)); - - if (data->type == adt7468) - data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5); - - for (i = 0; i <= 2; ++i) { - data->temp[i] = - lm85_read_value(client, LM85_REG_TEMP(i)); - data->pwm[i] = - lm85_read_value(client, LM85_REG_PWM(i)); - - if (IS_ADT7468_OFF64(data)) - data->temp[i] -= 64; - } - - data->alarms = lm85_read_value(client, LM85_REG_ALARM1); - - if (data->type == emc6d100) { - /* Three more voltage sensors */ - for (i = 5; i <= 7; ++i) { - data->in[i] = lm85_read_value(client, - EMC6D100_REG_IN(i)); - } - /* More alarm bits */ - data->alarms |= lm85_read_value(client, - EMC6D100_REG_ALARM3) << 16; - } else if (data->type == emc6d102 || data->type == emc6d103 || - data->type == emc6d103s) { - /* - * Have to read LSB bits after the MSB ones because - * the reading of the MSB bits has frozen the - * LSBs (backward from the ADM1027). - */ - int ext1 = lm85_read_value(client, - EMC6D102_REG_EXTEND_ADC1); - int ext2 = lm85_read_value(client, - EMC6D102_REG_EXTEND_ADC2); - int ext3 = lm85_read_value(client, - EMC6D102_REG_EXTEND_ADC3); - int ext4 = lm85_read_value(client, - EMC6D102_REG_EXTEND_ADC4); - data->in_ext[0] = ext3 & 0x0f; - data->in_ext[1] = ext4 & 0x0f; - data->in_ext[2] = ext4 >> 4; - data->in_ext[3] = ext3 >> 4; - data->in_ext[4] = ext2 >> 4; - - data->temp_ext[0] = ext1 & 0x0f; - data->temp_ext[1] = ext2 & 0x0f; - data->temp_ext[2] = ext1 >> 4; - } - - data->last_reading = jiffies; - } /* last_reading */ - - if (!data->valid || - time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) { - /* Things that don't change often */ - dev_dbg(&client->dev, "Reading config values\n"); - - for (i = 0; i <= 3; ++i) { - data->in_min[i] = - lm85_read_value(client, LM85_REG_IN_MIN(i)); - data->in_max[i] = - lm85_read_value(client, LM85_REG_IN_MAX(i)); - data->fan_min[i] = - lm85_read_value(client, LM85_REG_FAN_MIN(i)); - } - - if (!data->has_vid5) { - data->in_min[4] = lm85_read_value(client, - LM85_REG_IN_MIN(4)); - data->in_max[4] = lm85_read_value(client, - LM85_REG_IN_MAX(4)); - } - - if (data->type == emc6d100) { - for (i = 5; i <= 7; ++i) { - data->in_min[i] = lm85_read_value(client, - EMC6D100_REG_IN_MIN(i)); - data->in_max[i] = lm85_read_value(client, - EMC6D100_REG_IN_MAX(i)); - } - } - - for (i = 0; i <= 2; ++i) { - int val; - - data->temp_min[i] = - lm85_read_value(client, LM85_REG_TEMP_MIN(i)); - data->temp_max[i] = - lm85_read_value(client, LM85_REG_TEMP_MAX(i)); - - data->autofan[i].config = - lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); - val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); - data->pwm_freq[i] = val & 0x07; - data->zone[i].range = val >> 4; - data->autofan[i].min_pwm = - lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); - data->zone[i].limit = - lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); - data->zone[i].critical = - lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); - - if (IS_ADT7468_OFF64(data)) { - data->temp_min[i] -= 64; - data->temp_max[i] -= 64; - data->zone[i].limit -= 64; - data->zone[i].critical -= 64; - } - } - - if (data->type != emc6d103s) { - i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); - data->autofan[0].min_off = (i & 0x20) != 0; - data->autofan[1].min_off = (i & 0x40) != 0; - data->autofan[2].min_off = (i & 0x80) != 0; - - i = lm85_read_value(client, LM85_REG_AFAN_HYST1); - data->zone[0].hyst = i >> 4; - data->zone[1].hyst = i & 0x0f; - - i = lm85_read_value(client, LM85_REG_AFAN_HYST2); - data->zone[2].hyst = i >> 4; - } - - data->last_config = jiffies; - } /* last_config */ - - data->valid = 1; - - mutex_unlock(&data->update_lock); +static const struct i2c_device_id lm85_id[] = { + { "adm1027", adm1027 }, + { "adt7463", adt7463 }, + { "adt7468", adt7468 }, + { "lm85", lm85 }, + { "lm85b", lm85 }, + { "lm85c", lm85 }, + { "emc6d100", emc6d100 }, + { "emc6d101", emc6d100 }, + { "emc6d102", emc6d102 }, + { "emc6d103", emc6d103 }, + { "emc6d103s", emc6d103s }, + { } +}; +MODULE_DEVICE_TABLE(i2c, lm85_id); - return data; -} +static struct i2c_driver lm85_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "lm85", + }, + .probe = lm85_probe, + .id_table = lm85_id, + .detect = lm85_detect, + .address_list = normal_i2c, +}; module_i2c_driver(lm85_driver);