From 33df2ee1bb59b8cd14e3a375d826a40de21f388c Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Wed, 17 Jun 2009 16:26:08 -0700 Subject: rtc: rtc-ds1307 add ds1388 Extend the ds1307 driver to support ds1388 too. Signed-off-by: Joakim Tjernlund Signed-off-by: Alessandro Zummo Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/rtc/rtc-ds1307.c') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 2c4a65302a9d..52e2427e5a95 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -31,6 +31,7 @@ enum ds_type { ds_1338, ds_1339, ds_1340, + ds_1388, m41t00, rx_8025, // rs5c372 too? different address... @@ -94,6 +95,7 @@ enum ds_type { struct ds1307 { + u8 offset; /* register's offset */ u8 regs[11]; enum ds_type type; unsigned long flags; @@ -138,6 +140,7 @@ static const struct i2c_device_id ds1307_id[] = { { "ds1337", ds_1337 }, { "ds1338", ds_1338 }, { "ds1339", ds_1339 }, + { "ds1388", ds_1388 }, { "ds1340", ds_1340 }, { "m41t00", m41t00 }, { "rx8025", rx_8025 }, @@ -291,7 +294,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) /* read the RTC date and time registers all at once */ tmp = ds1307->read_block_data(ds1307->client, - DS1307_REG_SECS, 7, ds1307->regs); + ds1307->offset, 7, ds1307->regs); if (tmp != 7) { dev_err(dev, "%s error %d\n", "read", tmp); return -EIO; @@ -367,7 +370,8 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) "write", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); - result = ds1307->write_block_data(ds1307->client, 0, 7, buf); + result = ds1307->write_block_data(ds1307->client, + ds1307->offset, 7, buf); if (result < 0) { dev_err(dev, "%s error %d\n", "write", result); return result; @@ -632,9 +636,12 @@ static int __devinit ds1307_probe(struct i2c_client *client, if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) return -ENOMEM; - ds1307->client = client; i2c_set_clientdata(client, ds1307); - ds1307->type = id->driver_data; + + ds1307->client = client; + ds1307->type = id->driver_data; + ds1307->offset = 0; + buf = ds1307->regs; if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { ds1307->read_block_data = i2c_smbus_read_i2c_block_data; @@ -751,6 +758,9 @@ static int __devinit ds1307_probe(struct i2c_client *client, hour); } break; + case ds_1388: + ds1307->offset = 1; /* Seconds starts at 1 */ + break; default: break; } @@ -814,6 +824,7 @@ read_rtc: case rx_8025: case ds_1337: case ds_1339: + case ds_1388: break; } -- cgit v1.2.3 From 97f902b7be4dd6ba03c6aa8d3400783ed687ebd1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 17 Jun 2009 16:26:10 -0700 Subject: rtc: rtc-ds1307 add ds3231 Add ds3231 variant. For that, the BBSQI bit position was changed from a simple define into a lookup-array as it differs. This also removes writing to an unused bit in case of the ds1337. Signed-off-by: Wolfram Sang Acked-by: David Brownell Signed-off-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers/rtc/rtc-ds1307.c') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 52e2427e5a95..8a6f9a9f9cb8 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -32,6 +32,7 @@ enum ds_type { ds_1339, ds_1340, ds_1388, + ds_3231, m41t00, rx_8025, // rs5c372 too? different address... @@ -67,6 +68,7 @@ enum ds_type { #define DS1337_REG_CONTROL 0x0e # define DS1337_BIT_nEOSC 0x80 # define DS1339_BIT_BBSQI 0x20 +# define DS3231_BIT_BBSQW 0x40 /* same as BBSQI */ # define DS1337_BIT_RS2 0x10 # define DS1337_BIT_RS1 0x08 # define DS1337_BIT_INTCN 0x04 @@ -130,6 +132,9 @@ static const struct chip_desc chips[] = { }, [ds_1340] = { }, +[ds_3231] = { + .alarm = 1, +}, [m41t00] = { }, [rx_8025] = { @@ -142,6 +147,7 @@ static const struct i2c_device_id ds1307_id[] = { { "ds1339", ds_1339 }, { "ds1388", ds_1388 }, { "ds1340", ds_1340 }, + { "ds3231", ds_3231 }, { "m41t00", m41t00 }, { "rx8025", rx_8025 }, { } @@ -356,6 +362,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) switch (ds1307->type) { case ds_1337: case ds_1339: + case ds_3231: buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY; break; case ds_1340: @@ -628,6 +635,11 @@ static int __devinit ds1307_probe(struct i2c_client *client, struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int want_irq = false; unsigned char *buf; + static const int bbsqi_bitpos[] = { + [ds_1337] = 0, + [ds_1339] = DS1339_BIT_BBSQI, + [ds_3231] = DS3231_BIT_BBSQW, + }; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) @@ -654,6 +666,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, switch (ds1307->type) { case ds_1337: case ds_1339: + case ds_3231: /* has IRQ? */ if (ds1307->client->irq > 0 && chip->alarm) { INIT_WORK(&ds1307->work, ds1307_work); @@ -673,12 +686,12 @@ static int __devinit ds1307_probe(struct i2c_client *client, ds1307->regs[0] &= ~DS1337_BIT_nEOSC; /* Using IRQ? Disable the square wave and both alarms. - * For ds1339, be sure alarms can trigger when we're - * running on Vbackup (BBSQI); we assume ds1337 will - * ignore that bit + * For some variants, be sure alarms can trigger when we're + * running on Vbackup (BBSQI/BBSQW) */ if (want_irq) { - ds1307->regs[0] |= DS1337_BIT_INTCN | DS1339_BIT_BBSQI; + ds1307->regs[0] |= DS1337_BIT_INTCN + | bbsqi_bitpos[ds1307->type]; ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); } @@ -825,6 +838,7 @@ read_rtc: case ds_1337: case ds_1339: case ds_1388: + case ds_3231: break; } -- cgit v1.2.3 From e6229bec25be4ba00f31dd26e25721cc96c22262 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 18 Jun 2009 16:49:09 -0700 Subject: rtc: make rtc_update_irq callable with irqs enabled The rtc_update_irq() might be called with irqs enabled, if a interrupt handler was registered without IRQF_DISABLED. Use spin_lock_irqsave/spin_unlock_irqrestore instead of spin_lock/spin_unlock. Also update kerneldoc and drivers which do extra work to follow the current interface spec, as suggestted by David Brownell. Signed-off-by: Atsushi Nemoto Cc: Alessandro Zummo Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/rtc/rtc-ds1307.c') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 8a6f9a9f9cb8..47a93c022d91 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -267,12 +267,7 @@ static void ds1307_work(struct work_struct *work) control &= ~DS1337_BIT_A1IE; i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, control); - /* rtc_update_irq() assumes that it is called - * from IRQ-disabled context. - */ - local_irq_disable(); rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF); - local_irq_enable(); } out: -- cgit v1.2.3