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 * 15d20620deSHans-Juergen Koch * Tha 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 47d20620deSHans-Juergen Koch static unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, I2C_CLIENT_END}; 48d20620deSHans-Juergen Koch 49d20620deSHans-Juergen Koch /* 50d20620deSHans-Juergen Koch * Insmod parameters 51d20620deSHans-Juergen Koch */ 52d20620deSHans-Juergen Koch 53d20620deSHans-Juergen Koch /* fan_voltage: 5=5V fan, 12=12V fan, 0=don't change */ 54d20620deSHans-Juergen Koch static int fan_voltage; 55d20620deSHans-Juergen Koch /* prescaler: Possible values are 1, 2, 4, 8, 16 or 0 for don't change */ 56d20620deSHans-Juergen Koch static int prescaler; 57d20620deSHans-Juergen Koch /* clock: The clock frequency of the chip the driver should assume */ 58d20620deSHans-Juergen Koch static int clock = 254000; 59d20620deSHans-Juergen Koch 60d20620deSHans-Juergen Koch module_param(fan_voltage, int, S_IRUGO); 61d20620deSHans-Juergen Koch module_param(prescaler, int, S_IRUGO); 62d20620deSHans-Juergen Koch module_param(clock, int, S_IRUGO); 63d20620deSHans-Juergen Koch 64d20620deSHans-Juergen Koch I2C_CLIENT_INSMOD_1(max6650); 65d20620deSHans-Juergen Koch 66d20620deSHans-Juergen Koch /* 67d20620deSHans-Juergen Koch * MAX 6650/6651 registers 68d20620deSHans-Juergen Koch */ 69d20620deSHans-Juergen Koch 70d20620deSHans-Juergen Koch #define MAX6650_REG_SPEED 0x00 71d20620deSHans-Juergen Koch #define MAX6650_REG_CONFIG 0x02 72d20620deSHans-Juergen Koch #define MAX6650_REG_GPIO_DEF 0x04 73d20620deSHans-Juergen Koch #define MAX6650_REG_DAC 0x06 74d20620deSHans-Juergen Koch #define MAX6650_REG_ALARM_EN 0x08 75d20620deSHans-Juergen Koch #define MAX6650_REG_ALARM 0x0A 76d20620deSHans-Juergen Koch #define MAX6650_REG_TACH0 0x0C 77d20620deSHans-Juergen Koch #define MAX6650_REG_TACH1 0x0E 78d20620deSHans-Juergen Koch #define MAX6650_REG_TACH2 0x10 79d20620deSHans-Juergen Koch #define MAX6650_REG_TACH3 0x12 80d20620deSHans-Juergen Koch #define MAX6650_REG_GPIO_STAT 0x14 81d20620deSHans-Juergen Koch #define MAX6650_REG_COUNT 0x16 82d20620deSHans-Juergen Koch 83d20620deSHans-Juergen Koch /* 84d20620deSHans-Juergen Koch * Config register bits 85d20620deSHans-Juergen Koch */ 86d20620deSHans-Juergen Koch 87d20620deSHans-Juergen Koch #define MAX6650_CFG_V12 0x08 88d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_MASK 0x07 89d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_2 0x01 90d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_4 0x02 91d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_8 0x03 92d20620deSHans-Juergen Koch #define MAX6650_CFG_PRESCALER_16 0x04 93d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_MASK 0x30 94d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_ON 0x00 95d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_OFF 0x10 96d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_CLOSED_LOOP 0x20 97d20620deSHans-Juergen Koch #define MAX6650_CFG_MODE_OPEN_LOOP 0x30 98d20620deSHans-Juergen Koch #define MAX6650_COUNT_MASK 0x03 99d20620deSHans-Juergen Koch 100d20620deSHans-Juergen Koch /* Minimum and maximum values of the FAN-RPM */ 101d20620deSHans-Juergen Koch #define FAN_RPM_MIN 240 102d20620deSHans-Juergen Koch #define FAN_RPM_MAX 30000 103d20620deSHans-Juergen Koch 104d20620deSHans-Juergen Koch #define DIV_FROM_REG(reg) (1 << (reg & 7)) 105d20620deSHans-Juergen Koch 106d20620deSHans-Juergen Koch static int max6650_attach_adapter(struct i2c_adapter *adapter); 107d20620deSHans-Juergen Koch static int max6650_detect(struct i2c_adapter *adapter, int address, int kind); 108d20620deSHans-Juergen Koch static int max6650_init_client(struct i2c_client *client); 109d20620deSHans-Juergen Koch static int max6650_detach_client(struct i2c_client *client); 110d20620deSHans-Juergen Koch static struct max6650_data *max6650_update_device(struct device *dev); 111d20620deSHans-Juergen Koch 112d20620deSHans-Juergen Koch /* 113d20620deSHans-Juergen Koch * Driver data (common to all clients) 114d20620deSHans-Juergen Koch */ 115d20620deSHans-Juergen Koch 116d20620deSHans-Juergen Koch static struct i2c_driver max6650_driver = { 117d20620deSHans-Juergen Koch .driver = { 118d20620deSHans-Juergen Koch .name = "max6650", 119d20620deSHans-Juergen Koch }, 120d20620deSHans-Juergen Koch .attach_adapter = max6650_attach_adapter, 121d20620deSHans-Juergen Koch .detach_client = max6650_detach_client, 122d20620deSHans-Juergen Koch }; 123d20620deSHans-Juergen Koch 124d20620deSHans-Juergen Koch /* 125d20620deSHans-Juergen Koch * Client data (each client gets its own) 126d20620deSHans-Juergen Koch */ 127d20620deSHans-Juergen Koch 128d20620deSHans-Juergen Koch struct max6650_data 129d20620deSHans-Juergen Koch { 130d20620deSHans-Juergen Koch struct i2c_client client; 1311beeffe4STony Jones struct device *hwmon_dev; 132d20620deSHans-Juergen Koch struct mutex update_lock; 133d20620deSHans-Juergen Koch char valid; /* zero until following fields are valid */ 134d20620deSHans-Juergen Koch unsigned long last_updated; /* in jiffies */ 135d20620deSHans-Juergen Koch 136d20620deSHans-Juergen Koch /* register values */ 137d20620deSHans-Juergen Koch u8 speed; 138d20620deSHans-Juergen Koch u8 config; 139d20620deSHans-Juergen Koch u8 tach[4]; 140d20620deSHans-Juergen Koch u8 count; 141d20620deSHans-Juergen Koch u8 dac; 142d20620deSHans-Juergen Koch }; 143d20620deSHans-Juergen Koch 144d20620deSHans-Juergen Koch static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, 145d20620deSHans-Juergen Koch char *buf) 146d20620deSHans-Juergen Koch { 147d20620deSHans-Juergen Koch struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 148d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 149d20620deSHans-Juergen Koch int rpm; 150d20620deSHans-Juergen Koch 151d20620deSHans-Juergen Koch /* 152d20620deSHans-Juergen Koch * Calculation details: 153d20620deSHans-Juergen Koch * 154d20620deSHans-Juergen Koch * Each tachometer counts over an interval given by the "count" 155d20620deSHans-Juergen Koch * register (0.25, 0.5, 1 or 2 seconds). This module assumes 156d20620deSHans-Juergen Koch * that the fans produce two pulses per revolution (this seems 157d20620deSHans-Juergen Koch * to be the most common). 158d20620deSHans-Juergen Koch */ 159d20620deSHans-Juergen Koch 160d20620deSHans-Juergen Koch rpm = ((data->tach[attr->index] * 120) / DIV_FROM_REG(data->count)); 161d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", rpm); 162d20620deSHans-Juergen Koch } 163d20620deSHans-Juergen Koch 164d20620deSHans-Juergen Koch /* 165d20620deSHans-Juergen Koch * Set the fan speed to the specified RPM (or read back the RPM setting). 166d20620deSHans-Juergen Koch * This works in closed loop mode only. Use pwm1 for open loop speed setting. 167d20620deSHans-Juergen Koch * 168d20620deSHans-Juergen Koch * The MAX6650/1 will automatically control fan speed when in closed loop 169d20620deSHans-Juergen Koch * mode. 170d20620deSHans-Juergen Koch * 171d20620deSHans-Juergen Koch * Assumptions: 172d20620deSHans-Juergen Koch * 173d20620deSHans-Juergen Koch * 1) The MAX6650/1 internal 254kHz clock frequency is set correctly. Use 174d20620deSHans-Juergen Koch * the clock module parameter if you need to fine tune this. 175d20620deSHans-Juergen Koch * 176d20620deSHans-Juergen Koch * 2) The prescaler (low three bits of the config register) has already 177d20620deSHans-Juergen Koch * been set to an appropriate value. Use the prescaler module parameter 178d20620deSHans-Juergen Koch * if your BIOS doesn't initialize the chip properly. 179d20620deSHans-Juergen Koch * 180d20620deSHans-Juergen Koch * The relevant equations are given on pages 21 and 22 of the datasheet. 181d20620deSHans-Juergen Koch * 182d20620deSHans-Juergen Koch * From the datasheet, the relevant equation when in regulation is: 183d20620deSHans-Juergen Koch * 184d20620deSHans-Juergen Koch * [fCLK / (128 x (KTACH + 1))] = 2 x FanSpeed / KSCALE 185d20620deSHans-Juergen Koch * 186d20620deSHans-Juergen Koch * where: 187d20620deSHans-Juergen Koch * 188d20620deSHans-Juergen Koch * fCLK is the oscillator frequency (either the 254kHz internal 189d20620deSHans-Juergen Koch * oscillator or the externally applied clock) 190d20620deSHans-Juergen Koch * 191d20620deSHans-Juergen Koch * KTACH is the value in the speed register 192d20620deSHans-Juergen Koch * 193d20620deSHans-Juergen Koch * FanSpeed is the speed of the fan in rps 194d20620deSHans-Juergen Koch * 195d20620deSHans-Juergen Koch * KSCALE is the prescaler value (1, 2, 4, 8, or 16) 196d20620deSHans-Juergen Koch * 197d20620deSHans-Juergen Koch * When reading, we need to solve for FanSpeed. When writing, we need to 198d20620deSHans-Juergen Koch * solve for KTACH. 199d20620deSHans-Juergen Koch * 200d20620deSHans-Juergen Koch * Note: this tachometer is completely separate from the tachometers 201d20620deSHans-Juergen Koch * used to measure the fan speeds. Only one fan's speed (fan1) is 202d20620deSHans-Juergen Koch * controlled. 203d20620deSHans-Juergen Koch */ 204d20620deSHans-Juergen Koch 205d20620deSHans-Juergen Koch static ssize_t get_target(struct device *dev, struct device_attribute *devattr, 206d20620deSHans-Juergen Koch char *buf) 207d20620deSHans-Juergen Koch { 208d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 209d20620deSHans-Juergen Koch int kscale, ktach, rpm; 210d20620deSHans-Juergen Koch 211d20620deSHans-Juergen Koch /* 212d20620deSHans-Juergen Koch * Use the datasheet equation: 213d20620deSHans-Juergen Koch * 214d20620deSHans-Juergen Koch * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] 215d20620deSHans-Juergen Koch * 216d20620deSHans-Juergen Koch * then multiply by 60 to give rpm. 217d20620deSHans-Juergen Koch */ 218d20620deSHans-Juergen Koch 219d20620deSHans-Juergen Koch kscale = DIV_FROM_REG(data->config); 220d20620deSHans-Juergen Koch ktach = data->speed; 221d20620deSHans-Juergen Koch rpm = 60 * kscale * clock / (256 * (ktach + 1)); 222d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", rpm); 223d20620deSHans-Juergen Koch } 224d20620deSHans-Juergen Koch 225d20620deSHans-Juergen Koch static ssize_t set_target(struct device *dev, struct device_attribute *devattr, 226d20620deSHans-Juergen Koch const char *buf, size_t count) 227d20620deSHans-Juergen Koch { 228d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 229d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 230d20620deSHans-Juergen Koch int rpm = simple_strtoul(buf, NULL, 10); 231d20620deSHans-Juergen Koch int kscale, ktach; 232d20620deSHans-Juergen Koch 233d20620deSHans-Juergen Koch rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); 234d20620deSHans-Juergen Koch 235d20620deSHans-Juergen Koch /* 236d20620deSHans-Juergen Koch * Divide the required speed by 60 to get from rpm to rps, then 237d20620deSHans-Juergen Koch * use the datasheet equation: 238d20620deSHans-Juergen Koch * 239d20620deSHans-Juergen Koch * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 240d20620deSHans-Juergen Koch */ 241d20620deSHans-Juergen Koch 242d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 243d20620deSHans-Juergen Koch 244d20620deSHans-Juergen Koch kscale = DIV_FROM_REG(data->config); 245d20620deSHans-Juergen Koch ktach = ((clock * kscale) / (256 * rpm / 60)) - 1; 246d20620deSHans-Juergen Koch if (ktach < 0) 247d20620deSHans-Juergen Koch ktach = 0; 248d20620deSHans-Juergen Koch if (ktach > 255) 249d20620deSHans-Juergen Koch ktach = 255; 250d20620deSHans-Juergen Koch data->speed = ktach; 251d20620deSHans-Juergen Koch 252d20620deSHans-Juergen Koch i2c_smbus_write_byte_data(client, MAX6650_REG_SPEED, data->speed); 253d20620deSHans-Juergen Koch 254d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 255d20620deSHans-Juergen Koch 256d20620deSHans-Juergen Koch return count; 257d20620deSHans-Juergen Koch } 258d20620deSHans-Juergen Koch 259d20620deSHans-Juergen Koch /* 260d20620deSHans-Juergen Koch * Get/set the fan speed in open loop mode using pwm1 sysfs file. 261d20620deSHans-Juergen Koch * Speed is given as a relative value from 0 to 255, where 255 is maximum 262d20620deSHans-Juergen Koch * speed. Note that this is done by writing directly to the chip's DAC, 263d20620deSHans-Juergen Koch * it won't change the closed loop speed set by fan1_target. 264d20620deSHans-Juergen Koch * Also note that due to rounding errors it is possible that you don't read 265d20620deSHans-Juergen Koch * back exactly the value you have set. 266d20620deSHans-Juergen Koch */ 267d20620deSHans-Juergen Koch 268d20620deSHans-Juergen Koch static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, 269d20620deSHans-Juergen Koch char *buf) 270d20620deSHans-Juergen Koch { 271d20620deSHans-Juergen Koch int pwm; 272d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 273d20620deSHans-Juergen Koch 274d20620deSHans-Juergen Koch /* Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. 275d20620deSHans-Juergen Koch Lower DAC values mean higher speeds. */ 276d20620deSHans-Juergen Koch if (data->config & MAX6650_CFG_V12) 277d20620deSHans-Juergen Koch pwm = 255 - (255 * (int)data->dac)/180; 278d20620deSHans-Juergen Koch else 279d20620deSHans-Juergen Koch pwm = 255 - (255 * (int)data->dac)/76; 280d20620deSHans-Juergen Koch 281d20620deSHans-Juergen Koch if (pwm < 0) 282d20620deSHans-Juergen Koch pwm = 0; 283d20620deSHans-Juergen Koch 284d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", pwm); 285d20620deSHans-Juergen Koch } 286d20620deSHans-Juergen Koch 287d20620deSHans-Juergen Koch static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, 288d20620deSHans-Juergen Koch const char *buf, size_t count) 289d20620deSHans-Juergen Koch { 290d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 291d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 292d20620deSHans-Juergen Koch int pwm = simple_strtoul(buf, NULL, 10); 293d20620deSHans-Juergen Koch 294d20620deSHans-Juergen Koch pwm = SENSORS_LIMIT(pwm, 0, 255); 295d20620deSHans-Juergen Koch 296d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 297d20620deSHans-Juergen Koch 298d20620deSHans-Juergen Koch if (data->config & MAX6650_CFG_V12) 299d20620deSHans-Juergen Koch data->dac = 180 - (180 * pwm)/255; 300d20620deSHans-Juergen Koch else 301d20620deSHans-Juergen Koch data->dac = 76 - (76 * pwm)/255; 302d20620deSHans-Juergen Koch 303d20620deSHans-Juergen Koch i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac); 304d20620deSHans-Juergen Koch 305d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 306d20620deSHans-Juergen Koch 307d20620deSHans-Juergen Koch return count; 308d20620deSHans-Juergen Koch } 309d20620deSHans-Juergen Koch 310d20620deSHans-Juergen Koch /* 311d20620deSHans-Juergen Koch * Get/Set controller mode: 312d20620deSHans-Juergen Koch * Possible values: 313d20620deSHans-Juergen Koch * 0 = Fan always on 314d20620deSHans-Juergen Koch * 1 = Open loop, Voltage is set according to speed, not regulated. 315d20620deSHans-Juergen Koch * 2 = Closed loop, RPM for all fans regulated by fan1 tachometer 316d20620deSHans-Juergen Koch */ 317d20620deSHans-Juergen Koch 318d20620deSHans-Juergen Koch static ssize_t get_enable(struct device *dev, struct device_attribute *devattr, 319d20620deSHans-Juergen Koch char *buf) 320d20620deSHans-Juergen Koch { 321d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 322d20620deSHans-Juergen Koch int mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4; 323d20620deSHans-Juergen Koch int sysfs_modes[4] = {0, 1, 2, 1}; 324d20620deSHans-Juergen Koch 325d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", sysfs_modes[mode]); 326d20620deSHans-Juergen Koch } 327d20620deSHans-Juergen Koch 328d20620deSHans-Juergen Koch static ssize_t set_enable(struct device *dev, struct device_attribute *devattr, 329d20620deSHans-Juergen Koch const char *buf, size_t count) 330d20620deSHans-Juergen Koch { 331d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 332d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 333d20620deSHans-Juergen Koch int mode = simple_strtoul(buf, NULL, 10); 334d20620deSHans-Juergen Koch int max6650_modes[3] = {0, 3, 2}; 335d20620deSHans-Juergen Koch 336d20620deSHans-Juergen Koch if ((mode < 0)||(mode > 2)) { 337d20620deSHans-Juergen Koch dev_err(&client->dev, 338d20620deSHans-Juergen Koch "illegal value for pwm1_enable (%d)\n", mode); 339d20620deSHans-Juergen Koch return -EINVAL; 340d20620deSHans-Juergen Koch } 341d20620deSHans-Juergen Koch 342d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 343d20620deSHans-Juergen Koch 344d20620deSHans-Juergen Koch data->config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); 345d20620deSHans-Juergen Koch data->config = (data->config & ~MAX6650_CFG_MODE_MASK) 346d20620deSHans-Juergen Koch | (max6650_modes[mode] << 4); 347d20620deSHans-Juergen Koch 348d20620deSHans-Juergen Koch i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, data->config); 349d20620deSHans-Juergen Koch 350d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 351d20620deSHans-Juergen Koch 352d20620deSHans-Juergen Koch return count; 353d20620deSHans-Juergen Koch } 354d20620deSHans-Juergen Koch 355d20620deSHans-Juergen Koch /* 356d20620deSHans-Juergen Koch * Read/write functions for fan1_div sysfs file. The MAX6650 has no such 357d20620deSHans-Juergen Koch * divider. We handle this by converting between divider and counttime: 358d20620deSHans-Juergen Koch * 359d20620deSHans-Juergen Koch * (counttime == k) <==> (divider == 2^k), k = 0, 1, 2, or 3 360d20620deSHans-Juergen Koch * 361d20620deSHans-Juergen Koch * Lower values of k allow to connect a faster fan without the risk of 362d20620deSHans-Juergen Koch * counter overflow. The price is lower resolution. You can also set counttime 363d20620deSHans-Juergen Koch * using the module parameter. Note that the module parameter "prescaler" also 364d20620deSHans-Juergen Koch * influences the behaviour. Unfortunately, there's no sysfs attribute 365d20620deSHans-Juergen Koch * defined for that. See the data sheet for details. 366d20620deSHans-Juergen Koch */ 367d20620deSHans-Juergen Koch 368d20620deSHans-Juergen Koch static ssize_t get_div(struct device *dev, struct device_attribute *devattr, 369d20620deSHans-Juergen Koch char *buf) 370d20620deSHans-Juergen Koch { 371d20620deSHans-Juergen Koch struct max6650_data *data = max6650_update_device(dev); 372d20620deSHans-Juergen Koch 373d20620deSHans-Juergen Koch return sprintf(buf, "%d\n", DIV_FROM_REG(data->count)); 374d20620deSHans-Juergen Koch } 375d20620deSHans-Juergen Koch 376d20620deSHans-Juergen Koch static ssize_t set_div(struct device *dev, struct device_attribute *devattr, 377d20620deSHans-Juergen Koch const char *buf, size_t count) 378d20620deSHans-Juergen Koch { 379d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 380d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 381d20620deSHans-Juergen Koch int div = simple_strtoul(buf, NULL, 10); 382d20620deSHans-Juergen Koch 383d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 384d20620deSHans-Juergen Koch switch (div) { 385d20620deSHans-Juergen Koch case 1: 386d20620deSHans-Juergen Koch data->count = 0; 387d20620deSHans-Juergen Koch break; 388d20620deSHans-Juergen Koch case 2: 389d20620deSHans-Juergen Koch data->count = 1; 390d20620deSHans-Juergen Koch break; 391d20620deSHans-Juergen Koch case 4: 392d20620deSHans-Juergen Koch data->count = 2; 393d20620deSHans-Juergen Koch break; 394d20620deSHans-Juergen Koch case 8: 395d20620deSHans-Juergen Koch data->count = 3; 396d20620deSHans-Juergen Koch break; 397d20620deSHans-Juergen Koch default: 398d20620deSHans-Juergen Koch dev_err(&client->dev, 399d20620deSHans-Juergen Koch "illegal value for fan divider (%d)\n", div); 400d20620deSHans-Juergen Koch return -EINVAL; 401d20620deSHans-Juergen Koch } 402d20620deSHans-Juergen Koch 403d20620deSHans-Juergen Koch i2c_smbus_write_byte_data(client, MAX6650_REG_COUNT, data->count); 404d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 405d20620deSHans-Juergen Koch 406d20620deSHans-Juergen Koch return count; 407d20620deSHans-Juergen Koch } 408d20620deSHans-Juergen Koch 409d20620deSHans-Juergen Koch static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); 410d20620deSHans-Juergen Koch static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); 411d20620deSHans-Juergen Koch static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); 412d20620deSHans-Juergen Koch static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, get_fan, NULL, 3); 413d20620deSHans-Juergen Koch static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target); 414d20620deSHans-Juergen Koch static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div); 415d20620deSHans-Juergen Koch static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable); 416d20620deSHans-Juergen Koch static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); 417d20620deSHans-Juergen Koch 418d20620deSHans-Juergen Koch 419d20620deSHans-Juergen Koch static struct attribute *max6650_attrs[] = { 420d20620deSHans-Juergen Koch &sensor_dev_attr_fan1_input.dev_attr.attr, 421d20620deSHans-Juergen Koch &sensor_dev_attr_fan2_input.dev_attr.attr, 422d20620deSHans-Juergen Koch &sensor_dev_attr_fan3_input.dev_attr.attr, 423d20620deSHans-Juergen Koch &sensor_dev_attr_fan4_input.dev_attr.attr, 424d20620deSHans-Juergen Koch &dev_attr_fan1_target.attr, 425d20620deSHans-Juergen Koch &dev_attr_fan1_div.attr, 426d20620deSHans-Juergen Koch &dev_attr_pwm1_enable.attr, 427d20620deSHans-Juergen Koch &dev_attr_pwm1.attr, 428d20620deSHans-Juergen Koch NULL 429d20620deSHans-Juergen Koch }; 430d20620deSHans-Juergen Koch 431d20620deSHans-Juergen Koch static struct attribute_group max6650_attr_grp = { 432d20620deSHans-Juergen Koch .attrs = max6650_attrs, 433d20620deSHans-Juergen Koch }; 434d20620deSHans-Juergen Koch 435d20620deSHans-Juergen Koch /* 436d20620deSHans-Juergen Koch * Real code 437d20620deSHans-Juergen Koch */ 438d20620deSHans-Juergen Koch 439d20620deSHans-Juergen Koch static int max6650_attach_adapter(struct i2c_adapter *adapter) 440d20620deSHans-Juergen Koch { 441d20620deSHans-Juergen Koch if (!(adapter->class & I2C_CLASS_HWMON)) { 442d20620deSHans-Juergen Koch dev_dbg(&adapter->dev, 443d20620deSHans-Juergen Koch "FATAL: max6650_attach_adapter class HWMON not set\n"); 444d20620deSHans-Juergen Koch return 0; 445d20620deSHans-Juergen Koch } 446d20620deSHans-Juergen Koch 447d20620deSHans-Juergen Koch return i2c_probe(adapter, &addr_data, max6650_detect); 448d20620deSHans-Juergen Koch } 449d20620deSHans-Juergen Koch 450d20620deSHans-Juergen Koch /* 451d20620deSHans-Juergen Koch * The following function does more than just detection. If detection 452d20620deSHans-Juergen Koch * succeeds, it also registers the new chip. 453d20620deSHans-Juergen Koch */ 454d20620deSHans-Juergen Koch 455d20620deSHans-Juergen Koch static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) 456d20620deSHans-Juergen Koch { 457d20620deSHans-Juergen Koch struct i2c_client *client; 458d20620deSHans-Juergen Koch struct max6650_data *data; 459d20620deSHans-Juergen Koch int err = -ENODEV; 460d20620deSHans-Juergen Koch 461d20620deSHans-Juergen Koch dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind); 462d20620deSHans-Juergen Koch 463d20620deSHans-Juergen Koch if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 464d20620deSHans-Juergen Koch dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support " 465d20620deSHans-Juergen Koch "byte read mode, skipping.\n"); 466d20620deSHans-Juergen Koch return 0; 467d20620deSHans-Juergen Koch } 468d20620deSHans-Juergen Koch 469d20620deSHans-Juergen Koch if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { 470d20620deSHans-Juergen Koch dev_err(&adapter->dev, "max6650: out of memory.\n"); 471d20620deSHans-Juergen Koch return -ENOMEM; 472d20620deSHans-Juergen Koch } 473d20620deSHans-Juergen Koch 474d20620deSHans-Juergen Koch client = &data->client; 475d20620deSHans-Juergen Koch i2c_set_clientdata(client, data); 476d20620deSHans-Juergen Koch client->addr = address; 477d20620deSHans-Juergen Koch client->adapter = adapter; 478d20620deSHans-Juergen Koch client->driver = &max6650_driver; 479d20620deSHans-Juergen Koch 480d20620deSHans-Juergen Koch /* 481d20620deSHans-Juergen Koch * Now we do the remaining detection. A negative kind means that 482d20620deSHans-Juergen Koch * the driver was loaded with no force parameter (default), so we 483d20620deSHans-Juergen Koch * must both detect and identify the chip (actually there is only 484d20620deSHans-Juergen Koch * one possible kind of chip for now, max6650). A zero kind means that 485d20620deSHans-Juergen Koch * the driver was loaded with the force parameter, the detection 486d20620deSHans-Juergen Koch * step shall be skipped. A positive kind means that the driver 487d20620deSHans-Juergen Koch * was loaded with the force parameter and a given kind of chip is 488d20620deSHans-Juergen Koch * requested, so both the detection and the identification steps 489d20620deSHans-Juergen Koch * are skipped. 490d20620deSHans-Juergen Koch * 491d20620deSHans-Juergen Koch * Currently I can find no way to distinguish between a MAX6650 and 492d20620deSHans-Juergen Koch * a MAX6651. This driver has only been tried on the former. 493d20620deSHans-Juergen Koch */ 494d20620deSHans-Juergen Koch 495d20620deSHans-Juergen Koch if ((kind < 0) && 496d20620deSHans-Juergen Koch ( (i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0) 497d20620deSHans-Juergen Koch ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0) 498d20620deSHans-Juergen Koch ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0) 499d20620deSHans-Juergen Koch ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0) 500d20620deSHans-Juergen Koch ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) { 501d20620deSHans-Juergen Koch dev_dbg(&adapter->dev, 502d20620deSHans-Juergen Koch "max6650: detection failed at 0x%02x.\n", address); 503d20620deSHans-Juergen Koch goto err_free; 504d20620deSHans-Juergen Koch } 505d20620deSHans-Juergen Koch 506d20620deSHans-Juergen Koch dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address); 507d20620deSHans-Juergen Koch 508d20620deSHans-Juergen Koch strlcpy(client->name, "max6650", I2C_NAME_SIZE); 509d20620deSHans-Juergen Koch mutex_init(&data->update_lock); 510d20620deSHans-Juergen Koch 511d20620deSHans-Juergen Koch if ((err = i2c_attach_client(client))) { 512d20620deSHans-Juergen Koch dev_err(&adapter->dev, "max6650: failed to attach client.\n"); 513d20620deSHans-Juergen Koch goto err_free; 514d20620deSHans-Juergen Koch } 515d20620deSHans-Juergen Koch 516d20620deSHans-Juergen Koch /* 517d20620deSHans-Juergen Koch * Initialize the max6650 chip 518d20620deSHans-Juergen Koch */ 519d20620deSHans-Juergen Koch if (max6650_init_client(client)) 520d20620deSHans-Juergen Koch goto err_detach; 521d20620deSHans-Juergen Koch 522d20620deSHans-Juergen Koch err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); 523d20620deSHans-Juergen Koch if (err) 524d20620deSHans-Juergen Koch goto err_detach; 525d20620deSHans-Juergen Koch 5261beeffe4STony Jones data->hwmon_dev = hwmon_device_register(&client->dev); 5271beeffe4STony Jones if (!IS_ERR(data->hwmon_dev)) 528d20620deSHans-Juergen Koch return 0; 529d20620deSHans-Juergen Koch 5301beeffe4STony Jones err = PTR_ERR(data->hwmon_dev); 531d20620deSHans-Juergen Koch dev_err(&client->dev, "error registering hwmon device.\n"); 532d20620deSHans-Juergen Koch sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); 533d20620deSHans-Juergen Koch err_detach: 534d20620deSHans-Juergen Koch i2c_detach_client(client); 535d20620deSHans-Juergen Koch err_free: 536d20620deSHans-Juergen Koch kfree(data); 537d20620deSHans-Juergen Koch return err; 538d20620deSHans-Juergen Koch } 539d20620deSHans-Juergen Koch 540d20620deSHans-Juergen Koch static int max6650_detach_client(struct i2c_client *client) 541d20620deSHans-Juergen Koch { 542d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 543d20620deSHans-Juergen Koch int err; 544d20620deSHans-Juergen Koch 545d20620deSHans-Juergen Koch sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); 5461beeffe4STony Jones hwmon_device_unregister(data->hwmon_dev); 547d20620deSHans-Juergen Koch err = i2c_detach_client(client); 548d20620deSHans-Juergen Koch if (!err) 549d20620deSHans-Juergen Koch kfree(data); 550d20620deSHans-Juergen Koch return err; 551d20620deSHans-Juergen Koch } 552d20620deSHans-Juergen Koch 553d20620deSHans-Juergen Koch static int max6650_init_client(struct i2c_client *client) 554d20620deSHans-Juergen Koch { 555d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 556d20620deSHans-Juergen Koch int config; 557d20620deSHans-Juergen Koch int err = -EIO; 558d20620deSHans-Juergen Koch 559d20620deSHans-Juergen Koch config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); 560d20620deSHans-Juergen Koch 561d20620deSHans-Juergen Koch if (config < 0) { 562d20620deSHans-Juergen Koch dev_err(&client->dev, "Error reading config, aborting.\n"); 563d20620deSHans-Juergen Koch return err; 564d20620deSHans-Juergen Koch } 565d20620deSHans-Juergen Koch 566d20620deSHans-Juergen Koch switch (fan_voltage) { 567d20620deSHans-Juergen Koch case 0: 568d20620deSHans-Juergen Koch break; 569d20620deSHans-Juergen Koch case 5: 570d20620deSHans-Juergen Koch config &= ~MAX6650_CFG_V12; 571d20620deSHans-Juergen Koch break; 572d20620deSHans-Juergen Koch case 12: 573d20620deSHans-Juergen Koch config |= MAX6650_CFG_V12; 574d20620deSHans-Juergen Koch break; 575d20620deSHans-Juergen Koch default: 576d20620deSHans-Juergen Koch dev_err(&client->dev, 577d20620deSHans-Juergen Koch "illegal value for fan_voltage (%d)\n", 578d20620deSHans-Juergen Koch fan_voltage); 579d20620deSHans-Juergen Koch } 580d20620deSHans-Juergen Koch 581d20620deSHans-Juergen Koch dev_info(&client->dev, "Fan voltage is set to %dV.\n", 582d20620deSHans-Juergen Koch (config & MAX6650_CFG_V12) ? 12 : 5); 583d20620deSHans-Juergen Koch 584d20620deSHans-Juergen Koch switch (prescaler) { 585d20620deSHans-Juergen Koch case 0: 586d20620deSHans-Juergen Koch break; 587d20620deSHans-Juergen Koch case 1: 588d20620deSHans-Juergen Koch config &= ~MAX6650_CFG_PRESCALER_MASK; 589d20620deSHans-Juergen Koch break; 590d20620deSHans-Juergen Koch case 2: 591d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_PRESCALER_MASK) 592d20620deSHans-Juergen Koch | MAX6650_CFG_PRESCALER_2; 593d20620deSHans-Juergen Koch break; 594d20620deSHans-Juergen Koch case 4: 595d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_PRESCALER_MASK) 596d20620deSHans-Juergen Koch | MAX6650_CFG_PRESCALER_4; 597d20620deSHans-Juergen Koch break; 598d20620deSHans-Juergen Koch case 8: 599d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_PRESCALER_MASK) 600d20620deSHans-Juergen Koch | MAX6650_CFG_PRESCALER_8; 601d20620deSHans-Juergen Koch break; 602d20620deSHans-Juergen Koch case 16: 603d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_PRESCALER_MASK) 604d20620deSHans-Juergen Koch | MAX6650_CFG_PRESCALER_16; 605d20620deSHans-Juergen Koch break; 606d20620deSHans-Juergen Koch default: 607d20620deSHans-Juergen Koch dev_err(&client->dev, 608d20620deSHans-Juergen Koch "illegal value for prescaler (%d)\n", 609d20620deSHans-Juergen Koch prescaler); 610d20620deSHans-Juergen Koch } 611d20620deSHans-Juergen Koch 612d20620deSHans-Juergen Koch dev_info(&client->dev, "Prescaler is set to %d.\n", 613d20620deSHans-Juergen Koch 1 << (config & MAX6650_CFG_PRESCALER_MASK)); 614d20620deSHans-Juergen Koch 615d20620deSHans-Juergen Koch /* If mode is set to "full off", we change it to "open loop" and 616d20620deSHans-Juergen Koch * set DAC to 255, which has the same effect. We do this because 617d20620deSHans-Juergen Koch * there's no "full off" mode defined in hwmon specifcations. 618d20620deSHans-Juergen Koch */ 619d20620deSHans-Juergen Koch 620d20620deSHans-Juergen Koch if ((config & MAX6650_CFG_MODE_MASK) == MAX6650_CFG_MODE_OFF) { 621d20620deSHans-Juergen Koch dev_dbg(&client->dev, "Change mode to open loop, full off.\n"); 622d20620deSHans-Juergen Koch config = (config & ~MAX6650_CFG_MODE_MASK) 623d20620deSHans-Juergen Koch | MAX6650_CFG_MODE_OPEN_LOOP; 624d20620deSHans-Juergen Koch if (i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, 255)) { 625d20620deSHans-Juergen Koch dev_err(&client->dev, "DAC write error, aborting.\n"); 626d20620deSHans-Juergen Koch return err; 627d20620deSHans-Juergen Koch } 628d20620deSHans-Juergen Koch } 629d20620deSHans-Juergen Koch 630d20620deSHans-Juergen Koch if (i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, config)) { 631d20620deSHans-Juergen Koch dev_err(&client->dev, "Config write error, aborting.\n"); 632d20620deSHans-Juergen Koch return err; 633d20620deSHans-Juergen Koch } 634d20620deSHans-Juergen Koch 635d20620deSHans-Juergen Koch data->config = config; 636d20620deSHans-Juergen Koch data->count = i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT); 637d20620deSHans-Juergen Koch 638d20620deSHans-Juergen Koch return 0; 639d20620deSHans-Juergen Koch } 640d20620deSHans-Juergen Koch 641d20620deSHans-Juergen Koch static const u8 tach_reg[] = { 642d20620deSHans-Juergen Koch MAX6650_REG_TACH0, 643d20620deSHans-Juergen Koch MAX6650_REG_TACH1, 644d20620deSHans-Juergen Koch MAX6650_REG_TACH2, 645d20620deSHans-Juergen Koch MAX6650_REG_TACH3, 646d20620deSHans-Juergen Koch }; 647d20620deSHans-Juergen Koch 648d20620deSHans-Juergen Koch static struct max6650_data *max6650_update_device(struct device *dev) 649d20620deSHans-Juergen Koch { 650d20620deSHans-Juergen Koch int i; 651d20620deSHans-Juergen Koch struct i2c_client *client = to_i2c_client(dev); 652d20620deSHans-Juergen Koch struct max6650_data *data = i2c_get_clientdata(client); 653d20620deSHans-Juergen Koch 654d20620deSHans-Juergen Koch mutex_lock(&data->update_lock); 655d20620deSHans-Juergen Koch 656d20620deSHans-Juergen Koch if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { 657d20620deSHans-Juergen Koch data->speed = i2c_smbus_read_byte_data(client, 658d20620deSHans-Juergen Koch MAX6650_REG_SPEED); 659d20620deSHans-Juergen Koch data->config = i2c_smbus_read_byte_data(client, 660d20620deSHans-Juergen Koch MAX6650_REG_CONFIG); 661d20620deSHans-Juergen Koch for (i = 0; i < 4; i++) { 662d20620deSHans-Juergen Koch data->tach[i] = i2c_smbus_read_byte_data(client, 663d20620deSHans-Juergen Koch tach_reg[i]); 664d20620deSHans-Juergen Koch } 665d20620deSHans-Juergen Koch data->count = i2c_smbus_read_byte_data(client, 666d20620deSHans-Juergen Koch MAX6650_REG_COUNT); 667d20620deSHans-Juergen Koch data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); 668d20620deSHans-Juergen Koch 669d20620deSHans-Juergen Koch data->last_updated = jiffies; 670d20620deSHans-Juergen Koch data->valid = 1; 671d20620deSHans-Juergen Koch } 672d20620deSHans-Juergen Koch 673d20620deSHans-Juergen Koch mutex_unlock(&data->update_lock); 674d20620deSHans-Juergen Koch 675d20620deSHans-Juergen Koch return data; 676d20620deSHans-Juergen Koch } 677d20620deSHans-Juergen Koch 678d20620deSHans-Juergen Koch static int __init sensors_max6650_init(void) 679d20620deSHans-Juergen Koch { 680d20620deSHans-Juergen Koch return i2c_add_driver(&max6650_driver); 681d20620deSHans-Juergen Koch } 682d20620deSHans-Juergen Koch 683d20620deSHans-Juergen Koch static void __exit sensors_max6650_exit(void) 684d20620deSHans-Juergen Koch { 685d20620deSHans-Juergen Koch i2c_del_driver(&max6650_driver); 686d20620deSHans-Juergen Koch } 687d20620deSHans-Juergen Koch 688d20620deSHans-Juergen Koch MODULE_AUTHOR("Hans J. Koch"); 689d20620deSHans-Juergen Koch MODULE_DESCRIPTION("MAX6650 sensor driver"); 690d20620deSHans-Juergen Koch MODULE_LICENSE("GPL"); 691d20620deSHans-Juergen Koch 692d20620deSHans-Juergen Koch module_init(sensors_max6650_init); 693d20620deSHans-Juergen Koch module_exit(sensors_max6650_exit); 694