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: ftdi_sio: implement GPIO support for FT230X From: Johan Hovold Message-Id: <20180904124924.GA7278@localhost> Date: Tue, 4 Sep 2018 14:49:24 +0200 To: Karoly Pados Cc: Johan Hovold , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Loic Poulain , andy.shevchenko@gmail.com, ajaykuee@gmail.com, daniel.thompson@linaro.org List-ID: T24gU2F0LCBBdWcgMjUsIDIwMTggYXQgMTA6NDc6NDRQTSArMDIwMCwgS2Fyb2x5IFBhZG9zIHdy b3RlOgo+IFRoaXMgcGF0Y2ggdXNlcyB0aGUgQ0JVUyBiaXRiYW5nIG1vZGUgb2YgdGhlIGRldmlj ZSwgc28gdGhlcmUgaXMKPiBubyBjb25mbGljdCBiZXR3ZWVuIHRoZSBHUElPIGFuZCBWQ1AgZnVu Y3Rpb25hbGl0eS4KClBsZWFzZSBtYWtlIHRoZSBjb21taXQgbWVzc2FnZSBzZWxmLWNvbnRhaW5l ZCAoZS5nLiBkb24ndCByZWx5IG9uIHRoZQpzdW1tYXJ5LCBvciBtYWlsIFN1YmplY3QsIGV2ZW4g aWYgeW91IGZlZWwgbGlrZSB5b3UncmUgcmVwZWF0aW5nCnlvdXJzZWxmLikKCkFuZCB5b3UgY2Fu IGJlIGEgYml0IG1vcmUgdmVyYm9zZSB3aGVuIGRlc2NyaWJpbmcgeW91ciBwYXRjaCBoZXJlLgoK PiBTaWduZWQtb2ZmLWJ5OiBLYXJvbHkgUGFkb3MgPHBhZG9zQHBhZG9zLmh1Pgo+IC0tLQo+IAo+ IFRlc3RlZCBvbiBhbiBGVDIzMFggZGV2aWNlLiBUaG91Z2ggdGhlcmUgaXMgbm8gY29waWVkIGNv ZGUgZnJvbSBvdGhlciAKPiBzb3VyY2VzLCBsaWJmdGRpIHdhcyB1c2VkIGFzIGEgcmVmZXJlbmNl Lgo+IAo+IEkgbm90aWNlZCB0aGVyZSBoYXZlIGJlZW4gbnVtZXJvdXMgaGlzdG9yaWMgYXR0ZW1w dHMgYnkgb3RoZXIgcGVvcGxlIGF0IAo+IGFkZGluZyBHUElPIHN1cHBvcnQgdG8gZnRkaV9zaW8u IE9uZSB0cmllZCBhZGRpbmcgaXQgaW4gc29tZSB2ZXJ5IAo+IGFwcGxpY2F0aW9uLXNwZWNpZmlj IHdheSwgYW5vdGhlciBvbmUgdHJpZWQgdG8gdXNlIHRoZSBtZmQgZnJhbWV3b3JrLCB0aGUKPiB0 cmllZCB1c2luZyBhIEdQSU8gbW9kZSB3aGljaCBpcyBtdXR1YWxseSBleGNsdXNpdmUgdG8gVkNQ LCBhbm90aGVyCj4gb25lIGRpZCBub3QgaW1wbGVtZW50IHRoZSByZXZpZXcgcmVzdWx0cyBldGMu Li4gSSBob3BlIEkgbGVhcm5lZCBmcm9tIHRob3NlIAo+IGF0dGVtcHRzIGFuZCBhbSBwbGFubmlu ZyB0byByZXNwb25kIHRvIHJldmlld3MuIEFsc28sIHRoaXMgcGF0Y2ggZm9sbG93cyAKPiB0aGUg cm91Z2ggc3RydWN0dXJlIG9mIHRoZSBHUElPIHN1cHBvcnQgZm9yIGNwMjEweCBkZXZpY2VzIHRo YXQgaGF2ZSAKPiBhbHJlYWR5IGJlZW4gYWNjZXB0ZWQsIGluIHRoZSBob3BlIHRoYXQgaXQgaXMg YSBnb29kIHN0YXJ0aW5nIHBvaW50Lgo+IAo+IFRoaXMgcGF0Y2ggdXNlcyBDQlVTIGJpdGJhbmdp bmcgbW9kZSwgd2hpY2ggd29ya3MgbmljZWx5IGluIHBhcmFsbGVsIHdpdGgKPiB0aGUgVkNQIGZ1 bmN0aW9uLiBUaGUgb3RoZXIgbW9kZXMgZG8gbm90LCBhbmQgc28gSU1ITyBpdCBkb2VzIG5vdCBt YWtlCj4gc2Vuc2UgdG8gdHJ5IGFkZGluZyB0aGVtIHRvIHRoaXMgc2FtZSBtb2R1bGUuCj4KPiBG b3IgdGhpcyBkZXZpY2UsIHdoZW5ldmVyIGNoYW5naW5nIHRoZSBzdGF0ZSBvZiBhbnkgc2luZ2xl IHBpbiwgYWxsIHRoZQo+IG90aGVycyBuZWVkIHRvIGJlIHdyaXR0ZW4gdG9vLiBUaGlzIG1lYW5z IGluIG9yZGVyIHRvIGNoYW5nZSBhbnkgcGluLCB3ZSAKPiBuZWVkIHRvIGtub3cgdGhlIGN1cnJl bnQgc3RhdGUgb2YgYWxsIHRoZSBvdGhlcnMuIFNvIHdoZW4gdXNpbmcgR1BJTywKPiB3ZSBuZWVk IHRvIGhhdmUgYSBrbm93biBzdGFydGluZyBzdGF0ZSBmb3IgYWxsIHBpbnMsIGJ1dCB0aGVyZSBz ZWVtcyB0byAKPiBiZSBubyB3YXkgdG8gcmV0cmlldmUgdGhlIGV4aXN0aW5nIEdQSU8gY29uZmln dXJhdGlvbiAoZGlyZWN0aW9ucyBhbmQKPiBvdXRwdXQgcmVnaXN0ZXIgdmFsdWVzKS4gVGhlIHdh eSBJIGhhbmRsZSB0aGlzIGluIHRoaXMgcGF0Y2ggaXMgdGhhdCB3aGVuCj4gcmVxdWVzdGluZyBh IEdQSU8gZm9yIHRoZSBmaXJzdCB0aW1lLCB0aGUgbW9kdWxlIGluaXRpYWxpemVzIGFsbCBwaW5z IHRvIAo+IGEga25vd24gZGVmYXVsdCBzdGF0ZSAodG8gaW5wdXRzKS4gSW5wdXQgd2FzIGNob3Nl biwgYmVjYXVzZSBhIHBvdGVudGlhbGx5Cj4gZmxvYXRpbmcgcGluIGlzIGJldHRlciB0aGFuIGEg cG90ZW50aWFsIGRyaXZlciBjb25mbGljdCwgYmVjYXVzZSB0aGUgbGF0dGVyCj4gY291bGQgcmVz dWx0IGluIGhhcmR3YXJlIGRhbWFnZS4gSG93ZXZlciwgaWYgdGhlIHVzZXIgZG9lcyBub3QgcmVx dWVzdCBhIAo+IEdQSU8sIHRoZSBDQlVTIHBpbnMgYXJlIG5vdCBpbml0aWFsaXplZCwgYXZvaWRp bmcgdW5uZWNlc3NhcmlseSBjaGFuZ2luZyAKPiBoYXJkd2FyZSBzdGF0ZS4gSSBmaWd1cmVkIEkg Y2Fubm90IHJlbHkgb24gdGhlIGRlZmF1bHQgcG93ZXItb24gc3RhdGUgb2YKPiB0aGUgZGV2aWNl IGZvciB0aGlzIGFzIHRoZSB1c2VyIG1pZ2h0IGhhdmUgdXNlZCBsaWJmdGRpIGJlZm9yZSBsb2Fk aW5nIAo+IG91ciBtb2R1bGUuIFdoZW4gdGhlIG1vZHVsZSBpcyB1bmxvYWRlZCwgQ0JVUyBiaXRi YW5naW5nIG1vZGUgaXMgZXhpdGVkIAo+IGlmIGl0IHdlcmUgdXMgd2hvIGVudGVyZWQgaXQgZWFy bGllci4KClRoaXMgcGFyYWdyYXBoIHNlZW1zIGxpa2UgaXQgYmVsb25ncyBpbiB0aGUgY29tbWl0 IG1lc3NhZ2UgaW4gc29tZSBmb3JtLgoKQnV0IHlvdXIgYXBwcm9hY2ggc2VlbXMgcmVhc29uYWJs ZSwgZXZlbiBpZiBpdCBtZWFucyBhbGwgcGlucyBtYXkgY2hhbmdlCnN0YXRlIHdoZW4gcmVxdWVz dGluZyB0aGUgZmlyc3QuCgpBY3R1YWxseSwgYWZ0ZXIgdGhpbmtpbmcgYWJvdXQgdGhpcyBzb21l IG1vcmUsIGl0IG1heSBiZSBiZXR0ZXIgdG8ganVzdApjb25maWd1cmUgYWxsIHBpbnMgZHVyaW5n IHByb2JlLiBUaGUgZGV2aWNlIGlzIG1hbmFnZWQgYnkgdGhlIGtlcm5lbCwKYW5kIHdlIGNhbid0 IHJlYWxseSBjb25zaWRlciB3aGF0IHVzZXIgc3BhY2UgbWF5IGhhdmUgZG9uZSBiZWZvcmUsIGF0 CmxlYXN0IGlmIHdlIGNhbid0IHF1ZXJ5IHRoZSBkZXZpY2UuICBCZXR0ZXIgdG8gYmUgaW4gYSBj b25zaXN0ZW50IHN0YXRlCndoaWxlIHRoZSBkcml2ZXIgaXMgYm91bmQuCgo+IGNoZWNrcGF0Y2gu cGwgZW1pdHMgYSBidW5jaCBvZiB3YXJuaW5ncywgcmVjb21tZW5kaW5nIGNvbnN0IGZvciBzdHJ1 Y3RzLiAKPiBJIGFtIHVuc3VyZSBpZiB0aGlzIG1ha2VzIHNlbnNlLCBleGlzdGluZyBjb2RlIGlu IHRoaXMgc2FtZSBhbmQgYWxzbwo+IG90aGVyIG1vZHVsZXMgZG9lcyBub3QgYWRoZXJlIHRvIHRo aXMgcnVsZSBlaXRoZXIuIEkgZml4ZWQgZXZlcnl0aGluZyBlbHNlLgoKUmVhbGx5PyBDaGVja3Bh dGNoIGRvZXNuJ3QgY29tcGxhaW4gaGVyZS4gV2VyZSB5b3UgdXNpbmcgdGhlIC0tc3RyaWN0Cm9w dGlvbiwgcGVyaGFwcz8gRG9uJ3QgZG8gdGhhdC4uLgoKPiAgZHJpdmVycy91c2Ivc2VyaWFsL2Z0 ZGlfc2lvLmMgfCAyODQgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLQo+ICBkcml2 ZXJzL3VzYi9zZXJpYWwvZnRkaV9zaW8uaCB8ICAyNSArKysKPiAgMiBmaWxlcyBjaGFuZ2VkLCAz MDggaW5zZXJ0aW9ucygrKSwgMSBkZWxldGlvbigtKQo+IAo+IGRpZmYgLS1naXQgYS9kcml2ZXJz L3VzYi9zZXJpYWwvZnRkaV9zaW8uYyBiL2RyaXZlcnMvdXNiL3NlcmlhbC9mdGRpX3Npby5jCj4g aW5kZXggYjVjZWYzMjI4MjZmLi5kMWZmNGEzNzJiNmUgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy91 c2Ivc2VyaWFsL2Z0ZGlfc2lvLmMKPiArKysgYi9kcml2ZXJzL3VzYi9zZXJpYWwvZnRkaV9zaW8u Ywo+IEBAIC00MCw2ICs0MCw5IEBACj4gICNpbmNsdWRlIDxsaW51eC91c2IuaD4KPiAgI2luY2x1 ZGUgPGxpbnV4L3NlcmlhbC5oPgo+ICAjaW5jbHVkZSA8bGludXgvdXNiL3NlcmlhbC5oPgo+ICsj aWZkZWYgQ09ORklHX0dQSU9MSUIKPiArI2luY2x1ZGUgPGxpbnV4L2dwaW8vZHJpdmVyLmg+Cj4g KyNlbmRpZgoKTm8gaWZkZWYuCgo+ICAjaW5jbHVkZSAiZnRkaV9zaW8uaCIKPiAgI2luY2x1ZGUg ImZ0ZGlfc2lvX2lkcy5oIgo+ICAKPiBAQCAtNzIsNiArNzUsMTQgQEAgc3RydWN0IGZ0ZGlfcHJp dmF0ZSB7Cj4gIAl1bnNpZ25lZCBpbnQgbGF0ZW5jeTsJCS8qIGxhdGVuY3kgc2V0dGluZyBpbiB1 c2UgKi8KPiAgCXVuc2lnbmVkIHNob3J0IG1heF9wYWNrZXRfc2l6ZTsKPiAgCXN0cnVjdCBtdXRl eCBjZmdfbG9jazsgLyogQXZvaWQgbWVzcyBieSBwYXJhbGxlbCBjYWxscyBvZiBjb25maWcgaW9j dGwoKSBhbmQgY2hhbmdlX3NwZWVkKCkgKi8KPiArI2lmZGVmIENPTkZJR19HUElPTElCCj4gKwlz dHJ1Y3QgZ3Bpb19jaGlwIGdjOwo+ICsJYm9vbAlncGlvX3JlZ2lzdGVyZWQ7ICAvKiBpcyB0aGUg Z3Bpb2NoaXAgaW4ga2VybmVsIHJlZ2lzdGVyZWQgKi8KPiArCWJvb2wJZ3Bpb191c2VkOwkgIC8q IHRydWUgaWYgdGhlIHVzZXIgcmVxdWVzdGVkIGEgZ3BpbyAqLwo+ICsJdTgJZ3Bpb19hbHRmdW5j OwkgIC8qIHdoaWNoIHBpbnMgYXJlIGluIGdwaW8gbW9kZSAqLwo+ICsJdTgJZ3Bpb19pbnB1dDsJ ICAvKiBwaW4gZGlyZWN0aW9ucyBjYWNoZSAqLwo+ICsJdTgJZ3Bpb192YWx1ZTsJICAvKiBwaW4g dmFsdWUgZm9yIG91dHB1dHMgKi8KPiArI2VuZGlmCj4gIH07Cj4gIAo+ICAvKiBzdHJ1Y3QgZnRk aV9zaW9fcXVpcmsgaXMgdXNlZCBieSBkZXZpY2VzIHJlcXVpcmluZyBzcGVjaWFsIGF0dGVudGlv bi4gKi8KPiBAQCAtMTc2Niw2ICsxNzc3LDI2OCBAQCBzdGF0aWMgdm9pZCByZW1vdmVfc3lzZnNf YXR0cnMoc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCkKPiAgCj4gIH0KPiAgCj4gKyNpZmRl ZiBDT05GSUdfR1BJT0xJQgo+ICsKPiArc3RhdGljIGludCBmdGRpX3Npb19zZXRfY2J1cyhzdHJ1 Y3QgdXNiX3NlcmlhbF9wb3J0ICpwb3J0LAoKUGxlYXNlIGRyb3AgdGhlICJfc2lvIiBpbmZpeCBm cm9tIHlvdXIgZnVuY3Rpb25zLCAiZnRkaV8iIGFzIHByZWZpeCBpcwplbm91Z2guCgo+ICsJCQkg ICAgIHU4IGRpcmVjdGlvbiwKPiArCQkJICAgICB1OCB2YWx1ZSwKPiArCQkJICAgICB1OCBtb2Rl KQo+ICt7Cj4gKwlzdHJ1Y3QgZnRkaV9wcml2YXRlICpwcml2ID0gdXNiX2dldF9zZXJpYWxfcG9y dF9kYXRhKHBvcnQpOwoKU2luY2UgeW91IGhhdmUgcG9ydCBhbmQgcHJpdiBoZXJlIGFueXdheSwg eW91IGNvdWxkIGNvbnNpZGVyIG5vdCBwYXNzaW5nCmRpcmVjdGlvbiBhbmQgdmFsdWUgaW4gZXZl cnkgY2FsbC4gRXZlbiBtb2RlIGNvdWxkIGdvLCBpZiB5b3UgYWRkIGEKc2VwYXJhdGUgaGVscGVy IGZvciB0aGF0LCB3aGljaCB3b3VsZCBhbHNvIG1ha2UgdGhpcyBmdW5jdGlvbiBtb3JlCmFwcHJv cHJpYXRlbHkgbmFtZWQuCgo+ICsJdTE2IHZhbDsKPiArCj4gKwkvKiBkZXZpY2UncyBkaXJlY3Rp b24gcG9sYXJpdHkgaXMgZGlmZmVyZW50IGZyb20ga2VybmVsJ3MgKi8KCldoeSBzbz8gWW91IGNv dWxkIGp1c3QgcmVwbGFjZSBncGlvX2lucHV0IHdpdGggZ3Bpb19vdXRwdXQuIEkgdGhpbmsgdGhh dAptYXkgYmUgcHJlZmVycmVkLgoKPiArCWRpcmVjdGlvbiA9ICh+ZGlyZWN0aW9uKSAmIDB4MGY7 Cj4gKwo+ICsJdmFsID0gKG1vZGUgPDwgOCkgfCAoZGlyZWN0aW9uIDw8IDQpIHwgKHZhbHVlICYg MHgwZik7Cj4gKwlyZXR1cm4gdXNiX2NvbnRyb2xfbXNnKHBvcnQtPnNlcmlhbC0+ZGV2LAo+ICsJ CQkJIHVzYl9zbmRjdHJscGlwZShwb3J0LT5zZXJpYWwtPmRldiwgMCksCj4gKwkJCQkgRlRESV9T SU9fU0VUX0JJVE1PREVfUkVRVUVTVCwKPiArCQkJCSBGVERJX1NJT19TRVRfQklUTU9ERV9SRVFV RVNUX1RZUEUsIHZhbCwKPiArCQkJCSBwcml2LT5pbnRlcmZhY2UsIE5VTEwsIDAsIFdEUl9USU1F T1VUKTsKCkkgdGhpbmsgeW91IHNob3VsZCBsb2cgYW55IGVycm9ycyBoZXJlIChldmVuIGlmIHRo YXQgbWVhbnMgdHdvIGVycm9yCm1lc3NhZ2VzIGZvciBmYWlsZWQgc2V0KCkpLgoKPiArfQo+ICsK PiArc3RhdGljIGludCBmdGRpX3Npb19ncGlvX3JlcXVlc3Qoc3RydWN0IGdwaW9fY2hpcCAqZ2Ms IHVuc2lnbmVkIGludCBvZmZzZXQpCj4gK3sKPiArCXN0cnVjdCB1c2Jfc2VyaWFsX3BvcnQgKnBv cnQgPSBncGlvY2hpcF9nZXRfZGF0YShnYyk7Cj4gKwlzdHJ1Y3QgZnRkaV9wcml2YXRlICpwcml2 ID0gdXNiX2dldF9zZXJpYWxfcG9ydF9kYXRhKHBvcnQpOwo+ICsJaW50IHJlc3VsdCA9IDA7CgpO byBuZWVkIHRvIGluaXRpYWxpc2UuCgo+ICsKPiArCWlmIChwcml2LT5ncGlvX2FsdGZ1bmMgJiBC SVQob2Zmc2V0KSkKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCj4gKwlpZiAoIXByaXYtPmdwaW9f dXNlZCkgewo+ICsJCS8qIFNldCBkZWZhdWx0IHBpbiBzdGF0ZXMsIGFzIHdlIGNhbm5vdCBnZXQg dGhlbSBmcm9tIGRldmljZSAqLwo+ICsJCXByaXYtPmdwaW9faW5wdXQgPSAweGZmOwo+ICsJCXBy aXYtPmdwaW9fdmFsdWUgPSAweDAwOwo+ICsJCXJlc3VsdCA9IGZ0ZGlfc2lvX3NldF9jYnVzKHBv cnQsCj4gKwkJCQkJICAgcHJpdi0+Z3Bpb19pbnB1dCwKPiArCQkJCQkgICBwcml2LT5ncGlvX3Zh bHVlLAo+ICsJCQkJCSAgIEZURElfU0lPX0dQSU9fTU9ERV9DQlVTKTsKPiArCQlpZiAocmVzdWx0 KQo+ICsJCQlyZXR1cm4gcmVzdWx0Owo+ICsKPiArCQlwcml2LT5ncGlvX3VzZWQgPSB0cnVlOwo+ ICsJfQoKU28gSSB0aGluayB0aGlzIGluaXRpYWxpc2F0aW9uIHNob3VsZCBiZSBkb25lIGF0IHBy b2JlIGluc3RlYWQuCgo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGZ0 ZGlfc2lvX2dwaW9fZ2V0KHN0cnVjdCBncGlvX2NoaXAgKmdjLCB1bnNpZ25lZCBpbnQgZ3BpbykK PiArewo+ICsJc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCA9IGdwaW9jaGlwX2dldF9kYXRh KGdjKTsKPiArCXN0cnVjdCBmdGRpX3ByaXZhdGUgKnByaXYgPSB1c2JfZ2V0X3NlcmlhbF9wb3J0 X2RhdGEocG9ydCk7Cj4gKwlzdHJ1Y3QgdXNiX3NlcmlhbCAqc2VyaWFsID0gcG9ydC0+c2VyaWFs Owo+ICsJdW5zaWduZWQgY2hhciAqcmN2YnVmOwo+ICsJaW50IHJlc3VsdDsKPiArCj4gKwlyY3Zi dWYgPSBrbWFsbG9jKDEsIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFyY3ZidWYpCj4gKwkJcmV0dXJu IC1FTk9NRU07Cj4gKwo+ICsJcmVzdWx0ID0gdXNiX2NvbnRyb2xfbXNnKHNlcmlhbC0+ZGV2LAo+ ICsJCQkJIHVzYl9yY3ZjdHJscGlwZShzZXJpYWwtPmRldiwgMCksCj4gKwkJCQkgRlRESV9TSU9f UkVBRF9QSU5TX1JFUVVFU1QsCj4gKwkJCQkgRlRESV9TSU9fUkVBRF9QSU5TX1JFUVVFU1RfVFlQ RSwgMCwKPiArCQkJCSBwcml2LT5pbnRlcmZhY2UsIHJjdmJ1ZiwgMSwgV0RSX1RJTUVPVVQpOwo+ ICsKCk5vIG5ld2xpbmUuCgo+ICsJaWYgKHJlc3VsdCA8IDEpCj4gKwkJcmVzdWx0ID0gLUVJTzsK PiArCWVsc2UKPiArCQlyZXN1bHQgPSAhIShyY3ZidWZbMF0gJiBCSVQoZ3BpbykpOwo+ICsKPiAr CWtmcmVlKHJjdmJ1Zik7Cj4gKwo+ICsJcmV0dXJuIHJlc3VsdDsKPiArfQo+ICsKPiArc3RhdGlj IHZvaWQgZnRkaV9zaW9fZ3Bpb19zZXQoc3RydWN0IGdwaW9fY2hpcCAqZ2MsCj4gKwkJCSAgICAg IHVuc2lnbmVkIGludCBncGlvLAo+ICsJCQkgICAgICBpbnQgdmFsdWUKPiArKQoKQ2xvc2luZyBw YXJlbnRoZXNlcyBnb2VzIGFmdGVyIHZhbHVlLgoKPiArewo+ICsJc3RydWN0IHVzYl9zZXJpYWxf cG9ydCAqcG9ydCA9IGdwaW9jaGlwX2dldF9kYXRhKGdjKTsKPiArCXN0cnVjdCBmdGRpX3ByaXZh dGUgKnByaXYgPSB1c2JfZ2V0X3NlcmlhbF9wb3J0X2RhdGEocG9ydCk7Cj4gKwlpbnQgcmVzdWx0 Owo+ICsKPiArCWlmICh2YWx1ZSkKPiArCQlwcml2LT5ncGlvX3ZhbHVlIHw9IEJJVChncGlvKTsK PiArCWVsc2UKPiArCQlwcml2LT5ncGlvX3ZhbHVlICY9IH5CSVQoZ3Bpbyk7Cj4gKwo+ICsJcmVz dWx0ID0gZnRkaV9zaW9fc2V0X2NidXMocG9ydCwKPiArCQkJCSAgIHByaXYtPmdwaW9faW5wdXQs Cj4gKwkJCQkgICBwcml2LT5ncGlvX3ZhbHVlLAo+ICsJCQkJICAgRlRESV9TSU9fR1BJT19NT0RF X0NCVVMpOwo+ICsKCk5vIG5ld2xpbmUuCgo+ICsJaWYgKHJlc3VsdCA8IDApIHsKPiArCQlkZXZf ZXJyKCZwb3J0LT5zZXJpYWwtPmludGVyZmFjZS0+ZGV2LAo+ICsJCQkiZmFpbGVkIHRvIHNldCBH UElPIHZhbHVlOiAlZFxuIiwKPiArCQkJcmVzdWx0KTsKPiArCX0KPiArfQo+ICsKPiArc3RhdGlj IGludCBmdGRpX3Npb19ncGlvX2RpcmVjdGlvbl9nZXQoc3RydWN0IGdwaW9fY2hpcCAqZ2MsCj4g KwkJCQkgICAgICAgdW5zaWduZWQgaW50IGdwaW8pCj4gK3sKPiArCXN0cnVjdCB1c2Jfc2VyaWFs X3BvcnQgKnBvcnQgPSBncGlvY2hpcF9nZXRfZGF0YShnYyk7Cj4gKwlzdHJ1Y3QgZnRkaV9wcml2 YXRlICpwcml2ID0gdXNiX2dldF9zZXJpYWxfcG9ydF9kYXRhKHBvcnQpOwo+ICsKPiArCXJldHVy biBwcml2LT5ncGlvX2lucHV0ICYgQklUKGdwaW8pOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGZ0 ZGlfc2lvX2dwaW9fZGlyZWN0aW9uX2lucHV0KHN0cnVjdCBncGlvX2NoaXAgKmdjLAo+ICsJCQkJ CSB1bnNpZ25lZCBpbnQgZ3BpbykKPiArewo+ICsJc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9y dCA9IGdwaW9jaGlwX2dldF9kYXRhKGdjKTsKPiArCXN0cnVjdCBmdGRpX3ByaXZhdGUgKnByaXYg PSB1c2JfZ2V0X3NlcmlhbF9wb3J0X2RhdGEocG9ydCk7Cj4gKwo+ICsJcHJpdi0+Z3Bpb19pbnB1 dCB8PSBCSVQoZ3Bpbyk7Cj4gKwo+ICsJcmV0dXJuIGZ0ZGlfc2lvX3NldF9jYnVzKHBvcnQsCj4g KwkJCSAgcHJpdi0+Z3Bpb19pbnB1dCwKPiArCQkJICBwcml2LT5ncGlvX3ZhbHVlLAo+ICsJCQkg IEZURElfU0lPX0dQSU9fTU9ERV9DQlVTKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBmdGRpX3Np b19ncGlvX2RpcmVjdGlvbl9vdXRwdXQoc3RydWN0IGdwaW9fY2hpcCAqZ2MsCj4gKwkJCQkJICB1 bnNpZ25lZCBpbnQgZ3BpbywKPiArCQkJCQkgIGludCB2YWx1ZSkKPiArewo+ICsJc3RydWN0IHVz Yl9zZXJpYWxfcG9ydCAqcG9ydCA9IGdwaW9jaGlwX2dldF9kYXRhKGdjKTsKPiArCXN0cnVjdCBm dGRpX3ByaXZhdGUgKnByaXYgPSB1c2JfZ2V0X3NlcmlhbF9wb3J0X2RhdGEocG9ydCk7Cj4gKwo+ ICsJcHJpdi0+Z3Bpb19pbnB1dCAmPSB+QklUKGdwaW8pOwo+ICsJaWYgKHZhbHVlKQo+ICsJCXBy aXYtPmdwaW9fdmFsdWUgfD0gQklUKGdwaW8pOwo+ICsJZWxzZQo+ICsJCXByaXYtPmdwaW9fdmFs dWUgJj0gfkJJVChncGlvKTsKPiArCj4gKwlyZXR1cm4gZnRkaV9zaW9fc2V0X2NidXMocG9ydCwK PiArCQkJICBwcml2LT5ncGlvX2lucHV0LAo+ICsJCQkgIHByaXYtPmdwaW9fdmFsdWUsCj4gKwkJ CSAgRlRESV9TSU9fR1BJT19NT0RFX0NCVVMpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGZ0eF9n cGlvY29uZl9pbml0KHN0cnVjdCB1c2Jfc2VyaWFsX3BvcnQgKnBvcnQpCj4gK3sKPiArCXN0cnVj dCBmdGRpX3ByaXZhdGUgKnByaXYgPSB1c2JfZ2V0X3NlcmlhbF9wb3J0X2RhdGEocG9ydCk7Cj4g KwlzdHJ1Y3QgdXNiX3NlcmlhbCAqc2VyaWFsID0gcG9ydC0+c2VyaWFsOwo+ICsJY29uc3QgdTE2 IGNvbmZpZ19zaXplID0gMHgyNDsKPiArCXU4ICpjb25maWdfYnVmOwo+ICsJaW50IHJlc3VsdDsK PiArCXU4IGk7Cj4gKwo+ICsJLyogUmVhZCBwYXJ0IG9mIGRldmljZSBFRVBST00gKi8KPiArCWNv bmZpZ19idWYgPSBrbWFsbG9jKGNvbmZpZ19zaXplLCBHRlBfS0VSTkVMKTsKPiArCWlmICghY29u ZmlnX2J1ZikKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwgY29u ZmlnX3NpemUgLyAyOyBpKyspIHsKPiArCQlyZXN1bHQgPSB1c2JfY29udHJvbF9tc2coc2VyaWFs LT5kZXYsCj4gKwkJCQkJIHVzYl9yY3ZjdHJscGlwZShzZXJpYWwtPmRldiwgMCksCj4gKwkJCQkJ IEZURElfU0lPX1JFQURfRUVQUk9NX1JFUVVFU1QsCj4gKwkJCQkJIEZURElfU0lPX1JFQURfRUVQ Uk9NX1JFUVVFU1RfVFlQRSwgMCwKPiArCQkJCQkgaSwgY29uZmlnX2J1ZiArIChpICogMiksCgoy ICogaSwgcGFyZW50aGVzaXMgbm90IG5lZWRlZAoKPiArCQkJCQkgMiwgV0RSX1RJTUVPVVQpOwo+ ICsJCWlmIChyZXN1bHQgPCAyKSB7Cj4gKwkJCXJlc3VsdCA9IC1FSU87CgpSZXR1cm4gLUVJTyBm b3Igc2hvcnQgdHJhbnNmZXJzLCBidXQganVzdCByZXR1cm4gcmVzdWx0IG90aGVyd2lzZS4KCj4g KwkJCWJyZWFrOwo+ICsJCX0KPiArCX0KPiArCj4gKwlpZiAocmVzdWx0IDwgMCkgewo+ICsJCWtm cmVlKGNvbmZpZ19idWYpOwo+ICsJCXJldHVybiByZXN1bHQ7Cj4gKwl9CgpGYWN0b3IgdGhpcyBv dXQgdG8gYW4gZWVwcm9tIGhlbHBlciB0aGF0IGNhbiBiZSByZXVzZWQgYnkgb3RoZXIgY2hpcAp0 eXBlcy4KCj4gKwo+ICsJLyoKPiArCSAqIEFsbCBGVC1YIGRldmljZXMgaGF2ZSBhdCBsZWFzdCAx IEdQSU8sIHNvbWUgaGF2ZSBtb3JlLgo+ICsJICogQ2hpcC10eXBlIGd1ZXNzaW5nIGxvZ2ljIGJh c2VkIG9uIGxpYmZ0ZGkuCj4gKwkgKi8KPiArCXByaXYtPmdjLm5ncGlvID0gMTsKPiArCWlmIChz ZXJpYWwtPmRldi0+ZGVzY3JpcHRvci5iY2REZXZpY2UgPT0gMHgxMDAwKSAgLyogRlQyMzBYICov CgpNaXNzaW5nIGxlMTZfdG9fY3B1KCkuCgo+ICsJCXByaXYtPmdjLm5ncGlvID0gNDsKClNob3Vs ZG4ndCB0aGlzIGJlIGhhbmRsZWQgdGhlIG90aGVyIHdheSByb3VuZD8gSUlSQyB0aGVyZSBhcmUg dHdvIEZUWApkZXZpY2UgdHlwZXMgd2l0aCBmb3VyIHBpbnMsIGFuZCBvbmUgdHlwZSB3aGVyZSBv bmx5IG9uZSBwaW4gaXMKYWNjZXNzaWJsZS4KCj4gKwo+ICsJLyogRGV0ZXJtaW5lIHdoaWNoIHBp bnMgYXJlIGNvbmZpZ3VyZWQgZm9yIENCVVMgYml0YmFuZ2luZyAqLwo+ICsJcHJpdi0+Z3Bpb19h bHRmdW5jID0gMHhmZjsKPiArCWZvciAoaSA9IDA7IGkgPCBwcml2LT5nYy5uZ3BpbzsgKytpKSB7 Cj4gKwkJaWYgKGNvbmZpZ19idWZbMHgxQSArIGldID09IEZURElfU0lPX0NCVVNfTVVYX0dQSU8p CgoweDFhIHdhcnJhbnRzIGEgZGVmaW5lOyBidXQgeW91IHNob3VsZG4ndCBiZSByZWFkaW5nIDB4 MjQgYnl0ZXMgZnJvbQpvZmZzZXQgMCBhYm92ZSB3aGVuIHRoZSBwaW5jb25maWcgaXMgc3RvcmVk IGluIGp1c3QgYSBjb3VwbGUgb2Ygd29yZHMuCgo+ICsJCQlwcml2LT5ncGlvX2FsdGZ1bmMgJj0g fkJJVChpKTsKPiArCX0KPiArCj4gKwlrZnJlZShjb25maWdfYnVmKTsKPiArCj4gKwlyZXR1cm4g MDsKPiArfQo+ICsKPiArc3RhdGljIGludCBmdGRpX3Npb19ncGlvX2luaXQoc3RydWN0IHVzYl9z ZXJpYWxfcG9ydCAqcG9ydCkKPiArewo+ICsJc3RydWN0IGZ0ZGlfcHJpdmF0ZSAqcHJpdiA9IHVz Yl9nZXRfc2VyaWFsX3BvcnRfZGF0YShwb3J0KTsKPiArCXN0cnVjdCB1c2Jfc2VyaWFsICpzZXJp YWwgPSBwb3J0LT5zZXJpYWw7Cj4gKwlpbnQgcmVzdWx0Owo+ICsKPiArCS8qIERldmljZS1zcGVj aWZpYyBpbml0aWFsaXphdGlvbnMgKi8KPiArCXN3aXRjaCAocHJpdi0+Y2hpcF90eXBlKSB7Cj4g KwljYXNlIEZUWDoKPiArCQlyZXN1bHQgPSBmdHhfZ3Bpb2NvbmZfaW5pdChwb3J0KTsKPiArCQli cmVhazsKPiArCWRlZmF1bHQ6Cj4gKwkJcmV0dXJuIDA7Cj4gKwl9Cj4gKwo+ICsJaWYgKHJlc3Vs dCA8IDApCj4gKwkJcmV0dXJuIHJlc3VsdDsKPiArCj4gKwkvKiBSZWdpc3RlciBHUElPIGNoaXAg dG8ga2VybmVsICovCj4gKwlwcml2LT5nYy5sYWJlbCA9ICJmdGRpX3NpbyI7CgpNYXliZSB3ZSBz aG91bGRuJ3QgdXNlIHRoZSBsZWdhY3kgc2lvIHN1ZmZpeCBoZXJlOyAiZnRkaSIgb3IgImZ0ZGkt Y2J1cyIKc2hvdWxkIGRvLgoKPiArCXByaXYtPmdjLnJlcXVlc3QgPSBmdGRpX3Npb19ncGlvX3Jl cXVlc3Q7Cj4gKwlwcml2LT5nYy5nZXRfZGlyZWN0aW9uID0gZnRkaV9zaW9fZ3Bpb19kaXJlY3Rp b25fZ2V0Owo+ICsJcHJpdi0+Z2MuZGlyZWN0aW9uX2lucHV0ID0gZnRkaV9zaW9fZ3Bpb19kaXJl Y3Rpb25faW5wdXQ7Cj4gKwlwcml2LT5nYy5kaXJlY3Rpb25fb3V0cHV0ID0gZnRkaV9zaW9fZ3Bp b19kaXJlY3Rpb25fb3V0cHV0Owo+ICsJcHJpdi0+Z2MuZ2V0ID0gZnRkaV9zaW9fZ3Bpb19nZXQ7 Cj4gKwlwcml2LT5nYy5zZXQgPSBmdGRpX3Npb19ncGlvX3NldDsKPiArCXByaXYtPmdjLm93bmVy ID0gVEhJU19NT0RVTEU7Cj4gKwlwcml2LT5nYy5wYXJlbnQgPSAmc2VyaWFsLT5pbnRlcmZhY2Ut PmRldjsKPiArCXByaXYtPmdjLmJhc2UgPSAtMTsKPiArCXByaXYtPmdjLmNhbl9zbGVlcCA9IHRy dWU7Cj4gKwo+ICsJcmVzdWx0ID0gZ3Bpb2NoaXBfYWRkX2RhdGEoJnByaXYtPmdjLCBwb3J0KTsK PiArCWlmICghcmVzdWx0KQo+ICsJCXByaXYtPmdwaW9fcmVnaXN0ZXJlZCA9IHRydWU7Cj4gKwo+ ICsJcmV0dXJuIHJlc3VsdDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgZnRkaV9zaW9fZ3Bpb19y ZW1vdmUoc3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCkKPiArewo+ICsJc3RydWN0IGZ0ZGlf cHJpdmF0ZSAqcHJpdiA9IHVzYl9nZXRfc2VyaWFsX3BvcnRfZGF0YShwb3J0KTsKPiArCj4gKwlp ZiAocHJpdi0+Z3Bpb191c2VkKSB7Cj4gKwkJZnRkaV9zaW9fc2V0X2NidXMocG9ydCwgMCwgMCwg RlRESV9TSU9fR1BJT19NT0RFX1JFU0VUKTsKCklJUkMgdGhpcyBsZWF2ZXMgdGhlIHBpbnMgaW4g dGhlIHN0YXRlIHRoYXQgd2Ugc2V0IHRoZW0sIHdoaWNoIGlzIGZpbmUsCmJ1dCBjb3VsZCBiZSBo aWdobGlnaHRlZCBoZXJlLgoKPiArCQlwcml2LT5ncGlvX3VzZWQgPSBmYWxzZTsKPiArCX0KPiAr Cj4gKwlpZiAocHJpdi0+Z3Bpb19yZWdpc3RlcmVkKSB7Cj4gKwkJZ3Bpb2NoaXBfcmVtb3ZlKCZw cml2LT5nYyk7Cj4gKwkJcHJpdi0+Z3Bpb19yZWdpc3RlcmVkID0gZmFsc2U7Cj4gKwl9Cj4gK30K PiArCj4gKyNlbHNlCj4gKwo+ICtzdGF0aWMgaW50IGZ0ZGlfc2lvX2dwaW9faW5pdChzdHJ1Y3Qg dXNiX3NlcmlhbCAqc2VyaWFsKQoKQXMgdGhlIHRlc3Qgcm9ib3QgcmVwb3J0ZWQsIHRoZXNlIHNo b3VsZCB0YWtlIGEgcG9ydCBhcyB0aGVpciBhcmd1bWVudC4KCj4gK3sKPiArCXJldHVybiAwOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBmdGRpX3Npb19ncGlvX3JlbW92ZShzdHJ1Y3QgdXNiX3Nl cmlhbCAqc2VyaWFsKQo+ICt7Cj4gKwkvKiBOb3RoaW5nIHRvIGRvICovCgpDb21tZW50IG5vdCBy ZWFsbHkgbmVlZGVkOyB5b3UgY2FuIGV2ZW4gcHV0IHRoZSBicmFja2V0cyBhZnRlciB0aGUKY2xv c2luZyBwYXJlbnRoZXNlcwoKCS4uLiogc2VyaWFsKSB7IH0KCmFzIHdlIHNvbWV0aW1lcyBkbyBp biBoZWFkZXJzLCBpZiB5b3Ugd2FudC4KCj4gK30KPiArCj4gKyNlbmRpZgo+ICsKPiAgLyoKPiAg ICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqCj4gICAqIEZUREkgZHJpdmVyIHNwZWNpZmljIGZ1bmN0aW9u cwo+IEBAIC0xNzk0LDcgKzIwNjcsNyBAQCBzdGF0aWMgaW50IGZ0ZGlfc2lvX3BvcnRfcHJvYmUo c3RydWN0IHVzYl9zZXJpYWxfcG9ydCAqcG9ydCkKPiAgewo+ICAJc3RydWN0IGZ0ZGlfcHJpdmF0 ZSAqcHJpdjsKPiAgCWNvbnN0IHN0cnVjdCBmdGRpX3Npb19xdWlyayAqcXVpcmsgPSB1c2JfZ2V0 X3NlcmlhbF9kYXRhKHBvcnQtPnNlcmlhbCk7Cj4gLQo+ICsJaW50IHJlc3VsdDsKPiAgCj4gIAlw cml2ID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IGZ0ZGlfcHJpdmF0ZSksIEdGUF9LRVJORUwpOwo+ ICAJaWYgKCFwcml2KQo+IEBAIC0xODEzLDYgKzIwODYsMTMgQEAgc3RhdGljIGludCBmdGRpX3Np b19wb3J0X3Byb2JlKHN0cnVjdCB1c2Jfc2VyaWFsX3BvcnQgKnBvcnQpCj4gIAkJcHJpdi0+bGF0 ZW5jeSA9IDE2Owo+ICAJd3JpdGVfbGF0ZW5jeV90aW1lcihwb3J0KTsKPiAgCWNyZWF0ZV9zeXNm c19hdHRycyhwb3J0KTsKPiArCj4gKwlyZXN1bHQgPSBmdGRpX3Npb19ncGlvX2luaXQocG9ydCk7 Cj4gKwlpZiAocmVzdWx0IDwgMCkKPiArCQlkZXZfZXJyKCZwb3J0LT5zZXJpYWwtPmludGVyZmFj ZS0+ZGV2LAo+ICsJCQkiR1BJTyBpbml0aWFsaXNhdGlvbiBmYWlsZWQ6ICVkXG4iLAo+ICsJCQly ZXN1bHQpOwoKUGxlYXNlIHVzZSBicmFja2V0cyBmb3IgY29uZGl0aW9uYWxzIHdpdGggbXVsdGkt bGluZSBzdGF0ZW1lbnRzLgoKPiArCj4gIAlyZXR1cm4gMDsKPiAgfQo+ICAKPiBAQCAtMTkzMCw2 ICsyMjEwLDggQEAgc3RhdGljIGludCBmdGRpX3Npb19wb3J0X3JlbW92ZShzdHJ1Y3QgdXNiX3Nl cmlhbF9wb3J0ICpwb3J0KQo+ICB7Cj4gIAlzdHJ1Y3QgZnRkaV9wcml2YXRlICpwcml2ID0gdXNi X2dldF9zZXJpYWxfcG9ydF9kYXRhKHBvcnQpOwo+ICAKPiArCWZ0ZGlfc2lvX2dwaW9fcmVtb3Zl KHBvcnQpOwo+ICsKPiAgCXJlbW92ZV9zeXNmc19hdHRycyhwb3J0KTsKPiAgCj4gIAlrZnJlZShw cml2KTsKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2Ivc2VyaWFsL2Z0ZGlfc2lvLmggYi9kcml2 ZXJzL3VzYi9zZXJpYWwvZnRkaV9zaW8uaAo+IGluZGV4IGRjZDBiNmUwNWJhZi4uNTA0NmQwMmZl M2FjIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvdXNiL3NlcmlhbC9mdGRpX3Npby5oCj4gKysrIGIv ZHJpdmVycy91c2Ivc2VyaWFsL2Z0ZGlfc2lvLmgKPiBAQCAtMzYsNiArMzYsMTAgQEAKPiAgI2Rl ZmluZSBGVERJX1NJT19TRVRfRVJST1JfQ0hBUgkJNyAvKiBTZXQgdGhlIGVycm9yIGNoYXJhY3Rl ciAqLwo+ICAjZGVmaW5lIEZURElfU0lPX1NFVF9MQVRFTkNZX1RJTUVSCTkgLyogU2V0IHRoZSBs YXRlbmN5IHRpbWVyICovCj4gICNkZWZpbmUgRlRESV9TSU9fR0VUX0xBVEVOQ1lfVElNRVIJMTAg LyogR2V0IHRoZSBsYXRlbmN5IHRpbWVyICovCj4gKyNkZWZpbmUgRlRESV9TSU9fU0VUX0JJVE1P REUJCTExIC8qIFNldCBDQlVTIEdQSU8gcGluIG1vZGUgKi8KPiArI2RlZmluZSBGVERJX1NJT19S RUFEX1BJTlMJCTEyIC8qIFJlYWQgaW1tZWRpYXRlIHZhbHVlIG9mIHBpbnMgKi8KPiArI2RlZmlu ZSBGVERJX1NJT19SRUFEX0VFUFJPTQkJMTQ0IC8qIFJlYWQgRUVQUk9NICovCgpQbGVhc2UgdXNl IGhleCBub3RhdGlvbi4KCj4gKwo+ICAKPiAgLyogSW50ZXJmYWNlIGluZGljZXMgZm9yIEZUMjIz MiwgRlQyMjMySCBhbmQgRlQ0MjMySCBkZXZpY2VzICovCj4gICNkZWZpbmUgSU5URVJGQUNFX0EJ CTEKPiBAQCAtNDMzLDYgKzQzNywyNyBAQCBlbnVtIGZ0ZGlfc2lvX2JhdWRyYXRlIHsKPiAgICog ICAgICAgICAxID0gYWN0aXZlCj4gICAqLwo+ICAKPiArLyogRlRESV9TSU9fU0VUX0JJVE1PREUg Ki8KPiArI2RlZmluZSBGVERJX1NJT19TRVRfQklUTU9ERV9SRVFVRVNUX1RZUEUgMHg0MAo+ICsj ZGVmaW5lIEZURElfU0lPX1NFVF9CSVRNT0RFX1JFUVVFU1QgRlRESV9TSU9fU0VUX0JJVE1PREUK ClRoaXMgbG9va3MgYXdmdWxseSByZWR1bmRhbnQsIGJ1dCBJIHJlYWxpc2UgeW91J3JlIGp1c3Qg c3RpY2tpbmcgdG8gdGhlCmN1cnJlbnQgcGF0dGVybiAoYXMgeW91IHNob3VsZCkuCgo+ICsKPiAr LyogRlRESV9TSU9fUkVBRF9QSU5TICovCj4gKyNkZWZpbmUgRlRESV9TSU9fUkVBRF9QSU5TX1JF UVVFU1RfVFlQRSAweGMwCj4gKyNkZWZpbmUgRlRESV9TSU9fUkVBRF9QSU5TX1JFUVVFU1QgRlRE SV9TSU9fUkVBRF9QSU5TCj4gKwo+ICsvKgo+ICsgKiBGVERJX1NJT19SRUFEX0VFUFJPTQo+ICsg Kgo+ICsgKiBFRVBST00gZm9ybWF0IGZvdW5kIGluIEZUREkgQU5fMjAxLCAiRlQtWCBNVFAgbWVt b3J5IENvbmZpZ3VyYXRpb24iLAo+ICsgKiBodHRwOi8vd3d3LmZ0ZGljaGlwLmNvbS9TdXBwb3J0 L0RvY3VtZW50cy9BcHBOb3Rlcy9BTl8yMDFfRlQtWCUyME1UUCUyME1lbW9yeSUyMENvbmZpZ3Vy YXRpb24ucGRmCj4gKyAqLwo+ICsjZGVmaW5lIEZURElfU0lPX1JFQURfRUVQUk9NX1JFUVVFU1Rf VFlQRSAweGMwCj4gKyNkZWZpbmUgRlRESV9TSU9fUkVBRF9FRVBST01fUkVRVUVTVCBGVERJX1NJ T19SRUFEX0VFUFJPTQo+ICsKPiArI2RlZmluZSBGVERJX1NJT19HUElPX01PREVfQ0JVUwkJMHgy MAo+ICsjZGVmaW5lIEZURElfU0lPX0dQSU9fTU9ERV9SRVNFVAkweDAwCgpTb3J0IHRoZSBtb2Rl IGRlZmluZXMgYnkgdmFsdWUgaGVyZS4KCkFuZCB0aGVzZSBiZWxvbmcgd2l0aCBGVERJX1NFVF9C SVRNT0RFIGFib3ZlIGFuZCBzaG91bGQgYmUgcmVuYW1lZCB0bwpyZWZsZWN0IHRoYXQuCgo+ICsK PiArI2RlZmluZSBGVERJX1NJT19DQlVTX01VWF9HUElPCQk4Cj4gIAo+ICAKPiAgLyogRGVzY3Jp cHRvcnMgcmV0dXJuZWQgYnkgdGhlIGRldmljZQoKVGhhbmtzLApKb2hhbgo= 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=-2.4 required=3.0 tests=DKIM_SIGNED, MAILING_LIST_MULTI,SPF_PASS,T_DKIM_INVALID,URIBL_BLOCKED,USER_AGENT_MUTT 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 75858C433F5 for ; Tue, 4 Sep 2018 12:49:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F17BE2082B for ; Tue, 4 Sep 2018 12:49:21 +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="cQ0AH+GI" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F17BE2082B 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 S1727335AbeIDROT (ORCPT ); Tue, 4 Sep 2018 13:14:19 -0400 Received: from mail-lf1-f65.google.com ([209.85.167.65]:36971 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726157AbeIDROT (ORCPT ); Tue, 4 Sep 2018 13:14:19 -0400 Received: by mail-lf1-f65.google.com with SMTP id j8-v6so2838689lfb.4; Tue, 04 Sep 2018 05:49:17 -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=D6r0/+tpMLxVYW9JUwh0t/MIXhembdiDSeOxGXmx4HU=; b=cQ0AH+GIj0lWXQ/I1eBMfUx5TtxDKGAdpGaW3wasplltzpQFfBR1/mkPF4+IMUNUE+ BU9flze7Fmkv1sYacX9qfkBdXhbr05oqM7yYoA45GwCnYOlHc5r5vVsl2xO5e9zEBe7l ypOtbOeuQuc1s6zRJ2m8xNMlIhXRobqylIxaDncTUP1CbEHpZ71nimcL42t1DshMInf5 mNmGqXKgrYZKDGp6daxE/pDiiRcXHjDmli+nJ93NJYf/PkFky4H+lsiG4dnKVXUFUQGV jip+hVS99kkfNo3Tsnl2loGBuH90Gegdw7P3ZM5a/aK4V0zygs+vQrZRvOOm7aBfnNgi sTrw== 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=D6r0/+tpMLxVYW9JUwh0t/MIXhembdiDSeOxGXmx4HU=; b=BvZea3c3E8GuZazXaFJoDUNrtFIfBniX36RPBSx30Z1gG4VWIvFANF5OiXwYuZ1YeR 6EENL6U+u0zLklOqW+wQqrmrKFOMV+jTAfD/MPPB3rn1u5R/nbeswW/3Dvgn73khUTuX iPxX0N4thV1rMPTytGxMex0YXmoyFfSJ2XCsbiwFSMB8DiYz53WBQra7JHU9244En+Lb hJYqrJ4B6mSe2IDqJjAQHdGtkkVk7q2mpurTd8TWac3t0IPwLnn1mQawHbPBImzrSJ5c NkEH7DovAufQNTnUGQn8E912TaLTgUB0Brd5Q7zFVqw/3M8kGUcRAaMBbD+L3bqwJmrw PaKw== X-Gm-Message-State: APzg51AjqaKE3ZfR5B6qXOCQ3HxewNyE3h3+fjh9NiFt5r2quoYwwNLK z5R/W9j6Pn6v/nWhIb18UoQ= X-Google-Smtp-Source: ANB0VdYlJ/B+TllGHlCBMkIH+A0Vx6XBNT6awm2xq4UNez/jKm7buVL6xTr+FKKmDnohiNdp7Dhk6A== X-Received: by 2002:a19:4288:: with SMTP id p130-v6mr621449lfa.154.1536065356364; Tue, 04 Sep 2018 05:49:16 -0700 (PDT) Received: from xi.terra (c-74bee655.07-184-6d6c6d4.bbcust.telenor.se. [85.230.190.116]) by smtp.gmail.com with ESMTPSA id f4-v6sm4093010lfa.9.2018.09.04.05.49.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Sep 2018 05:49:15 -0700 (PDT) Received: from johan by xi.terra with local (Exim 4.91) (envelope-from ) id 1fxAlo-0001by-9C; Tue, 04 Sep 2018 14:49:24 +0200 Date: Tue, 4 Sep 2018 14:49:24 +0200 From: Johan Hovold To: Karoly Pados Cc: Johan Hovold , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Loic Poulain , andy.shevchenko@gmail.com, ajaykuee@gmail.com, daniel.thompson@linaro.org Subject: Re: [PATCH] USB: serial: ftdi_sio: implement GPIO support for FT230X Message-ID: <20180904124924.GA7278@localhost> References: <20180825204744.2307-1-pados@pados.hu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180825204744.2307-1-pados@pados.hu> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Aug 25, 2018 at 10:47:44PM +0200, Karoly Pados wrote: > This patch uses the CBUS bitbang mode of the device, so there is > no conflict between the GPIO and VCP functionality. Please make the commit message self-contained (e.g. don't rely on the summary, or mail Subject, even if you feel like you're repeating yourself.) And you can be a bit more verbose when describing your patch here. > Signed-off-by: Karoly Pados > --- > > Tested on an FT230X device. Though there is no copied code from other > sources, libftdi was used as a reference. > > I noticed there have been numerous historic attempts by other people at > adding GPIO support to ftdi_sio. One tried adding it in some very > application-specific way, another one tried to use the mfd framework, the > tried using a GPIO mode which is mutually exclusive to VCP, another > one did not implement the review results etc... I hope I learned from those > attempts and am planning to respond to reviews. Also, this patch follows > the rough structure of the GPIO support for cp210x devices that have > already been accepted, in the hope that it is a good starting point. > > This patch uses CBUS bitbanging mode, which works nicely in parallel with > the VCP function. The other modes do not, and so IMHO it does not make > sense to try adding them to this same module. > > For this device, whenever changing the state of any single pin, all the > others need to be written too. This means in order to change any pin, we > need to know the current state of all the others. So when using GPIO, > we need to have a known starting state for all pins, but there seems to > be no way to retrieve the existing GPIO configuration (directions and > output register values). The way I handle this in this patch is that when > requesting a GPIO for the first time, the module initializes all pins to > a known default state (to inputs). Input was chosen, because a potentially > floating pin is better than a potential driver conflict, because the latter > could result in hardware damage. However, if the user does not request a > GPIO, the CBUS pins are not initialized, avoiding unnecessarily changing > hardware state. I figured I cannot rely on the default power-on state of > the device for this as the user might have used libftdi before loading > our module. When the module is unloaded, CBUS bitbanging mode is exited > if it were us who entered it earlier. This paragraph seems like it belongs in the commit message in some form. But your approach seems reasonable, even if it means all pins may change state when requesting the first. Actually, after thinking about this some more, it may be better to just configure all pins during probe. The device is managed by the kernel, and we can't really consider what user space may have done before, at least if we can't query the device. Better to be in a consistent state while the driver is bound. > checkpatch.pl emits a bunch of warnings, recommending const for structs. > I am unsure if this makes sense, existing code in this same and also > other modules does not adhere to this rule either. I fixed everything else. Really? Checkpatch doesn't complain here. Were you using the --strict option, perhaps? Don't do that... > drivers/usb/serial/ftdi_sio.c | 284 +++++++++++++++++++++++++++++++++- > drivers/usb/serial/ftdi_sio.h | 25 +++ > 2 files changed, 308 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c > index b5cef322826f..d1ff4a372b6e 100644 > --- a/drivers/usb/serial/ftdi_sio.c > +++ b/drivers/usb/serial/ftdi_sio.c > @@ -40,6 +40,9 @@ > #include > #include > #include > +#ifdef CONFIG_GPIOLIB > +#include > +#endif No ifdef. > #include "ftdi_sio.h" > #include "ftdi_sio_ids.h" > > @@ -72,6 +75,14 @@ struct ftdi_private { > unsigned int latency; /* latency setting in use */ > unsigned short max_packet_size; > struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ > +#ifdef CONFIG_GPIOLIB > + struct gpio_chip gc; > + bool gpio_registered; /* is the gpiochip in kernel registered */ > + bool gpio_used; /* true if the user requested a gpio */ > + u8 gpio_altfunc; /* which pins are in gpio mode */ > + u8 gpio_input; /* pin directions cache */ > + u8 gpio_value; /* pin value for outputs */ > +#endif > }; > > /* struct ftdi_sio_quirk is used by devices requiring special attention. */ > @@ -1766,6 +1777,268 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) > > } > > +#ifdef CONFIG_GPIOLIB > + > +static int ftdi_sio_set_cbus(struct usb_serial_port *port, Please drop the "_sio" infix from your functions, "ftdi_" as prefix is enough. > + u8 direction, > + u8 value, > + u8 mode) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); Since you have port and priv here anyway, you could consider not passing direction and value in every call. Even mode could go, if you add a separate helper for that, which would also make this function more appropriately named. > + u16 val; > + > + /* device's direction polarity is different from kernel's */ Why so? You could just replace gpio_input with gpio_output. I think that may be preferred. > + direction = (~direction) & 0x0f; > + > + val = (mode << 8) | (direction << 4) | (value & 0x0f); > + return usb_control_msg(port->serial->dev, > + usb_sndctrlpipe(port->serial->dev, 0), > + FTDI_SIO_SET_BITMODE_REQUEST, > + FTDI_SIO_SET_BITMODE_REQUEST_TYPE, val, > + priv->interface, NULL, 0, WDR_TIMEOUT); I think you should log any errors here (even if that means two error messages for failed set()). > +} > + > +static int ftdi_sio_gpio_request(struct gpio_chip *gc, unsigned int offset) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + int result = 0; No need to initialise. > + > + if (priv->gpio_altfunc & BIT(offset)) > + return -ENODEV; > + > + if (!priv->gpio_used) { > + /* Set default pin states, as we cannot get them from device */ > + priv->gpio_input = 0xff; > + priv->gpio_value = 0x00; > + result = ftdi_sio_set_cbus(port, > + priv->gpio_input, > + priv->gpio_value, > + FTDI_SIO_GPIO_MODE_CBUS); > + if (result) > + return result; > + > + priv->gpio_used = true; > + } So I think this initialisation should be done at probe instead. > + > + return 0; > +} > + > +static int ftdi_sio_gpio_get(struct gpio_chip *gc, unsigned int gpio) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + struct usb_serial *serial = port->serial; > + unsigned char *rcvbuf; > + int result; > + > + rcvbuf = kmalloc(1, GFP_KERNEL); > + if (!rcvbuf) > + return -ENOMEM; > + > + result = usb_control_msg(serial->dev, > + usb_rcvctrlpipe(serial->dev, 0), > + FTDI_SIO_READ_PINS_REQUEST, > + FTDI_SIO_READ_PINS_REQUEST_TYPE, 0, > + priv->interface, rcvbuf, 1, WDR_TIMEOUT); > + No newline. > + if (result < 1) > + result = -EIO; > + else > + result = !!(rcvbuf[0] & BIT(gpio)); > + > + kfree(rcvbuf); > + > + return result; > +} > + > +static void ftdi_sio_gpio_set(struct gpio_chip *gc, > + unsigned int gpio, > + int value > +) Closing parentheses goes after value. > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + int result; > + > + if (value) > + priv->gpio_value |= BIT(gpio); > + else > + priv->gpio_value &= ~BIT(gpio); > + > + result = ftdi_sio_set_cbus(port, > + priv->gpio_input, > + priv->gpio_value, > + FTDI_SIO_GPIO_MODE_CBUS); > + No newline. > + if (result < 0) { > + dev_err(&port->serial->interface->dev, > + "failed to set GPIO value: %d\n", > + result); > + } > +} > + > +static int ftdi_sio_gpio_direction_get(struct gpio_chip *gc, > + unsigned int gpio) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + return priv->gpio_input & BIT(gpio); > +} > + > +static int ftdi_sio_gpio_direction_input(struct gpio_chip *gc, > + unsigned int gpio) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + priv->gpio_input |= BIT(gpio); > + > + return ftdi_sio_set_cbus(port, > + priv->gpio_input, > + priv->gpio_value, > + FTDI_SIO_GPIO_MODE_CBUS); > +} > + > +static int ftdi_sio_gpio_direction_output(struct gpio_chip *gc, > + unsigned int gpio, > + int value) > +{ > + struct usb_serial_port *port = gpiochip_get_data(gc); > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + priv->gpio_input &= ~BIT(gpio); > + if (value) > + priv->gpio_value |= BIT(gpio); > + else > + priv->gpio_value &= ~BIT(gpio); > + > + return ftdi_sio_set_cbus(port, > + priv->gpio_input, > + priv->gpio_value, > + FTDI_SIO_GPIO_MODE_CBUS); > +} > + > +static int ftx_gpioconf_init(struct usb_serial_port *port) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + struct usb_serial *serial = port->serial; > + const u16 config_size = 0x24; > + u8 *config_buf; > + int result; > + u8 i; > + > + /* Read part of device EEPROM */ > + config_buf = kmalloc(config_size, GFP_KERNEL); > + if (!config_buf) > + return -ENOMEM; > + > + for (i = 0; i < config_size / 2; i++) { > + result = usb_control_msg(serial->dev, > + usb_rcvctrlpipe(serial->dev, 0), > + FTDI_SIO_READ_EEPROM_REQUEST, > + FTDI_SIO_READ_EEPROM_REQUEST_TYPE, 0, > + i, config_buf + (i * 2), 2 * i, parenthesis not needed > + 2, WDR_TIMEOUT); > + if (result < 2) { > + result = -EIO; Return -EIO for short transfers, but just return result otherwise. > + break; > + } > + } > + > + if (result < 0) { > + kfree(config_buf); > + return result; > + } Factor this out to an eeprom helper that can be reused by other chip types. > + > + /* > + * All FT-X devices have at least 1 GPIO, some have more. > + * Chip-type guessing logic based on libftdi. > + */ > + priv->gc.ngpio = 1; > + if (serial->dev->descriptor.bcdDevice == 0x1000) /* FT230X */ Missing le16_to_cpu(). > + priv->gc.ngpio = 4; Shouldn't this be handled the other way round? IIRC there are two FTX device types with four pins, and one type where only one pin is accessible. > + > + /* Determine which pins are configured for CBUS bitbanging */ > + priv->gpio_altfunc = 0xff; > + for (i = 0; i < priv->gc.ngpio; ++i) { > + if (config_buf[0x1A + i] == FTDI_SIO_CBUS_MUX_GPIO) 0x1a warrants a define; but you shouldn't be reading 0x24 bytes from offset 0 above when the pinconfig is stored in just a couple of words. > + priv->gpio_altfunc &= ~BIT(i); > + } > + > + kfree(config_buf); > + > + return 0; > +} > + > +static int ftdi_sio_gpio_init(struct usb_serial_port *port) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + struct usb_serial *serial = port->serial; > + int result; > + > + /* Device-specific initializations */ > + switch (priv->chip_type) { > + case FTX: > + result = ftx_gpioconf_init(port); > + break; > + default: > + return 0; > + } > + > + if (result < 0) > + return result; > + > + /* Register GPIO chip to kernel */ > + priv->gc.label = "ftdi_sio"; Maybe we shouldn't use the legacy sio suffix here; "ftdi" or "ftdi-cbus" should do. > + priv->gc.request = ftdi_sio_gpio_request; > + priv->gc.get_direction = ftdi_sio_gpio_direction_get; > + priv->gc.direction_input = ftdi_sio_gpio_direction_input; > + priv->gc.direction_output = ftdi_sio_gpio_direction_output; > + priv->gc.get = ftdi_sio_gpio_get; > + priv->gc.set = ftdi_sio_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, port); > + if (!result) > + priv->gpio_registered = true; > + > + return result; > +} > + > +static void ftdi_sio_gpio_remove(struct usb_serial_port *port) > +{ > + struct ftdi_private *priv = usb_get_serial_port_data(port); > + > + if (priv->gpio_used) { > + ftdi_sio_set_cbus(port, 0, 0, FTDI_SIO_GPIO_MODE_RESET); IIRC this leaves the pins in the state that we set them, which is fine, but could be highlighted here. > + priv->gpio_used = false; > + } > + > + if (priv->gpio_registered) { > + gpiochip_remove(&priv->gc); > + priv->gpio_registered = false; > + } > +} > + > +#else > + > +static int ftdi_sio_gpio_init(struct usb_serial *serial) As the test robot reported, these should take a port as their argument. > +{ > + return 0; > +} > + > +static void ftdi_sio_gpio_remove(struct usb_serial *serial) > +{ > + /* Nothing to do */ Comment not really needed; you can even put the brackets after the closing parentheses ...* serial) { } as we sometimes do in headers, if you want. > +} > + > +#endif > + > /* > * *************************************************************************** > * FTDI driver specific functions > @@ -1794,7 +2067,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) > { > struct ftdi_private *priv; > const struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); > - > + int result; > > priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); > if (!priv) > @@ -1813,6 +2086,13 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) > priv->latency = 16; > write_latency_timer(port); > create_sysfs_attrs(port); > + > + result = ftdi_sio_gpio_init(port); > + if (result < 0) > + dev_err(&port->serial->interface->dev, > + "GPIO initialisation failed: %d\n", > + result); Please use brackets for conditionals with multi-line statements. > + > return 0; > } > > @@ -1930,6 +2210,8 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) > { > struct ftdi_private *priv = usb_get_serial_port_data(port); > > + ftdi_sio_gpio_remove(port); > + > remove_sysfs_attrs(port); > > kfree(priv); > diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h > index dcd0b6e05baf..5046d02fe3ac 100644 > --- a/drivers/usb/serial/ftdi_sio.h > +++ b/drivers/usb/serial/ftdi_sio.h > @@ -36,6 +36,10 @@ > #define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ > #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ > #define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ > +#define FTDI_SIO_SET_BITMODE 11 /* Set CBUS GPIO pin mode */ > +#define FTDI_SIO_READ_PINS 12 /* Read immediate value of pins */ > +#define FTDI_SIO_READ_EEPROM 144 /* Read EEPROM */ Please use hex notation. > + > > /* Interface indices for FT2232, FT2232H and FT4232H devices */ > #define INTERFACE_A 1 > @@ -433,6 +437,27 @@ enum ftdi_sio_baudrate { > * 1 = active > */ > > +/* FTDI_SIO_SET_BITMODE */ > +#define FTDI_SIO_SET_BITMODE_REQUEST_TYPE 0x40 > +#define FTDI_SIO_SET_BITMODE_REQUEST FTDI_SIO_SET_BITMODE This looks awfully redundant, but I realise you're just sticking to the current pattern (as you should). > + > +/* FTDI_SIO_READ_PINS */ > +#define FTDI_SIO_READ_PINS_REQUEST_TYPE 0xc0 > +#define FTDI_SIO_READ_PINS_REQUEST FTDI_SIO_READ_PINS > + > +/* > + * FTDI_SIO_READ_EEPROM > + * > + * EEPROM format found in FTDI AN_201, "FT-X MTP memory Configuration", > + * http://www.ftdichip.com/Support/Documents/AppNotes/AN_201_FT-X%20MTP%20Memory%20Configuration.pdf > + */ > +#define FTDI_SIO_READ_EEPROM_REQUEST_TYPE 0xc0 > +#define FTDI_SIO_READ_EEPROM_REQUEST FTDI_SIO_READ_EEPROM > + > +#define FTDI_SIO_GPIO_MODE_CBUS 0x20 > +#define FTDI_SIO_GPIO_MODE_RESET 0x00 Sort the mode defines by value here. And these belong with FTDI_SET_BITMODE above and should be renamed to reflect that. > + > +#define FTDI_SIO_CBUS_MUX_GPIO 8 > > > /* Descriptors returned by the device Thanks, Johan