diff options
Diffstat (limited to 'drivers/hwmon/adm1026.c')
| -rw-r--r-- | drivers/hwmon/adm1026.c | 591 | 
1 files changed, 275 insertions, 316 deletions
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index b3498acb9ab4..e67b9a50ac7c 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -266,7 +266,8 @@ struct pwm_data {  };  struct adm1026_data { -	struct device *hwmon_dev; +	struct i2c_client *client; +	const struct attribute_group *groups[3];  	struct mutex update_lock;  	int valid;		/* !=0 if following fields are valid */ @@ -298,37 +299,6 @@ struct adm1026_data {  	u8 config3;		/* Register value */  }; -static int adm1026_probe(struct i2c_client *client, -			 const struct i2c_device_id *id); -static int adm1026_detect(struct i2c_client *client, -			  struct i2c_board_info *info); -static int adm1026_remove(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 struct adm1026_data *adm1026_update_device(struct device *dev); -static void adm1026_init_client(struct i2c_client *client); - - -static const struct i2c_device_id adm1026_id[] = { -	{ "adm1026", 0 }, -	{ } -}; -MODULE_DEVICE_TABLE(i2c, adm1026_id); - -static struct i2c_driver adm1026_driver = { -	.class		= I2C_CLASS_HWMON, -	.driver = { -		.name	= "adm1026", -	}, -	.probe		= adm1026_probe, -	.remove		= adm1026_remove, -	.id_table	= adm1026_id, -	.detect		= adm1026_detect, -	.address_list	= normal_i2c, -}; -  static int adm1026_read_value(struct i2c_client *client, u8 reg)  {  	int res; @@ -357,212 +327,10 @@ static int adm1026_write_value(struct i2c_client *client, u8 reg, int value)  	return res;  } -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"); -	/* Read chip config */ -	data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1); -	data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2); -	data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3); - -	/* Inform user of chip config */ -	dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n", -		data->config1); -	if ((data->config1 & CFG1_MONITOR) == 0) { -		dev_dbg(&client->dev, -			"Monitoring not currently enabled.\n"); -	} -	if (data->config1 & CFG1_INT_ENABLE) { -		dev_dbg(&client->dev, -			"SMBALERT interrupts are enabled.\n"); -	} -	if (data->config1 & CFG1_AIN8_9) { -		dev_dbg(&client->dev, -			"in8 and in9 enabled. temp3 disabled.\n"); -	} else { -		dev_dbg(&client->dev, -			"temp3 enabled.  in8 and in9 disabled.\n"); -	} -	if (data->config1 & CFG1_THERM_HOT) { -		dev_dbg(&client->dev, -			"Automatic THERM, PWM, and temp limits enabled.\n"); -	} - -	if (data->config3 & CFG3_GPIO16_ENABLE) { -		dev_dbg(&client->dev, -			"GPIO16 enabled.  THERM pin disabled.\n"); -	} else { -		dev_dbg(&client->dev, -			"THERM pin enabled.  GPIO16 disabled.\n"); -	} -	if (data->config3 & CFG3_VREF_250) -		dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); -	else -		dev_dbg(&client->dev, "Vref is 1.82 Volts.\n"); -	/* Read and pick apart the existing GPIO configuration */ -	value = 0; -	for (i = 0; i <= 15; ++i) { -		if ((i & 0x03) == 0) { -			value = adm1026_read_value(client, -					ADM1026_REG_GPIO_CFG_0_3 + i / 4); -		} -		data->gpio_config[i] = value & 0x03; -		value >>= 2; -	} -	data->gpio_config[16] = (data->config3 >> 6) & 0x03; - -	/* ... and then print it */ -	adm1026_print_gpio(client); - -	/* -	 * If the user asks us to reprogram the GPIO config, then -	 * do it now. -	 */ -	if (gpio_input[0] != -1 || gpio_output[0] != -1 -		|| gpio_inverted[0] != -1 || gpio_normal[0] != -1 -		|| gpio_fan[0] != -1) { -		adm1026_fixup_gpio(client); -	} - -	/* -	 * WE INTENTIONALLY make no changes to the limits, -	 *   offsets, pwms, fans and zones.  If they were -	 *   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 -	 *   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 -	 *   will not result in potentially dangerous fan speed decrease. -	 */ -	data->pwm1.auto_pwm_min = 255; -	/* Start monitoring */ -	value = adm1026_read_value(client, ADM1026_REG_CONFIG1); -	/* Set MONITOR, clear interrupt acknowledge and s/w reset */ -	value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET); -	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value); -	data->config1 = value; -	adm1026_write_value(client, ADM1026_REG_CONFIG1, value); - -	/* initialize fan_div[] to hardware defaults */ -	value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) | -		(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8); -	for (i = 0; i <= 7; ++i) { -		data->fan_div[i] = DIV_FROM_REG(value & 0x03); -		value >>= 2; -	} -} - -static void adm1026_print_gpio(struct i2c_client *client) -{ -	struct adm1026_data *data = i2c_get_clientdata(client); -	int i; - -	dev_dbg(&client->dev, "GPIO config is:\n"); -	for (i = 0; i <= 7; ++i) { -		if (data->config2 & (1 << i)) { -			dev_dbg(&client->dev, "\t%sGP%s%d\n", -				data->gpio_config[i] & 0x02 ? "" : "!", -				data->gpio_config[i] & 0x01 ? "OUT" : "IN", -				i); -		} else { -			dev_dbg(&client->dev, "\tFAN%d\n", i); -		} -	} -	for (i = 8; i <= 15; ++i) { -		dev_dbg(&client->dev, "\t%sGP%s%d\n", -			data->gpio_config[i] & 0x02 ? "" : "!", -			data->gpio_config[i] & 0x01 ? "OUT" : "IN", -			i); -	} -	if (data->config3 & CFG3_GPIO16_ENABLE) { -		dev_dbg(&client->dev, "\t%sGP%s16\n", -			data->gpio_config[16] & 0x02 ? "" : "!", -			data->gpio_config[16] & 0x01 ? "OUT" : "IN"); -	} else { -		/* GPIO16 is THERM */ -		dev_dbg(&client->dev, "\tTHERM\n"); -	} -} - -static void adm1026_fixup_gpio(struct i2c_client *client) -{ -	struct adm1026_data *data = i2c_get_clientdata(client); -	int i; -	int value; - -	/* Make the changes requested. */ -	/* -	 * We may need to unlock/stop monitoring or soft-reset the -	 *    chip before we can make changes.  This hasn't been -	 *    tested much.  FIXME -	 */ - -	/* Make outputs */ -	for (i = 0; i <= 16; ++i) { -		if (gpio_output[i] >= 0 && gpio_output[i] <= 16) -			data->gpio_config[gpio_output[i]] |= 0x01; -		/* if GPIO0-7 is output, it isn't a FAN tach */ -		if (gpio_output[i] >= 0 && gpio_output[i] <= 7) -			data->config2 |= 1 << gpio_output[i]; -	} - -	/* Input overrides output */ -	for (i = 0; i <= 16; ++i) { -		if (gpio_input[i] >= 0 && gpio_input[i] <= 16) -			data->gpio_config[gpio_input[i]] &= ~0x01; -		/* if GPIO0-7 is input, it isn't a FAN tach */ -		if (gpio_input[i] >= 0 && gpio_input[i] <= 7) -			data->config2 |= 1 << gpio_input[i]; -	} - -	/* 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 */ -	for (i = 0; i <= 16; ++i) { -		if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) -			data->gpio_config[gpio_normal[i]] |= 0x02; -	} - -	/* Fan overrides input and output */ -	for (i = 0; i <= 7; ++i) { -		if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) -			data->config2 &= ~(1 << gpio_fan[i]); -	} - -	/* Write new configs to registers */ -	adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2); -	data->config3 = (data->config3 & 0x3f) -			| ((data->gpio_config[16] & 0x03) << 6); -	adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3); -	for (i = 15, value = 0; i >= 0; --i) { -		value <<= 2; -		value |= data->gpio_config[i] & 0x03; -		if ((i & 0x03) == 0) { -			adm1026_write_value(client, -					ADM1026_REG_GPIO_CFG_0_3 + i/4, -					value); -			value = 0; -		} -	} - -	/* Print the new config */ -	adm1026_print_gpio(client); -} - -  static struct adm1026_data *adm1026_update_device(struct device *dev)  { -	struct i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	int i;  	long value, alarms, gpio; @@ -728,8 +496,8 @@ static ssize_t set_in_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 i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -756,8 +524,8 @@ static ssize_t set_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 i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -815,8 +583,8 @@ static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr,  static ssize_t set_in16_min(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); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -840,8 +608,8 @@ static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr,  static ssize_t set_in16_max(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); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -888,8 +656,8 @@ static ssize_t set_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 i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -923,8 +691,8 @@ fan_offset(8);  /* Adjust fan_min to account for new fan divisor */  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); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	int new_min;  	int new_div = data->fan_div[fan]; @@ -952,8 +720,8 @@ static ssize_t set_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 i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int orig_div, new_div;  	int err; @@ -1024,8 +792,8 @@ static ssize_t set_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 i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -1053,8 +821,8 @@ static ssize_t set_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 i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -1097,8 +865,8 @@ static ssize_t set_temp_offset(struct device *dev,  {  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);  	int nr = sensor_attr->index; -	struct i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -1153,8 +921,8 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev,  {  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);  	int nr = sensor_attr->index; -	struct i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -1192,8 +960,8 @@ static ssize_t show_temp_crit_enable(struct device *dev,  static ssize_t set_temp_crit_enable(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); +	struct i2c_client *client = data->client;  	unsigned long val;  	int err; @@ -1233,8 +1001,8 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,  {  	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);  	int nr = sensor_attr->index; -	struct i2c_client *client = to_i2c_client(dev); -	struct adm1026_data *data = i2c_get_clientdata(client); +	struct adm1026_data *data = dev_get_drvdata(dev); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -1268,8 +1036,8 @@ static ssize_t set_analog_out_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); +	struct i2c_client *client = data->client;  	long val;  	int err; @@ -1317,6 +1085,9 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,  	if (err)  		return err; +	if (val > 255) +		return -EINVAL; +  	data->vrm = val;  	return count;  } @@ -1378,8 +1149,8 @@ static ssize_t show_alarm_mask(struct device *dev,  static ssize_t set_alarm_mask(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); +	struct i2c_client *client = data->client;  	unsigned long mask;  	long val;  	int err; @@ -1420,8 +1191,8 @@ static ssize_t show_gpio(struct device *dev, struct device_attribute *attr,  static ssize_t set_gpio(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); +	struct i2c_client *client = data->client;  	long gpio;  	long val;  	int err; @@ -1453,8 +1224,8 @@ static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr,  static ssize_t set_gpio_mask(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); +	struct i2c_client *client = data->client;  	long mask;  	long val;  	int err; @@ -1487,8 +1258,8 @@ static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr,  static ssize_t set_pwm_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); +	struct i2c_client *client = data->client;  	if (data->pwm1.enable == 1) {  		long val; @@ -1517,8 +1288,8 @@ static ssize_t set_auto_pwm_min(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); +	struct i2c_client *client = data->client;  	unsigned long val;  	int err; @@ -1553,8 +1324,8 @@ static ssize_t show_pwm_enable(struct device *dev,  static ssize_t set_pwm_enable(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); +	struct i2c_client *client = data->client;  	int old_enable;  	unsigned long val;  	int err; @@ -1829,18 +1600,220 @@ static int adm1026_detect(struct i2c_client *client,  	return 0;  } +static void adm1026_print_gpio(struct i2c_client *client) +{ +	struct adm1026_data *data = i2c_get_clientdata(client); +	int i; + +	dev_dbg(&client->dev, "GPIO config is:\n"); +	for (i = 0; i <= 7; ++i) { +		if (data->config2 & (1 << i)) { +			dev_dbg(&client->dev, "\t%sGP%s%d\n", +				data->gpio_config[i] & 0x02 ? "" : "!", +				data->gpio_config[i] & 0x01 ? "OUT" : "IN", +				i); +		} else { +			dev_dbg(&client->dev, "\tFAN%d\n", i); +		} +	} +	for (i = 8; i <= 15; ++i) { +		dev_dbg(&client->dev, "\t%sGP%s%d\n", +			data->gpio_config[i] & 0x02 ? "" : "!", +			data->gpio_config[i] & 0x01 ? "OUT" : "IN", +			i); +	} +	if (data->config3 & CFG3_GPIO16_ENABLE) { +		dev_dbg(&client->dev, "\t%sGP%s16\n", +			data->gpio_config[16] & 0x02 ? "" : "!", +			data->gpio_config[16] & 0x01 ? "OUT" : "IN"); +	} else { +		/* GPIO16 is THERM */ +		dev_dbg(&client->dev, "\tTHERM\n"); +	} +} + +static void adm1026_fixup_gpio(struct i2c_client *client) +{ +	struct adm1026_data *data = i2c_get_clientdata(client); +	int i; +	int value; + +	/* Make the changes requested. */ +	/* +	 * We may need to unlock/stop monitoring or soft-reset the +	 *    chip before we can make changes.  This hasn't been +	 *    tested much.  FIXME +	 */ + +	/* Make outputs */ +	for (i = 0; i <= 16; ++i) { +		if (gpio_output[i] >= 0 && gpio_output[i] <= 16) +			data->gpio_config[gpio_output[i]] |= 0x01; +		/* if GPIO0-7 is output, it isn't a FAN tach */ +		if (gpio_output[i] >= 0 && gpio_output[i] <= 7) +			data->config2 |= 1 << gpio_output[i]; +	} + +	/* Input overrides output */ +	for (i = 0; i <= 16; ++i) { +		if (gpio_input[i] >= 0 && gpio_input[i] <= 16) +			data->gpio_config[gpio_input[i]] &= ~0x01; +		/* if GPIO0-7 is input, it isn't a FAN tach */ +		if (gpio_input[i] >= 0 && gpio_input[i] <= 7) +			data->config2 |= 1 << gpio_input[i]; +	} + +	/* 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 */ +	for (i = 0; i <= 16; ++i) { +		if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) +			data->gpio_config[gpio_normal[i]] |= 0x02; +	} + +	/* Fan overrides input and output */ +	for (i = 0; i <= 7; ++i) { +		if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) +			data->config2 &= ~(1 << gpio_fan[i]); +	} + +	/* Write new configs to registers */ +	adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2); +	data->config3 = (data->config3 & 0x3f) +			| ((data->gpio_config[16] & 0x03) << 6); +	adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3); +	for (i = 15, value = 0; i >= 0; --i) { +		value <<= 2; +		value |= data->gpio_config[i] & 0x03; +		if ((i & 0x03) == 0) { +			adm1026_write_value(client, +					ADM1026_REG_GPIO_CFG_0_3 + i/4, +					value); +			value = 0; +		} +	} + +	/* Print the new config */ +	adm1026_print_gpio(client); +} + +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"); +	/* Read chip config */ +	data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1); +	data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2); +	data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3); + +	/* Inform user of chip config */ +	dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n", +		data->config1); +	if ((data->config1 & CFG1_MONITOR) == 0) { +		dev_dbg(&client->dev, +			"Monitoring not currently enabled.\n"); +	} +	if (data->config1 & CFG1_INT_ENABLE) { +		dev_dbg(&client->dev, +			"SMBALERT interrupts are enabled.\n"); +	} +	if (data->config1 & CFG1_AIN8_9) { +		dev_dbg(&client->dev, +			"in8 and in9 enabled. temp3 disabled.\n"); +	} else { +		dev_dbg(&client->dev, +			"temp3 enabled.  in8 and in9 disabled.\n"); +	} +	if (data->config1 & CFG1_THERM_HOT) { +		dev_dbg(&client->dev, +			"Automatic THERM, PWM, and temp limits enabled.\n"); +	} + +	if (data->config3 & CFG3_GPIO16_ENABLE) { +		dev_dbg(&client->dev, +			"GPIO16 enabled.  THERM pin disabled.\n"); +	} else { +		dev_dbg(&client->dev, +			"THERM pin enabled.  GPIO16 disabled.\n"); +	} +	if (data->config3 & CFG3_VREF_250) +		dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); +	else +		dev_dbg(&client->dev, "Vref is 1.82 Volts.\n"); +	/* Read and pick apart the existing GPIO configuration */ +	value = 0; +	for (i = 0; i <= 15; ++i) { +		if ((i & 0x03) == 0) { +			value = adm1026_read_value(client, +					ADM1026_REG_GPIO_CFG_0_3 + i / 4); +		} +		data->gpio_config[i] = value & 0x03; +		value >>= 2; +	} +	data->gpio_config[16] = (data->config3 >> 6) & 0x03; + +	/* ... and then print it */ +	adm1026_print_gpio(client); + +	/* +	 * If the user asks us to reprogram the GPIO config, then +	 * do it now. +	 */ +	if (gpio_input[0] != -1 || gpio_output[0] != -1 +		|| gpio_inverted[0] != -1 || gpio_normal[0] != -1 +		|| gpio_fan[0] != -1) { +		adm1026_fixup_gpio(client); +	} + +	/* +	 * WE INTENTIONALLY make no changes to the limits, +	 *   offsets, pwms, fans and zones.  If they were +	 *   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 +	 *   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 +	 *   will not result in potentially dangerous fan speed decrease. +	 */ +	data->pwm1.auto_pwm_min = 255; +	/* Start monitoring */ +	value = adm1026_read_value(client, ADM1026_REG_CONFIG1); +	/* Set MONITOR, clear interrupt acknowledge and s/w reset */ +	value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET); +	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value); +	data->config1 = value; +	adm1026_write_value(client, ADM1026_REG_CONFIG1, value); + +	/* initialize fan_div[] to hardware defaults */ +	value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) | +		(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8); +	for (i = 0; i <= 7; ++i) { +		data->fan_div[i] = DIV_FROM_REG(value & 0x03); +		value >>= 2; +	} +} +  static int adm1026_probe(struct i2c_client *client,  			 const struct i2c_device_id *id)  { +	struct device *dev = &client->dev; +	struct device *hwmon_dev;  	struct adm1026_data *data; -	int err; -	data = devm_kzalloc(&client->dev, sizeof(struct adm1026_data), -			    GFP_KERNEL); +	data = devm_kzalloc(dev, sizeof(struct adm1026_data), GFP_KERNEL);  	if (!data)  		return -ENOMEM;  	i2c_set_clientdata(client, data); +	data->client = client;  	mutex_init(&data->update_lock);  	/* Set the VRM version */ @@ -1849,48 +1822,34 @@ static int adm1026_probe(struct i2c_client *client,  	/* Initialize the ADM1026 chip */  	adm1026_init_client(client); -	/* Register sysfs hooks */ -	err = sysfs_create_group(&client->dev.kobj, &adm1026_group); -	if (err) -		return err; +	/* sysfs hooks */ +	data->groups[0] = &adm1026_group;  	if (data->config1 & CFG1_AIN8_9) -		err = sysfs_create_group(&client->dev.kobj, -					 &adm1026_group_in8_9); +		data->groups[1] = &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(&client->dev); -	if (IS_ERR(data->hwmon_dev)) { -		err = PTR_ERR(data->hwmon_dev); -		goto exitremove; -	} - -	return 0; +		data->groups[1] = &adm1026_group_temp3; -	/* Error out and cleanup code */ -exitremove: -	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); -	return err; +	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, +							   data, data->groups); +	return PTR_ERR_OR_ZERO(hwmon_dev);  } -static int adm1026_remove(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); -	return 0; -} +static const struct i2c_device_id adm1026_id[] = { +	{ "adm1026", 0 }, +	{ } +}; +MODULE_DEVICE_TABLE(i2c, adm1026_id); + +static struct i2c_driver adm1026_driver = { +	.class		= I2C_CLASS_HWMON, +	.driver = { +		.name	= "adm1026", +	}, +	.probe		= adm1026_probe, +	.id_table	= adm1026_id, +	.detect		= adm1026_detect, +	.address_list	= normal_i2c, +};  module_i2c_driver(adm1026_driver);  | 
