diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2008-11-24 19:27:16 +0100 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2008-11-24 19:27:16 +0100 |
| commit | 30926fd2523fd93741149dd4ccd0e69ed3e1854d (patch) | |
| tree | 36be7ee263f6590553ee2387c334bce493bfd968 /packages | |
| parent | c7d514e3de6cb0ddad3dbc7efd4428b24cd2d144 (diff) | |
linux-2.6.26: add patches for boc01 hardware
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/002-081105-headers.patch | 112 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/003-081124-nand.patch | 107 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/004-081105-usb.patch | 17 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/005-081105-isl12024.patch | 994 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/006-081105-at24c32.patch | 284 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/007-081105-lm73.patch | 317 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/008-081105-spi.patch | 100 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/010-081105-mii.patch | 519 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/011-081105-gpio.patch | 161 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/012-081121-cy3218-btns.patch | 243 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/boc01.dts | 67 | ||||
| -rw-r--r-- | packages/linux/linux-2.6.26/boc01/defconfig | 371 | ||||
| -rw-r--r-- | packages/linux/linux_2.6.26.bb | 11 |
13 files changed, 2998 insertions, 305 deletions
diff --git a/packages/linux/linux-2.6.26/boc01/002-081105-headers.patch b/packages/linux/linux-2.6.26/boc01/002-081105-headers.patch new file mode 100644 index 0000000000..b82dcbce4a --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/002-081105-headers.patch @@ -0,0 +1,112 @@ +diff -Nru /opt/Bollore/dev/oe/build/tmp/work/mpc8313e-rdb-angstrom-linux/linux-2.6.26-r1.1/linux-2.6.26/include/linux/i2c/isl12024.h ../linux-2.6.26.modified/include/linux/i2c/isl12024.h +--- /opt/Bollore/dev/oe/build/tmp/work/mpc8313e-rdb-angstrom-linux/linux-2.6.26-r1.1/linux-2.6.26/include/linux/i2c/isl12024.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.26.modified/include/linux/i2c/isl12024.h 2008-10-21 10:36:19.000000000 +0200 +@@ -0,0 +1,93 @@ ++#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_*/ +diff -Nru /opt/Bollore/dev/oe/build/tmp/work/mpc8313e-rdb-angstrom-linux/linux-2.6.26-r1.1/linux-2.6.26/include/linux/phy.h ../linux-2.6.26.modified/include/linux/phy.h +--- /opt/Bollore/dev/oe/build/tmp/work/mpc8313e-rdb-angstrom-linux/linux-2.6.26-r1.1/linux-2.6.26/include/linux/phy.h 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26.modified/include/linux/phy.h 2008-10-14 15:12:02.000000000 +0200 +@@ -339,6 +339,11 @@ + u32 features; + u32 flags; + ++ /* Called during discovery to test if the ++ * device can attach to the bus, even if ++ phy id and mask do not match */ ++ bool (*detect)(struct mii_bus *bus, int addr); ++ + /* + * Called to initialize the PHY, + * including after a reset diff --git a/packages/linux/linux-2.6.26/boc01/003-081124-nand.patch b/packages/linux/linux-2.6.26/boc01/003-081124-nand.patch new file mode 100644 index 0000000000..885bad2715 --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/003-081124-nand.patch @@ -0,0 +1,107 @@ +diff -Nru linux-2.6.26/drivers/mtd/nand/fsl_elbc_nand.c linux-2.6.26.modified/drivers/mtd/nand/fsl_elbc_nand.c +--- linux-2.6.26/drivers/mtd/nand/fsl_elbc_nand.c 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26.modified/drivers/mtd/nand/fsl_elbc_nand.c 2008-10-24 13:43:30.000000000 +0200 +@@ -89,7 +89,7 @@ + .eccbytes = 3, + .eccpos = {6, 7, 8}, + .oobfree = { {0, 5}, {9, 7} }, +- .oobavail = 12, ++// .oobavail = 12, + }; + + /* Small Page FLASH with FMR[ECCM] = 1 */ +@@ -97,7 +97,7 @@ + .eccbytes = 3, + .eccpos = {8, 9, 10}, + .oobfree = { {0, 5}, {6, 2}, {11, 5} }, +- .oobavail = 12, ++ //.oobavail = 12, + }; + + /* Large Page FLASH with FMR[ECCM] = 0 */ +@@ -105,7 +105,7 @@ + .eccbytes = 12, + .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56}, + .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }, +- .oobavail = 48, ++ //.oobavail = 48, + }; + + /* Large Page FLASH with FMR[ECCM] = 1 */ +@@ -113,7 +113,48 @@ + .eccbytes = 12, + .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, + .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, +- .oobavail = 48, ++// .oobavail = 48, ++}; ++/* ++ * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset ++ * 1, so we have to adjust bad block pattern. This pattern should be used for ++ * x8 chips only. So far hardware does not support x16 chips anyway. ++ */ ++static u8 scan_ff_pattern[] = { 0xff, }; ++ ++static struct nand_bbt_descr largepage_memorybased = { ++ .options = 0, ++ .offs = 0, ++ .len = 1, ++ .pattern = scan_ff_pattern, ++}; ++ ++/* ++ * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, ++ * interfere with ECC positions, that's why we implement our own descriptors. ++ * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. ++ */ ++static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; ++static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; ++ ++static struct nand_bbt_descr bbt_main_descr = { ++ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION, ++ .offs = 11, ++ .len = 4, ++ .veroffs = 15, ++ .maxblocks = 4, ++ .pattern = bbt_pattern, ++}; ++ ++static struct nand_bbt_descr bbt_mirror_descr = { ++ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ++ NAND_BBT_2BIT | NAND_BBT_VERSION, ++ .offs = 11, ++ .len = 4, ++ .veroffs = 15, ++ .maxblocks = 4, ++ .pattern = mirror_pattern, + }; + + /*=================================*/ +@@ -687,8 +728,9 @@ + chip->ecc.layout = (priv->fmr & FMR_ECCM) ? + &fsl_elbc_oob_lp_eccm1 : + &fsl_elbc_oob_lp_eccm0; +- mtd->ecclayout = chip->ecc.layout; +- mtd->oobavail = chip->ecc.layout->oobavail; ++ //mtd->ecclayout = chip->ecc.layout; ++ //mtd->oobavail = chip->ecc.layout->oobavail; ++ chip->badblock_pattern = &largepage_memorybased; + } + } else { + dev_err(ctrl->dev, +@@ -752,8 +794,12 @@ + chip->cmdfunc = fsl_elbc_cmdfunc; + chip->waitfunc = fsl_elbc_wait; + ++ chip->bbt_td = &bbt_main_descr; ++ chip->bbt_md = &bbt_mirror_descr; ++ + /* set up nand options */ +- chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR; ++ //chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR; ++ chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR | NAND_USE_FLASH_BBT; + + chip->controller = &ctrl->controller; + chip->priv = priv; + diff --git a/packages/linux/linux-2.6.26/boc01/004-081105-usb.patch b/packages/linux/linux-2.6.26/boc01/004-081105-usb.patch new file mode 100644 index 0000000000..f64119c4fa --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/004-081105-usb.patch @@ -0,0 +1,17 @@ +diff -Nru linux-2.6.26-officiel/arch/powerpc/platforms/83xx/usb.c /home/guilig/workspace/kernel-goobie-2.6.26/src/arch/powerpc/platforms/83xx/usb.c +--- linux-2.6.26-officiel/arch/powerpc/platforms/83xx/usb.c 2008-07-13 23:51:29.000000000 +0200 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/arch/powerpc/platforms/83xx/usb.c 2008-10-23 11:34:06.000000000 +0200 +@@ -166,10 +166,10 @@ + !strcmp(prop, "utmi"))) { + u32 refsel; + +- if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) ++// if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) + refsel = CONTROL_REFSEL_24MHZ; +- else +- refsel = CONTROL_REFSEL_48MHZ; ++// else ++// refsel = CONTROL_REFSEL_48MHZ; + /* Set UTMI_PHY_EN and REFSEL */ + out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, + CONTROL_UTMI_PHY_EN | refsel); diff --git a/packages/linux/linux-2.6.26/boc01/005-081105-isl12024.patch b/packages/linux/linux-2.6.26/boc01/005-081105-isl12024.patch new file mode 100644 index 0000000000..538a29ce7e --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/005-081105-isl12024.patch @@ -0,0 +1,994 @@ +diff -Nru linux-2.6.26-officiel/drivers/i2c/chips/isl12024-eeprom.c /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/isl12024-eeprom.c +--- linux-2.6.26-officiel/drivers/i2c/chips/isl12024-eeprom.c 1970-01-01 01:00:00.000000000 +0100 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/isl12024-eeprom.c 2008-11-06 10:41:46.000000000 +0100 +@@ -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); +diff -Nru linux-2.6.26-officiel/drivers/i2c/chips/Kconfig /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/Kconfig +--- linux-2.6.26-officiel/drivers/i2c/chips/Kconfig 2008-07-13 23:51:29.000000000 +0200 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/Kconfig 2008-11-05 15:49:03.000000000 +0100 +@@ -4,6 +4,12 @@ + + menu "Miscellaneous I2C Chip support" + ++config AT24C32 ++ tristate "24C32 EEPROM" ++ depends on SYSFS && EXPERIMENTAL ++ help ++ help not needed :) ++ + config DS1682 + tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm" + depends on EXPERIMENTAL +@@ -14,6 +20,15 @@ + This driver can also be built as a module. If so, the module + will be called ds1682. + ++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 +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-07-13 23:51:29.000000000 +0200 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/i2c/chips/Makefile 2008-11-06 11:04:27.000000000 +0100 +@@ -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_SENSORS_EEPROM) += eeprom.o + obj-$(CONFIG_SENSORS_MAX6875) += max6875.o +diff -Nru linux-2.6.26-officiel/drivers/rtc/Kconfig /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/rtc/Kconfig +--- linux-2.6.26-officiel/drivers/rtc/Kconfig 2008-07-13 23:51:29.000000000 +0200 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/rtc/Kconfig 2008-09-26 13:53:16.000000000 +0200 +@@ -124,6 +124,12 @@ + + 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 +diff -Nru linux-2.6.26-officiel/drivers/rtc/Makefile /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/rtc/Makefile +--- linux-2.6.26-officiel/drivers/rtc/Makefile 2008-07-13 23:51:29.000000000 +0200 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/rtc/Makefile 2008-09-26 14:25:25.000000000 +0200 +@@ -33,6 +33,7 @@ + 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_M48T59) += rtc-m48t59.o + obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o +diff -Nru linux-2.6.26-officiel/drivers/rtc/rtc-isl12024.c /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/rtc/rtc-isl12024.c +--- linux-2.6.26-officiel/drivers/rtc/rtc-isl12024.c 1970-01-01 01:00:00.000000000 +0100 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/drivers/rtc/rtc-isl12024.c 2008-10-21 10:41:51.000000000 +0200 +@@ -0,0 +1,564 @@ ++/* ++ * 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_get_datetime(struct i2c_client *client, struct rtc_time *tm, ++// unsigned char reg_base) ++//{ ++// unsigned char dt_addr[2] = { 0, reg_base }; ++// unsigned char buf[8]; ++// int i; ++// ++// struct i2c_msg msgs[] = { ++// { client->addr, 0, 2, dt_addr }, /* setup read ptr */ ++// { client->addr, I2C_M_RD, 8, buf }, /* read date */ ++// }; ++// ++// /* read date registers */ ++// if (i2c_transfer(client->adapter, &msgs[0], 2) != 2) { ++// dev_err(&client->dev, "%s: read error\n", __func__); ++// return -EIO; ++// } ++// ++// dev_dbg(&client->dev, ++// "%s: raw read data - sec=%02x, min=%02x, hr=%02x, " ++// "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n", ++// __func__, ++// buf[0], buf[1], buf[2], buf[3], ++// buf[4], buf[5], buf[6], buf[7]); ++// ++// /* Mask out the enable bits if these are alarm registers */ ++// if (reg_base < ISL12024_CCR_BASE) ++// for (i = 0; i <= 4; i++) ++// buf[i] &= 0x7F; ++// ++// tm->tm_sec = BCD2BIN(buf[CCR_SEC]); ++// tm->tm_min = BCD2BIN(buf[CCR_MIN]); ++// tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */ ++// tm->tm_mday = BCD2BIN(buf[CCR_MDAY]); ++// tm->tm_mon = BCD2BIN(buf[CCR_MONTH]) - 1; /* mon is 0-11 */ ++// tm->tm_year = BCD2BIN(buf[CCR_YEAR]) ++// + (BCD2BIN(buf[CCR_Y2K]) * 100) - 1900; ++// tm->tm_wday = buf[CCR_WDAY]; ++// ++// dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " ++// "mday=%d, mon=%d, year=%d, wday=%d\n", ++// __func__, ++// tm->tm_sec, tm->tm_min, tm->tm_hour, ++// tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); ++// ++// 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 + 1); ++ ++ /* 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 */ |
