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