hwmon: (ad7418) Catch I2C errors
If there is an i2c failure, the ad7416 reports its temperature as 0C. Return an error code so users can properly detect errors. Signed-off-by: Brandon Maier <brandon.maier@rockwellcollins.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
e9b95485c1
commit
45034e4827
@ -54,10 +54,11 @@ struct ad7418_data {
|
||||
u16 in[4];
|
||||
};
|
||||
|
||||
static struct ad7418_data *ad7418_update_device(struct device *dev)
|
||||
static int ad7418_update_device(struct device *dev)
|
||||
{
|
||||
struct ad7418_data *data = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = data->client;
|
||||
s32 val;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
@ -67,47 +68,74 @@ static struct ad7418_data *ad7418_update_device(struct device *dev)
|
||||
int i, ch;
|
||||
|
||||
/* read config register and clear channel bits */
|
||||
cfg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
|
||||
val = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
|
||||
if (val < 0)
|
||||
goto abort;
|
||||
|
||||
cfg = val;
|
||||
cfg &= 0x1F;
|
||||
|
||||
i2c_smbus_write_byte_data(client, AD7418_REG_CONF,
|
||||
val = i2c_smbus_write_byte_data(client, AD7418_REG_CONF,
|
||||
cfg | AD7418_CH_TEMP);
|
||||
if (val < 0)
|
||||
goto abort;
|
||||
|
||||
udelay(30);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
data->temp[i] =
|
||||
i2c_smbus_read_word_swapped(client,
|
||||
AD7418_REG_TEMP[i]);
|
||||
val = i2c_smbus_read_word_swapped(client,
|
||||
AD7418_REG_TEMP[i]);
|
||||
if (val < 0)
|
||||
goto abort;
|
||||
|
||||
data->temp[i] = val;
|
||||
}
|
||||
|
||||
for (i = 0, ch = 4; i < data->adc_max; i++, ch--) {
|
||||
i2c_smbus_write_byte_data(client,
|
||||
AD7418_REG_CONF,
|
||||
val = i2c_smbus_write_byte_data(client, AD7418_REG_CONF,
|
||||
cfg | AD7418_REG_ADC_CH(ch));
|
||||
if (val < 0)
|
||||
goto abort;
|
||||
|
||||
udelay(15);
|
||||
data->in[data->adc_max - 1 - i] =
|
||||
i2c_smbus_read_word_swapped(client,
|
||||
AD7418_REG_ADC);
|
||||
val = i2c_smbus_read_word_swapped(client,
|
||||
AD7418_REG_ADC);
|
||||
if (val < 0)
|
||||
goto abort;
|
||||
|
||||
data->in[data->adc_max - 1 - i] = val;
|
||||
}
|
||||
|
||||
/* restore old configuration value */
|
||||
i2c_smbus_write_word_swapped(client, AD7418_REG_CONF, cfg);
|
||||
val = i2c_smbus_write_word_swapped(client, AD7418_REG_CONF,
|
||||
cfg);
|
||||
if (val < 0)
|
||||
goto abort;
|
||||
|
||||
data->last_updated = jiffies;
|
||||
data->valid = 1;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
return 0;
|
||||
|
||||
return data;
|
||||
abort:
|
||||
data->valid = 0;
|
||||
mutex_unlock(&data->lock);
|
||||
return val;
|
||||
}
|
||||
|
||||
static ssize_t temp_show(struct device *dev, struct device_attribute *devattr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
|
||||
struct ad7418_data *data = ad7418_update_device(dev);
|
||||
struct ad7418_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = ad7418_update_device(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%d\n",
|
||||
LM75_TEMP_FROM_REG(data->temp[attr->index]));
|
||||
}
|
||||
@ -116,7 +144,12 @@ static ssize_t adc_show(struct device *dev, struct device_attribute *devattr,
|
||||
char *buf)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
|
||||
struct ad7418_data *data = ad7418_update_device(dev);
|
||||
struct ad7418_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = ad7418_update_device(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%d\n",
|
||||
((data->in[attr->index] >> 6) * 2500 + 512) / 1024);
|
||||
|
Loading…
Reference in New Issue
Block a user