xref: /aosp_15_r20/external/coreboot/src/drivers/i2c/rv3028c7/rv3028c7.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
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"
16 
rtc_eep_wait_ready(struct device * dev)17 static enum cb_err rtc_eep_wait_ready(struct device *dev)
18 {
19 	struct stopwatch sw;
20 	uint8_t status;
21 
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));
27 
28 	if (status & EE_BUSY_BIT) {
29 		return CB_ERR;
30 	} else {
31 		return CB_SUCCESS;
32 	}
33 }
34 
rtc_eep_auto_refresh(struct device * dev,uint8_t state)35 static enum cb_err rtc_eep_auto_refresh(struct device *dev, uint8_t state)
36 {
37 	uint8_t reg;
38 
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;
49 	}
50 	return CB_SUCCESS;
51 }
52 
rtc_eep_start_update(struct device * dev)53 static enum cb_err rtc_eep_start_update(struct device *dev)
54 {
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;
59 
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;
64 }
65 
rtc_set_time_date(struct device * dev)66 static void rtc_set_time_date(struct device *dev)
67 {
68 	struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
69 	uint8_t buf[7];
70 
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);
88 	}
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);
93 	}
94 }
95 
rtc_final(struct device * dev)96 static void rtc_final(struct device *dev)
97 {
98 	uint8_t buf[7];
99 
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]));
111 	}
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);
116 	}
117 }
118 
rtc_init(struct device * dev)119 static void rtc_init(struct device *dev)
120 {
121 	struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
122 	uint8_t reg, backup_reg, eep_update_needed = 0;
123 
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;
131 	}
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;
137 	}
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;
145 	}
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;
153 	}
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);
159 	}
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);
168 	}
169 	/*
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.
174 	 */
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);
178 	}
179 }
180 
181 #if CONFIG(HAVE_ACPI_TABLES)
rv3028c7_fill_ssdt(const struct device * dev)182 static void rv3028c7_fill_ssdt(const struct device *dev)
183 {
184 	const char *scope = acpi_device_scope(dev);
185 	struct drivers_i2c_rv3028c7_config *config = dev->chip_info;
186 	enum i2c_speed bus_speed;
187 
188 	if (!scope)
189 		return;
190 
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;
201 	}
202 
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,
208 	};
209 
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));
216 
217 	/* Resources */
218 	acpigen_write_name("_CRS");
219 
220 	acpigen_write_resourcetemplate_header();
221 	acpi_device_write_i2c(&i2c);
222 	acpigen_write_resourcetemplate_footer();
223 
224 	acpigen_pop_len(); /* Device */
225 	acpigen_pop_len(); /* Scope */
226 
227 	printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name,
228 			dev_path(dev));
229 }
230 
rv3028c7_acpi_name(const struct device * dev)231 static const char *rv3028c7_acpi_name(const struct device *dev)
232 {
233 	return RV3028C7_ACPI_NAME;
234 }
235 #endif
236 
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
246 };
247 
rtc_enable(struct device * dev)248 static void rtc_enable(struct device *dev)
249 {
250 	dev->ops = &rv3028c7_ops;
251 }
252 
253 struct chip_operations drivers_i2c_rv3028c7_ops = {
254 	.name = "RV-3028-C7",
255 	.enable_dev = rtc_enable
256 };
257