From 08e1a194bea902951f0e6bc9b0f2050ba031671f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jeremy=20Lain=C3=A9?= Date: Tue, 2 Dec 2008 07:07:45 +0100 Subject: linux-2.6.26: update patches for boc01 machine --- .../linux-2.6.26/boc01/005-081105-isl12024.patch | 994 --------------------- .../linux-2.6.26/boc01/005-081127-isl12024.patch | 946 ++++++++++++++++++++ .../linux/linux-2.6.26/boc01/007-081105-lm73.patch | 317 ------- .../linux/linux-2.6.26/boc01/007-081127-lm73.patch | 275 ++++++ .../linux/linux-2.6.26/boc01/008-081105-spi.patch | 100 --- .../linux/linux-2.6.26/boc01/008-081127-spi.patch | 327 +++++++ .../linux/linux-2.6.26/boc01/013-081127-lcd.patch | 663 ++++++++++++++ packages/linux/linux-2.6.26/boc01/boc01.dts | 3 +- packages/linux/linux-2.6.26/boc01/defconfig | 76 +- packages/linux/linux_2.6.26.bb | 9 +- 10 files changed, 2258 insertions(+), 1452 deletions(-) delete mode 100644 packages/linux/linux-2.6.26/boc01/005-081105-isl12024.patch create mode 100644 packages/linux/linux-2.6.26/boc01/005-081127-isl12024.patch delete mode 100644 packages/linux/linux-2.6.26/boc01/007-081105-lm73.patch create mode 100644 packages/linux/linux-2.6.26/boc01/007-081127-lm73.patch delete mode 100644 packages/linux/linux-2.6.26/boc01/008-081105-spi.patch create mode 100644 packages/linux/linux-2.6.26/boc01/008-081127-spi.patch create mode 100644 packages/linux/linux-2.6.26/boc01/013-081127-lcd.patch (limited to 'packages') 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 deleted file mode 100644 index 538a29ce7e..0000000000 --- a/packages/linux/linux-2.6.26/boc01/005-081105-isl12024.patch +++ /dev/null @@ -1,994 +0,0 @@ -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 -+#include -+#include -+//#include -+//#include -+#include -+#include -+#include -+ -+/* 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 "); -+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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#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; idev, "%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 */ -+ -+ 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;iaddr = 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 "); -+MODULE_DESCRIPTION("Intersil ISL12024 driver"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); -+ -+module_init(isl12024_init); -+module_exit(isl12024_exit); -diff -Nru linux-2.6.26-officiel/include/i2c/isl12024.h /home/guilig/workspace/kernel-goobie-2.6.26/src/include/linux/i2c/isl12024.h ---- linux-2.6.26-officiel/include/i2c/isl12024.h 1970-01-01 01:00:00.000000000 +0100 -+++ /home/guilig/workspace/kernel-goobie-2.6.26/src/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 --git a/packages/linux/linux-2.6.26/boc01/005-081127-isl12024.patch b/packages/linux/linux-2.6.26/boc01/005-081127-isl12024.patch new file mode 100644 index 0000000000..5e9f198b47 --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/005-081127-isl12024.patch @@ -0,0 +1,946 @@ +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 ++#include ++#include ++//#include ++//#include ++#include ++#include ++#include ++ ++/* 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 "); ++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/drivers/rtc/rtc-isl12024.c linux-2.6.26.mod/drivers/rtc/rtc-isl12024.c +--- linux-2.6.26/drivers/rtc/rtc-isl12024.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.26.mod/drivers/rtc/rtc-isl12024.c 2008-11-27 12:05:37.000000000 +0100 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#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; idev, "%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;iaddr = 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 "); ++MODULE_DESCRIPTION("Intersil ISL12024 driver"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION(DRV_VERSION); ++ ++module_init(isl12024_init); ++module_exit(isl12024_exit); +diff -Nru linux-2.6.26-officiel/include/i2c/isl12024.h /home/guilig/workspace/kernel-goobie-2.6.26/src/include/linux/i2c/isl12024.h +--- linux-2.6.26-officiel/include/i2c/isl12024.h 1970-01-01 01:00:00.000000000 +0100 ++++ /home/guilig/workspace/kernel-goobie-2.6.26/src/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 --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 deleted file mode 100644 index 4f51d5d222..0000000000 --- a/packages/linux/linux-2.6.26/boc01/007-081105-lm73.patch +++ /dev/null @@ -1,317 +0,0 @@ -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 -+ -+ 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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 "); -+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 diff --git a/packages/linux/linux-2.6.26/boc01/007-081127-lm73.patch b/packages/linux/linux-2.6.26/boc01/007-081127-lm73.patch new file mode 100644 index 0000000000..14787f8b04 --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/007-081127-lm73.patch @@ -0,0 +1,275 @@ +diff -Nru linux-2.6.26/drivers/hwmon/Kconfig linux-2.6.26.mod/drivers/hwmon/Kconfig +--- linux-2.6.26/drivers/hwmon/Kconfig 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26.mod/drivers/hwmon/Kconfig 2008-11-18 11:54:04.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/drivers/hwmon/lm73.c linux-2.6.26.mod/drivers/hwmon/lm73.c +--- linux-2.6.26/drivers/hwmon/lm73.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.26.mod/drivers/hwmon/lm73.c 2008-11-27 11:46:31.000000000 +0100 +@@ -0,0 +1,241 @@ ++ /* ++ * LM73 Sensor driver ++ * Based on LM75 ++ * ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* 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(lm73); ++ ++/* LM73 registers */ ++#define LM73_REG_INPUT 0x00 ++#define LM73_REG_CONF 0x01 ++#define LM73_REG_T_HIGH 0x02 ++#define LM73_REG_T_LOW 0x03 ++ ++static const u8 LM73_REG_TEMP[3] = { ++ LM73_REG_INPUT, /* input */ ++ LM73_REG_T_HIGH, /* max */ ++ LM73_REG_T_LOW, /* min */ ++}; ++ ++/* Each client has this additional data */ ++struct lm73_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 = min */ ++}; ++ ++static int lm73_attach_adapter(struct i2c_adapter *adapter); ++static int lm73_detect(struct i2c_adapter *adapter, int address, int kind); ++static int lm73_detach_client(struct i2c_client *client); ++static int lm73_read_value(struct i2c_client *client, u8 reg); ++static int lm73_write_value(struct i2c_client *client, u8 reg, short value); ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver lm73_driver = { ++ .driver = { ++ .name = "lm73", ++ }, ++ .attach_adapter = lm73_attach_adapter, ++ .detach_client = lm73_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 i2c_client *client = to_i2c_client(dev); ++ int iTemp = 0; ++ ++ iTemp = lm73_read_value(client, LM73_REG_TEMP[attr->index]); ++ ++ return sprintf(buf, "%d\n", iTemp); ++ ++ ++} ++ ++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); ++ int nr = attr->index; ++ ++ long tmp = simple_strtol(buf, NULL, 10); ++ ++ lm73_write_value(client, LM73_REG_TEMP[nr], tmp); ++ return count; ++} ++ ++static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, ++ show_temp, set_temp, 1); ++static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, ++ show_temp, set_temp, 2); ++static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); ++ ++static int lm73_attach_adapter(struct i2c_adapter *adapter) ++{ ++ if (!(adapter->class & I2C_CLASS_HWMON)) ++ return 0; ++ ++ return i2c_probe(adapter, &addr_data, lm73_detect); ++} ++ ++static struct attribute *lm73_attributes[] = { ++ &sensor_dev_attr_temp1_input.dev_attr.attr, ++ &sensor_dev_attr_temp1_max.dev_attr.attr, ++ &sensor_dev_attr_temp1_min.dev_attr.attr, ++ ++ NULL ++}; ++ ++static const struct attribute_group lm73_group = { ++ .attrs = lm73_attributes, ++}; ++ ++/* This function is called by i2c_probe */ ++static int lm73_detect(struct i2c_adapter *adapter, int address, int kind) ++{ ++ struct i2c_client *new_client; ++ struct lm73_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; ++ ++ if (!(data = kzalloc(sizeof(struct lm73_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 = &lm73_driver; ++ new_client->flags = 0; ++ ++ name = "lm73"; ++ ++ /* 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; ++ ++ /* Register sysfs hooks */ ++ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm73_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, &lm73_group); ++exit_detach: ++ i2c_detach_client(new_client); ++exit_free: ++ kfree(data); ++exit: ++ return err; ++} ++ ++static int lm73_detach_client(struct i2c_client *client) ++{ ++ struct lm73_data *data = i2c_get_clientdata(client); ++ hwmon_device_unregister(data->hwmon_dev); ++ sysfs_remove_group(&client->dev.kobj, &lm73_group); ++ i2c_detach_client(client); ++ kfree(data); ++ return 0; ++} ++ ++static int lm73_read_value(struct i2c_client *client, u8 reg) ++{ ++ short sVal; ++ ++ if (reg == LM73_REG_CONF) ++ return i2c_smbus_read_byte_data(client, reg); ++ else ++ { ++ sVal = swab16(i2c_smbus_read_word_data(client, reg)); ++ sVal = sVal >> 7; ++ ++ if(sVal & 0xFFFF) ++ { ++ sVal = sVal - 0x1; ++ sVal = ~sVal; ++ ++ return -sVal; ++ } ++ } ++ ++} ++ ++static int lm73_write_value(struct i2c_client *client, u8 reg, short value) ++{ ++ if (reg == LM73_REG_CONF) ++ return i2c_smbus_write_byte_data(client, reg, value); ++ else ++ { ++ value = value<<7; ++ return i2c_smbus_write_word_data(client, reg, swab16(value)); ++ ++ } ++} ++ ++static int __init sensors_lm73_init(void) ++{ ++ return i2c_add_driver(&lm73_driver); ++} ++ ++static void __exit sensors_lm73_exit(void) ++{ ++ i2c_del_driver(&lm73_driver); ++} ++ ++MODULE_AUTHOR("Ligneul Guillaume "); ++MODULE_DESCRIPTION("LM73 driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sensors_lm73_init); ++module_exit(sensors_lm73_exit); +diff -Nru linux-2.6.26/drivers/hwmon/Makefile linux-2.6.26.mod/drivers/hwmon/Makefile +--- linux-2.6.26/drivers/hwmon/Makefile 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26.mod/drivers/hwmon/Makefile 2008-11-18 11:54:04.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 diff --git a/packages/linux/linux-2.6.26/boc01/008-081105-spi.patch b/packages/linux/linux-2.6.26/boc01/008-081105-spi.patch deleted file mode 100644 index 0c2ddf3383..0000000000 --- a/packages/linux/linux-2.6.26/boc01/008-081105-spi.patch +++ /dev/null @@ -1,100 +0,0 @@ -diff -Nru linux-2.6.26-officiel/arch/powerpc/platforms/83xx/mpc831x_rdb.c /home/guilig/workspace/kernel-goobie-2.6.26/src/arch/powerpc/platforms/83xx/mpc831x_rdb.c ---- linux-2.6.26-officiel/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2008-07-13 23:51:29.000000000 +0200 -+++ /home/guilig/workspace/kernel-goobie-2.6.26/src/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2008-09-26 11:51:32.000000000 +0200 -@@ -15,16 +15,95 @@ - - #include - #include -- -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - #include - #include - #include -+#include -+ - - #include "mpc83xx.h" - - /* - * Setup the architecture - */ -+struct gpio { -+ __be32 gpdir; -+ __be32 gpodr; -+ __be32 gpdat; -+ __be32 gpier; -+ __be32 gpimr; -+ __be32 gpicr; -+} __attribute__ ((packed)); -+static struct gpio *gpio_regs; -+ -+static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity) -+{ -+ //printk(KERN_INFO "%s %d %d\n", __func__, cs, polarity); -+ if (polarity) -+ setbits32(&gpio_regs->gpdat, 1 << (31 - 13)); -+ else -+ clrbits32(&gpio_regs->gpdat, 1 << (31 - 13)); -+} -+ -+static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity) -+{ -+ //printk(KERN_INFO "%s %d %d\n", __func__, cs, polarity); -+ if (polarity) -+ clrbits32(&gpio_regs->gpdat, 1 << (31 - 13)); -+ else -+ setbits32(&gpio_regs->gpdat, 1 << (31 - 13)); -+ -+} -+ -+static struct mmc_spi_platform_data mpc8313_mmc_pdata = { -+ .ocr_mask = MMC_VDD_33_34, -+}; -+ -+static struct spi_board_info mpc8313_spi_boardinfo = { -+ .bus_num = 0x7000, -+ .chip_select = 0, -+ .max_speed_hz = 50000000, -+ .modalias = "spidev", -+ .platform_data = &mpc8313_mmc_pdata, -+}; -+ -+static int __init mpc8313_spi_init(void) -+{ -+ __be32 __iomem *psicrl; -+ -+ /* System I/O Configuration Register Low */ -+ psicrl = ioremap(get_immrbase() + MPC83XX_SICRL_OFFS, 0x4); -+ gpio_regs = ioremap(get_immrbase() + 0xc00, 0x20); -+ if (!psicrl || !gpio_regs) -+ return -ENOMEM; -+ -+ clrbits32(psicrl, 0x03F00000); -+ setbits32(psicrl, 0x30000000); -+ iounmap(psicrl); -+ -+ /* set GPIO13 as output */ -+ setbits32(&gpio_regs->gpdir, 1 << (31 - 13)); -+ clrbits32(&gpio_regs->gpodr, 1 << (31 - 13)); -+ setbits32(&gpio_regs->gpdat, 1 << (31 - 13)); -+ -+ return fsl_spi_init(&mpc8313_spi_boardinfo, 1, -+ mpc83xx_spi_activate_cs, -+ mpc83xx_spi_deactivate_cs); -+} -+ -+device_initcall(mpc8313_spi_init); -+ - static void __init mpc831x_rdb_setup_arch(void) - { - #ifdef CONFIG_PCI diff --git a/packages/linux/linux-2.6.26/boc01/008-081127-spi.patch b/packages/linux/linux-2.6.26/boc01/008-081127-spi.patch new file mode 100644 index 0000000000..41777a5753 --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/008-081127-spi.patch @@ -0,0 +1,327 @@ +--- linux-2.6.26.orig/drivers/spi/spi_mpc83xx.c 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26/drivers/spi/spi_mpc83xx.c 2008-11-26 11:32:07.000000000 +0100 +@@ -27,6 +27,8 @@ + #include + #include + ++//#define DBG_SPI 1 ++ + /* SPI Controller registers */ + struct mpc83xx_spi_reg { + u8 res1[0x20]; +@@ -114,6 +116,7 @@ + + static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val) + { ++ + out_be32(reg, val); + } + +@@ -157,11 +160,17 @@ + + mpc83xx_spi = spi_master_get_devdata(spi->master); + ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_chipselect (163)\n"); ++#endif DBG_SPI ++ + if (value == BITBANG_CS_INACTIVE) { + if (mpc83xx_spi->deactivate_cs) + mpc83xx_spi->deactivate_cs(spi->chip_select, pol); + } +- ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_chipselect (171)\n"); ++#endif DBG_SPI + if (value == BITBANG_CS_ACTIVE) { + u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + +@@ -171,6 +180,9 @@ + mpc83xx_spi->get_tx = cs->get_tx; + + if (cs->hw_mode != regval) { ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_chipselect (184)\n"); ++#endif DBG_SPI + unsigned long flags; + void *tmp_ptr = &mpc83xx_spi->base->mode; + +@@ -184,6 +196,9 @@ + mpc83xx_spi_write_reg(tmp_ptr, regval); + local_irq_restore(flags); + } ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_chipselect (196)\n"); ++#endif DBG_SPI + if (mpc83xx_spi->activate_cs) + mpc83xx_spi->activate_cs(spi->chip_select, pol); + } +@@ -266,26 +281,38 @@ + + cs->hw_mode |= SPMODE_LEN(bits_per_word); + +- if ((mpc83xx_spi->spibrg / hz) >= 64) { ++ /*if ((mpc83xx_spi->spibrg / hz) >= 64) { + pm = mpc83xx_spi->spibrg / (hz * 64) - 1; +- if (pm > 0x0f) { ++ if (pm > 0x0f) {*/ ++ if ((mpc83xx_spi->spibrg / hz) > 64) { ++ cs->hw_mode |= SPMODE_DIV16; ++ pm = mpc83xx_spi->spibrg / (hz * 64); ++ if (pm > 16) { + dev_err(&spi->dev, "Requested speed is too " + "low: %d Hz. Will use %d Hz instead.\n", + hz, mpc83xx_spi->spibrg / 1024); +- pm = 0x0f; ++ pm = 16; + } +- cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16; +- } else { ++ //cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16; ++ } else + pm = mpc83xx_spi->spibrg / (hz * 4); +- if (pm) +- pm--; +- cs->hw_mode |= SPMODE_PM(pm); +- } ++ if (pm) ++ pm--; ++ cs->hw_mode = 0x0F700000; ++ mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode,cs->hw_mode); + regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup_transfer regval=%4X\n",regval); ++#endif ++ ++ ++ + if (cs->hw_mode != regval) { + unsigned long flags; + void *tmp_ptr = &mpc83xx_spi->base->mode; +- ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup_transfer cs->hw_mode=%4X\n",cs->hw_mode); ++#endif + regval = cs->hw_mode; + /* Turn off IRQs locally to minimize time + * that SPI is disabled +@@ -322,15 +349,24 @@ + /* enable rx ints */ + mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE); + ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_bufs (338)\n"); ++#endif ++ + /* transmit word */ + word = mpc83xx_spi->get_tx(mpc83xx_spi); +- mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); + ++ mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_bufs (345)\n"); ++#endif + wait_for_completion(&mpc83xx_spi->done); + + /* disable rx ints */ + mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); +- ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_bufs (352)\n"); ++#endif + return mpc83xx_spi->count; + } + +@@ -360,15 +396,22 @@ + if (t->bits_per_word || t->speed_hz) { + /* Don't allow changes if CS is active */ + status = -EINVAL; +- ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_work (366)\n"); ++#endif + if (cs_change) + status = mpc83xx_spi_setup_transfer(spi, t); + if (status < 0) + break; + } +- ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_work (374)\n"); ++#endif + if (cs_change) + mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE); ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_work (379)\n"); ++#endif + cs_change = t->cs_change; + if (t->len) + status = mpc83xx_spi_bufs(spi, t); +@@ -439,26 +482,39 @@ + cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + /* mask out bits we are going to set */ + cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH +- | SPMODE_REV | SPMODE_LOOP); +- +- if (spi->mode & SPI_CPHA) ++ | SPMODE_REV); ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup (475) cs->hw_mode=0x%4X\n",cs->hw_mode); ++#endif ++ /*if (spi->mode & SPI_CPHA) + cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK; + if (spi->mode & SPI_CPOL) + cs->hw_mode |= SPMODE_CI_INACTIVEHIGH; + if (!(spi->mode & SPI_LSB_FIRST)) +- cs->hw_mode |= SPMODE_REV; +- if (spi->mode & SPI_LOOP) +- cs->hw_mode |= SPMODE_LOOP; ++ cs->hw_mode |= SPMODE_REV;*/ ++ //if (spi->mode & SPI_LOOP) ++ // cs->hw_mode |= SPMODE_LOOP; ++cs->hw_mode = 0x0F700000; ++mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode,cs->hw_mode); ++cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); ++ + ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup (486) cs->hw_mode=0x%4X\n",cs->hw_mode); ++#endif + retval = mpc83xx_spi_setup_transfer(spi, NULL); + if (retval < 0) { ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup (491) "); ++#endif + cs->hw_mode = hw_mode; /* Restore settings */ + return retval; + } +- +- dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n", ++#ifdef DBG_SPI ++ printk(KERN_INFO "%s, mode %d, %u bits/w, %u Hz\n", + __func__, spi->mode & (SPI_CPOL | SPI_CPHA), + spi->bits_per_word, spi->max_speed_hz); ++#endif + #if 0 /* Don't think this is needed */ + /* NOTE we _need_ to call chipselect() early, ideally with adapter + * setup, unless the hardware defaults cooperate to avoid confusion +@@ -518,7 +574,9 @@ + { + struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master); + unsigned long flags; +- ++#ifdef DBG_SPI ++printk(KERN_INFO "Debut_transfert\n"); ++#endif + m->actual_length = 0; + m->status = -EINPROGRESS; + +@@ -600,10 +658,12 @@ + goto unmap_io; + } + ++printk(KERN_INFO "irq_spi : 0x%2X\n", mpc83xx_spi->irq); ++ + /* Register for SPI Interrupt */ + ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq, + 0, "mpc83xx_spi", mpc83xx_spi); +- ++printk(KERN_INFO "irq_spi : 0x%2X\n", mpc83xx_spi->irq); + if (ret != 0) + goto unmap_io; + +@@ -628,7 +688,7 @@ + INIT_LIST_HEAD(&mpc83xx_spi->queue); + + mpc83xx_spi->workqueue = create_singlethread_workqueue( +- master->dev.parent->bus_id); ++ dev->dev.bus_id); + if (mpc83xx_spi->workqueue == NULL) { + ret = -EBUSY; + goto free_irq; +--- linux-2.6.26/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26.mod/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2008-11-27 11:55:52.000000000 +0100 +@@ -15,16 +15,82 @@ + + #include + #include +- ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + #include + #include + #include ++#include ++ + + #include "mpc83xx.h" + + /* + * Setup the architecture + */ ++ ++struct gpio { ++ __be32 gpdir; ++ __be32 gpodr; ++ __be32 gpdat; ++ __be32 gpier; ++ __be32 gpimr; ++ __be32 gpicr; ++} __attribute__ ((packed)); ++static struct gpio *gpio_regs; ++ ++static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity) ++{ ++ if (polarity) ++ setbits32(&gpio_regs->gpdat, 1 << (31 - 14)); ++ else ++ clrbits32(&gpio_regs->gpdat, 1 << (31 - 14)); ++} ++ ++static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity) ++{ ++ if (polarity) ++ clrbits32(&gpio_regs->gpdat, 1 << (31 - 14) ); ++ else ++ setbits32(&gpio_regs->gpdat, 1 << (31 - 14) ); ++ ++} ++ ++static struct spi_board_info mpc8313_spi_boardinfo = { ++ .bus_num = 0x7000, ++ .chip_select = 0, ++ .max_speed_hz = 50000000, ++ .modalias = "spidev", ++}; ++ ++static int __init mpc8313_spi_init(void) ++{ ++ /* System I/O Configuration Register Low */ ++ gpio_regs = ioremap(get_immrbase() + 0xc00, 0x20); ++ if ( !gpio_regs) ++ return -ENOMEM; ++ ++ /* set GPIO14 as output */ ++ setbits32(&gpio_regs->gpdir, 1 << (31 - 14)); ++ clrbits32(&gpio_regs->gpodr, 1 << (31 - 14)); ++ setbits32(&gpio_regs->gpdat, 1 << (31 - 14)); ++ ++ return fsl_spi_init(&mpc8313_spi_boardinfo, 1, ++ mpc83xx_spi_activate_cs, ++ mpc83xx_spi_deactivate_cs); ++} ++ ++device_initcall(mpc8313_spi_init); ++ + static void __init mpc831x_rdb_setup_arch(void) + { + #ifdef CONFIG_PCI diff --git a/packages/linux/linux-2.6.26/boc01/013-081127-lcd.patch b/packages/linux/linux-2.6.26/boc01/013-081127-lcd.patch new file mode 100644 index 0000000000..258ad6f9c9 --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/013-081127-lcd.patch @@ -0,0 +1,663 @@ +diff -uNr linux-2.6.26_orig/drivers/video/Kconfig linux-2.6.26/drivers/video/Kconfig +--- linux-2.6.26_orig/drivers/video/Kconfig 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26/drivers/video/Kconfig 2008-11-27 18:54:42.000000000 +0100 +@@ -480,6 +480,17 @@ + this driver, say Y or M; otherwise say N. You must specify the + GPIO IO address to be used for setting control and data. + ++config FB_NOVA ++ tristate "Nova 7506 Monochrome LCD board support" ++ depends on FB ++ select FB_SYS_FILLRECT ++ select FB_SYS_COPYAREA ++ select FB_SYS_IMAGEBLIT ++ select FB_SYS_FOPS ++ help ++ This enables support for the Nova 7506 Monochrome LCD board. The board ++ is based on the NT7506 lcd controller. ++ + config FB_ATARI + bool "Atari native chipset support" + depends on (FB = y) && ATARI +diff -uNr linux-2.6.26_orig/drivers/video/Makefile linux-2.6.26/drivers/video/Makefile +--- linux-2.6.26_orig/drivers/video/Makefile 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26/drivers/video/Makefile 2008-11-27 18:54:57.000000000 +0100 +@@ -13,8 +13,8 @@ + + obj-$(CONFIG_VT) += console/ + obj-$(CONFIG_LOGO) += logo/ +-obj-y += backlight/ display/ +- ++obj-y += backlight/ display/ ++obj-$(CONFIG_FB_NOVA) += N7506fb.o + obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o + obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o + obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o +diff -uNr linux-2.6.26_orig/drivers/video/N7506fb.c linux-2.6.26/drivers/video/N7506fb.c +--- linux-2.6.26_orig/drivers/video/N7506fb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.26/drivers/video/N7506fb.c 2008-11-27 18:41:29.000000000 +0100 +@@ -0,0 +1,550 @@ ++/* ++ * linux/drivers/video/N7506fb.c -- FB driver for Nova NT7506 monochrome LCD board ++ * ++ * Copyright (C) 2008, Alexandre Coffignal ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file COPYING in the main directory of this archive for ++ * more details. ++ * ++ * Layout is based on arcfb.c by Jaya Kumar ++ * ++ * This driver was written to be used with the Nova 7506 LCD board. ++ * ++ * ++ * ++ * ++ * Nova uses a ++ * set of NT7506 chips that control individual 128x128 LCD matrices. ++ * The interface between the board and the host is TTL based GPIO. ++ * ++ * General notes: ++ * - User must set tuhold. It's in microseconds. According to the 108 spec, ++ * the hold time is supposed to be at least 1 microsecond. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define floor8(a) (a&(~0x07)) ++#define floorXres(a,xres) (a&(~(xres - 1))) ++#define iceil8(a) (((int)((a+7)/8))*8) ++#define ceil128(a) (a|0x7F) ++#define ceilXres(a,xres) (a|(xres - 1)) ++ ++//NT7506 Hardware ++#define LCD_RST 0x08 ++#define LCD_RSTN 0x00 ++#define LCD_BCKLIGH 0x04 ++#define LCD_BCKLIGHN 0x00 ++#define LCD_RS 0x02 ++#define LCD_RSN 0x00 ++#define LCD_ERD 0x01 ++#define LCD_ERDN 0x00 ++ ++//Base address ++#define LCD_BASE 0xf0000000 ++#define LCD_SIZE 0x2 ++ ++#define CONTRASTE 0xF ++#define FRAME_PER_SECOND 5 ++ ++static struct resource *lcd_mem = NULL; ++static void * _lcd_io = NULL; ++static unsigned long tuhold; ++struct fb_info *info; ++static struct timer_list fb_timer; ++ ++struct novafb_par { ++ atomic_t ref_count; ++ unsigned char cslut[9]; ++ struct fb_info *info; ++ unsigned int irq; ++ spinlock_t lock; ++}; ++ ++static struct fb_fix_screeninfo novafb_fix __initdata = { ++ .id = "novafb", ++ .type = FB_TYPE_PACKED_PIXELS, ++ .visual = FB_VISUAL_MONO01, ++ .xpanstep = 1, ++ .ypanstep = 1, ++ .ywrapstep = 0, ++ .line_length=16, ++ .accel = FB_ACCEL_NONE, ++}; ++ ++static struct fb_var_screeninfo novafb_var __initdata = { ++ .xres = 128, ++ .yres = 128, ++ .xres_virtual = 128, ++ .yres_virtual = 128, ++ .bits_per_pixel = 1, ++ .nonstd = 1, ++}; ++ ++ ++static void NT7506_init_lcd(char ael); ++ ++static void NT7506_writeb_ctl(unsigned char value) ++{ ++ unsigned short svalue; ++ svalue=value<<8 | LCD_RSN | LCD_RST | LCD_ERDN | LCD_BCKLIGH; ++ iowrite16(svalue, _lcd_io); ++ udelay(tuhold); ++ //The data on DB0/7 are latched at the falling edge of the E_RD signal ++ svalue=value<<8 | LCD_RSN | LCD_RST | LCD_ERD | LCD_BCKLIGH; ++ iowrite16(svalue, _lcd_io); ++ udelay(tuhold); ++} ++ ++static void NT7506_writeb_data(unsigned char value) ++{ ++ unsigned short svalue; ++ svalue=value<<8|LCD_RS |LCD_RST | LCD_ERD | LCD_BCKLIGH ; ++ iowrite16(svalue, _lcd_io); ++ udelay(tuhold); ++ //The data on DB0/7 are latched at the falling edge of the E_RD signal ++ svalue=value<<8|LCD_RS |LCD_RST | LCD_ERDN | LCD_BCKLIGH; ++ iowrite16(svalue, _lcd_io); ++ udelay(tuhold); ++} ++ ++static void NT7506_set_start_line(unsigned char y) ++{ ++ NT7506_writeb_ctl(NT_START_LINE); ++ NT7506_writeb_ctl(y); ++} ++ ++static void NT7506_set_yaddr(unsigned char y) ++{ ++ NT7506_writeb_ctl(NT_PAGE_ADDR+y); ++} ++ ++static void NT7506_set_xaddr(unsigned char x) ++{ ++ NT7506_writeb_ctl(NT_COL_MSB | (x >> 0x04) ); //Send high nibble ++ NT7506_writeb_ctl(NT_COL_LSB | (x & 0x0F) ); //Send low nibble ++} ++ ++/* main novafb functions */ ++ ++static int novafb_open(struct fb_info *info, int user) ++{ ++ struct novafb_par *par = info->par; ++ atomic_inc(&par->ref_count); ++ return 0; ++} ++ ++static int novafb_release(struct fb_info *info, int user) ++{ ++ struct novafb_par *par = info->par; ++ int count = atomic_read(&par->ref_count); ++ if (!count) ++ return -EINVAL; ++ atomic_dec(&par->ref_count); ++ return 0; ++} ++ ++static int novafb_pan_display(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ if ((var->vmode & FB_VMODE_YWRAP) && (var->yoffset < 128) ++ && (info->var.yres <= 128)) ++ { ++ NT7506_set_start_line(var->yoffset); ++ info->var.yoffset = var->yoffset; ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++static void novafb_lcd_update(struct novafb_par *par, unsigned int dx, ++ unsigned int dy, unsigned int w, unsigned int h) ++{ ++ int bit,x,y,xfb,yfb,width,height,i; ++ char mask=0; ++ char dest[2048]; ++ char * src; ++ char value; ++ src = (unsigned char __force *) par->info->screen_base; ++ for(i=0;i<2048;i++) ++ { ++ dest[i]=0; ++ } ++ for(x=0;x<128/*(width)*/;x++) ++ { ++ for(y=0;y<16/*height/8*/;y++) ++ { ++ xfb=x/8; ++ yfb=y*8; ++ ++ for(bit=0;bit<8;yfb++,bit++) ++ { ++ mask = (1<<(7-(x%8))); ++ if(((src[yfb*16+xfb]&mask))) ++ value=1; ++ else ++ value=0; ++ ++ dest[y*128+x]+= (value<par; ++ ++ int xfb,yfb,i=0; ++ char * src = (unsigned char __force *) par->info->screen_base; ++ ++ for(yfb=image->dy;yfb<(image->height+image->dy);yfb++) ++ { ++ for(xfb=(image->dx)/8;xfb<(image->dx+image->width)/8;xfb++) ++ { ++ src[yfb*16+xfb]=image->data[i++]; ++ } ++ } ++ ++} ++ ++/* ++ * this is the access path from userspace. they can seek and write to ++ * the fb. it's inefficient for them to do anything less than 128*8 ++ * writes since we update the lcd in each write() anyway. ++ */ ++static ssize_t novafb_write(struct fb_info *info, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ unsigned long p; ++ int err=-EINVAL; ++ unsigned int fbmemlength ; ++ struct novafb_par *par; ++ unsigned int xres; ++ p = *ppos; ++ par = info->par; ++ xres = info->var.xres; ++ fbmemlength = (xres * info->var.yres)/8; ++ ++ if (p > fbmemlength) ++ { ++ return -ENOSPC; ++ } ++ err = 0; ++ if ((count + p) > fbmemlength) { ++ count = fbmemlength - p; ++ err = -ENOSPC; ++ } ++ ++ if (count) { ++ char *base_addr; ++ base_addr = (char __force *)info->screen_base; ++ count -= copy_from_user(base_addr + p, buf, count); ++ *ppos += count; ++ err = -EFAULT; ++ } ++ if (count) ++ { ++ return count; ++ } ++ return err; ++} ++ ++static int novafb_mmap(struct fb_info *info, struct vm_area_struct *vma) ++{ ++ unsigned long off; ++ unsigned long start; ++ u32 len; ++ ++ if (vma->vm_end - vma->vm_start == 0) ++ return 0; ++ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) ++ return -EINVAL; ++ off = vma->vm_pgoff << PAGE_SHIFT; ++ start = info->fix.smem_start; ++ len = info->fix.smem_len; ++ if (off >= len) ++ { ++ return -EINVAL; ++ ++ } ++ if ((vma->vm_end - vma->vm_start + off) > len) ++ { ++ return -EINVAL; ++ } ++ off += start; ++ vma->vm_pgoff = off >> PAGE_SHIFT; ++ if (remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)info->fix.smem_start) >> PAGE_SHIFT, ++ info->fix.smem_len, vma->vm_page_prot)) ++ ++ { ++ return -EAGAIN; ++ } ++ return 0; ++ ++} ++ ++static struct fb_ops novafb_ops = { ++ .owner = THIS_MODULE, ++ .fb_open = novafb_open, ++ .fb_read = fb_sys_read, ++ .fb_write = novafb_write, ++ .fb_release = novafb_release, ++ .fb_pan_display = novafb_pan_display, ++ .fb_fillrect = novafb_fillrect, ++ .fb_copyarea = novafb_copyarea, ++ .fb_imageblit = novafb_imageblit, ++// .fb_ioctl = novafb_ioctl, ++ .fb_mmap =novafb_mmap, ++}; ++ ++ ++static void ++novafb_refresh(int ignore_me ) ++{ ++ struct novafb_par *par = info->par; ++ novafb_lcd_update(par, 0, 0, 128,128); ++ fb_timer.expires = jiffies + (HZ/FRAME_PER_SECOND); ++ add_timer(&fb_timer); ++} ++ ++static int ++__init novafb_probe(struct platform_device *dev) ++{ ++ ++ int retval = -ENOMEM; ++ char * src; ++ int i; ++ ++ struct novafb_par *par; ++ static unsigned char *videomemory; ++ static int videomemorysize; ++ ++ NT7506_init_lcd(CONTRASTE); ++ ++ videomemorysize = (128*128/8)*2; ++ ++ if (!(videomemory = kmalloc(videomemorysize,GFP_ATOMIC))) ++ return retval; ++ memset(videomemory, 0, videomemorysize); ++ ++ info = framebuffer_alloc(sizeof(struct novafb_par), &dev->dev); ++ ++ if (!info) ++ goto err; ++ info->screen_base = (char __iomem *)videomemory; ++ info->fbops = &novafb_ops; ++ ++ info->var = novafb_var; ++ info->fix = novafb_fix; ++ info->fix.smem_start=(unsigned long)videomemory; ++ info->fix.smem_len = videomemorysize; ++ ++ par = info->par; ++ par->info = info; ++ par->cslut[0] = 0x00; ++ par->cslut[1] = 0x06; ++ src = (unsigned char __force *) par->info->screen_base; ++ for(i=0;iflags = FBINFO_FLAG_DEFAULT; ++ spin_lock_init(&par->lock); ++ platform_set_drvdata(dev, info); ++ retval = register_framebuffer(info); ++ if (retval < 0) ++ goto err1; ++ ++ init_timer(&fb_timer); ++ fb_timer.function = novafb_refresh; ++ fb_timer.expires = jiffies + (HZ / FRAME_PER_SECOND); ++ add_timer(&fb_timer); ++ ++ printk(KERN_INFO ++ "fb%d: nova frame buffer device, using %dK of video memory\n", ++ info->node, videomemorysize >> 10); ++ return 0; ++err1: ++ framebuffer_release(info); ++err: ++ vfree(videomemory); ++ return retval; ++} ++ ++static int novafb_remove(struct platform_device *dev) ++{ ++ struct fb_info *info = platform_get_drvdata(dev); ++ ++ if (info) { ++ unregister_framebuffer(info); ++ vfree((void __force *)info->screen_base); ++ framebuffer_release(info); ++ } ++ return 0; ++} ++ ++static struct platform_driver novafb_driver = { ++ .probe = novafb_probe, ++ .remove = novafb_remove, ++ .driver = { ++ .name = "novafb", ++ }, ++}; ++ ++static struct platform_device *novafb_device; ++ ++static int __init novafb_init(void) ++{ ++ int ret; ++ ++ ++ if (!(lcd_mem = request_mem_region(LCD_BASE, LCD_SIZE, "mpc8313-lcd"))) ++ return -ENOMEM; ++ ++ if (!(_lcd_io = ioremap(LCD_BASE, LCD_SIZE))) ++ { ++ release_mem_region(LCD_BASE, LCD_SIZE); ++ lcd_mem = NULL; ++ return -ENOMEM; ++ } ++ ret = platform_driver_register(&novafb_driver); ++ ++ if (!ret) { ++ novafb_device = platform_device_alloc("novafb", 0); ++ if (novafb_device) ++ { ++ ret = platform_device_add(novafb_device); ++ } ++ else ++ { ++ ret = -ENOMEM; ++ } ++ if (ret) ++ { ++ platform_device_put(novafb_device); ++ platform_driver_unregister(&novafb_driver); ++ } ++ ++ } ++ ++ ++ return ret; ++ ++} ++ ++ ++static void NT7506_init_lcd(char ael) ++{ ++ /* this resets the lcd*/ ++ iowrite16(LCD_RSTN | LCD_ERD | LCD_BCKLIGH, _lcd_io); ++ udelay(100); ++ iowrite16(LCD_RST| LCD_ERD | LCD_BCKLIGH, _lcd_io); ++ udelay(200); ++ /* Soft reset*/ ++ NT7506_writeb_ctl(NT_RESET); ++ /* Disable ICON display*/ ++ NT7506_writeb_ctl(NT_ICON|OFF); ++ /* Sets the duty ratio 1/128*/ ++ NT7506_writeb_ctl(NT_DUTY); NT7506_writeb_ctl(DUTY_1_128); ++ /* Sets reverse direction between RAM column address and segment driver*/ ++ NT7506_writeb_ctl(NT_ADC_REV); ++ NT7506_writeb_ctl(NT_SHL_NOR); ++ /* Enales the built in Oscillator circuit.*/ ++ NT7506_writeb_ctl(NT_OSC); ++ /* Set Initial row to 0*/ ++ NT7506_writeb_ctl(NT_COM0); NT7506_writeb_ctl(0); ++ /* Sets DC-DC*/ ++ NT7506_writeb_ctl(NT_DCDC|TIME6); ++ /* Selects resistance ratio of the internal resistor*/ ++ NT7506_writeb_ctl(NT_REG_RES|RES_7_2); ++ /* set Reference Voltage mode*/ ++ NT7506_writeb_ctl(NT_ELEC_VOL); NT7506_writeb_ctl(ael); ++ /* Selects LCD bias ratio*/ ++ NT7506_writeb_ctl(NT_BIAS|BIAS_1_11); ++ ++ NT7506_writeb_ctl(NT_DATA_DIR); NT7506_writeb_ctl(0); ++ NT7506_writeb_ctl(NT_FRC_PWM|PWM15); ++ /* Select power circuit functions */ ++ NT7506_writeb_ctl(NT_POWER|VC); ++ udelay(5000); ++ NT7506_writeb_ctl(NT_POWER|VC|VR); ++ udelay(5000); ++ NT7506_writeb_ctl(NT_POWER|VC|VR|VF); ++ udelay(5000); ++ /* Reverses the display status on LCD panel */ ++ NT7506_writeb_ctl(NT_REV_DISP|OFF); ++ /* Forces the whole LCD points to be turned on regardless of the contents of the display data RAM*/ ++ NT7506_writeb_ctl(NT_DISP|ON); ++ /* Set Initial Start Line Address */ ++ NT7506_writeb_ctl(NT_START_LINE); NT7506_writeb_ctl(0x00); ++ ++} ++ ++static void __exit novafb_exit(void) ++{ ++ if (lcd_mem) ++ release_mem_region(LCD_BASE, LCD_SIZE); ++ lcd_mem = NULL; ++ platform_device_unregister(novafb_device); ++ platform_driver_unregister(&novafb_driver); ++} ++ ++module_param(tuhold, ulong, 0); ++MODULE_PARM_DESC(tuhold, "Time to hold between strobing data to Nova board"); ++ ++module_init(novafb_init); ++module_exit(novafb_exit); ++ ++MODULE_DESCRIPTION("fbdev driver for nova NT7506 monochrome LCD board"); ++MODULE_AUTHOR("Alexandre Coffignal"); ++MODULE_LICENSE("GPL"); ++ +diff -uNr linux-2.6.26_orig/include/linux/NT7506.h linux-2.6.26/include/linux/NT7506.h +--- linux-2.6.26_orig/include/linux/NT7506.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.26/include/linux/NT7506.h 2008-11-13 12:46:05.000000000 +0100 +@@ -0,0 +1,70 @@ ++ ++/* ++ * (C) Copyright 2008 ++ * Alexandre Coffignal, CĂ©noSYS, alexandre.coffignal@cenosys.com ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ * ++ */ ++ ++#ifndef __LINUX_NOVAFB_H__ ++#define __LINUX_NOVAFB_H__ ++ ++ ++//NT7506 Instructions ++#define NT_ICON 0xA2 ++#define NT_PAGE_ADDR 0xB0 ++#define NT_COL_MSB 0x10 ++#define NT_COL_LSB 0x00 ++#define NT_DISP 0xAE ++#define NT_START_LINE 0x40 ++#define NT_COM0 0x44 ++#define NT_DUTY 0x48 ++#define DUTY_1_128 0x80 ++#define NT_REV_DISP 0xA6 ++#define NT_POWER 0x28 ++#define VC 0x04 ++#define VR 0x02 ++#define VF 0x01 ++#define NT_DCDC 0x64 ++#define TIME6 0x03 ++#define NT_REG_RES 0x20 ++#define RES_7_2 0x07 ++#define NT_ELEC_VOL 0x81 ++#define NT_BIAS 0x50 ++#define BIAS_1_11 0x06 ++#define NT_ADC_NOR 0xA0 ++#define NT_ADC_REV 0xA1 ++#define NT_SHL_NOR 0xC0 ++#define NT_SHL_REV 0xC8 ++#define NT_OSC 0xAB ++#define NT_RESET 0xE2 ++#define NT_DATA_DIR 0xe8 ++#define NT_FRC_PWM 0x90 ++#define PWM15 0x03 ++ ++#define ON 0x01 ++#define OFF 0x00 ++ ++ ++ ++ ++ ++#endif ++ diff --git a/packages/linux/linux-2.6.26/boc01/boc01.dts b/packages/linux/linux-2.6.26/boc01/boc01.dts index 725a11505f..dc66cb67bc 100644 --- a/packages/linux/linux-2.6.26/boc01/boc01.dts +++ b/packages/linux/linux-2.6.26/boc01/boc01.dts @@ -137,8 +137,7 @@ spi@7000 { device_type = "spi"; cell-index = <0>; - //compatible = "fsl,spi"; - compatible = "mpc83xx_spi"; + compatible = "fsl,spi"; reg = <0x7000 0x1000>; interrupts = <16 0x8>; interrupt-parent = <&ipic>; diff --git a/packages/linux/linux-2.6.26/boc01/defconfig b/packages/linux/linux-2.6.26/boc01/defconfig index 42f33dbb78..6e99b8e1ff 100644 --- a/packages/linux/linux-2.6.26/boc01/defconfig +++ b/packages/linux/linux-2.6.26/boc01/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.26 -# Fri Nov 21 11:33:35 2008 +# Fri Nov 28 10:11:36 2008 # # CONFIG_PPC64 is not set @@ -841,6 +841,7 @@ CONFIG_MARVELL_PHY=y CONFIG_FIXED_PHY=y # CONFIG_MDIO_BITBANG is not set # CONFIG_NET_ETHERNET is not set +CONFIG_MII=y CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set @@ -907,16 +908,22 @@ CONFIG_HOSTAP_PCI=m # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set -CONFIG_USB_USBNET=m +CONFIG_USB_USBNET=y # CONFIG_USB_NET_AX8817X is not set -CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDCETHER=y # CONFIG_USB_NET_DM9601 is not set # CONFIG_USB_NET_GL620A is not set # CONFIG_USB_NET_NET1080 is not set # CONFIG_USB_NET_PLUSB is not set # CONFIG_USB_NET_MCS7830 is not set # CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_CDC_SUBSET is not set +CONFIG_USB_NET_CDC_SUBSET=y +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +CONFIG_USB_BELKIN=y +# CONFIG_USB_ARMLINUX is not set +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_KC2190 is not set # CONFIG_USB_NET_ZAURUS is not set # CONFIG_WAN is not set CONFIG_ATM_DRIVERS=y @@ -996,7 +1003,10 @@ CONFIG_INPUT_CAPSENSE_BTNS=y # # Character devices # -# CONFIG_VT is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -1006,7 +1016,7 @@ CONFIG_DEVKMEM=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y +# CONFIG_SERIAL_8250_PCI is not set CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -1218,11 +1228,11 @@ CONFIG_FB=y # CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_IMAGEBLIT is not set # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_SYS_FOPS=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -1235,6 +1245,7 @@ CONFIG_FB=y # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +CONFIG_FB_NOVA=y # CONFIG_FB_OF is not set # CONFIG_FB_CT65550 is not set # CONFIG_FB_ASILIANT is not set @@ -1267,6 +1278,19 @@ CONFIG_FB=y # Display device support # # CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y # CONFIG_LOGO is not set # @@ -1512,25 +1536,7 @@ CONFIG_USB_MON=y # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_ATM is not set # CONFIG_USB_GADGET is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set - -# -# MMC/SD Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_BOUNCE=y -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_WBSD is not set -# CONFIG_MMC_TIFM_SD is not set -# CONFIG_MMC_SPI is not set +# CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1723,8 +1729,8 @@ CONFIG_LDM_PARTITION=y # CONFIG_EFI_PARTITION is not set # CONFIG_SYSV68_PARTITION is not set CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_DEFAULT="iso8859-15" +CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -1748,7 +1754,7 @@ CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -1758,7 +1764,7 @@ CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_9 is not set # CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set -CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_ISO8859_15=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=m @@ -1771,9 +1777,9 @@ CONFIG_BITREVERSE=y # CONFIG_GENERIC_FIND_FIRST_BIT is not set CONFIG_CRC_CCITT=m CONFIG_CRC16=m -CONFIG_CRC_ITU_T=m +CONFIG_CRC_ITU_T=y CONFIG_CRC32=y -CONFIG_CRC7=m +CONFIG_CRC7=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/packages/linux/linux_2.6.26.bb b/packages/linux/linux_2.6.26.bb index 405655ba05..bb4df19c3a 100644 --- a/packages/linux/linux_2.6.26.bb +++ b/packages/linux/linux_2.6.26.bb @@ -1,6 +1,6 @@ require linux.inc -PR = "r2" +PR = "r3" # Mark archs/machines that this kernel supports DEFAULT_PREFERENCE = "-1" @@ -17,13 +17,14 @@ SRC_URI_append_boc01 = "\ file://fsl-elbc-nand-backport.patch;patch=1 \ file://002-081105-headers.patch;patch=1 \ file://004-081105-usb.patch;patch=1 \ - file://005-081105-isl12024.patch;patch=1 \ + file://005-081127-isl12024.patch;patch=1 \ file://006-081105-at24c32.patch;patch=1 \ - file://007-081105-lm73.patch;patch=1 \ - file://008-081105-spi.patch;patch=1 \ + file://007-081127-lm73.patch;patch=1 \ + file://008-081127-spi.patch;patch=1 \ file://010-081105-mii.patch;patch=1 \ file://011-081105-gpio.patch;patch=1 \ file://012-081121-cy3218-btns.patch;patch=1 \ + file://013-081127-lcd.patch;patch=1 \ " SRC_URI_append_mpc8313e-rdb = "\ -- cgit v1.2.3