2.6.31 support (WiP)
[openwrt/staging/chunkeey.git] / target / linux / coldfire / patches / 056-m547x_8x_rtc_rv5c387a.patch
1 From 1353cd9749377dbcc8290dab5c098deec66fb956 Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Thu, 15 May 2008 13:24:58 -0600
4 Subject: [PATCH] Add RTC RV5C387A driver for MCF547x and MCF548x.
5
6 LTIBName: m547x-8x-rtc-rv5c387a
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
8 Signed-off-by: Shrek Wu <b16972@freescale.com>
9 ---
10 drivers/rtc/rtc-rs5c372.c | 67 +++++++++++++++++++++++++++++++++++++++++---
11 1 files changed, 62 insertions(+), 5 deletions(-)
12
13 --- a/drivers/rtc/rtc-rs5c372.c
14 +++ b/drivers/rtc/rtc-rs5c372.c
15 @@ -15,7 +15,6 @@
16
17 #define DRV_VERSION "0.5"
18
19 -
20 /*
21 * Ricoh has a family of I2C based RTCs, which differ only slightly from
22 * each other. Differences center on pinout (e.g. how many interrupts,
23 @@ -60,6 +59,15 @@
24 /* to read (style 1) or write registers starting at R */
25 #define RS5C_ADDR(R) (((R) << 4) | 0)
26
27 +#ifdef CONFIG_M547X_8X
28 +#define DRV_NAME "rv5c387a"
29 +/* i2c configuration */
30 +#define RV5C387_I2C_ADDR 0x32
31 +static unsigned short normal_i2c[] = {
32 + RV5C387_I2C_ADDR, I2C_CLIENT_END
33 +};
34 +I2C_CLIENT_INSMOD; /* defines addr_data */
35 +#endif
36
37 enum rtc_type {
38 rtc_undef = 0,
39 @@ -506,14 +514,14 @@ static int rs5c372_probe(struct i2c_clie
40 err = -ENODEV;
41 goto exit;
42 }
43 -
44 - if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) {
45 + rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL);
46 + if (!rs5c372) {
47 err = -ENOMEM;
48 goto exit;
49 }
50
51 /* we read registers 0x0f then 0x00-0x0f; skip the first one */
52 - rs5c372->regs=&rs5c372->buf[1];
53 + rs5c372->regs = &rs5c372->buf[1];
54
55 rs5c372->client = client;
56 i2c_set_clientdata(client, rs5c372);
57 @@ -605,7 +613,7 @@ static int rs5c372_probe(struct i2c_clie
58 case rtc_rv5c386: s = "rv5c386"; break;
59 case rtc_rv5c387a: s = "rv5c387a"; break;
60 default: s = "chip"; break;
61 - }; s;}),
62 + }; s; }),
63 rs5c372->time24 ? "24hr" : "am/pm"
64 );
65
66 @@ -645,12 +653,61 @@ static int rs5c372_remove(struct i2c_cli
67 return 0;
68 }
69
70 +#ifdef CONFIG_M547X_8X
71 +static int rv5c387_probe(struct i2c_adapter *adapter, int addr, int kind)
72 +{
73 + int rc = 0;
74 + struct i2c_client *new_client = NULL;
75 +
76 + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
77 + rc = -ENODEV;
78 + printk(KERN_DEBUG "%s i2c_check_functionality\n", __FUNCTION__);
79 + goto failout;
80 + }
81 +
82 + new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
83 + if (new_client == NULL) {
84 + rc = -ENOMEM;
85 + printk(KERN_DEBUG "%s kzalloc new_client\n", __FUNCTION__);
86 + goto failout;
87 + }
88 +
89 + new_client->addr = addr;
90 + new_client->adapter = adapter;
91 + new_client->driver = &rs5c372_driver;
92 + new_client->flags = 0;
93 + strcpy(new_client->name, DRV_NAME);
94 +
95 + rc = i2c_attach_client(new_client);
96 + if (rc < 0) {
97 + printk(KERN_DEBUG "%s i2c_attach_client\n", __FUNCTION__);
98 + goto failout;
99 + }
100 +
101 + rs5c372_probe(new_client);
102 + return 0;
103 +failout:
104 + kfree(new_client);
105 + return rc;
106 +}
107 +
108 +static int
109 +rv5c387_attach_adapter(struct i2c_adapter *adapter)
110 +{
111 + return i2c_probe(adapter, &addr_data, rv5c387_probe);
112 +}
113 +#endif
114 +
115 static struct i2c_driver rs5c372_driver = {
116 .driver = {
117 .name = "rtc-rs5c372",
118 },
119 +#ifdef CONFIG_M547X_8X
120 + .attach_adapter = &rv5c387_attach_adapter,
121 +#else
122 .probe = rs5c372_probe,
123 .remove = rs5c372_remove,
124 +#endif
125 };
126
127 static __init int rs5c372_init(void)