xref: /linux/drivers/rtc/rtc-nvidia-vrs10.c (revision d324e9a91502184e0ac201293a6ec0fbe10458ed)
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