1d20620deSHans-Juergen Koch /* 2d20620deSHans-Juergen Koch * max6650.c - Part of lm_sensors, Linux kernel modules for hardware 3d20620deSHans-Juergen Koch * monitoring. 4d20620deSHans-Juergen Koch * 5d20620deSHans-Juergen Koch * (C) 2007 by Hans J. Koch <hjk@linutronix.de> 6d20620deSHans-Juergen Koch * 7d20620deSHans-Juergen Koch * based on code written by John Morris <john.morris@spirentcom.com> 8d20620deSHans-Juergen Koch * Copyright (c) 2003 Spirent Communications 9d20620deSHans-Juergen Koch * and Claus Gindhart <claus.gindhart@kontron.com> 10d20620deSHans-Juergen Koch * 11d20620deSHans-Juergen Koch * This module has only been tested with the MAX6650 chip. It should 12d20620deSHans-Juergen Koch * also work with the MAX6651. It does not distinguish max6650 and max6651 13d20620deSHans-Juergen Koch * chips. 14d20620deSHans-Juergen Koch * 1552b5226fSChristian Engelmayer * The datasheet was last seen at: 16d20620deSHans-Juergen Koch * 17d20620deSHans-Juergen Koch * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf 18d20620deSHans-Juergen Koch * 19d20620deSHans-Juergen Koch * This program is free software; you can redistribute it and/or modify 20d20620deSHans-Juergen Koch * it under the terms of the GNU General Public License as published by 21d20620deSHans-Juergen Koch * the Free Software Foundation; either version 2 of the License, or 22d20620deSHans-Juergen Koch * (at your option) any later version. 23d20620deSHans-Juergen Koch * 24d20620deSHans-Juergen Koch * This program is distributed in the hope that it will be useful, 25d20620deSHans-Juergen Koch * but WITHOUT ANY WARRANTY; without even the implied warranty of 26d20620deSHans-Juergen Koch * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27d20620deSHans-Juergen Koch * GNU General Public License for more details. 28d20620deSHans-Juergen Koch * 29d20620deSHans-Juergen Koch * You should have received a copy of the GNU General Public License 30d20620deSHans-Juergen Koch * along with this program; if not, write to the Free Software 31d20620deSHans-Juergen Koch * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 32d20620deSHans-Juergen Koch */ 33d20620deSHans-Juergen Koch 34d20620deSHans-Juergen Koch #include <linux/module.h> 35d20620deSHans-Juergen Koch #include <linux/init.h> 36d20620deSHans-Juergen Koch #include <linux/slab.h> 37d20620deSHans-Juergen Koch #include <linux/jiffies.h> 38d20620deSHans-Juergen Koch #include <linux/i2c.h> 39d20620deSHans-Juergen Koch #include <linux/hwmon.h> 40d20620deSHans-Juergen Koch #include <linux/hwmon-sysfs.h> 41d20620deSHans-Juergen Koch #include <linux/err.h> 42d20620deSHans-Juergen Koch 43d20620deSHans-Juergen Koch /* 44d20620deSHans-Juergen Koch * Addresses to scan. There are four disjoint possibilities, by pin config. 45d20620deSHans-Juergen Koch */ 46d20620deSHans-Juergen Koch 4725e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, 4825e9c86dSMark M. Hoffman I2C_CLIENT_END}; 49d20620deSHans-Juergen Koch 50d20620deSHans-Juergen Koch /* 51d20620deSHans-Juergen Koch * Insmod parameters 52d20620deSHans-Juergen Koch */ 53d20620deSHans-Juergen Koch 54d20620deSHans-Juergen Koch /* fan_voltage: 5=5V fan, 12=12V fan, 0=don't change */ 55d20620deSHans-Juergen Koch static int fan_voltage; 56d20620deSHans-Juergen Koch /* prescaler: Possible values are 1, 2, 4, 8, 16 or 0 for don't change */ 57d20620deSHans-Juergen Koch static int prescaler; 58d20620deSHans-Juergen Koch /* clock: The clock frequency of the chip the driver should assume */ 59d20620deSHans-Juergen Koch static int clock = 254000; 60d20620deSHans-Juergen Koch 61d20620deSHans-Juergen Koch module_param(fan_voltage, int, S_IRUGO); 62d20620deSHans-Juergen Koch module_param(prescaler, int, S_IRUGO); 63d20620deSHans-Juergen Koch module_param(clock, int, S_IRUGO); 64d20620deSHans-Juergen Koch 65d20620deSHans-Juergen Koch I2C_CLIENT_INSMOD_1(max6650); 66d20620deSHans-Juergen Koch 67d20620deSHans-Juergen Koch /* 68d20620deSHans-Juergen Koch * MAX 6650/6651 registers 69d20620deSHans-Juergen Koch */ 70d20620deSHans-Juergen Koch 71d20620deSHans-Juergen Koch #define MAX6650_REG_SPEED 0x00 72d20620deSHans-Juergen Koch #define MAX6650_REG_CONFIG 0x02 73d20620deSHans-Juergen Koch #define MAX6650_REG_GPIO_DEF 0x04 74d20620deSHans-Juergen Koch #define MAX6650_REG_DAC 0x06 75d20620deSHans-Juergen Koch #define MAX6650_REG_ALARM_EN 0x08 76d20620deSHans-Juergen Koch #define MAX6650_REG_ALARM 0x0A 77d20620deSHans-Juergen Koch #define MAX6650_REG_TACH0 0x0C 78d20620deSHans-Juergen Koch #define MAX6650_REG_TACH1 0x0E 79d20620deSHans-Juergen Koch #define MAX6650_REG_TACH2 0x10 80d20620deSHans-Juergen Koch #define MAX6650_REG_TACH3 0x12 81d20620deSHans-Juergen Koch #define MAX6650_REG_GPIO_STAT 0x14 82d20620deSHans-Juergen Koch #define MAX6650_REG_COUNT 0x16 83d20620deSHans-Juergen Koch 84d20620deSHans-Juergen Koch /* 85d20620deSHans-Juergen Koch * Config register bits 86d20620deSHans-Juergen Koch */ 87d20620deSHans-Juergen Koch 88d20620deSHans-Juergen Koch #define MAX6650_CFG_V12 0x08 89d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_MASK 0x07 90d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_2 0x01 91d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_4 0x02 92d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_8 0x03 93d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_16 0x04 94d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_MASK 0x30 95d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_ON 0x00 96d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_OFF 0x10 97d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_CLOSED_LOOP 0x20 98d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_OPEN_LOOP 0x30 99d20620deSHans-Juergen Koch #define MAX6650_COUNT_MASK 0x03 100d20620deSHans-Juergen Koch 10152b5226fSChristian Engelmayer /* 10252b5226fSChristian Engelmayer * Alarm status register bits 10352b5226fSChristian Engelmayer */ 10452b5226fSChristian Engelmayer 10552b5226fSChristian Engelmayer #define MAX6650_ALRM_MAX 0x01 10652b5226fSChristian Engelmayer #define MAX6650_ALRM_MIN 0x02 10752b5226fSChristian Engelmayer #define MAX6650_ALRM_TACH 0x04 10852b5226fSChristian Engelmayer #define MAX6650_ALRM_GPIO1 0x08 10952b5226fSChristian Engelmayer #define MAX6650_ALRM_GPIO2 0x10 11052b5226fSChristian Engelmayer 111d20620deSHans-Juergen Koch /* Minimum and maximum values of the FAN-RPM */ 112d20620deSHans-Juergen Koch #define FAN_RPM_MIN 240 113d20620deSHans-Juergen Koch #define FAN_RPM_MAX 30000 114d20620deSHans-Juergen Koch 115d20620deSHans-Juergen Koch #define DIV_FROM_REG(reg) (1 << (reg & 7)) 116d20620deSHans-Juergen Koch 1170d57abd5SJean Delvare static int max6650_probe(struct i2c_client *client, 1180d57abd5SJean Delvare const struct i2c_device_id *id); 1190d57abd5SJean Delvare static int max6650_detect(struct i2c_client *client, int kind, 1200d57abd5SJean Delvare struct i2c_board_info *info); 121d20620deSHans-Juergen Koch static int max6650_init_client(struct i2c_client *client); 1220d57abd5SJean Delvare static int max6650_remove(struct i2c_client *client); 123d20620deSHans-Juergen Koch static struct max6650_data *max6650_update_device(struct device *dev); 124d20620deSHans-Juergen Koch 125d20620deSHans-Juergen Koch /* 126d20620deSHans-Juergen Koch * Driver data (common to all clients) 127d20620deSHans-Juergen Koch */ 128d20620deSHans-Juergen Koch 1290d57abd5SJean Delvare static const struct i2c_device_id max6650_id[] = { 1300d57abd5SJean Delvare { "max6650", max6650 }, 1310d57abd5SJean Delvare { } 1320d57abd5SJean Delvare }; 1330d57abd5SJean Delvare MODULE_DEVICE_TABLE(i2c, max6650_id); 1340d57abd5SJean Delvare 135d20620deSHans-Juergen Koch static struct i2c_driver max6650_driver = { 1360d57abd5SJean Delvare .class = I2C_CLASS_HWMON, 137d20620deSHans-Juergen Koch .driver = { 138d20620deSHans-Juergen Koch .name = "max6650", 139d20620deSHans-Juergen Koch }, 1400d57abd5SJean Delvare .probe = max6650_probe, 1410d57abd5SJean Delvare .remove = max6650_remove, 1420d57abd5SJean Delvare .id_table = max6650_id, 1430d57abd5SJean Delvare .detect = max6650_detect, 1440d57abd5SJean Delvare .address_data = &addr_data, 145d20620deSHans-Juergen Koch }; 146d20620deSHans-Juergen Koch 147d20620deSHans-Juergen Koch /* 148d20620deSHans-Juergen Koch * Client data (each client gets its own) 149d20620deSHans-Juergen Koch */ 150d20620deSHans-Juergen Koch 151d20620deSHans-Juergen Koch struct max6650_data 152d20620deSHans-Juergen Koch { 1531beeffe4STony Jones struct device *hwmon_dev; 154d20620deSHans-Juergen Koch struct mutex update_lock; 155d20620deSHans-Juergen Koch char valid; /* zero until following fields are valid */ 156d20620deSHans-Juergen Koch unsigned long last_updated; /* in jiffies */ 157d20620deSHans-Juergen Koch 158d20620deSHans-Juergen Koch /* register values */ 159d20620deSHans-Juergen Koch u8 speed; 160d20620deSHans-Juergen Koch u8 config; 161d20620deSHans-Juergen Koch u8 tach[4]; 162d20620deSHans-Juergen Koch u8 count; 163d20620deSHans-Juergen Koch u8 dac; 16452b5226fSChristian Engelmayer u8 alarm; 165d20620deSHans-Juergen Koch }; 166d20620deSHans-Juergen Koch 167d20620deSHans-Juergen Koch static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, 168d20620deSHans-Juergen Koch char *buf) 169d20620deSHans-Juergen Koch { 170d20620deSHans-Juergen Koch struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 171d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 172d20620deSHans-Juergen Koch int rpm; 173d20620deSHans-Juergen Koch 174d20620deSHans-Juergen Koch /* 175d20620deSHans-Juergen Koch * Calculation details: 176d20620deSHans-Juergen Koch * 177d20620deSHans-Juergen Koch * Each tachometer counts over an interval given by the "count" 178d20620deSHans-Juergen Koch * register (0.25, 0.5, 1 or 2 seconds). This module assumes 179d20620deSHans-Juergen Koch * that the fans produce two pulses per revolution (this seems 180d20620deSHans-Juergen Koch * to be the most common). 181d20620deSHans-Juergen Koch */ 182d20620deSHans-Juergen Koch 183d20620deSHans-Juergen Koch rpm = ((data->tach[attr->index] * 120) / DIV_FROM_REG(data->count)); 184d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", rpm); 185d20620deSHans-Juergen Koch } 186d20620deSHans-Juergen Koch 187d20620deSHans-Juergen Koch /* 188d20620deSHans-Juergen Koch * Set the fan speed to the specified RPM (or read back the RPM setting). 189d20620deSHans-Juergen Koch * This works in closed loop mode only. Use pwm1 for open loop speed setting. 190d20620deSHans-Juergen Koch * 191d20620deSHans-Juergen Koch * The MAX6650/1 will automatically control fan speed when in closed loop 192d20620deSHans-Juergen Koch * mode. 193d20620deSHans-Juergen Koch * 194d20620deSHans-Juergen Koch * Assumptions: 195d20620deSHans-Juergen Koch * 196d20620deSHans-Juergen Koch * 1) The MAX6650/1 internal 254kHz clock frequency is set correctly. Use 197d20620deSHans-Juergen Koch * the clock module parameter if you need to fine tune this. 198d20620deSHans-Juergen Koch * 199d20620deSHans-Juergen Koch * 2) The prescaler (low three bits of the config register) has already 200d20620deSHans-Juergen Koch * been set to an appropriate value. Use the prescaler module parameter 201d20620deSHans-Juergen Koch * if your BIOS doesn't initialize the chip properly. 202d20620deSHans-Juergen Koch * 203d20620deSHans-Juergen Koch * The relevant equations are given on pages 21 and 22 of the datasheet. 204d20620deSHans-Juergen Koch * 205d20620deSHans-Juergen Koch * From the datasheet, the relevant equation when in regulation is: 206d20620deSHans-Juergen Koch * 207d20620deSHans-Juergen Koch * [fCLK / (128 x (KTACH + 1))] = 2 x FanSpeed / KSCALE 208d20620deSHans-Juergen Koch * 209d20620deSHans-Juergen Koch * where: 210d20620deSHans-Juergen Koch * 211d20620deSHans-Juergen Koch * fCLK is the oscillator frequency (either the 254kHz internal 212d20620deSHans-Juergen Koch * oscillator or the externally applied clock) 213d20620deSHans-Juergen Koch * 214d20620deSHans-Juergen Koch * KTACH is the value in the speed register 215d20620deSHans-Juergen Koch * 216d20620deSHans-Juergen Koch * FanSpeed is the speed of the fan in rps 217d20620deSHans-Juergen Koch * 218d20620deSHans-Juergen Koch * KSCALE is the prescaler value (1, 2, 4, 8, or 16) 219d20620deSHans-Juergen Koch * 220d20620deSHans-Juergen Koch * When reading, we need to solve for FanSpeed. When writing, we need to 221d20620deSHans-Juergen Koch * solve for KTACH. 222d20620deSHans-Juergen Koch * 223d20620deSHans-Juergen Koch * Note: this tachometer is completely separate from the tachometers 224d20620deSHans-Juergen Koch * used to measure the fan speeds. Only one fan's speed (fan1) is 225d20620deSHans-Juergen Koch * controlled. 226d20620deSHans-Juergen Koch */ 227d20620deSHans-Juergen Koch 228d20620deSHans-Juergen Koch static ssize_t get_target(struct device *dev, struct device_attribute *devattr, 229d20620deSHans-Juergen Koch char *buf) 230d20620deSHans-Juergen Koch { 231d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 232d20620deSHans-Juergen Koch int kscale, ktach, rpm; 233d20620deSHans-Juergen Koch 234d20620deSHans-Juergen Koch /* 235d20620deSHans-Juergen Koch * Use the datasheet equation: 236d20620deSHans-Juergen Koch * 237d20620deSHans-Juergen Koch * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] 238d20620deSHans-Juergen Koch * 239d20620deSHans-Juergen Koch * then multiply by 60 to give rpm. 240d20620deSHans-Juergen Koch */ 241d20620deSHans-Juergen Koch 242d20620deSHans-Juergen Koch kscale = DIV_FROM_REG(data->config); 243d20620deSHans-Juergen Koch ktach = data->speed; 244d20620deSHans-Juergen Koch rpm = 60 * kscale * clock / (256 * (ktach + 1)); 245d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", rpm); 246d20620deSHans-Juergen Koch } 247d20620deSHans-Juergen Koch 248d20620deSHans-Juergen Koch static ssize_t set_target(struct device *dev, struct device_attribute *devattr, 249d20620deSHans-Juergen Koch const char *buf, size_t count) 250d20620deSHans-Juergen Koch { 251d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 252d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 253d20620deSHans-Juergen Koch int rpm = simple_strtoul(buf, NULL, 10); 254d20620deSHans-Juergen Koch int kscale, ktach; 255d20620deSHans-Juergen Koch 256d20620deSHans-Juergen Koch rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); 257d20620deSHans-Juergen Koch 258d20620deSHans-Juergen Koch /* 259d20620deSHans-Juergen Koch * Divide the required speed by 60 to get from rpm to rps, then 260d20620deSHans-Juergen Koch * use the datasheet equation: 261d20620deSHans-Juergen Koch * 262d20620deSHans-Juergen Koch * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 263d20620deSHans-Juergen Koch */ 264d20620deSHans-Juergen Koch 265d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 266d20620deSHans-Juergen Koch 267d20620deSHans-Juergen Koch kscale = DIV_FROM_REG(data->config); 268d20620deSHans-Juergen Koch ktach = ((clock * kscale) / (256 * rpm / 60)) - 1; 269d20620deSHans-Juergen Koch if (ktach < 0) 270d20620deSHans-Juergen Koch ktach = 0; 271d20620deSHans-Juergen Koch if (ktach > 255) 272d20620deSHans-Juergen Koch ktach = 255; 273d20620deSHans-Juergen Koch data->speed = ktach; 274d20620deSHans-Juergen Koch 275d20620deSHans-Juergen Koch i2c_smbus_write_byte_data(client, MAX6650_REG_SPEED, data->speed); 276d20620deSHans-Juergen Koch 277d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 278d20620deSHans-Juergen Koch 279d20620deSHans-Juergen Koch return count; 280d20620deSHans-Juergen Koch } 281d20620deSHans-Juergen Koch 282d20620deSHans-Juergen Koch /* 283d20620deSHans-Juergen Koch * Get/set the fan speed in open loop mode using pwm1 sysfs file. 284d20620deSHans-Juergen Koch * Speed is given as a relative value from 0 to 255, where 255 is maximum 285d20620deSHans-Juergen Koch * speed. Note that this is done by writing directly to the chip's DAC, 286d20620deSHans-Juergen Koch * it won't change the closed loop speed set by fan1_target. 287d20620deSHans-Juergen Koch * Also note that due to rounding errors it is possible that you don't read 288d20620deSHans-Juergen Koch * back exactly the value you have set. 289d20620deSHans-Juergen Koch */ 290d20620deSHans-Juergen Koch 291d20620deSHans-Juergen Koch static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, 292d20620deSHans-Juergen Koch char *buf) 293d20620deSHans-Juergen Koch { 294d20620deSHans-Juergen Koch int pwm; 295d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 296d20620deSHans-Juergen Koch 297d20620deSHans-Juergen Koch /* Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. 298d20620deSHans-Juergen Koch Lower DAC values mean higher speeds. */ 299d20620deSHans-Juergen Koch if (data->config & MAX6650_CFG_V12) 300d20620deSHans-Juergen Koch pwm = 255 - (255 * (int)data->dac)/180; 301d20620deSHans-Juergen Koch else 302d20620deSHans-Juergen Koch pwm = 255 - (255 * (int)data->dac)/76; 303d20620deSHans-Juergen Koch 304d20620deSHans-Juergen Koch if (pwm < 0) 305d20620deSHans-Juergen Koch pwm = 0; 306d20620deSHans-Juergen Koch 307d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", pwm); 308d20620deSHans-Juergen Koch } 309d20620deSHans-Juergen Koch 310d20620deSHans-Juergen Koch static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, 311d20620deSHans-Juergen Koch const char *buf, size_t count) 312d20620deSHans-Juergen Koch { 313d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 314d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 315d20620deSHans-Juergen Koch int pwm = simple_strtoul(buf, NULL, 10); 316d20620deSHans-Juergen Koch 317d20620deSHans-Juergen Koch pwm = SENSORS_LIMIT(pwm, 0, 255); 318d20620deSHans-Juergen Koch 319d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 320d20620deSHans-Juergen Koch 321d20620deSHans-Juergen Koch if (data->config & MAX6650_CFG_V12) 322d20620deSHans-Juergen Koch data->dac = 180 - (180 * pwm)/255; 323d20620deSHans-Juergen Koch else 324d20620deSHans-Juergen Koch data->dac = 76 - (76 * pwm)/255; 325d20620deSHans-Juergen Koch 326d20620deSHans-Juergen Koch i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac); 327d20620deSHans-Juergen Koch 328d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 329d20620deSHans-Juergen Koch 330d20620deSHans-Juergen Koch return count; 331d20620deSHans-Juergen Koch } 332d20620deSHans-Juergen Koch 333d20620deSHans-Juergen Koch /* 334d20620deSHans-Juergen Koch * Get/Set controller mode: 335d20620deSHans-Juergen Koch * Possible values: 336d20620deSHans-Juergen Koch * 0 = Fan always on 337d20620deSHans-Juergen Koch * 1 = Open loop, Voltage is set according to speed, not regulated. 338d20620deSHans-Juergen Koch * 2 = Closed loop, RPM for all fans regulated by fan1 tachometer 339d20620deSHans-Juergen Koch */ 340d20620deSHans-Juergen Koch 341d20620deSHans-Juergen Koch static ssize_t get_enable(struct device *dev, struct device_attribute *devattr, 342d20620deSHans-Juergen Koch char *buf) 343d20620deSHans-Juergen Koch { 344d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 345d20620deSHans-Juergen Koch int mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4; 346d20620deSHans-Juergen Koch int sysfs_modes[4] = {0, 1, 2, 1}; 347d20620deSHans-Juergen Koch 348d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", sysfs_modes[mode]); 349d20620deSHans-Juergen Koch } 350d20620deSHans-Juergen Koch 351d20620deSHans-Juergen Koch static ssize_t set_enable(struct device *dev, struct device_attribute *devattr, 352d20620deSHans-Juergen Koch const char *buf, size_t count) 353d20620deSHans-Juergen Koch { 354d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 355d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 356d20620deSHans-Juergen Koch int mode = simple_strtoul(buf, NULL, 10); 357d20620deSHans-Juergen Koch int max6650_modes[3] = {0, 3, 2}; 358d20620deSHans-Juergen Koch 359d20620deSHans-Juergen Koch if ((mode < 0)||(mode > 2)) { 360d20620deSHans-Juergen Koch dev_err(&client->dev, 361d20620deSHans-Juergen Koch "illegal value for pwm1_enable (%d)\n", mode); 362d20620deSHans-Juergen Koch return -EINVAL; 363d20620deSHans-Juergen Koch } 364d20620deSHans-Juergen Koch 365d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 366d20620deSHans-Juergen Koch 367d20620deSHans-Juergen Koch data->config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); 368d20620deSHans-Juergen Koch data->config = (data->config & ~MAX6650_CFG_MODE_MASK) 369d20620deSHans-Juergen Koch | (max6650_modes[mode] << 4); 370d20620deSHans-Juergen Koch 371d20620deSHans-Juergen Koch i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, data->config); 372d20620deSHans-Juergen Koch 373d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 374d20620deSHans-Juergen Koch 375d20620deSHans-Juergen Koch return count; 376d20620deSHans-Juergen Koch } 377d20620deSHans-Juergen Koch 378d20620deSHans-Juergen Koch /* 379d20620deSHans-Juergen Koch * Read/write functions for fan1_div sysfs file. The MAX6650 has no such 380d20620deSHans-Juergen Koch * divider. We handle this by converting between divider and counttime: 381d20620deSHans-Juergen Koch * 382d20620deSHans-Juergen Koch * (counttime == k) <==> (divider == 2^k), k = 0, 1, 2, or 3 383d20620deSHans-Juergen Koch * 384d20620deSHans-Juergen Koch * Lower values of k allow to connect a faster fan without the risk of 385d20620deSHans-Juergen Koch * counter overflow. The price is lower resolution. You can also set counttime 386d20620deSHans-Juergen Koch * using the module parameter. Note that the module parameter "prescaler" also 387d20620deSHans-Juergen Koch * influences the behaviour. Unfortunately, there's no sysfs attribute 388d20620deSHans-Juergen Koch * defined for that. See the data sheet for details. 389d20620deSHans-Juergen Koch */ 390d20620deSHans-Juergen Koch 391d20620deSHans-Juergen Koch static ssize_t get_div(struct device *dev, struct device_attribute *devattr, 392d20620deSHans-Juergen Koch char *buf) 393d20620deSHans-Juergen Koch { 394d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 395d20620deSHans-Juergen Koch 396d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", DIV_FROM_REG(data->count)); 397d20620deSHans-Juergen Koch } 398d20620deSHans-Juergen Koch 399d20620deSHans-Juergen Koch static ssize_t set_div(struct device *dev, struct device_attribute *devattr, 400d20620deSHans-Juergen Koch const char *buf, size_t count) 401d20620deSHans-Juergen Koch { 402d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 403d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 404d20620deSHans-Juergen Koch int div = simple_strtoul(buf, NULL, 10); 405d20620deSHans-Juergen Koch 406d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 407d20620deSHans-Juergen Koch switch (div) { 408d20620deSHans-Juergen Koch case 1: 409d20620deSHans-Juergen Koch data->count = 0; 410d20620deSHans-Juergen Koch break; 411d20620deSHans-Juergen Koch case 2: 412d20620deSHans-Juergen Koch data->count = 1; 413d20620deSHans-Juergen Koch break; 414d20620deSHans-Juergen Koch case 4: 415d20620deSHans-Juergen Koch data->count = 2; 416d20620deSHans-Juergen Koch break; 417d20620deSHans-Juergen Koch case 8: 418d20620deSHans-Juergen Koch data->count = 3; 419d20620deSHans-Juergen Koch break; 420d20620deSHans-Juergen Koch default: 421025dc740SJiri Slaby mutex_unlock(&data->update_lock); 422d20620deSHans-Juergen Koch dev_err(&client->dev, 423d20620deSHans-Juergen Koch "illegal value for fan divider (%d)\n", div); 424d20620deSHans-Juergen Koch return -EINVAL; 425d20620deSHans-Juergen Koch } 426d20620deSHans-Juergen Koch 427d20620deSHans-Juergen Koch i2c_smbus_write_byte_data(client, MAX6650_REG_COUNT, data->count); 428d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 429d20620deSHans-Juergen Koch 430d20620deSHans-Juergen Koch return count; 431d20620deSHans-Juergen Koch } 432d20620deSHans-Juergen Koch 43352b5226fSChristian Engelmayer /* 43452b5226fSChristian Engelmayer * Get alarm stati: 43552b5226fSChristian Engelmayer * Possible values: 43652b5226fSChristian Engelmayer * 0 = no alarm 43752b5226fSChristian Engelmayer * 1 = alarm 43852b5226fSChristian Engelmayer */ 43952b5226fSChristian Engelmayer 44052b5226fSChristian Engelmayer static ssize_t get_alarm(struct device *dev, struct device_attribute *devattr, 44152b5226fSChristian Engelmayer char *buf) 44252b5226fSChristian Engelmayer { 44352b5226fSChristian Engelmayer struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 44452b5226fSChristian Engelmayer struct max6650_data *data = max6650_update_device(dev); 44552b5226fSChristian Engelmayer struct i2c_client *client = to_i2c_client(dev); 44652b5226fSChristian Engelmayer int alarm = 0; 44752b5226fSChristian Engelmayer 44852b5226fSChristian Engelmayer if (data->alarm & attr->index) { 44952b5226fSChristian Engelmayer mutex_lock(&data->update_lock); 45052b5226fSChristian Engelmayer alarm = 1; 45152b5226fSChristian Engelmayer data->alarm &= ~attr->index; 45252b5226fSChristian Engelmayer data->alarm |= i2c_smbus_read_byte_data(client, 45352b5226fSChristian Engelmayer MAX6650_REG_ALARM); 45452b5226fSChristian Engelmayer mutex_unlock(&data->update_lock); 45552b5226fSChristian Engelmayer } 45652b5226fSChristian Engelmayer 45752b5226fSChristian Engelmayer return sprintf(buf, "%d\n", alarm); 45852b5226fSChristian Engelmayer } 45952b5226fSChristian Engelmayer 460d20620deSHans-Juergen Koch static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); 461d20620deSHans-Juergen Koch static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); 462d20620deSHans-Juergen Koch static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); 463d20620deSHans-Juergen Koch static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, get_fan, NULL, 3); 464d20620deSHans-Juergen Koch static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target); 465d20620deSHans-Juergen Koch static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div); 466d20620deSHans-Juergen Koch static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable); 467d20620deSHans-Juergen Koch static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); 46852b5226fSChristian Engelmayer static SENSOR_DEVICE_ATTR(fan1_max_alarm, S_IRUGO, get_alarm, NULL, 46952b5226fSChristian Engelmayer MAX6650_ALRM_MAX); 47052b5226fSChristian Engelmayer static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, get_alarm, NULL, 47152b5226fSChristian Engelmayer MAX6650_ALRM_MIN); 47252b5226fSChristian Engelmayer static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_alarm, NULL, 47352b5226fSChristian Engelmayer MAX6650_ALRM_TACH); 47452b5226fSChristian Engelmayer static SENSOR_DEVICE_ATTR(gpio1_alarm, S_IRUGO, get_alarm, NULL, 47552b5226fSChristian Engelmayer MAX6650_ALRM_GPIO1); 47652b5226fSChristian Engelmayer static SENSOR_DEVICE_ATTR(gpio2_alarm, S_IRUGO, get_alarm, NULL, 47752b5226fSChristian Engelmayer MAX6650_ALRM_GPIO2); 478d20620deSHans-Juergen Koch 47952b5226fSChristian Engelmayer static mode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a, 48052b5226fSChristian Engelmayer int n) 48152b5226fSChristian Engelmayer { 48252b5226fSChristian Engelmayer struct device *dev = container_of(kobj, struct device, kobj); 48352b5226fSChristian Engelmayer struct i2c_client *client = to_i2c_client(dev); 48452b5226fSChristian Engelmayer u8 alarm_en = i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN); 48552b5226fSChristian Engelmayer struct device_attribute *devattr; 48652b5226fSChristian Engelmayer 48752b5226fSChristian Engelmayer /* 48852b5226fSChristian Engelmayer * Hide the alarms that have not been enabled by the firmware 48952b5226fSChristian Engelmayer */ 49052b5226fSChristian Engelmayer 49152b5226fSChristian Engelmayer devattr = container_of(a, struct device_attribute, attr); 49252b5226fSChristian Engelmayer if (devattr == &sensor_dev_attr_fan1_max_alarm.dev_attr 49352b5226fSChristian Engelmayer || devattr == &sensor_dev_attr_fan1_min_alarm.dev_attr 49452b5226fSChristian Engelmayer || devattr == &sensor_dev_attr_fan1_fault.dev_attr 49552b5226fSChristian Engelmayer || devattr == &sensor_dev_attr_gpio1_alarm.dev_attr 49652b5226fSChristian Engelmayer || devattr == &sensor_dev_attr_gpio2_alarm.dev_attr) { 49752b5226fSChristian Engelmayer if (!(alarm_en & to_sensor_dev_attr(devattr)->index)) 49852b5226fSChristian Engelmayer return 0; 49952b5226fSChristian Engelmayer } 50052b5226fSChristian Engelmayer 50152b5226fSChristian Engelmayer return a->mode; 50252b5226fSChristian Engelmayer } 503d20620deSHans-Juergen Koch 504d20620deSHans-Juergen Koch static struct attribute *max6650_attrs[] = { 505d20620deSHans-Juergen Koch &sensor_dev_attr_fan1_input.dev_attr.attr, 506d20620deSHans-Juergen Koch &sensor_dev_attr_fan2_input.dev_attr.attr, 507d20620deSHans-Juergen Koch &sensor_dev_attr_fan3_input.dev_attr.attr, 508d20620deSHans-Juergen Koch &sensor_dev_attr_fan4_input.dev_attr.attr, 509d20620deSHans-Juergen Koch &dev_attr_fan1_target.attr, 510d20620deSHans-Juergen Koch &dev_attr_fan1_div.attr, 511d20620deSHans-Juergen Koch &dev_attr_pwm1_enable.attr, 512d20620deSHans-Juergen Koch &dev_attr_pwm1.attr, 51352b5226fSChristian Engelmayer &sensor_dev_attr_fan1_max_alarm.dev_attr.attr, 51452b5226fSChristian Engelmayer &sensor_dev_attr_fan1_min_alarm.dev_attr.attr, 51552b5226fSChristian Engelmayer &sensor_dev_attr_fan1_fault.dev_attr.attr, 51652b5226fSChristian Engelmayer &sensor_dev_attr_gpio1_alarm.dev_attr.attr, 51752b5226fSChristian Engelmayer &sensor_dev_attr_gpio2_alarm.dev_attr.attr, 518d20620deSHans-Juergen Koch NULL 519d20620deSHans-Juergen Koch }; 520d20620deSHans-Juergen Koch 521d20620deSHans-Juergen Koch static struct attribute_group max6650_attr_grp = { 522d20620deSHans-Juergen Koch .attrs = max6650_attrs, 52352b5226fSChristian Engelmayer .is_visible = max6650_attrs_visible, 524d20620deSHans-Juergen Koch }; 525d20620deSHans-Juergen Koch 526d20620deSHans-Juergen Koch /* 527d20620deSHans-Juergen Koch * Real code 528d20620deSHans-Juergen Koch */ 529d20620deSHans-Juergen Koch 5300d57abd5SJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */ 5310d57abd5SJean Delvare static int max6650_detect(struct i2c_client *client, int kind, 5320d57abd5SJean Delvare struct i2c_board_info *info) 533d20620deSHans-Juergen Koch { 5340d57abd5SJean Delvare struct i2c_adapter *adapter = client->adapter; 5350d57abd5SJean Delvare int address = client->addr; 536d20620deSHans-Juergen Koch 537d20620deSHans-Juergen Koch dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind); 538d20620deSHans-Juergen Koch 539d20620deSHans-Juergen Koch if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 540d20620deSHans-Juergen Koch dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support " 541d20620deSHans-Juergen Koch "byte read mode, skipping.\n"); 5420d57abd5SJean Delvare return -ENODEV; 543d20620deSHans-Juergen Koch } 544d20620deSHans-Juergen Koch 545d20620deSHans-Juergen Koch /* 546d20620deSHans-Juergen Koch * Now we do the remaining detection. A negative kind means that 547d20620deSHans-Juergen Koch * the driver was loaded with no force parameter (default), so we 548d20620deSHans-Juergen Koch * must both detect and identify the chip (actually there is only 549d20620deSHans-Juergen Koch * one possible kind of chip for now, max6650). A zero kind means that 550d20620deSHans-Juergen Koch * the driver was loaded with the force parameter, the detection 551d20620deSHans-Juergen Koch * step shall be skipped. A positive kind means that the driver 552d20620deSHans-Juergen Koch * was loaded with the force parameter and a given kind of chip is 553d20620deSHans-Juergen Koch * requested, so both the detection and the identification steps 554d20620deSHans-Juergen Koch * are skipped. 555d20620deSHans-Juergen Koch * 556d20620deSHans-Juergen Koch * Currently I can find no way to distinguish between a MAX6650 and 557d20620deSHans-Juergen Koch * a MAX6651. This driver has only been tried on the former. 558d20620deSHans-Juergen Koch */ 559d20620deSHans-Juergen Koch 560d20620deSHans-Juergen Koch if ((kind < 0) && 561d20620deSHans-Juergen Koch ( (i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0) 562d20620deSHans-Juergen Koch ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0) 563d20620deSHans-Juergen Koch ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0) 564d20620deSHans-Juergen Koch ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0) 565d20620deSHans-Juergen Koch ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) { 566d20620deSHans-Juergen Koch dev_dbg(&adapter->dev, 567d20620deSHans-Juergen Koch "max6650: detection failed at 0x%02x.\n", address); 5680d57abd5SJean Delvare return -ENODEV; 569d20620deSHans-Juergen Koch } 570d20620deSHans-Juergen Koch 571d20620deSHans-Juergen Koch dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address); 572d20620deSHans-Juergen Koch 5730d57abd5SJean Delvare strlcpy(info->type, "max6650", I2C_NAME_SIZE); 574d20620deSHans-Juergen Koch 5750d57abd5SJean Delvare return 0; 576d20620deSHans-Juergen Koch } 577d20620deSHans-Juergen Koch 5780d57abd5SJean Delvare static int max6650_probe(struct i2c_client *client, 5790d57abd5SJean Delvare const struct i2c_device_id *id) 5800d57abd5SJean Delvare { 5810d57abd5SJean Delvare struct max6650_data *data; 5820d57abd5SJean Delvare int err; 5830d57abd5SJean Delvare 5840d57abd5SJean Delvare if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { 5850d57abd5SJean Delvare dev_err(&client->dev, "out of memory.\n"); 5860d57abd5SJean Delvare return -ENOMEM; 5870d57abd5SJean Delvare } 5880d57abd5SJean Delvare 5890d57abd5SJean Delvare i2c_set_clientdata(client, data); 5900d57abd5SJean Delvare mutex_init(&data->update_lock); 5910d57abd5SJean Delvare 592d20620deSHans-Juergen Koch /* 593d20620deSHans-Juergen Koch * Initialize the max6650 chip 594d20620deSHans-Juergen Koch */ 5950d57abd5SJean Delvare err = max6650_init_client(client); 5960d57abd5SJean Delvare if (err) 5970d57abd5SJean Delvare goto err_free; 598d20620deSHans-Juergen Koch 599d20620deSHans-Juergen Koch err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); 600d20620deSHans-Juergen Koch if (err) 6010d57abd5SJean Delvare goto err_free; 602d20620deSHans-Juergen Koch 6031beeffe4STony Jones data->hwmon_dev = hwmon_device_register(&client->dev); 6041beeffe4STony Jones if (!IS_ERR(data->hwmon_dev)) 605d20620deSHans-Juergen Koch return 0; 606d20620deSHans-Juergen Koch 6071beeffe4STony Jones err = PTR_ERR(data->hwmon_dev); 608d20620deSHans-Juergen Koch dev_err(&client->dev, "error registering hwmon device.\n"); 609d20620deSHans-Juergen Koch sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); 610d20620deSHans-Juergen Koch err_free: 611d20620deSHans-Juergen Koch kfree(data); 612d20620deSHans-Juergen Koch return err; 613d20620deSHans-Juergen Koch } 614d20620deSHans-Juergen Koch 6150d57abd5SJean Delvare static int max6650_remove(struct i2c_client *client) 616d20620deSHans-Juergen Koch { 617d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 618d20620deSHans-Juergen Koch 619d20620deSHans-Juergen Koch sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); 6201beeffe4STony Jones hwmon_device_unregister(data->hwmon_dev); 621d20620deSHans-Juergen Koch kfree(data); 6220d57abd5SJean Delvare return 0; 623d20620deSHans-Juergen Koch } 624d20620deSHans-Juergen Koch 625d20620deSHans-Juergen Koch static int max6650_init_client(struct i2c_client *client) 626d20620deSHans-Juergen Koch { 627d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 628d20620deSHans-Juergen Koch int config; 629d20620deSHans-Juergen Koch int err = -EIO; 630d20620deSHans-Juergen Koch 631d20620deSHans-Juergen Koch config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); 632d20620deSHans-Juergen Koch 633d20620deSHans-Juergen Koch if (config < 0) { 634d20620deSHans-Juergen Koch dev_err(&client->dev, "Error reading config, aborting.\n"); 635d20620deSHans-Juergen Koch return err; 636d20620deSHans-Juergen Koch } 637d20620deSHans-Juergen Koch 638d20620deSHans-Juergen Koch switch (fan_voltage) { 639d20620deSHans-Juergen Koch case 0: 640d20620deSHans-Juergen Koch break; 641d20620deSHans-Juergen Koch case 5: 642d20620deSHans-Juergen Koch config &= ~MAX6650_CFG_V12; 643d20620deSHans-Juergen Koch break; 644d20620deSHans-Juergen Koch case 12: 645d20620deSHans-Juergen Koch config |= MAX6650_CFG_V12; 646d20620deSHans-Juergen Koch break; 647d20620deSHans-Juergen Koch default: 648d20620deSHans-Juergen Koch dev_err(&client->dev, 649d20620deSHans-Juergen Koch "illegal value for fan_voltage (%d)\n", 650d20620deSHans-Juergen Koch fan_voltage); 651d20620deSHans-Juergen Koch } 652d20620deSHans-Juergen Koch 653d20620deSHans-Juergen Koch dev_info(&client->dev, "Fan voltage is set to %dV.\n", 654d20620deSHans-Juergen Koch (config & MAX6650_CFG_V12) ? 12 : 5); 655d20620deSHans-Juergen Koch 656d20620deSHans-Juergen Koch switch (prescaler) { 657d20620deSHans-Juergen Koch case 0: 658d20620deSHans-Juergen Koch break; 659d20620deSHans-Juergen Koch case 1: 660d20620deSHans-Juergen Koch config &= ~MAX6650_CFG_PRESCALER_MASK; 661d20620deSHans-Juergen Koch break; 662d20620deSHans-Juergen Koch case 2: 663d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_PRESCALER_MASK) 664d20620deSHans-Juergen Koch | MAX6650_CFG_PRESCALER_2; 665d20620deSHans-Juergen Koch break; 666d20620deSHans-Juergen Koch case 4: 667d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_PRESCALER_MASK) 668d20620deSHans-Juergen Koch | MAX6650_CFG_PRESCALER_4; 669d20620deSHans-Juergen Koch break; 670d20620deSHans-Juergen Koch case 8: 671d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_PRESCALER_MASK) 672d20620deSHans-Juergen Koch | MAX6650_CFG_PRESCALER_8; 673d20620deSHans-Juergen Koch break; 674d20620deSHans-Juergen Koch case 16: 675d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_PRESCALER_MASK) 676d20620deSHans-Juergen Koch | MAX6650_CFG_PRESCALER_16; 677d20620deSHans-Juergen Koch break; 678d20620deSHans-Juergen Koch default: 679d20620deSHans-Juergen Koch dev_err(&client->dev, 680d20620deSHans-Juergen Koch "illegal value for prescaler (%d)\n", 681d20620deSHans-Juergen Koch prescaler); 682d20620deSHans-Juergen Koch } 683d20620deSHans-Juergen Koch 684d20620deSHans-Juergen Koch dev_info(&client->dev, "Prescaler is set to %d.\n", 685d20620deSHans-Juergen Koch 1 << (config & MAX6650_CFG_PRESCALER_MASK)); 686d20620deSHans-Juergen Koch 687d20620deSHans-Juergen Koch /* If mode is set to "full off", we change it to "open loop" and 688d20620deSHans-Juergen Koch * set DAC to 255, which has the same effect. We do this because 689d20620deSHans-Juergen Koch * there's no "full off" mode defined in hwmon specifcations. 690d20620deSHans-Juergen Koch */ 691d20620deSHans-Juergen Koch 692d20620deSHans-Juergen Koch if ((config & MAX6650_CFG_MODE_MASK) == MAX6650_CFG_MODE_OFF) { 693d20620deSHans-Juergen Koch dev_dbg(&client->dev, "Change mode to open loop, full off.\n"); 694d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_MODE_MASK) 695d20620deSHans-Juergen Koch | MAX6650_CFG_MODE_OPEN_LOOP; 696d20620deSHans-Juergen Koch if (i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, 255)) { 697d20620deSHans-Juergen Koch dev_err(&client->dev, "DAC write error, aborting.\n"); 698d20620deSHans-Juergen Koch return err; 699d20620deSHans-Juergen Koch } 700d20620deSHans-Juergen Koch } 701d20620deSHans-Juergen Koch 702d20620deSHans-Juergen Koch if (i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, config)) { 703d20620deSHans-Juergen Koch dev_err(&client->dev, "Config write error, aborting.\n"); 704d20620deSHans-Juergen Koch return err; 705d20620deSHans-Juergen Koch } 706d20620deSHans-Juergen Koch 707d20620deSHans-Juergen Koch data->config = config; 708d20620deSHans-Juergen Koch data->count = i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT); 709d20620deSHans-Juergen Koch 710d20620deSHans-Juergen Koch return 0; 711d20620deSHans-Juergen Koch } 712d20620deSHans-Juergen Koch 713d20620deSHans-Juergen Koch static const u8 tach_reg[] = { 714d20620deSHans-Juergen Koch MAX6650_REG_TACH0, 715d20620deSHans-Juergen Koch MAX6650_REG_TACH1, 716d20620deSHans-Juergen Koch MAX6650_REG_TACH2, 717d20620deSHans-Juergen Koch MAX6650_REG_TACH3, 718d20620deSHans-Juergen Koch }; 719d20620deSHans-Juergen Koch 720d20620deSHans-Juergen Koch static struct max6650_data *max6650_update_device(struct device *dev) 721d20620deSHans-Juergen Koch { 722d20620deSHans-Juergen Koch int i; 723d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 724d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 725d20620deSHans-Juergen Koch 726d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 727d20620deSHans-Juergen Koch 728d20620deSHans-Juergen Koch if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { 729d20620deSHans-Juergen Koch data->speed = i2c_smbus_read_byte_data(client, 730d20620deSHans-Juergen Koch MAX6650_REG_SPEED); 731d20620deSHans-Juergen Koch data->config = i2c_smbus_read_byte_data(client, 732d20620deSHans-Juergen Koch MAX6650_REG_CONFIG); 733d20620deSHans-Juergen Koch for (i = 0; i < 4; i++) { 734d20620deSHans-Juergen Koch data->tach[i] = i2c_smbus_read_byte_data(client, 735d20620deSHans-Juergen Koch tach_reg[i]); 736d20620deSHans-Juergen Koch } 737d20620deSHans-Juergen Koch data->count = i2c_smbus_read_byte_data(client, 738d20620deSHans-Juergen Koch MAX6650_REG_COUNT); 739d20620deSHans-Juergen Koch data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); 740d20620deSHans-Juergen Koch 74152b5226fSChristian Engelmayer /* Alarms are cleared on read in case the condition that 74252b5226fSChristian Engelmayer * caused the alarm is removed. Keep the value latched here 74352b5226fSChristian Engelmayer * for providing the register through different alarm files. */ 74452b5226fSChristian Engelmayer data->alarm |= i2c_smbus_read_byte_data(client, 74552b5226fSChristian Engelmayer MAX6650_REG_ALARM); 74652b5226fSChristian Engelmayer 747d20620deSHans-Juergen Koch data->last_updated = jiffies; 748d20620deSHans-Juergen Koch data->valid = 1; 749d20620deSHans-Juergen Koch } 750d20620deSHans-Juergen Koch 751d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 752d20620deSHans-Juergen Koch 753d20620deSHans-Juergen Koch return data; 754d20620deSHans-Juergen Koch } 755d20620deSHans-Juergen Koch 756d20620deSHans-Juergen Koch static int __init sensors_max6650_init(void) 757d20620deSHans-Juergen Koch { 758d20620deSHans-Juergen Koch return i2c_add_driver(&max6650_driver); 759d20620deSHans-Juergen Koch } 760d20620deSHans-Juergen Koch 761d20620deSHans-Juergen Koch static void __exit sensors_max6650_exit(void) 762d20620deSHans-Juergen Koch { 763d20620deSHans-Juergen Koch i2c_del_driver(&max6650_driver); 764d20620deSHans-Juergen Koch } 765d20620deSHans-Juergen Koch 766d20620deSHans-Juergen Koch MODULE_AUTHOR("Hans J. Koch"); 767d20620deSHans-Juergen Koch MODULE_DESCRIPTION("MAX6650 sensor driver"); 768d20620deSHans-Juergen Koch MODULE_LICENSE("GPL"); 769d20620deSHans-Juergen Koch 770d20620deSHans-Juergen Koch module_init(sensors_max6650_init); 771d20620deSHans-Juergen Koch module_exit(sensors_max6650_exit); 772