misc: nct1008: extended mode first reading fix
Bitan Biswas [Mon, 18 Jul 2011 06:12:59 +0000 (11:12 +0530)]
nct1008 first temperature reading in extended mode is incorrect.
A valid temperature is available in next measurement cycle after
changing temperature range.
- using table with delay expected for supported conversion
  rate of nct1008.

bug 852754

Original-Change-Id: Id68cbf6a83fe2a11ae2a6d94f0df51a3ebd37ac7
Reviewed-on: http://git-master/r/41506
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: R9fc8a721f1b25372324f7e38c3c477b9769d51bf

drivers/misc/nct1008.c

index d7c4927..44c470e 100644 (file)
@@ -120,6 +120,7 @@ static int nct1008_get_temp(struct device *dev, u8 *pTemp)
        else
                *pTemp = max(temp1, temp);
 
+       dev_dbg(dev, "\n %s: ret temp=%dC ", __func__, *pTemp);
        return 0;
 error:
        dev_err(&client->dev, "\n error in file=: %s %s() line=%d: "
@@ -541,7 +542,7 @@ static irqreturn_t nct1008_irq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static void nct1008_power_control(struct nct1008_data* data, bool is_enable)
+static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
 {
        int ret;
        if (!data->nct_reg) {
@@ -621,15 +622,18 @@ static int __devinit nct1008_configure_sensor(struct nct1008_data* data)
                /* setup alarm */
                hi_limit = pdata->thermal_zones[0];
 
-               err = i2c_smbus_write_byte_data(client, EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
+               err = i2c_smbus_write_byte_data(client,
+                       EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
                if (err)
                        goto error;
 
-               err = i2c_smbus_write_byte_data(client, LOCAL_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
+               err = i2c_smbus_write_byte_data(client,
+                       LOCAL_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
                if (err)
                        goto error;
 
-               err = i2c_smbus_write_byte_data(client, LOCAL_TEMP_LO_LIMIT_WR, 0);
+               err = i2c_smbus_write_byte_data(client,
+                       LOCAL_TEMP_LO_LIMIT_WR, 0);
                if (err)
                        goto error;
        } else {
@@ -711,12 +715,42 @@ static int __devinit nct1008_configure_irq(struct nct1008_data *data)
                        DRIVER_NAME, data);
 }
 
+static unsigned int get_ext_mode_delay_ms(unsigned int conv_rate)
+{
+       switch (conv_rate) {
+       case 0:
+               return 16000;
+       case 1:
+               return 8000;
+       case 2:
+               return 4000;
+       case 3:
+               return 2000;
+       case 4:
+               return 1000;
+       case 5:
+               return 500;
+       case 6:
+               return 250;
+       case 7:
+               return 125;
+       case 9:
+               return 32;
+       case 10:
+               return 16;
+       case 8:
+       default:
+               return 63;
+       }
+}
+
 static int __devinit nct1008_probe(struct i2c_client *client,
                                const struct i2c_device_id *id)
 {
        struct nct1008_data *data;
        int err;
        u8 temperature;
+       unsigned int delay;
 
        data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
 
@@ -747,6 +781,13 @@ static int __devinit nct1008_probe(struct i2c_client *client,
 
        nct1008_enable(client);         /* sensor is running */
 
+       /* switch to extended mode reports correct temperature
+        * from next measurement cycle */
+       if (data->plat_data.ext_range) {
+               delay = get_ext_mode_delay_ms(
+                       data->plat_data.conv_rate);
+               msleep(delay); /* 63msec for default conv rate 0x8 */
+       }
        err = nct1008_get_temp(&data->client->dev, &temperature);
        if (err) {
                pr_err("%s: get temp fail(%d)", __func__, err);
@@ -833,5 +874,5 @@ static void __exit nct1008_exit(void)
 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008");
 MODULE_LICENSE("GPL");
 
-module_init (nct1008_init);
-module_exit (nct1008_exit);
+module_init(nct1008_init);
+module_exit(nct1008_exit);