@@ -85,6 +85,7 @@ LOG_MODULE_REGISTER(CP9314, CONFIG_REGULATOR_LOG_LEVEL);
85
85
#define CP9314_REG_LION_CFG_3 0x34
86
86
#define CP9314_LB_MIN_FREQ_SEL_0 GENMASK(7, 6)
87
87
#define CP9314_MODE_CTRL_UPDATE_BW_1 GENMASK(5, 3)
88
+ #define CP9314_ALLOW_HW_I2C_LOCK BIT(0)
88
89
89
90
#define CP9314_REG_LB_CTRL 0x38
90
91
#define CP9314_LB1_DELTA_CFG_1 GENMASK(6, 3)
@@ -152,6 +153,8 @@ LOG_MODULE_REGISTER(CP9314, CONFIG_REGULATOR_LOG_LEVEL);
152
153
#define CP9314_PTE_2_OTP_1 0x0
153
154
#define CP9314_PTE_2_OTP_2 0x1
154
155
156
+ #define CP9314_REG_BACKDOOR_CTRL 0x8C
157
+
155
158
#define CP9314_FAULT1_STS 0x9A
156
159
#define CP9314_VIN_OV_STS BIT(4)
157
160
@@ -192,17 +195,25 @@ enum cp9314_sync_roles {
192
195
CP9314_ROLE_STANDALONE ,
193
196
};
194
197
198
+ enum cp9314_backdoor_keys {
199
+ CP9314_BACKDOOR_LOCKED_KEY = 0x0 ,
200
+ CP9314_BACKDOOR_PUBLIC_KEY = 0x0F ,
201
+ };
202
+
195
203
struct regulator_cp9314_config {
196
204
struct regulator_common_config common ;
197
205
struct i2c_dt_spec i2c ;
198
206
struct gpio_dt_spec en_pin ;
199
207
struct gpio_dt_spec pgood_pin ;
200
208
uint8_t initial_op_mode_idx ;
209
+ bool hw_i2c_lock ;
201
210
};
202
211
203
212
struct regulator_cp9314_data {
204
213
struct regulator_common_data data ;
205
214
enum cp9314_sync_roles sync_role ;
215
+ uint8_t backdoor_key ;
216
+ bool allow_hw_i2c_lock ;
206
217
};
207
218
208
219
struct cp9314_reg_patch {
@@ -284,14 +295,75 @@ static int regulator_cp9314_get_error_flags(const struct device *dev,
284
295
return 0 ;
285
296
}
286
297
298
+ static int regulator_cp9314_write_lock (const struct device * dev ,
299
+ const enum cp9314_backdoor_keys key )
300
+ {
301
+ const struct regulator_cp9314_config * config = dev -> config ;
302
+ struct regulator_cp9314_data * data = dev -> data ;
303
+ int ret ;
304
+
305
+ if (data -> allow_hw_i2c_lock == 0U ) {
306
+ ret = i2c_reg_update_byte_dt (& config -> i2c , CP9314_REG_LION_CFG_3 ,
307
+ CP9314_ALLOW_HW_I2C_LOCK , CP9314_ALLOW_HW_I2C_LOCK );
308
+ if (ret < 0 ) {
309
+ return ret ;
310
+ }
311
+
312
+ data -> allow_hw_i2c_lock = true;
313
+ }
314
+
315
+ if ((uint8_t )key == data -> backdoor_key ) {
316
+ return 0 ;
317
+ } else {
318
+ return i2c_reg_write_byte_dt (& config -> i2c , CP9314_REG_BACKDOOR_CTRL , (uint8_t )key );
319
+ }
320
+ }
321
+
322
+ static int regulator_cp9314_write_lock_init (const struct device * dev )
323
+ {
324
+ const struct regulator_cp9314_config * config = dev -> config ;
325
+ struct regulator_cp9314_data * data = dev -> data ;
326
+ uint8_t value ;
327
+ int ret ;
328
+
329
+ ret = i2c_reg_read_byte_dt (& config -> i2c , CP9314_REG_LION_CFG_3 , & value );
330
+ if (ret < 0 ) {
331
+ return ret ;
332
+ }
333
+
334
+ data -> allow_hw_i2c_lock = FIELD_GET (CP9314_ALLOW_HW_I2C_LOCK , value );
335
+
336
+ ret = i2c_reg_read_byte_dt (& config -> i2c , CP9314_REG_BACKDOOR_CTRL , & data -> backdoor_key );
337
+ if (ret < 0 ) {
338
+ return ret ;
339
+ }
340
+
341
+ return 0 ;
342
+ }
343
+
287
344
static int regulator_cp9314_disable (const struct device * dev )
288
345
{
289
346
const struct regulator_cp9314_config * config = dev -> config ;
347
+ int ret ;
290
348
291
349
if (config -> en_pin .port != NULL ) {
292
350
return gpio_pin_set_dt (& config -> en_pin , 0 );
293
351
}
294
352
353
+ if (config -> hw_i2c_lock != 0U ) {
354
+ ret = regulator_cp9314_write_lock (dev , CP9314_BACKDOOR_PUBLIC_KEY );
355
+ if (ret < 0 ) {
356
+ return ret ;
357
+ }
358
+
359
+ ret = i2c_reg_update_byte_dt (& config -> i2c , CP9314_REG_CTRL1 , CP9314_CP_EN , 0 );
360
+ if (ret < 0 ) {
361
+ return ret ;
362
+ }
363
+
364
+ return regulator_cp9314_write_lock (dev , CP9314_BACKDOOR_LOCKED_KEY );
365
+ }
366
+
295
367
return i2c_reg_update_byte_dt (& config -> i2c , CP9314_REG_CTRL1 , CP9314_CP_EN , 0 );
296
368
}
297
369
@@ -301,6 +373,13 @@ static int regulator_cp9314_enable(const struct device *dev)
301
373
uint8_t value ;
302
374
int ret ;
303
375
376
+ if (config -> hw_i2c_lock != 0U ) {
377
+ ret = regulator_cp9314_write_lock (dev , CP9314_BACKDOOR_PUBLIC_KEY );
378
+ if (ret < 0 ) {
379
+ return ret ;
380
+ }
381
+ }
382
+
304
383
ret = i2c_reg_read_byte_dt (& config -> i2c , CP9314_REG_CONVERTER , & value );
305
384
if (ret < 0 ) {
306
385
return ret ;
@@ -353,6 +432,13 @@ static int regulator_cp9314_enable(const struct device *dev)
353
432
}
354
433
}
355
434
435
+ if (config -> hw_i2c_lock != 0U ) {
436
+ ret = regulator_cp9314_write_lock (dev , CP9314_BACKDOOR_LOCKED_KEY );
437
+ if (ret < 0 ) {
438
+ return ret ;
439
+ }
440
+ }
441
+
356
442
return 0 ;
357
443
}
358
444
@@ -403,6 +489,19 @@ static int cp9314_do_soft_reset(const struct device *dev)
403
489
const struct regulator_cp9314_config * config = dev -> config ;
404
490
int ret ;
405
491
492
+ if (config -> hw_i2c_lock != 0U ) {
493
+ ret = regulator_cp9314_write_lock (dev , CP9314_BACKDOOR_PUBLIC_KEY );
494
+ if (ret < 0 ) {
495
+ return ret ;
496
+ }
497
+
498
+ ret = i2c_reg_update_byte_dt (& config -> i2c , CP9314_REG_LION_CFG_3 ,
499
+ CP9314_ALLOW_HW_I2C_LOCK , 0 );
500
+ if (ret < 0 ) {
501
+ return ret ;
502
+ }
503
+ }
504
+
406
505
ret = i2c_reg_write_byte_dt (& config -> i2c , CP9314_REG_CRUS_CTRL , CP9314_CRUS_KEY_SOFT_RESET );
407
506
if (ret < 0 ) {
408
507
return ret ;
@@ -416,6 +515,13 @@ static int cp9314_do_soft_reset(const struct device *dev)
416
515
417
516
k_msleep (CP9314_SOFT_RESET_DELAY_MSEC );
418
517
518
+ if (config -> hw_i2c_lock != 0U ) {
519
+ ret = regulator_cp9314_write_lock_init (dev );
520
+ if (ret < 0 ) {
521
+ return ret ;
522
+ }
523
+ }
524
+
419
525
return 0 ;
420
526
}
421
527
@@ -507,11 +613,30 @@ static int regulator_cp9314_init(const struct device *dev)
507
613
k_usleep (CP9314_EN_DEBOUNCE_USEC );
508
614
}
509
615
616
+ if (config -> hw_i2c_lock != 0U ) {
617
+ ret = regulator_cp9314_write_lock_init (dev );
618
+ if (ret < 0 ) {
619
+ return ret ;
620
+ }
621
+ } else {
622
+ data -> allow_hw_i2c_lock = 0 ;
623
+ }
624
+
510
625
ret = cp9314_do_soft_reset (dev );
511
626
if (ret < 0 ) {
512
627
return ret ;
513
628
}
514
629
630
+ if (data -> allow_hw_i2c_lock != 0U ) {
631
+ ret = i2c_reg_update_byte_dt (& config -> i2c , CP9314_REG_LION_CFG_3 ,
632
+ CP9314_ALLOW_HW_I2C_LOCK , 0x0 );
633
+ if (ret < 0 ) {
634
+ return ret ;
635
+ }
636
+
637
+ data -> allow_hw_i2c_lock = false;
638
+ }
639
+
515
640
ret = i2c_reg_read_byte_dt (& config -> i2c , CP9314_REG_BC_STS_C , & value );
516
641
if (ret < 0 ) {
517
642
return ret ;
@@ -597,6 +722,13 @@ static int regulator_cp9314_init(const struct device *dev)
597
722
}
598
723
}
599
724
725
+ if (config -> hw_i2c_lock != 0U ) {
726
+ ret = regulator_cp9314_write_lock (dev , CP9314_BACKDOOR_LOCKED_KEY );
727
+ if (ret < 0 ) {
728
+ return ret ;
729
+ }
730
+ }
731
+
600
732
regulator_common_data_init (dev );
601
733
602
734
return regulator_common_init (dev , false);
@@ -618,6 +750,7 @@ static const struct regulator_driver_api api = {
618
750
.pgood_pin = GPIO_DT_SPEC_INST_GET_OR(inst, cirrus_pgood_gpios, {}), \
619
751
.initial_op_mode_idx = \
620
752
DT_INST_ENUM_IDX_OR(inst, cirrus_initial_switched_capacitor_mode, -1) + 1, \
753
+ .hw_i2c_lock = DT_INST_PROP(inst, cirrus_hw_i2c_lock), \
621
754
}; \
622
755
\
623
756
DEVICE_DT_INST_DEFINE(inst, regulator_cp9314_init, NULL, &data_##inst, &config_##inst, \
0 commit comments