blob: 1310646a48219d9523b80a8fef6aec9756b89650 [file] [log] [blame]
Heiko Schocher52365232011-05-26 16:25:05 -07001/*
Mylène Josserandc2a1c142016-05-03 11:54:34 +02002 * Micro Crystal RV-3029 / RV-3049 rtc class driver
Heiko Schocher52365232011-05-26 16:25:05 -07003 *
4 * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
Michael Büsch2dca3d92016-03-04 22:40:30 +01005 * Michael Buesch <m@bues.ch>
Heiko Schocher52365232011-05-26 16:25:05 -07006 *
7 * based on previously existing rtc class drivers
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
Heiko Schocher52365232011-05-26 16:25:05 -070013 */
14
15#include <linux/module.h>
16#include <linux/i2c.h>
Mylène Josserandc2a1c142016-05-03 11:54:34 +020017#include <linux/spi/spi.h>
Heiko Schocher52365232011-05-26 16:25:05 -070018#include <linux/bcd.h>
19#include <linux/rtc.h>
Michael Büscha7f6e282016-03-04 22:40:55 +010020#include <linux/delay.h>
21#include <linux/of.h>
Michael Büscha696b312016-03-10 18:34:46 +010022#include <linux/hwmon.h>
23#include <linux/hwmon-sysfs.h>
Mylène Josserande6e38082016-05-03 11:54:33 +020024#include <linux/regmap.h>
Heiko Schocher52365232011-05-26 16:25:05 -070025
26/* Register map */
27/* control section */
Michael Büschaba39d22016-03-04 22:38:45 +010028#define RV3029_ONOFF_CTRL 0x00
Michael Büsch7697de32016-03-04 22:39:49 +010029#define RV3029_ONOFF_CTRL_WE BIT(0)
30#define RV3029_ONOFF_CTRL_TE BIT(1)
31#define RV3029_ONOFF_CTRL_TAR BIT(2)
32#define RV3029_ONOFF_CTRL_EERE BIT(3)
33#define RV3029_ONOFF_CTRL_SRON BIT(4)
34#define RV3029_ONOFF_CTRL_TD0 BIT(5)
35#define RV3029_ONOFF_CTRL_TD1 BIT(6)
36#define RV3029_ONOFF_CTRL_CLKINT BIT(7)
Michael Büschaba39d22016-03-04 22:38:45 +010037#define RV3029_IRQ_CTRL 0x01
Michael Büsch7697de32016-03-04 22:39:49 +010038#define RV3029_IRQ_CTRL_AIE BIT(0)
39#define RV3029_IRQ_CTRL_TIE BIT(1)
40#define RV3029_IRQ_CTRL_V1IE BIT(2)
41#define RV3029_IRQ_CTRL_V2IE BIT(3)
42#define RV3029_IRQ_CTRL_SRIE BIT(4)
Michael Büschaba39d22016-03-04 22:38:45 +010043#define RV3029_IRQ_FLAGS 0x02
Michael Büsch7697de32016-03-04 22:39:49 +010044#define RV3029_IRQ_FLAGS_AF BIT(0)
45#define RV3029_IRQ_FLAGS_TF BIT(1)
46#define RV3029_IRQ_FLAGS_V1IF BIT(2)
47#define RV3029_IRQ_FLAGS_V2IF BIT(3)
48#define RV3029_IRQ_FLAGS_SRF BIT(4)
Michael Büschaba39d22016-03-04 22:38:45 +010049#define RV3029_STATUS 0x03
Michael Büsch7697de32016-03-04 22:39:49 +010050#define RV3029_STATUS_VLOW1 BIT(2)
51#define RV3029_STATUS_VLOW2 BIT(3)
52#define RV3029_STATUS_SR BIT(4)
53#define RV3029_STATUS_PON BIT(5)
54#define RV3029_STATUS_EEBUSY BIT(7)
Michael Büschaba39d22016-03-04 22:38:45 +010055#define RV3029_RST_CTRL 0x04
Michael Büsch7697de32016-03-04 22:39:49 +010056#define RV3029_RST_CTRL_SYSR BIT(4)
Michael Büschaba39d22016-03-04 22:38:45 +010057#define RV3029_CONTROL_SECTION_LEN 0x05
Heiko Schocher52365232011-05-26 16:25:05 -070058
59/* watch section */
Michael Büschaba39d22016-03-04 22:38:45 +010060#define RV3029_W_SEC 0x08
61#define RV3029_W_MINUTES 0x09
62#define RV3029_W_HOURS 0x0A
Michael Büsch7697de32016-03-04 22:39:49 +010063#define RV3029_REG_HR_12_24 BIT(6) /* 24h/12h mode */
64#define RV3029_REG_HR_PM BIT(5) /* PM/AM bit in 12h mode */
Michael Büschaba39d22016-03-04 22:38:45 +010065#define RV3029_W_DATE 0x0B
66#define RV3029_W_DAYS 0x0C
67#define RV3029_W_MONTHS 0x0D
68#define RV3029_W_YEARS 0x0E
69#define RV3029_WATCH_SECTION_LEN 0x07
Heiko Schocher52365232011-05-26 16:25:05 -070070
71/* alarm section */
Michael Büschaba39d22016-03-04 22:38:45 +010072#define RV3029_A_SC 0x10
73#define RV3029_A_MN 0x11
74#define RV3029_A_HR 0x12
75#define RV3029_A_DT 0x13
76#define RV3029_A_DW 0x14
77#define RV3029_A_MO 0x15
78#define RV3029_A_YR 0x16
79#define RV3029_ALARM_SECTION_LEN 0x07
Heiko Schocher52365232011-05-26 16:25:05 -070080
81/* timer section */
Michael Büschaba39d22016-03-04 22:38:45 +010082#define RV3029_TIMER_LOW 0x18
83#define RV3029_TIMER_HIGH 0x19
Heiko Schocher52365232011-05-26 16:25:05 -070084
85/* temperature section */
Michael Büschaba39d22016-03-04 22:38:45 +010086#define RV3029_TEMP_PAGE 0x20
Heiko Schocher52365232011-05-26 16:25:05 -070087
88/* eeprom data section */
Michael Büschaba39d22016-03-04 22:38:45 +010089#define RV3029_E2P_EEDATA1 0x28
90#define RV3029_E2P_EEDATA2 0x29
Michael Büsch7697de32016-03-04 22:39:49 +010091#define RV3029_E2PDATA_SECTION_LEN 0x02
Heiko Schocher52365232011-05-26 16:25:05 -070092
93/* eeprom control section */
Michael Büschaba39d22016-03-04 22:38:45 +010094#define RV3029_CONTROL_E2P_EECTRL 0x30
Michael Büsch7697de32016-03-04 22:39:49 +010095#define RV3029_EECTRL_THP BIT(0) /* temp scan interval */
96#define RV3029_EECTRL_THE BIT(1) /* thermometer enable */
97#define RV3029_EECTRL_FD0 BIT(2) /* CLKOUT */
98#define RV3029_EECTRL_FD1 BIT(3) /* CLKOUT */
99#define RV3029_TRICKLE_1K BIT(4) /* 1.5K resistance */
100#define RV3029_TRICKLE_5K BIT(5) /* 5K resistance */
101#define RV3029_TRICKLE_20K BIT(6) /* 20K resistance */
102#define RV3029_TRICKLE_80K BIT(7) /* 80K resistance */
103#define RV3029_TRICKLE_MASK (RV3029_TRICKLE_1K |\
104 RV3029_TRICKLE_5K |\
105 RV3029_TRICKLE_20K |\
106 RV3029_TRICKLE_80K)
107#define RV3029_TRICKLE_SHIFT 4
108#define RV3029_CONTROL_E2P_XOFFS 0x31 /* XTAL offset */
109#define RV3029_CONTROL_E2P_XOFFS_SIGN BIT(7) /* Sign: 1->pos, 0->neg */
110#define RV3029_CONTROL_E2P_QCOEF 0x32 /* XTAL temp drift coef */
111#define RV3029_CONTROL_E2P_TURNOVER 0x33 /* XTAL turnover temp (in *C) */
112#define RV3029_CONTROL_E2P_TOV_MASK 0x3F /* XTAL turnover temp mask */
Heiko Schocher52365232011-05-26 16:25:05 -0700113
114/* user ram section */
Michael Büschaba39d22016-03-04 22:38:45 +0100115#define RV3029_USR1_RAM_PAGE 0x38
116#define RV3029_USR1_SECTION_LEN 0x04
117#define RV3029_USR2_RAM_PAGE 0x3C
118#define RV3029_USR2_SECTION_LEN 0x04
Heiko Schocher52365232011-05-26 16:25:05 -0700119
Mylène Josserande6e38082016-05-03 11:54:33 +0200120struct rv3029_data {
121 struct device *dev;
122 struct rtc_device *rtc;
123 struct regmap *regmap;
124 int irq;
125};
126
127static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200128 unsigned len)
Heiko Schocher52365232011-05-26 16:25:05 -0700129{
Mylène Josserande6e38082016-05-03 11:54:33 +0200130 struct rv3029_data *rv3029 = dev_get_drvdata(dev);
Heiko Schocher52365232011-05-26 16:25:05 -0700131
Michael Büschaba39d22016-03-04 22:38:45 +0100132 if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
133 (reg + len > RV3029_USR1_RAM_PAGE + 8))
Heiko Schocher52365232011-05-26 16:25:05 -0700134 return -EINVAL;
135
Mylène Josserande6e38082016-05-03 11:54:33 +0200136 return regmap_bulk_read(rv3029->regmap, reg, buf, len);
Heiko Schocher52365232011-05-26 16:25:05 -0700137}
138
Mylène Josserande6e38082016-05-03 11:54:33 +0200139static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200140 unsigned len)
Heiko Schocher52365232011-05-26 16:25:05 -0700141{
Mylène Josserande6e38082016-05-03 11:54:33 +0200142 struct rv3029_data *rv3029 = dev_get_drvdata(dev);
143
Michael Büschaba39d22016-03-04 22:38:45 +0100144 if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
145 (reg + len > RV3029_USR1_RAM_PAGE + 8))
Heiko Schocher52365232011-05-26 16:25:05 -0700146 return -EINVAL;
147
Mylène Josserande6e38082016-05-03 11:54:33 +0200148 return regmap_bulk_write(rv3029->regmap, reg, buf, len);
Heiko Schocher52365232011-05-26 16:25:05 -0700149}
150
Mylène Josserande6e38082016-05-03 11:54:33 +0200151static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
Michael Büsch2dca3d92016-03-04 22:40:30 +0100152{
153 u8 buf;
154 int ret;
155
Mylène Josserande6e38082016-05-03 11:54:33 +0200156 ret = rv3029_read_regs(dev, reg, &buf, 1);
Michael Büsch2dca3d92016-03-04 22:40:30 +0100157 if (ret < 0)
158 return ret;
159 buf &= ~mask;
160 buf |= set & mask;
Mylène Josserande6e38082016-05-03 11:54:33 +0200161 ret = rv3029_write_regs(dev, reg, &buf, 1);
Michael Büsch2dca3d92016-03-04 22:40:30 +0100162 if (ret < 0)
163 return ret;
164
165 return 0;
166}
167
Mylène Josserande6e38082016-05-03 11:54:33 +0200168static int rv3029_get_sr(struct device *dev, u8 *buf)
Heiko Schocher52365232011-05-26 16:25:05 -0700169{
Mylène Josserande6e38082016-05-03 11:54:33 +0200170 int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
Heiko Schocher52365232011-05-26 16:25:05 -0700171
172 if (ret < 0)
173 return -EIO;
Mylène Josserande6e38082016-05-03 11:54:33 +0200174 dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
Heiko Schocher52365232011-05-26 16:25:05 -0700175 return 0;
176}
177
Mylène Josserande6e38082016-05-03 11:54:33 +0200178static int rv3029_set_sr(struct device *dev, u8 val)
Heiko Schocher52365232011-05-26 16:25:05 -0700179{
180 u8 buf[1];
181 int sr;
182
183 buf[0] = val;
Mylène Josserande6e38082016-05-03 11:54:33 +0200184 sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
185 dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
Heiko Schocher52365232011-05-26 16:25:05 -0700186 if (sr < 0)
187 return -EIO;
188 return 0;
189}
190
Mylène Josserande6e38082016-05-03 11:54:33 +0200191static int rv3029_eeprom_busywait(struct device *dev)
Michael Büscha7f6e282016-03-04 22:40:55 +0100192{
193 int i, ret;
194 u8 sr;
195
196 for (i = 100; i > 0; i--) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200197 ret = rv3029_get_sr(dev, &sr);
Michael Büscha7f6e282016-03-04 22:40:55 +0100198 if (ret < 0)
199 break;
200 if (!(sr & RV3029_STATUS_EEBUSY))
201 break;
202 usleep_range(1000, 10000);
203 }
204 if (i <= 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200205 dev_err(dev, "EEPROM busy wait timeout.\n");
Michael Büscha7f6e282016-03-04 22:40:55 +0100206 return -ETIMEDOUT;
207 }
208
209 return ret;
210}
211
Mylène Josserande6e38082016-05-03 11:54:33 +0200212static int rv3029_eeprom_exit(struct device *dev)
Michael Büscha7f6e282016-03-04 22:40:55 +0100213{
214 /* Re-enable eeprom refresh */
Mylène Josserande6e38082016-05-03 11:54:33 +0200215 return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200216 RV3029_ONOFF_CTRL_EERE,
217 RV3029_ONOFF_CTRL_EERE);
Michael Büscha7f6e282016-03-04 22:40:55 +0100218}
219
Mylène Josserande6e38082016-05-03 11:54:33 +0200220static int rv3029_eeprom_enter(struct device *dev)
Michael Büscha7f6e282016-03-04 22:40:55 +0100221{
222 int ret;
223 u8 sr;
224
225 /* Check whether we are in the allowed voltage range. */
Mylène Josserande6e38082016-05-03 11:54:33 +0200226 ret = rv3029_get_sr(dev, &sr);
Michael Büscha7f6e282016-03-04 22:40:55 +0100227 if (ret < 0)
228 return ret;
229 if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
230 /* We clear the bits and retry once just in case
231 * we had a brown out in early startup.
232 */
233 sr &= ~RV3029_STATUS_VLOW1;
234 sr &= ~RV3029_STATUS_VLOW2;
Mylène Josserande6e38082016-05-03 11:54:33 +0200235 ret = rv3029_set_sr(dev, sr);
Michael Büscha7f6e282016-03-04 22:40:55 +0100236 if (ret < 0)
237 return ret;
238 usleep_range(1000, 10000);
Mylène Josserande6e38082016-05-03 11:54:33 +0200239 ret = rv3029_get_sr(dev, &sr);
Michael Büscha7f6e282016-03-04 22:40:55 +0100240 if (ret < 0)
241 return ret;
242 if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200243 dev_err(dev,
Michael Büscha7f6e282016-03-04 22:40:55 +0100244 "Supply voltage is too low to safely access the EEPROM.\n");
245 return -ENODEV;
246 }
247 }
248
249 /* Disable eeprom refresh. */
Mylène Josserande6e38082016-05-03 11:54:33 +0200250 ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE,
251 0);
Michael Büscha7f6e282016-03-04 22:40:55 +0100252 if (ret < 0)
253 return ret;
254
255 /* Wait for any previous eeprom accesses to finish. */
Mylène Josserande6e38082016-05-03 11:54:33 +0200256 ret = rv3029_eeprom_busywait(dev);
Michael Büscha7f6e282016-03-04 22:40:55 +0100257 if (ret < 0)
Mylène Josserande6e38082016-05-03 11:54:33 +0200258 rv3029_eeprom_exit(dev);
Michael Büscha7f6e282016-03-04 22:40:55 +0100259
260 return ret;
261}
262
Mylène Josserande6e38082016-05-03 11:54:33 +0200263static int rv3029_eeprom_read(struct device *dev, u8 reg,
Michael Büscha7f6e282016-03-04 22:40:55 +0100264 u8 buf[], size_t len)
265{
266 int ret, err;
267
Mylène Josserande6e38082016-05-03 11:54:33 +0200268 err = rv3029_eeprom_enter(dev);
Michael Büscha7f6e282016-03-04 22:40:55 +0100269 if (err < 0)
270 return err;
271
Mylène Josserande6e38082016-05-03 11:54:33 +0200272 ret = rv3029_read_regs(dev, reg, buf, len);
Michael Büscha7f6e282016-03-04 22:40:55 +0100273
Mylène Josserande6e38082016-05-03 11:54:33 +0200274 err = rv3029_eeprom_exit(dev);
Michael Büscha7f6e282016-03-04 22:40:55 +0100275 if (err < 0)
276 return err;
277
278 return ret;
279}
280
Mylène Josserande6e38082016-05-03 11:54:33 +0200281static int rv3029_eeprom_write(struct device *dev, u8 reg,
Michael Büscha7f6e282016-03-04 22:40:55 +0100282 u8 const buf[], size_t len)
283{
284 int ret, err;
285 size_t i;
286 u8 tmp;
287
Mylène Josserande6e38082016-05-03 11:54:33 +0200288 err = rv3029_eeprom_enter(dev);
Michael Büscha7f6e282016-03-04 22:40:55 +0100289 if (err < 0)
290 return err;
291
292 for (i = 0; i < len; i++, reg++) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200293 ret = rv3029_read_regs(dev, reg, &tmp, 1);
Michael Büscha7f6e282016-03-04 22:40:55 +0100294 if (ret < 0)
295 break;
296 if (tmp != buf[i]) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200297 ret = rv3029_write_regs(dev, reg, &buf[i], 1);
Michael Büscha7f6e282016-03-04 22:40:55 +0100298 if (ret < 0)
299 break;
300 }
Mylène Josserande6e38082016-05-03 11:54:33 +0200301 ret = rv3029_eeprom_busywait(dev);
Michael Büscha7f6e282016-03-04 22:40:55 +0100302 if (ret < 0)
303 break;
304 }
305
Mylène Josserande6e38082016-05-03 11:54:33 +0200306 err = rv3029_eeprom_exit(dev);
Michael Büscha7f6e282016-03-04 22:40:55 +0100307 if (err < 0)
308 return err;
309
310 return ret;
311}
312
Mylène Josserande6e38082016-05-03 11:54:33 +0200313static int rv3029_eeprom_update_bits(struct device *dev,
Michael Büsch39387dc2016-03-10 18:34:23 +0100314 u8 reg, u8 mask, u8 set)
315{
316 u8 buf;
317 int ret;
318
Mylène Josserande6e38082016-05-03 11:54:33 +0200319 ret = rv3029_eeprom_read(dev, reg, &buf, 1);
Michael Büsch39387dc2016-03-10 18:34:23 +0100320 if (ret < 0)
321 return ret;
322 buf &= ~mask;
323 buf |= set & mask;
Mylène Josserande6e38082016-05-03 11:54:33 +0200324 ret = rv3029_eeprom_write(dev, reg, &buf, 1);
Michael Büsch39387dc2016-03-10 18:34:23 +0100325 if (ret < 0)
326 return ret;
327
328 return 0;
329}
330
Mylène Josserande6e38082016-05-03 11:54:33 +0200331static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
Heiko Schocher52365232011-05-26 16:25:05 -0700332{
333 u8 buf[1];
334 int ret;
Michael Büschaba39d22016-03-04 22:38:45 +0100335 u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
Heiko Schocher52365232011-05-26 16:25:05 -0700336
Mylène Josserande6e38082016-05-03 11:54:33 +0200337 ret = rv3029_get_sr(dev, buf);
Heiko Schocher52365232011-05-26 16:25:05 -0700338 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200339 dev_err(dev, "%s: reading SR failed\n", __func__);
Heiko Schocher52365232011-05-26 16:25:05 -0700340 return -EIO;
341 }
342
Mylène Josserande6e38082016-05-03 11:54:33 +0200343 ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200344 RV3029_WATCH_SECTION_LEN);
Heiko Schocher52365232011-05-26 16:25:05 -0700345 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200346 dev_err(dev, "%s: reading RTC section failed\n", __func__);
Heiko Schocher52365232011-05-26 16:25:05 -0700347 return ret;
348 }
349
Michael Büschaba39d22016-03-04 22:38:45 +0100350 tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
351 tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]);
Heiko Schocher52365232011-05-26 16:25:05 -0700352
353 /* HR field has a more complex interpretation */
354 {
Michael Büschaba39d22016-03-04 22:38:45 +0100355 const u8 _hr = regs[RV3029_W_HOURS-RV3029_W_SEC];
356
357 if (_hr & RV3029_REG_HR_12_24) {
Heiko Schocher52365232011-05-26 16:25:05 -0700358 /* 12h format */
359 tm->tm_hour = bcd2bin(_hr & 0x1f);
Michael Büschaba39d22016-03-04 22:38:45 +0100360 if (_hr & RV3029_REG_HR_PM) /* PM flag set */
Heiko Schocher52365232011-05-26 16:25:05 -0700361 tm->tm_hour += 12;
362 } else /* 24h format */
363 tm->tm_hour = bcd2bin(_hr & 0x3f);
364 }
365
Michael Büschaba39d22016-03-04 22:38:45 +0100366 tm->tm_mday = bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]);
367 tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1;
368 tm->tm_year = bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100;
369 tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1;
Heiko Schocher52365232011-05-26 16:25:05 -0700370
371 return 0;
372}
373
Mylène Josserande6e38082016-05-03 11:54:33 +0200374static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
Heiko Schocher52365232011-05-26 16:25:05 -0700375{
Heiko Schocher52365232011-05-26 16:25:05 -0700376 struct rtc_time *const tm = &alarm->time;
377 int ret;
378 u8 regs[8];
379
Mylène Josserande6e38082016-05-03 11:54:33 +0200380 ret = rv3029_get_sr(dev, regs);
Heiko Schocher52365232011-05-26 16:25:05 -0700381 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200382 dev_err(dev, "%s: reading SR failed\n", __func__);
Heiko Schocher52365232011-05-26 16:25:05 -0700383 return -EIO;
384 }
385
Mylène Josserande6e38082016-05-03 11:54:33 +0200386 ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200387 RV3029_ALARM_SECTION_LEN);
Heiko Schocher52365232011-05-26 16:25:05 -0700388
389 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200390 dev_err(dev, "%s: reading alarm section failed\n", __func__);
Heiko Schocher52365232011-05-26 16:25:05 -0700391 return ret;
392 }
393
Michael Büschaba39d22016-03-04 22:38:45 +0100394 tm->tm_sec = bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f);
395 tm->tm_min = bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f);
396 tm->tm_hour = bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f);
397 tm->tm_mday = bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f);
398 tm->tm_mon = bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1;
399 tm->tm_year = bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100;
400 tm->tm_wday = bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1;
Heiko Schocher52365232011-05-26 16:25:05 -0700401
402 return 0;
403}
404
Mylène Josserande6e38082016-05-03 11:54:33 +0200405static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
Heiko Schocher52365232011-05-26 16:25:05 -0700406{
407 int ret;
Heiko Schocher52365232011-05-26 16:25:05 -0700408
Michael Büsch2dca3d92016-03-04 22:40:30 +0100409 /* enable/disable AIE irq */
Mylène Josserande6e38082016-05-03 11:54:33 +0200410 ret = rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200411 (enable ? RV3029_IRQ_CTRL_AIE : 0));
Heiko Schocher52365232011-05-26 16:25:05 -0700412 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200413 dev_err(dev, "can't update INT reg\n");
Heiko Schocher52365232011-05-26 16:25:05 -0700414 return ret;
415 }
416
417 return 0;
418}
419
Mylène Josserande6e38082016-05-03 11:54:33 +0200420static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
Heiko Schocher52365232011-05-26 16:25:05 -0700421{
422 struct rtc_time *const tm = &alarm->time;
423 int ret;
424 u8 regs[8];
425
426 /*
427 * The clock has an 8 bit wide bcd-coded register (they never learn)
428 * for the year. tm_year is an offset from 1900 and we are interested
429 * in the 2000-2099 range, so any value less than 100 is invalid.
430 */
431 if (tm->tm_year < 100)
432 return -EINVAL;
433
Mylène Josserande6e38082016-05-03 11:54:33 +0200434 ret = rv3029_get_sr(dev, regs);
Heiko Schocher52365232011-05-26 16:25:05 -0700435 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200436 dev_err(dev, "%s: reading SR failed\n", __func__);
Heiko Schocher52365232011-05-26 16:25:05 -0700437 return -EIO;
438 }
Michael Büschaba39d22016-03-04 22:38:45 +0100439 regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
440 regs[RV3029_A_MN-RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f);
441 regs[RV3029_A_HR-RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
442 regs[RV3029_A_DT-RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
443 regs[RV3029_A_MO-RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
444 regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
445 regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
Heiko Schocher52365232011-05-26 16:25:05 -0700446
Mylène Josserande6e38082016-05-03 11:54:33 +0200447 ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200448 RV3029_ALARM_SECTION_LEN);
Heiko Schocher52365232011-05-26 16:25:05 -0700449 if (ret < 0)
450 return ret;
451
452 if (alarm->enabled) {
Heiko Schocher52365232011-05-26 16:25:05 -0700453 /* clear AF flag */
Mylène Josserande6e38082016-05-03 11:54:33 +0200454 ret = rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200455 RV3029_IRQ_FLAGS_AF, 0);
Heiko Schocher52365232011-05-26 16:25:05 -0700456 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200457 dev_err(dev, "can't clear alarm flag\n");
Heiko Schocher52365232011-05-26 16:25:05 -0700458 return ret;
459 }
460 /* enable AIE irq */
Mylène Josserande6e38082016-05-03 11:54:33 +0200461 ret = rv3029_rtc_alarm_set_irq(dev, 1);
Heiko Schocher52365232011-05-26 16:25:05 -0700462 if (ret)
463 return ret;
464
Mylène Josserande6e38082016-05-03 11:54:33 +0200465 dev_dbg(dev, "alarm IRQ armed\n");
Heiko Schocher52365232011-05-26 16:25:05 -0700466 } else {
467 /* disable AIE irq */
Mylène Josserande6e38082016-05-03 11:54:33 +0200468 ret = rv3029_rtc_alarm_set_irq(dev, 0);
Heiko Schocher52365232011-05-26 16:25:05 -0700469 if (ret)
470 return ret;
471
Mylène Josserande6e38082016-05-03 11:54:33 +0200472 dev_dbg(dev, "alarm IRQ disabled\n");
Heiko Schocher52365232011-05-26 16:25:05 -0700473 }
474
475 return 0;
476}
477
Mylène Josserande6e38082016-05-03 11:54:33 +0200478static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
Heiko Schocher52365232011-05-26 16:25:05 -0700479{
480 u8 regs[8];
481 int ret;
482
483 /*
484 * The clock has an 8 bit wide bcd-coded register (they never learn)
485 * for the year. tm_year is an offset from 1900 and we are interested
486 * in the 2000-2099 range, so any value less than 100 is invalid.
487 */
488 if (tm->tm_year < 100)
489 return -EINVAL;
490
Michael Büschaba39d22016-03-04 22:38:45 +0100491 regs[RV3029_W_SEC-RV3029_W_SEC] = bin2bcd(tm->tm_sec);
492 regs[RV3029_W_MINUTES-RV3029_W_SEC] = bin2bcd(tm->tm_min);
493 regs[RV3029_W_HOURS-RV3029_W_SEC] = bin2bcd(tm->tm_hour);
494 regs[RV3029_W_DATE-RV3029_W_SEC] = bin2bcd(tm->tm_mday);
495 regs[RV3029_W_MONTHS-RV3029_W_SEC] = bin2bcd(tm->tm_mon+1);
496 regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
497 regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
Heiko Schocher52365232011-05-26 16:25:05 -0700498
Mylène Josserande6e38082016-05-03 11:54:33 +0200499 ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200500 RV3029_WATCH_SECTION_LEN);
Heiko Schocher52365232011-05-26 16:25:05 -0700501 if (ret < 0)
502 return ret;
503
Mylène Josserande6e38082016-05-03 11:54:33 +0200504 ret = rv3029_get_sr(dev, regs);
Heiko Schocher52365232011-05-26 16:25:05 -0700505 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200506 dev_err(dev, "%s: reading SR failed\n", __func__);
Heiko Schocher52365232011-05-26 16:25:05 -0700507 return ret;
508 }
509 /* clear PON bit */
Mylène Josserande6e38082016-05-03 11:54:33 +0200510 ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
Heiko Schocher52365232011-05-26 16:25:05 -0700511 if (ret < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200512 dev_err(dev, "%s: reading SR failed\n", __func__);
Heiko Schocher52365232011-05-26 16:25:05 -0700513 return ret;
514 }
515
516 return 0;
517}
Michael Büsche27e2162016-03-04 22:41:19 +0100518static const struct rv3029_trickle_tab_elem {
519 u32 r; /* resistance in ohms */
520 u8 conf; /* trickle config bits */
521} rv3029_trickle_tab[] = {
522 {
523 .r = 1076,
524 .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
525 RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
526 }, {
527 .r = 1091,
528 .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
529 RV3029_TRICKLE_20K,
530 }, {
531 .r = 1137,
532 .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
533 RV3029_TRICKLE_80K,
534 }, {
535 .r = 1154,
536 .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K,
537 }, {
538 .r = 1371,
539 .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_20K |
540 RV3029_TRICKLE_80K,
541 }, {
542 .r = 1395,
543 .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_20K,
544 }, {
545 .r = 1472,
546 .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_80K,
547 }, {
548 .r = 1500,
549 .conf = RV3029_TRICKLE_1K,
550 }, {
551 .r = 3810,
552 .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_20K |
553 RV3029_TRICKLE_80K,
554 }, {
555 .r = 4000,
556 .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_20K,
557 }, {
558 .r = 4706,
559 .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_80K,
560 }, {
561 .r = 5000,
562 .conf = RV3029_TRICKLE_5K,
563 }, {
564 .r = 16000,
565 .conf = RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
566 }, {
567 .r = 20000,
568 .conf = RV3029_TRICKLE_20K,
569 }, {
570 .r = 80000,
571 .conf = RV3029_TRICKLE_80K,
572 },
573};
574
Mylène Josserande6e38082016-05-03 11:54:33 +0200575static void rv3029_trickle_config(struct device *dev)
Michael Büsche27e2162016-03-04 22:41:19 +0100576{
Mylène Josserande6e38082016-05-03 11:54:33 +0200577 struct device_node *of_node = dev->of_node;
Michael Büsche27e2162016-03-04 22:41:19 +0100578 const struct rv3029_trickle_tab_elem *elem;
579 int i, err;
580 u32 ohms;
Michael Büsch39387dc2016-03-10 18:34:23 +0100581 u8 trickle_set_bits;
Michael Büsche27e2162016-03-04 22:41:19 +0100582
583 if (!of_node)
584 return;
585
586 /* Configure the trickle charger. */
Michael Büsche27e2162016-03-04 22:41:19 +0100587 err = of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms);
588 if (err) {
589 /* Disable trickle charger. */
Michael Büsch39387dc2016-03-10 18:34:23 +0100590 trickle_set_bits = 0;
Michael Büsche27e2162016-03-04 22:41:19 +0100591 } else {
592 /* Enable trickle charger. */
593 for (i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++) {
594 elem = &rv3029_trickle_tab[i];
595 if (elem->r >= ohms)
596 break;
597 }
Michael Büsch39387dc2016-03-10 18:34:23 +0100598 trickle_set_bits = elem->conf;
Mylène Josserande6e38082016-05-03 11:54:33 +0200599 dev_info(dev,
Michael Büsche27e2162016-03-04 22:41:19 +0100600 "Trickle charger enabled at %d ohms resistance.\n",
601 elem->r);
602 }
Mylène Josserande6e38082016-05-03 11:54:33 +0200603 err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
Michael Büsch39387dc2016-03-10 18:34:23 +0100604 RV3029_TRICKLE_MASK,
605 trickle_set_bits);
Michael Büsche27e2162016-03-04 22:41:19 +0100606 if (err < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200607 dev_err(dev, "Failed to update trickle charger config\n");
Michael Büsche27e2162016-03-04 22:41:19 +0100608 }
609}
610
Michael Büscha696b312016-03-10 18:34:46 +0100611#ifdef CONFIG_RTC_DRV_RV3029_HWMON
612
Mylène Josserande6e38082016-05-03 11:54:33 +0200613static int rv3029_read_temp(struct device *dev, int *temp_mC)
Michael Büscha696b312016-03-10 18:34:46 +0100614{
615 int ret;
616 u8 temp;
617
Mylène Josserande6e38082016-05-03 11:54:33 +0200618 ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
Michael Büscha696b312016-03-10 18:34:46 +0100619 if (ret < 0)
620 return ret;
621
622 *temp_mC = ((int)temp - 60) * 1000;
623
624 return 0;
625}
626
627static ssize_t rv3029_hwmon_show_temp(struct device *dev,
628 struct device_attribute *attr,
629 char *buf)
630{
Michael Büscha696b312016-03-10 18:34:46 +0100631 int ret, temp_mC;
632
Mylène Josserande6e38082016-05-03 11:54:33 +0200633 ret = rv3029_read_temp(dev, &temp_mC);
Michael Büscha696b312016-03-10 18:34:46 +0100634 if (ret < 0)
635 return ret;
636
637 return sprintf(buf, "%d\n", temp_mC);
638}
639
640static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
641 struct device_attribute *attr,
642 const char *buf,
643 size_t count)
644{
Michael Büscha696b312016-03-10 18:34:46 +0100645 unsigned long interval_ms;
646 int ret;
647 u8 th_set_bits = 0;
648
649 ret = kstrtoul(buf, 10, &interval_ms);
650 if (ret < 0)
651 return ret;
652
653 if (interval_ms != 0) {
654 th_set_bits |= RV3029_EECTRL_THE;
655 if (interval_ms >= 16000)
656 th_set_bits |= RV3029_EECTRL_THP;
657 }
Mylène Josserande6e38082016-05-03 11:54:33 +0200658 ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
Michael Büscha696b312016-03-10 18:34:46 +0100659 RV3029_EECTRL_THE | RV3029_EECTRL_THP,
660 th_set_bits);
661 if (ret < 0)
662 return ret;
663
664 return count;
665}
666
667static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
668 struct device_attribute *attr,
669 char *buf)
670{
Michael Büscha696b312016-03-10 18:34:46 +0100671 int ret, interval_ms;
672 u8 eectrl;
673
Mylène Josserande6e38082016-05-03 11:54:33 +0200674 ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
Michael Büscha696b312016-03-10 18:34:46 +0100675 &eectrl, 1);
676 if (ret < 0)
677 return ret;
678
679 if (eectrl & RV3029_EECTRL_THE) {
680 if (eectrl & RV3029_EECTRL_THP)
681 interval_ms = 16000;
682 else
683 interval_ms = 1000;
684 } else {
685 interval_ms = 0;
686 }
687
688 return sprintf(buf, "%d\n", interval_ms);
689}
690
691static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, rv3029_hwmon_show_temp,
692 NULL, 0);
693static SENSOR_DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO,
694 rv3029_hwmon_show_update_interval,
695 rv3029_hwmon_set_update_interval, 0);
696
697static struct attribute *rv3029_hwmon_attrs[] = {
698 &sensor_dev_attr_temp1_input.dev_attr.attr,
699 &sensor_dev_attr_update_interval.dev_attr.attr,
700 NULL,
701};
702ATTRIBUTE_GROUPS(rv3029_hwmon);
703
Mylène Josserande6e38082016-05-03 11:54:33 +0200704static void rv3029_hwmon_register(struct device *dev, const char *name)
Michael Büscha696b312016-03-10 18:34:46 +0100705{
Mylène Josserande6e38082016-05-03 11:54:33 +0200706 struct rv3029_data *rv3029 = dev_get_drvdata(dev);
Michael Büscha696b312016-03-10 18:34:46 +0100707 struct device *hwmon_dev;
708
Mylène Josserande6e38082016-05-03 11:54:33 +0200709 hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, rv3029,
710 rv3029_hwmon_groups);
Michael Büscha696b312016-03-10 18:34:46 +0100711 if (IS_ERR(hwmon_dev)) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200712 dev_warn(dev, "unable to register hwmon device %ld\n",
Mylène Josserand4e7f1a62016-05-03 11:54:32 +0200713 PTR_ERR(hwmon_dev));
Michael Büscha696b312016-03-10 18:34:46 +0100714 }
715}
716
717#else /* CONFIG_RTC_DRV_RV3029_HWMON */
718
Mylène Josserande6e38082016-05-03 11:54:33 +0200719static void rv3029_hwmon_register(struct device *dev, const char *name)
Michael Büscha696b312016-03-10 18:34:46 +0100720{
721}
722
723#endif /* CONFIG_RTC_DRV_RV3029_HWMON */
724
Michael Büschaba39d22016-03-04 22:38:45 +0100725static const struct rtc_class_ops rv3029_rtc_ops = {
Mylène Josserande6e38082016-05-03 11:54:33 +0200726 .read_time = rv3029_read_time,
727 .set_time = rv3029_set_time,
728 .read_alarm = rv3029_read_alarm,
729 .set_alarm = rv3029_set_alarm,
Heiko Schocher52365232011-05-26 16:25:05 -0700730};
731
Michael Büschaba39d22016-03-04 22:38:45 +0100732static struct i2c_device_id rv3029_id[] = {
Michael Büschbaba6232016-03-04 22:39:17 +0100733 { "rv3029", 0 },
Heiko Schocher52365232011-05-26 16:25:05 -0700734 { "rv3029c2", 0 },
735 { }
736};
Michael Büschaba39d22016-03-04 22:38:45 +0100737MODULE_DEVICE_TABLE(i2c, rv3029_id);
Heiko Schocher52365232011-05-26 16:25:05 -0700738
Mylène Josserande6e38082016-05-03 11:54:33 +0200739static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
740 const char *name)
Heiko Schocher52365232011-05-26 16:25:05 -0700741{
Mylène Josserande6e38082016-05-03 11:54:33 +0200742 struct rv3029_data *rv3029;
Heiko Schocher52365232011-05-26 16:25:05 -0700743 int rc = 0;
744 u8 buf[1];
745
Mylène Josserande6e38082016-05-03 11:54:33 +0200746 rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
747 if (!rv3029)
748 return -ENOMEM;
Heiko Schocher52365232011-05-26 16:25:05 -0700749
Mylène Josserande6e38082016-05-03 11:54:33 +0200750 rv3029->regmap = regmap;
751 rv3029->irq = irq;
752 rv3029->dev = dev;
753 dev_set_drvdata(dev, rv3029);
754
755 rc = rv3029_get_sr(dev, buf);
Gregory Hermant67ab2442014-04-03 14:50:17 -0700756 if (rc < 0) {
Mylène Josserande6e38082016-05-03 11:54:33 +0200757 dev_err(dev, "reading status failed\n");
Gregory Hermant67ab2442014-04-03 14:50:17 -0700758 return rc;
759 }
760
Mylène Josserande6e38082016-05-03 11:54:33 +0200761 rv3029_trickle_config(dev);
762 rv3029_hwmon_register(dev, name);
Michael Büsche27e2162016-03-04 22:41:19 +0100763
Mylène Josserande6e38082016-05-03 11:54:33 +0200764 rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
765 THIS_MODULE);
Heiko Schocher52365232011-05-26 16:25:05 -0700766
Mylène Josserande6e38082016-05-03 11:54:33 +0200767 return PTR_ERR_OR_ZERO(rv3029->rtc);
768}
Heiko Schocher52365232011-05-26 16:25:05 -0700769
Mylène Josserandc2a1c142016-05-03 11:54:34 +0200770#if IS_ENABLED(CONFIG_I2C)
771
Mylène Josserande6e38082016-05-03 11:54:33 +0200772static int rv3029_i2c_probe(struct i2c_client *client,
773 const struct i2c_device_id *id)
774{
775 struct regmap *regmap;
776 static const struct regmap_config config = {
777 .reg_bits = 8,
778 .val_bits = 8,
779 };
Heiko Schocher52365232011-05-26 16:25:05 -0700780
Mylène Josserande6e38082016-05-03 11:54:33 +0200781 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
782 I2C_FUNC_SMBUS_BYTE)) {
783 dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
784 return -ENODEV;
785 }
786
787 regmap = devm_regmap_init_i2c(client, &config);
788 if (IS_ERR(regmap)) {
789 dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
790 __func__, PTR_ERR(regmap));
791 return PTR_ERR(regmap);
792 }
793
794 return rv3029_probe(&client->dev, regmap, client->irq, client->name);
Heiko Schocher52365232011-05-26 16:25:05 -0700795}
796
Michael Büschaba39d22016-03-04 22:38:45 +0100797static struct i2c_driver rv3029_driver = {
Heiko Schocher52365232011-05-26 16:25:05 -0700798 .driver = {
799 .name = "rtc-rv3029c2",
800 },
Mylène Josserande6e38082016-05-03 11:54:33 +0200801 .probe = rv3029_i2c_probe,
Michael Büschaba39d22016-03-04 22:38:45 +0100802 .id_table = rv3029_id,
Heiko Schocher52365232011-05-26 16:25:05 -0700803};
804
Mylène Josserandc2a1c142016-05-03 11:54:34 +0200805static int rv3029_register_driver(void)
806{
807 return i2c_add_driver(&rv3029_driver);
808}
809
810static void rv3029_unregister_driver(void)
811{
812 i2c_del_driver(&rv3029_driver);
813}
814
815#else
816
817static int rv3029_register_driver(void)
818{
819 return 0;
820}
821
822static void rv3029_unregister_driver(void)
823{
824}
825
826#endif
827
828#if IS_ENABLED(CONFIG_SPI_MASTER)
829
830static int rv3049_probe(struct spi_device *spi)
831{
832 static const struct regmap_config config = {
833 .reg_bits = 8,
834 .val_bits = 8,
835 };
836 struct regmap *regmap;
837
838 regmap = devm_regmap_init_spi(spi, &config);
839 if (IS_ERR(regmap)) {
840 dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
841 __func__, PTR_ERR(regmap));
842 return PTR_ERR(regmap);
843 }
844
845 return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
846}
847
848static struct spi_driver rv3049_driver = {
849 .driver = {
850 .name = "rv3049",
851 },
852 .probe = rv3049_probe,
853};
854
855static int rv3049_register_driver(void)
856{
857 return spi_register_driver(&rv3049_driver);
858}
859
860static void rv3049_unregister_driver(void)
861{
862 spi_unregister_driver(&rv3049_driver);
863}
864
865#else
866
867static int rv3049_register_driver(void)
868{
869 return 0;
870}
871
872static void rv3049_unregister_driver(void)
873{
874}
875
876#endif
877
878static int __init rv30x9_init(void)
879{
880 int ret;
881
882 ret = rv3029_register_driver();
883 if (ret) {
884 pr_err("Failed to register rv3029 driver: %d\n", ret);
885 return ret;
886 }
887
888 ret = rv3049_register_driver();
889 if (ret) {
890 pr_err("Failed to register rv3049 driver: %d\n", ret);
891 rv3029_unregister_driver();
892 }
893
894 return ret;
895}
896module_init(rv30x9_init)
897
898static void __exit rv30x9_exit(void)
899{
900 rv3049_unregister_driver();
901 rv3029_unregister_driver();
902}
903module_exit(rv30x9_exit)
Heiko Schocher52365232011-05-26 16:25:05 -0700904
905MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
Michael Büsch2dca3d92016-03-04 22:40:30 +0100906MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
Mylène Josserandc2a1c142016-05-03 11:54:34 +0200907MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver");
Heiko Schocher52365232011-05-26 16:25:05 -0700908MODULE_LICENSE("GPL");
Mylène Josserandc2a1c142016-05-03 11:54:34 +0200909MODULE_ALIAS("spi:rv3049");