1139735Simp// SPDX-License-Identifier: GPL-2.0-or-later 2129198Scognet/* 3129198Scognet * asb100.c - Part of lm_sensors, Linux kernel modules for hardware 4129198Scognet * monitoring 5129198Scognet * 6129198Scognet * Copyright (C) 2004 Mark M. Hoffman <mhoffman@lightlink.com> 7129198Scognet * 8129198Scognet * (derived from w83781d.c) 9129198Scognet * 10129198Scognet * Copyright (C) 1998 - 2003 Frodo Looijaard <frodol@dds.nl>, 11129198Scognet * Philip Edelbrock <phil@netroedge.com>, and 12129198Scognet * Mark Studebaker <mdsxyz123@yahoo.com> 13129198Scognet */ 14129198Scognet 15129198Scognet/* 16129198Scognet * This driver supports the hardware sensor chips: Asus ASB100 and 17129198Scognet * ASB100-A "BACH". 18129198Scognet * 19129198Scognet * ASB100-A supports pwm1, while plain ASB100 does not. There is no known 20129198Scognet * way for the driver to tell which one is there. 21129198Scognet * 22129198Scognet * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA 23129198Scognet * asb100 7 3 1 4 0x31 0x0694 yes no 24129198Scognet */ 25129198Scognet 26129198Scognet#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 27129198Scognet 28129198Scognet#include <linux/module.h> 29129198Scognet#include <linux/slab.h> 30129198Scognet#include <linux/i2c.h> 31129198Scognet#include <linux/hwmon.h> 32129198Scognet#include <linux/hwmon-sysfs.h> 33129198Scognet#include <linux/hwmon-vid.h> 34129198Scognet#include <linux/err.h> 35166686Skevlo#include <linux/init.h> 36129198Scognet#include <linux/jiffies.h> 37129198Scognet#include <linux/mutex.h> 38129198Scognet#include "lm75.h" 39129198Scognet 40129198Scognet/* I2C addresses to scan */ 41129198Scognetstatic const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; 42129198Scognet 43129198Scognetstatic unsigned short force_subclients[4]; 44129198Scognetmodule_param_array(force_subclients, short, NULL, 0); 45129198ScognetMODULE_PARM_DESC(force_subclients, 46129198Scognet "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}"); 47129198Scognet 48129198Scognet/* Voltage IN registers 0-6 */ 49140310Scognet#define ASB100_REG_IN(nr) (0x20 + (nr)) 50146597Scognet#define ASB100_REG_IN_MAX(nr) (0x2b + (nr * 2)) 51166063Scognet#define ASB100_REG_IN_MIN(nr) (0x2c + (nr * 2)) 52129198Scognet 53129198Scognet/* FAN IN registers 1-3 */ 54129198Scognet#define ASB100_REG_FAN(nr) (0x28 + (nr)) 55129198Scognet#define ASB100_REG_FAN_MIN(nr) (0x3b + (nr)) 56129198Scognet 57129198Scognet/* TEMPERATURE registers 1-4 */ 58129198Scognetstatic const u16 asb100_reg_temp[] = {0, 0x27, 0x150, 0x250, 0x17}; 59129198Scognetstatic const u16 asb100_reg_temp_max[] = {0, 0x39, 0x155, 0x255, 0x18}; 60166063Scognetstatic const u16 asb100_reg_temp_hyst[] = {0, 0x3a, 0x153, 0x253, 0x19}; 61129198Scognet 62166063Scognet#define ASB100_REG_TEMP(nr) (asb100_reg_temp[nr]) 63166063Scognet#define ASB100_REG_TEMP_MAX(nr) (asb100_reg_temp_max[nr]) 64166063Scognet#define ASB100_REG_TEMP_HYST(nr) (asb100_reg_temp_hyst[nr]) 65166063Scognet 66166063Scognet#define ASB100_REG_TEMP2_CONFIG 0x0152 67166063Scognet#define ASB100_REG_TEMP3_CONFIG 0x0252 68129198Scognet 69129198Scognet 70129198Scognet#define ASB100_REG_CONFIG 0x40 71129198Scognet#define ASB100_REG_ALARM1 0x41 72129198Scognet#define ASB100_REG_ALARM2 0x42 73129198Scognet#define ASB100_REG_SMIM1 0x43 74129198Scognet#define ASB100_REG_SMIM2 0x44 75129198Scognet#define ASB100_REG_VID_FANDIV 0x47 76129198Scognet#define ASB100_REG_I2C_ADDR 0x48 77129198Scognet#define ASB100_REG_CHIPID 0x49 78129198Scognet#define ASB100_REG_I2C_SUBADDR 0x4a 79129198Scognet#define ASB100_REG_PIN 0x4b 80129198Scognet#define ASB100_REG_IRQ 0x4c 81129198Scognet#define ASB100_REG_BANK 0x4e 82129198Scognet#define ASB100_REG_CHIPMAN 0x4f 83129198Scognet 84129198Scognet#define ASB100_REG_WCHIPID 0x58 85129198Scognet 86129198Scognet/* bit 7 -> enable, bits 0-3 -> duty cycle */ 87129198Scognet#define ASB100_REG_PWM1 0x59 88129198Scognet 89129198Scognet/* 90129198Scognet * CONVERSIONS 91129198Scognet * Rounding and limit checking is only done on the TO_REG variants. 92166063Scognet */ 93129198Scognet 94129198Scognet/* These constants are a guess, consistent w/ w83781d */ 95166063Scognet#define ASB100_IN_MIN 0 96166063Scognet#define ASB100_IN_MAX 4080 97166063Scognet 98166063Scognet/* 99166063Scognet * IN: 1/1000 V (0V to 4.08V) 100166063Scognet * REG: 16mV/bit 101166063Scognet */ 102166063Scognetstatic u8 IN_TO_REG(unsigned val) 103166063Scognet{ 104166063Scognet unsigned nval = clamp_val(val, ASB100_IN_MIN, ASB100_IN_MAX); 105166063Scognet return (nval + 8) / 16; 106166063Scognet} 107166063Scognet 108166063Scognetstatic unsigned IN_FROM_REG(u8 reg) 109166063Scognet{ 110166063Scognet return reg * 16; 111166063Scognet} 112166063Scognet 113166063Scognetstatic u8 FAN_TO_REG(long rpm, int div) 114166063Scognet{ 115166063Scognet if (rpm == -1) 116166063Scognet return 0; 117166063Scognet if (rpm == 0) 118166063Scognet return 255; 119166063Scognet rpm = clamp_val(rpm, 1, 1000000); 120166063Scognet return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254); 121166063Scognet} 122166063Scognet 123166063Scognetstatic int FAN_FROM_REG(u8 val, int div) 124166063Scognet{ 125166063Scognet return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div); 126166063Scognet} 127166063Scognet 128166063Scognet/* These constants are a guess, consistent w/ w83781d */ 129166063Scognet#define ASB100_TEMP_MIN -128000 130166063Scognet#define ASB100_TEMP_MAX 127000 131166063Scognet 132166063Scognet/* 133135644Scognet * TEMP: 0.001C/bit (-128C to +127C) 134135644Scognet * REG: 1C/bit, two's complement 135135644Scognet */ 136146597Scognetstatic u8 TEMP_TO_REG(long temp) 137135644Scognet{ 138135644Scognet int ntemp = clamp_val(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX); 139129198Scognet ntemp += (ntemp < 0 ? -500 : 500); 140166063Scognet return (u8)(ntemp / 1000); 141166063Scognet} 142166063Scognet 143135644Scognetstatic int TEMP_FROM_REG(u8 reg) 144135644Scognet{ 145135644Scognet return (s8)reg * 1000; 146156191Scognet} 147156191Scognet 148147591Scognet/* 149135644Scognet * PWM: 0 - 255 per sensors documentation 150166063Scognet * REG: (6.25% duty cycle per bit) 151166063Scognet */ 152166063Scognetstatic u8 ASB100_PWM_TO_REG(int pwm) 153166063Scognet{ 154129198Scognet pwm = clamp_val(pwm, 0, 255); 155129198Scognet return (u8)(pwm / 16); 156166063Scognet} 157166063Scognet 158166063Scognetstatic int ASB100_PWM_FROM_REG(u8 reg) 159147591Scognet{ 160147591Scognet return reg * 16; 161147591Scognet} 162146597Scognet 163146597Scognet#define DIV_FROM_REG(val) (1 << (val)) 164146597Scognet 165146597Scognet/* 166146597Scognet * FAN DIV: 1, 2, 4, or 8 (defaults to 2) 167146597Scognet * REG: 0, 1, 2, or 3 (respectively) (defaults to 1) 168146597Scognet */ 169166063Scognetstatic u8 DIV_TO_REG(long val) 170166063Scognet{ 171166063Scognet return val == 8 ? 3 : val == 4 ? 2 : val == 1 ? 0 : 1; 172166063Scognet} 173166063Scognet 174166063Scognet/* 175166063Scognet * For each registered client, we need to keep some data in memory. That 176166063Scognet * data is pointed to by client->data. The structure itself is 177166063Scognet * dynamically allocated, at the same time the client itself is allocated. 178166063Scognet */ 179166063Scognetstruct asb100_data { 180166063Scognet struct device *hwmon_dev; 181166063Scognet struct mutex lock; 182166063Scognet 183166063Scognet struct mutex update_lock; 184166063Scognet unsigned long last_updated; /* In jiffies */ 185166063Scognet 186166063Scognet /* array of 2 pointers to subclients */ 187166063Scognet struct i2c_client *lm75[2]; 188166063Scognet 189166063Scognet bool valid; /* true if following fields are valid */ 190166063Scognet u8 in[7]; /* Register value */ 191166063Scognet u8 in_max[7]; /* Register value */ 192166063Scognet u8 in_min[7]; /* Register value */ 193166063Scognet u8 fan[3]; /* Register value */ 194166063Scognet u8 fan_min[3]; /* Register value */ 195166063Scognet u16 temp[4]; /* Register value (0 and 3 are u8 only) */ 196166063Scognet u16 temp_max[4]; /* Register value (0 and 3 are u8 only) */ 197166063Scognet u16 temp_hyst[4]; /* Register value (0 and 3 are u8 only) */ 198166063Scognet u8 fan_div[3]; /* Register encoding, right justified */ 199166063Scognet u8 pwm; /* Register encoding */ 200166063Scognet u8 vid; /* Register encoding, combined */ 201166063Scognet u32 alarms; /* Register encoding, combined */ 202166063Scognet u8 vrm; 203166063Scognet}; 204166063Scognet 205166063Scognetstatic int asb100_read_value(struct i2c_client *client, u16 reg); 206166063Scognetstatic void asb100_write_value(struct i2c_client *client, u16 reg, u16 val); 207166063Scognet 208147591Scognetstatic int asb100_probe(struct i2c_client *client); 209147591Scognetstatic int asb100_detect(struct i2c_client *client, 210147591Scognet struct i2c_board_info *info); 211147591Scognetstatic void asb100_remove(struct i2c_client *client); 212147591Scognetstatic struct asb100_data *asb100_update_device(struct device *dev); 213147591Scognetstatic void asb100_init_client(struct i2c_client *client); 214147591Scognet 215147591Scognetstatic const struct i2c_device_id asb100_id[] = { 216147591Scognet { "asb100" }, 217147591Scognet { } 218147591Scognet}; 219129198ScognetMODULE_DEVICE_TABLE(i2c, asb100_id); 220129198Scognet 221129198Scognetstatic struct i2c_driver asb100_driver = { 222129198Scognet .class = I2C_CLASS_HWMON, 223137758Scognet .driver = { 224140349Scognet .name = "asb100", 225137758Scognet }, 226137760Scognet .probe = asb100_probe, 227135644Scognet .remove = asb100_remove, 228166063Scognet .id_table = asb100_id, 229166063Scognet .detect = asb100_detect, 230166063Scognet .address_list = normal_i2c, 231166063Scognet}; 232166063Scognet 233166063Scognet/* 7 Voltages */ 234166063Scognet#define show_in_reg(reg) \ 235166063Scognetstatic ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ 236166063Scognet char *buf) \ 237166063Scognet{ \ 238166063Scognet int nr = to_sensor_dev_attr(attr)->index; \ 239166063Scognet struct asb100_data *data = asb100_update_device(dev); \ 240166063Scognet return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \ 241129198Scognet} 242129198Scognet 243129198Scognetshow_in_reg(in) 244129198Scognetshow_in_reg(in_min) 245129198Scognetshow_in_reg(in_max) 246129198Scognet 247129198Scognet#define set_in_reg(REG, reg) \ 248129198Scognetstatic ssize_t set_in_##reg(struct device *dev, struct device_attribute *attr, \ 249129198Scognet const char *buf, size_t count) \ 250129198Scognet{ \ 251129198Scognet int nr = to_sensor_dev_attr(attr)->index; \ 252129198Scognet struct i2c_client *client = to_i2c_client(dev); \ 253129198Scognet struct asb100_data *data = i2c_get_clientdata(client); \ 254129198Scognet unsigned long val; \ 255129198Scognet int err = kstrtoul(buf, 10, &val); \ 256129198Scognet if (err) \ 257129198Scognet return err; \ 258129198Scognet mutex_lock(&data->update_lock); \ 259129198Scognet data->in_##reg[nr] = IN_TO_REG(val); \ 260129198Scognet asb100_write_value(client, ASB100_REG_IN_##REG(nr), \ 261129198Scognet data->in_##reg[nr]); \ 262129198Scognet mutex_unlock(&data->update_lock); \ 263129198Scognet return count; \ 264129198Scognet} 265129198Scognet 266129198Scognetset_in_reg(MIN, min) 267129198Scognetset_in_reg(MAX, max) 268129198Scognet 269129198Scognet#define sysfs_in(offset) \ 270129198Scognetstatic SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ 271129198Scognet show_in, NULL, offset); \ 272129198Scognetstatic SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ 273129198Scognet show_in_min, set_in_min, offset); \ 274129198Scognetstatic SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ 275129198Scognet show_in_max, set_in_max, offset) 276129198Scognet 277129198Scognetsysfs_in(0); 278129198Scognetsysfs_in(1); 279129198Scognetsysfs_in(2); 280129198Scognetsysfs_in(3); 281129198Scognetsysfs_in(4); 282129198Scognetsysfs_in(5); 283129198Scognetsysfs_in(6); 284129198Scognet 285129198Scognet/* 3 Fans */ 286129198Scognetstatic ssize_t show_fan(struct device *dev, struct device_attribute *attr, 287129198Scognet char *buf) 288129198Scognet{ 289129198Scognet int nr = to_sensor_dev_attr(attr)->index; 290129198Scognet struct asb100_data *data = asb100_update_device(dev); 291129198Scognet return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], 292129198Scognet DIV_FROM_REG(data->fan_div[nr]))); 293129198Scognet} 294129198Scognet 295129198Scognetstatic ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, 296147591Scognet char *buf) 297146597Scognet{ 298146597Scognet int nr = to_sensor_dev_attr(attr)->index; 299146597Scognet struct asb100_data *data = asb100_update_device(dev); 300146597Scognet return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], 301146597Scognet DIV_FROM_REG(data->fan_div[nr]))); 302147591Scognet} 303150860Scognet 304150860Scognetstatic ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, 305146597Scognet char *buf) 306147591Scognet{ 307166063Scognet int nr = to_sensor_dev_attr(attr)->index; 308147591Scognet struct asb100_data *data = asb100_update_device(dev); 309147591Scognet return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); 310147591Scognet} 311147591Scognet 312166063Scognetstatic ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, 313146597Scognet const char *buf, size_t count) 314146597Scognet{ 315146597Scognet int nr = to_sensor_dev_attr(attr)->index; 316147591Scognet struct i2c_client *client = to_i2c_client(dev); 317146597Scognet struct asb100_data *data = i2c_get_clientdata(client); 318146597Scognet unsigned long val; 319146597Scognet int err; 320146597Scognet 321146597Scognet err = kstrtoul(buf, 10, &val); 322146597Scognet if (err) 323147591Scognet return err; 324146597Scognet 325146597Scognet mutex_lock(&data->update_lock); 326146597Scognet data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); 327146597Scognet asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]); 328129198Scognet mutex_unlock(&data->update_lock); 329129198Scognet return count; 330129198Scognet} 331135644Scognet 332135644Scognet/* 333129198Scognet * Note: we save and restore the fan minimum here, because its value is 334129198Scognet * determined in part by the fan divisor. This follows the principle of 335129198Scognet * least surprise; the user doesn't expect the fan minimum to change just 336129198Scognet * because the divisor changed. 337129198Scognet */ 338129198Scognetstatic ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, 339129198Scognet const char *buf, size_t count) 340129198Scognet{ 341129198Scognet int nr = to_sensor_dev_attr(attr)->index; 342129198Scognet struct i2c_client *client = to_i2c_client(dev); 343129198Scognet struct asb100_data *data = i2c_get_clientdata(client); 344129198Scognet unsigned long min; 345166063Scognet int reg; 346166063Scognet unsigned long val; 347129198Scognet int err; 348129198Scognet 349140313Scognet err = kstrtoul(buf, 10, &val); 350143294Smux if (err) 351143284Smux return err; 352129198Scognet 353140313Scognet mutex_lock(&data->update_lock); 354129198Scognet 355129198Scognet min = FAN_FROM_REG(data->fan_min[nr], 356129198Scognet DIV_FROM_REG(data->fan_div[nr])); 357129198Scognet data->fan_div[nr] = DIV_TO_REG(val); 358129198Scognet 359129198Scognet switch (nr) { 360129198Scognet case 0: /* fan 1 */ 361129198Scognet reg = asb100_read_value(client, ASB100_REG_VID_FANDIV); 362129198Scognet reg = (reg & 0xcf) | (data->fan_div[0] << 4); 363129198Scognet asb100_write_value(client, ASB100_REG_VID_FANDIV, reg); 364129198Scognet break; 365129198Scognet 366129198Scognet case 1: /* fan 2 */ 367129198Scognet reg = asb100_read_value(client, ASB100_REG_VID_FANDIV); 368129198Scognet reg = (reg & 0x3f) | (data->fan_div[1] << 6); 369135644Scognet asb100_write_value(client, ASB100_REG_VID_FANDIV, reg); 370129198Scognet break; 371129198Scognet 372129198Scognet case 2: /* fan 3 */ 373129198Scognet reg = asb100_read_value(client, ASB100_REG_PIN); 374129198Scognet reg = (reg & 0x3f) | (data->fan_div[2] << 6); 375129198Scognet asb100_write_value(client, ASB100_REG_PIN, reg); 376129198Scognet break; 377129198Scognet } 378129198Scognet 379129198Scognet data->fan_min[nr] = 380129198Scognet FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); 381129198Scognet asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]); 382129198Scognet 383134934Sscottl mutex_unlock(&data->update_lock); 384134934Sscottl 385134934Sscottl return count; 386134934Sscottl} 387134934Sscottl 388166063Scognet#define sysfs_fan(offset) \ 389166063Scognetstatic SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ 390166063Scognet show_fan, NULL, offset - 1); \ 391129198Scognetstatic SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ 392129198Scognet show_fan_min, set_fan_min, offset - 1); \ 393129198Scognetstatic SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ 394129198Scognet show_fan_div, set_fan_div, offset - 1) 395129198Scognet 396129198Scognetsysfs_fan(1); 397129198Scognetsysfs_fan(2); 398129198Scognetsysfs_fan(3); 399129198Scognet 400129198Scognet/* 4 Temp. Sensors */ 401129198Scognetstatic int sprintf_temp_from_reg(u16 reg, char *buf, int nr) 402129198Scognet{ 403166063Scognet int ret = 0; 404166063Scognet 405166063Scognet switch (nr) { 406129198Scognet case 1: case 2: 407166063Scognet ret = sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(reg)); 408166063Scognet break; 409166063Scognet case 0: case 3: default: 410166063Scognet ret = sprintf(buf, "%d\n", TEMP_FROM_REG(reg)); 411166063Scognet break; 412166063Scognet } 413166063Scognet return ret; 414166063Scognet} 415166063Scognet 416166063Scognet#define show_temp_reg(reg) \ 417166063Scognetstatic ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ 418166063Scognet char *buf) \ 419166063Scognet{ \ 420166063Scognet int nr = to_sensor_dev_attr(attr)->index; \ 421166063Scognet struct asb100_data *data = asb100_update_device(dev); \ 422166063Scognet return sprintf_temp_from_reg(data->reg[nr], buf, nr); \ 423166063Scognet} 424166063Scognet 425166063Scognetshow_temp_reg(temp); 426166063Scognetshow_temp_reg(temp_max); 427166063Scognetshow_temp_reg(temp_hyst); 428166063Scognet 429166063Scognet#define set_temp_reg(REG, reg) \ 430170502Scognetstatic ssize_t set_##reg(struct device *dev, struct device_attribute *attr, \ 431170502Scognet const char *buf, size_t count) \ 432166063Scognet{ \ 433166063Scognet int nr = to_sensor_dev_attr(attr)->index; \ 434166063Scognet struct i2c_client *client = to_i2c_client(dev); \ 435166063Scognet struct asb100_data *data = i2c_get_clientdata(client); \ 436143294Smux long val; \ 437143284Smux int err = kstrtol(buf, 10, &val); \ 438140313Scognet if (err) \ 439129198Scognet return err; \ 440129198Scognet mutex_lock(&data->update_lock); \ 441129198Scognet switch (nr) { \ 442129198Scognet case 1: case 2: \ 443129198Scognet data->reg[nr] = LM75_TEMP_TO_REG(val); \ 444129198Scognet break; \ 445140680Scognet case 0: case 3: default: \ 446140313Scognet data->reg[nr] = TEMP_TO_REG(val); \ 447140680Scognet break; \ 448140313Scognet } \ 449129198Scognet asb100_write_value(client, ASB100_REG_TEMP_##REG(nr+1), \ 450129198Scognet data->reg[nr]); \ 451129198Scognet mutex_unlock(&data->update_lock); \ 452129198Scognet return count; \ 453129198Scognet} 454129198Scognet 455129198Scognetset_temp_reg(MAX, temp_max); 456129198Scognetset_temp_reg(HYST, temp_hyst); 457129198Scognet 458129198Scognet#define sysfs_temp(num) \ 459129198Scognetstatic SENSOR_DEVICE_ATTR(temp##num##_input, S_IRUGO, \ 460129198Scognet show_temp, NULL, num - 1); \ 461129198Scognetstatic SENSOR_DEVICE_ATTR(temp##num##_max, S_IRUGO | S_IWUSR, \ 462129198Scognet show_temp_max, set_temp_max, num - 1); \ 463129198Scognetstatic SENSOR_DEVICE_ATTR(temp##num##_max_hyst, S_IRUGO | S_IWUSR, \ 464129198Scognet show_temp_hyst, set_temp_hyst, num - 1) 465129198Scognet 466129198Scognetsysfs_temp(1); 467129198Scognetsysfs_temp(2); 468129198Scognetsysfs_temp(3); 469129198Scognetsysfs_temp(4); 470129198Scognet 471143294Smux/* VID */ 472140313Scognetstatic ssize_t cpu0_vid_show(struct device *dev, 473129198Scognet struct device_attribute *attr, char *buf) 474129198Scognet{ 475129198Scognet struct asb100_data *data = asb100_update_device(dev); 476166063Scognet return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); 477129198Scognet} 478129198Scognet 479129198Scognetstatic DEVICE_ATTR_RO(cpu0_vid); 480129198Scognet 481129198Scognet/* VRM */ 482129198Scognetstatic ssize_t vrm_show(struct device *dev, struct device_attribute *attr, 483129198Scognet char *buf) 484129198Scognet{ 485140313Scognet struct asb100_data *data = dev_get_drvdata(dev); 486129198Scognet return sprintf(buf, "%d\n", data->vrm); 487146597Scognet} 488140313Scognet 489143294Smuxstatic ssize_t vrm_store(struct device *dev, struct device_attribute *attr, 490129198Scognet const char *buf, size_t count) 491140313Scognet{ 492129198Scognet struct asb100_data *data = dev_get_drvdata(dev); 493135644Scognet unsigned long val; 494161618Scognet int err; 495129198Scognet 496129198Scognet err = kstrtoul(buf, 10, &val); 497166063Scognet if (err) 498166063Scognet return err; 499166063Scognet 500166063Scognet if (val > 255) 501166063Scognet return -EINVAL; 502166063Scognet 503166063Scognet data->vrm = val; 504166063Scognet return count; 505166063Scognet} 506166063Scognet 507166063Scognet/* Alarms */ 508166063Scognetstatic DEVICE_ATTR_RW(vrm); 509166063Scognet 510166063Scognetstatic ssize_t alarms_show(struct device *dev, struct device_attribute *attr, 511166063Scognet char *buf) 512166063Scognet{ 513166063Scognet struct asb100_data *data = asb100_update_device(dev); 514166063Scognet return sprintf(buf, "%u\n", data->alarms); 515166063Scognet} 516166063Scognet 517166063Scognetstatic DEVICE_ATTR_RO(alarms); 518166063Scognet 519166063Scognetstatic ssize_t show_alarm(struct device *dev, struct device_attribute *attr, 520166063Scognet char *buf) 521166063Scognet{ 522166063Scognet int bitnr = to_sensor_dev_attr(attr)->index; 523166063Scognet struct asb100_data *data = asb100_update_device(dev); 524166063Scognet return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); 525166063Scognet} 526166063Scognetstatic SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); 527166063Scognetstatic SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); 528166063Scognetstatic SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); 529166063Scognetstatic SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); 530166063Scognetstatic SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); 531166063Scognetstatic SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); 532166063Scognetstatic SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); 533166063Scognetstatic SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); 534166063Scognetstatic SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); 535166063Scognetstatic SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); 536166063Scognetstatic SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13); 537166063Scognet 538166063Scognet/* 1 PWM */ 539166063Scognetstatic ssize_t pwm1_show(struct device *dev, struct device_attribute *attr, 540166063Scognet char *buf) 541166063Scognet{ 542166063Scognet struct asb100_data *data = asb100_update_device(dev); 543143294Smux return sprintf(buf, "%d\n", ASB100_PWM_FROM_REG(data->pwm & 0x0f)); 544143284Smux} 545140313Scognet 546129198Scognetstatic ssize_t pwm1_store(struct device *dev, struct device_attribute *attr, 547129198Scognet const char *buf, size_t count) 548129198Scognet{ 549129198Scognet struct i2c_client *client = to_i2c_client(dev); 550129198Scognet struct asb100_data *data = i2c_get_clientdata(client); 551129198Scognet unsigned long val; 552129198Scognet int err; 553129198Scognet 554129198Scognet err = kstrtoul(buf, 10, &val); 555129198Scognet if (err) 556135644Scognet return err; 557146597Scognet 558166063Scognet mutex_lock(&data->update_lock); 559166063Scognet data->pwm &= 0x80; /* keep the enable bit */ 560166063Scognet data->pwm |= (0x0f & ASB100_PWM_TO_REG(val)); 561166063Scognet asb100_write_value(client, ASB100_REG_PWM1, data->pwm); 562166063Scognet mutex_unlock(&data->update_lock); 563129198Scognet return count; 564143294Smux} 565129198Scognet 566129198Scognetstatic ssize_t pwm1_enable_show(struct device *dev, 567129198Scognet struct device_attribute *attr, char *buf) 568129198Scognet{ 569129198Scognet struct asb100_data *data = asb100_update_device(dev); 570129198Scognet return sprintf(buf, "%d\n", (data->pwm & 0x80) ? 1 : 0); 571129198Scognet} 572129198Scognet 573129198Scognetstatic ssize_t pwm1_enable_store(struct device *dev, 574129198Scognet struct device_attribute *attr, 575129198Scognet const char *buf, size_t count) 576129198Scognet{ 577135644Scognet struct i2c_client *client = to_i2c_client(dev); 578129198Scognet struct asb100_data *data = i2c_get_clientdata(client); 579129198Scognet unsigned long val; 580129198Scognet int err; 581129198Scognet 582129198Scognet err = kstrtoul(buf, 10, &val); 583129198Scognet if (err) 584129198Scognet return err; 585129198Scognet 586129198Scognet mutex_lock(&data->update_lock); 587129198Scognet data->pwm &= 0x0f; /* keep the duty cycle bits */ 588146597Scognet data->pwm |= (val ? 0x80 : 0x00); 589143671Sjmg asb100_write_value(client, ASB100_REG_PWM1, data->pwm); 590143671Sjmg mutex_unlock(&data->update_lock); 591143671Sjmg return count; 592143671Sjmg} 593135644Scognet 594143671Sjmgstatic DEVICE_ATTR_RW(pwm1); 595143671Sjmgstatic DEVICE_ATTR_RW(pwm1_enable); 596143671Sjmg 597135644Scognetstatic struct attribute *asb100_attributes[] = { 598166063Scognet &sensor_dev_attr_in0_input.dev_attr.attr, 599166063Scognet &sensor_dev_attr_in0_min.dev_attr.attr, 600166063Scognet &sensor_dev_attr_in0_max.dev_attr.attr, 601129198Scognet &sensor_dev_attr_in1_input.dev_attr.attr, 602129198Scognet &sensor_dev_attr_in1_min.dev_attr.attr, 603129198Scognet &sensor_dev_attr_in1_max.dev_attr.attr, 604129198Scognet &sensor_dev_attr_in2_input.dev_attr.attr, 605129198Scognet &sensor_dev_attr_in2_min.dev_attr.attr, 606129198Scognet &sensor_dev_attr_in2_max.dev_attr.attr, 607129198Scognet &sensor_dev_attr_in3_input.dev_attr.attr, 608129198Scognet &sensor_dev_attr_in3_min.dev_attr.attr, 609129198Scognet &sensor_dev_attr_in3_max.dev_attr.attr, 610129198Scognet &sensor_dev_attr_in4_input.dev_attr.attr, 611129198Scognet &sensor_dev_attr_in4_min.dev_attr.attr, 612140313Scognet &sensor_dev_attr_in4_max.dev_attr.attr, 613140313Scognet &sensor_dev_attr_in5_input.dev_attr.attr, 614146597Scognet &sensor_dev_attr_in5_min.dev_attr.attr, 615140313Scognet &sensor_dev_attr_in5_max.dev_attr.attr, 616140313Scognet &sensor_dev_attr_in6_input.dev_attr.attr, 617129198Scognet &sensor_dev_attr_in6_min.dev_attr.attr, 618129198Scognet &sensor_dev_attr_in6_max.dev_attr.attr, 619129198Scognet 620156191Scognet &sensor_dev_attr_fan1_input.dev_attr.attr, 621156191Scognet &sensor_dev_attr_fan1_min.dev_attr.attr, 622156191Scognet &sensor_dev_attr_fan1_div.dev_attr.attr, 623156191Scognet &sensor_dev_attr_fan2_input.dev_attr.attr, 624156191Scognet &sensor_dev_attr_fan2_min.dev_attr.attr, 625156191Scognet &sensor_dev_attr_fan2_div.dev_attr.attr, 626156191Scognet &sensor_dev_attr_fan3_input.dev_attr.attr, 627156191Scognet &sensor_dev_attr_fan3_min.dev_attr.attr, 628156191Scognet &sensor_dev_attr_fan3_div.dev_attr.attr, 629156191Scognet 630156191Scognet &sensor_dev_attr_temp1_input.dev_attr.attr, 631156191Scognet &sensor_dev_attr_temp1_max.dev_attr.attr, 632183838Sraj &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, 633183838Sraj &sensor_dev_attr_temp2_input.dev_attr.attr, 634156191Scognet &sensor_dev_attr_temp2_max.dev_attr.attr, 635156191Scognet &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, 636156191Scognet &sensor_dev_attr_temp3_input.dev_attr.attr, 637156191Scognet &sensor_dev_attr_temp3_max.dev_attr.attr, 638156191Scognet &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, 639129198Scognet &sensor_dev_attr_temp4_input.dev_attr.attr, 640129198Scognet &sensor_dev_attr_temp4_max.dev_attr.attr, 641129198Scognet &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, 642129198Scognet 643129198Scognet &sensor_dev_attr_in0_alarm.dev_attr.attr, 644129198Scognet &sensor_dev_attr_in1_alarm.dev_attr.attr, 645129198Scognet &sensor_dev_attr_in2_alarm.dev_attr.attr, 646129198Scognet &sensor_dev_attr_in3_alarm.dev_attr.attr, 647129198Scognet &sensor_dev_attr_in4_alarm.dev_attr.attr, 648129198Scognet &sensor_dev_attr_fan1_alarm.dev_attr.attr, 649156191Scognet &sensor_dev_attr_fan2_alarm.dev_attr.attr, 650156191Scognet &sensor_dev_attr_fan3_alarm.dev_attr.attr, 651156191Scognet &sensor_dev_attr_temp1_alarm.dev_attr.attr, 652156191Scognet &sensor_dev_attr_temp2_alarm.dev_attr.attr, 653156191Scognet &sensor_dev_attr_temp3_alarm.dev_attr.attr, 654156191Scognet 655166063Scognet &dev_attr_cpu0_vid.attr, 656166063Scognet &dev_attr_vrm.attr, 657166063Scognet &dev_attr_alarms.attr, 658129198Scognet &dev_attr_pwm1.attr, 659129198Scognet &dev_attr_pwm1_enable.attr, 660129198Scognet 661129198Scognet NULL 662135644Scognet}; 663146597Scognet 664143294Smuxstatic const struct attribute_group asb100_group = { 665129198Scognet .attrs = asb100_attributes, 666129198Scognet}; 667166063Scognet 668166063Scognetstatic int asb100_detect_subclients(struct i2c_client *client) 669173988Sjhb{ 670166063Scognet int i, id, err; 671166063Scognet int address = client->addr; 672166063Scognet unsigned short sc_addr[2]; 673166063Scognet struct asb100_data *data = i2c_get_clientdata(client); 674166063Scognet struct i2c_adapter *adapter = client->adapter; 675166063Scognet 676185494Sstas id = i2c_adapter_id(adapter); 677185494Sstas 678170406Scognet if (force_subclients[0] == id && force_subclients[1] == address) { 679170406Scognet for (i = 2; i <= 3; i++) { 680166063Scognet if (force_subclients[i] < 0x48 || 681166063Scognet force_subclients[i] > 0x4f) { 682166063Scognet dev_err(&client->dev, 683166063Scognet "invalid subclient address %d; must be 0x48-0x4f\n", 684166063Scognet force_subclients[i]); 685166063Scognet err = -ENODEV; 686166063Scognet goto ERROR_SC_2; 687166063Scognet } 688166063Scognet } 689166063Scognet asb100_write_value(client, ASB100_REG_I2C_SUBADDR, 690173988Sjhb (force_subclients[2] & 0x07) | 691166063Scognet ((force_subclients[3] & 0x07) << 4)); 692166063Scognet sc_addr[0] = force_subclients[2]; 693166063Scognet sc_addr[1] = force_subclients[3]; 694166063Scognet } else { 695166063Scognet int val = asb100_read_value(client, ASB100_REG_I2C_SUBADDR); 696166063Scognet sc_addr[0] = 0x48 + (val & 0x07); 697166063Scognet sc_addr[1] = 0x48 + ((val >> 4) & 0x07); 698166063Scognet } 699166063Scognet 700166063Scognet if (sc_addr[0] == sc_addr[1]) { 701166063Scognet dev_err(&client->dev, 702166063Scognet "duplicate addresses 0x%x for subclients\n", 703166063Scognet sc_addr[0]); 704166063Scognet err = -ENODEV; 705166063Scognet goto ERROR_SC_2; 706166063Scognet } 707166063Scognet 708166063Scognet data->lm75[0] = i2c_new_dummy_device(adapter, sc_addr[0]); 709166063Scognet if (IS_ERR(data->lm75[0])) { 710166063Scognet dev_err(&client->dev, 711166063Scognet "subclient %d registration at address 0x%x failed.\n", 712166063Scognet 1, sc_addr[0]); 713166063Scognet err = PTR_ERR(data->lm75[0]); 714166063Scognet goto ERROR_SC_2; 715166063Scognet } 716166063Scognet 717166063Scognet data->lm75[1] = i2c_new_dummy_device(adapter, sc_addr[1]); 718166063Scognet if (IS_ERR(data->lm75[1])) { 719166063Scognet dev_err(&client->dev, 720129198Scognet "subclient %d registration at address 0x%x failed.\n", 721129198Scognet 2, sc_addr[1]); 722129198Scognet err = PTR_ERR(data->lm75[1]); 723129198Scognet goto ERROR_SC_3; 724129198Scognet } 725129198Scognet 726147591Scognet return 0; 727140349Scognet 728137758Scognet/* Undo inits in case of errors */ 729137760ScognetERROR_SC_3: 730129198Scognet i2c_unregister_device(data->lm75[0]); 731129198ScognetERROR_SC_2: 732129198Scognet return err; 733129198Scognet} 734129198Scognet 735129198Scognet/* Return 0 if detection is successful, -ENODEV otherwise */ 736129198Scognetstatic int asb100_detect(struct i2c_client *client, 737129198Scognet struct i2c_board_info *info) 738129198Scognet{ 739129198Scognet struct i2c_adapter *adapter = client->adapter; 740129198Scognet int val1, val2; 741129198Scognet 742129198Scognet if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 743166063Scognet pr_debug("detect failed, smbus byte data not supported!\n"); 744173988Sjhb return -ENODEV; 745166063Scognet } 746166063Scognet 747166063Scognet val1 = i2c_smbus_read_byte_data(client, ASB100_REG_BANK); 748140313Scognet val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN); 749140313Scognet 750140313Scognet /* If we're in bank 0 */ 751129198Scognet if ((!(val1 & 0x07)) && 752129198Scognet /* Check for ASB100 ID (low byte) */ 753129198Scognet (((!(val1 & 0x80)) && (val2 != 0x94)) || 754129198Scognet /* Check for ASB100 ID (high byte ) */ 755129198Scognet ((val1 & 0x80) && (val2 != 0x06)))) { 756129198Scognet pr_debug("detect failed, bad chip id 0x%02x!\n", val2); 757129198Scognet return -ENODEV; 758147591Scognet } 759177103Sraj 760177103Sraj /* Put it now into bank 0 and Vendor ID High Byte */ 761177103Sraj i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 762129198Scognet (i2c_smbus_read_byte_data(client, ASB100_REG_BANK) & 0x78) 763171623Scognet | 0x80); 764171623Scognet 765171623Scognet /* Determine the chip type. */ 766171623Scognet val1 = i2c_smbus_read_byte_data(client, ASB100_REG_WCHIPID); 767171623Scognet val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN); 768171623Scognet 769129198Scognet if (val1 != 0x31 || val2 != 0x06) 770129198Scognet return -ENODEV; 771135644Scognet 772129198Scognet strscpy(info->type, "asb100", I2C_NAME_SIZE); 773129198Scognet 774129198Scognet return 0; 775129198Scognet} 776132514Scognet 777129198Scognetstatic int asb100_probe(struct i2c_client *client) 778129198Scognet{ 779129198Scognet int err; 780129198Scognet struct asb100_data *data; 781129198Scognet 782129198Scognet data = devm_kzalloc(&client->dev, sizeof(struct asb100_data), 783135644Scognet GFP_KERNEL); 784135644Scognet if (!data) 785129198Scognet return -ENOMEM; 786129198Scognet 787129198Scognet i2c_set_clientdata(client, data); 788129198Scognet mutex_init(&data->lock); 789129198Scognet mutex_init(&data->update_lock); 790129198Scognet 791135644Scognet /* Attach secondary lm75 clients */ 792129198Scognet err = asb100_detect_subclients(client); 793129198Scognet if (err) 794129198Scognet return err; 795129198Scognet 796129198Scognet /* Initialize the chip */ 797135644Scognet asb100_init_client(client); 798129198Scognet 799129198Scognet /* A few vars need to be filled upon startup */ 800129198Scognet data->fan_min[0] = asb100_read_value(client, ASB100_REG_FAN_MIN(0)); 801129198Scognet data->fan_min[1] = asb100_read_value(client, ASB100_REG_FAN_MIN(1)); 802129198Scognet data->fan_min[2] = asb100_read_value(client, ASB100_REG_FAN_MIN(2)); 803129198Scognet 804170086Syongari /* Register sysfs hooks */ 805170086Syongari err = sysfs_create_group(&client->dev.kobj, &asb100_group); 806129198Scognet if (err) 807129198Scognet goto ERROR3; 808129198Scognet 809129198Scognet data->hwmon_dev = hwmon_device_register(&client->dev); 810129198Scognet if (IS_ERR(data->hwmon_dev)) { 811129198Scognet err = PTR_ERR(data->hwmon_dev); 812129198Scognet goto ERROR4; 813129198Scognet } 814129198Scognet 815129198Scognet return 0; 816129198Scognet 817166063ScognetERROR4: 818166063Scognet sysfs_remove_group(&client->dev.kobj, &asb100_group); 819166063ScognetERROR3: 820129198Scognet i2c_unregister_device(data->lm75[1]); 821166063Scognet i2c_unregister_device(data->lm75[0]); 822166063Scognet return err; 823166063Scognet} 824166063Scognet 825166063Scognetstatic void asb100_remove(struct i2c_client *client) 826166063Scognet{ 827166063Scognet struct asb100_data *data = i2c_get_clientdata(client); 828166063Scognet 829166063Scognet hwmon_device_unregister(data->hwmon_dev); 830166063Scognet sysfs_remove_group(&client->dev.kobj, &asb100_group); 831166063Scognet 832166063Scognet i2c_unregister_device(data->lm75[1]); 833166063Scognet i2c_unregister_device(data->lm75[0]); 834166063Scognet} 835166063Scognet 836129198Scognet/* 837129198Scognet * The SMBus locks itself, usually, but nothing may access the chip between 838129198Scognet * bank switches. 839129198Scognet */ 840173988Sjhbstatic int asb100_read_value(struct i2c_client *client, u16 reg) 841137760Scognet{ 842137760Scognet struct asb100_data *data = i2c_get_clientdata(client); 843137760Scognet struct i2c_client *cl; 844137760Scognet int res, bank; 845137760Scognet 846140349Scognet mutex_lock(&data->lock); 847137760Scognet 848137760Scognet bank = (reg >> 8) & 0x0f; 849137760Scognet if (bank > 2) 850129198Scognet /* switch banks */ 851129198Scognet i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank); 852129198Scognet 853135644Scognet if (bank == 0 || bank > 2) { 854135644Scognet res = i2c_smbus_read_byte_data(client, reg & 0xff); 855135644Scognet } else { 856129198Scognet /* switch to subclient */ 857129198Scognet cl = data->lm75[bank - 1]; 858129198Scognet 859129198Scognet /* convert from ISA to LM75 I2C addresses */ 860129198Scognet switch (reg & 0xff) { 861129198Scognet case 0x50: /* TEMP */ 862129198Scognet res = i2c_smbus_read_word_swapped(cl, 0); 863129198Scognet break; 864129198Scognet case 0x52: /* CONFIG */ 865129198Scognet res = i2c_smbus_read_byte_data(cl, 1); 866129198Scognet break; 867129198Scognet case 0x53: /* HYST */ 868129198Scognet res = i2c_smbus_read_word_swapped(cl, 2); 869129198Scognet break; 870129198Scognet case 0x55: /* MAX */ 871129198Scognet default: 872129198Scognet res = i2c_smbus_read_word_swapped(cl, 3); 873140682Scognet break; 874140682Scognet } 875140682Scognet } 876140682Scognet 877140682Scognet if (bank > 2) 878140682Scognet i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0); 879140682Scognet 880140682Scognet mutex_unlock(&data->lock); 881140682Scognet 882143063Sjoerg return res; 883140682Scognet} 884140682Scognet 885140682Scognetstatic void asb100_write_value(struct i2c_client *client, u16 reg, u16 value) 886140682Scognet{ 887140682Scognet struct asb100_data *data = i2c_get_clientdata(client); 888143671Sjmg struct i2c_client *cl; 889143671Sjmg int bank; 890166063Scognet 891166063Scognet mutex_lock(&data->lock); 892140682Scognet 893140682Scognet bank = (reg >> 8) & 0x0f; 894140682Scognet if (bank > 2) 895140682Scognet /* switch banks */ 896140682Scognet i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank); 897140682Scognet 898140682Scognet if (bank == 0 || bank > 2) { 899166063Scognet i2c_smbus_write_byte_data(client, reg & 0xff, value & 0xff); 900166063Scognet } else { 901140682Scognet /* switch to subclient */ 902140682Scognet cl = data->lm75[bank - 1]; 903140682Scognet 904140682Scognet /* convert from ISA to LM75 I2C addresses */ 905140682Scognet switch (reg & 0xff) { 906143294Smux case 0x52: /* CONFIG */ 907143284Smux i2c_smbus_write_byte_data(cl, 1, value & 0xff); 908140682Scognet break; 909177103Sraj case 0x53: /* HYST */ 910140682Scognet i2c_smbus_write_word_swapped(cl, 2, value); 911140682Scognet break; 912140682Scognet case 0x55: /* MAX */ 913129198Scognet i2c_smbus_write_word_swapped(cl, 3, value); 914129198Scognet break; 915129198Scognet } 916129198Scognet } 917129198Scognet 918129198Scognet if (bank > 2) 919129198Scognet i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0); 920143063Sjoerg 921129198Scognet mutex_unlock(&data->lock); 922129198Scognet} 923129198Scognet 924129198Scognetstatic void asb100_init_client(struct i2c_client *client) 925137760Scognet{ 926129198Scognet struct asb100_data *data = i2c_get_clientdata(client); 927129198Scognet 928129198Scognet data->vrm = vid_which_vrm(); 929135644Scognet 930135644Scognet /* Start monitoring */ 931135644Scognet asb100_write_value(client, ASB100_REG_CONFIG, 932146597Scognet (asb100_read_value(client, ASB100_REG_CONFIG) & 0xf7) | 0x01); 933129198Scognet} 934129198Scognet 935129198Scognetstatic struct asb100_data *asb100_update_device(struct device *dev) 936129198Scognet{ 937129198Scognet struct i2c_client *client = to_i2c_client(dev); 938146597Scognet struct asb100_data *data = i2c_get_clientdata(client); 939129198Scognet int i; 940137758Scognet 941137760Scognet mutex_lock(&data->update_lock); 942146597Scognet 943146597Scognet if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 944129198Scognet || !data->valid) { 945129198Scognet 946129198Scognet dev_dbg(&client->dev, "starting device update...\n"); 947129198Scognet 948129198Scognet /* 7 voltage inputs */ 949129198Scognet for (i = 0; i < 7; i++) { 950129198Scognet data->in[i] = asb100_read_value(client, 951129198Scognet ASB100_REG_IN(i)); 952129198Scognet data->in_min[i] = asb100_read_value(client, 953129198Scognet ASB100_REG_IN_MIN(i)); 954129198Scognet data->in_max[i] = asb100_read_value(client, 955135644Scognet ASB100_REG_IN_MAX(i)); 956129198Scognet } 957129198Scognet 958143294Smux /* 3 fan inputs */ 959143284Smux for (i = 0; i < 3; i++) { 960140313Scognet data->fan[i] = asb100_read_value(client, 961129198Scognet ASB100_REG_FAN(i)); 962129198Scognet data->fan_min[i] = asb100_read_value(client, 963129198Scognet ASB100_REG_FAN_MIN(i)); 964140310Scognet } 965140310Scognet 966140310Scognet /* 4 temperature inputs */ 967140310Scognet for (i = 1; i <= 4; i++) { 968140310Scognet data->temp[i-1] = asb100_read_value(client, 969140310Scognet ASB100_REG_TEMP(i)); 970140310Scognet data->temp_max[i-1] = asb100_read_value(client, 971140310Scognet ASB100_REG_TEMP_MAX(i)); 972140310Scognet data->temp_hyst[i-1] = asb100_read_value(client, 973140310Scognet ASB100_REG_TEMP_HYST(i)); 974140349Scognet } 975140349Scognet 976140349Scognet /* VID and fan divisors */ 977146597Scognet i = asb100_read_value(client, ASB100_REG_VID_FANDIV); 978140310Scognet data->vid = i & 0x0f; 979140310Scognet data->vid |= (asb100_read_value(client, 980140310Scognet ASB100_REG_CHIPID) & 0x01) << 4; 981140310Scognet data->fan_div[0] = (i >> 4) & 0x03; 982140310Scognet data->fan_div[1] = (i >> 6) & 0x03; 983140310Scognet data->fan_div[2] = (asb100_read_value(client, 984140310Scognet ASB100_REG_PIN) >> 6) & 0x03; 985140310Scognet 986140310Scognet /* PWM */ 987140310Scognet data->pwm = asb100_read_value(client, ASB100_REG_PWM1); 988146597Scognet 989140310Scognet /* alarms */ 990140310Scognet data->alarms = asb100_read_value(client, ASB100_REG_ALARM1) + 991140310Scognet (asb100_read_value(client, ASB100_REG_ALARM2) << 8); 992140310Scognet 993140310Scognet data->last_updated = jiffies; 994140310Scognet data->valid = true; 995140310Scognet 996140310Scognet dev_dbg(&client->dev, "... device update complete\n"); 997143294Smux } 998143284Smux 999140310Scognet mutex_unlock(&data->update_lock); 1000140310Scognet 1001140310Scognet return data; 1002129198Scognet} 1003129198Scognet 1004129198Scognetmodule_i2c_driver(asb100_driver); 1005129198Scognet 1006129198ScognetMODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); 1007129198ScognetMODULE_DESCRIPTION("ASB100 Bach driver"); 1008129198ScognetMODULE_LICENSE("GPL"); 1009129198Scognet