diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2009-10-19 17:46:01 +0200 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2009-10-19 17:46:01 +0200 |
| commit | 83396675e812ff3022426c0065fb9d8b52b4d35e (patch) | |
| tree | 1712c6270955311e6ca5fd90259193ee08a659fb /recipes | |
| parent | 47e3f7bc0ec31948832e410f2a4cc201c81e04a2 (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.patch | 16 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/005-091008-isl12024.patch | 512 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/007-091005-lm73.patch | 242 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/008-091005-spi.patch | 226 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/011-090115-gpio.patch | 440 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/012-091019-capsense.patch | 858 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/013-091015-lcd.patch | 1070 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/boc01.dts | 348 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/boc01.dts.v1 | 348 | ||||
| -rw-r--r-- | recipes/linux/linux-2.6.31/boc01/defconfig | 2038 | ||||
| -rw-r--r-- | recipes/linux/linux_2.6.31.bb | 26 |
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 |
