// SPDX-License-Identifier: GPL-2.0-only /* * NVIDIA Voltage Regulator Specification RTC * * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. * All rights reserved. */ #include #include #include #include #include #include #define NVVRS_REG_VENDOR_ID 0x00 #define NVVRS_REG_MODEL_REV 0x01 /* Interrupts registers */ #define NVVRS_REG_INT_SRC1 0x10 #define NVVRS_REG_INT_SRC2 0x11 #define NVVRS_REG_INT_VENDOR 0x12 /* Control Registers */ #define NVVRS_REG_CTL_1 0x28 #define NVVRS_REG_CTL_2 0x29 /* RTC Registers */ #define NVVRS_REG_RTC_T3 0x70 #define NVVRS_REG_RTC_T2 0x71 #define NVVRS_REG_RTC_T1 0x72 #define NVVRS_REG_RTC_T0 0x73 #define NVVRS_REG_RTC_A3 0x74 #define NVVRS_REG_RTC_A2 0x75 #define NVVRS_REG_RTC_A1 0x76 #define NVVRS_REG_RTC_A0 0x77 /* Interrupt Mask */ #define NVVRS_INT_SRC1_RSTIRQ_MASK BIT(0) #define NVVRS_INT_SRC1_OSC_MASK BIT(1) #define NVVRS_INT_SRC1_EN_MASK BIT(2) #define NVVRS_INT_SRC1_RTC_MASK BIT(3) #define NVVRS_INT_SRC1_PEC_MASK BIT(4) #define NVVRS_INT_SRC1_WDT_MASK BIT(5) #define NVVRS_INT_SRC1_EM_PD_MASK BIT(6) #define NVVRS_INT_SRC1_INTERNAL_MASK BIT(7) #define NVVRS_INT_SRC2_PBSP_MASK BIT(0) #define NVVRS_INT_SRC2_ECC_DED_MASK BIT(1) #define NVVRS_INT_SRC2_TSD_MASK BIT(2) #define NVVRS_INT_SRC2_LDO_MASK BIT(3) #define NVVRS_INT_SRC2_BIST_MASK BIT(4) #define NVVRS_INT_SRC2_RT_CRC_MASK BIT(5) #define NVVRS_INT_SRC2_VENDOR_MASK BIT(7) #define NVVRS_INT_VENDOR0_MASK BIT(0) #define NVVRS_INT_VENDOR1_MASK BIT(1) #define NVVRS_INT_VENDOR2_MASK BIT(2) #define NVVRS_INT_VENDOR3_MASK BIT(3) #define NVVRS_INT_VENDOR4_MASK BIT(4) #define NVVRS_INT_VENDOR5_MASK BIT(5) #define NVVRS_INT_VENDOR6_MASK BIT(6) #define NVVRS_INT_VENDOR7_MASK BIT(7) /* Controller Register Mask */ #define NVVRS_REG_CTL_1_FORCE_SHDN (BIT(0) | BIT(1)) #define NVVRS_REG_CTL_1_FORCE_ACT BIT(2) #define NVVRS_REG_CTL_1_FORCE_INT BIT(3) #define NVVRS_REG_CTL_2_EN_PEC BIT(0) #define NVVRS_REG_CTL_2_REQ_PEC BIT(1) #define NVVRS_REG_CTL_2_RTC_PU BIT(2) #define NVVRS_REG_CTL_2_RTC_WAKE BIT(3) #define NVVRS_REG_CTL_2_RST_DLY 0xF0 #define ALARM_RESET_VAL 0xffffffff #define NVVRS_MIN_MODEL_REV 0x40 enum nvvrs_irq_regs { NVVRS_IRQ_REG_INT_SRC1 = 0, NVVRS_IRQ_REG_INT_SRC2 = 1, NVVRS_IRQ_REG_INT_VENDOR = 2, NVVRS_IRQ_REG_COUNT = 3, }; struct nvvrs_rtc_info { struct device *dev; struct i2c_client *client; struct rtc_device *rtc; unsigned int irq; }; static int nvvrs_update_bits(struct nvvrs_rtc_info *info, u8 reg, u8 mask, u8 value) { int ret; u8 val; ret = i2c_smbus_read_byte_data(info->client, reg); if (ret < 0) return ret; val = (u8)ret; val &= ~mask; val |= (value & mask); return i2c_smbus_write_byte_data(info->client, reg, val); } static int nvvrs_rtc_write_alarm(struct i2c_client *client, u8 *time) { int ret; ret = i2c_smbus_write_byte_data(client, NVVRS_REG_RTC_A3, time[3]); if (ret < 0) return ret; ret = i2c_smbus_write_byte_data(client, NVVRS_REG_RTC_A2, time[2]); if (ret < 0) return ret; ret = i2c_smbus_write_byte_data(client, NVVRS_REG_RTC_A1, time[1]); if (ret < 0) return ret; return i2c_smbus_write_byte_data(client, NVVRS_REG_RTC_A0, time[0]); } static int nvvrs_rtc_enable_alarm(struct nvvrs_rtc_info *info) { int ret; /* Set RTC_WAKE bit for autonomous wake from sleep */ ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_WAKE, NVVRS_REG_CTL_2_RTC_WAKE); if (ret < 0) return ret; /* Set RTC_PU bit for autonomous wake from shutdown */ ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_PU, NVVRS_REG_CTL_2_RTC_PU); if (ret < 0) return ret; return 0; } static int nvvrs_rtc_disable_alarm(struct nvvrs_rtc_info *info) { struct i2c_client *client = info->client; u8 val[4]; int ret; /* Clear RTC_WAKE bit */ ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_WAKE, 0); if (ret < 0) return ret; /* Clear RTC_PU bit */ ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_PU, 0); if (ret < 0) return ret; /* Write ALARM_RESET_VAL in RTC Alarm register to disable alarm */ val[0] = 0xff; val[1] = 0xff; val[2] = 0xff; val[3] = 0xff; ret = nvvrs_rtc_write_alarm(client, val); if (ret < 0) return ret; return 0; } static int nvvrs_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct nvvrs_rtc_info *info = dev_get_drvdata(dev); time64_t secs = 0; int ret; u8 val; /* * Multi-byte transfers are not supported with PEC enabled * Read MSB first to avoid coherency issues */ ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_T3); if (ret < 0) return ret; val = (u8)ret; secs |= (time64_t)val << 24; ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_T2); if (ret < 0) return ret; val = (u8)ret; secs |= (time64_t)val << 16; ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_T1); if (ret < 0) return ret; val = (u8)ret; secs |= (time64_t)val << 8; ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_T0); if (ret < 0) return ret; val = (u8)ret; secs |= val; rtc_time64_to_tm(secs, tm); return 0; } static int nvvrs_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct nvvrs_rtc_info *info = dev_get_drvdata(dev); time64_t secs; u8 time[4]; int ret; secs = rtc_tm_to_time64(tm); time[0] = secs & 0xff; time[1] = (secs >> 8) & 0xff; time[2] = (secs >> 16) & 0xff; time[3] = (secs >> 24) & 0xff; ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_RTC_T3, time[3]); if (ret < 0) return ret; ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_RTC_T2, time[2]); if (ret < 0) return ret; ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_RTC_T1, time[1]); if (ret < 0) return ret; ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_RTC_T0, time[0]); return ret; } static int nvvrs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct nvvrs_rtc_info *info = dev_get_drvdata(dev); time64_t alarm_val = 0; int ret; u8 val; /* Multi-byte transfers are not supported with PEC enabled */ ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_A3); if (ret < 0) return ret; val = (u8)ret; alarm_val |= (time64_t)val << 24; ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_A2); if (ret < 0) return ret; val = (u8)ret; alarm_val |= (time64_t)val << 16; ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_A1); if (ret < 0) return ret; val = (u8)ret; alarm_val |= (time64_t)val << 8; ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_A0); if (ret < 0) return ret; val = (u8)ret; alarm_val |= val; if (alarm_val == ALARM_RESET_VAL) alrm->enabled = 0; else alrm->enabled = 1; rtc_time64_to_tm(alarm_val, &alrm->time); return 0; } static int nvvrs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct nvvrs_rtc_info *info = dev_get_drvdata(dev); time64_t secs; u8 time[4]; int ret; if (!alrm->enabled) { ret = nvvrs_rtc_disable_alarm(info); if (ret < 0) return ret; } ret = nvvrs_rtc_enable_alarm(info); if (ret < 0) return ret; secs = rtc_tm_to_time64(&alrm->time); time[0] = secs & 0xff; time[1] = (secs >> 8) & 0xff; time[2] = (secs >> 16) & 0xff; time[3] = (secs >> 24) & 0xff; ret = nvvrs_rtc_write_alarm(info->client, time); return ret; } static int nvvrs_pseq_irq_clear(struct nvvrs_rtc_info *info) { unsigned int i; int ret; for (i = 0; i < NVVRS_IRQ_REG_COUNT; i++) { ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_INT_SRC1 + i); if (ret < 0) { dev_err(info->dev, "Failed to read INT_SRC%d : %d\n", i + 1, ret); return ret; } ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_INT_SRC1 + i, (u8)ret); if (ret < 0) { dev_err(info->dev, "Failed to clear INT_SRC%d : %d\n", i + 1, ret); return ret; } } return 0; } static irqreturn_t nvvrs_rtc_irq_handler(int irq, void *data) { struct nvvrs_rtc_info *info = data; int ret; /* Check for RTC alarm interrupt */ ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_INT_SRC1); if (ret < 0) return IRQ_NONE; if (ret & NVVRS_INT_SRC1_RTC_MASK) { rtc_lock(info->rtc); rtc_update_irq(info->rtc, 1, RTC_IRQF | RTC_AF); rtc_unlock(info->rtc); } /* Clear all interrupts */ if (nvvrs_pseq_irq_clear(info) < 0) return IRQ_NONE; return IRQ_HANDLED; } static int nvvrs_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { /* * This hardware does not support enabling/disabling the alarm IRQ * independently. The alarm is disabled by clearing the alarm time * via set_alarm(). */ return 0; } static const struct rtc_class_ops nvvrs_rtc_ops = { .read_time = nvvrs_rtc_read_time, .set_time = nvvrs_rtc_set_time, .read_alarm = nvvrs_rtc_read_alarm, .set_alarm = nvvrs_rtc_set_alarm, .alarm_irq_enable = nvvrs_rtc_alarm_irq_enable, }; static int nvvrs_pseq_vendor_info(struct nvvrs_rtc_info *info) { struct i2c_client *client = info->client; u8 vendor_id, model_rev; int ret; ret = i2c_smbus_read_byte_data(client, NVVRS_REG_VENDOR_ID); if (ret < 0) return dev_err_probe(&client->dev, ret, "Failed to read Vendor ID\n"); vendor_id = (u8)ret; ret = i2c_smbus_read_byte_data(client, NVVRS_REG_MODEL_REV); if (ret < 0) return dev_err_probe(&client->dev, ret, "Failed to read Model Revision\n"); model_rev = (u8)ret; if (model_rev < NVVRS_MIN_MODEL_REV) { return dev_err_probe(&client->dev, -ENODEV, "Chip revision 0x%02x is not supported!\n", model_rev); } dev_dbg(&client->dev, "NVVRS Vendor ID: 0x%02x, Model Rev: 0x%02x\n", vendor_id, model_rev); return 0; } static int nvvrs_rtc_probe(struct i2c_client *client) { struct nvvrs_rtc_info *info; int ret; info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; if (client->irq <= 0) return dev_err_probe(&client->dev, -EINVAL, "No IRQ specified\n"); info->irq = client->irq; info->dev = &client->dev; client->flags |= I2C_CLIENT_PEC; i2c_set_clientdata(client, info); info->client = client; /* Check vendor info */ if (nvvrs_pseq_vendor_info(info) < 0) return dev_err_probe(&client->dev, -EINVAL, "Failed to get vendor info\n"); /* Clear any pending IRQs before requesting IRQ handler */ if (nvvrs_pseq_irq_clear(info) < 0) return dev_err_probe(&client->dev, -EINVAL, "Failed to clear interrupts\n"); /* Allocate RTC device */ info->rtc = devm_rtc_allocate_device(info->dev); if (IS_ERR(info->rtc)) return PTR_ERR(info->rtc); info->rtc->ops = &nvvrs_rtc_ops; info->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; info->rtc->range_max = RTC_TIMESTAMP_END_2099; /* Request RTC IRQ */ ret = devm_request_threaded_irq(info->dev, info->irq, NULL, nvvrs_rtc_irq_handler, IRQF_ONESHOT, "nvvrs-rtc", info); if (ret < 0) { dev_err_probe(info->dev, ret, "Failed to request RTC IRQ\n"); return ret; } /* RTC as a wakeup source */ devm_device_init_wakeup(info->dev); return devm_rtc_register_device(info->rtc); } #ifdef CONFIG_PM_SLEEP static int nvvrs_rtc_suspend(struct device *dev) { struct nvvrs_rtc_info *info = dev_get_drvdata(dev); int ret; if (device_may_wakeup(dev)) { /* Set RTC_WAKE bit for auto wake system from suspend state */ ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_WAKE, NVVRS_REG_CTL_2_RTC_WAKE); if (ret < 0) { dev_err(info->dev, "Failed to set RTC_WAKE bit (%d)\n", ret); return ret; } return enable_irq_wake(info->irq); } return 0; } static int nvvrs_rtc_resume(struct device *dev) { struct nvvrs_rtc_info *info = dev_get_drvdata(dev); int ret; if (device_may_wakeup(dev)) { /* Clear FORCE_ACT bit */ ret = nvvrs_update_bits(info, NVVRS_REG_CTL_1, NVVRS_REG_CTL_1_FORCE_ACT, 0); if (ret < 0) { dev_err(info->dev, "Failed to clear FORCE_ACT bit (%d)\n", ret); return ret; } return disable_irq_wake(info->irq); } return 0; } #endif static SIMPLE_DEV_PM_OPS(nvvrs_rtc_pm_ops, nvvrs_rtc_suspend, nvvrs_rtc_resume); static const struct of_device_id nvvrs_rtc_of_match[] = { { .compatible = "nvidia,vrs-10" }, { }, }; MODULE_DEVICE_TABLE(of, nvvrs_rtc_of_match); static struct i2c_driver nvvrs_rtc_driver = { .driver = { .name = "rtc-nvidia-vrs10", .pm = &nvvrs_rtc_pm_ops, .of_match_table = nvvrs_rtc_of_match, }, .probe = nvvrs_rtc_probe, }; module_i2c_driver(nvvrs_rtc_driver); MODULE_AUTHOR("Shubhi Garg "); MODULE_DESCRIPTION("NVIDIA Voltage Regulator Specification RTC driver"); MODULE_LICENSE("GPL");