From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [v4,5/6] usb: roles: add USB Type-B GPIO connector driver From: Chunfeng Yun Message-Id: <1556261237-13823-6-git-send-email-chunfeng.yun@mediatek.com> Date: Fri, 26 Apr 2019 14:47:16 +0800 To: Rob Herring , Greg Kroah-Hartman , Heikki Krogerus Cc: Mark Rutland , Chunfeng Yun , Matthias Brugger , Adam Thomson , Li Jun , Badhri Jagan Sridharan , Hans de Goede , Andy Shevchenko , Min Guo , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Biju Das , Linus Walleij List-ID: RHVlIHRvIHRoZSByZXF1aXJlbWVudCBvZiB1c2ItY29ubmVjdG9yLnR4dCBiaW5kaW5nLCB0aGUg b2xkIHdheQp1c2luZyBleHRjb24gdG8gc3VwcG9ydCBVU0IgRHVhbC1Sb2xlIHN3aXRjaCBpcyBu b3cgZGVwcmVjYXRlZAp3aGVuIHVzZSBUeXBlLUIgY29ubmVjdG9yLgpUaGlzIHBhdGNoIGludHJv ZHVjZXMgYSBkcml2ZXIgb2YgVHlwZS1CIGNvbm5lY3RvciB3aGljaCB0eXBpY2FsbHkKdXNlcyBh biBpbnB1dCBHUElPIHRvIGRldGVjdCBVU0IgSUQgcGluLCBhbmQgdHJ5IHRvIHJlcGxhY2UgdGhl CmZ1bmN0aW9uIHByb3ZpZGVkIGJ5IGV4dGNvbi11c2ItZ3BpbyBkcml2ZXIKClNpZ25lZC1vZmYt Ynk6IENodW5mZW5nIFl1biA8Y2h1bmZlbmcueXVuQG1lZGlhdGVrLmNvbT4KLS0tCnY0IGNoYW5n ZXM6CiAgMS4gcmVtb3ZlIGxpbnV4L2dwaW8uaCBzdWdnZXN0ZWQgYnkgTGludXMKICAyLiBwdXQg bm9kZSB3aGVuIGVycm9yIGhhcHBlbnMKCnYzIGNoYW5nZXM6CiAgMS4gdHJlYXQgYnlwZS1CIGNv bm5lY3RvciBhcyBhIHZpcnR1YWwgZGV2aWNlOwogIDIuIGNoYW5nZSBmaWxlIG5hbWUgYWdhaW4K CnYyIGNoYW5nZXM6CiAgMS4gZmlsZSBuYW1lIGlzIGNoYW5nZWQKICAyLiB1c2UgbmV3IGNvbXBh dGlibGUKLS0tCiBkcml2ZXJzL3VzYi9yb2xlcy9LY29uZmlnICAgICAgICAgICB8ICAxMSArCiBk cml2ZXJzL3VzYi9yb2xlcy9NYWtlZmlsZSAgICAgICAgICB8ICAgMSArCiBkcml2ZXJzL3VzYi9y b2xlcy90eXBlYi1jb25uLWdwaW8uYyB8IDMwNSArKysrKysrKysrKysrKysrKysrKysrKysrKysr CiAzIGZpbGVzIGNoYW5nZWQsIDMxNyBpbnNlcnRpb25zKCspCiBjcmVhdGUgbW9kZSAxMDA2NDQg ZHJpdmVycy91c2Ivcm9sZXMvdHlwZWItY29ubi1ncGlvLmMKCmRpZmYgLS1naXQgYS9kcml2ZXJz L3VzYi9yb2xlcy9LY29uZmlnIGIvZHJpdmVycy91c2Ivcm9sZXMvS2NvbmZpZwppbmRleCBmOGIz MWFhNjc1MjYuLmQxMTU2ZTE4YTgxYSAxMDA2NDQKLS0tIGEvZHJpdmVycy91c2Ivcm9sZXMvS2Nv bmZpZworKysgYi9kcml2ZXJzL3VzYi9yb2xlcy9LY29uZmlnCkBAIC0yNiw0ICsyNiwxNSBAQCBj b25maWcgVVNCX1JPTEVTX0lOVEVMX1hIQ0kKIAkgIFRvIGNvbXBpbGUgdGhlIGRyaXZlciBhcyBh IG1vZHVsZSwgY2hvb3NlIE0gaGVyZTogdGhlIG1vZHVsZSB3aWxsCiAJICBiZSBjYWxsZWQgaW50 ZWwteGhjaS11c2Itcm9sZS1zd2l0Y2guCiAKK2NvbmZpZyBUWVBFQl9DT05OX0dQSU8KKwl0cmlz dGF0ZSAiVVNCIFR5cGUtQiBHUElPIENvbm5lY3RvciIKKwlkZXBlbmRzIG9uIEdQSU9MSUIKKwlo ZWxwCisJICBUaGUgZHJpdmVyIHN1cHBvcnRzIFVTQiByb2xlIHN3aXRjaCBiZXR3ZWVuIGhvc3Qg YW5kIGRldmljZSB2aWEgR1BJTworCSAgYmFzZWQgVVNCIGNhYmxlIGRldGVjdGlvbiwgdXNlZCB0 eXBpY2FsbHkgaWYgYW4gaW5wdXQgR1BJTyBpcyB1c2VkCisJICB0byBkZXRlY3QgVVNCIElEIHBp bi4KKworCSAgVG8gY29tcGlsZSB0aGUgZHJpdmVyIGFzIGEgbW9kdWxlLCBjaG9vc2UgTSBoZXJl OiB0aGUgbW9kdWxlIHdpbGwKKwkgIGJlIGNhbGxlZCB0eXBlYi1jb25uLWdwaW8ua28KKwogZW5k aWYgIyBVU0JfUk9MRV9TV0lUQ0gKZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL3JvbGVzL01ha2Vm aWxlIGIvZHJpdmVycy91c2Ivcm9sZXMvTWFrZWZpbGUKaW5kZXggNzU3YTdkMjc5N2ViLi41ZDU2 MjBkOWQxMTMgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL3JvbGVzL01ha2VmaWxlCisrKyBiL2Ry aXZlcnMvdXNiL3JvbGVzL01ha2VmaWxlCkBAIC0zLDMgKzMsNCBAQAogb2JqLSQoQ09ORklHX1VT Ql9ST0xFX1NXSVRDSCkJCSs9IHJvbGVzLm8KIHJvbGVzLXkJCQkJCTo9IGNsYXNzLm8KIG9iai0k KENPTkZJR19VU0JfUk9MRVNfSU5URUxfWEhDSSkJKz0gaW50ZWwteGhjaS11c2Itcm9sZS1zd2l0 Y2gubworb2JqLSQoQ09ORklHX1RZUEVCX0NPTk5fR1BJTykJCSs9IHR5cGViLWNvbm4tZ3Bpby5v CmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9yb2xlcy90eXBlYi1jb25uLWdwaW8uYyBiL2RyaXZl cnMvdXNiL3JvbGVzL3R5cGViLWNvbm4tZ3Bpby5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4 IDAwMDAwMDAwMDAwMC4uMDk3ZDJjYTEyYTEyCi0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy91 c2Ivcm9sZXMvdHlwZWItY29ubi1ncGlvLmMKQEAgLTAsMCArMSwzMDUgQEAKKy8vIFNQRFgtTGlj ZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wCisvKgorICogVVNCIFR5cGUtQiBHUElPIENvbm5lY3Rv ciBEcml2ZXIKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMTkgTWVkaWFUZWsgSW5jLgorICoKKyAq IEF1dGhvcjogQ2h1bmZlbmcgWXVuIDxjaHVuZmVuZy55dW5AbWVkaWF0ZWsuY29tPgorICoKKyAq IFNvbWUgY29kZSBib3Jyb3dlZCBmcm9tIGRyaXZlcnMvZXh0Y29uL2V4dGNvbi11c2ItZ3Bpby5j CisgKi8KKworI2luY2x1ZGUgPGxpbnV4L2RldmljZS5oPgorI2luY2x1ZGUgPGxpbnV4L2dwaW8v Y29uc3VtZXIuaD4KKyNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KKyNpbmNsdWRlIDxsaW51 eC9pcnEuaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKyNpbmNsdWRlIDxsaW51eC9vZi5o PgorI2luY2x1ZGUgPGxpbnV4L29mX2dyYXBoLmg+CisjaW5jbHVkZSA8bGludXgvcGluY3RybC9j b25zdW1lci5oPgorI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgorI2luY2x1ZGUg PGxpbnV4L3JlZ3VsYXRvci9jb25zdW1lci5oPgorI2luY2x1ZGUgPGxpbnV4L3VzYi9yb2xlLmg+ CisKKyNkZWZpbmUgVVNCX0dQSU9fREVCX01TCQkyMAkvKiBtcyAqLworI2RlZmluZSBVU0JfR1BJ T19ERUJfVVMJCSgoVVNCX0dQSU9fREVCX01TKSAqIDEwMDApCS8qIHVzICovCisKKyNkZWZpbmUg VVNCX0NPTk5fSVJRRglcCisJKElSUUZfVFJJR0dFUl9SSVNJTkcgfCBJUlFGX1RSSUdHRVJfRkFM TElORyB8IElSUUZfT05FU0hPVCkKKworc3RydWN0IHVzYl9jb25uX2luZm8geworCXN0cnVjdCBk ZXZpY2UgKmRldjsKKwlzdHJ1Y3QgdXNiX3JvbGVfc3dpdGNoICpyb2xlX3N3OworCWVudW0gdXNi X3JvbGUgbGFzdF9yb2xlOworCXN0cnVjdCByZWd1bGF0b3IgKnZidXM7CisJc3RydWN0IGRlbGF5 ZWRfd29yayBkd19kZXQ7CisJdW5zaWduZWQgbG9uZyBkZWJvdW5jZV9qaWZmaWVzOworCisJc3Ry dWN0IGdwaW9fZGVzYyAqaWRfZ3Bpb2Q7CisJc3RydWN0IGdwaW9fZGVzYyAqdmJ1c19ncGlvZDsK KwlpbnQgaWRfaXJxOworCWludCB2YnVzX2lycTsKK307CisKKy8qKgorICogIkRFVklDRSIgPSBW QlVTIGFuZCAiSE9TVCIgPSAhSUQsIHNvIHdlIGhhdmU6CisgKiBCb3RoICJERVZJQ0UiIGFuZCAi SE9TVCIgY2FuJ3QgYmUgc2V0IGFzIGFjdGl2ZSBhdCB0aGUgc2FtZSB0aW1lCisgKiBzbyBpZiAi SE9TVCIgaXMgYWN0aXZlIChpLmUuIElEIGlzIDApICB3ZSBrZWVwICJERVZJQ0UiIGluYWN0aXZl CisgKiBldmVuIGlmIFZCVVMgaXMgb24uCisgKgorICogIFJvbGUgICAgICAgICAgfCAgIElEICB8 ICBWQlVTCisgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqICBbMV0g REVWSUNFICAgIHwgICBIICAgfCAgIEgKKyAqICBbMl0gTk9ORSAgICAgIHwgICBIICAgfCAgIEwK KyAqICBbM10gSE9TVCAgICAgIHwgICBMICAgfCAgIEgKKyAqICBbNF0gSE9TVCAgICAgIHwgICBM ICAgfCAgIEwKKyAqCisgKiBJbiBjYXNlIHdlIGhhdmUgb25seSBvbmUgb2YgdGhlc2Ugc2lnbmFs czoKKyAqIC0gVkJVUyBvbmx5IC0gd2Ugd2FudCB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIFsxXSBh bmQgWzJdLCBzbyBJRCBpcyBhbHdheXMgMQorICogLSBJRCBvbmx5IC0gd2Ugd2FudCB0byBkaXN0 aW5ndWlzaCBiZXR3ZWVuIFsxXSBhbmQgWzRdLCBzbyBWQlVTID0gSUQKKyAqLworc3RhdGljIHZv aWQgdXNiX2Nvbm5fZGV0ZWN0X2NhYmxlKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKK3sKKwlz dHJ1Y3QgdXNiX2Nvbm5faW5mbyAqaW5mbzsKKwllbnVtIHVzYl9yb2xlIHJvbGU7CisJaW50IGlk LCB2YnVzLCByZXQ7CisKKwlpbmZvID0gY29udGFpbmVyX29mKHRvX2RlbGF5ZWRfd29yayh3b3Jr KSwKKwkJCSAgICBzdHJ1Y3QgdXNiX2Nvbm5faW5mbywgZHdfZGV0KTsKKworCS8qIGNoZWNrIElE IGFuZCBWQlVTICovCisJaWQgPSBpbmZvLT5pZF9ncGlvZCA/CisJCWdwaW9kX2dldF92YWx1ZV9j YW5zbGVlcChpbmZvLT5pZF9ncGlvZCkgOiAxOworCXZidXMgPSBpbmZvLT52YnVzX2dwaW9kID8K KwkJZ3Bpb2RfZ2V0X3ZhbHVlX2NhbnNsZWVwKGluZm8tPnZidXNfZ3Bpb2QpIDogaWQ7CisKKwlp ZiAoIWlkKQorCQlyb2xlID0gVVNCX1JPTEVfSE9TVDsKKwllbHNlIGlmICh2YnVzKQorCQlyb2xl ID0gVVNCX1JPTEVfREVWSUNFOworCWVsc2UKKwkJcm9sZSA9IFVTQl9ST0xFX05PTkU7CisKKwlk ZXZfZGJnKGluZm8tPmRldiwgInJvbGUgJWQvJWQsIGdwaW9zOiBpZCAlZCwgdmJ1cyAlZFxuIiwK KwkJaW5mby0+bGFzdF9yb2xlLCByb2xlLCBpZCwgdmJ1cyk7CisKKwlpZiAoaW5mby0+bGFzdF9y b2xlID09IHJvbGUpIHsKKwkJZGV2X3dhcm4oaW5mby0+ZGV2LCAicmVwZWF0ZWQgcm9sZTogJWRc biIsIHJvbGUpOworCQlyZXR1cm47CisJfQorCisJaWYgKGluZm8tPmxhc3Rfcm9sZSA9PSBVU0Jf Uk9MRV9IT1NUKQorCQlyZWd1bGF0b3JfZGlzYWJsZShpbmZvLT52YnVzKTsKKworCXJldCA9IHVz Yl9yb2xlX3N3aXRjaF9zZXRfcm9sZShpbmZvLT5yb2xlX3N3LCByb2xlKTsKKwlpZiAocmV0KQor CQlkZXZfZXJyKGluZm8tPmRldiwgImZhaWxlZCB0byBzZXQgcm9sZTogJWRcbiIsIHJldCk7CisK KwlpZiAocm9sZSA9PSBVU0JfUk9MRV9IT1NUKSB7CisJCXJldCA9IHJlZ3VsYXRvcl9lbmFibGUo aW5mby0+dmJ1cyk7CisJCWlmIChyZXQpCisJCQlkZXZfZXJyKGluZm8tPmRldiwgImVuYWJsZSB2 YnVzIHJlZ3VsYXRvciBmYWlsZWRcbiIpOworCX0KKworCWluZm8tPmxhc3Rfcm9sZSA9IHJvbGU7 CisKKwlkZXZfZGJnKGluZm8tPmRldiwgInZidXMgcmVndWxhdG9yIGlzICVzXG4iLAorCQlyZWd1 bGF0b3JfaXNfZW5hYmxlZChpbmZvLT52YnVzKSA/ICJlbmFibGVkIiA6ICJkaXNhYmxlZCIpOwor fQorCitzdGF0aWMgdm9pZCB1c2JfY29ubl9xdWV1ZV9kd29yayhzdHJ1Y3QgdXNiX2Nvbm5faW5m byAqaW5mbywKKwkJCQkgdW5zaWduZWQgbG9uZyBkZWxheSkKK3sKKwlxdWV1ZV9kZWxheWVkX3dv cmsoc3lzdGVtX3Bvd2VyX2VmZmljaWVudF93cSwgJmluZm8tPmR3X2RldCwgZGVsYXkpOworfQor CitzdGF0aWMgaXJxcmV0dXJuX3QgdXNiX2Nvbm5faXNyKGludCBpcnEsIHZvaWQgKmRldl9pZCkK K3sKKwlzdHJ1Y3QgdXNiX2Nvbm5faW5mbyAqaW5mbyA9IGRldl9pZDsKKworCXVzYl9jb25uX3F1 ZXVlX2R3b3JrKGluZm8sIGluZm8tPmRlYm91bmNlX2ppZmZpZXMpOworCisJcmV0dXJuIElSUV9I QU5ETEVEOworfQorCitzdGF0aWMgaW50IHVzYl9jb25uX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXYpCit7CisJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKKwlzdHJ1 Y3QgZGV2aWNlX25vZGUgKm5wID0gZGV2LT5vZl9ub2RlOworCXN0cnVjdCBkZXZpY2Vfbm9kZSAq cGFyZW50OworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqY2hpbGQ7CisJc3RydWN0IHVzYl9jb25uX2lu Zm8gKmluZm87CisJaW50IHJldCA9IDA7CisKKwlpZiAoIW5wKQorCQlyZXR1cm4gLUVJTlZBTDsK KworCWluZm8gPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKmluZm8pLCBHRlBfS0VSTkVMKTsK KwlpZiAoIWluZm8pCisJCXJldHVybiAtRU5PTUVNOworCisJaW5mby0+ZGV2ID0gZGV2OworCisJ Y2hpbGQgPSBvZl9nZXRfY2hpbGRfYnlfbmFtZShucCwgImNvbm5lY3RvciIpOworCWlmICghY2hp bGQpIHsKKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZmluZCBjb25uZWN0b3Igbm9kZVxuIik7 CisJCXJldHVybiAtRU5PREVWOworCX0KKworCWluZm8tPmlkX2dwaW9kID0gZGV2bV9ncGlvZF9n ZXRfZnJvbV9vZl9ub2RlKAorCQkJCWRldiwgY2hpbGQsICJpZC1ncGlvcyIsIDAsIEdQSU9EX0lO LCAiaWRwaW4iKTsKKwlpZiAoSVNfRVJSKGluZm8tPmlkX2dwaW9kKSkgeworCQlvZl9ub2RlX3B1 dChjaGlsZCk7CisJCXJldHVybiBQVFJfRVJSKGluZm8tPmlkX2dwaW9kKTsKKwl9CisKKwlpbmZv LT52YnVzX2dwaW9kID0gZGV2bV9ncGlvZF9nZXRfZnJvbV9vZl9ub2RlKAorCQkJCWRldiwgY2hp bGQsICJ2YnVzLWdwaW9zIiwgMCwgR1BJT0RfSU4sCisJCQkJInZidXNwaW4iKTsKKwlpZiAoSVNf RVJSKGluZm8tPnZidXNfZ3Bpb2QpKSB7CisJCW9mX25vZGVfcHV0KGNoaWxkKTsKKwkJcmV0dXJu IFBUUl9FUlIoaW5mby0+dmJ1c19ncGlvZCk7CisJfQorCisJaWYgKCFpbmZvLT5pZF9ncGlvZCAm JiAhaW5mby0+dmJ1c19ncGlvZCkgeworCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBnZXQgZ3Bp b3NcbiIpOworCQlyZXR1cm4gLUVOT0RFVjsKKwl9CisKKwlvZl9ub2RlX3B1dChjaGlsZCk7CisK KwlpZiAoaW5mby0+aWRfZ3Bpb2QpCisJCXJldCA9IGdwaW9kX3NldF9kZWJvdW5jZShpbmZvLT5p ZF9ncGlvZCwgVVNCX0dQSU9fREVCX1VTKTsKKwlpZiAoIXJldCAmJiBpbmZvLT52YnVzX2dwaW9k KQorCQlyZXQgPSBncGlvZF9zZXRfZGVib3VuY2UoaW5mby0+dmJ1c19ncGlvZCwgVVNCX0dQSU9f REVCX1VTKTsKKwlpZiAocmV0IDwgMCkKKwkJaW5mby0+ZGVib3VuY2VfamlmZmllcyA9IG1zZWNz X3RvX2ppZmZpZXMoVVNCX0dQSU9fREVCX01TKTsKKworCUlOSVRfREVMQVlFRF9XT1JLKCZpbmZv LT5kd19kZXQsIHVzYl9jb25uX2RldGVjdF9jYWJsZSk7CisKKwlpbmZvLT52YnVzID0gZGV2bV9y ZWd1bGF0b3JfZ2V0KGRldiwgInZidXMiKTsKKwlpZiAoSVNfRVJSKGluZm8tPnZidXMpKSB7CisJ CWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGdldCB2YnVzXG4iKTsKKwkJcmV0dXJuIFBUUl9FUlIo aW5mby0+dmJ1cyk7CisJfQorCisJY2hpbGQgPSBvZl9ncmFwaF9nZXRfZW5kcG9pbnRfYnlfcmVn cyhucCwgLTEsIDApOworCXBhcmVudCA9IG9mX2dyYXBoX2dldF9yZW1vdGVfcG9ydF9wYXJlbnQo Y2hpbGQpOworCWluZm8tPnJvbGVfc3cgPSBmd25vZGVfdXNiX3JvbGVfc3dpdGNoX2dldChvZl9m d25vZGVfaGFuZGxlKHBhcmVudCkpOworCW9mX25vZGVfcHV0KGNoaWxkKTsKKwlvZl9ub2RlX3B1 dChwYXJlbnQpOworCWlmIChJU19FUlIoaW5mby0+cm9sZV9zdykpIHsKKwkJZGV2X2VycihkZXYs ICJmYWlsZWQgdG8gZ2V0IHJvbGUgc3dpdGNoXG4iKTsKKwkJcmV0dXJuIFBUUl9FUlIoaW5mby0+ cm9sZV9zdyk7CisJfQorCisJaWYgKGluZm8tPmlkX2dwaW9kKSB7CisJCWluZm8tPmlkX2lycSA9 IGdwaW9kX3RvX2lycShpbmZvLT5pZF9ncGlvZCk7CisJCWlmIChpbmZvLT5pZF9pcnEgPCAwKSB7 CisJCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBnZXQgSUQgSVJRXG4iKTsKKwkJCXJldHVybiBp bmZvLT5pZF9pcnE7CisJCX0KKworCQlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRfaXJxKGRl diwgaW5mby0+aWRfaXJxLCBOVUxMLAorCQkJCQkJdXNiX2Nvbm5faXNyLCBVU0JfQ09OTl9JUlFG LAorCQkJCQkJcGRldi0+bmFtZSwgaW5mbyk7CisJCWlmIChyZXQgPCAwKSB7CisJCQlkZXZfZXJy KGRldiwgImZhaWxlZCB0byByZXF1ZXN0IElEIElSUVxuIik7CisJCQlyZXR1cm4gcmV0OworCQl9 CisJfQorCisJaWYgKGluZm8tPnZidXNfZ3Bpb2QpIHsKKwkJaW5mby0+dmJ1c19pcnEgPSBncGlv ZF90b19pcnEoaW5mby0+dmJ1c19ncGlvZCk7CisJCWlmIChpbmZvLT52YnVzX2lycSA8IDApIHsK KwkJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGdldCBWQlVTIElSUVxuIik7CisJCQlyZXR1cm4g aW5mby0+dmJ1c19pcnE7CisJCX0KKworCQlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRfaXJx KGRldiwgaW5mby0+dmJ1c19pcnEsIE5VTEwsCisJCQkJCQl1c2JfY29ubl9pc3IsIFVTQl9DT05O X0lSUUYsCisJCQkJCQlwZGV2LT5uYW1lLCBpbmZvKTsKKwkJaWYgKHJldCA8IDApIHsKKwkJCWRl dl9lcnIoZGV2LCAiZmFpbGVkIHRvIHJlcXVlc3QgVkJVUyBJUlFcbiIpOworCQkJcmV0dXJuIHJl dDsKKwkJfQorCX0KKworCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGluZm8pOworCisJLyog UGVyZm9ybSBpbml0aWFsIGRldGVjdGlvbiAqLworCXVzYl9jb25uX3F1ZXVlX2R3b3JrKGluZm8s IDApOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgdXNiX2Nvbm5fcmVtb3ZlKHN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCit7CisJc3RydWN0IHVzYl9jb25uX2luZm8gKmluZm8g PSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKKworCWNhbmNlbF9kZWxheWVkX3dvcmtfc3lu YygmaW5mby0+ZHdfZGV0KTsKKworCWlmIChpbmZvLT5sYXN0X3JvbGUgPT0gVVNCX1JPTEVfSE9T VCkKKwkJcmVndWxhdG9yX2Rpc2FibGUoaW5mby0+dmJ1cyk7CisKKwl1c2Jfcm9sZV9zd2l0Y2hf cHV0KGluZm8tPnJvbGVfc3cpOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgX19tYXli ZV91bnVzZWQgdXNiX2Nvbm5fc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJc3RydWN0 IHVzYl9jb25uX2luZm8gKmluZm8gPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKKworCWlmIChpbmZv LT5pZF9ncGlvZCkKKwkJZGlzYWJsZV9pcnEoaW5mby0+aWRfaXJxKTsKKwlpZiAoaW5mby0+dmJ1 c19ncGlvZCkKKwkJZGlzYWJsZV9pcnEoaW5mby0+dmJ1c19pcnEpOworCisJcGluY3RybF9wbV9z ZWxlY3Rfc2xlZXBfc3RhdGUoZGV2KTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IF9f bWF5YmVfdW51c2VkIHVzYl9jb25uX3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJc3Ry dWN0IHVzYl9jb25uX2luZm8gKmluZm8gPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKKworCXBpbmN0 cmxfcG1fc2VsZWN0X2RlZmF1bHRfc3RhdGUoZGV2KTsKKworCWlmIChpbmZvLT5pZF9ncGlvZCkK KwkJZW5hYmxlX2lycShpbmZvLT5pZF9pcnEpOworCWlmIChpbmZvLT52YnVzX2dwaW9kKQorCQll bmFibGVfaXJxKGluZm8tPnZidXNfaXJxKTsKKworCXVzYl9jb25uX3F1ZXVlX2R3b3JrKGluZm8s IDApOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBTSU1QTEVfREVWX1BNX09QUyh1c2JfY29u bl9wbV9vcHMsCisJCQkgdXNiX2Nvbm5fc3VzcGVuZCwgdXNiX2Nvbm5fcmVzdW1lKTsKKworI2Rl ZmluZSBERVZfUE1TX09QUyAoSVNfRU5BQkxFRChDT05GSUdfUE1fU0xFRVApID8gJnVzYl9jb25u X3BtX29wcyA6IE5VTEwpCisKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIHVzYl9j b25uX2R0X21hdGNoW10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJsaW51eCx0eXBlYi1jb25uLWdw aW8iLCB9LAorCXsgfQorfTsKK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIHVzYl9jb25uX2R0X21h dGNoKTsKKworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgdXNiX2Nvbm5fZHJpdmVyID0g eworCS5wcm9iZQkJPSB1c2JfY29ubl9wcm9iZSwKKwkucmVtb3ZlCQk9IHVzYl9jb25uX3JlbW92 ZSwKKwkuZHJpdmVyCQk9IHsKKwkJLm5hbWUJPSAidHlwZWItY29ubi1ncGlvIiwKKwkJLnBtCT0g REVWX1BNU19PUFMsCisJCS5vZl9tYXRjaF90YWJsZSA9IHVzYl9jb25uX2R0X21hdGNoLAorCX0s Cit9OworCittb2R1bGVfcGxhdGZvcm1fZHJpdmVyKHVzYl9jb25uX2RyaXZlcik7CisKK01PRFVM RV9BVVRIT1IoIkNodW5mZW5nIFl1biA8Y2h1bmZlbmcueXVuQG1lZGlhdGVrLmNvbT4iKTsKK01P RFVMRV9ERVNDUklQVElPTigiVVNCIFR5cGUtQiBHUElPIGNvbm5lY3RvciBkcml2ZXIiKTsKK01P RFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsK From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.9 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D599BC43218 for ; Fri, 26 Apr 2019 06:48:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9DD69206DD for ; Fri, 26 Apr 2019 06:48:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726321AbfDZGr4 (ORCPT ); Fri, 26 Apr 2019 02:47:56 -0400 Received: from Mailgw01.mediatek.com ([1.203.163.78]:30606 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726065AbfDZGry (ORCPT ); Fri, 26 Apr 2019 02:47:54 -0400 X-UUID: a2617321b56145769ac57800272f8e1f-20190426 X-UUID: a2617321b56145769ac57800272f8e1f-20190426 Received: from mtkcas34.mediatek.inc [(172.27.4.253)] by mailgw01.mediatek.com (envelope-from ) (mailgw01.mediatek.com ESMTP with TLS) with ESMTP id 611823525; Fri, 26 Apr 2019 14:47:42 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by MTKMBS31N2.mediatek.inc (172.27.4.87) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Fri, 26 Apr 2019 14:47:40 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Fri, 26 Apr 2019 14:47:39 +0800 From: Chunfeng Yun To: Rob Herring , Greg Kroah-Hartman , Heikki Krogerus CC: Mark Rutland , Chunfeng Yun , Matthias Brugger , Adam Thomson , Li Jun , Badhri Jagan Sridharan , Hans de Goede , Andy Shevchenko , Min Guo , , , , , , Biju Das , Linus Walleij Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver Date: Fri, 26 Apr 2019 14:47:16 +0800 Message-ID: <1556261237-13823-6-git-send-email-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1556261237-13823-1-git-send-email-chunfeng.yun@mediatek.com> References: <1556261237-13823-1-git-send-email-chunfeng.yun@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" X-MTK: N Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Message-ID: <20190426064716.4x8ePoqhLVSmq4but1Uz_es3pPOiYAgei4JZfiYEiic@z> Due to the requirement of usb-connector.txt binding, the old way using extcon to support USB Dual-Role switch is now deprecated when use Type-B connector. This patch introduces a driver of Type-B connector which typically uses an input GPIO to detect USB ID pin, and try to replace the function provided by extcon-usb-gpio driver Signed-off-by: Chunfeng Yun --- v4 changes: 1. remove linux/gpio.h suggested by Linus 2. put node when error happens v3 changes: 1. treat bype-B connector as a virtual device; 2. change file name again v2 changes: 1. file name is changed 2. use new compatible --- drivers/usb/roles/Kconfig | 11 + drivers/usb/roles/Makefile | 1 + drivers/usb/roles/typeb-conn-gpio.c | 305 ++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 drivers/usb/roles/typeb-conn-gpio.c diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index f8b31aa67526..d1156e18a81a 100644 --- a/drivers/usb/roles/Kconfig +++ b/drivers/usb/roles/Kconfig @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI To compile the driver as a module, choose M here: the module will be called intel-xhci-usb-role-switch. +config TYPEB_CONN_GPIO + tristate "USB Type-B GPIO Connector" + depends on GPIOLIB + help + The driver supports USB role switch between host and device via GPIO + based USB cable detection, used typically if an input GPIO is used + to detect USB ID pin. + + To compile the driver as a module, choose M here: the module will + be called typeb-conn-gpio.ko + endif # USB_ROLE_SWITCH diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index 757a7d2797eb..5d5620d9d113 100644 --- a/drivers/usb/roles/Makefile +++ b/drivers/usb/roles/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o roles-y := class.o obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb-conn-gpio.c new file mode 100644 index 000000000000..097d2ca12a12 --- /dev/null +++ b/drivers/usb/roles/typeb-conn-gpio.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * USB Type-B GPIO Connector Driver + * + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Chunfeng Yun + * + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USB_GPIO_DEB_MS 20 /* ms */ +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ + +#define USB_CONN_IRQF \ + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT) + +struct usb_conn_info { + struct device *dev; + struct usb_role_switch *role_sw; + enum usb_role last_role; + struct regulator *vbus; + struct delayed_work dw_det; + unsigned long debounce_jiffies; + + struct gpio_desc *id_gpiod; + struct gpio_desc *vbus_gpiod; + int id_irq; + int vbus_irq; +}; + +/** + * "DEVICE" = VBUS and "HOST" = !ID, so we have: + * Both "DEVICE" and "HOST" can't be set as active at the same time + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive + * even if VBUS is on. + * + * Role | ID | VBUS + * ------------------------------------ + * [1] DEVICE | H | H + * [2] NONE | H | L + * [3] HOST | L | H + * [4] HOST | L | L + * + * In case we have only one of these signals: + * - VBUS only - we want to distinguish between [1] and [2], so ID is always 1 + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID + */ +static void usb_conn_detect_cable(struct work_struct *work) +{ + struct usb_conn_info *info; + enum usb_role role; + int id, vbus, ret; + + info = container_of(to_delayed_work(work), + struct usb_conn_info, dw_det); + + /* check ID and VBUS */ + id = info->id_gpiod ? + gpiod_get_value_cansleep(info->id_gpiod) : 1; + vbus = info->vbus_gpiod ? + gpiod_get_value_cansleep(info->vbus_gpiod) : id; + + if (!id) + role = USB_ROLE_HOST; + else if (vbus) + role = USB_ROLE_DEVICE; + else + role = USB_ROLE_NONE; + + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", + info->last_role, role, id, vbus); + + if (info->last_role == role) { + dev_warn(info->dev, "repeated role: %d\n", role); + return; + } + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + ret = usb_role_switch_set_role(info->role_sw, role); + if (ret) + dev_err(info->dev, "failed to set role: %d\n", ret); + + if (role == USB_ROLE_HOST) { + ret = regulator_enable(info->vbus); + if (ret) + dev_err(info->dev, "enable vbus regulator failed\n"); + } + + info->last_role = role; + + dev_dbg(info->dev, "vbus regulator is %s\n", + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); +} + +static void usb_conn_queue_dwork(struct usb_conn_info *info, + unsigned long delay) +{ + queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay); +} + +static irqreturn_t usb_conn_isr(int irq, void *dev_id) +{ + struct usb_conn_info *info = dev_id; + + usb_conn_queue_dwork(info, info->debounce_jiffies); + + return IRQ_HANDLED; +} + +static int usb_conn_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *parent; + struct device_node *child; + struct usb_conn_info *info; + int ret = 0; + + if (!np) + return -EINVAL; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = dev; + + child = of_get_child_by_name(np, "connector"); + if (!child) { + dev_err(dev, "failed to find connector node\n"); + return -ENODEV; + } + + info->id_gpiod = devm_gpiod_get_from_of_node( + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); + if (IS_ERR(info->id_gpiod)) { + of_node_put(child); + return PTR_ERR(info->id_gpiod); + } + + info->vbus_gpiod = devm_gpiod_get_from_of_node( + dev, child, "vbus-gpios", 0, GPIOD_IN, + "vbuspin"); + if (IS_ERR(info->vbus_gpiod)) { + of_node_put(child); + return PTR_ERR(info->vbus_gpiod); + } + + if (!info->id_gpiod && !info->vbus_gpiod) { + dev_err(dev, "failed to get gpios\n"); + return -ENODEV; + } + + of_node_put(child); + + if (info->id_gpiod) + ret = gpiod_set_debounce(info->id_gpiod, USB_GPIO_DEB_US); + if (!ret && info->vbus_gpiod) + ret = gpiod_set_debounce(info->vbus_gpiod, USB_GPIO_DEB_US); + if (ret < 0) + info->debounce_jiffies = msecs_to_jiffies(USB_GPIO_DEB_MS); + + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); + + info->vbus = devm_regulator_get(dev, "vbus"); + if (IS_ERR(info->vbus)) { + dev_err(dev, "failed to get vbus\n"); + return PTR_ERR(info->vbus); + } + + child = of_graph_get_endpoint_by_regs(np, -1, 0); + parent = of_graph_get_remote_port_parent(child); + info->role_sw = fwnode_usb_role_switch_get(of_fwnode_handle(parent)); + of_node_put(child); + of_node_put(parent); + if (IS_ERR(info->role_sw)) { + dev_err(dev, "failed to get role switch\n"); + return PTR_ERR(info->role_sw); + } + + if (info->id_gpiod) { + info->id_irq = gpiod_to_irq(info->id_gpiod); + if (info->id_irq < 0) { + dev_err(dev, "failed to get ID IRQ\n"); + return info->id_irq; + } + + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request ID IRQ\n"); + return ret; + } + } + + if (info->vbus_gpiod) { + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); + if (info->vbus_irq < 0) { + dev_err(dev, "failed to get VBUS IRQ\n"); + return info->vbus_irq; + } + + ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request VBUS IRQ\n"); + return ret; + } + } + + platform_set_drvdata(pdev, info); + + /* Perform initial detection */ + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static int usb_conn_remove(struct platform_device *pdev) +{ + struct usb_conn_info *info = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&info->dw_det); + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + usb_role_switch_put(info->role_sw); + + return 0; +} + +static int __maybe_unused usb_conn_suspend(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + if (info->id_gpiod) + disable_irq(info->id_irq); + if (info->vbus_gpiod) + disable_irq(info->vbus_irq); + + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int __maybe_unused usb_conn_resume(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + pinctrl_pm_select_default_state(dev); + + if (info->id_gpiod) + enable_irq(info->id_irq); + if (info->vbus_gpiod) + enable_irq(info->vbus_irq); + + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, + usb_conn_suspend, usb_conn_resume); + +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? &usb_conn_pm_ops : NULL) + +static const struct of_device_id usb_conn_dt_match[] = { + { .compatible = "linux,typeb-conn-gpio", }, + { } +}; +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); + +static struct platform_driver usb_conn_driver = { + .probe = usb_conn_probe, + .remove = usb_conn_remove, + .driver = { + .name = "typeb-conn-gpio", + .pm = DEV_PMS_OPS, + .of_match_table = usb_conn_dt_match, + }, +}; + +module_platform_driver(usb_conn_driver); + +MODULE_AUTHOR("Chunfeng Yun "); +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); +MODULE_LICENSE("GPL v2"); -- 2.21.0