diff --git a/src/drivers/i2c/rx6110sa/chip.h b/src/drivers/i2c/rx6110sa/chip.h index b90a52963b..76db780f9a 100644 --- a/src/drivers/i2c/rx6110sa/chip.h +++ b/src/drivers/i2c/rx6110sa/chip.h @@ -23,4 +23,17 @@ struct drivers_i2c_rx6110sa_config { unsigned char user_year; /* User year to set */ unsigned char set_user_date; /* Use user date from device tree */ unsigned char cof_selection; /* Set up "clock out" frequency */ + unsigned char timer_clk; /* Set up timer clock */ + unsigned char timer_irq_en; /* Interrupt generation on timer */ + unsigned short timer_preset; /* Preset value for the timer */ + unsigned char timer_mode; /* Set the timer mode of operation */ + unsigned char timer_en; /* Enable timer operation */ + unsigned char irq_output_pin; /* 0: IRQ2 pin used, 1: IRQ1 pin used */ + unsigned char fout_output_pin; /* 0: IRQ2, 1: IRQ1, 2: DO/FOUT */ + unsigned char enable_1hz_out; /* If set enables 1 Hz output on IRQ1 */ + unsigned char pmon_sampling; /* Select power monitor sampling time */ + /* The following two bits set the power monitor and backup mode. */ + unsigned char bks_on; + unsigned char bks_off; + unsigned char iocut_en; /* Disable backup of I/O circuit. */ }; diff --git a/src/drivers/i2c/rx6110sa/rx6110sa.c b/src/drivers/i2c/rx6110sa/rx6110sa.c index 9d60bdb7e1..06735a7868 100644 --- a/src/drivers/i2c/rx6110sa/rx6110sa.c +++ b/src/drivers/i2c/rx6110sa/rx6110sa.c @@ -88,33 +88,54 @@ static void rx6110sa_init(struct device *dev) struct drivers_i2c_rx6110sa_config *config = dev->chip_info; uint8_t reg; - /* Do a dummy read first. */ - reg = rx6110sa_read(dev, SECOND_REG); - + /* Do a dummy read first as requested in the datasheet. */ + rx6110sa_read(dev, SECOND_REG); + /* + * Set battery backup mode and power monitor sampling time even if there + * was no power loss to make sure that the right mode is used as it + * directly influences the backup current consumption and therefore the + * backup time. + */ + reg = (config->pmon_sampling & PMON_SAMPL_MASK) | + (!!config->bks_off << 2) | (!!config->bks_on << 3) | + (!!config->iocut_en << 4); + rx6110sa_write(dev, BATTERY_BACKUP_REG, reg); /* * Check VLF-bit which indicates the RTC data loss, such as due to a * supply voltage drop. */ reg = rx6110sa_read(dev, FLAG_REGISTER); - if (!(reg & VLF_BIT)) /* No voltage low detected, everything is well. */ return; - /* * Voltage low detected, initialize RX6110 SA again. * Set first some registers to known state. */ - rx6110sa_write(dev, BATTERY_BACKUP_REG, 0x00); rx6110sa_write(dev, RESERVED_BIT_REG, RTC_INIT_VALUE); rx6110sa_write(dev, DIGITAL_REG, 0x00); - rx6110sa_write(dev, IRQ_CONTROL_REG, 0x00); + reg = (!!config->enable_1hz_out << 4) | + (!!config->irq_output_pin << 2) | + (config->fout_output_pin & FOUT_OUTPUT_PIN_MASK); + rx6110sa_write(dev, IRQ_CONTROL_REG, reg); /* Clear timer enable bit and set frequency of clock output. */ - reg = rx6110sa_read(dev, EXTENSION_REG); reg &= ~(FSEL_MASK | TE_BIT); reg |= (config->cof_selection << 6); + if (config->timer_preset) { + /* Timer needs to be in stop mode prior to programming it. */ + rx6110sa_write(dev, EXTENSION_REG, reg); + reg &= ~TSEL_MASK; + /* Program the timer preset value. */ + rx6110sa_write(dev, TMR_COUNTER_0_REG, + config->timer_preset & 0xff); + rx6110sa_write(dev, TMR_COUNTER_1_REG, + (config->timer_preset >> 8) & 0xff); + /* Set Timer Enable bit and the timer clock value. */ + reg |= ((!!config->timer_en << 4) | + (config->timer_clk & TSEL_MASK)); + } rx6110sa_write(dev, EXTENSION_REG, reg); /* Clear voltage low detect bit. */ @@ -140,7 +161,9 @@ static void rx6110sa_init(struct device *dev) rx6110sa_write(dev, MINUTE_REG, 0); rx6110sa_write(dev, SECOND_REG, 0); /* Start oscillator again as the RTC is set up now. */ - rx6110sa_write(dev, CTRL_REG, 0x00); + reg = (!!config->timer_irq_en << 4) | + (config->timer_mode & TMR_MODE_MASK); + rx6110sa_write(dev, CTRL_REG, reg); } static struct device_operations rx6110sa_ops = { diff --git a/src/drivers/i2c/rx6110sa/rx6110sa.h b/src/drivers/i2c/rx6110sa/rx6110sa.h index 99527e0420..ebd75ead60 100644 --- a/src/drivers/i2c/rx6110sa/rx6110sa.h +++ b/src/drivers/i2c/rx6110sa/rx6110sa.h @@ -38,6 +38,7 @@ #define EXTENSION_REG 0x1D #define TE_BIT (1 << 4) #define FSEL_MASK 0xC0 +#define TSEL_MASK 0x07 #define FLAG_REGISTER 0x1E #define VLF_BIT (1 << 1) #define CTRL_REG 0x1F @@ -46,9 +47,15 @@ #define UIE_BIT (1 << 5) #define STOP_BIT (1 << 6) #define TEST_BIT (1 << 7) +#define TMR_MODE_MASK 0x03 +#define TMR_MODE_NORM_BACKUP 0x00 +#define TMR_MODE_NORM_ONLY 0x01 +#define TMR_MODE_BACKUP_ONLY 0x03 #define DIGITAL_REG 0x30 #define BATTERY_BACKUP_REG 0x31 +#define PMON_SAMPL_MASK 0x03 #define IRQ_CONTROL_REG 0x32 +#define FOUT_OUTPUT_PIN_MASK 0x03 /* Define CLKOUT frequency divider values valid for parameter cof_selection */ #define COF_OFF 0x00 @@ -56,4 +63,26 @@ #define COF_1024_HZ 0x02 #define COF_32768_HZ 0x03 +/* Define valid clock rates for the internal timer */ +#define TMR_CLK_4096_HZ 0x00 +#define TMR_CLK_64_HZ 0x01 +#define TMR_CLK_1_HZ 0x02 +#define TMR_CLK_1_60_HZ 0x03 +#define TMR_CLK_1_3600_HZ 0x04 + +/* + * Define possible power monitor sampling times. This value decides for how + * long the power supply is sampled every second to detect a power down + * condition. + */ +#define PMON_SAMPL_2_MS 0x00 +#define PMON_SAMPL_16_MS 0x01 +#define PMON_SAMPL_128_MS 0x02 +#define PMON_SAMPL_256_MS 0x03 + +/* Define on which pin of the RTC the generated square wave will be driven. */ +#define FOUT_IRQ2 0x00 /* IRQ2 pin used for Fout */ +#define FOUT_IRQ1 0x01 /* IRQ1 pin used for Fout */ +#define FOUT_DO_FOUT 0x02 /* DO/FOUT pin used for Fout */ + #endif /* _I2C_RX6110SA_H_ */