Blame view
drivers/hwmon/max6639.c
16.8 KB
74ba9207e treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
a5b79d62f hwmon: Driver for... |
2 3 4 5 6 7 8 9 10 |
/* * max6639.c - Support for Maxim MAX6639 * * 2-Channel Temperature Monitor with Dual PWM Fan-Speed Controller * * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de> * * based on the initial MAX6639 support from semptian.net * by He Changqing <hechangqing@semptian.com> |
a5b79d62f hwmon: Driver for... |
11 12 13 14 15 16 17 18 19 20 21 |
*/ #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/jiffies.h> #include <linux/i2c.h> #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> #include <linux/err.h> #include <linux/mutex.h> |
0c9fe1614 hwmon: (max6639) ... |
22 |
#include <linux/platform_data/max6639.h> |
a5b79d62f hwmon: Driver for... |
23 24 |
/* Addresses to scan */ |
7edc8cc19 hwmon: (max6639) ... |
25 |
static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; |
a5b79d62f hwmon: Driver for... |
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
/* The MAX6639 registers, valid channel numbers: 0, 1 */ #define MAX6639_REG_TEMP(ch) (0x00 + (ch)) #define MAX6639_REG_STATUS 0x02 #define MAX6639_REG_OUTPUT_MASK 0x03 #define MAX6639_REG_GCONFIG 0x04 #define MAX6639_REG_TEMP_EXT(ch) (0x05 + (ch)) #define MAX6639_REG_ALERT_LIMIT(ch) (0x08 + (ch)) #define MAX6639_REG_OT_LIMIT(ch) (0x0A + (ch)) #define MAX6639_REG_THERM_LIMIT(ch) (0x0C + (ch)) #define MAX6639_REG_FAN_CONFIG1(ch) (0x10 + (ch) * 4) #define MAX6639_REG_FAN_CONFIG2a(ch) (0x11 + (ch) * 4) #define MAX6639_REG_FAN_CONFIG2b(ch) (0x12 + (ch) * 4) #define MAX6639_REG_FAN_CONFIG3(ch) (0x13 + (ch) * 4) #define MAX6639_REG_FAN_CNT(ch) (0x20 + (ch)) #define MAX6639_REG_TARGET_CNT(ch) (0x22 + (ch)) #define MAX6639_REG_FAN_PPR(ch) (0x24 + (ch)) #define MAX6639_REG_TARGTDUTY(ch) (0x26 + (ch)) #define MAX6639_REG_FAN_START_TEMP(ch) (0x28 + (ch)) #define MAX6639_REG_DEVID 0x3D #define MAX6639_REG_MANUID 0x3E #define MAX6639_REG_DEVREV 0x3F /* Register bits */ #define MAX6639_GCONFIG_STANDBY 0x80 #define MAX6639_GCONFIG_POR 0x40 #define MAX6639_GCONFIG_DISABLE_TIMEOUT 0x20 #define MAX6639_GCONFIG_CH2_LOCAL 0x10 |
177f3b920 hwmon: (max6639) ... |
54 |
#define MAX6639_GCONFIG_PWM_FREQ_HI 0x08 |
a5b79d62f hwmon: Driver for... |
55 56 |
#define MAX6639_FAN_CONFIG1_PWM 0x80 |
177f3b920 hwmon: (max6639) ... |
57 |
#define MAX6639_FAN_CONFIG3_THERM_FULL_SPEED 0x40 |
a5b79d62f hwmon: Driver for... |
58 |
static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; |
b63d97a36 hwmon: (max6639) ... |
59 60 |
#define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ 0 : (rpm_ranges[rpm_range] * 30) / (val)) |
2a844c148 hwmon: Replace SE... |
61 |
#define TEMP_LIMIT_TO_REG(val) clamp_val((val) / 1000, 0, 255) |
a5b79d62f hwmon: Driver for... |
62 63 64 65 66 |
/* * Client data (each client gets its own) */ struct max6639_data { |
7981c5846 hwmon: (max6639) ... |
67 |
struct i2c_client *client; |
a5b79d62f hwmon: Driver for... |
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
struct mutex update_lock; char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ /* Register values sampled regularly */ u16 temp[2]; /* Temperature, in 1/8 C, 0..255 C */ bool temp_fault[2]; /* Detected temperature diode failure */ u8 fan[2]; /* Register value: TACH count for fans >=30 */ u8 status; /* Detected channel alarms and fan failures */ /* Register values only written to */ u8 pwm[2]; /* Register value: Duty cycle 0..120 */ u8 temp_therm[2]; /* THERM Temperature, 0..255 C (->_max) */ u8 temp_alert[2]; /* ALERT Temperature, 0..255 C (->_crit) */ u8 temp_ot[2]; /* OT Temperature, 0..255 C (->_emergency) */ /* Register values initialized only once */ u8 ppr; /* Pulses per rotation 0..3 for 1..4 ppr */ u8 rpm_range; /* Index in above rpm_ranges table */ }; static struct max6639_data *max6639_update_device(struct device *dev) { |
7981c5846 hwmon: (max6639) ... |
91 92 |
struct max6639_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; |
a5b79d62f hwmon: Driver for... |
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
struct max6639_data *ret = data; int i; int status_reg; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { int res; dev_dbg(&client->dev, "Starting max6639 update "); status_reg = i2c_smbus_read_byte_data(client, MAX6639_REG_STATUS); if (status_reg < 0) { ret = ERR_PTR(status_reg); goto abort; } data->status = status_reg; for (i = 0; i < 2; i++) { res = i2c_smbus_read_byte_data(client, MAX6639_REG_FAN_CNT(i)); if (res < 0) { ret = ERR_PTR(res); goto abort; } data->fan[i] = res; res = i2c_smbus_read_byte_data(client, MAX6639_REG_TEMP_EXT(i)); if (res < 0) { ret = ERR_PTR(res); goto abort; } data->temp[i] = res >> 5; data->temp_fault[i] = res & 0x01; res = i2c_smbus_read_byte_data(client, MAX6639_REG_TEMP(i)); if (res < 0) { ret = ERR_PTR(res); goto abort; } data->temp[i] |= res << 3; } data->last_updated = jiffies; data->valid = 1; } abort: mutex_unlock(&data->update_lock); return ret; } |
0a0ab22a7 hwmon: (max6639) ... |
149 |
static ssize_t temp_input_show(struct device *dev, |
a5b79d62f hwmon: Driver for... |
150 151 152 153 154 155 156 157 158 159 160 161 162 |
struct device_attribute *dev_attr, char *buf) { long temp; struct max6639_data *data = max6639_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); if (IS_ERR(data)) return PTR_ERR(data); temp = data->temp[attr->index] * 125; return sprintf(buf, "%ld ", temp); } |
0a0ab22a7 hwmon: (max6639) ... |
163 |
static ssize_t temp_fault_show(struct device *dev, |
a5b79d62f hwmon: Driver for... |
164 165 166 167 168 169 170 171 172 173 174 |
struct device_attribute *dev_attr, char *buf) { struct max6639_data *data = max6639_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); if (IS_ERR(data)) return PTR_ERR(data); return sprintf(buf, "%d ", data->temp_fault[attr->index]); } |
0a0ab22a7 hwmon: (max6639) ... |
175 |
static ssize_t temp_max_show(struct device *dev, |
a5b79d62f hwmon: Driver for... |
176 177 |
struct device_attribute *dev_attr, char *buf) { |
a5b79d62f hwmon: Driver for... |
178 |
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); |
7981c5846 hwmon: (max6639) ... |
179 |
struct max6639_data *data = dev_get_drvdata(dev); |
a5b79d62f hwmon: Driver for... |
180 181 182 183 |
return sprintf(buf, "%d ", (data->temp_therm[attr->index] * 1000)); } |
0a0ab22a7 hwmon: (max6639) ... |
184 185 186 |
static ssize_t temp_max_store(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) |
a5b79d62f hwmon: Driver for... |
187 |
{ |
a5b79d62f hwmon: Driver for... |
188 |
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); |
7981c5846 hwmon: (max6639) ... |
189 190 |
struct max6639_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; |
a5b79d62f hwmon: Driver for... |
191 192 |
unsigned long val; int res; |
179c4fdb5 hwmon: replaced s... |
193 |
res = kstrtoul(buf, 10, &val); |
a5b79d62f hwmon: Driver for... |
194 195 196 197 198 199 200 201 202 203 204 |
if (res) return res; mutex_lock(&data->update_lock); data->temp_therm[attr->index] = TEMP_LIMIT_TO_REG(val); i2c_smbus_write_byte_data(client, MAX6639_REG_THERM_LIMIT(attr->index), data->temp_therm[attr->index]); mutex_unlock(&data->update_lock); return count; } |
0a0ab22a7 hwmon: (max6639) ... |
205 |
static ssize_t temp_crit_show(struct device *dev, |
a5b79d62f hwmon: Driver for... |
206 207 |
struct device_attribute *dev_attr, char *buf) { |
a5b79d62f hwmon: Driver for... |
208 |
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); |
7981c5846 hwmon: (max6639) ... |
209 |
struct max6639_data *data = dev_get_drvdata(dev); |
a5b79d62f hwmon: Driver for... |
210 211 212 213 |
return sprintf(buf, "%d ", (data->temp_alert[attr->index] * 1000)); } |
0a0ab22a7 hwmon: (max6639) ... |
214 215 216 |
static ssize_t temp_crit_store(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) |
a5b79d62f hwmon: Driver for... |
217 |
{ |
a5b79d62f hwmon: Driver for... |
218 |
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); |
7981c5846 hwmon: (max6639) ... |
219 220 |
struct max6639_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; |
a5b79d62f hwmon: Driver for... |
221 222 |
unsigned long val; int res; |
179c4fdb5 hwmon: replaced s... |
223 |
res = kstrtoul(buf, 10, &val); |
a5b79d62f hwmon: Driver for... |
224 225 226 227 228 229 230 231 232 233 234 |
if (res) return res; mutex_lock(&data->update_lock); data->temp_alert[attr->index] = TEMP_LIMIT_TO_REG(val); i2c_smbus_write_byte_data(client, MAX6639_REG_ALERT_LIMIT(attr->index), data->temp_alert[attr->index]); mutex_unlock(&data->update_lock); return count; } |
0a0ab22a7 hwmon: (max6639) ... |
235 |
static ssize_t temp_emergency_show(struct device *dev, |
a5b79d62f hwmon: Driver for... |
236 237 238 |
struct device_attribute *dev_attr, char *buf) { |
a5b79d62f hwmon: Driver for... |
239 |
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); |
7981c5846 hwmon: (max6639) ... |
240 |
struct max6639_data *data = dev_get_drvdata(dev); |
a5b79d62f hwmon: Driver for... |
241 242 243 244 |
return sprintf(buf, "%d ", (data->temp_ot[attr->index] * 1000)); } |
0a0ab22a7 hwmon: (max6639) ... |
245 246 247 |
static ssize_t temp_emergency_store(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) |
a5b79d62f hwmon: Driver for... |
248 |
{ |
a5b79d62f hwmon: Driver for... |
249 |
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); |
7981c5846 hwmon: (max6639) ... |
250 251 |
struct max6639_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; |
a5b79d62f hwmon: Driver for... |
252 253 |
unsigned long val; int res; |
179c4fdb5 hwmon: replaced s... |
254 |
res = kstrtoul(buf, 10, &val); |
a5b79d62f hwmon: Driver for... |
255 256 257 258 259 260 261 262 263 264 265 |
if (res) return res; mutex_lock(&data->update_lock); data->temp_ot[attr->index] = TEMP_LIMIT_TO_REG(val); i2c_smbus_write_byte_data(client, MAX6639_REG_OT_LIMIT(attr->index), data->temp_ot[attr->index]); mutex_unlock(&data->update_lock); return count; } |
0a0ab22a7 hwmon: (max6639) ... |
266 267 |
static ssize_t pwm_show(struct device *dev, struct device_attribute *dev_attr, char *buf) |
a5b79d62f hwmon: Driver for... |
268 |
{ |
a5b79d62f hwmon: Driver for... |
269 |
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); |
7981c5846 hwmon: (max6639) ... |
270 |
struct max6639_data *data = dev_get_drvdata(dev); |
a5b79d62f hwmon: Driver for... |
271 272 273 274 |
return sprintf(buf, "%d ", data->pwm[attr->index] * 255 / 120); } |
0a0ab22a7 hwmon: (max6639) ... |
275 276 277 |
static ssize_t pwm_store(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count) |
a5b79d62f hwmon: Driver for... |
278 |
{ |
a5b79d62f hwmon: Driver for... |
279 |
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); |
7981c5846 hwmon: (max6639) ... |
280 281 |
struct max6639_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; |
a5b79d62f hwmon: Driver for... |
282 283 |
unsigned long val; int res; |
179c4fdb5 hwmon: replaced s... |
284 |
res = kstrtoul(buf, 10, &val); |
a5b79d62f hwmon: Driver for... |
285 286 |
if (res) return res; |
2a844c148 hwmon: Replace SE... |
287 |
val = clamp_val(val, 0, 255); |
a5b79d62f hwmon: Driver for... |
288 289 290 291 292 293 294 295 296 |
mutex_lock(&data->update_lock); data->pwm[attr->index] = (u8)(val * 120 / 255); i2c_smbus_write_byte_data(client, MAX6639_REG_TARGTDUTY(attr->index), data->pwm[attr->index]); mutex_unlock(&data->update_lock); return count; } |
0a0ab22a7 hwmon: (max6639) ... |
297 |
static ssize_t fan_input_show(struct device *dev, |
a5b79d62f hwmon: Driver for... |
298 299 300 301 302 303 304 305 306 307 |
struct device_attribute *dev_attr, char *buf) { struct max6639_data *data = max6639_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); if (IS_ERR(data)) return PTR_ERR(data); return sprintf(buf, "%d ", FAN_FROM_REG(data->fan[attr->index], |
b63d97a36 hwmon: (max6639) ... |
308 |
data->rpm_range)); |
a5b79d62f hwmon: Driver for... |
309 |
} |
0a0ab22a7 hwmon: (max6639) ... |
310 |
static ssize_t alarm_show(struct device *dev, |
a5b79d62f hwmon: Driver for... |
311 312 313 314 315 316 317 318 319 320 321 |
struct device_attribute *dev_attr, char *buf) { struct max6639_data *data = max6639_update_device(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); if (IS_ERR(data)) return PTR_ERR(data); return sprintf(buf, "%d ", !!(data->status & (1 << attr->index))); } |
0a0ab22a7 hwmon: (max6639) ... |
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
static SENSOR_DEVICE_ATTR_RO(temp1_input, temp_input, 0); static SENSOR_DEVICE_ATTR_RO(temp2_input, temp_input, 1); static SENSOR_DEVICE_ATTR_RO(temp1_fault, temp_fault, 0); static SENSOR_DEVICE_ATTR_RO(temp2_fault, temp_fault, 1); static SENSOR_DEVICE_ATTR_RW(temp1_max, temp_max, 0); static SENSOR_DEVICE_ATTR_RW(temp2_max, temp_max, 1); static SENSOR_DEVICE_ATTR_RW(temp1_crit, temp_crit, 0); static SENSOR_DEVICE_ATTR_RW(temp2_crit, temp_crit, 1); static SENSOR_DEVICE_ATTR_RW(temp1_emergency, temp_emergency, 0); static SENSOR_DEVICE_ATTR_RW(temp2_emergency, temp_emergency, 1); static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0); static SENSOR_DEVICE_ATTR_RW(pwm2, pwm, 1); static SENSOR_DEVICE_ATTR_RO(fan1_input, fan_input, 0); static SENSOR_DEVICE_ATTR_RO(fan2_input, fan_input, 1); static SENSOR_DEVICE_ATTR_RO(fan1_fault, alarm, 1); static SENSOR_DEVICE_ATTR_RO(fan2_fault, alarm, 0); static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 3); static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, alarm, 2); static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 7); static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, 6); static SENSOR_DEVICE_ATTR_RO(temp1_emergency_alarm, alarm, 5); static SENSOR_DEVICE_ATTR_RO(temp2_emergency_alarm, alarm, 4); |
a5b79d62f hwmon: Driver for... |
344 |
|
7981c5846 hwmon: (max6639) ... |
345 |
static struct attribute *max6639_attrs[] = { |
a5b79d62f hwmon: Driver for... |
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
&sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp1_fault.dev_attr.attr, &sensor_dev_attr_temp2_fault.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp2_crit.dev_attr.attr, &sensor_dev_attr_temp1_emergency.dev_attr.attr, &sensor_dev_attr_temp2_emergency.dev_attr.attr, &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm2.dev_attr.attr, &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan1_fault.dev_attr.attr, &sensor_dev_attr_fan2_fault.dev_attr.attr, &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr, &sensor_dev_attr_temp2_emergency_alarm.dev_attr.attr, NULL }; |
7981c5846 hwmon: (max6639) ... |
370 |
ATTRIBUTE_GROUPS(max6639); |
a5b79d62f hwmon: Driver for... |
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
/* * returns respective index in rpm_ranges table * 1 by default on invalid range */ static int rpm_range_to_reg(int range) { int i; for (i = 0; i < ARRAY_SIZE(rpm_ranges); i++) { if (rpm_ranges[i] == range) return i; } return 1; /* default: 4000 RPM */ } |
7981c5846 hwmon: (max6639) ... |
387 388 |
static int max6639_init_client(struct i2c_client *client, struct max6639_data *data) |
a5b79d62f hwmon: Driver for... |
389 |
{ |
a5b79d62f hwmon: Driver for... |
390 |
struct max6639_platform_data *max6639_info = |
a8b3a3a53 hwmon: use dev_ge... |
391 |
dev_get_platdata(&client->dev); |
2f2da1ac0 hwmon: (max6639) ... |
392 |
int i; |
a5b79d62f hwmon: Driver for... |
393 |
int rpm_range = 1; /* default: 4000 RPM */ |
2f2da1ac0 hwmon: (max6639) ... |
394 |
int err; |
a5b79d62f hwmon: Driver for... |
395 |
|
177f3b920 hwmon: (max6639) ... |
396 |
/* Reset chip to default values, see below for GCONFIG setup */ |
a5b79d62f hwmon: Driver for... |
397 398 399 400 401 402 403 404 405 406 407 408 |
err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, MAX6639_GCONFIG_POR); if (err) goto exit; /* Fans pulse per revolution is 2 by default */ if (max6639_info && max6639_info->ppr > 0 && max6639_info->ppr < 5) data->ppr = max6639_info->ppr; else data->ppr = 2; data->ppr -= 1; |
a5b79d62f hwmon: Driver for... |
409 410 411 412 413 414 |
if (max6639_info) rpm_range = rpm_range_to_reg(max6639_info->rpm_range); data->rpm_range = rpm_range; for (i = 0; i < 2; i++) { |
2f2da1ac0 hwmon: (max6639) ... |
415 416 417 418 419 420 |
/* Set Fan pulse per revolution */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_FAN_PPR(i), data->ppr << 6); if (err) goto exit; |
a5b79d62f hwmon: Driver for... |
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
/* Fans config PWM, RPM */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_FAN_CONFIG1(i), MAX6639_FAN_CONFIG1_PWM | rpm_range); if (err) goto exit; /* Fans PWM polarity high by default */ if (max6639_info && max6639_info->pwm_polarity == 0) err = i2c_smbus_write_byte_data(client, MAX6639_REG_FAN_CONFIG2a(i), 0x00); else err = i2c_smbus_write_byte_data(client, MAX6639_REG_FAN_CONFIG2a(i), 0x02); if (err) goto exit; |
177f3b920 hwmon: (max6639) ... |
437 438 439 440 441 442 443 444 445 |
/* * /THERM full speed enable, * PWM frequency 25kHz, see also GCONFIG below */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_FAN_CONFIG3(i), MAX6639_FAN_CONFIG3_THERM_FULL_SPEED | 0x03); if (err) goto exit; |
a5b79d62f hwmon: Driver for... |
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 |
/* Max. temp. 80C/90C/100C */ data->temp_therm[i] = 80; data->temp_alert[i] = 90; data->temp_ot[i] = 100; err = i2c_smbus_write_byte_data(client, MAX6639_REG_THERM_LIMIT(i), data->temp_therm[i]); if (err) goto exit; err = i2c_smbus_write_byte_data(client, MAX6639_REG_ALERT_LIMIT(i), data->temp_alert[i]); if (err) goto exit; err = i2c_smbus_write_byte_data(client, MAX6639_REG_OT_LIMIT(i), data->temp_ot[i]); if (err) goto exit; /* PWM 120/120 (i.e. 100%) */ data->pwm[i] = 120; err = i2c_smbus_write_byte_data(client, MAX6639_REG_TARGTDUTY(i), data->pwm[i]); if (err) goto exit; } /* Start monitoring */ err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, |
177f3b920 hwmon: (max6639) ... |
474 475 |
MAX6639_GCONFIG_DISABLE_TIMEOUT | MAX6639_GCONFIG_CH2_LOCAL | MAX6639_GCONFIG_PWM_FREQ_HI); |
a5b79d62f hwmon: Driver for... |
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
exit: return err; } /* Return 0 if detection is successful, -ENODEV otherwise */ static int max6639_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; int dev_id, manu_id; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; /* Actual detection via device and manufacturer ID */ dev_id = i2c_smbus_read_byte_data(client, MAX6639_REG_DEVID); manu_id = i2c_smbus_read_byte_data(client, MAX6639_REG_MANUID); if (dev_id != 0x58 || manu_id != 0x4D) return -ENODEV; strlcpy(info->type, "max6639", I2C_NAME_SIZE); return 0; } |
674870385 hwmon: use simple... |
500 |
static int max6639_probe(struct i2c_client *client) |
a5b79d62f hwmon: Driver for... |
501 |
{ |
c1ea0a043 hwmon: (max6639) ... |
502 |
struct device *dev = &client->dev; |
a5b79d62f hwmon: Driver for... |
503 |
struct max6639_data *data; |
7981c5846 hwmon: (max6639) ... |
504 |
struct device *hwmon_dev; |
a5b79d62f hwmon: Driver for... |
505 |
int err; |
c1ea0a043 hwmon: (max6639) ... |
506 |
data = devm_kzalloc(dev, sizeof(struct max6639_data), GFP_KERNEL); |
b07405fbc hwmon: (max6639) ... |
507 508 |
if (!data) return -ENOMEM; |
a5b79d62f hwmon: Driver for... |
509 |
|
7981c5846 hwmon: (max6639) ... |
510 |
data->client = client; |
a5b79d62f hwmon: Driver for... |
511 512 513 |
mutex_init(&data->update_lock); /* Initialize the max6639 chip */ |
7981c5846 hwmon: (max6639) ... |
514 |
err = max6639_init_client(client, data); |
a5b79d62f hwmon: Driver for... |
515 |
if (err < 0) |
b07405fbc hwmon: (max6639) ... |
516 |
return err; |
a5b79d62f hwmon: Driver for... |
517 |
|
7981c5846 hwmon: (max6639) ... |
518 519 520 521 |
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, max6639_groups); return PTR_ERR_OR_ZERO(hwmon_dev); |
a5b79d62f hwmon: Driver for... |
522 |
} |
52f30f771 hwmon: (max6639) ... |
523 524 |
#ifdef CONFIG_PM_SLEEP static int max6639_suspend(struct device *dev) |
a5b79d62f hwmon: Driver for... |
525 |
{ |
52f30f771 hwmon: (max6639) ... |
526 |
struct i2c_client *client = to_i2c_client(dev); |
a5b79d62f hwmon: Driver for... |
527 528 529 530 531 532 533 |
int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); if (data < 0) return data; return i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, data | MAX6639_GCONFIG_STANDBY); } |
52f30f771 hwmon: (max6639) ... |
534 |
static int max6639_resume(struct device *dev) |
a5b79d62f hwmon: Driver for... |
535 |
{ |
52f30f771 hwmon: (max6639) ... |
536 |
struct i2c_client *client = to_i2c_client(dev); |
a5b79d62f hwmon: Driver for... |
537 538 539 540 541 542 543 |
int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); if (data < 0) return data; return i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, data & ~MAX6639_GCONFIG_STANDBY); } |
52f30f771 hwmon: (max6639) ... |
544 |
#endif /* CONFIG_PM_SLEEP */ |
a5b79d62f hwmon: Driver for... |
545 546 547 548 549 550 551 |
static const struct i2c_device_id max6639_id[] = { {"max6639", 0}, { } }; MODULE_DEVICE_TABLE(i2c, max6639_id); |
768821a30 hwmon: (max6639) ... |
552 |
static SIMPLE_DEV_PM_OPS(max6639_pm_ops, max6639_suspend, max6639_resume); |
52f30f771 hwmon: (max6639) ... |
553 |
|
a5b79d62f hwmon: Driver for... |
554 555 556 557 |
static struct i2c_driver max6639_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "max6639", |
52f30f771 hwmon: (max6639) ... |
558 |
.pm = &max6639_pm_ops, |
a5b79d62f hwmon: Driver for... |
559 |
}, |
674870385 hwmon: use simple... |
560 |
.probe_new = max6639_probe, |
a5b79d62f hwmon: Driver for... |
561 562 563 564 |
.id_table = max6639_id, .detect = max6639_detect, .address_list = normal_i2c, }; |
f0967eea8 hwmon: convert dr... |
565 |
module_i2c_driver(max6639_driver); |
a5b79d62f hwmon: Driver for... |
566 567 568 569 |
MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); MODULE_DESCRIPTION("max6639 driver"); MODULE_LICENSE("GPL"); |