From 0dc405de980a22721e9faba9127321f4849d10ab Mon Sep 17 00:00:00 2001 From: Werner Zeh Date: Wed, 7 Jun 2017 09:51:06 +0200 Subject: rx6110sa: Add more chip configuration options to chip The RTC RX6110SA has several configuration options which might be interesting to set. To make this setup independent of the driver itself but let it still be configurable on mainboard level, add more configuration options to the chip driver. Change-Id: I7f8b2aa7cd001a887f271be36f655e10e60e778b Signed-off-by: Werner Zeh Reviewed-on: https://review.coreboot.org/20084 Tested-by: build bot (Jenkins) Reviewed-by: Mario Scheithauer --- src/drivers/i2c/rx6110sa/chip.h | 13 ++++++++++++ src/drivers/i2c/rx6110sa/rx6110sa.c | 41 +++++++++++++++++++++++++++++-------- src/drivers/i2c/rx6110sa/rx6110sa.h | 29 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 9 deletions(-) (limited to 'src/drivers/i2c') 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_ */ -- cgit v1.2.3