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>
107 #define RV3029_CONTROL_E2P_XOFFS_SIGN BIT(7) /* Sign: 1->pos, 0->neg */
128 for (i = 100; i > 0; i--) { in rv3029_eeprom_busywait()
129 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_eeprom_busywait()
137 dev_err(rv3029->dev, "EEPROM busy wait timeout.\n"); in rv3029_eeprom_busywait()
138 return -ETIMEDOUT; in rv3029_eeprom_busywait()
146 /* Re-enable eeprom refresh */ in rv3029_eeprom_exit()
147 return regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL, in rv3029_eeprom_exit()
158 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_eeprom_enter()
162 return -ENODEV; in rv3029_eeprom_enter()
167 ret = regmap_update_bits(rv3029->regmap, RV3029_STATUS, in rv3029_eeprom_enter()
172 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_eeprom_enter()
176 dev_err(rv3029->dev, in rv3029_eeprom_enter()
177 "Supply voltage is too low to safely access the EEPROM.\n"); in rv3029_eeprom_enter()
178 return -ENODEV; in rv3029_eeprom_enter()
183 ret = regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL, in rv3029_eeprom_enter()
205 ret = regmap_bulk_read(rv3029->regmap, reg, buf, len); in rv3029_eeprom_read()
226 ret = regmap_read(rv3029->regmap, reg, &tmp); in rv3029_eeprom_write()
231 ret = regmap_write(rv3029->regmap, reg, tmp); in rv3029_eeprom_write()
273 rtc_lock(rv3029->rtc); in rv3029_handle_irq()
275 ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls); in rv3029_handle_irq()
278 rtc_unlock(rv3029->rtc); in rv3029_handle_irq()
282 ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags); in rv3029_handle_irq()
285 rtc_unlock(rv3029->rtc); in rv3029_handle_irq()
296 rtc_update_irq(rv3029->rtc, 1, events); in rv3029_handle_irq()
297 regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags); in rv3029_handle_irq()
298 regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls); in rv3029_handle_irq()
300 rtc_unlock(rv3029->rtc); in rv3029_handle_irq()
312 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_read_time()
317 return -EINVAL; in rv3029_read_time()
319 ret = regmap_bulk_read(rv3029->regmap, RV3029_W_SEC, regs, in rv3029_read_time()
324 tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]); in rv3029_read_time()
325 tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]); in rv3029_read_time()
329 const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC]; in rv3029_read_time()
333 tm->tm_hour = bcd2bin(_hr & 0x1f); in rv3029_read_time()
335 tm->tm_hour += 12; in rv3029_read_time()
337 tm->tm_hour = bcd2bin(_hr & 0x3f); in rv3029_read_time()
340 tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]); in rv3029_read_time()
341 tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1; in rv3029_read_time()
342 tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 100; in rv3029_read_time()
343 tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1; in rv3029_read_time()
351 struct rtc_time *const tm = &alarm->time; in rv3029_read_alarm()
356 ret = regmap_bulk_read(rv3029->regmap, RV3029_A_SC, regs, in rv3029_read_alarm()
361 ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls); in rv3029_read_alarm()
365 ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags); in rv3029_read_alarm()
369 tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f); in rv3029_read_alarm()
370 tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f); in rv3029_read_alarm()
371 tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f); in rv3029_read_alarm()
372 tm->tm_mday = bcd2bin(regs[RV3029_A_DT - RV3029_A_SC] & 0x3f); in rv3029_read_alarm()
373 tm->tm_mon = bcd2bin(regs[RV3029_A_MO - RV3029_A_SC] & 0x1f) - 1; in rv3029_read_alarm()
374 tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100; in rv3029_read_alarm()
375 tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1; in rv3029_read_alarm()
377 alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE); in rv3029_read_alarm()
378 alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled; in rv3029_read_alarm()
387 return regmap_update_bits(rv3029->regmap, RV3029_IRQ_CTRL, in rv3029_alarm_irq_enable()
395 struct rtc_time *const tm = &alarm->time; in rv3029_set_alarm()
400 regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X; in rv3029_set_alarm()
401 regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X; in rv3029_set_alarm()
402 regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour) & 0x3f) in rv3029_set_alarm()
404 regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday) & 0x3f) in rv3029_set_alarm()
406 regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd(tm->tm_mon + 1) & 0x1f) in rv3029_set_alarm()
408 regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd(tm->tm_wday + 1) & 0x7) in rv3029_set_alarm()
410 regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd(tm->tm_year - 100)) in rv3029_set_alarm()
414 ret = regmap_bulk_write(rv3029->regmap, RV3029_A_SC, regs, in rv3029_set_alarm()
419 return rv3029_alarm_irq_enable(dev, alarm->enabled); in rv3029_set_alarm()
428 regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec); in rv3029_set_time()
429 regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min); in rv3029_set_time()
430 regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour); in rv3029_set_time()
431 regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday); in rv3029_set_time()
432 regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1); in rv3029_set_time()
433 regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7; in rv3029_set_time()
434 regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100); in rv3029_set_time()
436 ret = regmap_bulk_write(rv3029->regmap, RV3029_W_SEC, regs, in rv3029_set_time()
442 return regmap_update_bits(rv3029->regmap, RV3029_STATUS, in rv3029_set_time()
449 unsigned long vl = 0; in rv3029_ioctl() local
454 ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr); in rv3029_ioctl()
459 vl = RTC_VL_ACCURACY_LOW; in rv3029_ioctl()
462 vl |= RTC_VL_DATA_INVALID; in rv3029_ioctl()
464 return put_user(vl, (unsigned int __user *)arg); in rv3029_ioctl()
467 return regmap_update_bits(rv3029->regmap, RV3029_STATUS, in rv3029_ioctl()
471 return -ENOIOCTLCMD; in rv3029_ioctl()
547 struct device_node *of_node = dev->of_node; in rv3029_trickle_config()
557 err = of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms); in rv3029_trickle_config()
565 if (elem->r >= ohms) in rv3029_trickle_config()
568 trickle_set_bits = elem->conf; in rv3029_trickle_config()
571 elem->r); in rv3029_trickle_config()
587 ret = regmap_read(rv3029->regmap, RV3029_TEMP_PAGE, &temp); in rv3029_read_temp()
591 *temp_mC = ((int)temp - 60) * 1000; in rv3029_read_temp()
723 return -ENOMEM; in rv3029_probe()
725 rv3029->regmap = regmap; in rv3029_probe()
726 rv3029->irq = irq; in rv3029_probe()
727 rv3029->dev = dev; in rv3029_probe()
733 rv3029->rtc = devm_rtc_allocate_device(dev); in rv3029_probe()
734 if (IS_ERR(rv3029->rtc)) in rv3029_probe()
735 return PTR_ERR(rv3029->rtc); in rv3029_probe()
737 if (rv3029->irq > 0) { in rv3029_probe()
743 rc = devm_request_threaded_irq(dev, rv3029->irq, in rv3029_probe()
749 rv3029->irq = 0; in rv3029_probe()
752 if (!rv3029->irq) in rv3029_probe()
753 clear_bit(RTC_FEATURE_ALARM, rv3029->rtc->features); in rv3029_probe()
755 rv3029->rtc->ops = &rv3029_rtc_ops; in rv3029_probe()
756 rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; in rv3029_probe()
757 rv3029->rtc->range_max = RTC_TIMESTAMP_END_2079; in rv3029_probe()
759 rc = devm_rtc_register_device(rv3029->rtc); in rv3029_probe()
763 nvmem_cfg.priv = rv3029->regmap; in rv3029_probe()
764 devm_rtc_nvmem_register(rv3029->rtc, &nvmem_cfg); in rv3029_probe()
796 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK | in rv3029_i2c_probe()
798 dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n"); in rv3029_i2c_probe()
799 return -ENODEV; in rv3029_i2c_probe()
806 return rv3029_probe(&client->dev, regmap, client->irq, client->name); in rv3029_i2c_probe()
864 return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049"); in rv3049_probe()
920 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");