1*9d6d6b06SShubhi Garg // SPDX-License-Identifier: GPL-2.0-only
2*9d6d6b06SShubhi Garg /*
3*9d6d6b06SShubhi Garg * NVIDIA Voltage Regulator Specification RTC
4*9d6d6b06SShubhi Garg *
5*9d6d6b06SShubhi Garg * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
6*9d6d6b06SShubhi Garg * All rights reserved.
7*9d6d6b06SShubhi Garg */
8*9d6d6b06SShubhi Garg
9*9d6d6b06SShubhi Garg #include <linux/bits.h>
10*9d6d6b06SShubhi Garg #include <linux/err.h>
11*9d6d6b06SShubhi Garg #include <linux/i2c.h>
12*9d6d6b06SShubhi Garg #include <linux/interrupt.h>
13*9d6d6b06SShubhi Garg #include <linux/module.h>
14*9d6d6b06SShubhi Garg #include <linux/rtc.h>
15*9d6d6b06SShubhi Garg
16*9d6d6b06SShubhi Garg #define NVVRS_REG_VENDOR_ID 0x00
17*9d6d6b06SShubhi Garg #define NVVRS_REG_MODEL_REV 0x01
18*9d6d6b06SShubhi Garg
19*9d6d6b06SShubhi Garg /* Interrupts registers */
20*9d6d6b06SShubhi Garg #define NVVRS_REG_INT_SRC1 0x10
21*9d6d6b06SShubhi Garg #define NVVRS_REG_INT_SRC2 0x11
22*9d6d6b06SShubhi Garg #define NVVRS_REG_INT_VENDOR 0x12
23*9d6d6b06SShubhi Garg
24*9d6d6b06SShubhi Garg /* Control Registers */
25*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_1 0x28
26*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_2 0x29
27*9d6d6b06SShubhi Garg
28*9d6d6b06SShubhi Garg /* RTC Registers */
29*9d6d6b06SShubhi Garg #define NVVRS_REG_RTC_T3 0x70
30*9d6d6b06SShubhi Garg #define NVVRS_REG_RTC_T2 0x71
31*9d6d6b06SShubhi Garg #define NVVRS_REG_RTC_T1 0x72
32*9d6d6b06SShubhi Garg #define NVVRS_REG_RTC_T0 0x73
33*9d6d6b06SShubhi Garg #define NVVRS_REG_RTC_A3 0x74
34*9d6d6b06SShubhi Garg #define NVVRS_REG_RTC_A2 0x75
35*9d6d6b06SShubhi Garg #define NVVRS_REG_RTC_A1 0x76
36*9d6d6b06SShubhi Garg #define NVVRS_REG_RTC_A0 0x77
37*9d6d6b06SShubhi Garg
38*9d6d6b06SShubhi Garg /* Interrupt Mask */
39*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC1_RSTIRQ_MASK BIT(0)
40*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC1_OSC_MASK BIT(1)
41*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC1_EN_MASK BIT(2)
42*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC1_RTC_MASK BIT(3)
43*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC1_PEC_MASK BIT(4)
44*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC1_WDT_MASK BIT(5)
45*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC1_EM_PD_MASK BIT(6)
46*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC1_INTERNAL_MASK BIT(7)
47*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC2_PBSP_MASK BIT(0)
48*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC2_ECC_DED_MASK BIT(1)
49*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC2_TSD_MASK BIT(2)
50*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC2_LDO_MASK BIT(3)
51*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC2_BIST_MASK BIT(4)
52*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC2_RT_CRC_MASK BIT(5)
53*9d6d6b06SShubhi Garg #define NVVRS_INT_SRC2_VENDOR_MASK BIT(7)
54*9d6d6b06SShubhi Garg #define NVVRS_INT_VENDOR0_MASK BIT(0)
55*9d6d6b06SShubhi Garg #define NVVRS_INT_VENDOR1_MASK BIT(1)
56*9d6d6b06SShubhi Garg #define NVVRS_INT_VENDOR2_MASK BIT(2)
57*9d6d6b06SShubhi Garg #define NVVRS_INT_VENDOR3_MASK BIT(3)
58*9d6d6b06SShubhi Garg #define NVVRS_INT_VENDOR4_MASK BIT(4)
59*9d6d6b06SShubhi Garg #define NVVRS_INT_VENDOR5_MASK BIT(5)
60*9d6d6b06SShubhi Garg #define NVVRS_INT_VENDOR6_MASK BIT(6)
61*9d6d6b06SShubhi Garg #define NVVRS_INT_VENDOR7_MASK BIT(7)
62*9d6d6b06SShubhi Garg
63*9d6d6b06SShubhi Garg /* Controller Register Mask */
64*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_1_FORCE_SHDN (BIT(0) | BIT(1))
65*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_1_FORCE_ACT BIT(2)
66*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_1_FORCE_INT BIT(3)
67*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_2_EN_PEC BIT(0)
68*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_2_REQ_PEC BIT(1)
69*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_2_RTC_PU BIT(2)
70*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_2_RTC_WAKE BIT(3)
71*9d6d6b06SShubhi Garg #define NVVRS_REG_CTL_2_RST_DLY 0xF0
72*9d6d6b06SShubhi Garg
73*9d6d6b06SShubhi Garg #define ALARM_RESET_VAL 0xffffffff
74*9d6d6b06SShubhi Garg #define NVVRS_MIN_MODEL_REV 0x40
75*9d6d6b06SShubhi Garg
76*9d6d6b06SShubhi Garg enum nvvrs_irq_regs {
77*9d6d6b06SShubhi Garg NVVRS_IRQ_REG_INT_SRC1 = 0,
78*9d6d6b06SShubhi Garg NVVRS_IRQ_REG_INT_SRC2 = 1,
79*9d6d6b06SShubhi Garg NVVRS_IRQ_REG_INT_VENDOR = 2,
80*9d6d6b06SShubhi Garg NVVRS_IRQ_REG_COUNT = 3,
81*9d6d6b06SShubhi Garg };
82*9d6d6b06SShubhi Garg
83*9d6d6b06SShubhi Garg struct nvvrs_rtc_info {
84*9d6d6b06SShubhi Garg struct device *dev;
85*9d6d6b06SShubhi Garg struct i2c_client *client;
86*9d6d6b06SShubhi Garg struct rtc_device *rtc;
87*9d6d6b06SShubhi Garg unsigned int irq;
88*9d6d6b06SShubhi Garg };
89*9d6d6b06SShubhi Garg
nvvrs_update_bits(struct nvvrs_rtc_info * info,u8 reg,u8 mask,u8 value)90*9d6d6b06SShubhi Garg static int nvvrs_update_bits(struct nvvrs_rtc_info *info, u8 reg,
91*9d6d6b06SShubhi Garg u8 mask, u8 value)
92*9d6d6b06SShubhi Garg {
93*9d6d6b06SShubhi Garg int ret;
94*9d6d6b06SShubhi Garg u8 val;
95*9d6d6b06SShubhi Garg
96*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, reg);
97*9d6d6b06SShubhi Garg if (ret < 0)
98*9d6d6b06SShubhi Garg return ret;
99*9d6d6b06SShubhi Garg
100*9d6d6b06SShubhi Garg val = (u8)ret;
101*9d6d6b06SShubhi Garg val &= ~mask;
102*9d6d6b06SShubhi Garg val |= (value & mask);
103*9d6d6b06SShubhi Garg
104*9d6d6b06SShubhi Garg return i2c_smbus_write_byte_data(info->client, reg, val);
105*9d6d6b06SShubhi Garg }
106*9d6d6b06SShubhi Garg
nvvrs_rtc_write_alarm(struct i2c_client * client,u8 * time)107*9d6d6b06SShubhi Garg static int nvvrs_rtc_write_alarm(struct i2c_client *client, u8 *time)
108*9d6d6b06SShubhi Garg {
109*9d6d6b06SShubhi Garg int ret;
110*9d6d6b06SShubhi Garg
111*9d6d6b06SShubhi Garg ret = i2c_smbus_write_byte_data(client, NVVRS_REG_RTC_A3, time[3]);
112*9d6d6b06SShubhi Garg if (ret < 0)
113*9d6d6b06SShubhi Garg return ret;
114*9d6d6b06SShubhi Garg
115*9d6d6b06SShubhi Garg ret = i2c_smbus_write_byte_data(client, NVVRS_REG_RTC_A2, time[2]);
116*9d6d6b06SShubhi Garg if (ret < 0)
117*9d6d6b06SShubhi Garg return ret;
118*9d6d6b06SShubhi Garg
119*9d6d6b06SShubhi Garg ret = i2c_smbus_write_byte_data(client, NVVRS_REG_RTC_A1, time[1]);
120*9d6d6b06SShubhi Garg if (ret < 0)
121*9d6d6b06SShubhi Garg return ret;
122*9d6d6b06SShubhi Garg
123*9d6d6b06SShubhi Garg return i2c_smbus_write_byte_data(client, NVVRS_REG_RTC_A0, time[0]);
124*9d6d6b06SShubhi Garg }
125*9d6d6b06SShubhi Garg
nvvrs_rtc_enable_alarm(struct nvvrs_rtc_info * info)126*9d6d6b06SShubhi Garg static int nvvrs_rtc_enable_alarm(struct nvvrs_rtc_info *info)
127*9d6d6b06SShubhi Garg {
128*9d6d6b06SShubhi Garg int ret;
129*9d6d6b06SShubhi Garg
130*9d6d6b06SShubhi Garg /* Set RTC_WAKE bit for autonomous wake from sleep */
131*9d6d6b06SShubhi Garg ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_WAKE,
132*9d6d6b06SShubhi Garg NVVRS_REG_CTL_2_RTC_WAKE);
133*9d6d6b06SShubhi Garg if (ret < 0)
134*9d6d6b06SShubhi Garg return ret;
135*9d6d6b06SShubhi Garg
136*9d6d6b06SShubhi Garg /* Set RTC_PU bit for autonomous wake from shutdown */
137*9d6d6b06SShubhi Garg ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_PU,
138*9d6d6b06SShubhi Garg NVVRS_REG_CTL_2_RTC_PU);
139*9d6d6b06SShubhi Garg if (ret < 0)
140*9d6d6b06SShubhi Garg return ret;
141*9d6d6b06SShubhi Garg
142*9d6d6b06SShubhi Garg return 0;
143*9d6d6b06SShubhi Garg }
144*9d6d6b06SShubhi Garg
nvvrs_rtc_disable_alarm(struct nvvrs_rtc_info * info)145*9d6d6b06SShubhi Garg static int nvvrs_rtc_disable_alarm(struct nvvrs_rtc_info *info)
146*9d6d6b06SShubhi Garg {
147*9d6d6b06SShubhi Garg struct i2c_client *client = info->client;
148*9d6d6b06SShubhi Garg u8 val[4];
149*9d6d6b06SShubhi Garg int ret;
150*9d6d6b06SShubhi Garg
151*9d6d6b06SShubhi Garg /* Clear RTC_WAKE bit */
152*9d6d6b06SShubhi Garg ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_WAKE,
153*9d6d6b06SShubhi Garg 0);
154*9d6d6b06SShubhi Garg if (ret < 0)
155*9d6d6b06SShubhi Garg return ret;
156*9d6d6b06SShubhi Garg
157*9d6d6b06SShubhi Garg /* Clear RTC_PU bit */
158*9d6d6b06SShubhi Garg ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2, NVVRS_REG_CTL_2_RTC_PU,
159*9d6d6b06SShubhi Garg 0);
160*9d6d6b06SShubhi Garg if (ret < 0)
161*9d6d6b06SShubhi Garg return ret;
162*9d6d6b06SShubhi Garg
163*9d6d6b06SShubhi Garg /* Write ALARM_RESET_VAL in RTC Alarm register to disable alarm */
164*9d6d6b06SShubhi Garg val[0] = 0xff;
165*9d6d6b06SShubhi Garg val[1] = 0xff;
166*9d6d6b06SShubhi Garg val[2] = 0xff;
167*9d6d6b06SShubhi Garg val[3] = 0xff;
168*9d6d6b06SShubhi Garg
169*9d6d6b06SShubhi Garg ret = nvvrs_rtc_write_alarm(client, val);
170*9d6d6b06SShubhi Garg if (ret < 0)
171*9d6d6b06SShubhi Garg return ret;
172*9d6d6b06SShubhi Garg
173*9d6d6b06SShubhi Garg return 0;
174*9d6d6b06SShubhi Garg }
175*9d6d6b06SShubhi Garg
nvvrs_rtc_read_time(struct device * dev,struct rtc_time * tm)176*9d6d6b06SShubhi Garg static int nvvrs_rtc_read_time(struct device *dev, struct rtc_time *tm)
177*9d6d6b06SShubhi Garg {
178*9d6d6b06SShubhi Garg struct nvvrs_rtc_info *info = dev_get_drvdata(dev);
179*9d6d6b06SShubhi Garg time64_t secs = 0;
180*9d6d6b06SShubhi Garg int ret;
181*9d6d6b06SShubhi Garg u8 val;
182*9d6d6b06SShubhi Garg
183*9d6d6b06SShubhi Garg /*
184*9d6d6b06SShubhi Garg * Multi-byte transfers are not supported with PEC enabled
185*9d6d6b06SShubhi Garg * Read MSB first to avoid coherency issues
186*9d6d6b06SShubhi Garg */
187*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_T3);
188*9d6d6b06SShubhi Garg if (ret < 0)
189*9d6d6b06SShubhi Garg return ret;
190*9d6d6b06SShubhi Garg
191*9d6d6b06SShubhi Garg val = (u8)ret;
192*9d6d6b06SShubhi Garg secs |= (time64_t)val << 24;
193*9d6d6b06SShubhi Garg
194*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_T2);
195*9d6d6b06SShubhi Garg if (ret < 0)
196*9d6d6b06SShubhi Garg return ret;
197*9d6d6b06SShubhi Garg
198*9d6d6b06SShubhi Garg val = (u8)ret;
199*9d6d6b06SShubhi Garg secs |= (time64_t)val << 16;
200*9d6d6b06SShubhi Garg
201*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_T1);
202*9d6d6b06SShubhi Garg if (ret < 0)
203*9d6d6b06SShubhi Garg return ret;
204*9d6d6b06SShubhi Garg
205*9d6d6b06SShubhi Garg val = (u8)ret;
206*9d6d6b06SShubhi Garg secs |= (time64_t)val << 8;
207*9d6d6b06SShubhi Garg
208*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_T0);
209*9d6d6b06SShubhi Garg if (ret < 0)
210*9d6d6b06SShubhi Garg return ret;
211*9d6d6b06SShubhi Garg
212*9d6d6b06SShubhi Garg val = (u8)ret;
213*9d6d6b06SShubhi Garg secs |= val;
214*9d6d6b06SShubhi Garg
215*9d6d6b06SShubhi Garg rtc_time64_to_tm(secs, tm);
216*9d6d6b06SShubhi Garg
217*9d6d6b06SShubhi Garg return 0;
218*9d6d6b06SShubhi Garg }
219*9d6d6b06SShubhi Garg
nvvrs_rtc_set_time(struct device * dev,struct rtc_time * tm)220*9d6d6b06SShubhi Garg static int nvvrs_rtc_set_time(struct device *dev, struct rtc_time *tm)
221*9d6d6b06SShubhi Garg {
222*9d6d6b06SShubhi Garg struct nvvrs_rtc_info *info = dev_get_drvdata(dev);
223*9d6d6b06SShubhi Garg time64_t secs;
224*9d6d6b06SShubhi Garg u8 time[4];
225*9d6d6b06SShubhi Garg int ret;
226*9d6d6b06SShubhi Garg
227*9d6d6b06SShubhi Garg secs = rtc_tm_to_time64(tm);
228*9d6d6b06SShubhi Garg time[0] = secs & 0xff;
229*9d6d6b06SShubhi Garg time[1] = (secs >> 8) & 0xff;
230*9d6d6b06SShubhi Garg time[2] = (secs >> 16) & 0xff;
231*9d6d6b06SShubhi Garg time[3] = (secs >> 24) & 0xff;
232*9d6d6b06SShubhi Garg
233*9d6d6b06SShubhi Garg ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_RTC_T3, time[3]);
234*9d6d6b06SShubhi Garg if (ret < 0)
235*9d6d6b06SShubhi Garg return ret;
236*9d6d6b06SShubhi Garg
237*9d6d6b06SShubhi Garg ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_RTC_T2, time[2]);
238*9d6d6b06SShubhi Garg if (ret < 0)
239*9d6d6b06SShubhi Garg return ret;
240*9d6d6b06SShubhi Garg
241*9d6d6b06SShubhi Garg ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_RTC_T1, time[1]);
242*9d6d6b06SShubhi Garg if (ret < 0)
243*9d6d6b06SShubhi Garg return ret;
244*9d6d6b06SShubhi Garg
245*9d6d6b06SShubhi Garg ret = i2c_smbus_write_byte_data(info->client, NVVRS_REG_RTC_T0, time[0]);
246*9d6d6b06SShubhi Garg
247*9d6d6b06SShubhi Garg return ret;
248*9d6d6b06SShubhi Garg }
249*9d6d6b06SShubhi Garg
nvvrs_rtc_read_alarm(struct device * dev,struct rtc_wkalrm * alrm)250*9d6d6b06SShubhi Garg static int nvvrs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
251*9d6d6b06SShubhi Garg {
252*9d6d6b06SShubhi Garg struct nvvrs_rtc_info *info = dev_get_drvdata(dev);
253*9d6d6b06SShubhi Garg time64_t alarm_val = 0;
254*9d6d6b06SShubhi Garg int ret;
255*9d6d6b06SShubhi Garg u8 val;
256*9d6d6b06SShubhi Garg
257*9d6d6b06SShubhi Garg /* Multi-byte transfers are not supported with PEC enabled */
258*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_A3);
259*9d6d6b06SShubhi Garg if (ret < 0)
260*9d6d6b06SShubhi Garg return ret;
261*9d6d6b06SShubhi Garg
262*9d6d6b06SShubhi Garg val = (u8)ret;
263*9d6d6b06SShubhi Garg alarm_val |= (time64_t)val << 24;
264*9d6d6b06SShubhi Garg
265*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_A2);
266*9d6d6b06SShubhi Garg if (ret < 0)
267*9d6d6b06SShubhi Garg return ret;
268*9d6d6b06SShubhi Garg
269*9d6d6b06SShubhi Garg val = (u8)ret;
270*9d6d6b06SShubhi Garg alarm_val |= (time64_t)val << 16;
271*9d6d6b06SShubhi Garg
272*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_A1);
273*9d6d6b06SShubhi Garg if (ret < 0)
274*9d6d6b06SShubhi Garg return ret;
275*9d6d6b06SShubhi Garg
276*9d6d6b06SShubhi Garg val = (u8)ret;
277*9d6d6b06SShubhi Garg alarm_val |= (time64_t)val << 8;
278*9d6d6b06SShubhi Garg
279*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_RTC_A0);
280*9d6d6b06SShubhi Garg if (ret < 0)
281*9d6d6b06SShubhi Garg return ret;
282*9d6d6b06SShubhi Garg
283*9d6d6b06SShubhi Garg val = (u8)ret;
284*9d6d6b06SShubhi Garg alarm_val |= val;
285*9d6d6b06SShubhi Garg
286*9d6d6b06SShubhi Garg if (alarm_val == ALARM_RESET_VAL)
287*9d6d6b06SShubhi Garg alrm->enabled = 0;
288*9d6d6b06SShubhi Garg else
289*9d6d6b06SShubhi Garg alrm->enabled = 1;
290*9d6d6b06SShubhi Garg
291*9d6d6b06SShubhi Garg rtc_time64_to_tm(alarm_val, &alrm->time);
292*9d6d6b06SShubhi Garg
293*9d6d6b06SShubhi Garg return 0;
294*9d6d6b06SShubhi Garg }
295*9d6d6b06SShubhi Garg
nvvrs_rtc_set_alarm(struct device * dev,struct rtc_wkalrm * alrm)296*9d6d6b06SShubhi Garg static int nvvrs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
297*9d6d6b06SShubhi Garg {
298*9d6d6b06SShubhi Garg struct nvvrs_rtc_info *info = dev_get_drvdata(dev);
299*9d6d6b06SShubhi Garg time64_t secs;
300*9d6d6b06SShubhi Garg u8 time[4];
301*9d6d6b06SShubhi Garg int ret;
302*9d6d6b06SShubhi Garg
303*9d6d6b06SShubhi Garg if (!alrm->enabled) {
304*9d6d6b06SShubhi Garg ret = nvvrs_rtc_disable_alarm(info);
305*9d6d6b06SShubhi Garg if (ret < 0)
306*9d6d6b06SShubhi Garg return ret;
307*9d6d6b06SShubhi Garg }
308*9d6d6b06SShubhi Garg
309*9d6d6b06SShubhi Garg ret = nvvrs_rtc_enable_alarm(info);
310*9d6d6b06SShubhi Garg if (ret < 0)
311*9d6d6b06SShubhi Garg return ret;
312*9d6d6b06SShubhi Garg
313*9d6d6b06SShubhi Garg secs = rtc_tm_to_time64(&alrm->time);
314*9d6d6b06SShubhi Garg time[0] = secs & 0xff;
315*9d6d6b06SShubhi Garg time[1] = (secs >> 8) & 0xff;
316*9d6d6b06SShubhi Garg time[2] = (secs >> 16) & 0xff;
317*9d6d6b06SShubhi Garg time[3] = (secs >> 24) & 0xff;
318*9d6d6b06SShubhi Garg
319*9d6d6b06SShubhi Garg ret = nvvrs_rtc_write_alarm(info->client, time);
320*9d6d6b06SShubhi Garg
321*9d6d6b06SShubhi Garg return ret;
322*9d6d6b06SShubhi Garg }
323*9d6d6b06SShubhi Garg
nvvrs_pseq_irq_clear(struct nvvrs_rtc_info * info)324*9d6d6b06SShubhi Garg static int nvvrs_pseq_irq_clear(struct nvvrs_rtc_info *info)
325*9d6d6b06SShubhi Garg {
326*9d6d6b06SShubhi Garg unsigned int i;
327*9d6d6b06SShubhi Garg int ret;
328*9d6d6b06SShubhi Garg
329*9d6d6b06SShubhi Garg for (i = 0; i < NVVRS_IRQ_REG_COUNT; i++) {
330*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client,
331*9d6d6b06SShubhi Garg NVVRS_REG_INT_SRC1 + i);
332*9d6d6b06SShubhi Garg if (ret < 0) {
333*9d6d6b06SShubhi Garg dev_err(info->dev, "Failed to read INT_SRC%d : %d\n",
334*9d6d6b06SShubhi Garg i + 1, ret);
335*9d6d6b06SShubhi Garg return ret;
336*9d6d6b06SShubhi Garg }
337*9d6d6b06SShubhi Garg
338*9d6d6b06SShubhi Garg ret = i2c_smbus_write_byte_data(info->client,
339*9d6d6b06SShubhi Garg NVVRS_REG_INT_SRC1 + i,
340*9d6d6b06SShubhi Garg (u8)ret);
341*9d6d6b06SShubhi Garg if (ret < 0) {
342*9d6d6b06SShubhi Garg dev_err(info->dev, "Failed to clear INT_SRC%d : %d\n",
343*9d6d6b06SShubhi Garg i + 1, ret);
344*9d6d6b06SShubhi Garg return ret;
345*9d6d6b06SShubhi Garg }
346*9d6d6b06SShubhi Garg }
347*9d6d6b06SShubhi Garg
348*9d6d6b06SShubhi Garg return 0;
349*9d6d6b06SShubhi Garg }
350*9d6d6b06SShubhi Garg
nvvrs_rtc_irq_handler(int irq,void * data)351*9d6d6b06SShubhi Garg static irqreturn_t nvvrs_rtc_irq_handler(int irq, void *data)
352*9d6d6b06SShubhi Garg {
353*9d6d6b06SShubhi Garg struct nvvrs_rtc_info *info = data;
354*9d6d6b06SShubhi Garg int ret;
355*9d6d6b06SShubhi Garg
356*9d6d6b06SShubhi Garg /* Check for RTC alarm interrupt */
357*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(info->client, NVVRS_REG_INT_SRC1);
358*9d6d6b06SShubhi Garg if (ret < 0)
359*9d6d6b06SShubhi Garg return IRQ_NONE;
360*9d6d6b06SShubhi Garg
361*9d6d6b06SShubhi Garg if (ret & NVVRS_INT_SRC1_RTC_MASK) {
362*9d6d6b06SShubhi Garg rtc_lock(info->rtc);
363*9d6d6b06SShubhi Garg rtc_update_irq(info->rtc, 1, RTC_IRQF | RTC_AF);
364*9d6d6b06SShubhi Garg rtc_unlock(info->rtc);
365*9d6d6b06SShubhi Garg }
366*9d6d6b06SShubhi Garg
367*9d6d6b06SShubhi Garg /* Clear all interrupts */
368*9d6d6b06SShubhi Garg if (nvvrs_pseq_irq_clear(info) < 0)
369*9d6d6b06SShubhi Garg return IRQ_NONE;
370*9d6d6b06SShubhi Garg
371*9d6d6b06SShubhi Garg return IRQ_HANDLED;
372*9d6d6b06SShubhi Garg }
373*9d6d6b06SShubhi Garg
nvvrs_rtc_alarm_irq_enable(struct device * dev,unsigned int enabled)374*9d6d6b06SShubhi Garg static int nvvrs_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
375*9d6d6b06SShubhi Garg {
376*9d6d6b06SShubhi Garg /*
377*9d6d6b06SShubhi Garg * This hardware does not support enabling/disabling the alarm IRQ
378*9d6d6b06SShubhi Garg * independently. The alarm is disabled by clearing the alarm time
379*9d6d6b06SShubhi Garg * via set_alarm().
380*9d6d6b06SShubhi Garg */
381*9d6d6b06SShubhi Garg return 0;
382*9d6d6b06SShubhi Garg }
383*9d6d6b06SShubhi Garg
384*9d6d6b06SShubhi Garg static const struct rtc_class_ops nvvrs_rtc_ops = {
385*9d6d6b06SShubhi Garg .read_time = nvvrs_rtc_read_time,
386*9d6d6b06SShubhi Garg .set_time = nvvrs_rtc_set_time,
387*9d6d6b06SShubhi Garg .read_alarm = nvvrs_rtc_read_alarm,
388*9d6d6b06SShubhi Garg .set_alarm = nvvrs_rtc_set_alarm,
389*9d6d6b06SShubhi Garg .alarm_irq_enable = nvvrs_rtc_alarm_irq_enable,
390*9d6d6b06SShubhi Garg };
391*9d6d6b06SShubhi Garg
nvvrs_pseq_vendor_info(struct nvvrs_rtc_info * info)392*9d6d6b06SShubhi Garg static int nvvrs_pseq_vendor_info(struct nvvrs_rtc_info *info)
393*9d6d6b06SShubhi Garg {
394*9d6d6b06SShubhi Garg struct i2c_client *client = info->client;
395*9d6d6b06SShubhi Garg u8 vendor_id, model_rev;
396*9d6d6b06SShubhi Garg int ret;
397*9d6d6b06SShubhi Garg
398*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(client, NVVRS_REG_VENDOR_ID);
399*9d6d6b06SShubhi Garg if (ret < 0)
400*9d6d6b06SShubhi Garg return dev_err_probe(&client->dev, ret,
401*9d6d6b06SShubhi Garg "Failed to read Vendor ID\n");
402*9d6d6b06SShubhi Garg
403*9d6d6b06SShubhi Garg vendor_id = (u8)ret;
404*9d6d6b06SShubhi Garg
405*9d6d6b06SShubhi Garg ret = i2c_smbus_read_byte_data(client, NVVRS_REG_MODEL_REV);
406*9d6d6b06SShubhi Garg if (ret < 0)
407*9d6d6b06SShubhi Garg return dev_err_probe(&client->dev, ret,
408*9d6d6b06SShubhi Garg "Failed to read Model Revision\n");
409*9d6d6b06SShubhi Garg
410*9d6d6b06SShubhi Garg model_rev = (u8)ret;
411*9d6d6b06SShubhi Garg
412*9d6d6b06SShubhi Garg if (model_rev < NVVRS_MIN_MODEL_REV) {
413*9d6d6b06SShubhi Garg return dev_err_probe(&client->dev, -ENODEV,
414*9d6d6b06SShubhi Garg "Chip revision 0x%02x is not supported!\n",
415*9d6d6b06SShubhi Garg model_rev);
416*9d6d6b06SShubhi Garg }
417*9d6d6b06SShubhi Garg
418*9d6d6b06SShubhi Garg dev_dbg(&client->dev, "NVVRS Vendor ID: 0x%02x, Model Rev: 0x%02x\n",
419*9d6d6b06SShubhi Garg vendor_id, model_rev);
420*9d6d6b06SShubhi Garg
421*9d6d6b06SShubhi Garg return 0;
422*9d6d6b06SShubhi Garg }
423*9d6d6b06SShubhi Garg
nvvrs_rtc_probe(struct i2c_client * client)424*9d6d6b06SShubhi Garg static int nvvrs_rtc_probe(struct i2c_client *client)
425*9d6d6b06SShubhi Garg {
426*9d6d6b06SShubhi Garg struct nvvrs_rtc_info *info;
427*9d6d6b06SShubhi Garg int ret;
428*9d6d6b06SShubhi Garg
429*9d6d6b06SShubhi Garg info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
430*9d6d6b06SShubhi Garg if (!info)
431*9d6d6b06SShubhi Garg return -ENOMEM;
432*9d6d6b06SShubhi Garg
433*9d6d6b06SShubhi Garg if (client->irq <= 0)
434*9d6d6b06SShubhi Garg return dev_err_probe(&client->dev, -EINVAL, "No IRQ specified\n");
435*9d6d6b06SShubhi Garg
436*9d6d6b06SShubhi Garg info->irq = client->irq;
437*9d6d6b06SShubhi Garg info->dev = &client->dev;
438*9d6d6b06SShubhi Garg client->flags |= I2C_CLIENT_PEC;
439*9d6d6b06SShubhi Garg i2c_set_clientdata(client, info);
440*9d6d6b06SShubhi Garg info->client = client;
441*9d6d6b06SShubhi Garg
442*9d6d6b06SShubhi Garg /* Check vendor info */
443*9d6d6b06SShubhi Garg if (nvvrs_pseq_vendor_info(info) < 0)
444*9d6d6b06SShubhi Garg return dev_err_probe(&client->dev, -EINVAL,
445*9d6d6b06SShubhi Garg "Failed to get vendor info\n");
446*9d6d6b06SShubhi Garg
447*9d6d6b06SShubhi Garg /* Clear any pending IRQs before requesting IRQ handler */
448*9d6d6b06SShubhi Garg if (nvvrs_pseq_irq_clear(info) < 0)
449*9d6d6b06SShubhi Garg return dev_err_probe(&client->dev, -EINVAL,
450*9d6d6b06SShubhi Garg "Failed to clear interrupts\n");
451*9d6d6b06SShubhi Garg
452*9d6d6b06SShubhi Garg /* Allocate RTC device */
453*9d6d6b06SShubhi Garg info->rtc = devm_rtc_allocate_device(info->dev);
454*9d6d6b06SShubhi Garg if (IS_ERR(info->rtc))
455*9d6d6b06SShubhi Garg return PTR_ERR(info->rtc);
456*9d6d6b06SShubhi Garg
457*9d6d6b06SShubhi Garg info->rtc->ops = &nvvrs_rtc_ops;
458*9d6d6b06SShubhi Garg info->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
459*9d6d6b06SShubhi Garg info->rtc->range_max = RTC_TIMESTAMP_END_2099;
460*9d6d6b06SShubhi Garg
461*9d6d6b06SShubhi Garg /* Request RTC IRQ */
462*9d6d6b06SShubhi Garg ret = devm_request_threaded_irq(info->dev, info->irq, NULL,
463*9d6d6b06SShubhi Garg nvvrs_rtc_irq_handler, IRQF_ONESHOT,
464*9d6d6b06SShubhi Garg "nvvrs-rtc", info);
465*9d6d6b06SShubhi Garg if (ret < 0) {
466*9d6d6b06SShubhi Garg dev_err_probe(info->dev, ret, "Failed to request RTC IRQ\n");
467*9d6d6b06SShubhi Garg return ret;
468*9d6d6b06SShubhi Garg }
469*9d6d6b06SShubhi Garg
470*9d6d6b06SShubhi Garg /* RTC as a wakeup source */
471*9d6d6b06SShubhi Garg devm_device_init_wakeup(info->dev);
472*9d6d6b06SShubhi Garg
473*9d6d6b06SShubhi Garg return devm_rtc_register_device(info->rtc);
474*9d6d6b06SShubhi Garg }
475*9d6d6b06SShubhi Garg
476*9d6d6b06SShubhi Garg #ifdef CONFIG_PM_SLEEP
nvvrs_rtc_suspend(struct device * dev)477*9d6d6b06SShubhi Garg static int nvvrs_rtc_suspend(struct device *dev)
478*9d6d6b06SShubhi Garg {
479*9d6d6b06SShubhi Garg struct nvvrs_rtc_info *info = dev_get_drvdata(dev);
480*9d6d6b06SShubhi Garg int ret;
481*9d6d6b06SShubhi Garg
482*9d6d6b06SShubhi Garg if (device_may_wakeup(dev)) {
483*9d6d6b06SShubhi Garg /* Set RTC_WAKE bit for auto wake system from suspend state */
484*9d6d6b06SShubhi Garg ret = nvvrs_update_bits(info, NVVRS_REG_CTL_2,
485*9d6d6b06SShubhi Garg NVVRS_REG_CTL_2_RTC_WAKE,
486*9d6d6b06SShubhi Garg NVVRS_REG_CTL_2_RTC_WAKE);
487*9d6d6b06SShubhi Garg if (ret < 0) {
488*9d6d6b06SShubhi Garg dev_err(info->dev, "Failed to set RTC_WAKE bit (%d)\n",
489*9d6d6b06SShubhi Garg ret);
490*9d6d6b06SShubhi Garg return ret;
491*9d6d6b06SShubhi Garg }
492*9d6d6b06SShubhi Garg
493*9d6d6b06SShubhi Garg return enable_irq_wake(info->irq);
494*9d6d6b06SShubhi Garg }
495*9d6d6b06SShubhi Garg
496*9d6d6b06SShubhi Garg return 0;
497*9d6d6b06SShubhi Garg }
498*9d6d6b06SShubhi Garg
nvvrs_rtc_resume(struct device * dev)499*9d6d6b06SShubhi Garg static int nvvrs_rtc_resume(struct device *dev)
500*9d6d6b06SShubhi Garg {
501*9d6d6b06SShubhi Garg struct nvvrs_rtc_info *info = dev_get_drvdata(dev);
502*9d6d6b06SShubhi Garg int ret;
503*9d6d6b06SShubhi Garg
504*9d6d6b06SShubhi Garg if (device_may_wakeup(dev)) {
505*9d6d6b06SShubhi Garg /* Clear FORCE_ACT bit */
506*9d6d6b06SShubhi Garg ret = nvvrs_update_bits(info, NVVRS_REG_CTL_1,
507*9d6d6b06SShubhi Garg NVVRS_REG_CTL_1_FORCE_ACT, 0);
508*9d6d6b06SShubhi Garg if (ret < 0) {
509*9d6d6b06SShubhi Garg dev_err(info->dev, "Failed to clear FORCE_ACT bit (%d)\n",
510*9d6d6b06SShubhi Garg ret);
511*9d6d6b06SShubhi Garg return ret;
512*9d6d6b06SShubhi Garg }
513*9d6d6b06SShubhi Garg
514*9d6d6b06SShubhi Garg return disable_irq_wake(info->irq);
515*9d6d6b06SShubhi Garg }
516*9d6d6b06SShubhi Garg
517*9d6d6b06SShubhi Garg return 0;
518*9d6d6b06SShubhi Garg }
519*9d6d6b06SShubhi Garg
520*9d6d6b06SShubhi Garg #endif
521*9d6d6b06SShubhi Garg static SIMPLE_DEV_PM_OPS(nvvrs_rtc_pm_ops, nvvrs_rtc_suspend, nvvrs_rtc_resume);
522*9d6d6b06SShubhi Garg
523*9d6d6b06SShubhi Garg static const struct of_device_id nvvrs_rtc_of_match[] = {
524*9d6d6b06SShubhi Garg { .compatible = "nvidia,vrs-10" },
525*9d6d6b06SShubhi Garg { },
526*9d6d6b06SShubhi Garg };
527*9d6d6b06SShubhi Garg MODULE_DEVICE_TABLE(of, nvvrs_rtc_of_match);
528*9d6d6b06SShubhi Garg
529*9d6d6b06SShubhi Garg static struct i2c_driver nvvrs_rtc_driver = {
530*9d6d6b06SShubhi Garg .driver = {
531*9d6d6b06SShubhi Garg .name = "rtc-nvidia-vrs10",
532*9d6d6b06SShubhi Garg .pm = &nvvrs_rtc_pm_ops,
533*9d6d6b06SShubhi Garg .of_match_table = nvvrs_rtc_of_match,
534*9d6d6b06SShubhi Garg },
535*9d6d6b06SShubhi Garg .probe = nvvrs_rtc_probe,
536*9d6d6b06SShubhi Garg };
537*9d6d6b06SShubhi Garg
538*9d6d6b06SShubhi Garg module_i2c_driver(nvvrs_rtc_driver);
539*9d6d6b06SShubhi Garg
540*9d6d6b06SShubhi Garg MODULE_AUTHOR("Shubhi Garg <shgarg@nvidia.com>");
541*9d6d6b06SShubhi Garg MODULE_DESCRIPTION("NVIDIA Voltage Regulator Specification RTC driver");
542*9d6d6b06SShubhi Garg MODULE_LICENSE("GPL");
543