summaryrefslogtreecommitdiff
path: root/packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch
diff options
context:
space:
mode:
authorRod Whitby <rod@whitby.id.au>2006-01-04 12:01:04 +0000
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>2006-01-04 12:01:04 +0000
commit01cabcc3fd22e25937dbe24ee14cdf464a1ec97e (patch)
tree50b88adf1cffcb979aa29dbbca40ec9d69769e1e /packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch
parent6c28c501d6db85c88873f4a722909a3e95e3f2e8 (diff)
nslu2-kernel: Added the scsi-idle patch, Enabled CONFIG_INPUT=y, cause Debian tools (especially yaird) assume that /proc/bus/input exists, Updated patchsets to match 2.6.15, removed some patches, and combined some others, Updated to class-based RTC driver from azummo, changed defconfig to remove the pwc module, memory-h-page-shift page revised due to feedback from RMK, Removed old kernel versions, Updated to 2.6.15 final.
Diffstat (limited to 'packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch')
-rw-r--r--packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch204
1 files changed, 204 insertions, 0 deletions
diff --git a/packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch b/packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch
new file mode 100644
index 0000000000..44f2636c5c
--- /dev/null
+++ b/packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch
@@ -0,0 +1,204 @@
+ drivers/i2c/chips/x1205.c | 116 ++++++++++++++++++++++++++++++----------------
+ 1 file changed, 76 insertions(+), 40 deletions(-)
+
+--- linux-nslu2.orig/drivers/i2c/chips/x1205.c 2005-12-12 18:59:07.000000000 +0100
++++ linux-nslu2/drivers/i2c/chips/x1205.c 2005-12-13 21:31:32.000000000 +0100
+@@ -22,9 +22,9 @@
+ #include <linux/string.h>
+ #include <linux/bcd.h>
+ #include <linux/rtc.h>
++#include <linux/delay.h>
+
+-
+-#define DRV_VERSION "1.0.0"
++#define DRV_VERSION "1.0.1"
+
+ /* Addresses to scan: none. This chip is located at
+ * 0x6f and uses a two bytes register addressing.
+@@ -141,35 +141,19 @@ static int x1205_validate_tm(struct rtc_
+ * Epoch is initialized as 2000. Time is set to UTC.
+ */
+ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
+- u8 reg_base)
++ unsigned char reg_base)
+ {
+ unsigned char dt_addr[2] = { 0, reg_base };
+- static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
+
+- unsigned char buf[8], sr;
++ unsigned char buf[8];
+
+ struct i2c_msg msgs[] = {
+- { client->addr, 0, 2, sr_addr }, /* setup read ptr */
+- { client->addr, I2C_M_RD, 1, &sr }, /* read status */
+ { client->addr, 0, 2, dt_addr }, /* setup read ptr */
+ { client->addr, I2C_M_RD, 8, buf }, /* read date */
+ };
+
+- /* read status register */
+- if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
+- dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+- return -EIO;
+- }
+-
+- /* check for battery failure */
+- if (sr & X1205_SR_RTCF) {
+- dev_warn(&client->dev,
+- "Clock had a power failure, you must set the date.\n");
+- return -EINVAL;
+- }
+-
+ /* read date registers */
+- if ((i2c_transfer(client->adapter, &msgs[2], 2)) != 2) {
++ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
+ dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
+ return -EIO;
+ }
+@@ -199,11 +183,28 @@ static int x1205_get_datetime(struct i2c
+ return 0;
+ }
+
++static int x1205_get_status(struct i2c_client *client, unsigned char *sr)
++{
++ static unsigned char sr_addr[2] = { 0, X1205_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", __FUNCTION__);
++ return -EIO;
++ }
++
++ return 0;
++}
++
+ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
+ int datetoo, u8 reg_base)
+ {
+- int i, err, xfer;
+-
++ int i, xfer;
+ unsigned char buf[8];
+
+ static const unsigned char wel[3] = { 0, X1205_REG_SR,
+@@ -214,15 +215,10 @@ static int x1205_set_datetime(struct i2c
+
+ static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
+
+- /* check if all values in the tm struct are correct */
+- if ((err = x1205_validate_tm(tm)) < 0)
+- return err;
+-
+- dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
+- "mday=%d, mon=%d, year=%d, wday=%d\n",
++ dev_dbg(&client->dev,
++ "%s: secs=%d, mins=%d, hours=%d\n",
+ __FUNCTION__,
+- tm->tm_sec, tm->tm_min, tm->tm_hour,
+- tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
++ tm->tm_sec, tm->tm_min, tm->tm_hour);
+
+ buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
+ buf[CCR_MIN] = BIN2BCD(tm->tm_min);
+@@ -232,6 +228,11 @@ static int x1205_set_datetime(struct i2c
+
+ /* should we also set the date? */
+ if (datetoo) {
++ dev_dbg(&client->dev,
++ "%s: mday=%d, mon=%d, year=%d, wday=%d\n",
++ __FUNCTION__,
++ tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
++
+ buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
+
+ /* month, 0 - 11 */
+@@ -280,6 +281,22 @@ static int x1205_set_datetime(struct i2c
+ return 0;
+ }
+
++static int x1205_fix_osc(struct i2c_client *client)
++{
++ int err;
++ struct rtc_time tm;
++
++ tm.tm_hour = 0;
++ tm.tm_min = 0;
++ tm.tm_sec = 0;
++
++ if ((err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE)) < 0)
++ dev_err(&client->dev,
++ "unable to restart the clock\n");
++
++ return err;
++}
++
+ static int x1205_get_dtrim(struct i2c_client *client, int *trim)
+ {
+ unsigned char dtr;
+@@ -352,14 +369,17 @@ static int x1205_hctosys(struct i2c_clie
+
+ struct rtc_time tm;
+ struct timespec tv;
++ unsigned char sr;
+
++ if ((err = x1205_get_status(client, &sr)) < 0)
++ return err;
+
+- err = x1205_get_datetime(client, &tm, X1205_CCR_BASE);
+- if (err) {
+- dev_err(&client->dev,
+- "Unable to set the system clock\n");
++ /* Don't set if we had a power failure */
++ if (sr & X1205_SR_RTCF)
++ return -EINVAL;
++
++ if ((err = x1205_get_datetime(client, &tm, X1205_CCR_BASE)) < 0)
+ return err;
+- }
+
+ /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
+ * whether it stores the most close value or the value with partial
+@@ -506,9 +526,9 @@ static int x1205_attach(struct i2c_adapt
+
+ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
+ {
+- struct i2c_client *client;
+-
+ int err = 0;
++ unsigned char sr;
++ struct i2c_client *client;
+
+ dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
+
+@@ -543,9 +563,25 @@ static int x1205_probe(struct i2c_adapte
+
+ dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
+
++ /* Check for power failures and eventualy enable the osc */
++ if ((err = x1205_get_status(client, &sr)) == 0) {
++ if (sr & X1205_SR_RTCF) {
++ dev_err(&client->dev,
++ "power failure detected, "
++ "please set the clock\n");
++ udelay(50);
++ x1205_fix_osc(client);
++ }
++ }
++ else
++ dev_err(&client->dev, "couldn't read status\n");
++
+ /* If requested, set the system time */
+- if (hctosys)
+- x1205_hctosys(client);
++ if (hctosys) {
++ if ((err = x1205_hctosys(client)) < 0)
++ dev_err(&client->dev,
++ "unable to set the system clock\n");
++ }
+
+ return 0;
+