diff options
Diffstat (limited to 'drivers/hwmon/adm1026.c')
-rw-r--r-- | drivers/hwmon/adm1026.c | 632 |
1 files changed, 360 insertions, 272 deletions
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 3e63c1486770..8002f68240c4 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -40,8 +40,8 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(adm1026); -static int gpio_input[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 }; +static int gpio_input[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 }; static int gpio_output[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; static int gpio_inverted[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -49,46 +49,49 @@ static int gpio_inverted[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, static int gpio_normal[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; static int gpio_fan[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -module_param_array(gpio_input,int,NULL,0); -MODULE_PARM_DESC(gpio_input,"List of GPIO pins (0-16) to program as inputs"); -module_param_array(gpio_output,int,NULL,0); -MODULE_PARM_DESC(gpio_output,"List of GPIO pins (0-16) to program as " +module_param_array(gpio_input, int, NULL, 0); +MODULE_PARM_DESC(gpio_input, "List of GPIO pins (0-16) to program as inputs"); +module_param_array(gpio_output, int, NULL, 0); +MODULE_PARM_DESC(gpio_output, "List of GPIO pins (0-16) to program as " "outputs"); -module_param_array(gpio_inverted,int,NULL,0); -MODULE_PARM_DESC(gpio_inverted,"List of GPIO pins (0-16) to program as " +module_param_array(gpio_inverted, int, NULL, 0); +MODULE_PARM_DESC(gpio_inverted, "List of GPIO pins (0-16) to program as " "inverted"); -module_param_array(gpio_normal,int,NULL,0); -MODULE_PARM_DESC(gpio_normal,"List of GPIO pins (0-16) to program as " +module_param_array(gpio_normal, int, NULL, 0); +MODULE_PARM_DESC(gpio_normal, "List of GPIO pins (0-16) to program as " "normal/non-inverted"); -module_param_array(gpio_fan,int,NULL,0); -MODULE_PARM_DESC(gpio_fan,"List of GPIO pins (0-7) to program as fan tachs"); +module_param_array(gpio_fan, int, NULL, 0); +MODULE_PARM_DESC(gpio_fan, "List of GPIO pins (0-7) to program as fan tachs"); /* Many ADM1026 constants specified below */ /* The ADM1026 registers */ -#define ADM1026_REG_CONFIG1 0x00 -#define CFG1_MONITOR 0x01 -#define CFG1_INT_ENABLE 0x02 -#define CFG1_INT_CLEAR 0x04 -#define CFG1_AIN8_9 0x08 -#define CFG1_THERM_HOT 0x10 -#define CFG1_DAC_AFC 0x20 -#define CFG1_PWM_AFC 0x40 -#define CFG1_RESET 0x80 -#define ADM1026_REG_CONFIG2 0x01 +#define ADM1026_REG_CONFIG1 0x00 +#define CFG1_MONITOR 0x01 +#define CFG1_INT_ENABLE 0x02 +#define CFG1_INT_CLEAR 0x04 +#define CFG1_AIN8_9 0x08 +#define CFG1_THERM_HOT 0x10 +#define CFG1_DAC_AFC 0x20 +#define CFG1_PWM_AFC 0x40 +#define CFG1_RESET 0x80 + +#define ADM1026_REG_CONFIG2 0x01 /* CONFIG2 controls FAN0/GPIO0 through FAN7/GPIO7 */ -#define ADM1026_REG_CONFIG3 0x07 -#define CFG3_GPIO16_ENABLE 0x01 -#define CFG3_CI_CLEAR 0x02 -#define CFG3_VREF_250 0x04 -#define CFG3_GPIO16_DIR 0x40 -#define CFG3_GPIO16_POL 0x80 -#define ADM1026_REG_E2CONFIG 0x13 -#define E2CFG_READ 0x01 -#define E2CFG_WRITE 0x02 -#define E2CFG_ERASE 0x04 -#define E2CFG_ROM 0x08 -#define E2CFG_CLK_EXT 0x80 + +#define ADM1026_REG_CONFIG3 0x07 +#define CFG3_GPIO16_ENABLE 0x01 +#define CFG3_CI_CLEAR 0x02 +#define CFG3_VREF_250 0x04 +#define CFG3_GPIO16_DIR 0x40 +#define CFG3_GPIO16_POL 0x80 + +#define ADM1026_REG_E2CONFIG 0x13 +#define E2CFG_READ 0x01 +#define E2CFG_WRITE 0x02 +#define E2CFG_ERASE 0x04 +#define E2CFG_ROM 0x08 +#define E2CFG_CLK_EXT 0x80 /* There are 10 general analog inputs and 7 dedicated inputs * They are: @@ -129,48 +132,48 @@ static u16 ADM1026_REG_TEMP_TMIN[] = { 0x10, 0x11, 0x12 }; static u16 ADM1026_REG_TEMP_THERM[] = { 0x0d, 0x0e, 0x0f }; static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f }; -#define ADM1026_REG_FAN(nr) (0x38 + (nr)) -#define ADM1026_REG_FAN_MIN(nr) (0x60 + (nr)) -#define ADM1026_REG_FAN_DIV_0_3 0x02 -#define ADM1026_REG_FAN_DIV_4_7 0x03 +#define ADM1026_REG_FAN(nr) (0x38 + (nr)) +#define ADM1026_REG_FAN_MIN(nr) (0x60 + (nr)) +#define ADM1026_REG_FAN_DIV_0_3 0x02 +#define ADM1026_REG_FAN_DIV_4_7 0x03 -#define ADM1026_REG_DAC 0x04 -#define ADM1026_REG_PWM 0x05 +#define ADM1026_REG_DAC 0x04 +#define ADM1026_REG_PWM 0x05 -#define ADM1026_REG_GPIO_CFG_0_3 0x08 -#define ADM1026_REG_GPIO_CFG_4_7 0x09 -#define ADM1026_REG_GPIO_CFG_8_11 0x0a -#define ADM1026_REG_GPIO_CFG_12_15 0x0b +#define ADM1026_REG_GPIO_CFG_0_3 0x08 +#define ADM1026_REG_GPIO_CFG_4_7 0x09 +#define ADM1026_REG_GPIO_CFG_8_11 0x0a +#define ADM1026_REG_GPIO_CFG_12_15 0x0b /* CFG_16 in REG_CFG3 */ -#define ADM1026_REG_GPIO_STATUS_0_7 0x24 -#define ADM1026_REG_GPIO_STATUS_8_15 0x25 +#define ADM1026_REG_GPIO_STATUS_0_7 0x24 +#define ADM1026_REG_GPIO_STATUS_8_15 0x25 /* STATUS_16 in REG_STATUS4 */ -#define ADM1026_REG_GPIO_MASK_0_7 0x1c -#define ADM1026_REG_GPIO_MASK_8_15 0x1d +#define ADM1026_REG_GPIO_MASK_0_7 0x1c +#define ADM1026_REG_GPIO_MASK_8_15 0x1d /* MASK_16 in REG_MASK4 */ -#define ADM1026_REG_COMPANY 0x16 -#define ADM1026_REG_VERSTEP 0x17 +#define ADM1026_REG_COMPANY 0x16 +#define ADM1026_REG_VERSTEP 0x17 /* These are the recognized values for the above regs */ -#define ADM1026_COMPANY_ANALOG_DEV 0x41 -#define ADM1026_VERSTEP_GENERIC 0x40 -#define ADM1026_VERSTEP_ADM1026 0x44 +#define ADM1026_COMPANY_ANALOG_DEV 0x41 +#define ADM1026_VERSTEP_GENERIC 0x40 +#define ADM1026_VERSTEP_ADM1026 0x44 -#define ADM1026_REG_MASK1 0x18 -#define ADM1026_REG_MASK2 0x19 -#define ADM1026_REG_MASK3 0x1a -#define ADM1026_REG_MASK4 0x1b +#define ADM1026_REG_MASK1 0x18 +#define ADM1026_REG_MASK2 0x19 +#define ADM1026_REG_MASK3 0x1a +#define ADM1026_REG_MASK4 0x1b -#define ADM1026_REG_STATUS1 0x20 -#define ADM1026_REG_STATUS2 0x21 -#define ADM1026_REG_STATUS3 0x22 -#define ADM1026_REG_STATUS4 0x23 +#define ADM1026_REG_STATUS1 0x20 +#define ADM1026_REG_STATUS2 0x21 +#define ADM1026_REG_STATUS3 0x22 +#define ADM1026_REG_STATUS4 0x23 #define ADM1026_FAN_ACTIVATION_TEMP_HYST -6 -#define ADM1026_FAN_CONTROL_TEMP_RANGE 20 -#define ADM1026_PWM_MAX 255 +#define ADM1026_FAN_CONTROL_TEMP_RANGE 20 +#define ADM1026_PWM_MAX 255 -/* Conversions. Rounding and limit checking is only done on the TO_REG +/* Conversions. Rounding and limit checking is only done on the TO_REG * variants. Note that you should be a bit careful with which arguments * these macros are called: arguments may be evaluated more than once. */ @@ -186,52 +189,49 @@ static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f }; * The values in this table are based on Table II, page 15 of the * datasheet. */ -static int adm1026_scaling[] = { /* .001 Volts */ - 2250, 2250, 2250, 2250, 2250, 2250, - 1875, 1875, 1875, 1875, 3000, 3330, +static int adm1026_scaling[] = { /* .001 Volts */ + 2250, 2250, 2250, 2250, 2250, 2250, + 1875, 1875, 1875, 1875, 3000, 3330, 3330, 4995, 2250, 12000, 13875 }; #define NEG12_OFFSET 16000 -#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from)) -#define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,adm1026_scaling[n],192),\ - 0,255)) -#define INS_FROM_REG(n,val) (SCALE(val,192,adm1026_scaling[n])) +#define SCALE(val, from, to) (((val)*(to) + ((from)/2))/(from)) +#define INS_TO_REG(n, val) (SENSORS_LIMIT(SCALE(val, adm1026_scaling[n], 192),\ + 0, 255)) +#define INS_FROM_REG(n, val) (SCALE(val, 192, adm1026_scaling[n])) /* FAN speed is measured using 22.5kHz clock and counts for 2 pulses * and we assume a 2 pulse-per-rev fan tach signal * 22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000 */ -#define FAN_TO_REG(val,div) ((val)<=0 ? 0xff : SENSORS_LIMIT(1350000/((val)*\ - (div)),1,254)) -#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==0xff ? 0 : 1350000/((val)*\ - (div))) +#define FAN_TO_REG(val, div) ((val) <= 0 ? 0xff : \ + SENSORS_LIMIT(1350000/((val)*(div)), 1, 254)) +#define FAN_FROM_REG(val, div) ((val) == 0 ? -1:(val) == 0xff ? 0 : \ + 1350000/((val)*(div))) #define DIV_FROM_REG(val) (1<<(val)) -#define DIV_TO_REG(val) ((val)>=8 ? 3 : (val)>=4 ? 2 : (val)>=2 ? 1 : 0) +#define DIV_TO_REG(val) ((val) >= 8 ? 3 : (val) >= 4 ? 2 : (val) >= 2 ? 1 : 0) /* Temperature is reported in 1 degC increments */ #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\ - -127,127)) + -127, 127)) #define TEMP_FROM_REG(val) ((val) * 1000) #define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\ - -127,127)) + -127, 127)) #define OFFSET_FROM_REG(val) ((val) * 1000) -#define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) +#define PWM_TO_REG(val) (SENSORS_LIMIT(val, 0, 255)) #define PWM_FROM_REG(val) (val) #define PWM_MIN_TO_REG(val) ((val) & 0xf0) #define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4)) -/* Analog output is a voltage, and scaled to millivolts. The datasheet - * indicates that the DAC could be used to drive the fans, but in our +/* Analog output is a voltage, and scaled to millivolts. The datasheet + * indicates that the DAC could be used to drive the fans, but in our * example board (Arima HDAMA) it isn't connected to the fans at all. */ -#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500),0,255)) +#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500), 0, 255)) #define DAC_FROM_REG(val) (((val)*2500)/255) -/* Typically used with systems using a v9.1 VRM spec ? */ -#define ADM1026_INIT_VRM 91 - /* Chip sampling rates * * Some sensors are not updated more frequently than once per second @@ -243,8 +243,8 @@ static int adm1026_scaling[] = { /* .001 Volts */ * So, we keep the config data up to date in the cache * when it is written and only sample it once every 5 *minutes* */ -#define ADM1026_DATA_INTERVAL (1 * HZ) -#define ADM1026_CONFIG_INTERVAL (5 * 60 * HZ) +#define ADM1026_DATA_INTERVAL (1 * HZ) +#define ADM1026_CONFIG_INTERVAL (5 * 60 * HZ) /* We allow for multiple chips in a single system. * @@ -261,37 +261,36 @@ struct pwm_data { struct adm1026_data { struct i2c_client client; struct device *hwmon_dev; - enum chips type; struct mutex update_lock; int valid; /* !=0 if following fields are valid */ unsigned long last_reading; /* In jiffies */ unsigned long last_config; /* In jiffies */ - u8 in[17]; /* Register value */ - u8 in_max[17]; /* Register value */ - u8 in_min[17]; /* Register value */ - s8 temp[3]; /* Register value */ - s8 temp_min[3]; /* Register value */ - s8 temp_max[3]; /* Register value */ - s8 temp_tmin[3]; /* Register value */ - s8 temp_crit[3]; /* Register value */ - s8 temp_offset[3]; /* Register value */ - u8 fan[8]; /* Register value */ - u8 fan_min[8]; /* Register value */ - u8 fan_div[8]; /* Decoded value */ - struct pwm_data pwm1; /* Pwm control values */ - int vid; /* Decoded value */ - u8 vrm; /* VRM version */ + u8 in[17]; /* Register value */ + u8 in_max[17]; /* Register value */ + u8 in_min[17]; /* Register value */ + s8 temp[3]; /* Register value */ + s8 temp_min[3]; /* Register value */ + s8 temp_max[3]; /* Register value */ + s8 temp_tmin[3]; /* Register value */ + s8 temp_crit[3]; /* Register value */ + s8 temp_offset[3]; /* Register value */ + u8 fan[8]; /* Register value */ + u8 fan_min[8]; /* Register value */ + u8 fan_div[8]; /* Decoded value */ + struct pwm_data pwm1; /* Pwm control values */ + int vid; /* Decoded value */ + u8 vrm; /* VRM version */ u8 analog_out; /* Register value (DAC) */ - long alarms; /* Register encoding, combined */ - long alarm_mask; /* Register encoding, combined */ - long gpio; /* Register encoding, combined */ - long gpio_mask; /* Register encoding, combined */ - u8 gpio_config[17]; /* Decoded value */ - u8 config1; /* Register value */ - u8 config2; /* Register value */ - u8 config3; /* Register value */ + long alarms; /* Register encoding, combined */ + long alarm_mask; /* Register encoding, combined */ + long gpio; /* Register encoding, combined */ + long gpio_mask; /* Register encoding, combined */ + u8 gpio_config[17]; /* Decoded value */ + u8 config1; /* Register value */ + u8 config2; /* Register value */ + u8 config3; /* Register value */ }; static int adm1026_attach_adapter(struct i2c_adapter *adapter); @@ -301,7 +300,7 @@ static int adm1026_detach_client(struct i2c_client *client); static int adm1026_read_value(struct i2c_client *client, u8 reg); static int adm1026_write_value(struct i2c_client *client, u8 reg, int value); static void adm1026_print_gpio(struct i2c_client *client); -static void adm1026_fixup_gpio(struct i2c_client *client); +static void adm1026_fixup_gpio(struct i2c_client *client); static struct adm1026_data *adm1026_update_device(struct device *dev); static void adm1026_init_client(struct i2c_client *client); @@ -311,7 +310,7 @@ static struct i2c_driver adm1026_driver = { .name = "adm1026", }, .attach_adapter = adm1026_attach_adapter, - .detach_client = adm1026_detach_client, + .detach_client = adm1026_detach_client, }; static int adm1026_attach_adapter(struct i2c_adapter *adapter) @@ -355,7 +354,7 @@ static void adm1026_init_client(struct i2c_client *client) int value, i; struct adm1026_data *data = i2c_get_clientdata(client); - dev_dbg(&client->dev, "Initializing device\n"); + dev_dbg(&client->dev, "Initializing device\n"); /* Read chip config */ data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1); data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2); @@ -384,7 +383,6 @@ static void adm1026_init_client(struct i2c_client *client) "and temp limits enabled.\n"); } - value = data->config3; if (data->config3 & CFG3_GPIO16_ENABLE) { dev_dbg(&client->dev, "GPIO16 enabled. THERM " "pin disabled.\n"); @@ -426,10 +424,10 @@ static void adm1026_init_client(struct i2c_client *client) * configured, we don't want to mess with them. * If they weren't, the default is 100% PWM, no * control and will suffice until 'sensors -s' - * can be run by the user. We DO set the default + * can be run by the user. We DO set the default * value for pwm1.auto_pwm_min to its maximum * so that enabling automatic pwm fan control - * without first setting a value for pwm1.auto_pwm_min + * without first setting a value for pwm1.auto_pwm_min * will not result in potentially dangerous fan speed decrease. */ data->pwm1.auto_pwm_min=255; @@ -453,7 +451,7 @@ static void adm1026_init_client(struct i2c_client *client) static void adm1026_print_gpio(struct i2c_client *client) { struct adm1026_data *data = i2c_get_clientdata(client); - int i; + int i; dev_dbg(&client->dev, "GPIO config is:"); for (i = 0;i <= 7;++i) { @@ -477,7 +475,7 @@ static void adm1026_print_gpio(struct i2c_client *client) data->gpio_config[16] & 0x02 ? "" : "!", data->gpio_config[16] & 0x01 ? "OUT" : "IN"); } else { - /* GPIO16 is THERM */ + /* GPIO16 is THERM */ dev_dbg(&client->dev, "\tTHERM\n"); } } @@ -485,8 +483,8 @@ static void adm1026_print_gpio(struct i2c_client *client) static void adm1026_fixup_gpio(struct i2c_client *client) { struct adm1026_data *data = i2c_get_clientdata(client); - int i; - int value; + int i; + int value; /* Make the changes requested. */ /* We may need to unlock/stop monitoring or soft-reset the @@ -516,14 +514,14 @@ static void adm1026_fixup_gpio(struct i2c_client *client) } } - /* Inverted */ + /* Inverted */ for (i = 0;i <= 16;++i) { if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) { data->gpio_config[gpio_inverted[i]] &= ~ 0x02; } } - /* Normal overrides inverted */ + /* Normal overrides inverted */ for (i = 0;i <= 16;++i) { if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) { data->gpio_config[gpio_normal[i]] |= 0x02; @@ -569,7 +567,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) if (!data->valid || time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) { /* Things that change quickly */ - dev_dbg(&client->dev,"Reading sensor values\n"); + dev_dbg(&client->dev, "Reading sensor values\n"); for (i = 0;i <= 16;++i) { data->in[i] = adm1026_read_value(client, ADM1026_REG_IN[i]); @@ -582,18 +580,18 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) for (i = 0;i <= 2;++i) { /* NOTE: temp[] is s8 and we assume 2's complement - * "conversion" in the assignment */ + * "conversion" in the assignment */ data->temp[i] = adm1026_read_value(client, ADM1026_REG_TEMP[i]); } - data->pwm1.pwm = adm1026_read_value(client, + data->pwm1.pwm = adm1026_read_value(client, ADM1026_REG_PWM); - data->analog_out = adm1026_read_value(client, + data->analog_out = adm1026_read_value(client, ADM1026_REG_DAC); /* GPIO16 is MSbit of alarms, move it to gpio */ alarms = adm1026_read_value(client, ADM1026_REG_STATUS4); - gpio = alarms & 0x80 ? 0x0100 : 0; /* GPIO16 */ + gpio = alarms & 0x80 ? 0x0100 : 0; /* GPIO16 */ alarms &= 0x7f; alarms <<= 8; alarms |= adm1026_read_value(client, ADM1026_REG_STATUS3); @@ -604,24 +602,24 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) data->alarms = alarms; /* Read the GPIO values */ - gpio |= adm1026_read_value(client, + gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_STATUS_8_15); gpio <<= 8; - gpio |= adm1026_read_value(client, + gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_STATUS_0_7); data->gpio = gpio; data->last_reading = jiffies; - }; /* last_reading */ + }; /* last_reading */ if (!data->valid || time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) { /* Things that don't change often */ dev_dbg(&client->dev, "Reading config values\n"); for (i = 0;i <= 16;++i) { - data->in_min[i] = adm1026_read_value(client, + data->in_min[i] = adm1026_read_value(client, ADM1026_REG_IN_MIN[i]); - data->in_max[i] = adm1026_read_value(client, + data->in_max[i] = adm1026_read_value(client, ADM1026_REG_IN_MAX[i]); } @@ -629,32 +627,32 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) | (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8); for (i = 0;i <= 7;++i) { - data->fan_min[i] = adm1026_read_value(client, + data->fan_min[i] = adm1026_read_value(client, ADM1026_REG_FAN_MIN(i)); data->fan_div[i] = DIV_FROM_REG(value & 0x03); value >>= 2; } for (i = 0; i <= 2; ++i) { - /* NOTE: temp_xxx[] are s8 and we assume 2's + /* NOTE: temp_xxx[] are s8 and we assume 2's * complement "conversion" in the assignment */ - data->temp_min[i] = adm1026_read_value(client, + data->temp_min[i] = adm1026_read_value(client, ADM1026_REG_TEMP_MIN[i]); - data->temp_max[i] = adm1026_read_value(client, + data->temp_max[i] = adm1026_read_value(client, ADM1026_REG_TEMP_MAX[i]); - data->temp_tmin[i] = adm1026_read_value(client, + data->temp_tmin[i] = adm1026_read_value(client, ADM1026_REG_TEMP_TMIN[i]); - data->temp_crit[i] = adm1026_read_value(client, + data->temp_crit[i] = adm1026_read_value(client, ADM1026_REG_TEMP_THERM[i]); - data->temp_offset[i] = adm1026_read_value(client, + data->temp_offset[i] = adm1026_read_value(client, ADM1026_REG_TEMP_OFFSET[i]); } /* Read the STATUS/alarm masks */ - alarms = adm1026_read_value(client, ADM1026_REG_MASK4); - gpio = alarms & 0x80 ? 0x0100 : 0; /* GPIO16 */ - alarms = (alarms & 0x7f) << 8; + alarms = adm1026_read_value(client, ADM1026_REG_MASK4); + gpio = alarms & 0x80 ? 0x0100 : 0; /* GPIO16 */ + alarms = (alarms & 0x7f) << 8; alarms |= adm1026_read_value(client, ADM1026_REG_MASK3); alarms <<= 8; alarms |= adm1026_read_value(client, ADM1026_REG_MASK2); @@ -663,24 +661,24 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) data->alarm_mask = alarms; /* Read the GPIO values */ - gpio |= adm1026_read_value(client, + gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_MASK_8_15); gpio <<= 8; gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_MASK_0_7); data->gpio_mask = gpio; /* Read various values from CONFIG1 */ - data->config1 = adm1026_read_value(client, + data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1); if (data->config1 & CFG1_PWM_AFC) { data->pwm1.enable = 2; - data->pwm1.auto_pwm_min = + data->pwm1.auto_pwm_min = PWM_MIN_FROM_REG(data->pwm1.pwm); } /* Read the GPIO config */ - data->config2 = adm1026_read_value(client, + data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2); - data->config3 = adm1026_read_value(client, + data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3); data->gpio_config[16] = (data->config3 >> 6) & 0x03; @@ -695,7 +693,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) } data->last_config = jiffies; - }; /* last_config */ + }; /* last_config */ dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n"); data->vid = (data->gpio >> 11) & 0x1f; @@ -710,15 +708,15 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr])); + return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in[nr])); } static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, char *buf) { struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; - struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr])); + struct adm1026_data *data = adm1026_update_device(dev); + return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_min[nr])); } static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -733,7 +731,7 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, data->in_min[nr] = INS_TO_REG(nr, val); adm1026_write_value(client, ADM1026_REG_IN_MIN[nr], data->in_min[nr]); mutex_unlock(&data->update_lock); - return count; + return count; } static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, char *buf) @@ -741,7 +739,7 @@ static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr])); + return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_max[nr])); } static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -788,13 +786,13 @@ in_reg(15); static ssize_t show_in16(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in[16]) - + return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in[16]) - NEG12_OFFSET); } static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, char *buf) { - struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_min[16]) + struct adm1026_data *data = adm1026_update_device(dev); + return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_min[16]) - NEG12_OFFSET); } static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -807,12 +805,12 @@ static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, c data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET); adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]); mutex_unlock(&data->update_lock); - return count; + return count; } static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_max[16]) + return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_max[16]) - NEG12_OFFSET); } static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -843,7 +841,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr], + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], data->fan_div[nr])); } static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, @@ -852,7 +850,7 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], data->fan_div[nr])); } static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, @@ -872,10 +870,10 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, return count; } -#define fan_offset(offset) \ -static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \ - offset - 1); \ -static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ +#define fan_offset(offset) \ +static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \ + offset - 1); \ +static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ show_fan_min, set_fan_min, offset - 1); fan_offset(1); @@ -892,8 +890,8 @@ static void fixup_fan_min(struct device *dev, int fan, int old_div) { struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int new_min; - int new_div = data->fan_div[fan]; + int new_min; + int new_div = data->fan_div[fan]; /* 0 and 0xff are special. Don't adjust them */ if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) { @@ -913,7 +911,7 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", data->fan_div[nr]); + return sprintf(buf, "%d\n", data->fan_div[nr]); } static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -922,10 +920,10 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val,orig_div,new_div,shift; + int val, orig_div, new_div, shift; val = simple_strtol(buf, NULL, 10); - new_div = DIV_TO_REG(val); + new_div = DIV_TO_REG(val); if (new_div == 0) { return -EINVAL; } @@ -946,14 +944,14 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, } if (data->fan_div[nr] != orig_div) { - fixup_fan_min(dev,nr,orig_div); + fixup_fan_min(dev, nr, orig_div); } mutex_unlock(&data->update_lock); return count; } -#define fan_offset_div(offset) \ -static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ +#define fan_offset_div(offset) \ +static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ show_fan_div, set_fan_div, offset - 1); fan_offset_div(1); @@ -972,7 +970,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr])); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); } static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, char *buf) @@ -980,7 +978,7 @@ static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr])); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr])); } static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1004,7 +1002,7 @@ static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr])); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr])); } static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1024,7 +1022,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, } #define temp_reg(offset) \ -static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ +static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \ NULL, offset - 1); \ static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ show_temp_min, set_temp_min, offset - 1); \ @@ -1042,7 +1040,7 @@ static ssize_t show_temp_offset(struct device *dev, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_offset[nr])); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_offset[nr])); } static ssize_t set_temp_offset(struct device *dev, struct device_attribute *attr, const char *buf, @@ -1076,7 +1074,7 @@ static ssize_t show_temp_auto_point1_temp_hyst(struct device *dev, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", TEMP_FROM_REG( + return sprintf(buf, "%d\n", TEMP_FROM_REG( ADM1026_FAN_ACTIVATION_TEMP_HYST + data->temp_tmin[nr])); } static ssize_t show_temp_auto_point2_temp(struct device *dev, @@ -1085,7 +1083,7 @@ static ssize_t show_temp_auto_point2_temp(struct device *dev, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr] + + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_tmin[nr] + ADM1026_FAN_CONTROL_TEMP_RANGE)); } static ssize_t show_temp_auto_point1_temp(struct device *dev, @@ -1094,7 +1092,7 @@ static ssize_t show_temp_auto_point1_temp(struct device *dev, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr])); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_tmin[nr])); } static ssize_t set_temp_auto_point1_temp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1113,13 +1111,13 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev, return count; } -#define temp_auto_point(offset) \ -static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp, S_IRUGO | S_IWUSR, \ - show_temp_auto_point1_temp, set_temp_auto_point1_temp, \ - offset - 1); \ -static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp_hyst, S_IRUGO, \ - show_temp_auto_point1_temp_hyst, NULL, offset - 1); \ -static SENSOR_DEVICE_ATTR(temp##offset##_auto_point2_temp, S_IRUGO, \ +#define temp_auto_point(offset) \ +static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp, \ + S_IRUGO | S_IWUSR, show_temp_auto_point1_temp, \ + set_temp_auto_point1_temp, offset - 1); \ +static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp_hyst, S_IRUGO,\ + show_temp_auto_point1_temp_hyst, NULL, offset - 1); \ +static SENSOR_DEVICE_ATTR(temp##offset##_auto_point2_temp, S_IRUGO, \ show_temp_auto_point2_temp, NULL, offset - 1); temp_auto_point(1); @@ -1130,7 +1128,7 @@ static ssize_t show_temp_crit_enable(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", (data->config1 & CFG1_THERM_HOT) >> 4); + return sprintf(buf, "%d\n", (data->config1 & CFG1_THERM_HOT) >> 4); } static ssize_t set_temp_crit_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1142,7 +1140,7 @@ static ssize_t set_temp_crit_enable(struct device *dev, if ((val == 1) || (val==0)) { mutex_lock(&data->update_lock); data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4); - adm1026_write_value(client, ADM1026_REG_CONFIG1, + adm1026_write_value(client, ADM1026_REG_CONFIG1, data->config1); mutex_unlock(&data->update_lock); } @@ -1163,7 +1161,7 @@ static ssize_t show_temp_crit(struct device *dev, struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); int nr = sensor_attr->index; struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_crit[nr])); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr])); } static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1193,7 +1191,7 @@ temp_crit_reg(3); static ssize_t show_analog_out_reg(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", DAC_FROM_REG(data->analog_out)); + return sprintf(buf, "%d\n", DAC_FROM_REG(data->analog_out)); } static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1209,26 +1207,25 @@ static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *a return count; } -static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg, +static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg, set_analog_out_reg); static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm)); + return sprintf(buf, "%d\n", vid_from_reg(data->vid & 0x3f, data->vrm)); } static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = dev_get_drvdata(dev); - return sprintf(buf,"%d\n", data->vrm); + return sprintf(buf, "%d\n", data->vrm); } static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct adm1026_data *data = i2c_get_clientdata(client); + struct adm1026_data *data = dev_get_drvdata(dev); data->vrm = simple_strtol(buf, NULL, 10); return count; @@ -1239,15 +1236,52 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf, "%ld\n", (long) (data->alarms)); + return sprintf(buf, "%ld\n", data->alarms); } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adm1026_data *data = adm1026_update_device(dev); + int bitnr = to_sensor_dev_attr(attr)->index; + return sprintf(buf, "%ld\n", (data->alarms >> bitnr) & 1); +} + +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(in14_alarm, S_IRUGO, show_alarm, NULL, 5); +static SENSOR_DEVICE_ATTR(in15_alarm, S_IRUGO, show_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(in16_alarm, S_IRUGO, show_alarm, NULL, 7); +static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 9); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 10); +static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 12); +static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 13); +static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 14); +static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 15); +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 16); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 17); +static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 18); +static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 19); +static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 20); +static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 21); +static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL, 22); +static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_alarm, NULL, 23); +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 24); +static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 25); +static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 26); + static ssize_t show_alarm_mask(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%ld\n", data->alarm_mask); + return sprintf(buf, "%ld\n", data->alarm_mask); } static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1283,7 +1317,7 @@ static DEVICE_ATTR(alarm_mask, S_IRUGO | S_IWUSR, show_alarm_mask, static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%ld\n", data->gpio); + return sprintf(buf, "%ld\n", data->gpio); } static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1291,16 +1325,16 @@ static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val = simple_strtol(buf, NULL, 10); - long gpio; + long gpio; mutex_lock(&data->update_lock); data->gpio = val & 0x1ffff; gpio = data->gpio; - adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_0_7,gpio & 0xff); + adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_0_7, gpio & 0xff); gpio >>= 8; - adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_8_15,gpio & 0xff); + adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_8_15, gpio & 0xff); gpio = ((gpio >> 1) & 0x80) | (data->alarms >> 24 & 0x7f); - adm1026_write_value(client, ADM1026_REG_STATUS4,gpio & 0xff); + adm1026_write_value(client, ADM1026_REG_STATUS4, gpio & 0xff); mutex_unlock(&data->update_lock); return count; } @@ -1311,7 +1345,7 @@ static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio); static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%ld\n", data->gpio_mask); + return sprintf(buf, "%ld\n", data->gpio_mask); } static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1319,16 +1353,16 @@ static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val = simple_strtol(buf, NULL, 10); - long mask; + long mask; mutex_lock(&data->update_lock); data->gpio_mask = val & 0x1ffff; mask = data->gpio_mask; - adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7,mask & 0xff); + adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7, mask & 0xff); mask >>= 8; - adm1026_write_value(client, ADM1026_REG_GPIO_MASK_8_15,mask & 0xff); + adm1026_write_value(client, ADM1026_REG_GPIO_MASK_8_15, mask & 0xff); mask = ((mask >> 1) & 0x80) | (data->alarm_mask >> 24 & 0x7f); - adm1026_write_value(client, ADM1026_REG_MASK1,mask & 0xff); + adm1026_write_value(client, ADM1026_REG_MASK1, mask & 0xff); mutex_unlock(&data->update_lock); return count; } @@ -1338,7 +1372,7 @@ static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask); static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm1.pwm)); + return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm1.pwm)); } static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1359,7 +1393,7 @@ static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, co static ssize_t show_auto_pwm_min(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", data->pwm1.auto_pwm_min); + return sprintf(buf, "%d\n", data->pwm1.auto_pwm_min); } static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1369,10 +1403,10 @@ static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *att int val = simple_strtol(buf, NULL, 10); mutex_lock(&data->update_lock); - data->pwm1.auto_pwm_min = SENSORS_LIMIT(val,0,255); + data->pwm1.auto_pwm_min = SENSORS_LIMIT(val, 0, 255); if (data->pwm1.enable == 2) { /* apply immediately */ data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) | - PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); + PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); } mutex_unlock(&data->update_lock); @@ -1380,12 +1414,12 @@ static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *att } static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf,"%d\n", ADM1026_PWM_MAX); + return sprintf(buf, "%d\n", ADM1026_PWM_MAX); } static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); - return sprintf(buf,"%d\n", data->pwm1.enable); + return sprintf(buf, "%d\n", data->pwm1.enable); } static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1393,7 +1427,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val = simple_strtol(buf, NULL, 10); - int old_enable; + int old_enable; if ((val >= 0) && (val < 3)) { mutex_lock(&data->update_lock); @@ -1403,15 +1437,15 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | ((val == 2) ? CFG1_PWM_AFC : 0); adm1026_write_value(client, ADM1026_REG_CONFIG1, data->config1); - if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */ + if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */ data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) | - PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); - adm1026_write_value(client, ADM1026_REG_PWM, + PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); + adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); } else if (!((old_enable == 1) && (val == 1))) { /* set pwm to safe value */ data->pwm1.pwm = 255; - adm1026_write_value(client, ADM1026_REG_PWM, + adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); } mutex_unlock(&data->update_lock); @@ -1420,20 +1454,20 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, } /* enable PWM fan control */ -static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); -static DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); -static DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); -static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, +static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); +static DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); +static DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); +static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, set_pwm_enable); -static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, show_pwm_enable, +static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, show_pwm_enable, set_pwm_enable); -static DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, show_pwm_enable, +static DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, show_pwm_enable, set_pwm_enable); -static DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO | S_IWUSR, +static DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO | S_IWUSR, show_auto_pwm_min, set_auto_pwm_min); -static DEVICE_ATTR(temp2_auto_point1_pwm, S_IRUGO | S_IWUSR, +static DEVICE_ATTR(temp2_auto_point1_pwm, S_IRUGO | S_IWUSR, show_auto_pwm_min, set_auto_pwm_min); -static DEVICE_ATTR(temp3_auto_point1_pwm, S_IRUGO | S_IWUSR, +static DEVICE_ATTR(temp3_auto_point1_pwm, S_IRUGO | S_IWUSR, show_auto_pwm_min, set_auto_pwm_min); static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL); @@ -1444,105 +1478,115 @@ static struct attribute *adm1026_attributes[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in0_max.dev_attr.attr, &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in0_alarm.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_in1_max.dev_attr.attr, &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, &sensor_dev_attr_in2_input.dev_attr.attr, &sensor_dev_attr_in2_max.dev_attr.attr, &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, &sensor_dev_attr_in3_input.dev_attr.attr, &sensor_dev_attr_in3_max.dev_attr.attr, &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in3_alarm.dev_attr.attr, &sensor_dev_attr_in4_input.dev_attr.attr, &sensor_dev_attr_in4_max.dev_attr.attr, &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in4_alarm.dev_attr.attr, &sensor_dev_attr_in5_input.dev_attr.attr, &sensor_dev_attr_in5_max.dev_attr.attr, &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in5_alarm.dev_attr.attr, &sensor_dev_attr_in6_input.dev_attr.attr, &sensor_dev_attr_in6_max.dev_attr.attr, &sensor_dev_attr_in6_min.dev_attr.attr, + &sensor_dev_attr_in6_alarm.dev_attr.attr, &sensor_dev_attr_in7_input.dev_attr.attr, &sensor_dev_attr_in7_max.dev_attr.attr, &sensor_dev_attr_in7_min.dev_attr.attr, - &sensor_dev_attr_in8_input.dev_attr.attr, - &sensor_dev_attr_in8_max.dev_attr.attr, - &sensor_dev_attr_in8_min.dev_attr.attr, - &sensor_dev_attr_in9_input.dev_attr.attr, - &sensor_dev_attr_in9_max.dev_attr.attr, - &sensor_dev_attr_in9_min.dev_attr.attr, + &sensor_dev_attr_in7_alarm.dev_attr.attr, &sensor_dev_attr_in10_input.dev_attr.attr, &sensor_dev_attr_in10_max.dev_attr.attr, &sensor_dev_attr_in10_min.dev_attr.attr, + &sensor_dev_attr_in10_alarm.dev_attr.attr, &sensor_dev_attr_in11_input.dev_attr.attr, &sensor_dev_attr_in11_max.dev_attr.attr, &sensor_dev_attr_in11_min.dev_attr.attr, + &sensor_dev_attr_in11_alarm.dev_attr.attr, &sensor_dev_attr_in12_input.dev_attr.attr, &sensor_dev_attr_in12_max.dev_attr.attr, &sensor_dev_attr_in12_min.dev_attr.attr, + &sensor_dev_attr_in12_alarm.dev_attr.attr, &sensor_dev_attr_in13_input.dev_attr.attr, &sensor_dev_attr_in13_max.dev_attr.attr, &sensor_dev_attr_in13_min.dev_attr.attr, + &sensor_dev_attr_in13_alarm.dev_attr.attr, &sensor_dev_attr_in14_input.dev_attr.attr, &sensor_dev_attr_in14_max.dev_attr.attr, &sensor_dev_attr_in14_min.dev_attr.attr, + &sensor_dev_attr_in14_alarm.dev_attr.attr, &sensor_dev_attr_in15_input.dev_attr.attr, &sensor_dev_attr_in15_max.dev_attr.attr, &sensor_dev_attr_in15_min.dev_attr.attr, + &sensor_dev_attr_in15_alarm.dev_attr.attr, &sensor_dev_attr_in16_input.dev_attr.attr, &sensor_dev_attr_in16_max.dev_attr.attr, &sensor_dev_attr_in16_min.dev_attr.attr, + &sensor_dev_attr_in16_alarm.dev_attr.attr, &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan2_div.dev_attr.attr, &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, &sensor_dev_attr_fan3_input.dev_attr.attr, &sensor_dev_attr_fan3_div.dev_attr.attr, &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan3_alarm.dev_attr.attr, &sensor_dev_attr_fan4_input.dev_attr.attr, &sensor_dev_attr_fan4_div.dev_attr.attr, &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan4_alarm.dev_attr.attr, &sensor_dev_attr_fan5_input.dev_attr.attr, &sensor_dev_attr_fan5_div.dev_attr.attr, &sensor_dev_attr_fan5_min.dev_attr.attr, + &sensor_dev_attr_fan5_alarm.dev_attr.attr, &sensor_dev_attr_fan6_input.dev_attr.attr, &sensor_dev_attr_fan6_div.dev_attr.attr, &sensor_dev_attr_fan6_min.dev_attr.attr, + &sensor_dev_attr_fan6_alarm.dev_attr.attr, &sensor_dev_attr_fan7_input.dev_attr.attr, &sensor_dev_attr_fan7_div.dev_attr.attr, &sensor_dev_attr_fan7_min.dev_attr.attr, + &sensor_dev_attr_fan7_alarm.dev_attr.attr, &sensor_dev_attr_fan8_input.dev_attr.attr, &sensor_dev_attr_fan8_div.dev_attr.attr, &sensor_dev_attr_fan8_min.dev_attr.attr, + &sensor_dev_attr_fan8_alarm.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, &sensor_dev_attr_temp2_min.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp3_max.dev_attr.attr, - &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, &sensor_dev_attr_temp1_offset.dev_attr.attr, &sensor_dev_attr_temp2_offset.dev_attr.attr, - &sensor_dev_attr_temp3_offset.dev_attr.attr, &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, - &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr, &sensor_dev_attr_temp2_auto_point1_temp_hyst.dev_attr.attr, - &sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr.attr, &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, - &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp2_crit.dev_attr.attr, - &sensor_dev_attr_temp3_crit.dev_attr.attr, &dev_attr_temp1_crit_enable.attr, &dev_attr_temp2_crit_enable.attr, - &dev_attr_temp3_crit_enable.attr, &dev_attr_cpu0_vid.attr, &dev_attr_vrm.attr, &dev_attr_alarms.attr, @@ -1557,10 +1601,8 @@ static struct attribute *adm1026_attributes[] = { &dev_attr_pwm3_enable.attr, &dev_attr_temp1_auto_point1_pwm.attr, &dev_attr_temp2_auto_point1_pwm.attr, - &dev_attr_temp3_auto_point1_pwm.attr, &dev_attr_temp1_auto_point2_pwm.attr, &dev_attr_temp2_auto_point2_pwm.attr, - &dev_attr_temp3_auto_point2_pwm.attr, &dev_attr_analog_out.attr, NULL }; @@ -1569,11 +1611,45 @@ static const struct attribute_group adm1026_group = { .attrs = adm1026_attributes, }; +static struct attribute *adm1026_attributes_temp3[] = { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_offset.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &dev_attr_temp3_crit_enable.attr, + &dev_attr_temp3_auto_point1_pwm.attr, + &dev_attr_temp3_auto_point2_pwm.attr, +}; + +static const struct attribute_group adm1026_group_temp3 = { + .attrs = adm1026_attributes_temp3, +}; + +static struct attribute *adm1026_attributes_in8_9[] = { + &sensor_dev_attr_in8_input.dev_attr.attr, + &sensor_dev_attr_in8_max.dev_attr.attr, + &sensor_dev_attr_in8_min.dev_attr.attr, + &sensor_dev_attr_in8_alarm.dev_attr.attr, + &sensor_dev_attr_in9_input.dev_attr.attr, + &sensor_dev_attr_in9_max.dev_attr.attr, + &sensor_dev_attr_in9_min.dev_attr.attr, + &sensor_dev_attr_in9_alarm.dev_attr.attr, +}; + +static const struct attribute_group adm1026_group_in8_9 = { + .attrs = adm1026_attributes_in8_9, +}; + static int adm1026_detect(struct i2c_adapter *adapter, int address, int kind) { int company, verstep; - struct i2c_client *new_client; + struct i2c_client *client; struct adm1026_data *data; int err = 0; const char *type_name = ""; @@ -1592,26 +1668,25 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, goto exit; } - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &adm1026_driver; - new_client->flags = 0; + client = &data->client; + i2c_set_clientdata(client, data); + client->addr = address; + client->adapter = adapter; + client->driver = &adm1026_driver; /* Now, we do the remaining detection. */ - company = adm1026_read_value(new_client, ADM1026_REG_COMPANY); - verstep = adm1026_read_value(new_client, ADM1026_REG_VERSTEP); + company = adm1026_read_value(client, ADM1026_REG_COMPANY); + verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP); - dev_dbg(&new_client->dev, "Detecting device at %d,0x%02x with" + dev_dbg(&client->dev, "Detecting device at %d,0x%02x with" " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", - i2c_adapter_id(new_client->adapter), new_client->addr, + i2c_adapter_id(client->adapter), client->addr, company, verstep); /* If auto-detecting, Determine the chip type. */ if (kind <= 0) { - dev_dbg(&new_client->dev, "Autodetecting device at %d,0x%02x " + dev_dbg(&client->dev, "Autodetecting device at %d,0x%02x " "...\n", i2c_adapter_id(adapter), address); if (company == ADM1026_COMPANY_ANALOG_DEV && verstep == ADM1026_VERSTEP_ADM1026) { @@ -1627,16 +1702,15 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, verstep); kind = any_chip; } else { - dev_dbg(&new_client->dev, ": Autodetection " + dev_dbg(&client->dev, ": Autodetection " "failed\n"); /* Not an ADM1026 ... */ - if (kind == 0) { /* User used force=x,y */ + if (kind == 0) { /* User used force=x,y */ dev_err(&adapter->dev, "Generic ADM1026 not " "found at %d,0x%02x. Try " "force_adm1026.\n", i2c_adapter_id(adapter), address); } - err = 0; goto exitfree; } } @@ -1655,28 +1729,34 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, err = -EFAULT; goto exitfree; } - strlcpy(new_client->name, type_name, I2C_NAME_SIZE); + strlcpy(client->name, type_name, I2C_NAME_SIZE); /* Fill in the remaining client fields */ - data->type = kind; - data->valid = 0; mutex_init(&data->update_lock); /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) + if ((err = i2c_attach_client(client))) goto exitfree; /* Set the VRM version */ data->vrm = vid_which_vrm(); /* Initialize the ADM1026 chip */ - adm1026_init_client(new_client); + adm1026_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1026_group))) + if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group))) goto exitdetach; + if (data->config1 & CFG1_AIN8_9) + err = sysfs_create_group(&client->dev.kobj, + &adm1026_group_in8_9); + else + err = sysfs_create_group(&client->dev.kobj, + &adm1026_group_temp3); + if (err) + goto exitremove; - data->hwmon_dev = hwmon_device_register(&new_client->dev); + data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); goto exitremove; @@ -1686,9 +1766,13 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, /* Error out and cleanup code */ exitremove: - sysfs_remove_group(&new_client->dev.kobj, &adm1026_group); + sysfs_remove_group(&client->dev.kobj, &adm1026_group); + if (data->config1 & CFG1_AIN8_9) + sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); + else + sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); exitdetach: - i2c_detach_client(new_client); + i2c_detach_client(client); exitfree: kfree(data); exit: @@ -1700,6 +1784,10 @@ static int adm1026_detach_client(struct i2c_client *client) struct adm1026_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adm1026_group); + if (data->config1 & CFG1_AIN8_9) + sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); + else + sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); i2c_detach_client(client); kfree(data); return 0; @@ -1710,14 +1798,14 @@ static int __init sm_adm1026_init(void) return i2c_add_driver(&adm1026_driver); } -static void __exit sm_adm1026_exit(void) +static void __exit sm_adm1026_exit(void) { i2c_del_driver(&adm1026_driver); } MODULE_LICENSE("GPL"); MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, " - "Justin Thiessen <jthiessen@penguincomputing.com>"); + "Justin Thiessen <jthiessen@penguincomputing.com>"); MODULE_DESCRIPTION("ADM1026 driver"); module_init(sm_adm1026_init); |