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: USB: serial: cp210x: Implement GPIO support for CP2102N From: Johan Hovold Message-Id: <20180620082507.GO32411@localhost> Date: Wed, 20 Jun 2018 10:25:07 +0200 To: Karoly Pados Cc: Johan Hovold , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org List-ID: T24gU3VuLCBKdW4gMTcsIDIwMTggYXQgMDg6MjU6MDNQTSArMDIwMCwgS2Fyb2x5IFBhZG9zIHdy b3RlOgo+IFByZXR0eSBtdWNoIHdoYXQgdGhlIHRpdGxlIHNheXMuIE5vIG90aGVyIGZ1bmN0aW9u cy9kZXZpY2VzCj4gdG91Y2hlZC4gVGVzdGVkIG9uIENQMjEwMk4tUUZOMjguCj4gCj4gTGltaXRh dGlvbjogRXZlbiB0aG91Z2ggdGhlIFFGTjI4IHBhY2thZ2UgaGFzIDcgR1BJT3MsCj4gdGhpcyBw YXRjaCBhbGxvd3MgdG8gY29udHJvbCBvbmx5IHRoZSBmaXJzdCA0Lgo+IFdoYXQgSSd2ZSBmb3Vu ZCB1c2luZyByZXZlcnNlIGVuZ2luZWVyaW5nIHJlZ2FyZGluZyB0aGUKPiBvdGhlciAzIHBpbnMg Y29sbGlkZXMgYm90aCB3aXRoIHJlYWxpdHkgYW5kIHdpdGggb3RoZXIKPiBkb2N1bWVudGVkIGZ1 bmN0aW9ucywgc28gSSBkaWQgbm90IGRhcmUgdG8ganVzdCB1c2UgbXkKPiBmaW5kaW5ncyBiZWNh dXNlIEkgY2Fubm90IHRlc3Qgb24gb3RoZXIgcGFja2FnZXMuCj4gSW5zdGVhZCwgSSBkZWNpZGVk IHRvIHBsYXkgaXQgc2FmZSBhbmQgb25seSBzdXBwb3J0IDQgR1BJT3MuCgpUaGFua3MgZm9yIHRo ZSBwYXRjaC4gTmljZSB0byBzZWUgdGhpcyBmaW5hbGx5IGJlIGltcGxlbWVudGVkIGZvcgpmdXJ0 aGVyIGRldmljZSB0eXBlcy4KCllvdSdyZSBnb25uYSBuZWVkIHRvIHVuaWZ5IGEgbG90IG9mIHRo aXMgd2l0aCB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbgpmb3IgY3AyMTA1IGhvd2V2ZXIuCgo+ IFNpZ25lZC1vZmYtYnk6IEthcm9seSBQYWRvcyA8cGFkb3NAcGFkb3MuaHU+Cj4gLS0tCj4gIGRy aXZlcnMvdXNiL3NlcmlhbC9jcDIxMHguYyB8IDI1OSArKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKy0KPiAgMSBmaWxlIGNoYW5nZWQsIDI1NyBpbnNlcnRpb25zKCspLCAyIGRlbGV0 aW9ucygtKQo+IAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9zZXJpYWwvY3AyMTB4LmMgYi9k cml2ZXJzL3VzYi9zZXJpYWwvY3AyMTB4LmMKPiBpbmRleCA3OTNiODYyNTJjNDYuLmFkYjQ1MDE4 NWNlOCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3VzYi9zZXJpYWwvY3AyMTB4LmMKPiArKysgYi9k cml2ZXJzL3VzYi9zZXJpYWwvY3AyMTB4LmMKPiBAQCAtNiw3ICs2LDggQEAKPiAgICoKPiAgICog U3VwcG9ydCB0byBzZXQgZmxvdyBjb250cm9sIGxpbmUgbGV2ZWxzIHVzaW5nIFRJT0NNR0VUIGFu ZCBUSU9DTVNFVAo+ICAgKiB0aGFua3MgdG8gS2FybCBIaXJhbW90byBrYXJsQGhpcmFtb3RvLm9y Zy4gUlRTQ1RTIGhhcmR3YXJlIGZsb3cKPiAtICogY29udHJvbCB0aGFua3MgdG8gTXVuaXIgTmFz c2FyIG5hc3Nhcm11QHJlYWwtdGltZS5jb20KPiArICogY29udHJvbCB0aGFua3MgdG8gTXVuaXIg TmFzc2FyIG5hc3Nhcm11QHJlYWwtdGltZS5jb20uCj4gKyAqIEdQSU8gc3VwcG9ydCBmb3IgQ1Ay MTAyTiB0aGFua3MgdG8gS2Fyb2x5IFBhZG9zLgoKTm8gbmVlZCB0byB0aGFuayB5b3Vyc2VsZiBo ZXJlLiBUaGlzIHdhcyBhZGRlZCBieSB0aGUgb3JpZ2luYWwgYXV0aG9yCih3aG8gYXBwZWFycyB0 byBoYXZlIHBhcnRseSBiZWVuIGRldmVsb3BpbmcgdGhpcyBkcml2ZXIgb3V0LW9mLXRyZWUpIHRv CmNyZWRpdCBjb250cmlidXRlcnMuCgpUaGUgZ2l0IGxvZ3Mgd2lsbCBrZWVwIGEgcmVjb3JkIG9m IHlvdXIgY29udHJpYnV0aW9ucy4KCj4gICAqCj4gICAqLwo+ICAKPiBAQCAtMjI5LDExICsyMzAs MTYgQEAgc3RydWN0IGNwMjEweF9zZXJpYWxfcHJpdmF0ZSB7Cj4gIAlzdHJ1Y3QgZ3Bpb19jaGlw CWdjOwo+ICAJdTgJCQljb25maWc7Cj4gIAl1OAkJCWdwaW9fbW9kZTsKPiArCXU4CQkJZ3Bpb19j b250cm9sOwo+ICsJdTgJCQlncGlvX2RpcjsKPiAgCWJvb2wJCQlncGlvX3JlZ2lzdGVyZWQ7Cj4g ICNlbmRpZgo+ICAJdTgJCQlwYXJ0bnVtOwo+ICB9Owo+ICAKPiArI2RlZmluZSBDUDIxMDJOX1BJ Tl9PUEVORFJBSU4odmFyLCBwaW4pCSghKCh2YXIpICYgQklUKHBpbikpKQo+ICsjZGVmaW5lIENQ MjEwMk5fUElOX0dQSU8odmFyLCBwaW4pCSghKCh2YXIpICYgQklUKHBpbikpKQoKVGhlc2UgYXJl IGluIGZhY3Qgbm90IGNwMjEwMm4gc3BlY2lmaWMuIElmIHRoZXkgYXJlIGF0IGFsbCBuZWVkZWQg aW4gdGhlCmVuZCB0aGV5IHNob3VsZCBiZSBpbXBsZW1lbnRlZCBhcyBnZW5lcmljIHN0YXRpYyBm dW5jdGlvbnMuCgo+ICsKPiAgc3RydWN0IGNwMjEweF9wb3J0X3ByaXZhdGUgewo+ICAJX191OAkJ CWJJbnRlcmZhY2VOdW1iZXI7Cj4gIAlib29sCQkJaGFzX3N3YXBwZWRfbGluZV9jdGw7Cj4gQEAg LTM0OSw2ICszNTUsNyBAQCBzdGF0aWMgc3RydWN0IHVzYl9zZXJpYWxfZHJpdmVyICogY29uc3Qg c2VyaWFsX2RyaXZlcnNbXSA9IHsKPiAgI2RlZmluZSBDUDIxMFhfR0VUX1BPUlRDT05GSUcJMHgz NzBDCj4gICNkZWZpbmUgQ1AyMTBYX0dFVF9ERVZJQ0VNT0RFCTB4MzcxMQo+ICAjZGVmaW5lIENQ MjEwWF9XUklURV9MQVRDSAkweDM3RTEKPiArI2RlZmluZSBDUDIxMFhfUkVBRF8yTkNPTkZJRwkw eDAwMEUKCktlZXAgdGhlIGRlZmluZXMgc29ydGVkIGJ5IHZhbHVlLgoKPiAgLyogUGFydCBudW1i ZXIgZGVmaW5pdGlvbnMgKi8KPiAgI2RlZmluZSBDUDIxMFhfUEFSVE5VTV9DUDIxMDEJMHgwMQo+ IEBAIC0zNjIsNiArMzY5LDE0IEBAIHN0YXRpYyBzdHJ1Y3QgdXNiX3NlcmlhbF9kcml2ZXIgKiBj b25zdCBzZXJpYWxfZHJpdmVyc1tdID0gewo+ICAjZGVmaW5lIENQMjEwWF9QQVJUTlVNX0NQMjEw Mk5fUUZOMjAJMHgyMgo+ICAjZGVmaW5lIENQMjEwWF9QQVJUTlVNX1VOS05PV04JMHhGRgo+ICAK PiArI2RlZmluZQlJU19DUDIxMDJOKHBhcnRudW0pICAgKCgocGFydG51bSkgPT0gQ1AyMTBYX1BB UlROVU1fQ1AyMTAyTl9RRk4yOCkgfHwgXAo+ICsJCQkgICAgICAgKChwYXJ0bnVtKSA9PSBDUDIx MFhfUEFSVE5VTV9DUDIxMDJOX1FGTjI0KSB8fCBcCj4gKwkJCSAgICAgICAoKHBhcnRudW0pID09 IENQMjEwWF9QQVJUTlVNX0NQMjEwMk5fUUZOMjApKQoKU28gcmV1c2UgdGhlIHN0YXRpYyBoZWxw ZXIgSSBtZW50aW9uZWQgaW4gbXkgY29tbWVudHMgdG8gdGhlIGJhdWRyYXRlCnBhdGNoLgoKPiAr Cj4gKyNkZWZpbmUgQ1AyMTBYXzJOQ09ORklHX0dQSU9fQ09OVFJPTF9JRFgJNjAwCj4gKyNkZWZp bmUgQ1AyMTBYXzJOQ09ORklHX0dQSU9fTU9ERV9JRFgJCTU4MQo+ICsjZGVmaW5lIENQMjEwWF8y TkNPTkZJR19HUElPX1JTVExBVENIX0lEWAk1ODcKClNvcnQgYnkgdmFsdWUuCgo+ICsKPiAgLyog Q1AyMTBYX0dFVF9DT01NX1NUQVRVUyByZXR1cm5zIHRoZXNlIDB4MTMgYnl0ZXMgKi8KPiAgc3Ry dWN0IGNwMjEweF9jb21tX3N0YXR1cyB7Cj4gIAlfX2xlMzIgICB1bEVycm9yczsKPiBAQCAtMTQ1 NSw2ICsxNDcwLDIzNSBAQCBzdGF0aWMgdm9pZCBjcDIxMHhfZ3Bpb19yZW1vdmUoc3RydWN0IHVz Yl9zZXJpYWwgKnNlcmlhbCkKPiAgCX0KPiAgfQo+ICAKPiArc3RhdGljIGludCBjcDIxMDJuX2dw aW9fZ2V0KHN0cnVjdCBncGlvX2NoaXAgKmdjLCB1bnNpZ25lZCBpbnQgZ3BpbykKPiArewo+ICsJ c3RydWN0IHVzYl9zZXJpYWwgKnNlcmlhbCA9IGdwaW9jaGlwX2dldF9kYXRhKGdjKTsKPiArCWlu dCByZXN1bHQ7Cj4gKwl1OCBidWY7Cj4gKwo+ICsJcmVzdWx0ID0gY3AyMTB4X3JlYWRfdmVuZG9y X2Jsb2NrKHNlcmlhbCwgUkVRVFlQRV9ERVZJQ0VfVE9fSE9TVCwKPiArCQkJCQkgIENQMjEwWF9S RUFEX0xBVENILCAmYnVmLCBzaXplb2YoYnVmKSk7Cj4gKwlpZiAocmVzdWx0IDwgMCkKPiArCQly ZXR1cm4gcmVzdWx0Owo+ICsKPiArCXJldHVybiAhIShidWYgJiBCSVQoZ3BpbykpOwo+ICt9CgpU aGlzIHNob3VsZCBiZSBoYW5kbGVkIGluIGNwMjEweF9ncGlvX2dldCgpIGJ5IG1ha2luZyB0aGUg Y29udHJvbApyZXF1ZXN0IHR5cGUgZGVwZW5kIG9uIHRoZSBkZXZpY2UgdHlwZS4KCk1ha2UgdGhl IGNwMjEwMm4gYmVoYXZpb3VyIHRoZSBkZWZhdWx0IGFzIGl0IGlzIHVzZWQgYWxzbyBieSBzb21l IGxlZ2FjeQpkZXZpY2VzLCBhbmQgZXhwbGljaXRseSBjaGVjayBmb3IgdGhlIGNwMjEwNSBvZGQg YmlyZC4gV2UnbGwgZGVhbCB3aXRoCmNwMjEwOCwgd2hpY2ggMTYgZ3Bpb3MgYW5kIGhlbmNlIHVz ZXMgMTYtYml0IG1hc2ssIHdoZW4gd2UgZ2V0IHRoZXJlLgoKPiArCj4gK3N0YXRpYyB2b2lkIGNw MjEwMm5fZ3Bpb19zZXQoc3RydWN0IGdwaW9fY2hpcCAqZ2MsIHVuc2lnbmVkIGludCBncGlvLCBp bnQgdmFsdWUpCj4gK3sKPiArCWludCByZXN1bHQ7Cj4gKwlzdHJ1Y3QgY3AyMTB4X2dwaW9fd3Jp dGUgYnVmOwo+ICsJc3RydWN0IHVzYl9zZXJpYWwgKnNlcmlhbCA9IGdwaW9jaGlwX2dldF9kYXRh KGdjKTsKPiArCXN0cnVjdCBjcDIxMHhfc2VyaWFsX3ByaXZhdGUgKnByaXYgPSB1c2JfZ2V0X3Nl cmlhbF9kYXRhKHNlcmlhbCk7Cj4gKwo+ICsJLyogSWdub3JlIHJlcXVlc3QgaWYgcGluIGlzIG5v dCBpbiBvdXIgY29udHJvbCAqLwo+ICsJaWYgKCFDUDIxMDJOX1BJTl9HUElPKHByaXYtPmdwaW9f Y29udHJvbCwgZ3BpbykpIHsKPiArCQlkZXZfd2Fybigmc2VyaWFsLT5pbnRlcmZhY2UtPmRldiwK PiArCQkJICJDYW5ub3QgY29udHJvbCBHUElPIHdpdGggYWN0aXZlIGFsdGVybmF0ZSBmdW5jdGlv bi5cbiIpOwo+ICsJCXJldHVybjsKPiArCX0KCk5vIG5lZWQgdG8gY2hlY2sgZm9yIHRoaXMgaW4g ZXZlcnkgY2FsbGJhY2s7IG1vdmUgdG8KY3AyMTB4X2dwaW9fcmVxdWVzdCgpLgoKPiArCj4gKwli dWYuc3RhdGUgPSAodmFsdWUgPT0gMSkgPyBCSVQoZ3BpbykgOiAwOwo+ICsJYnVmLm1hc2sgPSBC SVQoZ3Bpbyk7Cj4gKwo+ICsJcmVzdWx0ID0gdXNiX2NvbnRyb2xfbXNnKHNlcmlhbC0+ZGV2LAo+ ICsJCQkJIHVzYl9zbmRjdHJscGlwZShzZXJpYWwtPmRldiwgMCksCj4gKwkJCQkgQ1AyMTBYX1ZF TkRPUl9TUEVDSUZJQywKPiArCQkJCSBSRVFUWVBFX0hPU1RfVE9fREVWSUNFLAo+ICsJCQkJIENQ MjEwWF9XUklURV9MQVRDSCwKPiArCQkJCSAqKHUxNiAqKSZidWYsCgpBRkFJQ1QgdGhpcyB3aWxs IHdvcmsgYWxzbyBvbiBiaWctZW5kaWFuIG1hY2hpbmVzLCBidXQgdGhlIGltcGxpY2l0CmVuZGlh biBjb252ZXJzaW9ucyBpbnZvbHZlZCBtYWtlcyBteSBoZWFkIHNwaW4uIDspCgpJdCBtYXkgYmUg YmV0dGVyIHRvIGp1c3QgZW5jb2RlIHRoZSBtYXNrcyBleHBsaWNpdGx5IGZvciB0aGUgZGVmYXVs dAoobm9uLWNwMjEwNSkgY2FzZSB0aGF0IHVzZSB3SW5kZXg6CgoJYnVmLnN0YXRlIDw8IDggfCBi dWYubWFzawoKd2hlbiBtZXJnaW5nIHRoaXMgd2l0aCBjcDIxMHhfZ3Bpb19zZXQuCgo+ICsJCQkJ IE5VTEwsIDAsIFVTQl9DVFJMX1NFVF9USU1FT1VUKTsKPiArCj4gKwlpZiAocmVzdWx0IDwgMCkg ewo+ICsJCWRldl9lcnIoJnNlcmlhbC0+aW50ZXJmYWNlLT5kZXYsCj4gKwkJCSJGYWlsZWQgdG8g c2V0IEdQSU8gdmFsdWUuXG4iKTsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIGludCBjcDIxMDJu X2dwaW9fZGlyZWN0aW9uX2dldChzdHJ1Y3QgZ3Bpb19jaGlwICpnYywgdW5zaWduZWQgaW50IGdw aW8pCj4gK3sKPiArCXN0cnVjdCB1c2Jfc2VyaWFsICpzZXJpYWwgPSBncGlvY2hpcF9nZXRfZGF0 YShnYyk7Cj4gKwlzdHJ1Y3QgY3AyMTB4X3NlcmlhbF9wcml2YXRlICpwcml2ID0gdXNiX2dldF9z ZXJpYWxfZGF0YShzZXJpYWwpOwo+ICsKPiArCXJldHVybiBwcml2LT5ncGlvX2RpciAmIEJJVChn cGlvKTsKPiArfQoKU28gZm9yIGNwMjEwNSB3ZSBkZWNpZGVkIGFnYWluc3QgaW1wbGVtZW50aW5n IGFuIGlucHV0IG1vZGUuIFdlIGF0IGxlYXN0Cm5lZWQgdG8gYmUgY29uc2lzdGVudCBoZXJlLCBz byBJIHN1Z2dlc3Qgc3RhcnRpbmcgd2l0aCBkcm9wcGluZyB0aG9zZQpiaXRzIG9mIHRoZSBpbXBs ZW1lbnRhdGlvbiBhbmQgd2UgY2FuIGhhdmUgdGhhdCBkaXNjdXNzaW9uIGFnYWluIGFuZCwKZGVw ZW5kaW5nIG9uIHRoZSBvdXRjb21lLCBwb3NzaWJseSBlbmFibGUgaXQgZm9yIGFsbCBjcDIxMHgg ZGV2aWNlcwpsYXRlci4KCj4gK3N0YXRpYyB1MTYgZmxldGNoZXIxNih1OCAqZGF0YSwgdTE2IGJ5 dGVzKQo+ICt7Cj4gKwl1MTYgc3VtMSA9IDB4ZmYsIHN1bTIgPSAweGZmOwo+ICsJdTE2IHRsZW47 Cj4gKwo+ICsJd2hpbGUgKGJ5dGVzKSB7Cj4gKwkJdGxlbiA9IGJ5dGVzID49IDIwID8gMjAgOiBi eXRlczsKPiArCQlieXRlcyAtPSB0bGVuOwo+ICsJCWRvIHsKPiArCQkJc3VtMiArPSBzdW0xICs9 ICpkYXRhKys7Cj4gKwkJfSB3aGlsZSAoLS10bGVuKTsKPiArCQlzdW0xID0gKHN1bTEgJiAweGZm KSArIChzdW0xID4+IDgpOwo+ICsJCXN1bTIgPSAoc3VtMiAmIDB4ZmYpICsgKHN1bTIgPj4gOCk7 Cj4gKwl9Cj4gKwkvKiBTZWNvbmQgcmVkdWN0aW9uIHN0ZXAgdG8gcmVkdWNlIHN1bXMgdG8gOCBi aXRzICovCj4gKwlzdW0xID0gKHN1bTEgJiAweGZmKSArIChzdW0xID4+IDgpOwo+ICsJc3VtMiA9 IChzdW0yICYgMHhmZikgKyAoc3VtMiA+PiA4KTsKPiArCXJldHVybiBzdW0yIDw8IDggfCBzdW0x Owo+ICt9CgpJIHdhcyBnb2luZyB0byBjb21tZW50IG9uIHRoZSBvZGQgY29kaW5nIHN0eWxlIGFi b3ZlLCB3aGVuIEkgbm90aWNlZAp0aGF0IHlvdSd2ZSBjb3BpZWQgdGhpcyBpbXBsZW1lbnRhdGlv biBmcm9tIGEgc2lsYWJzIGZvcnVtIHBvc3QuIE5vdApnb29kIGF0IGFsbCAoYXMgdGhlcmUgd2Fz IG5vIGluZGljYXRpb24gb2YgYW55IGxpY2Vuc2UpLgoKUGxlYXNlIHJlbW92ZS4KCkZvcnR1bmF0 ZWx5LCB0aGUgYmVsb3cgY2hlY2tzdW0gaXMgcmVkdW5kYW50IHNvIG5vIG5lZWQgZm9yIHlvdSB0 bwpyZWltcGxlbWVudCB0aGlzIHlvdXJzZWxmLgoKPiArCj4gK3N0YXRpYyBpbnQgY3AyMTAybl9n cGlvX2luaXQoc3RydWN0IHVzYl9zZXJpYWwgKnNlcmlhbCkKPiArewo+ICsJY29uc3QgdTE2IENP TkZJR19TSVpFID0gMHgwMkE2Owo+ICsJaW50IHJlc3VsdDsKPiArCXUxNiBjb25maWdfY3N1bTsK PiArCXU4ICpjb25maWdfYnVmOwo+ICsJdTggZ3Bpb19jdHJsOwo+ICsJdTggZ3Bpb19tb2RlOwo+ ICsJdTggZ3Bpb19sYXRjaDsKPiArCXU4IGdwaW9fcnN0X2xhdGNoOwo+ICsJdTggaTsKPiArCWJv b2wgY29uZmlnX3ZhbGlkID0gdHJ1ZTsKPiArCXN0cnVjdCBjcDIxMHhfc2VyaWFsX3ByaXZhdGUg KnByaXYgPSB1c2JfZ2V0X3NlcmlhbF9kYXRhKHNlcmlhbCk7CgpTdHlsZSBuaXQ6IE1vdmUgbG9u Z2VyIGRlY2xhcmF0aW9ucyB0b3dhcmRzIHRoZSB0b3Agb2YgdGhlIGZ1bmN0aW9uCihyZXZlcnNl IHhtYXMgc3R5bGUpLgoKPiArCj4gKwkvKiBSZXRyaWV2ZSBkZXZpY2UgY29uZmlndXJhdGlvbiBm cm9tIHRoZSBkZXZpY2UuCj4gKwkgKiBUaGUgYXJyYXkgcmVjZWl2ZWQgY29udGFpbnMgYWxsIGN1 c3RvbWl6YXRpb24gc2V0dGluZ3MKPiArCSAqIGRvbmUgYXQgdGhlIGZhY3RvcnkvbWFudWZhY3R1 cmVyLgo+ICsJICogRm9ybWF0IG9mIHRoZSBhcnJheSBpcyBkb2N1bWVudGVkIGF0IHRoZSB0aW1l IG9mIHdyaXRpbmcgYXQKPiArCSAqIGh0dHBzOi8vd3d3LnNpbGFicy5jb20vY29tbXVuaXR5L2lu dGVyZmFjZS9rbm93bGVkZ2UtYmFzZS5lbnRyeS5odG1sLzIwMTcvMDMvMzEvY3AyMTAybl9zZXRj b25maWcteHNmYQo+ICsJICovCgpNdWx0aS1saW5lIGNvbW1lbnRzIHNob3VsZCB1c2UgdGhlIGZv bGxvd2luZyBmb3JtYXQKCgkvKgoJICogYmxhaC4uLgoJICovCgo+ICsJY29uZmlnX2J1ZiA9IGtt YWxsb2MoQ09ORklHX1NJWkUsIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFjb25maWdfYnVmKQo+ICsJ CXJldHVybiAtRU5PTUVNOwo+ICsKPiArCXJlc3VsdCA9IGNwMjEweF9yZWFkX3ZlbmRvcl9ibG9j ayhzZXJpYWwsCj4gKwkJCQkJICBSRVFUWVBFX0RFVklDRV9UT19IT1NULAo+ICsJCQkJCSAgQ1Ay MTBYX1JFQURfMk5DT05GSUcsCj4gKwkJCQkJICBjb25maWdfYnVmLAo+ICsJCQkJCSAgQ09ORklH X1NJWkUpOwo+ICsJaWYgKHJlc3VsdCA8IDApCj4gKwkJcmV0dXJuIHJlc3VsdDsKPiArCj4gKwkv KiBDaGVjayBjb25maWd1cmF0aW9uIGZvciB2YWxpZGl0eS4KPiArCSAqIFRoZSBsYXN0IHR3byBi eXRlcyBvZiB0aGUgYXJyYXkgY29udGFpbiBhIGZsZXRjaGVyMTYKPiArCSAqIGNoZWNrc3VtIG9m IGFsbCB0aGUgYnl0ZXMgYmVmb3JlLCB3aGljaCB3ZSBjYW4gdmFsaWRhdGUuCj4gKwkgKi8KPiAr CWNvbmZpZ19jc3VtID0gZmxldGNoZXIxNihjb25maWdfYnVmLCBDT05GSUdfU0laRSAtIDIpOwo+ ICsJaWYgKCgoY29uZmlnX2NzdW0gJiAweEZGKSAhPSBjb25maWdfYnVmW0NPTkZJR19TSVpFIC0g MV0pIHx8Cj4gKwkgICAgKChjb25maWdfY3N1bSA+PiA4KSAgICE9IGNvbmZpZ19idWZbQ09ORklH X1NJWkUgLSAyXSkpIHsKPiArCQljb25maWdfdmFsaWQgPSBmYWxzZTsKPiArCQlkZXZfZXJyKCZz ZXJpYWwtPmludGVyZmFjZS0+ZGV2LAo+ICsJCQkiQ29ycnVwdGVkIGRldmljZSBjb25maWd1cmF0 aW9uIHJlY2VpdmVkXG4iKTsKPiArCX0KClNvIGp1c3QgZHJvcCB0aGlzIGZvciBub3cuCgo+ICsK PiArCWdwaW9fbW9kZSA9IGNvbmZpZ19idWZbQ1AyMTBYXzJOQ09ORklHX0dQSU9fTU9ERV9JRFhd Owo+ICsJZ3Bpb19jdHJsID0gY29uZmlnX2J1ZltDUDIxMFhfMk5DT05GSUdfR1BJT19DT05UUk9M X0lEWF07Cj4gKwlncGlvX3JzdF9sYXRjaCA9IGNvbmZpZ19idWZbQ1AyMTBYXzJOQ09ORklHX0dQ SU9fUlNUTEFUQ0hfSURYXTsKPiArCj4gKwlrZnJlZShjb25maWdfYnVmKTsKPiArCj4gKwlpZiAo IWNvbmZpZ192YWxpZCkKPiArCQlyZXR1cm4gLUVJTzsKPiArCj4gKwkvKiBXZSBvbmx5IHN1cHBv cnQgNCBHUElPcyBldmVuIG9uIHRoZSBRRk4yOCBwYWNrYWdlIGJlY2F1c2UKPiArCSAqIGRvY3Vt ZW50YXRpb24gYWJvdXQgdGhlIENQMjEwMk4gR2V0Q29uZmlnIEFycmF5Cj4gKwkgKiBkb2VzIG5v dCBzZWVtIHRvIGNvcnJlc3BvbmQgdG8gcmVhbGl0eSBvbiB0aGlzIGRldmljZS4KPiArCSAqLwoK UGxlYXNlIGJlIG1vcmUgc3BlY2lmaWMgaGVyZTsgd2hhdCBkbyB5b3UgbWVhbiBieSBub3QgY29y cmVzcG9uZGluZyB0bwpyZWFsaXR5LgoKPiArCXByaXYtPmdjLm5ncGlvID0gNDsKPiArCj4gKwkv KiBHZXQgZGVmYXVsdCBwaW4gc3RhdGVzIGFmdGVyIHJlc2V0LiBOZWVkZWQgc28gd2UgY2FuIGRl dGVybWluZQo+ICsJICogdGhlIGRpcmVjdGlvbiBvZiBhbiBvcGVuLWRyYWluIHBpbi4KPiArCSAq Lwo+ICsJZ3Bpb19sYXRjaCA9IChncGlvX3JzdF9sYXRjaCA+PiAzKSAmIDB4MEY7Cj4gKwo+ICsJ LyogMCBpbmRpY2F0ZXMgb3Blbi1kcmFpbiBtb2RlLCAxIGlzIHB1c2gtcHVsbCAqLwo+ICsJcHJp di0+Z3Bpb19tb2RlID0gKGdwaW9fbW9kZSA+PiAzKSAmIDB4MEY7Cj4gKwo+ICsJLyogMCBpbmRp Y2F0ZXMgR1BJTyBtb2RlLCAxIGlzIGFsdGVybmF0ZSBmdW5jdGlvbiAqLwo+ICsJcHJpdi0+Z3Bp b19jb250cm9sID0gKGdwaW9fY3RybCA+PiAyKSAmIDB4MEY7Cj4gKwo+ICsJLyogVGhlIENQMjEw Mk4gZG9lcyBub3Qgc3RyaWN0bHkgaGFzIGlucHV0IGFuZCBvdXRwdXQgcGluIG1vZGVzLAo+ICsJ ICogaXQgb25seSBrbm93cyBvcGVuLWRyYWluIGFuZCBwdXNoLXB1bGwgbW9kZXMgd2hpY2ggaXMg c2V0IGF0Cj4gKwkgKiBmYWN0b3J5LiBBbiBvcGVuLWRyYWluIHBpbiBjYW4gZnVuY3Rpb24gYm90 aCBhcyBhbgo+ICsJICogaW5wdXQgb3IgYW4gb3V0cHV0LiBXZSBlbXVsYXRlIGlucHV0IG1vZGUg Zm9yIG9wZW4tZHJhaW4gcGlucwo+ICsJICogYnkgbWFraW5nIHN1cmUgdGhleSBhcmUgbm90IGRy aXZlbiBsb3csIGFuZCB3ZSBkbyBub3QgYWxsb3cKPiArCSAqIHB1c2gtcHVsbCBwaW5zIHRvIGJl IHNldCBhcyBhbiBpbnB1dC4KPiArCSAqLwo+ICsJZm9yIChpID0gMDsgaSA8IHByaXYtPmdjLm5n cGlvOyArK2kpIHsKPiArCQkvKiBTZXQgZGlyZWN0aW9uIHRvICJpbnB1dCIgaWZmCj4gKwkJICog cGluIGlzIG9wZW4tZHJhaW4gYW5kIHJlc2V0IHZhbHVlIGlzIDEKPiArCQkgKi8KPiArCQlpZiAo Q1AyMTAyTl9QSU5fT1BFTkRSQUlOKHByaXYtPmdwaW9fbW9kZSwgaSkgJiYKPiArCQkgICAgKGdw aW9fbGF0Y2ggJiBCSVQoaSkpKSB7Cj4gKwkJCXByaXYtPmdwaW9fZGlyIHw9IEJJVChpKTsKPiAr CQl9Cj4gKwl9CgpTbyB0aGlzIGNhbiBiZSBzaW1wbGlmaWVkIGEgYml0IGJ5IGRlZmVycmluZyBp bXBsZW1lbnRpbmcgYW4gaW5wdXQgbW9kZS4KCj4gKwo+ICsJcHJpdi0+Z2MubGFiZWwgPSAiY3Ay MTAybiI7Cj4gKwlwcml2LT5nYy5nZXRfZGlyZWN0aW9uID0gY3AyMTAybl9ncGlvX2RpcmVjdGlv bl9nZXQ7Cj4gKwlwcml2LT5nYy5kaXJlY3Rpb25faW5wdXQgPSBjcDIxMDJuX2dwaW9fZGlyZWN0 aW9uX2lucHV0Owo+ICsJcHJpdi0+Z2MuZGlyZWN0aW9uX291dHB1dCA9IGNwMjEwMm5fZ3Bpb19k aXJlY3Rpb25fb3V0cHV0Owo+ICsJcHJpdi0+Z2MuZ2V0ID0gY3AyMTAybl9ncGlvX2dldDsKPiAr CXByaXYtPmdjLnNldCA9IGNwMjEwMm5fZ3Bpb19zZXQ7Cj4gKwlwcml2LT5nYy5vd25lciA9IFRI SVNfTU9EVUxFOwo+ICsJcHJpdi0+Z2MucGFyZW50ID0gJnNlcmlhbC0+aW50ZXJmYWNlLT5kZXY7 Cj4gKwlwcml2LT5nYy5iYXNlID0gLTE7Cj4gKwlwcml2LT5nYy5jYW5fc2xlZXAgPSB0cnVlOwo+ ICsKPiArCXJlc3VsdCA9IGdwaW9jaGlwX2FkZF9kYXRhKCZwcml2LT5nYywgc2VyaWFsKTsKPiAr CWlmICghcmVzdWx0KQo+ICsJCXByaXYtPmdwaW9fcmVnaXN0ZXJlZCA9IHRydWU7CgpBbmQgdGhp cyB3aG9sZSBmdW5jdGlvbiBzaG91bGQgYmUgbWVyZ2VkIHdpdGggdGhlIGNwMjEwNSBpbXBsZW1l bnRhdGlvbi4KUmV0cmlldmluZyBhbmQgcGFyc2luZyB0aGUgY29uZmlndXJhdGlvbiBpcyBvYnZp b3VzbHkgZ29pbmcgdG8gcmVtYWluCnR5cGUgc3BlY2lmaWMgKGFuZCBsaXZlIGluIHRoZWlyIG93 biBmdW5jdGlvbnMpLCBidXQgdGhlIGFib3ZlCmluaXRpYWxpc2F0aW9uIGFuZCByZWdpc3RyYXRp b24gY2FuIGJlIHNoYXJlZC4KCj4gKwo+ICsJcmV0dXJuIHJlc3VsdDsKPiArfQo+ICsKPiAgI2Vs c2UKPiAgCj4gIHN0YXRpYyBpbnQgY3AyMTA1X3NoYXJlZF9ncGlvX2luaXQoc3RydWN0IHVzYl9z ZXJpYWwgKnNlcmlhbCkKPiBAQCAtMTQ2Miw2ICsxNzA2LDExIEBAIHN0YXRpYyBpbnQgY3AyMTA1 X3NoYXJlZF9ncGlvX2luaXQoc3RydWN0IHVzYl9zZXJpYWwgKnNlcmlhbCkKPiAgCXJldHVybiAw Owo+ICB9Cj4gIAo+ICtzdGF0aWMgaW50IGNwMjEwMm5fZ3Bpb19pbml0KHN0cnVjdCB1c2Jfc2Vy aWFsICpzZXJpYWwpCj4gK3sKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICBzdGF0aWMgdm9pZCBj cDIxMHhfZ3Bpb19yZW1vdmUoc3RydWN0IHVzYl9zZXJpYWwgKnNlcmlhbCkKPiAgewo+ICAJLyog Tm90aGluZyB0byBkbyAqLwo+IEBAIC0xNTIyLDcgKzE3NzEsMTMgQEAgc3RhdGljIGludCBjcDIx MHhfYXR0YWNoKHN0cnVjdCB1c2Jfc2VyaWFsICpzZXJpYWwpCj4gIAo+ICAJdXNiX3NldF9zZXJp YWxfZGF0YShzZXJpYWwsIHByaXYpOwo+ICAKPiAtCWlmIChwcml2LT5wYXJ0bnVtID09IENQMjEw WF9QQVJUTlVNX0NQMjEwNSkgewo+ICsJaWYgKElTX0NQMjEwMk4ocHJpdi0+cGFydG51bSkpIHsK PiArCQlyZXN1bHQgPSBjcDIxMDJuX2dwaW9faW5pdChzZXJpYWwpOwo+ICsJCWlmIChyZXN1bHQg PCAwKSB7Cj4gKwkJCWRldl9lcnIoJnNlcmlhbC0+aW50ZXJmYWNlLT5kZXYsCj4gKwkJCQkiR1BJ TyBpbml0aWFsaXNhdGlvbiBmYWlsZWQsIGNvbnRpbnVpbmcgd2l0aG91dCBHUElPIHN1cHBvcnRc biIpOwo+ICsJCX0KPiArCX0gZWxzZSBpZiAocHJpdi0+cGFydG51bSA9PSBDUDIxMFhfUEFSVE5V TV9DUDIxMDUpIHsKPiAgCQlyZXN1bHQgPSBjcDIxMDVfc2hhcmVkX2dwaW9faW5pdChzZXJpYWwp Owo+ICAJCWlmIChyZXN1bHQgPCAwKSB7Cj4gIAkJCWRldl9lcnIoJnNlcmlhbC0+aW50ZXJmYWNl LT5kZXYsCgpBbmQgdGhpcyBhbGwgc2hvdWxkIGJlIGhpZGRlbiBhd2F5IGluIGEgY29tbW9uIGNw MjEweF9ncGlvX2luaXQoKQpmdW5jdGlvbi4KClRoYW5rcywKSm9oYW4KLS0tClRvIHVuc3Vic2Ny aWJlIGZyb20gdGhpcyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBsaW51eC11c2Ii IGluCnRoZSBib2R5IG9mIGEgbWVzc2FnZSB0byBtYWpvcmRvbW9Admdlci5rZXJuZWwub3JnCk1v cmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWlu Zm8uaHRtbAo= 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=-0.9 required=3.0 tests=DKIM_SIGNED, MAILING_LIST_MULTI,SPF_PASS,T_DKIM_INVALID,URIBL_BLOCKED autolearn=ham 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 A2FB5C1B0F2 for ; Wed, 20 Jun 2018 08:32:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 46D13208B0 for ; Wed, 20 Jun 2018 08:32:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RKnDAaea" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 46D13208B0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753276AbeFTIcj (ORCPT ); Wed, 20 Jun 2018 04:32:39 -0400 Received: from mail-lf0-f65.google.com ([209.85.215.65]:42247 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751327AbeFTIcc (ORCPT ); Wed, 20 Jun 2018 04:32:32 -0400 Received: by mail-lf0-f65.google.com with SMTP id z207-v6so3628454lff.9; Wed, 20 Jun 2018 01:32:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=/BY7Qc7MkqVbDkxcyECo22hsj6nyre0WO1YJgaFlslo=; b=RKnDAaeaNRGibezqSVzu7GJcqX4eWIJ6+jlGVnuDR2LMGNnxpKN5TGjp43IM9eqt4u HZoLfQB25+OY1iiH0UByFBYECJveAJ+/j+Q0CJCeH1qbm2lgjJkzK3pXz7UfJgLUg0EV /VcNs9IqzwGgCboLGNeOREJZgkcnsEOpqA54tUDXUWyodCQcYBUZqPfl8kKkcdQvnKA9 KOf8OxPCeEO3Xal+8NafG0Vv8zVe8b2MPfgL6sZAiskcvcldqd8Bh3Z4v0t/xTInO6eh fibiJ6UfqPYB/q9MqZ7WCWdJdQUsTV91ew/lcL1rAJnbo2tCn4VvS4ct3CaSNFEzcFXx z8KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition:in-reply-to:user-agent; bh=/BY7Qc7MkqVbDkxcyECo22hsj6nyre0WO1YJgaFlslo=; b=koTIf95aSNJvPjbw82VT/iu/oj9q/mW0z8gjUD1kffz5g12rw+tJujkiJIrwwBznkm qXKmIdDyPYw1njUQJBhcetn9xcxHNMlo/tmFzY8ee2agkCiS4BSzjY2QN3KJ9+bOQNbW ekCuw23KJ69RyDJxv0lmoFMTn8gjCT8zLw4hnbdVX7cDoFLY/zgZ3hWpuL661xCRin69 QzTRxE1U8ySw2taa4vXazwm4vRLaDKb2Ugn3t4223CzreNu4PChAeSLHzF5H3IeYICET 1TSr40HXutN6NHVUIuwXFAwvzkbJOHE7UcnQ5c8l3vZwAp6Jo7skTQxHQmJqBrok+ui+ QQ7Q== X-Gm-Message-State: APt69E1oPMsAq30hHGghzV/B2TacWUEtrzDHaOwRIBXSGPAcJ5L9AJCi k20N+6KYQjj1VF6Llcx4Gpw= X-Google-Smtp-Source: ADUXVKJLmoj9om0m+RskqBINPy5qnTVCf7Tfo4paRXghORgT19zCl38DBIR10rYGO7u8IbcjD+NZVw== X-Received: by 2002:a2e:4dcc:: with SMTP id c73-v6mr12949789ljd.135.1529483137193; Wed, 20 Jun 2018 01:25:37 -0700 (PDT) Received: from xi.terra (c-8bb2e655.07-184-6d6c6d4.bbcust.telenor.se. [85.230.178.139]) by smtp.gmail.com with ESMTPSA id q66-v6sm308152lfg.17.2018.06.20.01.25.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Jun 2018 01:25:36 -0700 (PDT) Received: from johan by xi.terra with local (Exim 4.90_1) (envelope-from ) id 1fVYQN-0002y4-Ax; Wed, 20 Jun 2018 10:25:07 +0200 Date: Wed, 20 Jun 2018 10:25:07 +0200 From: Johan Hovold To: Karoly Pados Cc: Johan Hovold , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] USB: serial: cp210x: Implement GPIO support for CP2102N Message-ID: <20180620082507.GO32411@localhost> References: <20180617182503.23080-1-pados@pados.hu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180617182503.23080-1-pados@pados.hu> User-Agent: Mutt/1.10.0 (2018-05-17) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, Jun 17, 2018 at 08:25:03PM +0200, Karoly Pados wrote: > Pretty much what the title says. No other functions/devices > touched. Tested on CP2102N-QFN28. > > Limitation: Even though the QFN28 package has 7 GPIOs, > this patch allows to control only the first 4. > What I've found using reverse engineering regarding the > other 3 pins collides both with reality and with other > documented functions, so I did not dare to just use my > findings because I cannot test on other packages. > Instead, I decided to play it safe and only support 4 GPIOs. Thanks for the patch. Nice to see this finally be implemented for further device types. You're gonna need to unify a lot of this with the current implementation for cp2105 however. > Signed-off-by: Karoly Pados > --- > drivers/usb/serial/cp210x.c | 259 +++++++++++++++++++++++++++++++++++- > 1 file changed, 257 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c > index 793b86252c46..adb450185ce8 100644 > --- a/drivers/usb/serial/cp210x.c > +++ b/drivers/usb/serial/cp210x.c > @@ -6,7 +6,8 @@ > * > * Support to set flow control line levels using TIOCMGET and TIOCMSET > * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow > - * control thanks to Munir Nassar nassarmu@real-time.com > + * control thanks to Munir Nassar nassarmu@real-time.com. > + * GPIO support for CP2102N thanks to Karoly Pados. No need to thank yourself here. This was added by the original author (who appears to have partly been developing this driver out-of-tree) to credit contributers. The git logs will keep a record of your contributions. > * > */ > > @@ -229,11 +230,16 @@ struct cp210x_serial_private { > struct gpio_chip gc; > u8 config; > u8 gpio_mode; > + u8 gpio_control; > + u8 gpio_dir; > bool gpio_registered; > #endif > u8 partnum; > }; > > +#define CP2102N_PIN_OPENDRAIN(var, pin) (!((var) & BIT(pin))) > +#define CP2102N_PIN_GPIO(var, pin) (!((var) & BIT(pin))) These are in fact not cp2102n specific. If they are at all needed in the end they should be implemented as generic static functions. > + > struct cp210x_port_private { > __u8 bInterfaceNumber; > bool has_swapped_line_ctl; > @@ -349,6 +355,7 @@ static struct usb_serial_driver * const serial_drivers[] = { > #define CP210X_GET_PORTCONFIG 0x370C > #define CP210X_GET_DEVICEMODE 0x3711 > #define CP210X_WRITE_LATCH 0x37E1 > +#define CP210X_READ_2NCONFIG 0x000E Keep the defines sorted by value. > /* Part number definitions */ > #define CP210X_PARTNUM_CP2101 0x01 > @@ -362,6 +369,14 @@ static struct usb_serial_driver * const serial_drivers[] = { > #define CP210X_PARTNUM_CP2102N_QFN20 0x22 > #define CP210X_PARTNUM_UNKNOWN 0xFF > > +#define IS_CP2102N(partnum) (((partnum) == CP210X_PARTNUM_CP2102N_QFN28) || \ > + ((partnum) == CP210X_PARTNUM_CP2102N_QFN24) || \ > + ((partnum) == CP210X_PARTNUM_CP2102N_QFN20)) So reuse the static helper I mentioned in my comments to the baudrate patch. > + > +#define CP210X_2NCONFIG_GPIO_CONTROL_IDX 600 > +#define CP210X_2NCONFIG_GPIO_MODE_IDX 581 > +#define CP210X_2NCONFIG_GPIO_RSTLATCH_IDX 587 Sort by value. > + > /* CP210X_GET_COMM_STATUS returns these 0x13 bytes */ > struct cp210x_comm_status { > __le32 ulErrors; > @@ -1455,6 +1470,235 @@ static void cp210x_gpio_remove(struct usb_serial *serial) > } > } > > +static int cp2102n_gpio_get(struct gpio_chip *gc, unsigned int gpio) > +{ > + struct usb_serial *serial = gpiochip_get_data(gc); > + int result; > + u8 buf; > + > + result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, > + CP210X_READ_LATCH, &buf, sizeof(buf)); > + if (result < 0) > + return result; > + > + return !!(buf & BIT(gpio)); > +} This should be handled in cp210x_gpio_get() by making the control request type depend on the device type. Make the cp2102n behaviour the default as it is used also by some legacy devices, and explicitly check for the cp2105 odd bird. We'll deal with cp2108, which 16 gpios and hence uses 16-bit mask, when we get there. > + > +static void cp2102n_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) > +{ > + int result; > + struct cp210x_gpio_write buf; > + struct usb_serial *serial = gpiochip_get_data(gc); > + struct cp210x_serial_private *priv = usb_get_serial_data(serial); > + > + /* Ignore request if pin is not in our control */ > + if (!CP2102N_PIN_GPIO(priv->gpio_control, gpio)) { > + dev_warn(&serial->interface->dev, > + "Cannot control GPIO with active alternate function.\n"); > + return; > + } No need to check for this in every callback; move to cp210x_gpio_request(). > + > + buf.state = (value == 1) ? BIT(gpio) : 0; > + buf.mask = BIT(gpio); > + > + result = usb_control_msg(serial->dev, > + usb_sndctrlpipe(serial->dev, 0), > + CP210X_VENDOR_SPECIFIC, > + REQTYPE_HOST_TO_DEVICE, > + CP210X_WRITE_LATCH, > + *(u16 *)&buf, AFAICT this will work also on big-endian machines, but the implicit endian conversions involved makes my head spin. ;) It may be better to just encode the masks explicitly for the default (non-cp2105) case that use wIndex: buf.state << 8 | buf.mask when merging this with cp210x_gpio_set. > + NULL, 0, USB_CTRL_SET_TIMEOUT); > + > + if (result < 0) { > + dev_err(&serial->interface->dev, > + "Failed to set GPIO value.\n"); > + } > +} > + > +static int cp2102n_gpio_direction_get(struct gpio_chip *gc, unsigned int gpio) > +{ > + struct usb_serial *serial = gpiochip_get_data(gc); > + struct cp210x_serial_private *priv = usb_get_serial_data(serial); > + > + return priv->gpio_dir & BIT(gpio); > +} So for cp2105 we decided against implementing an input mode. We at least need to be consistent here, so I suggest starting with dropping those bits of the implementation and we can have that discussion again and, depending on the outcome, possibly enable it for all cp210x devices later. > +static u16 fletcher16(u8 *data, u16 bytes) > +{ > + u16 sum1 = 0xff, sum2 = 0xff; > + u16 tlen; > + > + while (bytes) { > + tlen = bytes >= 20 ? 20 : bytes; > + bytes -= tlen; > + do { > + sum2 += sum1 += *data++; > + } while (--tlen); > + sum1 = (sum1 & 0xff) + (sum1 >> 8); > + sum2 = (sum2 & 0xff) + (sum2 >> 8); > + } > + /* Second reduction step to reduce sums to 8 bits */ > + sum1 = (sum1 & 0xff) + (sum1 >> 8); > + sum2 = (sum2 & 0xff) + (sum2 >> 8); > + return sum2 << 8 | sum1; > +} I was going to comment on the odd coding style above, when I noticed that you've copied this implementation from a silabs forum post. Not good at all (as there was no indication of any license). Please remove. Fortunately, the below checksum is redundant so no need for you to reimplement this yourself. > + > +static int cp2102n_gpio_init(struct usb_serial *serial) > +{ > + const u16 CONFIG_SIZE = 0x02A6; > + int result; > + u16 config_csum; > + u8 *config_buf; > + u8 gpio_ctrl; > + u8 gpio_mode; > + u8 gpio_latch; > + u8 gpio_rst_latch; > + u8 i; > + bool config_valid = true; > + struct cp210x_serial_private *priv = usb_get_serial_data(serial); Style nit: Move longer declarations towards the top of the function (reverse xmas style). > + > + /* Retrieve device configuration from the device. > + * The array received contains all customization settings > + * done at the factory/manufacturer. > + * Format of the array is documented at the time of writing at > + * https://www.silabs.com/community/interface/knowledge-base.entry.html/2017/03/31/cp2102n_setconfig-xsfa > + */ Multi-line comments should use the following format /* * blah... */ > + config_buf = kmalloc(CONFIG_SIZE, GFP_KERNEL); > + if (!config_buf) > + return -ENOMEM; > + > + result = cp210x_read_vendor_block(serial, > + REQTYPE_DEVICE_TO_HOST, > + CP210X_READ_2NCONFIG, > + config_buf, > + CONFIG_SIZE); > + if (result < 0) > + return result; > + > + /* Check configuration for validity. > + * The last two bytes of the array contain a fletcher16 > + * checksum of all the bytes before, which we can validate. > + */ > + config_csum = fletcher16(config_buf, CONFIG_SIZE - 2); > + if (((config_csum & 0xFF) != config_buf[CONFIG_SIZE - 1]) || > + ((config_csum >> 8) != config_buf[CONFIG_SIZE - 2])) { > + config_valid = false; > + dev_err(&serial->interface->dev, > + "Corrupted device configuration received\n"); > + } So just drop this for now. > + > + gpio_mode = config_buf[CP210X_2NCONFIG_GPIO_MODE_IDX]; > + gpio_ctrl = config_buf[CP210X_2NCONFIG_GPIO_CONTROL_IDX]; > + gpio_rst_latch = config_buf[CP210X_2NCONFIG_GPIO_RSTLATCH_IDX]; > + > + kfree(config_buf); > + > + if (!config_valid) > + return -EIO; > + > + /* We only support 4 GPIOs even on the QFN28 package because > + * documentation about the CP2102N GetConfig Array > + * does not seem to correspond to reality on this device. > + */ Please be more specific here; what do you mean by not corresponding to reality. > + priv->gc.ngpio = 4; > + > + /* Get default pin states after reset. Needed so we can determine > + * the direction of an open-drain pin. > + */ > + gpio_latch = (gpio_rst_latch >> 3) & 0x0F; > + > + /* 0 indicates open-drain mode, 1 is push-pull */ > + priv->gpio_mode = (gpio_mode >> 3) & 0x0F; > + > + /* 0 indicates GPIO mode, 1 is alternate function */ > + priv->gpio_control = (gpio_ctrl >> 2) & 0x0F; > + > + /* The CP2102N does not strictly has input and output pin modes, > + * it only knows open-drain and push-pull modes which is set at > + * factory. An open-drain pin can function both as an > + * input or an output. We emulate input mode for open-drain pins > + * by making sure they are not driven low, and we do not allow > + * push-pull pins to be set as an input. > + */ > + for (i = 0; i < priv->gc.ngpio; ++i) { > + /* Set direction to "input" iff > + * pin is open-drain and reset value is 1 > + */ > + if (CP2102N_PIN_OPENDRAIN(priv->gpio_mode, i) && > + (gpio_latch & BIT(i))) { > + priv->gpio_dir |= BIT(i); > + } > + } So this can be simplified a bit by deferring implementing an input mode. > + > + priv->gc.label = "cp2102n"; > + priv->gc.get_direction = cp2102n_gpio_direction_get; > + priv->gc.direction_input = cp2102n_gpio_direction_input; > + priv->gc.direction_output = cp2102n_gpio_direction_output; > + priv->gc.get = cp2102n_gpio_get; > + priv->gc.set = cp2102n_gpio_set; > + priv->gc.owner = THIS_MODULE; > + priv->gc.parent = &serial->interface->dev; > + priv->gc.base = -1; > + priv->gc.can_sleep = true; > + > + result = gpiochip_add_data(&priv->gc, serial); > + if (!result) > + priv->gpio_registered = true; And this whole function should be merged with the cp2105 implementation. Retrieving and parsing the configuration is obviously going to remain type specific (and live in their own functions), but the above initialisation and registration can be shared. > + > + return result; > +} > + > #else > > static int cp2105_shared_gpio_init(struct usb_serial *serial) > @@ -1462,6 +1706,11 @@ static int cp2105_shared_gpio_init(struct usb_serial *serial) > return 0; > } > > +static int cp2102n_gpio_init(struct usb_serial *serial) > +{ > + return 0; > +} > + > static void cp210x_gpio_remove(struct usb_serial *serial) > { > /* Nothing to do */ > @@ -1522,7 +1771,13 @@ static int cp210x_attach(struct usb_serial *serial) > > usb_set_serial_data(serial, priv); > > - if (priv->partnum == CP210X_PARTNUM_CP2105) { > + if (IS_CP2102N(priv->partnum)) { > + result = cp2102n_gpio_init(serial); > + if (result < 0) { > + dev_err(&serial->interface->dev, > + "GPIO initialisation failed, continuing without GPIO support\n"); > + } > + } else if (priv->partnum == CP210X_PARTNUM_CP2105) { > result = cp2105_shared_gpio_init(serial); > if (result < 0) { > dev_err(&serial->interface->dev, And this all should be hidden away in a common cp210x_gpio_init() function. Thanks, Johan