RTC library for Max31341/2 devices
Fork of max3134x by
Embed:
(wiki syntax)
Show/hide line numbers
RtcBase.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 ******************************************************************************* 00032 */ 00033 00034 #include "RtcBase.h" 00035 00036 #define pr_err(fmt, ...) if(1) printf(fmt " (%s:%d)\r\n", ## __VA_ARGS__, __func__, __LINE__) 00037 #define pr_debug(fmt, ...) if(0) printf(fmt " (%s:%d)\r\n", ## __VA_ARGS__, __func__, __LINE__) 00038 00039 #define BCD2BIN(val) (((val) & 15) + ((val) >> 4) * 10) 00040 #define BIN2BCD(val) ((((val) / 10) << 4) + (val) % 10) 00041 00042 #define POST_INTR_WORK_SIGNAL_ID 0x1 00043 00044 RtcBase::RtcBase(const regmap_t *regmap, I2C *i2c, PinName inta_pin = NC, PinName intb_pin = NC) 00045 { 00046 if (i2c == NULL) { 00047 pr_err("i2c object is invalid!"); 00048 while (1); 00049 } 00050 i2c_handler = i2c; 00051 00052 this->regmap = regmap; 00053 00054 sw_reset_release(); 00055 00056 rtc_start(); 00057 00058 irq_disable_all(); 00059 00060 post_intr_work_thread = new Thread(); 00061 00062 post_intr_work_thread->start(Callback<void()>(this, &RtcBase::post_interrupt_work)); 00063 00064 if (inta_pin != NC) { 00065 this->inta_pin = new InterruptIn(inta_pin); 00066 00067 this->inta_pin->fall(Callback<void()>(this, &RtcBase::interrupt_handler)); 00068 00069 this->inta_pin->enable_irq(); 00070 } else { 00071 this->inta_pin = NULL; 00072 } 00073 00074 if (intb_pin != NC) { 00075 this->intb_pin = new InterruptIn(intb_pin); 00076 00077 this->intb_pin->fall(Callback<void()>(this, &RtcBase::interrupt_handler)); 00078 00079 this->intb_pin->enable_irq(); 00080 } else { 00081 this->intb_pin = NULL; 00082 } 00083 } 00084 00085 RtcBase::~RtcBase() 00086 { 00087 if (post_intr_work_thread) { 00088 delete post_intr_work_thread; 00089 } 00090 00091 if (inta_pin) { 00092 delete inta_pin; 00093 } 00094 00095 if (intb_pin) { 00096 delete intb_pin; 00097 } 00098 } 00099 00100 int RtcBase::read_register(uint8_t reg, uint8_t *value, uint8_t len) 00101 { 00102 int ret; 00103 00104 if (value == NULL) { 00105 pr_err("value is invalid!"); 00106 return -1; 00107 } 00108 00109 ret = i2c_handler->write(MAX3134X_I2C_W, (const char *) ®, 1, true); 00110 if (ret != 0) { 00111 pr_err("i2c write failed with %d!", ret); 00112 return -1; 00113 } 00114 00115 ret = i2c_handler->read(MAX3134X_I2C_R, (char *) value, len, false); 00116 if (ret < 0) { 00117 pr_err("i2c read failed with %d!", ret); 00118 return -1; 00119 } 00120 00121 return 0; 00122 } 00123 00124 int RtcBase::write_register(uint8_t reg, const uint8_t *value, uint8_t len) 00125 { 00126 int ret; 00127 uint8_t *buffer; 00128 00129 if (value == NULL) { 00130 pr_err("value is invalid!"); 00131 return -1; 00132 } 00133 00134 buffer = new uint8_t[1 + len]; 00135 buffer[0] = reg; 00136 00137 memcpy(&buffer[1], value, len); 00138 00139 ret = i2c_handler->write(MAX3134X_I2C_W, (const char *)buffer, 1 + len); 00140 if (ret != 0) { 00141 pr_err("i2c write failed with %d!", ret); 00142 } 00143 00144 delete[] buffer; 00145 00146 return ret; 00147 } 00148 00149 int RtcBase::rtc_regs_to_time(struct tm *time, const rtc_time_regs_t *regs) 00150 { 00151 /* tm_sec seconds [0,61] */ 00152 time->tm_sec = BCD2BIN(regs->seconds.bcd.value); 00153 00154 /* tm_min minutes [0,59] */ 00155 time->tm_min = BCD2BIN(regs->minutes.bcd.value); 00156 00157 /* tm_hour hour [0,23] */ 00158 time->tm_hour = BCD2BIN(regs->hours.bcd.value); 00159 00160 /* tm_wday day of week [0,6] (Sunday = 0) */ 00161 time->tm_wday = BCD2BIN(regs->day.bcd.value) - 1; 00162 00163 /* tm_mday day of month [1,31] */ 00164 time->tm_mday = BCD2BIN(regs->date.bcd.value); 00165 00166 /* tm_mon month of year [0,11] */ 00167 time->tm_mon = BCD2BIN(regs->month.bcd.value) - 1; 00168 00169 /* tm_year years since 2000 */ 00170 if (regs->month.bits.century) { 00171 time->tm_year = BCD2BIN(regs->year.bcd.value) + 200; 00172 } else { 00173 time->tm_year = BCD2BIN(regs->year.bcd.value) + 100; 00174 } 00175 00176 /* tm_yday day of year [0,365] */ 00177 time->tm_yday = 0; /* TODO */ 00178 00179 /* tm_isdst daylight savings flag */ 00180 time->tm_isdst = 0; /* TODO */ 00181 00182 return 0; 00183 } 00184 00185 int RtcBase::time_to_rtc_regs(rtc_time_regs_t *regs, const struct tm *time) 00186 { 00187 /********************************************************* 00188 * +----------+------+---------------------------+-------+ 00189 * | Member | Type | Meaning | Range | 00190 * +----------+------+---------------------------+-------+ 00191 * | tm_sec | int | seconds after the minute | 0-61* | 00192 * | tm_min | int | minutes after the hour | 0-59 | 00193 * | tm_hour | int | hours since midnight | 0-23 | 00194 * | tm_mday | int | day of the month | 1-31 | 00195 * | tm_mon | int | months since January | 0-11 | 00196 * | tm_year | int | years since 1900 | | 00197 * | tm_wday | int | days since Sunday | 0-6 | 00198 * | tm_yday | int | days since January 1 | 0-365 | 00199 * | tm_isdst | int | Daylight Saving Time flag | | 00200 * +----------+------+---------------------------+-------+ 00201 * * tm_sec is generally 0-59. The extra range is to accommodate for leap 00202 * seconds in certain systems. 00203 *********************************************************/ 00204 regs->seconds.bcd.value = BIN2BCD(time->tm_sec); 00205 00206 regs->minutes.bcd.value = BIN2BCD(time->tm_min); 00207 00208 regs->hours.bcd.value= BIN2BCD(time->tm_hour); 00209 00210 regs->day.bcd.value = BIN2BCD(time->tm_wday + 1); 00211 00212 regs->date.bcd.value = BIN2BCD(time->tm_mday); 00213 00214 regs->month.bcd.value = BIN2BCD(time->tm_mon + 1); 00215 00216 if (time->tm_year >= 200) { 00217 regs->month.bits.century = 1; 00218 regs->year.bcd.value = BIN2BCD(time->tm_year - 200); 00219 } else if (time->tm_year >= 100) { 00220 regs->month.bits.century = 0; 00221 regs->year.bcd.value = BIN2BCD(time->tm_year - 100); 00222 } else { 00223 pr_err("Invalid set date!"); 00224 return -1; 00225 } 00226 00227 return 0; 00228 } 00229 00230 int RtcBase::get_time(struct tm *time) 00231 { 00232 rtc_time_regs_t time_regs; 00233 00234 if (time == NULL) { 00235 pr_err("rtc_ctime is invalid!"); 00236 return -1; 00237 } 00238 00239 if (read_register(regmap->seconds, (uint8_t *) &time_regs, 00240 sizeof(time_regs)) < 0) { 00241 pr_err("read time registers failed!"); 00242 return -1; 00243 } 00244 00245 return rtc_regs_to_time(time, &time_regs); 00246 } 00247 00248 int RtcBase::set_rtc_time() 00249 { 00250 config_reg2_t reg; 00251 00252 /* Toggle Set_RTC bit to set RTC date */ 00253 00254 if (read_register(regmap->config_reg2, (uint8_t *)®, 1) < 0) { 00255 pr_err("read time registers failed!"); 00256 return -1; 00257 } 00258 00259 reg.bits.set_rtc = CONFIG_REG2_SET_RTC_RTCPRGM; 00260 if (write_register(regmap->config_reg2, (uint8_t *)®, 1) < 0) { 00261 pr_err("write config2 register failed!"); 00262 return -1; 00263 } 00264 00265 /* SET_RTC bit should be kept high at least 10ms */ 00266 ThisThread::sleep_for(10); 00267 00268 reg.bits.set_rtc = CONFIG_REG2_SET_RTC_RTCRUN; 00269 if (write_register(regmap->config_reg2, (uint8_t *)®, 1) < 0) { 00270 pr_err("write config2 register failed!"); 00271 return -1; 00272 } 00273 00274 return 0; 00275 } 00276 00277 int RtcBase::set_time(const struct tm *time) 00278 { 00279 rtc_time_regs_t time_regs; 00280 00281 if (time == NULL) { 00282 pr_err("rtc_ctime is invalid!"); 00283 return -1; 00284 } 00285 00286 time_to_rtc_regs(&time_regs, time); 00287 00288 if (write_register(regmap->seconds, (const uint8_t *) &time_regs, 00289 sizeof(time_regs)) < 0) { 00290 pr_err("read time registers failed!"); 00291 return -1; 00292 } 00293 00294 return set_rtc_time(); 00295 } 00296 00297 int RtcBase::nvram_write(const uint8_t *buffer, int offset, int length) 00298 { 00299 int totlen; 00300 00301 if (regmap->ram_start == REG_NOT_AVAILABLE) { 00302 pr_err("Device does not have NVRAM!"); 00303 return -1; 00304 } 00305 00306 totlen = regmap->ram_end - regmap->ram_start + 1; 00307 00308 if ((offset + length) > totlen) { 00309 return -1; 00310 } 00311 00312 if (length == 0) { 00313 return 0; 00314 } 00315 00316 if (write_register(regmap->ram_start + offset, buffer, length) < 0) { 00317 return -1; 00318 } 00319 00320 return 0; 00321 } 00322 00323 int RtcBase::nvram_read(uint8_t *buffer, int offset, int length) 00324 { 00325 int totlen; 00326 00327 if (regmap->ram_start == REG_NOT_AVAILABLE) { 00328 pr_err("Device does not have NVRAM!"); 00329 return -1; 00330 } 00331 00332 totlen = regmap->ram_end - regmap->ram_start + 1; 00333 00334 if ((offset + length) > totlen) { 00335 return -1; 00336 } 00337 00338 if (length == 0) { 00339 return -1; 00340 } 00341 00342 if (read_register(regmap->ram_start + offset, buffer, length) < 0) { 00343 return -1; 00344 } 00345 00346 return 0; 00347 } 00348 00349 int RtcBase::nvram_size() 00350 { 00351 if ((regmap->ram_start == REG_NOT_AVAILABLE) || 00352 (regmap->ram_end == REG_NOT_AVAILABLE)) { 00353 return 0; 00354 } 00355 00356 return regmap->ram_end - regmap->ram_start + 1; 00357 } 00358 00359 int RtcBase::time_to_alarm_regs(alarm_regs_t ®s, const struct tm *alarm_time) 00360 { 00361 regs.sec.bcd.value = BIN2BCD(alarm_time->tm_sec); 00362 regs.min.bcd.value = BIN2BCD(alarm_time->tm_min); 00363 regs.hrs.bcd.value = BIN2BCD(alarm_time->tm_hour); 00364 00365 if (regs.day_date.bits.dy_dt == 0) { 00366 /* Date match */ 00367 regs.day_date.bcd_date.value = BIN2BCD(alarm_time->tm_mday); 00368 } else { 00369 /* Day match */ 00370 regs.day_date.bcd_day.value = BIN2BCD(alarm_time->tm_wday); 00371 } 00372 regs.mon.bcd.value = BIN2BCD(alarm_time->tm_mon); 00373 00374 return 0; 00375 } 00376 00377 int RtcBase::alarm_regs_to_time(struct tm *alarm_time, const alarm_regs_t *regs) 00378 { 00379 alarm_time->tm_sec = BCD2BIN(regs->sec.bcd.value); 00380 alarm_time->tm_min = BCD2BIN(regs->min.bcd.value); 00381 alarm_time->tm_hour = BCD2BIN(regs->hrs.bcd.value); 00382 00383 if (regs->day_date.bits.dy_dt == 0) { /* date */ 00384 alarm_time->tm_mday = BCD2BIN(regs->day_date.bcd_date.value); 00385 } else { /* day */ 00386 alarm_time->tm_wday = BCD2BIN(regs->day_date.bcd_day.value); 00387 } 00388 00389 if (regmap->alm1_mon != REG_NOT_AVAILABLE) { 00390 alarm_time->tm_mon = BCD2BIN(regs->mon.bcd.value) - 1; 00391 } 00392 00393 if (regmap->alm1_year != REG_NOT_AVAILABLE) { 00394 alarm_time->tm_year = BCD2BIN(regs->year.bcd.value) + 100; /* XXX no century bit */ 00395 } 00396 00397 return 0; 00398 } 00399 00400 int RtcBase::set_alarm_period(alarm_no_t alarm_no, alarm_regs_t ®s, alarm_period_t period) 00401 { 00402 regs.sec.bits.a1m1 = 1; 00403 regs.min.bits.a1m2 = 1; 00404 regs.hrs.bits.a1m3 = 1; 00405 regs.day_date.bits.a1m4 = 1; 00406 regs.mon.bits.a1m5 = 1; 00407 regs.mon.bits.a1m6 = 1; 00408 regs.day_date.bits.dy_dt = 1; 00409 00410 switch (period) { 00411 case ALARM_PERIOD_ONETIME: 00412 if ((alarm_no == ALARM2) || (regmap->alm1_year == REG_NOT_AVAILABLE)) { /* not supported! */ 00413 return -1; 00414 } 00415 regs.mon.bits.a1m6 = 0; 00416 case ALARM_PERIOD_YEARLY: 00417 if ((alarm_no == ALARM2) || (regmap->alm1_mon == REG_NOT_AVAILABLE)) { /* not supported! */ 00418 return -1; 00419 } 00420 regs.mon.bits.a1m5 = 0; 00421 case ALARM_PERIOD_MONTHLY: 00422 regs.day_date.bits.dy_dt = 0; 00423 case ALARM_PERIOD_WEEKLY: 00424 regs.day_date.bits.a1m4 = 0; 00425 case ALARM_PERIOD_DAILY: 00426 regs.hrs.bits.a1m3 = 0; 00427 case ALARM_PERIOD_HOURLY: 00428 regs.min.bits.a1m2 = 0; 00429 case ALARM_PERIOD_EVERYMINUTE: 00430 regs.sec.bits.a1m1 = 0; 00431 case ALARM_PERIOD_EVERYSECOND: 00432 if ((alarm_no == ALARM2) && (period == ALARM_PERIOD_EVERYSECOND)) { 00433 return -1; /* Alarm2 does not support "once per second" alarm*/ 00434 } 00435 break; 00436 default: 00437 return -1; 00438 } 00439 00440 return 0; 00441 } 00442 00443 int RtcBase::set_alarm_regs(alarm_no_t alarm_no, const alarm_regs_t *regs) 00444 { 00445 uint8_t *ptr_regs = (uint8_t *)regs; 00446 uint8_t off = 0; 00447 uint8_t dev_ba; 00448 uint8_t len = sizeof(alarm_regs_t); 00449 00450 if (alarm_no == ALARM1) { 00451 dev_ba = regmap->alm1_sec; 00452 if (regmap->alm1_mon == REG_NOT_AVAILABLE) len -= 2; /* discard mon & year registers */ 00453 } else { 00454 dev_ba = regmap->alm2_min; 00455 off = 1; /* starts from min register */ 00456 len -= 3; /* discard min, mon & sec registers */ 00457 } 00458 00459 return write_register(dev_ba, &ptr_regs[off], len); 00460 } 00461 00462 int RtcBase::get_alarm_regs(alarm_no_t alarm_no, alarm_regs_t *regs) 00463 { 00464 uint8_t *ptr_regs = (uint8_t *)regs; 00465 uint8_t off = 0; 00466 uint8_t dev_ba; 00467 uint8_t len = sizeof(alarm_regs_t); 00468 00469 if (alarm_no == ALARM1) { 00470 dev_ba = regmap->alm1_sec; 00471 if (regmap->alm1_mon == REG_NOT_AVAILABLE) len -= 2; /* discard mon & year registers */ 00472 } else { 00473 regs->sec.raw = 0; /* zeroise second register for alarm2 */ 00474 dev_ba = regmap->alm2_min; 00475 off = 1; /* starts from min register (no sec register) */ 00476 len -= 2; /* discard mon & sec registers */ 00477 } 00478 00479 return read_register(dev_ba, &ptr_regs[off], len); 00480 } 00481 00482 int RtcBase::set_alarm(alarm_no_t alarm_no, const struct tm *alarm_time, alarm_period_t period) 00483 { 00484 int ret; 00485 alarm_regs_t regs; 00486 00487 ret = set_alarm_period(alarm_no, regs, period); 00488 if (ret) { 00489 return ret; 00490 } 00491 00492 /* Convert time structure to alarm registers */ 00493 ret = time_to_alarm_regs(regs, alarm_time); 00494 if (ret) { 00495 return ret; 00496 } 00497 00498 ret = set_alarm_regs(alarm_no, ®s); 00499 if (ret) { 00500 return ret; 00501 } 00502 00503 return 0; 00504 } 00505 00506 int RtcBase::get_alarm(alarm_no_t alarm_no, struct tm *alarm_time, alarm_period_t *period, bool *is_enabled) 00507 { 00508 int ret; 00509 alarm_regs_t regs; 00510 uint8_t reg; 00511 00512 ret = get_alarm_regs(alarm_no, ®s); 00513 if (ret) { 00514 return ret; 00515 } 00516 00517 /* Convert alarm registers to time structure */ 00518 ret = alarm_regs_to_time(alarm_time, ®s); 00519 if (ret) { 00520 return ret; 00521 } 00522 00523 *period = (alarm_no == ALARM1) ? ALARM_PERIOD_EVERYSECOND : ALARM_PERIOD_EVERYMINUTE; 00524 00525 if ((alarm_no == ALARM1) && (regs.sec.bits.a1m1 == 0)) *period = ALARM_PERIOD_EVERYMINUTE; 00526 if (regs.min.bits.a1m2 == 0) *period = ALARM_PERIOD_HOURLY; 00527 if (regs.hrs.bits.a1m3 == 0) *period = ALARM_PERIOD_DAILY; 00528 if (regs.day_date.bits.a1m4 == 0) *period = ALARM_PERIOD_WEEKLY; 00529 if (regs.day_date.bits.dy_dt == 0) *period = ALARM_PERIOD_MONTHLY; 00530 if ((alarm_no == ALARM1) && (regmap->alm1_mon != REG_NOT_AVAILABLE) && (regs.mon.bits.a1m5 == 0)) *period = ALARM_PERIOD_YEARLY; 00531 if ((alarm_no == ALARM1) && (regmap->alm1_mon != REG_NOT_AVAILABLE) && (regs.mon.bits.a1m6 == 0)) *period = ALARM_PERIOD_ONETIME; 00532 00533 ret = read_register(regmap->int_en_reg, (uint8_t *)®, 1); 00534 if (ret) { 00535 return ret; 00536 } 00537 00538 if (alarm_no == ALARM1) { 00539 *is_enabled = (reg & (1 << INTR_ID_ALARM1)) != 0; 00540 } else { 00541 *is_enabled = (reg & (1 << INTR_ID_ALARM2)) != 0; 00542 } 00543 00544 return 0; 00545 } 00546 00547 int RtcBase::set_power_mgmt_mode(power_mgmt_mode_t mode) 00548 { 00549 int ret; 00550 pwr_mgmt_reg_t reg; 00551 00552 if (regmap->pwr_mgmt_reg == REG_NOT_AVAILABLE) { 00553 pr_err("Device does not support power mgmt!"); 00554 return -1; 00555 } 00556 00557 ret = read_register(regmap->pwr_mgmt_reg, (uint8_t *)®, 1); 00558 if (ret) { 00559 return ret; 00560 } 00561 00562 reg.bits.d_mode = mode; 00563 00564 ret = write_register(regmap->pwr_mgmt_reg, (uint8_t *)®, 1); 00565 if (ret) { 00566 return ret; 00567 } 00568 00569 return 0; 00570 } 00571 00572 int RtcBase::comparator_threshold_level(comp_thresh_t th) 00573 { 00574 int ret; 00575 config_reg2_t reg; 00576 00577 if (regmap->pwr_mgmt_reg == REG_NOT_AVAILABLE) { 00578 pr_err("Device does not support analog comparator!"); 00579 return -1; 00580 } 00581 00582 ret = read_register(regmap->config_reg2, (uint8_t *)®, 1); 00583 if (ret) { 00584 return ret; 00585 } 00586 00587 reg.bits.bref = th; 00588 00589 ret = write_register(regmap->config_reg2, (uint8_t *)®, 1); 00590 if (ret) { 00591 return ret; 00592 } 00593 00594 return 0; 00595 } 00596 00597 int RtcBase::supply_select(power_mgmt_supply_t supply) 00598 { 00599 int ret; 00600 pwr_mgmt_reg_t reg; 00601 00602 if (regmap->pwr_mgmt_reg == REG_NOT_AVAILABLE) { 00603 pr_err("Device does not support power mgmt!"); 00604 return -1; 00605 } 00606 00607 ret = read_register(regmap->pwr_mgmt_reg, (uint8_t *)®, 1); 00608 if (ret) { 00609 return ret; 00610 } 00611 00612 switch (supply) { 00613 case POW_MGMT_SUPPLY_SEL_VCC: 00614 reg.bits.d_man_sel = 1; 00615 reg.bits.d_vback_sel = 0; 00616 break; 00617 case POW_MGMT_SUPPLY_SEL_AIN: 00618 reg.bits.d_man_sel = 1; 00619 reg.bits.d_vback_sel = 1; 00620 break; 00621 case POW_MGMT_SUPPLY_SEL_AUTO: 00622 default: 00623 reg.bits.d_man_sel = 0; 00624 break; 00625 } 00626 00627 ret = write_register(regmap->pwr_mgmt_reg, (uint8_t *)®, 1); 00628 if (ret) { 00629 return ret; 00630 } 00631 00632 return 0; 00633 } 00634 00635 int RtcBase::trickle_charger_enable(trickle_charger_ohm_t res, bool diode) 00636 { 00637 int ret; 00638 struct { 00639 unsigned char ohm : 2; 00640 unsigned char diode : 1; 00641 unsigned char schottky : 1; 00642 unsigned char : 4; 00643 } reg; 00644 00645 if (regmap->trickle_reg == REG_NOT_AVAILABLE) { /* trickle charger not supported! */ 00646 pr_err("Device does not support trickle charger!"); 00647 return -1; 00648 } 00649 00650 reg.ohm = res; 00651 00652 reg.diode = (diode) ? 1 : 0; 00653 00654 reg.schottky = 1; /* always enabled */ 00655 00656 ret = write_register(regmap->trickle_reg, (uint8_t *)®, 1); 00657 if (ret) { 00658 return ret; 00659 } 00660 00661 return 0; 00662 } 00663 00664 int RtcBase::trickle_charger_disable() 00665 { 00666 int ret; 00667 uint8_t reg; 00668 00669 if (regmap->trickle_reg == REG_NOT_AVAILABLE) { /* trickle charger not supported! */ 00670 pr_err("Device does not support trickle charger!"); 00671 return -1; 00672 } 00673 00674 reg = 0; 00675 00676 ret = write_register(regmap->trickle_reg, ®, 1); 00677 if (ret) { 00678 return ret; 00679 } 00680 00681 return 0; 00682 } 00683 00684 00685 int RtcBase::set_output_square_wave_frequency(square_wave_out_freq_t freq) 00686 { 00687 int ret; 00688 config_reg1_t reg; 00689 00690 ret = read_register(regmap->config_reg1, (uint8_t *)®, 1); 00691 if (ret) { 00692 return ret; 00693 } 00694 00695 reg.bits.rs = freq; 00696 00697 ret = write_register(regmap->config_reg1, (uint8_t *)®, 1); 00698 if (ret) { 00699 return ret; 00700 } 00701 00702 return 0; 00703 } 00704 00705 int RtcBase::set_clock_sync_delay(sync_delay_t delay) 00706 { 00707 int ret; 00708 clock_sync_reg_t reg; 00709 00710 ret = read_register(regmap->clock_sync_delay, (uint8_t *)®, 1); 00711 if (ret) { 00712 return ret; 00713 } 00714 00715 reg.bits.sync_delay = delay; 00716 00717 ret = write_register(regmap->clock_sync_delay, (uint8_t *)®, 1); 00718 if (ret) { 00719 return ret; 00720 } 00721 00722 return 0; 00723 } 00724 00725 int RtcBase::set_clkin_frequency(clkin_freq_t freq) 00726 { 00727 int ret; 00728 config_reg1_t reg; 00729 00730 ret = read_register(regmap->config_reg1, (uint8_t *)®, 1); 00731 if (ret) { 00732 return ret; 00733 } 00734 00735 reg.bits.clksel = freq; 00736 00737 ret = write_register(regmap->config_reg1, (uint8_t *)®, 1); 00738 if (ret) { 00739 return ret; 00740 } 00741 00742 if (freq == CLKIN_FREQ_1HZ) { 00743 ret = set_clock_sync_delay(SYNC_DLY_LESS_THAN_1SEC); 00744 } else { 00745 ret = set_clock_sync_delay(SYNC_DLY_LESS_THAN_100MS); 00746 } 00747 00748 return ret; 00749 } 00750 00751 int RtcBase::configure_intb_clkout_pin(config_intb_clkout_pin_t sel) 00752 { 00753 int ret; 00754 config_reg1_t reg; 00755 00756 ret = read_register(regmap->config_reg1, (uint8_t *)®, 1); 00757 if (ret) { 00758 return ret; 00759 } 00760 00761 reg.bits.intcn = (sel == CONFIGURE_PIN_AS_INTB) ? 1 : 0; 00762 00763 ret = write_register(regmap->config_reg1, (uint8_t *)®, 1); 00764 if (ret) { 00765 return ret; 00766 } 00767 00768 return 0; 00769 } 00770 00771 int RtcBase::configure_inta_clkin_pin(config_inta_clkin_pin_t sel) 00772 { 00773 int ret; 00774 config_reg1_t reg; 00775 00776 ret = read_register(regmap->config_reg1, (uint8_t *)®, 1); 00777 if (ret) { 00778 return ret; 00779 } 00780 00781 reg.bits.eclk = (sel == CONFIGURE_PIN_AS_CLKIN) ? 1 : 0; 00782 00783 ret = write_register(regmap->config_reg1, (uint8_t *)®, 1); 00784 if (ret) { 00785 return ret; 00786 } 00787 00788 if (sel == CONFIGURE_PIN_AS_CLKIN) { 00789 /* Default synchronization delay for external clock mode */ 00790 ret = set_clock_sync_delay(SYNC_DLY_LESS_THAN_1SEC); 00791 } else { 00792 /* Synchronization delay for internal oscillator mode */ 00793 ret = set_clock_sync_delay(SYNC_DLY_LESS_THAN_20MS); 00794 } 00795 00796 return ret; 00797 } 00798 00799 int RtcBase::timer_init(uint8_t value, bool repeat, timer_freq_t freq) 00800 { 00801 int ret; 00802 timer_config_t reg_cfg; 00803 00804 ret = read_register(regmap->timer_config, (uint8_t *)®_cfg, 1); 00805 if (ret) { 00806 return ret; 00807 } 00808 00809 reg_cfg.bits.te = 0; /* timer is reset */ 00810 reg_cfg.bits.tpause = 1; /* timer is paused */ 00811 reg_cfg.bits.trpt = repeat ? 1 : 0; /* Timer repeat mode */ 00812 reg_cfg.bits.tfs = freq; /* Timer frequency */ 00813 00814 ret = write_register(regmap->timer_config, (uint8_t *)®_cfg, 1); 00815 if (ret) { 00816 return ret; 00817 } 00818 00819 ret = write_register(regmap->timer_init, (uint8_t *)&value, 1); 00820 if (ret) { 00821 return ret; 00822 } 00823 00824 return 0; 00825 } 00826 00827 uint8_t RtcBase::timer_get() 00828 { 00829 int ret; 00830 uint8_t reg; 00831 00832 ret = read_register(regmap->timer_count, (uint8_t *)®, 1); 00833 if (ret) { 00834 return (uint8_t) - 1; 00835 } 00836 00837 return reg; 00838 } 00839 00840 int RtcBase::timer_start() 00841 { 00842 int ret; 00843 timer_config_t reg; 00844 00845 ret = read_register(regmap->timer_config, (uint8_t *)®, 1); 00846 if (ret) { 00847 return ret; 00848 } 00849 00850 reg.bits.te = 1; 00851 reg.bits.tpause = 0; 00852 00853 ret = write_register(regmap->timer_config, (uint8_t *)®, 1); 00854 if (ret) { 00855 return ret; 00856 } 00857 00858 return 0; 00859 } 00860 00861 int RtcBase::timer_pause() 00862 { 00863 int ret; 00864 timer_config_t reg; 00865 00866 ret = read_register(regmap->timer_config, (uint8_t *)®, 1); 00867 if (ret) { 00868 return ret; 00869 } 00870 00871 reg.bits.te = 1; 00872 reg.bits.tpause = 1; 00873 00874 ret = write_register(regmap->timer_config, (uint8_t *)®, 1); 00875 if (ret) { 00876 return ret; 00877 } 00878 00879 return 0; 00880 } 00881 00882 int RtcBase::timer_continue() 00883 { 00884 int ret; 00885 timer_config_t reg; 00886 00887 ret = read_register(regmap->timer_config, (uint8_t *)®, 1); 00888 if (ret) { 00889 return ret; 00890 } 00891 00892 reg.bits.te = 1; 00893 reg.bits.tpause = 0; 00894 00895 ret = write_register(regmap->timer_config, (uint8_t *)®, 1); 00896 if (ret) { 00897 return ret; 00898 } 00899 00900 return 0; 00901 } 00902 00903 int RtcBase::timer_stop() 00904 { 00905 int ret; 00906 timer_config_t reg; 00907 00908 ret = read_register(regmap->timer_config, (uint8_t *)®, 1); 00909 if (ret) { 00910 return ret; 00911 } 00912 00913 reg.bits.te = 0; 00914 reg.bits.tpause = 1; 00915 00916 ret = write_register(regmap->timer_config, (uint8_t *)®, 1); 00917 if (ret) { 00918 return ret; 00919 } 00920 00921 return 0; 00922 } 00923 00924 int RtcBase::data_retention_mode_config(int state) 00925 { 00926 int ret; 00927 config_reg1_t cfg1; 00928 config_reg2_t cfg2; 00929 00930 ret = read_register(regmap->config_reg1, (uint8_t *)&cfg1, 1); 00931 if (ret) { 00932 return ret; 00933 } 00934 00935 ret = read_register(regmap->config_reg2, (uint8_t *)&cfg2, 1); 00936 if (ret) { 00937 return ret; 00938 } 00939 00940 if (state) { 00941 cfg1.bits.osconz = 1; 00942 cfg2.bits.data_reten = 1; 00943 } else { 00944 cfg1.bits.osconz = 0; 00945 cfg2.bits.data_reten = 0; 00946 } 00947 00948 ret = write_register(regmap->config_reg1, (uint8_t *)&cfg1, 1); 00949 if (ret) { 00950 return ret; 00951 } 00952 00953 ret = write_register(regmap->config_reg2, (uint8_t *)&cfg2, 1); 00954 if (ret) { 00955 return ret; 00956 } 00957 00958 return 0; 00959 } 00960 00961 int RtcBase::data_retention_mode_enter() 00962 { 00963 return data_retention_mode_config(1); 00964 } 00965 00966 int RtcBase::data_retention_mode_exit() 00967 { 00968 return data_retention_mode_config(0); 00969 } 00970 00971 int RtcBase::i2c_timeout_config(int enable) 00972 { 00973 int ret; 00974 config_reg2_t reg; 00975 00976 ret = read_register(regmap->config_reg2, (uint8_t *)®, 1); 00977 if (ret) { 00978 return ret; 00979 } 00980 00981 reg.bits.i2c_timeout = (enable) ? 1 : 0; 00982 00983 ret = write_register(regmap->config_reg2, (uint8_t *)®, 1); 00984 if (ret) { 00985 return ret; 00986 } 00987 00988 return 0; 00989 } 00990 00991 int RtcBase::i2c_timeout_enable() 00992 { 00993 return i2c_timeout_config(1); 00994 } 00995 00996 int RtcBase::i2c_timeout_disable() 00997 { 00998 return i2c_timeout_config(0); 00999 } 01000 01001 int RtcBase::irq_enable(intr_id_t id) 01002 { 01003 int ret; 01004 uint8_t reg; 01005 01006 ret = read_register(regmap->int_en_reg, ®, 1); 01007 if (ret) { 01008 return ret; 01009 } 01010 01011 reg |= (1 << id); 01012 01013 ret = write_register(regmap->int_en_reg, ®, 1); 01014 if (ret) { 01015 return ret; 01016 } 01017 01018 return 0; 01019 } 01020 01021 int RtcBase::irq_disable(intr_id_t id) 01022 { 01023 int ret; 01024 uint8_t reg; 01025 01026 ret = read_register(regmap->int_en_reg, ®, 1); 01027 if (ret) { 01028 return ret; 01029 } 01030 01031 reg &= ~(1 << id); 01032 01033 ret = write_register(regmap->int_en_reg, ®, 1); 01034 if (ret) { 01035 return ret; 01036 } 01037 01038 return 0; 01039 } 01040 01041 int RtcBase::irq_disable_all() 01042 { 01043 int ret; 01044 uint8_t reg = 0; 01045 01046 ret = write_register(regmap->int_en_reg, ®, 1); 01047 if (ret) { 01048 return ret; 01049 } 01050 01051 return 0; 01052 } 01053 01054 void RtcBase::set_intr_handler(intr_id_t id, interrupt_handler_function func, void *cb) 01055 { 01056 interrupt_handler_list[id].func = func; 01057 interrupt_handler_list[id].cb = cb; 01058 } 01059 01060 void RtcBase::post_interrupt_work() 01061 { 01062 int ret; 01063 uint8_t reg, inten, mask; 01064 01065 01066 while (true) { 01067 Thread::signal_wait(POST_INTR_WORK_SIGNAL_ID); 01068 01069 ret = read_register(regmap->int_status_reg, ®, 1); 01070 if (ret) { 01071 pr_err("Read interrupt status register failed!"); 01072 } 01073 01074 ret = read_register(regmap->int_en_reg, &inten, 1); 01075 if (ret) { 01076 pr_err("Read interrupt enable register failed!"); 01077 } 01078 01079 for (int i = 0; i < INTR_ID_END; i++) { 01080 mask = (1 << i); 01081 if ((reg & mask) && (inten & mask)) { 01082 if (interrupt_handler_list[i].func != NULL) { 01083 interrupt_handler_list[i].func(interrupt_handler_list[i].cb); 01084 } 01085 } 01086 } 01087 } 01088 } 01089 01090 void RtcBase::interrupt_handler() 01091 { 01092 post_intr_work_thread->signal_set(POST_INTR_WORK_SIGNAL_ID); 01093 } 01094 01095 int RtcBase::sw_reset_assert() 01096 { 01097 int ret; 01098 config_reg1_t config_reg1; 01099 01100 ret = read_register(regmap->config_reg1, (uint8_t *) &config_reg1, 1); 01101 if (ret < 0) { 01102 pr_err("read_register failed!"); 01103 return ret; 01104 } 01105 01106 config_reg1.bits.swrstn = 0; /* Put device in reset state */ 01107 01108 ret = write_register(regmap->config_reg1, (const uint8_t *) &config_reg1, 1); 01109 if (ret < 0) { 01110 pr_err("read_register failed!"); 01111 return ret; 01112 } 01113 01114 return 0; 01115 } 01116 01117 int RtcBase::sw_reset_release() 01118 { 01119 int ret; 01120 config_reg1_t config_reg1; 01121 01122 ret = read_register(regmap->config_reg1, (uint8_t *) &config_reg1, 1); 01123 if (ret < 0) { 01124 pr_err("read_register failed!"); 01125 return ret; 01126 } 01127 01128 config_reg1.bits.swrstn = 1; /* Remove device from reset state */ 01129 01130 ret = write_register(regmap->config_reg1, (const uint8_t *) &config_reg1, 1); 01131 if (ret < 0) { 01132 pr_err("read_register failed!"); 01133 return ret; 01134 } 01135 01136 return 0; 01137 } 01138 01139 int RtcBase::rtc_start() 01140 { 01141 int ret; 01142 config_reg1_t config_reg1; 01143 01144 ret = read_register(regmap->config_reg1, (uint8_t *) &config_reg1, 1); 01145 if (ret < 0) { 01146 pr_err("read_register failed!"); 01147 return ret; 01148 } 01149 01150 config_reg1.bits.osconz = 0; /* Enable the oscillator */ 01151 01152 ret = write_register(regmap->config_reg1, (const uint8_t *) &config_reg1, 1); 01153 if (ret < 0) { 01154 pr_err("read_register failed!"); 01155 return ret; 01156 } 01157 01158 return 0; 01159 } 01160 01161 int RtcBase::rtc_stop() 01162 { 01163 int ret; 01164 config_reg1_t config_reg1; 01165 01166 ret = read_register(regmap->config_reg1, (uint8_t *) &config_reg1, 1); 01167 if (ret < 0) { 01168 pr_err("read_register failed!"); 01169 return ret; 01170 } 01171 01172 config_reg1.bits.osconz = 1; /* Disable the oscillator */ 01173 01174 ret = write_register(regmap->config_reg1, (const uint8_t *) &config_reg1, 1); 01175 if (ret < 0) { 01176 pr_err("read_register failed!"); 01177 return ret; 01178 } 01179 01180 return 0; 01181 }
Generated on Sun Aug 7 2022 16:13:41 by 1.7.2