@@ -146,6 +146,14 @@ config RTC_DRV_DS1307
This driver can also be built as a module. If so, the module
will be called rtc-ds1307.
+config RTC_NVRAM_SIZE
+ int "Size of embedded NVRAM in DS1307 compatible chips"
+ depends on RTC_DRV_DS1307
+ default 56
+ help
+ Size of the embedded NVRAM in DS1307 compatible chips. Defaults
+ to 56 bytes.
+
config RTC_DRV_DS1374
tristate "Dallas/Maxim DS1374"
depends on RTC_CLASS && I2C
@@ -33,6 +33,7 @@ enum ds_type {
ds_1340,
ds_1388,
ds_3231,
+ ds_32b35,
m41t00,
rx_8025,
// rs5c372 too? different address...
@@ -69,6 +70,7 @@ enum ds_type {
# define DS1337_BIT_nEOSC 0x80
# define DS1339_BIT_BBSQI 0x20
# define DS3231_BIT_BBSQW 0x40 /* same as BBSQI */
+# define DS3235_BIT_CONV 0x20
# define DS1337_BIT_RS2 0x10
# define DS1337_BIT_RS1 0x08
# define DS1337_BIT_INTCN 0x04
@@ -83,6 +85,7 @@ enum ds_type {
# define DS1340_BIT_OSF 0x80
#define DS1337_REG_STATUS 0x0f
# define DS1337_BIT_OSF 0x80
+# define DS3235_BIT_BSY 0x04
# define DS1337_BIT_A2I 0x02
# define DS1337_BIT_A1I 0x01
#define DS1339_REG_ALARM1_SECS 0x07
@@ -95,6 +98,8 @@ enum ds_type {
# define RX8025_BIT_VDET 0x40
# define RX8025_BIT_XST 0x20
+#define DS3235_REG_TEMP_MSB 0x11
+
struct ds1307 {
u8 offset; /* register's offset */
@@ -103,6 +108,7 @@ struct ds1307 {
unsigned long flags;
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
#define HAS_ALARM 1 /* bit 1 == irq claimed */
+#define HAS_SENSOR 2 /* bit 2 == sensor sysfs file active */
struct i2c_client *client;
struct rtc_device *rtc;
struct work_struct work;
@@ -113,19 +119,20 @@ struct ds1307 {
};
struct chip_desc {
- unsigned nvram56:1;
+ unsigned nvram:1;
unsigned alarm:1;
+ unsigned temp_sensor:1;
};
static const struct chip_desc chips[] = {
[ds_1307] = {
- .nvram56 = 1,
+ .nvram = 1,
},
[ds_1337] = {
.alarm = 1,
},
[ds_1338] = {
- .nvram56 = 1,
+ .nvram = 1,
},
[ds_1339] = {
.alarm = 1,
@@ -135,6 +142,11 @@ static const struct chip_desc chips[] =
[ds_3231] = {
.alarm = 1,
},
+[ds_32b35] = {
+ .nvram = 1,
+ .alarm = 1,
+ .temp_sensor = 1,
+},
[m41t00] = {
},
[rx_8025] = {
@@ -148,6 +160,7 @@ static const struct i2c_device_id ds1307
{ "ds1388", ds_1388 },
{ "ds1340", ds_1340 },
{ "ds3231", ds_3231 },
+ { "ds32b35", ds_32b35 },
{ "m41t00", m41t00 },
{ "rx8025", rx_8025 },
{ }
@@ -358,6 +371,7 @@ static int ds1307_set_time(struct device
case ds_1337:
case ds_1339:
case ds_3231:
+ case ds_32b35:
buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
break;
case ds_1340:
@@ -553,7 +567,11 @@ static const struct rtc_class_ops ds13xx
/*----------------------------------------------------------------------*/
-#define NVRAM_SIZE 56
+#ifdef CONFIG_RTC_NVRAM_SIZE
+# define NVRAM_SIZE CONFIG_RTC_NVRAM_SIZE
+#else
+# define NVRAM_SIZE 56
+#endif
static ssize_t
ds1307_nvram_read(struct file *filp, struct kobject *kobj,
@@ -620,6 +638,58 @@ static struct bin_attribute nvram = {
/*----------------------------------------------------------------------*/
+#define check_read_block(r, s) \
+ result = ds1307->read_block_data(client, r, s, temp); \
+ if (result < 0) \
+ goto err
+
+static ssize_t
+ds1307_temp_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct i2c_client *client;
+ struct ds1307 *ds1307;
+ int result;
+ u8 temp[2];
+ int value = 0;
+
+ client = kobj_to_i2c_client(kobj);
+ ds1307 = i2c_get_clientdata(client);
+
+ /* start new conversion if possible. */
+ check_read_block(DS1337_REG_STATUS, 1);
+ if (!(temp[0] & DS3235_BIT_BSY)) {
+ check_read_block(DS1337_REG_CONTROL, 1);
+ temp[0] |= DS3235_BIT_CONV;
+ result = ds1307->write_block_data(client, DS1337_REG_CONTROL, 1, temp);
+ if (result < 0)
+ goto err;
+ }
+
+ check_read_block(DS3235_REG_TEMP_MSB, 2);
+ value = (temp[1] >> 6) | (temp[0] & 0x7F) << 2;
+ if (temp[0] & 0x80)
+ value -= 512;
+
+err:
+ if (result < 0)
+ dev_err(&client->dev, "%s error %d\n", "temp read", result);
+
+ return sprintf(buf, "% 2d.%02ld\n", value / 4, abs((value % 4) * 25));
+}
+
+static struct bin_attribute ds1307_sensor = {
+ .attr = {
+ .name = "temperature",
+ .mode = S_IRUGO,
+ },
+ .read = ds1307_temp_read,
+ .size = 8,
+};
+
+/*----------------------------------------------------------------------*/
+
static struct i2c_driver ds1307_driver;
static int __devinit ds1307_probe(struct i2c_client *client,
@@ -636,6 +706,7 @@ static int __devinit ds1307_probe(struct
[ds_1337] = 0,
[ds_1339] = DS1339_BIT_BBSQI,
[ds_3231] = DS3231_BIT_BBSQW,
+ [ds_32b35] = DS3231_BIT_BBSQW,
};
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
@@ -664,6 +735,7 @@ static int __devinit ds1307_probe(struct
case ds_1337:
case ds_1339:
case ds_3231:
+ case ds_32b35:
/* has IRQ? */
if (ds1307->client->irq > 0 && chip->alarm) {
INIT_WORK(&ds1307->work, ds1307_work);
@@ -836,6 +908,7 @@ read_rtc:
case ds_1339:
case ds_1388:
case ds_3231:
+ case ds_32b35:
break;
}
@@ -889,11 +962,18 @@ read_rtc:
dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
}
- if (chip->nvram56) {
+ if (chip->nvram) {
err = sysfs_create_bin_file(&client->dev.kobj, &nvram);
if (err == 0) {
set_bit(HAS_NVRAM, &ds1307->flags);
- dev_info(&client->dev, "56 bytes nvram\n");
+ dev_info(&client->dev, "%d bytes nvram\n", NVRAM_SIZE);
+ }
+ }
+ if (chip->temp_sensor) {
+ err = sysfs_create_bin_file(&client->dev.kobj, &ds1307_sensor);
+ if (err == 0) {
+ set_bit(HAS_SENSOR, &ds1307->flags);
+ dev_info(&client->dev, "temperature sensor\n");
}
}
@@ -915,6 +995,9 @@ static int __devexit ds1307_remove(struc
cancel_work_sync(&ds1307->work);
}
+ if (test_and_clear_bit(HAS_SENSOR, &ds1307->flags))
+ sysfs_remove_bin_file(&client->dev.kobj, &ds1307_sensor);
+
if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
sysfs_remove_bin_file(&client->dev.kobj, &nvram);