summaryrefslogtreecommitdiff
path: root/packages/linux/linux-2.6.26/boc01/006-081105-at24c32.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/linux/linux-2.6.26/boc01/006-081105-at24c32.patch')
-rw-r--r--packages/linux/linux-2.6.26/boc01/006-081105-at24c32.patch284
1 files changed, 284 insertions, 0 deletions
diff --git a/packages/linux/linux-2.6.26/boc01/006-081105-at24c32.patch b/packages/linux/linux-2.6.26/boc01/006-081105-at24c32.patch
new file mode 100644
index 0000000000..1cd70feb4a
--- /dev/null
+++ b/packages/linux/linux-2.6.26/boc01/006-081105-at24c32.patch
@@ -0,0 +1,284 @@
+diff -Nru linux-2.6.26-officiel/drivers/i2c/chips/at24c32.c /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/at24c32.c
+--- linux-2.6.26-officiel/drivers/i2c/chips/at24c32.c 1970-01-01 01:00:00.000000000 +0100
++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/at24c32.c 2008-11-06 10:45:30.000000000 +0100
+@@ -0,0 +1,268 @@
++/*
++ * at24c32.c - Based on eeprom.c
++ *
++ * Copyright (C) 2007, CenoSYS (www.cenosys.com).
++ * Guillaume Ligneul
++ * Guillaume.ligneul@gmail.com
++ *
++ * Code is based on eeprom.c
++ *
++ * This software program is licensed subject to the GNU General Public License
++ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/mutex.h>
++
++/* Addresses to scan */
++static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
++ 0x55, 0x56, I2C_CLIENT_END };
++
++/* Insmod parameters */
++I2C_CLIENT_INSMOD_1(eeprom);
++
++
++/* Size of EEPROM in bytes */
++#define EEPROM_SIZE 32768
++
++/* possible types of eeprom devices */
++enum eeprom_nature {
++ UNKNOWN,
++ VAIO,
++};
++
++/* Each client has this additional data */
++struct eeprom_data {
++ struct i2c_client client;
++ struct mutex update_lock;
++ u8 valid; /* bitfield, bit!=0 if slice is valid */
++ unsigned long last_updated[8]; /* In jiffies, 8 slices */
++ u8 data[EEPROM_SIZE]; /* Register values */
++ enum eeprom_nature nature;
++};
++
++
++static int eeprom_attach_adapter(struct i2c_adapter *adapter);
++static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind);
++static int eeprom_detach_client(struct i2c_client *client);
++
++/* This is the driver that will be inserted */
++static struct i2c_driver eeprom_driver = {
++ .driver = {
++ .name = "eeprom",
++ },
++ .attach_adapter = eeprom_attach_adapter,
++ .detach_client = eeprom_detach_client,
++};
++
++static ssize_t eeprom_write(struct kobject *kobj, struct bin_attribute *bin_attr,
++ char *buf, loff_t off, size_t count)
++{
++ struct i2c_client *client = kobj_to_i2c_client(kobj);
++ struct eeprom_data *data = i2c_get_clientdata(client);
++ int ret;
++ u8 i2c_buf[256];
++
++ if (off >= 32)
++ return -ENOSPC;
++
++ if (off + count > 32)
++ count = 32 - off;
++
++ mutex_unlock(&data->update_lock);
++
++ struct i2c_msg msgs[1] = {
++ {
++ .addr = client->addr,
++ .flags = 0,
++ .len = count+2,
++ .buf = i2c_buf,
++ },
++ };
++
++ i2c_buf[0] = 0;
++ i2c_buf[1] = off;
++
++
++ memcpy(&i2c_buf[2], &buf[0], count );
++
++
++ ret = i2c_transfer(client->adapter, msgs, 1);
++
++ if(ret<0)
++ {
++ mutex_unlock(&data->update_lock);
++ return -EIO;
++ }
++
++ mutex_unlock(&data->update_lock);
++ return count;
++}
++
++int
++i2c_read(struct i2c_client *client, u8 reg, u8 buf[],
++ unsigned len)
++{
++ int ret;
++ u8 dt_addr[2];
++
++ struct i2c_msg msgs[2] = {
++ {
++ .addr = client->addr,
++ .flags = 0,
++ .len = 2,
++ .buf = dt_addr,
++ },
++ {
++ .addr = client->addr,
++ .flags = I2C_M_RD,
++ .len = len ,
++ .buf = buf ,
++ },
++ };
++
++ dt_addr[0] = 0;
++ dt_addr[1] = reg;
++
++ ret = i2c_transfer(client->adapter, msgs, 2);
++ if ( ret < 0) {
++ dev_err(&client->dev, "read error\n");
++ return -EIO;
++ }
++ return ret;
++}
++
++static ssize_t eeprom_read(struct kobject *kobj, struct bin_attribute *bin_attr,
++ char *buf, loff_t off, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
++ struct eeprom_data *data = i2c_get_clientdata(client);
++ int rc;
++
++ mutex_lock(&data->update_lock);
++
++ if (off >= EEPROM_SIZE)
++ return 0;
++
++ if (off + count > EEPROM_SIZE)
++ count = EEPROM_SIZE - off;
++
++ rc = i2c_read(client,off,buf,count);
++ if (rc < 0){
++ mutex_unlock(&data->update_lock);
++ return -EIO;
++ }
++
++ mutex_unlock(&data->update_lock);
++ return count;
++}
++
++static struct bin_attribute eeprom_attr = {
++ .attr = {
++ .name = "eeprom",
++ .mode = S_IRUGO,
++ },
++ .size = EEPROM_SIZE,
++ .read = eeprom_read,
++ .write = eeprom_write,
++
++};
++
++static int eeprom_attach_adapter(struct i2c_adapter *adapter)
++{
++ return i2c_probe(adapter, &addr_data, eeprom_detect);
++}
++
++/* This function is called by i2c_probe */
++static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
++{
++ struct i2c_client *new_client;
++ struct eeprom_data *data;
++ int err = 0;
++
++ /* There are three ways we can read the EEPROM data:
++ (1) I2C block reads (faster, but unsupported by most adapters)
++ (2) Consecutive byte reads (100% overhead)
++ (3) Regular byte data reads (200% overhead)
++ The third method is not implemented by this driver because all
++ known adapters support at least the second. */
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA
++ | I2C_FUNC_SMBUS_BYTE))
++ goto exit;
++
++ if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
++ err = -ENOMEM;
++ goto exit;
++ }
++
++ new_client = &data->client;
++ memset(data->data, 0xff, EEPROM_SIZE);
++ i2c_set_clientdata(new_client, data);
++ new_client->addr = address;
++ new_client->adapter = adapter;
++ new_client->driver = &eeprom_driver;
++ new_client->flags = 0;
++
++ /* Fill in the remaining client fields */
++ strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
++ data->valid = 0;
++ mutex_init(&data->update_lock);
++ data->nature = 0x00;
++
++ /* Tell the I2C layer a new client has arrived */
++ if ((err = i2c_attach_client(new_client)))
++ goto exit_kfree;
++
++ /* create the sysfs eeprom file */
++ err = sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
++ if (err)
++ goto exit_detach;
++
++ return 0;
++
++exit_detach:
++ i2c_detach_client(new_client);
++exit_kfree:
++ kfree(data);
++exit:
++ return err;
++}
++
++static int eeprom_detach_client(struct i2c_client *client)
++{
++ int err;
++
++ sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr);
++
++ err = i2c_detach_client(client);
++ if (err)
++ return err;
++
++ kfree(i2c_get_clientdata(client));
++
++ return 0;
++}
++
++static int __init eeprom_init(void)
++{
++ return i2c_add_driver(&eeprom_driver);
++
++}
++
++static void __exit eeprom_exit(void)
++{
++ i2c_del_driver(&eeprom_driver);
++}
++
++
++MODULE_AUTHOR("Guillaume Ligneul guillaume.ligneul@gmail.com");
++MODULE_DESCRIPTION("I2C EEPROM driver for AT24C32");
++MODULE_LICENSE("GPL");
++
++module_init(eeprom_init);
++module_exit(eeprom_exit);
+diff -Nru linux-2.6.26-officiel/drivers/i2c/chips/Makefile /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/Makefile
+--- linux-2.6.26-officiel/drivers/i2c/chips/Makefile 2008-11-06 11:12:07.000000000 +0100
++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/Makefile 2008-11-06 11:18:20.000000000 +0100
+@@ -9,7 +9,7 @@
+ # * I/O expander drivers go to drivers/gpio
+ #
+
+-
++obj-$(CONFIG_AT24C32) += at24c32.o
+ obj-$(CONFIG_ISL12024EEPROM) += isl12024-eeprom.o
+ obj-$(CONFIG_DS1682) += ds1682.o
+ obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o