Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: Driver for Maxim MAX6639

2-Channel Temperature Monitor with Dual PWM Fan-Speed Controller

Signed-off-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>

authored by

stigge@antcom.de and committed by
Guenter Roeck
a5b79d62 521cb40b

+713
+49
Documentation/hwmon/max6639
··· 1 + Kernel driver max6639 2 + ===================== 3 + 4 + Supported chips: 5 + * Maxim MAX6639 6 + Prefix: 'max6639' 7 + Addresses scanned: I2C 0x2c, 0x2e, 0x2f 8 + Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6639.pdf 9 + 10 + Authors: 11 + He Changqing <hechangqing@semptian.com> 12 + Roland Stigge <stigge@antcom.de> 13 + 14 + Description 15 + ----------- 16 + 17 + This driver implements support for the Maxim MAX6639. This chip is a 2-channel 18 + temperature monitor with dual PWM fan speed controller. It can monitor its own 19 + temperature and one external diode-connected transistor or two external 20 + diode-connected transistors. 21 + 22 + The following device attributes are implemented via sysfs: 23 + 24 + Attribute R/W Contents 25 + ---------------------------------------------------------------------------- 26 + temp1_input R Temperature channel 1 input (0..150 C) 27 + temp2_input R Temperature channel 2 input (0..150 C) 28 + temp1_fault R Temperature channel 1 diode fault 29 + temp2_fault R Temperature channel 2 diode fault 30 + temp1_max RW Set THERM temperature for input 1 31 + (in C, see datasheet) 32 + temp2_max RW Set THERM temperature for input 2 33 + temp1_crit RW Set ALERT temperature for input 1 34 + temp2_crit RW Set ALERT temperature for input 2 35 + temp1_emergency RW Set OT temperature for input 1 36 + (in C, see datasheet) 37 + temp2_emergency RW Set OT temperature for input 2 38 + pwm1 RW Fan 1 target duty cycle (0..255) 39 + pwm2 RW Fan 2 target duty cycle (0..255) 40 + fan1_input R TACH1 fan tachometer input (in RPM) 41 + fan2_input R TACH2 fan tachometer input (in RPM) 42 + fan1_fault R Fan 1 fault 43 + fan2_fault R Fan 2 fault 44 + temp1_max_alarm R Alarm on THERM temperature on channel 1 45 + temp2_max_alarm R Alarm on THERM temperature on channel 2 46 + temp1_crit_alarm R Alarm on ALERT temperature on channel 1 47 + temp2_crit_alarm R Alarm on ALERT temperature on channel 2 48 + temp1_emergency_alarm R Alarm on OT temperature on channel 1 49 + temp2_emergency_alarm R Alarm on OT temperature on channel 2
+10
drivers/hwmon/Kconfig
··· 685 685 This driver can also be built as a module. If so, the module 686 686 will be called max1619. 687 687 688 + config SENSORS_MAX6639 689 + tristate "Maxim MAX6639 sensor chip" 690 + depends on I2C && EXPERIMENTAL 691 + help 692 + If you say yes here you get support for the MAX6639 693 + sensor chips. 694 + 695 + This driver can also be built as a module. If so, the module 696 + will be called max6639. 697 + 688 698 config SENSORS_MAX6650 689 699 tristate "Maxim MAX6650 sensor chip" 690 700 depends on I2C && EXPERIMENTAL
+1
drivers/hwmon/Makefile
··· 84 84 obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o 85 85 obj-$(CONFIG_SENSORS_MAX1111) += max1111.o 86 86 obj-$(CONFIG_SENSORS_MAX1619) += max1619.o 87 + obj-$(CONFIG_SENSORS_MAX6639) += max6639.o 87 88 obj-$(CONFIG_SENSORS_MAX6650) += max6650.o 88 89 obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o 89 90 obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
+639
drivers/hwmon/max6639.c
··· 1 + /* 2 + * max6639.c - Support for Maxim MAX6639 3 + * 4 + * 2-Channel Temperature Monitor with Dual PWM Fan-Speed Controller 5 + * 6 + * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de> 7 + * 8 + * based on the initial MAX6639 support from semptian.net 9 + * by He Changqing <hechangqing@semptian.com> 10 + * 11 + * This program is free software; you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License as published by 13 + * the Free Software Foundation; either version 2 of the License, or 14 + * (at your option) any later version. 15 + * 16 + * This program is distributed in the hope that it will be useful, 17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 + * GNU General Public License for more details. 20 + * 21 + * You should have received a copy of the GNU General Public License 22 + * along with this program; if not, write to the Free Software 23 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 + */ 25 + 26 + #include <linux/module.h> 27 + #include <linux/init.h> 28 + #include <linux/slab.h> 29 + #include <linux/jiffies.h> 30 + #include <linux/i2c.h> 31 + #include <linux/hwmon.h> 32 + #include <linux/hwmon-sysfs.h> 33 + #include <linux/err.h> 34 + #include <linux/mutex.h> 35 + #include <linux/i2c/max6639.h> 36 + 37 + /* Addresses to scan */ 38 + static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; 39 + 40 + /* The MAX6639 registers, valid channel numbers: 0, 1 */ 41 + #define MAX6639_REG_TEMP(ch) (0x00 + (ch)) 42 + #define MAX6639_REG_STATUS 0x02 43 + #define MAX6639_REG_OUTPUT_MASK 0x03 44 + #define MAX6639_REG_GCONFIG 0x04 45 + #define MAX6639_REG_TEMP_EXT(ch) (0x05 + (ch)) 46 + #define MAX6639_REG_ALERT_LIMIT(ch) (0x08 + (ch)) 47 + #define MAX6639_REG_OT_LIMIT(ch) (0x0A + (ch)) 48 + #define MAX6639_REG_THERM_LIMIT(ch) (0x0C + (ch)) 49 + #define MAX6639_REG_FAN_CONFIG1(ch) (0x10 + (ch) * 4) 50 + #define MAX6639_REG_FAN_CONFIG2a(ch) (0x11 + (ch) * 4) 51 + #define MAX6639_REG_FAN_CONFIG2b(ch) (0x12 + (ch) * 4) 52 + #define MAX6639_REG_FAN_CONFIG3(ch) (0x13 + (ch) * 4) 53 + #define MAX6639_REG_FAN_CNT(ch) (0x20 + (ch)) 54 + #define MAX6639_REG_TARGET_CNT(ch) (0x22 + (ch)) 55 + #define MAX6639_REG_FAN_PPR(ch) (0x24 + (ch)) 56 + #define MAX6639_REG_TARGTDUTY(ch) (0x26 + (ch)) 57 + #define MAX6639_REG_FAN_START_TEMP(ch) (0x28 + (ch)) 58 + #define MAX6639_REG_DEVID 0x3D 59 + #define MAX6639_REG_MANUID 0x3E 60 + #define MAX6639_REG_DEVREV 0x3F 61 + 62 + /* Register bits */ 63 + #define MAX6639_GCONFIG_STANDBY 0x80 64 + #define MAX6639_GCONFIG_POR 0x40 65 + #define MAX6639_GCONFIG_DISABLE_TIMEOUT 0x20 66 + #define MAX6639_GCONFIG_CH2_LOCAL 0x10 67 + 68 + #define MAX6639_FAN_CONFIG1_PWM 0x80 69 + 70 + static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; 71 + 72 + #define FAN_FROM_REG(val, div, rpm_range) ((val) == 0 ? -1 : \ 73 + (val) == 255 ? 0 : (rpm_ranges[rpm_range] * 30) / ((div + 1) * (val))) 74 + #define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255) 75 + 76 + /* 77 + * Client data (each client gets its own) 78 + */ 79 + struct max6639_data { 80 + struct device *hwmon_dev; 81 + struct mutex update_lock; 82 + char valid; /* !=0 if following fields are valid */ 83 + unsigned long last_updated; /* In jiffies */ 84 + 85 + /* Register values sampled regularly */ 86 + u16 temp[2]; /* Temperature, in 1/8 C, 0..255 C */ 87 + bool temp_fault[2]; /* Detected temperature diode failure */ 88 + u8 fan[2]; /* Register value: TACH count for fans >=30 */ 89 + u8 status; /* Detected channel alarms and fan failures */ 90 + 91 + /* Register values only written to */ 92 + u8 pwm[2]; /* Register value: Duty cycle 0..120 */ 93 + u8 temp_therm[2]; /* THERM Temperature, 0..255 C (->_max) */ 94 + u8 temp_alert[2]; /* ALERT Temperature, 0..255 C (->_crit) */ 95 + u8 temp_ot[2]; /* OT Temperature, 0..255 C (->_emergency) */ 96 + 97 + /* Register values initialized only once */ 98 + u8 ppr; /* Pulses per rotation 0..3 for 1..4 ppr */ 99 + u8 rpm_range; /* Index in above rpm_ranges table */ 100 + }; 101 + 102 + static struct max6639_data *max6639_update_device(struct device *dev) 103 + { 104 + struct i2c_client *client = to_i2c_client(dev); 105 + struct max6639_data *data = i2c_get_clientdata(client); 106 + struct max6639_data *ret = data; 107 + int i; 108 + int status_reg; 109 + 110 + mutex_lock(&data->update_lock); 111 + 112 + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { 113 + int res; 114 + 115 + dev_dbg(&client->dev, "Starting max6639 update\n"); 116 + 117 + status_reg = i2c_smbus_read_byte_data(client, 118 + MAX6639_REG_STATUS); 119 + if (status_reg < 0) { 120 + ret = ERR_PTR(status_reg); 121 + goto abort; 122 + } 123 + 124 + data->status = status_reg; 125 + 126 + for (i = 0; i < 2; i++) { 127 + res = i2c_smbus_read_byte_data(client, 128 + MAX6639_REG_FAN_CNT(i)); 129 + if (res < 0) { 130 + ret = ERR_PTR(res); 131 + goto abort; 132 + } 133 + data->fan[i] = res; 134 + 135 + res = i2c_smbus_read_byte_data(client, 136 + MAX6639_REG_TEMP_EXT(i)); 137 + if (res < 0) { 138 + ret = ERR_PTR(res); 139 + goto abort; 140 + } 141 + data->temp[i] = res >> 5; 142 + data->temp_fault[i] = res & 0x01; 143 + 144 + res = i2c_smbus_read_byte_data(client, 145 + MAX6639_REG_TEMP(i)); 146 + if (res < 0) { 147 + ret = ERR_PTR(res); 148 + goto abort; 149 + } 150 + data->temp[i] |= res << 3; 151 + } 152 + 153 + data->last_updated = jiffies; 154 + data->valid = 1; 155 + } 156 + abort: 157 + mutex_unlock(&data->update_lock); 158 + 159 + return ret; 160 + } 161 + 162 + static ssize_t show_temp_input(struct device *dev, 163 + struct device_attribute *dev_attr, char *buf) 164 + { 165 + long temp; 166 + struct max6639_data *data = max6639_update_device(dev); 167 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 168 + 169 + if (IS_ERR(data)) 170 + return PTR_ERR(data); 171 + 172 + temp = data->temp[attr->index] * 125; 173 + return sprintf(buf, "%ld\n", temp); 174 + } 175 + 176 + static ssize_t show_temp_fault(struct device *dev, 177 + struct device_attribute *dev_attr, char *buf) 178 + { 179 + struct max6639_data *data = max6639_update_device(dev); 180 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 181 + 182 + if (IS_ERR(data)) 183 + return PTR_ERR(data); 184 + 185 + return sprintf(buf, "%d\n", data->temp_fault[attr->index]); 186 + } 187 + 188 + static ssize_t show_temp_max(struct device *dev, 189 + struct device_attribute *dev_attr, char *buf) 190 + { 191 + struct i2c_client *client = to_i2c_client(dev); 192 + struct max6639_data *data = i2c_get_clientdata(client); 193 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 194 + 195 + return sprintf(buf, "%d\n", (data->temp_therm[attr->index] * 1000)); 196 + } 197 + 198 + static ssize_t set_temp_max(struct device *dev, 199 + struct device_attribute *dev_attr, 200 + const char *buf, size_t count) 201 + { 202 + struct i2c_client *client = to_i2c_client(dev); 203 + struct max6639_data *data = i2c_get_clientdata(client); 204 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 205 + unsigned long val; 206 + int res; 207 + 208 + res = strict_strtoul(buf, 10, &val); 209 + if (res) 210 + return res; 211 + 212 + mutex_lock(&data->update_lock); 213 + data->temp_therm[attr->index] = TEMP_LIMIT_TO_REG(val); 214 + i2c_smbus_write_byte_data(client, 215 + MAX6639_REG_THERM_LIMIT(attr->index), 216 + data->temp_therm[attr->index]); 217 + mutex_unlock(&data->update_lock); 218 + return count; 219 + } 220 + 221 + static ssize_t show_temp_crit(struct device *dev, 222 + struct device_attribute *dev_attr, char *buf) 223 + { 224 + struct i2c_client *client = to_i2c_client(dev); 225 + struct max6639_data *data = i2c_get_clientdata(client); 226 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 227 + 228 + return sprintf(buf, "%d\n", (data->temp_alert[attr->index] * 1000)); 229 + } 230 + 231 + static ssize_t set_temp_crit(struct device *dev, 232 + struct device_attribute *dev_attr, 233 + const char *buf, size_t count) 234 + { 235 + struct i2c_client *client = to_i2c_client(dev); 236 + struct max6639_data *data = i2c_get_clientdata(client); 237 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 238 + unsigned long val; 239 + int res; 240 + 241 + res = strict_strtoul(buf, 10, &val); 242 + if (res) 243 + return res; 244 + 245 + mutex_lock(&data->update_lock); 246 + data->temp_alert[attr->index] = TEMP_LIMIT_TO_REG(val); 247 + i2c_smbus_write_byte_data(client, 248 + MAX6639_REG_ALERT_LIMIT(attr->index), 249 + data->temp_alert[attr->index]); 250 + mutex_unlock(&data->update_lock); 251 + return count; 252 + } 253 + 254 + static ssize_t show_temp_emergency(struct device *dev, 255 + struct device_attribute *dev_attr, 256 + char *buf) 257 + { 258 + struct i2c_client *client = to_i2c_client(dev); 259 + struct max6639_data *data = i2c_get_clientdata(client); 260 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 261 + 262 + return sprintf(buf, "%d\n", (data->temp_ot[attr->index] * 1000)); 263 + } 264 + 265 + static ssize_t set_temp_emergency(struct device *dev, 266 + struct device_attribute *dev_attr, 267 + const char *buf, size_t count) 268 + { 269 + struct i2c_client *client = to_i2c_client(dev); 270 + struct max6639_data *data = i2c_get_clientdata(client); 271 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 272 + unsigned long val; 273 + int res; 274 + 275 + res = strict_strtoul(buf, 10, &val); 276 + if (res) 277 + return res; 278 + 279 + mutex_lock(&data->update_lock); 280 + data->temp_ot[attr->index] = TEMP_LIMIT_TO_REG(val); 281 + i2c_smbus_write_byte_data(client, 282 + MAX6639_REG_OT_LIMIT(attr->index), 283 + data->temp_ot[attr->index]); 284 + mutex_unlock(&data->update_lock); 285 + return count; 286 + } 287 + 288 + static ssize_t show_pwm(struct device *dev, 289 + struct device_attribute *dev_attr, char *buf) 290 + { 291 + struct i2c_client *client = to_i2c_client(dev); 292 + struct max6639_data *data = i2c_get_clientdata(client); 293 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 294 + 295 + return sprintf(buf, "%d\n", data->pwm[attr->index] * 255 / 120); 296 + } 297 + 298 + static ssize_t set_pwm(struct device *dev, 299 + struct device_attribute *dev_attr, 300 + const char *buf, size_t count) 301 + { 302 + struct i2c_client *client = to_i2c_client(dev); 303 + struct max6639_data *data = i2c_get_clientdata(client); 304 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 305 + unsigned long val; 306 + int res; 307 + 308 + res = strict_strtoul(buf, 10, &val); 309 + if (res) 310 + return res; 311 + 312 + val = SENSORS_LIMIT(val, 0, 255); 313 + 314 + mutex_lock(&data->update_lock); 315 + data->pwm[attr->index] = (u8)(val * 120 / 255); 316 + i2c_smbus_write_byte_data(client, 317 + MAX6639_REG_TARGTDUTY(attr->index), 318 + data->pwm[attr->index]); 319 + mutex_unlock(&data->update_lock); 320 + return count; 321 + } 322 + 323 + static ssize_t show_fan_input(struct device *dev, 324 + struct device_attribute *dev_attr, char *buf) 325 + { 326 + struct max6639_data *data = max6639_update_device(dev); 327 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 328 + 329 + if (IS_ERR(data)) 330 + return PTR_ERR(data); 331 + 332 + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index], 333 + data->ppr, data->rpm_range)); 334 + } 335 + 336 + static ssize_t show_alarm(struct device *dev, 337 + struct device_attribute *dev_attr, char *buf) 338 + { 339 + struct max6639_data *data = max6639_update_device(dev); 340 + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); 341 + 342 + if (IS_ERR(data)) 343 + return PTR_ERR(data); 344 + 345 + return sprintf(buf, "%d\n", !!(data->status & (1 << attr->index))); 346 + } 347 + 348 + static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0); 349 + static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1); 350 + static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0); 351 + static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1); 352 + static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, 353 + set_temp_max, 0); 354 + static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, 355 + set_temp_max, 1); 356 + static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit, 357 + set_temp_crit, 0); 358 + static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit, 359 + set_temp_crit, 1); 360 + static SENSOR_DEVICE_ATTR(temp1_emergency, S_IWUSR | S_IRUGO, 361 + show_temp_emergency, set_temp_emergency, 0); 362 + static SENSOR_DEVICE_ATTR(temp2_emergency, S_IWUSR | S_IRUGO, 363 + show_temp_emergency, set_temp_emergency, 1); 364 + static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); 365 + static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); 366 + static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0); 367 + static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1); 368 + static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_alarm, NULL, 1); 369 + static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_alarm, NULL, 0); 370 + static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 3); 371 + static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 2); 372 + static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 7); 373 + static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 6); 374 + static SENSOR_DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO, show_alarm, NULL, 5); 375 + static SENSOR_DEVICE_ATTR(temp2_emergency_alarm, S_IRUGO, show_alarm, NULL, 4); 376 + 377 + 378 + static struct attribute *max6639_attributes[] = { 379 + &sensor_dev_attr_temp1_input.dev_attr.attr, 380 + &sensor_dev_attr_temp2_input.dev_attr.attr, 381 + &sensor_dev_attr_temp1_fault.dev_attr.attr, 382 + &sensor_dev_attr_temp2_fault.dev_attr.attr, 383 + &sensor_dev_attr_temp1_max.dev_attr.attr, 384 + &sensor_dev_attr_temp2_max.dev_attr.attr, 385 + &sensor_dev_attr_temp1_crit.dev_attr.attr, 386 + &sensor_dev_attr_temp2_crit.dev_attr.attr, 387 + &sensor_dev_attr_temp1_emergency.dev_attr.attr, 388 + &sensor_dev_attr_temp2_emergency.dev_attr.attr, 389 + &sensor_dev_attr_pwm1.dev_attr.attr, 390 + &sensor_dev_attr_pwm2.dev_attr.attr, 391 + &sensor_dev_attr_fan1_input.dev_attr.attr, 392 + &sensor_dev_attr_fan2_input.dev_attr.attr, 393 + &sensor_dev_attr_fan1_fault.dev_attr.attr, 394 + &sensor_dev_attr_fan2_fault.dev_attr.attr, 395 + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 396 + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, 397 + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, 398 + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, 399 + &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr, 400 + &sensor_dev_attr_temp2_emergency_alarm.dev_attr.attr, 401 + NULL 402 + }; 403 + 404 + static const struct attribute_group max6639_group = { 405 + .attrs = max6639_attributes, 406 + }; 407 + 408 + /* 409 + * returns respective index in rpm_ranges table 410 + * 1 by default on invalid range 411 + */ 412 + static int rpm_range_to_reg(int range) 413 + { 414 + int i; 415 + 416 + for (i = 0; i < ARRAY_SIZE(rpm_ranges); i++) { 417 + if (rpm_ranges[i] == range) 418 + return i; 419 + } 420 + 421 + return 1; /* default: 4000 RPM */ 422 + } 423 + 424 + static int max6639_init_client(struct i2c_client *client) 425 + { 426 + struct max6639_data *data = i2c_get_clientdata(client); 427 + struct max6639_platform_data *max6639_info = 428 + client->dev.platform_data; 429 + int i = 0; 430 + int rpm_range = 1; /* default: 4000 RPM */ 431 + int err = 0; 432 + 433 + /* Reset chip to default values */ 434 + err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, 435 + MAX6639_GCONFIG_POR); 436 + if (err) 437 + goto exit; 438 + 439 + /* Fans pulse per revolution is 2 by default */ 440 + if (max6639_info && max6639_info->ppr > 0 && 441 + max6639_info->ppr < 5) 442 + data->ppr = max6639_info->ppr; 443 + else 444 + data->ppr = 2; 445 + data->ppr -= 1; 446 + err = i2c_smbus_write_byte_data(client, 447 + MAX6639_REG_FAN_PPR(i), 448 + data->ppr << 5); 449 + if (err) 450 + goto exit; 451 + 452 + if (max6639_info) 453 + rpm_range = rpm_range_to_reg(max6639_info->rpm_range); 454 + data->rpm_range = rpm_range; 455 + 456 + for (i = 0; i < 2; i++) { 457 + 458 + /* Fans config PWM, RPM */ 459 + err = i2c_smbus_write_byte_data(client, 460 + MAX6639_REG_FAN_CONFIG1(i), 461 + MAX6639_FAN_CONFIG1_PWM | rpm_range); 462 + if (err) 463 + goto exit; 464 + 465 + /* Fans PWM polarity high by default */ 466 + if (max6639_info && max6639_info->pwm_polarity == 0) 467 + err = i2c_smbus_write_byte_data(client, 468 + MAX6639_REG_FAN_CONFIG2a(i), 0x00); 469 + else 470 + err = i2c_smbus_write_byte_data(client, 471 + MAX6639_REG_FAN_CONFIG2a(i), 0x02); 472 + if (err) 473 + goto exit; 474 + 475 + /* Max. temp. 80C/90C/100C */ 476 + data->temp_therm[i] = 80; 477 + data->temp_alert[i] = 90; 478 + data->temp_ot[i] = 100; 479 + err = i2c_smbus_write_byte_data(client, 480 + MAX6639_REG_THERM_LIMIT(i), 481 + data->temp_therm[i]); 482 + if (err) 483 + goto exit; 484 + err = i2c_smbus_write_byte_data(client, 485 + MAX6639_REG_ALERT_LIMIT(i), 486 + data->temp_alert[i]); 487 + if (err) 488 + goto exit; 489 + err = i2c_smbus_write_byte_data(client, 490 + MAX6639_REG_OT_LIMIT(i), data->temp_ot[i]); 491 + if (err) 492 + goto exit; 493 + 494 + /* PWM 120/120 (i.e. 100%) */ 495 + data->pwm[i] = 120; 496 + err = i2c_smbus_write_byte_data(client, 497 + MAX6639_REG_TARGTDUTY(i), data->pwm[i]); 498 + if (err) 499 + goto exit; 500 + } 501 + /* Start monitoring */ 502 + err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, 503 + MAX6639_GCONFIG_DISABLE_TIMEOUT | MAX6639_GCONFIG_CH2_LOCAL); 504 + exit: 505 + return err; 506 + } 507 + 508 + /* Return 0 if detection is successful, -ENODEV otherwise */ 509 + static int max6639_detect(struct i2c_client *client, 510 + struct i2c_board_info *info) 511 + { 512 + struct i2c_adapter *adapter = client->adapter; 513 + int dev_id, manu_id; 514 + 515 + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 516 + return -ENODEV; 517 + 518 + /* Actual detection via device and manufacturer ID */ 519 + dev_id = i2c_smbus_read_byte_data(client, MAX6639_REG_DEVID); 520 + manu_id = i2c_smbus_read_byte_data(client, MAX6639_REG_MANUID); 521 + if (dev_id != 0x58 || manu_id != 0x4D) 522 + return -ENODEV; 523 + 524 + strlcpy(info->type, "max6639", I2C_NAME_SIZE); 525 + 526 + return 0; 527 + } 528 + 529 + static int max6639_probe(struct i2c_client *client, 530 + const struct i2c_device_id *id) 531 + { 532 + struct max6639_data *data; 533 + int err; 534 + 535 + data = kzalloc(sizeof(struct max6639_data), GFP_KERNEL); 536 + if (!data) { 537 + err = -ENOMEM; 538 + goto exit; 539 + } 540 + 541 + i2c_set_clientdata(client, data); 542 + mutex_init(&data->update_lock); 543 + 544 + /* Initialize the max6639 chip */ 545 + err = max6639_init_client(client); 546 + if (err < 0) 547 + goto error_free; 548 + 549 + /* Register sysfs hooks */ 550 + err = sysfs_create_group(&client->dev.kobj, &max6639_group); 551 + if (err) 552 + goto error_free; 553 + 554 + data->hwmon_dev = hwmon_device_register(&client->dev); 555 + if (IS_ERR(data->hwmon_dev)) { 556 + err = PTR_ERR(data->hwmon_dev); 557 + goto error_remove; 558 + } 559 + 560 + dev_info(&client->dev, "temperature sensor and fan control found\n"); 561 + 562 + return 0; 563 + 564 + error_remove: 565 + sysfs_remove_group(&client->dev.kobj, &max6639_group); 566 + error_free: 567 + kfree(data); 568 + exit: 569 + return err; 570 + } 571 + 572 + static int max6639_remove(struct i2c_client *client) 573 + { 574 + struct max6639_data *data = i2c_get_clientdata(client); 575 + 576 + hwmon_device_unregister(data->hwmon_dev); 577 + sysfs_remove_group(&client->dev.kobj, &max6639_group); 578 + 579 + kfree(data); 580 + return 0; 581 + } 582 + 583 + static int max6639_suspend(struct i2c_client *client, pm_message_t mesg) 584 + { 585 + int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); 586 + if (data < 0) 587 + return data; 588 + 589 + return i2c_smbus_write_byte_data(client, 590 + MAX6639_REG_GCONFIG, data | MAX6639_GCONFIG_STANDBY); 591 + } 592 + 593 + static int max6639_resume(struct i2c_client *client) 594 + { 595 + int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); 596 + if (data < 0) 597 + return data; 598 + 599 + return i2c_smbus_write_byte_data(client, 600 + MAX6639_REG_GCONFIG, data & ~MAX6639_GCONFIG_STANDBY); 601 + } 602 + 603 + static const struct i2c_device_id max6639_id[] = { 604 + {"max6639", 0}, 605 + { } 606 + }; 607 + 608 + MODULE_DEVICE_TABLE(i2c, max6639_id); 609 + 610 + static struct i2c_driver max6639_driver = { 611 + .class = I2C_CLASS_HWMON, 612 + .driver = { 613 + .name = "max6639", 614 + }, 615 + .probe = max6639_probe, 616 + .remove = max6639_remove, 617 + .suspend = max6639_suspend, 618 + .resume = max6639_resume, 619 + .id_table = max6639_id, 620 + .detect = max6639_detect, 621 + .address_list = normal_i2c, 622 + }; 623 + 624 + static int __init max6639_init(void) 625 + { 626 + return i2c_add_driver(&max6639_driver); 627 + } 628 + 629 + static void __exit max6639_exit(void) 630 + { 631 + i2c_del_driver(&max6639_driver); 632 + } 633 + 634 + MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); 635 + MODULE_DESCRIPTION("max6639 driver"); 636 + MODULE_LICENSE("GPL"); 637 + 638 + module_init(max6639_init); 639 + module_exit(max6639_exit);
+14
include/linux/i2c/max6639.h
··· 1 + #ifndef _LINUX_MAX6639_H 2 + #define _LINUX_MAX6639_H 3 + 4 + #include <linux/types.h> 5 + 6 + /* platform data for the MAX6639 temperature sensor and fan control */ 7 + 8 + struct max6639_platform_data { 9 + bool pwm_polarity; /* Polarity low (0) or high (1, default) */ 10 + int ppr; /* Pulses per rotation 1..4 (default == 2) */ 11 + int rpm_range; /* 2000, 4000 (default), 8000 or 16000 */ 12 + }; 13 + 14 + #endif /* _LINUX_MAX6639_H */