1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Real Time Clock (RTC) Driver for sd3078
4*4882a593Smuzhiyun * Copyright (C) 2018 Zoro Li
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/bcd.h>
8*4882a593Smuzhiyun #include <linux/i2c.h>
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/regmap.h>
11*4882a593Smuzhiyun #include <linux/rtc.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #define SD3078_REG_SC 0x00
15*4882a593Smuzhiyun #define SD3078_REG_MN 0x01
16*4882a593Smuzhiyun #define SD3078_REG_HR 0x02
17*4882a593Smuzhiyun #define SD3078_REG_DW 0x03
18*4882a593Smuzhiyun #define SD3078_REG_DM 0x04
19*4882a593Smuzhiyun #define SD3078_REG_MO 0x05
20*4882a593Smuzhiyun #define SD3078_REG_YR 0x06
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #define SD3078_REG_CTRL1 0x0f
23*4882a593Smuzhiyun #define SD3078_REG_CTRL2 0x10
24*4882a593Smuzhiyun #define SD3078_REG_CTRL3 0x11
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #define KEY_WRITE1 0x80
27*4882a593Smuzhiyun #define KEY_WRITE2 0x04
28*4882a593Smuzhiyun #define KEY_WRITE3 0x80
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define NUM_TIME_REGS (SD3078_REG_YR - SD3078_REG_SC + 1)
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun /*
33*4882a593Smuzhiyun * The sd3078 has write protection
34*4882a593Smuzhiyun * and we can choose whether or not to use it.
35*4882a593Smuzhiyun * Write protection is turned off by default.
36*4882a593Smuzhiyun */
37*4882a593Smuzhiyun #define WRITE_PROTECT_EN 0
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun struct sd3078 {
40*4882a593Smuzhiyun struct rtc_device *rtc;
41*4882a593Smuzhiyun struct regmap *regmap;
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /*
45*4882a593Smuzhiyun * In order to prevent arbitrary modification of the time register,
46*4882a593Smuzhiyun * when modification of the register,
47*4882a593Smuzhiyun * the "write" bit needs to be written in a certain order.
48*4882a593Smuzhiyun * 1. set WRITE1 bit
49*4882a593Smuzhiyun * 2. set WRITE2 bit
50*4882a593Smuzhiyun * 3. set WRITE3 bit
51*4882a593Smuzhiyun */
sd3078_enable_reg_write(struct sd3078 * sd3078)52*4882a593Smuzhiyun static void sd3078_enable_reg_write(struct sd3078 *sd3078)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL2,
55*4882a593Smuzhiyun KEY_WRITE1, KEY_WRITE1);
56*4882a593Smuzhiyun regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL1,
57*4882a593Smuzhiyun KEY_WRITE2, KEY_WRITE2);
58*4882a593Smuzhiyun regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL1,
59*4882a593Smuzhiyun KEY_WRITE3, KEY_WRITE3);
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun #if WRITE_PROTECT_EN
63*4882a593Smuzhiyun /*
64*4882a593Smuzhiyun * In order to prevent arbitrary modification of the time register,
65*4882a593Smuzhiyun * we should disable the write function.
66*4882a593Smuzhiyun * when disable write,
67*4882a593Smuzhiyun * the "write" bit needs to be clear in a certain order.
68*4882a593Smuzhiyun * 1. clear WRITE2 bit
69*4882a593Smuzhiyun * 2. clear WRITE3 bit
70*4882a593Smuzhiyun * 3. clear WRITE1 bit
71*4882a593Smuzhiyun */
sd3078_disable_reg_write(struct sd3078 * sd3078)72*4882a593Smuzhiyun static void sd3078_disable_reg_write(struct sd3078 *sd3078)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL1,
75*4882a593Smuzhiyun KEY_WRITE2, 0);
76*4882a593Smuzhiyun regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL1,
77*4882a593Smuzhiyun KEY_WRITE3, 0);
78*4882a593Smuzhiyun regmap_update_bits(sd3078->regmap, SD3078_REG_CTRL2,
79*4882a593Smuzhiyun KEY_WRITE1, 0);
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun #endif
82*4882a593Smuzhiyun
sd3078_rtc_read_time(struct device * dev,struct rtc_time * tm)83*4882a593Smuzhiyun static int sd3078_rtc_read_time(struct device *dev, struct rtc_time *tm)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun unsigned char hour;
86*4882a593Smuzhiyun unsigned char rtc_data[NUM_TIME_REGS] = {0};
87*4882a593Smuzhiyun struct i2c_client *client = to_i2c_client(dev);
88*4882a593Smuzhiyun struct sd3078 *sd3078 = i2c_get_clientdata(client);
89*4882a593Smuzhiyun int ret;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun ret = regmap_bulk_read(sd3078->regmap, SD3078_REG_SC, rtc_data,
92*4882a593Smuzhiyun NUM_TIME_REGS);
93*4882a593Smuzhiyun if (ret < 0) {
94*4882a593Smuzhiyun dev_err(dev, "reading from RTC failed with err:%d\n", ret);
95*4882a593Smuzhiyun return ret;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun tm->tm_sec = bcd2bin(rtc_data[SD3078_REG_SC] & 0x7F);
99*4882a593Smuzhiyun tm->tm_min = bcd2bin(rtc_data[SD3078_REG_MN] & 0x7F);
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun /*
102*4882a593Smuzhiyun * The sd3078 supports 12/24 hour mode.
103*4882a593Smuzhiyun * When getting time,
104*4882a593Smuzhiyun * we need to convert the 12 hour mode to the 24 hour mode.
105*4882a593Smuzhiyun */
106*4882a593Smuzhiyun hour = rtc_data[SD3078_REG_HR];
107*4882a593Smuzhiyun if (hour & 0x80) /* 24H MODE */
108*4882a593Smuzhiyun tm->tm_hour = bcd2bin(rtc_data[SD3078_REG_HR] & 0x3F);
109*4882a593Smuzhiyun else if (hour & 0x20) /* 12H MODE PM */
110*4882a593Smuzhiyun tm->tm_hour = bcd2bin(rtc_data[SD3078_REG_HR] & 0x1F) + 12;
111*4882a593Smuzhiyun else /* 12H MODE AM */
112*4882a593Smuzhiyun tm->tm_hour = bcd2bin(rtc_data[SD3078_REG_HR] & 0x1F);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun tm->tm_mday = bcd2bin(rtc_data[SD3078_REG_DM] & 0x3F);
115*4882a593Smuzhiyun tm->tm_wday = rtc_data[SD3078_REG_DW] & 0x07;
116*4882a593Smuzhiyun tm->tm_mon = bcd2bin(rtc_data[SD3078_REG_MO] & 0x1F) - 1;
117*4882a593Smuzhiyun tm->tm_year = bcd2bin(rtc_data[SD3078_REG_YR]) + 100;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun return 0;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
sd3078_rtc_set_time(struct device * dev,struct rtc_time * tm)122*4882a593Smuzhiyun static int sd3078_rtc_set_time(struct device *dev, struct rtc_time *tm)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun unsigned char rtc_data[NUM_TIME_REGS];
125*4882a593Smuzhiyun struct i2c_client *client = to_i2c_client(dev);
126*4882a593Smuzhiyun struct sd3078 *sd3078 = i2c_get_clientdata(client);
127*4882a593Smuzhiyun int ret;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun rtc_data[SD3078_REG_SC] = bin2bcd(tm->tm_sec);
130*4882a593Smuzhiyun rtc_data[SD3078_REG_MN] = bin2bcd(tm->tm_min);
131*4882a593Smuzhiyun rtc_data[SD3078_REG_HR] = bin2bcd(tm->tm_hour) | 0x80;
132*4882a593Smuzhiyun rtc_data[SD3078_REG_DM] = bin2bcd(tm->tm_mday);
133*4882a593Smuzhiyun rtc_data[SD3078_REG_DW] = tm->tm_wday & 0x07;
134*4882a593Smuzhiyun rtc_data[SD3078_REG_MO] = bin2bcd(tm->tm_mon) + 1;
135*4882a593Smuzhiyun rtc_data[SD3078_REG_YR] = bin2bcd(tm->tm_year - 100);
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun #if WRITE_PROTECT_EN
138*4882a593Smuzhiyun sd3078_enable_reg_write(sd3078);
139*4882a593Smuzhiyun #endif
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun ret = regmap_bulk_write(sd3078->regmap, SD3078_REG_SC, rtc_data,
142*4882a593Smuzhiyun NUM_TIME_REGS);
143*4882a593Smuzhiyun if (ret < 0) {
144*4882a593Smuzhiyun dev_err(dev, "writing to RTC failed with err:%d\n", ret);
145*4882a593Smuzhiyun return ret;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun #if WRITE_PROTECT_EN
149*4882a593Smuzhiyun sd3078_disable_reg_write(sd3078);
150*4882a593Smuzhiyun #endif
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun return 0;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun static const struct rtc_class_ops sd3078_rtc_ops = {
156*4882a593Smuzhiyun .read_time = sd3078_rtc_read_time,
157*4882a593Smuzhiyun .set_time = sd3078_rtc_set_time,
158*4882a593Smuzhiyun };
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun static const struct regmap_config regmap_config = {
161*4882a593Smuzhiyun .reg_bits = 8,
162*4882a593Smuzhiyun .val_bits = 8,
163*4882a593Smuzhiyun .max_register = 0x11,
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun
sd3078_probe(struct i2c_client * client,const struct i2c_device_id * id)166*4882a593Smuzhiyun static int sd3078_probe(struct i2c_client *client,
167*4882a593Smuzhiyun const struct i2c_device_id *id)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun int ret;
170*4882a593Smuzhiyun struct sd3078 *sd3078;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
173*4882a593Smuzhiyun return -ENODEV;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun sd3078 = devm_kzalloc(&client->dev, sizeof(*sd3078), GFP_KERNEL);
176*4882a593Smuzhiyun if (!sd3078)
177*4882a593Smuzhiyun return -ENOMEM;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun sd3078->regmap = devm_regmap_init_i2c(client, ®map_config);
180*4882a593Smuzhiyun if (IS_ERR(sd3078->regmap)) {
181*4882a593Smuzhiyun dev_err(&client->dev, "regmap allocation failed\n");
182*4882a593Smuzhiyun return PTR_ERR(sd3078->regmap);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun i2c_set_clientdata(client, sd3078);
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun sd3078->rtc = devm_rtc_allocate_device(&client->dev);
188*4882a593Smuzhiyun if (IS_ERR(sd3078->rtc))
189*4882a593Smuzhiyun return PTR_ERR(sd3078->rtc);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun sd3078->rtc->ops = &sd3078_rtc_ops;
192*4882a593Smuzhiyun sd3078->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
193*4882a593Smuzhiyun sd3078->rtc->range_max = RTC_TIMESTAMP_END_2099;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun ret = rtc_register_device(sd3078->rtc);
196*4882a593Smuzhiyun if (ret)
197*4882a593Smuzhiyun return ret;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun sd3078_enable_reg_write(sd3078);
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun return 0;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun static const struct i2c_device_id sd3078_id[] = {
205*4882a593Smuzhiyun {"sd3078", 0},
206*4882a593Smuzhiyun { }
207*4882a593Smuzhiyun };
208*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, sd3078_id);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun static const struct of_device_id rtc_dt_match[] = {
211*4882a593Smuzhiyun { .compatible = "whwave,sd3078" },
212*4882a593Smuzhiyun {},
213*4882a593Smuzhiyun };
214*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rtc_dt_match);
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun static struct i2c_driver sd3078_driver = {
217*4882a593Smuzhiyun .driver = {
218*4882a593Smuzhiyun .name = "sd3078",
219*4882a593Smuzhiyun .of_match_table = of_match_ptr(rtc_dt_match),
220*4882a593Smuzhiyun },
221*4882a593Smuzhiyun .probe = sd3078_probe,
222*4882a593Smuzhiyun .id_table = sd3078_id,
223*4882a593Smuzhiyun };
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun module_i2c_driver(sd3078_driver);
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun MODULE_AUTHOR("Dianlong Li <long17.cool@163.com>");
228*4882a593Smuzhiyun MODULE_DESCRIPTION("SD3078 RTC driver");
229*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
230