summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/i2c/rx6110sa/chip.h13
-rw-r--r--src/drivers/i2c/rx6110sa/rx6110sa.c41
-rw-r--r--src/drivers/i2c/rx6110sa/rx6110sa.h29
3 files changed, 74 insertions, 9 deletions
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_ */