summaryrefslogtreecommitdiffstats
path: root/target/linux/coldfire/patches/056-m547x_8x_rtc_rv5c387a.patch
blob: 4d5db0ae4c76f3ba8480fa14feda5c5fa81ba9f0 (plain)
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)