drivers/i2c/rv3028c7: Add ACPI generation callbacks
[coreboot.git] / src / drivers / i2c / rv3028c7 / rv3028c7.c
blob87cbc247852acaaaed0643eb99b5c1c926763057
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi_device.h>
4 #include <acpi/acpigen.h>
5 #include <commonlib/bsd/bcd.h>
6 #include <console/console.h>
7 #include <delay.h>
8 #include <device/device.h>
9 #include <device/i2c.h>
10 #include <device/i2c_bus.h>
11 #include <timer.h>
12 #include <types.h>
13 #include <version.h>
14 #include "chip.h"
15 #include "rv3028c7.h"
17 static enum cb_err rtc_eep_wait_ready(struct device *dev)
19 struct stopwatch sw;
20 uint8_t status;
22 stopwatch_init_msecs_expire(&sw, EEP_SYNC_TIMEOUT_MS);
23 do {
24 status = (uint8_t)i2c_dev_readb_at(dev, STATUS_REG);
25 mdelay(1);
26 } while ((status & EE_BUSY_BIT) && !stopwatch_expired(&sw));
28 if (status & EE_BUSY_BIT) {
29 return CB_ERR;
30 } else {
31 return CB_SUCCESS;
35 static enum cb_err rtc_eep_auto_refresh(struct device *dev, uint8_t state)
37 uint8_t reg;
39 reg = (uint8_t)i2c_dev_readb_at(dev, CTRL1_REG);
40 reg &= ~EERD_BIT;
41 if (state == EEP_REFRESH_DIS)
42 reg |= EERD_BIT;
43 i2c_dev_writeb_at(dev, CTRL1_REG, reg);
44 /* Wait until the EEPROM has finished a possible running operation. */
45 if (rtc_eep_wait_ready(dev) != CB_SUCCESS) {
46 printk(BIOS_ERR, "%s: EEPROM access timed out (%d ms)!\n",
47 dev->chip_ops->name, EEP_SYNC_TIMEOUT_MS);
48 return CB_ERR;
50 return CB_SUCCESS;
53 static enum cb_err rtc_eep_start_update(struct device *dev)
55 /* Disable EEPROM auto refresh before writing RAM to EEPROM
56 to avoid race conditions. */
57 if (rtc_eep_auto_refresh(dev, EEP_REFRESH_DIS))
58 return CB_ERR;
60 /* Now start the update cycle.*/
61 i2c_dev_writeb_at(dev, EEP_CMD_REG, EEP_CMD_PREFIX);
62 i2c_dev_writeb_at(dev, EEP_CMD_REG, EEP_CMD_UPDATE);
63 return CB_SUCCESS;
66 static void rtc_set_time_date(struct device *dev)
68 struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
69 uint8_t buf[7];
71 /* The buffer contains the seconds through years of the new time and date.
72 Whenever a new date is set, the time is set to 00:00:00. */
73 buf[0] = 0; /* Entry for seconds. */
74 buf[1] = 0; /* Entry for minutes. */
75 buf[2] = 0; /* Entry for hours. */
76 if (config->set_user_date) {
77 buf[3] = config->user_weekday;
78 buf[4] = bin2bcd(config->user_day);
79 buf[5] = bin2bcd(config->user_month);
80 buf[6] = bin2bcd(config->user_year);
81 printk(BIOS_DEBUG, "%s: Set to user date\n", dev->chip_ops->name);
82 } else {
83 buf[3] = coreboot_build_date.weekday;
84 buf[4] = coreboot_build_date.day;
85 buf[5] = coreboot_build_date.month;
86 buf[6] = coreboot_build_date.year;
87 printk(BIOS_DEBUG, "%s: Set to coreboot build date\n", dev->chip_ops->name);
89 /* According to the datasheet, date and time should be transferred in "one go"
90 in order to avoid value corruption. */
91 if (i2c_dev_write_at(dev, buf, sizeof(buf), 0) != sizeof(buf)) {
92 printk(BIOS_ERR, "%s: Not able to set date and time!\n", dev->chip_ops->name);
96 static void rtc_final(struct device *dev)
98 uint8_t buf[7];
100 /* Read back current RTC date and time and print it to the console.
101 Date and time are read in "one go", the buffer contains seconds (byte 0)
102 through years (byte 6) after this read. */
103 if (i2c_dev_read_at(dev, buf, sizeof(buf), 0) != sizeof(buf)) {
104 printk(BIOS_ERR, "%s: Not able to read current date and time!\n",
105 dev->chip_ops->name);
106 } else {
107 printk(BIOS_INFO, "%s: Current date %02d.%02d.%02d %02d:%02d:%02d\n",
108 dev->chip_ops->name, bcd2bin(buf[5]), bcd2bin(buf[4]),
109 bcd2bin(buf[6]), bcd2bin(buf[2]), bcd2bin(buf[1]),
110 bcd2bin(buf[0]));
112 /* Make sure the EEPROM automatic refresh is enabled. */
113 if (rtc_eep_auto_refresh(dev, EEP_REFRESH_EN) != CB_SUCCESS) {
114 printk(BIOS_ERR, "%s: Not able to enable EEPROM auto refresh!\n",
115 dev->chip_ops->name);
119 static void rtc_init(struct device *dev)
121 struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
122 uint8_t reg, backup_reg, eep_update_needed = 0;
124 /* On every startup, the RTC synchronizes the internal EEPROM with RAM.
125 * During this time no operation shall modify RAM registers. Ensure this
126 * sync is finished before starting the initialization. */
127 if (rtc_eep_wait_ready(dev) != CB_SUCCESS) {
128 printk(BIOS_WARNING, "%s: Timeout on EEPROM sync after power on!\n",
129 dev->chip_ops->name);
130 return;
132 reg = backup_reg = (uint8_t)i2c_dev_readb_at(dev, EEP_BACKUP_REG);
133 /* Configure the switch-over setting according to devicetree. */
134 if (config->bckup_sw_mode) {
135 reg &= ~BSM_MASK;
136 reg |= config->bckup_sw_mode << BSM_BIT;
138 /* Configure the VBACKUP charging mode. */
139 if (config->cap_charge) {
140 reg &= ~TCR_MASK;
141 reg |= ((config->cap_charge - 1) << TCR_BIT);
142 reg |= TCE_BIT;
143 } else {
144 reg &= ~TCE_BIT;
146 /* According to the datasheet the Fast Edge Detection Enable (FEDE) bit
147 should always be set. */
148 reg |= FEDE_BIT;
149 if (reg != backup_reg) {
150 /* Write new register value into shadow RAM and request an EEPROM update. */
151 i2c_dev_writeb_at(dev, EEP_BACKUP_REG, reg);
152 eep_update_needed = 1;
154 /* Make sure the hour register is in 24h format.*/
155 reg = (uint8_t)i2c_dev_readb_at(dev, CTRL2_REG);
156 if (reg & HOUR_12_24_BIT) {
157 reg &= ~HOUR_12_24_BIT;
158 i2c_dev_writeb_at(dev, CTRL2_REG, reg);
160 /* Check for a possible voltage drop event. */
161 reg = (uint8_t)i2c_dev_readb_at(dev, STATUS_REG);
162 if (reg & PORF_BIT) {
163 /* Voltage drop was detected, date and time needs to be set properly. */
164 rtc_set_time_date(dev);
165 /* Clear the PORF bit to mark that the event was handled. */
166 reg &= ~PORF_BIT;
167 i2c_dev_writeb_at(dev, STATUS_REG, reg);
170 * Finally, trigger the EEPROM update procedure if needed.
171 * According to the datasheet, this update will consume ~63 ms.
172 * In order to not block the boot process here waiting for this update being finished,
173 * trigger the update now and check for readiness in the final hook.
175 if (eep_update_needed && rtc_eep_start_update(dev) != CB_SUCCESS) {
176 printk(BIOS_ERR, "%s: Not able to trigger EEPROM update!\n",
177 dev->chip_ops->name);
181 #if CONFIG(HAVE_ACPI_TABLES)
182 static void rv3028c7_fill_ssdt(const struct device *dev)
184 const char *scope = acpi_device_scope(dev);
185 struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
186 enum i2c_speed bus_speed;
188 if (!scope)
189 return;
191 switch (config->bus_speed) {
192 case I2C_SPEED_STANDARD:
193 case I2C_SPEED_FAST:
194 bus_speed = config->bus_speed;
195 break;
196 default:
197 bus_speed = I2C_SPEED_STANDARD;
198 printk(BIOS_INFO, "%s: Bus speed unsupported, fall back to %d kHz!\n",
199 dev->chip_ops->name, bus_speed / 1000);
200 break;
203 struct acpi_i2c i2c = {
204 .address = dev->path.i2c.device,
205 .mode_10bit = dev->path.i2c.mode_10bit,
206 .speed = bus_speed,
207 .resource = scope,
210 /* Device */
211 acpigen_write_scope(scope);
212 acpigen_write_device(acpi_device_name(dev));
213 acpigen_write_name_string("_HID", RV3028C7_HID_NAME);
214 acpigen_write_name_string("_DDN", RV3028C7_HID_DESC);
215 acpigen_write_STA(acpi_device_status(dev));
217 /* Resources */
218 acpigen_write_name("_CRS");
220 acpigen_write_resourcetemplate_header();
221 acpi_device_write_i2c(&i2c);
222 acpigen_write_resourcetemplate_footer();
224 acpigen_pop_len(); /* Device */
225 acpigen_pop_len(); /* Scope */
227 printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name,
228 dev_path(dev));
231 static const char *rv3028c7_acpi_name(const struct device *dev)
233 return RV3028C7_ACPI_NAME;
235 #endif
237 static struct device_operations rv3028c7_ops = {
238 .read_resources = noop_read_resources,
239 .set_resources = noop_set_resources,
240 .init = rtc_init,
241 .final = rtc_final,
242 #if CONFIG(HAVE_ACPI_TABLES)
243 .acpi_name = rv3028c7_acpi_name,
244 .acpi_fill_ssdt = rv3028c7_fill_ssdt,
245 #endif
248 static void rtc_enable(struct device *dev)
250 dev->ops = &rv3028c7_ops;
253 struct chip_operations drivers_i2c_rv3028c7_ops = {
254 CHIP_NAME("RV-3028-C7")
255 .enable_dev = rtc_enable