X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Frtc%2Frtc-rs5c372.c;h=56caf6b2c3e5d2fceface127d7dc197a839e0dac;hb=908cf4b925e419bc74f3297b2f0e51d6f8a81da2;hp=e7851e3739abd11030cdf0a724da2436315164dd;hpb=e7b3ca08549caccf5d6e1cf066780bf4f0ae77a7;p=pandora-kernel.git diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index e7851e3739ab..56caf6b2c3e5 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -13,13 +13,7 @@ #include #include -#define DRV_VERSION "0.4" - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD; +#define DRV_VERSION "0.5" /* @@ -75,6 +69,15 @@ enum rtc_type { rtc_rv5c387a, }; +static const struct i2c_device_id rs5c372_id[] = { + { "rs5c372a", rtc_rs5c372a }, + { "rs5c372b", rtc_rs5c372b }, + { "rv5c386", rtc_rv5c386 }, + { "rv5c387a", rtc_rv5c387a }, + { } +}; +MODULE_DEVICE_TABLE(i2c, rs5c372_id); + /* REVISIT: this assumes that: * - we're in the 21st century, so it's safe to ignore the century * bit for rv5c38[67] (REG_MONTH bit 7); @@ -88,9 +91,6 @@ struct rs5c372 { unsigned has_irq:1; char buf[17]; char *regs; - - /* on conversion to a "new style" i2c driver, this vanishes */ - struct i2c_client dev; }; static int rs5c_get_regs(struct rs5c372 *rs5c) @@ -108,7 +108,7 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) * least 80219 chips; this works around that bug. */ if ((i2c_transfer(client->adapter, msgs, 1)) != 1) { - pr_debug("%s: can't read registers\n", rs5c->rtc->name); + dev_warn(&client->dev, "can't read registers\n"); return -EIO; } @@ -175,7 +175,7 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, + __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); @@ -190,7 +190,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " "mday=%d, mon=%d, year=%d, wday=%d\n", - __FUNCTION__, + __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); @@ -204,7 +204,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) buf[7] = BIN2BCD(tm->tm_year - 100); if ((i2c_master_send(client, buf, 8)) != 8) { - dev_err(&client->dev, "%s: write error\n", __FUNCTION__); + dev_err(&client->dev, "%s: write error\n", __func__); return -EIO; } @@ -229,7 +229,7 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) *osc = (tmp & RS5C372_TRIM_XSL) ? 32000 : 32768; if (trim) { - dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, tmp); + dev_dbg(&client->dev, "%s: raw trim=%x\n", __func__, tmp); tmp &= RS5C372_TRIM_MASK; if (tmp & 0x3e) { int t = tmp & 0x3f; @@ -483,25 +483,36 @@ static int rs5c_sysfs_register(struct device *dev) return err; } +static void rs5c_sysfs_unregister(struct device *dev) +{ + device_remove_file(dev, &dev_attr_trim); + device_remove_file(dev, &dev_attr_osc); +} + #else static int rs5c_sysfs_register(struct device *dev) { return 0; } + +static void rs5c_sysfs_unregister(struct device *dev) +{ + /* nothing */ +} #endif /* SYSFS */ static struct i2c_driver rs5c372_driver; -static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) +static int rs5c372_probe(struct i2c_client *client, + const struct i2c_device_id *id) { int err = 0; - struct i2c_client *client; struct rs5c372 *rs5c372; struct rtc_time tm; - dev_dbg(adapter->class_dev.dev, "%s\n", __FUNCTION__); + dev_dbg(&client->dev, "%s\n", __func__); - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { err = -ENODEV; goto exit; } @@ -511,41 +522,16 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) goto exit; } - /* we read registers 0x0f then 0x00-0x0f; skip the first one */ - rs5c372->regs=&rs5c372->buf[1]; - - /* On conversion to a "new style" i2c driver, we'll be handed - * the i2c_client (we won't create it) - */ - client = &rs5c372->dev; rs5c372->client = client; - - /* I2C client */ - client->addr = address; - client->driver = &rs5c372_driver; - client->adapter = adapter; - - strlcpy(client->name, rs5c372_driver.driver.name, I2C_NAME_SIZE); - i2c_set_clientdata(client, rs5c372); + rs5c372->type = id->driver_data; - /* Inform the i2c layer */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; + /* we read registers 0x0f then 0x00-0x0f; skip the first one */ + rs5c372->regs = &rs5c372->buf[1]; err = rs5c_get_regs(rs5c372); if (err < 0) - goto exit_detach; - - /* For "new style" drivers, irq is in i2c_client and chip type - * info comes from i2c_client.dev.platform_data. Meanwhile: - * - * STICK BOARD-SPECIFIC SETUP CODE RIGHT HERE - */ - if (rs5c372->type == rtc_undef) { - rs5c372->type = rtc_rs5c372b; - dev_warn(&client->dev, "assuming rs5c372b\n"); - } + goto exit_kfree; /* clock may be set for am/pm or 24 hr time */ switch (rs5c372->type) { @@ -567,7 +553,7 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) break; default: dev_err(&client->dev, "unknown RTC type\n"); - goto exit_detach; + goto exit_kfree; } /* if the oscillator lost power and no other software (like @@ -601,7 +587,7 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) if ((i2c_master_send(client, buf, 3)) != 3) { dev_err(&client->dev, "setup error\n"); - goto exit_detach; + goto exit_kfree; } rs5c372->regs[RS5C_REG_CTRL1] = buf[1]; rs5c372->regs[RS5C_REG_CTRL2] = buf[2]; @@ -621,14 +607,14 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) rs5c372->time24 ? "24hr" : "am/pm" ); - /* FIXME when client->irq exists, use it to register alarm irq */ + /* REVISIT use client->irq to register alarm irq ... */ rs5c372->rtc = rtc_device_register(rs5c372_driver.driver.name, &client->dev, &rs5c372_rtc_ops, THIS_MODULE); if (IS_ERR(rs5c372->rtc)) { err = PTR_ERR(rs5c372->rtc); - goto exit_detach; + goto exit_kfree; } err = rs5c_sysfs_register(&client->dev); @@ -640,9 +626,6 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) exit_devreg: rtc_device_unregister(rs5c372->rtc); -exit_detach: - i2c_detach_client(client); - exit_kfree: kfree(rs5c372); @@ -650,24 +633,12 @@ exit: return err; } -static int rs5c372_attach(struct i2c_adapter *adapter) +static int rs5c372_remove(struct i2c_client *client) { - return i2c_probe(adapter, &addr_data, rs5c372_probe); -} - -static int rs5c372_detach(struct i2c_client *client) -{ - int err; struct rs5c372 *rs5c372 = i2c_get_clientdata(client); - if (rs5c372->rtc) - rtc_device_unregister(rs5c372->rtc); - - /* REVISIT properly destroy the sysfs files ... */ - - if ((err = i2c_detach_client(client))) - return err; - + rtc_device_unregister(rs5c372->rtc); + rs5c_sysfs_unregister(&client->dev); kfree(rs5c372); return 0; } @@ -676,8 +647,9 @@ static struct i2c_driver rs5c372_driver = { .driver = { .name = "rtc-rs5c372", }, - .attach_adapter = &rs5c372_attach, - .detach_client = &rs5c372_detach, + .probe = rs5c372_probe, + .remove = rs5c372_remove, + .id_table = rs5c372_id, }; static __init int rs5c372_init(void)