From 1353cd9749377dbcc8290dab5c098deec66fb956 Mon Sep 17 00:00:00 2001 From: Kurt Mahan 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 Signed-off-by: Shrek Wu --- 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)