1 /*
2  * Copyright (c) 2024 Cirrus Logic, Inc.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #define DT_DRV_COMPAT cirrus_cp9314
7 
8 #include <zephyr/device.h>
9 #include <zephyr/devicetree.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/drivers/regulator.h>
15 #include <zephyr/sys_clock.h>
16 #include <zephyr/sys/util.h>
17 
18 LOG_MODULE_REGISTER(CP9314, CONFIG_REGULATOR_LOG_LEVEL);
19 
20 #define CP9314_REG_DEVICE_ID 0x0
21 #define CP9314_DEV_ID        0xA4
22 
23 #define CP9314_REG_VOUT_UVP   0x2
24 #define CP9314_VOUT_UVP_DIS_0 BIT(7)
25 #define CP9314_VOUT_UVP_DIS_1 BIT(3)
26 #define CP9314_VOUT_UVP_DIS   CP9314_VOUT_UVP_DIS_0 | CP9314_VOUT_UVP_DIS_1
27 #define CP9314_VOUT_UVP       GENMASK(1, 0)
28 
29 #define CP9314_REG_OPTION_REG_1 0x3
30 #define CP9314_LB1_DELAY_CFG    GENMASK(5, 4)
31 #define CP9314_LB1_DELTA_CFG_0  GENMASK(3, 0)
32 
33 #define CP9314_REG_OPTION_REG_2     0x4
34 #define CP9314_LB2_DELTA_CFG_0      GENMASK(7, 5)
35 #define CP9314_MODE_CTRL_MIN_FREQ_0 GENMASK(2, 0)
36 
37 #define CP9314_REG_IIN_OCP   0x5
38 #define CP9314_IIN_OCP_DIS   BIT(7)
39 #define CP9314_TM_IIN_OC_CFG GENMASK(2, 0)
40 
41 #define CP9314_REG_IIN_PEAK_OCP 0x6
42 #define CP9314_IIN_PEAK_OCP_DIS BIT(7)
43 #define CP9314_IIN_PEAK_OCP     GENMASK(2, 0)
44 
45 #define CP9314_REG_VIN2OUT_OVP 0x7
46 #define CP9314_VIN2OUT_OVP     GENMASK(1, 0)
47 
48 #define CP9314_REG_VIN2OUT_UVP 0x8
49 #define CP9314_VIN2OUT_UVP     GENMASK(1, 0)
50 
51 #define CP9314_REG_CONVERTER    0x9
52 #define CP9314_FASTSHDN_PIN_STS BIT(6)
53 #define CP9314_PGOOD_PIN_STS    BIT(5)
54 #define CP9314_ACTIVE_STS       BIT(1)
55 
56 #define CP9314_REG_CTRL1    0xA
57 #define CP9314_CP_EN        BIT(7)
58 #define CP9314_MODE_CTRL_EN BIT(3)
59 
60 #define CP9314_REG_CTRL4        0xD
61 #define CP9314_SYNC_FUNCTION_EN BIT(7)
62 #define CP9314_SYNC_HOST_EN     BIT(6)
63 #define CP9314_FRC_SYNC_MODE    BIT(5)
64 #define CP9314_FRC_OP_MODE      BIT(3)
65 #define CP9314_MODE_MASK        GENMASK(2, 0)
66 #define CP9314_MODE_2TO1        1
67 #define CP9314_MODE_3TO1        2
68 
69 #define CP9314_REG_FLT_FLAG   0x12
70 #define CP9314_VIN_OVP_FLAG   BIT(1)
71 #define CP9314_VOUT_OVP_FLAG  BIT(0)
72 
73 #define CP9314_REG_COMP_FLAG0 0x2A
74 #define CP9314_IIN_OCP_FLAG   BIT(4)
75 
76 #define CP9314_REG_COMP_FLAG1 0x2C
77 #define CP9314_VIN2OUT_OVP_FLAG BIT(0)
78 
79 #define CP9314_REG_LION_CFG_1  0x31
80 #define CP9314_LB2_DELTA_CFG_1 GENMASK(7, 5)
81 
82 #define CP9314_REG_LION_INT_MASK_2 0x32
83 #define CP9314_CLEAR_INT           BIT(6)
84 
85 #define CP9314_REG_LION_CFG_3        0x34
86 #define CP9314_LB_MIN_FREQ_SEL_0     GENMASK(7, 6)
87 #define CP9314_MODE_CTRL_UPDATE_BW_1 GENMASK(5, 3)
88 #define CP9314_ALLOW_HW_I2C_LOCK     BIT(0)
89 
90 #define CP9314_REG_LB_CTRL       0x38
91 #define CP9314_LB1_DELTA_CFG_1   GENMASK(6, 3)
92 #define CP9314_LB_MIN_FREQ_SEL_1 GENMASK(2, 1)
93 
94 #define CP9314_REG_CRUS_CTRL       0x40
95 #define CP9314_CRUS_KEY_LOCK       0x0
96 #define CP9314_CRUS_KEY_UNLOCK     0xAA
97 #define CP9314_CRUS_KEY_SOFT_RESET 0xC6
98 
99 #define CP9314_REG_TRIM_5  0x46
100 #define CP9314_CSI_CHOP_EN BIT(2)
101 
102 #define CP9314_REG_TRIM_8            0x49
103 #define CP9314_MODE_CTRL_UPDATE_BW_0 GENMASK(2, 0)
104 
105 #define CP9314_REG_TRIM_9         0x4A
106 #define CP9314_FORCE_KEY_POLARITY BIT(2)
107 #define CP9314_TM_KEY_POLARITY    BIT(1)
108 #define CP9314_KEY_ACTIVE_LOW     0
109 #define CP9314_KEY_ACTIVE_HIGH    CP9314_TM_KEY_POLARITY
110 
111 #define CP9314_REG_BST_CP_PD_CFG 0x58
112 #define CP9314_LB1_BLANK_CFG     BIT(5)
113 
114 #define CP9314_REG_CFG_9            0x59
115 #define CP9314_VOUT_PCHG_TIME_CFG_0 GENMASK(2, 1)
116 
117 #define CP9314_REG_CFG_10           0x5A
118 #define CP9314_VOUT_PCHG_TIME_CFG_1 GENMASK(1, 0)
119 
120 #define CP9314_REG_BC_STS_C  0x62
121 #define CP9314_CHIP_REV_MASK GENMASK(7, 4)
122 #define CP9314_CHIP_REV_B1   0x3
123 
124 #define CP9314_REG_FORCE_SC_MISC 0x69
125 #define CP9314_FORCE_CSI_EN      BIT(0)
126 
127 #define CP9314_REG_TSBAT_CTRL     0x72
128 #define CP9314_LB1_STOP_PHASE_SEL BIT(4)
129 
130 #define CP9314_REG_TEST_MODE_CTRL 0x66
131 #define CP9314_SOFT_RESET_REQ     BIT(0)
132 
133 #define CP9314_REG_LION_COMP_CTRL_1 0x79
134 #define CP9314_VIN_SWITCH_OK_DIS_0  BIT(3)
135 #define CP9314_VOUT_OV_CFG_0        GENMASK(5, 4)
136 #define CP9314_VIN_SWITCH_OK_CFG    GENMASK(1, 0)
137 
138 #define CP9314_REG_LION_COMP_CTRL_2 0x7A
139 #define CP9314_VOUT_OV_CFG_1        GENMASK(3, 2)
140 
141 #define CP9314_REG_LION_COMP_CTRL_3 0x7B
142 #define CP9314_VIN_OV_CFG_0         GENMASK(4, 3)
143 #define CP9314_VIN_OV_CFG_1         GENMASK(1, 0)
144 #define CP9314_VIN_OV_CFG           CP9314_VIN_OV_CFG_0 | CP9314_VIN_OV_CFG_1
145 
146 #define CP9314_REG_LION_COMP_CTRL_4 0x7C
147 #define CP9314_FORCE_IIN_OC_CFG     BIT(1)
148 #define CP9314_VIN_SWITCH_OK_DIS_1  BIT(5)
149 
150 #define CP9314_REG_PTE_REG_2 0x8B
151 #define CP9314_PTE_2_MASK    GENMASK(7, 5)
152 #define CP9314_PTE_2_OTP_1   0x0
153 #define CP9314_PTE_2_OTP_2   0x1
154 
155 #define CP9314_REG_BACKDOOR_CTRL 0x8C
156 
157 #define CP9314_FAULT1_STS 0x9A
158 #define CP9314_VIN_OV_STS BIT(4)
159 
160 #define CP9314_SYS_STS    0x98
161 #define CP9314_VIN_UV_STS BIT(7)
162 
163 #define CP9314_REG_TM_SEQ_CTRL_1 0xAA
164 #define CP9314_TM_CSI_EN         BIT(5)
165 
166 #define CP9314_REG_STS_PIN_ADC_0 0xB4
167 #define CP9314_STS_PROG_LVL      GENMASK(7, 4)
168 #define CP9314_STS_ADDR_LVL      GENMASK(3, 0)
169 
170 #define CP9314_SOFT_RESET_DELAY_MSEC 200
171 #define CP9314_EN_DEBOUNCE_USEC      3000
172 #define CP9314_T_STARTUP_MSEC        120
173 
174 #define CP9314_DEVICE_MODE_HOST_4GANG_0x78      0x0
175 #define CP9314_DEVICE_MODE_HOST_4GANG_0x72      0x1
176 #define CP9314_DEVICE_MODE_HOST_3GANG_0x78      0x2
177 #define CP9314_DEVICE_MODE_HOST_3GANG_0x72      0x3
178 #define CP9314_DEVICE_MODE_HOST_2GANG_0x78      0x4
179 #define CP9314_DEVICE_MODE_HOST_2GANG_0x72      0x5
180 #define CP9314_DEVICE_MODE_HOST_STANDALONE_0x78 0x6
181 #define CP9314_DEVICE_MODE_HOST_STANDALONE_0x72 0x7
182 #define CP9314_DEVICE_MODE_DEVICE_4_0x68        0x8
183 #define CP9314_DEVICE_MODE_DEVICE_4_0x54        0x9
184 #define CP9314_DEVICE_MODE_DEVICE_3_0x56        0xA
185 #define CP9314_DEVICE_MODE_DEVICE_3_0x53        0xB
186 #define CP9314_DEVICE_MODE_DEVICE_2_0x79        0xC
187 #define CP9314_DEVICE_MODE_DEVICE_2_0x73        0xD
188 
189 enum cp9314_sync_roles {
190 	CP9314_ROLE_HOST,
191 	CP9314_ROLE_DEV2,
192 	CP9314_ROLE_DEV3,
193 	CP9314_ROLE_DEV4,
194 	CP9314_ROLE_STANDALONE,
195 };
196 
197 enum cp9314_backdoor_keys {
198 	CP9314_BACKDOOR_LOCKED_KEY = 0x0,
199 	CP9314_BACKDOOR_PUBLIC_KEY = 0x0F,
200 };
201 
202 struct regulator_cp9314_config {
203 	struct regulator_common_config common;
204 	struct i2c_dt_spec i2c;
205 	struct gpio_dt_spec en_pin;
206 	struct gpio_dt_spec pgood_pin;
207 	uint8_t initial_op_mode_idx;
208 	bool hw_i2c_lock;
209 };
210 
211 struct regulator_cp9314_data {
212 	struct regulator_common_data data;
213 	enum cp9314_sync_roles sync_role;
214 	uint8_t backdoor_key;
215 	bool allow_hw_i2c_lock;
216 };
217 
218 struct cp9314_reg_patch {
219 	uint8_t reg_addr;
220 	uint8_t mask;
221 	uint8_t value;
222 };
223 
224 /* OTP memory errata patch for OTP v1. Corrects trim errata. */
225 static struct cp9314_reg_patch otp_1_patch[3] = {
226 	{CP9314_REG_OPTION_REG_1, CP9314_LB1_DELAY_CFG, 0},
227 	{CP9314_REG_BST_CP_PD_CFG, CP9314_LB1_BLANK_CFG, CP9314_LB1_BLANK_CFG},
228 	{CP9314_REG_TSBAT_CTRL, CP9314_LB1_STOP_PHASE_SEL, CP9314_LB1_STOP_PHASE_SEL},
229 };
230 
regulator_cp9314_get_error_flags(const struct device * dev,regulator_error_flags_t * flags)231 static int regulator_cp9314_get_error_flags(const struct device *dev,
232 					    regulator_error_flags_t *flags)
233 {
234 	const struct regulator_cp9314_config *config = dev->config;
235 	uint8_t val[3];
236 	int ret;
237 
238 	*flags = 0U;
239 
240 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_FLT_FLAG, &val[0]);
241 	if (ret < 0) {
242 		return ret;
243 	}
244 
245 	if (FIELD_GET(CP9314_VIN_OVP_FLAG, val[0]) || FIELD_GET(CP9314_VOUT_OVP_FLAG, val[0])) {
246 		*flags |= REGULATOR_ERROR_OVER_VOLTAGE;
247 	}
248 
249 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_COMP_FLAG0, &val[1]);
250 	if (ret < 0) {
251 		return ret;
252 	}
253 
254 	if (FIELD_GET(CP9314_IIN_OCP_FLAG, val[1])) {
255 		*flags |= REGULATOR_ERROR_OVER_CURRENT;
256 	}
257 
258 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_COMP_FLAG1, &val[2]);
259 	if (ret < 0) {
260 		return ret;
261 	}
262 
263 	if (FIELD_GET(CP9314_VIN2OUT_OVP_FLAG, val[2])) {
264 		*flags |= REGULATOR_ERROR_OVER_VOLTAGE;
265 	}
266 
267 	LOG_DBG("FLT_FLAG = 0x%x, COMP_FLAG0 = 0x%x, COMP_FLAG1 = 0x%x", val[0], val[1], val[2]);
268 
269 	return 0;
270 }
271 
regulator_cp9314_write_lock(const struct device * dev,const enum cp9314_backdoor_keys key)272 static int regulator_cp9314_write_lock(const struct device *dev,
273 				       const enum cp9314_backdoor_keys key)
274 {
275 	const struct regulator_cp9314_config *config = dev->config;
276 	struct regulator_cp9314_data *data = dev->data;
277 	int ret;
278 
279 	if (data->allow_hw_i2c_lock == 0U) {
280 		ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_LION_CFG_3,
281 					     CP9314_ALLOW_HW_I2C_LOCK, CP9314_ALLOW_HW_I2C_LOCK);
282 		if (ret < 0) {
283 			return ret;
284 		}
285 
286 		data->allow_hw_i2c_lock = true;
287 	}
288 
289 	if ((uint8_t)key == data->backdoor_key) {
290 		return 0;
291 	} else {
292 		return i2c_reg_write_byte_dt(&config->i2c, CP9314_REG_BACKDOOR_CTRL, (uint8_t)key);
293 	}
294 }
295 
regulator_cp9314_write_lock_init(const struct device * dev)296 static int regulator_cp9314_write_lock_init(const struct device *dev)
297 {
298 	const struct regulator_cp9314_config *config = dev->config;
299 	struct regulator_cp9314_data *data = dev->data;
300 	uint8_t value;
301 	int ret;
302 
303 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_LION_CFG_3, &value);
304 	if (ret < 0) {
305 		return ret;
306 	}
307 
308 	data->allow_hw_i2c_lock = FIELD_GET(CP9314_ALLOW_HW_I2C_LOCK, value);
309 
310 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_BACKDOOR_CTRL, &data->backdoor_key);
311 	if (ret < 0) {
312 		return ret;
313 	}
314 
315 	return 0;
316 }
317 
regulator_cp9314_disable(const struct device * dev)318 static int regulator_cp9314_disable(const struct device *dev)
319 {
320 	const struct regulator_cp9314_config *config = dev->config;
321 	int ret;
322 
323 	if (config->en_pin.port != NULL) {
324 		return gpio_pin_set_dt(&config->en_pin, 0);
325 	}
326 
327 	if (config->hw_i2c_lock != 0U) {
328 		ret = regulator_cp9314_write_lock(dev, CP9314_BACKDOOR_PUBLIC_KEY);
329 		if (ret < 0) {
330 			return ret;
331 		}
332 
333 		ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CTRL1, CP9314_CP_EN, 0);
334 		if (ret < 0) {
335 			return ret;
336 		}
337 
338 		return regulator_cp9314_write_lock(dev, CP9314_BACKDOOR_LOCKED_KEY);
339 	}
340 
341 	return i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CTRL1, CP9314_CP_EN, 0);
342 }
343 
regulator_cp9314_enable(const struct device * dev)344 static int regulator_cp9314_enable(const struct device *dev)
345 {
346 	const struct regulator_cp9314_config *config = dev->config;
347 	uint8_t value;
348 	int ret;
349 
350 	if (config->hw_i2c_lock != 0U) {
351 		ret = regulator_cp9314_write_lock(dev, CP9314_BACKDOOR_PUBLIC_KEY);
352 		if (ret < 0) {
353 			return ret;
354 		}
355 	}
356 
357 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_CONVERTER, &value);
358 	if (ret < 0) {
359 		return ret;
360 	}
361 
362 	if (value & CP9314_ACTIVE_STS) {
363 		return 0;
364 	}
365 
366 	ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_LION_INT_MASK_2, CP9314_CLEAR_INT,
367 				     CP9314_CLEAR_INT);
368 	if (ret < 0) {
369 		return ret;
370 	}
371 
372 	ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_LION_INT_MASK_2, CP9314_CLEAR_INT, 0);
373 	if (ret < 0) {
374 		return ret;
375 	}
376 
377 	if (config->en_pin.port != NULL) {
378 		ret = gpio_pin_set_dt(&config->en_pin, 1);
379 		if (ret < 0) {
380 			return ret;
381 		}
382 	} else {
383 		ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CTRL1, CP9314_CP_EN,
384 					     CP9314_CP_EN);
385 		if (ret < 0) {
386 			LOG_ERR("Unable to set CP_EN");
387 			return ret;
388 		}
389 	}
390 
391 	k_msleep(CP9314_T_STARTUP_MSEC);
392 
393 	if (config->pgood_pin.port != NULL) {
394 		ret = gpio_pin_get_dt(&config->pgood_pin);
395 		if (ret < 0) {
396 			return ret;
397 		} else if (ret == 0) {
398 			return -EINVAL;
399 		}
400 	} else {
401 		ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_CONVERTER, &value);
402 		if (ret < 0) {
403 			return ret;
404 		} else if (FIELD_GET(CP9314_PGOOD_PIN_STS, value) == 0U) {
405 			return -EINVAL;
406 		}
407 	}
408 
409 	if (config->hw_i2c_lock != 0U) {
410 		ret = regulator_cp9314_write_lock(dev, CP9314_BACKDOOR_LOCKED_KEY);
411 		if (ret < 0) {
412 			return ret;
413 		}
414 	}
415 
416 	return 0;
417 }
418 
cp9314_cfg_sync(const struct device * dev)419 static int cp9314_cfg_sync(const struct device *dev)
420 {
421 	const struct regulator_cp9314_config *config = dev->config;
422 	struct regulator_cp9314_data *data = dev->data;
423 	uint8_t value = 0;
424 	int ret;
425 
426 	if (data->sync_role == CP9314_ROLE_HOST) {
427 		value = CP9314_SYNC_HOST_EN;
428 	}
429 
430 	ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CTRL4, CP9314_SYNC_HOST_EN, value);
431 	if (ret < 0) {
432 		return ret;
433 	}
434 
435 	ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CTRL4, CP9314_SYNC_FUNCTION_EN,
436 				     CP9314_SYNC_FUNCTION_EN);
437 	if (ret < 0) {
438 		return ret;
439 	}
440 
441 	return i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CTRL4, CP9314_FRC_SYNC_MODE,
442 				      CP9314_FRC_SYNC_MODE);
443 }
444 
cp9314_do_soft_reset(const struct device * dev)445 static int cp9314_do_soft_reset(const struct device *dev)
446 {
447 	const struct regulator_cp9314_config *config = dev->config;
448 	int ret;
449 
450 	if (config->hw_i2c_lock != 0U) {
451 		ret = regulator_cp9314_write_lock(dev, CP9314_BACKDOOR_PUBLIC_KEY);
452 		if (ret < 0) {
453 			return ret;
454 		}
455 
456 		ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_LION_CFG_3,
457 					     CP9314_ALLOW_HW_I2C_LOCK, 0);
458 		if (ret < 0) {
459 			return ret;
460 		}
461 	}
462 
463 	ret = i2c_reg_write_byte_dt(&config->i2c, CP9314_REG_CRUS_CTRL, CP9314_CRUS_KEY_SOFT_RESET);
464 	if (ret < 0) {
465 		return ret;
466 	}
467 
468 	ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_TEST_MODE_CTRL, CP9314_SOFT_RESET_REQ,
469 				     CP9314_SOFT_RESET_REQ);
470 	if (ret < 0) {
471 		return ret;
472 	}
473 
474 	k_msleep(CP9314_SOFT_RESET_DELAY_MSEC);
475 
476 	if (config->hw_i2c_lock != 0U) {
477 		ret = regulator_cp9314_write_lock_init(dev);
478 		if (ret < 0) {
479 			return ret;
480 		}
481 	}
482 
483 	return 0;
484 }
485 
regulator_cp9314_otp_init(const struct device * dev)486 static int regulator_cp9314_otp_init(const struct device *dev)
487 {
488 	const struct regulator_cp9314_config *config = dev->config;
489 	uint8_t value;
490 	int i, ret;
491 
492 	/*
493 	 * The PTE_2 field in the PTE_REG_2 register contains the value representing the OTP
494 	 * burned on the CP9314 device. The PTE_2 values in relation to the OTP table names
495 	 * are shown below.
496 	 *
497 	 * OTP-1 = 0x0, OTP-2 = 0x1, OTP-3 = 0x3, OTP-4 = 0x4
498 	 */
499 
500 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_PTE_REG_2, &value);
501 	if (ret < 0) {
502 		return ret;
503 	}
504 
505 	value = FIELD_GET(CP9314_PTE_2_MASK, value);
506 
507 	ret = i2c_reg_write_byte_dt(&config->i2c, CP9314_REG_CRUS_CTRL, CP9314_CRUS_KEY_UNLOCK);
508 	if (ret < 0) {
509 		return ret;
510 	}
511 
512 	if (value == CP9314_PTE_2_OTP_1) {
513 		for (i = 0; i < ARRAY_SIZE(otp_1_patch); i++) {
514 			i2c_reg_update_byte_dt(&config->i2c, otp_1_patch[i].reg_addr,
515 					       otp_1_patch[i].mask, otp_1_patch[i].value);
516 		}
517 	}
518 
519 	if (value <= CP9314_PTE_2_OTP_2) {
520 		i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CFG_9, CP9314_VOUT_PCHG_TIME_CFG_0,
521 				       0);
522 	}
523 
524 	return i2c_reg_write_byte_dt(&config->i2c, CP9314_REG_CRUS_CTRL, CP9314_CRUS_KEY_LOCK);
525 }
526 
regulator_cp9314_init(const struct device * dev)527 static int regulator_cp9314_init(const struct device *dev)
528 {
529 	const struct regulator_cp9314_config *config = dev->config;
530 	struct regulator_cp9314_data *data = dev->data;
531 	uint8_t value;
532 	int ret;
533 
534 	if (!i2c_is_ready_dt(&config->i2c)) {
535 		LOG_ERR("Bus device is not ready");
536 		return -ENODEV;
537 	}
538 
539 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_DEVICE_ID, &value);
540 	if (ret < 0) {
541 		LOG_ERR("No device found:%d\n", ret);
542 		return ret;
543 	}
544 
545 	if (value != CP9314_DEV_ID) {
546 		LOG_ERR("Invalid device ID found:0x%x!\n", value);
547 		return -ENOTSUP;
548 	}
549 
550 	if (config->pgood_pin.port != NULL) {
551 		if (!gpio_is_ready_dt(&config->pgood_pin)) {
552 			return -ENODEV;
553 		}
554 
555 		ret = gpio_pin_configure_dt(&config->pgood_pin, GPIO_INPUT);
556 		if (ret < 0) {
557 			return ret;
558 		}
559 	}
560 
561 	if (config->en_pin.port != NULL) {
562 		if (!gpio_is_ready_dt(&config->en_pin)) {
563 			return -ENODEV;
564 		}
565 
566 		ret = gpio_pin_configure_dt(&config->en_pin, GPIO_OUTPUT_INACTIVE);
567 		if (ret < 0) {
568 			return ret;
569 		}
570 
571 		k_usleep(CP9314_EN_DEBOUNCE_USEC);
572 	}
573 
574 	if (config->hw_i2c_lock != 0U) {
575 		ret = regulator_cp9314_write_lock_init(dev);
576 		if (ret < 0) {
577 			return ret;
578 		}
579 	} else {
580 		data->allow_hw_i2c_lock = 0;
581 	}
582 
583 	ret = cp9314_do_soft_reset(dev);
584 	if (ret < 0) {
585 		return ret;
586 	}
587 
588 	if (data->allow_hw_i2c_lock != 0U) {
589 		ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_LION_CFG_3,
590 					     CP9314_ALLOW_HW_I2C_LOCK, 0x0);
591 		if (ret < 0) {
592 			return ret;
593 		}
594 
595 		data->allow_hw_i2c_lock = false;
596 	}
597 
598 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_BC_STS_C, &value);
599 	if (ret < 0) {
600 		return ret;
601 	}
602 
603 	value = FIELD_GET(CP9314_CHIP_REV_MASK, value);
604 
605 	switch (value) {
606 	case CP9314_CHIP_REV_B1:
607 		break;
608 	default:
609 		LOG_ERR("Invalid CP9314 REV:0x%x\n", value);
610 		return -ENOTSUP;
611 	}
612 
613 	LOG_DBG("Found CP9314 REV:0x%x\n", value);
614 
615 	ret = regulator_cp9314_otp_init(dev);
616 	if (ret < 0) {
617 		return ret;
618 	}
619 
620 	ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CTRL4, CP9314_FRC_OP_MODE,
621 				     CP9314_FRC_OP_MODE);
622 	if (ret < 0) {
623 		return ret;
624 	}
625 
626 	ret = i2c_reg_read_byte_dt(&config->i2c, CP9314_REG_STS_PIN_ADC_0, &value);
627 	if (ret < 0) {
628 		return ret;
629 	}
630 
631 	value = FIELD_PREP(CP9314_STS_ADDR_LVL, value);
632 
633 	switch (value) {
634 	case CP9314_DEVICE_MODE_HOST_4GANG_0x78:
635 	case CP9314_DEVICE_MODE_HOST_4GANG_0x72:
636 	case CP9314_DEVICE_MODE_HOST_3GANG_0x78:
637 	case CP9314_DEVICE_MODE_HOST_3GANG_0x72:
638 	case CP9314_DEVICE_MODE_HOST_2GANG_0x78:
639 	case CP9314_DEVICE_MODE_HOST_2GANG_0x72:
640 		data->sync_role = CP9314_ROLE_HOST;
641 		break;
642 	case CP9314_DEVICE_MODE_HOST_STANDALONE_0x78:
643 	case CP9314_DEVICE_MODE_HOST_STANDALONE_0x72:
644 		data->sync_role = CP9314_ROLE_STANDALONE;
645 		break;
646 	case CP9314_DEVICE_MODE_DEVICE_4_0x68:
647 	case CP9314_DEVICE_MODE_DEVICE_4_0x54:
648 		data->sync_role = CP9314_ROLE_DEV4;
649 		break;
650 	case CP9314_DEVICE_MODE_DEVICE_3_0x56:
651 	case CP9314_DEVICE_MODE_DEVICE_3_0x53:
652 		data->sync_role = CP9314_ROLE_DEV3;
653 		break;
654 	case CP9314_DEVICE_MODE_DEVICE_2_0x79:
655 	case CP9314_DEVICE_MODE_DEVICE_2_0x73:
656 		data->sync_role = CP9314_ROLE_DEV2;
657 		break;
658 	default:
659 		return -EINVAL;
660 	}
661 
662 	if (data->sync_role != CP9314_ROLE_STANDALONE) {
663 		ret = cp9314_cfg_sync(dev);
664 		if (ret < 0) {
665 			return ret;
666 		}
667 	}
668 
669 	if (config->initial_op_mode_idx != 0) {
670 		ret = i2c_reg_update_byte_dt(&config->i2c, CP9314_REG_CTRL4, CP9314_MODE_MASK,
671 					     config->initial_op_mode_idx);
672 		if (ret < 0) {
673 			return ret;
674 		}
675 	}
676 
677 	if (config->hw_i2c_lock != 0U) {
678 		ret = regulator_cp9314_write_lock(dev, CP9314_BACKDOOR_LOCKED_KEY);
679 		if (ret < 0) {
680 			return ret;
681 		}
682 	}
683 
684 	regulator_common_data_init(dev);
685 
686 	return regulator_common_init(dev, false);
687 }
688 
689 static DEVICE_API(regulator, api) = {
690 	.enable = regulator_cp9314_enable,
691 	.disable = regulator_cp9314_disable,
692 	.get_error_flags = regulator_cp9314_get_error_flags,
693 };
694 
695 #define REGULATOR_CP9314_DEFINE(inst)                                                              \
696 	static struct regulator_cp9314_data data_##inst;                                           \
697                                                                                                    \
698 	static const struct regulator_cp9314_config config_##inst = {                              \
699 		.common = REGULATOR_DT_INST_COMMON_CONFIG_INIT(inst),                              \
700 		.i2c = I2C_DT_SPEC_INST_GET(inst),                                                 \
701 		.en_pin = GPIO_DT_SPEC_INST_GET_OR(inst, cirrus_en_gpios, {}),                     \
702 		.pgood_pin = GPIO_DT_SPEC_INST_GET_OR(inst, cirrus_pgood_gpios, {}),               \
703 		.initial_op_mode_idx =                                                             \
704 			DT_INST_ENUM_IDX_OR(inst, cirrus_initial_switched_capacitor_mode, -1) + 1, \
705 		.hw_i2c_lock = DT_INST_PROP(inst, cirrus_hw_i2c_lock),                             \
706 	};                                                                                         \
707                                                                                                    \
708 	DEVICE_DT_INST_DEFINE(inst, regulator_cp9314_init, NULL, &data_##inst, &config_##inst,     \
709 			      POST_KERNEL, CONFIG_REGULATOR_CP9314_INIT_PRIORITY, &api);
710 
711 DT_INST_FOREACH_STATUS_OKAY(REGULATOR_CP9314_DEFINE)
712