Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: add rv3029c2 RTC support

Add support for the Micro Crystal RV3029-C2 RTC chips.

Signed-off-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Gregory Hermant <gregory.hermant@calao-systems.com>
Cc: Wan ZongShun <mcuos.com@gmail.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Acked-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Heiko Schocher and committed by
Linus Torvalds
52365230 ae3551f9

+464
+9
drivers/rtc/Kconfig
··· 370 370 This driver can also be built as a module. If so, the module 371 371 will be called rtc-em3027. 372 372 373 + config RTC_DRV_RV3029C2 374 + tristate "Micro Crystal RTC" 375 + help 376 + If you say yes here you get support for the Micro Crystal 377 + RV3029-C2 RTC chips. 378 + 379 + This driver can also be built as a module. If so, the module 380 + will be called rtc-rv3029c2. 381 + 373 382 endif # I2C 374 383 375 384 comment "SPI RTC drivers"
+1
drivers/rtc/Makefile
··· 83 83 obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o 84 84 obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o 85 85 obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o 86 + obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o 86 87 obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o 87 88 obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o 88 89 obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o
+454
drivers/rtc/rtc-rv3029c2.c
··· 1 + /* 2 + * Micro Crystal RV-3029C2 rtc class driver 3 + * 4 + * Author: Gregory Hermant <gregory.hermant@calao-systems.com> 5 + * 6 + * based on previously existing rtc class drivers 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * NOTE: Currently this driver only supports the bare minimum for read 13 + * and write the RTC and alarms. The extra features provided by this chip 14 + * (trickle charger, eeprom, T° compensation) are unavailable. 15 + */ 16 + 17 + #include <linux/module.h> 18 + #include <linux/i2c.h> 19 + #include <linux/bcd.h> 20 + #include <linux/rtc.h> 21 + 22 + /* Register map */ 23 + /* control section */ 24 + #define RV3029C2_ONOFF_CTRL 0x00 25 + #define RV3029C2_IRQ_CTRL 0x01 26 + #define RV3029C2_IRQ_CTRL_AIE (1 << 0) 27 + #define RV3029C2_IRQ_FLAGS 0x02 28 + #define RV3029C2_IRQ_FLAGS_AF (1 << 0) 29 + #define RV3029C2_STATUS 0x03 30 + #define RV3029C2_STATUS_VLOW1 (1 << 2) 31 + #define RV3029C2_STATUS_VLOW2 (1 << 3) 32 + #define RV3029C2_STATUS_SR (1 << 4) 33 + #define RV3029C2_STATUS_PON (1 << 5) 34 + #define RV3029C2_STATUS_EEBUSY (1 << 7) 35 + #define RV3029C2_RST_CTRL 0x04 36 + #define RV3029C2_CONTROL_SECTION_LEN 0x05 37 + 38 + /* watch section */ 39 + #define RV3029C2_W_SEC 0x08 40 + #define RV3029C2_W_MINUTES 0x09 41 + #define RV3029C2_W_HOURS 0x0A 42 + #define RV3029C2_REG_HR_12_24 (1<<6) /* 24h/12h mode */ 43 + #define RV3029C2_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */ 44 + #define RV3029C2_W_DATE 0x0B 45 + #define RV3029C2_W_DAYS 0x0C 46 + #define RV3029C2_W_MONTHS 0x0D 47 + #define RV3029C2_W_YEARS 0x0E 48 + #define RV3029C2_WATCH_SECTION_LEN 0x07 49 + 50 + /* alarm section */ 51 + #define RV3029C2_A_SC 0x10 52 + #define RV3029C2_A_MN 0x11 53 + #define RV3029C2_A_HR 0x12 54 + #define RV3029C2_A_DT 0x13 55 + #define RV3029C2_A_DW 0x14 56 + #define RV3029C2_A_MO 0x15 57 + #define RV3029C2_A_YR 0x16 58 + #define RV3029C2_ALARM_SECTION_LEN 0x07 59 + 60 + /* timer section */ 61 + #define RV3029C2_TIMER_LOW 0x18 62 + #define RV3029C2_TIMER_HIGH 0x19 63 + 64 + /* temperature section */ 65 + #define RV3029C2_TEMP_PAGE 0x20 66 + 67 + /* eeprom data section */ 68 + #define RV3029C2_E2P_EEDATA1 0x28 69 + #define RV3029C2_E2P_EEDATA2 0x29 70 + 71 + /* eeprom control section */ 72 + #define RV3029C2_CONTROL_E2P_EECTRL 0x30 73 + #define RV3029C2_TRICKLE_1K (1<<0) /* 1K resistance */ 74 + #define RV3029C2_TRICKLE_5K (1<<1) /* 5K resistance */ 75 + #define RV3029C2_TRICKLE_20K (1<<2) /* 20K resistance */ 76 + #define RV3029C2_TRICKLE_80K (1<<3) /* 80K resistance */ 77 + #define RV3029C2_CONTROL_E2P_XTALOFFSET 0x31 78 + #define RV3029C2_CONTROL_E2P_QCOEF 0x32 79 + #define RV3029C2_CONTROL_E2P_TURNOVER 0x33 80 + 81 + /* user ram section */ 82 + #define RV3029C2_USR1_RAM_PAGE 0x38 83 + #define RV3029C2_USR1_SECTION_LEN 0x04 84 + #define RV3029C2_USR2_RAM_PAGE 0x3C 85 + #define RV3029C2_USR2_SECTION_LEN 0x04 86 + 87 + static int 88 + rv3029c2_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf, 89 + unsigned len) 90 + { 91 + int ret; 92 + 93 + if ((reg > RV3029C2_USR1_RAM_PAGE + 7) || 94 + (reg + len > RV3029C2_USR1_RAM_PAGE + 8)) 95 + return -EINVAL; 96 + 97 + ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf); 98 + if (ret < 0) 99 + return ret; 100 + if (ret < len) 101 + return -EIO; 102 + return 0; 103 + } 104 + 105 + static int 106 + rv3029c2_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], 107 + unsigned len) 108 + { 109 + if ((reg > RV3029C2_USR1_RAM_PAGE + 7) || 110 + (reg + len > RV3029C2_USR1_RAM_PAGE + 8)) 111 + return -EINVAL; 112 + 113 + return i2c_smbus_write_i2c_block_data(client, reg, len, buf); 114 + } 115 + 116 + static int 117 + rv3029c2_i2c_get_sr(struct i2c_client *client, u8 *buf) 118 + { 119 + int ret = rv3029c2_i2c_read_regs(client, RV3029C2_STATUS, buf, 1); 120 + 121 + if (ret < 0) 122 + return -EIO; 123 + dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); 124 + return 0; 125 + } 126 + 127 + static int 128 + rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val) 129 + { 130 + u8 buf[1]; 131 + int sr; 132 + 133 + buf[0] = val; 134 + sr = rv3029c2_i2c_write_regs(client, RV3029C2_STATUS, buf, 1); 135 + dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]); 136 + if (sr < 0) 137 + return -EIO; 138 + return 0; 139 + } 140 + 141 + static int 142 + rv3029c2_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) 143 + { 144 + u8 buf[1]; 145 + int ret; 146 + u8 regs[RV3029C2_WATCH_SECTION_LEN] = { 0, }; 147 + 148 + ret = rv3029c2_i2c_get_sr(client, buf); 149 + if (ret < 0) { 150 + dev_err(&client->dev, "%s: reading SR failed\n", __func__); 151 + return -EIO; 152 + } 153 + 154 + ret = rv3029c2_i2c_read_regs(client, RV3029C2_W_SEC , regs, 155 + RV3029C2_WATCH_SECTION_LEN); 156 + if (ret < 0) { 157 + dev_err(&client->dev, "%s: reading RTC section failed\n", 158 + __func__); 159 + return ret; 160 + } 161 + 162 + tm->tm_sec = bcd2bin(regs[RV3029C2_W_SEC-RV3029C2_W_SEC]); 163 + tm->tm_min = bcd2bin(regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC]); 164 + 165 + /* HR field has a more complex interpretation */ 166 + { 167 + const u8 _hr = regs[RV3029C2_W_HOURS-RV3029C2_W_SEC]; 168 + if (_hr & RV3029C2_REG_HR_12_24) { 169 + /* 12h format */ 170 + tm->tm_hour = bcd2bin(_hr & 0x1f); 171 + if (_hr & RV3029C2_REG_HR_PM) /* PM flag set */ 172 + tm->tm_hour += 12; 173 + } else /* 24h format */ 174 + tm->tm_hour = bcd2bin(_hr & 0x3f); 175 + } 176 + 177 + tm->tm_mday = bcd2bin(regs[RV3029C2_W_DATE-RV3029C2_W_SEC]); 178 + tm->tm_mon = bcd2bin(regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC]) - 1; 179 + tm->tm_year = bcd2bin(regs[RV3029C2_W_YEARS-RV3029C2_W_SEC]) + 100; 180 + tm->tm_wday = bcd2bin(regs[RV3029C2_W_DAYS-RV3029C2_W_SEC]) - 1; 181 + 182 + return 0; 183 + } 184 + 185 + static int rv3029c2_rtc_read_time(struct device *dev, struct rtc_time *tm) 186 + { 187 + return rv3029c2_i2c_read_time(to_i2c_client(dev), tm); 188 + } 189 + 190 + static int 191 + rv3029c2_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) 192 + { 193 + struct rtc_time *const tm = &alarm->time; 194 + int ret; 195 + u8 regs[8]; 196 + 197 + ret = rv3029c2_i2c_get_sr(client, regs); 198 + if (ret < 0) { 199 + dev_err(&client->dev, "%s: reading SR failed\n", __func__); 200 + return -EIO; 201 + } 202 + 203 + ret = rv3029c2_i2c_read_regs(client, RV3029C2_A_SC, regs, 204 + RV3029C2_ALARM_SECTION_LEN); 205 + 206 + if (ret < 0) { 207 + dev_err(&client->dev, "%s: reading alarm section failed\n", 208 + __func__); 209 + return ret; 210 + } 211 + 212 + tm->tm_sec = bcd2bin(regs[RV3029C2_A_SC-RV3029C2_A_SC] & 0x7f); 213 + tm->tm_min = bcd2bin(regs[RV3029C2_A_MN-RV3029C2_A_SC] & 0x7f); 214 + tm->tm_hour = bcd2bin(regs[RV3029C2_A_HR-RV3029C2_A_SC] & 0x3f); 215 + tm->tm_mday = bcd2bin(regs[RV3029C2_A_DT-RV3029C2_A_SC] & 0x3f); 216 + tm->tm_mon = bcd2bin(regs[RV3029C2_A_MO-RV3029C2_A_SC] & 0x1f) - 1; 217 + tm->tm_year = bcd2bin(regs[RV3029C2_A_YR-RV3029C2_A_SC] & 0x7f) + 100; 218 + tm->tm_wday = bcd2bin(regs[RV3029C2_A_DW-RV3029C2_A_SC] & 0x07) - 1; 219 + 220 + return 0; 221 + } 222 + 223 + static int 224 + rv3029c2_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 225 + { 226 + return rv3029c2_i2c_read_alarm(to_i2c_client(dev), alarm); 227 + } 228 + 229 + static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client, 230 + int enable) 231 + { 232 + int ret; 233 + u8 buf[1]; 234 + 235 + /* enable AIE irq */ 236 + ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_CTRL, buf, 1); 237 + if (ret < 0) { 238 + dev_err(&client->dev, "can't read INT reg\n"); 239 + return ret; 240 + } 241 + if (enable) 242 + buf[0] |= RV3029C2_IRQ_CTRL_AIE; 243 + else 244 + buf[0] &= ~RV3029C2_IRQ_CTRL_AIE; 245 + 246 + ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_CTRL, buf, 1); 247 + if (ret < 0) { 248 + dev_err(&client->dev, "can't set INT reg\n"); 249 + return ret; 250 + } 251 + 252 + return 0; 253 + } 254 + 255 + static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client, 256 + struct rtc_wkalrm *alarm) 257 + { 258 + struct rtc_time *const tm = &alarm->time; 259 + int ret; 260 + u8 regs[8]; 261 + 262 + /* 263 + * The clock has an 8 bit wide bcd-coded register (they never learn) 264 + * for the year. tm_year is an offset from 1900 and we are interested 265 + * in the 2000-2099 range, so any value less than 100 is invalid. 266 + */ 267 + if (tm->tm_year < 100) 268 + return -EINVAL; 269 + 270 + ret = rv3029c2_i2c_get_sr(client, regs); 271 + if (ret < 0) { 272 + dev_err(&client->dev, "%s: reading SR failed\n", __func__); 273 + return -EIO; 274 + } 275 + regs[RV3029C2_A_SC-RV3029C2_A_SC] = bin2bcd(tm->tm_sec & 0x7f); 276 + regs[RV3029C2_A_MN-RV3029C2_A_SC] = bin2bcd(tm->tm_min & 0x7f); 277 + regs[RV3029C2_A_HR-RV3029C2_A_SC] = bin2bcd(tm->tm_hour & 0x3f); 278 + regs[RV3029C2_A_DT-RV3029C2_A_SC] = bin2bcd(tm->tm_mday & 0x3f); 279 + regs[RV3029C2_A_MO-RV3029C2_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1); 280 + regs[RV3029C2_A_DW-RV3029C2_A_SC] = bin2bcd((tm->tm_wday & 7) - 1); 281 + regs[RV3029C2_A_YR-RV3029C2_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100); 282 + 283 + ret = rv3029c2_i2c_write_regs(client, RV3029C2_A_SC, regs, 284 + RV3029C2_ALARM_SECTION_LEN); 285 + if (ret < 0) 286 + return ret; 287 + 288 + if (alarm->enabled) { 289 + u8 buf[1]; 290 + 291 + /* clear AF flag */ 292 + ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_FLAGS, 293 + buf, 1); 294 + if (ret < 0) { 295 + dev_err(&client->dev, "can't read alarm flag\n"); 296 + return ret; 297 + } 298 + buf[0] &= ~RV3029C2_IRQ_FLAGS_AF; 299 + ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_FLAGS, 300 + buf, 1); 301 + if (ret < 0) { 302 + dev_err(&client->dev, "can't set alarm flag\n"); 303 + return ret; 304 + } 305 + /* enable AIE irq */ 306 + ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1); 307 + if (ret) 308 + return ret; 309 + 310 + dev_dbg(&client->dev, "alarm IRQ armed\n"); 311 + } else { 312 + /* disable AIE irq */ 313 + ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1); 314 + if (ret) 315 + return ret; 316 + 317 + dev_dbg(&client->dev, "alarm IRQ disabled\n"); 318 + } 319 + 320 + return 0; 321 + } 322 + 323 + static int rv3029c2_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) 324 + { 325 + return rv3029c2_rtc_i2c_set_alarm(to_i2c_client(dev), alarm); 326 + } 327 + 328 + static int 329 + rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) 330 + { 331 + u8 regs[8]; 332 + int ret; 333 + 334 + /* 335 + * The clock has an 8 bit wide bcd-coded register (they never learn) 336 + * for the year. tm_year is an offset from 1900 and we are interested 337 + * in the 2000-2099 range, so any value less than 100 is invalid. 338 + */ 339 + if (tm->tm_year < 100) 340 + return -EINVAL; 341 + 342 + regs[RV3029C2_W_SEC-RV3029C2_W_SEC] = bin2bcd(tm->tm_sec); 343 + regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC] = bin2bcd(tm->tm_min); 344 + regs[RV3029C2_W_HOURS-RV3029C2_W_SEC] = bin2bcd(tm->tm_hour); 345 + regs[RV3029C2_W_DATE-RV3029C2_W_SEC] = bin2bcd(tm->tm_mday); 346 + regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC] = bin2bcd(tm->tm_mon+1); 347 + regs[RV3029C2_W_DAYS-RV3029C2_W_SEC] = bin2bcd((tm->tm_wday & 7)+1); 348 + regs[RV3029C2_W_YEARS-RV3029C2_W_SEC] = bin2bcd(tm->tm_year - 100); 349 + 350 + ret = rv3029c2_i2c_write_regs(client, RV3029C2_W_SEC, regs, 351 + RV3029C2_WATCH_SECTION_LEN); 352 + if (ret < 0) 353 + return ret; 354 + 355 + ret = rv3029c2_i2c_get_sr(client, regs); 356 + if (ret < 0) { 357 + dev_err(&client->dev, "%s: reading SR failed\n", __func__); 358 + return ret; 359 + } 360 + /* clear PON bit */ 361 + ret = rv3029c2_i2c_set_sr(client, (regs[0] & ~RV3029C2_STATUS_PON)); 362 + if (ret < 0) { 363 + dev_err(&client->dev, "%s: reading SR failed\n", __func__); 364 + return ret; 365 + } 366 + 367 + return 0; 368 + } 369 + 370 + static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm) 371 + { 372 + return rv3029c2_i2c_set_time(to_i2c_client(dev), tm); 373 + } 374 + 375 + static const struct rtc_class_ops rv3029c2_rtc_ops = { 376 + .read_time = rv3029c2_rtc_read_time, 377 + .set_time = rv3029c2_rtc_set_time, 378 + .read_alarm = rv3029c2_rtc_read_alarm, 379 + .set_alarm = rv3029c2_rtc_set_alarm, 380 + }; 381 + 382 + static struct i2c_device_id rv3029c2_id[] = { 383 + { "rv3029c2", 0 }, 384 + { } 385 + }; 386 + MODULE_DEVICE_TABLE(i2c, rv3029c2_id); 387 + 388 + static int __devinit 389 + rv3029c2_probe(struct i2c_client *client, const struct i2c_device_id *id) 390 + { 391 + struct rtc_device *rtc; 392 + int rc = 0; 393 + u8 buf[1]; 394 + 395 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL)) 396 + return -ENODEV; 397 + 398 + rtc = rtc_device_register(client->name, 399 + &client->dev, &rv3029c2_rtc_ops, 400 + THIS_MODULE); 401 + 402 + if (IS_ERR(rtc)) 403 + return PTR_ERR(rtc); 404 + 405 + i2c_set_clientdata(client, rtc); 406 + 407 + rc = rv3029c2_i2c_get_sr(client, buf); 408 + if (rc < 0) { 409 + dev_err(&client->dev, "reading status failed\n"); 410 + goto exit_unregister; 411 + } 412 + 413 + return 0; 414 + 415 + exit_unregister: 416 + rtc_device_unregister(rtc); 417 + 418 + return rc; 419 + } 420 + 421 + static int __devexit rv3029c2_remove(struct i2c_client *client) 422 + { 423 + struct rtc_device *rtc = i2c_get_clientdata(client); 424 + 425 + rtc_device_unregister(rtc); 426 + 427 + return 0; 428 + } 429 + 430 + static struct i2c_driver rv3029c2_driver = { 431 + .driver = { 432 + .name = "rtc-rv3029c2", 433 + }, 434 + .probe = rv3029c2_probe, 435 + .remove = __devexit_p(rv3029c2_remove), 436 + .id_table = rv3029c2_id, 437 + }; 438 + 439 + static int __init rv3029c2_init(void) 440 + { 441 + return i2c_add_driver(&rv3029c2_driver); 442 + } 443 + 444 + static void __exit rv3029c2_exit(void) 445 + { 446 + i2c_del_driver(&rv3029c2_driver); 447 + } 448 + 449 + module_init(rv3029c2_init); 450 + module_exit(rv3029c2_exit); 451 + 452 + MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>"); 453 + MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver"); 454 + MODULE_LICENSE("GPL");