| 1 | |
| 2 | |
| 3 | * adm1031.c - Part of lm_sensors, Linux kernel modules for hardware
|
| 4 | * monitoring
|
| 5 | * Based on lm75.c and lm85.c
|
| 6 | * Supports adm1030 / adm1031
|
| 7 | * Copyright (C) 2004 Alexandre d'Alton <[email protected]>
|
| 8 | * Reworked by Jean Delvare <[email protected]>
|
| 9 |
|
| 10 |
|
| 11 | #include <linux/module.h>
|
| 12 | #include <linux/init.h>
|
| 13 | #include <linux/slab.h>
|
| 14 | #include <linux/jiffies.h>
|
| 15 | #include <linux/i2c.h>
|
| 16 | #include <linux/hwmon.h>
|
| 17 | #include <linux/hwmon-sysfs.h>
|
| 18 | #include <linux/err.h>
|
| 19 | #include <linux/mutex.h>
|
| 20 |
|
| 21 |
|
| 22 | #define ADM1031_REG_FAN_SPEED(nr) (0x08 + (nr))
|
| 23 | #define ADM1031_REG_FAN_DIV(nr) (0x20 + (nr))
|
| 24 | #define ADM1031_REG_PWM (0x22)
|
| 25 | #define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr))
|
| 26 | #define ADM1031_REG_FAN_FILTER (0x23)
|
| 27 |
|
| 28 | #define ADM1031_REG_TEMP_OFFSET(nr) (0x0d + (nr))
|
| 29 | #define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4 * (nr))
|
| 30 | #define ADM1031_REG_TEMP_MIN(nr) (0x15 + 4 * (nr))
|
| 31 | #define ADM1031_REG_TEMP_CRIT(nr) (0x16 + 4 * (nr))
|
| 32 |
|
| 33 | #define ADM1031_REG_TEMP(nr) (0x0a + (nr))
|
| 34 | #define ADM1031_REG_AUTO_TEMP(nr) (0x24 + (nr))
|
| 35 |
|
| 36 | #define ADM1031_REG_STATUS(nr) (0x2 + (nr))
|
| 37 |
|
| 38 | #define ADM1031_REG_CONF1 0x00
|
| 39 | #define ADM1031_REG_CONF2 0x01
|
| 40 | #define ADM1031_REG_EXT_TEMP 0x06
|
| 41 |
|
| 42 | #define ADM1031_CONF1_MONITOR_ENABLE 0x01
|
| 43 | #define ADM1031_CONF1_PWM_INVERT 0x08
|
| 44 | #define ADM1031_CONF1_AUTO_MODE 0x80
|
| 45 |
|
| 46 | #define ADM1031_CONF2_PWM1_ENABLE 0x01
|
| 47 | #define ADM1031_CONF2_PWM2_ENABLE 0x02
|
| 48 | #define ADM1031_CONF2_TACH1_ENABLE 0x04
|
| 49 | #define ADM1031_CONF2_TACH2_ENABLE 0x08
|
| 50 | #define ADM1031_CONF2_TEMP_ENABLE(chan) (0x10 << (chan))
|
| 51 |
|
| 52 | #define ADM1031_UPDATE_RATE_MASK 0x1c
|
| 53 | #define ADM1031_UPDATE_RATE_SHIFT 2
|
| 54 |
|
| 55 |
|
| 56 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
|
| 57 |
|
| 58 | enum chips { adm1030, adm1031 };
|
| 59 |
|
| 60 | typedef u8 auto_chan_table_t[8][2];
|
| 61 |
|
| 62 |
|
| 63 | struct adm1031_data {
|
| 64 | struct i2c_client *client;
|
| 65 | const struct attribute_group *groups[3];
|
| 66 | struct mutex update_lock;
|
| 67 | int chip_type;
|
| 68 | bool valid;
|
| 69 | unsigned long last_updated;
|
| 70 | unsigned int update_interval;
|
| 71 | |
| 72 | * The chan_select_table contains the possible configurations for
|
| 73 | * auto fan control.
|
| 74 |
|
| 75 | const auto_chan_table_t *chan_select_table;
|
| 76 | u16 alarm;
|
| 77 | u8 conf1;
|
| 78 | u8 conf2;
|
| 79 | u8 fan[2];
|
| 80 | u8 fan_div[2];
|
| 81 | u8 fan_min[2];
|
| 82 | u8 pwm[2];
|
| 83 | u8 old_pwm[2];
|
| 84 | s8 temp[3];
|
| 85 | u8 ext_temp[3];
|
| 86 | u8 auto_temp[3];
|
| 87 | u8 auto_temp_min[3];
|
| 88 | u8 auto_temp_off[3];
|
| 89 | u8 auto_temp_max[3];
|
| 90 | s8 temp_offset[3];
|
| 91 | s8 temp_min[3];
|
| 92 | s8 temp_max[3];
|
| 93 | s8 temp_crit[3];
|
| 94 | };
|
| 95 |
|
| 96 | static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
|
| 97 | {
|
| 98 | return i2c_smbus_read_byte_data(client, reg);
|
| 99 | }
|
| 100 |
|
| 101 | static inline int
|
| 102 | adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
|
| 103 | {
|
| 104 | return i2c_smbus_write_byte_data(client, reg, value);
|
| 105 | }
|
| 106 |
|
| 107 | static struct adm1031_data *adm1031_update_device(struct device *dev)
|
| 108 | {
|
| 109 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 110 | struct i2c_client *client = data->client;
|
| 111 | unsigned long next_update;
|
| 112 | int chan;
|
| 113 |
|
| 114 | mutex_lock(&data->update_lock);
|
| 115 |
|
| 116 | next_update = data->last_updated
|
| 117 | + msecs_to_jiffies(data->update_interval);
|
| 118 | if (time_after(jiffies, next_update) || !data->valid) {
|
| 119 |
|
| 120 | dev_dbg(&client->dev, "Starting adm1031 update\n");
|
| 121 | for (chan = 0;
|
| 122 | chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
|
| 123 | u8 oldh, newh;
|
| 124 |
|
| 125 | oldh =
|
| 126 | adm1031_read_value(client, ADM1031_REG_TEMP(chan));
|
| 127 | data->ext_temp[chan] =
|
| 128 | adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
|
| 129 | newh =
|
| 130 | adm1031_read_value(client, ADM1031_REG_TEMP(chan));
|
| 131 | if (newh != oldh) {
|
| 132 | data->ext_temp[chan] =
|
| 133 | adm1031_read_value(client,
|
| 134 | ADM1031_REG_EXT_TEMP);
|
| 135 | #ifdef DEBUG
|
| 136 | oldh =
|
| 137 | adm1031_read_value(client,
|
| 138 | ADM1031_REG_TEMP(chan));
|
| 139 |
|
| 140 |
|
| 141 | if (newh != oldh)
|
| 142 | dev_warn(&client->dev,
|
| 143 | "Remote temperature may be wrong.\n");
|
| 144 | #endif
|
| 145 | }
|
| 146 | data->temp[chan] = newh;
|
| 147 |
|
| 148 | data->temp_offset[chan] =
|
| 149 | adm1031_read_value(client,
|
| 150 | ADM1031_REG_TEMP_OFFSET(chan));
|
| 151 | data->temp_min[chan] =
|
| 152 | adm1031_read_value(client,
|
| 153 | ADM1031_REG_TEMP_MIN(chan));
|
| 154 | data->temp_max[chan] =
|
| 155 | adm1031_read_value(client,
|
| 156 | ADM1031_REG_TEMP_MAX(chan));
|
| 157 | data->temp_crit[chan] =
|
| 158 | adm1031_read_value(client,
|
| 159 | ADM1031_REG_TEMP_CRIT(chan));
|
| 160 | data->auto_temp[chan] =
|
| 161 | adm1031_read_value(client,
|
| 162 | ADM1031_REG_AUTO_TEMP(chan));
|
| 163 |
|
| 164 | }
|
| 165 |
|
| 166 | data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
|
| 167 | data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
|
| 168 |
|
| 169 | data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
|
| 170 | | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
|
| 171 | if (data->chip_type == adm1030)
|
| 172 | data->alarm &= 0xc0ff;
|
| 173 |
|
| 174 | for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
|
| 175 | chan++) {
|
| 176 | data->fan_div[chan] =
|
| 177 | adm1031_read_value(client,
|
| 178 | ADM1031_REG_FAN_DIV(chan));
|
| 179 | data->fan_min[chan] =
|
| 180 | adm1031_read_value(client,
|
| 181 | ADM1031_REG_FAN_MIN(chan));
|
| 182 | data->fan[chan] =
|
| 183 | adm1031_read_value(client,
|
| 184 | ADM1031_REG_FAN_SPEED(chan));
|
| 185 | data->pwm[chan] =
|
| 186 | (adm1031_read_value(client,
|
| 187 | ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
|
| 188 | }
|
| 189 | data->last_updated = jiffies;
|
| 190 | data->valid = true;
|
| 191 | }
|
| 192 |
|
| 193 | mutex_unlock(&data->update_lock);
|
| 194 |
|
| 195 | return data;
|
| 196 | }
|
| 197 |
|
| 198 | #define TEMP_TO_REG(val) (((val) < 0 ? ((val - 500) / 1000) : \
|
| 199 | ((val + 500) / 1000)))
|
| 200 |
|
| 201 | #define TEMP_FROM_REG(val) ((val) * 1000)
|
| 202 |
|
| 203 | #define TEMP_FROM_REG_EXT(val, ext) (TEMP_FROM_REG(val) + (ext) * 125)
|
| 204 |
|
| 205 | #define TEMP_OFFSET_TO_REG(val) (TEMP_TO_REG(val) & 0x8f)
|
| 206 | #define TEMP_OFFSET_FROM_REG(val) TEMP_FROM_REG((val) < 0 ? \
|
| 207 | (val) | 0x70 : (val))
|
| 208 |
|
| 209 | #define FAN_FROM_REG(reg, div) ((reg) ? \
|
| 210 | (11250 * 60) / ((reg) * (div)) : 0)
|
| 211 |
|
| 212 | static int FAN_TO_REG(int reg, int div)
|
| 213 | {
|
| 214 | int tmp;
|
| 215 | tmp = FAN_FROM_REG(clamp_val(reg, 0, 65535), div);
|
| 216 | return tmp > 255 ? 255 : tmp;
|
| 217 | }
|
| 218 |
|
| 219 | #define FAN_DIV_FROM_REG(reg) (1<<(((reg)&0xc0)>>6))
|
| 220 |
|
| 221 | #define PWM_TO_REG(val) (clamp_val((val), 0, 255) >> 4)
|
| 222 | #define PWM_FROM_REG(val) ((val) << 4)
|
| 223 |
|
| 224 | #define FAN_CHAN_FROM_REG(reg) (((reg) >> 5) & 7)
|
| 225 | #define FAN_CHAN_TO_REG(val, reg) \
|
| 226 | (((reg) & 0x1F) | (((val) << 5) & 0xe0))
|
| 227 |
|
| 228 | #define AUTO_TEMP_MIN_TO_REG(val, reg) \
|
| 229 | ((((val) / 500) & 0xf8) | ((reg) & 0x7))
|
| 230 | #define AUTO_TEMP_RANGE_FROM_REG(reg) (5000 * (1 << ((reg) & 0x7)))
|
| 231 | #define AUTO_TEMP_MIN_FROM_REG(reg) (1000 * ((((reg) >> 3) & 0x1f) << 2))
|
| 232 |
|
| 233 | #define AUTO_TEMP_MIN_FROM_REG_DEG(reg) ((((reg) >> 3) & 0x1f) << 2)
|
| 234 |
|
| 235 | #define AUTO_TEMP_OFF_FROM_REG(reg) \
|
| 236 | (AUTO_TEMP_MIN_FROM_REG(reg) - 5000)
|
| 237 |
|
| 238 | #define AUTO_TEMP_MAX_FROM_REG(reg) \
|
| 239 | (AUTO_TEMP_RANGE_FROM_REG(reg) + \
|
| 240 | AUTO_TEMP_MIN_FROM_REG(reg))
|
| 241 |
|
| 242 | static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm)
|
| 243 | {
|
| 244 | int ret;
|
| 245 | int range = ((val - AUTO_TEMP_MIN_FROM_REG(reg)) * 10) / (16 - pwm);
|
| 246 |
|
| 247 | ret = ((reg & 0xf8) |
|
| 248 | (range < 10000 ? 0 :
|
| 249 | range < 20000 ? 1 :
|
| 250 | range < 40000 ? 2 : range < 80000 ? 3 : 4));
|
| 251 | return ret;
|
| 252 | }
|
| 253 |
|
| 254 |
|
| 255 | #define GET_FAN_AUTO_BITFIELD(data, idx) \
|
| 256 | (*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx % 2]
|
| 257 |
|
| 258 | |
| 259 | * The tables below contains the possible values for the auto fan
|
| 260 | * control bitfields. the index in the table is the register value.
|
| 261 | * MSb is the auto fan control enable bit, so the four first entries
|
| 262 | * in the table disables auto fan control when both bitfields are zero.
|
| 263 |
|
| 264 | static const auto_chan_table_t auto_channel_select_table_adm1031 = {
|
| 265 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
|
| 266 | { 2 , 4 },
|
| 267 | { 2 , 2 },
|
| 268 | { 4 , 4 },
|
| 269 | { 7 , 7 },
|
| 270 | };
|
| 271 |
|
| 272 | static const auto_chan_table_t auto_channel_select_table_adm1030 = {
|
| 273 | { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
|
| 274 | { 2 , 0 },
|
| 275 | { 0xff , 0 },
|
| 276 | { 0xff , 0 },
|
| 277 | { 3 , 0 },
|
| 278 | };
|
| 279 |
|
| 280 | |
| 281 | * That function checks if a bitfield is valid and returns the other bitfield
|
| 282 | * nearest match if no exact match where found.
|
| 283 |
|
| 284 | static int
|
| 285 | get_fan_auto_nearest(struct adm1031_data *data, int chan, u8 val, u8 reg)
|
| 286 | {
|
| 287 | int i;
|
| 288 | int first_match = -1, exact_match = -1;
|
| 289 | u8 other_reg_val =
|
| 290 | (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1];
|
| 291 |
|
| 292 | if (val == 0)
|
| 293 | return 0;
|
| 294 |
|
| 295 | for (i = 0; i < 8; i++) {
|
| 296 | if ((val == (*data->chan_select_table)[i][chan]) &&
|
| 297 | ((*data->chan_select_table)[i][chan ? 0 : 1] ==
|
| 298 | other_reg_val)) {
|
| 299 |
|
| 300 | exact_match = i;
|
| 301 | break;
|
| 302 | } else if (val == (*data->chan_select_table)[i][chan] &&
|
| 303 | first_match == -1) {
|
| 304 | |
| 305 | * Save the first match in case of an exact match has
|
| 306 | * not been found
|
| 307 |
|
| 308 | first_match = i;
|
| 309 | }
|
| 310 | }
|
| 311 |
|
| 312 | if (exact_match >= 0)
|
| 313 | return exact_match;
|
| 314 | else if (first_match >= 0)
|
| 315 | return first_match;
|
| 316 |
|
| 317 | return -EINVAL;
|
| 318 | }
|
| 319 |
|
| 320 | static ssize_t fan_auto_channel_show(struct device *dev,
|
| 321 | struct device_attribute *attr, char *buf)
|
| 322 | {
|
| 323 | int nr = to_sensor_dev_attr(attr)->index;
|
| 324 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 325 | return sprintf(buf, "%d\n", GET_FAN_AUTO_BITFIELD(data, nr));
|
| 326 | }
|
| 327 |
|
| 328 | static ssize_t
|
| 329 | fan_auto_channel_store(struct device *dev, struct device_attribute *attr,
|
| 330 | const char *buf, size_t count)
|
| 331 | {
|
| 332 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 333 | struct i2c_client *client = data->client;
|
| 334 | int nr = to_sensor_dev_attr(attr)->index;
|
| 335 | long val;
|
| 336 | u8 reg;
|
| 337 | int ret;
|
| 338 | u8 old_fan_mode;
|
| 339 |
|
| 340 | ret = kstrtol(buf, 10, &val);
|
| 341 | if (ret)
|
| 342 | return ret;
|
| 343 |
|
| 344 | old_fan_mode = data->conf1;
|
| 345 |
|
| 346 | mutex_lock(&data->update_lock);
|
| 347 |
|
| 348 | ret = get_fan_auto_nearest(data, nr, val, data->conf1);
|
| 349 | if (ret < 0) {
|
| 350 | mutex_unlock(&data->update_lock);
|
| 351 | return ret;
|
| 352 | }
|
| 353 | reg = ret;
|
| 354 | data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
|
| 355 | if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^
|
| 356 | (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) {
|
| 357 | if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
|
| 358 | |
| 359 | * Switch to Auto Fan Mode
|
| 360 | * Save PWM registers
|
| 361 | * Set PWM registers to 33% Both
|
| 362 |
|
| 363 | data->old_pwm[0] = data->pwm[0];
|
| 364 | data->old_pwm[1] = data->pwm[1];
|
| 365 | adm1031_write_value(client, ADM1031_REG_PWM, 0x55);
|
| 366 | } else {
|
| 367 |
|
| 368 | data->pwm[0] = data->old_pwm[0];
|
| 369 | data->pwm[1] = data->old_pwm[1];
|
| 370 |
|
| 371 | adm1031_write_value(client, ADM1031_REG_PWM,
|
| 372 | data->pwm[0] | (data->pwm[1] << 4));
|
| 373 | }
|
| 374 | }
|
| 375 | data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
|
| 376 | adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1);
|
| 377 | mutex_unlock(&data->update_lock);
|
| 378 | return count;
|
| 379 | }
|
| 380 |
|
| 381 | static SENSOR_DEVICE_ATTR_RW(auto_fan1_channel, fan_auto_channel, 0);
|
| 382 | static SENSOR_DEVICE_ATTR_RW(auto_fan2_channel, fan_auto_channel, 1);
|
| 383 |
|
| 384 |
|
| 385 | static ssize_t auto_temp_off_show(struct device *dev,
|
| 386 | struct device_attribute *attr, char *buf)
|
| 387 | {
|
| 388 | int nr = to_sensor_dev_attr(attr)->index;
|
| 389 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 390 | return sprintf(buf, "%d\n",
|
| 391 | AUTO_TEMP_OFF_FROM_REG(data->auto_temp[nr]));
|
| 392 | }
|
| 393 | static ssize_t auto_temp_min_show(struct device *dev,
|
| 394 | struct device_attribute *attr, char *buf)
|
| 395 | {
|
| 396 | int nr = to_sensor_dev_attr(attr)->index;
|
| 397 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 398 | return sprintf(buf, "%d\n",
|
| 399 | AUTO_TEMP_MIN_FROM_REG(data->auto_temp[nr]));
|
| 400 | }
|
| 401 | static ssize_t
|
| 402 | auto_temp_min_store(struct device *dev, struct device_attribute *attr,
|
| 403 | const char *buf, size_t count)
|
| 404 | {
|
| 405 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 406 | struct i2c_client *client = data->client;
|
| 407 | int nr = to_sensor_dev_attr(attr)->index;
|
| 408 | long val;
|
| 409 | int ret;
|
| 410 |
|
| 411 | ret = kstrtol(buf, 10, &val);
|
| 412 | if (ret)
|
| 413 | return ret;
|
| 414 |
|
| 415 | val = clamp_val(val, 0, 127000);
|
| 416 | mutex_lock(&data->update_lock);
|
| 417 | data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
|
| 418 | adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
|
| 419 | data->auto_temp[nr]);
|
| 420 | mutex_unlock(&data->update_lock);
|
| 421 | return count;
|
| 422 | }
|
| 423 | static ssize_t auto_temp_max_show(struct device *dev,
|
| 424 | struct device_attribute *attr, char *buf)
|
| 425 | {
|
| 426 | int nr = to_sensor_dev_attr(attr)->index;
|
| 427 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 428 | return sprintf(buf, "%d\n",
|
| 429 | AUTO_TEMP_MAX_FROM_REG(data->auto_temp[nr]));
|
| 430 | }
|
| 431 | static ssize_t
|
| 432 | auto_temp_max_store(struct device *dev, struct device_attribute *attr,
|
| 433 | const char *buf, size_t count)
|
| 434 | {
|
| 435 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 436 | struct i2c_client *client = data->client;
|
| 437 | int nr = to_sensor_dev_attr(attr)->index;
|
| 438 | long val;
|
| 439 | int ret;
|
| 440 |
|
| 441 | ret = kstrtol(buf, 10, &val);
|
| 442 | if (ret)
|
| 443 | return ret;
|
| 444 |
|
| 445 | val = clamp_val(val, 0, 127000);
|
| 446 | mutex_lock(&data->update_lock);
|
| 447 | data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr],
|
| 448 | data->pwm[nr]);
|
| 449 | adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
|
| 450 | data->temp_max[nr]);
|
| 451 | mutex_unlock(&data->update_lock);
|
| 452 | return count;
|
| 453 | }
|
| 454 |
|
| 455 | static SENSOR_DEVICE_ATTR_RO(auto_temp1_off, auto_temp_off, 0);
|
| 456 | static SENSOR_DEVICE_ATTR_RW(auto_temp1_min, auto_temp_min, 0);
|
| 457 | static SENSOR_DEVICE_ATTR_RW(auto_temp1_max, auto_temp_max, 0);
|
| 458 | static SENSOR_DEVICE_ATTR_RO(auto_temp2_off, auto_temp_off, 1);
|
| 459 | static SENSOR_DEVICE_ATTR_RW(auto_temp2_min, auto_temp_min, 1);
|
| 460 | static SENSOR_DEVICE_ATTR_RW(auto_temp2_max, auto_temp_max, 1);
|
| 461 | static SENSOR_DEVICE_ATTR_RO(auto_temp3_off, auto_temp_off, 2);
|
| 462 | static SENSOR_DEVICE_ATTR_RW(auto_temp3_min, auto_temp_min, 2);
|
| 463 | static SENSOR_DEVICE_ATTR_RW(auto_temp3_max, auto_temp_max, 2);
|
| 464 |
|
| 465 |
|
| 466 | static ssize_t pwm_show(struct device *dev, struct device_attribute *attr,
|
| 467 | char *buf)
|
| 468 | {
|
| 469 | int nr = to_sensor_dev_attr(attr)->index;
|
| 470 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 471 | return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
|
| 472 | }
|
| 473 | static ssize_t pwm_store(struct device *dev, struct device_attribute *attr,
|
| 474 | const char *buf, size_t count)
|
| 475 | {
|
| 476 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 477 | struct i2c_client *client = data->client;
|
| 478 | int nr = to_sensor_dev_attr(attr)->index;
|
| 479 | long val;
|
| 480 | int ret, reg;
|
| 481 |
|
| 482 | ret = kstrtol(buf, 10, &val);
|
| 483 | if (ret)
|
| 484 | return ret;
|
| 485 |
|
| 486 | mutex_lock(&data->update_lock);
|
| 487 | if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) &&
|
| 488 | (((val>>4) & 0xf) != 5)) {
|
| 489 |
|
| 490 | mutex_unlock(&data->update_lock);
|
| 491 | return -EINVAL;
|
| 492 | }
|
| 493 | data->pwm[nr] = PWM_TO_REG(val);
|
| 494 | reg = adm1031_read_value(client, ADM1031_REG_PWM);
|
| 495 | adm1031_write_value(client, ADM1031_REG_PWM,
|
| 496 | nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf)
|
| 497 | : (data->pwm[nr] & 0xf) | (reg & 0xf0));
|
| 498 | mutex_unlock(&data->update_lock);
|
| 499 | return count;
|
| 500 | }
|
| 501 |
|
| 502 | static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0);
|
| 503 | static SENSOR_DEVICE_ATTR_RW(pwm2, pwm, 1);
|
| 504 | static SENSOR_DEVICE_ATTR_RW(auto_fan1_min_pwm, pwm, 0);
|
| 505 | static SENSOR_DEVICE_ATTR_RW(auto_fan2_min_pwm, pwm, 1);
|
| 506 |
|
| 507 |
|
| 508 |
|
| 509 | |
| 510 | * That function checks the cases where the fan reading is not
|
| 511 | * relevant. It is used to provide 0 as fan reading when the fan is
|
| 512 | * not supposed to run
|
| 513 |
|
| 514 | static int trust_fan_readings(struct adm1031_data *data, int chan)
|
| 515 | {
|
| 516 | int res = 0;
|
| 517 |
|
| 518 | if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
|
| 519 | switch (data->conf1 & 0x60) {
|
| 520 | case 0x00:
|
| 521 | |
| 522 | * remote temp1 controls fan1,
|
| 523 | * remote temp2 controls fan2
|
| 524 |
|
| 525 | res = data->temp[chan+1] >=
|
| 526 | AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]);
|
| 527 | break;
|
| 528 | case 0x20:
|
| 529 | res =
|
| 530 | data->temp[1] >=
|
| 531 | AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1]);
|
| 532 | break;
|
| 533 | case 0x40:
|
| 534 | res =
|
| 535 | data->temp[2] >=
|
| 536 | AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]);
|
| 537 | break;
|
| 538 | case 0x60:
|
| 539 | res =
|
| 540 | data->temp[0] >=
|
| 541 | AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[0])
|
| 542 | || data->temp[1] >=
|
| 543 | AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1])
|
| 544 | || (data->chip_type == adm1031
|
| 545 | && data->temp[2] >=
|
| 546 | AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]));
|
| 547 | break;
|
| 548 | }
|
| 549 | } else {
|
| 550 | res = data->pwm[chan] > 0;
|
| 551 | }
|
| 552 | return res;
|
| 553 | }
|
| 554 |
|
| 555 | static ssize_t fan_show(struct device *dev, struct device_attribute *attr,
|
| 556 | char *buf)
|
| 557 | {
|
| 558 | int nr = to_sensor_dev_attr(attr)->index;
|
| 559 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 560 | int value;
|
| 561 |
|
| 562 | value = trust_fan_readings(data, nr) ? FAN_FROM_REG(data->fan[nr],
|
| 563 | FAN_DIV_FROM_REG(data->fan_div[nr])) : 0;
|
| 564 | return sprintf(buf, "%d\n", value);
|
| 565 | }
|
| 566 |
|
| 567 | static ssize_t fan_div_show(struct device *dev, struct device_attribute *attr,
|
| 568 | char *buf)
|
| 569 | {
|
| 570 | int nr = to_sensor_dev_attr(attr)->index;
|
| 571 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 572 | return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[nr]));
|
| 573 | }
|
| 574 | static ssize_t fan_min_show(struct device *dev, struct device_attribute *attr,
|
| 575 | char *buf)
|
| 576 | {
|
| 577 | int nr = to_sensor_dev_attr(attr)->index;
|
| 578 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 579 | return sprintf(buf, "%d\n",
|
| 580 | FAN_FROM_REG(data->fan_min[nr],
|
| 581 | FAN_DIV_FROM_REG(data->fan_div[nr])));
|
| 582 | }
|
| 583 | static ssize_t fan_min_store(struct device *dev,
|
| 584 | struct device_attribute *attr, const char *buf,
|
| 585 | size_t count)
|
| 586 | {
|
| 587 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 588 | struct i2c_client *client = data->client;
|
| 589 | int nr = to_sensor_dev_attr(attr)->index;
|
| 590 | long val;
|
| 591 | int ret;
|
| 592 |
|
| 593 | ret = kstrtol(buf, 10, &val);
|
| 594 | if (ret)
|
| 595 | return ret;
|
| 596 |
|
| 597 | mutex_lock(&data->update_lock);
|
| 598 | if (val) {
|
| 599 | data->fan_min[nr] =
|
| 600 | FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr]));
|
| 601 | } else {
|
| 602 | data->fan_min[nr] = 0xff;
|
| 603 | }
|
| 604 | adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]);
|
| 605 | mutex_unlock(&data->update_lock);
|
| 606 | return count;
|
| 607 | }
|
| 608 | static ssize_t fan_div_store(struct device *dev,
|
| 609 | struct device_attribute *attr, const char *buf,
|
| 610 | size_t count)
|
| 611 | {
|
| 612 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 613 | struct i2c_client *client = data->client;
|
| 614 | int nr = to_sensor_dev_attr(attr)->index;
|
| 615 | long val;
|
| 616 | u8 tmp;
|
| 617 | int old_div;
|
| 618 | int new_min;
|
| 619 | int ret;
|
| 620 |
|
| 621 | ret = kstrtol(buf, 10, &val);
|
| 622 | if (ret)
|
| 623 | return ret;
|
| 624 |
|
| 625 | tmp = val == 8 ? 0xc0 :
|
| 626 | val == 4 ? 0x80 :
|
| 627 | val == 2 ? 0x40 :
|
| 628 | val == 1 ? 0x00 :
|
| 629 | 0xff;
|
| 630 | if (tmp == 0xff)
|
| 631 | return -EINVAL;
|
| 632 |
|
| 633 | mutex_lock(&data->update_lock);
|
| 634 |
|
| 635 | data->fan_div[nr] = adm1031_read_value(client,
|
| 636 | ADM1031_REG_FAN_DIV(nr));
|
| 637 | data->fan_min[nr] = adm1031_read_value(client,
|
| 638 | ADM1031_REG_FAN_MIN(nr));
|
| 639 |
|
| 640 |
|
| 641 | old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
|
| 642 | data->fan_div[nr] = tmp | (0x3f & data->fan_div[nr]);
|
| 643 | new_min = data->fan_min[nr] * old_div / val;
|
| 644 | data->fan_min[nr] = new_min > 0xff ? 0xff : new_min;
|
| 645 |
|
| 646 | adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr),
|
| 647 | data->fan_div[nr]);
|
| 648 | adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr),
|
| 649 | data->fan_min[nr]);
|
| 650 |
|
| 651 |
|
| 652 | data->valid = false;
|
| 653 | mutex_unlock(&data->update_lock);
|
| 654 | return count;
|
| 655 | }
|
| 656 |
|
| 657 | static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0);
|
| 658 | static SENSOR_DEVICE_ATTR_RW(fan1_min, fan_min, 0);
|
| 659 | static SENSOR_DEVICE_ATTR_RW(fan1_div, fan_div, 0);
|
| 660 | static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1);
|
| 661 | static SENSOR_DEVICE_ATTR_RW(fan2_min, fan_min, 1);
|
| 662 | static SENSOR_DEVICE_ATTR_RW(fan2_div, fan_div, 1);
|
| 663 |
|
| 664 |
|
| 665 | static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
|
| 666 | char *buf)
|
| 667 | {
|
| 668 | int nr = to_sensor_dev_attr(attr)->index;
|
| 669 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 670 | int ext;
|
| 671 | ext = nr == 0 ?
|
| 672 | ((data->ext_temp[nr] >> 6) & 0x3) * 2 :
|
| 673 | (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7));
|
| 674 | return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext));
|
| 675 | }
|
| 676 | static ssize_t temp_offset_show(struct device *dev,
|
| 677 | struct device_attribute *attr, char *buf)
|
| 678 | {
|
| 679 | int nr = to_sensor_dev_attr(attr)->index;
|
| 680 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 681 | return sprintf(buf, "%d\n",
|
| 682 | TEMP_OFFSET_FROM_REG(data->temp_offset[nr]));
|
| 683 | }
|
| 684 | static ssize_t temp_min_show(struct device *dev,
|
| 685 | struct device_attribute *attr, char *buf)
|
| 686 | {
|
| 687 | int nr = to_sensor_dev_attr(attr)->index;
|
| 688 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 689 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
|
| 690 | }
|
| 691 | static ssize_t temp_max_show(struct device *dev,
|
| 692 | struct device_attribute *attr, char *buf)
|
| 693 | {
|
| 694 | int nr = to_sensor_dev_attr(attr)->index;
|
| 695 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 696 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
|
| 697 | }
|
| 698 | static ssize_t temp_crit_show(struct device *dev,
|
| 699 | struct device_attribute *attr, char *buf)
|
| 700 | {
|
| 701 | int nr = to_sensor_dev_attr(attr)->index;
|
| 702 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 703 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
|
| 704 | }
|
| 705 | static ssize_t temp_offset_store(struct device *dev,
|
| 706 | struct device_attribute *attr,
|
| 707 | const char *buf, size_t count)
|
| 708 | {
|
| 709 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 710 | struct i2c_client *client = data->client;
|
| 711 | int nr = to_sensor_dev_attr(attr)->index;
|
| 712 | long val;
|
| 713 | int ret;
|
| 714 |
|
| 715 | ret = kstrtol(buf, 10, &val);
|
| 716 | if (ret)
|
| 717 | return ret;
|
| 718 |
|
| 719 | val = clamp_val(val, -15000, 15000);
|
| 720 | mutex_lock(&data->update_lock);
|
| 721 | data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val);
|
| 722 | adm1031_write_value(client, ADM1031_REG_TEMP_OFFSET(nr),
|
| 723 | data->temp_offset[nr]);
|
| 724 | mutex_unlock(&data->update_lock);
|
| 725 | return count;
|
| 726 | }
|
| 727 | static ssize_t temp_min_store(struct device *dev,
|
| 728 | struct device_attribute *attr, const char *buf,
|
| 729 | size_t count)
|
| 730 | {
|
| 731 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 732 | struct i2c_client *client = data->client;
|
| 733 | int nr = to_sensor_dev_attr(attr)->index;
|
| 734 | long val;
|
| 735 | int ret;
|
| 736 |
|
| 737 | ret = kstrtol(buf, 10, &val);
|
| 738 | if (ret)
|
| 739 | return ret;
|
| 740 |
|
| 741 | val = clamp_val(val, -55000, 127000);
|
| 742 | mutex_lock(&data->update_lock);
|
| 743 | data->temp_min[nr] = TEMP_TO_REG(val);
|
| 744 | adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
|
| 745 | data->temp_min[nr]);
|
| 746 | mutex_unlock(&data->update_lock);
|
| 747 | return count;
|
| 748 | }
|
| 749 | static ssize_t temp_max_store(struct device *dev,
|
| 750 | struct device_attribute *attr, const char *buf,
|
| 751 | size_t count)
|
| 752 | {
|
| 753 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 754 | struct i2c_client *client = data->client;
|
| 755 | int nr = to_sensor_dev_attr(attr)->index;
|
| 756 | long val;
|
| 757 | int ret;
|
| 758 |
|
| 759 | ret = kstrtol(buf, 10, &val);
|
| 760 | if (ret)
|
| 761 | return ret;
|
| 762 |
|
| 763 | val = clamp_val(val, -55000, 127000);
|
| 764 | mutex_lock(&data->update_lock);
|
| 765 | data->temp_max[nr] = TEMP_TO_REG(val);
|
| 766 | adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
|
| 767 | data->temp_max[nr]);
|
| 768 | mutex_unlock(&data->update_lock);
|
| 769 | return count;
|
| 770 | }
|
| 771 | static ssize_t temp_crit_store(struct device *dev,
|
| 772 | struct device_attribute *attr, const char *buf,
|
| 773 | size_t count)
|
| 774 | {
|
| 775 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 776 | struct i2c_client *client = data->client;
|
| 777 | int nr = to_sensor_dev_attr(attr)->index;
|
| 778 | long val;
|
| 779 | int ret;
|
| 780 |
|
| 781 | ret = kstrtol(buf, 10, &val);
|
| 782 | if (ret)
|
| 783 | return ret;
|
| 784 |
|
| 785 | val = clamp_val(val, -55000, 127000);
|
| 786 | mutex_lock(&data->update_lock);
|
| 787 | data->temp_crit[nr] = TEMP_TO_REG(val);
|
| 788 | adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
|
| 789 | data->temp_crit[nr]);
|
| 790 | mutex_unlock(&data->update_lock);
|
| 791 | return count;
|
| 792 | }
|
| 793 |
|
| 794 | static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
|
| 795 | static SENSOR_DEVICE_ATTR_RW(temp1_offset, temp_offset, 0);
|
| 796 | static SENSOR_DEVICE_ATTR_RW(temp1_min, temp_min, 0);
|
| 797 | static SENSOR_DEVICE_ATTR_RW(temp1_max, temp_max, 0);
|
| 798 | static SENSOR_DEVICE_ATTR_RW(temp1_crit, temp_crit, 0);
|
| 799 | static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
|
| 800 | static SENSOR_DEVICE_ATTR_RW(temp2_offset, temp_offset, 1);
|
| 801 | static SENSOR_DEVICE_ATTR_RW(temp2_min, temp_min, 1);
|
| 802 | static SENSOR_DEVICE_ATTR_RW(temp2_max, temp_max, 1);
|
| 803 | static SENSOR_DEVICE_ATTR_RW(temp2_crit, temp_crit, 1);
|
| 804 | static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
|
| 805 | static SENSOR_DEVICE_ATTR_RW(temp3_offset, temp_offset, 2);
|
| 806 | static SENSOR_DEVICE_ATTR_RW(temp3_min, temp_min, 2);
|
| 807 | static SENSOR_DEVICE_ATTR_RW(temp3_max, temp_max, 2);
|
| 808 | static SENSOR_DEVICE_ATTR_RW(temp3_crit, temp_crit, 2);
|
| 809 |
|
| 810 |
|
| 811 | static ssize_t alarms_show(struct device *dev, struct device_attribute *attr,
|
| 812 | char *buf)
|
| 813 | {
|
| 814 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 815 | return sprintf(buf, "%d\n", data->alarm);
|
| 816 | }
|
| 817 |
|
| 818 | static DEVICE_ATTR_RO(alarms);
|
| 819 |
|
| 820 | static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
|
| 821 | char *buf)
|
| 822 | {
|
| 823 | int bitnr = to_sensor_dev_attr(attr)->index;
|
| 824 | struct adm1031_data *data = adm1031_update_device(dev);
|
| 825 | return sprintf(buf, "%d\n", (data->alarm >> bitnr) & 1);
|
| 826 | }
|
| 827 |
|
| 828 | static SENSOR_DEVICE_ATTR_RO(fan1_alarm, alarm, 0);
|
| 829 | static SENSOR_DEVICE_ATTR_RO(fan1_fault, alarm, 1);
|
| 830 | static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, alarm, 2);
|
| 831 | static SENSOR_DEVICE_ATTR_RO(temp2_min_alarm, alarm, 3);
|
| 832 | static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, 4);
|
| 833 | static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 5);
|
| 834 | static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 6);
|
| 835 | static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, alarm, 7);
|
| 836 | static SENSOR_DEVICE_ATTR_RO(fan2_alarm, alarm, 8);
|
| 837 | static SENSOR_DEVICE_ATTR_RO(fan2_fault, alarm, 9);
|
| 838 | static SENSOR_DEVICE_ATTR_RO(temp3_max_alarm, alarm, 10);
|
| 839 | static SENSOR_DEVICE_ATTR_RO(temp3_min_alarm, alarm, 11);
|
| 840 | static SENSOR_DEVICE_ATTR_RO(temp3_crit_alarm, alarm, 12);
|
| 841 | static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 13);
|
| 842 | static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 14);
|
| 843 |
|
| 844 |
|
| 845 | static const unsigned int update_intervals[] = {
|
| 846 | 16000, 8000, 4000, 2000, 1000, 500, 250, 125,
|
| 847 | };
|
| 848 |
|
| 849 | static ssize_t update_interval_show(struct device *dev,
|
| 850 | struct device_attribute *attr, char *buf)
|
| 851 | {
|
| 852 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 853 |
|
| 854 | return sprintf(buf, "%u\n", data->update_interval);
|
| 855 | }
|
| 856 |
|
| 857 | static ssize_t update_interval_store(struct device *dev,
|
| 858 | struct device_attribute *attr,
|
| 859 | const char *buf, size_t count)
|
| 860 | {
|
| 861 | struct adm1031_data *data = dev_get_drvdata(dev);
|
| 862 | struct i2c_client *client = data->client;
|
| 863 | unsigned long val;
|
| 864 | int i, err;
|
| 865 | u8 reg;
|
| 866 |
|
| 867 | err = kstrtoul(buf, 10, &val);
|
| 868 | if (err)
|
| 869 | return err;
|
| 870 |
|
| 871 | |
| 872 | * Find the nearest update interval from the table.
|
| 873 | * Use it to determine the matching update rate.
|
| 874 |
|
| 875 | for (i = 0; i < ARRAY_SIZE(update_intervals) - 1; i++) {
|
| 876 | if (val >= update_intervals[i])
|
| 877 | break;
|
| 878 | }
|
| 879 |
|
| 880 |
|
| 881 |
|
| 882 | reg = adm1031_read_value(client, ADM1031_REG_FAN_FILTER);
|
| 883 | reg &= ~ADM1031_UPDATE_RATE_MASK;
|
| 884 | reg |= i << ADM1031_UPDATE_RATE_SHIFT;
|
| 885 | adm1031_write_value(client, ADM1031_REG_FAN_FILTER, reg);
|
| 886 |
|
| 887 | mutex_lock(&data->update_lock);
|
| 888 | data->update_interval = update_intervals[i];
|
| 889 | mutex_unlock(&data->update_lock);
|
| 890 |
|
| 891 | return count;
|
| 892 | }
|
| 893 |
|
| 894 | static DEVICE_ATTR_RW(update_interval);
|
| 895 |
|
| 896 | static struct attribute *adm1031_attributes[] = {
|
| 897 | &sensor_dev_attr_fan1_input.dev_attr.attr,
|
| 898 | &sensor_dev_attr_fan1_div.dev_attr.attr,
|
| 899 | &sensor_dev_attr_fan1_min.dev_attr.attr,
|
| 900 | &sensor_dev_attr_fan1_alarm.dev_attr.attr,
|
| 901 | &sensor_dev_attr_fan1_fault.dev_attr.attr,
|
| 902 | &sensor_dev_attr_pwm1.dev_attr.attr,
|
| 903 | &sensor_dev_attr_auto_fan1_channel.dev_attr.attr,
|
| 904 | &sensor_dev_attr_temp1_input.dev_attr.attr,
|
| 905 | &sensor_dev_attr_temp1_offset.dev_attr.attr,
|
| 906 | &sensor_dev_attr_temp1_min.dev_attr.attr,
|
| 907 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
|
| 908 | &sensor_dev_attr_temp1_max.dev_attr.attr,
|
| 909 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
|
| 910 | &sensor_dev_attr_temp1_crit.dev_attr.attr,
|
| 911 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
|
| 912 | &sensor_dev_attr_temp2_input.dev_attr.attr,
|
| 913 | &sensor_dev_attr_temp2_offset.dev_attr.attr,
|
| 914 | &sensor_dev_attr_temp2_min.dev_attr.attr,
|
| 915 | &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
|
| 916 | &sensor_dev_attr_temp2_max.dev_attr.attr,
|
| 917 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
|
| 918 | &sensor_dev_attr_temp2_crit.dev_attr.attr,
|
| 919 | &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
|
| 920 | &sensor_dev_attr_temp2_fault.dev_attr.attr,
|
| 921 |
|
| 922 | &sensor_dev_attr_auto_temp1_off.dev_attr.attr,
|
| 923 | &sensor_dev_attr_auto_temp1_min.dev_attr.attr,
|
| 924 | &sensor_dev_attr_auto_temp1_max.dev_attr.attr,
|
| 925 |
|
| 926 | &sensor_dev_attr_auto_temp2_off.dev_attr.attr,
|
| 927 | &sensor_dev_attr_auto_temp2_min.dev_attr.attr,
|
| 928 | &sensor_dev_attr_auto_temp2_max.dev_attr.attr,
|
| 929 |
|
| 930 | &sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr,
|
| 931 |
|
| 932 | &dev_attr_update_interval.attr,
|
| 933 | &dev_attr_alarms.attr,
|
| 934 |
|
| 935 | NULL
|
| 936 | };
|
| 937 |
|
| 938 | static const struct attribute_group adm1031_group = {
|
| 939 | .attrs = adm1031_attributes,
|
| 940 | };
|
| 941 |
|
| 942 | static struct attribute *adm1031_attributes_opt[] = {
|
| 943 | &sensor_dev_attr_fan2_input.dev_attr.attr,
|
| 944 | &sensor_dev_attr_fan2_div.dev_attr.attr,
|
| 945 | &sensor_dev_attr_fan2_min.dev_attr.attr,
|
| 946 | &sensor_dev_attr_fan2_alarm.dev_attr.attr,
|
| 947 | &sensor_dev_attr_fan2_fault.dev_attr.attr,
|
| 948 | &sensor_dev_attr_pwm2.dev_attr.attr,
|
| 949 | &sensor_dev_attr_auto_fan2_channel.dev_attr.attr,
|
| 950 | &sensor_dev_attr_temp3_input.dev_attr.attr,
|
| 951 | &sensor_dev_attr_temp3_offset.dev_attr.attr,
|
| 952 | &sensor_dev_attr_temp3_min.dev_attr.attr,
|
| 953 | &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
|
| 954 | &sensor_dev_attr_temp3_max.dev_attr.attr,
|
| 955 | &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
|
| 956 | &sensor_dev_attr_temp3_crit.dev_attr.attr,
|
| 957 | &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
|
| 958 | &sensor_dev_attr_temp3_fault.dev_attr.attr,
|
| 959 | &sensor_dev_attr_auto_temp3_off.dev_attr.attr,
|
| 960 | &sensor_dev_attr_auto_temp3_min.dev_attr.attr,
|
| 961 | &sensor_dev_attr_auto_temp3_max.dev_attr.attr,
|
| 962 | &sensor_dev_attr_auto_fan2_min_pwm.dev_attr.attr,
|
| 963 | NULL
|
| 964 | };
|
| 965 |
|
| 966 | static const struct attribute_group adm1031_group_opt = {
|
| 967 | .attrs = adm1031_attributes_opt,
|
| 968 | };
|
| 969 |
|
| 970 |
|
| 971 | static int adm1031_detect(struct i2c_client *client,
|
| 972 | struct i2c_board_info *info)
|
| 973 | {
|
| 974 | struct i2c_adapter *adapter = client->adapter;
|
| 975 | const char *name;
|
| 976 | int id, co;
|
| 977 |
|
| 978 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
| 979 | return -ENODEV;
|
| 980 |
|
| 981 | id = i2c_smbus_read_byte_data(client, 0x3d);
|
| 982 | co = i2c_smbus_read_byte_data(client, 0x3e);
|
| 983 |
|
| 984 | if (!((id == 0x31 || id == 0x30) && co == 0x41))
|
| 985 | return -ENODEV;
|
| 986 | name = (id == 0x30) ? "adm1030" : "adm1031";
|
| 987 |
|
| 988 | strscpy(info->type, name, I2C_NAME_SIZE);
|
| 989 |
|
| 990 | return 0;
|
| 991 | }
|
| 992 |
|
| 993 | static void adm1031_init_client(struct i2c_client *client)
|
| 994 | {
|
| 995 | unsigned int read_val;
|
| 996 | unsigned int mask;
|
| 997 | int i;
|
| 998 | struct adm1031_data *data = i2c_get_clientdata(client);
|
| 999 |
|
| 1000 | mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE);
|
| 1001 | if (data->chip_type == adm1031) {
|
| 1002 | mask |= (ADM1031_CONF2_PWM2_ENABLE |
|
| 1003 | ADM1031_CONF2_TACH2_ENABLE);
|
| 1004 | }
|
| 1005 |
|
| 1006 | read_val = adm1031_read_value(client, ADM1031_REG_CONF2);
|
| 1007 | if ((read_val | mask) != read_val)
|
| 1008 | adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask);
|
| 1009 |
|
| 1010 | read_val = adm1031_read_value(client, ADM1031_REG_CONF1);
|
| 1011 | if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) {
|
| 1012 | adm1031_write_value(client, ADM1031_REG_CONF1,
|
| 1013 | read_val | ADM1031_CONF1_MONITOR_ENABLE);
|
| 1014 | }
|
| 1015 |
|
| 1016 |
|
| 1017 | mask = ADM1031_UPDATE_RATE_MASK;
|
| 1018 | read_val = adm1031_read_value(client, ADM1031_REG_FAN_FILTER);
|
| 1019 | i = (read_val & mask) >> ADM1031_UPDATE_RATE_SHIFT;
|
| 1020 |
|
| 1021 | data->update_interval = update_intervals[i];
|
| 1022 | }
|
| 1023 |
|
| 1024 | static int adm1031_probe(struct i2c_client *client)
|
| 1025 | {
|
| 1026 | struct device *dev = &client->dev;
|
| 1027 | struct device *hwmon_dev;
|
| 1028 | struct adm1031_data *data;
|
| 1029 |
|
| 1030 | data = devm_kzalloc(dev, sizeof(struct adm1031_data), GFP_KERNEL);
|
| 1031 | if (!data)
|
| 1032 | return -ENOMEM;
|
| 1033 |
|
| 1034 | i2c_set_clientdata(client, data);
|
| 1035 | data->client = client;
|
| 1036 | data->chip_type = (uintptr_t)i2c_get_match_data(client);
|
| 1037 | mutex_init(&data->update_lock);
|
| 1038 |
|
| 1039 | if (data->chip_type == adm1030)
|
| 1040 | data->chan_select_table = &auto_channel_select_table_adm1030;
|
| 1041 | else
|
| 1042 | data->chan_select_table = &auto_channel_select_table_adm1031;
|
| 1043 |
|
| 1044 |
|
| 1045 | adm1031_init_client(client);
|
| 1046 |
|
| 1047 |
|
| 1048 | data->groups[0] = &adm1031_group;
|
| 1049 | if (data->chip_type == adm1031)
|
| 1050 | data->groups[1] = &adm1031_group_opt;
|
| 1051 |
|
| 1052 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
|
| 1053 | data, data->groups);
|
| 1054 | return PTR_ERR_OR_ZERO(hwmon_dev);
|
| 1055 | }
|
| 1056 |
|
| 1057 | static const struct i2c_device_id adm1031_id[] = {
|
| 1058 | { .name = "adm1030", .driver_data = adm1030 },
|
| 1059 | { .name = "adm1031", .driver_data = adm1031 },
|
| 1060 | { }
|
| 1061 | };
|
| 1062 | MODULE_DEVICE_TABLE(i2c, adm1031_id);
|
| 1063 |
|
| 1064 | static struct i2c_driver adm1031_driver = {
|
| 1065 | .class = I2C_CLASS_HWMON,
|
| 1066 | .driver = {
|
| 1067 | .name = "adm1031",
|
| 1068 | },
|
| 1069 | .probe = adm1031_probe,
|
| 1070 | .id_table = adm1031_id,
|
| 1071 | .detect = adm1031_detect,
|
| 1072 | .address_list = normal_i2c,
|
| 1073 | };
|
| 1074 |
|
| 1075 | module_i2c_driver(adm1031_driver);
|
| 1076 |
|
| 1077 | MODULE_AUTHOR("Alexandre d'Alton <[email protected]>");
|
| 1078 | MODULE_DESCRIPTION("ADM1031/ADM1030 driver");
|
| 1079 | MODULE_LICENSE("GPL");
|