static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) { struct s35390a *s35390a = i2c_get_clientdata(client); char buf[3], sts; int i, err; if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)) < 0) return -EIO; sts = bitrev8(sts); s35390a_alarm_irq_enable(client, 1); err = s35390a_get_reg(s35390a, S35390A_CMD_INT1_REG1, buf, sizeof(buf)); if (err < 0) return err; /* This chip returns the bits of each byte in reverse order */ for (i = 0; i < 3; ++i) { buf[i] = bitrev8(buf[i]); buf[i] &= ~0x80; } alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]); alm->time.tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_ALRM_BYTE_HOURS]); alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]); dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n", __func__, alm->time.tm_min, alm->time.tm_hour, alm->time.tm_wday); if (!(sts & BIT(2))) s35390a_alarm_irq_enable(client, 0); return 0; }
static void s35390a_work(struct work_struct *work) { struct s35390a *s35390a; struct i2c_client *client; char buf[1]; s35390a = container_of(work, struct s35390a, work); if (!s35390a) return; client = s35390a->client[0]; if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)) < 0) goto out; /* This chip returns the bits of each byte in reverse order */ buf[0] = bitrev8(buf[0]); if (buf[0] & BIT(2)) { /* Notify RTC core on event */ rtc_update_irq(s35390a->rtc, 1, RTC_IRQF | RTC_AF); s35390a_alarm_irq_enable(client, 0); } else if (buf[0] & BIT(0)) { /* Notify RTC core on event */ rtc_update_irq(s35390a->rtc, 1, RTC_PF | RTC_IRQF); } else if (buf[0] & BIT(1)) { /* Notify RTC core on event */ rtc_update_irq(s35390a->rtc, 1, RTC_UF | RTC_IRQF); } enable_irq(client->irq); out: return; }
static int s35390a_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) { return s35390a_alarm_irq_enable(to_i2c_client(dev), enabled); }