Lines Matching +full:vl +full:- +full:supply

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Micro Crystal RV-3029 / RV-3049 rtc class driver
5 * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
19 #include <linux/hwmon-sysfs.h>
106 #define RV3029_CONTROL_E2P_XOFFS_SIGN BIT(7) /* Sign: 1->pos, 0->neg */
127 for (i = 100; i > 0; i--) { in rv3029_eeprom_busywait()
128 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_eeprom_busywait()
136 dev_err(rv3029->dev, "EEPROM busy wait timeout.\n"); in rv3029_eeprom_busywait()
137 return -ETIMEDOUT; in rv3029_eeprom_busywait()
145 /* Re-enable eeprom refresh */ in rv3029_eeprom_exit()
146 return regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL, in rv3029_eeprom_exit()
157 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_eeprom_enter()
161 return -ENODEV; in rv3029_eeprom_enter()
166 ret = regmap_update_bits(rv3029->regmap, RV3029_STATUS, in rv3029_eeprom_enter()
171 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_eeprom_enter()
175 dev_err(rv3029->dev, in rv3029_eeprom_enter()
176 "Supply voltage is too low to safely access the EEPROM.\n"); in rv3029_eeprom_enter()
177 return -ENODEV; in rv3029_eeprom_enter()
182 ret = regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL, in rv3029_eeprom_enter()
204 ret = regmap_bulk_read(rv3029->regmap, reg, buf, len); in rv3029_eeprom_read()
225 ret = regmap_read(rv3029->regmap, reg, &tmp); in rv3029_eeprom_write()
230 ret = regmap_write(rv3029->regmap, reg, tmp); in rv3029_eeprom_write()
272 rtc_lock(rv3029->rtc); in rv3029_handle_irq()
274 ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls); in rv3029_handle_irq()
277 rtc_unlock(rv3029->rtc); in rv3029_handle_irq()
281 ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags); in rv3029_handle_irq()
284 rtc_unlock(rv3029->rtc); in rv3029_handle_irq()
295 rtc_update_irq(rv3029->rtc, 1, events); in rv3029_handle_irq()
296 regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags); in rv3029_handle_irq()
297 regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls); in rv3029_handle_irq()
299 rtc_unlock(rv3029->rtc); in rv3029_handle_irq()
311 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_read_time()
316 return -EINVAL; in rv3029_read_time()
318 ret = regmap_bulk_read(rv3029->regmap, RV3029_W_SEC, regs, in rv3029_read_time()
323 tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]); in rv3029_read_time()
324 tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]); in rv3029_read_time()
328 const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC]; in rv3029_read_time()
332 tm->tm_hour = bcd2bin(_hr & 0x1f); in rv3029_read_time()
334 tm->tm_hour += 12; in rv3029_read_time()
336 tm->tm_hour = bcd2bin(_hr & 0x3f); in rv3029_read_time()
339 tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]); in rv3029_read_time()
340 tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1; in rv3029_read_time()
341 tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 100; in rv3029_read_time()
342 tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1; in rv3029_read_time()
350 struct rtc_time *const tm = &alarm->time; in rv3029_read_alarm()
355 ret = regmap_bulk_read(rv3029->regmap, RV3029_A_SC, regs, in rv3029_read_alarm()
360 ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls); in rv3029_read_alarm()
364 ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags); in rv3029_read_alarm()
368 tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f); in rv3029_read_alarm()
369 tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f); in rv3029_read_alarm()
370 tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f); in rv3029_read_alarm()
371 tm->tm_mday = bcd2bin(regs[RV3029_A_DT - RV3029_A_SC] & 0x3f); in rv3029_read_alarm()
372 tm->tm_mon = bcd2bin(regs[RV3029_A_MO - RV3029_A_SC] & 0x1f) - 1; in rv3029_read_alarm()
373 tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100; in rv3029_read_alarm()
374 tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1; in rv3029_read_alarm()
376 alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE); in rv3029_read_alarm()
377 alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled; in rv3029_read_alarm()
386 return regmap_update_bits(rv3029->regmap, RV3029_IRQ_CTRL, in rv3029_alarm_irq_enable()
394 struct rtc_time *const tm = &alarm->time; in rv3029_set_alarm()
399 regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X; in rv3029_set_alarm()
400 regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X; in rv3029_set_alarm()
401 regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour) & 0x3f) in rv3029_set_alarm()
403 regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday) & 0x3f) in rv3029_set_alarm()
405 regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd(tm->tm_mon + 1) & 0x1f) in rv3029_set_alarm()
407 regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd(tm->tm_wday + 1) & 0x7) in rv3029_set_alarm()
409 regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd(tm->tm_year - 100)) in rv3029_set_alarm()
413 ret = regmap_bulk_write(rv3029->regmap, RV3029_A_SC, regs, in rv3029_set_alarm()
418 return rv3029_alarm_irq_enable(dev, alarm->enabled); in rv3029_set_alarm()
427 regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec); in rv3029_set_time()
428 regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min); in rv3029_set_time()
429 regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour); in rv3029_set_time()
430 regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday); in rv3029_set_time()
431 regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1); in rv3029_set_time()
432 regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7; in rv3029_set_time()
433 regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100); in rv3029_set_time()
435 ret = regmap_bulk_write(rv3029->regmap, RV3029_W_SEC, regs, in rv3029_set_time()
441 return regmap_update_bits(rv3029->regmap, RV3029_STATUS, in rv3029_set_time()
448 unsigned long vl = 0; in rv3029_ioctl() local
453 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_ioctl()
458 vl = RTC_VL_ACCURACY_LOW; in rv3029_ioctl()
461 vl |= RTC_VL_DATA_INVALID; in rv3029_ioctl()
463 return put_user(vl, (unsigned int __user *)arg); in rv3029_ioctl()
466 return regmap_update_bits(rv3029->regmap, RV3029_STATUS, in rv3029_ioctl()
470 return -ENOIOCTLCMD; in rv3029_ioctl()
546 struct device_node *of_node = dev->of_node; in rv3029_trickle_config()
556 err = of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms); in rv3029_trickle_config()
564 if (elem->r >= ohms) in rv3029_trickle_config()
567 trickle_set_bits = elem->conf; in rv3029_trickle_config()
570 elem->r); in rv3029_trickle_config()
586 ret = regmap_read(rv3029->regmap, RV3029_TEMP_PAGE, &temp); in rv3029_read_temp()
590 *temp_mC = ((int)temp - 60) * 1000; in rv3029_read_temp()
722 return -ENOMEM; in rv3029_probe()
724 rv3029->regmap = regmap; in rv3029_probe()
725 rv3029->irq = irq; in rv3029_probe()
726 rv3029->dev = dev; in rv3029_probe()
732 rv3029->rtc = devm_rtc_allocate_device(dev); in rv3029_probe()
733 if (IS_ERR(rv3029->rtc)) in rv3029_probe()
734 return PTR_ERR(rv3029->rtc); in rv3029_probe()
736 if (rv3029->irq > 0) { in rv3029_probe()
737 rc = devm_request_threaded_irq(dev, rv3029->irq, in rv3029_probe()
743 rv3029->irq = 0; in rv3029_probe()
746 if (!rv3029->irq) in rv3029_probe()
747 clear_bit(RTC_FEATURE_ALARM, rv3029->rtc->features); in rv3029_probe()
749 rv3029->rtc->ops = &rv3029_rtc_ops; in rv3029_probe()
750 rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; in rv3029_probe()
751 rv3029->rtc->range_max = RTC_TIMESTAMP_END_2079; in rv3029_probe()
753 rc = devm_rtc_register_device(rv3029->rtc); in rv3029_probe()
757 nvmem_cfg.priv = rv3029->regmap; in rv3029_probe()
758 devm_rtc_nvmem_register(rv3029->rtc, &nvmem_cfg); in rv3029_probe()
790 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK | in rv3029_i2c_probe()
792 dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n"); in rv3029_i2c_probe()
793 return -ENODEV; in rv3029_i2c_probe()
800 return rv3029_probe(&client->dev, regmap, client->irq, client->name); in rv3029_i2c_probe()
858 return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049"); in rv3049_probe()
914 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");