linux/drivers/usb/typec/ucsi/ucsi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * USB Type-C Connector System Software Interface driver
   4 *
   5 * Copyright (C) 2017, Intel Corporation
   6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
   7 */
   8
   9#include <linux/completion.h>
  10#include <linux/property.h>
  11#include <linux/device.h>
  12#include <linux/module.h>
  13#include <linux/delay.h>
  14#include <linux/slab.h>
  15#include <linux/usb/typec_dp.h>
  16
  17#include "ucsi.h"
  18#include "trace.h"
  19
  20/*
  21 * UCSI_TIMEOUT_MS - PPM communication timeout
  22 *
  23 * Ideally we could use MIN_TIME_TO_RESPOND_WITH_BUSY (which is defined in UCSI
  24 * specification) here as reference, but unfortunately we can't. It is very
  25 * difficult to estimate the time it takes for the system to process the command
  26 * before it is actually passed to the PPM.
  27 */
  28#define UCSI_TIMEOUT_MS         5000
  29
  30/*
  31 * UCSI_SWAP_TIMEOUT_MS - Timeout for role swap requests
  32 *
  33 * 5 seconds is close to the time it takes for CapsCounter to reach 0, so even
  34 * if the PPM does not generate Connector Change events before that with
  35 * partners that do not support USB Power Delivery, this should still work.
  36 */
  37#define UCSI_SWAP_TIMEOUT_MS    5000
  38
  39static int ucsi_acknowledge_command(struct ucsi *ucsi)
  40{
  41        u64 ctrl;
  42
  43        ctrl = UCSI_ACK_CC_CI;
  44        ctrl |= UCSI_ACK_COMMAND_COMPLETE;
  45
  46        return ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &ctrl, sizeof(ctrl));
  47}
  48
  49static int ucsi_acknowledge_connector_change(struct ucsi *ucsi)
  50{
  51        u64 ctrl;
  52
  53        ctrl = UCSI_ACK_CC_CI;
  54        ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
  55
  56        return ucsi->ops->async_write(ucsi, UCSI_CONTROL, &ctrl, sizeof(ctrl));
  57}
  58
  59static int ucsi_exec_command(struct ucsi *ucsi, u64 command);
  60
  61static int ucsi_read_error(struct ucsi *ucsi)
  62{
  63        u16 error;
  64        int ret;
  65
  66        /* Acknowlege the command that failed */
  67        ret = ucsi_acknowledge_command(ucsi);
  68        if (ret)
  69                return ret;
  70
  71        ret = ucsi_exec_command(ucsi, UCSI_GET_ERROR_STATUS);
  72        if (ret < 0)
  73                return ret;
  74
  75        ret = ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, &error, sizeof(error));
  76        if (ret)
  77                return ret;
  78
  79        switch (error) {
  80        case UCSI_ERROR_INCOMPATIBLE_PARTNER:
  81                return -EOPNOTSUPP;
  82        case UCSI_ERROR_CC_COMMUNICATION_ERR:
  83                return -ECOMM;
  84        case UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL:
  85                return -EPROTO;
  86        case UCSI_ERROR_DEAD_BATTERY:
  87                dev_warn(ucsi->dev, "Dead battery condition!\n");
  88                return -EPERM;
  89        case UCSI_ERROR_INVALID_CON_NUM:
  90        case UCSI_ERROR_UNREGONIZED_CMD:
  91        case UCSI_ERROR_INVALID_CMD_ARGUMENT:
  92                dev_err(ucsi->dev, "possible UCSI driver bug %u\n", error);
  93                return -EINVAL;
  94        case UCSI_ERROR_OVERCURRENT:
  95                dev_warn(ucsi->dev, "Overcurrent condition\n");
  96                break;
  97        case UCSI_ERROR_PARTNER_REJECTED_SWAP:
  98                dev_warn(ucsi->dev, "Partner rejected swap\n");
  99                break;
 100        case UCSI_ERROR_HARD_RESET:
 101                dev_warn(ucsi->dev, "Hard reset occurred\n");
 102                break;
 103        case UCSI_ERROR_PPM_POLICY_CONFLICT:
 104                dev_warn(ucsi->dev, "PPM Policy conflict\n");
 105                break;
 106        case UCSI_ERROR_SWAP_REJECTED:
 107                dev_warn(ucsi->dev, "Swap rejected\n");
 108                break;
 109        case UCSI_ERROR_UNDEFINED:
 110        default:
 111                dev_err(ucsi->dev, "unknown error %u\n", error);
 112                break;
 113        }
 114
 115        return -EIO;
 116}
 117
 118static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
 119{
 120        u32 cci;
 121        int ret;
 122
 123        ret = ucsi->ops->sync_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
 124        if (ret)
 125                return ret;
 126
 127        ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
 128        if (ret)
 129                return ret;
 130
 131        if (cci & UCSI_CCI_BUSY)
 132                return -EBUSY;
 133
 134        if (!(cci & UCSI_CCI_COMMAND_COMPLETE))
 135                return -EIO;
 136
 137        if (cci & UCSI_CCI_NOT_SUPPORTED)
 138                return -EOPNOTSUPP;
 139
 140        if (cci & UCSI_CCI_ERROR) {
 141                if (cmd == UCSI_GET_ERROR_STATUS)
 142                        return -EIO;
 143                return ucsi_read_error(ucsi);
 144        }
 145
 146        return UCSI_CCI_LENGTH(cci);
 147}
 148
 149static int ucsi_run_command(struct ucsi *ucsi, u64 command,
 150                            void *data, size_t size)
 151{
 152        u8 length;
 153        int ret;
 154
 155        ret = ucsi_exec_command(ucsi, command);
 156        if (ret < 0)
 157                return ret;
 158
 159        length = ret;
 160
 161        if (data) {
 162                ret = ucsi->ops->read(ucsi, UCSI_MESSAGE_IN, data, size);
 163                if (ret)
 164                        return ret;
 165        }
 166
 167        ret = ucsi_acknowledge_command(ucsi);
 168        if (ret)
 169                return ret;
 170
 171        return length;
 172}
 173
 174int ucsi_send_command(struct ucsi *ucsi, u64 command,
 175                      void *retval, size_t size)
 176{
 177        int ret;
 178
 179        mutex_lock(&ucsi->ppm_lock);
 180        ret = ucsi_run_command(ucsi, command, retval, size);
 181        mutex_unlock(&ucsi->ppm_lock);
 182
 183        return ret;
 184}
 185EXPORT_SYMBOL_GPL(ucsi_send_command);
 186
 187int ucsi_resume(struct ucsi *ucsi)
 188{
 189        u64 command;
 190
 191        /* Restore UCSI notification enable mask after system resume */
 192        command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
 193
 194        return ucsi_send_command(ucsi, command, NULL, 0);
 195}
 196EXPORT_SYMBOL_GPL(ucsi_resume);
 197/* -------------------------------------------------------------------------- */
 198
 199void ucsi_altmode_update_active(struct ucsi_connector *con)
 200{
 201        const struct typec_altmode *altmode = NULL;
 202        u64 command;
 203        int ret;
 204        u8 cur;
 205        int i;
 206
 207        command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(con->num);
 208        ret = ucsi_run_command(con->ucsi, command, &cur, sizeof(cur));
 209        if (ret < 0) {
 210                if (con->ucsi->version > 0x0100) {
 211                        dev_err(con->ucsi->dev,
 212                                "GET_CURRENT_CAM command failed\n");
 213                        return;
 214                }
 215                cur = 0xff;
 216        }
 217
 218        if (cur < UCSI_MAX_ALTMODES)
 219                altmode = typec_altmode_get_partner(con->port_altmode[cur]);
 220
 221        for (i = 0; con->partner_altmode[i]; i++)
 222                typec_altmode_update_active(con->partner_altmode[i],
 223                                            con->partner_altmode[i] == altmode);
 224}
 225
 226static u8 ucsi_altmode_next_mode(struct typec_altmode **alt, u16 svid)
 227{
 228        u8 mode = 1;
 229        int i;
 230
 231        for (i = 0; alt[i]; i++)
 232                if (alt[i]->svid == svid)
 233                        mode++;
 234
 235        return mode;
 236}
 237
 238static int ucsi_next_altmode(struct typec_altmode **alt)
 239{
 240        int i = 0;
 241
 242        for (i = 0; i < UCSI_MAX_ALTMODES; i++)
 243                if (!alt[i])
 244                        return i;
 245
 246        return -ENOENT;
 247}
 248
 249static int ucsi_register_altmode(struct ucsi_connector *con,
 250                                 struct typec_altmode_desc *desc,
 251                                 u8 recipient)
 252{
 253        struct typec_altmode *alt;
 254        bool override;
 255        int ret;
 256        int i;
 257
 258        override = !!(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_OVERRIDE);
 259
 260        switch (recipient) {
 261        case UCSI_RECIPIENT_CON:
 262                i = ucsi_next_altmode(con->port_altmode);
 263                if (i < 0) {
 264                        ret = i;
 265                        goto err;
 266                }
 267
 268                desc->mode = ucsi_altmode_next_mode(con->port_altmode,
 269                                                    desc->svid);
 270
 271                switch (desc->svid) {
 272                case USB_TYPEC_DP_SID:
 273                case USB_TYPEC_NVIDIA_VLINK_SID:
 274                        alt = ucsi_register_displayport(con, override, i, desc);
 275                        break;
 276                default:
 277                        alt = typec_port_register_altmode(con->port, desc);
 278                        break;
 279                }
 280
 281                if (IS_ERR(alt)) {
 282                        ret = PTR_ERR(alt);
 283                        goto err;
 284                }
 285
 286                con->port_altmode[i] = alt;
 287                break;
 288        case UCSI_RECIPIENT_SOP:
 289                i = ucsi_next_altmode(con->partner_altmode);
 290                if (i < 0) {
 291                        ret = i;
 292                        goto err;
 293                }
 294
 295                desc->mode = ucsi_altmode_next_mode(con->partner_altmode,
 296                                                    desc->svid);
 297
 298                alt = typec_partner_register_altmode(con->partner, desc);
 299                if (IS_ERR(alt)) {
 300                        ret = PTR_ERR(alt);
 301                        goto err;
 302                }
 303
 304                con->partner_altmode[i] = alt;
 305                break;
 306        default:
 307                return -EINVAL;
 308        }
 309
 310        trace_ucsi_register_altmode(recipient, alt);
 311
 312        return 0;
 313
 314err:
 315        dev_err(con->ucsi->dev, "failed to registers svid 0x%04x mode %d\n",
 316                desc->svid, desc->mode);
 317
 318        return ret;
 319}
 320
 321static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
 322{
 323        int max_altmodes = UCSI_MAX_ALTMODES;
 324        struct typec_altmode_desc desc;
 325        struct ucsi_altmode alt[2];
 326        u64 command;
 327        int num = 1;
 328        int ret;
 329        int len;
 330        int j;
 331        int i;
 332
 333        if (!(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_DETAILS))
 334                return 0;
 335
 336        if (recipient == UCSI_RECIPIENT_SOP && con->partner_altmode[0])
 337                return 0;
 338
 339        if (recipient == UCSI_RECIPIENT_CON)
 340                max_altmodes = con->ucsi->cap.num_alt_modes;
 341
 342        for (i = 0; i < max_altmodes;) {
 343                memset(alt, 0, sizeof(alt));
 344                command = UCSI_GET_ALTERNATE_MODES;
 345                command |= UCSI_GET_ALTMODE_RECIPIENT(recipient);
 346                command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num);
 347                command |= UCSI_GET_ALTMODE_OFFSET(i);
 348                len = ucsi_run_command(con->ucsi, command, alt, sizeof(alt));
 349                if (len <= 0)
 350                        return len;
 351
 352                /*
 353                 * This code is requesting one alt mode at a time, but some PPMs
 354                 * may still return two. If that happens both alt modes need be
 355                 * registered and the offset for the next alt mode has to be
 356                 * incremented.
 357                 */
 358                num = len / sizeof(alt[0]);
 359                i += num;
 360
 361                for (j = 0; j < num; j++) {
 362                        if (!alt[j].svid)
 363                                return 0;
 364
 365                        memset(&desc, 0, sizeof(desc));
 366                        desc.vdo = alt[j].mid;
 367                        desc.svid = alt[j].svid;
 368                        desc.roles = TYPEC_PORT_DRD;
 369
 370                        ret = ucsi_register_altmode(con, &desc, recipient);
 371                        if (ret)
 372                                return ret;
 373                }
 374        }
 375
 376        return 0;
 377}
 378
 379static void ucsi_unregister_altmodes(struct ucsi_connector *con, u8 recipient)
 380{
 381        const struct typec_altmode *pdev;
 382        struct typec_altmode **adev;
 383        int i = 0;
 384
 385        switch (recipient) {
 386        case UCSI_RECIPIENT_CON:
 387                adev = con->port_altmode;
 388                break;
 389        case UCSI_RECIPIENT_SOP:
 390                adev = con->partner_altmode;
 391                break;
 392        default:
 393                return;
 394        }
 395
 396        while (adev[i]) {
 397                if (recipient == UCSI_RECIPIENT_SOP &&
 398                    (adev[i]->svid == USB_TYPEC_DP_SID ||
 399                        adev[i]->svid == USB_TYPEC_NVIDIA_VLINK_SID)) {
 400                        pdev = typec_altmode_get_partner(adev[i]);
 401                        ucsi_displayport_remove_partner((void *)pdev);
 402                }
 403                typec_unregister_altmode(adev[i]);
 404                adev[i++] = NULL;
 405        }
 406}
 407
 408static void ucsi_pwr_opmode_change(struct ucsi_connector *con)
 409{
 410        switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
 411        case UCSI_CONSTAT_PWR_OPMODE_PD:
 412                typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_PD);
 413                break;
 414        case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5:
 415                typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_1_5A);
 416                break;
 417        case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0:
 418                typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_3_0A);
 419                break;
 420        default:
 421                typec_set_pwr_opmode(con->port, TYPEC_PWR_MODE_USB);
 422                break;
 423        }
 424}
 425
 426static int ucsi_register_partner(struct ucsi_connector *con)
 427{
 428        u8 pwr_opmode = UCSI_CONSTAT_PWR_OPMODE(con->status.flags);
 429        struct typec_partner_desc desc;
 430        struct typec_partner *partner;
 431
 432        if (con->partner)
 433                return 0;
 434
 435        memset(&desc, 0, sizeof(desc));
 436
 437        switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
 438        case UCSI_CONSTAT_PARTNER_TYPE_DEBUG:
 439                desc.accessory = TYPEC_ACCESSORY_DEBUG;
 440                break;
 441        case UCSI_CONSTAT_PARTNER_TYPE_AUDIO:
 442                desc.accessory = TYPEC_ACCESSORY_AUDIO;
 443                break;
 444        default:
 445                break;
 446        }
 447
 448        desc.usb_pd = pwr_opmode == UCSI_CONSTAT_PWR_OPMODE_PD;
 449
 450        partner = typec_register_partner(con->port, &desc);
 451        if (IS_ERR(partner)) {
 452                dev_err(con->ucsi->dev,
 453                        "con%d: failed to register partner (%ld)\n", con->num,
 454                        PTR_ERR(partner));
 455                return PTR_ERR(partner);
 456        }
 457
 458        con->partner = partner;
 459
 460        return 0;
 461}
 462
 463static void ucsi_unregister_partner(struct ucsi_connector *con)
 464{
 465        if (!con->partner)
 466                return;
 467
 468        ucsi_unregister_altmodes(con, UCSI_RECIPIENT_SOP);
 469        typec_unregister_partner(con->partner);
 470        con->partner = NULL;
 471}
 472
 473static void ucsi_partner_change(struct ucsi_connector *con)
 474{
 475        int ret;
 476
 477        if (!con->partner)
 478                return;
 479
 480        switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
 481        case UCSI_CONSTAT_PARTNER_TYPE_UFP:
 482                typec_set_data_role(con->port, TYPEC_HOST);
 483                break;
 484        case UCSI_CONSTAT_PARTNER_TYPE_DFP:
 485                typec_set_data_role(con->port, TYPEC_DEVICE);
 486                break;
 487        default:
 488                break;
 489        }
 490
 491        /* Complete pending data role swap */
 492        if (!completion_done(&con->complete))
 493                complete(&con->complete);
 494
 495        /* Can't rely on Partner Flags field. Always checking the alt modes. */
 496        ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
 497        if (ret)
 498                dev_err(con->ucsi->dev,
 499                        "con%d: failed to register partner alternate modes\n",
 500                        con->num);
 501        else
 502                ucsi_altmode_update_active(con);
 503}
 504
 505static void ucsi_handle_connector_change(struct work_struct *work)
 506{
 507        struct ucsi_connector *con = container_of(work, struct ucsi_connector,
 508                                                  work);
 509        struct ucsi *ucsi = con->ucsi;
 510        enum typec_role role;
 511        u64 command;
 512        int ret;
 513
 514        mutex_lock(&con->lock);
 515
 516        command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
 517        ret = ucsi_send_command(ucsi, command, &con->status,
 518                                sizeof(con->status));
 519        if (ret < 0) {
 520                dev_err(ucsi->dev, "%s: GET_CONNECTOR_STATUS failed (%d)\n",
 521                        __func__, ret);
 522                goto out_unlock;
 523        }
 524
 525        role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
 526
 527        if (con->status.change & UCSI_CONSTAT_POWER_OPMODE_CHANGE)
 528                ucsi_pwr_opmode_change(con);
 529
 530        if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) {
 531                typec_set_pwr_role(con->port, role);
 532
 533                /* Complete pending power role swap */
 534                if (!completion_done(&con->complete))
 535                        complete(&con->complete);
 536        }
 537
 538        if (con->status.change & UCSI_CONSTAT_CONNECT_CHANGE) {
 539                typec_set_pwr_role(con->port, role);
 540
 541                switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
 542                case UCSI_CONSTAT_PARTNER_TYPE_UFP:
 543                        typec_set_data_role(con->port, TYPEC_HOST);
 544                        break;
 545                case UCSI_CONSTAT_PARTNER_TYPE_DFP:
 546                        typec_set_data_role(con->port, TYPEC_DEVICE);
 547                        break;
 548                default:
 549                        break;
 550                }
 551
 552                if (con->status.flags & UCSI_CONSTAT_CONNECTED)
 553                        ucsi_register_partner(con);
 554                else
 555                        ucsi_unregister_partner(con);
 556        }
 557
 558        if (con->status.change & UCSI_CONSTAT_CAM_CHANGE) {
 559                /*
 560                 * We don't need to know the currently supported alt modes here.
 561                 * Running GET_CAM_SUPPORTED command just to make sure the PPM
 562                 * does not get stuck in case it assumes we do so.
 563                 */
 564                command = UCSI_GET_CAM_SUPPORTED;
 565                command |= UCSI_CONNECTOR_NUMBER(con->num);
 566                ucsi_run_command(con->ucsi, command, NULL, 0);
 567        }
 568
 569        if (con->status.change & UCSI_CONSTAT_PARTNER_CHANGE)
 570                ucsi_partner_change(con);
 571
 572        ret = ucsi_acknowledge_connector_change(ucsi);
 573        if (ret)
 574                dev_err(ucsi->dev, "%s: ACK failed (%d)", __func__, ret);
 575
 576        trace_ucsi_connector_change(con->num, &con->status);
 577
 578out_unlock:
 579        clear_bit(EVENT_PENDING, &ucsi->flags);
 580        mutex_unlock(&con->lock);
 581}
 582
 583/**
 584 * ucsi_connector_change - Process Connector Change Event
 585 * @ucsi: UCSI Interface
 586 * @num: Connector number
 587 */
 588void ucsi_connector_change(struct ucsi *ucsi, u8 num)
 589{
 590        struct ucsi_connector *con = &ucsi->connector[num - 1];
 591
 592        if (!test_and_set_bit(EVENT_PENDING, &ucsi->flags))
 593                schedule_work(&con->work);
 594}
 595EXPORT_SYMBOL_GPL(ucsi_connector_change);
 596
 597/* -------------------------------------------------------------------------- */
 598
 599static int ucsi_reset_connector(struct ucsi_connector *con, bool hard)
 600{
 601        u64 command;
 602
 603        command = UCSI_CONNECTOR_RESET | UCSI_CONNECTOR_NUMBER(con->num);
 604        command |= hard ? UCSI_CONNECTOR_RESET_HARD : 0;
 605
 606        return ucsi_send_command(con->ucsi, command, NULL, 0);
 607}
 608
 609static int ucsi_reset_ppm(struct ucsi *ucsi)
 610{
 611        u64 command = UCSI_PPM_RESET;
 612        unsigned long tmo;
 613        u32 cci;
 614        int ret;
 615
 616        ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command,
 617                                     sizeof(command));
 618        if (ret < 0)
 619                return ret;
 620
 621        tmo = jiffies + msecs_to_jiffies(UCSI_TIMEOUT_MS);
 622
 623        do {
 624                if (time_is_before_jiffies(tmo))
 625                        return -ETIMEDOUT;
 626
 627                ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
 628                if (ret)
 629                        return ret;
 630
 631                /* If the PPM is still doing something else, reset it again. */
 632                if (cci & ~UCSI_CCI_RESET_COMPLETE) {
 633                        ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL,
 634                                                     &command,
 635                                                     sizeof(command));
 636                        if (ret < 0)
 637                                return ret;
 638                }
 639
 640                msleep(20);
 641        } while (!(cci & UCSI_CCI_RESET_COMPLETE));
 642
 643        return 0;
 644}
 645
 646static int ucsi_role_cmd(struct ucsi_connector *con, u64 command)
 647{
 648        int ret;
 649
 650        ret = ucsi_send_command(con->ucsi, command, NULL, 0);
 651        if (ret == -ETIMEDOUT) {
 652                u64 c;
 653
 654                /* PPM most likely stopped responding. Resetting everything. */
 655                mutex_lock(&con->ucsi->ppm_lock);
 656                ucsi_reset_ppm(con->ucsi);
 657                mutex_unlock(&con->ucsi->ppm_lock);
 658
 659                c = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
 660                ucsi_send_command(con->ucsi, c, NULL, 0);
 661
 662                ucsi_reset_connector(con, true);
 663        }
 664
 665        return ret;
 666}
 667
 668static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role)
 669{
 670        struct ucsi_connector *con = typec_get_drvdata(port);
 671        u8 partner_type;
 672        u64 command;
 673        int ret = 0;
 674
 675        mutex_lock(&con->lock);
 676
 677        if (!con->partner) {
 678                ret = -ENOTCONN;
 679                goto out_unlock;
 680        }
 681
 682        partner_type = UCSI_CONSTAT_PARTNER_TYPE(con->status.flags);
 683        if ((partner_type == UCSI_CONSTAT_PARTNER_TYPE_DFP &&
 684             role == TYPEC_DEVICE) ||
 685            (partner_type == UCSI_CONSTAT_PARTNER_TYPE_UFP &&
 686             role == TYPEC_HOST))
 687                goto out_unlock;
 688
 689        command = UCSI_SET_UOR | UCSI_CONNECTOR_NUMBER(con->num);
 690        command |= UCSI_SET_UOR_ROLE(role);
 691        command |= UCSI_SET_UOR_ACCEPT_ROLE_SWAPS;
 692        ret = ucsi_role_cmd(con, command);
 693        if (ret < 0)
 694                goto out_unlock;
 695
 696        if (!wait_for_completion_timeout(&con->complete,
 697                                        msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS)))
 698                ret = -ETIMEDOUT;
 699
 700out_unlock:
 701        mutex_unlock(&con->lock);
 702
 703        return ret < 0 ? ret : 0;
 704}
 705
 706static int ucsi_pr_swap(struct typec_port *port, enum typec_role role)
 707{
 708        struct ucsi_connector *con = typec_get_drvdata(port);
 709        enum typec_role cur_role;
 710        u64 command;
 711        int ret = 0;
 712
 713        mutex_lock(&con->lock);
 714
 715        if (!con->partner) {
 716                ret = -ENOTCONN;
 717                goto out_unlock;
 718        }
 719
 720        cur_role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
 721
 722        if (cur_role == role)
 723                goto out_unlock;
 724
 725        command = UCSI_SET_PDR | UCSI_CONNECTOR_NUMBER(con->num);
 726        command |= UCSI_SET_PDR_ROLE(role);
 727        command |= UCSI_SET_PDR_ACCEPT_ROLE_SWAPS;
 728        ret = ucsi_role_cmd(con, command);
 729        if (ret < 0)
 730                goto out_unlock;
 731
 732        if (!wait_for_completion_timeout(&con->complete,
 733                                msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS))) {
 734                ret = -ETIMEDOUT;
 735                goto out_unlock;
 736        }
 737
 738        /* Something has gone wrong while swapping the role */
 739        if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) !=
 740            UCSI_CONSTAT_PWR_OPMODE_PD) {
 741                ucsi_reset_connector(con, true);
 742                ret = -EPROTO;
 743        }
 744
 745out_unlock:
 746        mutex_unlock(&con->lock);
 747
 748        return ret;
 749}
 750
 751static const struct typec_operations ucsi_ops = {
 752        .dr_set = ucsi_dr_swap,
 753        .pr_set = ucsi_pr_swap
 754};
 755
 756static struct fwnode_handle *ucsi_find_fwnode(struct ucsi_connector *con)
 757{
 758        struct fwnode_handle *fwnode;
 759        int i = 1;
 760
 761        device_for_each_child_node(con->ucsi->dev, fwnode)
 762                if (i++ == con->num)
 763                        return fwnode;
 764        return NULL;
 765}
 766
 767static int ucsi_register_port(struct ucsi *ucsi, int index)
 768{
 769        struct ucsi_connector *con = &ucsi->connector[index];
 770        struct typec_capability *cap = &con->typec_cap;
 771        enum typec_accessory *accessory = cap->accessory;
 772        u64 command;
 773        int ret;
 774
 775        INIT_WORK(&con->work, ucsi_handle_connector_change);
 776        init_completion(&con->complete);
 777        mutex_init(&con->lock);
 778        con->num = index + 1;
 779        con->ucsi = ucsi;
 780
 781        /* Get connector capability */
 782        command = UCSI_GET_CONNECTOR_CAPABILITY;
 783        command |= UCSI_CONNECTOR_NUMBER(con->num);
 784        ret = ucsi_run_command(ucsi, command, &con->cap, sizeof(con->cap));
 785        if (ret < 0)
 786                return ret;
 787
 788        if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DRP)
 789                cap->data = TYPEC_PORT_DRD;
 790        else if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DFP)
 791                cap->data = TYPEC_PORT_DFP;
 792        else if (con->cap.op_mode & UCSI_CONCAP_OPMODE_UFP)
 793                cap->data = TYPEC_PORT_UFP;
 794
 795        if ((con->cap.flags & UCSI_CONCAP_FLAG_PROVIDER) &&
 796            (con->cap.flags & UCSI_CONCAP_FLAG_CONSUMER))
 797                cap->type = TYPEC_PORT_DRP;
 798        else if (con->cap.flags & UCSI_CONCAP_FLAG_PROVIDER)
 799                cap->type = TYPEC_PORT_SRC;
 800        else if (con->cap.flags & UCSI_CONCAP_FLAG_CONSUMER)
 801                cap->type = TYPEC_PORT_SNK;
 802
 803        cap->revision = ucsi->cap.typec_version;
 804        cap->pd_revision = ucsi->cap.pd_version;
 805        cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
 806
 807        if (con->cap.op_mode & UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY)
 808                *accessory++ = TYPEC_ACCESSORY_AUDIO;
 809        if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY)
 810                *accessory = TYPEC_ACCESSORY_DEBUG;
 811
 812        cap->fwnode = ucsi_find_fwnode(con);
 813        cap->driver_data = con;
 814        cap->ops = &ucsi_ops;
 815
 816        /* Register the connector */
 817        con->port = typec_register_port(ucsi->dev, cap);
 818        if (IS_ERR(con->port))
 819                return PTR_ERR(con->port);
 820
 821        /* Alternate modes */
 822        ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_CON);
 823        if (ret)
 824                dev_err(ucsi->dev, "con%d: failed to register alt modes\n",
 825                        con->num);
 826
 827        /* Get the status */
 828        command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
 829        ret = ucsi_run_command(ucsi, command, &con->status,
 830                               sizeof(con->status));
 831        if (ret < 0) {
 832                dev_err(ucsi->dev, "con%d: failed to get status\n", con->num);
 833                return 0;
 834        }
 835
 836        switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
 837        case UCSI_CONSTAT_PARTNER_TYPE_UFP:
 838                typec_set_data_role(con->port, TYPEC_HOST);
 839                break;
 840        case UCSI_CONSTAT_PARTNER_TYPE_DFP:
 841                typec_set_data_role(con->port, TYPEC_DEVICE);
 842                break;
 843        default:
 844                break;
 845        }
 846
 847        /* Check if there is already something connected */
 848        if (con->status.flags & UCSI_CONSTAT_CONNECTED) {
 849                typec_set_pwr_role(con->port,
 850                                  !!(con->status.flags & UCSI_CONSTAT_PWR_DIR));
 851                ucsi_pwr_opmode_change(con);
 852                ucsi_register_partner(con);
 853        }
 854
 855        if (con->partner) {
 856                ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
 857                if (ret)
 858                        dev_err(ucsi->dev,
 859                                "con%d: failed to register alternate modes\n",
 860                                con->num);
 861                else
 862                        ucsi_altmode_update_active(con);
 863        }
 864
 865        trace_ucsi_register_port(con->num, &con->status);
 866
 867        return 0;
 868}
 869
 870/**
 871 * ucsi_init - Initialize UCSI interface
 872 * @ucsi: UCSI to be initialized
 873 *
 874 * Registers all ports @ucsi has and enables all notification events.
 875 */
 876int ucsi_init(struct ucsi *ucsi)
 877{
 878        struct ucsi_connector *con;
 879        u64 command;
 880        int ret;
 881        int i;
 882
 883        mutex_lock(&ucsi->ppm_lock);
 884
 885        /* Reset the PPM */
 886        ret = ucsi_reset_ppm(ucsi);
 887        if (ret) {
 888                dev_err(ucsi->dev, "failed to reset PPM!\n");
 889                goto err;
 890        }
 891
 892        /* Enable basic notifications */
 893        command = UCSI_SET_NOTIFICATION_ENABLE;
 894        command |= UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
 895        ret = ucsi_run_command(ucsi, command, NULL, 0);
 896        if (ret < 0)
 897                goto err_reset;
 898
 899        /* Get PPM capabilities */
 900        command = UCSI_GET_CAPABILITY;
 901        ret = ucsi_run_command(ucsi, command, &ucsi->cap, sizeof(ucsi->cap));
 902        if (ret < 0)
 903                goto err_reset;
 904
 905        if (!ucsi->cap.num_connectors) {
 906                ret = -ENODEV;
 907                goto err_reset;
 908        }
 909
 910        /* Allocate the connectors. Released in ucsi_unregister_ppm() */
 911        ucsi->connector = kcalloc(ucsi->cap.num_connectors + 1,
 912                                  sizeof(*ucsi->connector), GFP_KERNEL);
 913        if (!ucsi->connector) {
 914                ret = -ENOMEM;
 915                goto err_reset;
 916        }
 917
 918        /* Register all connectors */
 919        for (i = 0; i < ucsi->cap.num_connectors; i++) {
 920                ret = ucsi_register_port(ucsi, i);
 921                if (ret)
 922                        goto err_unregister;
 923        }
 924
 925        /* Enable all notifications */
 926        command = UCSI_SET_NOTIFICATION_ENABLE | UCSI_ENABLE_NTFY_ALL;
 927        ret = ucsi_run_command(ucsi, command, NULL, 0);
 928        if (ret < 0)
 929                goto err_unregister;
 930
 931        mutex_unlock(&ucsi->ppm_lock);
 932
 933        return 0;
 934
 935err_unregister:
 936        for (con = ucsi->connector; con->port; con++) {
 937                ucsi_unregister_partner(con);
 938                ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON);
 939                typec_unregister_port(con->port);
 940                con->port = NULL;
 941        }
 942
 943err_reset:
 944        ucsi_reset_ppm(ucsi);
 945err:
 946        mutex_unlock(&ucsi->ppm_lock);
 947
 948        return ret;
 949}
 950EXPORT_SYMBOL_GPL(ucsi_init);
 951
 952static void ucsi_init_work(struct work_struct *work)
 953{
 954        struct ucsi *ucsi = container_of(work, struct ucsi, work);
 955        int ret;
 956
 957        ret = ucsi_init(ucsi);
 958        if (ret)
 959                dev_err(ucsi->dev, "PPM init failed (%d)\n", ret);
 960}
 961
 962/**
 963 * ucsi_get_drvdata - Return private driver data pointer
 964 * @ucsi: UCSI interface
 965 */
 966void *ucsi_get_drvdata(struct ucsi *ucsi)
 967{
 968        return ucsi->driver_data;
 969}
 970EXPORT_SYMBOL_GPL(ucsi_get_drvdata);
 971
 972/**
 973 * ucsi_get_drvdata - Assign private driver data pointer
 974 * @ucsi: UCSI interface
 975 * @data: Private data pointer
 976 */
 977void ucsi_set_drvdata(struct ucsi *ucsi, void *data)
 978{
 979        ucsi->driver_data = data;
 980}
 981EXPORT_SYMBOL_GPL(ucsi_set_drvdata);
 982
 983/**
 984 * ucsi_create - Allocate UCSI instance
 985 * @dev: Device interface to the PPM (Platform Policy Manager)
 986 * @ops: I/O routines
 987 */
 988struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
 989{
 990        struct ucsi *ucsi;
 991
 992        if (!ops || !ops->read || !ops->sync_write || !ops->async_write)
 993                return ERR_PTR(-EINVAL);
 994
 995        ucsi = kzalloc(sizeof(*ucsi), GFP_KERNEL);
 996        if (!ucsi)
 997                return ERR_PTR(-ENOMEM);
 998
 999        INIT_WORK(&ucsi->work, ucsi_init_work);
1000        mutex_init(&ucsi->ppm_lock);
1001        ucsi->dev = dev;
1002        ucsi->ops = ops;
1003
1004        return ucsi;
1005}
1006EXPORT_SYMBOL_GPL(ucsi_create);
1007
1008/**
1009 * ucsi_destroy - Free UCSI instance
1010 * @ucsi: UCSI instance to be freed
1011 */
1012void ucsi_destroy(struct ucsi *ucsi)
1013{
1014        kfree(ucsi);
1015}
1016EXPORT_SYMBOL_GPL(ucsi_destroy);
1017
1018/**
1019 * ucsi_register - Register UCSI interface
1020 * @ucsi: UCSI instance
1021 */
1022int ucsi_register(struct ucsi *ucsi)
1023{
1024        int ret;
1025
1026        ret = ucsi->ops->read(ucsi, UCSI_VERSION, &ucsi->version,
1027                              sizeof(ucsi->version));
1028        if (ret)
1029                return ret;
1030
1031        if (!ucsi->version)
1032                return -ENODEV;
1033
1034        queue_work(system_long_wq, &ucsi->work);
1035
1036        return 0;
1037}
1038EXPORT_SYMBOL_GPL(ucsi_register);
1039
1040/**
1041 * ucsi_unregister - Unregister UCSI interface
1042 * @ucsi: UCSI interface to be unregistered
1043 *
1044 * Unregister UCSI interface that was created with ucsi_register().
1045 */
1046void ucsi_unregister(struct ucsi *ucsi)
1047{
1048        u64 cmd = UCSI_SET_NOTIFICATION_ENABLE;
1049        int i;
1050
1051        /* Make sure that we are not in the middle of driver initialization */
1052        cancel_work_sync(&ucsi->work);
1053
1054        /* Disable notifications */
1055        ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
1056
1057        for (i = 0; i < ucsi->cap.num_connectors; i++) {
1058                cancel_work_sync(&ucsi->connector[i].work);
1059                ucsi_unregister_partner(&ucsi->connector[i]);
1060                ucsi_unregister_altmodes(&ucsi->connector[i],
1061                                         UCSI_RECIPIENT_CON);
1062                typec_unregister_port(ucsi->connector[i].port);
1063        }
1064
1065        kfree(ucsi->connector);
1066}
1067EXPORT_SYMBOL_GPL(ucsi_unregister);
1068
1069MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
1070MODULE_LICENSE("GPL v2");
1071MODULE_DESCRIPTION("USB Type-C Connector System Software Interface driver");
1072