hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/power/supply/cros_usbpd-charger.c
....@@ -6,14 +6,19 @@
66 */
77
88 #include <linux/module.h>
9
-#include <linux/mfd/cros_ec.h>
10
-#include <linux/mfd/cros_ec_commands.h>
9
+#include <linux/platform_data/cros_ec_commands.h>
10
+#include <linux/platform_data/cros_ec_proto.h>
11
+#include <linux/platform_data/cros_usbpd_notify.h>
1112 #include <linux/platform_device.h>
1213 #include <linux/power_supply.h>
1314 #include <linux/slab.h>
1415
15
-#define CHARGER_DIR_NAME "CROS_USBPD_CHARGER%d"
16
-#define CHARGER_DIR_NAME_LENGTH sizeof(CHARGER_DIR_NAME)
16
+#define CHARGER_USBPD_DIR_NAME "CROS_USBPD_CHARGER%d"
17
+#define CHARGER_DEDICATED_DIR_NAME "CROS_DEDICATED_CHARGER"
18
+#define CHARGER_DIR_NAME_LENGTH (sizeof(CHARGER_USBPD_DIR_NAME) >= \
19
+ sizeof(CHARGER_DEDICATED_DIR_NAME) ? \
20
+ sizeof(CHARGER_USBPD_DIR_NAME) : \
21
+ sizeof(CHARGER_DEDICATED_DIR_NAME))
1722 #define CHARGER_CACHE_UPDATE_DELAY msecs_to_jiffies(500)
1823 #define CHARGER_MANUFACTURER_MODEL_LENGTH 32
1924
....@@ -42,12 +47,15 @@
4247 struct cros_ec_dev *ec_dev;
4348 struct cros_ec_device *ec_device;
4449 int num_charger_ports;
50
+ int num_usbpd_ports;
4551 int num_registered_psy;
4652 struct port_data *ports[EC_USB_PD_MAX_PORTS];
4753 struct notifier_block notifier;
4854 };
4955
5056 static enum power_supply_property cros_usbpd_charger_props[] = {
57
+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
58
+ POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT,
5159 POWER_SUPPLY_PROP_ONLINE,
5260 POWER_SUPPLY_PROP_STATUS,
5361 POWER_SUPPLY_PROP_CURRENT_MAX,
....@@ -56,6 +64,12 @@
5664 POWER_SUPPLY_PROP_MODEL_NAME,
5765 POWER_SUPPLY_PROP_MANUFACTURER,
5866 POWER_SUPPLY_PROP_USB_TYPE
67
+};
68
+
69
+static enum power_supply_property cros_usbpd_dedicated_charger_props[] = {
70
+ POWER_SUPPLY_PROP_ONLINE,
71
+ POWER_SUPPLY_PROP_STATUS,
72
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
5973 };
6074
6175 static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = {
....@@ -68,6 +82,15 @@
6882 POWER_SUPPLY_USB_TYPE_PD_DRP,
6983 POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID
7084 };
85
+
86
+/* Input voltage/current limit in mV/mA. Default to none. */
87
+static u16 input_voltage_limit = EC_POWER_LIMIT_NONE;
88
+static u16 input_current_limit = EC_POWER_LIMIT_NONE;
89
+
90
+static bool cros_usbpd_charger_port_is_dedicated(struct port_data *port)
91
+{
92
+ return port->port_number >= port->charger->num_usbpd_ports;
93
+}
7194
7295 static int cros_usbpd_charger_ec_command(struct charger_data *charger,
7396 unsigned int version,
....@@ -103,16 +126,27 @@
103126
104127 static int cros_usbpd_charger_get_num_ports(struct charger_data *charger)
105128 {
129
+ struct ec_response_charge_port_count resp;
130
+ int ret;
131
+
132
+ ret = cros_usbpd_charger_ec_command(charger, 0,
133
+ EC_CMD_CHARGE_PORT_COUNT,
134
+ NULL, 0, &resp, sizeof(resp));
135
+ if (ret < 0)
136
+ return ret;
137
+
138
+ return resp.port_count;
139
+}
140
+
141
+static int cros_usbpd_charger_get_usbpd_num_ports(struct charger_data *charger)
142
+{
106143 struct ec_response_usb_pd_ports resp;
107144 int ret;
108145
109146 ret = cros_usbpd_charger_ec_command(charger, 0, EC_CMD_USB_PD_PORTS,
110147 NULL, 0, &resp, sizeof(resp));
111
- if (ret < 0) {
112
- dev_err(charger->dev,
113
- "Unable to get the number or ports (err:0x%x)\n", ret);
148
+ if (ret < 0)
114149 return ret;
115
- }
116150
117151 return resp.num_ports;
118152 }
....@@ -246,7 +280,10 @@
246280 port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
247281 }
248282
249
- port->psy_desc.type = POWER_SUPPLY_TYPE_USB;
283
+ if (cros_usbpd_charger_port_is_dedicated(port))
284
+ port->psy_desc.type = POWER_SUPPLY_TYPE_MAINS;
285
+ else
286
+ port->psy_desc.type = POWER_SUPPLY_TYPE_USB;
250287
251288 dev_dbg(dev,
252289 "Port %d: type=%d vmax=%d vnow=%d cmax=%d clim=%d pmax=%d\n",
....@@ -281,8 +318,29 @@
281318 if (ret < 0)
282319 return ret;
283320
284
- ret = cros_usbpd_charger_get_discovery_info(port);
321
+ if (!cros_usbpd_charger_port_is_dedicated(port))
322
+ ret = cros_usbpd_charger_get_discovery_info(port);
285323 port->last_update = jiffies;
324
+
325
+ return ret;
326
+}
327
+
328
+static int cros_usbpd_charger_set_ext_power_limit(struct charger_data *charger,
329
+ u16 current_lim,
330
+ u16 voltage_lim)
331
+{
332
+ struct ec_params_external_power_limit_v1 req;
333
+ int ret;
334
+
335
+ req.current_lim = current_lim;
336
+ req.voltage_lim = voltage_lim;
337
+
338
+ ret = cros_usbpd_charger_ec_command(charger, 0,
339
+ EC_CMD_EXTERNAL_POWER_LIMIT,
340
+ &req, sizeof(req), NULL, 0);
341
+ if (ret < 0)
342
+ dev_err(charger->dev,
343
+ "Unable to set the 'External Power Limit': %d\n", ret);
286344
287345 return ret;
288346 }
....@@ -325,7 +383,7 @@
325383 */
326384 if (ec_device->mkbp_event_supported || port->psy_online)
327385 break;
328
- /* fall through */
386
+ fallthrough;
329387 case POWER_SUPPLY_PROP_CURRENT_MAX:
330388 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
331389 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
....@@ -359,6 +417,18 @@
359417 case POWER_SUPPLY_PROP_USB_TYPE:
360418 val->intval = port->psy_usb_type;
361419 break;
420
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
421
+ if (input_current_limit == EC_POWER_LIMIT_NONE)
422
+ val->intval = -1;
423
+ else
424
+ val->intval = input_current_limit * 1000;
425
+ break;
426
+ case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
427
+ if (input_voltage_limit == EC_POWER_LIMIT_NONE)
428
+ val->intval = -1;
429
+ else
430
+ val->intval = input_voltage_limit * 1000;
431
+ break;
362432 case POWER_SUPPLY_PROP_MODEL_NAME:
363433 val->strval = port->model_name;
364434 break;
....@@ -372,35 +442,97 @@
372442 return 0;
373443 }
374444
445
+static int cros_usbpd_charger_set_prop(struct power_supply *psy,
446
+ enum power_supply_property psp,
447
+ const union power_supply_propval *val)
448
+{
449
+ struct port_data *port = power_supply_get_drvdata(psy);
450
+ struct charger_data *charger = port->charger;
451
+ struct device *dev = charger->dev;
452
+ u16 intval;
453
+ int ret;
454
+
455
+ /* U16_MAX in mV/mA is the maximum supported value */
456
+ if (val->intval >= U16_MAX * 1000)
457
+ return -EINVAL;
458
+ /* A negative number is used to clear the limit */
459
+ if (val->intval < 0)
460
+ intval = EC_POWER_LIMIT_NONE;
461
+ else /* Convert from uA/uV to mA/mV */
462
+ intval = val->intval / 1000;
463
+
464
+ switch (psp) {
465
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
466
+ ret = cros_usbpd_charger_set_ext_power_limit(charger, intval,
467
+ input_voltage_limit);
468
+ if (ret < 0)
469
+ break;
470
+
471
+ input_current_limit = intval;
472
+ if (input_current_limit == EC_POWER_LIMIT_NONE)
473
+ dev_info(dev,
474
+ "External Current Limit cleared for all ports\n");
475
+ else
476
+ dev_info(dev,
477
+ "External Current Limit set to %dmA for all ports\n",
478
+ input_current_limit);
479
+ break;
480
+ case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
481
+ ret = cros_usbpd_charger_set_ext_power_limit(charger,
482
+ input_current_limit,
483
+ intval);
484
+ if (ret < 0)
485
+ break;
486
+
487
+ input_voltage_limit = intval;
488
+ if (input_voltage_limit == EC_POWER_LIMIT_NONE)
489
+ dev_info(dev,
490
+ "External Voltage Limit cleared for all ports\n");
491
+ else
492
+ dev_info(dev,
493
+ "External Voltage Limit set to %dmV for all ports\n",
494
+ input_voltage_limit);
495
+ break;
496
+ default:
497
+ ret = -EINVAL;
498
+ }
499
+
500
+ return ret;
501
+}
502
+
503
+static int cros_usbpd_charger_property_is_writeable(struct power_supply *psy,
504
+ enum power_supply_property psp)
505
+{
506
+ int ret;
507
+
508
+ switch (psp) {
509
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
510
+ case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
511
+ ret = 1;
512
+ break;
513
+ default:
514
+ ret = 0;
515
+ }
516
+
517
+ return ret;
518
+}
519
+
375520 static int cros_usbpd_charger_ec_event(struct notifier_block *nb,
376
- unsigned long queued_during_suspend,
521
+ unsigned long host_event,
377522 void *_notify)
378523 {
379
- struct cros_ec_device *ec_device;
380
- struct charger_data *charger;
381
- struct device *dev;
382
- u32 host_event;
524
+ struct charger_data *charger = container_of(nb, struct charger_data,
525
+ notifier);
383526
384
- charger = container_of(nb, struct charger_data, notifier);
385
- ec_device = charger->ec_device;
386
- dev = charger->dev;
387
-
388
- host_event = cros_ec_get_host_event(ec_device);
389
- if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU)) {
390
- cros_usbpd_charger_power_changed(charger->ports[0]->psy);
391
- return NOTIFY_OK;
392
- } else {
393
- return NOTIFY_DONE;
394
- }
527
+ cros_usbpd_charger_power_changed(charger->ports[0]->psy);
528
+ return NOTIFY_OK;
395529 }
396530
397531 static void cros_usbpd_charger_unregister_notifier(void *data)
398532 {
399533 struct charger_data *charger = data;
400
- struct cros_ec_device *ec_device = charger->ec_device;
401534
402
- blocking_notifier_chain_unregister(&ec_device->event_notifier,
403
- &charger->notifier);
535
+ cros_usbpd_unregister_notify(&charger->notifier);
404536 }
405537
406538 static int cros_usbpd_charger_probe(struct platform_device *pd)
....@@ -426,14 +558,53 @@
426558
427559 platform_set_drvdata(pd, charger);
428560
429
- charger->num_charger_ports = cros_usbpd_charger_get_num_ports(charger);
430
- if (charger->num_charger_ports <= 0) {
561
+ /*
562
+ * We need to know the number of USB PD ports in order to know whether
563
+ * there is a dedicated port. The dedicated port will always be
564
+ * after the USB PD ports, and there should be only one.
565
+ */
566
+ charger->num_usbpd_ports =
567
+ cros_usbpd_charger_get_usbpd_num_ports(charger);
568
+ if (charger->num_usbpd_ports <= 0) {
431569 /*
432570 * This can happen on a system that doesn't support USB PD.
433571 * Log a message, but no need to warn.
434572 */
573
+ dev_info(dev, "No USB PD charging ports found\n");
574
+ }
575
+
576
+ charger->num_charger_ports = cros_usbpd_charger_get_num_ports(charger);
577
+ if (charger->num_charger_ports < 0) {
578
+ /*
579
+ * This can happen on a system that doesn't support USB PD.
580
+ * Log a message, but no need to warn.
581
+ * Older ECs do not support the above command, in that case
582
+ * let's set up the number of charger ports equal to the number
583
+ * of USB PD ports
584
+ */
585
+ dev_info(dev, "Could not get charger port count\n");
586
+ charger->num_charger_ports = charger->num_usbpd_ports;
587
+ }
588
+
589
+ if (charger->num_charger_ports <= 0) {
590
+ /*
591
+ * This can happen on a system that doesn't support USB PD and
592
+ * doesn't have a dedicated port.
593
+ * Log a message, but no need to warn.
594
+ */
435595 dev_info(dev, "No charging ports found\n");
436596 ret = -ENODEV;
597
+ goto fail_nowarn;
598
+ }
599
+
600
+ /*
601
+ * Sanity checks on the number of ports:
602
+ * there should be at most 1 dedicated port
603
+ */
604
+ if (charger->num_charger_ports < charger->num_usbpd_ports ||
605
+ charger->num_charger_ports > (charger->num_usbpd_ports + 1)) {
606
+ dev_err(dev, "Unexpected number of charge port count\n");
607
+ ret = -EPROTO;
437608 goto fail_nowarn;
438609 }
439610
....@@ -448,21 +619,35 @@
448619
449620 port->charger = charger;
450621 port->port_number = i;
451
- sprintf(port->name, CHARGER_DIR_NAME, i);
452622
453623 psy_desc = &port->psy_desc;
454
- psy_desc->name = port->name;
455
- psy_desc->type = POWER_SUPPLY_TYPE_USB;
456624 psy_desc->get_property = cros_usbpd_charger_get_prop;
625
+ psy_desc->set_property = cros_usbpd_charger_set_prop;
626
+ psy_desc->property_is_writeable =
627
+ cros_usbpd_charger_property_is_writeable;
457628 psy_desc->external_power_changed =
458629 cros_usbpd_charger_power_changed;
459
- psy_desc->properties = cros_usbpd_charger_props;
460
- psy_desc->num_properties =
461
- ARRAY_SIZE(cros_usbpd_charger_props);
462
- psy_desc->usb_types = cros_usbpd_charger_usb_types;
463
- psy_desc->num_usb_types =
464
- ARRAY_SIZE(cros_usbpd_charger_usb_types);
465630 psy_cfg.drv_data = port;
631
+
632
+ if (cros_usbpd_charger_port_is_dedicated(port)) {
633
+ sprintf(port->name, CHARGER_DEDICATED_DIR_NAME);
634
+ psy_desc->type = POWER_SUPPLY_TYPE_MAINS;
635
+ psy_desc->properties =
636
+ cros_usbpd_dedicated_charger_props;
637
+ psy_desc->num_properties =
638
+ ARRAY_SIZE(cros_usbpd_dedicated_charger_props);
639
+ } else {
640
+ sprintf(port->name, CHARGER_USBPD_DIR_NAME, i);
641
+ psy_desc->type = POWER_SUPPLY_TYPE_USB;
642
+ psy_desc->properties = cros_usbpd_charger_props;
643
+ psy_desc->num_properties =
644
+ ARRAY_SIZE(cros_usbpd_charger_props);
645
+ psy_desc->usb_types = cros_usbpd_charger_usb_types;
646
+ psy_desc->num_usb_types =
647
+ ARRAY_SIZE(cros_usbpd_charger_usb_types);
648
+ }
649
+
650
+ psy_desc->name = port->name;
466651
467652 psy = devm_power_supply_register_no_ws(dev, psy_desc,
468653 &psy_cfg);
....@@ -481,21 +666,17 @@
481666 goto fail;
482667 }
483668
484
- if (ec_device->mkbp_event_supported) {
485
- /* Get PD events from the EC */
486
- charger->notifier.notifier_call = cros_usbpd_charger_ec_event;
487
- ret = blocking_notifier_chain_register(
488
- &ec_device->event_notifier,
489
- &charger->notifier);
490
- if (ret < 0) {
491
- dev_warn(dev, "failed to register notifier\n");
492
- } else {
493
- ret = devm_add_action_or_reset(dev,
494
- cros_usbpd_charger_unregister_notifier,
495
- charger);
496
- if (ret < 0)
497
- goto fail;
498
- }
669
+ /* Get PD events from the EC */
670
+ charger->notifier.notifier_call = cros_usbpd_charger_ec_event;
671
+ ret = cros_usbpd_register_notify(&charger->notifier);
672
+ if (ret < 0) {
673
+ dev_warn(dev, "failed to register notifier\n");
674
+ } else {
675
+ ret = devm_add_action_or_reset(dev,
676
+ cros_usbpd_charger_unregister_notifier,
677
+ charger);
678
+ if (ret < 0)
679
+ goto fail;
499680 }
500681
501682 return 0;