1*1c301fc5SJordan Crouse /* 2*1c301fc5SJordan Crouse * adt7475 - Thermal sensor driver for the ADT7475 chip and derivatives 3*1c301fc5SJordan Crouse * Copyright (C) 2007-2008, Advanced Micro Devices, Inc. 4*1c301fc5SJordan Crouse * Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net> 5*1c301fc5SJordan Crouse * Copyright (C) 2008 Hans de Goede <hdegoede@redhat.com> 6*1c301fc5SJordan Crouse 7*1c301fc5SJordan Crouse * Derived from the lm83 driver by Jean Delvare 8*1c301fc5SJordan Crouse * 9*1c301fc5SJordan Crouse * This program is free software; you can redistribute it and/or modify 10*1c301fc5SJordan Crouse * it under the terms of the GNU General Public License version 2 as 11*1c301fc5SJordan Crouse * published by the Free Software Foundation. 12*1c301fc5SJordan Crouse */ 13*1c301fc5SJordan Crouse 14*1c301fc5SJordan Crouse #include <linux/module.h> 15*1c301fc5SJordan Crouse #include <linux/init.h> 16*1c301fc5SJordan Crouse #include <linux/slab.h> 17*1c301fc5SJordan Crouse #include <linux/i2c.h> 18*1c301fc5SJordan Crouse #include <linux/hwmon.h> 19*1c301fc5SJordan Crouse #include <linux/hwmon-sysfs.h> 20*1c301fc5SJordan Crouse #include <linux/err.h> 21*1c301fc5SJordan Crouse 22*1c301fc5SJordan Crouse /* Indexes for the sysfs hooks */ 23*1c301fc5SJordan Crouse 24*1c301fc5SJordan Crouse #define INPUT 0 25*1c301fc5SJordan Crouse #define MIN 1 26*1c301fc5SJordan Crouse #define MAX 2 27*1c301fc5SJordan Crouse #define CONTROL 3 28*1c301fc5SJordan Crouse #define OFFSET 3 29*1c301fc5SJordan Crouse #define AUTOMIN 4 30*1c301fc5SJordan Crouse #define THERM 5 31*1c301fc5SJordan Crouse #define HYSTERSIS 6 32*1c301fc5SJordan Crouse 33*1c301fc5SJordan Crouse /* These are unique identifiers for the sysfs functions - unlike the 34*1c301fc5SJordan Crouse numbers above, these are not also indexes into an array 35*1c301fc5SJordan Crouse */ 36*1c301fc5SJordan Crouse 37*1c301fc5SJordan Crouse #define ALARM 9 38*1c301fc5SJordan Crouse #define FAULT 10 39*1c301fc5SJordan Crouse 40*1c301fc5SJordan Crouse /* 7475 Common Registers */ 41*1c301fc5SJordan Crouse 42*1c301fc5SJordan Crouse #define REG_VOLTAGE_BASE 0x21 43*1c301fc5SJordan Crouse #define REG_TEMP_BASE 0x25 44*1c301fc5SJordan Crouse #define REG_TACH_BASE 0x28 45*1c301fc5SJordan Crouse #define REG_PWM_BASE 0x30 46*1c301fc5SJordan Crouse #define REG_PWM_MAX_BASE 0x38 47*1c301fc5SJordan Crouse 48*1c301fc5SJordan Crouse #define REG_DEVID 0x3D 49*1c301fc5SJordan Crouse #define REG_VENDID 0x3E 50*1c301fc5SJordan Crouse 51*1c301fc5SJordan Crouse #define REG_STATUS1 0x41 52*1c301fc5SJordan Crouse #define REG_STATUS2 0x42 53*1c301fc5SJordan Crouse 54*1c301fc5SJordan Crouse #define REG_VOLTAGE_MIN_BASE 0x46 55*1c301fc5SJordan Crouse #define REG_VOLTAGE_MAX_BASE 0x47 56*1c301fc5SJordan Crouse 57*1c301fc5SJordan Crouse #define REG_TEMP_MIN_BASE 0x4E 58*1c301fc5SJordan Crouse #define REG_TEMP_MAX_BASE 0x4F 59*1c301fc5SJordan Crouse 60*1c301fc5SJordan Crouse #define REG_TACH_MIN_BASE 0x54 61*1c301fc5SJordan Crouse 62*1c301fc5SJordan Crouse #define REG_PWM_CONFIG_BASE 0x5C 63*1c301fc5SJordan Crouse 64*1c301fc5SJordan Crouse #define REG_TEMP_TRANGE_BASE 0x5F 65*1c301fc5SJordan Crouse 66*1c301fc5SJordan Crouse #define REG_PWM_MIN_BASE 0x64 67*1c301fc5SJordan Crouse 68*1c301fc5SJordan Crouse #define REG_TEMP_TMIN_BASE 0x67 69*1c301fc5SJordan Crouse #define REG_TEMP_THERM_BASE 0x6A 70*1c301fc5SJordan Crouse 71*1c301fc5SJordan Crouse #define REG_REMOTE1_HYSTERSIS 0x6D 72*1c301fc5SJordan Crouse #define REG_REMOTE2_HYSTERSIS 0x6E 73*1c301fc5SJordan Crouse 74*1c301fc5SJordan Crouse #define REG_TEMP_OFFSET_BASE 0x70 75*1c301fc5SJordan Crouse 76*1c301fc5SJordan Crouse #define REG_EXTEND1 0x76 77*1c301fc5SJordan Crouse #define REG_EXTEND2 0x77 78*1c301fc5SJordan Crouse #define REG_CONFIG5 0x7C 79*1c301fc5SJordan Crouse 80*1c301fc5SJordan Crouse #define CONFIG5_TWOSCOMP 0x01 81*1c301fc5SJordan Crouse #define CONFIG5_TEMPOFFSET 0x02 82*1c301fc5SJordan Crouse 83*1c301fc5SJordan Crouse /* ADT7475 Settings */ 84*1c301fc5SJordan Crouse 85*1c301fc5SJordan Crouse #define ADT7475_VOLTAGE_COUNT 2 86*1c301fc5SJordan Crouse #define ADT7475_TEMP_COUNT 3 87*1c301fc5SJordan Crouse #define ADT7475_TACH_COUNT 4 88*1c301fc5SJordan Crouse #define ADT7475_PWM_COUNT 3 89*1c301fc5SJordan Crouse 90*1c301fc5SJordan Crouse /* Macro to read the registers */ 91*1c301fc5SJordan Crouse 92*1c301fc5SJordan Crouse #define adt7475_read(reg) i2c_smbus_read_byte_data(client, (reg)) 93*1c301fc5SJordan Crouse 94*1c301fc5SJordan Crouse /* Macros to easily index the registers */ 95*1c301fc5SJordan Crouse 96*1c301fc5SJordan Crouse #define TACH_REG(idx) (REG_TACH_BASE + ((idx) * 2)) 97*1c301fc5SJordan Crouse #define TACH_MIN_REG(idx) (REG_TACH_MIN_BASE + ((idx) * 2)) 98*1c301fc5SJordan Crouse 99*1c301fc5SJordan Crouse #define PWM_REG(idx) (REG_PWM_BASE + (idx)) 100*1c301fc5SJordan Crouse #define PWM_MAX_REG(idx) (REG_PWM_MAX_BASE + (idx)) 101*1c301fc5SJordan Crouse #define PWM_MIN_REG(idx) (REG_PWM_MIN_BASE + (idx)) 102*1c301fc5SJordan Crouse #define PWM_CONFIG_REG(idx) (REG_PWM_CONFIG_BASE + (idx)) 103*1c301fc5SJordan Crouse 104*1c301fc5SJordan Crouse #define VOLTAGE_REG(idx) (REG_VOLTAGE_BASE + (idx)) 105*1c301fc5SJordan Crouse #define VOLTAGE_MIN_REG(idx) (REG_VOLTAGE_MIN_BASE + ((idx) * 2)) 106*1c301fc5SJordan Crouse #define VOLTAGE_MAX_REG(idx) (REG_VOLTAGE_MAX_BASE + ((idx) * 2)) 107*1c301fc5SJordan Crouse 108*1c301fc5SJordan Crouse #define TEMP_REG(idx) (REG_TEMP_BASE + (idx)) 109*1c301fc5SJordan Crouse #define TEMP_MIN_REG(idx) (REG_TEMP_MIN_BASE + ((idx) * 2)) 110*1c301fc5SJordan Crouse #define TEMP_MAX_REG(idx) (REG_TEMP_MAX_BASE + ((idx) * 2)) 111*1c301fc5SJordan Crouse #define TEMP_TMIN_REG(idx) (REG_TEMP_TMIN_BASE + (idx)) 112*1c301fc5SJordan Crouse #define TEMP_THERM_REG(idx) (REG_TEMP_THERM_BASE + (idx)) 113*1c301fc5SJordan Crouse #define TEMP_OFFSET_REG(idx) (REG_TEMP_OFFSET_BASE + (idx)) 114*1c301fc5SJordan Crouse #define TEMP_TRANGE_REG(idx) (REG_TEMP_TRANGE_BASE + (idx)) 115*1c301fc5SJordan Crouse 116*1c301fc5SJordan Crouse static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END }; 117*1c301fc5SJordan Crouse 118*1c301fc5SJordan Crouse I2C_CLIENT_INSMOD_1(adt7475); 119*1c301fc5SJordan Crouse 120*1c301fc5SJordan Crouse static const struct i2c_device_id adt7475_id[] = { 121*1c301fc5SJordan Crouse { "adt7475", adt7475 }, 122*1c301fc5SJordan Crouse { } 123*1c301fc5SJordan Crouse }; 124*1c301fc5SJordan Crouse MODULE_DEVICE_TABLE(i2c, adt7475_id); 125*1c301fc5SJordan Crouse 126*1c301fc5SJordan Crouse struct adt7475_data { 127*1c301fc5SJordan Crouse struct device *hwmon_dev; 128*1c301fc5SJordan Crouse struct mutex lock; 129*1c301fc5SJordan Crouse 130*1c301fc5SJordan Crouse unsigned long measure_updated; 131*1c301fc5SJordan Crouse unsigned long limits_updated; 132*1c301fc5SJordan Crouse char valid; 133*1c301fc5SJordan Crouse 134*1c301fc5SJordan Crouse u8 config5; 135*1c301fc5SJordan Crouse u16 alarms; 136*1c301fc5SJordan Crouse u16 voltage[3][3]; 137*1c301fc5SJordan Crouse u16 temp[7][3]; 138*1c301fc5SJordan Crouse u16 tach[2][4]; 139*1c301fc5SJordan Crouse u8 pwm[4][3]; 140*1c301fc5SJordan Crouse u8 range[3]; 141*1c301fc5SJordan Crouse u8 pwmctl[3]; 142*1c301fc5SJordan Crouse u8 pwmchan[3]; 143*1c301fc5SJordan Crouse }; 144*1c301fc5SJordan Crouse 145*1c301fc5SJordan Crouse static struct i2c_driver adt7475_driver; 146*1c301fc5SJordan Crouse static struct adt7475_data *adt7475_update_device(struct device *dev); 147*1c301fc5SJordan Crouse static void adt7475_read_hystersis(struct i2c_client *client); 148*1c301fc5SJordan Crouse static void adt7475_read_pwm(struct i2c_client *client, int index); 149*1c301fc5SJordan Crouse 150*1c301fc5SJordan Crouse /* Given a temp value, convert it to register value */ 151*1c301fc5SJordan Crouse 152*1c301fc5SJordan Crouse static inline u16 temp2reg(struct adt7475_data *data, long val) 153*1c301fc5SJordan Crouse { 154*1c301fc5SJordan Crouse u16 ret; 155*1c301fc5SJordan Crouse 156*1c301fc5SJordan Crouse if (!(data->config5 & CONFIG5_TWOSCOMP)) { 157*1c301fc5SJordan Crouse val = SENSORS_LIMIT(val, -64000, 191000); 158*1c301fc5SJordan Crouse ret = (val + 64500) / 1000; 159*1c301fc5SJordan Crouse } else { 160*1c301fc5SJordan Crouse val = SENSORS_LIMIT(val, -128000, 127000); 161*1c301fc5SJordan Crouse if (val < -500) 162*1c301fc5SJordan Crouse ret = (256500 + val) / 1000; 163*1c301fc5SJordan Crouse else 164*1c301fc5SJordan Crouse ret = (val + 500) / 1000; 165*1c301fc5SJordan Crouse } 166*1c301fc5SJordan Crouse 167*1c301fc5SJordan Crouse return ret << 2; 168*1c301fc5SJordan Crouse } 169*1c301fc5SJordan Crouse 170*1c301fc5SJordan Crouse /* Given a register value, convert it to a real temp value */ 171*1c301fc5SJordan Crouse 172*1c301fc5SJordan Crouse static inline int reg2temp(struct adt7475_data *data, u16 reg) 173*1c301fc5SJordan Crouse { 174*1c301fc5SJordan Crouse if (data->config5 & CONFIG5_TWOSCOMP) { 175*1c301fc5SJordan Crouse if (reg >= 512) 176*1c301fc5SJordan Crouse return (reg - 1024) * 250; 177*1c301fc5SJordan Crouse else 178*1c301fc5SJordan Crouse return reg * 250; 179*1c301fc5SJordan Crouse } else 180*1c301fc5SJordan Crouse return (reg - 256) * 250; 181*1c301fc5SJordan Crouse } 182*1c301fc5SJordan Crouse 183*1c301fc5SJordan Crouse static inline int tach2rpm(u16 tach) 184*1c301fc5SJordan Crouse { 185*1c301fc5SJordan Crouse if (tach == 0 || tach == 0xFFFF) 186*1c301fc5SJordan Crouse return 0; 187*1c301fc5SJordan Crouse 188*1c301fc5SJordan Crouse return (90000 * 60) / tach; 189*1c301fc5SJordan Crouse } 190*1c301fc5SJordan Crouse 191*1c301fc5SJordan Crouse static inline u16 rpm2tach(unsigned long rpm) 192*1c301fc5SJordan Crouse { 193*1c301fc5SJordan Crouse if (rpm == 0) 194*1c301fc5SJordan Crouse return 0; 195*1c301fc5SJordan Crouse 196*1c301fc5SJordan Crouse return SENSORS_LIMIT((90000 * 60) / rpm, 1, 0xFFFF); 197*1c301fc5SJordan Crouse } 198*1c301fc5SJordan Crouse 199*1c301fc5SJordan Crouse static inline int reg2vcc(u16 reg) 200*1c301fc5SJordan Crouse { 201*1c301fc5SJordan Crouse return (4296 * reg) / 1000; 202*1c301fc5SJordan Crouse } 203*1c301fc5SJordan Crouse 204*1c301fc5SJordan Crouse static inline int reg2vccp(u16 reg) 205*1c301fc5SJordan Crouse { 206*1c301fc5SJordan Crouse return (2929 * reg) / 1000; 207*1c301fc5SJordan Crouse } 208*1c301fc5SJordan Crouse 209*1c301fc5SJordan Crouse static inline u16 vcc2reg(long vcc) 210*1c301fc5SJordan Crouse { 211*1c301fc5SJordan Crouse vcc = SENSORS_LIMIT(vcc, 0, 4396); 212*1c301fc5SJordan Crouse return (vcc * 1000) / 4296; 213*1c301fc5SJordan Crouse } 214*1c301fc5SJordan Crouse 215*1c301fc5SJordan Crouse static inline u16 vccp2reg(long vcc) 216*1c301fc5SJordan Crouse { 217*1c301fc5SJordan Crouse vcc = SENSORS_LIMIT(vcc, 0, 2998); 218*1c301fc5SJordan Crouse return (vcc * 1000) / 2929; 219*1c301fc5SJordan Crouse } 220*1c301fc5SJordan Crouse 221*1c301fc5SJordan Crouse static u16 adt7475_read_word(struct i2c_client *client, int reg) 222*1c301fc5SJordan Crouse { 223*1c301fc5SJordan Crouse u16 val; 224*1c301fc5SJordan Crouse 225*1c301fc5SJordan Crouse val = i2c_smbus_read_byte_data(client, reg); 226*1c301fc5SJordan Crouse val |= (i2c_smbus_read_byte_data(client, reg + 1) << 8); 227*1c301fc5SJordan Crouse 228*1c301fc5SJordan Crouse return val; 229*1c301fc5SJordan Crouse } 230*1c301fc5SJordan Crouse 231*1c301fc5SJordan Crouse static void adt7475_write_word(struct i2c_client *client, int reg, u16 val) 232*1c301fc5SJordan Crouse { 233*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, reg + 1, val >> 8); 234*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, reg, val & 0xFF); 235*1c301fc5SJordan Crouse } 236*1c301fc5SJordan Crouse 237*1c301fc5SJordan Crouse /* Find the nearest value in a table - used for pwm frequency and 238*1c301fc5SJordan Crouse auto temp range */ 239*1c301fc5SJordan Crouse static int find_nearest(long val, const int *array, int size) 240*1c301fc5SJordan Crouse { 241*1c301fc5SJordan Crouse int i; 242*1c301fc5SJordan Crouse 243*1c301fc5SJordan Crouse if (val < array[0]) 244*1c301fc5SJordan Crouse return 0; 245*1c301fc5SJordan Crouse 246*1c301fc5SJordan Crouse if (val > array[size - 1]) 247*1c301fc5SJordan Crouse return size - 1; 248*1c301fc5SJordan Crouse 249*1c301fc5SJordan Crouse for (i = 0; i < size - 1; i++) { 250*1c301fc5SJordan Crouse int a, b; 251*1c301fc5SJordan Crouse 252*1c301fc5SJordan Crouse if (val > array[i + 1]) 253*1c301fc5SJordan Crouse continue; 254*1c301fc5SJordan Crouse 255*1c301fc5SJordan Crouse a = val - array[i]; 256*1c301fc5SJordan Crouse b = array[i + 1] - val; 257*1c301fc5SJordan Crouse 258*1c301fc5SJordan Crouse return (a <= b) ? i : i + 1; 259*1c301fc5SJordan Crouse } 260*1c301fc5SJordan Crouse 261*1c301fc5SJordan Crouse return 0; 262*1c301fc5SJordan Crouse } 263*1c301fc5SJordan Crouse 264*1c301fc5SJordan Crouse static ssize_t show_voltage(struct device *dev, struct device_attribute *attr, 265*1c301fc5SJordan Crouse char *buf) 266*1c301fc5SJordan Crouse { 267*1c301fc5SJordan Crouse struct adt7475_data *data = adt7475_update_device(dev); 268*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 269*1c301fc5SJordan Crouse unsigned short val; 270*1c301fc5SJordan Crouse 271*1c301fc5SJordan Crouse switch (sattr->nr) { 272*1c301fc5SJordan Crouse case ALARM: 273*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", 274*1c301fc5SJordan Crouse (data->alarms >> (sattr->index + 1)) & 1); 275*1c301fc5SJordan Crouse default: 276*1c301fc5SJordan Crouse val = data->voltage[sattr->nr][sattr->index]; 277*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", 278*1c301fc5SJordan Crouse sattr->index == 279*1c301fc5SJordan Crouse 0 ? reg2vccp(val) : reg2vcc(val)); 280*1c301fc5SJordan Crouse } 281*1c301fc5SJordan Crouse } 282*1c301fc5SJordan Crouse 283*1c301fc5SJordan Crouse static ssize_t set_voltage(struct device *dev, struct device_attribute *attr, 284*1c301fc5SJordan Crouse const char *buf, size_t count) 285*1c301fc5SJordan Crouse { 286*1c301fc5SJordan Crouse 287*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 288*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 289*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 290*1c301fc5SJordan Crouse unsigned char reg; 291*1c301fc5SJordan Crouse long val; 292*1c301fc5SJordan Crouse 293*1c301fc5SJordan Crouse if (strict_strtol(buf, 10, &val)) 294*1c301fc5SJordan Crouse return -EINVAL; 295*1c301fc5SJordan Crouse 296*1c301fc5SJordan Crouse mutex_lock(&data->lock); 297*1c301fc5SJordan Crouse 298*1c301fc5SJordan Crouse data->voltage[sattr->nr][sattr->index] = 299*1c301fc5SJordan Crouse sattr->index ? vcc2reg(val) : vccp2reg(val); 300*1c301fc5SJordan Crouse 301*1c301fc5SJordan Crouse if (sattr->nr == MIN) 302*1c301fc5SJordan Crouse reg = VOLTAGE_MIN_REG(sattr->index); 303*1c301fc5SJordan Crouse else 304*1c301fc5SJordan Crouse reg = VOLTAGE_MAX_REG(sattr->index); 305*1c301fc5SJordan Crouse 306*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, reg, 307*1c301fc5SJordan Crouse data->voltage[sattr->nr][sattr->index] >> 2); 308*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 309*1c301fc5SJordan Crouse 310*1c301fc5SJordan Crouse return count; 311*1c301fc5SJordan Crouse } 312*1c301fc5SJordan Crouse 313*1c301fc5SJordan Crouse static ssize_t show_temp(struct device *dev, struct device_attribute *attr, 314*1c301fc5SJordan Crouse char *buf) 315*1c301fc5SJordan Crouse { 316*1c301fc5SJordan Crouse struct adt7475_data *data = adt7475_update_device(dev); 317*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 318*1c301fc5SJordan Crouse int out; 319*1c301fc5SJordan Crouse 320*1c301fc5SJordan Crouse switch (sattr->nr) { 321*1c301fc5SJordan Crouse case HYSTERSIS: 322*1c301fc5SJordan Crouse mutex_lock(&data->lock); 323*1c301fc5SJordan Crouse out = data->temp[sattr->nr][sattr->index]; 324*1c301fc5SJordan Crouse if (sattr->index != 1) 325*1c301fc5SJordan Crouse out = (out >> 4) & 0xF; 326*1c301fc5SJordan Crouse else 327*1c301fc5SJordan Crouse out = (out & 0xF); 328*1c301fc5SJordan Crouse /* Show the value as an absolute number tied to 329*1c301fc5SJordan Crouse * THERM */ 330*1c301fc5SJordan Crouse out = reg2temp(data, data->temp[THERM][sattr->index]) - 331*1c301fc5SJordan Crouse out * 1000; 332*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 333*1c301fc5SJordan Crouse break; 334*1c301fc5SJordan Crouse 335*1c301fc5SJordan Crouse case OFFSET: 336*1c301fc5SJordan Crouse /* Offset is always 2's complement, regardless of the 337*1c301fc5SJordan Crouse * setting in CONFIG5 */ 338*1c301fc5SJordan Crouse mutex_lock(&data->lock); 339*1c301fc5SJordan Crouse out = (s8)data->temp[sattr->nr][sattr->index]; 340*1c301fc5SJordan Crouse if (data->config5 & CONFIG5_TEMPOFFSET) 341*1c301fc5SJordan Crouse out *= 1000; 342*1c301fc5SJordan Crouse else 343*1c301fc5SJordan Crouse out *= 500; 344*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 345*1c301fc5SJordan Crouse break; 346*1c301fc5SJordan Crouse 347*1c301fc5SJordan Crouse case ALARM: 348*1c301fc5SJordan Crouse out = (data->alarms >> (sattr->index + 4)) & 1; 349*1c301fc5SJordan Crouse break; 350*1c301fc5SJordan Crouse 351*1c301fc5SJordan Crouse case FAULT: 352*1c301fc5SJordan Crouse /* Note - only for remote1 and remote2 */ 353*1c301fc5SJordan Crouse out = data->alarms & (sattr->index ? 0x8000 : 0x4000); 354*1c301fc5SJordan Crouse out = out ? 0 : 1; 355*1c301fc5SJordan Crouse break; 356*1c301fc5SJordan Crouse 357*1c301fc5SJordan Crouse default: 358*1c301fc5SJordan Crouse /* All other temp values are in the configured format */ 359*1c301fc5SJordan Crouse out = reg2temp(data, data->temp[sattr->nr][sattr->index]); 360*1c301fc5SJordan Crouse } 361*1c301fc5SJordan Crouse 362*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", out); 363*1c301fc5SJordan Crouse } 364*1c301fc5SJordan Crouse 365*1c301fc5SJordan Crouse static ssize_t set_temp(struct device *dev, struct device_attribute *attr, 366*1c301fc5SJordan Crouse const char *buf, size_t count) 367*1c301fc5SJordan Crouse { 368*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 369*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 370*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 371*1c301fc5SJordan Crouse unsigned char reg = 0; 372*1c301fc5SJordan Crouse u8 out; 373*1c301fc5SJordan Crouse int temp; 374*1c301fc5SJordan Crouse long val; 375*1c301fc5SJordan Crouse 376*1c301fc5SJordan Crouse if (strict_strtol(buf, 10, &val)) 377*1c301fc5SJordan Crouse return -EINVAL; 378*1c301fc5SJordan Crouse 379*1c301fc5SJordan Crouse mutex_lock(&data->lock); 380*1c301fc5SJordan Crouse 381*1c301fc5SJordan Crouse /* We need the config register in all cases for temp <-> reg conv. */ 382*1c301fc5SJordan Crouse data->config5 = adt7475_read(REG_CONFIG5); 383*1c301fc5SJordan Crouse 384*1c301fc5SJordan Crouse switch (sattr->nr) { 385*1c301fc5SJordan Crouse case OFFSET: 386*1c301fc5SJordan Crouse if (data->config5 & CONFIG5_TEMPOFFSET) { 387*1c301fc5SJordan Crouse val = SENSORS_LIMIT(val, -63000, 127000); 388*1c301fc5SJordan Crouse out = data->temp[OFFSET][sattr->index] = val / 1000; 389*1c301fc5SJordan Crouse } else { 390*1c301fc5SJordan Crouse val = SENSORS_LIMIT(val, -63000, 64000); 391*1c301fc5SJordan Crouse out = data->temp[OFFSET][sattr->index] = val / 500; 392*1c301fc5SJordan Crouse } 393*1c301fc5SJordan Crouse break; 394*1c301fc5SJordan Crouse 395*1c301fc5SJordan Crouse case HYSTERSIS: 396*1c301fc5SJordan Crouse /* The value will be given as an absolute value, turn it 397*1c301fc5SJordan Crouse into an offset based on THERM */ 398*1c301fc5SJordan Crouse 399*1c301fc5SJordan Crouse /* Read fresh THERM and HYSTERSIS values from the chip */ 400*1c301fc5SJordan Crouse data->temp[THERM][sattr->index] = 401*1c301fc5SJordan Crouse adt7475_read(TEMP_THERM_REG(sattr->index)) << 2; 402*1c301fc5SJordan Crouse adt7475_read_hystersis(client); 403*1c301fc5SJordan Crouse 404*1c301fc5SJordan Crouse temp = reg2temp(data, data->temp[THERM][sattr->index]); 405*1c301fc5SJordan Crouse val = SENSORS_LIMIT(val, temp - 15000, temp); 406*1c301fc5SJordan Crouse val = (temp - val) / 1000; 407*1c301fc5SJordan Crouse 408*1c301fc5SJordan Crouse if (sattr->index != 1) { 409*1c301fc5SJordan Crouse data->temp[HYSTERSIS][sattr->index] &= 0xF0; 410*1c301fc5SJordan Crouse data->temp[HYSTERSIS][sattr->index] |= (val & 0xF) << 4; 411*1c301fc5SJordan Crouse } else { 412*1c301fc5SJordan Crouse data->temp[HYSTERSIS][sattr->index] &= 0x0F; 413*1c301fc5SJordan Crouse data->temp[HYSTERSIS][sattr->index] |= (val & 0xF); 414*1c301fc5SJordan Crouse } 415*1c301fc5SJordan Crouse 416*1c301fc5SJordan Crouse out = data->temp[HYSTERSIS][sattr->index]; 417*1c301fc5SJordan Crouse break; 418*1c301fc5SJordan Crouse 419*1c301fc5SJordan Crouse default: 420*1c301fc5SJordan Crouse data->temp[sattr->nr][sattr->index] = temp2reg(data, val); 421*1c301fc5SJordan Crouse 422*1c301fc5SJordan Crouse /* We maintain an extra 2 digits of precision for simplicity 423*1c301fc5SJordan Crouse * - shift those back off before writing the value */ 424*1c301fc5SJordan Crouse out = (u8) (data->temp[sattr->nr][sattr->index] >> 2); 425*1c301fc5SJordan Crouse } 426*1c301fc5SJordan Crouse 427*1c301fc5SJordan Crouse switch (sattr->nr) { 428*1c301fc5SJordan Crouse case MIN: 429*1c301fc5SJordan Crouse reg = TEMP_MIN_REG(sattr->index); 430*1c301fc5SJordan Crouse break; 431*1c301fc5SJordan Crouse case MAX: 432*1c301fc5SJordan Crouse reg = TEMP_MAX_REG(sattr->index); 433*1c301fc5SJordan Crouse break; 434*1c301fc5SJordan Crouse case OFFSET: 435*1c301fc5SJordan Crouse reg = TEMP_OFFSET_REG(sattr->index); 436*1c301fc5SJordan Crouse break; 437*1c301fc5SJordan Crouse case AUTOMIN: 438*1c301fc5SJordan Crouse reg = TEMP_TMIN_REG(sattr->index); 439*1c301fc5SJordan Crouse break; 440*1c301fc5SJordan Crouse case THERM: 441*1c301fc5SJordan Crouse reg = TEMP_THERM_REG(sattr->index); 442*1c301fc5SJordan Crouse break; 443*1c301fc5SJordan Crouse case HYSTERSIS: 444*1c301fc5SJordan Crouse if (sattr->index != 2) 445*1c301fc5SJordan Crouse reg = REG_REMOTE1_HYSTERSIS; 446*1c301fc5SJordan Crouse else 447*1c301fc5SJordan Crouse reg = REG_REMOTE2_HYSTERSIS; 448*1c301fc5SJordan Crouse 449*1c301fc5SJordan Crouse break; 450*1c301fc5SJordan Crouse } 451*1c301fc5SJordan Crouse 452*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, reg, out); 453*1c301fc5SJordan Crouse 454*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 455*1c301fc5SJordan Crouse return count; 456*1c301fc5SJordan Crouse } 457*1c301fc5SJordan Crouse 458*1c301fc5SJordan Crouse /* Table of autorange values - the user will write the value in millidegrees, 459*1c301fc5SJordan Crouse and we'll convert it */ 460*1c301fc5SJordan Crouse static const int autorange_table[] = { 461*1c301fc5SJordan Crouse 2000, 2500, 3330, 4000, 5000, 6670, 8000, 462*1c301fc5SJordan Crouse 10000, 13330, 16000, 20000, 26670, 32000, 40000, 463*1c301fc5SJordan Crouse 53330, 80000 464*1c301fc5SJordan Crouse }; 465*1c301fc5SJordan Crouse 466*1c301fc5SJordan Crouse static ssize_t show_point2(struct device *dev, struct device_attribute *attr, 467*1c301fc5SJordan Crouse char *buf) 468*1c301fc5SJordan Crouse { 469*1c301fc5SJordan Crouse struct adt7475_data *data = adt7475_update_device(dev); 470*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 471*1c301fc5SJordan Crouse int out, val; 472*1c301fc5SJordan Crouse 473*1c301fc5SJordan Crouse mutex_lock(&data->lock); 474*1c301fc5SJordan Crouse out = (data->range[sattr->index] >> 4) & 0x0F; 475*1c301fc5SJordan Crouse val = reg2temp(data, data->temp[AUTOMIN][sattr->index]); 476*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 477*1c301fc5SJordan Crouse 478*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", val + autorange_table[out]); 479*1c301fc5SJordan Crouse } 480*1c301fc5SJordan Crouse 481*1c301fc5SJordan Crouse static ssize_t set_point2(struct device *dev, struct device_attribute *attr, 482*1c301fc5SJordan Crouse const char *buf, size_t count) 483*1c301fc5SJordan Crouse { 484*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 485*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 486*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 487*1c301fc5SJordan Crouse int temp; 488*1c301fc5SJordan Crouse long val; 489*1c301fc5SJordan Crouse 490*1c301fc5SJordan Crouse if (strict_strtol(buf, 10, &val)) 491*1c301fc5SJordan Crouse return -EINVAL; 492*1c301fc5SJordan Crouse 493*1c301fc5SJordan Crouse mutex_lock(&data->lock); 494*1c301fc5SJordan Crouse 495*1c301fc5SJordan Crouse /* Get a fresh copy of the needed registers */ 496*1c301fc5SJordan Crouse data->config5 = adt7475_read(REG_CONFIG5); 497*1c301fc5SJordan Crouse data->temp[AUTOMIN][sattr->index] = 498*1c301fc5SJordan Crouse adt7475_read(TEMP_TMIN_REG(sattr->index)) << 2; 499*1c301fc5SJordan Crouse data->range[sattr->index] = 500*1c301fc5SJordan Crouse adt7475_read(TEMP_TRANGE_REG(sattr->index)); 501*1c301fc5SJordan Crouse 502*1c301fc5SJordan Crouse /* The user will write an absolute value, so subtract the start point 503*1c301fc5SJordan Crouse to figure the range */ 504*1c301fc5SJordan Crouse temp = reg2temp(data, data->temp[AUTOMIN][sattr->index]); 505*1c301fc5SJordan Crouse val = SENSORS_LIMIT(val, temp + autorange_table[0], 506*1c301fc5SJordan Crouse temp + autorange_table[ARRAY_SIZE(autorange_table) - 1]); 507*1c301fc5SJordan Crouse val -= temp; 508*1c301fc5SJordan Crouse 509*1c301fc5SJordan Crouse /* Find the nearest table entry to what the user wrote */ 510*1c301fc5SJordan Crouse val = find_nearest(val, autorange_table, ARRAY_SIZE(autorange_table)); 511*1c301fc5SJordan Crouse 512*1c301fc5SJordan Crouse data->range[sattr->index] &= ~0xF0; 513*1c301fc5SJordan Crouse data->range[sattr->index] |= val << 4; 514*1c301fc5SJordan Crouse 515*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, TEMP_TRANGE_REG(sattr->index), 516*1c301fc5SJordan Crouse data->range[sattr->index]); 517*1c301fc5SJordan Crouse 518*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 519*1c301fc5SJordan Crouse return count; 520*1c301fc5SJordan Crouse } 521*1c301fc5SJordan Crouse 522*1c301fc5SJordan Crouse static ssize_t show_tach(struct device *dev, struct device_attribute *attr, 523*1c301fc5SJordan Crouse char *buf) 524*1c301fc5SJordan Crouse { 525*1c301fc5SJordan Crouse struct adt7475_data *data = adt7475_update_device(dev); 526*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 527*1c301fc5SJordan Crouse int out; 528*1c301fc5SJordan Crouse 529*1c301fc5SJordan Crouse if (sattr->nr == ALARM) 530*1c301fc5SJordan Crouse out = (data->alarms >> (sattr->index + 10)) & 1; 531*1c301fc5SJordan Crouse else 532*1c301fc5SJordan Crouse out = tach2rpm(data->tach[sattr->nr][sattr->index]); 533*1c301fc5SJordan Crouse 534*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", out); 535*1c301fc5SJordan Crouse } 536*1c301fc5SJordan Crouse 537*1c301fc5SJordan Crouse static ssize_t set_tach(struct device *dev, struct device_attribute *attr, 538*1c301fc5SJordan Crouse const char *buf, size_t count) 539*1c301fc5SJordan Crouse { 540*1c301fc5SJordan Crouse 541*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 542*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 543*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 544*1c301fc5SJordan Crouse unsigned long val; 545*1c301fc5SJordan Crouse 546*1c301fc5SJordan Crouse if (strict_strtoul(buf, 10, &val)) 547*1c301fc5SJordan Crouse return -EINVAL; 548*1c301fc5SJordan Crouse 549*1c301fc5SJordan Crouse mutex_lock(&data->lock); 550*1c301fc5SJordan Crouse 551*1c301fc5SJordan Crouse data->tach[MIN][sattr->index] = rpm2tach(val); 552*1c301fc5SJordan Crouse 553*1c301fc5SJordan Crouse adt7475_write_word(client, TACH_MIN_REG(sattr->index), 554*1c301fc5SJordan Crouse data->tach[MIN][sattr->index]); 555*1c301fc5SJordan Crouse 556*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 557*1c301fc5SJordan Crouse return count; 558*1c301fc5SJordan Crouse } 559*1c301fc5SJordan Crouse 560*1c301fc5SJordan Crouse static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, 561*1c301fc5SJordan Crouse char *buf) 562*1c301fc5SJordan Crouse { 563*1c301fc5SJordan Crouse struct adt7475_data *data = adt7475_update_device(dev); 564*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 565*1c301fc5SJordan Crouse 566*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", data->pwm[sattr->nr][sattr->index]); 567*1c301fc5SJordan Crouse } 568*1c301fc5SJordan Crouse 569*1c301fc5SJordan Crouse static ssize_t show_pwmchan(struct device *dev, struct device_attribute *attr, 570*1c301fc5SJordan Crouse char *buf) 571*1c301fc5SJordan Crouse { 572*1c301fc5SJordan Crouse struct adt7475_data *data = adt7475_update_device(dev); 573*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 574*1c301fc5SJordan Crouse 575*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", data->pwmchan[sattr->index]); 576*1c301fc5SJordan Crouse } 577*1c301fc5SJordan Crouse 578*1c301fc5SJordan Crouse static ssize_t show_pwmctrl(struct device *dev, struct device_attribute *attr, 579*1c301fc5SJordan Crouse char *buf) 580*1c301fc5SJordan Crouse { 581*1c301fc5SJordan Crouse struct adt7475_data *data = adt7475_update_device(dev); 582*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 583*1c301fc5SJordan Crouse 584*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", data->pwmctl[sattr->index]); 585*1c301fc5SJordan Crouse } 586*1c301fc5SJordan Crouse 587*1c301fc5SJordan Crouse static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, 588*1c301fc5SJordan Crouse const char *buf, size_t count) 589*1c301fc5SJordan Crouse { 590*1c301fc5SJordan Crouse 591*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 592*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 593*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 594*1c301fc5SJordan Crouse unsigned char reg = 0; 595*1c301fc5SJordan Crouse long val; 596*1c301fc5SJordan Crouse 597*1c301fc5SJordan Crouse if (strict_strtol(buf, 10, &val)) 598*1c301fc5SJordan Crouse return -EINVAL; 599*1c301fc5SJordan Crouse 600*1c301fc5SJordan Crouse mutex_lock(&data->lock); 601*1c301fc5SJordan Crouse 602*1c301fc5SJordan Crouse switch (sattr->nr) { 603*1c301fc5SJordan Crouse case INPUT: 604*1c301fc5SJordan Crouse /* Get a fresh value for CONTROL */ 605*1c301fc5SJordan Crouse data->pwm[CONTROL][sattr->index] = 606*1c301fc5SJordan Crouse adt7475_read(PWM_CONFIG_REG(sattr->index)); 607*1c301fc5SJordan Crouse 608*1c301fc5SJordan Crouse /* If we are not in manual mode, then we shouldn't allow 609*1c301fc5SJordan Crouse * the user to set the pwm speed */ 610*1c301fc5SJordan Crouse if (((data->pwm[CONTROL][sattr->index] >> 5) & 7) != 7) { 611*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 612*1c301fc5SJordan Crouse return count; 613*1c301fc5SJordan Crouse } 614*1c301fc5SJordan Crouse 615*1c301fc5SJordan Crouse reg = PWM_REG(sattr->index); 616*1c301fc5SJordan Crouse break; 617*1c301fc5SJordan Crouse 618*1c301fc5SJordan Crouse case MIN: 619*1c301fc5SJordan Crouse reg = PWM_MIN_REG(sattr->index); 620*1c301fc5SJordan Crouse break; 621*1c301fc5SJordan Crouse 622*1c301fc5SJordan Crouse case MAX: 623*1c301fc5SJordan Crouse reg = PWM_MAX_REG(sattr->index); 624*1c301fc5SJordan Crouse break; 625*1c301fc5SJordan Crouse } 626*1c301fc5SJordan Crouse 627*1c301fc5SJordan Crouse data->pwm[sattr->nr][sattr->index] = SENSORS_LIMIT(val, 0, 0xFF); 628*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, reg, 629*1c301fc5SJordan Crouse data->pwm[sattr->nr][sattr->index]); 630*1c301fc5SJordan Crouse 631*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 632*1c301fc5SJordan Crouse 633*1c301fc5SJordan Crouse return count; 634*1c301fc5SJordan Crouse } 635*1c301fc5SJordan Crouse 636*1c301fc5SJordan Crouse /* Called by set_pwmctrl and set_pwmchan */ 637*1c301fc5SJordan Crouse 638*1c301fc5SJordan Crouse static int hw_set_pwm(struct i2c_client *client, int index, 639*1c301fc5SJordan Crouse unsigned int pwmctl, unsigned int pwmchan) 640*1c301fc5SJordan Crouse { 641*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 642*1c301fc5SJordan Crouse long val = 0; 643*1c301fc5SJordan Crouse 644*1c301fc5SJordan Crouse switch (pwmctl) { 645*1c301fc5SJordan Crouse case 0: 646*1c301fc5SJordan Crouse val = 0x03; /* Run at full speed */ 647*1c301fc5SJordan Crouse break; 648*1c301fc5SJordan Crouse case 1: 649*1c301fc5SJordan Crouse val = 0x07; /* Manual mode */ 650*1c301fc5SJordan Crouse break; 651*1c301fc5SJordan Crouse case 2: 652*1c301fc5SJordan Crouse switch (pwmchan) { 653*1c301fc5SJordan Crouse case 1: 654*1c301fc5SJordan Crouse /* Remote1 controls PWM */ 655*1c301fc5SJordan Crouse val = 0x00; 656*1c301fc5SJordan Crouse break; 657*1c301fc5SJordan Crouse case 2: 658*1c301fc5SJordan Crouse /* local controls PWM */ 659*1c301fc5SJordan Crouse val = 0x01; 660*1c301fc5SJordan Crouse break; 661*1c301fc5SJordan Crouse case 4: 662*1c301fc5SJordan Crouse /* remote2 controls PWM */ 663*1c301fc5SJordan Crouse val = 0x02; 664*1c301fc5SJordan Crouse break; 665*1c301fc5SJordan Crouse case 6: 666*1c301fc5SJordan Crouse /* local/remote2 control PWM */ 667*1c301fc5SJordan Crouse val = 0x05; 668*1c301fc5SJordan Crouse break; 669*1c301fc5SJordan Crouse case 7: 670*1c301fc5SJordan Crouse /* All three control PWM */ 671*1c301fc5SJordan Crouse val = 0x06; 672*1c301fc5SJordan Crouse break; 673*1c301fc5SJordan Crouse default: 674*1c301fc5SJordan Crouse return -EINVAL; 675*1c301fc5SJordan Crouse } 676*1c301fc5SJordan Crouse break; 677*1c301fc5SJordan Crouse default: 678*1c301fc5SJordan Crouse return -EINVAL; 679*1c301fc5SJordan Crouse } 680*1c301fc5SJordan Crouse 681*1c301fc5SJordan Crouse data->pwmctl[index] = pwmctl; 682*1c301fc5SJordan Crouse data->pwmchan[index] = pwmchan; 683*1c301fc5SJordan Crouse 684*1c301fc5SJordan Crouse data->pwm[CONTROL][index] &= ~0xE0; 685*1c301fc5SJordan Crouse data->pwm[CONTROL][index] |= (val & 7) << 5; 686*1c301fc5SJordan Crouse 687*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), 688*1c301fc5SJordan Crouse data->pwm[CONTROL][index]); 689*1c301fc5SJordan Crouse 690*1c301fc5SJordan Crouse return 0; 691*1c301fc5SJordan Crouse } 692*1c301fc5SJordan Crouse 693*1c301fc5SJordan Crouse static ssize_t set_pwmchan(struct device *dev, struct device_attribute *attr, 694*1c301fc5SJordan Crouse const char *buf, size_t count) 695*1c301fc5SJordan Crouse { 696*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 697*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 698*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 699*1c301fc5SJordan Crouse int r; 700*1c301fc5SJordan Crouse long val; 701*1c301fc5SJordan Crouse 702*1c301fc5SJordan Crouse if (strict_strtol(buf, 10, &val)) 703*1c301fc5SJordan Crouse return -EINVAL; 704*1c301fc5SJordan Crouse 705*1c301fc5SJordan Crouse mutex_lock(&data->lock); 706*1c301fc5SJordan Crouse /* Read Modify Write PWM values */ 707*1c301fc5SJordan Crouse adt7475_read_pwm(client, sattr->index); 708*1c301fc5SJordan Crouse r = hw_set_pwm(client, sattr->index, data->pwmctl[sattr->index], val); 709*1c301fc5SJordan Crouse if (r) 710*1c301fc5SJordan Crouse count = r; 711*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 712*1c301fc5SJordan Crouse 713*1c301fc5SJordan Crouse return count; 714*1c301fc5SJordan Crouse } 715*1c301fc5SJordan Crouse 716*1c301fc5SJordan Crouse static ssize_t set_pwmctrl(struct device *dev, struct device_attribute *attr, 717*1c301fc5SJordan Crouse const char *buf, size_t count) 718*1c301fc5SJordan Crouse { 719*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 720*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 721*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 722*1c301fc5SJordan Crouse int r; 723*1c301fc5SJordan Crouse long val; 724*1c301fc5SJordan Crouse 725*1c301fc5SJordan Crouse if (strict_strtol(buf, 10, &val)) 726*1c301fc5SJordan Crouse return -EINVAL; 727*1c301fc5SJordan Crouse 728*1c301fc5SJordan Crouse mutex_lock(&data->lock); 729*1c301fc5SJordan Crouse /* Read Modify Write PWM values */ 730*1c301fc5SJordan Crouse adt7475_read_pwm(client, sattr->index); 731*1c301fc5SJordan Crouse r = hw_set_pwm(client, sattr->index, val, data->pwmchan[sattr->index]); 732*1c301fc5SJordan Crouse if (r) 733*1c301fc5SJordan Crouse count = r; 734*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 735*1c301fc5SJordan Crouse 736*1c301fc5SJordan Crouse return count; 737*1c301fc5SJordan Crouse } 738*1c301fc5SJordan Crouse 739*1c301fc5SJordan Crouse /* List of frequencies for the PWM */ 740*1c301fc5SJordan Crouse static const int pwmfreq_table[] = { 741*1c301fc5SJordan Crouse 11, 14, 22, 29, 35, 44, 58, 88 742*1c301fc5SJordan Crouse }; 743*1c301fc5SJordan Crouse 744*1c301fc5SJordan Crouse static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr, 745*1c301fc5SJordan Crouse char *buf) 746*1c301fc5SJordan Crouse { 747*1c301fc5SJordan Crouse struct adt7475_data *data = adt7475_update_device(dev); 748*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 749*1c301fc5SJordan Crouse 750*1c301fc5SJordan Crouse return sprintf(buf, "%d\n", 751*1c301fc5SJordan Crouse pwmfreq_table[data->range[sattr->index] & 7]); 752*1c301fc5SJordan Crouse } 753*1c301fc5SJordan Crouse 754*1c301fc5SJordan Crouse static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr, 755*1c301fc5SJordan Crouse const char *buf, size_t count) 756*1c301fc5SJordan Crouse { 757*1c301fc5SJordan Crouse struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 758*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 759*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 760*1c301fc5SJordan Crouse int out; 761*1c301fc5SJordan Crouse long val; 762*1c301fc5SJordan Crouse 763*1c301fc5SJordan Crouse if (strict_strtol(buf, 10, &val)) 764*1c301fc5SJordan Crouse return -EINVAL; 765*1c301fc5SJordan Crouse 766*1c301fc5SJordan Crouse out = find_nearest(val, pwmfreq_table, ARRAY_SIZE(pwmfreq_table)); 767*1c301fc5SJordan Crouse 768*1c301fc5SJordan Crouse mutex_lock(&data->lock); 769*1c301fc5SJordan Crouse 770*1c301fc5SJordan Crouse data->range[sattr->index] = 771*1c301fc5SJordan Crouse adt7475_read(TEMP_TRANGE_REG(sattr->index)); 772*1c301fc5SJordan Crouse data->range[sattr->index] &= ~7; 773*1c301fc5SJordan Crouse data->range[sattr->index] |= out; 774*1c301fc5SJordan Crouse 775*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, TEMP_TRANGE_REG(sattr->index), 776*1c301fc5SJordan Crouse data->range[sattr->index]); 777*1c301fc5SJordan Crouse 778*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 779*1c301fc5SJordan Crouse return count; 780*1c301fc5SJordan Crouse } 781*1c301fc5SJordan Crouse 782*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 0); 783*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage, 784*1c301fc5SJordan Crouse set_voltage, MAX, 0); 785*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_voltage, 786*1c301fc5SJordan Crouse set_voltage, MIN, 0); 787*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, show_voltage, NULL, ALARM, 0); 788*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_voltage, NULL, INPUT, 1); 789*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage, 790*1c301fc5SJordan Crouse set_voltage, MAX, 1); 791*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage, 792*1c301fc5SJordan Crouse set_voltage, MIN, 1); 793*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 1); 794*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, INPUT, 0); 795*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_alarm, S_IRUGO, show_temp, NULL, ALARM, 0); 796*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_temp, NULL, FAULT, 0); 797*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp, 798*1c301fc5SJordan Crouse MAX, 0); 799*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp, 800*1c301fc5SJordan Crouse MIN, 0); 801*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp, 802*1c301fc5SJordan Crouse set_temp, OFFSET, 0); 803*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_auto_point1_temp, S_IRUGO | S_IWUSR, 804*1c301fc5SJordan Crouse show_temp, set_temp, AUTOMIN, 0); 805*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_auto_point2_temp, S_IRUGO | S_IWUSR, 806*1c301fc5SJordan Crouse show_point2, set_point2, 0, 0); 807*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, 808*1c301fc5SJordan Crouse THERM, 0); 809*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp1_crit_hyst, S_IRUGO | S_IWUSR, show_temp, 810*1c301fc5SJordan Crouse set_temp, HYSTERSIS, 0); 811*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, INPUT, 1); 812*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_alarm, S_IRUGO, show_temp, NULL, ALARM, 1); 813*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp, 814*1c301fc5SJordan Crouse MAX, 1); 815*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp, 816*1c301fc5SJordan Crouse MIN, 1); 817*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp, 818*1c301fc5SJordan Crouse set_temp, OFFSET, 1); 819*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_auto_point1_temp, S_IRUGO | S_IWUSR, 820*1c301fc5SJordan Crouse show_temp, set_temp, AUTOMIN, 1); 821*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IRUGO | S_IWUSR, 822*1c301fc5SJordan Crouse show_point2, set_point2, 0, 1); 823*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, 824*1c301fc5SJordan Crouse THERM, 1); 825*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp2_crit_hyst, S_IRUGO | S_IWUSR, show_temp, 826*1c301fc5SJordan Crouse set_temp, HYSTERSIS, 1); 827*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, INPUT, 2); 828*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_alarm, S_IRUGO, show_temp, NULL, ALARM, 2); 829*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_temp, NULL, FAULT, 2); 830*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp, 831*1c301fc5SJordan Crouse MAX, 2); 832*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp, 833*1c301fc5SJordan Crouse MIN, 2); 834*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp, 835*1c301fc5SJordan Crouse set_temp, OFFSET, 2); 836*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_auto_point1_temp, S_IRUGO | S_IWUSR, 837*1c301fc5SJordan Crouse show_temp, set_temp, AUTOMIN, 2); 838*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_auto_point2_temp, S_IRUGO | S_IWUSR, 839*1c301fc5SJordan Crouse show_point2, set_point2, 0, 2); 840*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, 841*1c301fc5SJordan Crouse THERM, 2); 842*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(temp3_crit_hyst, S_IRUGO | S_IWUSR, show_temp, 843*1c301fc5SJordan Crouse set_temp, HYSTERSIS, 2); 844*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_tach, NULL, INPUT, 0); 845*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_tach, set_tach, 846*1c301fc5SJordan Crouse MIN, 0); 847*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan1_alarm, S_IRUGO, show_tach, NULL, ALARM, 0); 848*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_tach, NULL, INPUT, 1); 849*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_tach, set_tach, 850*1c301fc5SJordan Crouse MIN, 1); 851*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan2_alarm, S_IRUGO, show_tach, NULL, ALARM, 1); 852*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_tach, NULL, INPUT, 2); 853*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_tach, set_tach, 854*1c301fc5SJordan Crouse MIN, 2); 855*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan3_alarm, S_IRUGO, show_tach, NULL, ALARM, 2); 856*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_tach, NULL, INPUT, 3); 857*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_tach, set_tach, 858*1c301fc5SJordan Crouse MIN, 3); 859*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(fan4_alarm, S_IRUGO, show_tach, NULL, ALARM, 3); 860*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT, 861*1c301fc5SJordan Crouse 0); 862*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm1_freq, S_IRUGO | S_IWUSR, show_pwmfreq, 863*1c301fc5SJordan Crouse set_pwmfreq, INPUT, 0); 864*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm1_enable, S_IRUGO | S_IWUSR, show_pwmctrl, 865*1c301fc5SJordan Crouse set_pwmctrl, INPUT, 0); 866*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm1_auto_channel_temp, S_IRUGO | S_IWUSR, 867*1c301fc5SJordan Crouse show_pwmchan, set_pwmchan, INPUT, 0); 868*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm, 869*1c301fc5SJordan Crouse set_pwm, MIN, 0); 870*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm, 871*1c301fc5SJordan Crouse set_pwm, MAX, 0); 872*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT, 873*1c301fc5SJordan Crouse 1); 874*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm2_freq, S_IRUGO | S_IWUSR, show_pwmfreq, 875*1c301fc5SJordan Crouse set_pwmfreq, INPUT, 1); 876*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm2_enable, S_IRUGO | S_IWUSR, show_pwmctrl, 877*1c301fc5SJordan Crouse set_pwmctrl, INPUT, 1); 878*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm2_auto_channel_temp, S_IRUGO | S_IWUSR, 879*1c301fc5SJordan Crouse show_pwmchan, set_pwmchan, INPUT, 1); 880*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm, 881*1c301fc5SJordan Crouse set_pwm, MIN, 1); 882*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm, 883*1c301fc5SJordan Crouse set_pwm, MAX, 1); 884*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT, 885*1c301fc5SJordan Crouse 2); 886*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm3_freq, S_IRUGO | S_IWUSR, show_pwmfreq, 887*1c301fc5SJordan Crouse set_pwmfreq, INPUT, 2); 888*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm3_enable, S_IRUGO | S_IWUSR, show_pwmctrl, 889*1c301fc5SJordan Crouse set_pwmctrl, INPUT, 2); 890*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm3_auto_channel_temp, S_IRUGO | S_IWUSR, 891*1c301fc5SJordan Crouse show_pwmchan, set_pwmchan, INPUT, 2); 892*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm, 893*1c301fc5SJordan Crouse set_pwm, MIN, 2); 894*1c301fc5SJordan Crouse static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm, 895*1c301fc5SJordan Crouse set_pwm, MAX, 2); 896*1c301fc5SJordan Crouse 897*1c301fc5SJordan Crouse static struct attribute *adt7475_attrs[] = { 898*1c301fc5SJordan Crouse &sensor_dev_attr_in1_input.dev_attr.attr, 899*1c301fc5SJordan Crouse &sensor_dev_attr_in1_max.dev_attr.attr, 900*1c301fc5SJordan Crouse &sensor_dev_attr_in1_min.dev_attr.attr, 901*1c301fc5SJordan Crouse &sensor_dev_attr_in1_alarm.dev_attr.attr, 902*1c301fc5SJordan Crouse &sensor_dev_attr_in2_input.dev_attr.attr, 903*1c301fc5SJordan Crouse &sensor_dev_attr_in2_max.dev_attr.attr, 904*1c301fc5SJordan Crouse &sensor_dev_attr_in2_min.dev_attr.attr, 905*1c301fc5SJordan Crouse &sensor_dev_attr_in2_alarm.dev_attr.attr, 906*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_input.dev_attr.attr, 907*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_alarm.dev_attr.attr, 908*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_fault.dev_attr.attr, 909*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_max.dev_attr.attr, 910*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_min.dev_attr.attr, 911*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_offset.dev_attr.attr, 912*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, 913*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, 914*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_crit.dev_attr.attr, 915*1c301fc5SJordan Crouse &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, 916*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_input.dev_attr.attr, 917*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_alarm.dev_attr.attr, 918*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_max.dev_attr.attr, 919*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_min.dev_attr.attr, 920*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_offset.dev_attr.attr, 921*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, 922*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, 923*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_crit.dev_attr.attr, 924*1c301fc5SJordan Crouse &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, 925*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_input.dev_attr.attr, 926*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_fault.dev_attr.attr, 927*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_alarm.dev_attr.attr, 928*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_max.dev_attr.attr, 929*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_min.dev_attr.attr, 930*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_offset.dev_attr.attr, 931*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, 932*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, 933*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_crit.dev_attr.attr, 934*1c301fc5SJordan Crouse &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, 935*1c301fc5SJordan Crouse &sensor_dev_attr_fan1_input.dev_attr.attr, 936*1c301fc5SJordan Crouse &sensor_dev_attr_fan1_min.dev_attr.attr, 937*1c301fc5SJordan Crouse &sensor_dev_attr_fan1_alarm.dev_attr.attr, 938*1c301fc5SJordan Crouse &sensor_dev_attr_fan2_input.dev_attr.attr, 939*1c301fc5SJordan Crouse &sensor_dev_attr_fan2_min.dev_attr.attr, 940*1c301fc5SJordan Crouse &sensor_dev_attr_fan2_alarm.dev_attr.attr, 941*1c301fc5SJordan Crouse &sensor_dev_attr_fan3_input.dev_attr.attr, 942*1c301fc5SJordan Crouse &sensor_dev_attr_fan3_min.dev_attr.attr, 943*1c301fc5SJordan Crouse &sensor_dev_attr_fan3_alarm.dev_attr.attr, 944*1c301fc5SJordan Crouse &sensor_dev_attr_fan4_input.dev_attr.attr, 945*1c301fc5SJordan Crouse &sensor_dev_attr_fan4_min.dev_attr.attr, 946*1c301fc5SJordan Crouse &sensor_dev_attr_fan4_alarm.dev_attr.attr, 947*1c301fc5SJordan Crouse &sensor_dev_attr_pwm1.dev_attr.attr, 948*1c301fc5SJordan Crouse &sensor_dev_attr_pwm1_freq.dev_attr.attr, 949*1c301fc5SJordan Crouse &sensor_dev_attr_pwm1_enable.dev_attr.attr, 950*1c301fc5SJordan Crouse &sensor_dev_attr_pwm1_auto_channel_temp.dev_attr.attr, 951*1c301fc5SJordan Crouse &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, 952*1c301fc5SJordan Crouse &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, 953*1c301fc5SJordan Crouse &sensor_dev_attr_pwm2.dev_attr.attr, 954*1c301fc5SJordan Crouse &sensor_dev_attr_pwm2_freq.dev_attr.attr, 955*1c301fc5SJordan Crouse &sensor_dev_attr_pwm2_enable.dev_attr.attr, 956*1c301fc5SJordan Crouse &sensor_dev_attr_pwm2_auto_channel_temp.dev_attr.attr, 957*1c301fc5SJordan Crouse &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, 958*1c301fc5SJordan Crouse &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, 959*1c301fc5SJordan Crouse &sensor_dev_attr_pwm3.dev_attr.attr, 960*1c301fc5SJordan Crouse &sensor_dev_attr_pwm3_freq.dev_attr.attr, 961*1c301fc5SJordan Crouse &sensor_dev_attr_pwm3_enable.dev_attr.attr, 962*1c301fc5SJordan Crouse &sensor_dev_attr_pwm3_auto_channel_temp.dev_attr.attr, 963*1c301fc5SJordan Crouse &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, 964*1c301fc5SJordan Crouse &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, 965*1c301fc5SJordan Crouse NULL, 966*1c301fc5SJordan Crouse }; 967*1c301fc5SJordan Crouse 968*1c301fc5SJordan Crouse struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs }; 969*1c301fc5SJordan Crouse 970*1c301fc5SJordan Crouse static int adt7475_detect(struct i2c_client *client, int kind, 971*1c301fc5SJordan Crouse struct i2c_board_info *info) 972*1c301fc5SJordan Crouse { 973*1c301fc5SJordan Crouse struct i2c_adapter *adapter = client->adapter; 974*1c301fc5SJordan Crouse 975*1c301fc5SJordan Crouse if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 976*1c301fc5SJordan Crouse return -ENODEV; 977*1c301fc5SJordan Crouse 978*1c301fc5SJordan Crouse if (kind <= 0) { 979*1c301fc5SJordan Crouse if (adt7475_read(REG_VENDID) != 0x41 || 980*1c301fc5SJordan Crouse adt7475_read(REG_DEVID) != 0x75) { 981*1c301fc5SJordan Crouse dev_err(&adapter->dev, 982*1c301fc5SJordan Crouse "Couldn't detect a adt7475 part at 0x%02x\n", 983*1c301fc5SJordan Crouse (unsigned int)client->addr); 984*1c301fc5SJordan Crouse return -ENODEV; 985*1c301fc5SJordan Crouse } 986*1c301fc5SJordan Crouse } 987*1c301fc5SJordan Crouse 988*1c301fc5SJordan Crouse strlcpy(info->type, adt7475_id[0].name, I2C_NAME_SIZE); 989*1c301fc5SJordan Crouse 990*1c301fc5SJordan Crouse return 0; 991*1c301fc5SJordan Crouse } 992*1c301fc5SJordan Crouse 993*1c301fc5SJordan Crouse static int adt7475_probe(struct i2c_client *client, 994*1c301fc5SJordan Crouse const struct i2c_device_id *id) 995*1c301fc5SJordan Crouse { 996*1c301fc5SJordan Crouse struct adt7475_data *data; 997*1c301fc5SJordan Crouse int i, ret = 0; 998*1c301fc5SJordan Crouse 999*1c301fc5SJordan Crouse data = kzalloc(sizeof(*data), GFP_KERNEL); 1000*1c301fc5SJordan Crouse if (data == NULL) 1001*1c301fc5SJordan Crouse return -ENOMEM; 1002*1c301fc5SJordan Crouse 1003*1c301fc5SJordan Crouse mutex_init(&data->lock); 1004*1c301fc5SJordan Crouse i2c_set_clientdata(client, data); 1005*1c301fc5SJordan Crouse 1006*1c301fc5SJordan Crouse /* Call adt7475_read_pwm for all pwm's as this will reprogram any 1007*1c301fc5SJordan Crouse pwm's which are disabled to manual mode with 0% duty cycle */ 1008*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_PWM_COUNT; i++) 1009*1c301fc5SJordan Crouse adt7475_read_pwm(client, i); 1010*1c301fc5SJordan Crouse 1011*1c301fc5SJordan Crouse ret = sysfs_create_group(&client->dev.kobj, &adt7475_attr_group); 1012*1c301fc5SJordan Crouse if (ret) 1013*1c301fc5SJordan Crouse goto efree; 1014*1c301fc5SJordan Crouse 1015*1c301fc5SJordan Crouse data->hwmon_dev = hwmon_device_register(&client->dev); 1016*1c301fc5SJordan Crouse if (IS_ERR(data->hwmon_dev)) { 1017*1c301fc5SJordan Crouse ret = PTR_ERR(data->hwmon_dev); 1018*1c301fc5SJordan Crouse goto eremove; 1019*1c301fc5SJordan Crouse } 1020*1c301fc5SJordan Crouse 1021*1c301fc5SJordan Crouse return 0; 1022*1c301fc5SJordan Crouse 1023*1c301fc5SJordan Crouse eremove: 1024*1c301fc5SJordan Crouse sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group); 1025*1c301fc5SJordan Crouse efree: 1026*1c301fc5SJordan Crouse kfree(data); 1027*1c301fc5SJordan Crouse return ret; 1028*1c301fc5SJordan Crouse } 1029*1c301fc5SJordan Crouse 1030*1c301fc5SJordan Crouse static int adt7475_remove(struct i2c_client *client) 1031*1c301fc5SJordan Crouse { 1032*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 1033*1c301fc5SJordan Crouse 1034*1c301fc5SJordan Crouse hwmon_device_unregister(data->hwmon_dev); 1035*1c301fc5SJordan Crouse sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group); 1036*1c301fc5SJordan Crouse kfree(data); 1037*1c301fc5SJordan Crouse 1038*1c301fc5SJordan Crouse return 0; 1039*1c301fc5SJordan Crouse } 1040*1c301fc5SJordan Crouse 1041*1c301fc5SJordan Crouse static struct i2c_driver adt7475_driver = { 1042*1c301fc5SJordan Crouse .class = I2C_CLASS_HWMON, 1043*1c301fc5SJordan Crouse .driver = { 1044*1c301fc5SJordan Crouse .name = "adt7475", 1045*1c301fc5SJordan Crouse }, 1046*1c301fc5SJordan Crouse .probe = adt7475_probe, 1047*1c301fc5SJordan Crouse .remove = adt7475_remove, 1048*1c301fc5SJordan Crouse .id_table = adt7475_id, 1049*1c301fc5SJordan Crouse .detect = adt7475_detect, 1050*1c301fc5SJordan Crouse .address_data = &addr_data, 1051*1c301fc5SJordan Crouse }; 1052*1c301fc5SJordan Crouse 1053*1c301fc5SJordan Crouse static void adt7475_read_hystersis(struct i2c_client *client) 1054*1c301fc5SJordan Crouse { 1055*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 1056*1c301fc5SJordan Crouse 1057*1c301fc5SJordan Crouse data->temp[HYSTERSIS][0] = (u16) adt7475_read(REG_REMOTE1_HYSTERSIS); 1058*1c301fc5SJordan Crouse data->temp[HYSTERSIS][1] = data->temp[HYSTERSIS][0]; 1059*1c301fc5SJordan Crouse data->temp[HYSTERSIS][2] = (u16) adt7475_read(REG_REMOTE2_HYSTERSIS); 1060*1c301fc5SJordan Crouse } 1061*1c301fc5SJordan Crouse 1062*1c301fc5SJordan Crouse static void adt7475_read_pwm(struct i2c_client *client, int index) 1063*1c301fc5SJordan Crouse { 1064*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 1065*1c301fc5SJordan Crouse unsigned int v; 1066*1c301fc5SJordan Crouse 1067*1c301fc5SJordan Crouse data->pwm[CONTROL][index] = adt7475_read(PWM_CONFIG_REG(index)); 1068*1c301fc5SJordan Crouse 1069*1c301fc5SJordan Crouse /* Figure out the internal value for pwmctrl and pwmchan 1070*1c301fc5SJordan Crouse based on the current settings */ 1071*1c301fc5SJordan Crouse v = (data->pwm[CONTROL][index] >> 5) & 7; 1072*1c301fc5SJordan Crouse 1073*1c301fc5SJordan Crouse if (v == 3) 1074*1c301fc5SJordan Crouse data->pwmctl[index] = 0; 1075*1c301fc5SJordan Crouse else if (v == 7) 1076*1c301fc5SJordan Crouse data->pwmctl[index] = 1; 1077*1c301fc5SJordan Crouse else if (v == 4) { 1078*1c301fc5SJordan Crouse /* The fan is disabled - we don't want to 1079*1c301fc5SJordan Crouse support that, so change to manual mode and 1080*1c301fc5SJordan Crouse set the duty cycle to 0 instead 1081*1c301fc5SJordan Crouse */ 1082*1c301fc5SJordan Crouse data->pwm[INPUT][index] = 0; 1083*1c301fc5SJordan Crouse data->pwm[CONTROL][index] &= ~0xE0; 1084*1c301fc5SJordan Crouse data->pwm[CONTROL][index] |= (7 << 5); 1085*1c301fc5SJordan Crouse 1086*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), 1087*1c301fc5SJordan Crouse data->pwm[INPUT][index]); 1088*1c301fc5SJordan Crouse 1089*1c301fc5SJordan Crouse i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), 1090*1c301fc5SJordan Crouse data->pwm[CONTROL][index]); 1091*1c301fc5SJordan Crouse 1092*1c301fc5SJordan Crouse data->pwmctl[index] = 1; 1093*1c301fc5SJordan Crouse } else { 1094*1c301fc5SJordan Crouse data->pwmctl[index] = 2; 1095*1c301fc5SJordan Crouse 1096*1c301fc5SJordan Crouse switch (v) { 1097*1c301fc5SJordan Crouse case 0: 1098*1c301fc5SJordan Crouse data->pwmchan[index] = 1; 1099*1c301fc5SJordan Crouse break; 1100*1c301fc5SJordan Crouse case 1: 1101*1c301fc5SJordan Crouse data->pwmchan[index] = 2; 1102*1c301fc5SJordan Crouse break; 1103*1c301fc5SJordan Crouse case 2: 1104*1c301fc5SJordan Crouse data->pwmchan[index] = 4; 1105*1c301fc5SJordan Crouse break; 1106*1c301fc5SJordan Crouse case 5: 1107*1c301fc5SJordan Crouse data->pwmchan[index] = 6; 1108*1c301fc5SJordan Crouse break; 1109*1c301fc5SJordan Crouse case 6: 1110*1c301fc5SJordan Crouse data->pwmchan[index] = 7; 1111*1c301fc5SJordan Crouse break; 1112*1c301fc5SJordan Crouse } 1113*1c301fc5SJordan Crouse } 1114*1c301fc5SJordan Crouse } 1115*1c301fc5SJordan Crouse 1116*1c301fc5SJordan Crouse static struct adt7475_data *adt7475_update_device(struct device *dev) 1117*1c301fc5SJordan Crouse { 1118*1c301fc5SJordan Crouse struct i2c_client *client = to_i2c_client(dev); 1119*1c301fc5SJordan Crouse struct adt7475_data *data = i2c_get_clientdata(client); 1120*1c301fc5SJordan Crouse u8 ext; 1121*1c301fc5SJordan Crouse int i; 1122*1c301fc5SJordan Crouse 1123*1c301fc5SJordan Crouse mutex_lock(&data->lock); 1124*1c301fc5SJordan Crouse 1125*1c301fc5SJordan Crouse /* Measurement values update every 2 seconds */ 1126*1c301fc5SJordan Crouse if (time_after(jiffies, data->measure_updated + HZ * 2) || 1127*1c301fc5SJordan Crouse !data->valid) { 1128*1c301fc5SJordan Crouse data->alarms = adt7475_read(REG_STATUS2) << 8; 1129*1c301fc5SJordan Crouse data->alarms |= adt7475_read(REG_STATUS1); 1130*1c301fc5SJordan Crouse 1131*1c301fc5SJordan Crouse ext = adt7475_read(REG_EXTEND1); 1132*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) 1133*1c301fc5SJordan Crouse data->voltage[INPUT][i] = 1134*1c301fc5SJordan Crouse (adt7475_read(VOLTAGE_REG(i)) << 2) | 1135*1c301fc5SJordan Crouse ((ext >> ((i + 1) * 2)) & 3); 1136*1c301fc5SJordan Crouse 1137*1c301fc5SJordan Crouse ext = adt7475_read(REG_EXTEND2); 1138*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_TEMP_COUNT; i++) 1139*1c301fc5SJordan Crouse data->temp[INPUT][i] = 1140*1c301fc5SJordan Crouse (adt7475_read(TEMP_REG(i)) << 2) | 1141*1c301fc5SJordan Crouse ((ext >> ((i + 1) * 2)) & 3); 1142*1c301fc5SJordan Crouse 1143*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_TACH_COUNT; i++) 1144*1c301fc5SJordan Crouse data->tach[INPUT][i] = 1145*1c301fc5SJordan Crouse adt7475_read_word(client, TACH_REG(i)); 1146*1c301fc5SJordan Crouse 1147*1c301fc5SJordan Crouse /* Updated by hw when in auto mode */ 1148*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_PWM_COUNT; i++) 1149*1c301fc5SJordan Crouse data->pwm[INPUT][i] = adt7475_read(PWM_REG(i)); 1150*1c301fc5SJordan Crouse 1151*1c301fc5SJordan Crouse data->measure_updated = jiffies; 1152*1c301fc5SJordan Crouse } 1153*1c301fc5SJordan Crouse 1154*1c301fc5SJordan Crouse /* Limits and settings, should never change update every 60 seconds */ 1155*1c301fc5SJordan Crouse if (time_after(jiffies, data->limits_updated + HZ * 2) || 1156*1c301fc5SJordan Crouse !data->valid) { 1157*1c301fc5SJordan Crouse data->config5 = adt7475_read(REG_CONFIG5); 1158*1c301fc5SJordan Crouse 1159*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) { 1160*1c301fc5SJordan Crouse /* Adjust values so they match the input precision */ 1161*1c301fc5SJordan Crouse data->voltage[MIN][i] = 1162*1c301fc5SJordan Crouse adt7475_read(VOLTAGE_MIN_REG(i)) << 2; 1163*1c301fc5SJordan Crouse data->voltage[MAX][i] = 1164*1c301fc5SJordan Crouse adt7475_read(VOLTAGE_MAX_REG(i)) << 2; 1165*1c301fc5SJordan Crouse } 1166*1c301fc5SJordan Crouse 1167*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_TEMP_COUNT; i++) { 1168*1c301fc5SJordan Crouse /* Adjust values so they match the input precision */ 1169*1c301fc5SJordan Crouse data->temp[MIN][i] = 1170*1c301fc5SJordan Crouse adt7475_read(TEMP_MIN_REG(i)) << 2; 1171*1c301fc5SJordan Crouse data->temp[MAX][i] = 1172*1c301fc5SJordan Crouse adt7475_read(TEMP_MAX_REG(i)) << 2; 1173*1c301fc5SJordan Crouse data->temp[AUTOMIN][i] = 1174*1c301fc5SJordan Crouse adt7475_read(TEMP_TMIN_REG(i)) << 2; 1175*1c301fc5SJordan Crouse data->temp[THERM][i] = 1176*1c301fc5SJordan Crouse adt7475_read(TEMP_THERM_REG(i)) << 2; 1177*1c301fc5SJordan Crouse data->temp[OFFSET][i] = 1178*1c301fc5SJordan Crouse adt7475_read(TEMP_OFFSET_REG(i)); 1179*1c301fc5SJordan Crouse } 1180*1c301fc5SJordan Crouse adt7475_read_hystersis(client); 1181*1c301fc5SJordan Crouse 1182*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_TACH_COUNT; i++) 1183*1c301fc5SJordan Crouse data->tach[MIN][i] = 1184*1c301fc5SJordan Crouse adt7475_read_word(client, TACH_MIN_REG(i)); 1185*1c301fc5SJordan Crouse 1186*1c301fc5SJordan Crouse for (i = 0; i < ADT7475_PWM_COUNT; i++) { 1187*1c301fc5SJordan Crouse data->pwm[MAX][i] = adt7475_read(PWM_MAX_REG(i)); 1188*1c301fc5SJordan Crouse data->pwm[MIN][i] = adt7475_read(PWM_MIN_REG(i)); 1189*1c301fc5SJordan Crouse /* Set the channel and control information */ 1190*1c301fc5SJordan Crouse adt7475_read_pwm(client, i); 1191*1c301fc5SJordan Crouse } 1192*1c301fc5SJordan Crouse 1193*1c301fc5SJordan Crouse data->range[0] = adt7475_read(TEMP_TRANGE_REG(0)); 1194*1c301fc5SJordan Crouse data->range[1] = adt7475_read(TEMP_TRANGE_REG(1)); 1195*1c301fc5SJordan Crouse data->range[2] = adt7475_read(TEMP_TRANGE_REG(2)); 1196*1c301fc5SJordan Crouse 1197*1c301fc5SJordan Crouse data->limits_updated = jiffies; 1198*1c301fc5SJordan Crouse data->valid = 1; 1199*1c301fc5SJordan Crouse } 1200*1c301fc5SJordan Crouse 1201*1c301fc5SJordan Crouse mutex_unlock(&data->lock); 1202*1c301fc5SJordan Crouse 1203*1c301fc5SJordan Crouse return data; 1204*1c301fc5SJordan Crouse } 1205*1c301fc5SJordan Crouse 1206*1c301fc5SJordan Crouse static int __init sensors_adt7475_init(void) 1207*1c301fc5SJordan Crouse { 1208*1c301fc5SJordan Crouse return i2c_add_driver(&adt7475_driver); 1209*1c301fc5SJordan Crouse } 1210*1c301fc5SJordan Crouse 1211*1c301fc5SJordan Crouse static void __exit sensors_adt7475_exit(void) 1212*1c301fc5SJordan Crouse { 1213*1c301fc5SJordan Crouse i2c_del_driver(&adt7475_driver); 1214*1c301fc5SJordan Crouse } 1215*1c301fc5SJordan Crouse 1216*1c301fc5SJordan Crouse MODULE_AUTHOR("Advanced Micro Devices, Inc"); 1217*1c301fc5SJordan Crouse MODULE_DESCRIPTION("adt7475 driver"); 1218*1c301fc5SJordan Crouse MODULE_LICENSE("GPL"); 1219*1c301fc5SJordan Crouse 1220*1c301fc5SJordan Crouse module_init(sensors_adt7475_init); 1221*1c301fc5SJordan Crouse module_exit(sensors_adt7475_exit); 1222