hwmon: (lm90) Rearrange code to no longer require forward declarations
authorGuenter Roeck <guenter.roeck@ericsson.com>
Thu, 28 Oct 2010 18:31:43 +0000 (20:31 +0200)
committerJean Delvare <khali@endymion.delvare>
Thu, 28 Oct 2010 18:31:43 +0000 (20:31 +0200)
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
drivers/hwmon/lm90.c

index 366bb624e655628bd646e44f4d030f7f411016d5..302d9eb9f27553183df877c09b89d9a18c7af3f1 100644 (file)
@@ -163,21 +163,6 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
 #define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm           */
 #define LM90_HAVE_TEMP3                (1 << 6) /* 3rd temperature sensor      */
 
-/*
- * Functions declaration
- */
-
-static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info);
-static int lm90_probe(struct i2c_client *client,
-                     const struct i2c_device_id *id);
-static void lm90_init_client(struct i2c_client *client);
-static void lm90_alert(struct i2c_client *client, unsigned int flag);
-static int lm90_remove(struct i2c_client *client);
-static struct lm90_data *lm90_update_device(struct device *dev);
-static inline void lm90_select_remote_channel(struct i2c_client *client,
-                                             struct lm90_data *data,
-                                             int channel);
-
 /*
  * Driver data (common to all clients)
  */
@@ -204,19 +189,6 @@ static const struct i2c_device_id lm90_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, lm90_id);
 
-static struct i2c_driver lm90_driver = {
-       .class          = I2C_CLASS_HWMON,
-       .driver = {
-               .name   = "lm90",
-       },
-       .probe          = lm90_probe,
-       .remove         = lm90_remove,
-       .alert          = lm90_alert,
-       .id_table       = lm90_id,
-       .detect         = lm90_detect,
-       .address_list   = normal_i2c,
-};
-
 /*
  * Client data (each client gets its own)
  */
@@ -255,6 +227,209 @@ struct lm90_data {
        u16 alarms; /* bitvector (upper 8 bits for max6695/96) */
 };
 
+/*
+ * Support functions
+ */
+
+/*
+ * The ADM1032 supports PEC but not on write byte transactions, so we need
+ * to explicitly ask for a transaction without PEC.
+ */
+static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
+{
+       return i2c_smbus_xfer(client->adapter, client->addr,
+                             client->flags & ~I2C_CLIENT_PEC,
+                             I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
+}
+
+/*
+ * It is assumed that client->update_lock is held (unless we are in
+ * detection or initialization steps). This matters when PEC is enabled,
+ * because we don't want the address pointer to change between the write
+ * byte and the read byte transactions.
+ */
+static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value)
+{
+       int err;
+
+       if (client->flags & I2C_CLIENT_PEC) {
+               err = adm1032_write_byte(client, reg);
+               if (err >= 0)
+                       err = i2c_smbus_read_byte(client);
+       } else
+               err = i2c_smbus_read_byte_data(client, reg);
+
+       if (err < 0) {
+               dev_warn(&client->dev, "Register %#02x read failed (%d)\n",
+                        reg, err);
+               return err;
+       }
+       *value = err;
+
+       return 0;
+}
+
+static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
+{
+       int err;
+       u8 oldh, newh, l;
+
+       /*
+        * There is a trick here. We have to read two registers to have the
+        * sensor temperature, but we have to beware a conversion could occur
+        * inbetween the readings. The datasheet says we should either use
+        * the one-shot conversion register, which we don't want to do
+        * (disables hardware monitoring) or monitor the busy bit, which is
+        * impossible (we can't read the values and monitor that bit at the
+        * exact same time). So the solution used here is to read the high
+        * byte once, then the low byte, then the high byte again. If the new
+        * high byte matches the old one, then we have a valid reading. Else
+        * we have to read the low byte again, and now we believe we have a
+        * correct reading.
+        */
+       if ((err = lm90_read_reg(client, regh, &oldh))
+        || (err = lm90_read_reg(client, regl, &l))
+        || (err = lm90_read_reg(client, regh, &newh)))
+               return err;
+       if (oldh != newh) {
+               err = lm90_read_reg(client, regl, &l);
+               if (err)
+                       return err;
+       }
+       *value = (newh << 8) | l;
+
+       return 0;
+}
+
+/*
+ * client->update_lock must be held when calling this function (unless we are
+ * in detection or initialization steps), and while a remote channel other
+ * than channel 0 is selected. Also, calling code must make sure to re-select
+ * external channel 0 before releasing the lock. This is necessary because
+ * various registers have different meanings as a result of selecting a
+ * non-default remote channel.
+ */
+static inline void lm90_select_remote_channel(struct i2c_client *client,
+                                             struct lm90_data *data,
+                                             int channel)
+{
+       u8 config;
+
+       if (data->kind == max6696) {
+               lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
+               config &= ~0x08;
+               if (channel)
+                       config |= 0x08;
+               i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+                                         config);
+       }
+}
+
+static struct lm90_data *lm90_update_device(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lm90_data *data = i2c_get_clientdata(client);
+
+       mutex_lock(&data->update_lock);
+
+       if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10)
+        || !data->valid) {
+               u8 h, l;
+               u8 alarms;
+
+               dev_dbg(&client->dev, "Updating lm90 data.\n");
+               lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]);
+               lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]);
+               lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]);
+               lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]);
+               lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst);
+
+               if (data->flags & LM90_HAVE_LOCAL_EXT) {
+                       lm90_read16(client, LM90_REG_R_LOCAL_TEMP,
+                                   MAX6657_REG_R_LOCAL_TEMPL,
+                                   &data->temp11[4]);
+               } else {
+                       if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP,
+                                         &h) == 0)
+                               data->temp11[4] = h << 8;
+               }
+               lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
+                           LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]);
+
+               if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) {
+                       data->temp11[1] = h << 8;
+                       if ((data->flags & LM90_HAVE_REM_LIMIT_EXT)
+                        && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL,
+                                         &l) == 0)
+                               data->temp11[1] |= l;
+               }
+               if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) {
+                       data->temp11[2] = h << 8;
+                       if ((data->flags & LM90_HAVE_REM_LIMIT_EXT)
+                        && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL,
+                                         &l) == 0)
+                               data->temp11[2] |= l;
+               }
+
+               if (data->flags & LM90_HAVE_OFFSET) {
+                       if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH,
+                                         &h) == 0
+                        && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL,
+                                         &l) == 0)
+                               data->temp11[3] = (h << 8) | l;
+               }
+               if (data->flags & LM90_HAVE_EMERGENCY) {
+                       lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG,
+                                     &data->temp8[4]);
+                       lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG,
+                                     &data->temp8[5]);
+               }
+               lm90_read_reg(client, LM90_REG_R_STATUS, &alarms);
+               data->alarms = alarms;  /* save as 16 bit value */
+
+               if (data->kind == max6696) {
+                       lm90_select_remote_channel(client, data, 1);
+                       lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT,
+                                     &data->temp8[6]);
+                       lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG,
+                                     &data->temp8[7]);
+                       lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
+                                   LM90_REG_R_REMOTE_TEMPL, &data->temp11[5]);
+                       if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h))
+                               data->temp11[6] = h << 8;
+                       if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h))
+                               data->temp11[7] = h << 8;
+                       lm90_select_remote_channel(client, data, 0);
+
+                       if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2,
+                                          &alarms))
+                               data->alarms |= alarms << 8;
+               }
+
+               /* Re-enable ALERT# output if it was originally enabled and
+                * relevant alarms are all clear */
+               if ((data->config_orig & 0x80) == 0
+                && (data->alarms & data->alert_alarms) == 0) {
+                       u8 config;
+
+                       lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
+                       if (config & 0x80) {
+                               dev_dbg(&client->dev, "Re-enabling ALERT#\n");
+                               i2c_smbus_write_byte_data(client,
+                                                         LM90_REG_W_CONFIG1,
+                                                         config & ~0x80);
+                       }
+               }
+
+               data->last_updated = jiffies;
+               data->valid = 1;
+       }
+
+       mutex_unlock(&data->update_lock);
+
+       return data;
+}
+
 /*
  * Conversions
  * For local temperatures and limits, critical limits and the hysteresis
@@ -770,79 +945,17 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec);
  * Real code
  */
 
-/*
- * The ADM1032 supports PEC but not on write byte transactions, so we need
- * to explicitly ask for a transaction without PEC.
- */
-static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
-{
-       return i2c_smbus_xfer(client->adapter, client->addr,
-                             client->flags & ~I2C_CLIENT_PEC,
-                             I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
-}
-
-/*
- * It is assumed that client->update_lock is held (unless we are in
- * detection or initialization steps). This matters when PEC is enabled,
- * because we don't want the address pointer to change between the write
- * byte and the read byte transactions.
- */
-static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value)
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int lm90_detect(struct i2c_client *new_client,
+                      struct i2c_board_info *info)
 {
-       int err;
+       struct i2c_adapter *adapter = new_client->adapter;
+       int address = new_client->addr;
+       const char *name = NULL;
+       int man_id, chip_id, reg_config1, reg_convrate;
 
-       if (client->flags & I2C_CLIENT_PEC) {
-               err = adm1032_write_byte(client, reg);
-               if (err >= 0)
-                       err = i2c_smbus_read_byte(client);
-       } else
-               err = i2c_smbus_read_byte_data(client, reg);
-
-       if (err < 0) {
-               dev_warn(&client->dev, "Register %#02x read failed (%d)\n",
-                        reg, err);
-               return err;
-       }
-       *value = err;
-
-       return 0;
-}
-
-/*
- * client->update_lock must be held when calling this function (unless we are
- * in detection or initialization steps), and while a remote channel other
- * than channel 0 is selected. Also, calling code must make sure to re-select
- * external channel 0 before releasing the lock. This is necessary because
- * various registers have different meanings as a result of selecting a
- * non-default remote channel.
- */
-static inline void lm90_select_remote_channel(struct i2c_client *client,
-                                             struct lm90_data *data,
-                                             int channel)
-{
-       u8 config;
-
-       if (data->kind == max6696) {
-               lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
-               config &= ~0x08;
-               if (channel)
-                       config |= 0x08;
-               i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
-                                         config);
-       }
-}
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm90_detect(struct i2c_client *new_client,
-                      struct i2c_board_info *info)
-{
-       struct i2c_adapter *adapter = new_client->adapter;
-       int address = new_client->addr;
-       const char *name = NULL;
-       int man_id, chip_id, reg_config1, reg_convrate;
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               return -ENODEV;
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
 
        /* detection and identification */
        if ((man_id = i2c_smbus_read_byte_data(new_client,
@@ -1023,6 +1136,47 @@ static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data)
        sysfs_remove_group(&client->dev.kobj, &lm90_group);
 }
 
+static void lm90_init_client(struct i2c_client *client)
+{
+       u8 config;
+       struct lm90_data *data = i2c_get_clientdata(client);
+
+       /*
+        * Start the conversions.
+        */
+       i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE,
+                                 5); /* 2 Hz */
+       if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) {
+               dev_warn(&client->dev, "Initialization failed!\n");
+               return;
+       }
+       data->config_orig = config;
+
+       /* Check Temperature Range Select */
+       if (data->kind == adt7461) {
+               if (config & 0x04)
+                       data->flags |= LM90_FLAG_ADT7461_EXT;
+       }
+
+       /*
+        * Put MAX6680/MAX8881 into extended resolution (bit 0x10,
+        * 0.125 degree resolution) and range (0x08, extend range
+        * to -64 degree) mode for the remote temperature sensor.
+        */
+       if (data->kind == max6680)
+               config |= 0x18;
+
+       /*
+        * Select external channel 0 for max6695/96
+        */
+       if (data->kind == max6696)
+               config &= ~0x08;
+
+       config &= 0xBF; /* run */
+       if (config != data->config_orig) /* Only write if changed */
+               i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
+}
+
 static int lm90_probe(struct i2c_client *new_client,
                      const struct i2c_device_id *id)
 {
@@ -1134,47 +1288,6 @@ exit:
        return err;
 }
 
-static void lm90_init_client(struct i2c_client *client)
-{
-       u8 config;
-       struct lm90_data *data = i2c_get_clientdata(client);
-
-       /*
-        * Start the conversions.
-        */
-       i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE,
-                                 5); /* 2 Hz */
-       if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) {
-               dev_warn(&client->dev, "Initialization failed!\n");
-               return;
-       }
-       data->config_orig = config;
-
-       /* Check Temperature Range Select */
-       if (data->kind == adt7461) {
-               if (config & 0x04)
-                       data->flags |= LM90_FLAG_ADT7461_EXT;
-       }
-
-       /*
-        * Put MAX6680/MAX8881 into extended resolution (bit 0x10,
-        * 0.125 degree resolution) and range (0x08, extend range
-        * to -64 degree) mode for the remote temperature sensor.
-        */
-       if (data->kind == max6680)
-               config |= 0x18;
-
-       /*
-        * Select external channel 0 for max6695/96
-        */
-       if (data->kind == max6696)
-               config &= ~0x08;
-
-       config &= 0xBF; /* run */
-       if (config != data->config_orig) /* Only write if changed */
-               i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
-}
-
 static int lm90_remove(struct i2c_client *client)
 {
        struct lm90_data *data = i2c_get_clientdata(client);
@@ -1230,142 +1343,18 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag)
        }
 }
 
-static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
-{
-       int err;
-       u8 oldh, newh, l;
-
-       /*
-        * There is a trick here. We have to read two registers to have the
-        * sensor temperature, but we have to beware a conversion could occur
-        * inbetween the readings. The datasheet says we should either use
-        * the one-shot conversion register, which we don't want to do
-        * (disables hardware monitoring) or monitor the busy bit, which is
-        * impossible (we can't read the values and monitor that bit at the
-        * exact same time). So the solution used here is to read the high
-        * byte once, then the low byte, then the high byte again. If the new
-        * high byte matches the old one, then we have a valid reading. Else
-        * we have to read the low byte again, and now we believe we have a
-        * correct reading.
-        */
-       if ((err = lm90_read_reg(client, regh, &oldh))
-        || (err = lm90_read_reg(client, regl, &l))
-        || (err = lm90_read_reg(client, regh, &newh)))
-               return err;
-       if (oldh != newh) {
-               err = lm90_read_reg(client, regl, &l);
-               if (err)
-                       return err;
-       }
-       *value = (newh << 8) | l;
-
-       return 0;
-}
-
-static struct lm90_data *lm90_update_device(struct device *dev)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-       struct lm90_data *data = i2c_get_clientdata(client);
-
-       mutex_lock(&data->update_lock);
-
-       if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10)
-        || !data->valid) {
-               u8 h, l;
-               u8 alarms;
-
-               dev_dbg(&client->dev, "Updating lm90 data.\n");
-               lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]);
-               lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]);
-               lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]);
-               lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]);
-               lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst);
-
-               if (data->flags & LM90_HAVE_LOCAL_EXT) {
-                       lm90_read16(client, LM90_REG_R_LOCAL_TEMP,
-                                   MAX6657_REG_R_LOCAL_TEMPL,
-                                   &data->temp11[4]);
-               } else {
-                       if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP,
-                                         &h) == 0)
-                               data->temp11[4] = h << 8;
-               }
-               lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
-                           LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]);
-
-               if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) {
-                       data->temp11[1] = h << 8;
-                       if ((data->flags & LM90_HAVE_REM_LIMIT_EXT)
-                        && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL,
-                                         &l) == 0)
-                               data->temp11[1] |= l;
-               }
-               if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) {
-                       data->temp11[2] = h << 8;
-                       if ((data->flags & LM90_HAVE_REM_LIMIT_EXT)
-                        && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL,
-                                         &l) == 0)
-                               data->temp11[2] |= l;
-               }
-
-               if (data->flags & LM90_HAVE_OFFSET) {
-                       if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH,
-                                         &h) == 0
-                        && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL,
-                                         &l) == 0)
-                               data->temp11[3] = (h << 8) | l;
-               }
-               if (data->flags & LM90_HAVE_EMERGENCY) {
-                       lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG,
-                                     &data->temp8[4]);
-                       lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG,
-                                     &data->temp8[5]);
-               }
-               lm90_read_reg(client, LM90_REG_R_STATUS, &alarms);
-               data->alarms = alarms;  /* save as 16 bit value */
-
-               if (data->kind == max6696) {
-                       lm90_select_remote_channel(client, data, 1);
-                       lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT,
-                                     &data->temp8[6]);
-                       lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG,
-                                     &data->temp8[7]);
-                       lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
-                                   LM90_REG_R_REMOTE_TEMPL, &data->temp11[5]);
-                       if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h))
-                               data->temp11[6] = h << 8;
-                       if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h))
-                               data->temp11[7] = h << 8;
-                       lm90_select_remote_channel(client, data, 0);
-
-                       if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2,
-                                          &alarms))
-                               data->alarms |= alarms << 8;
-               }
-
-               /* Re-enable ALERT# output if it was originally enabled and
-                * relevant alarms are all clear */
-               if ((data->config_orig & 0x80) == 0
-                && (data->alarms & data->alert_alarms) == 0) {
-                       u8 config;
-
-                       lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
-                       if (config & 0x80) {
-                               dev_dbg(&client->dev, "Re-enabling ALERT#\n");
-                               i2c_smbus_write_byte_data(client,
-                                                         LM90_REG_W_CONFIG1,
-                                                         config & ~0x80);
-                       }
-               }
-
-               data->last_updated = jiffies;
-               data->valid = 1;
-       }
-
-       mutex_unlock(&data->update_lock);
-
-       return data;
-}
+static struct i2c_driver lm90_driver = {
+       .class          = I2C_CLASS_HWMON,
+       .driver = {
+               .name   = "lm90",
+       },
+       .probe          = lm90_probe,
+       .remove         = lm90_remove,
+       .alert          = lm90_alert,
+       .id_table       = lm90_id,
+       .detect         = lm90_detect,
+       .address_list   = normal_i2c,
+};
 
 static int __init sensors_lm90_init(void)
 {