···11+Kernel driver max663922+=====================33+44+Supported chips:55+ * Maxim MAX663966+ Prefix: 'max6639'77+ Addresses scanned: I2C 0x2c, 0x2e, 0x2f88+ Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6639.pdf99+1010+Authors:1111+ He Changqing <hechangqing@semptian.com>1212+ Roland Stigge <stigge@antcom.de>1313+1414+Description1515+-----------1616+1717+This driver implements support for the Maxim MAX6639. This chip is a 2-channel1818+temperature monitor with dual PWM fan speed controller. It can monitor its own1919+temperature and one external diode-connected transistor or two external2020+diode-connected transistors.2121+2222+The following device attributes are implemented via sysfs:2323+2424+Attribute R/W Contents2525+----------------------------------------------------------------------------2626+temp1_input R Temperature channel 1 input (0..150 C)2727+temp2_input R Temperature channel 2 input (0..150 C)2828+temp1_fault R Temperature channel 1 diode fault2929+temp2_fault R Temperature channel 2 diode fault3030+temp1_max RW Set THERM temperature for input 13131+ (in C, see datasheet)3232+temp2_max RW Set THERM temperature for input 23333+temp1_crit RW Set ALERT temperature for input 13434+temp2_crit RW Set ALERT temperature for input 23535+temp1_emergency RW Set OT temperature for input 13636+ (in C, see datasheet)3737+temp2_emergency RW Set OT temperature for input 23838+pwm1 RW Fan 1 target duty cycle (0..255)3939+pwm2 RW Fan 2 target duty cycle (0..255)4040+fan1_input R TACH1 fan tachometer input (in RPM)4141+fan2_input R TACH2 fan tachometer input (in RPM)4242+fan1_fault R Fan 1 fault4343+fan2_fault R Fan 2 fault4444+temp1_max_alarm R Alarm on THERM temperature on channel 14545+temp2_max_alarm R Alarm on THERM temperature on channel 24646+temp1_crit_alarm R Alarm on ALERT temperature on channel 14747+temp2_crit_alarm R Alarm on ALERT temperature on channel 24848+temp1_emergency_alarm R Alarm on OT temperature on channel 14949+temp2_emergency_alarm R Alarm on OT temperature on channel 2
+10
drivers/hwmon/Kconfig
···685685 This driver can also be built as a module. If so, the module686686 will be called max1619.687687688688+config SENSORS_MAX6639689689+ tristate "Maxim MAX6639 sensor chip"690690+ depends on I2C && EXPERIMENTAL691691+ help692692+ If you say yes here you get support for the MAX6639693693+ sensor chips.694694+695695+ This driver can also be built as a module. If so, the module696696+ will be called max6639.697697+688698config SENSORS_MAX6650689699 tristate "Maxim MAX6650 sensor chip"690700 depends on I2C && EXPERIMENTAL
···11+/*22+ * max6639.c - Support for Maxim MAX663933+ *44+ * 2-Channel Temperature Monitor with Dual PWM Fan-Speed Controller55+ *66+ * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de>77+ *88+ * based on the initial MAX6639 support from semptian.net99+ * by He Changqing <hechangqing@semptian.com>1010+ *1111+ * This program is free software; you can redistribute it and/or modify1212+ * it under the terms of the GNU General Public License as published by1313+ * the Free Software Foundation; either version 2 of the License, or1414+ * (at your option) any later version.1515+ *1616+ * This program is distributed in the hope that it will be useful,1717+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1818+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1919+ * GNU General Public License for more details.2020+ *2121+ * You should have received a copy of the GNU General Public License2222+ * along with this program; if not, write to the Free Software2323+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2424+ */2525+2626+#include <linux/module.h>2727+#include <linux/init.h>2828+#include <linux/slab.h>2929+#include <linux/jiffies.h>3030+#include <linux/i2c.h>3131+#include <linux/hwmon.h>3232+#include <linux/hwmon-sysfs.h>3333+#include <linux/err.h>3434+#include <linux/mutex.h>3535+#include <linux/i2c/max6639.h>3636+3737+/* Addresses to scan */3838+static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END };3939+4040+/* The MAX6639 registers, valid channel numbers: 0, 1 */4141+#define MAX6639_REG_TEMP(ch) (0x00 + (ch))4242+#define MAX6639_REG_STATUS 0x024343+#define MAX6639_REG_OUTPUT_MASK 0x034444+#define MAX6639_REG_GCONFIG 0x044545+#define MAX6639_REG_TEMP_EXT(ch) (0x05 + (ch))4646+#define MAX6639_REG_ALERT_LIMIT(ch) (0x08 + (ch))4747+#define MAX6639_REG_OT_LIMIT(ch) (0x0A + (ch))4848+#define MAX6639_REG_THERM_LIMIT(ch) (0x0C + (ch))4949+#define MAX6639_REG_FAN_CONFIG1(ch) (0x10 + (ch) * 4)5050+#define MAX6639_REG_FAN_CONFIG2a(ch) (0x11 + (ch) * 4)5151+#define MAX6639_REG_FAN_CONFIG2b(ch) (0x12 + (ch) * 4)5252+#define MAX6639_REG_FAN_CONFIG3(ch) (0x13 + (ch) * 4)5353+#define MAX6639_REG_FAN_CNT(ch) (0x20 + (ch))5454+#define MAX6639_REG_TARGET_CNT(ch) (0x22 + (ch))5555+#define MAX6639_REG_FAN_PPR(ch) (0x24 + (ch))5656+#define MAX6639_REG_TARGTDUTY(ch) (0x26 + (ch))5757+#define MAX6639_REG_FAN_START_TEMP(ch) (0x28 + (ch))5858+#define MAX6639_REG_DEVID 0x3D5959+#define MAX6639_REG_MANUID 0x3E6060+#define MAX6639_REG_DEVREV 0x3F6161+6262+/* Register bits */6363+#define MAX6639_GCONFIG_STANDBY 0x806464+#define MAX6639_GCONFIG_POR 0x406565+#define MAX6639_GCONFIG_DISABLE_TIMEOUT 0x206666+#define MAX6639_GCONFIG_CH2_LOCAL 0x106767+6868+#define MAX6639_FAN_CONFIG1_PWM 0x806969+7070+static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 };7171+7272+#define FAN_FROM_REG(val, div, rpm_range) ((val) == 0 ? -1 : \7373+ (val) == 255 ? 0 : (rpm_ranges[rpm_range] * 30) / ((div + 1) * (val)))7474+#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255)7575+7676+/*7777+ * Client data (each client gets its own)7878+ */7979+struct max6639_data {8080+ struct device *hwmon_dev;8181+ struct mutex update_lock;8282+ char valid; /* !=0 if following fields are valid */8383+ unsigned long last_updated; /* In jiffies */8484+8585+ /* Register values sampled regularly */8686+ u16 temp[2]; /* Temperature, in 1/8 C, 0..255 C */8787+ bool temp_fault[2]; /* Detected temperature diode failure */8888+ u8 fan[2]; /* Register value: TACH count for fans >=30 */8989+ u8 status; /* Detected channel alarms and fan failures */9090+9191+ /* Register values only written to */9292+ u8 pwm[2]; /* Register value: Duty cycle 0..120 */9393+ u8 temp_therm[2]; /* THERM Temperature, 0..255 C (->_max) */9494+ u8 temp_alert[2]; /* ALERT Temperature, 0..255 C (->_crit) */9595+ u8 temp_ot[2]; /* OT Temperature, 0..255 C (->_emergency) */9696+9797+ /* Register values initialized only once */9898+ u8 ppr; /* Pulses per rotation 0..3 for 1..4 ppr */9999+ u8 rpm_range; /* Index in above rpm_ranges table */100100+};101101+102102+static struct max6639_data *max6639_update_device(struct device *dev)103103+{104104+ struct i2c_client *client = to_i2c_client(dev);105105+ struct max6639_data *data = i2c_get_clientdata(client);106106+ struct max6639_data *ret = data;107107+ int i;108108+ int status_reg;109109+110110+ mutex_lock(&data->update_lock);111111+112112+ if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {113113+ int res;114114+115115+ dev_dbg(&client->dev, "Starting max6639 update\n");116116+117117+ status_reg = i2c_smbus_read_byte_data(client,118118+ MAX6639_REG_STATUS);119119+ if (status_reg < 0) {120120+ ret = ERR_PTR(status_reg);121121+ goto abort;122122+ }123123+124124+ data->status = status_reg;125125+126126+ for (i = 0; i < 2; i++) {127127+ res = i2c_smbus_read_byte_data(client,128128+ MAX6639_REG_FAN_CNT(i));129129+ if (res < 0) {130130+ ret = ERR_PTR(res);131131+ goto abort;132132+ }133133+ data->fan[i] = res;134134+135135+ res = i2c_smbus_read_byte_data(client,136136+ MAX6639_REG_TEMP_EXT(i));137137+ if (res < 0) {138138+ ret = ERR_PTR(res);139139+ goto abort;140140+ }141141+ data->temp[i] = res >> 5;142142+ data->temp_fault[i] = res & 0x01;143143+144144+ res = i2c_smbus_read_byte_data(client,145145+ MAX6639_REG_TEMP(i));146146+ if (res < 0) {147147+ ret = ERR_PTR(res);148148+ goto abort;149149+ }150150+ data->temp[i] |= res << 3;151151+ }152152+153153+ data->last_updated = jiffies;154154+ data->valid = 1;155155+ }156156+abort:157157+ mutex_unlock(&data->update_lock);158158+159159+ return ret;160160+}161161+162162+static ssize_t show_temp_input(struct device *dev,163163+ struct device_attribute *dev_attr, char *buf)164164+{165165+ long temp;166166+ struct max6639_data *data = max6639_update_device(dev);167167+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);168168+169169+ if (IS_ERR(data))170170+ return PTR_ERR(data);171171+172172+ temp = data->temp[attr->index] * 125;173173+ return sprintf(buf, "%ld\n", temp);174174+}175175+176176+static ssize_t show_temp_fault(struct device *dev,177177+ struct device_attribute *dev_attr, char *buf)178178+{179179+ struct max6639_data *data = max6639_update_device(dev);180180+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);181181+182182+ if (IS_ERR(data))183183+ return PTR_ERR(data);184184+185185+ return sprintf(buf, "%d\n", data->temp_fault[attr->index]);186186+}187187+188188+static ssize_t show_temp_max(struct device *dev,189189+ struct device_attribute *dev_attr, char *buf)190190+{191191+ struct i2c_client *client = to_i2c_client(dev);192192+ struct max6639_data *data = i2c_get_clientdata(client);193193+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);194194+195195+ return sprintf(buf, "%d\n", (data->temp_therm[attr->index] * 1000));196196+}197197+198198+static ssize_t set_temp_max(struct device *dev,199199+ struct device_attribute *dev_attr,200200+ const char *buf, size_t count)201201+{202202+ struct i2c_client *client = to_i2c_client(dev);203203+ struct max6639_data *data = i2c_get_clientdata(client);204204+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);205205+ unsigned long val;206206+ int res;207207+208208+ res = strict_strtoul(buf, 10, &val);209209+ if (res)210210+ return res;211211+212212+ mutex_lock(&data->update_lock);213213+ data->temp_therm[attr->index] = TEMP_LIMIT_TO_REG(val);214214+ i2c_smbus_write_byte_data(client,215215+ MAX6639_REG_THERM_LIMIT(attr->index),216216+ data->temp_therm[attr->index]);217217+ mutex_unlock(&data->update_lock);218218+ return count;219219+}220220+221221+static ssize_t show_temp_crit(struct device *dev,222222+ struct device_attribute *dev_attr, char *buf)223223+{224224+ struct i2c_client *client = to_i2c_client(dev);225225+ struct max6639_data *data = i2c_get_clientdata(client);226226+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);227227+228228+ return sprintf(buf, "%d\n", (data->temp_alert[attr->index] * 1000));229229+}230230+231231+static ssize_t set_temp_crit(struct device *dev,232232+ struct device_attribute *dev_attr,233233+ const char *buf, size_t count)234234+{235235+ struct i2c_client *client = to_i2c_client(dev);236236+ struct max6639_data *data = i2c_get_clientdata(client);237237+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);238238+ unsigned long val;239239+ int res;240240+241241+ res = strict_strtoul(buf, 10, &val);242242+ if (res)243243+ return res;244244+245245+ mutex_lock(&data->update_lock);246246+ data->temp_alert[attr->index] = TEMP_LIMIT_TO_REG(val);247247+ i2c_smbus_write_byte_data(client,248248+ MAX6639_REG_ALERT_LIMIT(attr->index),249249+ data->temp_alert[attr->index]);250250+ mutex_unlock(&data->update_lock);251251+ return count;252252+}253253+254254+static ssize_t show_temp_emergency(struct device *dev,255255+ struct device_attribute *dev_attr,256256+ char *buf)257257+{258258+ struct i2c_client *client = to_i2c_client(dev);259259+ struct max6639_data *data = i2c_get_clientdata(client);260260+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);261261+262262+ return sprintf(buf, "%d\n", (data->temp_ot[attr->index] * 1000));263263+}264264+265265+static ssize_t set_temp_emergency(struct device *dev,266266+ struct device_attribute *dev_attr,267267+ const char *buf, size_t count)268268+{269269+ struct i2c_client *client = to_i2c_client(dev);270270+ struct max6639_data *data = i2c_get_clientdata(client);271271+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);272272+ unsigned long val;273273+ int res;274274+275275+ res = strict_strtoul(buf, 10, &val);276276+ if (res)277277+ return res;278278+279279+ mutex_lock(&data->update_lock);280280+ data->temp_ot[attr->index] = TEMP_LIMIT_TO_REG(val);281281+ i2c_smbus_write_byte_data(client,282282+ MAX6639_REG_OT_LIMIT(attr->index),283283+ data->temp_ot[attr->index]);284284+ mutex_unlock(&data->update_lock);285285+ return count;286286+}287287+288288+static ssize_t show_pwm(struct device *dev,289289+ struct device_attribute *dev_attr, char *buf)290290+{291291+ struct i2c_client *client = to_i2c_client(dev);292292+ struct max6639_data *data = i2c_get_clientdata(client);293293+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);294294+295295+ return sprintf(buf, "%d\n", data->pwm[attr->index] * 255 / 120);296296+}297297+298298+static ssize_t set_pwm(struct device *dev,299299+ struct device_attribute *dev_attr,300300+ const char *buf, size_t count)301301+{302302+ struct i2c_client *client = to_i2c_client(dev);303303+ struct max6639_data *data = i2c_get_clientdata(client);304304+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);305305+ unsigned long val;306306+ int res;307307+308308+ res = strict_strtoul(buf, 10, &val);309309+ if (res)310310+ return res;311311+312312+ val = SENSORS_LIMIT(val, 0, 255);313313+314314+ mutex_lock(&data->update_lock);315315+ data->pwm[attr->index] = (u8)(val * 120 / 255);316316+ i2c_smbus_write_byte_data(client,317317+ MAX6639_REG_TARGTDUTY(attr->index),318318+ data->pwm[attr->index]);319319+ mutex_unlock(&data->update_lock);320320+ return count;321321+}322322+323323+static ssize_t show_fan_input(struct device *dev,324324+ struct device_attribute *dev_attr, char *buf)325325+{326326+ struct max6639_data *data = max6639_update_device(dev);327327+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);328328+329329+ if (IS_ERR(data))330330+ return PTR_ERR(data);331331+332332+ return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index],333333+ data->ppr, data->rpm_range));334334+}335335+336336+static ssize_t show_alarm(struct device *dev,337337+ struct device_attribute *dev_attr, char *buf)338338+{339339+ struct max6639_data *data = max6639_update_device(dev);340340+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);341341+342342+ if (IS_ERR(data))343343+ return PTR_ERR(data);344344+345345+ return sprintf(buf, "%d\n", !!(data->status & (1 << attr->index)));346346+}347347+348348+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0);349349+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1);350350+static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0);351351+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1);352352+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,353353+ set_temp_max, 0);354354+static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,355355+ set_temp_max, 1);356356+static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit,357357+ set_temp_crit, 0);358358+static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit,359359+ set_temp_crit, 1);360360+static SENSOR_DEVICE_ATTR(temp1_emergency, S_IWUSR | S_IRUGO,361361+ show_temp_emergency, set_temp_emergency, 0);362362+static SENSOR_DEVICE_ATTR(temp2_emergency, S_IWUSR | S_IRUGO,363363+ show_temp_emergency, set_temp_emergency, 1);364364+static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);365365+static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);366366+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);367367+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);368368+static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_alarm, NULL, 1);369369+static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_alarm, NULL, 0);370370+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 3);371371+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 2);372372+static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 7);373373+static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 6);374374+static SENSOR_DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO, show_alarm, NULL, 5);375375+static SENSOR_DEVICE_ATTR(temp2_emergency_alarm, S_IRUGO, show_alarm, NULL, 4);376376+377377+378378+static struct attribute *max6639_attributes[] = {379379+ &sensor_dev_attr_temp1_input.dev_attr.attr,380380+ &sensor_dev_attr_temp2_input.dev_attr.attr,381381+ &sensor_dev_attr_temp1_fault.dev_attr.attr,382382+ &sensor_dev_attr_temp2_fault.dev_attr.attr,383383+ &sensor_dev_attr_temp1_max.dev_attr.attr,384384+ &sensor_dev_attr_temp2_max.dev_attr.attr,385385+ &sensor_dev_attr_temp1_crit.dev_attr.attr,386386+ &sensor_dev_attr_temp2_crit.dev_attr.attr,387387+ &sensor_dev_attr_temp1_emergency.dev_attr.attr,388388+ &sensor_dev_attr_temp2_emergency.dev_attr.attr,389389+ &sensor_dev_attr_pwm1.dev_attr.attr,390390+ &sensor_dev_attr_pwm2.dev_attr.attr,391391+ &sensor_dev_attr_fan1_input.dev_attr.attr,392392+ &sensor_dev_attr_fan2_input.dev_attr.attr,393393+ &sensor_dev_attr_fan1_fault.dev_attr.attr,394394+ &sensor_dev_attr_fan2_fault.dev_attr.attr,395395+ &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,396396+ &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,397397+ &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,398398+ &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,399399+ &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr,400400+ &sensor_dev_attr_temp2_emergency_alarm.dev_attr.attr,401401+ NULL402402+};403403+404404+static const struct attribute_group max6639_group = {405405+ .attrs = max6639_attributes,406406+};407407+408408+/*409409+ * returns respective index in rpm_ranges table410410+ * 1 by default on invalid range411411+ */412412+static int rpm_range_to_reg(int range)413413+{414414+ int i;415415+416416+ for (i = 0; i < ARRAY_SIZE(rpm_ranges); i++) {417417+ if (rpm_ranges[i] == range)418418+ return i;419419+ }420420+421421+ return 1; /* default: 4000 RPM */422422+}423423+424424+static int max6639_init_client(struct i2c_client *client)425425+{426426+ struct max6639_data *data = i2c_get_clientdata(client);427427+ struct max6639_platform_data *max6639_info =428428+ client->dev.platform_data;429429+ int i = 0;430430+ int rpm_range = 1; /* default: 4000 RPM */431431+ int err = 0;432432+433433+ /* Reset chip to default values */434434+ err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG,435435+ MAX6639_GCONFIG_POR);436436+ if (err)437437+ goto exit;438438+439439+ /* Fans pulse per revolution is 2 by default */440440+ if (max6639_info && max6639_info->ppr > 0 &&441441+ max6639_info->ppr < 5)442442+ data->ppr = max6639_info->ppr;443443+ else444444+ data->ppr = 2;445445+ data->ppr -= 1;446446+ err = i2c_smbus_write_byte_data(client,447447+ MAX6639_REG_FAN_PPR(i),448448+ data->ppr << 5);449449+ if (err)450450+ goto exit;451451+452452+ if (max6639_info)453453+ rpm_range = rpm_range_to_reg(max6639_info->rpm_range);454454+ data->rpm_range = rpm_range;455455+456456+ for (i = 0; i < 2; i++) {457457+458458+ /* Fans config PWM, RPM */459459+ err = i2c_smbus_write_byte_data(client,460460+ MAX6639_REG_FAN_CONFIG1(i),461461+ MAX6639_FAN_CONFIG1_PWM | rpm_range);462462+ if (err)463463+ goto exit;464464+465465+ /* Fans PWM polarity high by default */466466+ if (max6639_info && max6639_info->pwm_polarity == 0)467467+ err = i2c_smbus_write_byte_data(client,468468+ MAX6639_REG_FAN_CONFIG2a(i), 0x00);469469+ else470470+ err = i2c_smbus_write_byte_data(client,471471+ MAX6639_REG_FAN_CONFIG2a(i), 0x02);472472+ if (err)473473+ goto exit;474474+475475+ /* Max. temp. 80C/90C/100C */476476+ data->temp_therm[i] = 80;477477+ data->temp_alert[i] = 90;478478+ data->temp_ot[i] = 100;479479+ err = i2c_smbus_write_byte_data(client,480480+ MAX6639_REG_THERM_LIMIT(i),481481+ data->temp_therm[i]);482482+ if (err)483483+ goto exit;484484+ err = i2c_smbus_write_byte_data(client,485485+ MAX6639_REG_ALERT_LIMIT(i),486486+ data->temp_alert[i]);487487+ if (err)488488+ goto exit;489489+ err = i2c_smbus_write_byte_data(client,490490+ MAX6639_REG_OT_LIMIT(i), data->temp_ot[i]);491491+ if (err)492492+ goto exit;493493+494494+ /* PWM 120/120 (i.e. 100%) */495495+ data->pwm[i] = 120;496496+ err = i2c_smbus_write_byte_data(client,497497+ MAX6639_REG_TARGTDUTY(i), data->pwm[i]);498498+ if (err)499499+ goto exit;500500+ }501501+ /* Start monitoring */502502+ err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG,503503+ MAX6639_GCONFIG_DISABLE_TIMEOUT | MAX6639_GCONFIG_CH2_LOCAL);504504+exit:505505+ return err;506506+}507507+508508+/* Return 0 if detection is successful, -ENODEV otherwise */509509+static int max6639_detect(struct i2c_client *client,510510+ struct i2c_board_info *info)511511+{512512+ struct i2c_adapter *adapter = client->adapter;513513+ int dev_id, manu_id;514514+515515+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))516516+ return -ENODEV;517517+518518+ /* Actual detection via device and manufacturer ID */519519+ dev_id = i2c_smbus_read_byte_data(client, MAX6639_REG_DEVID);520520+ manu_id = i2c_smbus_read_byte_data(client, MAX6639_REG_MANUID);521521+ if (dev_id != 0x58 || manu_id != 0x4D)522522+ return -ENODEV;523523+524524+ strlcpy(info->type, "max6639", I2C_NAME_SIZE);525525+526526+ return 0;527527+}528528+529529+static int max6639_probe(struct i2c_client *client,530530+ const struct i2c_device_id *id)531531+{532532+ struct max6639_data *data;533533+ int err;534534+535535+ data = kzalloc(sizeof(struct max6639_data), GFP_KERNEL);536536+ if (!data) {537537+ err = -ENOMEM;538538+ goto exit;539539+ }540540+541541+ i2c_set_clientdata(client, data);542542+ mutex_init(&data->update_lock);543543+544544+ /* Initialize the max6639 chip */545545+ err = max6639_init_client(client);546546+ if (err < 0)547547+ goto error_free;548548+549549+ /* Register sysfs hooks */550550+ err = sysfs_create_group(&client->dev.kobj, &max6639_group);551551+ if (err)552552+ goto error_free;553553+554554+ data->hwmon_dev = hwmon_device_register(&client->dev);555555+ if (IS_ERR(data->hwmon_dev)) {556556+ err = PTR_ERR(data->hwmon_dev);557557+ goto error_remove;558558+ }559559+560560+ dev_info(&client->dev, "temperature sensor and fan control found\n");561561+562562+ return 0;563563+564564+error_remove:565565+ sysfs_remove_group(&client->dev.kobj, &max6639_group);566566+error_free:567567+ kfree(data);568568+exit:569569+ return err;570570+}571571+572572+static int max6639_remove(struct i2c_client *client)573573+{574574+ struct max6639_data *data = i2c_get_clientdata(client);575575+576576+ hwmon_device_unregister(data->hwmon_dev);577577+ sysfs_remove_group(&client->dev.kobj, &max6639_group);578578+579579+ kfree(data);580580+ return 0;581581+}582582+583583+static int max6639_suspend(struct i2c_client *client, pm_message_t mesg)584584+{585585+ int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG);586586+ if (data < 0)587587+ return data;588588+589589+ return i2c_smbus_write_byte_data(client,590590+ MAX6639_REG_GCONFIG, data | MAX6639_GCONFIG_STANDBY);591591+}592592+593593+static int max6639_resume(struct i2c_client *client)594594+{595595+ int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG);596596+ if (data < 0)597597+ return data;598598+599599+ return i2c_smbus_write_byte_data(client,600600+ MAX6639_REG_GCONFIG, data & ~MAX6639_GCONFIG_STANDBY);601601+}602602+603603+static const struct i2c_device_id max6639_id[] = {604604+ {"max6639", 0},605605+ { }606606+};607607+608608+MODULE_DEVICE_TABLE(i2c, max6639_id);609609+610610+static struct i2c_driver max6639_driver = {611611+ .class = I2C_CLASS_HWMON,612612+ .driver = {613613+ .name = "max6639",614614+ },615615+ .probe = max6639_probe,616616+ .remove = max6639_remove,617617+ .suspend = max6639_suspend,618618+ .resume = max6639_resume,619619+ .id_table = max6639_id,620620+ .detect = max6639_detect,621621+ .address_list = normal_i2c,622622+};623623+624624+static int __init max6639_init(void)625625+{626626+ return i2c_add_driver(&max6639_driver);627627+}628628+629629+static void __exit max6639_exit(void)630630+{631631+ i2c_del_driver(&max6639_driver);632632+}633633+634634+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");635635+MODULE_DESCRIPTION("max6639 driver");636636+MODULE_LICENSE("GPL");637637+638638+module_init(max6639_init);639639+module_exit(max6639_exit);
+14
include/linux/i2c/max6639.h
···11+#ifndef _LINUX_MAX6639_H22+#define _LINUX_MAX6639_H33+44+#include <linux/types.h>55+66+/* platform data for the MAX6639 temperature sensor and fan control */77+88+struct max6639_platform_data {99+ bool pwm_polarity; /* Polarity low (0) or high (1, default) */1010+ int ppr; /* Pulses per rotation 1..4 (default == 2) */1111+ int rpm_range; /* 2000, 4000 (default), 8000 or 16000 */1212+};1313+1414+#endif /* _LINUX_MAX6639_H */