summaryrefslogtreecommitdiff
path: root/packages/linux/nslu2-kernel/2.6.14/30-i2c-x1205.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/linux/nslu2-kernel/2.6.14/30-i2c-x1205.patch')
-rw-r--r--packages/linux/nslu2-kernel/2.6.14/30-i2c-x1205.patch148
1 files changed, 120 insertions, 28 deletions
diff --git a/packages/linux/nslu2-kernel/2.6.14/30-i2c-x1205.patch b/packages/linux/nslu2-kernel/2.6.14/30-i2c-x1205.patch
index c212238941..1e775ba8b8 100644
--- a/packages/linux/nslu2-kernel/2.6.14/30-i2c-x1205.patch
+++ b/packages/linux/nslu2-kernel/2.6.14/30-i2c-x1205.patch
@@ -1,13 +1,13 @@
---- linux-2.6.14-rc2/drivers/i2c/chips/Kconfig 2005-09-24 13:17:13.000000000 +0200
-+++ test3/drivers/i2c/chips/Kconfig 2005-09-24 16:09:51.000000000 +0200
-@@ -126,4 +126,14 @@
+diff -urN linux-2.6.14-rc3/drivers/i2c/chips/Kconfig test9/drivers/i2c/chips/Kconfig
+--- linux-2.6.14-rc3/drivers/i2c/chips/Kconfig 2005-10-01 13:46:50.000000000 +0200
++++ test9/drivers/i2c/chips/Kconfig 2005-10-03 16:10:22.000000000 +0200
+@@ -126,4 +126,13 @@
This driver can also be built as a module. If so, the module
will be called max6875.
+config SENSORS_X1205
+ tristate "Xicor X1205 RTC chip"
+ depends on I2C
-+ select I2C_SENSOR
+ help
+ If you say yes here you get support for the Xicor X1205 RTC chip.
+
@@ -15,8 +15,9 @@
+ will be called x1205
+
endmenu
---- linux-2.6.14-rc2/drivers/i2c/chips/Makefile 2005-09-17 12:42:33.000000000 +0200
-+++ test3/drivers/i2c/chips/Makefile 2005-09-24 16:49:34.000000000 +0200
+diff -urN linux-2.6.14-rc3/drivers/i2c/chips/Makefile test9/drivers/i2c/chips/Makefile
+--- linux-2.6.14-rc3/drivers/i2c/chips/Makefile 2005-09-17 12:42:33.000000000 +0200
++++ test9/drivers/i2c/chips/Makefile 2005-10-01 15:30:06.000000000 +0200
@@ -13,6 +13,7 @@
obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o
obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
@@ -25,10 +26,10 @@
ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
EXTRA_CFLAGS += -DDEBUG
-diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x1205.c
---- linux-2.6.14-rc2/drivers/i2c/chips/x1205.c 1970-01-01 01:00:00.000000000 +0100
-+++ test3/drivers/i2c/chips/x1205.c 2005-09-24 16:11:16.000000000 +0200
-@@ -0,0 +1,522 @@
+diff -urN linux-2.6.14-rc3/drivers/i2c/chips/x1205.c test9/drivers/i2c/chips/x1205.c
+--- linux-2.6.14-rc3/drivers/i2c/chips/x1205.c 1970-01-01 01:00:00.000000000 +0100
++++ test9/drivers/i2c/chips/x1205.c 2005-10-03 16:02:57.000000000 +0200
+@@ -0,0 +1,612 @@
+/*
+ * linux/drivers/i2c/chips/x1205.c
+ *
@@ -62,7 +63,7 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+#define EPOCH_1900 1900
+#define EPOCH_1970 1970
+
-+#define DRIVER_VERSION "0.9.5"
++#define DRIVER_VERSION "0.9.6"
+#define DRIVER_NAME (x1205_driver.name)
+
+
@@ -140,20 +141,36 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
+ u8 reg_base)
+{
-+ static unsigned char addr[2] = { 0, };
-+ unsigned char buf[8];
++ static unsigned char dt_addr[] = { 0, };
++ static unsigned char sr_addr[] = { 0, };
+
-+ struct i2c_msg msgs[2] = {
-+ { client->addr, 0, 2, addr }, /* random read */
++ unsigned char buf[8], sr;
++
++ struct i2c_msg msgs[] = {
++ { client->addr, 0, 2, sr_addr }, /* random read */
++ { client->addr, I2C_M_RD, 1, &sr },
++ { client->addr, 0, 2, dt_addr }, /* random read */
+ { client->addr, I2C_M_RD, 8, buf },
+ };
+
+ struct x1205_data *xdata = i2c_get_clientdata(client);
+
-+ addr[1] = reg_base;
++ dt_addr[1] = reg_base;
++ sr_addr[1] = X1205_REG_SR;
++
++ if ((i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs))) ==
++ ARRAY_SIZE(msgs)) {
++ /* did we read the correct number of messages? */
+
-+ if ((i2c_transfer(client->adapter, msgs, 2)) == 2) {
-+ /* did we read 2 messages? */
++ /* check for battery failure */
++ if (sr & X1205_SR_RTCF)
++ {
++ dev_info(&client->adapter->dev,
++ "%s: Clock had a power failure, you must set the date.\n",
++ DRIVER_NAME);
++
++ return -EINVAL;
++ }
+
+ dev_dbg(&client->dev,
+ "%s: raw read data - sec-%02x min-%02x hr-%02x"
@@ -318,6 +335,14 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+ return 0;
+}
+
++struct x1205_limit
++{
++ unsigned char reg;
++ unsigned char mask;
++ unsigned char min;
++ unsigned char max;
++};
++
+static int x1205_validate_client(struct i2c_client *client)
+{
+ int i, xfer;
@@ -326,7 +351,7 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+ * address and check if the given bits are zero.
+ */
+
-+ const unsigned char probe_pattern[] = {
++ const unsigned char probe_zero_pattern[] = {
+
+ X1205_REG_SR, 0x18,
+ X1205_REG_Y2K, 0xC6,
@@ -337,7 +362,7 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+ X1205_REG_MN, 0x80,
+ X1205_REG_SC, 0x80,
+ X1205_REG_DTR, 0xF8,
-+ X1205_REG_ATR, 0x18,
++ X1205_REG_ATR, 0xC0,
+ X1205_REG_INT, 0x18,
+ X1205_REG_0, 0xFF,
+ X1205_REG_Y2K1, 0xC6,
@@ -352,7 +377,35 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+ X1205_REG_HRA0, 0x40,
+ };
+
-+ for (i = 0; i < sizeof(probe_pattern); i += 2)
++ const struct x1205_limit probe_limits_pattern[] = {
++ /* register, mask, min, max */
++ { X1205_REG_Y2K, 0xFF, 19, 20 },
++ { X1205_REG_DW, 0xFF, 0, 6 },
++ { X1205_REG_YR, 0xFF, 0, 99 },
++ { X1205_REG_MO, 0xFF, 0, 12 },
++ { X1205_REG_DT, 0xFF, 0, 31 },
++ { X1205_REG_HR, 0x7F, 0, 23 },
++ { X1205_REG_MN, 0xFF, 0, 59 },
++ { X1205_REG_SC, 0xFF, 0, 59 },
++ { X1205_REG_Y2K1, 0xFF, 19, 20 },
++ { X1205_REG_DWA1, 0x7F, 0, 6 },
++ { X1205_REG_MOA1, 0x7F, 0, 12 },
++ { X1205_REG_DTA1, 0x7F, 0, 31 },
++ { X1205_REG_HRA1, 0x7F, 0, 23 },
++ { X1205_REG_MNA1, 0x7F, 0, 59 },
++ { X1205_REG_SCA1, 0x7F, 0, 59 },
++ { X1205_REG_Y2K0, 0xFF, 19, 20 },
++ { X1205_REG_DWA0, 0x7F, 0, 6 },
++ { X1205_REG_MOA0, 0x7F, 0, 12 },
++ { X1205_REG_DTA0, 0x7F, 0, 31 },
++ { X1205_REG_HRA0, 0x7F, 0, 23 },
++ { X1205_REG_MNA0, 0x7F, 0, 59 },
++ { X1205_REG_SCA0, 0x7F, 0, 59 },
++ };
++
++ /* check that registers have bits a 0 where expected */
++
++ for (i = 0; i < ARRAY_SIZE(probe_zero_pattern); i += 2)
+ {
+ unsigned char buf;
+
@@ -364,7 +417,7 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+ };
+
+ addr[0] = 0x00;
-+ addr[1] = probe_pattern[i];
++ addr[1] = probe_zero_pattern[i];
+
+ xfer = i2c_transfer(client->adapter, msgs, 2);
+
@@ -376,15 +429,53 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+ return -EIO;
+ }
+
-+ if ((buf & probe_pattern[i+1]) != 0) {
++ if ((buf & probe_zero_pattern[i+1]) != 0) {
+ dev_dbg(&client->adapter->dev,
-+ "%s: register %x, pattern %d: %x\n",
++ "%s: register %x, zero pattern %d: %x\n",
+ __FUNCTION__, addr[1], i, buf);
+
+ return -ENODEV;
+ }
+ }
+
++ /* check limits */
++
++ for (i = 0; i < ARRAY_SIZE(probe_limits_pattern); i++)
++ {
++ unsigned char buf, val;
++
++ static unsigned char addr[2];
++
++ struct i2c_msg msgs[2] = {
++ { client->addr, 0, 2, addr }, /* random read */
++ { client->addr, I2C_M_RD, 1, &buf },
++ };
++
++ addr[0] = 0x00;
++ addr[1] = probe_limits_pattern[i].reg;
++
++ xfer = i2c_transfer(client->adapter, msgs, 2);
++
++ if (xfer != 2) {
++ dev_dbg(&client->adapter->dev,
++ "%s: could not read register %x\n",
++ __FUNCTION__, addr[1]);
++
++ return -EIO;
++ }
++
++ val = BCD2BIN(buf & probe_limits_pattern[i].mask);
++
++ if (val > probe_limits_pattern[i].max ||
++ val < probe_limits_pattern[i].min) {
++ dev_dbg(&client->adapter->dev,
++ "%s: register %x, lim pattern %d: %d\n",
++ __FUNCTION__, addr[1], i, val);
++
++ return -ENODEV;
++ }
++ }
++
+ return 0;
+}
+
@@ -444,7 +535,7 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+
+ list_add(&xdata->list, &x1205_clients);
+
-+ dev_info(&adapter->dev, "%s: chip found, driver " DRIVER_VERSION "\n",
++ dev_info(&adapter->dev, "%s: Chip found, driver " DRIVER_VERSION "\n",
+ DRIVER_NAME);
+
+ /* If requested, se the system time */
@@ -551,9 +642,9 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+
+module_init(x1205_init);
+module_exit(x1205_exit);
---- linux-2.6.14-rc2/include/linux/x1205.h 1970-01-01 01:00:00.000000000 +0100
-+++ test3/include/linux/x1205.h 2005-09-24 16:59:28.000000000 +0200
-@@ -0,0 +1,66 @@
+--- linux-2.6.14-rc3/include/linux/x1205.h 1970-01-01 01:00:00.000000000 +0100
++++ test9/include/linux/x1205.h 2005-10-03 15:38:21.000000000 +0200
+@@ -0,0 +1,67 @@
+
+/* commands */
+
@@ -613,6 +704,7 @@ diff -urN linux-2.6.14-rc2/drivers/i2c/chips/x1205.c test3/drivers/i2c/chips/x12
+#define X1205_CCR_BASE 0x30 /* Base address of CCR */
+#define X1205_ALM0_BASE 0x00 /* Base address of ALARM0 */
+
++#define X1205_SR_RTCF 0x01
+#define X1205_SR_WEL 0x02 /* Write Enable Latch bit */
+#define X1205_SR_RWEL 0x04 /* Register Write Enable Bit */
+