Lines Matching +full:vdet +full:- +full:disable
1 // SPDX-License-Identifier: GPL-2.0-only
118 * - we're in the 21st century, so it's safe to ignore the century
120 * - we should use ALARM_A not ALARM_B (may be wrong on some boards)
135 struct i2c_client *client = rs5c->client; in rs5c_get_regs()
138 .addr = client->addr, in rs5c_get_regs()
140 .len = sizeof(rs5c->buf), in rs5c_get_regs()
141 .buf = rs5c->buf in rs5c_get_regs()
152 * The third method on the other hand doesn't work for the SMBus-only in rs5c_get_regs()
156 if (rs5c->smbus) { in rs5c_get_regs()
158 int size = sizeof(rs5c->buf) - 1; in rs5c_get_regs()
161 rs5c->buf + 1) != size) { in rs5c_get_regs()
162 dev_warn(&client->dev, "can't read registers\n"); in rs5c_get_regs()
163 return -EIO; in rs5c_get_regs()
166 if ((i2c_transfer(client->adapter, msgs, 1)) != 1) { in rs5c_get_regs()
167 dev_warn(&client->dev, "can't read registers\n"); in rs5c_get_regs()
168 return -EIO; in rs5c_get_regs()
172 dev_dbg(&client->dev, in rs5c_get_regs()
174 rs5c->regs + 0, rs5c->regs[3], in rs5c_get_regs()
175 rs5c->regs + 4, rs5c->regs[7], in rs5c_get_regs()
176 rs5c->regs + 8, rs5c->regs + 11, in rs5c_get_regs()
177 rs5c->regs[14], rs5c->regs[15]); in rs5c_get_regs()
186 if (rs5c->time24) in rs5c_reg2hr()
199 if (rs5c->time24) in rs5c_hr2reg()
203 return 0x20 | bin2bcd(hour - 12); in rs5c_hr2reg()
216 unsigned char ctrl2 = rs5c->regs[RS5C_REG_CTRL2]; in rs5c372_rtc_read_time()
221 switch (rs5c->type) { in rs5c372_rtc_read_time()
224 if ((rs5c->type == rtc_r2025sd && !(ctrl2 & R2x2x_CTRL2_XSTP)) || in rs5c372_rtc_read_time()
225 (rs5c->type == rtc_r2221tl && (ctrl2 & R2x2x_CTRL2_XSTP))) { in rs5c372_rtc_read_time()
226 dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n"); in rs5c372_rtc_read_time()
227 return -EINVAL; in rs5c372_rtc_read_time()
232 dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n"); in rs5c372_rtc_read_time()
233 return -EINVAL; in rs5c372_rtc_read_time()
237 tm->tm_sec = bcd2bin(rs5c->regs[RS5C372_REG_SECS] & 0x7f); in rs5c372_rtc_read_time()
238 tm->tm_min = bcd2bin(rs5c->regs[RS5C372_REG_MINS] & 0x7f); in rs5c372_rtc_read_time()
239 tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]); in rs5c372_rtc_read_time()
241 tm->tm_wday = bcd2bin(rs5c->regs[RS5C372_REG_WDAY] & 0x07); in rs5c372_rtc_read_time()
242 tm->tm_mday = bcd2bin(rs5c->regs[RS5C372_REG_DAY] & 0x3f); in rs5c372_rtc_read_time()
244 /* tm->tm_mon is zero-based */ in rs5c372_rtc_read_time()
245 tm->tm_mon = bcd2bin(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1; in rs5c372_rtc_read_time()
247 /* year is 1900 + tm->tm_year */ in rs5c372_rtc_read_time()
248 tm->tm_year = bcd2bin(rs5c->regs[RS5C372_REG_YEAR]) + 100; in rs5c372_rtc_read_time()
250 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " in rs5c372_rtc_read_time()
253 tm->tm_sec, tm->tm_min, tm->tm_hour, in rs5c372_rtc_read_time()
254 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); in rs5c372_rtc_read_time()
267 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " in rs5c372_rtc_set_time()
270 tm->tm_sec, tm->tm_min, tm->tm_hour, in rs5c372_rtc_set_time()
271 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); in rs5c372_rtc_set_time()
274 buf[0] = bin2bcd(tm->tm_sec); in rs5c372_rtc_set_time()
275 buf[1] = bin2bcd(tm->tm_min); in rs5c372_rtc_set_time()
276 buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour); in rs5c372_rtc_set_time()
277 buf[3] = bin2bcd(tm->tm_wday); in rs5c372_rtc_set_time()
278 buf[4] = bin2bcd(tm->tm_mday); in rs5c372_rtc_set_time()
279 buf[5] = bin2bcd(tm->tm_mon + 1); in rs5c372_rtc_set_time()
280 buf[6] = bin2bcd(tm->tm_year - 100); in rs5c372_rtc_set_time()
283 dev_dbg(&client->dev, "%s: write error in line %i\n", in rs5c372_rtc_set_time()
285 return -EIO; in rs5c372_rtc_set_time()
292 switch (rs5c->type) { in rs5c372_rtc_set_time()
296 if (rs5c->type == rtc_r2025sd) in rs5c372_rtc_set_time()
307 dev_dbg(&client->dev, "%s: write error in line %i\n", in rs5c372_rtc_set_time()
309 return -EIO; in rs5c372_rtc_set_time()
327 u8 tmp = rs5c372->regs[RS5C372_REG_TRIM]; in rs5c372_get_trim()
330 if (rs5c372->type == rtc_rs5c372a || rs5c372->type == rtc_rs5c372b) in rs5c372_get_trim()
337 dev_dbg(&client->dev, "%s: raw trim=%x\n", __func__, tmp); in rs5c372_get_trim()
345 t = t - 1; in rs5c372_get_trim()
364 buf = rs5c->regs[RS5C_REG_CTRL1]; in rs5c_rtc_alarm_irq_enable()
366 if (!rs5c->has_irq) in rs5c_rtc_alarm_irq_enable()
367 return -EINVAL; in rs5c_rtc_alarm_irq_enable()
381 status = -EIO; in rs5c_rtc_alarm_irq_enable()
383 rs5c->regs[RS5C_REG_CTRL1] = buf; in rs5c_rtc_alarm_irq_enable()
409 t->time.tm_sec = 0; in rs5c_read_alarm()
410 t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); in rs5c_read_alarm()
411 t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); in rs5c_read_alarm()
414 t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); in rs5c_read_alarm()
415 t->pending = !!(rs5c->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_AAFG); in rs5c_read_alarm()
428 if (t->time.tm_mday != -1 in rs5c_set_alarm()
429 || t->time.tm_mon != -1 in rs5c_set_alarm()
430 || t->time.tm_year != -1) in rs5c_set_alarm()
431 return -EINVAL; in rs5c_set_alarm()
435 /* if needed, disable irq (clears pending status) */ in rs5c_set_alarm()
439 if (rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE) { in rs5c_set_alarm()
441 buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; in rs5c_set_alarm()
443 dev_dbg(dev, "can't disable alarm\n"); in rs5c_set_alarm()
444 return -EIO; in rs5c_set_alarm()
446 rs5c->regs[RS5C_REG_CTRL1] = buf[0]; in rs5c_set_alarm()
450 buf[0] = bin2bcd(t->time.tm_min); in rs5c_set_alarm()
451 buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); in rs5c_set_alarm()
458 return -EIO; in rs5c_set_alarm()
463 if (t->enabled) { in rs5c_set_alarm()
465 buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; in rs5c_set_alarm()
468 rs5c->regs[RS5C_REG_CTRL1] = buf[0]; in rs5c_set_alarm()
505 ctrl2 = i2c_smbus_read_byte_data(rs5c->client, addr); in rs5c372_ioctl()
511 switch (rs5c->type) { in rs5c372_ioctl()
514 if ((rs5c->type == rtc_r2025sd && !(ctrl2 & R2x2x_CTRL2_XSTP)) || in rs5c372_ioctl()
515 (rs5c->type == rtc_r2221tl && (ctrl2 & R2x2x_CTRL2_XSTP))) { in rs5c372_ioctl()
529 /* clear VDET bit */ in rs5c372_ioctl()
530 if (rs5c->type == rtc_r2025sd || rs5c->type == rtc_r2221tl) { in rs5c372_ioctl()
532 if (i2c_smbus_write_byte_data(rs5c->client, addr, ctrl2) < 0) { in rs5c372_ioctl()
533 dev_dbg(&rs5c->client->dev, "%s: write error in line %i\n", in rs5c372_ioctl()
535 return -EIO; in rs5c372_ioctl()
540 return -ENOIOCTLCMD; in rs5c372_ioctl()
551 u8 val = rs5c->regs[RS5C372_REG_TRIM]; in rs5c372_read_offset()
555 switch (rs5c->type) { in rs5c372_read_offset()
576 *offset = -(((~val) & 0x3F) + 1) * ppb_per_step; in rs5c372_read_offset()
578 *offset = (val - 1) * ppb_per_step; in rs5c372_read_offset()
593 switch (rs5c->type) { in rs5c372_set_offset()
596 tmp = rs5c->regs[RS5C372_REG_TRIM]; in rs5c372_set_offset()
609 if (steps >= -0x3E && steps <= 0x3E) { in rs5c372_set_offset()
628 if (steps > 0x3E || steps < -0x3E) in rs5c372_set_offset()
629 return -ERANGE; in rs5c372_set_offset()
636 val |= (~(-steps - 1)) & 0x3F; in rs5c372_set_offset()
646 if (rs5c->type == rtc_rs5c372a || rs5c->type == rtc_rs5c372b) in rs5c372_set_offset()
652 dev_dbg(&rs5c->client->dev, "write 0x%x for offset %ld\n", val, offset); in rs5c372_set_offset()
654 if (i2c_smbus_write_byte_data(rs5c->client, addr, val) < 0) { in rs5c372_set_offset()
655 dev_err(&rs5c->client->dev, "failed to write 0x%x to reg %d\n", val, addr); in rs5c372_set_offset()
656 return -EIO; in rs5c372_set_offset()
659 rs5c->regs[RS5C372_REG_TRIM] = val; in rs5c372_set_offset()
744 buf[0] = rs5c372->regs[RS5C_REG_CTRL1]; in rs5c_oscillator_setup()
745 buf[1] = rs5c372->regs[RS5C_REG_CTRL2]; in rs5c_oscillator_setup()
747 switch (rs5c372->type) { in rs5c_oscillator_setup()
763 switch (rs5c372->type) { in rs5c_oscillator_setup()
767 rs5c372->time24 = 1; in rs5c_oscillator_setup()
774 rs5c372->time24 = 1; in rs5c_oscillator_setup()
783 ret = i2c_smbus_write_byte_data(rs5c372->client, addr, buf[i]); in rs5c_oscillator_setup()
788 rs5c372->regs[RS5C_REG_CTRL1] = buf[0]; in rs5c_oscillator_setup()
789 rs5c372->regs[RS5C_REG_CTRL2] = buf[1]; in rs5c_oscillator_setup()
800 dev_dbg(&client->dev, "%s\n", __func__); in rs5c372_probe()
802 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | in rs5c372_probe()
808 if (i2c_check_functionality(client->adapter, in rs5c372_probe()
814 err = -ENODEV; in rs5c372_probe()
819 rs5c372 = devm_kzalloc(&client->dev, sizeof(struct rs5c372), in rs5c372_probe()
822 err = -ENOMEM; in rs5c372_probe()
826 rs5c372->client = client; in rs5c372_probe()
828 if (client->dev.of_node) { in rs5c372_probe()
829 rs5c372->type = (uintptr_t)of_device_get_match_data(&client->dev); in rs5c372_probe()
832 rs5c372->type = id->driver_data; in rs5c372_probe()
835 /* we read registers 0x0f then 0x00-0x0f; skip the first one */ in rs5c372_probe()
836 rs5c372->regs = &rs5c372->buf[1]; in rs5c372_probe()
837 rs5c372->smbus = smbus_mode; in rs5c372_probe()
844 switch (rs5c372->type) { in rs5c372_probe()
850 if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24) in rs5c372_probe()
851 rs5c372->time24 = 1; in rs5c372_probe()
857 if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24) in rs5c372_probe()
858 rs5c372->time24 = 1; in rs5c372_probe()
864 dev_err(&client->dev, "unknown RTC type\n"); in rs5c372_probe()
876 dev_err(&client->dev, "setup error\n"); in rs5c372_probe()
880 dev_info(&client->dev, "%s found, %s\n", in rs5c372_probe()
881 ({ char *s; switch (rs5c372->type) { in rs5c372_probe()
890 rs5c372->time24 ? "24hr" : "am/pm" in rs5c372_probe()
893 /* REVISIT use client->irq to register alarm irq ... */ in rs5c372_probe()
894 rs5c372->rtc = devm_rtc_device_register(&client->dev, in rs5c372_probe()
898 if (IS_ERR(rs5c372->rtc)) { in rs5c372_probe()
899 err = PTR_ERR(rs5c372->rtc); in rs5c372_probe()
903 err = rs5c_sysfs_register(&client->dev); in rs5c372_probe()
915 rs5c_sysfs_unregister(&client->dev); in rs5c372_remove()
920 .name = "rtc-rs5c372",
933 "Paul Mundt <lethal@linux-sh.org>");