Blame view
drivers/rtc/rtc-rv3029c2.c
23.1 KB
52365230e
|
1 |
/* |
c2a1c1454
|
2 |
* Micro Crystal RV-3029 / RV-3049 rtc class driver |
52365230e
|
3 4 |
* * Author: Gregory Hermant <gregory.hermant@calao-systems.com> |
2dca3d9e1
|
5 |
* Michael Buesch <m@bues.ch> |
52365230e
|
6 7 8 9 10 11 12 |
* * based on previously existing rtc class drivers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * |
52365230e
|
13 14 15 16 |
*/ #include <linux/module.h> #include <linux/i2c.h> |
c2a1c1454
|
17 |
#include <linux/spi/spi.h> |
52365230e
|
18 19 |
#include <linux/bcd.h> #include <linux/rtc.h> |
a7f6e2874
|
20 21 |
#include <linux/delay.h> #include <linux/of.h> |
a696b31e2
|
22 23 |
#include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> |
e6e380821
|
24 |
#include <linux/regmap.h> |
52365230e
|
25 26 27 |
/* Register map */ /* control section */ |
aba39d27b
|
28 |
#define RV3029_ONOFF_CTRL 0x00 |
7697de35f
|
29 30 31 32 33 34 35 36 |
#define RV3029_ONOFF_CTRL_WE BIT(0) #define RV3029_ONOFF_CTRL_TE BIT(1) #define RV3029_ONOFF_CTRL_TAR BIT(2) #define RV3029_ONOFF_CTRL_EERE BIT(3) #define RV3029_ONOFF_CTRL_SRON BIT(4) #define RV3029_ONOFF_CTRL_TD0 BIT(5) #define RV3029_ONOFF_CTRL_TD1 BIT(6) #define RV3029_ONOFF_CTRL_CLKINT BIT(7) |
aba39d27b
|
37 |
#define RV3029_IRQ_CTRL 0x01 |
7697de35f
|
38 39 40 41 42 |
#define RV3029_IRQ_CTRL_AIE BIT(0) #define RV3029_IRQ_CTRL_TIE BIT(1) #define RV3029_IRQ_CTRL_V1IE BIT(2) #define RV3029_IRQ_CTRL_V2IE BIT(3) #define RV3029_IRQ_CTRL_SRIE BIT(4) |
aba39d27b
|
43 |
#define RV3029_IRQ_FLAGS 0x02 |
7697de35f
|
44 45 46 47 48 |
#define RV3029_IRQ_FLAGS_AF BIT(0) #define RV3029_IRQ_FLAGS_TF BIT(1) #define RV3029_IRQ_FLAGS_V1IF BIT(2) #define RV3029_IRQ_FLAGS_V2IF BIT(3) #define RV3029_IRQ_FLAGS_SRF BIT(4) |
aba39d27b
|
49 |
#define RV3029_STATUS 0x03 |
7697de35f
|
50 51 52 53 54 |
#define RV3029_STATUS_VLOW1 BIT(2) #define RV3029_STATUS_VLOW2 BIT(3) #define RV3029_STATUS_SR BIT(4) #define RV3029_STATUS_PON BIT(5) #define RV3029_STATUS_EEBUSY BIT(7) |
aba39d27b
|
55 |
#define RV3029_RST_CTRL 0x04 |
7697de35f
|
56 |
#define RV3029_RST_CTRL_SYSR BIT(4) |
aba39d27b
|
57 |
#define RV3029_CONTROL_SECTION_LEN 0x05 |
52365230e
|
58 59 |
/* watch section */ |
aba39d27b
|
60 61 62 |
#define RV3029_W_SEC 0x08 #define RV3029_W_MINUTES 0x09 #define RV3029_W_HOURS 0x0A |
7697de35f
|
63 64 |
#define RV3029_REG_HR_12_24 BIT(6) /* 24h/12h mode */ #define RV3029_REG_HR_PM BIT(5) /* PM/AM bit in 12h mode */ |
aba39d27b
|
65 66 67 68 69 |
#define RV3029_W_DATE 0x0B #define RV3029_W_DAYS 0x0C #define RV3029_W_MONTHS 0x0D #define RV3029_W_YEARS 0x0E #define RV3029_WATCH_SECTION_LEN 0x07 |
52365230e
|
70 71 |
/* alarm section */ |
aba39d27b
|
72 73 74 75 76 77 78 |
#define RV3029_A_SC 0x10 #define RV3029_A_MN 0x11 #define RV3029_A_HR 0x12 #define RV3029_A_DT 0x13 #define RV3029_A_DW 0x14 #define RV3029_A_MO 0x15 #define RV3029_A_YR 0x16 |
dc492e866
|
79 |
#define RV3029_A_AE_X BIT(7) |
aba39d27b
|
80 |
#define RV3029_ALARM_SECTION_LEN 0x07 |
52365230e
|
81 82 |
/* timer section */ |
aba39d27b
|
83 84 |
#define RV3029_TIMER_LOW 0x18 #define RV3029_TIMER_HIGH 0x19 |
52365230e
|
85 86 |
/* temperature section */ |
aba39d27b
|
87 |
#define RV3029_TEMP_PAGE 0x20 |
52365230e
|
88 89 |
/* eeprom data section */ |
aba39d27b
|
90 91 |
#define RV3029_E2P_EEDATA1 0x28 #define RV3029_E2P_EEDATA2 0x29 |
7697de35f
|
92 |
#define RV3029_E2PDATA_SECTION_LEN 0x02 |
52365230e
|
93 94 |
/* eeprom control section */ |
aba39d27b
|
95 |
#define RV3029_CONTROL_E2P_EECTRL 0x30 |
7697de35f
|
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
#define RV3029_EECTRL_THP BIT(0) /* temp scan interval */ #define RV3029_EECTRL_THE BIT(1) /* thermometer enable */ #define RV3029_EECTRL_FD0 BIT(2) /* CLKOUT */ #define RV3029_EECTRL_FD1 BIT(3) /* CLKOUT */ #define RV3029_TRICKLE_1K BIT(4) /* 1.5K resistance */ #define RV3029_TRICKLE_5K BIT(5) /* 5K resistance */ #define RV3029_TRICKLE_20K BIT(6) /* 20K resistance */ #define RV3029_TRICKLE_80K BIT(7) /* 80K resistance */ #define RV3029_TRICKLE_MASK (RV3029_TRICKLE_1K |\ RV3029_TRICKLE_5K |\ RV3029_TRICKLE_20K |\ RV3029_TRICKLE_80K) #define RV3029_TRICKLE_SHIFT 4 #define RV3029_CONTROL_E2P_XOFFS 0x31 /* XTAL offset */ #define RV3029_CONTROL_E2P_XOFFS_SIGN BIT(7) /* Sign: 1->pos, 0->neg */ #define RV3029_CONTROL_E2P_QCOEF 0x32 /* XTAL temp drift coef */ #define RV3029_CONTROL_E2P_TURNOVER 0x33 /* XTAL turnover temp (in *C) */ #define RV3029_CONTROL_E2P_TOV_MASK 0x3F /* XTAL turnover temp mask */ |
52365230e
|
114 115 |
/* user ram section */ |
aba39d27b
|
116 117 118 119 |
#define RV3029_USR1_RAM_PAGE 0x38 #define RV3029_USR1_SECTION_LEN 0x04 #define RV3029_USR2_RAM_PAGE 0x3C #define RV3029_USR2_SECTION_LEN 0x04 |
52365230e
|
120 |
|
e6e380821
|
121 122 123 124 125 126 127 128 |
struct rv3029_data { struct device *dev; struct rtc_device *rtc; struct regmap *regmap; int irq; }; static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf, |
abe2f551e
|
129 |
unsigned int len) |
52365230e
|
130 |
{ |
e6e380821
|
131 |
struct rv3029_data *rv3029 = dev_get_drvdata(dev); |
52365230e
|
132 |
|
aba39d27b
|
133 |
if ((reg > RV3029_USR1_RAM_PAGE + 7) || |
abe2f551e
|
134 |
(reg + len > RV3029_USR1_RAM_PAGE + 8)) |
52365230e
|
135 |
return -EINVAL; |
e6e380821
|
136 |
return regmap_bulk_read(rv3029->regmap, reg, buf, len); |
52365230e
|
137 |
} |
e6e380821
|
138 |
static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[], |
abe2f551e
|
139 |
unsigned int len) |
52365230e
|
140 |
{ |
e6e380821
|
141 |
struct rv3029_data *rv3029 = dev_get_drvdata(dev); |
aba39d27b
|
142 |
if ((reg > RV3029_USR1_RAM_PAGE + 7) || |
abe2f551e
|
143 |
(reg + len > RV3029_USR1_RAM_PAGE + 8)) |
52365230e
|
144 |
return -EINVAL; |
e6e380821
|
145 |
return regmap_bulk_write(rv3029->regmap, reg, buf, len); |
52365230e
|
146 |
} |
e6e380821
|
147 |
static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set) |
2dca3d9e1
|
148 149 150 |
{ u8 buf; int ret; |
e6e380821
|
151 |
ret = rv3029_read_regs(dev, reg, &buf, 1); |
2dca3d9e1
|
152 153 154 155 |
if (ret < 0) return ret; buf &= ~mask; buf |= set & mask; |
e6e380821
|
156 |
ret = rv3029_write_regs(dev, reg, &buf, 1); |
2dca3d9e1
|
157 158 159 160 161 |
if (ret < 0) return ret; return 0; } |
e6e380821
|
162 |
static int rv3029_get_sr(struct device *dev, u8 *buf) |
52365230e
|
163 |
{ |
e6e380821
|
164 |
int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1); |
52365230e
|
165 166 167 |
if (ret < 0) return -EIO; |
e6e380821
|
168 169 |
dev_dbg(dev, "status = 0x%.2x (%d) ", buf[0], buf[0]); |
52365230e
|
170 171 |
return 0; } |
e6e380821
|
172 |
static int rv3029_set_sr(struct device *dev, u8 val) |
52365230e
|
173 174 175 176 177 |
{ u8 buf[1]; int sr; buf[0] = val; |
e6e380821
|
178 179 180 |
sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1); dev_dbg(dev, "status = 0x%.2x (%d) ", buf[0], buf[0]); |
52365230e
|
181 182 183 184 |
if (sr < 0) return -EIO; return 0; } |
e6e380821
|
185 |
static int rv3029_eeprom_busywait(struct device *dev) |
a7f6e2874
|
186 187 188 189 190 |
{ int i, ret; u8 sr; for (i = 100; i > 0; i--) { |
e6e380821
|
191 |
ret = rv3029_get_sr(dev, &sr); |
a7f6e2874
|
192 193 194 195 196 197 198 |
if (ret < 0) break; if (!(sr & RV3029_STATUS_EEBUSY)) break; usleep_range(1000, 10000); } if (i <= 0) { |
e6e380821
|
199 200 |
dev_err(dev, "EEPROM busy wait timeout. "); |
a7f6e2874
|
201 202 203 204 205 |
return -ETIMEDOUT; } return ret; } |
e6e380821
|
206 |
static int rv3029_eeprom_exit(struct device *dev) |
a7f6e2874
|
207 208 |
{ /* Re-enable eeprom refresh */ |
e6e380821
|
209 |
return rv3029_update_bits(dev, RV3029_ONOFF_CTRL, |
4e7f1a605
|
210 211 |
RV3029_ONOFF_CTRL_EERE, RV3029_ONOFF_CTRL_EERE); |
a7f6e2874
|
212 |
} |
e6e380821
|
213 |
static int rv3029_eeprom_enter(struct device *dev) |
a7f6e2874
|
214 215 216 217 218 |
{ int ret; u8 sr; /* Check whether we are in the allowed voltage range. */ |
e6e380821
|
219 |
ret = rv3029_get_sr(dev, &sr); |
a7f6e2874
|
220 221 222 223 224 225 226 227 |
if (ret < 0) return ret; if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) { /* We clear the bits and retry once just in case * we had a brown out in early startup. */ sr &= ~RV3029_STATUS_VLOW1; sr &= ~RV3029_STATUS_VLOW2; |
e6e380821
|
228 |
ret = rv3029_set_sr(dev, sr); |
a7f6e2874
|
229 230 231 |
if (ret < 0) return ret; usleep_range(1000, 10000); |
e6e380821
|
232 |
ret = rv3029_get_sr(dev, &sr); |
a7f6e2874
|
233 234 235 |
if (ret < 0) return ret; if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) { |
e6e380821
|
236 |
dev_err(dev, |
a7f6e2874
|
237 238 239 240 241 242 243 |
"Supply voltage is too low to safely access the EEPROM. "); return -ENODEV; } } /* Disable eeprom refresh. */ |
e6e380821
|
244 245 |
ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE, 0); |
a7f6e2874
|
246 247 248 249 |
if (ret < 0) return ret; /* Wait for any previous eeprom accesses to finish. */ |
e6e380821
|
250 |
ret = rv3029_eeprom_busywait(dev); |
a7f6e2874
|
251 |
if (ret < 0) |
e6e380821
|
252 |
rv3029_eeprom_exit(dev); |
a7f6e2874
|
253 254 255 |
return ret; } |
e6e380821
|
256 |
static int rv3029_eeprom_read(struct device *dev, u8 reg, |
a7f6e2874
|
257 258 259 |
u8 buf[], size_t len) { int ret, err; |
e6e380821
|
260 |
err = rv3029_eeprom_enter(dev); |
a7f6e2874
|
261 262 |
if (err < 0) return err; |
e6e380821
|
263 |
ret = rv3029_read_regs(dev, reg, buf, len); |
a7f6e2874
|
264 |
|
e6e380821
|
265 |
err = rv3029_eeprom_exit(dev); |
a7f6e2874
|
266 267 268 269 270 |
if (err < 0) return err; return ret; } |
e6e380821
|
271 |
static int rv3029_eeprom_write(struct device *dev, u8 reg, |
a7f6e2874
|
272 273 274 275 276 |
u8 const buf[], size_t len) { int ret, err; size_t i; u8 tmp; |
e6e380821
|
277 |
err = rv3029_eeprom_enter(dev); |
a7f6e2874
|
278 279 280 281 |
if (err < 0) return err; for (i = 0; i < len; i++, reg++) { |
e6e380821
|
282 |
ret = rv3029_read_regs(dev, reg, &tmp, 1); |
a7f6e2874
|
283 284 285 |
if (ret < 0) break; if (tmp != buf[i]) { |
e6e380821
|
286 |
ret = rv3029_write_regs(dev, reg, &buf[i], 1); |
a7f6e2874
|
287 288 289 |
if (ret < 0) break; } |
e6e380821
|
290 |
ret = rv3029_eeprom_busywait(dev); |
a7f6e2874
|
291 292 293 |
if (ret < 0) break; } |
e6e380821
|
294 |
err = rv3029_eeprom_exit(dev); |
a7f6e2874
|
295 296 297 298 299 |
if (err < 0) return err; return ret; } |
e6e380821
|
300 |
static int rv3029_eeprom_update_bits(struct device *dev, |
39387dc2c
|
301 302 303 304 |
u8 reg, u8 mask, u8 set) { u8 buf; int ret; |
e6e380821
|
305 |
ret = rv3029_eeprom_read(dev, reg, &buf, 1); |
39387dc2c
|
306 307 308 309 |
if (ret < 0) return ret; buf &= ~mask; buf |= set & mask; |
e6e380821
|
310 |
ret = rv3029_eeprom_write(dev, reg, &buf, 1); |
39387dc2c
|
311 312 313 314 315 |
if (ret < 0) return ret; return 0; } |
0ddc5b89c
|
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
static irqreturn_t rv3029_handle_irq(int irq, void *dev_id) { struct device *dev = dev_id; struct rv3029_data *rv3029 = dev_get_drvdata(dev); struct mutex *lock = &rv3029->rtc->ops_lock; unsigned long events = 0; u8 flags, controls; int ret; mutex_lock(lock); ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1); if (ret) { dev_warn(dev, "Read IRQ Control Register error %d ", ret); mutex_unlock(lock); return IRQ_NONE; } ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1); if (ret) { dev_warn(dev, "Read IRQ Flags Register error %d ", ret); mutex_unlock(lock); return IRQ_NONE; } if (flags & RV3029_IRQ_FLAGS_AF) { flags &= ~RV3029_IRQ_FLAGS_AF; controls &= ~RV3029_IRQ_CTRL_AIE; events |= RTC_AF; } if (events) { rtc_update_irq(rv3029->rtc, 1, events); rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1); rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1); } mutex_unlock(lock); return IRQ_HANDLED; } |
e6e380821
|
358 |
static int rv3029_read_time(struct device *dev, struct rtc_time *tm) |
52365230e
|
359 360 361 |
{ u8 buf[1]; int ret; |
aba39d27b
|
362 |
u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, }; |
52365230e
|
363 |
|
e6e380821
|
364 |
ret = rv3029_get_sr(dev, buf); |
52365230e
|
365 |
if (ret < 0) { |
e6e380821
|
366 367 |
dev_err(dev, "%s: reading SR failed ", __func__); |
52365230e
|
368 369 |
return -EIO; } |
e6e380821
|
370 |
ret = rv3029_read_regs(dev, RV3029_W_SEC, regs, |
4e7f1a605
|
371 |
RV3029_WATCH_SECTION_LEN); |
52365230e
|
372 |
if (ret < 0) { |
e6e380821
|
373 374 |
dev_err(dev, "%s: reading RTC section failed ", __func__); |
52365230e
|
375 376 |
return ret; } |
abe2f551e
|
377 378 |
tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]); tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]); |
52365230e
|
379 380 381 |
/* HR field has a more complex interpretation */ { |
abe2f551e
|
382 |
const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC]; |
aba39d27b
|
383 384 |
if (_hr & RV3029_REG_HR_12_24) { |
52365230e
|
385 386 |
/* 12h format */ tm->tm_hour = bcd2bin(_hr & 0x1f); |
aba39d27b
|
387 |
if (_hr & RV3029_REG_HR_PM) /* PM flag set */ |
52365230e
|
388 389 390 391 |
tm->tm_hour += 12; } else /* 24h format */ tm->tm_hour = bcd2bin(_hr & 0x3f); } |
abe2f551e
|
392 393 394 395 |
tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]); tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1; tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 100; tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1; |
52365230e
|
396 397 398 |
return 0; } |
e6e380821
|
399 |
static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
52365230e
|
400 401 402 |
{ struct rtc_time *const tm = &alarm->time; int ret; |
0ddc5b89c
|
403 |
u8 regs[8], controls, flags; |
52365230e
|
404 |
|
e6e380821
|
405 |
ret = rv3029_get_sr(dev, regs); |
52365230e
|
406 |
if (ret < 0) { |
e6e380821
|
407 408 |
dev_err(dev, "%s: reading SR failed ", __func__); |
52365230e
|
409 410 |
return -EIO; } |
e6e380821
|
411 |
ret = rv3029_read_regs(dev, RV3029_A_SC, regs, |
4e7f1a605
|
412 |
RV3029_ALARM_SECTION_LEN); |
52365230e
|
413 414 |
if (ret < 0) { |
e6e380821
|
415 416 |
dev_err(dev, "%s: reading alarm section failed ", __func__); |
52365230e
|
417 418 |
return ret; } |
0ddc5b89c
|
419 420 421 422 423 424 425 426 427 428 429 430 |
ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1); if (ret) { dev_err(dev, "Read IRQ Control Register error %d ", ret); return ret; } ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1); if (ret < 0) { dev_err(dev, "Read IRQ Flags Register error %d ", ret); return ret; } |
abe2f551e
|
431 432 433 434 435 436 437 |
tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f); tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f); tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f); tm->tm_mday = bcd2bin(regs[RV3029_A_DT - RV3029_A_SC] & 0x3f); tm->tm_mon = bcd2bin(regs[RV3029_A_MO - RV3029_A_SC] & 0x1f) - 1; tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100; tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1; |
52365230e
|
438 |
|
0ddc5b89c
|
439 440 |
alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE); alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled; |
52365230e
|
441 442 |
return 0; } |
0ddc5b89c
|
443 |
static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable) |
52365230e
|
444 445 |
{ int ret; |
0ddc5b89c
|
446 447 448 449 450 451 452 453 |
u8 controls; ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1); if (ret < 0) { dev_warn(dev, "Read IRQ Control Register error %d ", ret); return ret; } |
52365230e
|
454 |
|
2dca3d9e1
|
455 |
/* enable/disable AIE irq */ |
0ddc5b89c
|
456 457 458 459 460 461 |
if (enable) controls |= RV3029_IRQ_CTRL_AIE; else controls &= ~RV3029_IRQ_CTRL_AIE; ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1); |
52365230e
|
462 |
if (ret < 0) { |
e6e380821
|
463 464 |
dev_err(dev, "can't update INT reg "); |
52365230e
|
465 466 467 468 469 |
return ret; } return 0; } |
e6e380821
|
470 |
static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
52365230e
|
471 472 473 474 475 476 477 478 479 480 481 482 |
{ struct rtc_time *const tm = &alarm->time; int ret; u8 regs[8]; /* * The clock has an 8 bit wide bcd-coded register (they never learn) * for the year. tm_year is an offset from 1900 and we are interested * in the 2000-2099 range, so any value less than 100 is invalid. */ if (tm->tm_year < 100) return -EINVAL; |
e6e380821
|
483 |
ret = rv3029_get_sr(dev, regs); |
52365230e
|
484 |
if (ret < 0) { |
e6e380821
|
485 486 |
dev_err(dev, "%s: reading SR failed ", __func__); |
52365230e
|
487 488 |
return -EIO; } |
aba39d27b
|
489 |
|
dc492e866
|
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
/* Activate all the alarms with AE_x bit */ regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X; regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X; regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour) & 0x3f) | RV3029_A_AE_X; regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday) & 0x3f) | RV3029_A_AE_X; regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd(tm->tm_mon + 1) & 0x1f) | RV3029_A_AE_X; regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd(tm->tm_wday + 1) & 0x7) | RV3029_A_AE_X; regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd(tm->tm_year - 100)) | RV3029_A_AE_X; /* Write the alarm */ |
e6e380821
|
505 |
ret = rv3029_write_regs(dev, RV3029_A_SC, regs, |
4e7f1a605
|
506 |
RV3029_ALARM_SECTION_LEN); |
52365230e
|
507 508 509 510 |
if (ret < 0) return ret; if (alarm->enabled) { |
52365230e
|
511 |
/* enable AIE irq */ |
0ddc5b89c
|
512 |
ret = rv3029_alarm_irq_enable(dev, 1); |
52365230e
|
513 514 |
if (ret) return ret; |
52365230e
|
515 516 |
} else { /* disable AIE irq */ |
0ddc5b89c
|
517 |
ret = rv3029_alarm_irq_enable(dev, 0); |
52365230e
|
518 519 |
if (ret) return ret; |
52365230e
|
520 521 522 523 |
} return 0; } |
e6e380821
|
524 |
static int rv3029_set_time(struct device *dev, struct rtc_time *tm) |
52365230e
|
525 526 527 528 529 530 531 532 533 534 535 |
{ u8 regs[8]; int ret; /* * The clock has an 8 bit wide bcd-coded register (they never learn) * for the year. tm_year is an offset from 1900 and we are interested * in the 2000-2099 range, so any value less than 100 is invalid. */ if (tm->tm_year < 100) return -EINVAL; |
abe2f551e
|
536 537 538 539 540 |
regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec); regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min); regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour); regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday); regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1); |
38201ca3c
|
541 |
regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7; |
abe2f551e
|
542 |
regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100); |
52365230e
|
543 |
|
e6e380821
|
544 |
ret = rv3029_write_regs(dev, RV3029_W_SEC, regs, |
4e7f1a605
|
545 |
RV3029_WATCH_SECTION_LEN); |
52365230e
|
546 547 |
if (ret < 0) return ret; |
e6e380821
|
548 |
ret = rv3029_get_sr(dev, regs); |
52365230e
|
549 |
if (ret < 0) { |
e6e380821
|
550 551 |
dev_err(dev, "%s: reading SR failed ", __func__); |
52365230e
|
552 553 554 |
return ret; } /* clear PON bit */ |
e6e380821
|
555 |
ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON)); |
52365230e
|
556 |
if (ret < 0) { |
e6e380821
|
557 558 |
dev_err(dev, "%s: reading SR failed ", __func__); |
52365230e
|
559 560 561 562 563 |
return ret; } return 0; } |
abe2f551e
|
564 |
|
e27e21603
|
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 |
static const struct rv3029_trickle_tab_elem { u32 r; /* resistance in ohms */ u8 conf; /* trickle config bits */ } rv3029_trickle_tab[] = { { .r = 1076, .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K | RV3029_TRICKLE_20K | RV3029_TRICKLE_80K, }, { .r = 1091, .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K | RV3029_TRICKLE_20K, }, { .r = 1137, .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K | RV3029_TRICKLE_80K, }, { .r = 1154, .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K, }, { .r = 1371, .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_20K | RV3029_TRICKLE_80K, }, { .r = 1395, .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_20K, }, { .r = 1472, .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_80K, }, { .r = 1500, .conf = RV3029_TRICKLE_1K, }, { .r = 3810, .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_20K | RV3029_TRICKLE_80K, }, { .r = 4000, .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_20K, }, { .r = 4706, .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_80K, }, { .r = 5000, .conf = RV3029_TRICKLE_5K, }, { .r = 16000, .conf = RV3029_TRICKLE_20K | RV3029_TRICKLE_80K, }, { .r = 20000, .conf = RV3029_TRICKLE_20K, }, { .r = 80000, .conf = RV3029_TRICKLE_80K, }, }; |
e6e380821
|
621 |
static void rv3029_trickle_config(struct device *dev) |
e27e21603
|
622 |
{ |
e6e380821
|
623 |
struct device_node *of_node = dev->of_node; |
e27e21603
|
624 625 626 |
const struct rv3029_trickle_tab_elem *elem; int i, err; u32 ohms; |
39387dc2c
|
627 |
u8 trickle_set_bits; |
e27e21603
|
628 629 630 631 632 |
if (!of_node) return; /* Configure the trickle charger. */ |
e27e21603
|
633 634 635 |
err = of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms); if (err) { /* Disable trickle charger. */ |
39387dc2c
|
636 |
trickle_set_bits = 0; |
e27e21603
|
637 638 639 640 641 642 643 |
} else { /* Enable trickle charger. */ for (i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++) { elem = &rv3029_trickle_tab[i]; if (elem->r >= ohms) break; } |
39387dc2c
|
644 |
trickle_set_bits = elem->conf; |
e6e380821
|
645 |
dev_info(dev, |
e27e21603
|
646 647 648 649 |
"Trickle charger enabled at %d ohms resistance. ", elem->r); } |
e6e380821
|
650 |
err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL, |
39387dc2c
|
651 652 |
RV3029_TRICKLE_MASK, trickle_set_bits); |
abe2f551e
|
653 |
if (err < 0) |
e6e380821
|
654 655 |
dev_err(dev, "Failed to update trickle charger config "); |
e27e21603
|
656 |
} |
a696b31e2
|
657 |
#ifdef CONFIG_RTC_DRV_RV3029_HWMON |
e6e380821
|
658 |
static int rv3029_read_temp(struct device *dev, int *temp_mC) |
a696b31e2
|
659 660 661 |
{ int ret; u8 temp; |
e6e380821
|
662 |
ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1); |
a696b31e2
|
663 664 665 666 667 668 669 670 671 672 673 674 |
if (ret < 0) return ret; *temp_mC = ((int)temp - 60) * 1000; return 0; } static ssize_t rv3029_hwmon_show_temp(struct device *dev, struct device_attribute *attr, char *buf) { |
a696b31e2
|
675 |
int ret, temp_mC; |
e6e380821
|
676 |
ret = rv3029_read_temp(dev, &temp_mC); |
a696b31e2
|
677 678 679 680 681 682 683 684 685 686 687 688 |
if (ret < 0) return ret; return sprintf(buf, "%d ", temp_mC); } static ssize_t rv3029_hwmon_set_update_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { |
a696b31e2
|
689 690 691 692 693 694 695 696 697 698 699 700 701 |
unsigned long interval_ms; int ret; u8 th_set_bits = 0; ret = kstrtoul(buf, 10, &interval_ms); if (ret < 0) return ret; if (interval_ms != 0) { th_set_bits |= RV3029_EECTRL_THE; if (interval_ms >= 16000) th_set_bits |= RV3029_EECTRL_THP; } |
e6e380821
|
702 |
ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL, |
a696b31e2
|
703 704 705 706 707 708 709 710 711 712 713 714 |
RV3029_EECTRL_THE | RV3029_EECTRL_THP, th_set_bits); if (ret < 0) return ret; return count; } static ssize_t rv3029_hwmon_show_update_interval(struct device *dev, struct device_attribute *attr, char *buf) { |
a696b31e2
|
715 716 |
int ret, interval_ms; u8 eectrl; |
e6e380821
|
717 |
ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL, |
a696b31e2
|
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 |
&eectrl, 1); if (ret < 0) return ret; if (eectrl & RV3029_EECTRL_THE) { if (eectrl & RV3029_EECTRL_THP) interval_ms = 16000; else interval_ms = 1000; } else { interval_ms = 0; } return sprintf(buf, "%d ", interval_ms); } static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, rv3029_hwmon_show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, rv3029_hwmon_show_update_interval, rv3029_hwmon_set_update_interval, 0); static struct attribute *rv3029_hwmon_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_update_interval.dev_attr.attr, NULL, }; ATTRIBUTE_GROUPS(rv3029_hwmon); |
e6e380821
|
747 |
static void rv3029_hwmon_register(struct device *dev, const char *name) |
a696b31e2
|
748 |
{ |
e6e380821
|
749 |
struct rv3029_data *rv3029 = dev_get_drvdata(dev); |
a696b31e2
|
750 |
struct device *hwmon_dev; |
e6e380821
|
751 752 |
hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, rv3029, rv3029_hwmon_groups); |
a696b31e2
|
753 |
if (IS_ERR(hwmon_dev)) { |
e6e380821
|
754 755 |
dev_warn(dev, "unable to register hwmon device %ld ", |
4e7f1a605
|
756 |
PTR_ERR(hwmon_dev)); |
a696b31e2
|
757 758 759 760 |
} } #else /* CONFIG_RTC_DRV_RV3029_HWMON */ |
e6e380821
|
761 |
static void rv3029_hwmon_register(struct device *dev, const char *name) |
a696b31e2
|
762 763 764 765 |
{ } #endif /* CONFIG_RTC_DRV_RV3029_HWMON */ |
0ddc5b89c
|
766 |
static struct rtc_class_ops rv3029_rtc_ops = { |
e6e380821
|
767 768 |
.read_time = rv3029_read_time, .set_time = rv3029_set_time, |
52365230e
|
769 |
}; |
e6e380821
|
770 771 |
static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq, const char *name) |
52365230e
|
772 |
{ |
e6e380821
|
773 |
struct rv3029_data *rv3029; |
52365230e
|
774 775 |
int rc = 0; u8 buf[1]; |
e6e380821
|
776 777 778 779 780 781 782 783 |
rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL); if (!rv3029) return -ENOMEM; rv3029->regmap = regmap; rv3029->irq = irq; rv3029->dev = dev; dev_set_drvdata(dev, rv3029); |
52365230e
|
784 |
|
e6e380821
|
785 |
rc = rv3029_get_sr(dev, buf); |
67ab2440b
|
786 |
if (rc < 0) { |
e6e380821
|
787 788 |
dev_err(dev, "reading status failed "); |
67ab2440b
|
789 790 |
return rc; } |
e6e380821
|
791 792 793 794 795 |
rv3029_trickle_config(dev); rv3029_hwmon_register(dev, name); rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops, THIS_MODULE); |
0ddc5b89c
|
796 797 798 799 800 |
if (IS_ERR(rv3029->rtc)) { dev_err(dev, "unable to register the class device "); return PTR_ERR(rv3029->rtc); } |
e27e21603
|
801 |
|
0ddc5b89c
|
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 |
if (rv3029->irq > 0) { rc = devm_request_threaded_irq(dev, rv3029->irq, NULL, rv3029_handle_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "rv3029", dev); if (rc) { dev_warn(dev, "unable to request IRQ, alarms disabled "); rv3029->irq = 0; } else { rv3029_rtc_ops.read_alarm = rv3029_read_alarm; rv3029_rtc_ops.set_alarm = rv3029_set_alarm; rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable; } } return 0; |
e6e380821
|
819 |
} |
52365230e
|
820 |
|
c2a1c1454
|
821 |
#if IS_ENABLED(CONFIG_I2C) |
e6e380821
|
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 |
static int rv3029_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct regmap *regmap; static const struct regmap_config config = { .reg_bits = 8, .val_bits = 8, }; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_BYTE)) { dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE "); return -ENODEV; } |
52365230e
|
837 |
|
e6e380821
|
838 839 840 841 842 843 844 |
regmap = devm_regmap_init_i2c(client, &config); if (IS_ERR(regmap)) { dev_err(&client->dev, "%s: regmap allocation failed: %ld ", __func__, PTR_ERR(regmap)); return PTR_ERR(regmap); } |
52365230e
|
845 |
|
e6e380821
|
846 |
return rv3029_probe(&client->dev, regmap, client->irq, client->name); |
52365230e
|
847 |
} |
814db2bc4
|
848 849 850 851 852 853 |
static struct i2c_device_id rv3029_id[] = { { "rv3029", 0 }, { "rv3029c2", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, rv3029_id); |
aba39d27b
|
854 |
static struct i2c_driver rv3029_driver = { |
52365230e
|
855 856 857 |
.driver = { .name = "rtc-rv3029c2", }, |
e6e380821
|
858 |
.probe = rv3029_i2c_probe, |
aba39d27b
|
859 |
.id_table = rv3029_id, |
52365230e
|
860 |
}; |
c2a1c1454
|
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 |
static int rv3029_register_driver(void) { return i2c_add_driver(&rv3029_driver); } static void rv3029_unregister_driver(void) { i2c_del_driver(&rv3029_driver); } #else static int rv3029_register_driver(void) { return 0; } static void rv3029_unregister_driver(void) { } #endif #if IS_ENABLED(CONFIG_SPI_MASTER) static int rv3049_probe(struct spi_device *spi) { static const struct regmap_config config = { .reg_bits = 8, .val_bits = 8, }; struct regmap *regmap; regmap = devm_regmap_init_spi(spi, &config); if (IS_ERR(regmap)) { dev_err(&spi->dev, "%s: regmap allocation failed: %ld ", __func__, PTR_ERR(regmap)); return PTR_ERR(regmap); } return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049"); } static struct spi_driver rv3049_driver = { .driver = { .name = "rv3049", }, .probe = rv3049_probe, }; static int rv3049_register_driver(void) { return spi_register_driver(&rv3049_driver); } static void rv3049_unregister_driver(void) { spi_unregister_driver(&rv3049_driver); } #else static int rv3049_register_driver(void) { return 0; } static void rv3049_unregister_driver(void) { } #endif static int __init rv30x9_init(void) { int ret; ret = rv3029_register_driver(); if (ret) { pr_err("Failed to register rv3029 driver: %d ", ret); return ret; } ret = rv3049_register_driver(); if (ret) { pr_err("Failed to register rv3049 driver: %d ", ret); rv3029_unregister_driver(); } return ret; } module_init(rv30x9_init) static void __exit rv30x9_exit(void) { rv3049_unregister_driver(); rv3029_unregister_driver(); } module_exit(rv30x9_exit) |
52365230e
|
963 964 |
MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>"); |
2dca3d9e1
|
965 |
MODULE_AUTHOR("Michael Buesch <m@bues.ch>"); |
c2a1c1454
|
966 |
MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver"); |
52365230e
|
967 |
MODULE_LICENSE("GPL"); |
c2a1c1454
|
968 |
MODULE_ALIAS("spi:rv3049"); |