All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <1541687328.2091.2.camel@analog.com>

diff --git a/a/1.txt b/N1/1.txt
index 9e68d56..abd7e31 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,477 +1,881 @@
-T24gU2IsIDIwMTgtMTEtMDMgYXQgMTI6MTYgKzAwMDAsIEpvbmF0aGFuIENhbWVyb24gd3JvdGU6
-DQo+IE9uIE1vbiwgMjkgT2N0IDIwMTggMTg6Mzg6MzEgKzAyMDANCj4gU3RlZmFuIFBvcGEgPHN0
-ZWZhbi5wb3BhQGFuYWxvZy5jb20+IHdyb3RlOg0KPiANCj4gPiANCj4gPiBUaGUgYWQ3MTI0LTQg
-YW5kIGFkNzEyNC04IGFyZSBhIGZhbWlseSBvZiA0IGFuZCA4IGNoYW5uZWwgc2lnbWEtZGVsdGEN
-Cj4gPiBBRENzDQo+ID4gd2l0aCAyNC1iaXQgcHJlY2lzaW9uIGFuZCByZWZlcmVuY2UuDQo+ID4g
-DQo+ID4gVGhyZWUgcG93ZXIgbW9kZXMgYXJlIGF2YWlsYWJsZSB3aGljaCBpbiB0dXJuIGFmZmVj
-dCB0aGUgb3V0cHV0IGRhdGENCj4gPiByYXRlOg0KPiA+IMKgKiBGdWxsIHBvd2VyOiA5LjM4IFNQ
-UyB0byAxOSwyMDAgU1BTDQo+ID4gwqAqIE1pZCBwb3dlcjogMi4zNCBTUFMgdG8gNDgwMCBTUFMN
-Cj4gPiDCoCogTG93IHBvd2VyOiAxLjE3IFNQUyB0byAyNDAwIFNQUw0KPiA+IA0KPiA+IFRoZSBh
-ZDcxMjQtNCBjYW4gYmUgY29uZmlndXJlZCB0byBoYXZlIGZvdXIgZGlmZmVyZW50aWFsIGlucHV0
-cywgd2hpbGUNCj4gPiBhZDcxMjQtOCBjYW4gaGF2ZSA4LiBNb3Jlb3ZlciwgYWQ3MTI0IGFsc28g
-c3VwcG9ydHMgcGVyIGNoYW5uZWwNCj4gPiBjb25maWd1cmF0aW9uLiBFYWNoIGNvbmZpZ3VyYXRp
-b24gY29uc2lzdHMgb2YgZ2FpbiwgcmVmZXJlbmNlIHNvdXJjZSwNCj4gPiBvdXRwdXQgZGF0YSBy
-YXRlIGFuZCBiaXBvbGFyL3VuaXBvbGFyIGNvbmZpZ3VyYXRpb24uDQo+ID4gDQo+ID4gRGF0YXNo
-ZWV0czoNCj4gPiBMaW5rOiBodHRwOi8vd3d3LmFuYWxvZy5jb20vbWVkaWEvZW4vdGVjaG5pY2Fs
-LWRvY3VtZW50YXRpb24vZGF0YS1zaGVldA0KPiA+IHMvQUQ3MTI0LTQucGRmDQo+ID4gTGluazog
-aHR0cDovL3d3dy5hbmFsb2cuY29tL21lZGlhL2VuL3RlY2huaWNhbC1kb2N1bWVudGF0aW9uL2Rh
-dGEtc2hlZXQNCj4gPiBzL2FkNzEyNC04LnBkZg0KPiA+IA0KPiA+IFNpZ25lZC1vZmYtYnk6IFN0
-ZWZhbiBQb3BhIDxzdGVmYW4ucG9wYUBhbmFsb2cuY29tPg0KPiBIaSBTdGVmYW4sDQo+IA0KPiBU
-aGUgZGlzY3Vzc2lvbiBhcm91bmQgdGhlIERUIGJpbmRpbmcgaGFzIGdvdHRlbiBtZSBsb29raW5n
-IGF0IGJpdA0KPiBtb3JlIGNsb3NlbHkgYXQgdGhhdCBmb3IgdGhpcyB2ZXJzaW9uLg0KPiANCj4g
-U29tZSBtb3N0IGNvbW1lbnRzIGluIHRoYXQgc2VjdGlvbi7CoMKgQWxzbyBhIHJlYWxseSBtaW5v
-ciBvcmRlcmluZyBpc3N1ZQ0KPiBpbg0KPiByZW1vdmUgd2hpY2ggSSdkIGp1c3QgaGF2ZSBmaXhl
-ZCBpZiB3ZSB3ZXJlbid0IGdvaW5nIGFyb3VuZCBhZ2FpbiBmb3INCj4gdGhlIGJpbmRpbmcuDQo+
-IA0KPiBNYWluIGJpbmRpbmcgdGhpbmcgaXMgSSBkb24ndCB0aGluayB0aGUgb2RyIHZhbHVlIGJl
-bG9uZ3MgaW4gRFQuDQo+IEdhaW4gaXMgbW9yZSBtYXJnaW5hbCAodW5sZXNzIHRoZSBwYXJ0IGNh
-biBhY3R1YWxseSBiZSBkYW1hZ2VkIGJ5DQo+IGEgd3JvbmcgdmFsdWUgLSB3aGljaCBJIGhvcGUg
-aXQgY2FuJ3QhKS7CoMKgSSdtIG5vdCB0aGF0IGZ1c3NlZA0KPiBhcyB0aGVyZSBhcmUgZGVmaW5p
-dGVseSByZWFzb25zIHRvIHNwZWNpZnkgYSBkZWZhdWx0IHNjYWxlIHRvDQo+IGNvdmVyIHRoZSBy
-ZWFzb25hYmxlIHJhbmdlIG9uIGEgcGluLg0KPiANCj4gVGhhbmtzLA0KPiANCj4gSm9uYXRoYW4N
-Cg0KSGkgSm9uYXRoYW4sDQoNClRoYW5rIHlvdSBmb3IgdGhlIHJldmlldyEgU28sIGhvdyBzaG91
-bGQgSSBwcm9jZWVkPw0KDQpGaXJzdCwgd2UgbmVlZCBhbiBhZGMudHh0IGZpbGUgd2hlcmUgImJp
-cG9sYXIiIGFuZCBzb21ldGhpbmcgbGlrZSAiZGlmZi0NCmNoYW5uZWxzIiBzaG91bGQgYmUgZG9j
-dW1lbnRlZC4gU2hvdWxkIHRoZSBmaWxlIGJlIHBsYWNlZCB1bmRlcg0KRG9jdW1lbnRhdGlvbi9k
-ZXZpY2V0cmVlL2JpbmRpbmdzL2lpby9hZGM/DQoNClJlZ2FyZGluZyB0aGUgIm9kci1oeiIgcHJv
-cGVydHksIGl0IHRvdGFsbHkgbWFrZXMgc2Vuc2UgdG8gcmVtb3ZlIGl0IGZyb20NCnRoZSBEVC4g
-SG93IGFib3V0IHRoZSAiZ2FpbiI/IFNob3VsZCB3ZSBsZWF2ZSBpdCBpbiB0aGUgRFQgYW5kIGFs
-c28gYWRkIHRoZQ0KcG9zc2liaWxpdHkgdG8gYmUgY29uZmlndXJlZCBmcm9tIHVzZXIgc3BhY2U/
-DQoNClJlZ2FyZHMsDQotU3RlZmFuDQo+ID4gDQo+ID4gLS0tDQo+ID4gQ2hhbmdlcyBpbiB2MjoN
-Cj4gPiAJLSBBZGRlZCB0aGlzIGNvbW1pdC4NCj4gPiBDaGFuZ2VzIGluIHYzOg0KPiA+IAktIFJl
-bW92ZWQgY2hhbm5lbCwgYWRkcmVzcywgc2Nhbl9pbmRleCBhbmQgc2hpZnQgZmllbGRzIGZyb20N
-Cj4gPiAJwqDCoGFkNzEyNF9jaGFubmVsX3RlbXBsYXRlLg0KPiA+IAktIEFkZGVkIGEgc2FuaXR5
-IGNoZWNrIGZvciB2YWwyIGluIGFkNzEyNF93cml0ZV9yYXcoKS4NCj4gPiAJLSBVc2VkIHRoZSAi
-cmVnIiBwcm9wZXJ0eSB0byBnZXQgdGhlIGNoYW5uZWwgYWRkcmVzcyBhbmQgImFkaSxkaWZmLQ0K
-PiA+IGNoYW5uZWxzIg0KPiA+IAnCoMKgZm9yIHRoZSBkaWZmZXJlbnRpYWwgcGlucy4gVGhlICJh
-ZGksY2hhbm5lbC1udW1iZXIiIHByb3BlcnR5IHdhcw0KPiA+IHJlbW92ZWQuDQo+ID4gCS0gV2hl
-biBjYWxsaW5nIHJlZ3VsYXRvcl9nZXRfb3B0aW9uYWwsIHRoZSBwcm9iZSBpcyBnaXZlbiB1cCBp
-bg0KPiA+IGNhc2Ugb2YgZXJyb3IsDQo+ID4gCcKgwqBidXQgY29udGludWVzIGluIGNhc2Ugb2Yg
-LUVOT0RFVi4NCj4gPiAJLSBjbGtfZGlzYWJsZV91bnByZXBhcmUoKSBpcyBjYWxsZWQgYmVmb3Jl
-DQo+ID4gYWRfc2RfY2xlYW51cF9idWZmZXJfYW5kX3RyaWdnZXINCj4gPiAJwqDCoGluIGFkNzEy
-NF9yZW1vdmUoKS4NCj4gPiANCj4gPiDCoE1BSU5UQUlORVJTwqDCoMKgwqDCoMKgwqDCoMKgwqDC
-oMKgwqDCoHzCoMKgwqA3ICsNCj4gPiDCoGRyaXZlcnMvaWlvL2FkYy9LY29uZmlnwqDCoHzCoMKg
-MTEgKw0KPiA+IMKgZHJpdmVycy9paW8vYWRjL01ha2VmaWxlIHzCoMKgwqAxICsNCj4gPiDCoGRy
-aXZlcnMvaWlvL2FkYy9hZDcxMjQuYyB8IDY0OA0KPiA+ICsrKysrKysrKysrKysrKysrKysrKysr
-KysrKysrKysrKysrKysrKysrKysrKysrDQo+ID4gwqA0IGZpbGVzIGNoYW5nZWQsIDY2NyBpbnNl
-cnRpb25zKCspDQo+ID4gwqBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9paW8vYWRjL2FkNzEy
-NC5jDQo+ID4gDQo+ID4gZGlmZiAtLWdpdCBhL01BSU5UQUlORVJTIGIvTUFJTlRBSU5FUlMNCj4g
-PiBpbmRleCBmNjQyMDQ0Li4zYTFiZmNiIDEwMDY0NA0KPiA+IC0tLSBhL01BSU5UQUlORVJTDQo+
-ID4gKysrIGIvTUFJTlRBSU5FUlMNCj4gPiBAQCAtODM5LDYgKzgzOSwxMyBAQCBTOglTdXBwb3J0
-ZWQNCj4gPiDCoEY6CWRyaXZlcnMvaWlvL2RhYy9hZDU3NTguYw0KPiA+IMKgRjoJRG9jdW1lbnRh
-dGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2lpby9kYWMvYWQ1NzU4LnR4dA0KPiA+IMKgDQo+ID4g
-K0FOQUxPRyBERVZJQ0VTIElOQyBBRDcxMjQgRFJJVkVSDQo+ID4gK006CVN0ZWZhbiBQb3BhIDxz
-dGVmYW4ucG9wYUBhbmFsb2cuY29tPg0KPiA+ICtMOglsaW51eC1paW9Admdlci5rZXJuZWwub3Jn
-DQo+ID4gK1c6CWh0dHA6Ly9lei5hbmFsb2cuY29tL2NvbW11bml0eS9saW51eC1kZXZpY2UtZHJp
-dmVycw0KPiA+ICtTOglTdXBwb3J0ZWQNCj4gPiArRjoJZHJpdmVycy9paW8vYWRjL2FkNzEyNC5j
-DQo+ID4gKw0KPiA+IMKgQU5BTE9HIERFVklDRVMgSU5DIEFEOTM4OUIgRFJJVkVSDQo+ID4gwqBN
-OglIYW5zIFZlcmt1aWwgPGhhbnMudmVya3VpbEBjaXNjby5jb20+DQo+ID4gwqBMOglsaW51eC1t
-ZWRpYUB2Z2VyLmtlcm5lbC5vcmcNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9paW8vYWRjL0tj
-b25maWcgYi9kcml2ZXJzL2lpby9hZGMvS2NvbmZpZw0KPiA+IGluZGV4IGE1MmZlYTguLjE0OGEx
-MGYgMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy9paW8vYWRjL0tjb25maWcNCj4gPiArKysgYi9k
-cml2ZXJzL2lpby9hZGMvS2NvbmZpZw0KPiA+IEBAIC0xMCw2ICsxMCwxNyBAQCBjb25maWcgQURf
-U0lHTUFfREVMVEENCj4gPiDCoAlzZWxlY3QgSUlPX0JVRkZFUg0KPiA+IMKgCXNlbGVjdCBJSU9f
-VFJJR0dFUkVEX0JVRkZFUg0KPiA+IMKgDQo+ID4gK2NvbmZpZyBBRDcxMjQNCj4gPiArCXRyaXN0
-YXRlICJBbmFsb2cgRGV2aWNlcyBBRDcxMjQgYW5kIHNpbWlsYXIgc2lnbWEtZGVsdGEgQURDcw0K
-PiA+IGRyaXZlciINCj4gPiArCWRlcGVuZHMgb24gU1BJX01BU1RFUg0KPiA+ICsJc2VsZWN0IEFE
-X1NJR01BX0RFTFRBDQo+ID4gKwloZWxwDQo+ID4gKwnCoMKgU2F5IHllcyBoZXJlIHRvIGJ1aWxk
-IHN1cHBvcnQgZm9yIEFuYWxvZyBEZXZpY2VzIEFENzEyNC00DQo+ID4gYW5kIEFENzEyNC04DQo+
-ID4gKwnCoMKgU1BJIGFuYWxvZyB0byBkaWdpdGFsIGNvbnZlcnRlcnMgKEFEQykuDQo+ID4gKw0K
-PiA+ICsJwqDCoFRvIGNvbXBpbGUgdGhpcyBkcml2ZXIgYXMgYSBtb2R1bGUsIGNob29zZSBNIGhl
-cmU6IHRoZQ0KPiA+IG1vZHVsZSB3aWxsIGJlDQo+ID4gKwnCoMKgY2FsbGVkIGFkNzEyNC4NCj4g
-PiArDQo+ID4gwqBjb25maWcgQUQ3MjY2DQo+ID4gwqAJdHJpc3RhdGUgIkFuYWxvZyBEZXZpY2Vz
-IEFENzI2NS9BRDcyNjYgQURDIGRyaXZlciINCj4gPiDCoAlkZXBlbmRzIG9uIFNQSV9NQVNURVIN
-Cj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9paW8vYWRjL01ha2VmaWxlIGIvZHJpdmVycy9paW8v
-YWRjL01ha2VmaWxlDQo+ID4gaW5kZXggYTZlNmEwYi4uNzYxNjhiMiAxMDA2NDQNCj4gPiAtLS0g
-YS9kcml2ZXJzL2lpby9hZGMvTWFrZWZpbGUNCj4gPiArKysgYi9kcml2ZXJzL2lpby9hZGMvTWFr
-ZWZpbGUNCj4gPiBAQCAtNSw2ICs1LDcgQEANCj4gPiDCoA0KPiA+IMKgIyBXaGVuIGFkZGluZyBu
-ZXcgZW50cmllcyBrZWVwIHRoZSBsaXN0IGluIGFscGhhYmV0aWNhbCBvcmRlcg0KPiA+IMKgb2Jq
-LSQoQ09ORklHX0FEX1NJR01BX0RFTFRBKSArPSBhZF9zaWdtYV9kZWx0YS5vDQo+ID4gK29iai0k
-KENPTkZJR19BRDcxMjQpICs9IGFkNzEyNC5vDQo+ID4gwqBvYmotJChDT05GSUdfQUQ3MjY2KSAr
-PSBhZDcyNjYubw0KPiA+IMKgb2JqLSQoQ09ORklHX0FENzI5MSkgKz0gYWQ3MjkxLm8NCj4gPiDC
-oG9iai0kKENPTkZJR19BRDcyOTgpICs9IGFkNzI5OC5vDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZl
-cnMvaWlvL2FkYy9hZDcxMjQuYyBiL2RyaXZlcnMvaWlvL2FkYy9hZDcxMjQuYw0KPiA+IG5ldyBm
-aWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMC4uMDY2MDEzNQ0KPiA+IC0tLSAvZGV2
-L251bGwNCj4gPiArKysgYi9kcml2ZXJzL2lpby9hZGMvYWQ3MTI0LmMNCj4gPiBAQCAtMCwwICsx
-LDY0OCBAQA0KPiA+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsNCj4gPiAr
-LyoNCj4gPiArICogQUQ3MTI0IFNQSSBBREMgZHJpdmVyDQo+ID4gKyAqDQo+ID4gKyAqIENvcHly
-aWdodCAyMDE4IEFuYWxvZyBEZXZpY2VzIEluYy4NCj4gPiArICovDQo+ID4gKyNpbmNsdWRlIDxs
-aW51eC9iaXRmaWVsZC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+DQo+ID4gKyNpbmNs
-dWRlIDxsaW51eC9kZWxheS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ID4g
-KyNpbmNsdWRlIDxsaW51eC9lcnIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPg0K
-PiA+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9yZWd1
-bGF0b3IvY29uc3VtZXIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3NwaS9zcGkuaD4NCj4gPiAr
-DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9paW8vaWlvLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9p
-aW8vYWRjL2FkX3NpZ21hX2RlbHRhLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9paW8vc3lzZnMu
-aD4NCj4gPiArDQo+ID4gKy8qIEFENzEyNCByZWdpc3RlcnMgKi8NCj4gPiArI2RlZmluZSBBRDcx
-MjRfQ09NTVMJCQkweDAwDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X1NUQVRVUwkJCTB4MDANCj4gPiAr
-I2RlZmluZSBBRDcxMjRfQURDX0NPTlRST0wJCTB4MDENCj4gPiArI2RlZmluZSBBRDcxMjRfREFU
-QQkJCTB4MDINCj4gPiArI2RlZmluZSBBRDcxMjRfSU9fQ09OVFJPTF8xCQkweDAzDQo+ID4gKyNk
-ZWZpbmUgQUQ3MTI0X0lPX0NPTlRST0xfMgkJMHgwNA0KPiA+ICsjZGVmaW5lIEFENzEyNF9JRAkJ
-CTB4MDUNCj4gPiArI2RlZmluZSBBRDcxMjRfRVJST1IJCQkweDA2DQo+ID4gKyNkZWZpbmUgQUQ3
-MTI0X0VSUk9SX0VOCQkweDA3DQo+ID4gKyNkZWZpbmUgQUQ3MTI0X01DTEtfQ09VTlQJCTB4MDgN
-Cj4gPiArI2RlZmluZSBBRDcxMjRfQ0hBTk5FTCh4KQkJKDB4MDkgKyAoeCkpDQo+ID4gKyNkZWZp
-bmUgQUQ3MTI0X0NPTkZJRyh4KQkJKDB4MTkgKyAoeCkpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0ZJ
-TFRFUih4KQkJKDB4MjEgKyAoeCkpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X09GRlNFVCh4KQkJKDB4
-MjkgKyAoeCkpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0dBSU4oeCkJCQkoMHgzMSArICh4KSkNCj4g
-PiArDQo+ID4gKy8qIEFENzEyNF9TVEFUVVMgKi8NCj4gPiArI2RlZmluZSBBRDcxMjRfU1RBVFVT
-X1BPUl9GTEFHX01TSwlCSVQoNCkNCj4gPiArDQo+ID4gKy8qIEFENzEyNF9BRENfQ09OVFJPTCAq
-Lw0KPiA+ICsjZGVmaW5lIEFENzEyNF9BRENfQ1RSTF9QV1JfTVNLCUdFTk1BU0soNywgNikNCj4g
-PiArI2RlZmluZSBBRDcxMjRfQURDX0NUUkxfUFdSKHgpCQlGSUVMRF9QUkVQKEFENzEyNF9BRENf
-Q1QNCj4gPiBSTF9QV1JfTVNLLCB4KQ0KPiA+ICsjZGVmaW5lIEFENzEyNF9BRENfQ1RSTF9NT0RF
-X01TSwlHRU5NQVNLKDUsIDIpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0FEQ19DVFJMX01PREUoeCkJ
-RklFTERfUFJFUChBRDcxMjRfQURDX0NUUkxfTU9ERQ0KPiA+IF9NU0ssIHgpDQo+ID4gKw0KPiA+
-ICsvKiBBRDcxMjRfQ0hBTk5FTF9YICovDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0NIQU5ORUxfRU5f
-TVNLCQlCSVQoMTUpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0NIQU5ORUxfRU4oeCkJCUZJRUxEX1BS
-RVAoQUQ3MTI0X0NIQU5ORUxfDQo+ID4gRU5fTVNLLCB4KQ0KPiA+ICsjZGVmaW5lIEFENzEyNF9D
-SEFOTkVMX1NFVFVQX01TSwlHRU5NQVNLKDE0LCAxMikNCj4gPiArI2RlZmluZSBBRDcxMjRfQ0hB
-Tk5FTF9TRVRVUCh4KQlGSUVMRF9QUkVQKEFENzEyNF9DSEFOTkVMX1NFVFVQDQo+ID4gX01TSywg
-eCkNCj4gPiArI2RlZmluZSBBRDcxMjRfQ0hBTk5FTF9BSU5QX01TSwlHRU5NQVNLKDksIDUpDQo+
-ID4gKyNkZWZpbmUgQUQ3MTI0X0NIQU5ORUxfQUlOUCh4KQkJRklFTERfUFJFUChBRDcxMjRfQ0hB
-Tk5FDQo+ID4gTF9BSU5QX01TSywgeCkNCj4gPiArI2RlZmluZSBBRDcxMjRfQ0hBTk5FTF9BSU5N
-X01TSwlHRU5NQVNLKDQsIDApDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0NIQU5ORUxfQUlOTSh4KQkJ
-RklFTERfUFJFUChBRDcxMjRfQ0hBTk5FDQo+ID4gTF9BSU5NX01TSywgeCkNCj4gPiArDQo+ID4g
-Ky8qIEFENzEyNF9DT05GSUdfWCAqLw0KPiA+ICsjZGVmaW5lIEFENzEyNF9DT05GSUdfQklQT0xB
-Ul9NU0sJQklUKDExKQ0KPiA+ICsjZGVmaW5lIEFENzEyNF9DT05GSUdfQklQT0xBUih4KQlGSUVM
-RF9QUkVQKEFENzEyNF9DT05GSUdfQklQT0wNCj4gPiBBUl9NU0ssIHgpDQo+ID4gKyNkZWZpbmUg
-QUQ3MTI0X0NPTkZJR19SRUZfU0VMX01TSwlHRU5NQVNLKDQsIDMpDQo+ID4gKyNkZWZpbmUgQUQ3
-MTI0X0NPTkZJR19SRUZfU0VMKHgpCUZJRUxEX1BSRVAoQUQ3MTI0X0NPTkZJR19SRUZfUw0KPiA+
-IEVMX01TSywgeCkNCj4gPiArI2RlZmluZSBBRDcxMjRfQ09ORklHX1BHQV9NU0sJCUdFTk1BU0so
-MiwgMCkNCj4gPiArI2RlZmluZSBBRDcxMjRfQ09ORklHX1BHQSh4KQkJRklFTERfUFJFUChBRDcx
-MjRfQ09ORklHX1ANCj4gPiBHQV9NU0ssIHgpDQo+ID4gKw0KPiA+ICsvKiBBRDcxMjRfRklMVEVS
-X1ggKi8NCj4gPiArI2RlZmluZSBBRDcxMjRfRklMVEVSX0ZTX01TSwkJR0VOTUFTSygxMCwgMCkN
-Cj4gPiArI2RlZmluZSBBRDcxMjRfRklMVEVSX0ZTKHgpCQlGSUVMRF9QUkVQKEFENzEyNF9GSUxU
-RVJfRlMNCj4gPiBfTVNLLCB4KQ0KPiA+ICsNCj4gPiArZW51bSBhZDcxMjRfaWRzIHsNCj4gPiAr
-CUlEX0FENzEyNF80LA0KPiA+ICsJSURfQUQ3MTI0XzgsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtl
-bnVtIGFkNzEyNF9yZWZfc2VsIHsNCj4gPiArCUFENzEyNF9SRUZJTjEsDQo+ID4gKwlBRDcxMjRf
-UkVGSU4yLA0KPiA+ICsJQUQ3MTI0X0lOVF9SRUYsDQo+ID4gKwlBRDcxMjRfQVZERF9SRUYsDQo+
-ID4gK307DQo+ID4gKw0KPiA+ICtlbnVtIGFkNzEyNF9wb3dlcl9tb2RlIHsNCj4gPiArCUFENzEy
-NF9MT1dfUE9XRVIsDQo+ID4gKwlBRDcxMjRfTUlEX1BPV0VSLA0KPiA+ICsJQUQ3MTI0X0ZVTExf
-UE9XRVIsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IGFk
-NzEyNF9nYWluWzhdID0gew0KPiA+ICsJMSwgMiwgNCwgOCwgMTYsIDMyLCA2NCwgMTI4DQo+ID4g
-K307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3QgaW50IGFkNzEyNF9tYXN0ZXJfY2xrX2ZyZXFf
-aHpbM10gPSB7DQo+ID4gKwlbQUQ3MTI0X0xPV19QT1dFUl0gPSA3NjgwMCwNCj4gPiArCVtBRDcx
-MjRfTUlEX1BPV0VSXSA9IDE1MzYwMCwNCj4gPiArCVtBRDcxMjRfRlVMTF9QT1dFUl0gPSA2MTQ0
-MDAsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGFkNzEy
-NF9yZWZfbmFtZXNbXSA9IHsNCj4gPiArCVtBRDcxMjRfUkVGSU4xXSA9ICJyZWZpbjEiLA0KPiA+
-ICsJW0FENzEyNF9SRUZJTjJdID0gInJlZmluMiIsDQo+ID4gKwlbQUQ3MTI0X0lOVF9SRUZdID0g
-ImludCIsDQo+ID4gKwlbQUQ3MTI0X0FWRERfUkVGXSA9ICJhdmRkIiwNCj4gPiArfTsNCj4gPiAr
-DQo+ID4gK3N0cnVjdCBhZDcxMjRfY2hpcF9pbmZvIHsNCj4gPiArCXVuc2lnbmVkIGludCBudW1f
-aW5wdXRzOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RydWN0IGFkNzEyNF9jaGFubmVsX2NvbmZp
-ZyB7DQo+ID4gKwllbnVtIGFkNzEyNF9yZWZfc2VsIHJlZnNlbDsNCj4gPiArCWJvb2wgYmlwb2xh
-cjsNCj4gPiArCXVuc2lnbmVkIGludCBhaW47DQo+ID4gKwl1bnNpZ25lZCBpbnQgdnJlZl9tdjsN
-Cj4gPiArCXVuc2lnbmVkIGludCBwZ2FfYml0czsNCj4gPiArCXVuc2lnbmVkIGludCBvZHI7DQo+
-ID4gK307DQo+ID4gKw0KPiA+ICtzdHJ1Y3QgYWQ3MTI0X3N0YXRlIHsNCj4gPiArCWNvbnN0IHN0
-cnVjdCBhZDcxMjRfY2hpcF9pbmZvICpjaGlwX2luZm87DQo+ID4gKwlzdHJ1Y3QgYWRfc2lnbWFf
-ZGVsdGEgc2Q7DQo+ID4gKwlzdHJ1Y3QgYWQ3MTI0X2NoYW5uZWxfY29uZmlnIGNoYW5uZWxfY29u
-ZmlnWzRdOw0KPiA+ICsJc3RydWN0IHJlZ3VsYXRvciAqdnJlZls0XTsNCj4gPiArCXN0cnVjdCBj
-bGsgKm1jbGs7DQo+ID4gKwl1bnNpZ25lZCBpbnQgYWRjX2NvbnRyb2w7DQo+ID4gKwl1bnNpZ25l
-ZCBpbnQgbnVtX2NoYW5uZWxzOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0
-cnVjdCBpaW9fY2hhbl9zcGVjIGFkNzEyNF9jaGFubmVsX3RlbXBsYXRlID0gew0KPiA+ICsJLnR5
-cGUgPSBJSU9fVk9MVEFHRSwNCj4gPiArCS5pbmRleGVkID0gMSwNCj4gPiArCS5kaWZmZXJlbnRp
-YWwgPSAxLA0KPiA+ICsJLmluZm9fbWFza19zZXBhcmF0ZSA9IEJJVChJSU9fQ0hBTl9JTkZPX1JB
-VykgfA0KPiA+ICsJCUJJVChJSU9fQ0hBTl9JTkZPX1NDQUxFKSB8DQo+ID4gKwkJQklUKElJT19D
-SEFOX0lORk9fT0ZGU0VUKSB8DQo+ID4gKwkJQklUKElJT19DSEFOX0lORk9fU0FNUF9GUkVRKSwN
-Cj4gPiArCS5zY2FuX3R5cGUgPSB7DQo+ID4gKwkJLnNpZ24gPSAndScsDQo+ID4gKwkJLnJlYWxi
-aXRzID0gMjQsDQo+ID4gKwkJLnN0b3JhZ2ViaXRzID0gMzIsDQo+ID4gKwl9LA0KPiA+ICt9Ow0K
-PiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBhZDcxMjRfY2hpcF9pbmZvIGFkNzEyNF9jaGlwX2lu
-Zm9fdGJsW10gPSB7DQo+ID4gKwlbSURfQUQ3MTI0XzRdID0gew0KPiA+ICsJCS5udW1faW5wdXRz
-ID0gOCwNCj4gPiArCX0sDQo+ID4gKwlbSURfQUQ3MTI0XzhdID0gew0KPiA+ICsJCS5udW1faW5w
-dXRzID0gMTYsDQo+ID4gKwl9LA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGludCBhZDcx
-MjRfZmluZF9jbG9zZXN0X21hdGNoKGNvbnN0IGludCAqYXJyYXksDQo+ID4gKwkJCQnCoMKgwqDC
-oMKgdW5zaWduZWQgaW50IHNpemUsIGludCB2YWwpDQo+ID4gK3sNCj4gPiArCWludCBpOw0KPiA+
-ICsNCj4gPiArCWZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsNCj4gPiArCQlpZiAodmFsIDw9
-IGFycmF5W2ldKQ0KPiA+ICsJCQlyZXR1cm4gaTsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXR1
-cm4gc2l6ZSAtIDE7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgYWQ3MTI0X3NwaV93
-cml0ZV9tYXNrKHN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0LA0KPiA+ICsJCQkJwqB1bnNpZ25lZCBp
-bnQgYWRkciwNCj4gPiArCQkJCcKgdW5zaWduZWQgbG9uZyBtYXNrLA0KPiA+ICsJCQkJwqB1bnNp
-Z25lZCBpbnQgdmFsLA0KPiA+ICsJCQkJwqB1bnNpZ25lZCBpbnQgYnl0ZXMpDQo+ID4gK3sNCj4g
-PiArCXVuc2lnbmVkIGludCByZWFkdmFsOw0KPiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwly
-ZXQgPSBhZF9zZF9yZWFkX3JlZygmc3QtPnNkLCBhZGRyLCBieXRlcywgJnJlYWR2YWwpOw0KPiA+
-ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwlyZWFkdmFs
-ICY9IH5tYXNrOw0KPiA+ICsJcmVhZHZhbCB8PSB2YWw7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIGFk
-X3NkX3dyaXRlX3JlZygmc3QtPnNkLCBhZGRyLCBieXRlcywgcmVhZHZhbCk7DQo+ID4gK30NCj4g
-PiArDQo+ID4gK3N0YXRpYyBpbnQgYWQ3MTI0X3NldF9tb2RlKHN0cnVjdCBhZF9zaWdtYV9kZWx0
-YSAqc2QsDQo+ID4gKwkJCcKgwqDCoGVudW0gYWRfc2lnbWFfZGVsdGFfbW9kZSBtb2RlKQ0KPiA+
-ICt7DQo+ID4gKwlzdHJ1Y3QgYWQ3MTI0X3N0YXRlICpzdCA9IGNvbnRhaW5lcl9vZihzZCwgc3Ry
-dWN0DQo+ID4gYWQ3MTI0X3N0YXRlLCBzZCk7DQo+ID4gKw0KPiA+ICsJc3QtPmFkY19jb250cm9s
-ICY9IH5BRDcxMjRfQURDX0NUUkxfTU9ERV9NU0s7DQo+ID4gKwlzdC0+YWRjX2NvbnRyb2wgfD0g
-QUQ3MTI0X0FEQ19DVFJMX01PREUobW9kZSk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIGFkX3NkX3dy
-aXRlX3JlZygmc3QtPnNkLCBBRDcxMjRfQURDX0NPTlRST0wsIDIsIHN0LQ0KPiA+ID5hZGNfY29u
-dHJvbCk7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgYWQ3MTI0X3NldF9jaGFubmVs
-KHN0cnVjdCBhZF9zaWdtYV9kZWx0YSAqc2QsIHVuc2lnbmVkIGludA0KPiA+IGNoYW5uZWwpDQo+
-ID4gK3sNCj4gPiArCXN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0ID0gY29udGFpbmVyX29mKHNkLCBz
-dHJ1Y3QNCj4gPiBhZDcxMjRfc3RhdGUsIHNkKTsNCj4gPiArCXVuc2lnbmVkIGludCB2YWw7DQo+
-ID4gKw0KPiA+ICsJdmFsID0gc3QtPmNoYW5uZWxfY29uZmlnW2NoYW5uZWxdLmFpbiB8IEFENzEy
-NF9DSEFOTkVMX0VOKDEpIHwNCj4gPiArCcKgwqDCoMKgwqDCoEFENzEyNF9DSEFOTkVMX1NFVFVQ
-KGNoYW5uZWwpOw0KPiA+ICsNCj4gPiArCXJldHVybiBhZF9zZF93cml0ZV9yZWcoJnN0LT5zZCwg
-QUQ3MTI0X0NIQU5ORUwoY2hhbm5lbCksIDIsDQo+ID4gdmFsKTsNCj4gPiArfQ0KPiA+ICsNCj4g
-PiArc3RhdGljIGNvbnN0IHN0cnVjdCBhZF9zaWdtYV9kZWx0YV9pbmZvIGFkNzEyNF9zaWdtYV9k
-ZWx0YV9pbmZvID0gew0KPiA+ICsJLnNldF9jaGFubmVsID0gYWQ3MTI0X3NldF9jaGFubmVsLA0K
-PiA+ICsJLnNldF9tb2RlID0gYWQ3MTI0X3NldF9tb2RlLA0KPiA+ICsJLmhhc19yZWdpc3RlcnMg
-PSB0cnVlLA0KPiA+ICsJLmFkZHJfc2hpZnQgPSAwLA0KPiA+ICsJLnJlYWRfbWFzayA9IEJJVCg2
-KSwNCj4gPiArCS5kYXRhX3JlZyA9IEFENzEyNF9EQVRBLA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAr
-c3RhdGljIGludCBhZDcxMjRfc2V0X2NoYW5uZWxfb2RyKHN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0
-LA0KPiA+ICsJCQkJwqDCoHVuc2lnbmVkIGludCBjaGFubmVsLA0KPiA+ICsJCQkJwqDCoHVuc2ln
-bmVkIGludCBvZHIpDQo+ID4gK3sNCj4gPiArCXVuc2lnbmVkIGludCBmY2xrLCBvZHJfc2VsX2Jp
-dHM7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCWZjbGsgPSBjbGtfZ2V0X3JhdGUoc3Qt
-Pm1jbGspOw0KPiA+ICsJLyoNCj4gPiArCcKgKiBGU1sxMDowXSA9IGZDTEsgLyAoZkFEQyB4IDMy
-KSB3aGVyZToNCj4gPiArCcKgKiBmQURDIGlzIHRoZSBvdXRwdXQgZGF0YSByYXRlDQo+ID4gKwnC
-oCogZkNMSyBpcyB0aGUgbWFzdGVyIGNsb2NrIGZyZXF1ZW5jeQ0KPiA+ICsJwqAqIEZTWzEwOjBd
-IGFyZSB0aGUgYml0cyBpbiB0aGUgZmlsdGVyIHJlZ2lzdGVyDQo+ID4gKwnCoCogRlNbMTA6MF0g
-Y2FuIGhhdmUgYSB2YWx1ZSBmcm9tIDEgdG8gMjA0Nw0KPiA+ICsJwqAqLw0KPiA+ICsJb2RyX3Nl
-bF9iaXRzID0gRElWX1JPVU5EX0NMT1NFU1QoZmNsaywgb2RyICogMzIpOw0KPiA+ICsJaWYgKG9k
-cl9zZWxfYml0cyA8IDEpDQo+ID4gKwkJb2RyX3NlbF9iaXRzID0gMTsNCj4gPiArCWVsc2UgaWYg
-KG9kcl9zZWxfYml0cyA+IDIwNDcpDQo+ID4gKwkJb2RyX3NlbF9iaXRzID0gMjA0NzsNCj4gPiAr
-DQo+ID4gKwlyZXQgPSBhZDcxMjRfc3BpX3dyaXRlX21hc2soc3QsIEFENzEyNF9GSUxURVIoY2hh
-bm5lbCksDQo+ID4gKwkJCQnCoMKgwqDCoEFENzEyNF9GSUxURVJfRlNfTVNLLA0KPiA+ICsJCQkJ
-wqDCoMKgwqBBRDcxMjRfRklMVEVSX0ZTKG9kcl9zZWxfYml0cyksDQo+ID4gMyk7DQo+ID4gKwlp
-ZiAocmV0IDwgMCkNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsJLyogZkFEQyA9IGZDTEsgLyAo
-RlNbMTA6MF0geCAzMikgKi8NCj4gPiArCXN0LT5jaGFubmVsX2NvbmZpZ1tjaGFubmVsXS5vZHIg
-PQ0KPiA+ICsJCURJVl9ST1VORF9DTE9TRVNUKGZjbGssIG9kcl9zZWxfYml0cyAqIDMyKTsNCj4g
-PiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBhZDcx
-MjRfcmVhZF9yYXcoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiwNCj4gPiArCQkJwqDCoMKgc3Ry
-dWN0IGlpb19jaGFuX3NwZWMgY29uc3QgKmNoYW4sDQo+ID4gKwkJCcKgwqDCoGludCAqdmFsLCBp
-bnQgKnZhbDIsIGxvbmcgaW5mbykNCj4gPiArew0KPiA+ICsJc3RydWN0IGFkNzEyNF9zdGF0ZSAq
-c3QgPSBpaW9fcHJpdihpbmRpb19kZXYpOw0KPiA+ICsJaW50IGlkeCwgcmV0Ow0KPiA+ICsNCj4g
-PiArCXN3aXRjaCAoaW5mbykgew0KPiA+ICsJY2FzZSBJSU9fQ0hBTl9JTkZPX1JBVzoNCj4gPiAr
-CQlyZXQgPSBhZF9zaWdtYV9kZWx0YV9zaW5nbGVfY29udmVyc2lvbihpbmRpb19kZXYsDQo+ID4g
-Y2hhbiwgdmFsKTsNCj4gPiArCQlpZiAocmV0IDwgMCkNCj4gPiArCQkJcmV0dXJuIHJldDsNCj4g
-PiArDQo+ID4gKwkJLyogQWZ0ZXIgdGhlIGNvbnZlcnNpb24gaXMgcGVyZm9ybWVkLCBkaXNhYmxl
-IHRoZQ0KPiA+IGNoYW5uZWwgKi8NCj4gPiArCQlyZXQgPSBhZF9zZF93cml0ZV9yZWcoJnN0LT5z
-ZCwNCj4gPiArCQkJCcKgwqDCoMKgwqDCoEFENzEyNF9DSEFOTkVMKGNoYW4tPmFkZHJlc3MpLA0K
-PiA+IDIsDQo+ID4gKwkJCQnCoMKgwqDCoMKgwqBzdC0+Y2hhbm5lbF9jb25maWdbY2hhbi0NCj4g
-PiA+YWRkcmVzc10uYWluIHwNCj4gPiArCQkJCcKgwqDCoMKgwqDCoEFENzEyNF9DSEFOTkVMX0VO
-KDApKTsNCj4gPiArCQlpZiAocmV0IDwgMCkNCj4gPiArCQkJcmV0dXJuIHJldDsNCj4gPiArDQo+
-ID4gKwkJcmV0dXJuIElJT19WQUxfSU5UOw0KPiA+ICsJY2FzZSBJSU9fQ0hBTl9JTkZPX1NDQUxF
-Og0KPiA+ICsJCWlkeCA9IHN0LT5jaGFubmVsX2NvbmZpZ1tjaGFuLT5hZGRyZXNzXS5wZ2FfYml0
-czsNCj4gPiArCQkqdmFsID0gc3QtPmNoYW5uZWxfY29uZmlnW2NoYW4tPmFkZHJlc3NdLnZyZWZf
-bXYgLw0KPiA+ICsJCQlhZDcxMjRfZ2FpbltpZHhdOw0KPiA+ICsJCWlmIChzdC0+Y2hhbm5lbF9j
-b25maWdbY2hhbi0+YWRkcmVzc10uYmlwb2xhcikNCj4gPiArCQkJKnZhbDIgPSBjaGFuLT5zY2Fu
-X3R5cGUucmVhbGJpdHMgLSAxOw0KPiA+ICsJCWVsc2UNCj4gPiArCQkJKnZhbDIgPSBjaGFuLT5z
-Y2FuX3R5cGUucmVhbGJpdHM7DQo+ID4gKw0KPiA+ICsJCXJldHVybiBJSU9fVkFMX0ZSQUNUSU9O
-QUxfTE9HMjsNCj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19PRkZTRVQ6DQo+ID4gKwkJaWYgKHN0
-LT5jaGFubmVsX2NvbmZpZ1tjaGFuLT5hZGRyZXNzXS5iaXBvbGFyKSB7DQo+ID4gKwkJCS8qIENv
-ZGUgPSAyXihuIOKIkiAxKSDDlyAoKEFpbiDDlyBHYWluIC8gVnJlZikgKw0KPiA+IDEpICovDQo+
-ID4gKwkJCWlkeCA9IHN0LT5jaGFubmVsX2NvbmZpZ1tjaGFuLQ0KPiA+ID5hZGRyZXNzXS5wZ2Ff
-Yml0czsNCj4gPiArCQkJKnZhbCA9IC0oc3QtPmNoYW5uZWxfY29uZmlnW2NoYW4tDQo+ID4gPmFk
-ZHJlc3NdLnZyZWZfbXYgLw0KPiA+ICsJCQkJwqBhZDcxMjRfZ2FpbltpZHhdKTsNCj4gPiArCQl9
-IGVsc2Ugew0KPiA+ICsJCQkqdmFsID0gMDsNCj4gPiArCQl9DQo+ID4gKw0KPiA+ICsJCXJldHVy
-biBJSU9fVkFMX0lOVDsNCj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19TQU1QX0ZSRVE6DQo+ID4g
-KwkJKnZhbCA9IHN0LT5jaGFubmVsX2NvbmZpZ1tjaGFuLT5hZGRyZXNzXS5vZHI7DQo+ID4gKw0K
-PiA+ICsJCXJldHVybiBJSU9fVkFMX0lOVDsNCj4gPiArCWRlZmF1bHQ6DQo+ID4gKwkJcmV0dXJu
-IC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgYWQ3MTI0
-X3dyaXRlX3JhdyhzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2LA0KPiA+ICsJCQnCoMKgwqDCoHN0
-cnVjdCBpaW9fY2hhbl9zcGVjIGNvbnN0ICpjaGFuLA0KPiA+ICsJCQnCoMKgwqDCoGludCB2YWws
-IGludCB2YWwyLCBsb25nIGluZm8pDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBhZDcxMjRfc3RhdGUg
-KnN0ID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwlzd2l0Y2ggKGluZm8pIHsN
-Cj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19TQU1QX0ZSRVE6DQo+ID4gKwkJaWYgKHZhbDIgIT0g
-MCkNCj4gPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKw0KPiA+ICsJCXJldHVybiBhZDcxMjRf
-c2V0X2NoYW5uZWxfb2RyKHN0LCBjaGFuLT5hZGRyZXNzLCB2YWwpOw0KPiA+ICsJZGVmYXVsdDoN
-Cj4gPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCX0NCj4gPiArfQ0KPiA+ICsNCj4gPiArc3Rh
-dGljIGNvbnN0IHN0cnVjdCBpaW9faW5mbyBhZDcxMjRfaW5mbyA9IHsNCj4gPiArCS5yZWFkX3Jh
-dyA9IGFkNzEyNF9yZWFkX3JhdywNCj4gPiArCS53cml0ZV9yYXcgPSBhZDcxMjRfd3JpdGVfcmF3
-LA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGludCBhZDcxMjRfc29mdF9yZXNldChzdHJ1
-Y3QgYWQ3MTI0X3N0YXRlICpzdCkNCj4gPiArew0KPiA+ICsJdW5zaWduZWQgaW50IHJlYWR2YWws
-IHRpbWVvdXQ7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCXJldCA9IGFkX3NkX3Jlc2V0
-KCZzdC0+c2QsIDY0KTsNCj4gPiArCWlmIChyZXQgPCAwKQ0KPiA+ICsJCXJldHVybiByZXQ7DQo+
-ID4gKw0KPiA+ICsJdGltZW91dCA9IDEwMDsNCj4gPiArCWRvIHsNCj4gPiArCQlyZXQgPSBhZF9z
-ZF9yZWFkX3JlZygmc3QtPnNkLCBBRDcxMjRfU1RBVFVTLCAxLA0KPiA+ICZyZWFkdmFsKTsNCj4g
-PiArCQlpZiAocmV0IDwgMCkNCj4gPiArCQkJcmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwkJaWYg
-KCEocmVhZHZhbCAmIEFENzEyNF9TVEFUVVNfUE9SX0ZMQUdfTVNLKSkNCj4gPiArCQkJcmV0dXJu
-IDA7DQo+ID4gKw0KPiA+ICsJCS8qIFRoZSBBRDcxMjQgcmVxdWlyZXMgdHlwaWNhbGx5IDJtcyB0
-byBwb3dlciB1cCBhbmQNCj4gPiBzZXR0bGUgKi8NCj4gPiArCQl1c2xlZXBfcmFuZ2UoMTAwLCAy
-MDAwKTsNCj4gPiArCX0gd2hpbGUgKC0tdGltZW91dCk7DQo+ID4gKw0KPiA+ICsJZGV2X2Vycigm
-c3QtPnNkLnNwaS0+ZGV2LCAiU29mdCByZXNldCBmYWlsZWRcbiIpOw0KPiA+ICsNCj4gPiArCXJl
-dHVybiAtRUlPOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IGFkNzEyNF9pbml0X2No
-YW5uZWxfdnJlZihzdHJ1Y3QgYWQ3MTI0X3N0YXRlICpzdCwNCj4gPiArCQkJCcKgwqDCoMKgdW5z
-aWduZWQgaW50IGNoYW5uZWxfbnVtYmVyKQ0KPiA+ICt7DQo+ID4gKwl1bnNpZ25lZCBpbnQgcmVm
-c2VsID0gc3QtDQo+ID4gPmNoYW5uZWxfY29uZmlnW2NoYW5uZWxfbnVtYmVyXS5yZWZzZWw7DQo+
-ID4gKw0KPiA+ICsJc3dpdGNoIChyZWZzZWwpIHsNCj4gPiArCWNhc2UgQUQ3MTI0X1JFRklOMToN
-Cj4gPiArCWNhc2UgQUQ3MTI0X1JFRklOMjoNCj4gPiArCWNhc2UgQUQ3MTI0X0FWRERfUkVGOg0K
-PiA+ICsJCWlmIChJU19FUlIoc3QtPnZyZWZbcmVmc2VsXSkpIHsNCj4gPiArCQkJZGV2X2Vycigm
-c3QtPnNkLnNwaS0+ZGV2LA0KPiA+ICsJCQkJIkVycm9yLCB0cnlpbmcgdG8gdXNlIGV4dGVybmFs
-IHZvbHRhZ2UNCj4gPiByZWZlcmVuY2Ugd2l0aG91dCBhICVzIHJlZ3VsYXRvci4iLA0KPiA+ICsJ
-CQkJYWQ3MTI0X3JlZl9uYW1lc1tyZWZzZWxdKTsNCj4gPiArCQkJCXJldHVybiBQVFJfRVJSKHN0
-LT52cmVmW3JlZnNlbF0pOw0KPiA+ICsJCX0NCj4gPiArCQlzdC0+Y2hhbm5lbF9jb25maWdbY2hh
-bm5lbF9udW1iZXJdLnZyZWZfbXYgPQ0KPiA+ICsJCQlyZWd1bGF0b3JfZ2V0X3ZvbHRhZ2Uoc3Qt
-PnZyZWZbcmVmc2VsXSk7DQo+ID4gKwkJLyogQ29udmVyc2lvbiBmcm9tIHVWIHRvIG1WICovDQo+
-ID4gKwkJc3QtPmNoYW5uZWxfY29uZmlnW2NoYW5uZWxfbnVtYmVyXS52cmVmX212IC89IDEwMDA7
-DQo+ID4gKwkJYnJlYWs7DQo+ID4gKwljYXNlIEFENzEyNF9JTlRfUkVGOg0KPiA+ICsJCXN0LT5j
-aGFubmVsX2NvbmZpZ1tjaGFubmVsX251bWJlcl0udnJlZl9tdiA9IDI1MDA7DQo+ID4gKwkJYnJl
-YWs7DQo+ID4gKwlkZWZhdWx0Og0KPiA+ICsJCWRldl9lcnIoJnN0LT5zZC5zcGktPmRldiwgIklu
-dmFsaWQgcmVmZXJlbmNlICVkXG4iLA0KPiA+IHJlZnNlbCk7DQo+ID4gKwkJcmV0dXJuIC1FSU5W
-QUw7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4g
-K3N0YXRpYyBpbnQgYWQ3MTI0X29mX3BhcnNlX2NoYW5uZWxfY29uZmlnKHN0cnVjdCBpaW9fZGV2
-ICppbmRpb19kZXYsDQo+ID4gKwkJCQkJwqDCoHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnApDQo+ID4g
-K3sNCj4gPiArCXN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0ID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsN
-Cj4gPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqY2hpbGQ7DQo+ID4gKwlzdHJ1Y3QgaWlvX2NoYW5f
-c3BlYyAqY2hhbjsNCj4gPiArCXVuc2lnbmVkIGludCBhaW5bMl0sIGNoYW5uZWwgPSAwLCB0bXA7
-DQo+ID4gKwlpbnQgcmV0LCByZXM7DQo+ID4gKw0KPiA+ICsJc3QtPm51bV9jaGFubmVscyA9IG9m
-X2dldF9hdmFpbGFibGVfY2hpbGRfY291bnQobnApOw0KPiA+ICsJaWYgKCFzdC0+bnVtX2NoYW5u
-ZWxzKSB7DQo+ID4gKwkJZGV2X2VycihpbmRpb19kZXYtPmRldi5wYXJlbnQsICJubyBjaGFubmVs
-DQo+ID4gY2hpbGRyZW5cbiIpOw0KPiA+ICsJCXJldHVybiAtRU5PREVWOw0KPiA+ICsJfQ0KPiA+
-ICsNCj4gPiArCWNoYW4gPSBkZXZtX2tjYWxsb2MoaW5kaW9fZGV2LT5kZXYucGFyZW50LCBzdC0+
-bnVtX2NoYW5uZWxzLA0KPiA+ICsJCQnCoMKgwqDCoHNpemVvZigqY2hhbiksIEdGUF9LRVJORUwp
-Ow0KPiA+ICsJaWYgKCFjaGFuKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4gPiAr
-CWluZGlvX2Rldi0+Y2hhbm5lbHMgPSBjaGFuOw0KPiA+ICsJaW5kaW9fZGV2LT5udW1fY2hhbm5l
-bHMgPSBzdC0+bnVtX2NoYW5uZWxzOw0KPiA+ICsNCj4gPiArCWZvcl9lYWNoX2F2YWlsYWJsZV9j
-aGlsZF9vZl9ub2RlKG5wLCBjaGlsZCkgew0KPiA+ICsJCXJldCA9IG9mX3Byb3BlcnR5X3JlYWRf
-dTMyKGNoaWxkLCAicmVnIiwgJmNoYW5uZWwpOw0KPiA+ICsJCWlmIChyZXQpDQo+ID4gKwkJCWdv
-dG8gZXJyOw0KPiA+ICsNCj4gPiArCQlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMl9hcnJheShj
-aGlsZCwgImFkaSxkaWZmLQ0KPiA+IGNoYW5uZWxzIiwNCj4gPiArCQkJCQkJwqBhaW4sIDIpOw0K
-PiBUaGlzIGFjdHVhbGx5IGZlZWxzIGxpa2Ugc29tZXRoaW5nIHdlIGNvdWxkIHN0YW5kYXJkaXpl
-IGFzIHdlbGwgYXMNCj4gYmlwb2xhci4NCj4gSW4gdGhlIG9sZGVzdCBkcml2ZXJzIHdlIGFjdHVh
-bGx5IGxldCB1c2Vyc3BhY2UgY29uZmlndXJlIGFsbCBvZiB0aGlzLA0KPiBidXQNCj4gSSBjYW4g
-dW5kZXJzdGFuZCB0aGF0IG9ubHkgc29tZSBjb21iaW5hdGlvbnMgbWFrZSBzZW5zZSBvbiBhIGdp
-dmVuIGJvYXJkDQo+IHNvIGl0IGFyZ3VhYmx5IG1ha2VzIHNlbnNlIHRvIG9ubHkgZW5hYmxlIHRo
-b3NlLCBwYXJ0aWN1bGFybHkgd2hlbiB0aGVyZQ0KPiBpcyBhIHJlZmVyZW5jZSBzZWxlY3QgdGhh
-dCBoYXMgdG8gYmUgcGFpcmVkIHdpdGggY2hhbm5lbCBjaG9pY2UuDQo+IA0KPiA+IA0KPiA+ICsJ
-CWlmIChyZXQpDQo+ID4gKwkJCWdvdG8gZXJyOw0KPiA+ICsNCj4gPiArCQlpZiAoYWluWzBdID49
-IHN0LT5jaGlwX2luZm8tPm51bV9pbnB1dHMgfHwNCj4gPiArCQnCoMKgwqDCoGFpblsxXSA+PSBz
-dC0+Y2hpcF9pbmZvLT5udW1faW5wdXRzKSB7DQo+ID4gKwkJCWRldl9lcnIoaW5kaW9fZGV2LT5k
-ZXYucGFyZW50LA0KPiA+ICsJCQkJIklucHV0IHBpbiBudW1iZXIgb3V0IG9mIHJhbmdlLlxuIik7
-DQo+ID4gKwkJCXJldCA9IC1FSU5WQUw7DQo+ID4gKwkJCWdvdG8gZXJyOw0KPiA+ICsJCX0NCj4g
-PiArCQlzdC0+Y2hhbm5lbF9jb25maWdbY2hhbm5lbF0uYWluID0NCj4gPiBBRDcxMjRfQ0hBTk5F
-TF9BSU5QKGFpblswXSkgfA0KPiA+ICsJCQkJCQnCoMKgQUQ3MTI0X0NIQU5ORUxfQUlOTSgNCj4g
-PiBhaW5bMV0pOw0KPiA+ICsJCXN0LT5jaGFubmVsX2NvbmZpZ1tjaGFubmVsXS5iaXBvbGFyID0N
-Cj4gPiArCQkJb2ZfcHJvcGVydHlfcmVhZF9ib29sKGNoaWxkLCAiYWRpLGJpcG9sYXIiKTsNCj4g
-PiArDQo+ID4gKwkJcmV0ID0gb2ZfcHJvcGVydHlfcmVhZF91MzIoY2hpbGQsICJhZGkscmVmZXJl
-bmNlLQ0KPiA+IHNlbGVjdCIsICZ0bXApOw0KPiA+ICsJCWlmIChyZXQpDQo+ID4gKwkJCXN0LT5j
-aGFubmVsX2NvbmZpZ1tjaGFubmVsXS5yZWZzZWwgPQ0KPiA+IEFENzEyNF9JTlRfUkVGOw0KPiA+
-ICsJCWVsc2UNCj4gPiArCQkJc3QtPmNoYW5uZWxfY29uZmlnW2NoYW5uZWxdLnJlZnNlbCA9IHRt
-cDsNCj4gPiArDQo+ID4gKwkJcmV0ID0gb2ZfcHJvcGVydHlfcmVhZF91MzIoY2hpbGQsICJhZGks
-Z2FpbiIsICZ0bXApOw0KPiA+ICsJCWlmIChyZXQpIHsNCj4gPiArCQkJc3QtPmNoYW5uZWxfY29u
-ZmlnW2NoYW5uZWxdLnBnYV9iaXRzID0gMDsNCj4gPiArCQl9IGVsc2Ugew0KPiA+ICsJCQlyZXMg
-PSBhZDcxMjRfZmluZF9jbG9zZXN0X21hdGNoKGFkNzEyNF9nYWluLA0KPiA+ICsJCQkJCQlBUlJB
-WV9TSVpFKGFkNzEyNF9nYWluDQo+ID4gKSwgdG1wKTsNCj4gPiArCQkJc3QtPmNoYW5uZWxfY29u
-ZmlnW2NoYW5uZWxdLnBnYV9iaXRzID0gcmVzOw0KPiBIbW0uIFRoZSBvbGQgcXVlc3Rpb24gb2Yg
-d2hhdCB0byBwdXQgaW4gRFQgYXMgaXQgcmVmbGVjdHMgd2lyaW5nIGFuZA0KPiB3aGF0IHRvIGxl
-YXZlIHRvIHVzZXJzcGFjZS4gR2FpbiBpcyB0cmlja3kgYXMgb25seSBzb21lIHZhbHVlcyBtYWtl
-IHNlbnNlDQo+IGZvciBhIGdpdmVuIHN5c3RlbSwgYnV0IHRoZXJlIGNhbiBiZSBtb3JlIHRoYW4g
-b25lIHRoYXQgZG9lcy4uLg0KPiBUaGlzIGlzIHByb2JhYmx5IHJlYXNvbmFibGUgYXMgaXQgY2Fu
-IGJlIGNvbnNpZGVyZWQgYXMgc2V0dGluZyB0aGUNCj4gZGVmYXVsdA0KPiB0aGF0IG1ha2VzIHNl
-bnNlIGZvciB3aGF0IGlzIHdpcmVkLsKgwqBQb3RlbnRpYWxseSB1c2VyIHNwYWNlIGNvdWxkDQo+
-IG92ZXJyaWRlDQo+IGl0IGxhdGVyIGlmIGl0IHdhbnRlZCB0by4NCj4gDQo+ID4gDQo+ID4gKwkJ
-fQ0KPiA+ICsNCj4gPiArCQlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMihjaGlsZCwgImFkaSxv
-ZHItaHoiLCAmdG1wKTsNCj4gV2h5IGlzIHRoaXMgaW4gRFQuIFRoaXMgb25lIGZlZWxzIGxpa2Ug
-YSB1c2Vyc3BhY2UgY2hvaWNlIHRvIG1lLiBJdCdzDQo+IG9ubHkgdGFuZ2VudGlhbGx5IGNvbm5l
-Y3RlZCB0byBob3cgdGhpbmdzIGFyZSBjb25uZWN0ZWQgb24gdGhlIGJvYXJkLg0KPiBZb3UgYWxz
-byBzdXBwb3J0IGNvbnRyb2wgZnJvbSB1c2Vyc3BhY2UuwqDCoEkgd291bGQgcGljayBhIHNlbnNp
-YmxlDQo+IGdlbmVyYWwgZGVmYXVsdCBhbmQgdGhlbiBkcm9wIHRoaXMgZnJvbSB0aGUgRFQgYmlu
-ZGluZy4gSXQncyBvcHRpb25hbA0KPiBhbnl3YXkuDQo+IA0KPiA+IA0KPiA+ICsJCWlmIChyZXQp
-DQo+ID4gKwkJCS8qDQo+ID4gKwkJCcKgKiA5IFNQUyBpcyB0aGUgbWluaW11bSBvdXRwdXQgZGF0
-YSByYXRlDQo+ID4gc3VwcG9ydGVkDQo+ID4gKwkJCcKgKiByZWdhcmRsZXNzIG9mIHRoZSBzZWxl
-Y3RlZCBwb3dlciBtb2RlLg0KPiA+ICsJCQnCoCovDQo+ID4gKwkJCXN0LT5jaGFubmVsX2NvbmZp
-Z1tjaGFubmVsXS5vZHIgPSA5Ow0KPiA+ICsJCWVsc2UNCj4gPiArCQkJc3QtPmNoYW5uZWxfY29u
-ZmlnW2NoYW5uZWxdLm9kciA9IHRtcDsNCj4gPiArDQo+ID4gKwkJKmNoYW4gPSBhZDcxMjRfY2hh
-bm5lbF90ZW1wbGF0ZTsNCj4gPiArCQljaGFuLT5hZGRyZXNzID0gY2hhbm5lbDsNCj4gPiArCQlj
-aGFuLT5zY2FuX2luZGV4ID0gY2hhbm5lbDsNCj4gPiArCQljaGFuLT5jaGFubmVsID0gYWluWzBd
-Ow0KPiA+ICsJCWNoYW4tPmNoYW5uZWwyID0gYWluWzFdOw0KPiA+ICsNCj4gPiArCQljaGFuKys7
-DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK2VycjoNCj4gPiArCW9mX25v
-ZGVfcHV0KGNoaWxkKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ICt9DQo+ID4gKw0K
-PiA+ICtzdGF0aWMgaW50IGFkNzEyNF9zZXR1cChzdHJ1Y3QgYWQ3MTI0X3N0YXRlICpzdCkNCj4g
-PiArew0KPiA+ICsJdW5zaWduZWQgaW50IHZhbCwgZmNsaywgcG93ZXJfbW9kZTsNCj4gPiArCWlu
-dCBpLCByZXQ7DQo+ID4gKw0KPiA+ICsJZmNsayA9IGNsa19nZXRfcmF0ZShzdC0+bWNsayk7DQo+
-ID4gKwlpZiAoIWZjbGspDQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKw0KPiA+ICsJLyog
-VGhlIHBvd2VyIG1vZGUgY2hhbmdlcyB0aGUgbWFzdGVyIGNsb2NrIGZyZXF1ZW5jeSAqLw0KPiA+
-ICsJcG93ZXJfbW9kZSA9DQo+ID4gYWQ3MTI0X2ZpbmRfY2xvc2VzdF9tYXRjaChhZDcxMjRfbWFz
-dGVyX2Nsa19mcmVxX2h6LA0KPiA+ICsJCQkJCUFSUkFZX1NJWkUoYWQ3MTI0X21hc3Rlcl9jbGtf
-Zg0KPiA+IHJlcV9oeiksDQo+ID4gKwkJCQkJZmNsayk7DQo+ID4gKwlpZiAoZmNsayAhPSBhZDcx
-MjRfbWFzdGVyX2Nsa19mcmVxX2h6W3Bvd2VyX21vZGVdKSB7DQo+ID4gKwkJcmV0ID0gY2xrX3Nl
-dF9yYXRlKHN0LT5tY2xrLCBmY2xrKTsNCj4gPiArCQlpZiAocmV0KQ0KPiA+ICsJCQlyZXR1cm4g
-cmV0Ow0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCS8qIFNldCB0aGUgcG93ZXIgbW9kZSAqLw0KPiA+
-ICsJc3QtPmFkY19jb250cm9sICY9IH5BRDcxMjRfQURDX0NUUkxfUFdSX01TSzsNCj4gPiArCXN0
-LT5hZGNfY29udHJvbCB8PSBBRDcxMjRfQURDX0NUUkxfUFdSKHBvd2VyX21vZGUpOw0KPiA+ICsJ
-cmV0ID0gYWRfc2Rfd3JpdGVfcmVnKCZzdC0+c2QsIEFENzEyNF9BRENfQ09OVFJPTCwgMiwgc3Qt
-DQo+ID4gPmFkY19jb250cm9sKTsNCj4gPiArCWlmIChyZXQgPCAwKQ0KPiA+ICsJCXJldHVybiBy
-ZXQ7DQo+ID4gKw0KPiA+ICsJZm9yIChpID0gMDsgaSA8IHN0LT5udW1fY2hhbm5lbHM7IGkrKykg
-ew0KPiA+ICsJCXZhbCA9IHN0LT5jaGFubmVsX2NvbmZpZ1tpXS5haW4gfA0KPiA+IEFENzEyNF9D
-SEFOTkVMX1NFVFVQKGkpOw0KPiA+ICsJCXJldCA9IGFkX3NkX3dyaXRlX3JlZygmc3QtPnNkLCBB
-RDcxMjRfQ0hBTk5FTChpKSwgMiwNCj4gPiB2YWwpOw0KPiA+ICsJCWlmIChyZXQgPCAwKQ0KPiA+
-ICsJCQlyZXR1cm4gcmV0Ow0KPiA+ICsNCj4gPiArCQlyZXQgPSBhZDcxMjRfaW5pdF9jaGFubmVs
-X3ZyZWYoc3QsIGkpOw0KPiA+ICsJCWlmIChyZXQgPCAwKQ0KPiA+ICsJCQlyZXR1cm4gcmV0Ow0K
-PiA+ICsNCj4gPiArCQl2YWwgPSBBRDcxMjRfQ09ORklHX0JJUE9MQVIoc3QtDQo+ID4gPmNoYW5u
-ZWxfY29uZmlnW2ldLmJpcG9sYXIpIHwNCj4gPiArCQnCoMKgwqDCoMKgwqBBRDcxMjRfQ09ORklH
-X1JFRl9TRUwoc3QtDQo+ID4gPmNoYW5uZWxfY29uZmlnW2ldLnJlZnNlbCkgfA0KPiA+ICsJCcKg
-wqDCoMKgwqDCoEFENzEyNF9DT05GSUdfUEdBKHN0LQ0KPiA+ID5jaGFubmVsX2NvbmZpZ1tpXS5w
-Z2FfYml0cyk7DQo+ID4gKwkJcmV0ID0gYWRfc2Rfd3JpdGVfcmVnKCZzdC0+c2QsIEFENzEyNF9D
-T05GSUcoaSksIDIsDQo+ID4gdmFsKTsNCj4gPiArCQlpZiAocmV0IDwgMCkNCj4gPiArCQkJcmV0
-dXJuIHJldDsNCj4gPiArDQo+ID4gKwkJcmV0ID0gYWQ3MTI0X3NldF9jaGFubmVsX29kcihzdCwg
-aSwgc3QtDQo+ID4gPmNoYW5uZWxfY29uZmlnW2ldLm9kcik7DQo+ID4gKwkJaWYgKHJldCA8IDAp
-DQo+ID4gKwkJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHJldDsN
-Cj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBhZDcxMjRfcHJvYmUoc3RydWN0IHNwaV9k
-ZXZpY2UgKnNwaSkNCj4gPiArew0KPiA+ICsJY29uc3Qgc3RydWN0IHNwaV9kZXZpY2VfaWQgKmlk
-Ow0KPiA+ICsJc3RydWN0IGFkNzEyNF9zdGF0ZSAqc3Q7DQo+ID4gKwlzdHJ1Y3QgaWlvX2RldiAq
-aW5kaW9fZGV2Ow0KPiA+ICsJaW50IGksIHJldDsNCj4gPiArDQo+ID4gKwlpbmRpb19kZXYgPSBk
-ZXZtX2lpb19kZXZpY2VfYWxsb2MoJnNwaS0+ZGV2LCBzaXplb2YoKnN0KSk7DQo+ID4gKwlpZiAo
-IWluZGlvX2RldikNCj4gPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gPiArDQo+ID4gKwlzdCA9IGlp
-b19wcml2KGluZGlvX2Rldik7DQo+ID4gKw0KPiA+ICsJaWQgPSBzcGlfZ2V0X2RldmljZV9pZChz
-cGkpOw0KPiA+ICsJc3QtPmNoaXBfaW5mbyA9ICZhZDcxMjRfY2hpcF9pbmZvX3RibFtpZC0+ZHJp
-dmVyX2RhdGFdOw0KPiA+ICsNCj4gPiArCWFkX3NkX2luaXQoJnN0LT5zZCwgaW5kaW9fZGV2LCBz
-cGksICZhZDcxMjRfc2lnbWFfZGVsdGFfaW5mbyk7DQo+ID4gKw0KPiA+ICsJc3BpX3NldF9kcnZk
-YXRhKHNwaSwgaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwlpbmRpb19kZXYtPmRldi5wYXJlbnQg
-PSAmc3BpLT5kZXY7DQo+ID4gKwlpbmRpb19kZXYtPm5hbWUgPSBzcGlfZ2V0X2RldmljZV9pZChz
-cGkpLT5uYW1lOw0KPiA+ICsJaW5kaW9fZGV2LT5tb2RlcyA9IElORElPX0RJUkVDVF9NT0RFOw0K
-PiA+ICsJaW5kaW9fZGV2LT5pbmZvID0gJmFkNzEyNF9pbmZvOw0KPiA+ICsNCj4gPiArCXJldCA9
-IGFkNzEyNF9vZl9wYXJzZV9jaGFubmVsX2NvbmZpZyhpbmRpb19kZXYsIHNwaS0NCj4gPiA+ZGV2
-Lm9mX25vZGUpOw0KPiA+ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiAr
-DQo+ID4gKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShzdC0+dnJlZik7IGkrKykgew0KPiA+
-ICsJCWlmIChpICE9IEFENzEyNF9JTlRfUkVGKSB7DQo+ID4gKwkJCXN0LT52cmVmW2ldID0NCj4g
-PiBkZXZtX3JlZ3VsYXRvcl9nZXRfb3B0aW9uYWwoJnNwaS0+ZGV2LA0KPiA+ICsJCQkJCQkJYWQ3
-MTI0X3JlZl9uYW0NCj4gPiBlc1tpXSk7DQo+ID4gKwkJCWlmIChQVFJfRVJSKHN0LT52cmVmW2ld
-KSA9PSAtRU5PREVWKQ0KPiA+ICsJCQkJY29udGludWU7DQo+ID4gKwkJCWVsc2UgaWYgKElTX0VS
-UihzdC0+dnJlZltpXSkpDQo+ID4gKwkJCQlyZXR1cm4gUFRSX0VSUihzdC0+dnJlZltpXSk7DQo+
-ID4gKw0KPiA+ICsJCQlyZXQgPSByZWd1bGF0b3JfZW5hYmxlKHN0LT52cmVmW2ldKTsNCj4gPiAr
-CQkJaWYgKHJldCkNCj4gPiArCQkJCXJldHVybiByZXQ7DQo+ID4gKwkJfQ0KPiA+ICsJfQ0KPiA+
-ICsNCj4gPiArCXN0LT5tY2xrID0gZGV2bV9jbGtfZ2V0KCZzcGktPmRldiwgIm1jbGsiKTsNCj4g
-PiArCWlmIChJU19FUlIoc3QtPm1jbGspKSB7DQo+ID4gKwkJcmV0ID0gUFRSX0VSUihzdC0+bWNs
-ayk7DQo+ID4gKwkJZ290byBlcnJvcl9yZWd1bGF0b3JfZGlzYWJsZTsNCj4gPiArCX0NCj4gPiAr
-DQo+ID4gKwlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUoc3QtPm1jbGspOw0KPiA+ICsJaWYgKHJl
-dCA8IDApDQo+ID4gKwkJZ290byBlcnJvcl9yZWd1bGF0b3JfZGlzYWJsZTsNCj4gPiArDQo+ID4g
-KwlyZXQgPSBhZDcxMjRfc29mdF9yZXNldChzdCk7DQo+ID4gKwlpZiAocmV0IDwgMCkNCj4gPiAr
-CQlnb3RvIGVycm9yX2Nsa19kaXNhYmxlX3VucHJlcGFyZTsNCj4gPiArDQo+ID4gKwlyZXQgPSBh
-ZDcxMjRfc2V0dXAoc3QpOw0KPiA+ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJZ290byBlcnJvcl9j
-bGtfZGlzYWJsZV91bnByZXBhcmU7DQo+ID4gKw0KPiA+ICsJcmV0ID0gYWRfc2Rfc2V0dXBfYnVm
-ZmVyX2FuZF90cmlnZ2VyKGluZGlvX2Rldik7DQo+ID4gKwlpZiAocmV0IDwgMCkNCj4gPiArCQln
-b3RvIGVycm9yX2Nsa19kaXNhYmxlX3VucHJlcGFyZTsNCj4gPiArDQo+ID4gKwlyZXQgPSBpaW9f
-ZGV2aWNlX3JlZ2lzdGVyKGluZGlvX2Rldik7DQo+ID4gKwlpZiAocmV0IDwgMCkgew0KPiA+ICsJ
-CWRldl9lcnIoJnNwaS0+ZGV2LCAiRmFpbGVkIHRvIHJlZ2lzdGVyIGlpbyBkZXZpY2VcbiIpOw0K
-PiA+ICsJCWdvdG8gZXJyb3JfcmVtb3ZlX3RyaWdnZXI7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJ
-cmV0dXJuIDA7DQo+ID4gKw0KPiA+ICtlcnJvcl9yZW1vdmVfdHJpZ2dlcjoNCj4gPiArCWFkX3Nk
-X2NsZWFudXBfYnVmZmVyX2FuZF90cmlnZ2VyKGluZGlvX2Rldik7DQo+ID4gK2Vycm9yX2Nsa19k
-aXNhYmxlX3VucHJlcGFyZToNCj4gPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShzdC0+bWNsayk7
-DQo+ID4gK2Vycm9yX3JlZ3VsYXRvcl9kaXNhYmxlOg0KPiA+ICsJZm9yIChpID0gQVJSQVlfU0la
-RShzdC0+dnJlZikgLSAxOyBpID49IDA7IGktLSkgew0KPiA+ICsJCWlmICghSVNfRVJSX09SX05V
-TEwoc3QtPnZyZWZbaV0pKQ0KPiA+ICsJCQlyZWd1bGF0b3JfZGlzYWJsZShzdC0+dnJlZltpXSk7
-DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHJldDsNCj4gPiArfQ0KPiA+ICsNCj4gPiAr
-c3RhdGljIGludCBhZDcxMjRfcmVtb3ZlKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpDQo+ID4gK3sN
-Cj4gPiArCXN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYgPSBzcGlfZ2V0X2RydmRhdGEoc3BpKTsN
-Cj4gPiArCXN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0ID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4g
-PiArCWludCBpOw0KPiA+ICsNCj4gPiArCWlpb19kZXZpY2VfdW5yZWdpc3RlcihpbmRpb19kZXYp
-Ow0KPiA+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHN0LT5tY2xrKTsNCj4gPiArCWFkX3NkX2Ns
-ZWFudXBfYnVmZmVyX2FuZF90cmlnZ2VyKGluZGlvX2Rldik7DQo+IFRoZSBvcmRlcmluZyBoZXJl
-IHNob3VsZCBtYXRjaCB0aGF0IGluIHRoZSBlcnJvciBwYXRoIGFib3ZlLg0KPiAoc28gdGhlIHR3
-byB0aGluZ3MgaGVyZSBzaG91bGQgYmUgcmV2ZXJzZWQpLg0KPiBJdCdzIGluIHRoZSBjYXRlZ29y
-eSBvZiBtYWtpbmcgdGhpbmdzIG9idmlvdXNseSBzYWZlIHJhdGhlciB0aGFuIGFuDQo+IGFjdHVh
-bCBpc3N1ZS4NCj4gSSBsaWtlIHRvIGJlIGFibGUgdG8gY2hlY2sgdGhlIG9yZGVyaW5nIG9ubHkg
-b25jZSByYXRoZXIgdGhhbiB0d2ljZQ0KPiB3aGVuIHJldmlld2luZyBzbyB3aWxsIGFsd2F5cyBj
-b25maXJtIHRoZXkgbWF0Y2guDQo+IA0KPiA+IA0KPiA+ICsNCj4gPiArCWZvciAoaSA9IEFSUkFZ
-X1NJWkUoc3QtPnZyZWYpIC0gMTsgaSA+PSAwOyBpLS0pIHsNCj4gPiArCQlpZiAoIUlTX0VSUl9P
-Ul9OVUxMKHN0LT52cmVmW2ldKSkNCj4gPiArCQkJcmVndWxhdG9yX2Rpc2FibGUoc3QtPnZyZWZb
-aV0pOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+
-ICtzdGF0aWMgY29uc3Qgc3RydWN0IHNwaV9kZXZpY2VfaWQgYWQ3MTI0X2lkX3RhYmxlW10gPSB7
-DQo+ID4gKwl7ICJhZDcxMjQtNCIsIElEX0FENzEyNF80IH0sDQo+ID4gKwl7ICJhZDcxMjQtOCIs
-IElEX0FENzEyNF84IH0sDQo+ID4gKwl7fQ0KPiA+ICt9Ow0KPiA+ICtNT0RVTEVfREVWSUNFX1RB
-QkxFKHNwaSwgYWQ3MTI0X2lkX3RhYmxlKTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1
-Y3Qgb2ZfZGV2aWNlX2lkIGFkNzEyNF9vZl9tYXRjaFtdID0gew0KPiA+ICsJeyAuY29tcGF0aWJs
-ZSA9ICJhZGksYWQ3MTI0LTQiIH0sDQo+ID4gKwl7IC5jb21wYXRpYmxlID0gImFkaSxhZDcxMjQt
-OCIgfSwNCj4gPiArCXsgfSwNCj4gPiArfTsNCj4gPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwg
-YWQ3MTI0X29mX21hdGNoKTsNCj4gPiArDQo+ID4gK3N0YXRpYyBzdHJ1Y3Qgc3BpX2RyaXZlciBh
-ZDcxMTI0X2RyaXZlciA9IHsNCj4gPiArCS5kcml2ZXIgPSB7DQo+ID4gKwkJLm5hbWUgPSAiYWQ3
-MTI0IiwNCj4gPiArCQkub2ZfbWF0Y2hfdGFibGUgPSBhZDcxMjRfb2ZfbWF0Y2gsDQo+ID4gKwl9
-LA0KPiA+ICsJLnByb2JlID0gYWQ3MTI0X3Byb2JlLA0KPiA+ICsJLnJlbW92ZQk9IGFkNzEyNF9y
-ZW1vdmUsDQo+ID4gKwkuaWRfdGFibGUgPSBhZDcxMjRfaWRfdGFibGUsDQo+ID4gK307DQo+ID4g
-K21vZHVsZV9zcGlfZHJpdmVyKGFkNzExMjRfZHJpdmVyKTsNCj4gPiArDQo+ID4gK01PRFVMRV9B
-VVRIT1IoIlN0ZWZhbiBQb3BhIDxzdGVmYW4ucG9wYUBhbmFsb2cuY29tPiIpOw0KPiA+ICtNT0RV
-TEVfREVTQ1JJUFRJT04oIkFuYWxvZyBEZXZpY2VzIEFENzEyNCBTUEkgZHJpdmVyIik7DQo+ID4g
-K01PRFVMRV9MSUNFTlNFKCJHUEwiKTsNCj4g
+On Sb, 2018-11-03 at 12:16 +0000, Jonathan Cameron wrote:
+> On Mon, 29 Oct 2018 18:38:31 +0200
+> Stefan Popa <stefan.popa@analog.com> wrote:
+> 
+> > 
+> > The ad7124-4 and ad7124-8 are a family of 4 and 8 channel sigma-delta
+> > ADCs
+> > with 24-bit precision and reference.
+> > 
+> > Three power modes are available which in turn affect the output data
+> > rate:
+> >  * Full power: 9.38 SPS to 19,200 SPS
+> >  * Mid power: 2.34 SPS to 4800 SPS
+> >  * Low power: 1.17 SPS to 2400 SPS
+> > 
+> > The ad7124-4 can be configured to have four differential inputs, while
+> > ad7124-8 can have 8. Moreover, ad7124 also supports per channel
+> > configuration. Each configuration consists of gain, reference source,
+> > output data rate and bipolar/unipolar configuration.
+> > 
+> > Datasheets:
+> > Link: http://www.analog.com/media/en/technical-documentation/data-sheet
+> > s/AD7124-4.pdf
+> > Link: http://www.analog.com/media/en/technical-documentation/data-sheet
+> > s/ad7124-8.pdf
+> > 
+> > Signed-off-by: Stefan Popa <stefan.popa@analog.com>
+> Hi Stefan,
+> 
+> The discussion around the DT binding has gotten me looking at bit
+> more closely at that for this version.
+> 
+> Some most comments in that section.  Also a really minor ordering issue
+> in
+> remove which I'd just have fixed if we weren't going around again for
+> the binding.
+> 
+> Main binding thing is I don't think the odr value belongs in DT.
+> Gain is more marginal (unless the part can actually be damaged by
+> a wrong value - which I hope it can't!).  I'm not that fussed
+> as there are definitely reasons to specify a default scale to
+> cover the reasonable range on a pin.
+> 
+> Thanks,
+> 
+> Jonathan
+
+Hi Jonathan,
+
+Thank you for the review! So, how should I proceed?
+
+First, we need an adc.txt file where "bipolar" and something like "diff-
+channels" should be documented. Should the file be placed under
+Documentation/devicetree/bindings/iio/adc?
+
+Regarding the "odr-hz" property, it totally makes sense to remove it from
+the DT. How about the "gain"? Should we leave it in the DT and also add the
+possibility to be configured from user space?
+
+Regards,
+-Stefan
+> > 
+> > ---
+> > Changes in v2:
+> > 	- Added this commit.
+> > Changes in v3:
+> > 	- Removed channel, address, scan_index and shift fields from
+> > 	  ad7124_channel_template.
+> > 	- Added a sanity check for val2 in ad7124_write_raw().
+> > 	- Used the "reg" property to get the channel address and "adi,diff-
+> > channels"
+> > 	  for the differential pins. The "adi,channel-number" property was
+> > removed.
+> > 	- When calling regulator_get_optional, the probe is given up in
+> > case of error,
+> > 	  but continues in case of -ENODEV.
+> > 	- clk_disable_unprepare() is called before
+> > ad_sd_cleanup_buffer_and_trigger
+> > 	  in ad7124_remove().
+> > 
+> >  MAINTAINERS              |   7 +
+> >  drivers/iio/adc/Kconfig  |  11 +
+> >  drivers/iio/adc/Makefile |   1 +
+> >  drivers/iio/adc/ad7124.c | 648
+> > +++++++++++++++++++++++++++++++++++++++++++++++
+> >  4 files changed, 667 insertions(+)
+> >  create mode 100644 drivers/iio/adc/ad7124.c
+> > 
+> > diff --git a/MAINTAINERS b/MAINTAINERS
+> > index f642044..3a1bfcb 100644
+> > --- a/MAINTAINERS
+> > +++ b/MAINTAINERS
+> > @@ -839,6 +839,13 @@ S:	Supported
+> >  F:	drivers/iio/dac/ad5758.c
+> >  F:	Documentation/devicetree/bindings/iio/dac/ad5758.txt
+> >  
+> > +ANALOG DEVICES INC AD7124 DRIVER
+> > +M:	Stefan Popa <stefan.popa@analog.com>
+> > +L:	linux-iio@vger.kernel.org
+> > +W:	http://ez.analog.com/community/linux-device-drivers
+> > +S:	Supported
+> > +F:	drivers/iio/adc/ad7124.c
+> > +
+> >  ANALOG DEVICES INC AD9389B DRIVER
+> >  M:	Hans Verkuil <hans.verkuil@cisco.com>
+> >  L:	linux-media@vger.kernel.org
+> > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
+> > index a52fea8..148a10f 100644
+> > --- a/drivers/iio/adc/Kconfig
+> > +++ b/drivers/iio/adc/Kconfig
+> > @@ -10,6 +10,17 @@ config AD_SIGMA_DELTA
+> >  	select IIO_BUFFER
+> >  	select IIO_TRIGGERED_BUFFER
+> >  
+> > +config AD7124
+> > +	tristate "Analog Devices AD7124 and similar sigma-delta ADCs
+> > driver"
+> > +	depends on SPI_MASTER
+> > +	select AD_SIGMA_DELTA
+> > +	help
+> > +	  Say yes here to build support for Analog Devices AD7124-4
+> > and AD7124-8
+> > +	  SPI analog to digital converters (ADC).
+> > +
+> > +	  To compile this driver as a module, choose M here: the
+> > module will be
+> > +	  called ad7124.
+> > +
+> >  config AD7266
+> >  	tristate "Analog Devices AD7265/AD7266 ADC driver"
+> >  	depends on SPI_MASTER
+> > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
+> > index a6e6a0b..76168b2 100644
+> > --- a/drivers/iio/adc/Makefile
+> > +++ b/drivers/iio/adc/Makefile
+> > @@ -5,6 +5,7 @@
+> >  
+> >  # When adding new entries keep the list in alphabetical order
+> >  obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
+> > +obj-$(CONFIG_AD7124) += ad7124.o
+> >  obj-$(CONFIG_AD7266) += ad7266.o
+> >  obj-$(CONFIG_AD7291) += ad7291.o
+> >  obj-$(CONFIG_AD7298) += ad7298.o
+> > diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c
+> > new file mode 100644
+> > index 0000000..0660135
+> > --- /dev/null
+> > +++ b/drivers/iio/adc/ad7124.c
+> > @@ -0,0 +1,648 @@
+> > +// SPDX-License-Identifier: GPL-2.0+
+> > +/*
+> > + * AD7124 SPI ADC driver
+> > + *
+> > + * Copyright 2018 Analog Devices Inc.
+> > + */
+> > +#include <linux/bitfield.h>
+> > +#include <linux/clk.h>
+> > +#include <linux/delay.h>
+> > +#include <linux/device.h>
+> > +#include <linux/err.h>
+> > +#include <linux/kernel.h>
+> > +#include <linux/module.h>
+> > +#include <linux/regulator/consumer.h>
+> > +#include <linux/spi/spi.h>
+> > +
+> > +#include <linux/iio/iio.h>
+> > +#include <linux/iio/adc/ad_sigma_delta.h>
+> > +#include <linux/iio/sysfs.h>
+> > +
+> > +/* AD7124 registers */
+> > +#define AD7124_COMMS			0x00
+> > +#define AD7124_STATUS			0x00
+> > +#define AD7124_ADC_CONTROL		0x01
+> > +#define AD7124_DATA			0x02
+> > +#define AD7124_IO_CONTROL_1		0x03
+> > +#define AD7124_IO_CONTROL_2		0x04
+> > +#define AD7124_ID			0x05
+> > +#define AD7124_ERROR			0x06
+> > +#define AD7124_ERROR_EN		0x07
+> > +#define AD7124_MCLK_COUNT		0x08
+> > +#define AD7124_CHANNEL(x)		(0x09 + (x))
+> > +#define AD7124_CONFIG(x)		(0x19 + (x))
+> > +#define AD7124_FILTER(x)		(0x21 + (x))
+> > +#define AD7124_OFFSET(x)		(0x29 + (x))
+> > +#define AD7124_GAIN(x)			(0x31 + (x))
+> > +
+> > +/* AD7124_STATUS */
+> > +#define AD7124_STATUS_POR_FLAG_MSK	BIT(4)
+> > +
+> > +/* AD7124_ADC_CONTROL */
+> > +#define AD7124_ADC_CTRL_PWR_MSK	GENMASK(7, 6)
+> > +#define AD7124_ADC_CTRL_PWR(x)		FIELD_PREP(AD7124_ADC_CT
+> > RL_PWR_MSK, x)
+> > +#define AD7124_ADC_CTRL_MODE_MSK	GENMASK(5, 2)
+> > +#define AD7124_ADC_CTRL_MODE(x)	FIELD_PREP(AD7124_ADC_CTRL_MODE
+> > _MSK, x)
+> > +
+> > +/* AD7124_CHANNEL_X */
+> > +#define AD7124_CHANNEL_EN_MSK		BIT(15)
+> > +#define AD7124_CHANNEL_EN(x)		FIELD_PREP(AD7124_CHANNEL_
+> > EN_MSK, x)
+> > +#define AD7124_CHANNEL_SETUP_MSK	GENMASK(14, 12)
+> > +#define AD7124_CHANNEL_SETUP(x)	FIELD_PREP(AD7124_CHANNEL_SETUP
+> > _MSK, x)
+> > +#define AD7124_CHANNEL_AINP_MSK	GENMASK(9, 5)
+> > +#define AD7124_CHANNEL_AINP(x)		FIELD_PREP(AD7124_CHANNE
+> > L_AINP_MSK, x)
+> > +#define AD7124_CHANNEL_AINM_MSK	GENMASK(4, 0)
+> > +#define AD7124_CHANNEL_AINM(x)		FIELD_PREP(AD7124_CHANNE
+> > L_AINM_MSK, x)
+> > +
+> > +/* AD7124_CONFIG_X */
+> > +#define AD7124_CONFIG_BIPOLAR_MSK	BIT(11)
+> > +#define AD7124_CONFIG_BIPOLAR(x)	FIELD_PREP(AD7124_CONFIG_BIPOL
+> > AR_MSK, x)
+> > +#define AD7124_CONFIG_REF_SEL_MSK	GENMASK(4, 3)
+> > +#define AD7124_CONFIG_REF_SEL(x)	FIELD_PREP(AD7124_CONFIG_REF_S
+> > EL_MSK, x)
+> > +#define AD7124_CONFIG_PGA_MSK		GENMASK(2, 0)
+> > +#define AD7124_CONFIG_PGA(x)		FIELD_PREP(AD7124_CONFIG_P
+> > GA_MSK, x)
+> > +
+> > +/* AD7124_FILTER_X */
+> > +#define AD7124_FILTER_FS_MSK		GENMASK(10, 0)
+> > +#define AD7124_FILTER_FS(x)		FIELD_PREP(AD7124_FILTER_FS
+> > _MSK, x)
+> > +
+> > +enum ad7124_ids {
+> > +	ID_AD7124_4,
+> > +	ID_AD7124_8,
+> > +};
+> > +
+> > +enum ad7124_ref_sel {
+> > +	AD7124_REFIN1,
+> > +	AD7124_REFIN2,
+> > +	AD7124_INT_REF,
+> > +	AD7124_AVDD_REF,
+> > +};
+> > +
+> > +enum ad7124_power_mode {
+> > +	AD7124_LOW_POWER,
+> > +	AD7124_MID_POWER,
+> > +	AD7124_FULL_POWER,
+> > +};
+> > +
+> > +static const unsigned int ad7124_gain[8] = {
+> > +	1, 2, 4, 8, 16, 32, 64, 128
+> > +};
+> > +
+> > +static const int ad7124_master_clk_freq_hz[3] = {
+> > +	[AD7124_LOW_POWER] = 76800,
+> > +	[AD7124_MID_POWER] = 153600,
+> > +	[AD7124_FULL_POWER] = 614400,
+> > +};
+> > +
+> > +static const char * const ad7124_ref_names[] = {
+> > +	[AD7124_REFIN1] = "refin1",
+> > +	[AD7124_REFIN2] = "refin2",
+> > +	[AD7124_INT_REF] = "int",
+> > +	[AD7124_AVDD_REF] = "avdd",
+> > +};
+> > +
+> > +struct ad7124_chip_info {
+> > +	unsigned int num_inputs;
+> > +};
+> > +
+> > +struct ad7124_channel_config {
+> > +	enum ad7124_ref_sel refsel;
+> > +	bool bipolar;
+> > +	unsigned int ain;
+> > +	unsigned int vref_mv;
+> > +	unsigned int pga_bits;
+> > +	unsigned int odr;
+> > +};
+> > +
+> > +struct ad7124_state {
+> > +	const struct ad7124_chip_info *chip_info;
+> > +	struct ad_sigma_delta sd;
+> > +	struct ad7124_channel_config channel_config[4];
+> > +	struct regulator *vref[4];
+> > +	struct clk *mclk;
+> > +	unsigned int adc_control;
+> > +	unsigned int num_channels;
+> > +};
+> > +
+> > +static const struct iio_chan_spec ad7124_channel_template = {
+> > +	.type = IIO_VOLTAGE,
+> > +	.indexed = 1,
+> > +	.differential = 1,
+> > +	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+> > +		BIT(IIO_CHAN_INFO_SCALE) |
+> > +		BIT(IIO_CHAN_INFO_OFFSET) |
+> > +		BIT(IIO_CHAN_INFO_SAMP_FREQ),
+> > +	.scan_type = {
+> > +		.sign = 'u',
+> > +		.realbits = 24,
+> > +		.storagebits = 32,
+> > +	},
+> > +};
+> > +
+> > +static struct ad7124_chip_info ad7124_chip_info_tbl[] = {
+> > +	[ID_AD7124_4] = {
+> > +		.num_inputs = 8,
+> > +	},
+> > +	[ID_AD7124_8] = {
+> > +		.num_inputs = 16,
+> > +	},
+> > +};
+> > +
+> > +static int ad7124_find_closest_match(const int *array,
+> > +				     unsigned int size, int val)
+> > +{
+> > +	int i;
+> > +
+> > +	for (i = 0; i < size; i++) {
+> > +		if (val <= array[i])
+> > +			return i;
+> > +	}
+> > +
+> > +	return size - 1;
+> > +}
+> > +
+> > +static int ad7124_spi_write_mask(struct ad7124_state *st,
+> > +				 unsigned int addr,
+> > +				 unsigned long mask,
+> > +				 unsigned int val,
+> > +				 unsigned int bytes)
+> > +{
+> > +	unsigned int readval;
+> > +	int ret;
+> > +
+> > +	ret = ad_sd_read_reg(&st->sd, addr, bytes, &readval);
+> > +	if (ret < 0)
+> > +		return ret;
+> > +
+> > +	readval &= ~mask;
+> > +	readval |= val;
+> > +
+> > +	return ad_sd_write_reg(&st->sd, addr, bytes, readval);
+> > +}
+> > +
+> > +static int ad7124_set_mode(struct ad_sigma_delta *sd,
+> > +			   enum ad_sigma_delta_mode mode)
+> > +{
+> > +	struct ad7124_state *st = container_of(sd, struct
+> > ad7124_state, sd);
+> > +
+> > +	st->adc_control &= ~AD7124_ADC_CTRL_MODE_MSK;
+> > +	st->adc_control |= AD7124_ADC_CTRL_MODE(mode);
+> > +
+> > +	return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st-
+> > >adc_control);
+> > +}
+> > +
+> > +static int ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int
+> > channel)
+> > +{
+> > +	struct ad7124_state *st = container_of(sd, struct
+> > ad7124_state, sd);
+> > +	unsigned int val;
+> > +
+> > +	val = st->channel_config[channel].ain | AD7124_CHANNEL_EN(1) |
+> > +	      AD7124_CHANNEL_SETUP(channel);
+> > +
+> > +	return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(channel), 2,
+> > val);
+> > +}
+> > +
+> > +static const struct ad_sigma_delta_info ad7124_sigma_delta_info = {
+> > +	.set_channel = ad7124_set_channel,
+> > +	.set_mode = ad7124_set_mode,
+> > +	.has_registers = true,
+> > +	.addr_shift = 0,
+> > +	.read_mask = BIT(6),
+> > +	.data_reg = AD7124_DATA,
+> > +};
+> > +
+> > +static int ad7124_set_channel_odr(struct ad7124_state *st,
+> > +				  unsigned int channel,
+> > +				  unsigned int odr)
+> > +{
+> > +	unsigned int fclk, odr_sel_bits;
+> > +	int ret;
+> > +
+> > +	fclk = clk_get_rate(st->mclk);
+> > +	/*
+> > +	 * FS[10:0] = fCLK / (fADC x 32) where:
+> > +	 * fADC is the output data rate
+> > +	 * fCLK is the master clock frequency
+> > +	 * FS[10:0] are the bits in the filter register
+> > +	 * FS[10:0] can have a value from 1 to 2047
+> > +	 */
+> > +	odr_sel_bits = DIV_ROUND_CLOSEST(fclk, odr * 32);
+> > +	if (odr_sel_bits < 1)
+> > +		odr_sel_bits = 1;
+> > +	else if (odr_sel_bits > 2047)
+> > +		odr_sel_bits = 2047;
+> > +
+> > +	ret = ad7124_spi_write_mask(st, AD7124_FILTER(channel),
+> > +				    AD7124_FILTER_FS_MSK,
+> > +				    AD7124_FILTER_FS(odr_sel_bits),
+> > 3);
+> > +	if (ret < 0)
+> > +		return ret;
+> > +	/* fADC = fCLK / (FS[10:0] x 32) */
+> > +	st->channel_config[channel].odr =
+> > +		DIV_ROUND_CLOSEST(fclk, odr_sel_bits * 32);
+> > +
+> > +	return 0;
+> > +}
+> > +
+> > +static int ad7124_read_raw(struct iio_dev *indio_dev,
+> > +			   struct iio_chan_spec const *chan,
+> > +			   int *val, int *val2, long info)
+> > +{
+> > +	struct ad7124_state *st = iio_priv(indio_dev);
+> > +	int idx, ret;
+> > +
+> > +	switch (info) {
+> > +	case IIO_CHAN_INFO_RAW:
+> > +		ret = ad_sigma_delta_single_conversion(indio_dev,
+> > chan, val);
+> > +		if (ret < 0)
+> > +			return ret;
+> > +
+> > +		/* After the conversion is performed, disable the
+> > channel */
+> > +		ret = ad_sd_write_reg(&st->sd,
+> > +				      AD7124_CHANNEL(chan->address),
+> > 2,
+> > +				      st->channel_config[chan-
+> > >address].ain |
+> > +				      AD7124_CHANNEL_EN(0));
+> > +		if (ret < 0)
+> > +			return ret;
+> > +
+> > +		return IIO_VAL_INT;
+> > +	case IIO_CHAN_INFO_SCALE:
+> > +		idx = st->channel_config[chan->address].pga_bits;
+> > +		*val = st->channel_config[chan->address].vref_mv /
+> > +			ad7124_gain[idx];
+> > +		if (st->channel_config[chan->address].bipolar)
+> > +			*val2 = chan->scan_type.realbits - 1;
+> > +		else
+> > +			*val2 = chan->scan_type.realbits;
+> > +
+> > +		return IIO_VAL_FRACTIONAL_LOG2;
+> > +	case IIO_CHAN_INFO_OFFSET:
+> > +		if (st->channel_config[chan->address].bipolar) {
+> > +			/* Code = 2^(n − 1) × ((Ain × Gain / Vref) +
+> > 1) */
+> > +			idx = st->channel_config[chan-
+> > >address].pga_bits;
+> > +			*val = -(st->channel_config[chan-
+> > >address].vref_mv /
+> > +				 ad7124_gain[idx]);
+> > +		} else {
+> > +			*val = 0;
+> > +		}
+> > +
+> > +		return IIO_VAL_INT;
+> > +	case IIO_CHAN_INFO_SAMP_FREQ:
+> > +		*val = st->channel_config[chan->address].odr;
+> > +
+> > +		return IIO_VAL_INT;
+> > +	default:
+> > +		return -EINVAL;
+> > +	}
+> > +}
+> > +
+> > +static int ad7124_write_raw(struct iio_dev *indio_dev,
+> > +			    struct iio_chan_spec const *chan,
+> > +			    int val, int val2, long info)
+> > +{
+> > +	struct ad7124_state *st = iio_priv(indio_dev);
+> > +
+> > +	switch (info) {
+> > +	case IIO_CHAN_INFO_SAMP_FREQ:
+> > +		if (val2 != 0)
+> > +			return -EINVAL;
+> > +
+> > +		return ad7124_set_channel_odr(st, chan->address, val);
+> > +	default:
+> > +		return -EINVAL;
+> > +	}
+> > +}
+> > +
+> > +static const struct iio_info ad7124_info = {
+> > +	.read_raw = ad7124_read_raw,
+> > +	.write_raw = ad7124_write_raw,
+> > +};
+> > +
+> > +static int ad7124_soft_reset(struct ad7124_state *st)
+> > +{
+> > +	unsigned int readval, timeout;
+> > +	int ret;
+> > +
+> > +	ret = ad_sd_reset(&st->sd, 64);
+> > +	if (ret < 0)
+> > +		return ret;
+> > +
+> > +	timeout = 100;
+> > +	do {
+> > +		ret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1,
+> > &readval);
+> > +		if (ret < 0)
+> > +			return ret;
+> > +
+> > +		if (!(readval & AD7124_STATUS_POR_FLAG_MSK))
+> > +			return 0;
+> > +
+> > +		/* The AD7124 requires typically 2ms to power up and
+> > settle */
+> > +		usleep_range(100, 2000);
+> > +	} while (--timeout);
+> > +
+> > +	dev_err(&st->sd.spi->dev, "Soft reset failed\n");
+> > +
+> > +	return -EIO;
+> > +}
+> > +
+> > +static int ad7124_init_channel_vref(struct ad7124_state *st,
+> > +				    unsigned int channel_number)
+> > +{
+> > +	unsigned int refsel = st-
+> > >channel_config[channel_number].refsel;
+> > +
+> > +	switch (refsel) {
+> > +	case AD7124_REFIN1:
+> > +	case AD7124_REFIN2:
+> > +	case AD7124_AVDD_REF:
+> > +		if (IS_ERR(st->vref[refsel])) {
+> > +			dev_err(&st->sd.spi->dev,
+> > +				"Error, trying to use external voltage
+> > reference without a %s regulator.",
+> > +				ad7124_ref_names[refsel]);
+> > +				return PTR_ERR(st->vref[refsel]);
+> > +		}
+> > +		st->channel_config[channel_number].vref_mv =
+> > +			regulator_get_voltage(st->vref[refsel]);
+> > +		/* Conversion from uV to mV */
+> > +		st->channel_config[channel_number].vref_mv /= 1000;
+> > +		break;
+> > +	case AD7124_INT_REF:
+> > +		st->channel_config[channel_number].vref_mv = 2500;
+> > +		break;
+> > +	default:
+> > +		dev_err(&st->sd.spi->dev, "Invalid reference %d\n",
+> > refsel);
+> > +		return -EINVAL;
+> > +	}
+> > +
+> > +	return 0;
+> > +}
+> > +
+> > +static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
+> > +					  struct device_node *np)
+> > +{
+> > +	struct ad7124_state *st = iio_priv(indio_dev);
+> > +	struct device_node *child;
+> > +	struct iio_chan_spec *chan;
+> > +	unsigned int ain[2], channel = 0, tmp;
+> > +	int ret, res;
+> > +
+> > +	st->num_channels = of_get_available_child_count(np);
+> > +	if (!st->num_channels) {
+> > +		dev_err(indio_dev->dev.parent, "no channel
+> > children\n");
+> > +		return -ENODEV;
+> > +	}
+> > +
+> > +	chan = devm_kcalloc(indio_dev->dev.parent, st->num_channels,
+> > +			    sizeof(*chan), GFP_KERNEL);
+> > +	if (!chan)
+> > +		return -ENOMEM;
+> > +
+> > +	indio_dev->channels = chan;
+> > +	indio_dev->num_channels = st->num_channels;
+> > +
+> > +	for_each_available_child_of_node(np, child) {
+> > +		ret = of_property_read_u32(child, "reg", &channel);
+> > +		if (ret)
+> > +			goto err;
+> > +
+> > +		ret = of_property_read_u32_array(child, "adi,diff-
+> > channels",
+> > +						 ain, 2);
+> This actually feels like something we could standardize as well as
+> bipolar.
+> In the oldest drivers we actually let userspace configure all of this,
+> but
+> I can understand that only some combinations make sense on a given board
+> so it arguably makes sense to only enable those, particularly when there
+> is a reference select that has to be paired with channel choice.
+> 
+> > 
+> > +		if (ret)
+> > +			goto err;
+> > +
+> > +		if (ain[0] >= st->chip_info->num_inputs ||
+> > +		    ain[1] >= st->chip_info->num_inputs) {
+> > +			dev_err(indio_dev->dev.parent,
+> > +				"Input pin number out of range.\n");
+> > +			ret = -EINVAL;
+> > +			goto err;
+> > +		}
+> > +		st->channel_config[channel].ain =
+> > AD7124_CHANNEL_AINP(ain[0]) |
+> > +						  AD7124_CHANNEL_AINM(
+> > ain[1]);
+> > +		st->channel_config[channel].bipolar =
+> > +			of_property_read_bool(child, "adi,bipolar");
+> > +
+> > +		ret = of_property_read_u32(child, "adi,reference-
+> > select", &tmp);
+> > +		if (ret)
+> > +			st->channel_config[channel].refsel =
+> > AD7124_INT_REF;
+> > +		else
+> > +			st->channel_config[channel].refsel = tmp;
+> > +
+> > +		ret = of_property_read_u32(child, "adi,gain", &tmp);
+> > +		if (ret) {
+> > +			st->channel_config[channel].pga_bits = 0;
+> > +		} else {
+> > +			res = ad7124_find_closest_match(ad7124_gain,
+> > +						ARRAY_SIZE(ad7124_gain
+> > ), tmp);
+> > +			st->channel_config[channel].pga_bits = res;
+> Hmm. The old question of what to put in DT as it reflects wiring and
+> what to leave to userspace. Gain is tricky as only some values make sense
+> for a given system, but there can be more than one that does...
+> This is probably reasonable as it can be considered as setting the
+> default
+> that makes sense for what is wired.  Potentially user space could
+> override
+> it later if it wanted to.
+> 
+> > 
+> > +		}
+> > +
+> > +		ret = of_property_read_u32(child, "adi,odr-hz", &tmp);
+> Why is this in DT. This one feels like a userspace choice to me. It's
+> only tangentially connected to how things are connected on the board.
+> You also support control from userspace.  I would pick a sensible
+> general default and then drop this from the DT binding. It's optional
+> anyway.
+> 
+> > 
+> > +		if (ret)
+> > +			/*
+> > +			 * 9 SPS is the minimum output data rate
+> > supported
+> > +			 * regardless of the selected power mode.
+> > +			 */
+> > +			st->channel_config[channel].odr = 9;
+> > +		else
+> > +			st->channel_config[channel].odr = tmp;
+> > +
+> > +		*chan = ad7124_channel_template;
+> > +		chan->address = channel;
+> > +		chan->scan_index = channel;
+> > +		chan->channel = ain[0];
+> > +		chan->channel2 = ain[1];
+> > +
+> > +		chan++;
+> > +	}
+> > +
+> > +	return 0;
+> > +err:
+> > +	of_node_put(child);
+> > +
+> > +	return ret;
+> > +}
+> > +
+> > +static int ad7124_setup(struct ad7124_state *st)
+> > +{
+> > +	unsigned int val, fclk, power_mode;
+> > +	int i, ret;
+> > +
+> > +	fclk = clk_get_rate(st->mclk);
+> > +	if (!fclk)
+> > +		return -EINVAL;
+> > +
+> > +	/* The power mode changes the master clock frequency */
+> > +	power_mode =
+> > ad7124_find_closest_match(ad7124_master_clk_freq_hz,
+> > +					ARRAY_SIZE(ad7124_master_clk_f
+> > req_hz),
+> > +					fclk);
+> > +	if (fclk != ad7124_master_clk_freq_hz[power_mode]) {
+> > +		ret = clk_set_rate(st->mclk, fclk);
+> > +		if (ret)
+> > +			return ret;
+> > +	}
+> > +
+> > +	/* Set the power mode */
+> > +	st->adc_control &= ~AD7124_ADC_CTRL_PWR_MSK;
+> > +	st->adc_control |= AD7124_ADC_CTRL_PWR(power_mode);
+> > +	ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st-
+> > >adc_control);
+> > +	if (ret < 0)
+> > +		return ret;
+> > +
+> > +	for (i = 0; i < st->num_channels; i++) {
+> > +		val = st->channel_config[i].ain |
+> > AD7124_CHANNEL_SETUP(i);
+> > +		ret = ad_sd_write_reg(&st->sd, AD7124_CHANNEL(i), 2,
+> > val);
+> > +		if (ret < 0)
+> > +			return ret;
+> > +
+> > +		ret = ad7124_init_channel_vref(st, i);
+> > +		if (ret < 0)
+> > +			return ret;
+> > +
+> > +		val = AD7124_CONFIG_BIPOLAR(st-
+> > >channel_config[i].bipolar) |
+> > +		      AD7124_CONFIG_REF_SEL(st-
+> > >channel_config[i].refsel) |
+> > +		      AD7124_CONFIG_PGA(st-
+> > >channel_config[i].pga_bits);
+> > +		ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(i), 2,
+> > val);
+> > +		if (ret < 0)
+> > +			return ret;
+> > +
+> > +		ret = ad7124_set_channel_odr(st, i, st-
+> > >channel_config[i].odr);
+> > +		if (ret < 0)
+> > +			return ret;
+> > +	}
+> > +
+> > +	return ret;
+> > +}
+> > +
+> > +static int ad7124_probe(struct spi_device *spi)
+> > +{
+> > +	const struct spi_device_id *id;
+> > +	struct ad7124_state *st;
+> > +	struct iio_dev *indio_dev;
+> > +	int i, ret;
+> > +
+> > +	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+> > +	if (!indio_dev)
+> > +		return -ENOMEM;
+> > +
+> > +	st = iio_priv(indio_dev);
+> > +
+> > +	id = spi_get_device_id(spi);
+> > +	st->chip_info = &ad7124_chip_info_tbl[id->driver_data];
+> > +
+> > +	ad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info);
+> > +
+> > +	spi_set_drvdata(spi, indio_dev);
+> > +
+> > +	indio_dev->dev.parent = &spi->dev;
+> > +	indio_dev->name = spi_get_device_id(spi)->name;
+> > +	indio_dev->modes = INDIO_DIRECT_MODE;
+> > +	indio_dev->info = &ad7124_info;
+> > +
+> > +	ret = ad7124_of_parse_channel_config(indio_dev, spi-
+> > >dev.of_node);
+> > +	if (ret < 0)
+> > +		return ret;
+> > +
+> > +	for (i = 0; i < ARRAY_SIZE(st->vref); i++) {
+> > +		if (i != AD7124_INT_REF) {
+> > +			st->vref[i] =
+> > devm_regulator_get_optional(&spi->dev,
+> > +							ad7124_ref_nam
+> > es[i]);
+> > +			if (PTR_ERR(st->vref[i]) == -ENODEV)
+> > +				continue;
+> > +			else if (IS_ERR(st->vref[i]))
+> > +				return PTR_ERR(st->vref[i]);
+> > +
+> > +			ret = regulator_enable(st->vref[i]);
+> > +			if (ret)
+> > +				return ret;
+> > +		}
+> > +	}
+> > +
+> > +	st->mclk = devm_clk_get(&spi->dev, "mclk");
+> > +	if (IS_ERR(st->mclk)) {
+> > +		ret = PTR_ERR(st->mclk);
+> > +		goto error_regulator_disable;
+> > +	}
+> > +
+> > +	ret = clk_prepare_enable(st->mclk);
+> > +	if (ret < 0)
+> > +		goto error_regulator_disable;
+> > +
+> > +	ret = ad7124_soft_reset(st);
+> > +	if (ret < 0)
+> > +		goto error_clk_disable_unprepare;
+> > +
+> > +	ret = ad7124_setup(st);
+> > +	if (ret < 0)
+> > +		goto error_clk_disable_unprepare;
+> > +
+> > +	ret = ad_sd_setup_buffer_and_trigger(indio_dev);
+> > +	if (ret < 0)
+> > +		goto error_clk_disable_unprepare;
+> > +
+> > +	ret = iio_device_register(indio_dev);
+> > +	if (ret < 0) {
+> > +		dev_err(&spi->dev, "Failed to register iio device\n");
+> > +		goto error_remove_trigger;
+> > +	}
+> > +
+> > +	return 0;
+> > +
+> > +error_remove_trigger:
+> > +	ad_sd_cleanup_buffer_and_trigger(indio_dev);
+> > +error_clk_disable_unprepare:
+> > +	clk_disable_unprepare(st->mclk);
+> > +error_regulator_disable:
+> > +	for (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) {
+> > +		if (!IS_ERR_OR_NULL(st->vref[i]))
+> > +			regulator_disable(st->vref[i]);
+> > +	}
+> > +
+> > +	return ret;
+> > +}
+> > +
+> > +static int ad7124_remove(struct spi_device *spi)
+> > +{
+> > +	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+> > +	struct ad7124_state *st = iio_priv(indio_dev);
+> > +	int i;
+> > +
+> > +	iio_device_unregister(indio_dev);
+> > +	clk_disable_unprepare(st->mclk);
+> > +	ad_sd_cleanup_buffer_and_trigger(indio_dev);
+> The ordering here should match that in the error path above.
+> (so the two things here should be reversed).
+> It's in the category of making things obviously safe rather than an
+> actual issue.
+> I like to be able to check the ordering only once rather than twice
+> when reviewing so will always confirm they match.
+> 
+> > 
+> > +
+> > +	for (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) {
+> > +		if (!IS_ERR_OR_NULL(st->vref[i]))
+> > +			regulator_disable(st->vref[i]);
+> > +	}
+> > +
+> > +	return 0;
+> > +}
+> > +
+> > +static const struct spi_device_id ad7124_id_table[] = {
+> > +	{ "ad7124-4", ID_AD7124_4 },
+> > +	{ "ad7124-8", ID_AD7124_8 },
+> > +	{}
+> > +};
+> > +MODULE_DEVICE_TABLE(spi, ad7124_id_table);
+> > +
+> > +static const struct of_device_id ad7124_of_match[] = {
+> > +	{ .compatible = "adi,ad7124-4" },
+> > +	{ .compatible = "adi,ad7124-8" },
+> > +	{ },
+> > +};
+> > +MODULE_DEVICE_TABLE(of, ad7124_of_match);
+> > +
+> > +static struct spi_driver ad71124_driver = {
+> > +	.driver = {
+> > +		.name = "ad7124",
+> > +		.of_match_table = ad7124_of_match,
+> > +	},
+> > +	.probe = ad7124_probe,
+> > +	.remove	= ad7124_remove,
+> > +	.id_table = ad7124_id_table,
+> > +};
+> > +module_spi_driver(ad71124_driver);
+> > +
+> > +MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
+> > +MODULE_DESCRIPTION("Analog Devices AD7124 SPI driver");
+> > +MODULE_LICENSE("GPL");
+>
diff --git a/a/content_digest b/N1/content_digest
index 3c26bbc..9e5a56d 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -15,482 +15,886 @@
  " linux-kernel@vger.kernel.org <linux-kernel@vger.kernel.org>\0"
  "\00:1\0"
  "b\0"
- "T24gU2IsIDIwMTgtMTEtMDMgYXQgMTI6MTYgKzAwMDAsIEpvbmF0aGFuIENhbWVyb24gd3JvdGU6\n"
- "DQo+IE9uIE1vbiwgMjkgT2N0IDIwMTggMTg6Mzg6MzEgKzAyMDANCj4gU3RlZmFuIFBvcGEgPHN0\n"
- "ZWZhbi5wb3BhQGFuYWxvZy5jb20+IHdyb3RlOg0KPiANCj4gPiANCj4gPiBUaGUgYWQ3MTI0LTQg\n"
- "YW5kIGFkNzEyNC04IGFyZSBhIGZhbWlseSBvZiA0IGFuZCA4IGNoYW5uZWwgc2lnbWEtZGVsdGEN\n"
- "Cj4gPiBBRENzDQo+ID4gd2l0aCAyNC1iaXQgcHJlY2lzaW9uIGFuZCByZWZlcmVuY2UuDQo+ID4g\n"
- "DQo+ID4gVGhyZWUgcG93ZXIgbW9kZXMgYXJlIGF2YWlsYWJsZSB3aGljaCBpbiB0dXJuIGFmZmVj\n"
- "dCB0aGUgb3V0cHV0IGRhdGENCj4gPiByYXRlOg0KPiA+IMKgKiBGdWxsIHBvd2VyOiA5LjM4IFNQ\n"
- "UyB0byAxOSwyMDAgU1BTDQo+ID4gwqAqIE1pZCBwb3dlcjogMi4zNCBTUFMgdG8gNDgwMCBTUFMN\n"
- "Cj4gPiDCoCogTG93IHBvd2VyOiAxLjE3IFNQUyB0byAyNDAwIFNQUw0KPiA+IA0KPiA+IFRoZSBh\n"
- "ZDcxMjQtNCBjYW4gYmUgY29uZmlndXJlZCB0byBoYXZlIGZvdXIgZGlmZmVyZW50aWFsIGlucHV0\n"
- "cywgd2hpbGUNCj4gPiBhZDcxMjQtOCBjYW4gaGF2ZSA4LiBNb3Jlb3ZlciwgYWQ3MTI0IGFsc28g\n"
- "c3VwcG9ydHMgcGVyIGNoYW5uZWwNCj4gPiBjb25maWd1cmF0aW9uLiBFYWNoIGNvbmZpZ3VyYXRp\n"
- "b24gY29uc2lzdHMgb2YgZ2FpbiwgcmVmZXJlbmNlIHNvdXJjZSwNCj4gPiBvdXRwdXQgZGF0YSBy\n"
- "YXRlIGFuZCBiaXBvbGFyL3VuaXBvbGFyIGNvbmZpZ3VyYXRpb24uDQo+ID4gDQo+ID4gRGF0YXNo\n"
- "ZWV0czoNCj4gPiBMaW5rOiBodHRwOi8vd3d3LmFuYWxvZy5jb20vbWVkaWEvZW4vdGVjaG5pY2Fs\n"
- "LWRvY3VtZW50YXRpb24vZGF0YS1zaGVldA0KPiA+IHMvQUQ3MTI0LTQucGRmDQo+ID4gTGluazog\n"
- "aHR0cDovL3d3dy5hbmFsb2cuY29tL21lZGlhL2VuL3RlY2huaWNhbC1kb2N1bWVudGF0aW9uL2Rh\n"
- "dGEtc2hlZXQNCj4gPiBzL2FkNzEyNC04LnBkZg0KPiA+IA0KPiA+IFNpZ25lZC1vZmYtYnk6IFN0\n"
- "ZWZhbiBQb3BhIDxzdGVmYW4ucG9wYUBhbmFsb2cuY29tPg0KPiBIaSBTdGVmYW4sDQo+IA0KPiBU\n"
- "aGUgZGlzY3Vzc2lvbiBhcm91bmQgdGhlIERUIGJpbmRpbmcgaGFzIGdvdHRlbiBtZSBsb29raW5n\n"
- "IGF0IGJpdA0KPiBtb3JlIGNsb3NlbHkgYXQgdGhhdCBmb3IgdGhpcyB2ZXJzaW9uLg0KPiANCj4g\n"
- "U29tZSBtb3N0IGNvbW1lbnRzIGluIHRoYXQgc2VjdGlvbi7CoMKgQWxzbyBhIHJlYWxseSBtaW5v\n"
- "ciBvcmRlcmluZyBpc3N1ZQ0KPiBpbg0KPiByZW1vdmUgd2hpY2ggSSdkIGp1c3QgaGF2ZSBmaXhl\n"
- "ZCBpZiB3ZSB3ZXJlbid0IGdvaW5nIGFyb3VuZCBhZ2FpbiBmb3INCj4gdGhlIGJpbmRpbmcuDQo+\n"
- "IA0KPiBNYWluIGJpbmRpbmcgdGhpbmcgaXMgSSBkb24ndCB0aGluayB0aGUgb2RyIHZhbHVlIGJl\n"
- "bG9uZ3MgaW4gRFQuDQo+IEdhaW4gaXMgbW9yZSBtYXJnaW5hbCAodW5sZXNzIHRoZSBwYXJ0IGNh\n"
- "biBhY3R1YWxseSBiZSBkYW1hZ2VkIGJ5DQo+IGEgd3JvbmcgdmFsdWUgLSB3aGljaCBJIGhvcGUg\n"
- "aXQgY2FuJ3QhKS7CoMKgSSdtIG5vdCB0aGF0IGZ1c3NlZA0KPiBhcyB0aGVyZSBhcmUgZGVmaW5p\n"
- "dGVseSByZWFzb25zIHRvIHNwZWNpZnkgYSBkZWZhdWx0IHNjYWxlIHRvDQo+IGNvdmVyIHRoZSBy\n"
- "ZWFzb25hYmxlIHJhbmdlIG9uIGEgcGluLg0KPiANCj4gVGhhbmtzLA0KPiANCj4gSm9uYXRoYW4N\n"
- "Cg0KSGkgSm9uYXRoYW4sDQoNClRoYW5rIHlvdSBmb3IgdGhlIHJldmlldyEgU28sIGhvdyBzaG91\n"
- "bGQgSSBwcm9jZWVkPw0KDQpGaXJzdCwgd2UgbmVlZCBhbiBhZGMudHh0IGZpbGUgd2hlcmUgImJp\n"
- "cG9sYXIiIGFuZCBzb21ldGhpbmcgbGlrZSAiZGlmZi0NCmNoYW5uZWxzIiBzaG91bGQgYmUgZG9j\n"
- "dW1lbnRlZC4gU2hvdWxkIHRoZSBmaWxlIGJlIHBsYWNlZCB1bmRlcg0KRG9jdW1lbnRhdGlvbi9k\n"
- "ZXZpY2V0cmVlL2JpbmRpbmdzL2lpby9hZGM/DQoNClJlZ2FyZGluZyB0aGUgIm9kci1oeiIgcHJv\n"
- "cGVydHksIGl0IHRvdGFsbHkgbWFrZXMgc2Vuc2UgdG8gcmVtb3ZlIGl0IGZyb20NCnRoZSBEVC4g\n"
- "SG93IGFib3V0IHRoZSAiZ2FpbiI/IFNob3VsZCB3ZSBsZWF2ZSBpdCBpbiB0aGUgRFQgYW5kIGFs\n"
- "c28gYWRkIHRoZQ0KcG9zc2liaWxpdHkgdG8gYmUgY29uZmlndXJlZCBmcm9tIHVzZXIgc3BhY2U/\n"
- "DQoNClJlZ2FyZHMsDQotU3RlZmFuDQo+ID4gDQo+ID4gLS0tDQo+ID4gQ2hhbmdlcyBpbiB2MjoN\n"
- "Cj4gPiAJLSBBZGRlZCB0aGlzIGNvbW1pdC4NCj4gPiBDaGFuZ2VzIGluIHYzOg0KPiA+IAktIFJl\n"
- "bW92ZWQgY2hhbm5lbCwgYWRkcmVzcywgc2Nhbl9pbmRleCBhbmQgc2hpZnQgZmllbGRzIGZyb20N\n"
- "Cj4gPiAJwqDCoGFkNzEyNF9jaGFubmVsX3RlbXBsYXRlLg0KPiA+IAktIEFkZGVkIGEgc2FuaXR5\n"
- "IGNoZWNrIGZvciB2YWwyIGluIGFkNzEyNF93cml0ZV9yYXcoKS4NCj4gPiAJLSBVc2VkIHRoZSAi\n"
- "cmVnIiBwcm9wZXJ0eSB0byBnZXQgdGhlIGNoYW5uZWwgYWRkcmVzcyBhbmQgImFkaSxkaWZmLQ0K\n"
- "PiA+IGNoYW5uZWxzIg0KPiA+IAnCoMKgZm9yIHRoZSBkaWZmZXJlbnRpYWwgcGlucy4gVGhlICJh\n"
- "ZGksY2hhbm5lbC1udW1iZXIiIHByb3BlcnR5IHdhcw0KPiA+IHJlbW92ZWQuDQo+ID4gCS0gV2hl\n"
- "biBjYWxsaW5nIHJlZ3VsYXRvcl9nZXRfb3B0aW9uYWwsIHRoZSBwcm9iZSBpcyBnaXZlbiB1cCBp\n"
- "bg0KPiA+IGNhc2Ugb2YgZXJyb3IsDQo+ID4gCcKgwqBidXQgY29udGludWVzIGluIGNhc2Ugb2Yg\n"
- "LUVOT0RFVi4NCj4gPiAJLSBjbGtfZGlzYWJsZV91bnByZXBhcmUoKSBpcyBjYWxsZWQgYmVmb3Jl\n"
- "DQo+ID4gYWRfc2RfY2xlYW51cF9idWZmZXJfYW5kX3RyaWdnZXINCj4gPiAJwqDCoGluIGFkNzEy\n"
- "NF9yZW1vdmUoKS4NCj4gPiANCj4gPiDCoE1BSU5UQUlORVJTwqDCoMKgwqDCoMKgwqDCoMKgwqDC\n"
- "oMKgwqDCoHzCoMKgwqA3ICsNCj4gPiDCoGRyaXZlcnMvaWlvL2FkYy9LY29uZmlnwqDCoHzCoMKg\n"
- "MTEgKw0KPiA+IMKgZHJpdmVycy9paW8vYWRjL01ha2VmaWxlIHzCoMKgwqAxICsNCj4gPiDCoGRy\n"
- "aXZlcnMvaWlvL2FkYy9hZDcxMjQuYyB8IDY0OA0KPiA+ICsrKysrKysrKysrKysrKysrKysrKysr\n"
- "KysrKysrKysrKysrKysrKysrKysrKysrDQo+ID4gwqA0IGZpbGVzIGNoYW5nZWQsIDY2NyBpbnNl\n"
- "cnRpb25zKCspDQo+ID4gwqBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9paW8vYWRjL2FkNzEy\n"
- "NC5jDQo+ID4gDQo+ID4gZGlmZiAtLWdpdCBhL01BSU5UQUlORVJTIGIvTUFJTlRBSU5FUlMNCj4g\n"
- "PiBpbmRleCBmNjQyMDQ0Li4zYTFiZmNiIDEwMDY0NA0KPiA+IC0tLSBhL01BSU5UQUlORVJTDQo+\n"
- "ID4gKysrIGIvTUFJTlRBSU5FUlMNCj4gPiBAQCAtODM5LDYgKzgzOSwxMyBAQCBTOglTdXBwb3J0\n"
- "ZWQNCj4gPiDCoEY6CWRyaXZlcnMvaWlvL2RhYy9hZDU3NTguYw0KPiA+IMKgRjoJRG9jdW1lbnRh\n"
- "dGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2lpby9kYWMvYWQ1NzU4LnR4dA0KPiA+IMKgDQo+ID4g\n"
- "K0FOQUxPRyBERVZJQ0VTIElOQyBBRDcxMjQgRFJJVkVSDQo+ID4gK006CVN0ZWZhbiBQb3BhIDxz\n"
- "dGVmYW4ucG9wYUBhbmFsb2cuY29tPg0KPiA+ICtMOglsaW51eC1paW9Admdlci5rZXJuZWwub3Jn\n"
- "DQo+ID4gK1c6CWh0dHA6Ly9lei5hbmFsb2cuY29tL2NvbW11bml0eS9saW51eC1kZXZpY2UtZHJp\n"
- "dmVycw0KPiA+ICtTOglTdXBwb3J0ZWQNCj4gPiArRjoJZHJpdmVycy9paW8vYWRjL2FkNzEyNC5j\n"
- "DQo+ID4gKw0KPiA+IMKgQU5BTE9HIERFVklDRVMgSU5DIEFEOTM4OUIgRFJJVkVSDQo+ID4gwqBN\n"
- "OglIYW5zIFZlcmt1aWwgPGhhbnMudmVya3VpbEBjaXNjby5jb20+DQo+ID4gwqBMOglsaW51eC1t\n"
- "ZWRpYUB2Z2VyLmtlcm5lbC5vcmcNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9paW8vYWRjL0tj\n"
- "b25maWcgYi9kcml2ZXJzL2lpby9hZGMvS2NvbmZpZw0KPiA+IGluZGV4IGE1MmZlYTguLjE0OGEx\n"
- "MGYgMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy9paW8vYWRjL0tjb25maWcNCj4gPiArKysgYi9k\n"
- "cml2ZXJzL2lpby9hZGMvS2NvbmZpZw0KPiA+IEBAIC0xMCw2ICsxMCwxNyBAQCBjb25maWcgQURf\n"
- "U0lHTUFfREVMVEENCj4gPiDCoAlzZWxlY3QgSUlPX0JVRkZFUg0KPiA+IMKgCXNlbGVjdCBJSU9f\n"
- "VFJJR0dFUkVEX0JVRkZFUg0KPiA+IMKgDQo+ID4gK2NvbmZpZyBBRDcxMjQNCj4gPiArCXRyaXN0\n"
- "YXRlICJBbmFsb2cgRGV2aWNlcyBBRDcxMjQgYW5kIHNpbWlsYXIgc2lnbWEtZGVsdGEgQURDcw0K\n"
- "PiA+IGRyaXZlciINCj4gPiArCWRlcGVuZHMgb24gU1BJX01BU1RFUg0KPiA+ICsJc2VsZWN0IEFE\n"
- "X1NJR01BX0RFTFRBDQo+ID4gKwloZWxwDQo+ID4gKwnCoMKgU2F5IHllcyBoZXJlIHRvIGJ1aWxk\n"
- "IHN1cHBvcnQgZm9yIEFuYWxvZyBEZXZpY2VzIEFENzEyNC00DQo+ID4gYW5kIEFENzEyNC04DQo+\n"
- "ID4gKwnCoMKgU1BJIGFuYWxvZyB0byBkaWdpdGFsIGNvbnZlcnRlcnMgKEFEQykuDQo+ID4gKw0K\n"
- "PiA+ICsJwqDCoFRvIGNvbXBpbGUgdGhpcyBkcml2ZXIgYXMgYSBtb2R1bGUsIGNob29zZSBNIGhl\n"
- "cmU6IHRoZQ0KPiA+IG1vZHVsZSB3aWxsIGJlDQo+ID4gKwnCoMKgY2FsbGVkIGFkNzEyNC4NCj4g\n"
- "PiArDQo+ID4gwqBjb25maWcgQUQ3MjY2DQo+ID4gwqAJdHJpc3RhdGUgIkFuYWxvZyBEZXZpY2Vz\n"
- "IEFENzI2NS9BRDcyNjYgQURDIGRyaXZlciINCj4gPiDCoAlkZXBlbmRzIG9uIFNQSV9NQVNURVIN\n"
- "Cj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9paW8vYWRjL01ha2VmaWxlIGIvZHJpdmVycy9paW8v\n"
- "YWRjL01ha2VmaWxlDQo+ID4gaW5kZXggYTZlNmEwYi4uNzYxNjhiMiAxMDA2NDQNCj4gPiAtLS0g\n"
- "YS9kcml2ZXJzL2lpby9hZGMvTWFrZWZpbGUNCj4gPiArKysgYi9kcml2ZXJzL2lpby9hZGMvTWFr\n"
- "ZWZpbGUNCj4gPiBAQCAtNSw2ICs1LDcgQEANCj4gPiDCoA0KPiA+IMKgIyBXaGVuIGFkZGluZyBu\n"
- "ZXcgZW50cmllcyBrZWVwIHRoZSBsaXN0IGluIGFscGhhYmV0aWNhbCBvcmRlcg0KPiA+IMKgb2Jq\n"
- "LSQoQ09ORklHX0FEX1NJR01BX0RFTFRBKSArPSBhZF9zaWdtYV9kZWx0YS5vDQo+ID4gK29iai0k\n"
- "KENPTkZJR19BRDcxMjQpICs9IGFkNzEyNC5vDQo+ID4gwqBvYmotJChDT05GSUdfQUQ3MjY2KSAr\n"
- "PSBhZDcyNjYubw0KPiA+IMKgb2JqLSQoQ09ORklHX0FENzI5MSkgKz0gYWQ3MjkxLm8NCj4gPiDC\n"
- "oG9iai0kKENPTkZJR19BRDcyOTgpICs9IGFkNzI5OC5vDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZl\n"
- "cnMvaWlvL2FkYy9hZDcxMjQuYyBiL2RyaXZlcnMvaWlvL2FkYy9hZDcxMjQuYw0KPiA+IG5ldyBm\n"
- "aWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMC4uMDY2MDEzNQ0KPiA+IC0tLSAvZGV2\n"
- "L251bGwNCj4gPiArKysgYi9kcml2ZXJzL2lpby9hZGMvYWQ3MTI0LmMNCj4gPiBAQCAtMCwwICsx\n"
- "LDY0OCBAQA0KPiA+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsNCj4gPiAr\n"
- "LyoNCj4gPiArICogQUQ3MTI0IFNQSSBBREMgZHJpdmVyDQo+ID4gKyAqDQo+ID4gKyAqIENvcHly\n"
- "aWdodCAyMDE4IEFuYWxvZyBEZXZpY2VzIEluYy4NCj4gPiArICovDQo+ID4gKyNpbmNsdWRlIDxs\n"
- "aW51eC9iaXRmaWVsZC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+DQo+ID4gKyNpbmNs\n"
- "dWRlIDxsaW51eC9kZWxheS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ID4g\n"
- "KyNpbmNsdWRlIDxsaW51eC9lcnIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPg0K\n"
- "PiA+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9yZWd1\n"
- "bGF0b3IvY29uc3VtZXIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3NwaS9zcGkuaD4NCj4gPiAr\n"
- "DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9paW8vaWlvLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9p\n"
- "aW8vYWRjL2FkX3NpZ21hX2RlbHRhLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9paW8vc3lzZnMu\n"
- "aD4NCj4gPiArDQo+ID4gKy8qIEFENzEyNCByZWdpc3RlcnMgKi8NCj4gPiArI2RlZmluZSBBRDcx\n"
- "MjRfQ09NTVMJCQkweDAwDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X1NUQVRVUwkJCTB4MDANCj4gPiAr\n"
- "I2RlZmluZSBBRDcxMjRfQURDX0NPTlRST0wJCTB4MDENCj4gPiArI2RlZmluZSBBRDcxMjRfREFU\n"
- "QQkJCTB4MDINCj4gPiArI2RlZmluZSBBRDcxMjRfSU9fQ09OVFJPTF8xCQkweDAzDQo+ID4gKyNk\n"
- "ZWZpbmUgQUQ3MTI0X0lPX0NPTlRST0xfMgkJMHgwNA0KPiA+ICsjZGVmaW5lIEFENzEyNF9JRAkJ\n"
- "CTB4MDUNCj4gPiArI2RlZmluZSBBRDcxMjRfRVJST1IJCQkweDA2DQo+ID4gKyNkZWZpbmUgQUQ3\n"
- "MTI0X0VSUk9SX0VOCQkweDA3DQo+ID4gKyNkZWZpbmUgQUQ3MTI0X01DTEtfQ09VTlQJCTB4MDgN\n"
- "Cj4gPiArI2RlZmluZSBBRDcxMjRfQ0hBTk5FTCh4KQkJKDB4MDkgKyAoeCkpDQo+ID4gKyNkZWZp\n"
- "bmUgQUQ3MTI0X0NPTkZJRyh4KQkJKDB4MTkgKyAoeCkpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0ZJ\n"
- "TFRFUih4KQkJKDB4MjEgKyAoeCkpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X09GRlNFVCh4KQkJKDB4\n"
- "MjkgKyAoeCkpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0dBSU4oeCkJCQkoMHgzMSArICh4KSkNCj4g\n"
- "PiArDQo+ID4gKy8qIEFENzEyNF9TVEFUVVMgKi8NCj4gPiArI2RlZmluZSBBRDcxMjRfU1RBVFVT\n"
- "X1BPUl9GTEFHX01TSwlCSVQoNCkNCj4gPiArDQo+ID4gKy8qIEFENzEyNF9BRENfQ09OVFJPTCAq\n"
- "Lw0KPiA+ICsjZGVmaW5lIEFENzEyNF9BRENfQ1RSTF9QV1JfTVNLCUdFTk1BU0soNywgNikNCj4g\n"
- "PiArI2RlZmluZSBBRDcxMjRfQURDX0NUUkxfUFdSKHgpCQlGSUVMRF9QUkVQKEFENzEyNF9BRENf\n"
- "Q1QNCj4gPiBSTF9QV1JfTVNLLCB4KQ0KPiA+ICsjZGVmaW5lIEFENzEyNF9BRENfQ1RSTF9NT0RF\n"
- "X01TSwlHRU5NQVNLKDUsIDIpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0FEQ19DVFJMX01PREUoeCkJ\n"
- "RklFTERfUFJFUChBRDcxMjRfQURDX0NUUkxfTU9ERQ0KPiA+IF9NU0ssIHgpDQo+ID4gKw0KPiA+\n"
- "ICsvKiBBRDcxMjRfQ0hBTk5FTF9YICovDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0NIQU5ORUxfRU5f\n"
- "TVNLCQlCSVQoMTUpDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0NIQU5ORUxfRU4oeCkJCUZJRUxEX1BS\n"
- "RVAoQUQ3MTI0X0NIQU5ORUxfDQo+ID4gRU5fTVNLLCB4KQ0KPiA+ICsjZGVmaW5lIEFENzEyNF9D\n"
- "SEFOTkVMX1NFVFVQX01TSwlHRU5NQVNLKDE0LCAxMikNCj4gPiArI2RlZmluZSBBRDcxMjRfQ0hB\n"
- "Tk5FTF9TRVRVUCh4KQlGSUVMRF9QUkVQKEFENzEyNF9DSEFOTkVMX1NFVFVQDQo+ID4gX01TSywg\n"
- "eCkNCj4gPiArI2RlZmluZSBBRDcxMjRfQ0hBTk5FTF9BSU5QX01TSwlHRU5NQVNLKDksIDUpDQo+\n"
- "ID4gKyNkZWZpbmUgQUQ3MTI0X0NIQU5ORUxfQUlOUCh4KQkJRklFTERfUFJFUChBRDcxMjRfQ0hB\n"
- "Tk5FDQo+ID4gTF9BSU5QX01TSywgeCkNCj4gPiArI2RlZmluZSBBRDcxMjRfQ0hBTk5FTF9BSU5N\n"
- "X01TSwlHRU5NQVNLKDQsIDApDQo+ID4gKyNkZWZpbmUgQUQ3MTI0X0NIQU5ORUxfQUlOTSh4KQkJ\n"
- "RklFTERfUFJFUChBRDcxMjRfQ0hBTk5FDQo+ID4gTF9BSU5NX01TSywgeCkNCj4gPiArDQo+ID4g\n"
- "Ky8qIEFENzEyNF9DT05GSUdfWCAqLw0KPiA+ICsjZGVmaW5lIEFENzEyNF9DT05GSUdfQklQT0xB\n"
- "Ul9NU0sJQklUKDExKQ0KPiA+ICsjZGVmaW5lIEFENzEyNF9DT05GSUdfQklQT0xBUih4KQlGSUVM\n"
- "RF9QUkVQKEFENzEyNF9DT05GSUdfQklQT0wNCj4gPiBBUl9NU0ssIHgpDQo+ID4gKyNkZWZpbmUg\n"
- "QUQ3MTI0X0NPTkZJR19SRUZfU0VMX01TSwlHRU5NQVNLKDQsIDMpDQo+ID4gKyNkZWZpbmUgQUQ3\n"
- "MTI0X0NPTkZJR19SRUZfU0VMKHgpCUZJRUxEX1BSRVAoQUQ3MTI0X0NPTkZJR19SRUZfUw0KPiA+\n"
- "IEVMX01TSywgeCkNCj4gPiArI2RlZmluZSBBRDcxMjRfQ09ORklHX1BHQV9NU0sJCUdFTk1BU0so\n"
- "MiwgMCkNCj4gPiArI2RlZmluZSBBRDcxMjRfQ09ORklHX1BHQSh4KQkJRklFTERfUFJFUChBRDcx\n"
- "MjRfQ09ORklHX1ANCj4gPiBHQV9NU0ssIHgpDQo+ID4gKw0KPiA+ICsvKiBBRDcxMjRfRklMVEVS\n"
- "X1ggKi8NCj4gPiArI2RlZmluZSBBRDcxMjRfRklMVEVSX0ZTX01TSwkJR0VOTUFTSygxMCwgMCkN\n"
- "Cj4gPiArI2RlZmluZSBBRDcxMjRfRklMVEVSX0ZTKHgpCQlGSUVMRF9QUkVQKEFENzEyNF9GSUxU\n"
- "RVJfRlMNCj4gPiBfTVNLLCB4KQ0KPiA+ICsNCj4gPiArZW51bSBhZDcxMjRfaWRzIHsNCj4gPiAr\n"
- "CUlEX0FENzEyNF80LA0KPiA+ICsJSURfQUQ3MTI0XzgsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtl\n"
- "bnVtIGFkNzEyNF9yZWZfc2VsIHsNCj4gPiArCUFENzEyNF9SRUZJTjEsDQo+ID4gKwlBRDcxMjRf\n"
- "UkVGSU4yLA0KPiA+ICsJQUQ3MTI0X0lOVF9SRUYsDQo+ID4gKwlBRDcxMjRfQVZERF9SRUYsDQo+\n"
- "ID4gK307DQo+ID4gKw0KPiA+ICtlbnVtIGFkNzEyNF9wb3dlcl9tb2RlIHsNCj4gPiArCUFENzEy\n"
- "NF9MT1dfUE9XRVIsDQo+ID4gKwlBRDcxMjRfTUlEX1BPV0VSLA0KPiA+ICsJQUQ3MTI0X0ZVTExf\n"
- "UE9XRVIsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IGFk\n"
- "NzEyNF9nYWluWzhdID0gew0KPiA+ICsJMSwgMiwgNCwgOCwgMTYsIDMyLCA2NCwgMTI4DQo+ID4g\n"
- "K307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3QgaW50IGFkNzEyNF9tYXN0ZXJfY2xrX2ZyZXFf\n"
- "aHpbM10gPSB7DQo+ID4gKwlbQUQ3MTI0X0xPV19QT1dFUl0gPSA3NjgwMCwNCj4gPiArCVtBRDcx\n"
- "MjRfTUlEX1BPV0VSXSA9IDE1MzYwMCwNCj4gPiArCVtBRDcxMjRfRlVMTF9QT1dFUl0gPSA2MTQ0\n"
- "MDAsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGFkNzEy\n"
- "NF9yZWZfbmFtZXNbXSA9IHsNCj4gPiArCVtBRDcxMjRfUkVGSU4xXSA9ICJyZWZpbjEiLA0KPiA+\n"
- "ICsJW0FENzEyNF9SRUZJTjJdID0gInJlZmluMiIsDQo+ID4gKwlbQUQ3MTI0X0lOVF9SRUZdID0g\n"
- "ImludCIsDQo+ID4gKwlbQUQ3MTI0X0FWRERfUkVGXSA9ICJhdmRkIiwNCj4gPiArfTsNCj4gPiAr\n"
- "DQo+ID4gK3N0cnVjdCBhZDcxMjRfY2hpcF9pbmZvIHsNCj4gPiArCXVuc2lnbmVkIGludCBudW1f\n"
- "aW5wdXRzOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RydWN0IGFkNzEyNF9jaGFubmVsX2NvbmZp\n"
- "ZyB7DQo+ID4gKwllbnVtIGFkNzEyNF9yZWZfc2VsIHJlZnNlbDsNCj4gPiArCWJvb2wgYmlwb2xh\n"
- "cjsNCj4gPiArCXVuc2lnbmVkIGludCBhaW47DQo+ID4gKwl1bnNpZ25lZCBpbnQgdnJlZl9tdjsN\n"
- "Cj4gPiArCXVuc2lnbmVkIGludCBwZ2FfYml0czsNCj4gPiArCXVuc2lnbmVkIGludCBvZHI7DQo+\n"
- "ID4gK307DQo+ID4gKw0KPiA+ICtzdHJ1Y3QgYWQ3MTI0X3N0YXRlIHsNCj4gPiArCWNvbnN0IHN0\n"
- "cnVjdCBhZDcxMjRfY2hpcF9pbmZvICpjaGlwX2luZm87DQo+ID4gKwlzdHJ1Y3QgYWRfc2lnbWFf\n"
- "ZGVsdGEgc2Q7DQo+ID4gKwlzdHJ1Y3QgYWQ3MTI0X2NoYW5uZWxfY29uZmlnIGNoYW5uZWxfY29u\n"
- "ZmlnWzRdOw0KPiA+ICsJc3RydWN0IHJlZ3VsYXRvciAqdnJlZls0XTsNCj4gPiArCXN0cnVjdCBj\n"
- "bGsgKm1jbGs7DQo+ID4gKwl1bnNpZ25lZCBpbnQgYWRjX2NvbnRyb2w7DQo+ID4gKwl1bnNpZ25l\n"
- "ZCBpbnQgbnVtX2NoYW5uZWxzOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0\n"
- "cnVjdCBpaW9fY2hhbl9zcGVjIGFkNzEyNF9jaGFubmVsX3RlbXBsYXRlID0gew0KPiA+ICsJLnR5\n"
- "cGUgPSBJSU9fVk9MVEFHRSwNCj4gPiArCS5pbmRleGVkID0gMSwNCj4gPiArCS5kaWZmZXJlbnRp\n"
- "YWwgPSAxLA0KPiA+ICsJLmluZm9fbWFza19zZXBhcmF0ZSA9IEJJVChJSU9fQ0hBTl9JTkZPX1JB\n"
- "VykgfA0KPiA+ICsJCUJJVChJSU9fQ0hBTl9JTkZPX1NDQUxFKSB8DQo+ID4gKwkJQklUKElJT19D\n"
- "SEFOX0lORk9fT0ZGU0VUKSB8DQo+ID4gKwkJQklUKElJT19DSEFOX0lORk9fU0FNUF9GUkVRKSwN\n"
- "Cj4gPiArCS5zY2FuX3R5cGUgPSB7DQo+ID4gKwkJLnNpZ24gPSAndScsDQo+ID4gKwkJLnJlYWxi\n"
- "aXRzID0gMjQsDQo+ID4gKwkJLnN0b3JhZ2ViaXRzID0gMzIsDQo+ID4gKwl9LA0KPiA+ICt9Ow0K\n"
- "PiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBhZDcxMjRfY2hpcF9pbmZvIGFkNzEyNF9jaGlwX2lu\n"
- "Zm9fdGJsW10gPSB7DQo+ID4gKwlbSURfQUQ3MTI0XzRdID0gew0KPiA+ICsJCS5udW1faW5wdXRz\n"
- "ID0gOCwNCj4gPiArCX0sDQo+ID4gKwlbSURfQUQ3MTI0XzhdID0gew0KPiA+ICsJCS5udW1faW5w\n"
- "dXRzID0gMTYsDQo+ID4gKwl9LA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGludCBhZDcx\n"
- "MjRfZmluZF9jbG9zZXN0X21hdGNoKGNvbnN0IGludCAqYXJyYXksDQo+ID4gKwkJCQnCoMKgwqDC\n"
- "oMKgdW5zaWduZWQgaW50IHNpemUsIGludCB2YWwpDQo+ID4gK3sNCj4gPiArCWludCBpOw0KPiA+\n"
- "ICsNCj4gPiArCWZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsNCj4gPiArCQlpZiAodmFsIDw9\n"
- "IGFycmF5W2ldKQ0KPiA+ICsJCQlyZXR1cm4gaTsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXR1\n"
- "cm4gc2l6ZSAtIDE7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgYWQ3MTI0X3NwaV93\n"
- "cml0ZV9tYXNrKHN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0LA0KPiA+ICsJCQkJwqB1bnNpZ25lZCBp\n"
- "bnQgYWRkciwNCj4gPiArCQkJCcKgdW5zaWduZWQgbG9uZyBtYXNrLA0KPiA+ICsJCQkJwqB1bnNp\n"
- "Z25lZCBpbnQgdmFsLA0KPiA+ICsJCQkJwqB1bnNpZ25lZCBpbnQgYnl0ZXMpDQo+ID4gK3sNCj4g\n"
- "PiArCXVuc2lnbmVkIGludCByZWFkdmFsOw0KPiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwly\n"
- "ZXQgPSBhZF9zZF9yZWFkX3JlZygmc3QtPnNkLCBhZGRyLCBieXRlcywgJnJlYWR2YWwpOw0KPiA+\n"
- "ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwlyZWFkdmFs\n"
- "ICY9IH5tYXNrOw0KPiA+ICsJcmVhZHZhbCB8PSB2YWw7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIGFk\n"
- "X3NkX3dyaXRlX3JlZygmc3QtPnNkLCBhZGRyLCBieXRlcywgcmVhZHZhbCk7DQo+ID4gK30NCj4g\n"
- "PiArDQo+ID4gK3N0YXRpYyBpbnQgYWQ3MTI0X3NldF9tb2RlKHN0cnVjdCBhZF9zaWdtYV9kZWx0\n"
- "YSAqc2QsDQo+ID4gKwkJCcKgwqDCoGVudW0gYWRfc2lnbWFfZGVsdGFfbW9kZSBtb2RlKQ0KPiA+\n"
- "ICt7DQo+ID4gKwlzdHJ1Y3QgYWQ3MTI0X3N0YXRlICpzdCA9IGNvbnRhaW5lcl9vZihzZCwgc3Ry\n"
- "dWN0DQo+ID4gYWQ3MTI0X3N0YXRlLCBzZCk7DQo+ID4gKw0KPiA+ICsJc3QtPmFkY19jb250cm9s\n"
- "ICY9IH5BRDcxMjRfQURDX0NUUkxfTU9ERV9NU0s7DQo+ID4gKwlzdC0+YWRjX2NvbnRyb2wgfD0g\n"
- "QUQ3MTI0X0FEQ19DVFJMX01PREUobW9kZSk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIGFkX3NkX3dy\n"
- "aXRlX3JlZygmc3QtPnNkLCBBRDcxMjRfQURDX0NPTlRST0wsIDIsIHN0LQ0KPiA+ID5hZGNfY29u\n"
- "dHJvbCk7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgYWQ3MTI0X3NldF9jaGFubmVs\n"
- "KHN0cnVjdCBhZF9zaWdtYV9kZWx0YSAqc2QsIHVuc2lnbmVkIGludA0KPiA+IGNoYW5uZWwpDQo+\n"
- "ID4gK3sNCj4gPiArCXN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0ID0gY29udGFpbmVyX29mKHNkLCBz\n"
- "dHJ1Y3QNCj4gPiBhZDcxMjRfc3RhdGUsIHNkKTsNCj4gPiArCXVuc2lnbmVkIGludCB2YWw7DQo+\n"
- "ID4gKw0KPiA+ICsJdmFsID0gc3QtPmNoYW5uZWxfY29uZmlnW2NoYW5uZWxdLmFpbiB8IEFENzEy\n"
- "NF9DSEFOTkVMX0VOKDEpIHwNCj4gPiArCcKgwqDCoMKgwqDCoEFENzEyNF9DSEFOTkVMX1NFVFVQ\n"
- "KGNoYW5uZWwpOw0KPiA+ICsNCj4gPiArCXJldHVybiBhZF9zZF93cml0ZV9yZWcoJnN0LT5zZCwg\n"
- "QUQ3MTI0X0NIQU5ORUwoY2hhbm5lbCksIDIsDQo+ID4gdmFsKTsNCj4gPiArfQ0KPiA+ICsNCj4g\n"
- "PiArc3RhdGljIGNvbnN0IHN0cnVjdCBhZF9zaWdtYV9kZWx0YV9pbmZvIGFkNzEyNF9zaWdtYV9k\n"
- "ZWx0YV9pbmZvID0gew0KPiA+ICsJLnNldF9jaGFubmVsID0gYWQ3MTI0X3NldF9jaGFubmVsLA0K\n"
- "PiA+ICsJLnNldF9tb2RlID0gYWQ3MTI0X3NldF9tb2RlLA0KPiA+ICsJLmhhc19yZWdpc3RlcnMg\n"
- "PSB0cnVlLA0KPiA+ICsJLmFkZHJfc2hpZnQgPSAwLA0KPiA+ICsJLnJlYWRfbWFzayA9IEJJVCg2\n"
- "KSwNCj4gPiArCS5kYXRhX3JlZyA9IEFENzEyNF9EQVRBLA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAr\n"
- "c3RhdGljIGludCBhZDcxMjRfc2V0X2NoYW5uZWxfb2RyKHN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0\n"
- "LA0KPiA+ICsJCQkJwqDCoHVuc2lnbmVkIGludCBjaGFubmVsLA0KPiA+ICsJCQkJwqDCoHVuc2ln\n"
- "bmVkIGludCBvZHIpDQo+ID4gK3sNCj4gPiArCXVuc2lnbmVkIGludCBmY2xrLCBvZHJfc2VsX2Jp\n"
- "dHM7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCWZjbGsgPSBjbGtfZ2V0X3JhdGUoc3Qt\n"
- "Pm1jbGspOw0KPiA+ICsJLyoNCj4gPiArCcKgKiBGU1sxMDowXSA9IGZDTEsgLyAoZkFEQyB4IDMy\n"
- "KSB3aGVyZToNCj4gPiArCcKgKiBmQURDIGlzIHRoZSBvdXRwdXQgZGF0YSByYXRlDQo+ID4gKwnC\n"
- "oCogZkNMSyBpcyB0aGUgbWFzdGVyIGNsb2NrIGZyZXF1ZW5jeQ0KPiA+ICsJwqAqIEZTWzEwOjBd\n"
- "IGFyZSB0aGUgYml0cyBpbiB0aGUgZmlsdGVyIHJlZ2lzdGVyDQo+ID4gKwnCoCogRlNbMTA6MF0g\n"
- "Y2FuIGhhdmUgYSB2YWx1ZSBmcm9tIDEgdG8gMjA0Nw0KPiA+ICsJwqAqLw0KPiA+ICsJb2RyX3Nl\n"
- "bF9iaXRzID0gRElWX1JPVU5EX0NMT1NFU1QoZmNsaywgb2RyICogMzIpOw0KPiA+ICsJaWYgKG9k\n"
- "cl9zZWxfYml0cyA8IDEpDQo+ID4gKwkJb2RyX3NlbF9iaXRzID0gMTsNCj4gPiArCWVsc2UgaWYg\n"
- "KG9kcl9zZWxfYml0cyA+IDIwNDcpDQo+ID4gKwkJb2RyX3NlbF9iaXRzID0gMjA0NzsNCj4gPiAr\n"
- "DQo+ID4gKwlyZXQgPSBhZDcxMjRfc3BpX3dyaXRlX21hc2soc3QsIEFENzEyNF9GSUxURVIoY2hh\n"
- "bm5lbCksDQo+ID4gKwkJCQnCoMKgwqDCoEFENzEyNF9GSUxURVJfRlNfTVNLLA0KPiA+ICsJCQkJ\n"
- "wqDCoMKgwqBBRDcxMjRfRklMVEVSX0ZTKG9kcl9zZWxfYml0cyksDQo+ID4gMyk7DQo+ID4gKwlp\n"
- "ZiAocmV0IDwgMCkNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsJLyogZkFEQyA9IGZDTEsgLyAo\n"
- "RlNbMTA6MF0geCAzMikgKi8NCj4gPiArCXN0LT5jaGFubmVsX2NvbmZpZ1tjaGFubmVsXS5vZHIg\n"
- "PQ0KPiA+ICsJCURJVl9ST1VORF9DTE9TRVNUKGZjbGssIG9kcl9zZWxfYml0cyAqIDMyKTsNCj4g\n"
- "PiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBhZDcx\n"
- "MjRfcmVhZF9yYXcoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiwNCj4gPiArCQkJwqDCoMKgc3Ry\n"
- "dWN0IGlpb19jaGFuX3NwZWMgY29uc3QgKmNoYW4sDQo+ID4gKwkJCcKgwqDCoGludCAqdmFsLCBp\n"
- "bnQgKnZhbDIsIGxvbmcgaW5mbykNCj4gPiArew0KPiA+ICsJc3RydWN0IGFkNzEyNF9zdGF0ZSAq\n"
- "c3QgPSBpaW9fcHJpdihpbmRpb19kZXYpOw0KPiA+ICsJaW50IGlkeCwgcmV0Ow0KPiA+ICsNCj4g\n"
- "PiArCXN3aXRjaCAoaW5mbykgew0KPiA+ICsJY2FzZSBJSU9fQ0hBTl9JTkZPX1JBVzoNCj4gPiAr\n"
- "CQlyZXQgPSBhZF9zaWdtYV9kZWx0YV9zaW5nbGVfY29udmVyc2lvbihpbmRpb19kZXYsDQo+ID4g\n"
- "Y2hhbiwgdmFsKTsNCj4gPiArCQlpZiAocmV0IDwgMCkNCj4gPiArCQkJcmV0dXJuIHJldDsNCj4g\n"
- "PiArDQo+ID4gKwkJLyogQWZ0ZXIgdGhlIGNvbnZlcnNpb24gaXMgcGVyZm9ybWVkLCBkaXNhYmxl\n"
- "IHRoZQ0KPiA+IGNoYW5uZWwgKi8NCj4gPiArCQlyZXQgPSBhZF9zZF93cml0ZV9yZWcoJnN0LT5z\n"
- "ZCwNCj4gPiArCQkJCcKgwqDCoMKgwqDCoEFENzEyNF9DSEFOTkVMKGNoYW4tPmFkZHJlc3MpLA0K\n"
- "PiA+IDIsDQo+ID4gKwkJCQnCoMKgwqDCoMKgwqBzdC0+Y2hhbm5lbF9jb25maWdbY2hhbi0NCj4g\n"
- "PiA+YWRkcmVzc10uYWluIHwNCj4gPiArCQkJCcKgwqDCoMKgwqDCoEFENzEyNF9DSEFOTkVMX0VO\n"
- "KDApKTsNCj4gPiArCQlpZiAocmV0IDwgMCkNCj4gPiArCQkJcmV0dXJuIHJldDsNCj4gPiArDQo+\n"
- "ID4gKwkJcmV0dXJuIElJT19WQUxfSU5UOw0KPiA+ICsJY2FzZSBJSU9fQ0hBTl9JTkZPX1NDQUxF\n"
- "Og0KPiA+ICsJCWlkeCA9IHN0LT5jaGFubmVsX2NvbmZpZ1tjaGFuLT5hZGRyZXNzXS5wZ2FfYml0\n"
- "czsNCj4gPiArCQkqdmFsID0gc3QtPmNoYW5uZWxfY29uZmlnW2NoYW4tPmFkZHJlc3NdLnZyZWZf\n"
- "bXYgLw0KPiA+ICsJCQlhZDcxMjRfZ2FpbltpZHhdOw0KPiA+ICsJCWlmIChzdC0+Y2hhbm5lbF9j\n"
- "b25maWdbY2hhbi0+YWRkcmVzc10uYmlwb2xhcikNCj4gPiArCQkJKnZhbDIgPSBjaGFuLT5zY2Fu\n"
- "X3R5cGUucmVhbGJpdHMgLSAxOw0KPiA+ICsJCWVsc2UNCj4gPiArCQkJKnZhbDIgPSBjaGFuLT5z\n"
- "Y2FuX3R5cGUucmVhbGJpdHM7DQo+ID4gKw0KPiA+ICsJCXJldHVybiBJSU9fVkFMX0ZSQUNUSU9O\n"
- "QUxfTE9HMjsNCj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19PRkZTRVQ6DQo+ID4gKwkJaWYgKHN0\n"
- "LT5jaGFubmVsX2NvbmZpZ1tjaGFuLT5hZGRyZXNzXS5iaXBvbGFyKSB7DQo+ID4gKwkJCS8qIENv\n"
- "ZGUgPSAyXihuIOKIkiAxKSDDlyAoKEFpbiDDlyBHYWluIC8gVnJlZikgKw0KPiA+IDEpICovDQo+\n"
- "ID4gKwkJCWlkeCA9IHN0LT5jaGFubmVsX2NvbmZpZ1tjaGFuLQ0KPiA+ID5hZGRyZXNzXS5wZ2Ff\n"
- "Yml0czsNCj4gPiArCQkJKnZhbCA9IC0oc3QtPmNoYW5uZWxfY29uZmlnW2NoYW4tDQo+ID4gPmFk\n"
- "ZHJlc3NdLnZyZWZfbXYgLw0KPiA+ICsJCQkJwqBhZDcxMjRfZ2FpbltpZHhdKTsNCj4gPiArCQl9\n"
- "IGVsc2Ugew0KPiA+ICsJCQkqdmFsID0gMDsNCj4gPiArCQl9DQo+ID4gKw0KPiA+ICsJCXJldHVy\n"
- "biBJSU9fVkFMX0lOVDsNCj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19TQU1QX0ZSRVE6DQo+ID4g\n"
- "KwkJKnZhbCA9IHN0LT5jaGFubmVsX2NvbmZpZ1tjaGFuLT5hZGRyZXNzXS5vZHI7DQo+ID4gKw0K\n"
- "PiA+ICsJCXJldHVybiBJSU9fVkFMX0lOVDsNCj4gPiArCWRlZmF1bHQ6DQo+ID4gKwkJcmV0dXJu\n"
- "IC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgYWQ3MTI0\n"
- "X3dyaXRlX3JhdyhzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2LA0KPiA+ICsJCQnCoMKgwqDCoHN0\n"
- "cnVjdCBpaW9fY2hhbl9zcGVjIGNvbnN0ICpjaGFuLA0KPiA+ICsJCQnCoMKgwqDCoGludCB2YWws\n"
- "IGludCB2YWwyLCBsb25nIGluZm8pDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBhZDcxMjRfc3RhdGUg\n"
- "KnN0ID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwlzd2l0Y2ggKGluZm8pIHsN\n"
- "Cj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19TQU1QX0ZSRVE6DQo+ID4gKwkJaWYgKHZhbDIgIT0g\n"
- "MCkNCj4gPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKw0KPiA+ICsJCXJldHVybiBhZDcxMjRf\n"
- "c2V0X2NoYW5uZWxfb2RyKHN0LCBjaGFuLT5hZGRyZXNzLCB2YWwpOw0KPiA+ICsJZGVmYXVsdDoN\n"
- "Cj4gPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCX0NCj4gPiArfQ0KPiA+ICsNCj4gPiArc3Rh\n"
- "dGljIGNvbnN0IHN0cnVjdCBpaW9faW5mbyBhZDcxMjRfaW5mbyA9IHsNCj4gPiArCS5yZWFkX3Jh\n"
- "dyA9IGFkNzEyNF9yZWFkX3JhdywNCj4gPiArCS53cml0ZV9yYXcgPSBhZDcxMjRfd3JpdGVfcmF3\n"
- "LA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGludCBhZDcxMjRfc29mdF9yZXNldChzdHJ1\n"
- "Y3QgYWQ3MTI0X3N0YXRlICpzdCkNCj4gPiArew0KPiA+ICsJdW5zaWduZWQgaW50IHJlYWR2YWws\n"
- "IHRpbWVvdXQ7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCXJldCA9IGFkX3NkX3Jlc2V0\n"
- "KCZzdC0+c2QsIDY0KTsNCj4gPiArCWlmIChyZXQgPCAwKQ0KPiA+ICsJCXJldHVybiByZXQ7DQo+\n"
- "ID4gKw0KPiA+ICsJdGltZW91dCA9IDEwMDsNCj4gPiArCWRvIHsNCj4gPiArCQlyZXQgPSBhZF9z\n"
- "ZF9yZWFkX3JlZygmc3QtPnNkLCBBRDcxMjRfU1RBVFVTLCAxLA0KPiA+ICZyZWFkdmFsKTsNCj4g\n"
- "PiArCQlpZiAocmV0IDwgMCkNCj4gPiArCQkJcmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwkJaWYg\n"
- "KCEocmVhZHZhbCAmIEFENzEyNF9TVEFUVVNfUE9SX0ZMQUdfTVNLKSkNCj4gPiArCQkJcmV0dXJu\n"
- "IDA7DQo+ID4gKw0KPiA+ICsJCS8qIFRoZSBBRDcxMjQgcmVxdWlyZXMgdHlwaWNhbGx5IDJtcyB0\n"
- "byBwb3dlciB1cCBhbmQNCj4gPiBzZXR0bGUgKi8NCj4gPiArCQl1c2xlZXBfcmFuZ2UoMTAwLCAy\n"
- "MDAwKTsNCj4gPiArCX0gd2hpbGUgKC0tdGltZW91dCk7DQo+ID4gKw0KPiA+ICsJZGV2X2Vycigm\n"
- "c3QtPnNkLnNwaS0+ZGV2LCAiU29mdCByZXNldCBmYWlsZWRcbiIpOw0KPiA+ICsNCj4gPiArCXJl\n"
- "dHVybiAtRUlPOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IGFkNzEyNF9pbml0X2No\n"
- "YW5uZWxfdnJlZihzdHJ1Y3QgYWQ3MTI0X3N0YXRlICpzdCwNCj4gPiArCQkJCcKgwqDCoMKgdW5z\n"
- "aWduZWQgaW50IGNoYW5uZWxfbnVtYmVyKQ0KPiA+ICt7DQo+ID4gKwl1bnNpZ25lZCBpbnQgcmVm\n"
- "c2VsID0gc3QtDQo+ID4gPmNoYW5uZWxfY29uZmlnW2NoYW5uZWxfbnVtYmVyXS5yZWZzZWw7DQo+\n"
- "ID4gKw0KPiA+ICsJc3dpdGNoIChyZWZzZWwpIHsNCj4gPiArCWNhc2UgQUQ3MTI0X1JFRklOMToN\n"
- "Cj4gPiArCWNhc2UgQUQ3MTI0X1JFRklOMjoNCj4gPiArCWNhc2UgQUQ3MTI0X0FWRERfUkVGOg0K\n"
- "PiA+ICsJCWlmIChJU19FUlIoc3QtPnZyZWZbcmVmc2VsXSkpIHsNCj4gPiArCQkJZGV2X2Vycigm\n"
- "c3QtPnNkLnNwaS0+ZGV2LA0KPiA+ICsJCQkJIkVycm9yLCB0cnlpbmcgdG8gdXNlIGV4dGVybmFs\n"
- "IHZvbHRhZ2UNCj4gPiByZWZlcmVuY2Ugd2l0aG91dCBhICVzIHJlZ3VsYXRvci4iLA0KPiA+ICsJ\n"
- "CQkJYWQ3MTI0X3JlZl9uYW1lc1tyZWZzZWxdKTsNCj4gPiArCQkJCXJldHVybiBQVFJfRVJSKHN0\n"
- "LT52cmVmW3JlZnNlbF0pOw0KPiA+ICsJCX0NCj4gPiArCQlzdC0+Y2hhbm5lbF9jb25maWdbY2hh\n"
- "bm5lbF9udW1iZXJdLnZyZWZfbXYgPQ0KPiA+ICsJCQlyZWd1bGF0b3JfZ2V0X3ZvbHRhZ2Uoc3Qt\n"
- "PnZyZWZbcmVmc2VsXSk7DQo+ID4gKwkJLyogQ29udmVyc2lvbiBmcm9tIHVWIHRvIG1WICovDQo+\n"
- "ID4gKwkJc3QtPmNoYW5uZWxfY29uZmlnW2NoYW5uZWxfbnVtYmVyXS52cmVmX212IC89IDEwMDA7\n"
- "DQo+ID4gKwkJYnJlYWs7DQo+ID4gKwljYXNlIEFENzEyNF9JTlRfUkVGOg0KPiA+ICsJCXN0LT5j\n"
- "aGFubmVsX2NvbmZpZ1tjaGFubmVsX251bWJlcl0udnJlZl9tdiA9IDI1MDA7DQo+ID4gKwkJYnJl\n"
- "YWs7DQo+ID4gKwlkZWZhdWx0Og0KPiA+ICsJCWRldl9lcnIoJnN0LT5zZC5zcGktPmRldiwgIklu\n"
- "dmFsaWQgcmVmZXJlbmNlICVkXG4iLA0KPiA+IHJlZnNlbCk7DQo+ID4gKwkJcmV0dXJuIC1FSU5W\n"
- "QUw7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4g\n"
- "K3N0YXRpYyBpbnQgYWQ3MTI0X29mX3BhcnNlX2NoYW5uZWxfY29uZmlnKHN0cnVjdCBpaW9fZGV2\n"
- "ICppbmRpb19kZXYsDQo+ID4gKwkJCQkJwqDCoHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnApDQo+ID4g\n"
- "K3sNCj4gPiArCXN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0ID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsN\n"
- "Cj4gPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqY2hpbGQ7DQo+ID4gKwlzdHJ1Y3QgaWlvX2NoYW5f\n"
- "c3BlYyAqY2hhbjsNCj4gPiArCXVuc2lnbmVkIGludCBhaW5bMl0sIGNoYW5uZWwgPSAwLCB0bXA7\n"
- "DQo+ID4gKwlpbnQgcmV0LCByZXM7DQo+ID4gKw0KPiA+ICsJc3QtPm51bV9jaGFubmVscyA9IG9m\n"
- "X2dldF9hdmFpbGFibGVfY2hpbGRfY291bnQobnApOw0KPiA+ICsJaWYgKCFzdC0+bnVtX2NoYW5u\n"
- "ZWxzKSB7DQo+ID4gKwkJZGV2X2VycihpbmRpb19kZXYtPmRldi5wYXJlbnQsICJubyBjaGFubmVs\n"
- "DQo+ID4gY2hpbGRyZW5cbiIpOw0KPiA+ICsJCXJldHVybiAtRU5PREVWOw0KPiA+ICsJfQ0KPiA+\n"
- "ICsNCj4gPiArCWNoYW4gPSBkZXZtX2tjYWxsb2MoaW5kaW9fZGV2LT5kZXYucGFyZW50LCBzdC0+\n"
- "bnVtX2NoYW5uZWxzLA0KPiA+ICsJCQnCoMKgwqDCoHNpemVvZigqY2hhbiksIEdGUF9LRVJORUwp\n"
- "Ow0KPiA+ICsJaWYgKCFjaGFuKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4gPiAr\n"
- "CWluZGlvX2Rldi0+Y2hhbm5lbHMgPSBjaGFuOw0KPiA+ICsJaW5kaW9fZGV2LT5udW1fY2hhbm5l\n"
- "bHMgPSBzdC0+bnVtX2NoYW5uZWxzOw0KPiA+ICsNCj4gPiArCWZvcl9lYWNoX2F2YWlsYWJsZV9j\n"
- "aGlsZF9vZl9ub2RlKG5wLCBjaGlsZCkgew0KPiA+ICsJCXJldCA9IG9mX3Byb3BlcnR5X3JlYWRf\n"
- "dTMyKGNoaWxkLCAicmVnIiwgJmNoYW5uZWwpOw0KPiA+ICsJCWlmIChyZXQpDQo+ID4gKwkJCWdv\n"
- "dG8gZXJyOw0KPiA+ICsNCj4gPiArCQlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMl9hcnJheShj\n"
- "aGlsZCwgImFkaSxkaWZmLQ0KPiA+IGNoYW5uZWxzIiwNCj4gPiArCQkJCQkJwqBhaW4sIDIpOw0K\n"
- "PiBUaGlzIGFjdHVhbGx5IGZlZWxzIGxpa2Ugc29tZXRoaW5nIHdlIGNvdWxkIHN0YW5kYXJkaXpl\n"
- "IGFzIHdlbGwgYXMNCj4gYmlwb2xhci4NCj4gSW4gdGhlIG9sZGVzdCBkcml2ZXJzIHdlIGFjdHVh\n"
- "bGx5IGxldCB1c2Vyc3BhY2UgY29uZmlndXJlIGFsbCBvZiB0aGlzLA0KPiBidXQNCj4gSSBjYW4g\n"
- "dW5kZXJzdGFuZCB0aGF0IG9ubHkgc29tZSBjb21iaW5hdGlvbnMgbWFrZSBzZW5zZSBvbiBhIGdp\n"
- "dmVuIGJvYXJkDQo+IHNvIGl0IGFyZ3VhYmx5IG1ha2VzIHNlbnNlIHRvIG9ubHkgZW5hYmxlIHRo\n"
- "b3NlLCBwYXJ0aWN1bGFybHkgd2hlbiB0aGVyZQ0KPiBpcyBhIHJlZmVyZW5jZSBzZWxlY3QgdGhh\n"
- "dCBoYXMgdG8gYmUgcGFpcmVkIHdpdGggY2hhbm5lbCBjaG9pY2UuDQo+IA0KPiA+IA0KPiA+ICsJ\n"
- "CWlmIChyZXQpDQo+ID4gKwkJCWdvdG8gZXJyOw0KPiA+ICsNCj4gPiArCQlpZiAoYWluWzBdID49\n"
- "IHN0LT5jaGlwX2luZm8tPm51bV9pbnB1dHMgfHwNCj4gPiArCQnCoMKgwqDCoGFpblsxXSA+PSBz\n"
- "dC0+Y2hpcF9pbmZvLT5udW1faW5wdXRzKSB7DQo+ID4gKwkJCWRldl9lcnIoaW5kaW9fZGV2LT5k\n"
- "ZXYucGFyZW50LA0KPiA+ICsJCQkJIklucHV0IHBpbiBudW1iZXIgb3V0IG9mIHJhbmdlLlxuIik7\n"
- "DQo+ID4gKwkJCXJldCA9IC1FSU5WQUw7DQo+ID4gKwkJCWdvdG8gZXJyOw0KPiA+ICsJCX0NCj4g\n"
- "PiArCQlzdC0+Y2hhbm5lbF9jb25maWdbY2hhbm5lbF0uYWluID0NCj4gPiBBRDcxMjRfQ0hBTk5F\n"
- "TF9BSU5QKGFpblswXSkgfA0KPiA+ICsJCQkJCQnCoMKgQUQ3MTI0X0NIQU5ORUxfQUlOTSgNCj4g\n"
- "PiBhaW5bMV0pOw0KPiA+ICsJCXN0LT5jaGFubmVsX2NvbmZpZ1tjaGFubmVsXS5iaXBvbGFyID0N\n"
- "Cj4gPiArCQkJb2ZfcHJvcGVydHlfcmVhZF9ib29sKGNoaWxkLCAiYWRpLGJpcG9sYXIiKTsNCj4g\n"
- "PiArDQo+ID4gKwkJcmV0ID0gb2ZfcHJvcGVydHlfcmVhZF91MzIoY2hpbGQsICJhZGkscmVmZXJl\n"
- "bmNlLQ0KPiA+IHNlbGVjdCIsICZ0bXApOw0KPiA+ICsJCWlmIChyZXQpDQo+ID4gKwkJCXN0LT5j\n"
- "aGFubmVsX2NvbmZpZ1tjaGFubmVsXS5yZWZzZWwgPQ0KPiA+IEFENzEyNF9JTlRfUkVGOw0KPiA+\n"
- "ICsJCWVsc2UNCj4gPiArCQkJc3QtPmNoYW5uZWxfY29uZmlnW2NoYW5uZWxdLnJlZnNlbCA9IHRt\n"
- "cDsNCj4gPiArDQo+ID4gKwkJcmV0ID0gb2ZfcHJvcGVydHlfcmVhZF91MzIoY2hpbGQsICJhZGks\n"
- "Z2FpbiIsICZ0bXApOw0KPiA+ICsJCWlmIChyZXQpIHsNCj4gPiArCQkJc3QtPmNoYW5uZWxfY29u\n"
- "ZmlnW2NoYW5uZWxdLnBnYV9iaXRzID0gMDsNCj4gPiArCQl9IGVsc2Ugew0KPiA+ICsJCQlyZXMg\n"
- "PSBhZDcxMjRfZmluZF9jbG9zZXN0X21hdGNoKGFkNzEyNF9nYWluLA0KPiA+ICsJCQkJCQlBUlJB\n"
- "WV9TSVpFKGFkNzEyNF9nYWluDQo+ID4gKSwgdG1wKTsNCj4gPiArCQkJc3QtPmNoYW5uZWxfY29u\n"
- "ZmlnW2NoYW5uZWxdLnBnYV9iaXRzID0gcmVzOw0KPiBIbW0uIFRoZSBvbGQgcXVlc3Rpb24gb2Yg\n"
- "d2hhdCB0byBwdXQgaW4gRFQgYXMgaXQgcmVmbGVjdHMgd2lyaW5nIGFuZA0KPiB3aGF0IHRvIGxl\n"
- "YXZlIHRvIHVzZXJzcGFjZS4gR2FpbiBpcyB0cmlja3kgYXMgb25seSBzb21lIHZhbHVlcyBtYWtl\n"
- "IHNlbnNlDQo+IGZvciBhIGdpdmVuIHN5c3RlbSwgYnV0IHRoZXJlIGNhbiBiZSBtb3JlIHRoYW4g\n"
- "b25lIHRoYXQgZG9lcy4uLg0KPiBUaGlzIGlzIHByb2JhYmx5IHJlYXNvbmFibGUgYXMgaXQgY2Fu\n"
- "IGJlIGNvbnNpZGVyZWQgYXMgc2V0dGluZyB0aGUNCj4gZGVmYXVsdA0KPiB0aGF0IG1ha2VzIHNl\n"
- "bnNlIGZvciB3aGF0IGlzIHdpcmVkLsKgwqBQb3RlbnRpYWxseSB1c2VyIHNwYWNlIGNvdWxkDQo+\n"
- "IG92ZXJyaWRlDQo+IGl0IGxhdGVyIGlmIGl0IHdhbnRlZCB0by4NCj4gDQo+ID4gDQo+ID4gKwkJ\n"
- "fQ0KPiA+ICsNCj4gPiArCQlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMihjaGlsZCwgImFkaSxv\n"
- "ZHItaHoiLCAmdG1wKTsNCj4gV2h5IGlzIHRoaXMgaW4gRFQuIFRoaXMgb25lIGZlZWxzIGxpa2Ug\n"
- "YSB1c2Vyc3BhY2UgY2hvaWNlIHRvIG1lLiBJdCdzDQo+IG9ubHkgdGFuZ2VudGlhbGx5IGNvbm5l\n"
- "Y3RlZCB0byBob3cgdGhpbmdzIGFyZSBjb25uZWN0ZWQgb24gdGhlIGJvYXJkLg0KPiBZb3UgYWxz\n"
- "byBzdXBwb3J0IGNvbnRyb2wgZnJvbSB1c2Vyc3BhY2UuwqDCoEkgd291bGQgcGljayBhIHNlbnNp\n"
- "YmxlDQo+IGdlbmVyYWwgZGVmYXVsdCBhbmQgdGhlbiBkcm9wIHRoaXMgZnJvbSB0aGUgRFQgYmlu\n"
- "ZGluZy4gSXQncyBvcHRpb25hbA0KPiBhbnl3YXkuDQo+IA0KPiA+IA0KPiA+ICsJCWlmIChyZXQp\n"
- "DQo+ID4gKwkJCS8qDQo+ID4gKwkJCcKgKiA5IFNQUyBpcyB0aGUgbWluaW11bSBvdXRwdXQgZGF0\n"
- "YSByYXRlDQo+ID4gc3VwcG9ydGVkDQo+ID4gKwkJCcKgKiByZWdhcmRsZXNzIG9mIHRoZSBzZWxl\n"
- "Y3RlZCBwb3dlciBtb2RlLg0KPiA+ICsJCQnCoCovDQo+ID4gKwkJCXN0LT5jaGFubmVsX2NvbmZp\n"
- "Z1tjaGFubmVsXS5vZHIgPSA5Ow0KPiA+ICsJCWVsc2UNCj4gPiArCQkJc3QtPmNoYW5uZWxfY29u\n"
- "ZmlnW2NoYW5uZWxdLm9kciA9IHRtcDsNCj4gPiArDQo+ID4gKwkJKmNoYW4gPSBhZDcxMjRfY2hh\n"
- "bm5lbF90ZW1wbGF0ZTsNCj4gPiArCQljaGFuLT5hZGRyZXNzID0gY2hhbm5lbDsNCj4gPiArCQlj\n"
- "aGFuLT5zY2FuX2luZGV4ID0gY2hhbm5lbDsNCj4gPiArCQljaGFuLT5jaGFubmVsID0gYWluWzBd\n"
- "Ow0KPiA+ICsJCWNoYW4tPmNoYW5uZWwyID0gYWluWzFdOw0KPiA+ICsNCj4gPiArCQljaGFuKys7\n"
- "DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK2VycjoNCj4gPiArCW9mX25v\n"
- "ZGVfcHV0KGNoaWxkKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ICt9DQo+ID4gKw0K\n"
- "PiA+ICtzdGF0aWMgaW50IGFkNzEyNF9zZXR1cChzdHJ1Y3QgYWQ3MTI0X3N0YXRlICpzdCkNCj4g\n"
- "PiArew0KPiA+ICsJdW5zaWduZWQgaW50IHZhbCwgZmNsaywgcG93ZXJfbW9kZTsNCj4gPiArCWlu\n"
- "dCBpLCByZXQ7DQo+ID4gKw0KPiA+ICsJZmNsayA9IGNsa19nZXRfcmF0ZShzdC0+bWNsayk7DQo+\n"
- "ID4gKwlpZiAoIWZjbGspDQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKw0KPiA+ICsJLyog\n"
- "VGhlIHBvd2VyIG1vZGUgY2hhbmdlcyB0aGUgbWFzdGVyIGNsb2NrIGZyZXF1ZW5jeSAqLw0KPiA+\n"
- "ICsJcG93ZXJfbW9kZSA9DQo+ID4gYWQ3MTI0X2ZpbmRfY2xvc2VzdF9tYXRjaChhZDcxMjRfbWFz\n"
- "dGVyX2Nsa19mcmVxX2h6LA0KPiA+ICsJCQkJCUFSUkFZX1NJWkUoYWQ3MTI0X21hc3Rlcl9jbGtf\n"
- "Zg0KPiA+IHJlcV9oeiksDQo+ID4gKwkJCQkJZmNsayk7DQo+ID4gKwlpZiAoZmNsayAhPSBhZDcx\n"
- "MjRfbWFzdGVyX2Nsa19mcmVxX2h6W3Bvd2VyX21vZGVdKSB7DQo+ID4gKwkJcmV0ID0gY2xrX3Nl\n"
- "dF9yYXRlKHN0LT5tY2xrLCBmY2xrKTsNCj4gPiArCQlpZiAocmV0KQ0KPiA+ICsJCQlyZXR1cm4g\n"
- "cmV0Ow0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCS8qIFNldCB0aGUgcG93ZXIgbW9kZSAqLw0KPiA+\n"
- "ICsJc3QtPmFkY19jb250cm9sICY9IH5BRDcxMjRfQURDX0NUUkxfUFdSX01TSzsNCj4gPiArCXN0\n"
- "LT5hZGNfY29udHJvbCB8PSBBRDcxMjRfQURDX0NUUkxfUFdSKHBvd2VyX21vZGUpOw0KPiA+ICsJ\n"
- "cmV0ID0gYWRfc2Rfd3JpdGVfcmVnKCZzdC0+c2QsIEFENzEyNF9BRENfQ09OVFJPTCwgMiwgc3Qt\n"
- "DQo+ID4gPmFkY19jb250cm9sKTsNCj4gPiArCWlmIChyZXQgPCAwKQ0KPiA+ICsJCXJldHVybiBy\n"
- "ZXQ7DQo+ID4gKw0KPiA+ICsJZm9yIChpID0gMDsgaSA8IHN0LT5udW1fY2hhbm5lbHM7IGkrKykg\n"
- "ew0KPiA+ICsJCXZhbCA9IHN0LT5jaGFubmVsX2NvbmZpZ1tpXS5haW4gfA0KPiA+IEFENzEyNF9D\n"
- "SEFOTkVMX1NFVFVQKGkpOw0KPiA+ICsJCXJldCA9IGFkX3NkX3dyaXRlX3JlZygmc3QtPnNkLCBB\n"
- "RDcxMjRfQ0hBTk5FTChpKSwgMiwNCj4gPiB2YWwpOw0KPiA+ICsJCWlmIChyZXQgPCAwKQ0KPiA+\n"
- "ICsJCQlyZXR1cm4gcmV0Ow0KPiA+ICsNCj4gPiArCQlyZXQgPSBhZDcxMjRfaW5pdF9jaGFubmVs\n"
- "X3ZyZWYoc3QsIGkpOw0KPiA+ICsJCWlmIChyZXQgPCAwKQ0KPiA+ICsJCQlyZXR1cm4gcmV0Ow0K\n"
- "PiA+ICsNCj4gPiArCQl2YWwgPSBBRDcxMjRfQ09ORklHX0JJUE9MQVIoc3QtDQo+ID4gPmNoYW5u\n"
- "ZWxfY29uZmlnW2ldLmJpcG9sYXIpIHwNCj4gPiArCQnCoMKgwqDCoMKgwqBBRDcxMjRfQ09ORklH\n"
- "X1JFRl9TRUwoc3QtDQo+ID4gPmNoYW5uZWxfY29uZmlnW2ldLnJlZnNlbCkgfA0KPiA+ICsJCcKg\n"
- "wqDCoMKgwqDCoEFENzEyNF9DT05GSUdfUEdBKHN0LQ0KPiA+ID5jaGFubmVsX2NvbmZpZ1tpXS5w\n"
- "Z2FfYml0cyk7DQo+ID4gKwkJcmV0ID0gYWRfc2Rfd3JpdGVfcmVnKCZzdC0+c2QsIEFENzEyNF9D\n"
- "T05GSUcoaSksIDIsDQo+ID4gdmFsKTsNCj4gPiArCQlpZiAocmV0IDwgMCkNCj4gPiArCQkJcmV0\n"
- "dXJuIHJldDsNCj4gPiArDQo+ID4gKwkJcmV0ID0gYWQ3MTI0X3NldF9jaGFubmVsX29kcihzdCwg\n"
- "aSwgc3QtDQo+ID4gPmNoYW5uZWxfY29uZmlnW2ldLm9kcik7DQo+ID4gKwkJaWYgKHJldCA8IDAp\n"
- "DQo+ID4gKwkJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHJldDsN\n"
- "Cj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBhZDcxMjRfcHJvYmUoc3RydWN0IHNwaV9k\n"
- "ZXZpY2UgKnNwaSkNCj4gPiArew0KPiA+ICsJY29uc3Qgc3RydWN0IHNwaV9kZXZpY2VfaWQgKmlk\n"
- "Ow0KPiA+ICsJc3RydWN0IGFkNzEyNF9zdGF0ZSAqc3Q7DQo+ID4gKwlzdHJ1Y3QgaWlvX2RldiAq\n"
- "aW5kaW9fZGV2Ow0KPiA+ICsJaW50IGksIHJldDsNCj4gPiArDQo+ID4gKwlpbmRpb19kZXYgPSBk\n"
- "ZXZtX2lpb19kZXZpY2VfYWxsb2MoJnNwaS0+ZGV2LCBzaXplb2YoKnN0KSk7DQo+ID4gKwlpZiAo\n"
- "IWluZGlvX2RldikNCj4gPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gPiArDQo+ID4gKwlzdCA9IGlp\n"
- "b19wcml2KGluZGlvX2Rldik7DQo+ID4gKw0KPiA+ICsJaWQgPSBzcGlfZ2V0X2RldmljZV9pZChz\n"
- "cGkpOw0KPiA+ICsJc3QtPmNoaXBfaW5mbyA9ICZhZDcxMjRfY2hpcF9pbmZvX3RibFtpZC0+ZHJp\n"
- "dmVyX2RhdGFdOw0KPiA+ICsNCj4gPiArCWFkX3NkX2luaXQoJnN0LT5zZCwgaW5kaW9fZGV2LCBz\n"
- "cGksICZhZDcxMjRfc2lnbWFfZGVsdGFfaW5mbyk7DQo+ID4gKw0KPiA+ICsJc3BpX3NldF9kcnZk\n"
- "YXRhKHNwaSwgaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwlpbmRpb19kZXYtPmRldi5wYXJlbnQg\n"
- "PSAmc3BpLT5kZXY7DQo+ID4gKwlpbmRpb19kZXYtPm5hbWUgPSBzcGlfZ2V0X2RldmljZV9pZChz\n"
- "cGkpLT5uYW1lOw0KPiA+ICsJaW5kaW9fZGV2LT5tb2RlcyA9IElORElPX0RJUkVDVF9NT0RFOw0K\n"
- "PiA+ICsJaW5kaW9fZGV2LT5pbmZvID0gJmFkNzEyNF9pbmZvOw0KPiA+ICsNCj4gPiArCXJldCA9\n"
- "IGFkNzEyNF9vZl9wYXJzZV9jaGFubmVsX2NvbmZpZyhpbmRpb19kZXYsIHNwaS0NCj4gPiA+ZGV2\n"
- "Lm9mX25vZGUpOw0KPiA+ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiAr\n"
- "DQo+ID4gKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShzdC0+dnJlZik7IGkrKykgew0KPiA+\n"
- "ICsJCWlmIChpICE9IEFENzEyNF9JTlRfUkVGKSB7DQo+ID4gKwkJCXN0LT52cmVmW2ldID0NCj4g\n"
- "PiBkZXZtX3JlZ3VsYXRvcl9nZXRfb3B0aW9uYWwoJnNwaS0+ZGV2LA0KPiA+ICsJCQkJCQkJYWQ3\n"
- "MTI0X3JlZl9uYW0NCj4gPiBlc1tpXSk7DQo+ID4gKwkJCWlmIChQVFJfRVJSKHN0LT52cmVmW2ld\n"
- "KSA9PSAtRU5PREVWKQ0KPiA+ICsJCQkJY29udGludWU7DQo+ID4gKwkJCWVsc2UgaWYgKElTX0VS\n"
- "UihzdC0+dnJlZltpXSkpDQo+ID4gKwkJCQlyZXR1cm4gUFRSX0VSUihzdC0+dnJlZltpXSk7DQo+\n"
- "ID4gKw0KPiA+ICsJCQlyZXQgPSByZWd1bGF0b3JfZW5hYmxlKHN0LT52cmVmW2ldKTsNCj4gPiAr\n"
- "CQkJaWYgKHJldCkNCj4gPiArCQkJCXJldHVybiByZXQ7DQo+ID4gKwkJfQ0KPiA+ICsJfQ0KPiA+\n"
- "ICsNCj4gPiArCXN0LT5tY2xrID0gZGV2bV9jbGtfZ2V0KCZzcGktPmRldiwgIm1jbGsiKTsNCj4g\n"
- "PiArCWlmIChJU19FUlIoc3QtPm1jbGspKSB7DQo+ID4gKwkJcmV0ID0gUFRSX0VSUihzdC0+bWNs\n"
- "ayk7DQo+ID4gKwkJZ290byBlcnJvcl9yZWd1bGF0b3JfZGlzYWJsZTsNCj4gPiArCX0NCj4gPiAr\n"
- "DQo+ID4gKwlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUoc3QtPm1jbGspOw0KPiA+ICsJaWYgKHJl\n"
- "dCA8IDApDQo+ID4gKwkJZ290byBlcnJvcl9yZWd1bGF0b3JfZGlzYWJsZTsNCj4gPiArDQo+ID4g\n"
- "KwlyZXQgPSBhZDcxMjRfc29mdF9yZXNldChzdCk7DQo+ID4gKwlpZiAocmV0IDwgMCkNCj4gPiAr\n"
- "CQlnb3RvIGVycm9yX2Nsa19kaXNhYmxlX3VucHJlcGFyZTsNCj4gPiArDQo+ID4gKwlyZXQgPSBh\n"
- "ZDcxMjRfc2V0dXAoc3QpOw0KPiA+ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJZ290byBlcnJvcl9j\n"
- "bGtfZGlzYWJsZV91bnByZXBhcmU7DQo+ID4gKw0KPiA+ICsJcmV0ID0gYWRfc2Rfc2V0dXBfYnVm\n"
- "ZmVyX2FuZF90cmlnZ2VyKGluZGlvX2Rldik7DQo+ID4gKwlpZiAocmV0IDwgMCkNCj4gPiArCQln\n"
- "b3RvIGVycm9yX2Nsa19kaXNhYmxlX3VucHJlcGFyZTsNCj4gPiArDQo+ID4gKwlyZXQgPSBpaW9f\n"
- "ZGV2aWNlX3JlZ2lzdGVyKGluZGlvX2Rldik7DQo+ID4gKwlpZiAocmV0IDwgMCkgew0KPiA+ICsJ\n"
- "CWRldl9lcnIoJnNwaS0+ZGV2LCAiRmFpbGVkIHRvIHJlZ2lzdGVyIGlpbyBkZXZpY2VcbiIpOw0K\n"
- "PiA+ICsJCWdvdG8gZXJyb3JfcmVtb3ZlX3RyaWdnZXI7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJ\n"
- "cmV0dXJuIDA7DQo+ID4gKw0KPiA+ICtlcnJvcl9yZW1vdmVfdHJpZ2dlcjoNCj4gPiArCWFkX3Nk\n"
- "X2NsZWFudXBfYnVmZmVyX2FuZF90cmlnZ2VyKGluZGlvX2Rldik7DQo+ID4gK2Vycm9yX2Nsa19k\n"
- "aXNhYmxlX3VucHJlcGFyZToNCj4gPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShzdC0+bWNsayk7\n"
- "DQo+ID4gK2Vycm9yX3JlZ3VsYXRvcl9kaXNhYmxlOg0KPiA+ICsJZm9yIChpID0gQVJSQVlfU0la\n"
- "RShzdC0+dnJlZikgLSAxOyBpID49IDA7IGktLSkgew0KPiA+ICsJCWlmICghSVNfRVJSX09SX05V\n"
- "TEwoc3QtPnZyZWZbaV0pKQ0KPiA+ICsJCQlyZWd1bGF0b3JfZGlzYWJsZShzdC0+dnJlZltpXSk7\n"
- "DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHJldDsNCj4gPiArfQ0KPiA+ICsNCj4gPiAr\n"
- "c3RhdGljIGludCBhZDcxMjRfcmVtb3ZlKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpDQo+ID4gK3sN\n"
- "Cj4gPiArCXN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYgPSBzcGlfZ2V0X2RydmRhdGEoc3BpKTsN\n"
- "Cj4gPiArCXN0cnVjdCBhZDcxMjRfc3RhdGUgKnN0ID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4g\n"
- "PiArCWludCBpOw0KPiA+ICsNCj4gPiArCWlpb19kZXZpY2VfdW5yZWdpc3RlcihpbmRpb19kZXYp\n"
- "Ow0KPiA+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHN0LT5tY2xrKTsNCj4gPiArCWFkX3NkX2Ns\n"
- "ZWFudXBfYnVmZmVyX2FuZF90cmlnZ2VyKGluZGlvX2Rldik7DQo+IFRoZSBvcmRlcmluZyBoZXJl\n"
- "IHNob3VsZCBtYXRjaCB0aGF0IGluIHRoZSBlcnJvciBwYXRoIGFib3ZlLg0KPiAoc28gdGhlIHR3\n"
- "byB0aGluZ3MgaGVyZSBzaG91bGQgYmUgcmV2ZXJzZWQpLg0KPiBJdCdzIGluIHRoZSBjYXRlZ29y\n"
- "eSBvZiBtYWtpbmcgdGhpbmdzIG9idmlvdXNseSBzYWZlIHJhdGhlciB0aGFuIGFuDQo+IGFjdHVh\n"
- "bCBpc3N1ZS4NCj4gSSBsaWtlIHRvIGJlIGFibGUgdG8gY2hlY2sgdGhlIG9yZGVyaW5nIG9ubHkg\n"
- "b25jZSByYXRoZXIgdGhhbiB0d2ljZQ0KPiB3aGVuIHJldmlld2luZyBzbyB3aWxsIGFsd2F5cyBj\n"
- "b25maXJtIHRoZXkgbWF0Y2guDQo+IA0KPiA+IA0KPiA+ICsNCj4gPiArCWZvciAoaSA9IEFSUkFZ\n"
- "X1NJWkUoc3QtPnZyZWYpIC0gMTsgaSA+PSAwOyBpLS0pIHsNCj4gPiArCQlpZiAoIUlTX0VSUl9P\n"
- "Ul9OVUxMKHN0LT52cmVmW2ldKSkNCj4gPiArCQkJcmVndWxhdG9yX2Rpc2FibGUoc3QtPnZyZWZb\n"
- "aV0pOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+\n"
- "ICtzdGF0aWMgY29uc3Qgc3RydWN0IHNwaV9kZXZpY2VfaWQgYWQ3MTI0X2lkX3RhYmxlW10gPSB7\n"
- "DQo+ID4gKwl7ICJhZDcxMjQtNCIsIElEX0FENzEyNF80IH0sDQo+ID4gKwl7ICJhZDcxMjQtOCIs\n"
- "IElEX0FENzEyNF84IH0sDQo+ID4gKwl7fQ0KPiA+ICt9Ow0KPiA+ICtNT0RVTEVfREVWSUNFX1RB\n"
- "QkxFKHNwaSwgYWQ3MTI0X2lkX3RhYmxlKTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1\n"
- "Y3Qgb2ZfZGV2aWNlX2lkIGFkNzEyNF9vZl9tYXRjaFtdID0gew0KPiA+ICsJeyAuY29tcGF0aWJs\n"
- "ZSA9ICJhZGksYWQ3MTI0LTQiIH0sDQo+ID4gKwl7IC5jb21wYXRpYmxlID0gImFkaSxhZDcxMjQt\n"
- "OCIgfSwNCj4gPiArCXsgfSwNCj4gPiArfTsNCj4gPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwg\n"
- "YWQ3MTI0X29mX21hdGNoKTsNCj4gPiArDQo+ID4gK3N0YXRpYyBzdHJ1Y3Qgc3BpX2RyaXZlciBh\n"
- "ZDcxMTI0X2RyaXZlciA9IHsNCj4gPiArCS5kcml2ZXIgPSB7DQo+ID4gKwkJLm5hbWUgPSAiYWQ3\n"
- "MTI0IiwNCj4gPiArCQkub2ZfbWF0Y2hfdGFibGUgPSBhZDcxMjRfb2ZfbWF0Y2gsDQo+ID4gKwl9\n"
- "LA0KPiA+ICsJLnByb2JlID0gYWQ3MTI0X3Byb2JlLA0KPiA+ICsJLnJlbW92ZQk9IGFkNzEyNF9y\n"
- "ZW1vdmUsDQo+ID4gKwkuaWRfdGFibGUgPSBhZDcxMjRfaWRfdGFibGUsDQo+ID4gK307DQo+ID4g\n"
- "K21vZHVsZV9zcGlfZHJpdmVyKGFkNzExMjRfZHJpdmVyKTsNCj4gPiArDQo+ID4gK01PRFVMRV9B\n"
- "VVRIT1IoIlN0ZWZhbiBQb3BhIDxzdGVmYW4ucG9wYUBhbmFsb2cuY29tPiIpOw0KPiA+ICtNT0RV\n"
- "TEVfREVTQ1JJUFRJT04oIkFuYWxvZyBEZXZpY2VzIEFENzEyNCBTUEkgZHJpdmVyIik7DQo+ID4g\n"
- K01PRFVMRV9MSUNFTlNFKCJHUEwiKTsNCj4g
+ "On Sb, 2018-11-03 at 12:16 +0000, Jonathan Cameron wrote:\n"
+ "> On Mon, 29 Oct 2018 18:38:31 +0200\n"
+ "> Stefan Popa <stefan.popa@analog.com> wrote:\n"
+ "> \n"
+ "> > \n"
+ "> > The ad7124-4 and ad7124-8 are a family of 4 and 8 channel sigma-delta\n"
+ "> > ADCs\n"
+ "> > with 24-bit precision and reference.\n"
+ "> > \n"
+ "> > Three power modes are available which in turn affect the output data\n"
+ "> > rate:\n"
+ "> > \302\240* Full power: 9.38 SPS to 19,200 SPS\n"
+ "> > \302\240* Mid power: 2.34 SPS to 4800 SPS\n"
+ "> > \302\240* Low power: 1.17 SPS to 2400 SPS\n"
+ "> > \n"
+ "> > The ad7124-4 can be configured to have four differential inputs, while\n"
+ "> > ad7124-8 can have 8. Moreover, ad7124 also supports per channel\n"
+ "> > configuration. Each configuration consists of gain, reference source,\n"
+ "> > output data rate and bipolar/unipolar configuration.\n"
+ "> > \n"
+ "> > Datasheets:\n"
+ "> > Link: http://www.analog.com/media/en/technical-documentation/data-sheet\n"
+ "> > s/AD7124-4.pdf\n"
+ "> > Link: http://www.analog.com/media/en/technical-documentation/data-sheet\n"
+ "> > s/ad7124-8.pdf\n"
+ "> > \n"
+ "> > Signed-off-by: Stefan Popa <stefan.popa@analog.com>\n"
+ "> Hi Stefan,\n"
+ "> \n"
+ "> The discussion around the DT binding has gotten me looking at bit\n"
+ "> more closely at that for this version.\n"
+ "> \n"
+ "> Some most comments in that section.\302\240\302\240Also a really minor ordering issue\n"
+ "> in\n"
+ "> remove which I'd just have fixed if we weren't going around again for\n"
+ "> the binding.\n"
+ "> \n"
+ "> Main binding thing is I don't think the odr value belongs in DT.\n"
+ "> Gain is more marginal (unless the part can actually be damaged by\n"
+ "> a wrong value - which I hope it can't!).\302\240\302\240I'm not that fussed\n"
+ "> as there are definitely reasons to specify a default scale to\n"
+ "> cover the reasonable range on a pin.\n"
+ "> \n"
+ "> Thanks,\n"
+ "> \n"
+ "> Jonathan\n"
+ "\n"
+ "Hi Jonathan,\n"
+ "\n"
+ "Thank you for the review! So, how should I proceed?\n"
+ "\n"
+ "First, we need an adc.txt file where \"bipolar\" and something like \"diff-\n"
+ "channels\" should be documented. Should the file be placed under\n"
+ "Documentation/devicetree/bindings/iio/adc?\n"
+ "\n"
+ "Regarding the \"odr-hz\" property, it totally makes sense to remove it from\n"
+ "the DT. How about the \"gain\"? Should we leave it in the DT and also add the\n"
+ "possibility to be configured from user space?\n"
+ "\n"
+ "Regards,\n"
+ "-Stefan\n"
+ "> > \n"
+ "> > ---\n"
+ "> > Changes in v2:\n"
+ "> > \t- Added this commit.\n"
+ "> > Changes in v3:\n"
+ "> > \t- Removed channel, address, scan_index and shift fields from\n"
+ "> > \t\302\240\302\240ad7124_channel_template.\n"
+ "> > \t- Added a sanity check for val2 in ad7124_write_raw().\n"
+ "> > \t- Used the \"reg\" property to get the channel address and \"adi,diff-\n"
+ "> > channels\"\n"
+ "> > \t\302\240\302\240for the differential pins. The \"adi,channel-number\" property was\n"
+ "> > removed.\n"
+ "> > \t- When calling regulator_get_optional, the probe is given up in\n"
+ "> > case of error,\n"
+ "> > \t\302\240\302\240but continues in case of -ENODEV.\n"
+ "> > \t- clk_disable_unprepare() is called before\n"
+ "> > ad_sd_cleanup_buffer_and_trigger\n"
+ "> > \t\302\240\302\240in ad7124_remove().\n"
+ "> > \n"
+ "> > \302\240MAINTAINERS\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240|\302\240\302\240\302\2407 +\n"
+ "> > \302\240drivers/iio/adc/Kconfig\302\240\302\240|\302\240\302\24011 +\n"
+ "> > \302\240drivers/iio/adc/Makefile |\302\240\302\240\302\2401 +\n"
+ "> > \302\240drivers/iio/adc/ad7124.c | 648\n"
+ "> > +++++++++++++++++++++++++++++++++++++++++++++++\n"
+ "> > \302\2404 files changed, 667 insertions(+)\n"
+ "> > \302\240create mode 100644 drivers/iio/adc/ad7124.c\n"
+ "> > \n"
+ "> > diff --git a/MAINTAINERS b/MAINTAINERS\n"
+ "> > index f642044..3a1bfcb 100644\n"
+ "> > --- a/MAINTAINERS\n"
+ "> > +++ b/MAINTAINERS\n"
+ "> > @@ -839,6 +839,13 @@ S:\tSupported\n"
+ "> > \302\240F:\tdrivers/iio/dac/ad5758.c\n"
+ "> > \302\240F:\tDocumentation/devicetree/bindings/iio/dac/ad5758.txt\n"
+ "> > \302\240\n"
+ "> > +ANALOG DEVICES INC AD7124 DRIVER\n"
+ "> > +M:\tStefan Popa <stefan.popa@analog.com>\n"
+ "> > +L:\tlinux-iio@vger.kernel.org\n"
+ "> > +W:\thttp://ez.analog.com/community/linux-device-drivers\n"
+ "> > +S:\tSupported\n"
+ "> > +F:\tdrivers/iio/adc/ad7124.c\n"
+ "> > +\n"
+ "> > \302\240ANALOG DEVICES INC AD9389B DRIVER\n"
+ "> > \302\240M:\tHans Verkuil <hans.verkuil@cisco.com>\n"
+ "> > \302\240L:\tlinux-media@vger.kernel.org\n"
+ "> > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig\n"
+ "> > index a52fea8..148a10f 100644\n"
+ "> > --- a/drivers/iio/adc/Kconfig\n"
+ "> > +++ b/drivers/iio/adc/Kconfig\n"
+ "> > @@ -10,6 +10,17 @@ config AD_SIGMA_DELTA\n"
+ "> > \302\240\tselect IIO_BUFFER\n"
+ "> > \302\240\tselect IIO_TRIGGERED_BUFFER\n"
+ "> > \302\240\n"
+ "> > +config AD7124\n"
+ "> > +\ttristate \"Analog Devices AD7124 and similar sigma-delta ADCs\n"
+ "> > driver\"\n"
+ "> > +\tdepends on SPI_MASTER\n"
+ "> > +\tselect AD_SIGMA_DELTA\n"
+ "> > +\thelp\n"
+ "> > +\t\302\240\302\240Say yes here to build support for Analog Devices AD7124-4\n"
+ "> > and AD7124-8\n"
+ "> > +\t\302\240\302\240SPI analog to digital converters (ADC).\n"
+ "> > +\n"
+ "> > +\t\302\240\302\240To compile this driver as a module, choose M here: the\n"
+ "> > module will be\n"
+ "> > +\t\302\240\302\240called ad7124.\n"
+ "> > +\n"
+ "> > \302\240config AD7266\n"
+ "> > \302\240\ttristate \"Analog Devices AD7265/AD7266 ADC driver\"\n"
+ "> > \302\240\tdepends on SPI_MASTER\n"
+ "> > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile\n"
+ "> > index a6e6a0b..76168b2 100644\n"
+ "> > --- a/drivers/iio/adc/Makefile\n"
+ "> > +++ b/drivers/iio/adc/Makefile\n"
+ "> > @@ -5,6 +5,7 @@\n"
+ "> > \302\240\n"
+ "> > \302\240# When adding new entries keep the list in alphabetical order\n"
+ "> > \302\240obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o\n"
+ "> > +obj-$(CONFIG_AD7124) += ad7124.o\n"
+ "> > \302\240obj-$(CONFIG_AD7266) += ad7266.o\n"
+ "> > \302\240obj-$(CONFIG_AD7291) += ad7291.o\n"
+ "> > \302\240obj-$(CONFIG_AD7298) += ad7298.o\n"
+ "> > diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c\n"
+ "> > new file mode 100644\n"
+ "> > index 0000000..0660135\n"
+ "> > --- /dev/null\n"
+ "> > +++ b/drivers/iio/adc/ad7124.c\n"
+ "> > @@ -0,0 +1,648 @@\n"
+ "> > +// SPDX-License-Identifier: GPL-2.0+\n"
+ "> > +/*\n"
+ "> > + * AD7124 SPI ADC driver\n"
+ "> > + *\n"
+ "> > + * Copyright 2018 Analog Devices Inc.\n"
+ "> > + */\n"
+ "> > +#include <linux/bitfield.h>\n"
+ "> > +#include <linux/clk.h>\n"
+ "> > +#include <linux/delay.h>\n"
+ "> > +#include <linux/device.h>\n"
+ "> > +#include <linux/err.h>\n"
+ "> > +#include <linux/kernel.h>\n"
+ "> > +#include <linux/module.h>\n"
+ "> > +#include <linux/regulator/consumer.h>\n"
+ "> > +#include <linux/spi/spi.h>\n"
+ "> > +\n"
+ "> > +#include <linux/iio/iio.h>\n"
+ "> > +#include <linux/iio/adc/ad_sigma_delta.h>\n"
+ "> > +#include <linux/iio/sysfs.h>\n"
+ "> > +\n"
+ "> > +/* AD7124 registers */\n"
+ "> > +#define AD7124_COMMS\t\t\t0x00\n"
+ "> > +#define AD7124_STATUS\t\t\t0x00\n"
+ "> > +#define AD7124_ADC_CONTROL\t\t0x01\n"
+ "> > +#define AD7124_DATA\t\t\t0x02\n"
+ "> > +#define AD7124_IO_CONTROL_1\t\t0x03\n"
+ "> > +#define AD7124_IO_CONTROL_2\t\t0x04\n"
+ "> > +#define AD7124_ID\t\t\t0x05\n"
+ "> > +#define AD7124_ERROR\t\t\t0x06\n"
+ "> > +#define AD7124_ERROR_EN\t\t0x07\n"
+ "> > +#define AD7124_MCLK_COUNT\t\t0x08\n"
+ "> > +#define AD7124_CHANNEL(x)\t\t(0x09 + (x))\n"
+ "> > +#define AD7124_CONFIG(x)\t\t(0x19 + (x))\n"
+ "> > +#define AD7124_FILTER(x)\t\t(0x21 + (x))\n"
+ "> > +#define AD7124_OFFSET(x)\t\t(0x29 + (x))\n"
+ "> > +#define AD7124_GAIN(x)\t\t\t(0x31 + (x))\n"
+ "> > +\n"
+ "> > +/* AD7124_STATUS */\n"
+ "> > +#define AD7124_STATUS_POR_FLAG_MSK\tBIT(4)\n"
+ "> > +\n"
+ "> > +/* AD7124_ADC_CONTROL */\n"
+ "> > +#define AD7124_ADC_CTRL_PWR_MSK\tGENMASK(7, 6)\n"
+ "> > +#define AD7124_ADC_CTRL_PWR(x)\t\tFIELD_PREP(AD7124_ADC_CT\n"
+ "> > RL_PWR_MSK, x)\n"
+ "> > +#define AD7124_ADC_CTRL_MODE_MSK\tGENMASK(5, 2)\n"
+ "> > +#define AD7124_ADC_CTRL_MODE(x)\tFIELD_PREP(AD7124_ADC_CTRL_MODE\n"
+ "> > _MSK, x)\n"
+ "> > +\n"
+ "> > +/* AD7124_CHANNEL_X */\n"
+ "> > +#define AD7124_CHANNEL_EN_MSK\t\tBIT(15)\n"
+ "> > +#define AD7124_CHANNEL_EN(x)\t\tFIELD_PREP(AD7124_CHANNEL_\n"
+ "> > EN_MSK, x)\n"
+ "> > +#define AD7124_CHANNEL_SETUP_MSK\tGENMASK(14, 12)\n"
+ "> > +#define AD7124_CHANNEL_SETUP(x)\tFIELD_PREP(AD7124_CHANNEL_SETUP\n"
+ "> > _MSK, x)\n"
+ "> > +#define AD7124_CHANNEL_AINP_MSK\tGENMASK(9, 5)\n"
+ "> > +#define AD7124_CHANNEL_AINP(x)\t\tFIELD_PREP(AD7124_CHANNE\n"
+ "> > L_AINP_MSK, x)\n"
+ "> > +#define AD7124_CHANNEL_AINM_MSK\tGENMASK(4, 0)\n"
+ "> > +#define AD7124_CHANNEL_AINM(x)\t\tFIELD_PREP(AD7124_CHANNE\n"
+ "> > L_AINM_MSK, x)\n"
+ "> > +\n"
+ "> > +/* AD7124_CONFIG_X */\n"
+ "> > +#define AD7124_CONFIG_BIPOLAR_MSK\tBIT(11)\n"
+ "> > +#define AD7124_CONFIG_BIPOLAR(x)\tFIELD_PREP(AD7124_CONFIG_BIPOL\n"
+ "> > AR_MSK, x)\n"
+ "> > +#define AD7124_CONFIG_REF_SEL_MSK\tGENMASK(4, 3)\n"
+ "> > +#define AD7124_CONFIG_REF_SEL(x)\tFIELD_PREP(AD7124_CONFIG_REF_S\n"
+ "> > EL_MSK, x)\n"
+ "> > +#define AD7124_CONFIG_PGA_MSK\t\tGENMASK(2, 0)\n"
+ "> > +#define AD7124_CONFIG_PGA(x)\t\tFIELD_PREP(AD7124_CONFIG_P\n"
+ "> > GA_MSK, x)\n"
+ "> > +\n"
+ "> > +/* AD7124_FILTER_X */\n"
+ "> > +#define AD7124_FILTER_FS_MSK\t\tGENMASK(10, 0)\n"
+ "> > +#define AD7124_FILTER_FS(x)\t\tFIELD_PREP(AD7124_FILTER_FS\n"
+ "> > _MSK, x)\n"
+ "> > +\n"
+ "> > +enum ad7124_ids {\n"
+ "> > +\tID_AD7124_4,\n"
+ "> > +\tID_AD7124_8,\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +enum ad7124_ref_sel {\n"
+ "> > +\tAD7124_REFIN1,\n"
+ "> > +\tAD7124_REFIN2,\n"
+ "> > +\tAD7124_INT_REF,\n"
+ "> > +\tAD7124_AVDD_REF,\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +enum ad7124_power_mode {\n"
+ "> > +\tAD7124_LOW_POWER,\n"
+ "> > +\tAD7124_MID_POWER,\n"
+ "> > +\tAD7124_FULL_POWER,\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +static const unsigned int ad7124_gain[8] = {\n"
+ "> > +\t1, 2, 4, 8, 16, 32, 64, 128\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +static const int ad7124_master_clk_freq_hz[3] = {\n"
+ "> > +\t[AD7124_LOW_POWER] = 76800,\n"
+ "> > +\t[AD7124_MID_POWER] = 153600,\n"
+ "> > +\t[AD7124_FULL_POWER] = 614400,\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +static const char * const ad7124_ref_names[] = {\n"
+ "> > +\t[AD7124_REFIN1] = \"refin1\",\n"
+ "> > +\t[AD7124_REFIN2] = \"refin2\",\n"
+ "> > +\t[AD7124_INT_REF] = \"int\",\n"
+ "> > +\t[AD7124_AVDD_REF] = \"avdd\",\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +struct ad7124_chip_info {\n"
+ "> > +\tunsigned int num_inputs;\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +struct ad7124_channel_config {\n"
+ "> > +\tenum ad7124_ref_sel refsel;\n"
+ "> > +\tbool bipolar;\n"
+ "> > +\tunsigned int ain;\n"
+ "> > +\tunsigned int vref_mv;\n"
+ "> > +\tunsigned int pga_bits;\n"
+ "> > +\tunsigned int odr;\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +struct ad7124_state {\n"
+ "> > +\tconst struct ad7124_chip_info *chip_info;\n"
+ "> > +\tstruct ad_sigma_delta sd;\n"
+ "> > +\tstruct ad7124_channel_config channel_config[4];\n"
+ "> > +\tstruct regulator *vref[4];\n"
+ "> > +\tstruct clk *mclk;\n"
+ "> > +\tunsigned int adc_control;\n"
+ "> > +\tunsigned int num_channels;\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +static const struct iio_chan_spec ad7124_channel_template = {\n"
+ "> > +\t.type = IIO_VOLTAGE,\n"
+ "> > +\t.indexed = 1,\n"
+ "> > +\t.differential = 1,\n"
+ "> > +\t.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |\n"
+ "> > +\t\tBIT(IIO_CHAN_INFO_SCALE) |\n"
+ "> > +\t\tBIT(IIO_CHAN_INFO_OFFSET) |\n"
+ "> > +\t\tBIT(IIO_CHAN_INFO_SAMP_FREQ),\n"
+ "> > +\t.scan_type = {\n"
+ "> > +\t\t.sign = 'u',\n"
+ "> > +\t\t.realbits = 24,\n"
+ "> > +\t\t.storagebits = 32,\n"
+ "> > +\t},\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +static struct ad7124_chip_info ad7124_chip_info_tbl[] = {\n"
+ "> > +\t[ID_AD7124_4] = {\n"
+ "> > +\t\t.num_inputs = 8,\n"
+ "> > +\t},\n"
+ "> > +\t[ID_AD7124_8] = {\n"
+ "> > +\t\t.num_inputs = 16,\n"
+ "> > +\t},\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +static int ad7124_find_closest_match(const int *array,\n"
+ "> > +\t\t\t\t\302\240\302\240\302\240\302\240\302\240unsigned int size, int val)\n"
+ "> > +{\n"
+ "> > +\tint i;\n"
+ "> > +\n"
+ "> > +\tfor (i = 0; i < size; i++) {\n"
+ "> > +\t\tif (val <= array[i])\n"
+ "> > +\t\t\treturn i;\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\treturn size - 1;\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_spi_write_mask(struct ad7124_state *st,\n"
+ "> > +\t\t\t\t\302\240unsigned int addr,\n"
+ "> > +\t\t\t\t\302\240unsigned long mask,\n"
+ "> > +\t\t\t\t\302\240unsigned int val,\n"
+ "> > +\t\t\t\t\302\240unsigned int bytes)\n"
+ "> > +{\n"
+ "> > +\tunsigned int readval;\n"
+ "> > +\tint ret;\n"
+ "> > +\n"
+ "> > +\tret = ad_sd_read_reg(&st->sd, addr, bytes, &readval);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\treadval &= ~mask;\n"
+ "> > +\treadval |= val;\n"
+ "> > +\n"
+ "> > +\treturn ad_sd_write_reg(&st->sd, addr, bytes, readval);\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_set_mode(struct ad_sigma_delta *sd,\n"
+ "> > +\t\t\t\302\240\302\240\302\240enum ad_sigma_delta_mode mode)\n"
+ "> > +{\n"
+ "> > +\tstruct ad7124_state *st = container_of(sd, struct\n"
+ "> > ad7124_state, sd);\n"
+ "> > +\n"
+ "> > +\tst->adc_control &= ~AD7124_ADC_CTRL_MODE_MSK;\n"
+ "> > +\tst->adc_control |= AD7124_ADC_CTRL_MODE(mode);\n"
+ "> > +\n"
+ "> > +\treturn ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st-\n"
+ "> > >adc_control);\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int\n"
+ "> > channel)\n"
+ "> > +{\n"
+ "> > +\tstruct ad7124_state *st = container_of(sd, struct\n"
+ "> > ad7124_state, sd);\n"
+ "> > +\tunsigned int val;\n"
+ "> > +\n"
+ "> > +\tval = st->channel_config[channel].ain | AD7124_CHANNEL_EN(1) |\n"
+ "> > +\t\302\240\302\240\302\240\302\240\302\240\302\240AD7124_CHANNEL_SETUP(channel);\n"
+ "> > +\n"
+ "> > +\treturn ad_sd_write_reg(&st->sd, AD7124_CHANNEL(channel), 2,\n"
+ "> > val);\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static const struct ad_sigma_delta_info ad7124_sigma_delta_info = {\n"
+ "> > +\t.set_channel = ad7124_set_channel,\n"
+ "> > +\t.set_mode = ad7124_set_mode,\n"
+ "> > +\t.has_registers = true,\n"
+ "> > +\t.addr_shift = 0,\n"
+ "> > +\t.read_mask = BIT(6),\n"
+ "> > +\t.data_reg = AD7124_DATA,\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +static int ad7124_set_channel_odr(struct ad7124_state *st,\n"
+ "> > +\t\t\t\t\302\240\302\240unsigned int channel,\n"
+ "> > +\t\t\t\t\302\240\302\240unsigned int odr)\n"
+ "> > +{\n"
+ "> > +\tunsigned int fclk, odr_sel_bits;\n"
+ "> > +\tint ret;\n"
+ "> > +\n"
+ "> > +\tfclk = clk_get_rate(st->mclk);\n"
+ "> > +\t/*\n"
+ "> > +\t\302\240* FS[10:0] = fCLK / (fADC x 32) where:\n"
+ "> > +\t\302\240* fADC is the output data rate\n"
+ "> > +\t\302\240* fCLK is the master clock frequency\n"
+ "> > +\t\302\240* FS[10:0] are the bits in the filter register\n"
+ "> > +\t\302\240* FS[10:0] can have a value from 1 to 2047\n"
+ "> > +\t\302\240*/\n"
+ "> > +\todr_sel_bits = DIV_ROUND_CLOSEST(fclk, odr * 32);\n"
+ "> > +\tif (odr_sel_bits < 1)\n"
+ "> > +\t\todr_sel_bits = 1;\n"
+ "> > +\telse if (odr_sel_bits > 2047)\n"
+ "> > +\t\todr_sel_bits = 2047;\n"
+ "> > +\n"
+ "> > +\tret = ad7124_spi_write_mask(st, AD7124_FILTER(channel),\n"
+ "> > +\t\t\t\t\302\240\302\240\302\240\302\240AD7124_FILTER_FS_MSK,\n"
+ "> > +\t\t\t\t\302\240\302\240\302\240\302\240AD7124_FILTER_FS(odr_sel_bits),\n"
+ "> > 3);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\treturn ret;\n"
+ "> > +\t/* fADC = fCLK / (FS[10:0] x 32) */\n"
+ "> > +\tst->channel_config[channel].odr =\n"
+ "> > +\t\tDIV_ROUND_CLOSEST(fclk, odr_sel_bits * 32);\n"
+ "> > +\n"
+ "> > +\treturn 0;\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_read_raw(struct iio_dev *indio_dev,\n"
+ "> > +\t\t\t\302\240\302\240\302\240struct iio_chan_spec const *chan,\n"
+ "> > +\t\t\t\302\240\302\240\302\240int *val, int *val2, long info)\n"
+ "> > +{\n"
+ "> > +\tstruct ad7124_state *st = iio_priv(indio_dev);\n"
+ "> > +\tint idx, ret;\n"
+ "> > +\n"
+ "> > +\tswitch (info) {\n"
+ "> > +\tcase IIO_CHAN_INFO_RAW:\n"
+ "> > +\t\tret = ad_sigma_delta_single_conversion(indio_dev,\n"
+ "> > chan, val);\n"
+ "> > +\t\tif (ret < 0)\n"
+ "> > +\t\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\t\t/* After the conversion is performed, disable the\n"
+ "> > channel */\n"
+ "> > +\t\tret = ad_sd_write_reg(&st->sd,\n"
+ "> > +\t\t\t\t\302\240\302\240\302\240\302\240\302\240\302\240AD7124_CHANNEL(chan->address),\n"
+ "> > 2,\n"
+ "> > +\t\t\t\t\302\240\302\240\302\240\302\240\302\240\302\240st->channel_config[chan-\n"
+ "> > >address].ain |\n"
+ "> > +\t\t\t\t\302\240\302\240\302\240\302\240\302\240\302\240AD7124_CHANNEL_EN(0));\n"
+ "> > +\t\tif (ret < 0)\n"
+ "> > +\t\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\t\treturn IIO_VAL_INT;\n"
+ "> > +\tcase IIO_CHAN_INFO_SCALE:\n"
+ "> > +\t\tidx = st->channel_config[chan->address].pga_bits;\n"
+ "> > +\t\t*val = st->channel_config[chan->address].vref_mv /\n"
+ "> > +\t\t\tad7124_gain[idx];\n"
+ "> > +\t\tif (st->channel_config[chan->address].bipolar)\n"
+ "> > +\t\t\t*val2 = chan->scan_type.realbits - 1;\n"
+ "> > +\t\telse\n"
+ "> > +\t\t\t*val2 = chan->scan_type.realbits;\n"
+ "> > +\n"
+ "> > +\t\treturn IIO_VAL_FRACTIONAL_LOG2;\n"
+ "> > +\tcase IIO_CHAN_INFO_OFFSET:\n"
+ "> > +\t\tif (st->channel_config[chan->address].bipolar) {\n"
+ "> > +\t\t\t/* Code = 2^(n \342\210\222 1) \303\227 ((Ain \303\227 Gain / Vref) +\n"
+ "> > 1) */\n"
+ "> > +\t\t\tidx = st->channel_config[chan-\n"
+ "> > >address].pga_bits;\n"
+ "> > +\t\t\t*val = -(st->channel_config[chan-\n"
+ "> > >address].vref_mv /\n"
+ "> > +\t\t\t\t\302\240ad7124_gain[idx]);\n"
+ "> > +\t\t} else {\n"
+ "> > +\t\t\t*val = 0;\n"
+ "> > +\t\t}\n"
+ "> > +\n"
+ "> > +\t\treturn IIO_VAL_INT;\n"
+ "> > +\tcase IIO_CHAN_INFO_SAMP_FREQ:\n"
+ "> > +\t\t*val = st->channel_config[chan->address].odr;\n"
+ "> > +\n"
+ "> > +\t\treturn IIO_VAL_INT;\n"
+ "> > +\tdefault:\n"
+ "> > +\t\treturn -EINVAL;\n"
+ "> > +\t}\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_write_raw(struct iio_dev *indio_dev,\n"
+ "> > +\t\t\t\302\240\302\240\302\240\302\240struct iio_chan_spec const *chan,\n"
+ "> > +\t\t\t\302\240\302\240\302\240\302\240int val, int val2, long info)\n"
+ "> > +{\n"
+ "> > +\tstruct ad7124_state *st = iio_priv(indio_dev);\n"
+ "> > +\n"
+ "> > +\tswitch (info) {\n"
+ "> > +\tcase IIO_CHAN_INFO_SAMP_FREQ:\n"
+ "> > +\t\tif (val2 != 0)\n"
+ "> > +\t\t\treturn -EINVAL;\n"
+ "> > +\n"
+ "> > +\t\treturn ad7124_set_channel_odr(st, chan->address, val);\n"
+ "> > +\tdefault:\n"
+ "> > +\t\treturn -EINVAL;\n"
+ "> > +\t}\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static const struct iio_info ad7124_info = {\n"
+ "> > +\t.read_raw = ad7124_read_raw,\n"
+ "> > +\t.write_raw = ad7124_write_raw,\n"
+ "> > +};\n"
+ "> > +\n"
+ "> > +static int ad7124_soft_reset(struct ad7124_state *st)\n"
+ "> > +{\n"
+ "> > +\tunsigned int readval, timeout;\n"
+ "> > +\tint ret;\n"
+ "> > +\n"
+ "> > +\tret = ad_sd_reset(&st->sd, 64);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\ttimeout = 100;\n"
+ "> > +\tdo {\n"
+ "> > +\t\tret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1,\n"
+ "> > &readval);\n"
+ "> > +\t\tif (ret < 0)\n"
+ "> > +\t\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\t\tif (!(readval & AD7124_STATUS_POR_FLAG_MSK))\n"
+ "> > +\t\t\treturn 0;\n"
+ "> > +\n"
+ "> > +\t\t/* The AD7124 requires typically 2ms to power up and\n"
+ "> > settle */\n"
+ "> > +\t\tusleep_range(100, 2000);\n"
+ "> > +\t} while (--timeout);\n"
+ "> > +\n"
+ "> > +\tdev_err(&st->sd.spi->dev, \"Soft reset failed\\n\");\n"
+ "> > +\n"
+ "> > +\treturn -EIO;\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_init_channel_vref(struct ad7124_state *st,\n"
+ "> > +\t\t\t\t\302\240\302\240\302\240\302\240unsigned int channel_number)\n"
+ "> > +{\n"
+ "> > +\tunsigned int refsel = st-\n"
+ "> > >channel_config[channel_number].refsel;\n"
+ "> > +\n"
+ "> > +\tswitch (refsel) {\n"
+ "> > +\tcase AD7124_REFIN1:\n"
+ "> > +\tcase AD7124_REFIN2:\n"
+ "> > +\tcase AD7124_AVDD_REF:\n"
+ "> > +\t\tif (IS_ERR(st->vref[refsel])) {\n"
+ "> > +\t\t\tdev_err(&st->sd.spi->dev,\n"
+ "> > +\t\t\t\t\"Error, trying to use external voltage\n"
+ "> > reference without a %s regulator.\",\n"
+ "> > +\t\t\t\tad7124_ref_names[refsel]);\n"
+ "> > +\t\t\t\treturn PTR_ERR(st->vref[refsel]);\n"
+ "> > +\t\t}\n"
+ "> > +\t\tst->channel_config[channel_number].vref_mv =\n"
+ "> > +\t\t\tregulator_get_voltage(st->vref[refsel]);\n"
+ "> > +\t\t/* Conversion from uV to mV */\n"
+ "> > +\t\tst->channel_config[channel_number].vref_mv /= 1000;\n"
+ "> > +\t\tbreak;\n"
+ "> > +\tcase AD7124_INT_REF:\n"
+ "> > +\t\tst->channel_config[channel_number].vref_mv = 2500;\n"
+ "> > +\t\tbreak;\n"
+ "> > +\tdefault:\n"
+ "> > +\t\tdev_err(&st->sd.spi->dev, \"Invalid reference %d\\n\",\n"
+ "> > refsel);\n"
+ "> > +\t\treturn -EINVAL;\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\treturn 0;\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,\n"
+ "> > +\t\t\t\t\t\302\240\302\240struct device_node *np)\n"
+ "> > +{\n"
+ "> > +\tstruct ad7124_state *st = iio_priv(indio_dev);\n"
+ "> > +\tstruct device_node *child;\n"
+ "> > +\tstruct iio_chan_spec *chan;\n"
+ "> > +\tunsigned int ain[2], channel = 0, tmp;\n"
+ "> > +\tint ret, res;\n"
+ "> > +\n"
+ "> > +\tst->num_channels = of_get_available_child_count(np);\n"
+ "> > +\tif (!st->num_channels) {\n"
+ "> > +\t\tdev_err(indio_dev->dev.parent, \"no channel\n"
+ "> > children\\n\");\n"
+ "> > +\t\treturn -ENODEV;\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\tchan = devm_kcalloc(indio_dev->dev.parent, st->num_channels,\n"
+ "> > +\t\t\t\302\240\302\240\302\240\302\240sizeof(*chan), GFP_KERNEL);\n"
+ "> > +\tif (!chan)\n"
+ "> > +\t\treturn -ENOMEM;\n"
+ "> > +\n"
+ "> > +\tindio_dev->channels = chan;\n"
+ "> > +\tindio_dev->num_channels = st->num_channels;\n"
+ "> > +\n"
+ "> > +\tfor_each_available_child_of_node(np, child) {\n"
+ "> > +\t\tret = of_property_read_u32(child, \"reg\", &channel);\n"
+ "> > +\t\tif (ret)\n"
+ "> > +\t\t\tgoto err;\n"
+ "> > +\n"
+ "> > +\t\tret = of_property_read_u32_array(child, \"adi,diff-\n"
+ "> > channels\",\n"
+ "> > +\t\t\t\t\t\t\302\240ain, 2);\n"
+ "> This actually feels like something we could standardize as well as\n"
+ "> bipolar.\n"
+ "> In the oldest drivers we actually let userspace configure all of this,\n"
+ "> but\n"
+ "> I can understand that only some combinations make sense on a given board\n"
+ "> so it arguably makes sense to only enable those, particularly when there\n"
+ "> is a reference select that has to be paired with channel choice.\n"
+ "> \n"
+ "> > \n"
+ "> > +\t\tif (ret)\n"
+ "> > +\t\t\tgoto err;\n"
+ "> > +\n"
+ "> > +\t\tif (ain[0] >= st->chip_info->num_inputs ||\n"
+ "> > +\t\t\302\240\302\240\302\240\302\240ain[1] >= st->chip_info->num_inputs) {\n"
+ "> > +\t\t\tdev_err(indio_dev->dev.parent,\n"
+ "> > +\t\t\t\t\"Input pin number out of range.\\n\");\n"
+ "> > +\t\t\tret = -EINVAL;\n"
+ "> > +\t\t\tgoto err;\n"
+ "> > +\t\t}\n"
+ "> > +\t\tst->channel_config[channel].ain =\n"
+ "> > AD7124_CHANNEL_AINP(ain[0]) |\n"
+ "> > +\t\t\t\t\t\t\302\240\302\240AD7124_CHANNEL_AINM(\n"
+ "> > ain[1]);\n"
+ "> > +\t\tst->channel_config[channel].bipolar =\n"
+ "> > +\t\t\tof_property_read_bool(child, \"adi,bipolar\");\n"
+ "> > +\n"
+ "> > +\t\tret = of_property_read_u32(child, \"adi,reference-\n"
+ "> > select\", &tmp);\n"
+ "> > +\t\tif (ret)\n"
+ "> > +\t\t\tst->channel_config[channel].refsel =\n"
+ "> > AD7124_INT_REF;\n"
+ "> > +\t\telse\n"
+ "> > +\t\t\tst->channel_config[channel].refsel = tmp;\n"
+ "> > +\n"
+ "> > +\t\tret = of_property_read_u32(child, \"adi,gain\", &tmp);\n"
+ "> > +\t\tif (ret) {\n"
+ "> > +\t\t\tst->channel_config[channel].pga_bits = 0;\n"
+ "> > +\t\t} else {\n"
+ "> > +\t\t\tres = ad7124_find_closest_match(ad7124_gain,\n"
+ "> > +\t\t\t\t\t\tARRAY_SIZE(ad7124_gain\n"
+ "> > ), tmp);\n"
+ "> > +\t\t\tst->channel_config[channel].pga_bits = res;\n"
+ "> Hmm. The old question of what to put in DT as it reflects wiring and\n"
+ "> what to leave to userspace. Gain is tricky as only some values make sense\n"
+ "> for a given system, but there can be more than one that does...\n"
+ "> This is probably reasonable as it can be considered as setting the\n"
+ "> default\n"
+ "> that makes sense for what is wired.\302\240\302\240Potentially user space could\n"
+ "> override\n"
+ "> it later if it wanted to.\n"
+ "> \n"
+ "> > \n"
+ "> > +\t\t}\n"
+ "> > +\n"
+ "> > +\t\tret = of_property_read_u32(child, \"adi,odr-hz\", &tmp);\n"
+ "> Why is this in DT. This one feels like a userspace choice to me. It's\n"
+ "> only tangentially connected to how things are connected on the board.\n"
+ "> You also support control from userspace.\302\240\302\240I would pick a sensible\n"
+ "> general default and then drop this from the DT binding. It's optional\n"
+ "> anyway.\n"
+ "> \n"
+ "> > \n"
+ "> > +\t\tif (ret)\n"
+ "> > +\t\t\t/*\n"
+ "> > +\t\t\t\302\240* 9 SPS is the minimum output data rate\n"
+ "> > supported\n"
+ "> > +\t\t\t\302\240* regardless of the selected power mode.\n"
+ "> > +\t\t\t\302\240*/\n"
+ "> > +\t\t\tst->channel_config[channel].odr = 9;\n"
+ "> > +\t\telse\n"
+ "> > +\t\t\tst->channel_config[channel].odr = tmp;\n"
+ "> > +\n"
+ "> > +\t\t*chan = ad7124_channel_template;\n"
+ "> > +\t\tchan->address = channel;\n"
+ "> > +\t\tchan->scan_index = channel;\n"
+ "> > +\t\tchan->channel = ain[0];\n"
+ "> > +\t\tchan->channel2 = ain[1];\n"
+ "> > +\n"
+ "> > +\t\tchan++;\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\treturn 0;\n"
+ "> > +err:\n"
+ "> > +\tof_node_put(child);\n"
+ "> > +\n"
+ "> > +\treturn ret;\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_setup(struct ad7124_state *st)\n"
+ "> > +{\n"
+ "> > +\tunsigned int val, fclk, power_mode;\n"
+ "> > +\tint i, ret;\n"
+ "> > +\n"
+ "> > +\tfclk = clk_get_rate(st->mclk);\n"
+ "> > +\tif (!fclk)\n"
+ "> > +\t\treturn -EINVAL;\n"
+ "> > +\n"
+ "> > +\t/* The power mode changes the master clock frequency */\n"
+ "> > +\tpower_mode =\n"
+ "> > ad7124_find_closest_match(ad7124_master_clk_freq_hz,\n"
+ "> > +\t\t\t\t\tARRAY_SIZE(ad7124_master_clk_f\n"
+ "> > req_hz),\n"
+ "> > +\t\t\t\t\tfclk);\n"
+ "> > +\tif (fclk != ad7124_master_clk_freq_hz[power_mode]) {\n"
+ "> > +\t\tret = clk_set_rate(st->mclk, fclk);\n"
+ "> > +\t\tif (ret)\n"
+ "> > +\t\t\treturn ret;\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\t/* Set the power mode */\n"
+ "> > +\tst->adc_control &= ~AD7124_ADC_CTRL_PWR_MSK;\n"
+ "> > +\tst->adc_control |= AD7124_ADC_CTRL_PWR(power_mode);\n"
+ "> > +\tret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st-\n"
+ "> > >adc_control);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\tfor (i = 0; i < st->num_channels; i++) {\n"
+ "> > +\t\tval = st->channel_config[i].ain |\n"
+ "> > AD7124_CHANNEL_SETUP(i);\n"
+ "> > +\t\tret = ad_sd_write_reg(&st->sd, AD7124_CHANNEL(i), 2,\n"
+ "> > val);\n"
+ "> > +\t\tif (ret < 0)\n"
+ "> > +\t\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\t\tret = ad7124_init_channel_vref(st, i);\n"
+ "> > +\t\tif (ret < 0)\n"
+ "> > +\t\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\t\tval = AD7124_CONFIG_BIPOLAR(st-\n"
+ "> > >channel_config[i].bipolar) |\n"
+ "> > +\t\t\302\240\302\240\302\240\302\240\302\240\302\240AD7124_CONFIG_REF_SEL(st-\n"
+ "> > >channel_config[i].refsel) |\n"
+ "> > +\t\t\302\240\302\240\302\240\302\240\302\240\302\240AD7124_CONFIG_PGA(st-\n"
+ "> > >channel_config[i].pga_bits);\n"
+ "> > +\t\tret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(i), 2,\n"
+ "> > val);\n"
+ "> > +\t\tif (ret < 0)\n"
+ "> > +\t\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\t\tret = ad7124_set_channel_odr(st, i, st-\n"
+ "> > >channel_config[i].odr);\n"
+ "> > +\t\tif (ret < 0)\n"
+ "> > +\t\t\treturn ret;\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\treturn ret;\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_probe(struct spi_device *spi)\n"
+ "> > +{\n"
+ "> > +\tconst struct spi_device_id *id;\n"
+ "> > +\tstruct ad7124_state *st;\n"
+ "> > +\tstruct iio_dev *indio_dev;\n"
+ "> > +\tint i, ret;\n"
+ "> > +\n"
+ "> > +\tindio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));\n"
+ "> > +\tif (!indio_dev)\n"
+ "> > +\t\treturn -ENOMEM;\n"
+ "> > +\n"
+ "> > +\tst = iio_priv(indio_dev);\n"
+ "> > +\n"
+ "> > +\tid = spi_get_device_id(spi);\n"
+ "> > +\tst->chip_info = &ad7124_chip_info_tbl[id->driver_data];\n"
+ "> > +\n"
+ "> > +\tad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info);\n"
+ "> > +\n"
+ "> > +\tspi_set_drvdata(spi, indio_dev);\n"
+ "> > +\n"
+ "> > +\tindio_dev->dev.parent = &spi->dev;\n"
+ "> > +\tindio_dev->name = spi_get_device_id(spi)->name;\n"
+ "> > +\tindio_dev->modes = INDIO_DIRECT_MODE;\n"
+ "> > +\tindio_dev->info = &ad7124_info;\n"
+ "> > +\n"
+ "> > +\tret = ad7124_of_parse_channel_config(indio_dev, spi-\n"
+ "> > >dev.of_node);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\treturn ret;\n"
+ "> > +\n"
+ "> > +\tfor (i = 0; i < ARRAY_SIZE(st->vref); i++) {\n"
+ "> > +\t\tif (i != AD7124_INT_REF) {\n"
+ "> > +\t\t\tst->vref[i] =\n"
+ "> > devm_regulator_get_optional(&spi->dev,\n"
+ "> > +\t\t\t\t\t\t\tad7124_ref_nam\n"
+ "> > es[i]);\n"
+ "> > +\t\t\tif (PTR_ERR(st->vref[i]) == -ENODEV)\n"
+ "> > +\t\t\t\tcontinue;\n"
+ "> > +\t\t\telse if (IS_ERR(st->vref[i]))\n"
+ "> > +\t\t\t\treturn PTR_ERR(st->vref[i]);\n"
+ "> > +\n"
+ "> > +\t\t\tret = regulator_enable(st->vref[i]);\n"
+ "> > +\t\t\tif (ret)\n"
+ "> > +\t\t\t\treturn ret;\n"
+ "> > +\t\t}\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\tst->mclk = devm_clk_get(&spi->dev, \"mclk\");\n"
+ "> > +\tif (IS_ERR(st->mclk)) {\n"
+ "> > +\t\tret = PTR_ERR(st->mclk);\n"
+ "> > +\t\tgoto error_regulator_disable;\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\tret = clk_prepare_enable(st->mclk);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\tgoto error_regulator_disable;\n"
+ "> > +\n"
+ "> > +\tret = ad7124_soft_reset(st);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\tgoto error_clk_disable_unprepare;\n"
+ "> > +\n"
+ "> > +\tret = ad7124_setup(st);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\tgoto error_clk_disable_unprepare;\n"
+ "> > +\n"
+ "> > +\tret = ad_sd_setup_buffer_and_trigger(indio_dev);\n"
+ "> > +\tif (ret < 0)\n"
+ "> > +\t\tgoto error_clk_disable_unprepare;\n"
+ "> > +\n"
+ "> > +\tret = iio_device_register(indio_dev);\n"
+ "> > +\tif (ret < 0) {\n"
+ "> > +\t\tdev_err(&spi->dev, \"Failed to register iio device\\n\");\n"
+ "> > +\t\tgoto error_remove_trigger;\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\treturn 0;\n"
+ "> > +\n"
+ "> > +error_remove_trigger:\n"
+ "> > +\tad_sd_cleanup_buffer_and_trigger(indio_dev);\n"
+ "> > +error_clk_disable_unprepare:\n"
+ "> > +\tclk_disable_unprepare(st->mclk);\n"
+ "> > +error_regulator_disable:\n"
+ "> > +\tfor (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) {\n"
+ "> > +\t\tif (!IS_ERR_OR_NULL(st->vref[i]))\n"
+ "> > +\t\t\tregulator_disable(st->vref[i]);\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\treturn ret;\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static int ad7124_remove(struct spi_device *spi)\n"
+ "> > +{\n"
+ "> > +\tstruct iio_dev *indio_dev = spi_get_drvdata(spi);\n"
+ "> > +\tstruct ad7124_state *st = iio_priv(indio_dev);\n"
+ "> > +\tint i;\n"
+ "> > +\n"
+ "> > +\tiio_device_unregister(indio_dev);\n"
+ "> > +\tclk_disable_unprepare(st->mclk);\n"
+ "> > +\tad_sd_cleanup_buffer_and_trigger(indio_dev);\n"
+ "> The ordering here should match that in the error path above.\n"
+ "> (so the two things here should be reversed).\n"
+ "> It's in the category of making things obviously safe rather than an\n"
+ "> actual issue.\n"
+ "> I like to be able to check the ordering only once rather than twice\n"
+ "> when reviewing so will always confirm they match.\n"
+ "> \n"
+ "> > \n"
+ "> > +\n"
+ "> > +\tfor (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) {\n"
+ "> > +\t\tif (!IS_ERR_OR_NULL(st->vref[i]))\n"
+ "> > +\t\t\tregulator_disable(st->vref[i]);\n"
+ "> > +\t}\n"
+ "> > +\n"
+ "> > +\treturn 0;\n"
+ "> > +}\n"
+ "> > +\n"
+ "> > +static const struct spi_device_id ad7124_id_table[] = {\n"
+ "> > +\t{ \"ad7124-4\", ID_AD7124_4 },\n"
+ "> > +\t{ \"ad7124-8\", ID_AD7124_8 },\n"
+ "> > +\t{}\n"
+ "> > +};\n"
+ "> > +MODULE_DEVICE_TABLE(spi, ad7124_id_table);\n"
+ "> > +\n"
+ "> > +static const struct of_device_id ad7124_of_match[] = {\n"
+ "> > +\t{ .compatible = \"adi,ad7124-4\" },\n"
+ "> > +\t{ .compatible = \"adi,ad7124-8\" },\n"
+ "> > +\t{ },\n"
+ "> > +};\n"
+ "> > +MODULE_DEVICE_TABLE(of, ad7124_of_match);\n"
+ "> > +\n"
+ "> > +static struct spi_driver ad71124_driver = {\n"
+ "> > +\t.driver = {\n"
+ "> > +\t\t.name = \"ad7124\",\n"
+ "> > +\t\t.of_match_table = ad7124_of_match,\n"
+ "> > +\t},\n"
+ "> > +\t.probe = ad7124_probe,\n"
+ "> > +\t.remove\t= ad7124_remove,\n"
+ "> > +\t.id_table = ad7124_id_table,\n"
+ "> > +};\n"
+ "> > +module_spi_driver(ad71124_driver);\n"
+ "> > +\n"
+ "> > +MODULE_AUTHOR(\"Stefan Popa <stefan.popa@analog.com>\");\n"
+ "> > +MODULE_DESCRIPTION(\"Analog Devices AD7124 SPI driver\");\n"
+ "> > +MODULE_LICENSE(\"GPL\");\n"
+ >
 
-e06a8a28b99ad60797454ff47de4aa7430450614fb1fd30876a70c59a62f08b0
+1bb1ae41f7659d5d3c19a90b240171e7b283545067f0a8af9a4961a232698c77

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.