mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2024-12-14 19:04:39 +00:00
c49f135f72
SVN-Revision: 16547
128 lines
3.2 KiB
Diff
128 lines
3.2 KiB
Diff
From 1353cd9749377dbcc8290dab5c098deec66fb956 Mon Sep 17 00:00:00 2001
|
|
From: Kurt Mahan <kmahan@freescale.com>
|
|
Date: Thu, 15 May 2008 13:24:58 -0600
|
|
Subject: [PATCH] Add RTC RV5C387A driver for MCF547x and MCF548x.
|
|
|
|
LTIBName: m547x-8x-rtc-rv5c387a
|
|
Signed-off-by: Kurt Mahan <kmahan@freescale.com>
|
|
Signed-off-by: Shrek Wu <b16972@freescale.com>
|
|
---
|
|
drivers/rtc/rtc-rs5c372.c | 67 +++++++++++++++++++++++++++++++++++++++++---
|
|
1 files changed, 62 insertions(+), 5 deletions(-)
|
|
|
|
--- a/drivers/rtc/rtc-rs5c372.c
|
|
+++ b/drivers/rtc/rtc-rs5c372.c
|
|
@@ -15,7 +15,6 @@
|
|
|
|
#define DRV_VERSION "0.5"
|
|
|
|
-
|
|
/*
|
|
* Ricoh has a family of I2C based RTCs, which differ only slightly from
|
|
* each other. Differences center on pinout (e.g. how many interrupts,
|
|
@@ -60,6 +59,15 @@
|
|
/* to read (style 1) or write registers starting at R */
|
|
#define RS5C_ADDR(R) (((R) << 4) | 0)
|
|
|
|
+#ifdef CONFIG_M547X_8X
|
|
+#define DRV_NAME "rv5c387a"
|
|
+/* i2c configuration */
|
|
+#define RV5C387_I2C_ADDR 0x32
|
|
+static unsigned short normal_i2c[] = {
|
|
+ RV5C387_I2C_ADDR, I2C_CLIENT_END
|
|
+};
|
|
+I2C_CLIENT_INSMOD; /* defines addr_data */
|
|
+#endif
|
|
|
|
enum rtc_type {
|
|
rtc_undef = 0,
|
|
@@ -506,14 +514,14 @@ static int rs5c372_probe(struct i2c_clie
|
|
err = -ENODEV;
|
|
goto exit;
|
|
}
|
|
-
|
|
- if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) {
|
|
+ rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL);
|
|
+ if (!rs5c372) {
|
|
err = -ENOMEM;
|
|
goto exit;
|
|
}
|
|
|
|
/* we read registers 0x0f then 0x00-0x0f; skip the first one */
|
|
- rs5c372->regs=&rs5c372->buf[1];
|
|
+ rs5c372->regs = &rs5c372->buf[1];
|
|
|
|
rs5c372->client = client;
|
|
i2c_set_clientdata(client, rs5c372);
|
|
@@ -605,7 +613,7 @@ static int rs5c372_probe(struct i2c_clie
|
|
case rtc_rv5c386: s = "rv5c386"; break;
|
|
case rtc_rv5c387a: s = "rv5c387a"; break;
|
|
default: s = "chip"; break;
|
|
- }; s;}),
|
|
+ }; s; }),
|
|
rs5c372->time24 ? "24hr" : "am/pm"
|
|
);
|
|
|
|
@@ -645,12 +653,61 @@ static int rs5c372_remove(struct i2c_cli
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_M547X_8X
|
|
+static int rv5c387_probe(struct i2c_adapter *adapter, int addr, int kind)
|
|
+{
|
|
+ int rc = 0;
|
|
+ struct i2c_client *new_client = NULL;
|
|
+
|
|
+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
|
|
+ rc = -ENODEV;
|
|
+ printk(KERN_DEBUG "%s i2c_check_functionality\n", __FUNCTION__);
|
|
+ goto failout;
|
|
+ }
|
|
+
|
|
+ new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
|
|
+ if (new_client == NULL) {
|
|
+ rc = -ENOMEM;
|
|
+ printk(KERN_DEBUG "%s kzalloc new_client\n", __FUNCTION__);
|
|
+ goto failout;
|
|
+ }
|
|
+
|
|
+ new_client->addr = addr;
|
|
+ new_client->adapter = adapter;
|
|
+ new_client->driver = &rs5c372_driver;
|
|
+ new_client->flags = 0;
|
|
+ strcpy(new_client->name, DRV_NAME);
|
|
+
|
|
+ rc = i2c_attach_client(new_client);
|
|
+ if (rc < 0) {
|
|
+ printk(KERN_DEBUG "%s i2c_attach_client\n", __FUNCTION__);
|
|
+ goto failout;
|
|
+ }
|
|
+
|
|
+ rs5c372_probe(new_client);
|
|
+ return 0;
|
|
+failout:
|
|
+ kfree(new_client);
|
|
+ return rc;
|
|
+}
|
|
+
|
|
+static int
|
|
+rv5c387_attach_adapter(struct i2c_adapter *adapter)
|
|
+{
|
|
+ return i2c_probe(adapter, &addr_data, rv5c387_probe);
|
|
+}
|
|
+#endif
|
|
+
|
|
static struct i2c_driver rs5c372_driver = {
|
|
.driver = {
|
|
.name = "rtc-rs5c372",
|
|
},
|
|
+#ifdef CONFIG_M547X_8X
|
|
+ .attach_adapter = &rv5c387_attach_adapter,
|
|
+#else
|
|
.probe = rs5c372_probe,
|
|
.remove = rs5c372_remove,
|
|
+#endif
|
|
};
|
|
|
|
static __init int rs5c372_init(void)
|