diff options
Diffstat (limited to 'packages/linux/linux-2.6.26/boc01/007-081105-lm73.patch')
-rw-r--r-- | packages/linux/linux-2.6.26/boc01/007-081105-lm73.patch | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/packages/linux/linux-2.6.26/boc01/007-081105-lm73.patch b/packages/linux/linux-2.6.26/boc01/007-081105-lm73.patch new file mode 100644 index 0000000000..4f51d5d222 --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/007-081105-lm73.patch @@ -0,0 +1,317 @@ +diff -Nru linux-2.6.26-officiel/drivers/hwmon/Kconfig /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/hwmon/Kconfig +--- linux-2.6.26-officiel/drivers/hwmon/Kconfig 2008-07-13 23:51:29.000000000 +0200 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/hwmon/Kconfig 2008-11-06 11:25:51.000000000 +0100 +@@ -390,6 +390,15 @@ + This driver can also be built as a module. If so, the module + will be called lm70. + ++config SENSORS_LM73 ++ tristate "National Semiconductor LM73" ++ depends on I2C ++ help ++ If you say yes here you get support for National Semiconductor LM73 ++ sensor chips ++ This driver can also be built as a module. If so, the module ++ will be called lm73. ++ + config SENSORS_LM75 + tristate "National Semiconductor LM75 and compatibles" + depends on I2C +diff -Nru linux-2.6.26-officiel/drivers/hwmon/lm73.c /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/hwmon/lm73.c +--- linux-2.6.26-officiel/drivers/hwmon/lm73.c 1970-01-01 01:00:00.000000000 +0100 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/hwmon/lm73.c 2008-11-04 14:57:12.000000000 +0100 +@@ -0,0 +1,283 @@ ++/* ++ lm75.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/slab.h> ++#include <linux/jiffies.h> ++#include <linux/i2c.h> ++#include <linux/hwmon.h> ++#include <linux/hwmon-sysfs.h> ++#include <linux/err.h> ++#include <linux/mutex.h> ++#include "lm75.h" ++ ++ ++/* Addresses to scan */ ++static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, ++ 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; ++ ++/* Insmod parameters */ ++I2C_CLIENT_INSMOD_1(lm75); ++ ++/* Many LM75 constants specified below */ ++ ++/* The LM75 registers */ ++#define LM75_REG_CONF 0x01 ++static const u8 LM75_REG_TEMP[3] = { ++ 0x00, /* input */ ++ 0x02, /* max */ ++ 0x02, /* hyst */ ++}; ++ ++/* Each client has this additional data */ ++struct lm75_data { ++ struct i2c_client client; ++ struct device *hwmon_dev; ++ struct mutex update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ u16 temp[3]; /* Register values, ++ 0 = input ++ 1 = max ++ 2 = hyst */ ++}; ++ ++static int lm75_attach_adapter(struct i2c_adapter *adapter); ++static int lm75_detect(struct i2c_adapter *adapter, int address, int kind); ++static void lm75_init_client(struct i2c_client *client); ++static int lm75_detach_client(struct i2c_client *client); ++static int lm75_read_value(struct i2c_client *client, u8 reg); ++static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); ++static struct lm75_data *lm75_update_device(struct device *dev); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver lm75_driver = { ++ .driver = { ++ .name = "lm75", ++ }, ++ .attach_adapter = lm75_attach_adapter, ++ .detach_client = lm75_detach_client, ++}; ++ ++static ssize_t show_temp(struct device *dev, struct device_attribute *da, ++ char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); ++ struct lm75_data *data = lm75_update_device(dev); ++ return sprintf(buf, "%d\n", ++ LM75_TEMP_FROM_REG(data->temp[attr->index])); ++} ++ ++static ssize_t set_temp(struct device *dev, struct device_attribute *da, ++ const char *buf, size_t count) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); ++ struct i2c_client *client = to_i2c_client(dev); ++ struct lm75_data *data = i2c_get_clientdata(client); ++ int nr = attr->index; ++ long temp = simple_strtol(buf, NULL, 10); ++ ++ mutex_lock(&data->update_lock); ++ data->temp[nr] = LM75_TEMP_TO_REG(temp); ++ lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); ++ mutex_unlock(&data->update_lock); ++ return count; ++} ++ ++static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, ++ show_temp, set_temp, 1); ++static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, ++ show_temp, set_temp, 2); ++static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); ++ ++static int lm75_attach_adapter(struct i2c_adapter *adapter) ++{ ++ if (!(adapter->class & I2C_CLASS_HWMON)) ++ return 0; ++ ++ return i2c_probe(adapter, &addr_data, lm75_detect); ++} ++ ++static struct attribute *lm75_attributes[] = { ++ &sensor_dev_attr_temp1_input.dev_attr.attr, ++ &sensor_dev_attr_temp1_max.dev_attr.attr, ++ &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, ++ ++ NULL ++}; ++ ++static const struct attribute_group lm75_group = { ++ .attrs = lm75_attributes, ++}; ++ ++/* This function is called by i2c_probe */ ++static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct lm75_data *data; ++ int err = 0; ++ const char *name = ""; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA)) ++ goto exit; ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access lm75_{read,write}_value. */ ++ if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ new_client = &data->client; ++ i2c_set_clientdata(new_client, data); ++ new_client->addr = address; ++ new_client->adapter = adapter; ++ new_client->driver = &lm75_driver; ++ new_client->flags = 0; ++ ++ name = "lm75"; ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strlcpy(new_client->name, name, I2C_NAME_SIZE); ++ data->valid = 0; ++ mutex_init(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto exit_free; ++ ++ /* Initialize the LM75 chip */ ++ lm75_init_client(new_client); ++ ++ /* Register sysfs hooks */ ++ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group))) ++ goto exit_detach; ++ ++ data->hwmon_dev = hwmon_device_register(&new_client->dev); ++ if (IS_ERR(data->hwmon_dev)) { ++ err = PTR_ERR(data->hwmon_dev); ++ goto exit_remove; ++ } ++ ++ return 0; ++ ++exit_remove: ++ sysfs_remove_group(&new_client->dev.kobj, &lm75_group); ++exit_detach: ++ i2c_detach_client(new_client); ++exit_free: ++ kfree(data); ++exit: ++ return err; ++} ++ ++static int lm75_detach_client(struct i2c_client *client) ++{ ++ struct lm75_data *data = i2c_get_clientdata(client); ++ hwmon_device_unregister(data->hwmon_dev); ++ sysfs_remove_group(&client->dev.kobj, &lm75_group); ++ i2c_detach_client(client); ++ kfree(data); ++ return 0; ++} ++ ++/* All registers are word-sized, except for the configuration register. ++ LM75 uses a high-byte first convention, which is exactly opposite to ++ the SMBus standard. */ ++static int lm75_read_value(struct i2c_client *client, u8 reg) ++{ ++ int value; ++ ++ if (reg == LM75_REG_CONF) ++ return i2c_smbus_read_byte_data(client, reg); ++ ++ value = i2c_smbus_read_word_data(client, reg); ++ return (value < 0) ? value : swab16(value); ++} ++ ++static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ if (reg == LM75_REG_CONF) ++ return i2c_smbus_write_byte_data(client, reg, value); ++ else ++ return i2c_smbus_write_word_data(client, reg, swab16(value)); ++} ++ ++static void lm75_init_client(struct i2c_client *client) ++{ ++ int reg; ++ ++ /* Enable if in shutdown mode */ ++ reg = lm75_read_value(client, LM75_REG_CONF); ++ if (reg >= 0 && (reg & 0x01)) ++ lm75_write_value(client, LM75_REG_CONF, reg & 0xfe); ++} ++ ++static struct lm75_data *lm75_update_device(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct lm75_data *data = i2c_get_clientdata(client); ++ ++ mutex_lock(&data->update_lock); ++ ++ if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ++ || !data->valid) { ++ int i; ++ dev_dbg(&client->dev, "Starting lm75 update\n"); ++ ++ for (i = 0; i < ARRAY_SIZE(data->temp); i++) { ++ int status; ++ ++ status = lm75_read_value(client, LM75_REG_TEMP[i]); ++ if (status < 0) ++ dev_dbg(&client->dev, "reg %d, err %d\n", ++ LM75_REG_TEMP[i], status); ++ else ++ data->temp[i] = status; ++ } ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ mutex_unlock(&data->update_lock); ++ ++ return data; ++} ++ ++static int __init sensors_lm75_init(void) ++{ ++ return i2c_add_driver(&lm75_driver); ++} ++ ++static void __exit sensors_lm75_exit(void) ++{ ++ i2c_del_driver(&lm75_driver); ++} ++ ++MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); ++MODULE_DESCRIPTION("LM75 driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sensors_lm75_init); ++module_exit(sensors_lm75_exit); +diff -Nru linux-2.6.26-officiel/drivers/hwmon/Makefile /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/hwmon/Makefile +--- linux-2.6.26-officiel/drivers/hwmon/Makefile 2008-07-13 23:51:29.000000000 +0200 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/hwmon/Makefile 2008-11-06 11:26:13.000000000 +0100 +@@ -47,6 +47,7 @@ + obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o + obj-$(CONFIG_SENSORS_LM63) += lm63.o + obj-$(CONFIG_SENSORS_LM70) += lm70.o ++obj-$(CONFIG_SENSORS_LM73) += lm73.o + obj-$(CONFIG_SENSORS_LM75) += lm75.o + obj-$(CONFIG_SENSORS_LM77) += lm77.o + obj-$(CONFIG_SENSORS_LM78) += lm78.o |