|
@@ -205,19 +205,14 @@ static int ds13307_set_time(struct device *dev, struct rtc_time *time) {
|
|
|
|
|
|
static int ds13307_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
|
|
|
struct i2c_client *client;
|
|
|
- u8 buf[5], ctl[2], addr = DS1337_CTL;
|
|
|
+ u8 buf[9], addr = DS1337_ALRM1;
|
|
|
int h12;
|
|
|
client = to_i2c_client(dev);
|
|
|
- if(ds13307_read_bytes(client, &addr, ctl, 2)) {
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- // select for A1IE bit
|
|
|
- alarm->enabled = ctl[0] & 0x01;
|
|
|
- // select for A1F bit
|
|
|
- alarm->pending = ctl[1] & 0x01;
|
|
|
-
|
|
|
- addr = DS1337_ALRM1;
|
|
|
- if (!ds13307_read_bytes(client, &addr, buf, 4)) {
|
|
|
+ if (!ds13307_read_bytes(client, &addr, buf, 9)) {
|
|
|
+ // select for A1IE bit
|
|
|
+ alarm->enabled = buf[7] & 0x01;
|
|
|
+ // select for A1F bit
|
|
|
+ alarm->pending = buf[8] & 0x01;
|
|
|
alarm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
|
|
|
alarm->time.tm_min = bcd2bin(buf[1] & 0x7F);
|
|
|
h12 = ds13307_check_12h_am_pm(&buf[2]);
|
|
@@ -238,6 +233,51 @@ static int ds13307_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
|
|
|
return -EIO;
|
|
|
}
|
|
|
|
|
|
+/* Sets the alarm to the values passed to the function */
|
|
|
+static int ds13307_write_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
|
|
|
+ struct i2c_client *client;
|
|
|
+ u8 buf[9], addr = DS1337_ALRM1;
|
|
|
+ client = to_i2c_client(dev);
|
|
|
+ if(!ds13307_read_bytes(client, &addr, buf, 9)) {
|
|
|
+ // enable or disable the alarm as requested
|
|
|
+ if ((alarm->enabled && (!(buf[7] & 0x01))) || ((!alarm->enabled && (buf[7] & 0x01)))) {
|
|
|
+ buf[7] ^= 0x01;
|
|
|
+ }
|
|
|
+ // disable alarm 2
|
|
|
+ if (buf[7] & 0x02) {
|
|
|
+ buf[7] ^= 0x02;
|
|
|
+ }
|
|
|
+ // clear the status bit
|
|
|
+ if (buf[8] & 0x01) {
|
|
|
+ buf[8] ^= 0x01;
|
|
|
+ }
|
|
|
+ buf[0] = bin2bcd(alarm->time.tm_sec);
|
|
|
+ buf[1] = bin2bcd(alarm->time.tm_min);
|
|
|
+ buf[2] = bin2bcd(alarm->time.tm_hour);
|
|
|
+ buf[3] = bin2bcd(alarm->time.tm_mday);
|
|
|
+ if(!ds13307_write_bytes(client, &addr, buf, 9)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return -EIO;
|
|
|
+}
|
|
|
+
|
|
|
+static int ds13307_alarm_irq_enable(struct device *dev, unsigned int enabled) {
|
|
|
+ struct i2c_client *client;
|
|
|
+ u8 buf, addr = DS1337_CTL;
|
|
|
+ client = to_i2c_client(dev);
|
|
|
+ if (ds13307_read_bytes(client, &addr, &buf, 1)) {
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+ if ((!enabled && (buf & 0x01)) || (enabled & (!(buf & 0x01)))) {
|
|
|
+ buf ^= 0x01;
|
|
|
+ }
|
|
|
+ if(!ds13307_write_bytes(client, &addr, &buf, 1)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return -EIO;
|
|
|
+}
|
|
|
+
|
|
|
static struct rtc_class_ops ds13307_rtc_ops = {
|
|
|
.read_time = ds13307_read_time,
|
|
|
.set_time = ds13307_set_time
|
|
@@ -296,6 +336,9 @@ static int ds13307_probe(struct i2c_client *client,
|
|
|
if (IS_ERR(rtc)) {
|
|
|
return PTR_ERR(rtc);
|
|
|
}
|
|
|
+ rtc->uie_unsupported = 1;
|
|
|
+ device_set_wakeup_capable(&client->dev, 0);
|
|
|
+ client->irq = 0;
|
|
|
if (model_detected == DEVICE_DS1307) {
|
|
|
ds1307_nvmem.name = "ds1307_nvram";
|
|
|
ds1307_nvmem.word_size = 1;
|
|
@@ -306,6 +349,8 @@ static int ds13307_probe(struct i2c_client *client,
|
|
|
rtc->nvmem_config = &ds1307_nvmem;
|
|
|
} else {
|
|
|
ds13307_rtc_ops.read_alarm = ds13307_read_alarm;
|
|
|
+ ds13307_rtc_ops.set_alarm = ds13307_write_alarm;
|
|
|
+ ds13307_rtc_ops.alarm_irq_enable = ds13307_alarm_irq_enable;
|
|
|
}
|
|
|
rtc->ops = &ds13307_rtc_ops;
|
|
|
i2c_set_clientdata(client,rtc);
|