diff options
author | sreenivasulu velpula <svelpula@nvidia.com> | 2013-12-03 15:03:31 +0530 |
---|---|---|
committer | Sandeep Trasi <strasi@nvidia.com> | 2014-04-03 10:29:38 -0700 |
commit | ab87b6c92f28d666277fdcac392d13a4602dcd38 (patch) | |
tree | 7e0778d48387d7f65a817726b382691afbba15c7 /drivers/hwmon | |
parent | 50097a19989aa7e8ffd6dc94f35b7e6b0f0d8761 (diff) |
drivers: hwmon: Add support for NVT210
NVT210 Temperature sensor
Bug 1382499
Bug 1442432
Change-Id: I06fd1d8c250423ab3b5b90b76925d2d52330eaa2
Signed-off-by: sreenivasulu velpula <svelpula@nvidia.com>
Reviewed-on: http://git-master/r/337707
Signed-off-by: sreenivasulu velpula <svelpula@nvidia.com>
Reviewed-on: http://git-master/r/364893
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sandeep Trasi <strasi@nvidia.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 10 | ||||
-rw-r--r-- | drivers/hwmon/tmon-tmp411.c | 414 |
2 files changed, 301 insertions, 123 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 9f444b3d7585..a0becc671d88 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1323,15 +1323,15 @@ config SENSORS_VEXPRESS range of information like temperature, power, energy. config SENSORS_TMON_TMP411 - tristate "Temperature Monitor driver" - depends on !SENSORS_TMP401 + tristate "Temperature Monitor driver for TMP411 and NVT210" + depends on !SENSORS_TMP401 && !SENSORS_LM90 default n help - This driver supports TMP411 sensor by TI. It is used to update + This driver supports TMP411 and NVT210 sensors. It is used to update registers dynamically based on the curret temperature. - If you say yes here temperature monitor driver will monitor - temperature. + If you say yes here temperature monitoring support for TMP411 and NVT210 + will be available. config SENSORS_VIA_CPUTEMP tristate "VIA CPU temperature sensor" diff --git a/drivers/hwmon/tmon-tmp411.c b/drivers/hwmon/tmon-tmp411.c index 759e3caeaf4a..e3b2137f22bf 100644 --- a/drivers/hwmon/tmon-tmp411.c +++ b/drivers/hwmon/tmon-tmp411.c @@ -19,7 +19,7 @@ * */ -/* Note: Copied temperature conversion code from TMP411 driver */ +/* Note: Copied temperature conversion code from tmp401 driver */ #include <linux/module.h> #include <linux/i2c.h> @@ -44,26 +44,31 @@ #define TMON_NOCHANGE (INT_MAX - 1) /* - * The TMP411 registers, note some registers have different addresses for + * The TMP411/NVT210 registers, note some registers have different addresses for * reading and writing */ #define REG_STATUS 0x02 #define REG_CFG_READ 0x03 +#define REG_CFG_WRITE 0x09 #define REG_CON_RATE_READ 0x04 #define REG_CONV_RATE_WRITE 0x0A +#define REG_MAN_ID 0xFE /* Flags */ -#define EXTND_CNFG_RNG 0x04 -#define CONFIG_SHUTDOWN 0x40 -#define STATUS_LOCAL_CRIT 0x01 -#define STATUS_REMOTE_CRIT 0x02 -#define STATUS_REMOTE_OPEN 0x04 -#define STATUS_REMOTE_LOW 0x08 -#define STATUS_REMOTE_HIGH 0x10 -#define STATUS_LOCAL_LOW 0x20 -#define STATUS_LOCAL_HIGH 0x40 -#define STATUS_RTHRM 0x02 -#define STATUS_LTHRM 0x01 +#define CFG_EXTEND (0x1<<2) +#define CFG_ALERT_MASK (0x1<<7) +#define CFG_STANDBY (0x1<<6) +#define CFG_ALERT_DISABLE (0x1<<5) +#define STATUS_LOCAL_CRIT 0x01 +#define STATUS_REMOTE_CRIT 0x02 +#define STATUS_REMOTE_OPEN 0x04 +#define STATUS_REMOTE_LOW 0x08 +#define STATUS_REMOTE_HIGH 0x10 +#define STATUS_LOCAL_LOW 0x20 +#define STATUS_LOCAL_HIGH 0x40 +#define STATUS_RTHRM 0x02 +#define STATUS_LTHRM 0x01 + /* Based on POR values of CONVERSION RATE REGISTER (125ms) + @@ -90,6 +95,21 @@ enum alert_type { REMOTE_LOW_ALERT, }; +enum tmp_sensor { + TMP411 = 0, + NVT210, +}; + +enum temp_type { + LOCAL = 0, + REMOTE, +}; + +static enum tmp_sensor tmon_device; + +/* TMP411/NVT210 registers +Note: Local temperature low bytes not applicable in case of NVT210 +index 0 for local temperatures and 1 for remote temperatures */ static const u8 REG_TEMP_MSB[2] = { 0x00, 0x01 }; static const u8 REG_TEMP_LSB[2] = { 0x15, 0x10 }; static const u8 REG_TEMP_LOW_LIMIT_MSB_RD[2] = { 0x06, 0x08 }; @@ -101,10 +121,12 @@ static const u8 REG_TEMP_HIGH_LIMIT_LSB[2] = { 0x16, 0x13 }; static const u8 REG_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 }; #ifdef CONFIG_PM +/* index 0 for local temperatures and 1 for remote temperatures */ static u16 temp_low_limit[2]; static u16 temp_high_limit[2]; static u8 temp_crit_limit[2]; static u8 conv_rate; +static u8 config; #endif struct tmon_info { @@ -128,18 +150,19 @@ struct tmon_info { }; +/* Return Both High byte and Low byte */ static u16 temp_to_reg(long temp, u8 config) { - if (config & EXTND_CNFG_RNG) { - temp = SENSORS_LIMIT(temp, -64000, 191000); + if (config & CFG_EXTEND) { + temp = clamp_val(temp, -64000, 191000); temp += 64000; } else - temp = SENSORS_LIMIT(temp, 0, 127000); + temp = clamp_val(temp, 0, 127000); return (temp * 160 + 312) / 625; /* Copied from TMP411 driver */ } -static int tmon_read(struct i2c_client *client, u8 reg, u8 *value) +static s32 tmon_read(struct i2c_client *client, u8 reg, u8 *value) { s32 tmp; @@ -152,18 +175,20 @@ static int tmon_read(struct i2c_client *client, u8 reg, u8 *value) return 0; } -static int reg_to_temp(u16 reg, u8 config) +/* Expects both High byte and Low byte, If not Low bytes then + make Low byte as 0 */ +static s32 reg_to_temp(u16 reg, u8 config) { - int temp = reg; + s32 temp = reg; - if (config & EXTND_CNFG_RNG) + if (config & CFG_EXTEND) temp -= 64 * 256; return (temp * 625 + 80) / 160; /* Copied from TMP411 driver */ } -static int tmon_read_remote_temp(struct i2c_client *client, - int *ptemp) +static s32 tmon_read_remote_temp(struct i2c_client *client, + s32 *ptemp) { u8 config; u8 tmp; @@ -183,7 +208,7 @@ static int tmon_read_remote_temp(struct i2c_client *client, return 0; } -static int tmon_read_local_temp(struct i2c_client *client, +static s32 tmon_read_local_temp(struct i2c_client *client, int *ptemp) { u8 config; @@ -193,14 +218,153 @@ static int tmon_read_local_temp(struct i2c_client *client, TMON_RD(client, REG_CFG_READ, &config); TMON_RD(client, REG_TEMP_MSB[0], &tmp); temperature = ((u16)tmp) << 8; - TMON_RD(client, REG_TEMP_LSB[0], &tmp); - temperature |= tmp; + if (tmon_device == TMP411) { + TMON_RD(client, REG_TEMP_LSB[0], &tmp); + temperature |= tmp; + } + + *ptemp = reg_to_temp(temperature, config); + + return 0; +} + + +static s32 tmon_read_low_limit(struct i2c_client *client, + s32 *ptemp, enum temp_type typ) +{ + u8 config; + u8 tmp; + int err; + u16 temperature = 0; + struct tmon_info *data = i2c_get_clientdata(client); + TMON_RD(client, REG_CFG_READ, &config); + TMON_RD(client, REG_TEMP_LOW_LIMIT_MSB_RD[typ], &tmp); + temperature = ((u16)tmp) << 8; + if ((typ == REMOTE) || (typ == LOCAL && tmon_device == TMP411)) { + TMON_RD(client, REG_TEMP_LOW_LIMIT_LSB[typ], &tmp); + temperature |= tmp; + } *ptemp = reg_to_temp(temperature, config); + if (typ == REMOTE) + *ptemp = *ptemp + data->pdata->remote_offset; + return 0; +} +static s32 tmon_read_high_limit(struct i2c_client *client, + s32 *ptemp, enum temp_type typ) +{ + u8 config; + u8 tmp; + int err; + u16 temperature = 0; + struct tmon_info *data = i2c_get_clientdata(client); + + TMON_RD(client, REG_CFG_READ, &config); + TMON_RD(client, REG_TEMP_HIGH_LIMIT_MSB_RD[typ], &tmp); + temperature = ((u16)tmp) << 8; + if ((typ == REMOTE) || (typ == LOCAL && tmon_device == TMP411)) { + TMON_RD(client, REG_TEMP_HIGH_LIMIT_LSB[typ], &tmp); + temperature |= tmp; + } + *ptemp = reg_to_temp(temperature, config); + if (typ == REMOTE) + *ptemp = *ptemp + data->pdata->remote_offset; return 0; } +static s32 tmon_read_critical_limit(struct i2c_client *client, + s32 *ptemp, enum temp_type typ) +{ + u8 config; + u8 tmp; + int err; + u16 temperature = 0; + struct tmon_info *data = i2c_get_clientdata(client); + + TMON_RD(client, REG_CFG_READ, &config); + TMON_RD(client, REG_TEMP_CRIT_LIMIT[typ], &tmp); + temperature = ((u16)tmp) << 8; + *ptemp = reg_to_temp(temperature, config); + if (typ == REMOTE) + *ptemp = *ptemp + data->pdata->remote_offset; + return 0; +} + +static int tmon_write_high_limit(struct i2c_client *client, + s32 temp, enum temp_type typ) +{ + u8 config; + u8 reg8_val; + int err; + u16 reg16_val; + struct tmon_info *data = i2c_get_clientdata(client); + + TMON_RD(client, REG_CFG_READ, &config); + if (typ == REMOTE) + temp = temp - data->pdata->remote_offset; + + reg16_val = temp_to_reg(temp, config); + reg8_val = reg16_val >> 8; + + mutex_lock(&data->update_lock); + TMON_WRT(client, REG_TEMP_HIGH_LIMIT_MSB_WRT[typ], reg8_val); + if (tmon_device == TMP411) + TMON_WRT(client, REG_TEMP_HIGH_LIMIT_LSB[typ], + (reg16_val & 0xFF)); + mutex_unlock(&data->update_lock); + return 0; +} + +static int tmon_write_low_limit(struct i2c_client *client, + s32 temp, enum temp_type typ) +{ + u8 config; + u8 reg8_val; + int err; + u16 reg16_val; + struct tmon_info *data = i2c_get_clientdata(client); + + TMON_RD(client, REG_CFG_READ, &config); + + if (typ == REMOTE) + temp = temp - data->pdata->remote_offset; + + reg16_val = temp_to_reg(temp, config); + reg8_val = reg16_val >> 8; + + mutex_lock(&data->update_lock); + TMON_WRT(client, REG_TEMP_LOW_LIMIT_MSB_WRT[typ], reg8_val); + if (tmon_device == TMP411) + TMON_WRT(client, REG_TEMP_LOW_LIMIT_LSB[typ], + (reg16_val & 0xFF)); + mutex_unlock(&data->update_lock); + return 0; +} + +#if FUTURE_USE +static int tmon_write_critical_limit(struct i2c_client *client, + s32 temp, enum temp_type typ) +{ + u8 config; + u16 reg16_val; + u8 reg8_val; + int err; + struct tmon_info *data = i2c_get_clientdata(client); + + TMON_RD(client, REG_CFG_READ, &config); + if (typ == REMOTE) + temp = temp - data->pdata->remote_offset; + + reg16_val = temp_to_reg(temp, config); + reg8_val = reg16_val >> 8; + mutex_lock(&data->update_lock); + TMON_WRT(client, REG_TEMP_CRIT_LIMIT[typ], reg8_val); + mutex_unlock(&data->update_lock); + return 0; +} +#endif + static ssize_t show_temp_value(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -218,39 +382,19 @@ static ssize_t show_temp_value(struct device *dev, static ssize_t show_remote_low_limit(struct device *dev, struct device_attribute *devattr, char *buf) { - u16 low_limit = 0; - u8 config = 0; - u8 temp; - int err; - struct tmon_info *data = i2c_get_clientdata(to_i2c_client(dev)); - - TMON_RD(to_i2c_client(dev), REG_TEMP_LOW_LIMIT_MSB_RD[1], &temp); - low_limit = ((u16)temp) << 8; - TMON_RD(to_i2c_client(dev), REG_TEMP_LOW_LIMIT_LSB[1], &temp); - low_limit |= temp; - TMON_RD(to_i2c_client(dev), REG_CFG_READ, &config); + s32 low_limit = 0; - return sprintf(buf, "%d\n", (reg_to_temp(low_limit, config) + - data->pdata->remote_offset)); + tmon_read_low_limit(to_i2c_client(dev), &low_limit, REMOTE); + return sprintf(buf, "%d\n", low_limit); } static ssize_t show_remote_high_limit(struct device *dev, struct device_attribute *devattr, char *buf) { - u16 high_limit = 0; - u8 config; - u8 temp; - int err; - struct tmon_info *data = i2c_get_clientdata(to_i2c_client(dev)); - - TMON_RD(to_i2c_client(dev), REG_TEMP_HIGH_LIMIT_MSB_RD[1], &temp); - high_limit = ((u16)temp) << 8; - TMON_RD(to_i2c_client(dev), REG_TEMP_HIGH_LIMIT_LSB[1], &temp); - high_limit |= temp; - TMON_RD(to_i2c_client(dev), REG_CFG_READ, &config); + s32 high_limit = 0; - return sprintf(buf, "%d\n", (reg_to_temp(high_limit, config) + - data->pdata->remote_offset)); + tmon_read_high_limit(to_i2c_client(dev), &high_limit, REMOTE); + return sprintf(buf, "%d\n", high_limit); } static int clear_alert(struct tmon_info *data) @@ -389,44 +533,27 @@ static ssize_t show_alert_blocking(struct device *dev, static ssize_t show_remote_shutdown_limit(struct device *dev, struct device_attribute *devattr, char *buf) { - u8 config = 0; - u8 temp; - int err; - struct tmon_info *data = i2c_get_clientdata(to_i2c_client(dev)); - TMON_RD(to_i2c_client(dev), REG_TEMP_CRIT_LIMIT[1], &temp); - TMON_RD(to_i2c_client(dev), REG_CFG_READ, &config); - if (config & EXTND_CNFG_RNG) - temp = temp - 64; - return sprintf(buf, "%d\n", (temp * 1000 + - data->pdata->remote_offset)); + s32 temp; + s32 err; + err = tmon_read_critical_limit(to_i2c_client(dev), &temp, REMOTE); + if (err) + return err; + return sprintf(buf, "%d\n", temp); } static ssize_t store_remote_low_limit(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { - int index = to_sensor_dev_attr(devattr)->index; - struct tmon_info *data = i2c_get_clientdata(to_i2c_client(dev)); long val; - u16 reg; - u8 config; - int err; + s32 err; if (kstrtol(buf, 10, &val)) return -EINVAL; - TMON_RD(to_i2c_client(dev), REG_CFG_READ, &config); - - reg = temp_to_reg((val - data->pdata->remote_offset), config); - - mutex_lock(&data->update_lock); - - TMON_WRT(to_i2c_client(dev), - REG_TEMP_LOW_LIMIT_MSB_WRT[index], reg >> 8); - TMON_WRT(to_i2c_client(dev), - REG_TEMP_LOW_LIMIT_LSB[index], reg & 0xFF); - - mutex_unlock(&data->update_lock); + err = tmon_write_low_limit(to_i2c_client(dev), val, REMOTE); + if (err) + return err; return count; } @@ -434,26 +561,15 @@ static ssize_t store_remote_high_limit(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { - int index = to_sensor_dev_attr(devattr)->index; - struct tmon_info *data = i2c_get_clientdata(to_i2c_client(dev)); long val; - u16 reg; - u8 config; int err; if (kstrtol(buf, 10, &val)) return -EINVAL; - TMON_RD(to_i2c_client(dev), REG_CFG_READ, &config); - reg = temp_to_reg((val - data->pdata->remote_offset), config); - - mutex_lock(&data->update_lock); - TMON_WRT(to_i2c_client(dev), - REG_TEMP_HIGH_LIMIT_MSB_WRT[index], reg >> 8); - TMON_WRT(to_i2c_client(dev), - REG_TEMP_HIGH_LIMIT_LSB[index], reg & 0xFF); - - mutex_unlock(&data->update_lock); + err = tmon_write_high_limit(to_i2c_client(dev), val, REMOTE); + if (err) + return err; return count; } @@ -579,6 +695,8 @@ static int tmon_tmp411_probe(struct i2c_client *client, struct tmon_info *data; int err; int i; + u8 man_id; + u8 config; if (tmon_pdata == NULL) { dev_err(&client->dev, "no platform data\n"); @@ -591,10 +709,41 @@ static int tmon_tmp411_probe(struct i2c_client *client, return -ENODEV; } - data = kzalloc(sizeof(struct tmon_info), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(struct tmon_info), GFP_KERNEL); if (!data) return -ENOMEM; + TMON_RD(client, REG_MAN_ID, &man_id); + if (man_id == 0x41) { + tmon_device = NVT210; + dev_info(&client->dev, "detected NVT210\n"); + } else if (man_id == 0x55) { + tmon_device = TMP411; + dev_info(&client->dev, "detected TMP411\n"); + } else { + dev_warn(&client->dev, + "unsuported t-sensor with manufacturer-id:0x%x\n", + man_id); + return -EINVAL; + } + + TMON_RD(client, REG_CFG_READ, &config); + + /* Enable Alert, Extended mode and disable stand by */ + config |= CFG_EXTEND; + config &= ~CFG_ALERT_MASK; + config &= ~CFG_STANDBY; + config &= ~CFG_ALERT_DISABLE; + err = i2c_smbus_write_byte_data(client, REG_CFG_WRITE, config); + + /*FIXME: Is it required to wait for one temperature conversion? */ + + if (err < 0) { + dev_warn(&client->dev, + "\n Failed to write config for temperature sensor\n"); + return err; + } + data->client = client; i2c_set_clientdata(client, data); data->pdata = tmon_pdata; @@ -603,6 +752,14 @@ static int tmon_tmp411_probe(struct i2c_client *client, spin_lock_init(&data->alert_spinlock); data->sysfs_therm_alert_timeout = 0; data->therm_alert = 0; + + /* + * Suppose, if we get alert interrupts immediately after irq + * registeration and before disable_irq_nosync, then once entered + * in to Isr, if the below variable is set then irq will be disabled, + * otherwise it's likely that continious interrupts comes. + */ + data->disable_intr_reqr = 1; init_waitqueue_head(&data->alert_wait_queue); if (data->pdata->alert_gpio != -1) { @@ -613,12 +770,16 @@ static int tmon_tmp411_probe(struct i2c_client *client, IRQF_TRIGGER_LOW, "tmon alert", data); + dev_info(&client->dev, "\n Tmon IRQ registered for gpio:%d\n", + data->pdata->alert_gpio); + if (!err) { /*Disable now and enable only when sysfs alert is opened */ disable_irq_nosync(data->irq_num); data->alert_info = - kzalloc(sizeof(struct i2c_smbus_alert_setup), + devm_kzalloc(&client->dev, + sizeof(struct i2c_smbus_alert_setup), GFP_KERNEL); if (!data->alert_info) { err = -ENOMEM; @@ -631,7 +792,7 @@ static int tmon_tmp411_probe(struct i2c_client *client, dev_warn(&client->dev, "failed to get irq for alert gpio:%d\n", data->pdata->alert_gpio); - goto err_free_data; + return err; } } @@ -656,11 +817,8 @@ err_exit: for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) device_remove_file(&client->dev, &tmp411_attr[i].dev_attr); i2c_unregister_device(data->ara); - kfree(data->alert_info); err_irq: free_irq(data->irq_num, data); -err_free_data: - kfree(data); return err; } @@ -699,22 +857,23 @@ static int tmon_tmp411_suspend(struct device *dev) * by the low byte */ TMON_RD(client, REG_TEMP_LOW_LIMIT_MSB_RD[i], &tmp); - temp_low_limit[i] = tmp; - temp_low_limit[i] = temp_low_limit[i] << 8; - - TMON_RD(client, REG_TEMP_LOW_LIMIT_LSB[i], &tmp); - temp_low_limit[i] |= tmp; + temp_low_limit[i] = ((u16)tmp) << 8; + if ((i == REMOTE) || (i == LOCAL && tmon_device == TMP411)) { + TMON_RD(client, REG_TEMP_LOW_LIMIT_LSB[i], &tmp); + temp_low_limit[i] |= tmp; + } TMON_RD(client, REG_TEMP_HIGH_LIMIT_MSB_RD[i], &tmp); - temp_high_limit[i] = tmp; - temp_high_limit[i] = temp_high_limit[i] << 8; - - TMON_RD(client, REG_TEMP_HIGH_LIMIT_LSB[i], &tmp); - temp_high_limit[i] |= tmp; + temp_high_limit[i] = ((u16)tmp) << 8; + if ((i == REMOTE) || (i == LOCAL && tmon_device == TMP411)) { + TMON_RD(client, REG_TEMP_HIGH_LIMIT_LSB[i], &tmp); + temp_high_limit[i] |= tmp; + } TMON_RD(client, REG_TEMP_CRIT_LIMIT[i], &temp_crit_limit[i]); } TMON_RD(client, REG_CON_RATE_READ, &conv_rate); + TMON_RD(client, REG_CFG_READ, &config); cancel_delayed_work_sync(&data->tmon_work); return 0; @@ -724,36 +883,55 @@ static int tmon_tmp411_resume(struct device *dev) { int i; int err; + u8 curr_cnfg; + u8 limit_correction = 0; + struct i2c_client *client = to_i2c_client(dev); struct tmon_info *data = i2c_get_clientdata(client); + TMON_RD(client, REG_CFG_READ, &curr_cnfg); + + /* Stop the temperature conversions */ + curr_cnfg = (curr_cnfg & (~CFG_STANDBY)); + TMON_WRT(client, REG_CFG_WRITE, curr_cnfg); + /* Restore temperature limits */ for (i = 0; i < 2; i++) { TMON_WRT(client, REG_TEMP_HIGH_LIMIT_MSB_WRT[i], - (temp_high_limit[i] >> 8)); + (temp_high_limit[i] >> 8) + limit_correction); - TMON_WRT(client, - REG_TEMP_HIGH_LIMIT_LSB[i], - (temp_high_limit[i] & 0xFF)); + if ((i == REMOTE) || (i == LOCAL && tmon_device == TMP411)) { + TMON_WRT(client, + REG_TEMP_HIGH_LIMIT_LSB[i], + (temp_high_limit[i] & 0xFF)); + } TMON_WRT(client, REG_TEMP_LOW_LIMIT_MSB_WRT[i], - (temp_low_limit[i] >> 8)); + (temp_low_limit[i] >> 8) + limit_correction); - TMON_WRT(client, - REG_TEMP_LOW_LIMIT_LSB[i], - (temp_low_limit[i] & 0xFF)); + if ((i == REMOTE) || (i == LOCAL && tmon_device == TMP411)) { + TMON_WRT(client, + REG_TEMP_LOW_LIMIT_LSB[i], + (temp_low_limit[i] & 0xFF)); + } TMON_WRT(client, REG_TEMP_CRIT_LIMIT[i], - temp_crit_limit[i]); + temp_crit_limit[i] + limit_correction); } TMON_WRT(client, REG_CONV_RATE_WRITE, conv_rate); + /* Start the temperature conversion and restore config */ + TMON_WRT(client, REG_CFG_WRITE, config); + + /* FIXME: Is it required to wait for one temperature conversion? */ + schedule_delayed_work(&data->tmon_work, msecs_to_jiffies(data->pdata->delta_time)); return 0; } + #endif static const struct dev_pm_ops tegra_tmp411_dev_pm_ops = { @@ -779,7 +957,7 @@ static struct i2c_driver tmon_tmp411_driver = { #endif }, .probe = tmon_tmp411_probe, - .remove = __devexit_p(tmon_tmp411_remove), + .remove = tmon_tmp411_remove, .id_table = tmon_tmp411_id, }; |