linux/drivers/power/supply/cros_usbpd-charger.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Power supply driver for ChromeOS EC based USB PD Charger.
   4 *
   5 * Copyright (c) 2014 - 2018 Google, Inc
   6 */
   7
   8#include <linux/module.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>
  12#include <linux/platform_device.h>
  13#include <linux/power_supply.h>
  14#include <linux/slab.h>
  15
  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))
  22#define CHARGER_CACHE_UPDATE_DELAY              msecs_to_jiffies(500)
  23#define CHARGER_MANUFACTURER_MODEL_LENGTH       32
  24
  25#define DRV_NAME "cros-usbpd-charger"
  26
  27struct port_data {
  28        int port_number;
  29        char name[CHARGER_DIR_NAME_LENGTH];
  30        char manufacturer[CHARGER_MANUFACTURER_MODEL_LENGTH];
  31        char model_name[CHARGER_MANUFACTURER_MODEL_LENGTH];
  32        struct power_supply *psy;
  33        struct power_supply_desc psy_desc;
  34        int psy_usb_type;
  35        int psy_online;
  36        int psy_status;
  37        int psy_current_max;
  38        int psy_voltage_max_design;
  39        int psy_voltage_now;
  40        int psy_power_max;
  41        struct charger_data *charger;
  42        unsigned long last_update;
  43};
  44
  45struct charger_data {
  46        struct device *dev;
  47        struct cros_ec_dev *ec_dev;
  48        struct cros_ec_device *ec_device;
  49        int num_charger_ports;
  50        int num_usbpd_ports;
  51        int num_registered_psy;
  52        struct port_data *ports[EC_USB_PD_MAX_PORTS];
  53        struct notifier_block notifier;
  54};
  55
  56static enum power_supply_property cros_usbpd_charger_props[] = {
  57        POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
  58        POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT,
  59        POWER_SUPPLY_PROP_ONLINE,
  60        POWER_SUPPLY_PROP_STATUS,
  61        POWER_SUPPLY_PROP_CURRENT_MAX,
  62        POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
  63        POWER_SUPPLY_PROP_VOLTAGE_NOW,
  64        POWER_SUPPLY_PROP_MODEL_NAME,
  65        POWER_SUPPLY_PROP_MANUFACTURER,
  66        POWER_SUPPLY_PROP_USB_TYPE
  67};
  68
  69static 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,
  73};
  74
  75static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = {
  76        POWER_SUPPLY_USB_TYPE_UNKNOWN,
  77        POWER_SUPPLY_USB_TYPE_SDP,
  78        POWER_SUPPLY_USB_TYPE_DCP,
  79        POWER_SUPPLY_USB_TYPE_CDP,
  80        POWER_SUPPLY_USB_TYPE_C,
  81        POWER_SUPPLY_USB_TYPE_PD,
  82        POWER_SUPPLY_USB_TYPE_PD_DRP,
  83        POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID
  84};
  85
  86/* Input voltage/current limit in mV/mA. Default to none. */
  87static u16 input_voltage_limit = EC_POWER_LIMIT_NONE;
  88static u16 input_current_limit = EC_POWER_LIMIT_NONE;
  89
  90static bool cros_usbpd_charger_port_is_dedicated(struct port_data *port)
  91{
  92        return port->port_number >= port->charger->num_usbpd_ports;
  93}
  94
  95static int cros_usbpd_charger_ec_command(struct charger_data *charger,
  96                                         unsigned int version,
  97                                         unsigned int command,
  98                                         void *outdata,
  99                                         unsigned int outsize,
 100                                         void *indata,
 101                                         unsigned int insize)
 102{
 103        struct cros_ec_dev *ec_dev = charger->ec_dev;
 104        struct cros_ec_command *msg;
 105        int ret;
 106
 107        msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
 108        if (!msg)
 109                return -ENOMEM;
 110
 111        msg->version = version;
 112        msg->command = ec_dev->cmd_offset + command;
 113        msg->outsize = outsize;
 114        msg->insize = insize;
 115
 116        if (outsize)
 117                memcpy(msg->data, outdata, outsize);
 118
 119        ret = cros_ec_cmd_xfer_status(charger->ec_device, msg);
 120        if (ret >= 0 && insize)
 121                memcpy(indata, msg->data, insize);
 122
 123        kfree(msg);
 124        return ret;
 125}
 126
 127static int cros_usbpd_charger_get_num_ports(struct charger_data *charger)
 128{
 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
 141static int cros_usbpd_charger_get_usbpd_num_ports(struct charger_data *charger)
 142{
 143        struct ec_response_usb_pd_ports resp;
 144        int ret;
 145
 146        ret = cros_usbpd_charger_ec_command(charger, 0, EC_CMD_USB_PD_PORTS,
 147                                            NULL, 0, &resp, sizeof(resp));
 148        if (ret < 0)
 149                return ret;
 150
 151        return resp.num_ports;
 152}
 153
 154static int cros_usbpd_charger_get_discovery_info(struct port_data *port)
 155{
 156        struct charger_data *charger = port->charger;
 157        struct ec_params_usb_pd_discovery_entry resp;
 158        struct ec_params_usb_pd_info_request req;
 159        int ret;
 160
 161        req.port = port->port_number;
 162
 163        ret = cros_usbpd_charger_ec_command(charger, 0,
 164                                            EC_CMD_USB_PD_DISCOVERY,
 165                                            &req, sizeof(req),
 166                                            &resp, sizeof(resp));
 167        if (ret < 0) {
 168                dev_err(charger->dev,
 169                        "Unable to query discovery info (err:0x%x)\n", ret);
 170                return ret;
 171        }
 172
 173        dev_dbg(charger->dev, "Port %d: VID = 0x%x, PID=0x%x, PTYPE=0x%x\n",
 174                port->port_number, resp.vid, resp.pid, resp.ptype);
 175
 176        snprintf(port->manufacturer, sizeof(port->manufacturer), "%x",
 177                 resp.vid);
 178        snprintf(port->model_name, sizeof(port->model_name), "%x", resp.pid);
 179
 180        return 0;
 181}
 182
 183static int cros_usbpd_charger_get_power_info(struct port_data *port)
 184{
 185        struct charger_data *charger = port->charger;
 186        struct ec_response_usb_pd_power_info resp;
 187        struct ec_params_usb_pd_power_info req;
 188        int last_psy_status, last_psy_usb_type;
 189        struct device *dev = charger->dev;
 190        int ret;
 191
 192        req.port = port->port_number;
 193        ret = cros_usbpd_charger_ec_command(charger, 0,
 194                                            EC_CMD_USB_PD_POWER_INFO,
 195                                            &req, sizeof(req),
 196                                            &resp, sizeof(resp));
 197        if (ret < 0) {
 198                dev_err(dev, "Unable to query PD power info (err:0x%x)\n", ret);
 199                return ret;
 200        }
 201
 202        last_psy_status = port->psy_status;
 203        last_psy_usb_type = port->psy_usb_type;
 204
 205        switch (resp.role) {
 206        case USB_PD_PORT_POWER_DISCONNECTED:
 207                port->psy_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 208                port->psy_online = 0;
 209                break;
 210        case USB_PD_PORT_POWER_SOURCE:
 211                port->psy_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 212                port->psy_online = 0;
 213                break;
 214        case USB_PD_PORT_POWER_SINK:
 215                port->psy_status = POWER_SUPPLY_STATUS_CHARGING;
 216                port->psy_online = 1;
 217                break;
 218        case USB_PD_PORT_POWER_SINK_NOT_CHARGING:
 219                port->psy_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 220                port->psy_online = 1;
 221                break;
 222        default:
 223                dev_err(dev, "Unknown role %d\n", resp.role);
 224                break;
 225        }
 226
 227        port->psy_voltage_max_design = resp.meas.voltage_max;
 228        port->psy_voltage_now = resp.meas.voltage_now;
 229        port->psy_current_max = resp.meas.current_max;
 230        port->psy_power_max = resp.max_power;
 231
 232        switch (resp.type) {
 233        case USB_CHG_TYPE_BC12_SDP:
 234        case USB_CHG_TYPE_VBUS:
 235                port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
 236                break;
 237        case USB_CHG_TYPE_NONE:
 238                /*
 239                 * For dual-role devices when we are a source, the firmware
 240                 * reports the type as NONE. Report such chargers as type
 241                 * USB_PD_DRP.
 242                 */
 243                if (resp.role == USB_PD_PORT_POWER_SOURCE && resp.dualrole)
 244                        port->psy_usb_type = POWER_SUPPLY_USB_TYPE_PD_DRP;
 245                else
 246                        port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
 247                break;
 248        case USB_CHG_TYPE_OTHER:
 249        case USB_CHG_TYPE_PROPRIETARY:
 250                port->psy_usb_type = POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID;
 251                break;
 252        case USB_CHG_TYPE_C:
 253                port->psy_usb_type = POWER_SUPPLY_USB_TYPE_C;
 254                break;
 255        case USB_CHG_TYPE_BC12_DCP:
 256                port->psy_usb_type = POWER_SUPPLY_USB_TYPE_DCP;
 257                break;
 258        case USB_CHG_TYPE_BC12_CDP:
 259                port->psy_usb_type = POWER_SUPPLY_USB_TYPE_CDP;
 260                break;
 261        case USB_CHG_TYPE_PD:
 262                if (resp.dualrole)
 263                        port->psy_usb_type = POWER_SUPPLY_USB_TYPE_PD_DRP;
 264                else
 265                        port->psy_usb_type = POWER_SUPPLY_USB_TYPE_PD;
 266                break;
 267        case USB_CHG_TYPE_UNKNOWN:
 268                /*
 269                 * While the EC is trying to determine the type of charger that
 270                 * has been plugged in, it will report the charger type as
 271                 * unknown. Additionally since the power capabilities are
 272                 * unknown, report the max current and voltage as zero.
 273                 */
 274                port->psy_usb_type = POWER_SUPPLY_USB_TYPE_UNKNOWN;
 275                port->psy_voltage_max_design = 0;
 276                port->psy_current_max = 0;
 277                break;
 278        default:
 279                dev_err(dev, "Port %d: default case!\n", port->port_number);
 280                port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
 281        }
 282
 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;
 287
 288        dev_dbg(dev,
 289                "Port %d: type=%d vmax=%d vnow=%d cmax=%d clim=%d pmax=%d\n",
 290                port->port_number, resp.type, resp.meas.voltage_max,
 291                resp.meas.voltage_now, resp.meas.current_max,
 292                resp.meas.current_lim, resp.max_power);
 293
 294        /*
 295         * If power supply type or status changed, explicitly call
 296         * power_supply_changed. This results in udev event getting generated
 297         * and allows user mode apps to react quicker instead of waiting for
 298         * their next poll of power supply status.
 299         */
 300        if (last_psy_usb_type != port->psy_usb_type ||
 301            last_psy_status != port->psy_status)
 302                power_supply_changed(port->psy);
 303
 304        return 0;
 305}
 306
 307static int cros_usbpd_charger_get_port_status(struct port_data *port,
 308                                              bool ratelimit)
 309{
 310        int ret;
 311
 312        if (ratelimit &&
 313            time_is_after_jiffies(port->last_update +
 314                                  CHARGER_CACHE_UPDATE_DELAY))
 315                return 0;
 316
 317        ret = cros_usbpd_charger_get_power_info(port);
 318        if (ret < 0)
 319                return ret;
 320
 321        if (!cros_usbpd_charger_port_is_dedicated(port))
 322                ret = cros_usbpd_charger_get_discovery_info(port);
 323        port->last_update = jiffies;
 324
 325        return ret;
 326}
 327
 328static 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);
 344
 345        return ret;
 346}
 347
 348static void cros_usbpd_charger_power_changed(struct power_supply *psy)
 349{
 350        struct port_data *port = power_supply_get_drvdata(psy);
 351        struct charger_data *charger = port->charger;
 352        int i;
 353
 354        for (i = 0; i < charger->num_registered_psy; i++)
 355                cros_usbpd_charger_get_port_status(charger->ports[i], false);
 356}
 357
 358static int cros_usbpd_charger_get_prop(struct power_supply *psy,
 359                                       enum power_supply_property psp,
 360                                       union power_supply_propval *val)
 361{
 362        struct port_data *port = power_supply_get_drvdata(psy);
 363        struct charger_data *charger = port->charger;
 364        struct cros_ec_device *ec_device = charger->ec_device;
 365        struct device *dev = charger->dev;
 366        int ret;
 367
 368        /* Only refresh ec_port_status for dynamic properties */
 369        switch (psp) {
 370        case POWER_SUPPLY_PROP_ONLINE:
 371                /*
 372                 * If mkbp_event_supported, then we can be assured that
 373                 * the driver's state for the online property is consistent
 374                 * with the hardware. However, if we aren't event driven,
 375                 * the optimization before to skip an ec_port_status get
 376                 * and only returned cached values of the online property will
 377                 * cause a delay in detecting a cable attach until one of the
 378                 * other properties are read.
 379                 *
 380                 * Allow an ec_port_status refresh for online property check
 381                 * if we're not already online to check for plug events if
 382                 * not mkbp_event_supported.
 383                 */
 384                if (ec_device->mkbp_event_supported || port->psy_online)
 385                        break;
 386                fallthrough;
 387        case POWER_SUPPLY_PROP_CURRENT_MAX:
 388        case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
 389        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 390                ret = cros_usbpd_charger_get_port_status(port, true);
 391                if (ret < 0) {
 392                        dev_err(dev, "Failed to get port status (err:0x%x)\n",
 393                                ret);
 394                        return -EINVAL;
 395                }
 396                break;
 397        default:
 398                break;
 399        }
 400
 401        switch (psp) {
 402        case POWER_SUPPLY_PROP_ONLINE:
 403                val->intval = port->psy_online;
 404                break;
 405        case POWER_SUPPLY_PROP_STATUS:
 406                val->intval = port->psy_status;
 407                break;
 408        case POWER_SUPPLY_PROP_CURRENT_MAX:
 409                val->intval = port->psy_current_max * 1000;
 410                break;
 411        case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
 412                val->intval = port->psy_voltage_max_design * 1000;
 413                break;
 414        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 415                val->intval = port->psy_voltage_now * 1000;
 416                break;
 417        case POWER_SUPPLY_PROP_USB_TYPE:
 418                val->intval = port->psy_usb_type;
 419                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;
 432        case POWER_SUPPLY_PROP_MODEL_NAME:
 433                val->strval = port->model_name;
 434                break;
 435        case POWER_SUPPLY_PROP_MANUFACTURER:
 436                val->strval = port->manufacturer;
 437                break;
 438        default:
 439                return -EINVAL;
 440        }
 441
 442        return 0;
 443}
 444
 445static 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
 503static 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
 520static int cros_usbpd_charger_ec_event(struct notifier_block *nb,
 521                                       unsigned long host_event,
 522                                       void *_notify)
 523{
 524        struct charger_data *charger = container_of(nb, struct charger_data,
 525                                                    notifier);
 526
 527        cros_usbpd_charger_power_changed(charger->ports[0]->psy);
 528        return NOTIFY_OK;
 529}
 530
 531static void cros_usbpd_charger_unregister_notifier(void *data)
 532{
 533        struct charger_data *charger = data;
 534
 535        cros_usbpd_unregister_notify(&charger->notifier);
 536}
 537
 538static int cros_usbpd_charger_probe(struct platform_device *pd)
 539{
 540        struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent);
 541        struct cros_ec_device *ec_device = ec_dev->ec_dev;
 542        struct power_supply_desc *psy_desc;
 543        struct device *dev = &pd->dev;
 544        struct charger_data *charger;
 545        struct power_supply *psy;
 546        struct port_data *port;
 547        int ret = -EINVAL;
 548        int i;
 549
 550        charger = devm_kzalloc(dev, sizeof(struct charger_data),
 551                               GFP_KERNEL);
 552        if (!charger)
 553                return -ENOMEM;
 554
 555        charger->dev = dev;
 556        charger->ec_dev = ec_dev;
 557        charger->ec_device = ec_device;
 558
 559        platform_set_drvdata(pd, charger);
 560
 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) {
 569                /*
 570                 * This can happen on a system that doesn't support USB PD.
 571                 * Log a message, but no need to warn.
 572                 */
 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                 */
 595                dev_info(dev, "No charging ports found\n");
 596                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;
 608                goto fail_nowarn;
 609        }
 610
 611        for (i = 0; i < charger->num_charger_ports; i++) {
 612                struct power_supply_config psy_cfg = {};
 613
 614                port = devm_kzalloc(dev, sizeof(struct port_data), GFP_KERNEL);
 615                if (!port) {
 616                        ret = -ENOMEM;
 617                        goto fail;
 618                }
 619
 620                port->charger = charger;
 621                port->port_number = i;
 622
 623                psy_desc = &port->psy_desc;
 624                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;
 628                psy_desc->external_power_changed =
 629                                        cros_usbpd_charger_power_changed;
 630                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;
 651
 652                psy = devm_power_supply_register_no_ws(dev, psy_desc,
 653                                                       &psy_cfg);
 654                if (IS_ERR(psy)) {
 655                        dev_err(dev, "Failed to register power supply\n");
 656                        continue;
 657                }
 658                port->psy = psy;
 659
 660                charger->ports[charger->num_registered_psy++] = port;
 661        }
 662
 663        if (!charger->num_registered_psy) {
 664                ret = -ENODEV;
 665                dev_err(dev, "No power supplies registered\n");
 666                goto fail;
 667        }
 668
 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;
 680        }
 681
 682        return 0;
 683
 684fail:
 685        WARN(1, "%s: Failing probe (err:0x%x)\n", dev_name(dev), ret);
 686
 687fail_nowarn:
 688        dev_info(dev, "Failing probe (err:0x%x)\n", ret);
 689        return ret;
 690}
 691
 692#ifdef CONFIG_PM_SLEEP
 693static int cros_usbpd_charger_resume(struct device *dev)
 694{
 695        struct charger_data *charger = dev_get_drvdata(dev);
 696        int i;
 697
 698        if (!charger)
 699                return 0;
 700
 701        for (i = 0; i < charger->num_registered_psy; i++) {
 702                power_supply_changed(charger->ports[i]->psy);
 703                charger->ports[i]->last_update =
 704                                jiffies - CHARGER_CACHE_UPDATE_DELAY;
 705        }
 706
 707        return 0;
 708}
 709#endif
 710
 711static SIMPLE_DEV_PM_OPS(cros_usbpd_charger_pm_ops, NULL,
 712                         cros_usbpd_charger_resume);
 713
 714static struct platform_driver cros_usbpd_charger_driver = {
 715        .driver = {
 716                .name = DRV_NAME,
 717                .pm = &cros_usbpd_charger_pm_ops,
 718        },
 719        .probe = cros_usbpd_charger_probe
 720};
 721
 722module_platform_driver(cros_usbpd_charger_driver);
 723
 724MODULE_LICENSE("GPL");
 725MODULE_DESCRIPTION("ChromeOS EC USBPD charger");
 726MODULE_ALIAS("platform:" DRV_NAME);
 727