1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
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)
|