diff for duplicates of <56965661.2010307@topic.nl> diff --git a/a/1.txt b/N1/1.txt index e5efc27..20213cd 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,224 +1,385 @@ -77u/T24gMTMtMDEtMTYgMTQ6MjQsIEd1ZW50ZXIgUm9lY2sgd3JvdGU6Cj4gT24gMDEvMTMvMjAx -NiAwMzowNSBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4+IFRoaXMgYWRkcyBzdXBwb3J0IGZv -ciB0aGUgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCAgSTJDIFN5c3RlbSBNb25pdG9yLgo+PiBU -aGUgTFRDMjk5MCBzdXBwb3J0cyBhIGNvbWJpbmF0aW9uIG9mIHZvbHRhZ2UsIGN1cnJlbnQgYW5k -IHRlbXBlcmF0dXJlCj4+IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5IHN1 -cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4+IGJ5IG1lYXN1cmluZyB0d28gZGlmZmVyZW50 -aWFsIHZvbHRhZ2VzIGFjcm9zcyBzZXJpZXMgcmVzaXN0b3JzLCBpbgo+PiBhZGRpdGlvbiB0byB0 -aGUgVmNjIHN1cHBseSB2b2x0YWdlIGFuZCBpbnRlcm5hbCB0ZW1wZXJhdHVyZS4KPj4KPj4gVGhp -cyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRvcGljIE1pYW1pIFNPTSB3aGljaCB1c2Vz -IHRoaXMgY2hpcAo+PiB0byBtb25pdG9yIHRoZSBjdXJyZW50cyBmbG93aW5nIGludG8gdGhlIEZQ -R0EgYW5kIHRoZSBDUFUgcGFydHMuCj4+Cj4+IFNpZ25lZC1vZmYtYnk6IE1pa2UgTG9vaWptYW5z -IDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPgo+IE1pa2UsCj4KPiBUaGF0IGxvb2tzIG11Y2gg -YmV0dGVyLiBDYW4geW91IHNlbmQgbWUgdGhlIG91dHB1dCBvZiBpMmNkdW1wIGZvciB0aGUgY2hp -cCA/Cj4gVGhhdCB3b3VsZCBoZWxwIG1lIHdyaXRpbmcgbW9kdWxlIHRlc3QgY29kZSBmb3IgaXQu -CgpJJ20ga2luZGEgaW50ZXJlc3RlZCBpbnRvIGhvdyB0aGF0IHdvdWxkIHdvcmsuCgpJJ2xsIGhh -dmUgdG8gcmVtb3ZlIHRoZSBkcml2ZXIgZmlyc3QgdG8gZ2V0IGkyY2R1bXAgdG8gd29yayBvbiB0 -aGUgY2hpcC4gSSAKY2Fubm90IGZvcmNlIGEgZGV2aWNlIHJlbW92YWwgZnJvbSB1c2VyIHNwYWNl -IHdoaWxlIHJ1bm5pbmcsIGNhbiBJPwpBbmQgaSBzdXBwb3NlIHlvdSB3YW50IGEgZHVtcCBvZiBh -IGNoaXAgaW4gcnVubmluZyBzdGF0dXM/IChPbiBib290LCBhbGwgYXJlIApyZWdpc3RlcnMgYXJl -IHNpbXBseSBzZXQgdG8gemVybykKCgo+IFRoYW5rcywKPiBHdWVudGVyCj4KPj4gLS0tCj4+IHYy -OiBQcm9jZXNzZWQgYWxsIHJldmlldyBjb21tZW50cy4KPj4gICAgICBQdXQgY2hpcCBpbnRvIGNv -bnRpbnVvdXMgbWVhc3VyZW1lbnQgbW9kZS4KPj4gICAgICBBZGRlZCBkdWN1bWVudGF0aW9uLgo+ -PiAgICAgIFVzZSBzdGFuZGFyZCBod21vbiBpbnRlcmZhY2VzIGFuZCBtYWNyb3MuCj4+Cj4+ICAg -RG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwIHwgIDQ0ICsrKysrKysrKysrKwo+PiAgIGRyaXZl -cnMvaHdtb24vS2NvbmZpZyAgICAgICB8ICAxNCArKysrCj4+ICAgZHJpdmVycy9od21vbi9NYWtl -ZmlsZSAgICAgIHwgICAxICsKPj4gICBkcml2ZXJzL2h3bW9uL2x0YzI5OTAuYyAgICAgfCAxNjAK -Pj4gKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPj4gICA0IGZp -bGVzIGNoYW5nZWQsIDIxOSBpbnNlcnRpb25zKCspCj4+ICAgY3JlYXRlIG1vZGUgMTAwNjQ0IERv -Y3VtZW50YXRpb24vaHdtb24vbHRjMjk5MAo+PiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJz -L2h3bW9uL2x0YzI5OTAuYwo+Pgo+PiBkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9od21vbi9s -dGMyOTkwIGIvRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCj4+IG5ldyBmaWxlIG1vZGUgMTAw -NjQ0Cj4+IGluZGV4IDAwMDAwMDAuLjgzOGI3NGUKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9E -b2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPj4gQEAgLTAsMCArMSw0NCBAQAo+PiArS2VybmVs -IGRyaXZlciBsdGMyOTkwCj4+ICs9PT09PT09PT09PT09PT09PT09PT0KPj4gKwo+PiArU3VwcG9y -dGVkIGNoaXBzOgo+PiArICAqIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAKPj4gKyAgICBQcmVm -aXg6ICdsdGMyOTkwJwo+PiArICAgIEFkZHJlc3NlcyBzY2FubmVkOiAtCj4+ICsgICAgRGF0YXNo -ZWV0OiBodHRwOi8vd3d3LmxpbmVhci5jb20vcHJvZHVjdC9sdGMyOTkwCj4+ICsKPj4gK0F1dGhv -cjogTWlrZSBMb29pam1hbnMgPG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgo+PiArCj4+ICsKPj4g -K0Rlc2NyaXB0aW9uCj4+ICstLS0tLS0tLS0tLQo+PiArCj4+ICtMVEMyOTkwIGlzIGEgUXVhZCBJ -MkMgVm9sdGFnZSwgQ3VycmVudCBhbmQgVGVtcGVyYXR1cmUgTW9uaXRvci4KPj4gK1RoZSBjaGlw -J3MgaW5wdXRzIGNhbiBtZWFzdXJlIDQgdm9sdGFnZXMsIG9yIHR3byBpbnB1dHMgdG9nZXRoZXIg -KDErMiBhbmQgMys0KQo+PiArY2FuIGJlIGNvbWJpbmVkIHRvIG1lYXN1cmUgYSBkaWZmZXJlbnRp -YWwgdm9sdGFnZSwgd2hpY2ggaXMgdHlwaWNhbGx5IHVzZWQgdG8KPj4gK21lYXN1cmUgY3VycmVu -dCB0aHJvdWdoIGEgc2VyaWVzIHJlc2lzdG9yLCBvciBhIHRlbXBlcmF0dXJlLgo+PiArCj4+ICtU -aGlzIGRyaXZlciBjdXJyZW50bHkgdXNlcyB0aGUgMnggZGlmZmVyZW50aWFsIG1vZGUgb25seS4g -SW4gb3JkZXIgdG8gc3VwcG9ydAo+PiArb3RoZXIgbW9kZXMsIHRoZSBkcml2ZXIgd2lsbCBuZWVk -IHRvIGJlIGV4cGFuZGVkLgo+PiArCj4+ICsKPj4gK1VzYWdlIE5vdGVzCj4+ICstLS0tLS0tLS0t -LQo+PiArCj4+ICtUaGlzIGRyaXZlciBkb2VzIG5vdCBwcm9iZSBmb3IgUE1CdXMgZGV2aWNlcy4g -WW91IHdpbGwgaGF2ZSB0byBpbnN0YW50aWF0ZQo+PiArZGV2aWNlcyBleHBsaWNpdGx5Lgo+PiAr -Cj4+ICsKPj4gK1N5c2ZzIGF0dHJpYnV0ZXMKPj4gKy0tLS0tLS0tLS0tLS0tLS0KPj4gKwo+PiAr -VGhlICJjdXJyKl9pbnB1dCIgbWVhc3VyZW1lbnRzIGFjdHVhbGx5IHJlcG9ydCB0aGUgdm9sdGFn -ZSBkcm9wIGFjcm9zcyB0aGUKPj4gK2lucHV0IHBpbnMgaW4gbWljcm92b2x0cy4gVGhpcyBpcyBl -cXVpdmFsZW50IHRvIHRoZSBjdXJyZW50IHRocm91Z2ggYSAxbU9obQo+PiArc2Vuc2UgcmVzaXN0 -b3IuIERpdmlkZSB0aGUgcmVwb3J0ZWQgdmFsdWUgYnkgdGhlIGFjdHVhbCBzZW5zZSByZXNpc3Rv -ciB2YWx1ZQo+PiAraW4gbU9obSB0byBnZXQgdGhlIGFjdHVhbCB2YWx1ZS4KPj4gKwo+PiAraW4w -X2lucHV0ICAgICBWb2x0YWdlIGF0IFZjYyBwaW4gaW4gbWlsbGl2b2x0IChyYW5nZSAyLjVWIHRv -IDVWKQo+PiArdGVtcDFfaW5wdXQgICBJbnRlcm5hbCBjaGlwIHRlbXBlcmF0dXJlIGluIG1pbGxp -ZGVncmVlcyBDZWxjaXVzCj4+ICtjdXJyMV9pbnB1dCAgIEN1cnJlbnQgaW4gbUEgYWNyb3NzIHYx -LXYyIGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3IuCj4+ICtjdXJyMl9pbnB1dCAgIEN1 -cnJlbnQgaW4gbUEgYWNyb3NzIHYzLXY0IGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3Iu -Cj4+ICsKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMvaHdt -b24vS2NvbmZpZwo+PiBpbmRleCA4MGE3M2JmLi44YTMxZDY0IDEwMDY0NAo+PiAtLS0gYS9kcml2 -ZXJzL2h3bW9uL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4+IEBAIC02 -ODUsNiArNjg1LDIwIEBAIGNvbmZpZyBTRU5TT1JTX0xUQzI5NDUKPj4gICAgICAgICBUaGlzIGRy -aXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2ls -bAo+PiAgICAgICAgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Pgo+PiArY29uZmlnIFNFTlNPUlNfTFRD -Mjk5MAo+PiArICAgIHRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50 -IG1vbml0b3JpbmcgbW9kZSBvbmx5KSIKPj4gKyAgICBkZXBlbmRzIG9uIEkyQwo+PiArICAgIGhl -bHAKPj4gKyAgICAgIElmIHlvdSBzYXkgeWVzIGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciBMaW5l -YXIgVGVjaG5vbG9neSBMVEMyOTkwCj4+ICsgICAgICBJMkMgU3lzdGVtIE1vbml0b3IuIFRoZSBM -VEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9sdGFnZSwKPj4gKyAgICAgIGN1cnJl -bnQgYW5kIHRlbXBlcmF0dXJlIG1vbml0b3JpbmcsIGJ1dCBpbiBhZGRpdGlvbiB0byB0aGUgVmNj -IHN1cHBseQo+PiArICAgICAgdm9sdGFnZSBhbmQgY2hpcCB0ZW1wZXJhdHVyZSwgdGhpcyBkcml2 -ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMKPj4gKyAgICAgIHJlYWRpbmcgdHdvIGN1cnJlbnRz -IGJ5IG1lYXN1cmluZyB0d28gZGlmZmVyZW50aWFsIHZvbHRhZ2VzIGFjcm9zcwo+PiArICAgICAg -c2VyaWVzIHJlc2lzdG9ycy4KPj4gKwo+PiArICAgICAgVGhpcyBkcml2ZXIgY2FuIGFsc28gYmUg -YnVpbHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwKPj4gKyAgICAgIGJlIGNh -bGxlZCBsdGMyOTkwLgo+PiArCj4+ICAgY29uZmlnIFNFTlNPUlNfTFRDNDE1MQo+PiAgICAgICB0 -cmlzdGF0ZSAiTGluZWFyIFRlY2hub2xvZ3kgTFRDNDE1MSIKPj4gICAgICAgZGVwZW5kcyBvbiBJ -MkMKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9u -L01ha2VmaWxlCj4+IGluZGV4IDEyYTMyMzkuLmU0YmQxNWIgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZl -cnMvaHdtb24vTWFrZWZpbGUKPj4gKysrIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+PiBAQCAt -MTAxLDYgKzEwMSw3IEBAIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyMzQpICAgICs9IGxtOTUy -MzQubwo+PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDEpICAgICs9IGxtOTUyNDEubwo+ -PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDUpICAgICs9IGxtOTUyNDUubwo+PiAgIG9i -ai0kKENPTkZJR19TRU5TT1JTX0xUQzI5NDUpICAgICs9IGx0YzI5NDUubwo+PiArb2JqLSQoQ09O -RklHX1NFTlNPUlNfTFRDMjk5MCkgICAgKz0gbHRjMjk5MC5vCj4+ICAgb2JqLSQoQ09ORklHX1NF -TlNPUlNfTFRDNDE1MSkgICAgKz0gbHRjNDE1MS5vCj4+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNf -TFRDNDIxNSkgICAgKz0gbHRjNDIxNS5vCj4+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDIy -MikgICAgKz0gbHRjNDIyMi5vCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL2x0YzI5OTAu -YyBiL2RyaXZlcnMvaHdtb24vbHRjMjk5MC5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGlu -ZGV4IDAwMDAwMDAuLjM3MjBmZjcKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL2h3 -bW9uL2x0YzI5OTAuYwo+PiBAQCAtMCwwICsxLDE2MCBAQAo+PiArLyoKPj4gKyAqIERyaXZlciBm -b3IgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCBwb3dlciBtb25pdG9yCj4+ICsgKgo+PiArICog -Q29weXJpZ2h0IChDKSAyMDE0IFRvcGljIEVtYmVkZGVkIFByb2R1Y3RzCj4+ICsgKiBBdXRob3I6 -IE1pa2UgTG9vaWptYW5zIDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPj4gKyAqCj4+ICsgKiBM -aWNlbnNlOiBHUEx2Mgo+PiArICoKPj4gKyAqIFRoaXMgZHJpdmVyIGFzc3VtZXMgdGhlIGNoaXAg -aXMgd2lyZWQgYXMgYSBkdWFsIGN1cnJlbnQgbW9uaXRvciwgYW5kCj4+ICsgKiByZXBvcnRzIHRo -ZSB2b2x0YWdlIGRyb3AgYWNyb3NzIHR3byBzZXJpZXMgcmVzaXN0b3JzLiBJdCBhbHNvIHJlcG9y -dHMKPj4gKyAqIHRoZSBjaGlwJ3MgaW50ZXJuYWwgdGVtcGVyYXR1cmUgYW5kIFZjYyBwb3dlciBz -dXBwbHkgdm9sdGFnZS4KPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgvZGVsYXkuaD4K -Ck5vdCBuZWVkZWQsIHdpbGwgYmUgcmVtb3ZlZCBpbiB2MwoKPj4gKyNpbmNsdWRlIDxsaW51eC9l -cnIuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9od21vbi5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2h3 -bW9uLXN5c2ZzLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvaTJjLmg+Cj4+ICsjaW5jbHVkZSA8bGlu -dXgva2VybmVsLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+ICsjaW5jbHVkZSA8 -bGludXgvc2xhYi5oPgoKTm90IG5lZWRlZAoKPj4gKwo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRV -UyAgICAweDAwCj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTCAgICAweDAxCj4+ICsjZGVmaW5l -IExUQzI5OTBfVFJJR0dFUiAgICAweDAyCj4+ICsjZGVmaW5lIExUQzI5OTBfVElOVF9NU0IgICAg -MHgwNAo+PiArI2RlZmluZSBMVEMyOTkwX1RJTlRfTFNCICAgIDB4MDUKPj4gKyNkZWZpbmUgTFRD -Mjk5MF9WMV9NU0IgICAgMHgwNgo+PiArI2RlZmluZSBMVEMyOTkwX1YxX0xTQiAgICAweDA3Cj4+ -ICsjZGVmaW5lIExUQzI5OTBfVjJfTVNCICAgIDB4MDgKPj4gKyNkZWZpbmUgTFRDMjk5MF9WMl9M -U0IgICAgMHgwOQo+PiArI2RlZmluZSBMVEMyOTkwX1YzX01TQiAgICAweDBBCj4+ICsjZGVmaW5l -IExUQzI5OTBfVjNfTFNCICAgIDB4MEIKPj4gKyNkZWZpbmUgTFRDMjk5MF9WNF9NU0IgICAgMHgw -Qwo+PiArI2RlZmluZSBMVEMyOTkwX1Y0X0xTQiAgICAweDBECj4+ICsjZGVmaW5lIExUQzI5OTBf -VkNDX01TQiAgICAweDBFCj4+ICsjZGVmaW5lIExUQzI5OTBfVkNDX0xTQiAgICAweDBGCj4+ICsK -Pgo+IExTQiBub3QgdXNlZC4KCkFncmVlLiBXaWxsIHJlbW92ZSB0aGVtLCBpdCdzIGNsdXR0ZXIu -Cgo+Cj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX0JVU1kgICAgQklUKDApCj4+ICsjZGVmaW5l -IExUQzI5OTBfU1RBVFVTX1RJTlQgICAgQklUKDEpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVT -X1YxICAgIEJJVCgyKQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WMiAgICBCSVQoMykKPj4g -KyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVjMgICAgQklUKDQpCj4+ICsjZGVmaW5lIExUQzI5OTBf -U1RBVFVTX1Y0ICAgIEJJVCg1KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WQ0MgICAgQklU -KDYpCj4+ICsKPiBObyBsb25nZXIgdXNlZCA/CgpObyBuZWVkIGZvciBzdGF0dXMgcmVhZCB3aGVu -IGluIGNvbnRpbnVvdXMgbW9kZSwgc28gdGhleSBoYXZlIG5vIHBvaW50IGJlaW5nIGhlcmUuCgo+ -Cj4+ICsvKiBPbmx5IGRlZmluZSBjb250cm9sIHNldHRpbmdzIHdlIGFjdHVhbGx5IHVzZSAqLwo+ -Cj4gSG1tbSAuLi4gYnV0IG5vdCBhbGwgYXJlIHVzZWQuCgpJIHRoaW5rIGl0J3MgYmV0dGVyIHRv -IHJlbW92ZSB0aGF0IGNvbW1lbnQgOikKCj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9LRUxW -SU4gICAgICAgIEJJVCg3KQo+PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0xfU0lOR0xFICAgICAg -ICBCSVQoNikKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01FQVNVUkVfQUxMICAgICgweDMg -PDwgMykKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVCAgICAweDA2Cj4+ -ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RFX1ZPTFRBR0UgICAgMHgwNwo+PiArCj4+ICsv -KiBjb252ZXJ0IHJhdyByZWdpc3RlciB2YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4g -MTYtYml0IHJhbmdlICovCj4+ICtzdGF0aWMgaW50IGx0YzI5OTBfdm9sdGFnZV90b19pbnQoaW50 -IHJhdykKPj4gK3sKPj4gKyAgICBpZiAocmF3ICYgQklUKDE0KSkgewo+PiArICAgICAgICByZXR1 -cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZGKSkgPDwgMjsKPj4gKyAgICB9IGVsc2Ugewo+PiAr -ICAgICAgICByZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKPj4gKyAgICB9Cj4+ICt9Cj4+ICsK -Pj4gKy8qIFJldHVybiB0aGUgY29udmVydGVkIHZhbHVlIGZyb20gdGhlIGdpdmVuIHJlZ2lzdGVy -IGluIHVWIG9yIG1DICovCj4+ICtzdGF0aWMgaW50IGx0YzI5OTBfZ2V0X3ZhbHVlKHN0cnVjdCBp -MmNfY2xpZW50ICppMmMsIHU4IGluZGV4KQo+PiArewo+PiArICAgIGludCB2YWw7Cj4+ICsgICAg -aW50IHJlc3VsdDsKPj4gKwo+PiArICAgIHZhbCA9IGkyY19zbWJ1c19yZWFkX3dvcmRfc3dhcHBl -ZChpMmMsIChpbmRleCA8PCAxKSArIExUQzI5OTBfVElOVF9NU0IpOwo+PiArICAgIGlmICh1bmxp -a2VseSh2YWwgPCAwKSkKPj4gKyAgICAgICAgcmV0dXJuIHZhbDsKPj4gKwo+PiArICAgIGlmIChp -bmRleCA9PSAwKSB7IC8qIGludGVybmFsIHRlbXAsIDAuMDYyNSBkZWdyZWVzL0xTQiwgMTMtYml0 -ICAqLwo+PiArICAgICAgICB2YWwgPSAodmFsICYgMHgxRkZGKSA8PCAzOwo+PiArICAgICAgICBy -ZXN1bHQgPSAodmFsICogMTAwMCkgPj4gNzsKPj4gKyAgICB9IGVsc2UgaWYgKGluZGV4IDwgNSkg -eyAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IgKi8KPj4gKyAgICAgICAgcmVzdWx0ID0gbHRjMjk5MF92 -b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICogMTAwKTsKPj4gKyAgICB9IGVsc2UgeyAv -KiBWY2MsIDMwNS4xOM68Vi9MU0IsIDIuNVYgb2Zmc2V0ICovCj4+ICsgICAgICAgIHJlc3VsdCA9 -IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDMwNTE4IC8gKDQgKiAxMDAgKiAxMDAwKTsK -Pj4gKyAgICAgICAgcmVzdWx0ICs9IDI1MDA7Cj4+ICsgICAgfQo+PiArCj4gV2l0aCB0aGUgcmVn -aXN0ZXIgaW4gaW5kZXggKHNlZSBiZWxvdykgdGhpcyBjb3VsZCBiZQo+Cj4gICAgICB2YWwgPSBp -MmNfc21idXNfcmVhZF93b3JkX3N3YXBwZWQoaTJjLCBpbmRleCk7Cj4KPiAgICAgIHN3aXRjaCAo -aW5kZXgpIHsKPiAgICAgIGNhc2UgTFRDMjk5MF9USU5UX01TQjoKPiAgICAgICAgICB2YWwgPSAo -dmFsICYgMHgxRkZGKSA8PCAzOwo+ICAgICAgICAgIHJlc3VsdCA9ICh2YWwgKiAxMDAwKSA+PiA3 -Owo+ICAgICAgICAgIGJyZWFrOwo+ICAgICAgY2FzZSBMVEMyOTkwX1YxX01TQjoKPiAgICAgIGNh -c2UgTFRDMjk5MF9WMl9NU0I6Cj4gICAgICAgICAgLi4uCj4gICAgICAgICAgcmVzdWx0ID0gbHRj -Mjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICogMTAwKTsKPiAgICAgICAgICBi -cmVhazsKPiAgICAgIGNhc2UgTFRDMjk5MF9WQ0NfTVNCOgo+ICAgICAgICAgIHJlc3VsdCA9IGx0 -YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDMwNTE4IC8gKDQgKiAxMDAgKiAxMDAwKTsKPiAg -ICAgICAgICByZXN1bHQgKz0gMjUwMDsKPiAgICAgICAgICBicmVhazsKPiAgICAgIGRlZmF1bHQ6 -Cj4gICAgICAgICAgcmVzdWx0ID0gMDsgICAgLyogd29uJ3QgaGFwcGVuLCBtYWtlcyBjb21waWxl -ciBoYXBweSAqLwo+ICAgICAgICAgIGJyZWFrOwo+ICAgICAgfQo+Cj4gd2hpY2ggSSB0aGluayB3 -b3VsZCBiZSBlYXNpZXIgdG8gdW5kZXJzdGFuZC4KCkFncmVlLCBnb29kIHBvaW50LiBBbHNvIHVz -aW5nIHRoZSByZWdpc3RlciBuYW1lcyBoZWxwcyByZWFkYWJpbGl0eS4KCj4+ICsgICAgcmV0dXJu -IHJlc3VsdDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHNzaXplX3QgbHRjMjk5MF9zaG93X3ZhbHVl -KHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKyAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2Vf -YXR0cmlidXRlICpkYSwgY2hhciAqYnVmKQo+PiArewo+PiArICAgIHN0cnVjdCBzZW5zb3JfZGV2 -aWNlX2F0dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4+ICsgICAgaW50 -IHZhbHVlOwo+PiArCj4+ICsgICAgdmFsdWUgPSBsdGMyOTkwX2dldF92YWx1ZShkZXZfZ2V0X2Ry -dmRhdGEoZGV2KSwgYXR0ci0+aW5kZXgpOwo+PiArICAgIHJldHVybiBzbnByaW50ZihidWYsIFBB -R0VfU0laRSwgIiVkXG4iLCB2YWx1ZSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBTRU5TT1JfREVW -SUNFX0FUVFIodGVtcDFfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwg -MCk7Cj4+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKGN1cnIxX2lucHV0LCBTX0lSVUdPLCBs -dGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsIDEpOwo+PiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU -UihjdXJyMl9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLCAzKTsKPj4g -K3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2lucHV0LCBTX0lSVUdPLCBsdGMyOTkwX3No -b3dfdmFsdWUsIE5VTEwsIDUpOwo+Cj4gQ29uc2lkZXIgcHJvdmlkaW5nIHRoZSByZWdpc3RlciBN -U0IgaW4gaW5kZXguCj4KPiBFeGFtcGxlOgo+ICAgICAgc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU -Uih0ZW1wMV9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+IExUQzI5 -OTBfVElOVF9NU0IpOwoKQWdyZWUsIGFzIGFib3ZlLgoKPj4gKwo+PiArc3RhdGljIHN0cnVjdCBh -dHRyaWJ1dGUgKmx0YzI5OTBfYXR0cnNbXSA9IHsKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX3Rl -bXAxX2lucHV0LmRldl9hdHRyLmF0dHIsCj4+ICsgICAgJnNlbnNvcl9kZXZfYXR0cl9jdXJyMV9p -bnB1dC5kZXZfYXR0ci5hdHRyLAo+PiArICAgICZzZW5zb3JfZGV2X2F0dHJfY3VycjJfaW5wdXQu -ZGV2X2F0dHIuYXR0ciwKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX2luMF9pbnB1dC5kZXZfYXR0 -ci5hdHRyLAo+PiArICAgIE5VTEwsCj4+ICt9Owo+PiArQVRUUklCVVRFX0dST1VQUyhsdGMyOTkw -KTsKPj4gKwo+PiArc3RhdGljIGludCBsdGMyOTkwX2kyY19wcm9iZShzdHJ1Y3QgaTJjX2NsaWVu -dCAqaTJjLAo+PiArICAgIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkICppZCkKPgo+IFBsZWFz -ZSBhbGlnbiBjb250aW51YXRpb24gbGluZXMgd2l0aCAnKCcuCj4KPj4gK3sKPj4gKyAgICBpbnQg -cmV0Owo+PiArICAgIHN0cnVjdCBkZXZpY2UgKmh3bW9uX2RldjsKPj4gKwo+PiArICAgIGlmICgh -aTJjX2NoZWNrX2Z1bmN0aW9uYWxpdHkoaTJjLT5hZGFwdGVyLCBJMkNfRlVOQ19TTUJVU19CWVRF -X0RBVEEpKQo+Cj4gQWxzbyBuZWVkIGNhcGFiaWxpdHkgdG8gcmVhZCB3b3Jkcy4KCkd1ZXNzIHNv -Li4uCgo+Cj4+ICsgICAgICAgIHJldHVybiAtRU5PREVWOwo+PiArCj4+ICsgICAgLyogU2V0dXAg -Y29udGludW91cyBtb2RlLCBjdXJyZW50IG1vbml0b3IgKi8KPj4gKyAgICByZXQgPSBpMmNfc21i -dXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9DT05UUk9MLAo+PiArICAgICAgICBMVEMy -OTkwX0NPTlRST0xfTUVBU1VSRV9BTEwgfCBMVEMyOTkwX0NPTlRST0xfTU9ERV9DVVJSRU5UKTsK -Pj4gKyAgICBpZiAocmV0IDwgMCkgewo+PiArICAgICAgICBkZXZfZXJyKCZpMmMtPmRldiwgIkVy -cm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+PiArICAgICAgICByZXR1cm4g -cmV0Owo+PiArICAgIH0KPj4gKyAgICAvKiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91 -cyBjb252ZXJzaW9uICovCj4+ICsgICAgcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShp -MmMsIExUQzI5OTBfVFJJR0dFUiwgMSk7Cj4+ICsgICAgaWYgKHJldCA8IDApIHsKPj4gKyAgICAg -ICAgZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRvIHN0YXJ0IGFxdWlzaXRpb24u -XG4iKTsKPgo+IHMvYXF1aXNpdGlvbi9hY3F1aXNpdGlvbi8KPgo+PiArICAgICAgICByZXR1cm4g -cmV0Owo+PiArICAgIH0KPj4gKwo+PiArICAgIGh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNl -X3JlZ2lzdGVyX3dpdGhfZ3JvdXBzKCZpMmMtPmRldiwKPj4gKyAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICBpMmMtPm5hbWUsCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -aTJjLAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx0YzI5OTBfZ3JvdXBzKTsK -Pj4gKwo+PiArICAgIHJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25fZGV2KTsKPj4gK30KPj4g -Kwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkIGx0YzI5OTBfaTJjX2lkW10g -PSB7Cj4+ICsgICAgeyAibHRjMjk5MCIsIDAgfSwKPj4gKyAgICB7fQo+PiArfTsKPj4gK01PRFVM -RV9ERVZJQ0VfVEFCTEUoaTJjLCBsdGMyOTkwX2kyY19pZCk7Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1 -Y3QgaTJjX2RyaXZlciBsdGMyOTkwX2kyY19kcml2ZXIgPSB7Cj4+ICsgICAgLmRyaXZlciA9IHsK -Pj4gKyAgICAgICAgLm5hbWUgPSAibHRjMjk5MCIsCj4+ICsgICAgfSwKPj4gKyAgICAucHJvYmUg -ICAgPSBsdGMyOTkwX2kyY19wcm9iZSwKPj4gKyAgICAuaWRfdGFibGUgPSBsdGMyOTkwX2kyY19p -ZCwKPj4gK307Cj4+ICsKPj4gK21vZHVsZV9pMmNfZHJpdmVyKGx0YzI5OTBfaTJjX2RyaXZlcik7 -Cj4+ICsKPj4gK01PRFVMRV9ERVNDUklQVElPTigiTFRDMjk5MCBTZW5zb3IgRHJpdmVyIik7Cj4+ -ICtNT0RVTEVfQVVUSE9SKCJUb3BpYyBFbWJlZGRlZCBQcm9kdWN0cyIpOwo+PiArTU9EVUxFX0xJ -Q0VOU0UoIkdQTCB2MiIpOwo+Pgo+CgoKCktpbmQgcmVnYXJkcywKCk1pa2UgTG9vaWptYW5zClN5 -c3RlbSBFeHBlcnQKClRPUElDIEVtYmVkZGVkIFByb2R1Y3RzCkVpbmRob3ZlbnNld2VnIDMyLUMs -IE5MLTU2ODMgS0ggQmVzdApQb3N0YnVzIDQ0MCwgTkwtNTY4MCBBSyBCZXN0ClRlbGVmb29uOiAr -MzEgKDApIDQ5OSAzMyA2OSA3OQpFLW1haWw6IG1pa2UubG9vaWptYW5zQHRvcGljcHJvZHVjdHMu -Y29tCldlYnNpdGU6IHd3dy50b3BpY3Byb2R1Y3RzLmNvbQoKUGxlYXNlIGNvbnNpZGVyIHRoZSBl -bnZpcm9ubWVudCBiZWZvcmUgcHJpbnRpbmcgdGhpcyBlLW1haWwKCgoKCgoKX19fX19fX19fX19f -X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vuc29ycyBtYWlsaW5nIGxp -c3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMubG0tc2Vuc29ycy5vcmcv -bWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz +On 13-01-16 14:24, Guenter Roeck wrote: +> On 01/13/2016 03:05 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> +> +> Mike, +> +> That looks much better. Can you send me the output of i2cdump for the chip ? +> That would help me writing module test code for it. + +I'm kinda interested into how that would work. + +I'll have to remove the driver first to get i2cdump to work on the chip. I +cannot force a device removal from user space while running, can I? +And i suppose you want a dump of a chip in running status? (On boot, all are +registers are simply set to zero) + + +> Thanks, +> Guenter +> +>> --- +>> 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 | 160 +>> ++++++++++++++++++++++++++++++++++++++++++++ +>> 4 files changed, 219 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..3720ff7 +>> --- /dev/null +>> +++ b/drivers/hwmon/ltc2990.c +>> @@ -0,0 +1,160 @@ +>> +/* +>> + * 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/delay.h> + +Not needed, will be removed in v3 + +>> +#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> +>> +#include <linux/slab.h> + +Not needed + +>> + +>> +#define LTC2990_STATUS 0x00 +>> +#define LTC2990_CONTROL 0x01 +>> +#define LTC2990_TRIGGER 0x02 +>> +#define LTC2990_TINT_MSB 0x04 +>> +#define LTC2990_TINT_LSB 0x05 +>> +#define LTC2990_V1_MSB 0x06 +>> +#define LTC2990_V1_LSB 0x07 +>> +#define LTC2990_V2_MSB 0x08 +>> +#define LTC2990_V2_LSB 0x09 +>> +#define LTC2990_V3_MSB 0x0A +>> +#define LTC2990_V3_LSB 0x0B +>> +#define LTC2990_V4_MSB 0x0C +>> +#define LTC2990_V4_LSB 0x0D +>> +#define LTC2990_VCC_MSB 0x0E +>> +#define LTC2990_VCC_LSB 0x0F +>> + +> +> LSB not used. + +Agree. Will remove them, it's clutter. + +> +>> +#define LTC2990_STATUS_BUSY BIT(0) +>> +#define LTC2990_STATUS_TINT BIT(1) +>> +#define LTC2990_STATUS_V1 BIT(2) +>> +#define LTC2990_STATUS_V2 BIT(3) +>> +#define LTC2990_STATUS_V3 BIT(4) +>> +#define LTC2990_STATUS_V4 BIT(5) +>> +#define LTC2990_STATUS_VCC BIT(6) +>> + +> No longer used ? + +No need for status read when in continuous mode, so they have no point being here. + +> +>> +/* Only define control settings we actually use */ +> +> Hmmm ... but not all are used. + +I think it's better to remove that comment :) + +>> +#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 index) +>> +{ +>> + int val; +>> + int result; +>> + +>> + val = i2c_smbus_read_word_swapped(i2c, (index << 1) + LTC2990_TINT_MSB); +>> + if (unlikely(val < 0)) +>> + return val; +>> + +>> + if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 13-bit */ +>> + val = (val & 0x1FFF) << 3; +>> + result = (val * 1000) >> 7; +>> + } else if (index < 5) { /* Vx-Vy, 19.42uV/LSB */ +>> + result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100); +>> + } else { /* Vcc, 305.18μV/LSB, 2.5V offset */ +>> + result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000); +>> + result += 2500; +>> + } +>> + +> With the register in index (see below) this could be +> +> val = i2c_smbus_read_word_swapped(i2c, index); +> +> switch (index) { +> case LTC2990_TINT_MSB: +> val = (val & 0x1FFF) << 3; +> result = (val * 1000) >> 7; +> break; +> case LTC2990_V1_MSB: +> case LTC2990_V2_MSB: +> ... +> result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100); +> break; +> case LTC2990_VCC_MSB: +> result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000); +> result += 2500; +> break; +> default: +> result = 0; /* won't happen, makes compiler happy */ +> break; +> } +> +> which I think would be easier to understand. + +Agree, good point. Also using the register names helps readability. + +>> + return result; +>> +} +>> + +>> +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; +>> + +>> + value = ltc2990_get_value(dev_get_drvdata(dev), attr->index); +>> + return snprintf(buf, PAGE_SIZE, "%d\n", value); +>> +} +>> + +>> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL, 0); +>> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL, 1); +>> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL, 3); +>> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL, 5); +> +> Consider providing the register MSB in index. +> +> Example: +> static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL, +> LTC2990_TINT_MSB); + +Agree, as above. + +>> + +>> +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) +> +> Please align continuation lines with '('. +> +>> +{ +>> + int ret; +>> + struct device *hwmon_dev; +>> + +>> + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) +> +> Also need capability to read words. + +Guess so... + +> +>> + 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 aquisition.\n"); +> +> s/aquisition/acquisition/ +> +>> + 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"); +>> +> + + + +Kind regards, + +Mike Looijmans +System Expert + +TOPIC Embedded Products +Eindhovenseweg 32-C, NL-5683 KH Best +Postbus 440, NL-5680 AK Best +Telefoon: +31 (0) 499 33 69 79 +E-mail: mike.looijmans@topicproducts.com +Website: www.topicproducts.com + +Please consider the environment before printing this e-mail diff --git a/a/content_digest b/N1/content_digest index 8a7f581..a281704 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -3,237 +3,398 @@ "ref\01452683150-27747-1-git-send-email-mike.looijmans@topic.nl\0" "ref\05696500E.4090905@roeck-us.net\0" "From\0Mike Looijmans <mike.looijmans@topic.nl>\0" - "Subject\0Re: [lm-sensors] [PATCH v2] hwmon: Add LTC2990 sensor driver\0" - "Date\0Wed, 13 Jan 2016 13:51:29 +0000\0" + "Subject\0Re: [PATCH v2] hwmon: Add LTC2990 sensor driver\0" + "Date\0Wed, 13 Jan 2016 14:51:29 +0100\0" "To\0Guenter Roeck <linux@roeck-us.net>" - " lm-sensors@lm-sensors.org\0" - "Cc\0jdelvare@suse.com" - " linux-kernel@vger.kernel.org\0" + " <lm-sensors@lm-sensors.org>\0" + "Cc\0<jdelvare@suse.com>" + " <linux-kernel@vger.kernel.org>\0" "\00:1\0" "b\0" - "77u/T24gMTMtMDEtMTYgMTQ6MjQsIEd1ZW50ZXIgUm9lY2sgd3JvdGU6Cj4gT24gMDEvMTMvMjAx\n" - "NiAwMzowNSBBTSwgTWlrZSBMb29pam1hbnMgd3JvdGU6Cj4+IFRoaXMgYWRkcyBzdXBwb3J0IGZv\n" - "ciB0aGUgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCAgSTJDIFN5c3RlbSBNb25pdG9yLgo+PiBU\n" - "aGUgTFRDMjk5MCBzdXBwb3J0cyBhIGNvbWJpbmF0aW9uIG9mIHZvbHRhZ2UsIGN1cnJlbnQgYW5k\n" - "IHRlbXBlcmF0dXJlCj4+IG1vbml0b3JpbmcuIFRoaXMgZHJpdmVyIGN1cnJlbnRseSBvbmx5IHN1\n" - "cHBvcnRzIHJlYWRpbmcgdHdvIGN1cnJlbnRzCj4+IGJ5IG1lYXN1cmluZyB0d28gZGlmZmVyZW50\n" - "aWFsIHZvbHRhZ2VzIGFjcm9zcyBzZXJpZXMgcmVzaXN0b3JzLCBpbgo+PiBhZGRpdGlvbiB0byB0\n" - "aGUgVmNjIHN1cHBseSB2b2x0YWdlIGFuZCBpbnRlcm5hbCB0ZW1wZXJhdHVyZS4KPj4KPj4gVGhp\n" - "cyBpcyBzdWZmaWNpZW50IHRvIHN1cHBvcnQgdGhlIFRvcGljIE1pYW1pIFNPTSB3aGljaCB1c2Vz\n" - "IHRoaXMgY2hpcAo+PiB0byBtb25pdG9yIHRoZSBjdXJyZW50cyBmbG93aW5nIGludG8gdGhlIEZQ\n" - "R0EgYW5kIHRoZSBDUFUgcGFydHMuCj4+Cj4+IFNpZ25lZC1vZmYtYnk6IE1pa2UgTG9vaWptYW5z\n" - "IDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPgo+IE1pa2UsCj4KPiBUaGF0IGxvb2tzIG11Y2gg\n" - "YmV0dGVyLiBDYW4geW91IHNlbmQgbWUgdGhlIG91dHB1dCBvZiBpMmNkdW1wIGZvciB0aGUgY2hp\n" - "cCA/Cj4gVGhhdCB3b3VsZCBoZWxwIG1lIHdyaXRpbmcgbW9kdWxlIHRlc3QgY29kZSBmb3IgaXQu\n" - "CgpJJ20ga2luZGEgaW50ZXJlc3RlZCBpbnRvIGhvdyB0aGF0IHdvdWxkIHdvcmsuCgpJJ2xsIGhh\n" - "dmUgdG8gcmVtb3ZlIHRoZSBkcml2ZXIgZmlyc3QgdG8gZ2V0IGkyY2R1bXAgdG8gd29yayBvbiB0\n" - "aGUgY2hpcC4gSSAKY2Fubm90IGZvcmNlIGEgZGV2aWNlIHJlbW92YWwgZnJvbSB1c2VyIHNwYWNl\n" - "IHdoaWxlIHJ1bm5pbmcsIGNhbiBJPwpBbmQgaSBzdXBwb3NlIHlvdSB3YW50IGEgZHVtcCBvZiBh\n" - "IGNoaXAgaW4gcnVubmluZyBzdGF0dXM/IChPbiBib290LCBhbGwgYXJlIApyZWdpc3RlcnMgYXJl\n" - "IHNpbXBseSBzZXQgdG8gemVybykKCgo+IFRoYW5rcywKPiBHdWVudGVyCj4KPj4gLS0tCj4+IHYy\n" - "OiBQcm9jZXNzZWQgYWxsIHJldmlldyBjb21tZW50cy4KPj4gICAgICBQdXQgY2hpcCBpbnRvIGNv\n" - "bnRpbnVvdXMgbWVhc3VyZW1lbnQgbW9kZS4KPj4gICAgICBBZGRlZCBkdWN1bWVudGF0aW9uLgo+\n" - "PiAgICAgIFVzZSBzdGFuZGFyZCBod21vbiBpbnRlcmZhY2VzIGFuZCBtYWNyb3MuCj4+Cj4+ICAg\n" - "RG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwIHwgIDQ0ICsrKysrKysrKysrKwo+PiAgIGRyaXZl\n" - "cnMvaHdtb24vS2NvbmZpZyAgICAgICB8ICAxNCArKysrCj4+ICAgZHJpdmVycy9od21vbi9NYWtl\n" - "ZmlsZSAgICAgIHwgICAxICsKPj4gICBkcml2ZXJzL2h3bW9uL2x0YzI5OTAuYyAgICAgfCAxNjAK\n" - "Pj4gKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPj4gICA0IGZp\n" - "bGVzIGNoYW5nZWQsIDIxOSBpbnNlcnRpb25zKCspCj4+ICAgY3JlYXRlIG1vZGUgMTAwNjQ0IERv\n" - "Y3VtZW50YXRpb24vaHdtb24vbHRjMjk5MAo+PiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJz\n" - "L2h3bW9uL2x0YzI5OTAuYwo+Pgo+PiBkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9od21vbi9s\n" - "dGMyOTkwIGIvRG9jdW1lbnRhdGlvbi9od21vbi9sdGMyOTkwCj4+IG5ldyBmaWxlIG1vZGUgMTAw\n" - "NjQ0Cj4+IGluZGV4IDAwMDAwMDAuLjgzOGI3NGUKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9E\n" - "b2N1bWVudGF0aW9uL2h3bW9uL2x0YzI5OTAKPj4gQEAgLTAsMCArMSw0NCBAQAo+PiArS2VybmVs\n" - "IGRyaXZlciBsdGMyOTkwCj4+ICs9PT09PT09PT09PT09PT09PT09PT0KPj4gKwo+PiArU3VwcG9y\n" - "dGVkIGNoaXBzOgo+PiArICAqIExpbmVhciBUZWNobm9sb2d5IExUQzI5OTAKPj4gKyAgICBQcmVm\n" - "aXg6ICdsdGMyOTkwJwo+PiArICAgIEFkZHJlc3NlcyBzY2FubmVkOiAtCj4+ICsgICAgRGF0YXNo\n" - "ZWV0OiBodHRwOi8vd3d3LmxpbmVhci5jb20vcHJvZHVjdC9sdGMyOTkwCj4+ICsKPj4gK0F1dGhv\n" - "cjogTWlrZSBMb29pam1hbnMgPG1pa2UubG9vaWptYW5zQHRvcGljLm5sPgo+PiArCj4+ICsKPj4g\n" - "K0Rlc2NyaXB0aW9uCj4+ICstLS0tLS0tLS0tLQo+PiArCj4+ICtMVEMyOTkwIGlzIGEgUXVhZCBJ\n" - "MkMgVm9sdGFnZSwgQ3VycmVudCBhbmQgVGVtcGVyYXR1cmUgTW9uaXRvci4KPj4gK1RoZSBjaGlw\n" - "J3MgaW5wdXRzIGNhbiBtZWFzdXJlIDQgdm9sdGFnZXMsIG9yIHR3byBpbnB1dHMgdG9nZXRoZXIg\n" - "KDErMiBhbmQgMys0KQo+PiArY2FuIGJlIGNvbWJpbmVkIHRvIG1lYXN1cmUgYSBkaWZmZXJlbnRp\n" - "YWwgdm9sdGFnZSwgd2hpY2ggaXMgdHlwaWNhbGx5IHVzZWQgdG8KPj4gK21lYXN1cmUgY3VycmVu\n" - "dCB0aHJvdWdoIGEgc2VyaWVzIHJlc2lzdG9yLCBvciBhIHRlbXBlcmF0dXJlLgo+PiArCj4+ICtU\n" - "aGlzIGRyaXZlciBjdXJyZW50bHkgdXNlcyB0aGUgMnggZGlmZmVyZW50aWFsIG1vZGUgb25seS4g\n" - "SW4gb3JkZXIgdG8gc3VwcG9ydAo+PiArb3RoZXIgbW9kZXMsIHRoZSBkcml2ZXIgd2lsbCBuZWVk\n" - "IHRvIGJlIGV4cGFuZGVkLgo+PiArCj4+ICsKPj4gK1VzYWdlIE5vdGVzCj4+ICstLS0tLS0tLS0t\n" - "LQo+PiArCj4+ICtUaGlzIGRyaXZlciBkb2VzIG5vdCBwcm9iZSBmb3IgUE1CdXMgZGV2aWNlcy4g\n" - "WW91IHdpbGwgaGF2ZSB0byBpbnN0YW50aWF0ZQo+PiArZGV2aWNlcyBleHBsaWNpdGx5Lgo+PiAr\n" - "Cj4+ICsKPj4gK1N5c2ZzIGF0dHJpYnV0ZXMKPj4gKy0tLS0tLS0tLS0tLS0tLS0KPj4gKwo+PiAr\n" - "VGhlICJjdXJyKl9pbnB1dCIgbWVhc3VyZW1lbnRzIGFjdHVhbGx5IHJlcG9ydCB0aGUgdm9sdGFn\n" - "ZSBkcm9wIGFjcm9zcyB0aGUKPj4gK2lucHV0IHBpbnMgaW4gbWljcm92b2x0cy4gVGhpcyBpcyBl\n" - "cXVpdmFsZW50IHRvIHRoZSBjdXJyZW50IHRocm91Z2ggYSAxbU9obQo+PiArc2Vuc2UgcmVzaXN0\n" - "b3IuIERpdmlkZSB0aGUgcmVwb3J0ZWQgdmFsdWUgYnkgdGhlIGFjdHVhbCBzZW5zZSByZXNpc3Rv\n" - "ciB2YWx1ZQo+PiAraW4gbU9obSB0byBnZXQgdGhlIGFjdHVhbCB2YWx1ZS4KPj4gKwo+PiAraW4w\n" - "X2lucHV0ICAgICBWb2x0YWdlIGF0IFZjYyBwaW4gaW4gbWlsbGl2b2x0IChyYW5nZSAyLjVWIHRv\n" - "IDVWKQo+PiArdGVtcDFfaW5wdXQgICBJbnRlcm5hbCBjaGlwIHRlbXBlcmF0dXJlIGluIG1pbGxp\n" - "ZGVncmVlcyBDZWxjaXVzCj4+ICtjdXJyMV9pbnB1dCAgIEN1cnJlbnQgaW4gbUEgYWNyb3NzIHYx\n" - "LXYyIGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3IuCj4+ICtjdXJyMl9pbnB1dCAgIEN1\n" - "cnJlbnQgaW4gbUEgYWNyb3NzIHYzLXY0IGFzc3VtaW5nIGEgMW1PaG0gc2Vuc2UgcmVzaXN0b3Iu\n" - "Cj4+ICsKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vS2NvbmZpZyBiL2RyaXZlcnMvaHdt\n" - "b24vS2NvbmZpZwo+PiBpbmRleCA4MGE3M2JmLi44YTMxZDY0IDEwMDY0NAo+PiAtLS0gYS9kcml2\n" - "ZXJzL2h3bW9uL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9od21vbi9LY29uZmlnCj4+IEBAIC02\n" - "ODUsNiArNjg1LDIwIEBAIGNvbmZpZyBTRU5TT1JTX0xUQzI5NDUKPj4gICAgICAgICBUaGlzIGRy\n" - "aXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2ls\n" - "bAo+PiAgICAgICAgIGJlIGNhbGxlZCBsdGMyOTQ1Lgo+Pgo+PiArY29uZmlnIFNFTlNPUlNfTFRD\n" - "Mjk5MAo+PiArICAgIHRyaXN0YXRlICJMaW5lYXIgVGVjaG5vbG9neSBMVEMyOTkwIChjdXJyZW50\n" - "IG1vbml0b3JpbmcgbW9kZSBvbmx5KSIKPj4gKyAgICBkZXBlbmRzIG9uIEkyQwo+PiArICAgIGhl\n" - "bHAKPj4gKyAgICAgIElmIHlvdSBzYXkgeWVzIGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciBMaW5l\n" - "YXIgVGVjaG5vbG9neSBMVEMyOTkwCj4+ICsgICAgICBJMkMgU3lzdGVtIE1vbml0b3IuIFRoZSBM\n" - "VEMyOTkwIHN1cHBvcnRzIGEgY29tYmluYXRpb24gb2Ygdm9sdGFnZSwKPj4gKyAgICAgIGN1cnJl\n" - "bnQgYW5kIHRlbXBlcmF0dXJlIG1vbml0b3JpbmcsIGJ1dCBpbiBhZGRpdGlvbiB0byB0aGUgVmNj\n" - "IHN1cHBseQo+PiArICAgICAgdm9sdGFnZSBhbmQgY2hpcCB0ZW1wZXJhdHVyZSwgdGhpcyBkcml2\n" - "ZXIgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMKPj4gKyAgICAgIHJlYWRpbmcgdHdvIGN1cnJlbnRz\n" - "IGJ5IG1lYXN1cmluZyB0d28gZGlmZmVyZW50aWFsIHZvbHRhZ2VzIGFjcm9zcwo+PiArICAgICAg\n" - "c2VyaWVzIHJlc2lzdG9ycy4KPj4gKwo+PiArICAgICAgVGhpcyBkcml2ZXIgY2FuIGFsc28gYmUg\n" - "YnVpbHQgYXMgYSBtb2R1bGUuIElmIHNvLCB0aGUgbW9kdWxlIHdpbGwKPj4gKyAgICAgIGJlIGNh\n" - "bGxlZCBsdGMyOTkwLgo+PiArCj4+ICAgY29uZmlnIFNFTlNPUlNfTFRDNDE1MQo+PiAgICAgICB0\n" - "cmlzdGF0ZSAiTGluZWFyIFRlY2hub2xvZ3kgTFRDNDE1MSIKPj4gICAgICAgZGVwZW5kcyBvbiBJ\n" - "MkMKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9u\n" - "L01ha2VmaWxlCj4+IGluZGV4IDEyYTMyMzkuLmU0YmQxNWIgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZl\n" - "cnMvaHdtb24vTWFrZWZpbGUKPj4gKysrIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+PiBAQCAt\n" - "MTAxLDYgKzEwMSw3IEBAIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyMzQpICAgICs9IGxtOTUy\n" - "MzQubwo+PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDEpICAgICs9IGxtOTUyNDEubwo+\n" - "PiAgIG9iai0kKENPTkZJR19TRU5TT1JTX0xNOTUyNDUpICAgICs9IGxtOTUyNDUubwo+PiAgIG9i\n" - "ai0kKENPTkZJR19TRU5TT1JTX0xUQzI5NDUpICAgICs9IGx0YzI5NDUubwo+PiArb2JqLSQoQ09O\n" - "RklHX1NFTlNPUlNfTFRDMjk5MCkgICAgKz0gbHRjMjk5MC5vCj4+ICAgb2JqLSQoQ09ORklHX1NF\n" - "TlNPUlNfTFRDNDE1MSkgICAgKz0gbHRjNDE1MS5vCj4+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNf\n" - "TFRDNDIxNSkgICAgKz0gbHRjNDIxNS5vCj4+ICAgb2JqLSQoQ09ORklHX1NFTlNPUlNfTFRDNDIy\n" - "MikgICAgKz0gbHRjNDIyMi5vCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL2x0YzI5OTAu\n" - "YyBiL2RyaXZlcnMvaHdtb24vbHRjMjk5MC5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGlu\n" - "ZGV4IDAwMDAwMDAuLjM3MjBmZjcKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL2h3\n" - "bW9uL2x0YzI5OTAuYwo+PiBAQCAtMCwwICsxLDE2MCBAQAo+PiArLyoKPj4gKyAqIERyaXZlciBm\n" - "b3IgTGluZWFyIFRlY2hub2xvZ3kgTFRDMjk5MCBwb3dlciBtb25pdG9yCj4+ICsgKgo+PiArICog\n" - "Q29weXJpZ2h0IChDKSAyMDE0IFRvcGljIEVtYmVkZGVkIFByb2R1Y3RzCj4+ICsgKiBBdXRob3I6\n" - "IE1pa2UgTG9vaWptYW5zIDxtaWtlLmxvb2lqbWFuc0B0b3BpYy5ubD4KPj4gKyAqCj4+ICsgKiBM\n" - "aWNlbnNlOiBHUEx2Mgo+PiArICoKPj4gKyAqIFRoaXMgZHJpdmVyIGFzc3VtZXMgdGhlIGNoaXAg\n" - "aXMgd2lyZWQgYXMgYSBkdWFsIGN1cnJlbnQgbW9uaXRvciwgYW5kCj4+ICsgKiByZXBvcnRzIHRo\n" - "ZSB2b2x0YWdlIGRyb3AgYWNyb3NzIHR3byBzZXJpZXMgcmVzaXN0b3JzLiBJdCBhbHNvIHJlcG9y\n" - "dHMKPj4gKyAqIHRoZSBjaGlwJ3MgaW50ZXJuYWwgdGVtcGVyYXR1cmUgYW5kIFZjYyBwb3dlciBz\n" - "dXBwbHkgdm9sdGFnZS4KPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgvZGVsYXkuaD4K\n" - "Ck5vdCBuZWVkZWQsIHdpbGwgYmUgcmVtb3ZlZCBpbiB2MwoKPj4gKyNpbmNsdWRlIDxsaW51eC9l\n" - "cnIuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9od21vbi5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2h3\n" - "bW9uLXN5c2ZzLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvaTJjLmg+Cj4+ICsjaW5jbHVkZSA8bGlu\n" - "dXgva2VybmVsLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+ICsjaW5jbHVkZSA8\n" - "bGludXgvc2xhYi5oPgoKTm90IG5lZWRlZAoKPj4gKwo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRV\n" - "UyAgICAweDAwCj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTCAgICAweDAxCj4+ICsjZGVmaW5l\n" - "IExUQzI5OTBfVFJJR0dFUiAgICAweDAyCj4+ICsjZGVmaW5lIExUQzI5OTBfVElOVF9NU0IgICAg\n" - "MHgwNAo+PiArI2RlZmluZSBMVEMyOTkwX1RJTlRfTFNCICAgIDB4MDUKPj4gKyNkZWZpbmUgTFRD\n" - "Mjk5MF9WMV9NU0IgICAgMHgwNgo+PiArI2RlZmluZSBMVEMyOTkwX1YxX0xTQiAgICAweDA3Cj4+\n" - "ICsjZGVmaW5lIExUQzI5OTBfVjJfTVNCICAgIDB4MDgKPj4gKyNkZWZpbmUgTFRDMjk5MF9WMl9M\n" - "U0IgICAgMHgwOQo+PiArI2RlZmluZSBMVEMyOTkwX1YzX01TQiAgICAweDBBCj4+ICsjZGVmaW5l\n" - "IExUQzI5OTBfVjNfTFNCICAgIDB4MEIKPj4gKyNkZWZpbmUgTFRDMjk5MF9WNF9NU0IgICAgMHgw\n" - "Qwo+PiArI2RlZmluZSBMVEMyOTkwX1Y0X0xTQiAgICAweDBECj4+ICsjZGVmaW5lIExUQzI5OTBf\n" - "VkNDX01TQiAgICAweDBFCj4+ICsjZGVmaW5lIExUQzI5OTBfVkNDX0xTQiAgICAweDBGCj4+ICsK\n" - "Pgo+IExTQiBub3QgdXNlZC4KCkFncmVlLiBXaWxsIHJlbW92ZSB0aGVtLCBpdCdzIGNsdXR0ZXIu\n" - "Cgo+Cj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVTX0JVU1kgICAgQklUKDApCj4+ICsjZGVmaW5l\n" - "IExUQzI5OTBfU1RBVFVTX1RJTlQgICAgQklUKDEpCj4+ICsjZGVmaW5lIExUQzI5OTBfU1RBVFVT\n" - "X1YxICAgIEJJVCgyKQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WMiAgICBCSVQoMykKPj4g\n" - "KyNkZWZpbmUgTFRDMjk5MF9TVEFUVVNfVjMgICAgQklUKDQpCj4+ICsjZGVmaW5lIExUQzI5OTBf\n" - "U1RBVFVTX1Y0ICAgIEJJVCg1KQo+PiArI2RlZmluZSBMVEMyOTkwX1NUQVRVU19WQ0MgICAgQklU\n" - "KDYpCj4+ICsKPiBObyBsb25nZXIgdXNlZCA/CgpObyBuZWVkIGZvciBzdGF0dXMgcmVhZCB3aGVu\n" - "IGluIGNvbnRpbnVvdXMgbW9kZSwgc28gdGhleSBoYXZlIG5vIHBvaW50IGJlaW5nIGhlcmUuCgo+\n" - "Cj4+ICsvKiBPbmx5IGRlZmluZSBjb250cm9sIHNldHRpbmdzIHdlIGFjdHVhbGx5IHVzZSAqLwo+\n" - "Cj4gSG1tbSAuLi4gYnV0IG5vdCBhbGwgYXJlIHVzZWQuCgpJIHRoaW5rIGl0J3MgYmV0dGVyIHRv\n" - "IHJlbW92ZSB0aGF0IGNvbW1lbnQgOikKCj4+ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9LRUxW\n" - "SU4gICAgICAgIEJJVCg3KQo+PiArI2RlZmluZSBMVEMyOTkwX0NPTlRST0xfU0lOR0xFICAgICAg\n" - "ICBCSVQoNikKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01FQVNVUkVfQUxMICAgICgweDMg\n" - "PDwgMykKPj4gKyNkZWZpbmUgTFRDMjk5MF9DT05UUk9MX01PREVfQ1VSUkVOVCAgICAweDA2Cj4+\n" - "ICsjZGVmaW5lIExUQzI5OTBfQ09OVFJPTF9NT0RFX1ZPTFRBR0UgICAgMHgwNwo+PiArCj4+ICsv\n" - "KiBjb252ZXJ0IHJhdyByZWdpc3RlciB2YWx1ZSB0byBzaWduLWV4dGVuZGVkIGludGVnZXIgaW4g\n" - "MTYtYml0IHJhbmdlICovCj4+ICtzdGF0aWMgaW50IGx0YzI5OTBfdm9sdGFnZV90b19pbnQoaW50\n" - "IHJhdykKPj4gK3sKPj4gKyAgICBpZiAocmF3ICYgQklUKDE0KSkgewo+PiArICAgICAgICByZXR1\n" - "cm4gLSgweDQwMDAgLSAocmF3ICYgMHgzRkZGKSkgPDwgMjsKPj4gKyAgICB9IGVsc2Ugewo+PiAr\n" - "ICAgICAgICByZXR1cm4gKHJhdyAmIDB4M0ZGRikgPDwgMjsKPj4gKyAgICB9Cj4+ICt9Cj4+ICsK\n" - "Pj4gKy8qIFJldHVybiB0aGUgY29udmVydGVkIHZhbHVlIGZyb20gdGhlIGdpdmVuIHJlZ2lzdGVy\n" - "IGluIHVWIG9yIG1DICovCj4+ICtzdGF0aWMgaW50IGx0YzI5OTBfZ2V0X3ZhbHVlKHN0cnVjdCBp\n" - "MmNfY2xpZW50ICppMmMsIHU4IGluZGV4KQo+PiArewo+PiArICAgIGludCB2YWw7Cj4+ICsgICAg\n" - "aW50IHJlc3VsdDsKPj4gKwo+PiArICAgIHZhbCA9IGkyY19zbWJ1c19yZWFkX3dvcmRfc3dhcHBl\n" - "ZChpMmMsIChpbmRleCA8PCAxKSArIExUQzI5OTBfVElOVF9NU0IpOwo+PiArICAgIGlmICh1bmxp\n" - "a2VseSh2YWwgPCAwKSkKPj4gKyAgICAgICAgcmV0dXJuIHZhbDsKPj4gKwo+PiArICAgIGlmIChp\n" - "bmRleCA9PSAwKSB7IC8qIGludGVybmFsIHRlbXAsIDAuMDYyNSBkZWdyZWVzL0xTQiwgMTMtYml0\n" - "ICAqLwo+PiArICAgICAgICB2YWwgPSAodmFsICYgMHgxRkZGKSA8PCAzOwo+PiArICAgICAgICBy\n" - "ZXN1bHQgPSAodmFsICogMTAwMCkgPj4gNzsKPj4gKyAgICB9IGVsc2UgaWYgKGluZGV4IDwgNSkg\n" - "eyAvKiBWeC1WeSwgMTkuNDJ1Vi9MU0IgKi8KPj4gKyAgICAgICAgcmVzdWx0ID0gbHRjMjk5MF92\n" - "b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICogMTAwKTsKPj4gKyAgICB9IGVsc2UgeyAv\n" - "KiBWY2MsIDMwNS4xOM68Vi9MU0IsIDIuNVYgb2Zmc2V0ICovCj4+ICsgICAgICAgIHJlc3VsdCA9\n" - "IGx0YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDMwNTE4IC8gKDQgKiAxMDAgKiAxMDAwKTsK\n" - "Pj4gKyAgICAgICAgcmVzdWx0ICs9IDI1MDA7Cj4+ICsgICAgfQo+PiArCj4gV2l0aCB0aGUgcmVn\n" - "aXN0ZXIgaW4gaW5kZXggKHNlZSBiZWxvdykgdGhpcyBjb3VsZCBiZQo+Cj4gICAgICB2YWwgPSBp\n" - "MmNfc21idXNfcmVhZF93b3JkX3N3YXBwZWQoaTJjLCBpbmRleCk7Cj4KPiAgICAgIHN3aXRjaCAo\n" - "aW5kZXgpIHsKPiAgICAgIGNhc2UgTFRDMjk5MF9USU5UX01TQjoKPiAgICAgICAgICB2YWwgPSAo\n" - "dmFsICYgMHgxRkZGKSA8PCAzOwo+ICAgICAgICAgIHJlc3VsdCA9ICh2YWwgKiAxMDAwKSA+PiA3\n" - "Owo+ICAgICAgICAgIGJyZWFrOwo+ICAgICAgY2FzZSBMVEMyOTkwX1YxX01TQjoKPiAgICAgIGNh\n" - "c2UgTFRDMjk5MF9WMl9NU0I6Cj4gICAgICAgICAgLi4uCj4gICAgICAgICAgcmVzdWx0ID0gbHRj\n" - "Mjk5MF92b2x0YWdlX3RvX2ludCh2YWwpICogMTk0MiAvICg0ICogMTAwKTsKPiAgICAgICAgICBi\n" - "cmVhazsKPiAgICAgIGNhc2UgTFRDMjk5MF9WQ0NfTVNCOgo+ICAgICAgICAgIHJlc3VsdCA9IGx0\n" - "YzI5OTBfdm9sdGFnZV90b19pbnQodmFsKSAqIDMwNTE4IC8gKDQgKiAxMDAgKiAxMDAwKTsKPiAg\n" - "ICAgICAgICByZXN1bHQgKz0gMjUwMDsKPiAgICAgICAgICBicmVhazsKPiAgICAgIGRlZmF1bHQ6\n" - "Cj4gICAgICAgICAgcmVzdWx0ID0gMDsgICAgLyogd29uJ3QgaGFwcGVuLCBtYWtlcyBjb21waWxl\n" - "ciBoYXBweSAqLwo+ICAgICAgICAgIGJyZWFrOwo+ICAgICAgfQo+Cj4gd2hpY2ggSSB0aGluayB3\n" - "b3VsZCBiZSBlYXNpZXIgdG8gdW5kZXJzdGFuZC4KCkFncmVlLCBnb29kIHBvaW50LiBBbHNvIHVz\n" - "aW5nIHRoZSByZWdpc3RlciBuYW1lcyBoZWxwcyByZWFkYWJpbGl0eS4KCj4+ICsgICAgcmV0dXJu\n" - "IHJlc3VsdDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHNzaXplX3QgbHRjMjk5MF9zaG93X3ZhbHVl\n" - "KHN0cnVjdCBkZXZpY2UgKmRldiwKPj4gKyAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2Vf\n" - "YXR0cmlidXRlICpkYSwgY2hhciAqYnVmKQo+PiArewo+PiArICAgIHN0cnVjdCBzZW5zb3JfZGV2\n" - "aWNlX2F0dHJpYnV0ZSAqYXR0ciA9IHRvX3NlbnNvcl9kZXZfYXR0cihkYSk7Cj4+ICsgICAgaW50\n" - "IHZhbHVlOwo+PiArCj4+ICsgICAgdmFsdWUgPSBsdGMyOTkwX2dldF92YWx1ZShkZXZfZ2V0X2Ry\n" - "dmRhdGEoZGV2KSwgYXR0ci0+aW5kZXgpOwo+PiArICAgIHJldHVybiBzbnByaW50ZihidWYsIFBB\n" - "R0VfU0laRSwgIiVkXG4iLCB2YWx1ZSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBTRU5TT1JfREVW\n" - "SUNFX0FUVFIodGVtcDFfaW5wdXQsIFNfSVJVR08sIGx0YzI5OTBfc2hvd192YWx1ZSwgTlVMTCwg\n" - "MCk7Cj4+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKGN1cnIxX2lucHV0LCBTX0lSVUdPLCBs\n" - "dGMyOTkwX3Nob3dfdmFsdWUsIE5VTEwsIDEpOwo+PiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU\n" - "UihjdXJyMl9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLCAzKTsKPj4g\n" - "K3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2lucHV0LCBTX0lSVUdPLCBsdGMyOTkwX3No\n" - "b3dfdmFsdWUsIE5VTEwsIDUpOwo+Cj4gQ29uc2lkZXIgcHJvdmlkaW5nIHRoZSByZWdpc3RlciBN\n" - "U0IgaW4gaW5kZXguCj4KPiBFeGFtcGxlOgo+ICAgICAgc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRU\n" - "Uih0ZW1wMV9pbnB1dCwgU19JUlVHTywgbHRjMjk5MF9zaG93X3ZhbHVlLCBOVUxMLAo+IExUQzI5\n" - "OTBfVElOVF9NU0IpOwoKQWdyZWUsIGFzIGFib3ZlLgoKPj4gKwo+PiArc3RhdGljIHN0cnVjdCBh\n" - "dHRyaWJ1dGUgKmx0YzI5OTBfYXR0cnNbXSA9IHsKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX3Rl\n" - "bXAxX2lucHV0LmRldl9hdHRyLmF0dHIsCj4+ICsgICAgJnNlbnNvcl9kZXZfYXR0cl9jdXJyMV9p\n" - "bnB1dC5kZXZfYXR0ci5hdHRyLAo+PiArICAgICZzZW5zb3JfZGV2X2F0dHJfY3VycjJfaW5wdXQu\n" - "ZGV2X2F0dHIuYXR0ciwKPj4gKyAgICAmc2Vuc29yX2Rldl9hdHRyX2luMF9pbnB1dC5kZXZfYXR0\n" - "ci5hdHRyLAo+PiArICAgIE5VTEwsCj4+ICt9Owo+PiArQVRUUklCVVRFX0dST1VQUyhsdGMyOTkw\n" - "KTsKPj4gKwo+PiArc3RhdGljIGludCBsdGMyOTkwX2kyY19wcm9iZShzdHJ1Y3QgaTJjX2NsaWVu\n" - "dCAqaTJjLAo+PiArICAgIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkICppZCkKPgo+IFBsZWFz\n" - "ZSBhbGlnbiBjb250aW51YXRpb24gbGluZXMgd2l0aCAnKCcuCj4KPj4gK3sKPj4gKyAgICBpbnQg\n" - "cmV0Owo+PiArICAgIHN0cnVjdCBkZXZpY2UgKmh3bW9uX2RldjsKPj4gKwo+PiArICAgIGlmICgh\n" - "aTJjX2NoZWNrX2Z1bmN0aW9uYWxpdHkoaTJjLT5hZGFwdGVyLCBJMkNfRlVOQ19TTUJVU19CWVRF\n" - "X0RBVEEpKQo+Cj4gQWxzbyBuZWVkIGNhcGFiaWxpdHkgdG8gcmVhZCB3b3Jkcy4KCkd1ZXNzIHNv\n" - "Li4uCgo+Cj4+ICsgICAgICAgIHJldHVybiAtRU5PREVWOwo+PiArCj4+ICsgICAgLyogU2V0dXAg\n" - "Y29udGludW91cyBtb2RlLCBjdXJyZW50IG1vbml0b3IgKi8KPj4gKyAgICByZXQgPSBpMmNfc21i\n" - "dXNfd3JpdGVfYnl0ZV9kYXRhKGkyYywgTFRDMjk5MF9DT05UUk9MLAo+PiArICAgICAgICBMVEMy\n" - "OTkwX0NPTlRST0xfTUVBU1VSRV9BTEwgfCBMVEMyOTkwX0NPTlRST0xfTU9ERV9DVVJSRU5UKTsK\n" - "Pj4gKyAgICBpZiAocmV0IDwgMCkgewo+PiArICAgICAgICBkZXZfZXJyKCZpMmMtPmRldiwgIkVy\n" - "cm9yOiBGYWlsZWQgdG8gc2V0IGNvbnRyb2wgbW9kZS5cbiIpOwo+PiArICAgICAgICByZXR1cm4g\n" - "cmV0Owo+PiArICAgIH0KPj4gKyAgICAvKiBUcmlnZ2VyIG9uY2UgdG8gc3RhcnQgY29udGludW91\n" - "cyBjb252ZXJzaW9uICovCj4+ICsgICAgcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShp\n" - "MmMsIExUQzI5OTBfVFJJR0dFUiwgMSk7Cj4+ICsgICAgaWYgKHJldCA8IDApIHsKPj4gKyAgICAg\n" - "ICAgZGV2X2VycigmaTJjLT5kZXYsICJFcnJvcjogRmFpbGVkIHRvIHN0YXJ0IGFxdWlzaXRpb24u\n" - "XG4iKTsKPgo+IHMvYXF1aXNpdGlvbi9hY3F1aXNpdGlvbi8KPgo+PiArICAgICAgICByZXR1cm4g\n" - "cmV0Owo+PiArICAgIH0KPj4gKwo+PiArICAgIGh3bW9uX2RldiA9IGRldm1faHdtb25fZGV2aWNl\n" - "X3JlZ2lzdGVyX3dpdGhfZ3JvdXBzKCZpMmMtPmRldiwKPj4gKyAgICAgICAgICAgICAgICAgICAg\n" - "ICAgICAgICAgICBpMmMtPm5hbWUsCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\n" - "aTJjLAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx0YzI5OTBfZ3JvdXBzKTsK\n" - "Pj4gKwo+PiArICAgIHJldHVybiBQVFJfRVJSX09SX1pFUk8oaHdtb25fZGV2KTsKPj4gK30KPj4g\n" - "Kwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfZGV2aWNlX2lkIGx0YzI5OTBfaTJjX2lkW10g\n" - "PSB7Cj4+ICsgICAgeyAibHRjMjk5MCIsIDAgfSwKPj4gKyAgICB7fQo+PiArfTsKPj4gK01PRFVM\n" - "RV9ERVZJQ0VfVEFCTEUoaTJjLCBsdGMyOTkwX2kyY19pZCk7Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1\n" - "Y3QgaTJjX2RyaXZlciBsdGMyOTkwX2kyY19kcml2ZXIgPSB7Cj4+ICsgICAgLmRyaXZlciA9IHsK\n" - "Pj4gKyAgICAgICAgLm5hbWUgPSAibHRjMjk5MCIsCj4+ICsgICAgfSwKPj4gKyAgICAucHJvYmUg\n" - "ICAgPSBsdGMyOTkwX2kyY19wcm9iZSwKPj4gKyAgICAuaWRfdGFibGUgPSBsdGMyOTkwX2kyY19p\n" - "ZCwKPj4gK307Cj4+ICsKPj4gK21vZHVsZV9pMmNfZHJpdmVyKGx0YzI5OTBfaTJjX2RyaXZlcik7\n" - "Cj4+ICsKPj4gK01PRFVMRV9ERVNDUklQVElPTigiTFRDMjk5MCBTZW5zb3IgRHJpdmVyIik7Cj4+\n" - "ICtNT0RVTEVfQVVUSE9SKCJUb3BpYyBFbWJlZGRlZCBQcm9kdWN0cyIpOwo+PiArTU9EVUxFX0xJ\n" - "Q0VOU0UoIkdQTCB2MiIpOwo+Pgo+CgoKCktpbmQgcmVnYXJkcywKCk1pa2UgTG9vaWptYW5zClN5\n" - "c3RlbSBFeHBlcnQKClRPUElDIEVtYmVkZGVkIFByb2R1Y3RzCkVpbmRob3ZlbnNld2VnIDMyLUMs\n" - "IE5MLTU2ODMgS0ggQmVzdApQb3N0YnVzIDQ0MCwgTkwtNTY4MCBBSyBCZXN0ClRlbGVmb29uOiAr\n" - "MzEgKDApIDQ5OSAzMyA2OSA3OQpFLW1haWw6IG1pa2UubG9vaWptYW5zQHRvcGljcHJvZHVjdHMu\n" - "Y29tCldlYnNpdGU6IHd3dy50b3BpY3Byb2R1Y3RzLmNvbQoKUGxlYXNlIGNvbnNpZGVyIHRoZSBl\n" - "bnZpcm9ubWVudCBiZWZvcmUgcHJpbnRpbmcgdGhpcyBlLW1haWwKCgoKCgoKX19fX19fX19fX19f\n" - "X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbG0tc2Vuc29ycyBtYWlsaW5nIGxp\n" - "c3QKbG0tc2Vuc29yc0BsbS1zZW5zb3JzLm9yZwpodHRwOi8vbGlzdHMubG0tc2Vuc29ycy5vcmcv\n" - bWFpbG1hbi9saXN0aW5mby9sbS1zZW5zb3Jz + "\357\273\277On 13-01-16 14:24, Guenter Roeck wrote:\n" + "> On 01/13/2016 03:05 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" + "> Mike,\n" + ">\n" + "> That looks much better. Can you send me the output of i2cdump for the chip ?\n" + "> That would help me writing module test code for it.\n" + "\n" + "I'm kinda interested into how that would work.\n" + "\n" + "I'll have to remove the driver first to get i2cdump to work on the chip. I \n" + "cannot force a device removal from user space while running, can I?\n" + "And i suppose you want a dump of a chip in running status? (On boot, all are \n" + "registers are simply set to zero)\n" + "\n" + "\n" + "> Thanks,\n" + "> Guenter\n" + ">\n" + ">> ---\n" + ">> v2: Processed all review comments.\n" + ">> Put chip into continuous measurement mode.\n" + ">> Added ducumentation.\n" + ">> Use standard hwmon interfaces and macros.\n" + ">>\n" + ">> Documentation/hwmon/ltc2990 | 44 ++++++++++++\n" + ">> drivers/hwmon/Kconfig | 14 ++++\n" + ">> drivers/hwmon/Makefile | 1 +\n" + ">> drivers/hwmon/ltc2990.c | 160\n" + ">> ++++++++++++++++++++++++++++++++++++++++++++\n" + ">> 4 files changed, 219 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" + ">> This driver can also be built as a module. If so, the module will\n" + ">> be called ltc2945.\n" + ">>\n" + ">> +config SENSORS_LTC2990\n" + ">> + tristate \"Linear Technology LTC2990 (current monitoring mode only)\"\n" + ">> + depends on I2C\n" + ">> + help\n" + ">> + If you say yes here you get support for Linear Technology LTC2990\n" + ">> + I2C System Monitor. The LTC2990 supports a combination of voltage,\n" + ">> + current and temperature monitoring, but in addition to the Vcc supply\n" + ">> + voltage and chip temperature, this driver currently only supports\n" + ">> + reading two currents by measuring two differential voltages across\n" + ">> + series resistors.\n" + ">> +\n" + ">> + This driver can also be built as a module. If so, the module will\n" + ">> + be called ltc2990.\n" + ">> +\n" + ">> config SENSORS_LTC4151\n" + ">> tristate \"Linear Technology LTC4151\"\n" + ">> depends 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) += lm95234.o\n" + ">> obj-$(CONFIG_SENSORS_LM95241) += lm95241.o\n" + ">> obj-$(CONFIG_SENSORS_LM95245) += lm95245.o\n" + ">> obj-$(CONFIG_SENSORS_LTC2945) += ltc2945.o\n" + ">> +obj-$(CONFIG_SENSORS_LTC2990) += ltc2990.o\n" + ">> obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o\n" + ">> obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o\n" + ">> obj-$(CONFIG_SENSORS_LTC4222) += ltc4222.o\n" + ">> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c\n" + ">> new file mode 100644\n" + ">> index 0000000..3720ff7\n" + ">> --- /dev/null\n" + ">> +++ b/drivers/hwmon/ltc2990.c\n" + ">> @@ -0,0 +1,160 @@\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/delay.h>\n" + "\n" + "Not needed, will be removed in v3\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" + ">> +#include <linux/slab.h>\n" + "\n" + "Not needed\n" + "\n" + ">> +\n" + ">> +#define LTC2990_STATUS 0x00\n" + ">> +#define LTC2990_CONTROL 0x01\n" + ">> +#define LTC2990_TRIGGER 0x02\n" + ">> +#define LTC2990_TINT_MSB 0x04\n" + ">> +#define LTC2990_TINT_LSB 0x05\n" + ">> +#define LTC2990_V1_MSB 0x06\n" + ">> +#define LTC2990_V1_LSB 0x07\n" + ">> +#define LTC2990_V2_MSB 0x08\n" + ">> +#define LTC2990_V2_LSB 0x09\n" + ">> +#define LTC2990_V3_MSB 0x0A\n" + ">> +#define LTC2990_V3_LSB 0x0B\n" + ">> +#define LTC2990_V4_MSB 0x0C\n" + ">> +#define LTC2990_V4_LSB 0x0D\n" + ">> +#define LTC2990_VCC_MSB 0x0E\n" + ">> +#define LTC2990_VCC_LSB 0x0F\n" + ">> +\n" + ">\n" + "> LSB not used.\n" + "\n" + "Agree. Will remove them, it's clutter.\n" + "\n" + ">\n" + ">> +#define LTC2990_STATUS_BUSY BIT(0)\n" + ">> +#define LTC2990_STATUS_TINT BIT(1)\n" + ">> +#define LTC2990_STATUS_V1 BIT(2)\n" + ">> +#define LTC2990_STATUS_V2 BIT(3)\n" + ">> +#define LTC2990_STATUS_V3 BIT(4)\n" + ">> +#define LTC2990_STATUS_V4 BIT(5)\n" + ">> +#define LTC2990_STATUS_VCC BIT(6)\n" + ">> +\n" + "> No longer used ?\n" + "\n" + "No need for status read when in continuous mode, so they have no point being here.\n" + "\n" + ">\n" + ">> +/* Only define control settings we actually use */\n" + ">\n" + "> Hmmm ... but not all are used.\n" + "\n" + "I think it's better to remove that comment :)\n" + "\n" + ">> +#define LTC2990_CONTROL_KELVIN BIT(7)\n" + ">> +#define LTC2990_CONTROL_SINGLE BIT(6)\n" + ">> +#define LTC2990_CONTROL_MEASURE_ALL (0x3 << 3)\n" + ">> +#define LTC2990_CONTROL_MODE_CURRENT 0x06\n" + ">> +#define LTC2990_CONTROL_MODE_VOLTAGE 0x07\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" + ">> + if (raw & BIT(14)) {\n" + ">> + return -(0x4000 - (raw & 0x3FFF)) << 2;\n" + ">> + } else {\n" + ">> + return (raw & 0x3FFF) << 2;\n" + ">> + }\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 index)\n" + ">> +{\n" + ">> + int val;\n" + ">> + int result;\n" + ">> +\n" + ">> + val = i2c_smbus_read_word_swapped(i2c, (index << 1) + LTC2990_TINT_MSB);\n" + ">> + if (unlikely(val < 0))\n" + ">> + return val;\n" + ">> +\n" + ">> + if (index == 0) { /* internal temp, 0.0625 degrees/LSB, 13-bit */\n" + ">> + val = (val & 0x1FFF) << 3;\n" + ">> + result = (val * 1000) >> 7;\n" + ">> + } else if (index < 5) { /* Vx-Vy, 19.42uV/LSB */\n" + ">> + result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);\n" + ">> + } else { /* Vcc, 305.18\316\274V/LSB, 2.5V offset */\n" + ">> + result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);\n" + ">> + result += 2500;\n" + ">> + }\n" + ">> +\n" + "> With the register in index (see below) this could be\n" + ">\n" + "> val = i2c_smbus_read_word_swapped(i2c, index);\n" + ">\n" + "> switch (index) {\n" + "> case LTC2990_TINT_MSB:\n" + "> val = (val & 0x1FFF) << 3;\n" + "> result = (val * 1000) >> 7;\n" + "> break;\n" + "> case LTC2990_V1_MSB:\n" + "> case LTC2990_V2_MSB:\n" + "> ...\n" + "> result = ltc2990_voltage_to_int(val) * 1942 / (4 * 100);\n" + "> break;\n" + "> case LTC2990_VCC_MSB:\n" + "> result = ltc2990_voltage_to_int(val) * 30518 / (4 * 100 * 1000);\n" + "> result += 2500;\n" + "> break;\n" + "> default:\n" + "> result = 0; /* won't happen, makes compiler happy */\n" + "> break;\n" + "> }\n" + ">\n" + "> which I think would be easier to understand.\n" + "\n" + "Agree, good point. Also using the register names helps readability.\n" + "\n" + ">> + return result;\n" + ">> +}\n" + ">> +\n" + ">> +static ssize_t ltc2990_show_value(struct device *dev,\n" + ">> + struct device_attribute *da, char *buf)\n" + ">> +{\n" + ">> + struct sensor_device_attribute *attr = to_sensor_dev_attr(da);\n" + ">> + int value;\n" + ">> +\n" + ">> + value = ltc2990_get_value(dev_get_drvdata(dev), attr->index);\n" + ">> + return snprintf(buf, PAGE_SIZE, \"%d\\n\", value);\n" + ">> +}\n" + ">> +\n" + ">> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL, 0);\n" + ">> +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL, 1);\n" + ">> +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL, 3);\n" + ">> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL, 5);\n" + ">\n" + "> Consider providing the register MSB in index.\n" + ">\n" + "> Example:\n" + "> static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,\n" + "> LTC2990_TINT_MSB);\n" + "\n" + "Agree, as above.\n" + "\n" + ">> +\n" + ">> +static struct attribute *ltc2990_attrs[] = {\n" + ">> + &sensor_dev_attr_temp1_input.dev_attr.attr,\n" + ">> + &sensor_dev_attr_curr1_input.dev_attr.attr,\n" + ">> + &sensor_dev_attr_curr2_input.dev_attr.attr,\n" + ">> + &sensor_dev_attr_in0_input.dev_attr.attr,\n" + ">> + NULL,\n" + ">> +};\n" + ">> +ATTRIBUTE_GROUPS(ltc2990);\n" + ">> +\n" + ">> +static int ltc2990_i2c_probe(struct i2c_client *i2c,\n" + ">> + const struct i2c_device_id *id)\n" + ">\n" + "> Please align continuation lines with '('.\n" + ">\n" + ">> +{\n" + ">> + int ret;\n" + ">> + struct device *hwmon_dev;\n" + ">> +\n" + ">> + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))\n" + ">\n" + "> Also need capability to read words.\n" + "\n" + "Guess so...\n" + "\n" + ">\n" + ">> + return -ENODEV;\n" + ">> +\n" + ">> + /* Setup continuous mode, current monitor */\n" + ">> + ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,\n" + ">> + LTC2990_CONTROL_MEASURE_ALL | LTC2990_CONTROL_MODE_CURRENT);\n" + ">> + if (ret < 0) {\n" + ">> + dev_err(&i2c->dev, \"Error: Failed to set control mode.\\n\");\n" + ">> + return ret;\n" + ">> + }\n" + ">> + /* Trigger once to start continuous conversion */\n" + ">> + ret = i2c_smbus_write_byte_data(i2c, LTC2990_TRIGGER, 1);\n" + ">> + if (ret < 0) {\n" + ">> + dev_err(&i2c->dev, \"Error: Failed to start aquisition.\\n\");\n" + ">\n" + "> s/aquisition/acquisition/\n" + ">\n" + ">> + return ret;\n" + ">> + }\n" + ">> +\n" + ">> + hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,\n" + ">> + i2c->name,\n" + ">> + i2c,\n" + ">> + ltc2990_groups);\n" + ">> +\n" + ">> + return PTR_ERR_OR_ZERO(hwmon_dev);\n" + ">> +}\n" + ">> +\n" + ">> +static const struct i2c_device_id ltc2990_i2c_id[] = {\n" + ">> + { \"ltc2990\", 0 },\n" + ">> + {}\n" + ">> +};\n" + ">> +MODULE_DEVICE_TABLE(i2c, ltc2990_i2c_id);\n" + ">> +\n" + ">> +static struct i2c_driver ltc2990_i2c_driver = {\n" + ">> + .driver = {\n" + ">> + .name = \"ltc2990\",\n" + ">> + },\n" + ">> + .probe = ltc2990_i2c_probe,\n" + ">> + .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" + ">>\n" + ">\n" + "\n" + "\n" + "\n" + "Kind regards,\n" + "\n" + "Mike Looijmans\n" + "System Expert\n" + "\n" + "TOPIC Embedded Products\n" + "Eindhovenseweg 32-C, NL-5683 KH Best\n" + "Postbus 440, NL-5680 AK Best\n" + "Telefoon: +31 (0) 499 33 69 79\n" + "E-mail: mike.looijmans@topicproducts.com\n" + "Website: www.topicproducts.com\n" + "\n" + Please consider the environment before printing this e-mail -bf02236fb649ce32a2a5e2be850c124a17cf6bc1f195000846841abd549775be +0e7bf1ef12197d70315070b79ee41219019dc8cfd28ba1041b2c813c5c18996b
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.