summaryrefslogtreecommitdiff
path: root/recipes
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2009-10-19 17:46:01 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2009-10-19 17:46:01 +0200
commit83396675e812ff3022426c0065fb9d8b52b4d35e (patch)
tree1712c6270955311e6ca5fd90259193ee08a659fb /recipes
parent47e3f7bc0ec31948832e410f2a4cc201c81e04a2 (diff)
linux-2.6.31: initial port of boc01 patches
Diffstat (limited to 'recipes')
-rw-r--r--recipes/linux/linux-2.6.31/boc01/004-081205-usb.patch16
-rw-r--r--recipes/linux/linux-2.6.31/boc01/005-091008-isl12024.patch512
-rw-r--r--recipes/linux/linux-2.6.31/boc01/007-091005-lm73.patch242
-rw-r--r--recipes/linux/linux-2.6.31/boc01/008-091005-spi.patch226
-rw-r--r--recipes/linux/linux-2.6.31/boc01/011-090115-gpio.patch440
-rw-r--r--recipes/linux/linux-2.6.31/boc01/012-091019-capsense.patch858
-rw-r--r--recipes/linux/linux-2.6.31/boc01/013-091015-lcd.patch1070
-rw-r--r--recipes/linux/linux-2.6.31/boc01/boc01.dts348
-rw-r--r--recipes/linux/linux-2.6.31/boc01/boc01.dts.v1348
-rw-r--r--recipes/linux/linux-2.6.31/boc01/defconfig2038
-rw-r--r--recipes/linux/linux_2.6.31.bb26
11 files changed, 6124 insertions, 0 deletions
diff --git a/recipes/linux/linux-2.6.31/boc01/004-081205-usb.patch b/recipes/linux/linux-2.6.31/boc01/004-081205-usb.patch
new file mode 100644
index 0000000000..dc7eba64d0
--- /dev/null
+++ b/recipes/linux/linux-2.6.31/boc01/004-081205-usb.patch
@@ -0,0 +1,16 @@
+--- linux-2.6.27.orig/arch/powerpc/platforms/83xx/usb.c 2008-12-05 14:50:43.000000000 +0100
++++ linux-2.6.27.modif/arch/powerpc/platforms/83xx/usb.c 2008-12-05 14:51:17.000000000 +0100
+@@ -172,10 +172,10 @@
+ !strcmp(prop, "utmi"))) {
+ u32 refsel;
+
+- if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
++// if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
+ refsel = CONTROL_REFSEL_24MHZ;
+- else
+- refsel = CONTROL_REFSEL_48MHZ;
++// else
++// refsel = CONTROL_REFSEL_48MHZ;
+ /* Set UTMI_PHY_EN and REFSEL */
+ out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,
+ CONTROL_UTMI_PHY_EN | refsel);
diff --git a/recipes/linux/linux-2.6.31/boc01/005-091008-isl12024.patch b/recipes/linux/linux-2.6.31/boc01/005-091008-isl12024.patch
new file mode 100644
index 0000000000..401ce4d9c8
--- /dev/null
+++ b/recipes/linux/linux-2.6.31/boc01/005-091008-isl12024.patch
@@ -0,0 +1,512 @@
+Index: linux-2.6.31/drivers/misc/eeprom/at24.c
+===================================================================
+--- linux-2.6.31.orig/drivers/misc/eeprom/at24.c 2009-10-19 16:55:01.000000000 +0200
++++ linux-2.6.31/drivers/misc/eeprom/at24.c 2009-10-19 16:55:05.000000000 +0200
+@@ -115,6 +115,8 @@
+ { "spd", AT24_DEVICE_MAGIC(2048 / 8,
+ AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },
+ { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },
++ /* Intersil RTC/Unique-ID isl12024 eeprom handled here */
++ { "isl12024-eeprom", AT24_DEVICE_MAGIC(4096 / 8, AT24_FLAG_ADDR16) },
+ /* 24rf08 quirk is handled at i2c-core */
+ { "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },
+ { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
+Index: linux-2.6.31/drivers/rtc/Kconfig
+===================================================================
+--- linux-2.6.31.orig/drivers/rtc/Kconfig 2009-10-19 16:55:01.000000000 +0200
++++ linux-2.6.31/drivers/rtc/Kconfig 2009-10-19 16:55:05.000000000 +0200
+@@ -128,6 +128,12 @@
+
+ if I2C
+
++config RTC_DRV_ISL12024
++ tristate "Intersil 12024 RTC/Unique-ID"
++ 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, EPSON RX-8025"
+ help
+Index: linux-2.6.31/drivers/rtc/Makefile
+===================================================================
+--- linux-2.6.31.orig/drivers/rtc/Makefile 2009-10-19 16:55:01.000000000 +0200
++++ linux-2.6.31/drivers/rtc/Makefile 2009-10-19 16:55:05.000000000 +0200
+@@ -40,6 +40,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_M41T94) += rtc-m41t94.o
+ obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o
+Index: linux-2.6.31/drivers/rtc/rtc-isl12024.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.31/drivers/rtc/rtc-isl12024.c 2009-10-19 16:57:37.000000000 +0200
+@@ -0,0 +1,465 @@
++/*
++ * Intersil ISL12024 class driver
++ *
++ *
++ * Copyright (C) 2007, CenoSYS (www.cenosys.com).
++ *
++ * Guillaume Ligneul <guillaume.ligneul@gmail.com>
++ * Sylvain Giroudon <sylvain.giroudon@goobie.fr>
++ * Jeremy Laine <jeremy.laine@bolloretelecom.eu>
++ *
++ * This software program is licensed subject to the GNU General Public License
++ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
++ */
++
++#include <linux/module.h>
++#include <linux/i2c.h>
++#include <linux/bcd.h>
++#include <linux/rtc.h>
++#include <linux/delay.h>
++
++#define DRV_VERSION "0.3"
++
++#define ISL12024_CCR_BASE 0x30 /* Base address of CCR */
++#define ISL12024_ALM0_BASE 0x00 /* Base address of ALARM0 */
++#define ISL12024_INT_AL0E 0x20 /* Alarm 0 enable */
++
++/* Register map */
++
++/* device id section */
++#define ISL12024_REG_ID 0x20
++
++/* rtc section */
++#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_SC 0x30
++#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
++
++static int isl12024_get_status(struct i2c_client *client, unsigned char *sr);
++static int isl12024_fix_osc(struct i2c_client *client);
++
++static struct i2c_driver isl12024_driver;
++
++static 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;
++}
++
++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, };
++
++ if (isl12024_get_status(client, &sr) < 0) {
++ dev_err(&client->dev, "reading SR failed\n");
++ return -EIO;
++ }
++
++ err = isl12024_i2c_read_regs(client, ISL12024_REG_SC, regs, ISL12024_RTC_SECTION_LEN);
++
++ if (err < 0) {
++ dev_err(&client->dev, "reading RTC section failed\n");
++ return err;
++ }
++
++ 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_REG_SR_WEL };
++
++ static const unsigned char rwel[3] = { 0, ISL12024_REG_SR,
++ ISL12024_REG_SR_WEL | ISL12024_REG_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_REG_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 )
++ dev_err(&client->dev, "unable to restart the oscillator (%d)\n", err);
++
++ 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 ssize_t isl12024_show_id(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ int err;
++ int len = 0;
++ int i;
++ u8 id_buffer[ISL12024_RTC_SECTION_LEN];
++
++ /* Read unique id from eeprom */
++ err = isl12024_i2c_read_regs(client, ISL12024_REG_ID, id_buffer, sizeof(id_buffer));
++ if (err < 0) {
++ dev_err(&client->dev, "reading RTC section failed\n");
++ return err;
++ }
++
++ /* Print hexadecimal */
++ for (i = 0; i < sizeof(id_buffer); i++)
++ len += sprintf(buf + len, "%02X", id_buffer[i]);
++ len += sprintf(buf + len, "\n");
++ return len;
++}
++
++static DEVICE_ATTR(id, S_IRUGO, isl12024_show_id, NULL);
++
++static int
++isl12024_probe(struct i2c_client *client, const struct i2c_device_id *id)
++{
++ int rc = 0;
++ unsigned char sr;
++ struct rtc_device *rtc = NULL;
++
++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
++ return -ENODEV;
++
++ if (isl12024_i2c_validate_client(client) < 0)
++ return -ENODEV;
++
++ dev_info(&client->dev,
++ "chip found, driver version " DRV_VERSION "\n");
++
++ rtc = rtc_device_register(isl12024_driver.driver.name,
++ &client->dev, &isl12024_rtc_ops,
++ THIS_MODULE);
++
++ if (IS_ERR(rtc))
++ return PTR_ERR(rtc);
++
++ i2c_set_clientdata(client, rtc);
++
++ rc = isl12024_get_status(client, &sr);
++ if (rc < 0) {
++ dev_err(&client->dev, "reading status failed\n");
++ goto exit_unregister;
++ }
++
++ /* Check for power failures and enable the osc */
++ if (sr & ISL12024_REG_SR_RTCF) {
++ dev_warn(&client->dev, "rtc power failure detected, "
++ "please set clock.\n");
++ udelay(50);
++ isl12024_fix_osc(client);
++ }
++
++ /* Register sysfs hooks */
++ rc = device_create_file(&client->dev, &dev_attr_id);
++ if (rc < 0)
++ goto exit_unregister;
++
++ return 0;
++
++exit_unregister:
++ rtc_device_unregister(rtc);
++
++ return rc;
++}
++
++static int
++isl12024_remove(struct i2c_client *client)
++{
++ struct rtc_device *rtc = i2c_get_clientdata(client);
++
++ rtc_device_unregister(rtc);
++ device_remove_file(&client->dev, &dev_attr_id);
++
++ return 0;
++}
++
++static const struct i2c_device_id isl12024_id[] = {
++ { "isl12024", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, isl12024_id);
++
++static struct i2c_driver isl12024_driver = {
++ .driver = {
++ .name = "rtc-isl12024",
++ },
++ .probe = isl12024_probe,
++ .remove = isl12024_remove,
++ .id_table = isl12024_id,
++};
++
++/* module init/exit */
++
++static int __init isl12024_init(void)
++{
++ return i2c_add_driver(&isl12024_driver);
++}
++
++static void __exit isl12024_exit(void)
++{
++ i2c_del_driver(&isl12024_driver);
++}
++
++MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@cenosys.com>");
++MODULE_DESCRIPTION("Intersil ISL12024 driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
++
++module_init(isl12024_init);
++module_exit(isl12024_exit);
diff --git a/recipes/linux/linux-2.6.31/boc01/007-091005-lm73.patch b/recipes/linux/linux-2.6.31/boc01/007-091005-lm73.patch
new file mode 100644
index 0000000000..bc43a0a70a
--- /dev/null
+++ b/recipes/linux/linux-2.6.31/boc01/007-091005-lm73.patch
@@ -0,0 +1,242 @@
+Index: linux-2.6.29/drivers/hwmon/Kconfig
+===================================================================
+--- linux-2.6.29.orig/drivers/hwmon/Kconfig 2009-10-05 18:27:57.000000000 +0200
++++ linux-2.6.29/drivers/hwmon/Kconfig 2009-10-05 18:28:35.000000000 +0200
+@@ -448,6 +448,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
+Index: linux-2.6.29/drivers/hwmon/lm73.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.29/drivers/hwmon/lm73.c 2009-10-05 18:28:49.000000000 +0200
+@@ -0,0 +1,205 @@
++/*
++ * LM73 Sensor driver
++ * Based on LM75
++ *
++ * Copyright (C) 2007, CenoSYS (www.cenosys.com).
++ * Copyright (C) 2009, Bollore telecom (www.bolloretelecom.eu).
++ *
++ * Guillaume Ligneul <guillaume.ligneul@cenosys.com>
++ * Adrien Demarez <adrien.demarez@bolloretelecom.eu>
++ * Jeremy Laine <jeremy.laine@bolloretelecom.eu>
++ *
++ * This software program is licensed subject to the GNU General Public License
++ * (GPL).Version 2,June 1991, available at
++ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/err.h>
++
++
++/* Addresses scanned */
++static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c,
++ 0x4d, 0x4e, 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_MAX 0x02
++#define LM73_REG_MIN 0x03
++#define LM73_REG_CTRL 0x04
++#define LM73_REG_ID 0x07
++
++#define LM73_ID 0x9001 /* or 0x190 after a swab16() */
++#define DRVNAME "lm73"
++#define LM73_TEMP_MIN (-40)
++#define LM73_TEMP_MAX 150
++
++/*-----------------------------------------------------------------------*/
++
++
++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);
++ long temp;
++ short value;
++
++ int status = strict_strtol(buf, 10, &temp);
++ if(status < 0)
++ return status;
++
++ /* Write value */
++ value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4),
++ (LM73_TEMP_MAX*4)) << 5;
++ i2c_smbus_write_word_data(client, attr->index, swab16(value));
++ return count;
++}
++
++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);
++ /* use integer division instead of equivalent right shift to
++ guarantee arithmetic shift and preserve the sign */
++ int temp = ((s16) (swab16(i2c_smbus_read_word_data(client,
++ attr->index)))*250) / 32;
++ return sprintf(buf, "%d\n", temp);
++}
++
++
++/*-----------------------------------------------------------------------*/
++
++/* sysfs attributes for hwmon */
++
++static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
++ show_temp, set_temp, LM73_REG_MAX);
++static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
++ show_temp, set_temp, LM73_REG_MIN);
++static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
++ show_temp, NULL, LM73_REG_INPUT);
++
++
++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,
++};
++
++/*-----------------------------------------------------------------------*/
++
++/* device probe and removal */
++
++static int
++lm73_probe(struct i2c_client *client, const struct i2c_device_id *id)
++{
++ struct device *hwmon_dev;
++ int status;
++
++ /* Register sysfs hooks */
++ status = sysfs_create_group(&client->dev.kobj, &lm73_group);
++ if (status)
++ return status;
++
++ hwmon_dev = hwmon_device_register(&client->dev);
++ if (IS_ERR(hwmon_dev)) {
++ status = PTR_ERR(hwmon_dev);
++ goto exit_remove;
++ }
++ i2c_set_clientdata(client, hwmon_dev);
++
++ dev_info(&client->dev, "%s: sensor '%s'\n",
++ dev_name(hwmon_dev), client->name);
++
++ return 0;
++
++exit_remove:
++ sysfs_remove_group(&client->dev.kobj, &lm73_group);
++ return status;
++}
++
++static int lm73_remove(struct i2c_client *client)
++{
++ struct device *hwmon_dev = i2c_get_clientdata(client);
++
++ hwmon_device_unregister(hwmon_dev);
++ sysfs_remove_group(&client->dev.kobj, &lm73_group);
++ i2c_set_clientdata(client, NULL);
++ return 0;
++}
++
++static const struct i2c_device_id lm73_ids[] = {
++ { "lm73", lm73 },
++ { /* LIST END */ }
++};
++MODULE_DEVICE_TABLE(i2c, lm73_ids);
++
++/* Return 0 if detection is successful, -ENODEV otherwise */
++static int lm73_detect(struct i2c_client *new_client, int kind,
++ struct i2c_board_info *info)
++{
++ struct i2c_adapter *adapter = new_client->adapter;
++ u16 id;
++ u8 ctrl;
++
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
++ I2C_FUNC_SMBUS_WORD_DATA))
++ return -ENODEV;
++
++ /* Check device ID */
++ id = i2c_smbus_read_word_data(new_client, LM73_REG_ID);
++ ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL);
++ if ((id != LM73_ID) || (ctrl & 0x10))
++ return -ENODEV;
++
++ strlcpy(info->type, "lm73", I2C_NAME_SIZE);
++
++ return 0;
++}
++
++static struct i2c_driver lm73_driver = {
++ .class = I2C_CLASS_HWMON,
++ .driver = {
++ .name = "lm73",
++ },
++ .probe = lm73_probe,
++ .remove = lm73_remove,
++ .id_table = lm73_ids,
++ .detect = lm73_detect,
++ .address_data = &addr_data,
++};
++
++/* module glue */
++
++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("Guillaume Ligneul <guillaume.ligneul@cenosys.com>");
++MODULE_DESCRIPTION("LM73 driver");
++MODULE_LICENSE("GPL");
++
++module_init(sensors_lm73_init);
++module_exit(sensors_lm73_exit);
+Index: linux-2.6.29/drivers/hwmon/Makefile
+===================================================================
+--- linux-2.6.29.orig/drivers/hwmon/Makefile 2009-10-05 18:27:57.000000000 +0200
++++ linux-2.6.29/drivers/hwmon/Makefile 2009-10-05 18:28:35.000000000 +0200
+@@ -54,6 +54,7 @@
+ obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.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/recipes/linux/linux-2.6.31/boc01/008-091005-spi.patch b/recipes/linux/linux-2.6.31/boc01/008-091005-spi.patch
new file mode 100644
index 0000000000..ea775a8b73
--- /dev/null
+++ b/recipes/linux/linux-2.6.31/boc01/008-091005-spi.patch
@@ -0,0 +1,226 @@
+Index: linux-2.6.31/arch/powerpc/platforms/83xx/mpc831x_rdb.c
+===================================================================
+--- linux-2.6.31.orig/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2009-10-19 16:32:13.000000000 +0200
++++ linux-2.6.31/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2009-10-19 16:48:50.000000000 +0200
+@@ -14,18 +14,175 @@
+ */
+
+ #include <linux/pci.h>
++#include <linux/interrupt.h>
+ #include <linux/of_platform.h>
++#include <linux/spi/spi.h>
++#include <linux/fsl_devices.h>
+
+ #include <asm/time.h>
+ #include <asm/ipic.h>
+ #include <asm/udbg.h>
++#include <asm/qe.h>
+ #include <sysdev/fsl_pci.h>
++#include <sysdev/fsl_soc.h>
+
+ #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 int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
++ struct spi_board_info *board_infos,
++ unsigned int num_board_infos,
++ void (*cs_control)(struct spi_device *dev,
++ bool on))
++{
++ struct device_node *np;
++ unsigned int i = 0;
++
++ for_each_compatible_node(np, type, compatible) {
++ int ret;
++ unsigned int j;
++ const void *prop;
++ struct resource res[2];
++ struct platform_device *pdev;
++ struct fsl_spi_platform_data pdata = {
++ .cs_control = cs_control,
++ };
++
++ memset(res, 0, sizeof(res));
++
++ pdata.sysclk = sysclk;
++
++ prop = of_get_property(np, "reg", NULL);
++ if (!prop)
++ goto err;
++ pdata.bus_num = *(u32 *)prop;
++
++ prop = of_get_property(np, "cell-index", NULL);
++ if (prop)
++ i = *(u32 *)prop;
++
++ prop = of_get_property(np, "mode", NULL);
++ if (prop && !strcmp(prop, "cpu-qe"))
++ pdata.qe_mode = 1;
++
++ for (j = 0; j < num_board_infos; j++) {
++ if (board_infos[j].bus_num == pdata.bus_num)
++ pdata.max_chipselect++;
++ }
++
++ if (!pdata.max_chipselect)
++ continue;
++
++ ret = of_address_to_resource(np, 0, &res[0]);
++ if (ret)
++ goto err;
++
++ ret = of_irq_to_resource(np, 0, &res[1]);
++ if (ret == NO_IRQ)
++ goto err;
++
++ pdev = platform_device_alloc("mpc83xx_spi", i);
++ if (!pdev)
++ goto err;
++
++ ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
++ if (ret)
++ goto unreg;
++
++ ret = platform_device_add_resources(pdev, res,
++ ARRAY_SIZE(res));
++ if (ret)
++ goto unreg;
++
++ ret = platform_device_add(pdev);
++ if (ret)
++ goto unreg;
++
++ goto next;
++unreg:
++ platform_device_del(pdev);
++err:
++ pr_err("%s: registration failed\n", np->full_name);
++next:
++ i++;
++ }
++
++ return i;
++}
++
++static int __init fsl_spi_init(struct spi_board_info *board_infos,
++ unsigned int num_board_infos,
++ void (*cs_control)(struct spi_device *spi,
++ bool on))
++{
++ u32 sysclk = -1;
++ int ret;
++
++ /* SPI controller is either clocked from QE or SoC clock */
++ sysclk = get_brgfreq();
++ if (sysclk == -1) {
++ sysclk = fsl_get_sys_freq();
++ if (sysclk == -1)
++ return -ENODEV;
++ }
++
++ ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
++ num_board_infos, cs_control);
++ if (!ret)
++ of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
++ num_board_infos, cs_control);
++
++ return spi_register_board_info(board_infos, num_board_infos);
++}
++
++static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
++{
++ pr_debug("%s %d %d\n", __func__, spi->chip_select, on);
++ par_io_data_set(3, 13, on);
++}
++
++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)
++{
++ __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 - 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_cs_control);
++}
++machine_device_initcall(mpc831x_rdb, mpc8313_spi_init);
++
+ static void __init mpc831x_rdb_setup_arch(void)
+ {
+ #ifdef CONFIG_PCI
+Index: linux-2.6.31/drivers/spi/spi_mpc8xxx.c
+===================================================================
+--- linux-2.6.31.orig/drivers/spi/spi_mpc8xxx.c 2009-10-19 16:32:13.000000000 +0200
++++ linux-2.6.31/drivers/spi/spi_mpc8xxx.c 2009-10-19 16:41:27.000000000 +0200
+@@ -285,7 +285,9 @@
+ if (pm)
+ pm--;
+
+- cs->hw_mode |= SPMODE_PM(pm);
++ cs->hw_mode = 0x0F700000;
++ mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode,cs->hw_mode);
++
+ regval = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode);
+ if (cs->hw_mode != regval) {
+ unsigned long flags;
+@@ -445,7 +447,7 @@
+ cs->hw_mode = mpc8xxx_spi_read_reg(&mpc8xxx_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);
++ | SPMODE_REV );
+
+ if (spi->mode & SPI_CPHA)
+ cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK;
+@@ -453,8 +455,10 @@
+ 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 = 0x0F700000;
++ mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode,cs->hw_mode);
++ cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+
+ retval = mpc8xxx_spi_setup_transfer(spi, NULL);
+ if (retval < 0) {
+@@ -602,7 +606,7 @@
+ INIT_LIST_HEAD(&mpc8xxx_spi->queue);
+
+ mpc8xxx_spi->workqueue = create_singlethread_workqueue(
+- dev_name(master->dev.parent));
++ dev_name(&dev->dev));
+ if (mpc8xxx_spi->workqueue == NULL) {
+ ret = -EBUSY;
+ goto free_irq;
diff --git a/recipes/linux/linux-2.6.31/boc01/011-090115-gpio.patch b/recipes/linux/linux-2.6.31/boc01/011-090115-gpio.patch
new file mode 100644
index 0000000000..fd20dccea3
--- /dev/null
+++ b/recipes/linux/linux-2.6.31/boc01/011-090115-gpio.patch
@@ -0,0 +1,440 @@
+Index: linux-2.6.29/drivers/char/Kconfig
+===================================================================
+--- linux-2.6.29.orig/drivers/char/Kconfig 2009-03-24 00:12:14.000000000 +0100
++++ linux-2.6.29/drivers/char/Kconfig 2009-04-01 17:37:55.000000000 +0200
+@@ -1020,6 +1020,24 @@
+ tristate "NEC VR4100 series General-purpose I/O Unit support"
+ depends on CPU_VR41XX
+
++config GPIO_MPC8313
++ tristate "mpc8313e gpio"
++ depends on PPC_MPC831x
++ select INPUT
++ default y
++ help
++ Give userspace