Maxim Integrated / max3133x
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers max3133x.cpp Source File

max3133x.cpp

00001 /*******************************************************************************
00002  * Copyright(C) Analog Devices 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 Analog Devices Inc.
00023  * shall not be used except as stated in the Analog Devices Inc.
00024  * 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. Analog Devices Inc.retains all ownership rights.
00030  *******************************************************************************
00031  */
00032 
00033 #include "max3133x.hpp"
00034 #include <iostream>
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 #define SWAPBYTES(val)  (((val & 0xFF) << 8) | ((val & 0xFF00) >> 8))
00042 
00043 #define POST_INTR_WORK_SIGNAL_ID            0x1
00044 
00045 MAX3133X::MAX3133X(const reg_addr_t *reg_addr, I2C *i2c, PinName inta_pin, PinName intb_pin)
00046 {
00047     int ret;
00048     if (i2c == NULL || reg_addr == NULL) {
00049         pr_err("i2c object is invalid!");
00050         return;
00051     }
00052 
00053     this->reg_addr = reg_addr;
00054     i2c_handler = i2c;
00055 
00056     ret = interrupt_disable(INT_ALL);
00057     if (ret != MAX3133X_NO_ERR) {
00058         pr_err("interrupt_disable failed!");
00059         return;
00060     }
00061 
00062     for (int i = 0; i < NUM_OF_INTR_ID; i++) {
00063         interrupt_handler_list[i].func = NULL;
00064         interrupt_handler_list[i].cb = NULL;
00065     }
00066 
00067     if (inta_pin != NC) {
00068         this->inta_pin = new InterruptIn(inta_pin);
00069         this->inta_pin->fall(Callback<void()>(this, &MAX3133X::interrupt_handler));
00070         this->inta_pin->enable_irq();
00071     } else
00072         this->inta_pin = NULL;
00073 
00074     if (intb_pin != NC) {
00075         this->intb_pin = new InterruptIn(intb_pin);
00076         this->intb_pin->fall(Callback<void()>(this, &MAX3133X::interrupt_handler));
00077         this->intb_pin->enable_irq();
00078     } else
00079         this->intb_pin = NULL;
00080 
00081     if (inta_pin != NC || intb_pin != NC)
00082     {
00083         post_intr_work_thread = new Thread();
00084         post_intr_work_thread->start(Callback<void()>(this, &MAX3133X::post_interrupt_work));
00085     }
00086 }
00087 
00088 int MAX3133X::read_register(uint8_t reg, uint8_t *value, uint8_t len)
00089 {
00090     int rtn_val;
00091 
00092     if (value == NULL)
00093         return MAX3133X_NULL_VALUE_ERR;
00094 
00095     rtn_val = i2c_handler->write(MAX3133X_I2C_W, (const char *)&reg, 1, true);
00096     if (rtn_val != 0)
00097         return MAX3133X_WRITE_REG_ERR;
00098 
00099     rtn_val = i2c_handler->read(MAX3133X_I2C_R, (char *) value, len, false);
00100     if (rtn_val != 0)
00101         return MAX3133X_READ_REG_ERR;
00102 
00103     return MAX3133X_NO_ERR;
00104 }
00105 
00106 int MAX3133X::write_register(uint8_t reg, const uint8_t *value, uint8_t len)
00107 {
00108     int rtn_val;
00109     uint8_t *local_data;
00110 
00111     if (value == NULL)
00112         return MAX3133X_NULL_VALUE_ERR;
00113 
00114     local_data = new uint8_t[1 + len];
00115     local_data[0] = reg;
00116 
00117     memcpy(&local_data[1], value, len);
00118 
00119     rtn_val = i2c_handler->write(MAX3133X_I2C_W, (const char *)local_data, 1 + len);
00120     delete[] local_data;  //delete local_data anymore not used
00121 
00122     if (rtn_val != 0)
00123         return MAX3133X_WRITE_REG_ERR;
00124 
00125     return MAX3133X_NO_ERR;
00126 }
00127 
00128 #define SET_BIT_FIELD(address, reg_name, bit_field_name, value)                 \
00129 {   int ret;                                                                    \
00130     ret = read_register(address, (uint8_t *)&(reg_name), 1);                    \
00131     if (ret != MAX3133X_NO_ERR) {                                               \
00132         return ret;                                                             \
00133     }                                                                           \
00134     if (bit_field_name != value) {                                              \
00135         bit_field_name = value;                                                 \
00136         ret = write_register(address, (uint8_t *)&(reg_name), 1);               \
00137         if (ret != MAX3133X_NO_ERR) {                                           \
00138             return ret;                                                         \
00139         }                                                                       \
00140     }                                                                           \
00141 }
00142 
00143 inline void MAX3133X::rtc_regs_to_time(struct tm *time, const max3133x_rtc_time_regs_t *regs, uint16_t *sub_sec)
00144 {
00145     if (sub_sec != NULL)
00146         *sub_sec = (1000 * regs->seconds_1_128_reg.raw) / 128.0;
00147 
00148     /* tm_sec seconds [0,61] */
00149     time->tm_sec = BCD2BIN(regs->seconds_reg.bcd.value);
00150 
00151     /* tm_min minutes [0,59] */
00152     time->tm_min = BCD2BIN(regs->minutes_reg.bcd.value);
00153 
00154     /* tm_hour hour [0,23] */
00155     hour_format_t format = regs->hours_reg.bits_24hr.f_24_12 == 1 ? HOUR12 : HOUR24;
00156     if (format == HOUR24)
00157         time->tm_hour = BCD2BIN(regs->hours_reg.bcd_24hr.value);
00158     else if (format == HOUR12) {
00159         uint8_t hr24 = to_24hr(BCD2BIN(regs->hours_reg.bcd_12hr.value), regs->hours_reg.bits_12hr.am_pm);
00160         time->tm_hour = hr24;
00161     }
00162 
00163     /* tm_wday day of week [0,6] (Sunday = 0) */
00164     time->tm_wday = BCD2BIN(regs->day_reg.bcd.value) - 1;
00165 
00166     /* tm_mday day of month [1,31] */
00167     time->tm_mday = BCD2BIN(regs->date_reg.bcd.value);
00168 
00169     /* tm_mon month of year [0,11] */
00170     time->tm_mon = BCD2BIN(regs->month_reg.bcd.value) - 1;
00171 
00172     /* tm_year years since 2000 */
00173     if (regs->month_reg.bits.century)
00174         time->tm_year = BCD2BIN(regs->year_reg.bcd.value) + 200;
00175     else
00176         time->tm_year = BCD2BIN(regs->year_reg.bcd.value) + 100;
00177 
00178     /* tm_yday day of year [0,365] */
00179     time->tm_yday = 0;
00180 
00181     /* tm_isdst daylight savings flag */
00182     time->tm_isdst = 0;
00183 }
00184 
00185 inline int MAX3133X::time_to_rtc_regs(max3133x_rtc_time_regs_t *regs, const struct tm *time, hour_format_t format)
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_reg.bcd.value = BIN2BCD(time->tm_sec);
00205 
00206     regs->minutes_reg.bcd.value = BIN2BCD(time->tm_min);
00207 
00208     if (format == HOUR24) {
00209         regs->hours_reg.bcd_24hr.value = BIN2BCD(time->tm_hour);
00210         regs->hours_reg.bits_24hr.f_24_12 = HOUR24;
00211     } else if (format == HOUR12) {
00212         uint8_t hr_12, pm;
00213         to_12hr(time->tm_hour, &hr_12, &pm);
00214         regs->hours_reg.bcd_12hr.value = BIN2BCD(hr_12);
00215         regs->hours_reg.bits_12hr.f_24_12 = HOUR12;
00216         regs->hours_reg.bits_12hr.am_pm = pm;
00217     } else {
00218         pr_err("Invalid Hour Format!");
00219         return MAX3133X_INVALID_TIME_ERR;
00220     }
00221 
00222     regs->day_reg.bcd.value   = BIN2BCD(time->tm_wday + 1);
00223     regs->date_reg.bcd.value  = BIN2BCD(time->tm_mday);
00224     regs->month_reg.bcd.value = BIN2BCD(time->tm_mon + 1);
00225 
00226     if (time->tm_year >= 200) {
00227         regs->month_reg.bits.century = 1;
00228         regs->year_reg.bcd.value = BIN2BCD(time->tm_year - 200);
00229     } else if (time->tm_year >= 100) {
00230         regs->month_reg.bits.century = 0;
00231         regs->year_reg.bcd.value = BIN2BCD(time->tm_year - 100);
00232     } else {
00233         pr_err("Invalid set date!");
00234         return MAX3133X_INVALID_DATE_ERR;
00235     }
00236 
00237     return MAX3133X_NO_ERR;
00238 }
00239 
00240 int MAX3133X::get_time(struct tm *time, uint16_t *sub_sec)
00241 {
00242     int ret;
00243     max3133x_rtc_time_regs_t max3133x_rtc_time_regs = {};
00244     if (time == NULL) {
00245         pr_err("rtc_ctime is invalid!");
00246         return MAX3133X_NULL_VALUE_ERR;
00247     }
00248 
00249     ret = read_register(reg_addr->seconds_1_128_reg_addr, (uint8_t *) &max3133x_rtc_time_regs.seconds_1_128_reg, sizeof(max3133x_rtc_time_regs));
00250     if (ret != MAX3133X_NO_ERR) {
00251         pr_err("read time registers failed!");
00252         return ret;
00253     }
00254 
00255     rtc_regs_to_time(time, &max3133x_rtc_time_regs, sub_sec);
00256     return MAX3133X_NO_ERR;
00257 }
00258 
00259 int MAX3133X::set_time(const struct tm *time, hour_format_t format)
00260 {
00261     int ret;
00262     max3133x_rtc_time_regs_t max3133x_rtc_time_regs = {};
00263 
00264     if (time == NULL) {
00265         pr_err("rtc_ctime is invalid!");
00266         return MAX3133X_NULL_VALUE_ERR;
00267     }
00268 
00269     ret = time_to_rtc_regs(&max3133x_rtc_time_regs, time, format);
00270     if (ret != MAX3133X_NO_ERR)
00271         return ret;
00272 
00273     ret = write_register(reg_addr->seconds_reg_addr, (uint8_t *)&max3133x_rtc_time_regs.seconds_reg.raw, sizeof(max3133x_rtc_time_regs)-1);
00274     if (ret != MAX3133X_NO_ERR) {
00275         pr_err("write time registers failed!");
00276         return ret;
00277     }
00278 
00279     return MAX3133X_NO_ERR;
00280 }
00281 
00282 inline void MAX3133X::timestamp_regs_to_time(timestamp_t *timestamp, const max3133x_ts_regs_t *timestamp_reg)
00283 {
00284     /* tm_sec seconds [0,61] */
00285     timestamp->ctime.tm_sec = BCD2BIN(timestamp_reg->ts_sec_reg.bcd.value);
00286 
00287     /* tm_min minutes [0,59] */
00288     timestamp->ctime.tm_min = BCD2BIN(timestamp_reg->ts_min_reg.bcd.value);
00289 
00290     /* tm_hour hour [0,23] */
00291     hour_format_t format = timestamp_reg->ts_hour_reg.bits_24hr.f_24_12 ? HOUR12 : HOUR24;
00292     if (format == HOUR24)
00293         timestamp->ctime.tm_hour = BCD2BIN(timestamp_reg->ts_hour_reg.bcd_24hr.value);
00294     else if (format == HOUR12) {
00295         uint8_t hr24 = to_24hr(BCD2BIN(timestamp_reg->ts_hour_reg.bcd_12hr.value), timestamp_reg->ts_hour_reg.bits_12hr.am_pm);
00296         timestamp->ctime.tm_hour = hr24;
00297     }
00298 
00299     /* tm_mday day of month [1,31] */
00300     timestamp->ctime.tm_mday = BCD2BIN(timestamp_reg->ts_date_reg.bcd.value);
00301 
00302     /* tm_mon month of year [0,11] */
00303     timestamp->ctime.tm_mon = BCD2BIN(timestamp_reg->ts_month_reg.bcd.value) - 1;
00304 
00305     /* tm_year years since 2000 */
00306     if (timestamp_reg->ts_month_reg.bits.century)
00307         timestamp->ctime.tm_year = BCD2BIN(timestamp_reg->ts_year_reg.bcd.value) + 200;
00308     else
00309         timestamp->ctime.tm_year = BCD2BIN(timestamp_reg->ts_year_reg.bcd.value) + 100;
00310 
00311     /* tm_yday day of year [0,365] */
00312     timestamp->ctime.tm_yday = 0; /* TODO */
00313 
00314     /* tm_isdst daylight savings flag */
00315     timestamp->ctime.tm_isdst = 0; /* TODO */
00316 
00317     timestamp->sub_sec = (1000 * timestamp_reg->ts_sec_1_128_reg.raw) / 128.0;
00318 }
00319 
00320 int MAX3133X::get_status_reg(max3133x_status_reg_t * status_reg)
00321 {
00322     return read_register(reg_addr->status_reg_addr, &status_reg->raw, 1);
00323 }
00324 
00325 int MAX3133X::get_interrupt_reg(max3133x_int_en_reg_t * int_en_reg)
00326 {
00327     return read_register(reg_addr->int_en_reg_addr, &int_en_reg->raw, 1);
00328 }
00329 
00330 int MAX3133X::interrupt_enable(uint8_t mask)
00331 {
00332     int ret;
00333     max3133x_int_en_reg_t   int_en_reg = {};
00334 
00335     ret = read_register(reg_addr->int_en_reg_addr, &int_en_reg.raw, 1);
00336     if (ret != MAX3133X_NO_ERR)
00337         return ret;
00338 
00339     int_en_reg.raw |= mask;
00340     return write_register(reg_addr->int_en_reg_addr, &int_en_reg.raw, 1);
00341 }
00342 
00343 int MAX3133X::interrupt_disable(uint8_t mask)
00344 {
00345     int ret;
00346     max3133x_int_en_reg_t   int_en_reg = {};
00347 
00348     ret = read_register(reg_addr->int_en_reg_addr, &int_en_reg.raw, 1);
00349     if (ret != MAX3133X_NO_ERR)
00350         return ret;
00351 
00352     int_en_reg.raw &= ~mask;
00353     return write_register(reg_addr->int_en_reg_addr, &int_en_reg.raw, 1);
00354 }
00355 
00356 int MAX3133X::sw_reset_assert()
00357 {
00358     max3133x_rtc_reset_reg_t    rtc_reset_reg = {};
00359     SET_BIT_FIELD(reg_addr->rtc_reset_reg_addr, rtc_reset_reg, rtc_reset_reg.bits.swrst, 1);
00360     return MAX3133X_NO_ERR;
00361 }
00362 
00363 int MAX3133X::sw_reset_release()
00364 {
00365     max3133x_rtc_reset_reg_t    rtc_reset_reg = {};
00366     SET_BIT_FIELD(reg_addr->rtc_reset_reg_addr, rtc_reset_reg, rtc_reset_reg.bits.swrst, 0);
00367     return MAX3133X_NO_ERR;
00368 }
00369 
00370 int MAX3133X::sw_reset()
00371 {
00372     int ret;
00373     ret = sw_reset_assert();
00374     if (ret != MAX3133X_NO_ERR)
00375         return ret;
00376 
00377     ThisThread::sleep_for(5);
00378     return sw_reset_release();
00379 }
00380 
00381 int MAX31331::rtc_config(rtc_config_t *max31331_config)
00382 {
00383     int ret;
00384     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00385     max31331_rtc_config2_reg_t  rtc_config2_reg = {};
00386 
00387     rtc_config1_reg.bits.a1ac        = max31331_config->a1ac;
00388     rtc_config1_reg.bits.dip         = max31331_config->dip;
00389     rtc_config1_reg.bits.data_ret    = max31331_config->data_ret;
00390     rtc_config1_reg.bits.i2c_timeout = max31331_config->i2c_timeout;
00391     rtc_config1_reg.bits.en_osc      = max31331_config->en_osc;
00392 
00393     ret =  write_register(reg_addr.rtc_config1_reg_addr, &rtc_config1_reg.raw, 1);
00394     if (ret != MAX3133X_NO_ERR)
00395         return ret;
00396 
00397     rtc_config2_reg.bits.clko_hz        = max31331_config->clko_hz;
00398     rtc_config2_reg.bits.enclko         = max31331_config->enclko;
00399 
00400     return write_register(reg_addr.rtc_config2_reg_addr, &rtc_config2_reg.raw, 1);
00401 }
00402 
00403 int MAX31334::rtc_config(rtc_config_t *max31334_config)
00404 {
00405     int ret;
00406     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00407     max31334_rtc_config2_reg_t  rtc_config2_reg = {};
00408 
00409     rtc_config1_reg.bits.a1ac        = max31334_config->a1ac;
00410     rtc_config1_reg.bits.dip         = max31334_config->dip;
00411     rtc_config1_reg.bits.data_ret    = max31334_config->data_ret;
00412     rtc_config1_reg.bits.i2c_timeout = max31334_config->i2c_timeout;
00413     rtc_config1_reg.bits.en_osc      = max31334_config->en_osc;
00414 
00415     ret =  write_register(reg_addr.rtc_config1_reg_addr, &rtc_config1_reg.raw, 1);
00416     if (ret != MAX3133X_NO_ERR)
00417         return ret;
00418 
00419     rtc_config2_reg.bits.clko_hz    = max31334_config->clko_hz;
00420     rtc_config2_reg.bits.enclko     = max31334_config->enclko;
00421     rtc_config2_reg.bits.ddb        = max31334_config->ddb;
00422     rtc_config2_reg.bits.dse        = max31334_config->dse;
00423 
00424     return write_register(reg_addr.rtc_config2_reg_addr, &rtc_config2_reg.raw, 1);
00425 }
00426 
00427 int MAX31331::get_rtc_config(rtc_config_t *max31331_config)
00428 {
00429     int ret;
00430     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00431     max31331_rtc_config2_reg_t  rtc_config2_reg = {};
00432 
00433     ret = read_register(reg_addr.rtc_config1_reg_addr, &rtc_config1_reg.raw, 1);
00434     if (ret != MAX3133X_NO_ERR)
00435         return ret;
00436 
00437     max31331_config->a1ac        = (a1ac_t)rtc_config1_reg.bits.a1ac;
00438     max31331_config->dip         = (dip_t)rtc_config1_reg.bits.dip;
00439     max31331_config->data_ret    = (data_ret_t)rtc_config1_reg.bits.data_ret;
00440     max31331_config->i2c_timeout = (i2c_timeout_t)rtc_config1_reg.bits.i2c_timeout;
00441     max31331_config->en_osc      = (en_osc_t)rtc_config1_reg.bits.en_osc;
00442 
00443     ret = read_register(reg_addr.rtc_config2_reg_addr, &rtc_config2_reg.raw, 1);
00444     if (ret != MAX3133X_NO_ERR)
00445         return ret;
00446 
00447     max31331_config->clko_hz     = (clko_hz_t)rtc_config2_reg.bits.clko_hz;
00448     max31331_config->enclko      = (enclko_t)rtc_config2_reg.bits.enclko;
00449     return MAX3133X_NO_ERR;
00450 }
00451 
00452 int MAX31334::get_rtc_config(rtc_config_t *max31334_config)
00453 {
00454     int ret;
00455     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00456     max31334_rtc_config2_reg_t  rtc_config2_reg = {};
00457 
00458     ret =  read_register(reg_addr.rtc_config1_reg_addr, &rtc_config1_reg.raw, 1);
00459     if (ret != MAX3133X_NO_ERR)
00460         return ret;
00461 
00462     max31334_config->a1ac           = (a1ac_t)rtc_config1_reg.bits.a1ac;
00463     max31334_config->dip            = (dip_t)rtc_config1_reg.bits.dip;
00464     max31334_config->data_ret       = (data_ret_t)rtc_config1_reg.bits.data_ret;
00465     max31334_config->i2c_timeout    = (i2c_timeout_t)rtc_config1_reg.bits.i2c_timeout;
00466     max31334_config->en_osc         = (en_osc_t)rtc_config1_reg.bits.en_osc;
00467 
00468     ret = read_register(reg_addr.rtc_config2_reg_addr, &rtc_config2_reg.raw, 1);
00469     if (ret != MAX3133X_NO_ERR)
00470         return ret;
00471 
00472     max31334_config->clko_hz        = (clko_hz_t)rtc_config2_reg.bits.clko_hz;
00473     max31334_config->ddb            = (ddb_t)rtc_config2_reg.bits.ddb;
00474     max31334_config->dse            = (dse_t)rtc_config2_reg.bits.dse;
00475     max31334_config->enclko         = (enclko_t)rtc_config2_reg.bits.enclko;
00476 
00477     return MAX3133X_NO_ERR;
00478 }
00479 
00480 int MAX3133X::set_alarm1_auto_clear(a1ac_t a1ac)
00481 {
00482     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00483     SET_BIT_FIELD(reg_addr->rtc_config1_reg_addr, rtc_config1_reg, rtc_config1_reg.bits.a1ac, a1ac);
00484     return MAX3133X_NO_ERR;
00485 }
00486 
00487 int MAX3133X::set_din_polarity(dip_t dip)
00488 {
00489     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00490     SET_BIT_FIELD(reg_addr->rtc_config1_reg_addr, rtc_config1_reg, rtc_config1_reg.bits.dip, dip);
00491     return MAX3133X_NO_ERR;
00492 }
00493 
00494 int MAX3133X::data_retention_mode_config(bool enable)
00495 {
00496     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00497     SET_BIT_FIELD(reg_addr->rtc_config1_reg_addr, rtc_config1_reg, rtc_config1_reg.bits.data_ret, enable);
00498     return MAX3133X_NO_ERR;
00499 }
00500 
00501 int MAX3133X::data_retention_mode_enter()
00502 {
00503     return data_retention_mode_config(1);
00504 }
00505 
00506 int MAX3133X::data_retention_mode_exit()
00507 {
00508     return data_retention_mode_config(0);
00509 }
00510 
00511 int MAX3133X::i2c_timeout_config(bool enable)
00512 {
00513     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00514     SET_BIT_FIELD(reg_addr->rtc_config1_reg_addr, rtc_config1_reg, rtc_config1_reg.bits.i2c_timeout, enable);
00515     return MAX3133X_NO_ERR;
00516 }
00517 
00518 int MAX3133X::i2c_timeout_enable()
00519 {
00520     return i2c_timeout_config(1);
00521 }
00522 
00523 int MAX3133X::i2c_timeout_disable()
00524 {
00525     return i2c_timeout_config(0);
00526 }
00527 
00528 int MAX3133X::oscillator_config(bool enable)
00529 {
00530     max3133x_rtc_config1_reg_t  rtc_config1_reg = {};
00531     SET_BIT_FIELD(reg_addr->rtc_config1_reg_addr, rtc_config1_reg, rtc_config1_reg.bits.en_osc, enable);
00532     return MAX3133X_NO_ERR;
00533 }
00534 
00535 int MAX3133X::oscillator_enable()
00536 {
00537     return oscillator_config(1);
00538 }
00539 
00540 int MAX3133X::oscillator_disable()
00541 {
00542     return oscillator_config(0);
00543 }
00544 
00545 int MAX31334::get_sleep_state()
00546 {
00547     int ret;
00548     max31334_rtc_config2_reg_t  rtc_config2_reg = {};
00549 
00550     ret = read_register(reg_addr.rtc_config2_reg_addr, &rtc_config2_reg.raw, 1);
00551     if (ret != MAX3133X_NO_ERR)
00552         return ret;
00553 
00554     return rtc_config2_reg.bits.slst;
00555 }
00556 
00557 int MAX31334::din_sleep_entry_config(bool enable)
00558 {
00559     max31334_rtc_config2_reg_t  rtc_config2_reg = {};
00560     SET_BIT_FIELD(reg_addr.rtc_config2_reg_addr, rtc_config2_reg, rtc_config2_reg.bits.dse, enable);
00561     return MAX3133X_NO_ERR;
00562 }
00563 
00564 int MAX31334::din_sleep_entry_enable()
00565 {
00566     return din_sleep_entry_config(1);
00567 }
00568 
00569 int MAX31334::din_sleep_entry_disable()
00570 {
00571     return din_sleep_entry_config(0);
00572 }
00573 
00574 int MAX31334::din_pin_debounce_config(bool enable)
00575 {
00576     max31334_rtc_config2_reg_t  rtc_config2_reg = {};
00577     SET_BIT_FIELD(reg_addr.rtc_config2_reg_addr, rtc_config2_reg, rtc_config2_reg.bits.ddb, enable);
00578     return MAX3133X_NO_ERR;
00579 }
00580 
00581 int MAX31334::din_pin_debounce_enable()
00582 {
00583     return din_pin_debounce_config(1);
00584 }
00585 
00586 int MAX31334::din_pin_debounce_disable()
00587 {
00588     return din_pin_debounce_config(0);
00589 }
00590 
00591 int MAX3133X::clkout_config(bool enable)
00592 {
00593     max31334_rtc_config2_reg_t  rtc_config2_reg = {};
00594     SET_BIT_FIELD(reg_addr->rtc_config2_reg_addr, rtc_config2_reg, rtc_config2_reg.bits.enclko, enable);
00595     return MAX3133X_NO_ERR;
00596 }
00597 
00598 int MAX3133X::clkout_enable()
00599 {
00600     return clkout_config(1);
00601 }
00602 
00603 int MAX3133X::clkout_disable()
00604 {
00605     return clkout_config(0);
00606 }
00607 
00608 int MAX3133X::set_clko_freq(clko_hz_t    clko_hz)
00609 {
00610     max31334_rtc_config2_reg_t  rtc_config2_reg = {};
00611     SET_BIT_FIELD(reg_addr->rtc_config2_reg_addr, rtc_config2_reg, rtc_config2_reg.bits.clko_hz, clko_hz);
00612     return MAX3133X_NO_ERR;
00613 }
00614 
00615 int MAX3133X::get_clko_freq(clko_hz_t    *clko_hz)
00616 {
00617     int ret;
00618     max31334_rtc_config2_reg_t  rtc_config2_reg = {};
00619 
00620     ret = read_register(reg_addr->rtc_config2_reg_addr, &rtc_config2_reg.raw, 1);
00621     if (ret != MAX3133X_NO_ERR)
00622         return ret;
00623 
00624     *clko_hz = (clko_hz_t)rtc_config2_reg.bits.clko_hz;
00625     return MAX3133X_NO_ERR;
00626 }
00627 
00628 int MAX3133X::timestamp_function_enable()
00629 {
00630     max3133x_timestamp_config_reg_t timestamp_config_reg = {};
00631     SET_BIT_FIELD(reg_addr->timestamp_config_reg_addr, timestamp_config_reg, timestamp_config_reg.bits.tse, 1);
00632     return MAX3133X_NO_ERR;
00633 }
00634 
00635 int MAX3133X::timestamp_function_disable()
00636 {
00637     max3133x_timestamp_config_reg_t timestamp_config_reg = {};
00638     SET_BIT_FIELD(reg_addr->timestamp_config_reg_addr, timestamp_config_reg, timestamp_config_reg.bits.tse, 0);
00639     return MAX3133X_NO_ERR;
00640 }
00641 
00642 int MAX3133X::timestamp_registers_reset()
00643 {
00644     max3133x_timestamp_config_reg_t timestamp_config_reg = {};
00645     SET_BIT_FIELD(reg_addr->timestamp_config_reg_addr, timestamp_config_reg, timestamp_config_reg.bits.tsr, 1);
00646     return MAX3133X_NO_ERR;
00647 }
00648 
00649 int MAX3133X::timestamp_overwrite_config(bool enable)
00650 {
00651     max3133x_timestamp_config_reg_t timestamp_config_reg = {};
00652     SET_BIT_FIELD(reg_addr->timestamp_config_reg_addr, timestamp_config_reg, timestamp_config_reg.bits.tsow, enable);
00653     return MAX3133X_NO_ERR;
00654 }
00655 
00656 int MAX3133X::timestamp_overwrite_enable()
00657 {
00658     return timestamp_overwrite_config(1);
00659 }
00660 
00661 int MAX3133X::timestamp_overwrite_disable()
00662 {
00663     return timestamp_overwrite_config(0);
00664 }
00665 
00666 int MAX3133X::timestamp_record_enable(uint8_t record_enable_mask)
00667 {
00668     int ret;
00669     max3133x_timestamp_config_reg_t timestamp_config_reg = {};
00670 
00671     if (record_enable_mask > (TSVLOW | TSPWM | TSDIN))
00672         return MAX3133X_INVALID_MASK_ERR;
00673 
00674     ret = read_register(reg_addr->timestamp_config_reg_addr, &timestamp_config_reg.raw, 1);
00675     if (ret != MAX3133X_NO_ERR)
00676         return ret;
00677 
00678     timestamp_config_reg.raw |= record_enable_mask;
00679     return write_register(reg_addr->timestamp_config_reg_addr, &timestamp_config_reg.raw, 1);
00680 }
00681 
00682 int MAX3133X::timestamp_record_disable(uint8_t record_disable_mask)
00683 {
00684     int ret;
00685     max3133x_timestamp_config_reg_t timestamp_config_reg = {};
00686 
00687     if (record_disable_mask > (TSVLOW | TSPWM | TSDIN))
00688         return MAX3133X_INVALID_MASK_ERR;
00689 
00690     ret = read_register(reg_addr->timestamp_config_reg_addr, &timestamp_config_reg.raw, 1);
00691     if (ret != MAX3133X_NO_ERR)
00692         return ret;
00693 
00694     timestamp_config_reg.raw &= ~record_disable_mask;
00695     return write_register(reg_addr->timestamp_config_reg_addr, &timestamp_config_reg.raw, 1);
00696 }
00697 
00698 int MAX31331::timer_init(uint8_t timer_init, bool repeat, timer_freq_t freq)
00699 {
00700     int ret;
00701     max3133x_timer_config_reg_t     timer_config_reg = {};
00702 
00703     ret = read_register(reg_addr.timer_config_reg_addr, &timer_config_reg.raw, 1);
00704     if (ret != MAX3133X_NO_ERR)
00705         return ret;
00706 
00707     timer_config_reg.bits.te = 0;                   /* timer is reset */
00708     timer_config_reg.bits.tpause = 1;               /* timer is paused */
00709     timer_config_reg.bits.trpt = repeat ? 1 : 0;    /* Timer repeat mode */
00710     timer_config_reg.bits.tfs = freq;               /* Timer frequency */
00711 
00712     ret = write_register(reg_addr.timer_config_reg_addr, &timer_config_reg.raw, 1);
00713     if (ret != MAX3133X_NO_ERR)
00714         return ret;
00715 
00716     return write_register(reg_addr.timer_init_reg_addr, &timer_init, 1);
00717 }
00718 
00719 int MAX31334::timer_init(uint16_t timer_init, bool repeat, timer_freq_t freq)
00720 {
00721     int ret;
00722     max3133x_timer_config_reg_t timer_config_reg = {};
00723 
00724     ret = read_register(reg_addr.timer_config_reg_addr, &timer_config_reg.raw, 1);
00725     if (ret != MAX3133X_NO_ERR)
00726         return ret;
00727 
00728     timer_config_reg.bits.te = 0;                   /* timer is reset */
00729     timer_config_reg.bits.tpause = 1;               /* timer is paused */
00730     timer_config_reg.bits.trpt = repeat ? 1 : 0;    /* Timer repeat mode */
00731     timer_config_reg.bits.tfs = freq;               /* Timer frequency */
00732 
00733     ret = write_register(reg_addr.timer_config_reg_addr, &timer_config_reg.raw, 1);
00734     if (ret != MAX3133X_NO_ERR)
00735         return ret;
00736 
00737     timer_init = SWAPBYTES(timer_init);
00738 
00739     return write_register(reg_addr.timer_init2_reg_addr, (uint8_t *)&timer_init, 2);
00740 }
00741 
00742 int MAX31331::timer_get()
00743 {
00744     int ret;
00745     uint8_t timer_count;
00746 
00747     ret = read_register(reg_addr.timer_count_reg_addr, &timer_count, 1);
00748     if (ret != MAX3133X_NO_ERR)
00749         return ret;
00750 
00751     return timer_count;
00752 }
00753 
00754 int MAX31334::timer_get()
00755 {
00756     int ret;
00757     uint16_t timer_count;
00758 
00759     ret = read_register(reg_addr.timer_count2_reg_addr, (uint8_t *)&timer_count, 2);
00760     if (ret != MAX3133X_NO_ERR)
00761         return ret;
00762 
00763     return SWAPBYTES(timer_count);
00764 }
00765 
00766 int MAX3133X::timer_start()
00767 {
00768     int ret;
00769     max3133x_timer_config_reg_t timer_config_reg = {};
00770 
00771     ret = read_register(reg_addr->timer_config_reg_addr, &timer_config_reg.raw, 1);
00772     if (ret != MAX3133X_NO_ERR)
00773         return ret;
00774 
00775     timer_config_reg.bits.te         = 1;
00776     timer_config_reg.bits.tpause     = 0;
00777 
00778     return write_register(reg_addr->timer_config_reg_addr, &timer_config_reg.raw, 1);
00779 }
00780 
00781 int MAX3133X::timer_pause()
00782 {
00783     int ret;
00784     max3133x_timer_config_reg_t timer_config_reg = {};
00785 
00786     ret = read_register(reg_addr->timer_config_reg_addr, &timer_config_reg.raw, 1);
00787     if (ret != MAX3133X_NO_ERR)
00788         return ret;
00789 
00790     timer_config_reg.bits.te         = 1;
00791     timer_config_reg.bits.tpause     = 1;
00792 
00793     return write_register(reg_addr->timer_config_reg_addr, &timer_config_reg.raw, 1);
00794 }
00795 
00796 int MAX3133X::timer_continue()
00797 {
00798     int ret;
00799     max3133x_timer_config_reg_t timer_config_reg = {};
00800 
00801     ret = read_register(reg_addr->timer_config_reg_addr, &timer_config_reg.raw, 1);
00802     if (ret != MAX3133X_NO_ERR)
00803         return ret;
00804 
00805     timer_config_reg.bits.te         = 1;
00806     timer_config_reg.bits.tpause     = 0;
00807 
00808     return write_register(reg_addr->timer_config_reg_addr, &timer_config_reg.raw, 1);
00809 }
00810 
00811 int MAX3133X::timer_stop()
00812 {
00813     int ret;
00814     max3133x_timer_config_reg_t timer_config_reg = {};
00815 
00816     ret = read_register(reg_addr->timer_config_reg_addr, &timer_config_reg.raw, 1);
00817     if (ret != MAX3133X_NO_ERR)
00818         return ret;
00819 
00820     timer_config_reg.bits.te         = 0;
00821     timer_config_reg.bits.tpause     = 1;
00822 
00823     return write_register(reg_addr->timer_config_reg_addr, &timer_config_reg.raw, 1);
00824 }
00825 
00826 int MAX31334::sleep_enter()
00827 {
00828     max31334_sleep_config_reg_t sleep_config_reg = {};
00829     SET_BIT_FIELD(reg_addr.sleep_config_reg_addr, sleep_config_reg, sleep_config_reg.bits.slp, 1);
00830     return MAX3133X_NO_ERR;
00831 }
00832 
00833 int MAX31334::sleep_exit()
00834 {
00835     max31334_sleep_config_reg_t sleep_config_reg = {};
00836     SET_BIT_FIELD(reg_addr.sleep_config_reg_addr, sleep_config_reg, sleep_config_reg.bits.slp, 0);
00837     return MAX3133X_NO_ERR;
00838 }
00839 
00840 int MAX31334::set_wait_state_timeout(wsto_t wsto)
00841 {
00842     max31334_sleep_config_reg_t sleep_config_reg = {};
00843     SET_BIT_FIELD(reg_addr.sleep_config_reg_addr, sleep_config_reg, sleep_config_reg.bits.wsto, wsto);
00844     return MAX3133X_NO_ERR;
00845 }
00846 
00847 int MAX31334::get_wait_state_timeout(wsto_t* wsto)
00848 {
00849     int ret;
00850     max31334_sleep_config_reg_t sleep_config_reg = {};
00851 
00852     ret = read_register(reg_addr.sleep_config_reg_addr, &sleep_config_reg.raw, 1);
00853     if (ret != MAX3133X_NO_ERR)
00854         return ret;
00855 
00856     *wsto = (wsto_t)sleep_config_reg.bits.wsto;
00857     return MAX3133X_NO_ERR;
00858 }
00859 
00860 int MAX31334::wakeup_enable(uint8_t wakeup_enable_mask)
00861 {
00862     int ret;
00863     max31334_sleep_config_reg_t sleep_config_reg = {};
00864 
00865     ret = read_register(reg_addr.sleep_config_reg_addr, &sleep_config_reg.raw, 1);
00866     if (ret != MAX3133X_NO_ERR)
00867         return ret;
00868 
00869     sleep_config_reg.raw |= wakeup_enable_mask;
00870     return write_register(reg_addr.sleep_config_reg_addr, &sleep_config_reg.raw, 1);
00871 }
00872 
00873 int MAX31334::wakeup_disable(uint8_t wakeup_disable_mask)
00874 {
00875     int ret;
00876     max31334_sleep_config_reg_t sleep_config_reg = {};
00877 
00878     ret = read_register(reg_addr.sleep_config_reg_addr, &sleep_config_reg.raw, 1);
00879     if (ret != MAX3133X_NO_ERR)
00880         return ret;
00881 
00882     sleep_config_reg.raw &= ~wakeup_disable_mask;
00883     return write_register(reg_addr.sleep_config_reg_addr, &sleep_config_reg.raw, 1);
00884 }
00885 
00886 int MAX3133X::battery_voltage_detector_config(bool enable)
00887 {
00888     max3133x_pwr_mgmt_reg_t pwr_mgmt_reg = {};
00889     SET_BIT_FIELD(reg_addr->pwr_mgmt_reg_addr, pwr_mgmt_reg, pwr_mgmt_reg.bits.en_vbat_detect, enable);
00890     return MAX3133X_NO_ERR;
00891 }
00892 
00893 int MAX3133X::battery_voltage_detector_enable()
00894 {
00895     return battery_voltage_detector_config(1);
00896 }
00897 
00898 int MAX3133X::battery_voltage_detector_disable()
00899 {
00900     return battery_voltage_detector_config(0);
00901 }
00902 
00903 int MAX3133X::supply_select(power_mgmt_supply_t supply)
00904 {
00905     int ret;
00906     max3133x_pwr_mgmt_reg_t pwr_mgmt_reg = {};
00907 
00908     ret = read_register(reg_addr->pwr_mgmt_reg_addr, &pwr_mgmt_reg.raw, 1);
00909     if (ret != MAX3133X_NO_ERR)
00910         return ret;
00911 
00912     switch (supply) {
00913     case POW_MGMT_SUPPLY_SEL_VCC:
00914         pwr_mgmt_reg.bits.manual_sel = 1;
00915         pwr_mgmt_reg.bits.vback_sel = 0;
00916         break;
00917     case POW_MGMT_SUPPLY_SEL_VBAT:
00918         pwr_mgmt_reg.bits.manual_sel = 1;
00919         pwr_mgmt_reg.bits.vback_sel = 1;
00920         break;
00921     case POW_MGMT_SUPPLY_SEL_AUTO:
00922     default:
00923         pwr_mgmt_reg.bits.manual_sel = 0;
00924         break;
00925     }
00926 
00927     return write_register(reg_addr->pwr_mgmt_reg_addr, &pwr_mgmt_reg.raw, 1);
00928 }
00929 
00930 int MAX3133X::trickle_charger_enable(trickle_charger_ohm_t res, bool diode)
00931 {
00932     max3133x_trickle_reg_reg_t  trickle_reg_reg = {};
00933     trickle_reg_reg.bits.trickle = res;
00934 
00935     if (diode)
00936         trickle_reg_reg.bits.trickle |= 0x04;
00937 
00938     trickle_reg_reg.bits.en_trickle = true;
00939 
00940     return write_register(reg_addr->trickle_reg_addr, &trickle_reg_reg.raw, 1);
00941 }
00942 
00943 int MAX3133X::trickle_charger_disable()
00944 {
00945     max3133x_trickle_reg_reg_t  trickle_reg_reg = {};
00946     SET_BIT_FIELD(reg_addr->trickle_reg_addr, trickle_reg_reg, trickle_reg_reg.bits.en_trickle, 0);
00947     return MAX3133X_NO_ERR;
00948 }
00949 
00950 int MAX3133X::get_timestamp(int ts_num, timestamp_t *timestamp)
00951 {
00952     int ret;
00953     max3133x_ts_regs_t          timestamp_reg;
00954     max3133x_ts_flags_reg_t     ts_flags_reg;
00955     uint8_t ts_reg_addr;
00956     uint8_t ts_flag_reg_addr = reg_addr->ts0_flags_reg_addr + sizeof(max3133x_ts_regs_t)*ts_num;
00957 
00958     ret = read_register(ts_flag_reg_addr, (uint8_t *)&ts_flags_reg, 1);
00959     if (ret != MAX3133X_NO_ERR)
00960         return ret;
00961 
00962     timestamp->ts_num = (ts_num_t)ts_num;
00963     timestamp->ts_trigger = (ts_trigger_t)(ts_flags_reg.raw & 0xF);
00964 
00965     if (ts_flags_reg.raw == NOT_TRIGGERED) // no need to read timestamp register
00966         return MAX3133X_NO_ERR;
00967 
00968     ts_reg_addr = reg_addr->ts0_sec_1_128_reg_addr + sizeof(max3133x_ts_regs_t)*ts_num;
00969     ret = read_register(ts_reg_addr, (uint8_t *)&timestamp_reg, sizeof(max3133x_ts_regs_t)-1);
00970     if (ret != MAX3133X_NO_ERR)
00971         return ret;
00972 
00973     timestamp_regs_to_time(timestamp, &timestamp_reg);
00974     return MAX3133X_NO_ERR;
00975 }
00976 
00977 int MAX3133X::offset_configuration(int meas)
00978 {
00979     short int offset;
00980     double acc = (meas - 32768)*30.5175;
00981 
00982     offset = (short int)(acc/0.477);
00983 
00984     return write_register(reg_addr->offset_high_reg_addr, (uint8_t *)&offset, 2);
00985 }
00986 
00987 int MAX3133X::oscillator_flag_config(bool enable)
00988 {
00989     max3133x_int_en_reg_t   int_en_reg = {};
00990     SET_BIT_FIELD(reg_addr->int_en_reg_addr, int_en_reg, int_en_reg.bits.dosf, !enable);
00991     return MAX3133X_NO_ERR;
00992 }
00993 
00994 void MAX3133X::set_intr_handler(intr_id_t id, interrupt_handler_function func, void *cb)
00995 {
00996     interrupt_handler_list[id].func = func;
00997     interrupt_handler_list[id].cb = cb;
00998 }
00999 
01000 void MAX3133X::post_interrupt_work()
01001 {
01002     int ret;
01003     uint8_t mask;
01004     max3133x_int_en_reg_t   int_en_reg = {};
01005     max3133x_status_reg_t   status_reg = {};
01006 
01007     while (true) {
01008         ThisThread::flags_wait_any(POST_INTR_WORK_SIGNAL_ID);
01009 
01010         ret = read_register(reg_addr->status_reg_addr, &status_reg.raw, 1);
01011         if (ret != MAX3133X_NO_ERR) {
01012             pr_err("Read status register failed!");
01013             continue;
01014         }
01015 
01016         ret = read_register(reg_addr->int_en_reg_addr, &int_en_reg.raw, 1);
01017         if (ret != MAX3133X_NO_ERR) {
01018             pr_err("Read interrupt enable register failed!");
01019             continue;
01020         }
01021 
01022         for (int i = 0; i < NUM_OF_INTR_ID; i++) {
01023             mask = (1 << i);
01024             if ((status_reg.raw & mask) && (int_en_reg.raw & mask)) {
01025                 if (interrupt_handler_list[i].func != NULL)
01026                     interrupt_handler_list[i].func(interrupt_handler_list[i].cb);
01027             }
01028         }
01029     }
01030 }
01031 
01032 void MAX3133X::interrupt_handler()
01033 {
01034     post_intr_work_thread->flags_set(POST_INTR_WORK_SIGNAL_ID);
01035 }
01036 
01037 uint8_t MAX3133X::to_24hr(uint8_t hr, uint8_t pm) {
01038     if (pm) {
01039         if (hr < 12)
01040             hr += 12;
01041     } else {
01042         if (hr == 12)
01043             hr -= 12;
01044     }
01045     return hr;
01046 }
01047 
01048 void MAX3133X::to_12hr(uint8_t hr, uint8_t *hr_12, uint8_t *pm) {
01049     if (hr == 0) {
01050         *hr_12 = 12;
01051         *pm = 0;
01052     } else if (hr < 12) {
01053         *hr_12 = hr;
01054         *pm = 0;
01055     } else if (hr == 12) {
01056         *hr_12 = 12;
01057         *pm = 1;
01058     } else {
01059         *hr_12 = hr - 12;
01060         *pm = 1;
01061     }
01062 }
01063 
01064 int MAX3133X::set_alarm_period(alarm_no_t alarm_no, max3133x_alarm_regs_t &regs, alarm_period_t period)
01065 {
01066     regs.sec.bits.am1 = 1;
01067     regs.min.bits.am2 = 1;
01068     regs.hrs.bits_24hr.am3 = 1;
01069     regs.day_date.bits.am4 = 1;
01070     regs.mon.bits.am5 = 1;
01071     regs.mon.bits.am6 = 1;
01072     regs.day_date.bits.dy_dt_match = 1;
01073 
01074     switch (period) {
01075     case ALARM_PERIOD_ONETIME:
01076         if (alarm_no == ALARM2) /* not supported! */
01077             return MAX3133X_ALARM_ONETIME_NOT_SUPP_ERR;
01078         regs.mon.bits.am6 = 0;
01079     case ALARM_PERIOD_YEARLY:
01080         if (alarm_no == ALARM2) /* not supported! */
01081             return MAX3133X_ALARM_YEARLY_NOT_SUPP_ERR;
01082         regs.mon.bits.am5 = 0;
01083     case ALARM_PERIOD_MONTHLY:
01084         regs.day_date.bits.dy_dt_match = 0;
01085     case ALARM_PERIOD_WEEKLY:
01086         regs.day_date.bits.am4 = 0;
01087     case ALARM_PERIOD_DAILY:
01088         regs.hrs.bits_24hr.am3 = 0;
01089     case ALARM_PERIOD_HOURLY:
01090         regs.min.bits.am2 = 0;
01091     case ALARM_PERIOD_EVERYMINUTE:
01092         if ((alarm_no == ALARM2) && (period == ALARM_PERIOD_EVERYMINUTE))
01093             return MAX3133X_ALARM_EVERYMINUTE_NOT_SUPP_ERR; /* Alarm2 does not support "every minute" alarm*/
01094         regs.sec.bits.am1 = 0;
01095     case ALARM_PERIOD_EVERYSECOND:
01096         if ((alarm_no == ALARM2) && (period == ALARM_PERIOD_EVERYSECOND))
01097             return MAX3133X_ALARM_EVERYSECOND_NOT_SUPP_ERR; /* Alarm2 does not support "once per second" alarm*/
01098         break;
01099     default:
01100         return MAX3133X_INVALID_ALARM_PERIOD_ERR;
01101     }
01102 
01103     return MAX3133X_NO_ERR;
01104 }
01105 
01106 int MAX3133X::time_to_alarm_regs(max3133x_alarm_regs_t &regs, const struct tm *alarm_time, hour_format_t format)
01107 {
01108     regs.sec.bcd.value = BIN2BCD(alarm_time->tm_sec);
01109     regs.min.bcd.value = BIN2BCD(alarm_time->tm_min);
01110 
01111     if (format == HOUR24)
01112         regs.hrs.bcd_24hr.value = BIN2BCD(alarm_time->tm_hour);
01113     else if (format == HOUR12) {
01114         uint8_t hr_12, pm;
01115         to_12hr(alarm_time->tm_hour, &hr_12, &pm);
01116         regs.hrs.bcd_12hr.value = BIN2BCD(hr_12);
01117         regs.hrs.bits_12hr.am_pm = pm;
01118     } else {
01119         pr_err("Invalid Hour Format!");
01120         return MAX3133X_INVALID_TIME_ERR;
01121     }
01122 
01123     if (regs.day_date.bits.dy_dt_match == 0)/* Date match */
01124         regs.day_date.bcd_date.value = BIN2BCD(alarm_time->tm_mday);
01125     else /* Day match */
01126         regs.day_date.bcd_day.value = BIN2BCD(alarm_time->tm_wday);
01127 
01128     regs.mon.bcd.value = BIN2BCD(alarm_time->tm_mon + 1);
01129 
01130     if (alarm_time->tm_year >= 200)
01131         regs.year.bcd.value = BIN2BCD(alarm_time->tm_year - 200);
01132     else if (alarm_time->tm_year >= 100)
01133         regs.year.bcd.value = BIN2BCD(alarm_time->tm_year - 100);
01134     else {
01135         pr_err("Invalid set year!");
01136         return MAX3133X_INVALID_DATE_ERR;
01137     }
01138 
01139     return MAX3133X_NO_ERR;
01140 }
01141 
01142 int MAX3133X::set_alarm_regs(alarm_no_t alarm_no, const max3133x_alarm_regs_t *regs)
01143 {
01144     uint8_t len = sizeof(max3133x_alarm_regs_t);
01145 
01146     if (alarm_no == ALARM1)
01147         return write_register(reg_addr->alm1_sec_reg_addr, (uint8_t *)&regs->sec.raw, len);
01148     else
01149         return write_register(reg_addr->alm2_min_reg_addr, (uint8_t *)&regs->min.raw, len-3);
01150 }
01151 
01152 int MAX3133X::get_rtc_time_format(hour_format_t *format)
01153 {
01154     int ret;
01155     max3133x_hours_reg_t    hours_reg = {};
01156     ret = read_register(reg_addr->hours_reg_addr, (uint8_t *)&hours_reg.raw, 1);
01157     if (ret != MAX3133X_NO_ERR)
01158         return ret;
01159 
01160     *format = (hour_format_t)hours_reg.bits_24hr.f_24_12;
01161 
01162     return MAX3133X_NO_ERR;
01163 }
01164 
01165 int MAX3133X::set_alarm(alarm_no_t alarm_no, const struct tm *alarm_time, alarm_period_t period)
01166 {
01167     int ret;
01168     max3133x_alarm_regs_t alarm_regs = {};
01169     hour_format_t format = {};
01170 
01171     ret = set_alarm_period(alarm_no, alarm_regs, period);
01172     if (ret != MAX3133X_NO_ERR)
01173         return ret;
01174 
01175     ret = get_rtc_time_format(&format);
01176     if (ret != MAX3133X_NO_ERR)
01177         return ret;
01178 
01179     /* Convert time structure to alarm registers */
01180     ret = time_to_alarm_regs(alarm_regs, alarm_time, format);
01181     if (ret != MAX3133X_NO_ERR)
01182         return ret;
01183 
01184     return set_alarm_regs(alarm_no, &alarm_regs);
01185 }
01186 
01187 inline void MAX3133X::alarm_regs_to_time(alarm_no_t alarm_no, struct tm *alarm_time, const max3133x_alarm_regs_t *regs, hour_format_t format)
01188 {
01189     alarm_time->tm_min = BCD2BIN(regs->min.bcd.value);
01190 
01191     if (format == HOUR24)
01192         alarm_time->tm_hour = BCD2BIN(regs->hrs.bcd_24hr.value);
01193     else if (format == HOUR12)
01194         alarm_time->tm_hour = to_24hr(BCD2BIN(regs->hrs.bcd_12hr.value), regs->hrs.bits_12hr.am_pm);
01195 
01196     if (regs->day_date.bits.dy_dt_match == 0) { /* date */
01197         alarm_time->tm_mday = BCD2BIN(regs->day_date.bcd_date.value);
01198         alarm_time->tm_wday = 0;
01199     } else { /* day */
01200         alarm_time->tm_wday = BCD2BIN(regs->day_date.bcd_day.value);
01201         alarm_time->tm_mday = 0;
01202     }
01203 
01204     if (alarm_no == ALARM1) {
01205         alarm_time->tm_sec = BCD2BIN(regs->sec.bcd.value);
01206         alarm_time->tm_mon = BCD2BIN(regs->mon.bcd.value) - 1;
01207         alarm_time->tm_year = BCD2BIN(regs->year.bcd.value) + 100;  /* XXX no century bit */
01208     }
01209 }
01210 
01211 int MAX3133X::get_alarm(alarm_no_t alarm_no, struct tm *alarm_time, alarm_period_t *period, bool *is_enabled)
01212 {
01213     int ret;
01214     max3133x_alarm_regs_t alarm_regs = {};
01215     max3133x_int_en_reg_t int_en_reg = {};
01216     uint8_t len = sizeof(max3133x_alarm_regs_t);
01217     hour_format_t format;
01218 
01219     ret = get_rtc_time_format(&format);
01220     if (ret != MAX3133X_NO_ERR)
01221         return ret;
01222 
01223     if (alarm_no == ALARM1)
01224         ret = read_register(reg_addr->alm1_sec_reg_addr, &alarm_regs.sec.raw, len);
01225     else
01226         ret = read_register(reg_addr->alm2_min_reg_addr, &alarm_regs.min.raw, len-3);
01227 
01228     if (ret != MAX3133X_NO_ERR)
01229         return ret;
01230 
01231     /* Convert alarm registers to time structure */
01232     alarm_regs_to_time(alarm_no, alarm_time, &alarm_regs, format);
01233 
01234     *period = ALARM_PERIOD_EVERYSECOND;
01235 
01236     if (alarm_no == ALARM1) {
01237         if (alarm_regs.sec.bits.am1 == 0)
01238             *period = ALARM_PERIOD_EVERYMINUTE;
01239     }
01240 
01241     if (alarm_regs.min.bits.am2 == 0)
01242         *period = ALARM_PERIOD_HOURLY;
01243     if (alarm_regs.hrs.bits_24hr.am3 == 0)
01244         *period = ALARM_PERIOD_DAILY;
01245     if (alarm_regs.day_date.bits.am4 == 0)
01246         *period = ALARM_PERIOD_WEEKLY;
01247     if (alarm_regs.day_date.bits.dy_dt_match == 0)
01248         *period = ALARM_PERIOD_MONTHLY;
01249     if (alarm_no == ALARM1) {
01250         if (alarm_regs.mon.bits.am5 == 0)
01251             *period = ALARM_PERIOD_YEARLY;
01252         if (alarm_regs.mon.bits.am6 == 0)
01253             *period = ALARM_PERIOD_ONETIME;
01254     }
01255 
01256     ret = read_register(reg_addr->int_en_reg_addr, (uint8_t *)&int_en_reg.raw, 1);
01257     if (ret != MAX3133X_NO_ERR)
01258         return ret;
01259 
01260     if (alarm_no == ALARM1)
01261         *is_enabled = ((int_en_reg.raw & A1IE) == A1IE);
01262     else
01263         *is_enabled = ((int_en_reg.raw & A2IE) == A2IE);
01264 
01265     return MAX3133X_NO_ERR;
01266 }
01267 
01268 const MAX3133X::reg_addr_t MAX31334::reg_addr = {
01269         MAX31334_STATUS,
01270         MAX31334_INT_EN,
01271         MAX31334_RTC_RESET,
01272         MAX31334_RTC_CONFIG1,
01273         MAX31334_RTC_CONFIG2,
01274         MAX31334_TIMESTAMP_CONFIG,
01275         MAX31334_TIMER_CONFIG,
01276         MAX31334_SLEEP_CONFIG,
01277         MAX31334_SECONDS_1_128,
01278         MAX31334_SECONDS,
01279         MAX31334_MINUTES,
01280         MAX31334_HOURS,
01281         MAX31334_DAY,
01282         MAX31334_DATE,
01283         MAX31334_MONTH,
01284         MAX31334_YEAR,
01285         MAX31334_ALM1_SEC,
01286         MAX31334_ALM1_MIN,
01287         MAX31334_ALM1_HRS,
01288         MAX31334_ALM1_DAY_DATE,
01289         MAX31334_ALM1_MON,
01290         MAX31334_ALM1_YEAR,
01291         MAX31334_ALM2_MIN,
01292         MAX31334_ALM2_HRS,
01293         MAX31334_ALM2_DAY_DATE,
01294         REG_NOT_AVAILABLE,
01295         MAX31334_TIMER_COUNT2,
01296         MAX31334_TIMER_COUNT1,
01297         REG_NOT_AVAILABLE,
01298         MAX31334_TIMER_INIT2,
01299         MAX31334_TIMER_INIT1,
01300         MAX31334_PWR_MGMT,
01301         MAX31334_TRICKLE_REG,
01302         MAX31334_OFFSET_HIGH,
01303         MAX31334_OFFSET_LOW,
01304         MAX31334_TS0_SEC_1_128,
01305         MAX31334_TS0_SEC,
01306         MAX31334_TS0_MIN,
01307         MAX31334_TS0_HOUR,
01308         MAX31334_TS0_DATE,
01309         MAX31334_TS0_MONTH,
01310         MAX31334_TS0_YEAR,
01311         MAX31334_TS0_FLAGS,
01312         MAX31334_TS1_SEC_1_128,
01313         MAX31334_TS1_SEC,
01314         MAX31334_TS1_MIN,
01315         MAX31334_TS1_HOUR,
01316         MAX31334_TS1_DATE,
01317         MAX31334_TS1_MONTH,
01318         MAX31334_TS1_YEAR,
01319         MAX31334_TS1_FLAGS,
01320         MAX31334_TS2_SEC_1_128,
01321         MAX31334_TS2_SEC,
01322         MAX31334_TS2_MIN,
01323         MAX31334_TS2_HOUR,
01324         MAX31334_TS2_DATE,
01325         MAX31334_TS2_MONTH,
01326         MAX31334_TS2_YEAR,
01327         MAX31334_TS2_FLAGS,
01328         MAX31334_TS3_SEC_1_128,
01329         MAX31334_TS3_SEC,
01330         MAX31334_TS3_MIN,
01331         MAX31334_TS3_HOUR,
01332         MAX31334_TS3_DATE,
01333         MAX31334_TS3_MONTH,
01334         MAX31334_TS3_YEAR,
01335         MAX31334_TS3_FLAGS
01336 };
01337 
01338 const MAX3133X::reg_addr_t MAX31331::reg_addr = {
01339         MAX31331_STATUS,
01340         MAX31331_INT_EN,
01341         MAX31331_RTC_RESET,
01342         MAX31331_RTC_CONFIG1,
01343         MAX31331_RTC_CONFIG2,
01344         MAX31331_TIMESTAMP_CONFIG,
01345         MAX31331_TIMER_CONFIG,
01346         REG_NOT_AVAILABLE,
01347         MAX31331_SECONDS_1_128,
01348         MAX31331_SECONDS,
01349         MAX31331_MINUTES,
01350         MAX31331_HOURS,
01351         MAX31331_DAY,
01352         MAX31331_DATE,
01353         MAX31331_MONTH,
01354         MAX31331_YEAR,
01355         MAX31331_ALM1_SEC,
01356         MAX31331_ALM1_MIN,
01357         MAX31331_ALM1_HRS,
01358         MAX31331_ALM1_DAY_DATE,
01359         MAX31331_ALM1_MON,
01360         MAX31331_ALM1_YEAR,
01361         MAX31331_ALM2_MIN,
01362         MAX31331_ALM2_HRS,
01363         MAX31331_ALM2_DAY_DATE,
01364         MAX31331_TIMER_COUNT,
01365         REG_NOT_AVAILABLE,
01366         REG_NOT_AVAILABLE,
01367         MAX31331_TIMER_INIT,
01368         REG_NOT_AVAILABLE,
01369         REG_NOT_AVAILABLE,
01370         MAX31331_PWR_MGMT,
01371         MAX31331_TRICKLE_REG,
01372         MAX31331_OFFSET_HIGH,
01373         MAX31331_OFFSET_LOW,
01374         MAX31331_TS0_SEC_1_128,
01375         MAX31331_TS0_SEC,
01376         MAX31331_TS0_MIN,
01377         MAX31331_TS0_HOUR,
01378         MAX31331_TS0_DATE,
01379         MAX31331_TS0_MONTH,
01380         MAX31331_TS0_YEAR,
01381         MAX31331_TS0_FLAGS,
01382         MAX31331_TS1_SEC_1_128,
01383         MAX31331_TS1_SEC,
01384         MAX31331_TS1_MIN,
01385         MAX31331_TS1_HOUR,
01386         MAX31331_TS1_DATE,
01387         MAX31331_TS1_MONTH,
01388         MAX31331_TS1_YEAR,
01389         MAX31331_TS1_FLAGS,
01390         MAX31331_TS2_SEC_1_128,
01391         MAX31331_TS2_SEC,
01392         MAX31331_TS2_MIN,
01393         MAX31331_TS2_HOUR,
01394         MAX31331_TS2_DATE,
01395         MAX31331_TS2_MONTH,
01396         MAX31331_TS2_YEAR,
01397         MAX31331_TS2_FLAGS,
01398         MAX31331_TS3_SEC_1_128,
01399         MAX31331_TS3_SEC,
01400         MAX31331_TS3_MIN,
01401         MAX31331_TS3_HOUR,
01402         MAX31331_TS3_DATE,
01403         MAX31331_TS3_MONTH,
01404         MAX31331_TS3_YEAR,
01405         MAX31331_TS3_FLAGS
01406 };