summaryrefslogtreecommitdiff
path: root/packages/linux/linux-2.6.27/boc01/005-090112-isl12024.patch
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2009-02-26 13:11:08 +0100
committerJeremy Lainé <jeremy.laine@m4x.org>2009-02-26 13:11:08 +0100
commit9db305be9d88f1950df77c30ec78339332e9340c (patch)
tree79fb2de4c35ac1c383215f0cc84823ce4ae78150 /packages/linux/linux-2.6.27/boc01/005-090112-isl12024.patch
parent2c15084856164efbcb1caff09eef99ba12b2deba (diff)
linux-2.6.27: improve boc01 EEPROM support
Diffstat (limited to 'packages/linux/linux-2.6.27/boc01/005-090112-isl12024.patch')
-rw-r--r--packages/linux/linux-2.6.27/boc01/005-090112-isl12024.patch950
1 files changed, 0 insertions, 950 deletions
diff --git a/packages/linux/linux-2.6.27/boc01/005-090112-isl12024.patch b/packages/linux/linux-2.6.27/boc01/005-090112-isl12024.patch
deleted file mode 100644
index 32bde9dfc8..0000000000
--- a/packages/linux/linux-2.6.27/boc01/005-090112-isl12024.patch
+++ /dev/null
@@ -1,950 +0,0 @@
-Index: linux-2.6.27/drivers/i2c/chips/isl12024-eeprom.c
-===================================================================
---- /dev/null
-+++ linux-2.6.27/drivers/i2c/chips/isl12024-eeprom.c
-@@ -0,0 +1,254 @@
-+/*
-+ * Intersil ISL12024 EEPROM class driver
-+ *
-+ *
-+ * 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>
-+#include <linux/i2c/isl12024.h>
-+
-+/* Addresses to scan */
-+static const unsigned short normal_i2c[] = { ISL12024_I2C_EEPROM_ADDR, I2C_CLIENT_END };
-+
-+/* Insmod parameters */
-+I2C_CLIENT_INSMOD_1(eeprom);
-+
-+
-+/* Size of EEPROM in bytes */
-+#define EEPROM_SIZE 4096
-+
-+/* Each client has this additional data */
-+struct eeprom_data {
-+ struct i2c_client client;
-+ struct mutex update_lock;
-+};
-+
-+int
-+isl12024_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;
-+}
-+
-+
-+int
-+isl12024_i2c_write(struct i2c_client *client, u8 reg, u8 const buf[],
-+ unsigned len)
-+{
-+ int ret;
-+ u8 i2c_buf[EEPROM_SIZE];
-+
-+ struct i2c_msg msgs[1] = {
-+ {
-+ .addr = client->addr,
-+ .flags = 0,
-+ .len = len+2,
-+ .buf = i2c_buf,
-+ },
-+ };
-+
-+ i2c_buf[0] = 0;
-+ i2c_buf[1] = reg;
-+
-+
-+ memcpy(&i2c_buf[2], &buf[0], len );
-+
-+
-+ ret = i2c_transfer(client->adapter, msgs, 1);
-+ printk(KERN_INFO "i2c_transfer %d\n",ret);
-+ return ret;
-+}
-+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 = "isl12024-eeprom",
-+ },
-+ .attach_adapter = eeprom_attach_adapter,
-+ .detach_client = eeprom_detach_client,
-+};
-+
-+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 = isl12024_i2c_read(client,0,buf,EEPROM_SIZE);
-+
-+ if (rc < 0){
-+ mutex_unlock(&data->update_lock);
-+ return -EIO;
-+ }
-+
-+ mutex_unlock(&data->update_lock);
-+ return count;
-+}
-+
-+static ssize_t eeprom_write(struct kobject *kobj, struct bin_attribute *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);
-+
-+ if (off >= 256)
-+ return -ENOSPC;
-+
-+ if (off + count > 256)
-+ count = 256 - off;
-+
-+ mutex_unlock(&data->update_lock);
-+ if (isl12024_i2c_write(client, off, buf, count) < 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;
-+
-+ 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;
-+ i2c_set_clientdata(new_client, data);
-+ new_client->addr = address;
-+ new_client->adapter = adapter;
-+ new_client->driver = &eeprom_driver;
-+ new_client->flags = 0;
-+
-+ strlcpy(new_client->name, "isl12024-eeprom", I2C_NAME_SIZE);
-+ mutex_init(&data->update_lock);
-+
-+ /* 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@cenosys.com>");
-+MODULE_DESCRIPTION("I2C Intersil12024 EEPROM driver");
-+MODULE_LICENSE("GPL");
-+
-+module_init(eeprom_init);
-+module_exit(eeprom_exit);
-Index: linux-2.6.27/drivers/i2c/chips/Kconfig
-===================================================================
---- linux-2.6.27.orig/drivers/i2c/chips/Kconfig
-+++ linux-2.6.27/drivers/i2c/chips/Kconfig
-@@ -40,6 +40,15 @@ config AT24
- This driver can also be built as a module. If so, the module
- will be called at24.
-
-+config ISL12024EEPROM
-+ tristate "Intersil 12024 EEPROM"
-+ depends on RTC_DRV_ISL12024
-+ help
-+ If you say yes here you get support for Intersil12024 EEPROM.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called isl12024-eeprom.
-+
- config SENSORS_EEPROM
- tristate "EEPROM reader"
- depends on EXPERIMENTAL
-Index: linux-2.6.27/drivers/i2c/chips/Makefile
-===================================================================
---- linux-2.6.27.orig/drivers/i2c/chips/Makefile
-+++ linux-2.6.27/drivers/i2c/chips/Makefile
-@@ -9,6 +9,8 @@
- # * I/O expander drivers go to drivers/gpio
- #
-
-+
-+obj-$(CONFIG_ISL12024EEPROM) += isl12024-eeprom.o
- obj-$(CONFIG_DS1682) += ds1682.o
- obj-$(CONFIG_AT24) += at24.o
- obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
-Index: linux-2.6.27/drivers/rtc/Kconfig
-===================================================================
---- linux-2.6.27.orig/drivers/rtc/Kconfig
-+++ linux-2.6.27/drivers/rtc/Kconfig
-@@ -124,6 +124,12 @@ comment "I2C RTC drivers"
-
- if I2C
-
-+config RTC_DRV_ISL12024
-+ tristate "Intersil 12024 RTC/ UniqueID"
-+ help
-+ If you say yes ....
-+ This driver can also be built as a module.
-+
- config RTC_DRV_DS1307
- tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
- help
-Index: linux-2.6.27/drivers/rtc/Makefile
-===================================================================
---- linux-2.6.27.orig/drivers/rtc/Makefile
-+++ linux-2.6.27/drivers/rtc/Makefile
-@@ -34,6 +34,7 @@ obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds17
- obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
- obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
- obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
-+obj-$(CONFIG_RTC_DRV_ISL12024) += rtc-isl12024.o
- obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o
- obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
- obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o
-Index: linux-2.6.27/drivers/rtc/rtc-isl12024.c
-===================================================================
---- /dev/null
-+++ linux-2.6.27/drivers/rtc/rtc-isl12024.c
-@@ -0,0 +1,516 @@
-+/*
-+ * Intersil ISL12024 class driver
-+ *
-+ *
-+ * Copyright (C) 2007, CenoSYS (www.cenosys.com).
-+ * Guillaume Ligneul
-+ * Guillaume.ligneul@gmail.com
-+ *
-+ * 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/module.h>
-+#include <linux/i2c.h>
-+#include <linux/bcd.h>
-+#include <linux/rtc.h>
-+#include <linux/proc_fs.h>
-+#include <linux/i2c/isl12024.h>
-+#include <linux/delay.h>
-+
-+
-+#define DBG 1
-+#undef DBG
-+
-+static u8 buf_id[ISL12024_RTC_SECTION_LEN] = { 0 ,};
-+
-+#define DRV_NAME "isl12024"
-+#define DRV_VERSION "0.1"
-+
-+/* i2c configuration */
-+
-+static const unsigned short normal_i2c[] = {
-+ ISL12024_I2C_ADDR >>1, I2C_CLIENT_END
-+};
-+I2C_CLIENT_INSMOD;
-+
-+/* Procfs management */
-+static struct proc_dir_entry * root_proc = NULL;
-+static struct proc_dir_entry * entry_proc = NULL;
-+static int read_proc (char * page, char ** start, off_t off, int count, int * eof, void * data);
-+
-+static int isl12024_get_status(struct i2c_client *client, unsigned char *sr);
-+static int isl12024_fix_osc(struct i2c_client *client);
-+
-+
-+static int isl12024_attach_adapter(struct i2c_adapter *adapter);
-+static int isl12024_detach_client(struct i2c_client *client);
-+
-+// To debug (may be add in includ/linux/i2c-id.h)
-+#define I2C_DRIVERID_ISL12024 97
-+
-+static struct i2c_driver isl12024_driver = {
-+ .driver = {
-+ .name = DRV_NAME,
-+ },
-+ .id = I2C_DRIVERID_ISL12024,
-+ .attach_adapter = &isl12024_attach_adapter,
-+ .detach_client = &isl12024_detach_client,
-+};
-+
-+int
-+isl12024_i2c_read_regs(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;
-+}
-+
-+EXPORT_SYMBOL(isl12024_i2c_read_regs);
-+
-+
-+int
-+isl12024_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
-+ unsigned len)
-+{
-+ int ret;
-+ u8 i2c_buf[10];
-+
-+ struct i2c_msg msgs[1] = {
-+ {
-+ .addr = client->addr,
-+ .flags = 0,
-+ .len = len+2,
-+ .buf = i2c_buf,
-+ },
-+ };
-+
-+ i2c_buf[0] = 0;
-+ i2c_buf[1] = reg;
-+
-+
-+ memcpy(&i2c_buf[2], &buf[0], len );
-+
-+
-+ ret = i2c_transfer(client->adapter, msgs, 1);
-+ printk(KERN_INFO "i2c_transfer %d\n",ret);
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL(isl12024_i2c_set_regs);
-+
-+static int isl12024_i2c_validate_client(struct i2c_client *client)
-+{
-+ u8 regs[ISL12024_RTC_SECTION_LEN] = { 0, };
-+ u8 zero_mask[ISL12024_RTC_SECTION_LEN] = {
-+ 0x80, 0x80, 0x40, 0xc0, 0xe0, 0x00, 0xf8, 0xc6
-+ };
-+
-+ int i;
-+ int ret;
-+
-+ ret = isl12024_i2c_read_regs(client, ISL12024_REG_SC, regs, ISL12024_RTC_SECTION_LEN);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ for (i = 0; i < ISL12024_RTC_SECTION_LEN; ++i) {
-+ if (regs[i] & zero_mask[i]) /* check if bits are cleared */
-+ return -ENODEV;
-+
-+ }
-+
-+ return 0;
-+}
-+
-+static int isl12024_read_time(struct i2c_client *client,
-+ struct rtc_time *tm)
-+{
-+ unsigned char sr;
-+ int err;
-+ u8 regs[ISL12024_RTC_SECTION_LEN] = { 0, };
-+
-+ printk(KERN_INFO "%s\n ",__FUNCTION__ );
-+
-+
-+ if (isl12024_get_status(client, &sr) < 0) {
-+ dev_err(&client->dev, "%s: reading SR failed\n", __func__);
-+ return -EIO;
-+ }
-+
-+ err = isl12024_i2c_read_regs(client, ISL12024_REG_SC, regs, ISL12024_RTC_SECTION_LEN);
-+
-+#ifdef DBG
-+ int i;
-+ for(i=0; i<ISL12024_RTC_SECTION_LEN; i++)
-+ printk(KERN_INFO "0x%2X\n", regs[i]);
-+#endif
-+
-+ if (err < 0) {
-+ dev_err(&client->dev, "%s: reading RTC section failed\n",
-+ __func__);
-+ return sr;
-+ }
-+
-+ tm->tm_sec = BCD2BIN(regs[0]);
-+ tm->tm_min = BCD2BIN(regs[1]);
-+
-+ { /* HR field has a more complex interpretation */
-+ const u8 _hr = regs[2];
-+ if (_hr & ISL12024_REG_HR_MIL) /* 24h format */
-+ tm->tm_hour = BCD2BIN(_hr & 0x3f);
-+ else { // 12h format
-+ tm->tm_hour = BCD2BIN(_hr & 0x1f);
-+ if (_hr & ISL12024_REG_HR_PM) /* PM flag set */
-+ tm->tm_hour += 12;
-+ }
-+ }
-+
-+ tm->tm_mday = BCD2BIN(regs[3]);
-+ tm->tm_mon = BCD2BIN(regs[4]);
-+ tm->tm_year = BCD2BIN(regs[5]) + 100;
-+ tm->tm_wday = BCD2BIN(regs[6]);
-+
-+ return rtc_valid_tm(tm);
-+}
-+
-+static int isl12024_get_status(struct i2c_client *client, unsigned char *sr)
-+{
-+ static unsigned char sr_addr[2] = { 0, ISL12024_REG_SR };
-+
-+ struct i2c_msg msgs[] = {
-+ { client->addr, 0, 2, sr_addr }, /* setup read ptr */
-+ { client->addr, I2C_M_RD, 1, sr }, /* read status */
-+ };
-+
-+ /* read status register */
-+ if (i2c_transfer(client->adapter, &msgs[0], 2) != 2) {
-+ dev_err(&client->dev, "%s: read error\n", __func__);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int isl12024_set_datetime(struct i2c_client *client, struct rtc_time *tm,
-+ int datetoo, u8 reg_base, unsigned char alm_enable)
-+{
-+ int i, xfer, nbytes;
-+ unsigned char buf[8];
-+ unsigned char rdata[10] = { 0, reg_base };
-+
-+ static const unsigned char wel[3] = { 0, ISL12024_REG_SR,
-+ ISL12024_SR_WEL };
-+
-+ static const unsigned char rwel[3] = { 0, ISL12024_REG_SR,
-+ ISL12024_SR_WEL | ISL12024_SR_RWEL };
-+
-+ static const unsigned char diswe[3] = { 0, ISL12024_REG_SR, 0 };
-+
-+ dev_dbg(&client->dev,
-+ "%s: secs=%d, mins=%d, hours=%d\n",
-+ __func__,
-+ tm->tm_sec, tm->tm_min, tm->tm_hour);
-+
-+ buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
-+ buf[CCR_MIN] = BIN2BCD(tm->tm_min);
-+
-+ /* set hour and 24hr bit */
-+ buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | ISL12024_HR_MIL;
-+
-+ /* should we also set the date? */
-+ if (datetoo) {
-+ dev_dbg(&client->dev,
-+ "%s: mday=%d, mon=%d, year=%d, wday=%d\n",
-+ __func__,
-+ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-+ buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
-+
-+ /* month, 1 - 12 */
-+ buf[CCR_MONTH] = BIN2BCD(tm->tm_mon);
-+
-+ /* year, since the rtc epoch*/
-+ buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100);
-+ buf[CCR_WDAY] = tm->tm_wday & 0x07;
-+ buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100);
-+ }
-+
-+ /* If writing alarm registers, set compare bits on registers 0-4 */
-+ if (reg_base < ISL12024_CCR_BASE)
-+ for (i = 0; i <= 4; i++)
-+ buf[i] |= 0x80;
-+
-+ /* this sequence is required to unlock the chip */
-+ if ((xfer = i2c_master_send(client, wel, 3)) != 3) {
-+ dev_err(&client->dev, "%s: wel - %d\n", __func__, xfer);
-+ return -EIO;
-+ }
-+
-+ if ((xfer = i2c_master_send(client, rwel, 3)) != 3) {
-+ dev_err(&client->dev, "%s: rwel - %d\n", __func__, xfer);
-+ return -EIO;
-+ }
-+
-+
-+ /* write register's data */
-+ if (datetoo)
-+ nbytes = 8;
-+ else
-+ nbytes = 3;
-+ for (i = 0; i < nbytes; i++)
-+ rdata[2+i] = buf[i];
-+
-+ xfer = i2c_master_send(client, rdata, nbytes+2);
-+ if (xfer != nbytes+2) {
-+ dev_err(&client->dev,
-+ "%s: result=%d addr=%02x, data=%02x\n",
-+ __func__,
-+ xfer, rdata[1], rdata[2]);
-+ return -EIO;
-+ }
-+
-+ /* If we wrote to the nonvolatile region, wait 10msec for write cycle*/
-+ if (reg_base < ISL12024_CCR_BASE) {
-+ unsigned char al0e[3] = { 0, ISL12024_REG_INT, 0 };
-+
-+ msleep(10);
-+
-+ /* ...and set or clear the AL0E bit in the INT register */
-+
-+ /* Need to set RWEL again as the write has cleared it */
-+ xfer = i2c_master_send(client, rwel, 3);
-+ if (xfer != 3) {
-+ dev_err(&client->dev,
-+ "%s: aloe rwel - %d\n",
-+ __func__,
-+ xfer);
-+ return -EIO;
-+ }
-+
-+ if (alm_enable)
-+ al0e[2] = ISL12024_INT_AL0E;
-+
-+ xfer = i2c_master_send(client, al0e, 3);
-+ if (xfer != 3) {
-+ dev_err(&client->dev,
-+ "%s: al0e - %d\n",
-+ __func__,
-+ xfer);
-+ return -EIO;
-+ }
-+
-+ /* and wait 10msec again for this write to complete */
-+ msleep(10);
-+ }
-+
-+ /* disable further writes */
-+ if ((xfer = i2c_master_send(client, diswe, 3)) != 3) {
-+ dev_err(&client->dev, "%s: diswe - %d\n", __func__, xfer);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int isl12024_fix_osc(struct i2c_client *client)
-+{
-+ int err;
-+ struct rtc_time tm;
-+
-+ tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
-+
-+ err = isl12024_set_datetime(client, &tm, 0, ISL12024_CCR_BASE, 0);
-+ if (err < 0)
-+ printk(KERN_INFO "unable to restart the oscillator\n");
-+
-+ return err;
-+}
-+
-+static int isl12024_rtc_read_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return isl12024_read_time(to_i2c_client(dev), tm);
-+
-+}
-+
-+static int isl12024_rtc_set_time(struct device *dev, struct rtc_time *tm)
-+{
-+ return isl12024_set_datetime(to_i2c_client(dev),
-+ tm, 1, ISL12024_CCR_BASE, 0);
-+}
-+
-+static int
-+isl12024_rtc_proc(struct device *dev, struct seq_file *seq)
-+{
-+
-+ /* Nothing to do */
-+
-+ return 0;
-+}
-+
-+static const struct rtc_class_ops isl12024_rtc_ops = {
-+ .proc = isl12024_rtc_proc,
-+ .read_time = isl12024_rtc_read_time,
-+ .set_time = isl12024_rtc_set_time,
-+};
-+
-+static int read_proc (char * page, char ** start, off_t off, int count, int * eof, void * data)
-+{
-+ int i=0;
-+
-+ printk("id: 0x");
-+ for(i=0;i<ISL12024_RTC_SECTION_LEN;i++)
-+ printk("%02X",buf_id[i]);
-+ printk("\n");
-+ return 0;
-+}
-+
-+static int
-+isl12024_probe(struct i2c_adapter *adapter, int addr, int kind)
-+{
-+
-+ int rc = 0;
-+ int err = 0;
-+ unsigned char sr;
-+ struct i2c_client *new_client = NULL;
-+ struct rtc_device *rtc = NULL;
-+
-+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-+ rc = -ENODEV;
-+ goto failout;
-+ }
-+
-+ new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-+ if (new_client == NULL) {
-+ rc = -ENOMEM;
-+ goto failout;
-+ }
-+
-+ new_client->addr = addr;
-+ new_client->adapter = adapter;
-+ new_client->driver = &isl12024_driver;
-+ new_client->flags = 0;
-+ strcpy(new_client->name, DRV_NAME);
-+
-+ if (kind < 0) {
-+ rc = isl12024_i2c_validate_client(new_client);
-+ if (rc < 0)
-+ goto failout;
-+ }
-+
-+ rc = i2c_attach_client(new_client);
-+ if (rc < 0)
-+ goto failout;
-+
-+ rtc = rtc_device_register(isl12024_driver.driver.name,
-+ &new_client->dev,
-+ &isl12024_rtc_ops, THIS_MODULE);
-+
-+ if (IS_ERR(rtc)) {
-+ printk("Error during rtc registration\n");
-+ rc = PTR_ERR(rtc);
-+ goto failout;
-+ }
-+
-+ i2c_set_clientdata(new_client, rtc);
-+
-+ /* Check for power failures and eventualy enable the osc */
-+ if ((err = isl12024_get_status(new_client, &sr)) == 0) {
-+ if (sr & ISL12024_SR_RTCF) {
-+ printk(KERN_INFO "power failure detected, "
-+ "please set the clock\n");
-+ udelay(50);
-+ isl12024_fix_osc(new_client);
-+ }
-+ }
-+ else
-+ printk(KERN_INFO "couldn't read status\n");
-+
-+ root_proc = proc_mkdir( "isl12024", 0 );
-+ entry_proc = create_proc_entry("id", S_IFREG | S_IRUGO | S_IWUSR, root_proc);
-+
-+ if (entry_proc == NULL)
-+ return -1;
-+
-+ entry_proc->owner = THIS_MODULE;
-+ entry_proc->read_proc = read_proc;
-+
-+ /* read unique id from eeprom */
-+ isl12024_i2c_read_regs(new_client, ISL12024_REG_ID, buf_id, sizeof(buf_id));
-+
-+
-+ return 0;
-+
-+ failout:
-+ kfree(new_client);
-+ return rc;
-+}
-+
-+static int
-+isl12024_attach_adapter (struct i2c_adapter *adapter)
-+{
-+ return i2c_probe(adapter, &addr_data, isl12024_probe);
-+}
-+
-+static int
-+isl12024_detach_client(struct i2c_client *client)
-+{
-+ int rc;
-+ struct rtc_device *const rtc = i2c_get_clientdata(client);
-+
-+ if (rtc)
-+ rtc_device_unregister(rtc);
-+
-+ rc = i2c_detach_client(client);
-+ if (rc)
-+ return rc;
-+
-+ kfree(client);
-+
-+ return 0;
-+}
-+
-+/* module init/exit */
-+
-+static int __init isl12024_init(void)
-+{
-+ return i2c_add_driver(&isl12024_driver);
-+}
-+
-+static void __exit isl12024_exit(void)
-+{
-+ i2c_del_driver(&isl12024_driver);
-+}
-+
-+MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@cenosys.com>");
-+MODULE_DESCRIPTION("Intersil ISL12024 driver");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-+
-+module_init(isl12024_init);
-+module_exit(isl12024_exit);
-Index: linux-2.6.27/include/linux/i2c/isl12024.h
-===================================================================
---- /dev/null
-+++ linux-2.6.27/include/linux/i2c/isl12024.h
-@@ -0,0 +1,103 @@
-+/*
-+ * Intersil ISL12024 chip registers definitions
-+ *
-+ *
-+ * Copyright (C) 2008, CenoSYS (www.cenosys.com).
-+ * Guillaume Ligneul
-+ * Guillaume.ligneul@gmail.com
-+ *
-+ * 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
-+ */
-+
-+#ifndef ISL12024_H_
-+#define ISL12024_H_
-+
-+#define ISL12024_REG_SR 0x3F /* status register */
-+#define ISL12024_REG_Y2K 0x37
-+#define ISL12024_REG_DW 0x36
-+#define ISL12024_REG_YR 0x35
-+#define ISL12024_REG_MO 0x34
-+#define ISL12024_REG_DT 0x33
-+#define ISL12024_REG_HR 0x32
-+#define ISL12024_REG_MN 0x31
-+#define ISL12024_REG_SC 0x30
-+#define ISL12024_REG_DTR 0x13
-+#define ISL12024_REG_ATR 0x12
-+#define ISL12024_REG_INT 0x11
-+#define ISL12024_REG_0 0x10
-+#define ISL12024_REG_Y2K1 0x0F
-+#define ISL12024_REG_DWA1 0x0E
-+#define ISL12024_REG_YRA1 0x0D
-+#define ISL12024_REG_MOA1 0x0C
-+#define ISL12024_REG_DTA1 0x0B
-+#define ISL12024_REG_HRA1 0x0A
-+#define ISL12024_REG_MNA1 0x09
-+#define ISL12024_REG_SCA1 0x08
-+#define ISL12024_REG_Y2K0 0x07
-+#define ISL12024_REG_DWA0 0x06
-+#define ISL12024_REG_YRA0 0x05
-+#define ISL12024_REG_MOA0 0x04
-+#define ISL12024_REG_DTA0 0x03
-+#define ISL12024_REG_HRA0 0x02
-+#define ISL12024_REG_MNA0 0x01
-+#define ISL12024_REG_SCA0 0x00
-+
-+#define ISL12024_CCR_BASE 0x30 /* Base address of CCR */
-+#define ISL12024_ALM0_BASE 0x00 /* Base address of ALARM0 */
-+
-+#define ISL12024_SR_RTCF 0x01 /* Clock failure */
-+#define ISL12024_SR_WEL 0x02 /* Write Enable Latch */
-+#define ISL12024_SR_RWEL 0x04 /* Register Write Enable */
-+#define ISL12024_SR_AL0 0x20 /* Alarm 0 match */
-+
-+#define ISL12024_DTR_DTR0 0x01
-+#define ISL12024_DTR_DTR1 0x02
-+#define ISL12024_DTR_DTR2 0x04
-+
-+#define ISL12024_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */
-+
-+#define ISL12024_INT_AL0E 0x20 /* Alarm 0 enable */
-+/* I2C ADDRESS */
-+#define ISL12024_I2C_ADDR 0xDE
-+#define ISL12024_I2C_EEPROM_ADDR 0x57
-+/* device id section */
-+#define ISL12024_REG_ID 0x20
-+/* Register map */
-+/* rtc section */
-+//#define ISL12024_REG_MSB 0x00
-+//#define ISL12024_REG_SC 0x30 /* Seconds */
-+//#define ISL12024_REG_MN 0x31 /* Minutes */
-+//#define ISL12024_REG_HR 0x32 /* Hours */
-+#define ISL12024_REG_HR_MIL (1<<7) /* 24h/12h mode */
-+#define ISL12024_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */
-+//#define ISL12024_REG_DT 0x33 /* Date */
-+//#define ISL12024_REG_MO 0x34 /* Month */
-+//#define ISL12024_REG_YR 0x35 /* Year */
-+//#define ISL12024_REG_DW 0x36
-+//#define ISL12024_REG_Y2K 0x37
-+#define ISL12024_RTC_SECTION_LEN 8
-+
-+
-+
-+/* control/status section */
-+//#define ISL12024_REG_SR 0x3F
-+//#define ISL12024_REG_SR_BAT (1<<7) /* battery */
-+//#define ISL12024_REG_SR_AL1 (1<<6) /* alarm 0 */
-+//#define ISL12024_REG_SR_AL0 (1<<5) /* alarm 1 */
-+//#define ISL12024_REG_SR_OSCF (1<<4) /* oscillator fail */
-+//#define ISL12024_REG_SR_RWEL (1<<2) /* register write enable latch */
-+//#define ISL12024_REG_SR_WEL (1<<1) /* write enable latch */
-+//#define ISL12024_REG_SR_RTCF (1<<0) /* rtc fail */
-+//#define ISL12024_REG_INT 0x11
-+
-+#define CCR_SEC 0
-+#define CCR_MIN 1
-+#define CCR_HOUR 2
-+#define CCR_MDAY 3
-+#define CCR_MONTH 4
-+#define CCR_YEAR 5
-+#define CCR_WDAY 6
-+#define CCR_Y2K 7
-+
-+#endif /*ISL12024_H_*/