aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Reichel <sebastian.reichel@collabora.com>2018-09-16 07:10:37 -0400
committerSebastian Reichel <sebastian.reichel@collabora.com>2018-09-16 07:10:37 -0400
commit782853cf9b1bd349ed726390a6fbe40f745931b7 (patch)
tree19a0d88136ab6a06e0e85a7f1d1020b0a9726c48
parent2e04dd441a2ecc049505b2cbfabc355a48115b59 (diff)
parent3af15cfacd1eef7f223802d49a88cae23c509183 (diff)
Merge tag 'psy-mfd-cros-immutable-for-v4.20-signed' into psy-next
Immutable branch for mfd and power-supply for v4.20 Immutable branch between mfd and power-supply for driver changes in CROS USBPD charger driver. Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-rw-r--r--drivers/power/supply/cros_usbpd-charger.c115
-rw-r--r--include/linux/mfd/cros_ec_commands.h10
2 files changed, 111 insertions, 14 deletions
diff --git a/drivers/power/supply/cros_usbpd-charger.c b/drivers/power/supply/cros_usbpd-charger.c
index f2b8de502b82..7e9c3984ef6a 100644
--- a/drivers/power/supply/cros_usbpd-charger.c
+++ b/drivers/power/supply/cros_usbpd-charger.c
@@ -12,8 +12,12 @@
12#include <linux/power_supply.h> 12#include <linux/power_supply.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14 14
15#define CHARGER_DIR_NAME "CROS_USBPD_CHARGER%d" 15#define CHARGER_USBPD_DIR_NAME "CROS_USBPD_CHARGER%d"
16#define CHARGER_DIR_NAME_LENGTH sizeof(CHARGER_DIR_NAME) 16#define CHARGER_DEDICATED_DIR_NAME "CROS_DEDICATED_CHARGER"
17#define CHARGER_DIR_NAME_LENGTH (sizeof(CHARGER_USBPD_DIR_NAME) >= \
18 sizeof(CHARGER_DEDICATED_DIR_NAME) ? \
19 sizeof(CHARGER_USBPD_DIR_NAME) : \
20 sizeof(CHARGER_DEDICATED_DIR_NAME))
17#define CHARGER_CACHE_UPDATE_DELAY msecs_to_jiffies(500) 21#define CHARGER_CACHE_UPDATE_DELAY msecs_to_jiffies(500)
18#define CHARGER_MANUFACTURER_MODEL_LENGTH 32 22#define CHARGER_MANUFACTURER_MODEL_LENGTH 32
19 23
@@ -42,6 +46,7 @@ struct charger_data {
42 struct cros_ec_dev *ec_dev; 46 struct cros_ec_dev *ec_dev;
43 struct cros_ec_device *ec_device; 47 struct cros_ec_device *ec_device;
44 int num_charger_ports; 48 int num_charger_ports;
49 int num_usbpd_ports;
45 int num_registered_psy; 50 int num_registered_psy;
46 struct port_data *ports[EC_USB_PD_MAX_PORTS]; 51 struct port_data *ports[EC_USB_PD_MAX_PORTS];
47 struct notifier_block notifier; 52 struct notifier_block notifier;
@@ -58,6 +63,12 @@ static enum power_supply_property cros_usbpd_charger_props[] = {
58 POWER_SUPPLY_PROP_USB_TYPE 63 POWER_SUPPLY_PROP_USB_TYPE
59}; 64};
60 65
66static enum power_supply_property cros_usbpd_dedicated_charger_props[] = {
67 POWER_SUPPLY_PROP_ONLINE,
68 POWER_SUPPLY_PROP_STATUS,
69 POWER_SUPPLY_PROP_VOLTAGE_NOW,
70};
71
61static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = { 72static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = {
62 POWER_SUPPLY_USB_TYPE_UNKNOWN, 73 POWER_SUPPLY_USB_TYPE_UNKNOWN,
63 POWER_SUPPLY_USB_TYPE_SDP, 74 POWER_SUPPLY_USB_TYPE_SDP,
@@ -69,6 +80,11 @@ static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = {
69 POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID 80 POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID
70}; 81};
71 82
83static bool cros_usbpd_charger_port_is_dedicated(struct port_data *port)
84{
85 return port->port_number >= port->charger->num_usbpd_ports;
86}
87
72static int cros_usbpd_charger_ec_command(struct charger_data *charger, 88static int cros_usbpd_charger_ec_command(struct charger_data *charger,
73 unsigned int version, 89 unsigned int version,
74 unsigned int command, 90 unsigned int command,
@@ -103,6 +119,23 @@ static int cros_usbpd_charger_ec_command(struct charger_data *charger,
103 119
104static int cros_usbpd_charger_get_num_ports(struct charger_data *charger) 120static int cros_usbpd_charger_get_num_ports(struct charger_data *charger)
105{ 121{
122 struct ec_response_charge_port_count resp;
123 int ret;
124
125 ret = cros_usbpd_charger_ec_command(charger, 0,
126 EC_CMD_CHARGE_PORT_COUNT,
127 NULL, 0, &resp, sizeof(resp));
128 if (ret < 0) {
129 dev_err(charger->dev,
130 "Unable to get the number of ports (err:0x%x)\n", ret);
131 return ret;
132 }
133
134 return resp.port_count;
135}
136
137static int cros_usbpd_charger_get_usbpd_num_ports(struct charger_data *charger)
138{
106 struct ec_response_usb_pd_ports resp; 139 struct ec_response_usb_pd_ports resp;
107 int ret; 140 int ret;
108 141
@@ -246,7 +279,10 @@ static int cros_usbpd_charger_get_power_info(struct port_data *port)
246 port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP; 279 port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
247 } 280 }
248 281
249 port->psy_desc.type = POWER_SUPPLY_TYPE_USB; 282 if (cros_usbpd_charger_port_is_dedicated(port))
283 port->psy_desc.type = POWER_SUPPLY_TYPE_MAINS;
284 else
285 port->psy_desc.type = POWER_SUPPLY_TYPE_USB;
250 286
251 dev_dbg(dev, 287 dev_dbg(dev,
252 "Port %d: type=%d vmax=%d vnow=%d cmax=%d clim=%d pmax=%d\n", 288 "Port %d: type=%d vmax=%d vnow=%d cmax=%d clim=%d pmax=%d\n",
@@ -281,7 +317,8 @@ static int cros_usbpd_charger_get_port_status(struct port_data *port,
281 if (ret < 0) 317 if (ret < 0)
282 return ret; 318 return ret;
283 319
284 ret = cros_usbpd_charger_get_discovery_info(port); 320 if (!cros_usbpd_charger_port_is_dedicated(port))
321 ret = cros_usbpd_charger_get_discovery_info(port);
285 port->last_update = jiffies; 322 port->last_update = jiffies;
286 323
287 return ret; 324 return ret;
@@ -424,17 +461,56 @@ static int cros_usbpd_charger_probe(struct platform_device *pd)
424 461
425 platform_set_drvdata(pd, charger); 462 platform_set_drvdata(pd, charger);
426 463
464 /*
465 * We need to know the number of USB PD ports in order to know whether
466 * there is a dedicated port. The dedicated port will always be
467 * after the USB PD ports, and there should be only one.
468 */
469 charger->num_usbpd_ports =
470 cros_usbpd_charger_get_usbpd_num_ports(charger);
471 if (charger->num_usbpd_ports <= 0) {
472 /*
473 * This can happen on a system that doesn't support USB PD.
474 * Log a message, but no need to warn.
475 */
476 dev_info(dev, "No USB PD charging ports found\n");
477 }
478
427 charger->num_charger_ports = cros_usbpd_charger_get_num_ports(charger); 479 charger->num_charger_ports = cros_usbpd_charger_get_num_ports(charger);
428 if (charger->num_charger_ports <= 0) { 480 if (charger->num_charger_ports < 0) {
429 /* 481 /*
430 * This can happen on a system that doesn't support USB PD. 482 * This can happen on a system that doesn't support USB PD.
431 * Log a message, but no need to warn. 483 * Log a message, but no need to warn.
484 * Older ECs do not support the above command, in that case
485 * let's set up the number of charger ports equal to the number
486 * of USB PD ports
487 */
488 dev_info(dev, "Could not get charger port count\n");
489 charger->num_charger_ports = charger->num_usbpd_ports;
490 }
491
492 if (charger->num_charger_ports <= 0) {
493 /*
494 * This can happen on a system that doesn't support USB PD and
495 * doesn't have a dedicated port.
496 * Log a message, but no need to warn.
432 */ 497 */
433 dev_info(dev, "No charging ports found\n"); 498 dev_info(dev, "No charging ports found\n");
434 ret = -ENODEV; 499 ret = -ENODEV;
435 goto fail_nowarn; 500 goto fail_nowarn;
436 } 501 }
437 502
503 /*
504 * Sanity checks on the number of ports:
505 * there should be at most 1 dedicated port
506 */
507 if (charger->num_charger_ports < charger->num_usbpd_ports ||
508 charger->num_charger_ports > (charger->num_usbpd_ports + 1)) {
509 dev_err(dev, "Unexpected number of charge port count\n");
510 ret = -EPROTO;
511 goto fail_nowarn;
512 }
513
438 for (i = 0; i < charger->num_charger_ports; i++) { 514 for (i = 0; i < charger->num_charger_ports; i++) {
439 struct power_supply_config psy_cfg = {}; 515 struct power_supply_config psy_cfg = {};
440 516
@@ -446,22 +522,33 @@ static int cros_usbpd_charger_probe(struct platform_device *pd)
446 522
447 port->charger = charger; 523 port->charger = charger;
448 port->port_number = i; 524 port->port_number = i;
449 sprintf(port->name, CHARGER_DIR_NAME, i);
450 525
451 psy_desc = &port->psy_desc; 526 psy_desc = &port->psy_desc;
452 psy_desc->name = port->name;
453 psy_desc->type = POWER_SUPPLY_TYPE_USB;
454 psy_desc->get_property = cros_usbpd_charger_get_prop; 527 psy_desc->get_property = cros_usbpd_charger_get_prop;
455 psy_desc->external_power_changed = 528 psy_desc->external_power_changed =
456 cros_usbpd_charger_power_changed; 529 cros_usbpd_charger_power_changed;
457 psy_desc->properties = cros_usbpd_charger_props;
458 psy_desc->num_properties =
459 ARRAY_SIZE(cros_usbpd_charger_props);
460 psy_desc->usb_types = cros_usbpd_charger_usb_types;
461 psy_desc->num_usb_types =
462 ARRAY_SIZE(cros_usbpd_charger_usb_types);
463 psy_cfg.drv_data = port; 530 psy_cfg.drv_data = port;
464 531
532 if (cros_usbpd_charger_port_is_dedicated(port)) {
533 sprintf(port->name, CHARGER_DEDICATED_DIR_NAME);
534 psy_desc->type = POWER_SUPPLY_TYPE_MAINS;
535 psy_desc->properties =
536 cros_usbpd_dedicated_charger_props;
537 psy_desc->num_properties =
538 ARRAY_SIZE(cros_usbpd_dedicated_charger_props);
539 } else {
540 sprintf(port->name, CHARGER_USBPD_DIR_NAME, i);
541 psy_desc->type = POWER_SUPPLY_TYPE_USB;
542 psy_desc->properties = cros_usbpd_charger_props;
543 psy_desc->num_properties =
544 ARRAY_SIZE(cros_usbpd_charger_props);
545 psy_desc->usb_types = cros_usbpd_charger_usb_types;
546 psy_desc->num_usb_types =
547 ARRAY_SIZE(cros_usbpd_charger_usb_types);
548 }
549
550 psy_desc->name = port->name;
551
465 psy = devm_power_supply_register_no_ws(dev, psy_desc, 552 psy = devm_power_supply_register_no_ws(dev, psy_desc,
466 &psy_cfg); 553 &psy_cfg);
467 if (IS_ERR(psy)) { 554 if (IS_ERR(psy)) {
diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h
index 6e1ab9bead28..20ee71f10865 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -3102,6 +3102,16 @@ struct ec_params_usb_pd_info_request {
3102 uint8_t port; 3102 uint8_t port;
3103} __packed; 3103} __packed;
3104 3104
3105/*
3106 * This command will return the number of USB PD charge port + the number
3107 * of dedicated port present.
3108 * EC_CMD_USB_PD_PORTS does NOT include the dedicated ports
3109 */
3110#define EC_CMD_CHARGE_PORT_COUNT 0x0105
3111struct ec_response_charge_port_count {
3112 uint8_t port_count;
3113} __packed;
3114
3105/* Read USB-PD Device discovery info */ 3115/* Read USB-PD Device discovery info */
3106#define EC_CMD_USB_PD_DISCOVERY 0x0113 3116#define EC_CMD_USB_PD_DISCOVERY 0x0113
3107struct ec_params_usb_pd_discovery_entry { 3117struct ec_params_usb_pd_discovery_entry {