aboutsummaryrefslogtreecommitdiff
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2011-02-18 14:46:19 -0500
committerNicolas Pitre <nicolas.pitre@linaro.org>2011-02-18 14:46:19 -0500
commitc49f87aa34f7fa4850b8838a945475e4062bad61 (patch)
treee2d8af4d57671aa35798c1ddca503974ba40fff0 /drivers/hwmon
parenta12fc999485eb5d9ecad74554f0baac9688d28e2 (diff)
parent69ad303ab8321656d6144d13b2444a5595bb6581 (diff)
Merge commit 'v2.6.36.4' into linaro-2.6.36HEADmaster
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/applesmc.c48
-rw-r--r--drivers/hwmon/lm63.c59
-rw-r--r--drivers/hwmon/via686a.c14
3 files changed, 75 insertions, 46 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index b6598aa557a..87a5fd51dd5 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -162,6 +162,10 @@ static const char *temperature_sensors_sets[][41] = {
/* Set 22: MacBook Pro 7,1 */
{ "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S",
"TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL },
+/* Set 23: MacBook Air 3,1 */
+ { "TB0T", "TB1T", "TB2T", "TC0D", "TC0E", "TC0P", "TC1E", "TCZ3",
+ "TCZ4", "TCZ5", "TG0E", "TG1E", "TG2E", "TGZ3", "TGZ4", "TGZ5",
+ "TH0F", "TH0O", "TM0P" },
};
/* List of keys used to read/write fan speeds */
@@ -444,38 +448,22 @@ static int applesmc_read_motion_sensor(int index, s16* value)
}
/*
- * applesmc_device_init - initialize the accelerometer. Returns zero on success
- * and negative error code on failure. Can sleep.
+ * applesmc_device_init - initialize the accelerometer. Can sleep.
*/
-static int applesmc_device_init(void)
+static void applesmc_device_init(void)
{
- int total, ret = -ENXIO;
+ int total;
u8 buffer[2];
if (!applesmc_accelerometer)
- return 0;
+ return;
mutex_lock(&applesmc_lock);
for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
- if (debug)
- printk(KERN_DEBUG "applesmc try %d\n", total);
if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
- (buffer[0] != 0x00 || buffer[1] != 0x00)) {
- if (total == INIT_TIMEOUT_MSECS) {
- printk(KERN_DEBUG "applesmc: device has"
- " already been initialized"
- " (0x%02x, 0x%02x).\n",
- buffer[0], buffer[1]);
- } else {
- printk(KERN_DEBUG "applesmc: device"
- " successfully initialized"
- " (0x%02x, 0x%02x).\n",
- buffer[0], buffer[1]);
- }
- ret = 0;
+ (buffer[0] != 0x00 || buffer[1] != 0x00))
goto out;
- }
buffer[0] = 0xe0;
buffer[1] = 0x00;
applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
@@ -486,7 +474,6 @@ static int applesmc_device_init(void)
out:
mutex_unlock(&applesmc_lock);
- return ret;
}
/*
@@ -512,13 +499,8 @@ static int applesmc_get_fan_count(void)
/* Device model stuff */
static int applesmc_probe(struct platform_device *dev)
{
- int ret;
-
- ret = applesmc_device_init();
- if (ret)
- return ret;
+ applesmc_device_init();
- printk(KERN_INFO "applesmc: device successfully initialized.\n");
return 0;
}
@@ -535,9 +517,7 @@ static int applesmc_pm_resume(struct device *dev)
/* Reinitialize device on resume from hibernation */
static int applesmc_pm_restore(struct device *dev)
{
- int ret = applesmc_device_init();
- if (ret)
- return ret;
+ applesmc_device_init();
return applesmc_pm_resume(dev);
}
@@ -1524,11 +1504,17 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
{ .accelerometer = 1, .light = 1, .temperature_set = 21 },
/* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */
{ .accelerometer = 1, .light = 1, .temperature_set = 22 },
+/* MacBook Air 3,1: accelerometer, backlight and temperature set 23 */
+ { .accelerometer = 0, .light = 0, .temperature_set = 23 },
};
/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
* So we need to put "Apple MacBook Pro" before "Apple MacBook". */
static __initdata struct dmi_system_id applesmc_whitelist[] = {
+ { applesmc_dmi_match, "Apple MacBook Air 3", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3") },
+ &applesmc_dmi_data[23]},
{ applesmc_dmi_match, "Apple MacBook Air 2", {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") },
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 776aeb3019d..508cb291f71 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -98,6 +98,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
* value, it uses signed 8-bit values with LSB = 1 degree Celsius.
* For remote temperature, low and high limits, it uses signed 11-bit values
* with LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
+ * For LM64 the actual remote diode temperature is 16 degree Celsius higher
+ * than the register reading. Remote temperature setpoints have to be
+ * adapted accordingly.
*/
#define FAN_FROM_REG(reg) ((reg) == 0xFFFC || (reg) == 0 ? 0 : \
@@ -165,6 +168,8 @@ struct lm63_data {
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
+ int kind;
+ int temp2_offset;
/* registers values */
u8 config, config_fan;
@@ -247,16 +252,34 @@ static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dum
return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
}
-static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
- char *buf)
+/*
+ * There are 8bit registers for both local(temp1) and remote(temp2) sensor.
+ * For remote sensor registers temp2_offset has to be considered,
+ * for local sensor it must not.
+ * So we need separate 8bit accessors for local and remote sensor.
+ */
+static ssize_t show_local_temp8(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct lm63_data *data = lm63_update_device(dev);
return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]));
}
-static ssize_t set_temp8(struct device *dev, struct device_attribute *dummy,
- const char *buf, size_t count)
+static ssize_t show_remote_temp8(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct lm63_data *data = lm63_update_device(dev);
+ return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index])
+ + data->temp2_offset);
+}
+
+static ssize_t set_local_temp8(struct device *dev,
+ struct device_attribute *dummy,
+ const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm63_data *data = i2c_get_clientdata(client);
@@ -274,7 +297,8 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct lm63_data *data = lm63_update_device(dev);
- return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]));
+ return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index])
+ + data->temp2_offset);
}
static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
@@ -294,7 +318,7 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
int nr = attr->index;
mutex_lock(&data->update_lock);
- data->temp11[nr] = TEMP11_TO_REG(val);
+ data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset);
i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
data->temp11[nr] >> 8);
i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
@@ -310,6 +334,7 @@ static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute
{
struct lm63_data *data = lm63_update_device(dev);
return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2])
+ + data->temp2_offset
- TEMP8_FROM_REG(data->temp2_crit_hyst));
}
@@ -324,7 +349,7 @@ static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *
long hyst;
mutex_lock(&data->update_lock);
- hyst = TEMP8_FROM_REG(data->temp8[2]) - val;
+ hyst = TEMP8_FROM_REG(data->temp8[2]) + data->temp2_offset - val;
i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
HYST_TO_REG(hyst));
mutex_unlock(&data->update_lock);
@@ -355,16 +380,21 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1);
static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
-static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
- set_temp8, 1);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8,
+ set_local_temp8, 1);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
set_temp11, 1);
static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
set_temp11, 2);
-static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2);
+/*
+ * On LM63, temp2_crit can be set only once, which should be job
+ * of the bootloader.
+ */
+static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8,
+ NULL, 2);
static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
set_temp2_crit_hyst);
@@ -479,7 +509,12 @@ static int lm63_probe(struct i2c_client *new_client,
data->valid = 0;
mutex_init(&data->update_lock);
- /* Initialize the LM63 chip */
+ /* Set the device type */
+ data->kind = id->driver_data;
+ if (data->kind == lm64)
+ data->temp2_offset = 16000;
+
+ /* Initialize chip */
lm63_init_client(new_client);
/* Register sysfs hooks */
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index f397ce7ad59..b2074e3ba2f 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -687,6 +687,13 @@ static int __devexit via686a_remove(struct platform_device *pdev)
return 0;
}
+static void via686a_update_fan_div(struct via686a_data *data)
+{
+ int reg = via686a_read_value(data, VIA686A_REG_FANDIV);
+ data->fan_div[0] = (reg >> 4) & 0x03;
+ data->fan_div[1] = reg >> 6;
+}
+
static void __devinit via686a_init_device(struct via686a_data *data)
{
u8 reg;
@@ -700,6 +707,9 @@ static void __devinit via686a_init_device(struct via686a_data *data)
via686a_write_value(data, VIA686A_REG_TEMP_MODE,
(reg & ~VIA686A_TEMP_MODE_MASK)
| VIA686A_TEMP_MODE_CONTINUOUS);
+
+ /* Pre-read fan clock divisor values */
+ via686a_update_fan_div(data);
}
static struct via686a_data *via686a_update_device(struct device *dev)
@@ -751,9 +761,7 @@ static struct via686a_data *via686a_update_device(struct device *dev)
(via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
0xc0) >> 6;
- i = via686a_read_value(data, VIA686A_REG_FANDIV);
- data->fan_div[0] = (i >> 4) & 0x03;
- data->fan_div[1] = i >> 6;
+ via686a_update_fan_div(data);
data->alarms =
via686a_read_value(data,
VIA686A_REG_ALARM1) |