diff for duplicates of <569912F2.9020906@roeck-us.net> diff --git a/a/1.txt b/N1/1.txt index 37af6a3..22e4a69 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,174 +1,292 @@ -T24gMDEvMTUvMjAxNiAwMTo1NCBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4gVGhpcyBhZGRz -IHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwICBJMkMgU3lzdGVtIE1v -bml0b3IuCj4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLCBj -dXJyZW50IGFuZCB0ZW1wZXJhdHVyZQo+IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVyIGN1cnJlbnRs -eSBvbmx5IHN1cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4gYnkgbWVhc3VyaW5nIHR3byBk -aWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMsIGluCj4gYWRkaXRp -b24gdG8gdGhlIFZjYyBzdXBwbHkgdm9sdGFnZSBhbmQgaW50ZXJuYWwgdGVtcGVyYXR1cmUuCj4K -PiBUaGlzIGlzIHN1ZmZpY2llbnQgdG8gc3VwcG9ydCB0aGUgVG9waWMgTWlhbWkgU09NIHdoaWNo -IHVzZXMgdGhpcyBjaGlwCj4gdG8gbW9uaXRvciB0aGUgY3VycmVudHMgZmxvd2luZyBpbnRvIHRo -ZSBGUEdBIGFuZCB0aGUgQ1BVIHBhcnRzLgo+Cj4gU2lnbmVkLW9mZi1ieTogTWlrZSBMb29pam1h -bnMgPG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgoKQXBwbGllZCB0byAtbmV4dC4KClRoYW5rcywK -R3VlbnRlcgoKPiAtLS0KPiB2NDogRml4IGNoZWNrcGF0Y2ggd2FybmluZ3MKPiAgICAgIGx0YzI5 -OTBfZ2V0X3ZhbHVlIGNhbiByZXR1cm4gZXJyb3IgY29kZQo+IHYzOiBSZW1vdmUgdW51c2VkIGlu -Y2x1ZGVzLgo+ICAgICAgUmVtb3ZlIChtb3N0KSB1bnVzZWQgcmVnaXN0ZXIgZGVmaW5lcy4KPiAg -ICAgIEFsc28gY2hlY2sgb24gU01CVVMgV09SRCBjYXBhYmlsaXR5Lgo+ICAgICAgVXNlIHJlZ2lz -dGVyIGRlZmluZXMgYXMgdmFsdWUgaW5kaWNlcy4KPiAgICAgIEFsaWdubWVudCBmaXh1cHMgd2l0 -aCAiKCIuCj4gdjI6IFByb2Nlc3NlZCBhbGwgcmV2aWV3IGNvbW1lbnRzLgo+ICAgICAgIFB1dCBj -aGlwIGludG8gY29udGludW91cyBtZWFzdXJlbWVudCBtb2RlLgo+ICAgICAgIEFkZGVkIGR1Y3Vt -ZW50YXRpb24uCj4gICAgICAgVXNlIHN0YW5kYXJkIGh3bW9uIGludGVyZmFjZXMgYW5kIG1hY3Jv -cy4KPiAgIERvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5MCB8ICA0NCArKysrKysrKysrKysKPiAg -IGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgICAgICB8ICAxNCArKysrCj4gICBkcml2ZXJzL2h3bW9u -L01ha2VmaWxlICAgICAgfCAgIDEgKwo+ICAgZHJpdmVycy9od21vbi9sdGMyOTkwLmMgICAgIHwg -MTYxICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gICA0IGZp -bGVzIGNoYW5nZWQsIDIyMCBpbnNlcnRpb25zKCspCj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgRG9j -dW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9o -d21vbi9sdGMyOTkwLmMKPgo+IGRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5 -OTAgYi9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+ -IGluZGV4IDAwMDAwMDAuLjgzOGI3NGUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvRG9jdW1lbnRh -dGlvbi9od21vbi9sdGMyOTkwCj4gQEAgLTAsMCArMSw0NCBAQAo+ICtLZXJuZWwgZHJpdmVyIGx0 -YzI5OTAKPiArPT09PT09PT09PT09PT09PT09PT09Cj4gKwo+ICtTdXBwb3J0ZWQgY2hpcHM6Cj4g -KyAgKiBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCj4gKyAgICBQcmVmaXg6ICdsdGMyOTkwJwo+ -ICsgICAgQWRkcmVzc2VzIHNjYW5uZWQ6IC0KPiArICAgIERhdGFzaGVldDogaHR0cDovL3d3dy5s -aW5lYXIuY29tL3Byb2R1Y3QvbHRjMjk5MAo+ICsKPiArQXV0aG9yOiBNaWtlIExvb2lqbWFucyA8 -bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4gKwo+ICsKPiArRGVzY3JpcHRpb24KPiArLS0tLS0t -LS0tLS0KPiArCj4gK0xUQzI5OTAgaXMgYSBRdWFkIEkyQyBWb2x0YWdlLCBDdXJyZW50IGFuZCBU -ZW1wZXJhdHVyZSBNb25pdG9yLgo+ICtUaGUgY2hpcCdzIGlucHV0cyBjYW4gbWVhc3VyZSA0IHZv -bHRhZ2VzLCBvciB0d28gaW5wdXRzIHRvZ2V0aGVyICgxKzIgYW5kIDMrNCkKPiArY2FuIGJlIGNv -bWJpbmVkIHRvIG1lYXN1cmUgYSBkaWZmZXJlbnRpYWwgdm9sdGFnZSwgd2hpY2ggaXMgdHlwaWNh -bGx5IHVzZWQgdG8KPiArbWVhc3VyZSBjdXJyZW50IHRocm91Z2ggYSBzZXJpZXMgcmVzaXN0b3Is -IG9yIGEgdGVtcGVyYXR1cmUuCj4gKwo+ICtUaGlzIGRyaXZlciBjdXJyZW50bHkgdXNlcyB0aGUg -MnggZGlmZmVyZW50aWFsIG1vZGUgb25seS4gSW4gb3JkZXIgdG8gc3VwcG9ydAo+ICtvdGhlciBt -b2RlcywgdGhlIGRyaXZlciB3aWxsIG5lZWQgdG8gYmUgZXhwYW5kZWQuCj4gKwo+ICsKPiArVXNh -Z2UgTm90ZXMKPiArLS0tLS0tLS0tLS0KPiArCj4gK1RoaXMgZHJpdmVyIGRvZXMgbm90IHByb2Jl -IGZvciBQTUJ1cyBkZXZpY2VzLiBZb3Ugd2lsbCBoYXZlIHRvIGluc3RhbnRpYXRlCj4gK2Rldmlj -ZXMgZXhwbGljaXRseS4KPiArCj4gKwo+ICtTeXNmcyBhdHRyaWJ1dGVzCj4gKy0tLS0tLS0tLS0t -LS0tLS0KPiArCj4gK1RoZSAiY3VycipfaW5wdXQiIG1lYXN1cmVtZW50cyBhY3R1YWxseSByZXBv -cnQgdGhlIHZvbHRhZ2UgZHJvcCBhY3Jvc3MgdGhlCj4gK2lucHV0IHBpbnMgaW4gbWljcm92b2x0 -cy4gVGhpcyBpcyBlcXVpdmFsZW50IHRvIHRoZSBjdXJyZW50IHRocm91Z2ggYSAxbU9obQo+ICtz -ZW5zZSByZXNpc3Rvci4gRGl2aWRlIHRoZSByZXBvcnRlZCB2YWx1ZSBieSB0aGUgYWN0dWFsIHNl -bnNlIHJlc2lzdG9yIHZhbHVlCj4gK2luIG1PaG0gdG8gZ2V0IHRoZSBhY3R1YWwgdmFsdWUuCj4g -Kwo+ICtpbjBfaW5wdXQgICAgIFZvbHRhZ2UgYXQgVmNjIHBpbiBpbiBtaWxsaXZvbHQgKHJhbmdl -IDIuNVYgdG8gNVYpCj4gK3RlbXAxX2lucHV0ICAgSW50ZXJuYWwgY2hpcCB0ZW1wZXJhdHVyZSBp -biBtaWxsaWRlZ3JlZXMgQ2VsY2l1cwo+ICtjdXJyMV9pbnB1dCAgIEN1cnJlbnQgaW4gbUEgYWNy -b3NzIHYxLXYyIGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3IuCj4gK2N1cnIyX2lucHV0 -ICAgQ3VycmVudCBpbiBtQSBhY3Jvc3MgdjMtdjQgYXNzdW1pbmcgYSAxbU9obSBzZW5zZSByZXNp -c3Rvci4KPiArCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMv -aHdtb24vS2NvbmZpZwo+IGluZGV4IDgwYTczYmYuLjhhMzFkNjQgMTAwNjQ0Cj4gLS0tIGEvZHJp -dmVycy9od21vbi9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4gQEAgLTY4 -NSw2ICs2ODUsMjAgQEAgY29uZmlnIFNFTlNPUlNfTFRDMjk0NQo+ICAgCSAgVGhpcyBkcml2ZXIg -Y2FuIGFsc28gYmUgYnVpbHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwKPiAg -IAkgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Cj4gK2NvbmZpZyBTRU5TT1JTX0xUQzI5OTAKPiArCXRy -aXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50IG1vbml0b3JpbmcgbW9k -ZSBvbmx5KSIKPiArCWRlcGVuZHMgb24gSTJDCj4gKwloZWxwCj4gKwkgIElmIHlvdSBzYXkgeWVz -IGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCj4gKwkg -IEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBv -ZiB2b2x0YWdlLAo+ICsJICBjdXJyZW50IGFuZCB0ZW1wZXJhdHVyZSBtb25pdG9yaW5nLCBidXQg -aW4gYWRkaXRpb24gdG8gdGhlIFZjYyBzdXBwbHkKPiArCSAgdm9sdGFnZSBhbmQgY2hpcCB0ZW1w -ZXJhdHVyZSwgdGhpcyBkcml2ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMKPiArCSAgcmVhZGlu -ZyB0d28gY3VycmVudHMgYnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNy -b3NzCj4gKwkgIHNlcmllcyByZXNpc3RvcnMuCj4gKwo+ICsJICBUaGlzIGRyaXZlciBjYW4gYWxz -byBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2lsbAo+ICsJICBiZSBj -YWxsZWQgbHRjMjk5MC4KPiArCj4gICBjb25maWcgU0VOU09SU19MVEM0MTUxCj4gICAJdHJpc3Rh -dGUgIkxpbmVhciBUZWNobm9sb2d5IExUQzQxNTEiCj4gICAJZGVwZW5kcyBvbiBJMkMKPiBkaWZm -IC0tZ2l0IGEvZHJpdmVycy9od21vbi9NYWtlZmlsZSBiL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUK -PiBpbmRleCAxMmEzMjM5Li5lNGJkMTViIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvaHdtb24vTWFr -ZWZpbGUKPiArKysgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4gQEAgLTEwMSw2ICsxMDEsNyBA -QCBvYmotJChDT05GSUdfU0VOU09SU19MTTk1MjM0KQkrPSBsbTk1MjM0Lm8KPiAgIG9iai0kKENP -TkZJR19TRU5TT1JTX0xNOTUyNDEpCSs9IGxtOTUyNDEubwo+ICAgb2JqLSQoQ09ORklHX1NFTlNP -UlNfTE05NTI0NSkJKz0gbG05NTI0NS5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEMyOTQ1 -KQkrPSBsdGMyOTQ1Lm8KPiArb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDMjk5MCkJKz0gbHRjMjk5 -MC5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEM0MTUxKQkrPSBsdGM0MTUxLm8KPiAgIG9i -ai0kKENPTkZJR19TRU5TT1JTX0xUQzQyMTUpCSs9IGx0YzQyMTUubwo+ICAgb2JqLSQoQ09ORklH -X1NFTlNPUlNfTFRDNDIyMikJKz0gbHRjNDIyMi5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdt -b24vbHRjMjk5MC5jIGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKPiBuZXcgZmlsZSBtb2RlIDEw -MDY0NAo+IGluZGV4IDAwMDAwMDAuLjhmOGZlMDUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJp -dmVycy9od21vbi9sdGMyOTkwLmMKPiBAQCAtMCwwICsxLDE2MSBAQAo+ICsvKgo+ICsgKiBEcml2 -ZXIgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIgbW9uaXRvcgo+ICsgKgo+ICsg -KiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9waWMgRW1iZWRkZWQgUHJvZHVjdHMKPiArICogQXV0aG9y -OiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4gKyAqCj4gKyAqIExp -Y2Vuc2U6IEdQTHYyCj4gKyAqCj4gKyAqIFRoaXMgZHJpdmVyIGFzc3VtZXMgdGhlIGNoaXAgaXMg -d2lyZWQgYXMgYSBkdWFsIGN1cnJlbnQgbW9uaXRvciwgYW5kCj4gKyAqIHJlcG9ydHMgdGhlIHZv -bHRhZ2UgZHJvcCBhY3Jvc3MgdHdvIHNlcmllcyByZXNpc3RvcnMuIEl0IGFsc28gcmVwb3J0cwo+ -ICsgKiB0aGUgY2hpcCdzIGludGVybmFsIHRlbXBlcmF0dXJlIGFuZCBWY2MgcG93ZXIgc3VwcGx5 -IHZvbHRhZ2UuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgo+ICsjaW5jbHVk -ZSA8bGludXgvaHdtb24uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+Cj4gKyNp -bmNsdWRlIDxsaW51eC9pMmMuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5j -bHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTCTB4MDAK -PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0wJMHgwMQo+ICsjZGVmaW5lIExUQzI5OTBfVFJJR0dF -UgkweDAyCj4gKyNkZWZpbmUgTFRDMjk5MF9USU5UX01TQgkweDA0Cj4gKyNkZWZpbmUgTFRDMjk5 -MF9WMV9NU0IJMHgwNgo+ICsjZGVmaW5lIExUQzI5OTBfVjJfTVNCCTB4MDgKPiArI2RlZmluZSBM -VEMyOTkwX1YzX01TQgkweDBBCj4gKyNkZWZpbmUgTFRDMjk5MF9WNF9NU0IJMHgwQwo+ICsjZGVm -aW5lIExUQzI5OTBfVkNDX01TQgkweDBFCj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9L -RUxWSU4JCUJJVCg3KQo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9TSU5HTEUJCUJJVCg2KQo+ -ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NRUFTVVJFX0FMTAkoMHgzIDw8IDMpCj4gKyNkZWZp -bmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVAkweDA2Cj4gKyNkZWZpbmUgTFRDMjk5MF9D -T05UUk9MX01PREVfVk9MVEFHRQkweDA3Cj4gKwo+ICsvKiBjb252ZXJ0IHJhdyByZWdpc3RlciB2 -YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4gMTYtYml0IHJhbmdlICovCj4gK3N0YXRp -YyBpbnQgbHRjMjk5MF92b2x0YWdlX3RvX2ludChpbnQgcmF3KQo+ICt7Cj4gKwlpZiAocmF3ICYg -QklUKDE0KSkKPiArCQlyZXR1cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZGKSkgPDwgMjsKPiAr -CWVsc2UKPiArCQlyZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKPiArfQo+ICsKPiArLyogUmV0 -dXJuIHRoZSBjb252ZXJ0ZWQgdmFsdWUgZnJvbSB0aGUgZ2l2ZW4gcmVnaXN0ZXIgaW4gdVYgb3Ig -bUMgKi8KPiArc3RhdGljIGludCBsdGMyOTkwX2dldF92YWx1ZShzdHJ1Y3QgaTJjX2NsaWVudCAq -aTJjLCB1OCByZWcsIGludCAqcmVzdWx0KQo+ICt7Cj4gKwlpbnQgdmFsOwo+ICsKPiArCXZhbCA9 -IGkyY19zbWJ1c19yZWFkX3dvcmRfc3dhcHBlZChpMmMsIHJlZyk7Cj4gKwlpZiAodW5saWtlbHko -dmFsIDwgMCkpCj4gKwkJcmV0dXJuIHZhbDsKPiArCj4gKwlzd2l0Y2ggKHJlZykgewo+ICsJY2Fz -ZSBMVEMyOTkwX1RJTlRfTVNCOgo+ICsJCS8qIGludGVybmFsIHRlbXAsIDAuMDYyNSBkZWdyZWVz -L0xTQiwgMTMtYml0ICAqLwo+ICsJCXZhbCA9ICh2YWwgJiAweDFGRkYpIDw8IDM7Cj4gKwkJKnJl -c3VsdCA9ICh2YWwgKiAxMDAwKSA+PiA3Owo+ICsJCWJyZWFrOwo+ICsJY2FzZSBMVEMyOTkwX1Yx -X01TQjoKPiArCWNhc2UgTFRDMjk5MF9WM19NU0I6Cj4gKwkJIC8qIFZ4LVZ5LCAxOS40MnVWL0xT -Qi4gRGVwZW5kcyBvbiBtb2RlLiAqLwo+ICsJCSpyZXN1bHQgPSBsdGMyOTkwX3ZvbHRhZ2VfdG9f -aW50KHZhbCkgKiAxOTQyIC8gKDQgKiAxMDApOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBMVEMyOTkw -X1ZDQ19NU0I6Cj4gKwkJLyogVmNjLCAzMDUuMTjOvFYvTFNCLCAyLjVWIG9mZnNldCAqLwo+ICsJ -CSpyZXN1bHQgPSAobHRjMjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMzA1MTggLwo+ICsJCQkg -ICAoNCAqIDEwMCAqIDEwMDApKSArIDI1MDA7Cj4gKwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ICsJ -CXJldHVybiAtRUlOVkFMOyAvKiB3b24ndCBoYXBwZW4sIGtlZXAgY29tcGlsZXIgaGFwcHkgKi8K -PiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHNzaXplX3QgbHRjMjk5 -MF9zaG93X3ZhbHVlKHN0cnVjdCBkZXZpY2UgKmRldiwKPiArCQkJCSAgc3RydWN0IGRldmljZV9h -dHRyaWJ1dGUgKmRhLCBjaGFyICpidWYpCj4gK3sKPiArCXN0cnVjdCBzZW5zb3JfZGV2aWNlX2F0 -dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4gKwlpbnQgdmFsdWU7Cj4g -KwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IGx0YzI5OTBfZ2V0X3ZhbHVlKGRldl9nZXRfZHJ2ZGF0 -YShkZXYpLCBhdHRyLT5pbmRleCwgJnZhbHVlKTsKPiArCWlmICh1bmxpa2VseShyZXQgPCAwKSkK -PiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwg -IiVkXG4iLCB2YWx1ZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVt -cDFfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwKPiArCQkJICBMVEMy -OTkwX1RJTlRfTVNCKTsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihjdXJyMV9pbnB1dCwg -U19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+ICsJCQkgIExUQzI5OTBfVjFfTVNC -KTsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihjdXJyMl9pbnB1dCwgU19JUlVHTywgbHRj -Mjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+ICsJCQkgIExUQzI5OTBfVjNfTVNCKTsKPiArc3RhdGlj -IFNFTlNPUl9ERVZJQ0VfQVRUUihpbjBfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1 -ZSwgTlVMTCwKPiArCQkJICBMVEMyOTkwX1ZDQ19NU0IpOwo+ICsKPiArc3RhdGljIHN0cnVjdCBh -dHRyaWJ1dGUgKmx0YzI5OTBfYXR0cnNbXSA9IHsKPiArCSZzZW5zb3JfZGV2X2F0dHJfdGVtcDFf -aW5wdXQuZGV2X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfY3VycjFfaW5wdXQuZGV2 -X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfY3VycjJfaW5wdXQuZGV2X2F0dHIuYXR0 -ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfaW4wX2lucHV0LmRldl9hdHRyLmF0dHIsCj4gKwlOVUxM -LAo+ICt9Owo+ICtBVFRSSUJVVEVfR1JPVVBTKGx0YzI5OTApOwo+ICsKPiArc3RhdGljIGludCBs -dGMyOTkwX2kyY19wcm9iZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLAo+ICsJCQkgICAgIGNvbnN0 -IHN0cnVjdCBpMmNfZGV2aWNlX2lkICppZCkKPiArewo+ICsJaW50IHJldDsKPiArCXN0cnVjdCBk -ZXZpY2UgKmh3bW9uX2RldjsKPiArCj4gKwlpZiAoIWkyY19jaGVja19mdW5jdGlvbmFsaXR5KGky -Yy0+YWRhcHRlciwgSTJDX0ZVTkNfU01CVVNfQllURV9EQVRBIHwKPiArCQkJCSAgICAgSTJDX0ZV -TkNfU01CVVNfV09SRF9EQVRBKSkKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCj4gKwkvKiBTZXR1 -cCBjb250aW51b3VzIG1vZGUsIGN1cnJlbnQgbW9uaXRvciAqLwo+ICsJcmV0ID0gaTJjX3NtYnVz -X3dyaXRlX2J5dGVfZGF0YShpMmMsIExUQzI5OTBfQ09OVFJPTCwKPiArCQkJCQlMVEMyOTkwX0NP -TlRST0xfTUVBU1VSRV9BTEwgfAo+ICsJCQkJCUxUQzI5OTBfQ09OVFJPTF9NT0RFX0NVUlJFTlQp -Owo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKCZpMmMtPmRldiwgIkVycm9yOiBGYWls -ZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwkv -KiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91cyBjb252ZXJzaW9uICovCj4gKwlyZXQg -PSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9UUklHR0VSLCAxKTsKPiAr -CWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRv -IHN0YXJ0IGFjcXVpc2l0aW9uLlxuIik7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlo -d21vbl9kZXYgPSBkZXZtX2h3bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygmaTJjLT5k -ZXYsCj4gKwkJCQkJCQkgICBpMmMtPm5hbWUsCj4gKwkJCQkJCQkgICBpMmMsCj4gKwkJCQkJCQkg -ICBsdGMyOTkwX2dyb3Vwcyk7Cj4gKwo+ICsJcmV0dXJuIFBUUl9FUlJfT1JfWkVSTyhod21vbl9k -ZXYpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgbHRjMjk5 -MF9pMmNfaWRbXSA9IHsKPiArCXsgImx0YzI5OTAiLCAwIH0sCj4gKwl7fQo+ICt9Owo+ICtNT0RV -TEVfREVWSUNFX1RBQkxFKGkyYywgbHRjMjk5MF9pMmNfaWQpOwo+ICsKPiArc3RhdGljIHN0cnVj -dCBpMmNfZHJpdmVyIGx0YzI5OTBfaTJjX2RyaXZlciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJ -Lm5hbWUgPSAibHRjMjk5MCIsCj4gKwl9LAo+ICsJLnByb2JlICAgID0gbHRjMjk5MF9pMmNfcHJv -YmUsCj4gKwkuaWRfdGFibGUgPSBsdGMyOTkwX2kyY19pZCwKPiArfTsKPiArCj4gK21vZHVsZV9p -MmNfZHJpdmVyKGx0YzI5OTBfaTJjX2RyaXZlcik7Cj4gKwo+ICtNT0RVTEVfREVTQ1JJUFRJT04o -IkxUQzI5OTAgU2Vuc29yIERyaXZlciIpOwo+ICtNT0RVTEVfQVVUSE9SKCJUb3BpYyBFbWJlZGRl -ZCBQcm9kdWN0cyIpOwo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Cj4KCgpfX19fX19fX19f -X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcg -bGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMub3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9y -Zy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNvcnM +On 01/15/2016 01:54 AM, Mike Looijmans wrote: +> This adds support for the Linear Technology LTC2990 I2C System Monitor. +> The LTC2990 supports a combination of voltage, current and temperature +> monitoring. This driver currently only supports reading two currents +> by measuring two differential voltages across series resistors, in +> addition to the Vcc supply voltage and internal temperature. +> +> This is sufficient to support the Topic Miami SOM which uses this chip +> to monitor the currents flowing into the FPGA and the CPU parts. +> +> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl> + +Applied to -next. + +Thanks, +Guenter + +> --- +> v4: Fix checkpatch warnings +> ltc2990_get_value can return error code +> v3: Remove unused includes. +> Remove (most) unused register defines. +> Also check on SMBUS WORD capability. +> Use register defines as value indices. +> Alignment fixups with "(". +> v2: Processed all review comments. +> Put chip into continuous measurement mode. +> Added ducumentation. +> Use standard hwmon interfaces and macros. +> Documentation/hwmon/ltc2990 | 44 ++++++++++++ +> drivers/hwmon/Kconfig | 14 ++++ +> drivers/hwmon/Makefile | 1 + +> drivers/hwmon/ltc2990.c | 161 ++++++++++++++++++++++++++++++++++++++++++++ +> 4 files changed, 220 insertions(+) +> create mode 100644 Documentation/hwmon/ltc2990 +> create mode 100644 drivers/hwmon/ltc2990.c +> +> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990 +> new file mode 100644 +> index 0000000..838b74e +> --- /dev/null +> +++ b/Documentation/hwmon/ltc2990 +> @@ -0,0 +1,44 @@ +> +Kernel driver ltc2990 +> +===================== +> + +> +Supported chips: +> + * Linear Technology LTC2990 +> + Prefix: 'ltc2990' +> + Addresses scanned: - +> + Datasheet: http://www.linear.com/product/ltc2990 +> + +> +Author: Mike Looijmans <mike.looijmans@topic.nl> +> + +> + +> +Description +> +----------- +> + +> +LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor. +> +The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4) +> +can be combined to measure a differential voltage, which is typically used to +> +measure current through a series resistor, or a temperature. +> + +> +This driver currently uses the 2x differential mode only. In order to support +> +other modes, the driver will need to be expanded. +> + +> + +> +Usage Notes +> +----------- +> + +> +This driver does not probe for PMBus devices. You will have to instantiate +> +devices explicitly. +> + +> + +> +Sysfs attributes +> +---------------- +> + +> +The "curr*_input" measurements actually report the voltage drop across the +> +input pins in microvolts. This is equivalent to the current through a 1mOhm +> +sense resistor. Divide the reported value by the actual sense resistor value +> +in mOhm to get the actual value. +> + +> +in0_input Voltage at Vcc pin in millivolt (range 2.5V to 5V) +> +temp1_input Internal chip temperature in millidegrees Celcius +> +curr1_input Current in mA across v1-v2 assuming a 1mOhm sense resistor. +> +curr2_input Current in mA across v3-v4 assuming a 1mOhm sense resistor. +> + +> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +> index 80a73bf..8a31d64 100644 +> --- a/drivers/hwmon/Kconfig +> +++ b/drivers/hwmon/Kconfig +> @@ -685,6 +685,20 @@ config SENSORS_LTC2945 +> This driver can also be built as a module. If so, the module will +> be called ltc2945. +> +> +config SENSORS_LTC2990 +> + tristate "Linear Technology LTC2990 (current monitoring mode only)" +> + depends on I2C +> + help +> + If you say yes here you get support for Linear Technology LTC2990 +> + I2C System Monitor. The LTC2990 supports a combination of voltage, +> + current and temperature monitoring, but in addition to the Vcc supply +> + voltage and chip temperature, this driver currently only supports +> + reading two currents by measuring two differential voltages across +> + series resistors. +> + +> + This driver can also be built as a module. If so, the module will +> + be called ltc2990. +> + +> config SENSORS_LTC4151 +> tristate "Linear Technology LTC4151" +> depends on I2C +> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile +> index 12a3239..e4bd15b 100644 +> --- a/drivers/hwmon/Makefile +> +++ b/drivers/hwmon/Makefile +> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234) += lm95234.o +> obj-$(CONFIG_SENSORS_LM95241) += lm95241.o +> obj-$(CONFIG_SENSORS_LM95245) += lm95245.o +> obj-$(CONFIG_SENSORS_LTC2945) += ltc2945.o +> +obj-$(CONFIG_SENSORS_LTC2990) += ltc2990.o +> obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o +> obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o +> obj-$(CONFIG_SENSORS_LTC4222) += ltc4222.o +> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c +> new file mode 100644 +> index 0000000..8f8fe05 +> --- /dev/null +> +++ b/drivers/hwmon/ltc2990.c +> @@ -0,0 +1,161 @@ +> +/* +> + * Driver for Linear Technology LTC2990 power monitor +> + * +> + * Copyright (C) 2014 Topic Embedded Products +> + * Author: Mike Looijmans <mike.looijmans@topic.nl> +> + * +> + * License: GPLv2 +> + * +> + * This driver assumes the chip is wired as a dual current monitor, and +> + * reports the voltage drop across two series resistors. It also reports +> + * the chip's internal temperature and Vcc power supply voltage. +> + */ +> + +> +#include <linux/err.h> +> +#include <linux/hwmon.h> +> +#include <linux/hwmon-sysfs.h> +> +#include <linux/i2c.h> +> +#include <linux/kernel.h> +> +#include <linux/module.h> +> + +> +#define LTC2990_STATUS 0x00 +> +#define LTC2990_CONTROL 0x01 +> +#define LTC2990_TRIGGER 0x02 +> +#define LTC2990_TINT_MSB 0x04 +> +#define LTC2990_V1_MSB 0x06 +> +#define LTC2990_V2_MSB 0x08 +> +#define LTC2990_V3_MSB 0x0A +> +#define LTC2990_V4_MSB 0x0C +> +#define LTC2990_VCC_MSB 0x0E +> + +> +#define LTC2990_CONTROL_KELVIN BIT(7) +> +#define LTC2990_CONTROL_SINGLE BIT(6) +> +#define LTC2990_CONTROL_MEASURE_ALL (0x3 << 3) +> +#define LTC2990_CONTROL_MODE_CURRENT 0x06 +> +#define LTC2990_CONTROL_MODE_VOLTAGE 0x07 +> + +> +/* convert raw register value to sign-extended integer in 16-bit range */ +> +static int ltc2990_voltage_to_int(int raw) +> +{ +> + if (raw & BIT(14)) +> + return -(0x4000 - (raw & 0x3FFF)) << 2; +> + else +> + return (raw & 0x3FFF) << 2; +> +} +> + +> +/* Return the converted value from the given register in uV or mC */ +> +static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, int *result) +> +{ +> + int val; +> + +> + val = i2c_smbus_read_word_swapped(i2c, reg); +> + if (unlikely(val < 0)) +> + return val; +> + +> + switch (reg) { +> + case LTC2990_TINT_MSB: +> + /* internal temp, 0.0625 degrees/LSB, 13-bit */ +> + val = (val & 0x1FFF) << 3; +> + *result = (val * 1000) >> 7; +> + break; +> + case LTC2990_V1_MSB: +> + case LTC2990_V3_MSB: +> + /* Vx-Vy, 19.42uV/LSB. Depends on mode. */ +> + *result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100); +> + break; +> + case LTC2990_VCC_MSB: +> + /* Vcc, 305.18μV/LSB, 2.5V offset */ +> + *result = (ltc2990_voltage_to_int(val) * 30518 / +> + (4 * 100 * 1000)) + 2500; +> + break; +> + default: +> + return -EINVAL; /* won't happen, keep compiler happy */ +> + } +> + +> + return 0; +> +} +> + +> +static ssize_t ltc2990_show_value(struct device *dev, +> + struct device_attribute *da, char *buf) +> +{ +> + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); +> + int value; +> + int ret; +> + +> + ret = ltc2990_get_value(dev_get_drvdata(dev), attr->index, &value); +> + if (unlikely(ret < 0)) +> + return ret; +> + +> + return snprintf(buf, PAGE_SIZE, "%d\n", value); +> +} +> + +> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL, +> + LTC2990_TINT_MSB); +> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL, +> + LTC2990_V1_MSB); +> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL, +> + LTC2990_V3_MSB); +> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL, +> + LTC2990_VCC_MSB); +> + +> +static struct attribute *ltc2990_attrs[] = { +> + &sensor_dev_attr_temp1_input.dev_attr.attr, +> + &sensor_dev_attr_curr1_input.dev_attr.attr, +> + &sensor_dev_attr_curr2_input.dev_attr.attr, +> + &sensor_dev_attr_in0_input.dev_attr.attr, +> + NULL, +> +}; +> +ATTRIBUTE_GROUPS(ltc2990); +> + +> +static int ltc2990_i2c_probe(struct i2c_client *i2c, +> + const struct i2c_device_id *id) +> +{ +> + int ret; +> + struct device *hwmon_dev; +> + +> + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA | +> + I2C_FUNC_SMBUS_WORD_DATA)) +> + return -ENODEV; +> + +> + /* Setup continuous mode, current monitor */ +> + ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL, +> + LTC2990_CONTROL_MEASURE_ALL | +> + LTC2990_CONTROL_MODE_CURRENT); +> + if (ret < 0) { +> + dev_err(&i2c->dev, "Error: Failed to set control mode.\n"); +> + return ret; +> + } +> + /* Trigger once to start continuous conversion */ +> + ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1); +> + if (ret < 0) { +> + dev_err(&i2c->dev, "Error: Failed to start acquisition.\n"); +> + return ret; +> + } +> + +> + hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev, +> + i2c->name, +> + i2c, +> + ltc2990_groups); +> + +> + return PTR_ERR_OR_ZERO(hwmon_dev); +> +} +> + +> +static const struct i2c_device_id ltc2990_i2c_id[] = { +> + { "ltc2990", 0 }, +> + {} +> +}; +> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id); +> + +> +static struct i2c_driver ltc2990_i2c_driver = { +> + .driver = { +> + .name = "ltc2990", +> + }, +> + .probe = ltc2990_i2c_probe, +> + .id_table = ltc2990_i2c_id, +> +}; +> + +> +module_i2c_driver(ltc2990_i2c_driver); +> + +> +MODULE_DESCRIPTION("LTC2990 Sensor Driver"); +> +MODULE_AUTHOR("Topic Embedded Products"); +> +MODULE_LICENSE("GPL v2"); +> diff --git a/a/content_digest b/N1/content_digest index 4ee5997..3572d93 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,186 +1,304 @@ "ref\01452851699-14652-1-git-send-email-mike.looijmans@topic.nl\0" "From\0Guenter Roeck <linux@roeck-us.net>\0" - "Subject\0Re: [lm-sensors] [PATCH v4] hwmon: Add LTC2990 sensor driver\0" - "Date\0Fri, 15 Jan 2016 15:40:34 +0000\0" + "Subject\0Re: [PATCH v4] hwmon: Add LTC2990 sensor driver\0" + "Date\0Fri, 15 Jan 2016 07:40:34 -0800\0" "To\0Mike Looijmans <mike.looijmans@topic.nl>" " lm-sensors@lm-sensors.org\0" "Cc\0jdelvare@suse.com" " linux-kernel@vger.kernel.org\0" "\00:1\0" "b\0" - "T24gMDEvMTUvMjAxNiAwMTo1NCBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4gVGhpcyBhZGRz\n" - "IHN1cHBvcnQgZm9yIHRoZSBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwICBJMkMgU3lzdGVtIE1v\n" - "bml0b3IuCj4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBvZiB2b2x0YWdlLCBj\n" - "dXJyZW50IGFuZCB0ZW1wZXJhdHVyZQo+IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVyIGN1cnJlbnRs\n" - "eSBvbmx5IHN1cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4gYnkgbWVhc3VyaW5nIHR3byBk\n" - "aWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNyb3NzIHNlcmllcyByZXNpc3RvcnMsIGluCj4gYWRkaXRp\n" - "b24gdG8gdGhlIFZjYyBzdXBwbHkgdm9sdGFnZSBhbmQgaW50ZXJuYWwgdGVtcGVyYXR1cmUuCj4K\n" - "PiBUaGlzIGlzIHN1ZmZpY2llbnQgdG8gc3VwcG9ydCB0aGUgVG9waWMgTWlhbWkgU09NIHdoaWNo\n" - "IHVzZXMgdGhpcyBjaGlwCj4gdG8gbW9uaXRvciB0aGUgY3VycmVudHMgZmxvd2luZyBpbnRvIHRo\n" - "ZSBGUEdBIGFuZCB0aGUgQ1BVIHBhcnRzLgo+Cj4gU2lnbmVkLW9mZi1ieTogTWlrZSBMb29pam1h\n" - "bnMgPG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgoKQXBwbGllZCB0byAtbmV4dC4KClRoYW5rcywK\n" - "R3VlbnRlcgoKPiAtLS0KPiB2NDogRml4IGNoZWNrcGF0Y2ggd2FybmluZ3MKPiAgICAgIGx0YzI5\n" - "OTBfZ2V0X3ZhbHVlIGNhbiByZXR1cm4gZXJyb3IgY29kZQo+IHYzOiBSZW1vdmUgdW51c2VkIGlu\n" - "Y2x1ZGVzLgo+ICAgICAgUmVtb3ZlIChtb3N0KSB1bnVzZWQgcmVnaXN0ZXIgZGVmaW5lcy4KPiAg\n" - "ICAgIEFsc28gY2hlY2sgb24gU01CVVMgV09SRCBjYXBhYmlsaXR5Lgo+ICAgICAgVXNlIHJlZ2lz\n" - "dGVyIGRlZmluZXMgYXMgdmFsdWUgaW5kaWNlcy4KPiAgICAgIEFsaWdubWVudCBmaXh1cHMgd2l0\n" - "aCAiKCIuCj4gdjI6IFByb2Nlc3NlZCBhbGwgcmV2aWV3IGNvbW1lbnRzLgo+ICAgICAgIFB1dCBj\n" - "aGlwIGludG8gY29udGludW91cyBtZWFzdXJlbWVudCBtb2RlLgo+ICAgICAgIEFkZGVkIGR1Y3Vt\n" - "ZW50YXRpb24uCj4gICAgICAgVXNlIHN0YW5kYXJkIGh3bW9uIGludGVyZmFjZXMgYW5kIG1hY3Jv\n" - "cy4KPiAgIERvY3VtZW50YXRpb24vaHdtb24vbHRjMjk5MCB8ICA0NCArKysrKysrKysrKysKPiAg\n" - "IGRyaXZlcnMvaHdtb24vS2NvbmZpZyAgICAgICB8ICAxNCArKysrCj4gICBkcml2ZXJzL2h3bW9u\n" - "L01ha2VmaWxlICAgICAgfCAgIDEgKwo+ICAgZHJpdmVycy9od21vbi9sdGMyOTkwLmMgICAgIHwg\n" - "MTYxICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gICA0IGZp\n" - "bGVzIGNoYW5nZWQsIDIyMCBpbnNlcnRpb25zKCspCj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgRG9j\n" - "dW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCj4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9o\n" - "d21vbi9sdGMyOTkwLmMKPgo+IGRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5\n" - "OTAgYi9Eb2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+\n" - "IGluZGV4IDAwMDAwMDAuLjgzOGI3NGUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvRG9jdW1lbnRh\n" - "dGlvbi9od21vbi9sdGMyOTkwCj4gQEAgLTAsMCArMSw0NCBAQAo+ICtLZXJuZWwgZHJpdmVyIGx0\n" - "YzI5OTAKPiArPT09PT09PT09PT09PT09PT09PT09Cj4gKwo+ICtTdXBwb3J0ZWQgY2hpcHM6Cj4g\n" - "KyAgKiBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCj4gKyAgICBQcmVmaXg6ICdsdGMyOTkwJwo+\n" - "ICsgICAgQWRkcmVzc2VzIHNjYW5uZWQ6IC0KPiArICAgIERhdGFzaGVldDogaHR0cDovL3d3dy5s\n" - "aW5lYXIuY29tL3Byb2R1Y3QvbHRjMjk5MAo+ICsKPiArQXV0aG9yOiBNaWtlIExvb2lqbWFucyA8\n" - "bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4gKwo+ICsKPiArRGVzY3JpcHRpb24KPiArLS0tLS0t\n" - "LS0tLS0KPiArCj4gK0xUQzI5OTAgaXMgYSBRdWFkIEkyQyBWb2x0YWdlLCBDdXJyZW50IGFuZCBU\n" - "ZW1wZXJhdHVyZSBNb25pdG9yLgo+ICtUaGUgY2hpcCdzIGlucHV0cyBjYW4gbWVhc3VyZSA0IHZv\n" - "bHRhZ2VzLCBvciB0d28gaW5wdXRzIHRvZ2V0aGVyICgxKzIgYW5kIDMrNCkKPiArY2FuIGJlIGNv\n" - "bWJpbmVkIHRvIG1lYXN1cmUgYSBkaWZmZXJlbnRpYWwgdm9sdGFnZSwgd2hpY2ggaXMgdHlwaWNh\n" - "bGx5IHVzZWQgdG8KPiArbWVhc3VyZSBjdXJyZW50IHRocm91Z2ggYSBzZXJpZXMgcmVzaXN0b3Is\n" - "IG9yIGEgdGVtcGVyYXR1cmUuCj4gKwo+ICtUaGlzIGRyaXZlciBjdXJyZW50bHkgdXNlcyB0aGUg\n" - "MnggZGlmZmVyZW50aWFsIG1vZGUgb25seS4gSW4gb3JkZXIgdG8gc3VwcG9ydAo+ICtvdGhlciBt\n" - "b2RlcywgdGhlIGRyaXZlciB3aWxsIG5lZWQgdG8gYmUgZXhwYW5kZWQuCj4gKwo+ICsKPiArVXNh\n" - "Z2UgTm90ZXMKPiArLS0tLS0tLS0tLS0KPiArCj4gK1RoaXMgZHJpdmVyIGRvZXMgbm90IHByb2Jl\n" - "IGZvciBQTUJ1cyBkZXZpY2VzLiBZb3Ugd2lsbCBoYXZlIHRvIGluc3RhbnRpYXRlCj4gK2Rldmlj\n" - "ZXMgZXhwbGljaXRseS4KPiArCj4gKwo+ICtTeXNmcyBhdHRyaWJ1dGVzCj4gKy0tLS0tLS0tLS0t\n" - "LS0tLS0KPiArCj4gK1RoZSAiY3VycipfaW5wdXQiIG1lYXN1cmVtZW50cyBhY3R1YWxseSByZXBv\n" - "cnQgdGhlIHZvbHRhZ2UgZHJvcCBhY3Jvc3MgdGhlCj4gK2lucHV0IHBpbnMgaW4gbWljcm92b2x0\n" - "cy4gVGhpcyBpcyBlcXVpdmFsZW50IHRvIHRoZSBjdXJyZW50IHRocm91Z2ggYSAxbU9obQo+ICtz\n" - "ZW5zZSByZXNpc3Rvci4gRGl2aWRlIHRoZSByZXBvcnRlZCB2YWx1ZSBieSB0aGUgYWN0dWFsIHNl\n" - "bnNlIHJlc2lzdG9yIHZhbHVlCj4gK2luIG1PaG0gdG8gZ2V0IHRoZSBhY3R1YWwgdmFsdWUuCj4g\n" - "Kwo+ICtpbjBfaW5wdXQgICAgIFZvbHRhZ2UgYXQgVmNjIHBpbiBpbiBtaWxsaXZvbHQgKHJhbmdl\n" - "IDIuNVYgdG8gNVYpCj4gK3RlbXAxX2lucHV0ICAgSW50ZXJuYWwgY2hpcCB0ZW1wZXJhdHVyZSBp\n" - "biBtaWxsaWRlZ3JlZXMgQ2VsY2l1cwo+ICtjdXJyMV9pbnB1dCAgIEN1cnJlbnQgaW4gbUEgYWNy\n" - "b3NzIHYxLXYyIGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3IuCj4gK2N1cnIyX2lucHV0\n" - "ICAgQ3VycmVudCBpbiBtQSBhY3Jvc3MgdjMtdjQgYXNzdW1pbmcgYSAxbU9obSBzZW5zZSByZXNp\n" - "c3Rvci4KPiArCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMv\n" - "aHdtb24vS2NvbmZpZwo+IGluZGV4IDgwYTczYmYuLjhhMzFkNjQgMTAwNjQ0Cj4gLS0tIGEvZHJp\n" - "dmVycy9od21vbi9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4gQEAgLTY4\n" - "NSw2ICs2ODUsMjAgQEAgY29uZmlnIFNFTlNPUlNfTFRDMjk0NQo+ICAgCSAgVGhpcyBkcml2ZXIg\n" - "Y2FuIGFsc28gYmUgYnVpbHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwKPiAg\n" - "IAkgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Cj4gK2NvbmZpZyBTRU5TT1JTX0xUQzI5OTAKPiArCXRy\n" - "aXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50IG1vbml0b3JpbmcgbW9k\n" - "ZSBvbmx5KSIKPiArCWRlcGVuZHMgb24gSTJDCj4gKwloZWxwCj4gKwkgIElmIHlvdSBzYXkgeWVz\n" - "IGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciBMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwCj4gKwkg\n" - "IEkyQyBTeXN0ZW0gTW9uaXRvci4gVGhlIExUQzI5OTAgc3VwcG9ydHMgYSBjb21iaW5hdGlvbiBv\n" - "ZiB2b2x0YWdlLAo+ICsJICBjdXJyZW50IGFuZCB0ZW1wZXJhdHVyZSBtb25pdG9yaW5nLCBidXQg\n" - "aW4gYWRkaXRpb24gdG8gdGhlIFZjYyBzdXBwbHkKPiArCSAgdm9sdGFnZSBhbmQgY2hpcCB0ZW1w\n" - "ZXJhdHVyZSwgdGhpcyBkcml2ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMKPiArCSAgcmVhZGlu\n" - "ZyB0d28gY3VycmVudHMgYnkgbWVhc3VyaW5nIHR3byBkaWZmZXJlbnRpYWwgdm9sdGFnZXMgYWNy\n" - "b3NzCj4gKwkgIHNlcmllcyByZXNpc3RvcnMuCj4gKwo+ICsJICBUaGlzIGRyaXZlciBjYW4gYWxz\n" - "byBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2lsbAo+ICsJICBiZSBj\n" - "YWxsZWQgbHRjMjk5MC4KPiArCj4gICBjb25maWcgU0VOU09SU19MVEM0MTUxCj4gICAJdHJpc3Rh\n" - "dGUgIkxpbmVhciBUZWNobm9sb2d5IExUQzQxNTEiCj4gICAJZGVwZW5kcyBvbiBJMkMKPiBkaWZm\n" - "IC0tZ2l0IGEvZHJpdmVycy9od21vbi9NYWtlZmlsZSBiL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUK\n" - "PiBpbmRleCAxMmEzMjM5Li5lNGJkMTViIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvaHdtb24vTWFr\n" - "ZWZpbGUKPiArKysgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4gQEAgLTEwMSw2ICsxMDEsNyBA\n" - "QCBvYmotJChDT05GSUdfU0VOU09SU19MTTk1MjM0KQkrPSBsbTk1MjM0Lm8KPiAgIG9iai0kKENP\n" - "TkZJR19TRU5TT1JTX0xNOTUyNDEpCSs9IGxtOTUyNDEubwo+ICAgb2JqLSQoQ09ORklHX1NFTlNP\n" - "UlNfTE05NTI0NSkJKz0gbG05NTI0NS5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEMyOTQ1\n" - "KQkrPSBsdGMyOTQ1Lm8KPiArb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDMjk5MCkJKz0gbHRjMjk5\n" - "MC5vCj4gICBvYmotJChDT05GSUdfU0VOU09SU19MVEM0MTUxKQkrPSBsdGM0MTUxLm8KPiAgIG9i\n" - "ai0kKENPTkZJR19TRU5TT1JTX0xUQzQyMTUpCSs9IGx0YzQyMTUubwo+ICAgb2JqLSQoQ09ORklH\n" - "X1NFTlNPUlNfTFRDNDIyMikJKz0gbHRjNDIyMi5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdt\n" - "b24vbHRjMjk5MC5jIGIvZHJpdmVycy9od21vbi9sdGMyOTkwLmMKPiBuZXcgZmlsZSBtb2RlIDEw\n" - "MDY0NAo+IGluZGV4IDAwMDAwMDAuLjhmOGZlMDUKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJp\n" - "dmVycy9od21vbi9sdGMyOTkwLmMKPiBAQCAtMCwwICsxLDE2MSBAQAo+ICsvKgo+ICsgKiBEcml2\n" - "ZXIgZm9yIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAgcG93ZXIgbW9uaXRvcgo+ICsgKgo+ICsg\n" - "KiBDb3B5cmlnaHQgKEMpIDIwMTQgVG9waWMgRW1iZWRkZWQgUHJvZHVjdHMKPiArICogQXV0aG9y\n" - "OiBNaWtlIExvb2lqbWFucyA8bWlrZS5sb29pam1hbnNAdG9waWMubmw+Cj4gKyAqCj4gKyAqIExp\n" - "Y2Vuc2U6IEdQTHYyCj4gKyAqCj4gKyAqIFRoaXMgZHJpdmVyIGFzc3VtZXMgdGhlIGNoaXAgaXMg\n" - "d2lyZWQgYXMgYSBkdWFsIGN1cnJlbnQgbW9uaXRvciwgYW5kCj4gKyAqIHJlcG9ydHMgdGhlIHZv\n" - "bHRhZ2UgZHJvcCBhY3Jvc3MgdHdvIHNlcmllcyByZXNpc3RvcnMuIEl0IGFsc28gcmVwb3J0cwo+\n" - "ICsgKiB0aGUgY2hpcCdzIGludGVybmFsIHRlbXBlcmF0dXJlIGFuZCBWY2MgcG93ZXIgc3VwcGx5\n" - "IHZvbHRhZ2UuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgo+ICsjaW5jbHVk\n" - "ZSA8bGludXgvaHdtb24uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+Cj4gKyNp\n" - "bmNsdWRlIDxsaW51eC9pMmMuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5j\n" - "bHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTCTB4MDAK\n" - "PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0wJMHgwMQo+ICsjZGVmaW5lIExUQzI5OTBfVFJJR0dF\n" - "UgkweDAyCj4gKyNkZWZpbmUgTFRDMjk5MF9USU5UX01TQgkweDA0Cj4gKyNkZWZpbmUgTFRDMjk5\n" - "MF9WMV9NU0IJMHgwNgo+ICsjZGVmaW5lIExUQzI5OTBfVjJfTVNCCTB4MDgKPiArI2RlZmluZSBM\n" - "VEMyOTkwX1YzX01TQgkweDBBCj4gKyNkZWZpbmUgTFRDMjk5MF9WNF9NU0IJMHgwQwo+ICsjZGVm\n" - "aW5lIExUQzI5OTBfVkNDX01TQgkweDBFCj4gKwo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9L\n" - "RUxWSU4JCUJJVCg3KQo+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9TSU5HTEUJCUJJVCg2KQo+\n" - "ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NRUFTVVJFX0FMTAkoMHgzIDw8IDMpCj4gKyNkZWZp\n" - "bmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVAkweDA2Cj4gKyNkZWZpbmUgTFRDMjk5MF9D\n" - "T05UUk9MX01PREVfVk9MVEFHRQkweDA3Cj4gKwo+ICsvKiBjb252ZXJ0IHJhdyByZWdpc3RlciB2\n" - "YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4gMTYtYml0IHJhbmdlICovCj4gK3N0YXRp\n" - "YyBpbnQgbHRjMjk5MF92b2x0YWdlX3RvX2ludChpbnQgcmF3KQo+ICt7Cj4gKwlpZiAocmF3ICYg\n" - "QklUKDE0KSkKPiArCQlyZXR1cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZGKSkgPDwgMjsKPiAr\n" - "CWVsc2UKPiArCQlyZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKPiArfQo+ICsKPiArLyogUmV0\n" - "dXJuIHRoZSBjb252ZXJ0ZWQgdmFsdWUgZnJvbSB0aGUgZ2l2ZW4gcmVnaXN0ZXIgaW4gdVYgb3Ig\n" - "bUMgKi8KPiArc3RhdGljIGludCBsdGMyOTkwX2dldF92YWx1ZShzdHJ1Y3QgaTJjX2NsaWVudCAq\n" - "aTJjLCB1OCByZWcsIGludCAqcmVzdWx0KQo+ICt7Cj4gKwlpbnQgdmFsOwo+ICsKPiArCXZhbCA9\n" - "IGkyY19zbWJ1c19yZWFkX3dvcmRfc3dhcHBlZChpMmMsIHJlZyk7Cj4gKwlpZiAodW5saWtlbHko\n" - "dmFsIDwgMCkpCj4gKwkJcmV0dXJuIHZhbDsKPiArCj4gKwlzd2l0Y2ggKHJlZykgewo+ICsJY2Fz\n" - "ZSBMVEMyOTkwX1RJTlRfTVNCOgo+ICsJCS8qIGludGVybmFsIHRlbXAsIDAuMDYyNSBkZWdyZWVz\n" - "L0xTQiwgMTMtYml0ICAqLwo+ICsJCXZhbCA9ICh2YWwgJiAweDFGRkYpIDw8IDM7Cj4gKwkJKnJl\n" - "c3VsdCA9ICh2YWwgKiAxMDAwKSA+PiA3Owo+ICsJCWJyZWFrOwo+ICsJY2FzZSBMVEMyOTkwX1Yx\n" - "X01TQjoKPiArCWNhc2UgTFRDMjk5MF9WM19NU0I6Cj4gKwkJIC8qIFZ4LVZ5LCAxOS40MnVWL0xT\n" - "Qi4gRGVwZW5kcyBvbiBtb2RlLiAqLwo+ICsJCSpyZXN1bHQgPSBsdGMyOTkwX3ZvbHRhZ2VfdG9f\n" - "aW50KHZhbCkgKiAxOTQyIC8gKDQgKiAxMDApOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBMVEMyOTkw\n" - "X1ZDQ19NU0I6Cj4gKwkJLyogVmNjLCAzMDUuMTjOvFYvTFNCLCAyLjVWIG9mZnNldCAqLwo+ICsJ\n" - "CSpyZXN1bHQgPSAobHRjMjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMzA1MTggLwo+ICsJCQkg\n" - "ICAoNCAqIDEwMCAqIDEwMDApKSArIDI1MDA7Cj4gKwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ICsJ\n" - "CXJldHVybiAtRUlOVkFMOyAvKiB3b24ndCBoYXBwZW4sIGtlZXAgY29tcGlsZXIgaGFwcHkgKi8K\n" - "PiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHNzaXplX3QgbHRjMjk5\n" - "MF9zaG93X3ZhbHVlKHN0cnVjdCBkZXZpY2UgKmRldiwKPiArCQkJCSAgc3RydWN0IGRldmljZV9h\n" - "dHRyaWJ1dGUgKmRhLCBjaGFyICpidWYpCj4gK3sKPiArCXN0cnVjdCBzZW5zb3JfZGV2aWNlX2F0\n" - "dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4gKwlpbnQgdmFsdWU7Cj4g\n" - "KwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IGx0YzI5OTBfZ2V0X3ZhbHVlKGRldl9nZXRfZHJ2ZGF0\n" - "YShkZXYpLCBhdHRyLT5pbmRleCwgJnZhbHVlKTsKPiArCWlmICh1bmxpa2VseShyZXQgPCAwKSkK\n" - "PiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwg\n" - "IiVkXG4iLCB2YWx1ZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVt\n" - "cDFfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwKPiArCQkJICBMVEMy\n" - "OTkwX1RJTlRfTVNCKTsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihjdXJyMV9pbnB1dCwg\n" - "U19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+ICsJCQkgIExUQzI5OTBfVjFfTVNC\n" - "KTsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihjdXJyMl9pbnB1dCwgU19JUlVHTywgbHRj\n" - "Mjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+ICsJCQkgIExUQzI5OTBfVjNfTVNCKTsKPiArc3RhdGlj\n" - "IFNFTlNPUl9ERVZJQ0VfQVRUUihpbjBfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1\n" - "ZSwgTlVMTCwKPiArCQkJICBMVEMyOTkwX1ZDQ19NU0IpOwo+ICsKPiArc3RhdGljIHN0cnVjdCBh\n" - "dHRyaWJ1dGUgKmx0YzI5OTBfYXR0cnNbXSA9IHsKPiArCSZzZW5zb3JfZGV2X2F0dHJfdGVtcDFf\n" - "aW5wdXQuZGV2X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfY3VycjFfaW5wdXQuZGV2\n" - "X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfY3VycjJfaW5wdXQuZGV2X2F0dHIuYXR0\n" - "ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfaW4wX2lucHV0LmRldl9hdHRyLmF0dHIsCj4gKwlOVUxM\n" - "LAo+ICt9Owo+ICtBVFRSSUJVVEVfR1JPVVBTKGx0YzI5OTApOwo+ICsKPiArc3RhdGljIGludCBs\n" - "dGMyOTkwX2kyY19wcm9iZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLAo+ICsJCQkgICAgIGNvbnN0\n" - "IHN0cnVjdCBpMmNfZGV2aWNlX2lkICppZCkKPiArewo+ICsJaW50IHJldDsKPiArCXN0cnVjdCBk\n" - "ZXZpY2UgKmh3bW9uX2RldjsKPiArCj4gKwlpZiAoIWkyY19jaGVja19mdW5jdGlvbmFsaXR5KGky\n" - "Yy0+YWRhcHRlciwgSTJDX0ZVTkNfU01CVVNfQllURV9EQVRBIHwKPiArCQkJCSAgICAgSTJDX0ZV\n" - "TkNfU01CVVNfV09SRF9EQVRBKSkKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCj4gKwkvKiBTZXR1\n" - "cCBjb250aW51b3VzIG1vZGUsIGN1cnJlbnQgbW9uaXRvciAqLwo+ICsJcmV0ID0gaTJjX3NtYnVz\n" - "X3dyaXRlX2J5dGVfZGF0YShpMmMsIExUQzI5OTBfQ09OVFJPTCwKPiArCQkJCQlMVEMyOTkwX0NP\n" - "TlRST0xfTUVBU1VSRV9BTEwgfAo+ICsJCQkJCUxUQzI5OTBfQ09OVFJPTF9NT0RFX0NVUlJFTlQp\n" - "Owo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKCZpMmMtPmRldiwgIkVycm9yOiBGYWls\n" - "ZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwkv\n" - "KiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91cyBjb252ZXJzaW9uICovCj4gKwlyZXQg\n" - "PSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9UUklHR0VSLCAxKTsKPiAr\n" - "CWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRv\n" - "IHN0YXJ0IGFjcXVpc2l0aW9uLlxuIik7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlo\n" - "d21vbl9kZXYgPSBkZXZtX2h3bW9uX2RldmljZV9yZWdpc3Rlcl93aXRoX2dyb3VwcygmaTJjLT5k\n" - "ZXYsCj4gKwkJCQkJCQkgICBpMmMtPm5hbWUsCj4gKwkJCQkJCQkgICBpMmMsCj4gKwkJCQkJCQkg\n" - "ICBsdGMyOTkwX2dyb3Vwcyk7Cj4gKwo+ICsJcmV0dXJuIFBUUl9FUlJfT1JfWkVSTyhod21vbl9k\n" - "ZXYpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgbHRjMjk5\n" - "MF9pMmNfaWRbXSA9IHsKPiArCXsgImx0YzI5OTAiLCAwIH0sCj4gKwl7fQo+ICt9Owo+ICtNT0RV\n" - "TEVfREVWSUNFX1RBQkxFKGkyYywgbHRjMjk5MF9pMmNfaWQpOwo+ICsKPiArc3RhdGljIHN0cnVj\n" - "dCBpMmNfZHJpdmVyIGx0YzI5OTBfaTJjX2RyaXZlciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJ\n" - "Lm5hbWUgPSAibHRjMjk5MCIsCj4gKwl9LAo+ICsJLnByb2JlICAgID0gbHRjMjk5MF9pMmNfcHJv\n" - "YmUsCj4gKwkuaWRfdGFibGUgPSBsdGMyOTkwX2kyY19pZCwKPiArfTsKPiArCj4gK21vZHVsZV9p\n" - "MmNfZHJpdmVyKGx0YzI5OTBfaTJjX2RyaXZlcik7Cj4gKwo+ICtNT0RVTEVfREVTQ1JJUFRJT04o\n" - "IkxUQzI5OTAgU2Vuc29yIERyaXZlciIpOwo+ICtNT0RVTEVfQVVUSE9SKCJUb3BpYyBFbWJlZGRl\n" - "ZCBQcm9kdWN0cyIpOwo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Cj4KCgpfX19fX19fX19f\n" - "X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcg\n" - "bGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMub3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9y\n" - Zy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNvcnM + "On 01/15/2016 01:54 AM, Mike Looijmans wrote:\n" + "> This adds support for the Linear Technology LTC2990 I2C System Monitor.\n" + "> The LTC2990 supports a combination of voltage, current and temperature\n" + "> monitoring. This driver currently only supports reading two currents\n" + "> by measuring two differential voltages across series resistors, in\n" + "> addition to the Vcc supply voltage and internal temperature.\n" + ">\n" + "> This is sufficient to support the Topic Miami SOM which uses this chip\n" + "> to monitor the currents flowing into the FPGA and the CPU parts.\n" + ">\n" + "> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>\n" + "\n" + "Applied to -next.\n" + "\n" + "Thanks,\n" + "Guenter\n" + "\n" + "> ---\n" + "> v4: Fix checkpatch warnings\n" + "> ltc2990_get_value can return error code\n" + "> v3: Remove unused includes.\n" + "> Remove (most) unused register defines.\n" + "> Also check on SMBUS WORD capability.\n" + "> Use register defines as value indices.\n" + "> Alignment fixups with \"(\".\n" + "> v2: Processed all review comments.\n" + "> Put chip into continuous measurement mode.\n" + "> Added ducumentation.\n" + "> Use standard hwmon interfaces and macros.\n" + "> Documentation/hwmon/ltc2990 | 44 ++++++++++++\n" + "> drivers/hwmon/Kconfig | 14 ++++\n" + "> drivers/hwmon/Makefile | 1 +\n" + "> drivers/hwmon/ltc2990.c | 161 ++++++++++++++++++++++++++++++++++++++++++++\n" + "> 4 files changed, 220 insertions(+)\n" + "> create mode 100644 Documentation/hwmon/ltc2990\n" + "> create mode 100644 drivers/hwmon/ltc2990.c\n" + ">\n" + "> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990\n" + "> new file mode 100644\n" + "> index 0000000..838b74e\n" + "> --- /dev/null\n" + "> +++ b/Documentation/hwmon/ltc2990\n" + "> @@ -0,0 +1,44 @@\n" + "> +Kernel driver ltc2990\n" + "> +=====================\n" + "> +\n" + "> +Supported chips:\n" + "> + * Linear Technology LTC2990\n" + "> + Prefix: 'ltc2990'\n" + "> + Addresses scanned: -\n" + "> + Datasheet: http://www.linear.com/product/ltc2990\n" + "> +\n" + "> +Author: Mike Looijmans <mike.looijmans@topic.nl>\n" + "> +\n" + "> +\n" + "> +Description\n" + "> +-----------\n" + "> +\n" + "> +LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.\n" + "> +The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)\n" + "> +can be combined to measure a differential voltage, which is typically used to\n" + "> +measure current through a series resistor, or a temperature.\n" + "> +\n" + "> +This driver currently uses the 2x differential mode only. In order to support\n" + "> +other modes, the driver will need to be expanded.\n" + "> +\n" + "> +\n" + "> +Usage Notes\n" + "> +-----------\n" + "> +\n" + "> +This driver does not probe for PMBus devices. You will have to instantiate\n" + "> +devices explicitly.\n" + "> +\n" + "> +\n" + "> +Sysfs attributes\n" + "> +----------------\n" + "> +\n" + "> +The \"curr*_input\" measurements actually report the voltage drop across the\n" + "> +input pins in microvolts. This is equivalent to the current through a 1mOhm\n" + "> +sense resistor. Divide the reported value by the actual sense resistor value\n" + "> +in mOhm to get the actual value.\n" + "> +\n" + "> +in0_input Voltage at Vcc pin in millivolt (range 2.5V to 5V)\n" + "> +temp1_input Internal chip temperature in millidegrees Celcius\n" + "> +curr1_input Current in mA across v1-v2 assuming a 1mOhm sense resistor.\n" + "> +curr2_input Current in mA across v3-v4 assuming a 1mOhm sense resistor.\n" + "> +\n" + "> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig\n" + "> index 80a73bf..8a31d64 100644\n" + "> --- a/drivers/hwmon/Kconfig\n" + "> +++ b/drivers/hwmon/Kconfig\n" + "> @@ -685,6 +685,20 @@ config SENSORS_LTC2945\n" + "> \t This driver can also be built as a module. If so, the module will\n" + "> \t be called ltc2945.\n" + ">\n" + "> +config SENSORS_LTC2990\n" + "> +\ttristate \"Linear Technology LTC2990 (current monitoring mode only)\"\n" + "> +\tdepends on I2C\n" + "> +\thelp\n" + "> +\t If you say yes here you get support for Linear Technology LTC2990\n" + "> +\t I2C System Monitor. The LTC2990 supports a combination of voltage,\n" + "> +\t current and temperature monitoring, but in addition to the Vcc supply\n" + "> +\t voltage and chip temperature, this driver currently only supports\n" + "> +\t reading two currents by measuring two differential voltages across\n" + "> +\t series resistors.\n" + "> +\n" + "> +\t This driver can also be built as a module. If so, the module will\n" + "> +\t be called ltc2990.\n" + "> +\n" + "> config SENSORS_LTC4151\n" + "> \ttristate \"Linear Technology LTC4151\"\n" + "> \tdepends on I2C\n" + "> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile\n" + "> index 12a3239..e4bd15b 100644\n" + "> --- a/drivers/hwmon/Makefile\n" + "> +++ b/drivers/hwmon/Makefile\n" + "> @@ -101,6 +101,7 @@ obj-$(CONFIG_SENSORS_LM95234)\t+= lm95234.o\n" + "> obj-$(CONFIG_SENSORS_LM95241)\t+= lm95241.o\n" + "> obj-$(CONFIG_SENSORS_LM95245)\t+= lm95245.o\n" + "> obj-$(CONFIG_SENSORS_LTC2945)\t+= ltc2945.o\n" + "> +obj-$(CONFIG_SENSORS_LTC2990)\t+= ltc2990.o\n" + "> obj-$(CONFIG_SENSORS_LTC4151)\t+= ltc4151.o\n" + "> obj-$(CONFIG_SENSORS_LTC4215)\t+= ltc4215.o\n" + "> obj-$(CONFIG_SENSORS_LTC4222)\t+= ltc4222.o\n" + "> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c\n" + "> new file mode 100644\n" + "> index 0000000..8f8fe05\n" + "> --- /dev/null\n" + "> +++ b/drivers/hwmon/ltc2990.c\n" + "> @@ -0,0 +1,161 @@\n" + "> +/*\n" + "> + * Driver for Linear Technology LTC2990 power monitor\n" + "> + *\n" + "> + * Copyright (C) 2014 Topic Embedded Products\n" + "> + * Author: Mike Looijmans <mike.looijmans@topic.nl>\n" + "> + *\n" + "> + * License: GPLv2\n" + "> + *\n" + "> + * This driver assumes the chip is wired as a dual current monitor, and\n" + "> + * reports the voltage drop across two series resistors. It also reports\n" + "> + * the chip's internal temperature and Vcc power supply voltage.\n" + "> + */\n" + "> +\n" + "> +#include <linux/err.h>\n" + "> +#include <linux/hwmon.h>\n" + "> +#include <linux/hwmon-sysfs.h>\n" + "> +#include <linux/i2c.h>\n" + "> +#include <linux/kernel.h>\n" + "> +#include <linux/module.h>\n" + "> +\n" + "> +#define LTC2990_STATUS\t0x00\n" + "> +#define LTC2990_CONTROL\t0x01\n" + "> +#define LTC2990_TRIGGER\t0x02\n" + "> +#define LTC2990_TINT_MSB\t0x04\n" + "> +#define LTC2990_V1_MSB\t0x06\n" + "> +#define LTC2990_V2_MSB\t0x08\n" + "> +#define LTC2990_V3_MSB\t0x0A\n" + "> +#define LTC2990_V4_MSB\t0x0C\n" + "> +#define LTC2990_VCC_MSB\t0x0E\n" + "> +\n" + "> +#define LTC2990_CONTROL_KELVIN\t\tBIT(7)\n" + "> +#define LTC2990_CONTROL_SINGLE\t\tBIT(6)\n" + "> +#define LTC2990_CONTROL_MEASURE_ALL\t(0x3 << 3)\n" + "> +#define LTC2990_CONTROL_MODE_CURRENT\t0x06\n" + "> +#define LTC2990_CONTROL_MODE_VOLTAGE\t0x07\n" + "> +\n" + "> +/* convert raw register value to sign-extended integer in 16-bit range */\n" + "> +static int ltc2990_voltage_to_int(int raw)\n" + "> +{\n" + "> +\tif (raw & BIT(14))\n" + "> +\t\treturn -(0x4000 - (raw & 0x3FFF)) << 2;\n" + "> +\telse\n" + "> +\t\treturn (raw & 0x3FFF) << 2;\n" + "> +}\n" + "> +\n" + "> +/* Return the converted value from the given register in uV or mC */\n" + "> +static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, int *result)\n" + "> +{\n" + "> +\tint val;\n" + "> +\n" + "> +\tval = i2c_smbus_read_word_swapped(i2c, reg);\n" + "> +\tif (unlikely(val < 0))\n" + "> +\t\treturn val;\n" + "> +\n" + "> +\tswitch (reg) {\n" + "> +\tcase LTC2990_TINT_MSB:\n" + "> +\t\t/* internal temp, 0.0625 degrees/LSB, 13-bit */\n" + "> +\t\tval = (val & 0x1FFF) << 3;\n" + "> +\t\t*result = (val * 1000) >> 7;\n" + "> +\t\tbreak;\n" + "> +\tcase LTC2990_V1_MSB:\n" + "> +\tcase LTC2990_V3_MSB:\n" + "> +\t\t /* Vx-Vy, 19.42uV/LSB. Depends on mode. */\n" + "> +\t\t*result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);\n" + "> +\t\tbreak;\n" + "> +\tcase LTC2990_VCC_MSB:\n" + "> +\t\t/* Vcc, 305.18\316\274V/LSB, 2.5V offset */\n" + "> +\t\t*result = (ltc2990_voltage_to_int(val) * 30518 /\n" + "> +\t\t\t (4 * 100 * 1000)) + 2500;\n" + "> +\t\tbreak;\n" + "> +\tdefault:\n" + "> +\t\treturn -EINVAL; /* won't happen, keep compiler happy */\n" + "> +\t}\n" + "> +\n" + "> +\treturn 0;\n" + "> +}\n" + "> +\n" + "> +static ssize_t ltc2990_show_value(struct device *dev,\n" + "> +\t\t\t\t struct device_attribute *da, char *buf)\n" + "> +{\n" + "> +\tstruct sensor_device_attribute *attr = to_sensor_dev_attr(da);\n" + "> +\tint value;\n" + "> +\tint ret;\n" + "> +\n" + "> +\tret = ltc2990_get_value(dev_get_drvdata(dev), attr->index, &value);\n" + "> +\tif (unlikely(ret < 0))\n" + "> +\t\treturn ret;\n" + "> +\n" + "> +\treturn snprintf(buf, PAGE_SIZE, \"%d\\n\", value);\n" + "> +}\n" + "> +\n" + "> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,\n" + "> +\t\t\t LTC2990_TINT_MSB);\n" + "> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL,\n" + "> +\t\t\t LTC2990_V1_MSB);\n" + "> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL,\n" + "> +\t\t\t LTC2990_V3_MSB);\n" + "> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,\n" + "> +\t\t\t LTC2990_VCC_MSB);\n" + "> +\n" + "> +static struct attribute *ltc2990_attrs[] = {\n" + "> +\t&sensor_dev_attr_temp1_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_curr1_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_curr2_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in0_input.dev_attr.attr,\n" + "> +\tNULL,\n" + "> +};\n" + "> +ATTRIBUTE_GROUPS(ltc2990);\n" + "> +\n" + "> +static int ltc2990_i2c_probe(struct i2c_client *i2c,\n" + "> +\t\t\t const struct i2c_device_id *id)\n" + "> +{\n" + "> +\tint ret;\n" + "> +\tstruct device *hwmon_dev;\n" + "> +\n" + "> +\tif (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |\n" + "> +\t\t\t\t I2C_FUNC_SMBUS_WORD_DATA))\n" + "> +\t\treturn -ENODEV;\n" + "> +\n" + "> +\t/* Setup continuous mode, current monitor */\n" + "> +\tret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,\n" + "> +\t\t\t\t\tLTC2990_CONTROL_MEASURE_ALL |\n" + "> +\t\t\t\t\tLTC2990_CONTROL_MODE_CURRENT);\n" + "> +\tif (ret < 0) {\n" + "> +\t\tdev_err(&i2c->dev, \"Error: Failed to set control mode.\\n\");\n" + "> +\t\treturn ret;\n" + "> +\t}\n" + "> +\t/* Trigger once to start continuous conversion */\n" + "> +\tret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);\n" + "> +\tif (ret < 0) {\n" + "> +\t\tdev_err(&i2c->dev, \"Error: Failed to start acquisition.\\n\");\n" + "> +\t\treturn ret;\n" + "> +\t}\n" + "> +\n" + "> +\thwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,\n" + "> +\t\t\t\t\t\t\t i2c->name,\n" + "> +\t\t\t\t\t\t\t i2c,\n" + "> +\t\t\t\t\t\t\t ltc2990_groups);\n" + "> +\n" + "> +\treturn PTR_ERR_OR_ZERO(hwmon_dev);\n" + "> +}\n" + "> +\n" + "> +static const struct i2c_device_id ltc2990_i2c_id[] = {\n" + "> +\t{ \"ltc2990\", 0 },\n" + "> +\t{}\n" + "> +};\n" + "> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);\n" + "> +\n" + "> +static struct i2c_driver ltc2990_i2c_driver = {\n" + "> +\t.driver = {\n" + "> +\t\t.name = \"ltc2990\",\n" + "> +\t},\n" + "> +\t.probe = ltc2990_i2c_probe,\n" + "> +\t.id_table = ltc2990_i2c_id,\n" + "> +};\n" + "> +\n" + "> +module_i2c_driver(ltc2990_i2c_driver);\n" + "> +\n" + "> +MODULE_DESCRIPTION(\"LTC2990 Sensor Driver\");\n" + "> +MODULE_AUTHOR(\"Topic Embedded Products\");\n" + "> +MODULE_LICENSE(\"GPL v2\");\n" + > -e341c0ad953c6641405d10f420de1abb5d43719bd2639e52bef4e6c50b88617a +a01f7774ad388113a43407ae2d49d3314dfb4323b592713d74b4201638381585
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.