diff for duplicates of <20140324075221.GF8541@lee--X1> diff --git a/a/1.txt b/N1/1.txt index b93571a..03c5f2d 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,331 +1,595 @@ -PiBGcm9tOiBPcGVuc291cmNlIFtTdGV2ZSBUd2lzc10gPHN0d2lzcy5vcGVuc291cmNlQGRpYXNl -bWkuY29tPgo+IAo+IEFkZCB0aGUgSFdNT04gZHJpdmVyIGZvciBEQTkwNjMKPiAKPiBTaWduZWQt -b2ZmLWJ5OiBPcGVuc291cmNlIFtTdGV2ZSBUd2lzc10gPHN0d2lzcy5vcGVuc291cmNlQGRpYXNl -bWkuY29tPgo+IC0tLQo+IAo+ICBkcml2ZXJzL2h3bW9uL0tjb25maWcgICAgICAgICAgICAgICAg -fCAgIDEwICsKPiAgZHJpdmVycy9od21vbi9NYWtlZmlsZSAgICAgICAgICAgICAgIHwgICAgMSAr -Cj4gIGRyaXZlcnMvaHdtb24vZGE5MDYzLWh3bW9uLmMgICAgICAgICB8ICA0NTYgKysrKysrKysr -KysrKysrKysrKysrKysrKysrKysrKysrKwo+ICBpbmNsdWRlL2xpbnV4L21mZC9kYTkwNjMvcmVn -aXN0ZXJzLmggfCAgIDM0ICsrKwoKSSdkIHByZWZlciB0byBzZWUgYWxsIHZhbHVlcyBpbiBoZXgs -IGJ1dCB0aGlzIHByb2JhYmx5IGEgcHJlZmVyZW5jZQp0aGluZyByYXRoZXIgdGhhbiBzb21ldGhp -bmcgd2hpY2ggd291bGQgcHJldmVudCBhY2NlcHRhbmNlLgoKRm9yIHRoZSBNRkQgaGVhZGVyIGNo -YW5nZXM6CiAgQWNrZWQtYnk6IExlZSBKb25lcyA8bGVlLmpvbmVzQGxpbmFyby5vcmc+Cgo+ICA0 -IGZpbGVzIGNoYW5nZWQsIDUwMSBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBk -cml2ZXJzL2h3bW9uL2RhOTA2My1od21vbi5jCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdt -b24vS2NvbmZpZyBiL2RyaXZlcnMvaHdtb24vS2NvbmZpZwo+IGluZGV4IGYyODhiNjAuLjY4YWE4 -ODYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9od21vbi9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9o -d21vbi9LY29uZmlnCj4gQEAgLTM5MSw2ICszOTEsMTYgQEAgY29uZmlnIFNFTlNPUlNfREE5MDU1 -Cj4gIAkgIFRoaXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiAgSWYgc28s -IHRoZSBtb2R1bGUKPiAgCSAgd2lsbCBiZSBjYWxsZWQgZGE5MDU1LWh3bW9uLgo+ICAKPiArY29u -ZmlnIFNFTlNPUlNfREE5MDYzCj4gKwl0cmlzdGF0ZSAiRGlhbG9nIFNlbWljb25kdWN0b3IgREE5 -MDYzIgo+ICsJZGVwZW5kcyBvbiBNRkRfREE5MDYzCj4gKwloZWxwCj4gKwkgIElmIHlvdSBzYXkg -eWVzIGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciB0aGUgaGFyZHdhcmUKPiArCSAgbW9uaXRvcmlu -ZyBmZWF0dXJlcyBvZiB0aGUgREE5MDYzIFBvd2VyIE1hbmFnZW1lbnQgSUMuCj4gKwo+ICsJICBU -aGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1 -bGUKPiArCSAgd2lsbCBiZSBjYWxsZWQgZGE5MDYzLWh3bW9uLgo+ICsKPiAgY29uZmlnIFNFTlNP -UlNfSTVLX0FNQgo+ICAJdHJpc3RhdGUgIkZCLURJTU0gQU1CIHRlbXBlcmF0dXJlIHNlbnNvciBv -biBJbnRlbCA1MDAwIHNlcmllcyBjaGlwc2V0cyIKPiAgCWRlcGVuZHMgb24gUENJCj4gZGlmZiAt -LWdpdCBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4g -aW5kZXggYzQ4Zjk4Ny4uNDE3NGIwNyAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2h3bW9uL01ha2Vm -aWxlCj4gKysrIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+IEBAIC00OSw2ICs0OSw3IEBAIG9i -ai0kKENPTkZJR19TRU5TT1JTX0FUWFAxKQkrPSBhdHhwMS5vCj4gIG9iai0kKENPTkZJR19TRU5T -T1JTX0NPUkVURU1QKQkrPSBjb3JldGVtcC5vCj4gIG9iai0kKENPTkZJR19TRU5TT1JTX0RBOTA1 -Ml9BREMpKz0gZGE5MDUyLWh3bW9uLm8KPiAgb2JqLSQoQ09ORklHX1NFTlNPUlNfREE5MDU1KSs9 -IGRhOTA1NS1od21vbi5vCj4gK29iai0kKENPTkZJR19TRU5TT1JTX0RBOTA2MykJKz0gZGE5MDYz -LWh3bW9uLm8KPiAgb2JqLSQoQ09ORklHX1NFTlNPUlNfRE1FMTczNykJKz0gZG1lMTczNy5vCj4g -IG9iai0kKENPTkZJR19TRU5TT1JTX0RTNjIwKQkrPSBkczYyMC5vCj4gIG9iai0kKENPTkZJR19T -RU5TT1JTX0RTMTYyMSkJKz0gZHMxNjIxLm8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9k -YTkwNjMtaHdtb24uYyBiL2RyaXZlcnMvaHdtb24vZGE5MDYzLWh3bW9uLmMKPiBuZXcgZmlsZSBt -b2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjc3NTZjYjIKPiAtLS0gL2Rldi9udWxsCj4gKysr -IGIvZHJpdmVycy9od21vbi9kYTkwNjMtaHdtb24uYwo+IEBAIC0wLDAgKzEsNDU2IEBACj4gKy8q -IGRhOTA2My1od21vbi5jIC0gSGFyZHdhcmUgbW9uaXRvciBzdXBwb3J0IGZvciBEQTkwNjMKPiAr -ICogQ29weXJpZ2h0IChDKSAyMDE0IERpYWxvZyBTZW1pY29uZHVjdG9yIEx0ZC4KPiArICoKPiAr -ICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0 -IGFuZC9vcgo+ICsgKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGlicmFy -eSBHZW5lcmFsIFB1YmxpYwo+ICsgKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBT -b2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKPiArICogdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNl -LCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgo+ICsgKgo+ICsgKiBUaGlz -IGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1 -bCwKPiArICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxp -ZWQgd2FycmFudHkgb2YKPiArICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFS -VElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKPiArICogTGlicmFyeSBHZW5lcmFsIFB1Ymxp -YyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4 -L2tlcm5lbC5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51 -eC9lcnIuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9p -bml0Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zdHJp -bmcuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8 -bGludXgvaHdtb24uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+Cj4gKyNpbmNs -dWRlIDxsaW51eC9yZWdtYXAuaD4KPiArI2luY2x1ZGUgPGxpbnV4L21mZC9kYTkwNjMvY29yZS5o -Pgo+ICsjaW5jbHVkZSA8bGludXgvbWZkL2RhOTA2My9wZGF0YS5oPgo+ICsKPiArI2RlZmluZSBE -QTkwNjNfQURDX1JFUwkoMSA8PCAoREE5MDYzX0FEQ19SRVNfTF9CSVRTICsgREE5MDYzX0FEQ19S -RVNfTV9CSVRTKSkKPiArI2RlZmluZSBEQTkwNjNfQURDX01BWAkoREE5MDYzX0FEQ19SRVMgLSAx -KQo+ICsjZGVmaW5lIERBOTA2M18yVjUJMjUwMAo+ICsjZGVmaW5lIERBOTA2M181VjAJNTAwMAo+ -ICsjZGVmaW5lIERBOTA2M181VjUJNTUwMAo+ICsjZGVmaW5lIERBOTA2M19USlVOQ19NCS00MjAK -PiArI2RlZmluZSBEQTkwNjNfVEpVTkNfQwktODEyCj4gKyNkZWZpbmUgREE5MDYzX1ZCQkFUX00J -MjA0OAo+ICsKPiArZW51bSBkYTkwNjNfYWRjIHsKPiArCURBOTA2M19DSEFOX1ZTWVMgPSBEQTkw -NjNfQURDX01VWF9WU1lTLAo+ICsJREE5MDYzX0NIQU5fQURDSU4xID0gREE5MDYzX0FEQ19NVVhf -QURDSU4xLAo+ICsJREE5MDYzX0NIQU5fQURDSU4yID0gREE5MDYzX0FEQ19NVVhfQURDSU4yLAo+ -ICsJREE5MDYzX0NIQU5fQURDSU4zID0gREE5MDYzX0FEQ19NVVhfQURDSU4zLAo+ICsJREE5MDYz -X0NIQU5fVEpVTkMgPSBEQTkwNjNfQURDX01VWF9UX1NFTlNFLAo+ICsJREE5MDYzX0NIQU5fVkJC -QVQgPSBEQTkwNjNfQURDX01VWF9WQkJBVCwKPiArCURBOTA2M19DSEFOX0xET19HMSA9IERBOTA2 -M19BRENfTVVYX0xET19HMSwKPiArCURBOTA2M19DSEFOX0xET19HMiA9IERBOTA2M19BRENfTVVY -X0xET19HMiwKPiArCURBOTA2M19DSEFOX0xET19HMyA9IERBOTA2M19BRENfTVVYX0xET19HMwo+ -ICt9Owo+ICsKPiArc3RydWN0IGRhOTA2M19od21vbiB7Cj4gKwlzdHJ1Y3QgZGE5MDYzICpkYTkw -NjM7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpjbGFzc2RldjsKPiArCXN0cnVjdCBtdXRleCBod21vbl9t -dXRleDsKPiArCXN0cnVjdCBjb21wbGV0aW9uIGFkY19yZWFkeTsKPiArCXNpZ25lZCBjaGFyIHRq -dW5jX29mZnNldDsKPiArCWludCBpcnE7Cj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IGRhOTA2M19h -ZGNfY29udmVydChzdHJ1Y3QgZGE5MDYzX2h3bW9uICpod21vbiwgaW50IGNoYW5uZWwsCj4gKwkJ -CSAgICAgIGludCAqdmFsdWUpCj4gK3sKPiArCWludCB2YWwgPSAqdmFsdWU7Cj4gKwlpbnQgcmV0 -ID0gMDsKPiArCj4gKwlzd2l0Y2ggKGNoYW5uZWwpIHsKPiArCWNhc2UgREE5MDYzX0NIQU5fQURD -SU4xOgo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9BRENJTjI6Cj4gKwljYXNlIERBOTA2M19DSEFOX0FE -Q0lOMzoKPiArCQl2YWwgPSAoREE5MDYzXzJWNSAqIHZhbCkgLyBEQTkwNjNfQURDX01BWDsKPiAr -CQlicmVhazsKPiArCWNhc2UgREE5MDYzX0NIQU5fVlNZUzoKPiArCQl2YWwgPSAoKERBOTA2M181 -VjUgLSBEQTkwNjNfMlY1KSAqIHZhbCkgLyBEQTkwNjNfQURDX01BWCArCj4gKwkJCURBOTA2M18y -VjU7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIERBOTA2M19DSEFOX1RKVU5DOgo+ICsJCXZhbCAtPSBo -d21vbi0+dGp1bmNfb2Zmc2V0Owo+ICsJCXZhbCA9IChEQTkwNjNfVEpVTkNfTSAqICh2YWwgKyBE -QTkwNjNfVEpVTkNfQykpID4+IDEwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9W -QkJBVDoKPiArCQl2YWwgPSAoREE5MDYzXzVWMCAqIHZhbCkgLyBEQTkwNjNfQURDX01BWDsKPiAr -CQlicmVhazsKPiArCWRlZmF1bHQ6Cj4gKwkJcmV0ID0gLUVJTlZBTDsKPiArCQlnb3RvIGVycl9j -b252ZXJ0Owo+ICsJfQo+ICsKPiArCSp2YWx1ZSA9IHZhbDsKPiArZXJyX2NvbnZlcnQ6Cj4gKwly -ZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGRhOTA2M19hZGNfY3VycmVudF9zd2l0 -Y2goc3RydWN0IGRhOTA2M19od21vbiAqaHdtb24sIGludCBjaGFubmVsLAo+ICsJCQkJICAgICBi -b29sIG9uKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsJdW5zaWduZWQgaW50IHZhbDsKPiArCXVuc2ln -bmVkIGludCBtYXNrOwo+ICsKPiArCXN3aXRjaCAoY2hhbm5lbCkgewo+ICsJY2FzZSBEQTkwNjNf -Q0hBTl9BRENJTjE6Cj4gKwkJbWFzayA9IERBOTA2M19BRENfQUQxX0lTUkNfRU47Cj4gKwkJYnJl -YWs7Cj4gKwljYXNlIERBOTA2M19DSEFOX0FEQ0lOMjoKPiArCQltYXNrID0gREE5MDYzX0FEQ19B -RDJfSVNSQ19FTjsKPiArCQlicmVhazsKPiArCWNhc2UgREE5MDYzX0NIQU5fQURDSU4zOgo+ICsJ -CW1hc2sgPSBEQTkwNjNfQURDX0FEM19JU1JDX0VOOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoK -PiArCQlyZXQgPSAtRUlOVkFMOwo+ICsJCWdvdG8gZXJyX3N3aXRjaDsKPiArCX0KPiArCj4gKwlp -ZiAob24pCj4gKwkJdmFsID0gbWFzazsKPiArCWVsc2UKPiArCQl2YWwgPSB+bWFzazsKPiArCj4g -KwlyZXQgPSByZWdtYXBfdXBkYXRlX2JpdHMoaHdtb24tPmRhOTA2My0+cmVnbWFwLCBEQTkwNjNf -UkVHX0FEQ19DT05ULAo+ICsJCQkJIG1hc2ssIHZhbCk7Cj4gK2Vycl9zd2l0Y2g6Cj4gKwlyZXR1 -cm4gcmV0Owo+ICsKPiArfQo+ICsKPiArc3RhdGljIGludCBkYTkwNjNfYWRjX21hbnVhbF9yZWFk -KHN0cnVjdCBkYTkwNjNfaHdtb24gKmh3bW9uLCBpbnQgY2hhbm5lbCkKPiArewo+ICsJaW50IHJl -dDsKPiArCXVuc2lnbmVkIGNoYXIgdmFsOwo+ICsJdW5zaWduZWQgY2hhciBkYXRhWzJdOwo+ICsJ -aW50IGFkY19tYW47Cj4gKwo+ICsJbXV0ZXhfbG9jaygmaHdtb24tPmh3bW9uX211dGV4KTsKPiAr -Cj4gKwlpbml0X2NvbXBsZXRpb24oJmh3bW9uLT5hZGNfcmVhZHkpOwo+ICsKPiArCXZhbCA9IChj -aGFubmVsICYgREE5MDYzX0FEQ19NVVhfTUFTSykgfCBEQTkwNjNfQURDX01BTjsKPiArCXJldCA9 -IHJlZ21hcF91cGRhdGVfYml0cyhod21vbi0+ZGE5MDYzLT5yZWdtYXAsIERBOTA2M19SRUdfQURD -X01BTiwKPiArCQkJCSBEQTkwNjNfQURDX01VWF9NQVNLIHwgREE5MDYzX0FEQ19NQU4sIHZhbCk7 -Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlnb3RvIGVycl9tcmVhZDsKPiArCj4gKwlyZXQgPSB3YWl0 -X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoJmh3bW9uLT5hZGNfcmVhZHksCj4gKwkJCQkJICBtc2Vj -c190b19qaWZmaWVzKDEwMDApKTsKPiArCWlmIChyZXQgPT0gMCkgewo+ICsJCXJldCA9IC1FVElN -RURPVVQ7Cj4gKwkJZ290byBlcnJfbXJlYWQ7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3Jl -YWQoaHdtb24tPmRhOTA2My0+cmVnbWFwLCBEQTkwNjNfUkVHX0FEQ19NQU4sICZhZGNfbWFuKTsK -PiArCWlmIChyZXQgPCAwKQo+ICsJCWdvdG8gZXJyX21yZWFkOwo+ICsKPiArCS8qIGRhdGEgdmFs -dWUgaXMgbm90IHJlYWR5ICovCj4gKwlpZiAoYWRjX21hbiAmIERBOTA2M19BRENfTUFOID09IDAp -IHsKPiArCQlyZXQgPSAtRUlOVkFMOwo+ICsJCWdvdG8gZXJyX21yZWFkOwo+ICsJfQo+ICsKPiAr -CXJldCA9IHJlZ21hcF9idWxrX3JlYWQoaHdtb24tPmRhOTA2My0+cmVnbWFwLAo+ICsJCQkgICAg -ICAgREE5MDYzX1JFR19BRENfUkVTX0wsIGRhdGEsIDIpOwo+ICsJaWYgKHJldCA8IDApCj4gKwkJ -Z290byBlcnJfbXJlYWQ7Cj4gKwo+ICsJcmV0ID0gKGRhdGFbMF0gJiBEQTkwNjNfQURDX1JFU19M -X01BU0spID4+IERBOTA2M19BRENfUkVTX0xfU0hJRlQ7Cj4gKwlyZXQgfD0gZGF0YVsxXSA8PCBE -QTkwNjNfQURDX1JFU19MX0JJVFM7Cj4gK2Vycl9tcmVhZDoKPiArCW11dGV4X3VubG9jaygmaHdt -b24tPmh3bW9uX211dGV4KTsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBpcnFy -ZXR1cm5fdCBkYTkwNjNfaHdtb25faXJxX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqaXJxX2RhdGEp -Cj4gK3sKPiArCXN0cnVjdCBkYTkwNjNfaHdtb24gKmh3bW9uID0gaXJxX2RhdGE7Cj4gKwljb21w -bGV0ZSgmaHdtb24tPmFkY19yZWFkeSk7Cj4gKwlyZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gK30KPiAr -Cj4gK3N0YXRpYyBzc2l6ZV90IGRhOTA2M19hZGNfcmVhZChzdHJ1Y3QgZGV2aWNlICpkZXYsCj4g -KwkJCSAgICAgICBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqZGV2YXR0ciwgY2hhciAqYnVmKQo+ -ICt7Cj4gKwlzdHJ1Y3QgZGE5MDYzX2h3bW9uICpod21vbiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYp -Owo+ICsJaW50IGNoYW5uZWwgPSB0b19zZW5zb3JfZGV2X2F0dHIoZGV2YXR0ciktPmluZGV4Owo+ -ICsJaW50IHZhbDsKPiArCWludCByZXQ7Cj4gKwo+ICsJc3dpdGNoIChjaGFubmVsKSB7Cj4gKwlj -YXNlIERBOTA2M19DSEFOX0FEQ0lOMToKPiArCWNhc2UgREE5MDYzX0NIQU5fQURDSU4yOgo+ICsJ -Y2FzZSBEQTkwNjNfQ0hBTl9BRENJTjM6Cj4gKwkJLyogZmFsbHRocm91Z2ggZm9yIEFEQyBtZWFz -dXJlcyAqLwo+ICsJCXJldCA9IGRhOTA2M19hZGNfY3VycmVudF9zd2l0Y2goaHdtb24sIGNoYW5u -ZWwsIHRydWUpOwo+ICsJCWlmIChyZXQgPCAwKQo+ICsJCQlnb3RvIGVycl9yZWFkOwo+ICsKPiAr -CQl2YWwgPSBkYTkwNjNfYWRjX21hbnVhbF9yZWFkKGh3bW9uLCBjaGFubmVsKTsKPiArCQlpZiAo -dmFsIDwgMCkgewo+ICsJCQlyZXQgPSB2YWw7Cj4gKwkJCWlmIChyZXQgPT0gLUVJTlZBTCkKPiAr -CQkJCWRldl9lcnIoZGV2LCAiQ29udmVyc2lvbiB3YXMgbm90IGNvbXBsZXRlZFxuIik7Cj4gKwkJ -CWVsc2UKPiArCQkJCWRldl9lcnIoZGV2LCAiQURDIHJlYWQgZXJyb3IgJWRcbiIsIHJldCk7Cj4g -KwkJCWdvdG8gZXJyX3JlYWQ7Cj4gKwkJfQo+ICsKPiArCQlyZXQgPSBkYTkwNjNfYWRjX2N1cnJl -bnRfc3dpdGNoKGh3bW9uLCBjaGFubmVsLCBmYWxzZSk7Cj4gKwkJaWYgKHJldCA8IDApIHsKPiAr -CQkJZGV2X2VycihkZXYsICJDb3VsZCBub3Qgc3dpdGNoIGN1cnJlbnRcbiIpOwo+ICsJCQlnb3Rv -IGVycl9yZWFkOwo+ICsJCX0KPiArCQlicmVhazsKPiArCj4gKwljYXNlIERBOTA2M19DSEFOX1ZT -WVM6Cj4gKwljYXNlIERBOTA2M19DSEFOX1RKVU5DOgo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9WQkJB -VDoKPiArCQkvKiBmYWxsdGhyb3VnaCBmb3IgaW50ZXJuYWwgbWVhc3VyZXMgKi8KPiArCQl2YWwg -PSBkYTkwNjNfYWRjX21hbnVhbF9yZWFkKGh3bW9uLCBjaGFubmVsKTsKPiArCQlpZiAodmFsIDwg -MCkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkFEQyByZWFkIGVycm9yICVkXG4iLCB2YWwpOwo+ICsJ -CQlyZXR1cm4gdmFsOwo+ICsJCX0KPiArCQlicmVhazsKPiArCj4gKwlkZWZhdWx0Ogo+ICsJCS8q -IGVycm9yIGNhc2UgKi8KPiArCQlyZXQgPSAtRUlOVkFMOwo+ICsJCWdvdG8gZXJyX3JlYWQ7Cj4g -Kwl9Cj4gKwo+ICsJcmV0ID0gZGE5MDYzX2FkY19jb252ZXJ0KGh3bW9uLCBjaGFubmVsLCAmdmFs -KTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycihkZXYsICJGYWlsZWQgdG8gY29udmVy -dCBBREMgdmFsdWUgJWRcbiIsIHJldCk7Cj4gKwkJZ290byBlcnJfcmVhZDsKPiArCX0KPiArCj4g -KwlyZXR1cm4gc3ByaW50ZihidWYsICIlZFxuIiwgdmFsKTsKPiArZXJyX3JlYWQ6Cj4gKwlyZXR1 -cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgc3NpemVfdCBkYTkwNjNfc2hvd19uYW1lKHN0cnVj -dCBkZXZpY2UgKmRldiwKPiArCQkJCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFy -ICpidWYpCj4gK3sKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgREE5MDYzX0RSVk5BTUVfSFdNT04g -IlxuIik7Cj4gK30KPiArCj4gK3N0YXRpYyBzc2l6ZV90IGRhOTA2M19zaG93X2xhYmVsKHN0cnVj -dCBkZXZpY2UgKmRldiwKPiArCQkJCSBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqZGV2YXR0ciwg -Y2hhciAqYnVmKQo+ICt7Cj4gKwlpbnQgY2hhbm5lbCA9IHRvX3NlbnNvcl9kZXZfYXR0cihkZXZh -dHRyKS0+aW5kZXg7Cj4gKwljaGFyICpsYWJlbDsKPiArCj4gKwlzd2l0Y2ggKGNoYW5uZWwpIHsK -PiArCWNhc2UgREE5MDYzX0NIQU5fVlNZUzoKPiArCQlsYWJlbCA9ICJWU1lTIjsKPiArCQlicmVh -azsKPiArCWNhc2UgREE5MDYzX0NIQU5fQURDSU4xOgo+ICsJCWxhYmVsID0gIkFEQ0lOMSI7Cj4g -KwkJYnJlYWs7Cj4gKwljYXNlIERBOTA2M19DSEFOX0FEQ0lOMjoKPiArCQlsYWJlbCA9ICJBRENJ -TjIiOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9BRENJTjM6Cj4gKwkJbGFiZWwg -PSAiQURDSU4zIjsKPiArCQlicmVhazsKPiArCWNhc2UgREE5MDYzX0NIQU5fVEpVTkM6Cj4gKwkJ -bGFiZWwgPSAiVEpVTkMiOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9WQkJBVDoK -PiArCQlsYWJlbCA9ICJWQkJBVCI7Cj4gKwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ICsJCWxhYmVs -ID0gIlVOS05PV04iOwo+ICsJfQo+ICsKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBs -YWJlbCk7Cj4gK30KPiArCj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2lucHV0LCBT -X0lSVUdPLAo+ICsJCQkgIGRhOTA2M19hZGNfcmVhZCwgTlVMTCwgREE5MDYzX0NIQU5fVlNZUyk7 -Cj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2xhYmVsLCBTX0lSVUdPLAo+ICsJCQkg -IGRhOTA2M19zaG93X2xhYmVsLCBOVUxMLCBEQTkwNjNfQ0hBTl9WU1lTKTsKPiArCj4gK3N0YXRp -YyBTRU5TT1JfREVWSUNFX0FUVFIoaW4xX2lucHV0LCBTX0lSVUdPLAo+ICsJCQkgIGRhOTA2M19h -ZGNfcmVhZCwgTlVMTCwgREE5MDYzX0NIQU5fQURDSU4xKTsKPiArc3RhdGljIFNFTlNPUl9ERVZJ -Q0VfQVRUUihpbjFfbGFiZWwsIFNfSVJVR08sCj4gKwkJCSAgZGE5MDYzX3Nob3dfbGFiZWwsIE5V -TEwsIERBOTA2M19DSEFOX0FEQ0lOMSk7Cj4gKwo+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRS -KGluMl9pbnB1dCwgU19JUlVHTywKPiArCQkJICBkYTkwNjNfYWRjX3JlYWQsIE5VTEwsIERBOTA2 -M19DSEFOX0FEQ0lOMik7Cj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4yX2xhYmVsLCBT -X0lSVUdPLAo+ICsJCQkgIGRhOTA2M19zaG93X2xhYmVsLCBOVUxMLCBEQTkwNjNfQ0hBTl9BRENJ -TjIpOwo+ICsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihpbjNfaW5wdXQsIFNfSVJVR08s -Cj4gKwkJCSAgZGE5MDYzX2FkY19yZWFkLCBOVUxMLCBEQTkwNjNfQ0hBTl9BRENJTjMpOwo+ICtz -dGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKGluM19sYWJlbCwgU19JUlVHTywKPiArCQkJICBkYTkw -NjNfc2hvd19sYWJlbCwgTlVMTCwgREE5MDYzX0NIQU5fQURDSU4zKTsKPiArCj4gK3N0YXRpYyBT -RU5TT1JfREVWSUNFX0FUVFIoaW40X2lucHV0LCBTX0lSVUdPLAo+ICsJCQkgIGRhOTA2M19hZGNf -cmVhZCwgTlVMTCwgREE5MDYzX0NIQU5fVkJCQVQpOwo+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9B -VFRSKGluNF9sYWJlbCwgU19JUlVHTywKPiArCQkJICBkYTkwNjNfc2hvd19sYWJlbCwgTlVMTCwg -REE5MDYzX0NIQU5fVkJCQVQpOwo+ICsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUih0ZW1w -MV9pbnB1dCwgU19JUlVHTywKPiArCQkJICBkYTkwNjNfYWRjX3JlYWQsIE5VTEwsIERBOTA2M19D -SEFOX1RKVU5DKTsKPiArCj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVtcDFfbGFiZWws -IFNfSVJVR08sCj4gKwkJCSAgZGE5MDYzX3Nob3dfbGFiZWwsIE5VTEwsIERBOTA2M19DSEFOX1RK -VU5DKTsKPiArCj4gK3N0YXRpYyBERVZJQ0VfQVRUUihuYW1lLCBTX0lSVUdPLCBkYTkwNjNfc2hv -d19uYW1lLCBOVUxMKTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpkYTkwNjNfYXR0 -cmlidXRlc1tdID0gewo+ICsJJmRldl9hdHRyX25hbWUuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0 -dHJfaW4wX2lucHV0LmRldl9hdHRyLmF0dHIsCj4gKwkmc2Vuc29yX2Rldl9hdHRyX2luMF9sYWJl -bC5kZXZfYXR0ci5hdHRyLAo+ICsJJnNlbnNvcl9kZXZfYXR0cl9pbjFfaW5wdXQuZGV2X2F0dHIu -YXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfaW4xX2xhYmVsLmRldl9hdHRyLmF0dHIsCj4gKwkm -c2Vuc29yX2Rldl9hdHRyX2luMl9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+ICsJJnNlbnNvcl9kZXZf -YXR0cl9pbjJfbGFiZWwuZGV2X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfaW4zX2lu -cHV0LmRldl9hdHRyLmF0dHIsCj4gKwkmc2Vuc29yX2Rldl9hdHRyX2luM19sYWJlbC5kZXZfYXR0 -ci5hdHRyLAo+ICsJJnNlbnNvcl9kZXZfYXR0cl9pbjRfaW5wdXQuZGV2X2F0dHIuYXR0ciwKPiAr -CSZzZW5zb3JfZGV2X2F0dHJfaW40X2xhYmVsLmRldl9hdHRyLmF0dHIsCj4gKwkmc2Vuc29yX2Rl -dl9hdHRyX3RlbXAxX2lucHV0LmRldl9hdHRyLmF0dHIsCj4gKwkmc2Vuc29yX2Rldl9hdHRyX3Rl -bXAxX2xhYmVsLmRldl9hdHRyLmF0dHIsCj4gKwlOVUxMCj4gK307Cj4gKwo+ICtzdGF0aWMgY29u -c3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBkYTkwNjNfYXR0cl9ncm91cCA9IHsKPiArCS5hdHRy -cyA9IGRhOTA2M19hdHRyaWJ1dGVzLAo+ICt9Owo+ICsKPiArc3RhdGljIGludCBkYTkwNjNfaHdt -b25fcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IGRh -OTA2MyAqZGE5MDYzID0gZGV2X2dldF9kcnZkYXRhKHBkZXYtPmRldi5wYXJlbnQpOwo+ICsJc3Ry -dWN0IGRhOTA2M19wZGF0YSAqcGRhdGEgPSBkYTkwNjMtPmRldi0+cGxhdGZvcm1fZGF0YTsKPiAr -CXN0cnVjdCBkYTkwNjNfaHdtb24gKmh3bW9uOwo+ICsJaW50IHJldDsKPiArCXVuc2lnbmVkIGlu -dCB2YWw7Cj4gKwo+ICsJaHdtb24gPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgc2l6ZW9mKHN0 -cnVjdCBkYTkwNjNfaHdtb24pLAo+ICsJCQkgICAgIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFod21v -bikKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwltdXRleF9pbml0KCZod21vbi0+aHdtb25f -bXV0ZXgpOwo+ICsJaW5pdF9jb21wbGV0aW9uKCZod21vbi0+YWRjX3JlYWR5KTsKPiArCWh3bW9u -LT5kYTkwNjMgPSBkYTkwNjM7Cj4gKwo+ICsJLyogZW5hYmxlIHRoZSBBREMgZnVuY3Rpb25zIGZv -ciBHUElPIDAsMSwyICovCj4gKwl2YWwgPSAoREE5MDYzX0dQSU8wX1BJTl9BRENJTjEgPDwgREE5 -MDYzX0dQSU8wX1BJTl9NQVNLX1NISUZUIHwKPiArCSAgICAgICBEQTkwNjNfR1BJTzFfUElOX0FE -Q0lOMl9DT01QIDw8IERBOTA2M19HUElPMV9QSU5fTUFTS19TSElGVCk7Cj4gKwlyZXQgPSByZWdt -YXBfdXBkYXRlX2JpdHMoaHdtb24tPmRhOTA2My0+cmVnbWFwLCBEQTkwNjNfUkVHX0dQSU9fMF8x -LAo+ICsJCQkJIChEQTkwNjNfR1BJTzBfUElOX01BU0sgfAo+ICsJCQkJICBEQTkwNjNfR1BJTzFf -UElOX01BU0spLCB2YWwpOwo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKCZwZGV2LT5k -ZXYsCj4gKwkJCSJGYWlsZWQgdG8gYWx0ZXIgdGhlIEFEQ0lOIDEsMiBiaXRzIGZvciB0aGUgR1BJ -TyAwLDEgcmVnaXN0ZXJcbiIpOwo+ICsJCXJldHVybiAtRUlPOwo+ICsJfQo+ICsKPiArCXZhbCA9 -IERBOTA2M19HUElPMl9QSU5fQURDSU4zIDw8IERBOTA2M19HUElPMl9QSU5fTUFTS19TSElGVDsK -PiArCXJldCA9IHJlZ21hcF91cGRhdGVfYml0cyhod21vbi0+ZGE5MDYzLT5yZWdtYXAsIERBOTA2 -M19SRUdfR1BJT18yXzMsCj4gKwkJCQkgREE5MDYzX0dQSU8yX1BJTl9NQVNLLCB2YWwpOwo+ICsJ -aWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsCj4gKwkJCSJGYWlsZWQgdG8g -YWx0ZXIgdGhlIEFEQ0lOIDMgYml0cyBmb3IgdGhlIEdQSU8gMiwzIHJlZ2lzdGVyXG4iKTsKPiAr -CQlyZXR1cm4gLUVJTzsKPiArCX0KPiArCj4gKwkvKiBkZWJvdW5jZSBBREMgSSBzZXR0aW5ncyAq -Lwo+ICsJdmFsID0gKERBOTA2M19BRENJTjFfREVCX09OIDw8IERBOTA2M19SRUdfQURDSU4xX0RF -Ql9TSElGVCB8Cj4gKwkgICAgICAgREE5MDYzX0FEQ0lOMl9ERUJfT04gPDwgREE5MDYzX1JFR19B -RENJTjJfREVCX1NISUZUIHwKPiArCSAgICAgICBEQTkwNjNfQURDSU4zX0RFQl9PTiA8PCBEQTkw -NjNfUkVHX0FEQ0lOM19ERUJfU0hJRlQpOwo+ICsJcmV0ID0gcmVnbWFwX3VwZGF0ZV9iaXRzKGh3 -bW9uLT5kYTkwNjMtPnJlZ21hcCwgREE5MDYzX1JFR19BRENfQ0ZHLAo+ICsJCQkJIChEQTkwNjNf -UkVHX0FEQ0lOMV9ERUJfTUFTSyB8Cj4gKwkJCQkgIERBOTA2M19SRUdfQURDSU4yX0RFQl9NQVNL -IHwKPiArCQkJCSAgREE5MDYzX1JFR19BRENJTjNfREVCX01BU0spLCB2YWwpOwo+ICsJaWYgKHJl -dCA8IDApIHsKPiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsCj4gKwkJCSJGYWlsZWQgdG8gYWx0ZXIg -dGhlIEFEQyBjb25maWd1cmF0aW9uIHJlZ2lzdGVyXG4iKTsKPiArCQlyZXR1cm4gLUVJTzsKPiAr -CX0KPiArCj4gKwkvKiBzZXQgdXAgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbnMgKi8KPiArCXZh -bCA9IChwZGF0YS0+aHdtb25fcGRhdGEtPmFkY2luMV9jdXIgPDwgREE5MDYzX1JFR19BRENJTjFf -Q1VSX1NISUZUIHwKPiArCSAgICAgICBwZGF0YS0+aHdtb25fcGRhdGEtPmFkY2luMl9jdXIgPDwg -REE5MDYzX1JFR19BRENJTjJfQ1VSX1NISUZUIHwKPiArCSAgICAgICBwZGF0YS0+aHdtb25fcGRh -dGEtPmFkY2luM19jdXIgPDwgREE5MDYzX1JFR19BRENJTjNfQ1VSX1NISUZUKTsKPiArCXJldCA9 -IHJlZ21hcF91cGRhdGVfYml0cyhod21vbi0+ZGE5MDYzLT5yZWdtYXAsIERBOTA2M19SRUdfQURD -X0NGRywKPiArCQkJCSAoREE5MDYzX1JFR19BRENJTjFfQ1VSX01BU0sgfAo+ICsJCQkJICBEQTkw -NjNfUkVHX0FEQ0lOMl9DVVJfTUFTSyB8Cj4gKwkJCQkgIERBOTA2M19SRUdfQURDSU4zX0NVUl9N -QVNLKSwgdmFsKTsKPiArCj4gKwlyZXQgPSByZWdtYXBfcmVhZChkYTkwNjMtPnJlZ21hcCwgREE5 -MDYzX1JFR19BRENfQ0ZHLCAmdmFsKTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2Vycigm -cGRldi0+ZGV2LAo+ICsJCQkiRmFpbGVkIHRvIHJlYWQgcmVhZCB0aGUgQURDIGNvbmZpZ3VyYXRp -b24gcmVnaXN0ZXJcbiIpOwo+ICsJCXJldHVybiAtRUlPOwo+ICsJfQo+ICsKPiArCWh3bW9uLT5p -cnEgPSBwbGF0Zm9ybV9nZXRfaXJxX2J5bmFtZShwZGV2LCBEQTkwNjNfRFJWTkFNRV9IV01PTik7 -Cj4gKwlpZiAoaHdtb24tPmlycSA8IDApCj4gKwkJcmV0dXJuIGh3bW9uLT5pcnE7Cj4gKwo+ICsJ -cmV0ID0gZGV2bV9yZXF1ZXN0X3RocmVhZGVkX2lycSgmcGRldi0+ZGV2LCBod21vbi0+aXJxLCBO -VUxMLAo+ICsJCQkJCWRhOTA2M19od21vbl9pcnFfaGFuZGxlciwKPiArCQkJCQlJUlFGX1RSSUdH -RVJfTE9XIHwgSVJRRl9PTkVTSE9ULAo+ICsJCQkJCSJIV01PTiIsIGh3bW9uKTsKPiArCWlmIChy -ZXQpIHsKPiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJGYWlsZWQgdG8gcmVxdWVzdCBJUlEuXG4i -KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBk -ZXYsIGh3bW9uKTsKPiArCj4gKwkvKiBzZXQgdHJpbSB0ZW1wZXJhdHVyZSBvZmZzZXQgdG8gdmFs -dWUgcmVhZCBhdCBzdGFydHVwICovCj4gKwlod21vbi0+dGp1bmNfb2Zmc2V0ID0gKHNpZ25lZCBj -aGFyKWh3bW9uLT5kYTkwNjMtPnRfb2Zmc2V0Owo+ICsKPiArCXJldCA9IHN5c2ZzX2NyZWF0ZV9n -cm91cCgmcGRldi0+ZGV2LmtvYmosICZkYTkwNjNfYXR0cl9ncm91cCk7Cj4gKwlpZiAocmV0KQo+ -ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJaHdtb24tPmNsYXNzZGV2ID0gaHdtb25fZGV2aWNlX3Jl -Z2lzdGVyKCZwZGV2LT5kZXYpOwo+ICsJaWYgKElTX0VSUihod21vbi0+Y2xhc3NkZXYpKSB7Cj4g -KwkJc3lzZnNfcmVtb3ZlX2dyb3VwKCZwZGV2LT5kZXYua29iaiwgJmRhOTA2M19hdHRyX2dyb3Vw -KTsKPiArCQlyZXR1cm4gUFRSX0VSUihod21vbi0+Y2xhc3NkZXYpOwo+ICsJfQo+ICsKPiArCXJl -dHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGRhOTA2M19od21vbl9yZW1vdmUoc3RydWN0 -IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IGRhOTA2M19od21vbiAqaHdt -b24gPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKPiArCj4gKwlod21vbl9kZXZpY2VfdW5y -ZWdpc3Rlcihod21vbi0+Y2xhc3NkZXYpOwo+ICsJc3lzZnNfcmVtb3ZlX2dyb3VwKCZwZGV2LT5k -ZXYua29iaiwgJmRhOTA2M19hdHRyX2dyb3VwKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK -PiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgZGE5MDYzX2h3bW9uX2RyaXZlciA9IHsK -PiArCS5wcm9iZSA9IGRhOTA2M19od21vbl9wcm9iZSwKPiArCS5yZW1vdmUgPSBkYTkwNjNfaHdt -b25fcmVtb3ZlLAo+ICsJLmRyaXZlciA9IHsKPiArCQkgICAubmFtZSA9IERBOTA2M19EUlZOQU1F -X0hXTU9OLAo+ICsJCSAgIC5vd25lciA9IFRISVNfTU9EVUxFLAo+ICsJCSAgIH0sCj4gK307Cj4g -Kwo+ICttb2R1bGVfcGxhdGZvcm1fZHJpdmVyKGRhOTA2M19od21vbl9kcml2ZXIpOwo+ICsKPiAr -TU9EVUxFX0RFU0NSSVBUSU9OKCJIYXJkd2FyZSBtb25pdG9yIHN1cHBvcnQgZGV2aWNlIGRyaXZl -ciBmb3IgRGlhbG9nIERBOTA2MyIpOwo+ICtNT0RVTEVfQVVUSE9SKCJTIFR3aXNzIDxzdHdpc3Mu -b3BlbnNvdXJjZUBkaWFzZW1pLmNvbT4iKTsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+ -ICtNT0RVTEVfQUxJQVMoInBsYXRmb3JtOiIgREE5MDYzX0RSVk5BTUVfSFdNT04pOwo+IGRpZmYg -LS1naXQgYS9pbmNsdWRlL2xpbnV4L21mZC9kYTkwNjMvcmVnaXN0ZXJzLmggYi9pbmNsdWRlL2xp -bnV4L21mZC9kYTkwNjMvcmVnaXN0ZXJzLmgKPiBpbmRleCAwOWE4NWM2Li45MjIzNzFiIDEwMDY0 -NAo+IC0tLSBhL2luY2x1ZGUvbGludXgvbWZkL2RhOTA2My9yZWdpc3RlcnMuaAo+ICsrKyBiL2lu -Y2x1ZGUvbGludXgvbWZkL2RhOTA2My9yZWdpc3RlcnMuaAo+IEBAIC00NzQsNiArNDc0LDcgQEAK -PiAgCj4gIC8qIERBOTA2M19SRUdfR1BJT18wXzEgKGFkZHI9MHgxNSkgKi8KPiAgI2RlZmluZQlE -QTkwNjNfR1BJTzBfUElOX01BU0sJCQkweDAzCj4gKyNkZWZpbmUJREE5MDYzX0dQSU8wX1BJTl9N -QVNLX1NISUZUCQkwCj4gICNkZWZpbmUJCURBOTA2M19HUElPMF9QSU5fQURDSU4xCQkweDAwCj4g -ICNkZWZpbmUJCURBOTA2M19HUElPMF9QSU5fR1BJCQkweDAxCj4gICNkZWZpbmUJCURBOTA2M19H -UElPMF9QSU5fR1BPX09ECQkweDAyCj4gQEAgLTQ4NSw2ICs0ODYsNyBAQAo+ICAjZGVmaW5lCQlE -QTkwNjNfR1BJTzBfVFlQRV9HUE9fVkREX0lPMgkweDA0Cj4gICNkZWZpbmUJREE5MDYzX0dQSU8w -X05PX1dBS0VVUAkJCTB4MDgKPiAgI2RlZmluZQlEQTkwNjNfR1BJTzFfUElOX01BU0sJCQkweDMw -Cj4gKyNkZWZpbmUJREE5MDYzX0dQSU8xX1BJTl9NQVNLX1NISUZUCQk0Cj4gICNkZWZpbmUJCURB -OTA2M19HUElPMV9QSU5fQURDSU4yX0NPTVAJMHgwMAo+ICAjZGVmaW5lCQlEQTkwNjNfR1BJTzFf -UElOX0dQSQkJMHgxMAo+ICAjZGVmaW5lCQlEQTkwNjNfR1BJTzFfUElOX0dQT19PRAkJMHgyMAo+ -IEBAIC00OTgsNiArNTAwLDcgQEAKPiAgCj4gIC8qIERBOTA2M19SRUdfR1BJT18yXzMgKGFkZHI9 -MHgxNikgKi8KPiAgI2RlZmluZQlEQTkwNjNfR1BJTzJfUElOX01BU0sJCQkweDAzCj4gKyNkZWZp -bmUJREE5MDYzX0dQSU8yX1BJTl9NQVNLX1NISUZUCQkwCj4gICNkZWZpbmUJCURBOTA2M19HUElP -Ml9QSU5fQURDSU4zCQkweDAwCj4gICNkZWZpbmUJCURBOTA2M19HUElPMl9QSU5fR1BJCQkweDAx -Cj4gICNkZWZpbmUJCURBOTA2M19HUElPMl9QSU5fR1BPX1BTUwkweDAyCj4gQEAgLTgxMyw2ICs4 -MTYsNyBAQAo+ICAjZGVmaW5lCURBOTA2M19WU1lTX1ZBTF9CQVNFCQkJMHgwMAo+ICAKPiAgLyog -REE5MDYzX1JFR19BRENfUkVTX0wgKGFkZHI9MHgzNykgKi8KPiArI2RlZmluZQlEQTkwNjNfQURD -X1JFU19MX1NISUZUCQkJNgo+ICAjZGVmaW5lCURBOTA2M19BRENfUkVTX0xfQklUUwkJCTIKPiAg -I2RlZmluZQlEQTkwNjNfQURDX1JFU19MX01BU0sJCQkweEMwCj4gIAo+IEBAIC05NzksNiArOTgz -LDM2IEBACj4gICNkZWZpbmUgREE5MDYzX0dQSU9fRElNCQkJCTB4ODAKPiAgI2RlZmluZSBEQTkw -NjNfR1BJT19QV01fTUFTSwkJCTB4N0YKPiAgCj4gKy8qIERBOTA2M19SRUdfQURDX0NGRyAoYWRk -cj0weEM5KSAqLwo+ICsjZGVmaW5lIERBOTA2M19SRUdfQURDSU4xX0NVUl9NQVNLCQkweDAzCj4g -KyNkZWZpbmUgREE5MDYzX1JFR19BRENJTjFfQ1VSX1NISUZUCQkwCj4gKyNkZWZpbmUJCURBOTA2 -M19BRENJTjFfQ1VSXzFVQQkJMHgwMAo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4xX0NVUl8yVUEJ -CTB4MDEKPiArI2RlZmluZQkJREE5MDYzX0FEQ0lOMV9DVVJfMTBVQQkJMHgwMgo+ICsjZGVmaW5l -CQlEQTkwNjNfQURDSU4xX0NVUl80MFVBCQkweDAzCj4gKyNkZWZpbmUgREE5MDYzX1JFR19BRENJ -TjJfQ1VSX01BU0sJCTB4MEMKPiArI2RlZmluZSBEQTkwNjNfUkVHX0FEQ0lOMl9DVVJfU0hJRlQJ -CTIKPiArI2RlZmluZQkJREE5MDYzX0FEQ0lOMl9DVVJfMVVBCQkweDAwCj4gKyNkZWZpbmUJCURB -OTA2M19BRENJTjJfQ1VSXzJVQQkJMHgwMQo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4yX0NVUl8x -MFVBCQkweDAyCj4gKyNkZWZpbmUJCURBOTA2M19BRENJTjJfQ1VSXzQwVUEJCTB4MDMKPiArI2Rl -ZmluZSBEQTkwNjNfUkVHX0FEQ0lOM19DVVJfTUFTSwkJMHgxMAo+ICsjZGVmaW5lIERBOTA2M19S -RUdfQURDSU4zX0NVUl9TSElGVAkJNAo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4zX0NVUl8xMFVB -CQkweDAwCj4gKyNkZWZpbmUJCURBOTA2M19BRENJTjNfQ1VSXzQwVUEJCTB4MDEKPiArI2RlZmlu -ZSBEQTkwNjNfUkVHX0FEQ0lOMV9ERUJfTUFTSwkJMHgyMAo+ICsjZGVmaW5lIERBOTA2M19SRUdf -QURDSU4xX0RFQl9TSElGVAkJNQo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4xX0RFQl9PRkYJCTB4 -MDAKPiArI2RlZmluZQkJREE5MDYzX0FEQ0lOMV9ERUJfT04JCTB4MDEKPiArI2RlZmluZSBEQTkw -NjNfUkVHX0FEQ0lOMl9ERUJfTUFTSwkJMHg0MAo+ICsjZGVmaW5lIERBOTA2M19SRUdfQURDSU4y -X0RFQl9TSElGVAkJNgo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4yX0RFQl9PRkYJCTB4MDAKPiAr -I2RlZmluZQkJREE5MDYzX0FEQ0lOMl9ERUJfT04JCTB4MDEKPiArI2RlZmluZSBEQTkwNjNfUkVH -X0FEQ0lOM19ERUJfTUFTSwkJMHg4MAo+ICsjZGVmaW5lIERBOTA2M19SRUdfQURDSU4zX0RFQl9T -SElGVAkJNwo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4zX0RFQl9PRkYJCTB4MDAKPiArI2RlZmlu -ZQkJREE5MDYzX0FEQ0lOM19ERUJfT04JCTB4MDEKPiArCj4gIC8qIERBOTA2M19SRUdfQ09ORklH -X0ggKGFkZHI9MHgxMEQpICovCj4gICNkZWZpbmUgREE5MDYzX1BXTV9DTEtfTUFTSwkJCTB4MDEK -PiAgI2RlZmluZQkJREE5MDYzX1BXTV9DTEtfUFdNMk1IWgkJMHgwMAoKLS0gCkxlZSBKb25lcwpM -aW5hcm8gU1RNaWNyb2VsZWN0cm9uaWNzIExhbmRpbmcgVGVhbSBMZWFkCkxpbmFyby5vcmcg4pSC -IE9wZW4gc291cmNlIHNvZnR3YXJlIGZvciBBUk0gU29DcwpGb2xsb3cgTGluYXJvOiBGYWNlYm9v -ayB8IFR3aXR0ZXIgfCBCbG9nCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f -X19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMu -b3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNv -cnM +> From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> +> +> Add the HWMON driver for DA9063 +> +> Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> +> --- +> +> drivers/hwmon/Kconfig | 10 + +> drivers/hwmon/Makefile | 1 + +> drivers/hwmon/da9063-hwmon.c | 456 ++++++++++++++++++++++++++++++++++ +> include/linux/mfd/da9063/registers.h | 34 +++ + +I'd prefer to see all values in hex, but this probably a preference +thing rather than something which would prevent acceptance. + +For the MFD header changes: + Acked-by: Lee Jones <lee.jones@linaro.org> + +> 4 files changed, 501 insertions(+) +> create mode 100644 drivers/hwmon/da9063-hwmon.c +> +> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +> index f288b60..68aa886 100644 +> --- a/drivers/hwmon/Kconfig +> +++ b/drivers/hwmon/Kconfig +> @@ -391,6 +391,16 @@ config SENSORS_DA9055 +> This driver can also be built as a module. If so, the module +> will be called da9055-hwmon. +> +> +config SENSORS_DA9063 +> + tristate "Dialog Semiconductor DA9063" +> + depends on MFD_DA9063 +> + help +> + If you say yes here you get support for the hardware +> + monitoring features of the DA9063 Power Management IC. +> + +> + This driver can also be built as a module. If so, the module +> + will be called da9063-hwmon. +> + +> config SENSORS_I5K_AMB +> tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets" +> depends on PCI +> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile +> index c48f987..4174b07 100644 +> --- a/drivers/hwmon/Makefile +> +++ b/drivers/hwmon/Makefile +> @@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o +> obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o +> obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o +> obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o +> +obj-$(CONFIG_SENSORS_DA9063) += da9063-hwmon.o +> obj-$(CONFIG_SENSORS_DME1737) += dme1737.o +> obj-$(CONFIG_SENSORS_DS620) += ds620.o +> obj-$(CONFIG_SENSORS_DS1621) += ds1621.o +> diff --git a/drivers/hwmon/da9063-hwmon.c b/drivers/hwmon/da9063-hwmon.c +> new file mode 100644 +> index 0000000..7756cb2 +> --- /dev/null +> +++ b/drivers/hwmon/da9063-hwmon.c +> @@ -0,0 +1,456 @@ +> +/* da9063-hwmon.c - Hardware monitor support for DA9063 +> + * Copyright (C) 2014 Dialog Semiconductor Ltd. +> + * +> + * This library is free software; you can redistribute it and/or +> + * modify it under the terms of the GNU Library General Public +> + * License as published by the Free Software Foundation; either +> + * version 2 of the License, or (at your option) any later version. +> + * +> + * This library is distributed in the hope that it will be useful, +> + * but WITHOUT ANY WARRANTY; without even the implied warranty of +> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +> + * Library General Public License for more details. +> + */ +> + +> +#include <linux/kernel.h> +> +#include <linux/module.h> +> +#include <linux/err.h> +> +#include <linux/delay.h> +> +#include <linux/init.h> +> +#include <linux/slab.h> +> +#include <linux/string.h> +> +#include <linux/platform_device.h> +> +#include <linux/hwmon.h> +> +#include <linux/hwmon-sysfs.h> +> +#include <linux/regmap.h> +> +#include <linux/mfd/da9063/core.h> +> +#include <linux/mfd/da9063/pdata.h> +> + +> +#define DA9063_ADC_RES (1 << (DA9063_ADC_RES_L_BITS + DA9063_ADC_RES_M_BITS)) +> +#define DA9063_ADC_MAX (DA9063_ADC_RES - 1) +> +#define DA9063_2V5 2500 +> +#define DA9063_5V0 5000 +> +#define DA9063_5V5 5500 +> +#define DA9063_TJUNC_M -420 +> +#define DA9063_TJUNC_C -812 +> +#define DA9063_VBBAT_M 2048 +> + +> +enum da9063_adc { +> + DA9063_CHAN_VSYS = DA9063_ADC_MUX_VSYS, +> + DA9063_CHAN_ADCIN1 = DA9063_ADC_MUX_ADCIN1, +> + DA9063_CHAN_ADCIN2 = DA9063_ADC_MUX_ADCIN2, +> + DA9063_CHAN_ADCIN3 = DA9063_ADC_MUX_ADCIN3, +> + DA9063_CHAN_TJUNC = DA9063_ADC_MUX_T_SENSE, +> + DA9063_CHAN_VBBAT = DA9063_ADC_MUX_VBBAT, +> + DA9063_CHAN_LDO_G1 = DA9063_ADC_MUX_LDO_G1, +> + DA9063_CHAN_LDO_G2 = DA9063_ADC_MUX_LDO_G2, +> + DA9063_CHAN_LDO_G3 = DA9063_ADC_MUX_LDO_G3 +> +}; +> + +> +struct da9063_hwmon { +> + struct da9063 *da9063; +> + struct device *classdev; +> + struct mutex hwmon_mutex; +> + struct completion adc_ready; +> + signed char tjunc_offset; +> + int irq; +> +}; +> + +> +static int da9063_adc_convert(struct da9063_hwmon *hwmon, int channel, +> + int *value) +> +{ +> + int val = *value; +> + int ret = 0; +> + +> + switch (channel) { +> + case DA9063_CHAN_ADCIN1: +> + case DA9063_CHAN_ADCIN2: +> + case DA9063_CHAN_ADCIN3: +> + val = (DA9063_2V5 * val) / DA9063_ADC_MAX; +> + break; +> + case DA9063_CHAN_VSYS: +> + val = ((DA9063_5V5 - DA9063_2V5) * val) / DA9063_ADC_MAX + +> + DA9063_2V5; +> + break; +> + case DA9063_CHAN_TJUNC: +> + val -= hwmon->tjunc_offset; +> + val = (DA9063_TJUNC_M * (val + DA9063_TJUNC_C)) >> 10; +> + break; +> + case DA9063_CHAN_VBBAT: +> + val = (DA9063_5V0 * val) / DA9063_ADC_MAX; +> + break; +> + default: +> + ret = -EINVAL; +> + goto err_convert; +> + } +> + +> + *value = val; +> +err_convert: +> + return ret; +> +} +> + +> +static int da9063_adc_current_switch(struct da9063_hwmon *hwmon, int channel, +> + bool on) +> +{ +> + int ret; +> + unsigned int val; +> + unsigned int mask; +> + +> + switch (channel) { +> + case DA9063_CHAN_ADCIN1: +> + mask = DA9063_ADC_AD1_ISRC_EN; +> + break; +> + case DA9063_CHAN_ADCIN2: +> + mask = DA9063_ADC_AD2_ISRC_EN; +> + break; +> + case DA9063_CHAN_ADCIN3: +> + mask = DA9063_ADC_AD3_ISRC_EN; +> + break; +> + default: +> + ret = -EINVAL; +> + goto err_switch; +> + } +> + +> + if (on) +> + val = mask; +> + else +> + val = ~mask; +> + +> + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CONT, +> + mask, val); +> +err_switch: +> + return ret; +> + +> +} +> + +> +static int da9063_adc_manual_read(struct da9063_hwmon *hwmon, int channel) +> +{ +> + int ret; +> + unsigned char val; +> + unsigned char data[2]; +> + int adc_man; +> + +> + mutex_lock(&hwmon->hwmon_mutex); +> + +> + init_completion(&hwmon->adc_ready); +> + +> + val = (channel & DA9063_ADC_MUX_MASK) | DA9063_ADC_MAN; +> + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_MAN, +> + DA9063_ADC_MUX_MASK | DA9063_ADC_MAN, val); +> + if (ret < 0) +> + goto err_mread; +> + +> + ret = wait_for_completion_timeout(&hwmon->adc_ready, +> + msecs_to_jiffies(1000)); +> + if (ret == 0) { +> + ret = -ETIMEDOUT; +> + goto err_mread; +> + } +> + +> + ret = regmap_read(hwmon->da9063->regmap, DA9063_REG_ADC_MAN, &adc_man); +> + if (ret < 0) +> + goto err_mread; +> + +> + /* data value is not ready */ +> + if (adc_man & DA9063_ADC_MAN == 0) { +> + ret = -EINVAL; +> + goto err_mread; +> + } +> + +> + ret = regmap_bulk_read(hwmon->da9063->regmap, +> + DA9063_REG_ADC_RES_L, data, 2); +> + if (ret < 0) +> + goto err_mread; +> + +> + ret = (data[0] & DA9063_ADC_RES_L_MASK) >> DA9063_ADC_RES_L_SHIFT; +> + ret |= data[1] << DA9063_ADC_RES_L_BITS; +> +err_mread: +> + mutex_unlock(&hwmon->hwmon_mutex); +> + return ret; +> +} +> + +> +static irqreturn_t da9063_hwmon_irq_handler(int irq, void *irq_data) +> +{ +> + struct da9063_hwmon *hwmon = irq_data; +> + complete(&hwmon->adc_ready); +> + return IRQ_HANDLED; +> +} +> + +> +static ssize_t da9063_adc_read(struct device *dev, +> + struct device_attribute *devattr, char *buf) +> +{ +> + struct da9063_hwmon *hwmon = dev_get_drvdata(dev); +> + int channel = to_sensor_dev_attr(devattr)->index; +> + int val; +> + int ret; +> + +> + switch (channel) { +> + case DA9063_CHAN_ADCIN1: +> + case DA9063_CHAN_ADCIN2: +> + case DA9063_CHAN_ADCIN3: +> + /* fallthrough for ADC measures */ +> + ret = da9063_adc_current_switch(hwmon, channel, true); +> + if (ret < 0) +> + goto err_read; +> + +> + val = da9063_adc_manual_read(hwmon, channel); +> + if (val < 0) { +> + ret = val; +> + if (ret == -EINVAL) +> + dev_err(dev, "Conversion was not completed\n"); +> + else +> + dev_err(dev, "ADC read error %d\n", ret); +> + goto err_read; +> + } +> + +> + ret = da9063_adc_current_switch(hwmon, channel, false); +> + if (ret < 0) { +> + dev_err(dev, "Could not switch current\n"); +> + goto err_read; +> + } +> + break; +> + +> + case DA9063_CHAN_VSYS: +> + case DA9063_CHAN_TJUNC: +> + case DA9063_CHAN_VBBAT: +> + /* fallthrough for internal measures */ +> + val = da9063_adc_manual_read(hwmon, channel); +> + if (val < 0) { +> + dev_err(dev, "ADC read error %d\n", val); +> + return val; +> + } +> + break; +> + +> + default: +> + /* error case */ +> + ret = -EINVAL; +> + goto err_read; +> + } +> + +> + ret = da9063_adc_convert(hwmon, channel, &val); +> + if (ret < 0) { +> + dev_err(dev, "Failed to convert ADC value %d\n", ret); +> + goto err_read; +> + } +> + +> + return sprintf(buf, "%d\n", val); +> +err_read: +> + return ret; +> +} +> + +> +static ssize_t da9063_show_name(struct device *dev, +> + struct device_attribute *attr, char *buf) +> +{ +> + return sprintf(buf, DA9063_DRVNAME_HWMON "\n"); +> +} +> + +> +static ssize_t da9063_show_label(struct device *dev, +> + struct device_attribute *devattr, char *buf) +> +{ +> + int channel = to_sensor_dev_attr(devattr)->index; +> + char *label; +> + +> + switch (channel) { +> + case DA9063_CHAN_VSYS: +> + label = "VSYS"; +> + break; +> + case DA9063_CHAN_ADCIN1: +> + label = "ADCIN1"; +> + break; +> + case DA9063_CHAN_ADCIN2: +> + label = "ADCIN2"; +> + break; +> + case DA9063_CHAN_ADCIN3: +> + label = "ADCIN3"; +> + break; +> + case DA9063_CHAN_TJUNC: +> + label = "TJUNC"; +> + break; +> + case DA9063_CHAN_VBBAT: +> + label = "VBBAT"; +> + break; +> + default: +> + label = "UNKNOWN"; +> + } +> + +> + return sprintf(buf, "%s\n", label); +> +} +> + +> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, +> + da9063_adc_read, NULL, DA9063_CHAN_VSYS); +> +static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, +> + da9063_show_label, NULL, DA9063_CHAN_VSYS); +> + +> +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, +> + da9063_adc_read, NULL, DA9063_CHAN_ADCIN1); +> +static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, +> + da9063_show_label, NULL, DA9063_CHAN_ADCIN1); +> + +> +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, +> + da9063_adc_read, NULL, DA9063_CHAN_ADCIN2); +> +static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, +> + da9063_show_label, NULL, DA9063_CHAN_ADCIN2); +> + +> +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, +> + da9063_adc_read, NULL, DA9063_CHAN_ADCIN3); +> +static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, +> + da9063_show_label, NULL, DA9063_CHAN_ADCIN3); +> + +> +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, +> + da9063_adc_read, NULL, DA9063_CHAN_VBBAT); +> +static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, +> + da9063_show_label, NULL, DA9063_CHAN_VBBAT); +> + +> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, +> + da9063_adc_read, NULL, DA9063_CHAN_TJUNC); +> + +> +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, +> + da9063_show_label, NULL, DA9063_CHAN_TJUNC); +> + +> +static DEVICE_ATTR(name, S_IRUGO, da9063_show_name, NULL); +> + +> +static struct attribute *da9063_attributes[] = { +> + &dev_attr_name.attr, +> + &sensor_dev_attr_in0_input.dev_attr.attr, +> + &sensor_dev_attr_in0_label.dev_attr.attr, +> + &sensor_dev_attr_in1_input.dev_attr.attr, +> + &sensor_dev_attr_in1_label.dev_attr.attr, +> + &sensor_dev_attr_in2_input.dev_attr.attr, +> + &sensor_dev_attr_in2_label.dev_attr.attr, +> + &sensor_dev_attr_in3_input.dev_attr.attr, +> + &sensor_dev_attr_in3_label.dev_attr.attr, +> + &sensor_dev_attr_in4_input.dev_attr.attr, +> + &sensor_dev_attr_in4_label.dev_attr.attr, +> + &sensor_dev_attr_temp1_input.dev_attr.attr, +> + &sensor_dev_attr_temp1_label.dev_attr.attr, +> + NULL +> +}; +> + +> +static const struct attribute_group da9063_attr_group = { +> + .attrs = da9063_attributes, +> +}; +> + +> +static int da9063_hwmon_probe(struct platform_device *pdev) +> +{ +> + struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); +> + struct da9063_pdata *pdata = da9063->dev->platform_data; +> + struct da9063_hwmon *hwmon; +> + int ret; +> + unsigned int val; +> + +> + hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9063_hwmon), +> + GFP_KERNEL); +> + if (!hwmon) +> + return -ENOMEM; +> + +> + mutex_init(&hwmon->hwmon_mutex); +> + init_completion(&hwmon->adc_ready); +> + hwmon->da9063 = da9063; +> + +> + /* enable the ADC functions for GPIO 0,1,2 */ +> + val = (DA9063_GPIO0_PIN_ADCIN1 << DA9063_GPIO0_PIN_MASK_SHIFT | +> + DA9063_GPIO1_PIN_ADCIN2_COMP << DA9063_GPIO1_PIN_MASK_SHIFT); +> + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_GPIO_0_1, +> + (DA9063_GPIO0_PIN_MASK | +> + DA9063_GPIO1_PIN_MASK), val); +> + if (ret < 0) { +> + dev_err(&pdev->dev, +> + "Failed to alter the ADCIN 1,2 bits for the GPIO 0,1 register\n"); +> + return -EIO; +> + } +> + +> + val = DA9063_GPIO2_PIN_ADCIN3 << DA9063_GPIO2_PIN_MASK_SHIFT; +> + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_GPIO_2_3, +> + DA9063_GPIO2_PIN_MASK, val); +> + if (ret < 0) { +> + dev_err(&pdev->dev, +> + "Failed to alter the ADCIN 3 bits for the GPIO 2,3 register\n"); +> + return -EIO; +> + } +> + +> + /* debounce ADC I settings */ +> + val = (DA9063_ADCIN1_DEB_ON << DA9063_REG_ADCIN1_DEB_SHIFT | +> + DA9063_ADCIN2_DEB_ON << DA9063_REG_ADCIN2_DEB_SHIFT | +> + DA9063_ADCIN3_DEB_ON << DA9063_REG_ADCIN3_DEB_SHIFT); +> + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CFG, +> + (DA9063_REG_ADCIN1_DEB_MASK | +> + DA9063_REG_ADCIN2_DEB_MASK | +> + DA9063_REG_ADCIN3_DEB_MASK), val); +> + if (ret < 0) { +> + dev_err(&pdev->dev, +> + "Failed to alter the ADC configuration register\n"); +> + return -EIO; +> + } +> + +> + /* set up the current configurations */ +> + val = (pdata->hwmon_pdata->adcin1_cur << DA9063_REG_ADCIN1_CUR_SHIFT | +> + pdata->hwmon_pdata->adcin2_cur << DA9063_REG_ADCIN2_CUR_SHIFT | +> + pdata->hwmon_pdata->adcin3_cur << DA9063_REG_ADCIN3_CUR_SHIFT); +> + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CFG, +> + (DA9063_REG_ADCIN1_CUR_MASK | +> + DA9063_REG_ADCIN2_CUR_MASK | +> + DA9063_REG_ADCIN3_CUR_MASK), val); +> + +> + ret = regmap_read(da9063->regmap, DA9063_REG_ADC_CFG, &val); +> + if (ret < 0) { +> + dev_err(&pdev->dev, +> + "Failed to read read the ADC configuration register\n"); +> + return -EIO; +> + } +> + +> + hwmon->irq = platform_get_irq_byname(pdev, DA9063_DRVNAME_HWMON); +> + if (hwmon->irq < 0) +> + return hwmon->irq; +> + +> + ret = devm_request_threaded_irq(&pdev->dev, hwmon->irq, NULL, +> + da9063_hwmon_irq_handler, +> + IRQF_TRIGGER_LOW | IRQF_ONESHOT, +> + "HWMON", hwmon); +> + if (ret) { +> + dev_err(&pdev->dev, "Failed to request IRQ.\n"); +> + return ret; +> + } +> + +> + platform_set_drvdata(pdev, hwmon); +> + +> + /* set trim temperature offset to value read at startup */ +> + hwmon->tjunc_offset = (signed char)hwmon->da9063->t_offset; +> + +> + ret = sysfs_create_group(&pdev->dev.kobj, &da9063_attr_group); +> + if (ret) +> + return ret; +> + +> + hwmon->classdev = hwmon_device_register(&pdev->dev); +> + if (IS_ERR(hwmon->classdev)) { +> + sysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group); +> + return PTR_ERR(hwmon->classdev); +> + } +> + +> + return 0; +> +} +> + +> +static int da9063_hwmon_remove(struct platform_device *pdev) +> +{ +> + struct da9063_hwmon *hwmon = platform_get_drvdata(pdev); +> + +> + hwmon_device_unregister(hwmon->classdev); +> + sysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group); +> + +> + return 0; +> +} +> + +> +static struct platform_driver da9063_hwmon_driver = { +> + .probe = da9063_hwmon_probe, +> + .remove = da9063_hwmon_remove, +> + .driver = { +> + .name = DA9063_DRVNAME_HWMON, +> + .owner = THIS_MODULE, +> + }, +> +}; +> + +> +module_platform_driver(da9063_hwmon_driver); +> + +> +MODULE_DESCRIPTION("Hardware monitor support device driver for Dialog DA9063"); +> +MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>"); +> +MODULE_LICENSE("GPL v2"); +> +MODULE_ALIAS("platform:" DA9063_DRVNAME_HWMON); +> diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h +> index 09a85c6..922371b 100644 +> --- a/include/linux/mfd/da9063/registers.h +> +++ b/include/linux/mfd/da9063/registers.h +> @@ -474,6 +474,7 @@ +> +> /* DA9063_REG_GPIO_0_1 (addr=0x15) */ +> #define DA9063_GPIO0_PIN_MASK 0x03 +> +#define DA9063_GPIO0_PIN_MASK_SHIFT 0 +> #define DA9063_GPIO0_PIN_ADCIN1 0x00 +> #define DA9063_GPIO0_PIN_GPI 0x01 +> #define DA9063_GPIO0_PIN_GPO_OD 0x02 +> @@ -485,6 +486,7 @@ +> #define DA9063_GPIO0_TYPE_GPO_VDD_IO2 0x04 +> #define DA9063_GPIO0_NO_WAKEUP 0x08 +> #define DA9063_GPIO1_PIN_MASK 0x30 +> +#define DA9063_GPIO1_PIN_MASK_SHIFT 4 +> #define DA9063_GPIO1_PIN_ADCIN2_COMP 0x00 +> #define DA9063_GPIO1_PIN_GPI 0x10 +> #define DA9063_GPIO1_PIN_GPO_OD 0x20 +> @@ -498,6 +500,7 @@ +> +> /* DA9063_REG_GPIO_2_3 (addr=0x16) */ +> #define DA9063_GPIO2_PIN_MASK 0x03 +> +#define DA9063_GPIO2_PIN_MASK_SHIFT 0 +> #define DA9063_GPIO2_PIN_ADCIN3 0x00 +> #define DA9063_GPIO2_PIN_GPI 0x01 +> #define DA9063_GPIO2_PIN_GPO_PSS 0x02 +> @@ -813,6 +816,7 @@ +> #define DA9063_VSYS_VAL_BASE 0x00 +> +> /* DA9063_REG_ADC_RES_L (addr=0x37) */ +> +#define DA9063_ADC_RES_L_SHIFT 6 +> #define DA9063_ADC_RES_L_BITS 2 +> #define DA9063_ADC_RES_L_MASK 0xC0 +> +> @@ -979,6 +983,36 @@ +> #define DA9063_GPIO_DIM 0x80 +> #define DA9063_GPIO_PWM_MASK 0x7F +> +> +/* DA9063_REG_ADC_CFG (addr=0xC9) */ +> +#define DA9063_REG_ADCIN1_CUR_MASK 0x03 +> +#define DA9063_REG_ADCIN1_CUR_SHIFT 0 +> +#define DA9063_ADCIN1_CUR_1UA 0x00 +> +#define DA9063_ADCIN1_CUR_2UA 0x01 +> +#define DA9063_ADCIN1_CUR_10UA 0x02 +> +#define DA9063_ADCIN1_CUR_40UA 0x03 +> +#define DA9063_REG_ADCIN2_CUR_MASK 0x0C +> +#define DA9063_REG_ADCIN2_CUR_SHIFT 2 +> +#define DA9063_ADCIN2_CUR_1UA 0x00 +> +#define DA9063_ADCIN2_CUR_2UA 0x01 +> +#define DA9063_ADCIN2_CUR_10UA 0x02 +> +#define DA9063_ADCIN2_CUR_40UA 0x03 +> +#define DA9063_REG_ADCIN3_CUR_MASK 0x10 +> +#define DA9063_REG_ADCIN3_CUR_SHIFT 4 +> +#define DA9063_ADCIN3_CUR_10UA 0x00 +> +#define DA9063_ADCIN3_CUR_40UA 0x01 +> +#define DA9063_REG_ADCIN1_DEB_MASK 0x20 +> +#define DA9063_REG_ADCIN1_DEB_SHIFT 5 +> +#define DA9063_ADCIN1_DEB_OFF 0x00 +> +#define DA9063_ADCIN1_DEB_ON 0x01 +> +#define DA9063_REG_ADCIN2_DEB_MASK 0x40 +> +#define DA9063_REG_ADCIN2_DEB_SHIFT 6 +> +#define DA9063_ADCIN2_DEB_OFF 0x00 +> +#define DA9063_ADCIN2_DEB_ON 0x01 +> +#define DA9063_REG_ADCIN3_DEB_MASK 0x80 +> +#define DA9063_REG_ADCIN3_DEB_SHIFT 7 +> +#define DA9063_ADCIN3_DEB_OFF 0x00 +> +#define DA9063_ADCIN3_DEB_ON 0x01 +> + +> /* DA9063_REG_CONFIG_H (addr=0x10D) */ +> #define DA9063_PWM_CLK_MASK 0x01 +> #define DA9063_PWM_CLK_PWM2MHZ 0x00 + +-- +Lee Jones +Linaro STMicroelectronics Landing Team Lead +Linaro.org │ Open source software for ARM SoCs +Follow Linaro: Facebook | Twitter | Blog diff --git a/a/content_digest b/N1/content_digest index 36621c1..efd890f 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,7 +1,7 @@ "ref\0cover.1395607051.git.stwiss.opensource@diasemi.com\0" "ref\0420d4f5c8436a66b511693531cfeda131258ce69.1395607051.git.stwiss.opensource@diasemi.com\0" "From\0Lee Jones <lee.jones@linaro.org>\0" - "Subject\0Re: [lm-sensors] [RFC V1 1/3] hwmon: da9063: HWMON driver\0" + "Subject\0Re: [RFC V1 1/3] hwmon: da9063: HWMON driver\0" "Date\0Mon, 24 Mar 2014 07:52:21 +0000\0" "To\0Opensource [Steve Twiss] <stwiss.opensource@diasemi.com>\0" "Cc\0Guenter Roeck <linux@roeck-us.net>" @@ -16,336 +16,600 @@ " Samuel Ortiz <sameo@linux.intel.com>\0" "\00:1\0" "b\0" - "PiBGcm9tOiBPcGVuc291cmNlIFtTdGV2ZSBUd2lzc10gPHN0d2lzcy5vcGVuc291cmNlQGRpYXNl\n" - "bWkuY29tPgo+IAo+IEFkZCB0aGUgSFdNT04gZHJpdmVyIGZvciBEQTkwNjMKPiAKPiBTaWduZWQt\n" - "b2ZmLWJ5OiBPcGVuc291cmNlIFtTdGV2ZSBUd2lzc10gPHN0d2lzcy5vcGVuc291cmNlQGRpYXNl\n" - "bWkuY29tPgo+IC0tLQo+IAo+ICBkcml2ZXJzL2h3bW9uL0tjb25maWcgICAgICAgICAgICAgICAg\n" - "fCAgIDEwICsKPiAgZHJpdmVycy9od21vbi9NYWtlZmlsZSAgICAgICAgICAgICAgIHwgICAgMSAr\n" - "Cj4gIGRyaXZlcnMvaHdtb24vZGE5MDYzLWh3bW9uLmMgICAgICAgICB8ICA0NTYgKysrKysrKysr\n" - "KysrKysrKysrKysrKysrKysrKysrKysrKwo+ICBpbmNsdWRlL2xpbnV4L21mZC9kYTkwNjMvcmVn\n" - "aXN0ZXJzLmggfCAgIDM0ICsrKwoKSSdkIHByZWZlciB0byBzZWUgYWxsIHZhbHVlcyBpbiBoZXgs\n" - "IGJ1dCB0aGlzIHByb2JhYmx5IGEgcHJlZmVyZW5jZQp0aGluZyByYXRoZXIgdGhhbiBzb21ldGhp\n" - "bmcgd2hpY2ggd291bGQgcHJldmVudCBhY2NlcHRhbmNlLgoKRm9yIHRoZSBNRkQgaGVhZGVyIGNo\n" - "YW5nZXM6CiAgQWNrZWQtYnk6IExlZSBKb25lcyA8bGVlLmpvbmVzQGxpbmFyby5vcmc+Cgo+ICA0\n" - "IGZpbGVzIGNoYW5nZWQsIDUwMSBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBk\n" - "cml2ZXJzL2h3bW9uL2RhOTA2My1od21vbi5jCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdt\n" - "b24vS2NvbmZpZyBiL2RyaXZlcnMvaHdtb24vS2NvbmZpZwo+IGluZGV4IGYyODhiNjAuLjY4YWE4\n" - "ODYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9od21vbi9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9o\n" - "d21vbi9LY29uZmlnCj4gQEAgLTM5MSw2ICszOTEsMTYgQEAgY29uZmlnIFNFTlNPUlNfREE5MDU1\n" - "Cj4gIAkgIFRoaXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiAgSWYgc28s\n" - "IHRoZSBtb2R1bGUKPiAgCSAgd2lsbCBiZSBjYWxsZWQgZGE5MDU1LWh3bW9uLgo+ICAKPiArY29u\n" - "ZmlnIFNFTlNPUlNfREE5MDYzCj4gKwl0cmlzdGF0ZSAiRGlhbG9nIFNlbWljb25kdWN0b3IgREE5\n" - "MDYzIgo+ICsJZGVwZW5kcyBvbiBNRkRfREE5MDYzCj4gKwloZWxwCj4gKwkgIElmIHlvdSBzYXkg\n" - "eWVzIGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciB0aGUgaGFyZHdhcmUKPiArCSAgbW9uaXRvcmlu\n" - "ZyBmZWF0dXJlcyBvZiB0aGUgREE5MDYzIFBvd2VyIE1hbmFnZW1lbnQgSUMuCj4gKwo+ICsJICBU\n" - "aGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1\n" - "bGUKPiArCSAgd2lsbCBiZSBjYWxsZWQgZGE5MDYzLWh3bW9uLgo+ICsKPiAgY29uZmlnIFNFTlNP\n" - "UlNfSTVLX0FNQgo+ICAJdHJpc3RhdGUgIkZCLURJTU0gQU1CIHRlbXBlcmF0dXJlIHNlbnNvciBv\n" - "biBJbnRlbCA1MDAwIHNlcmllcyBjaGlwc2V0cyIKPiAgCWRlcGVuZHMgb24gUENJCj4gZGlmZiAt\n" - "LWdpdCBhL2RyaXZlcnMvaHdtb24vTWFrZWZpbGUgYi9kcml2ZXJzL2h3bW9uL01ha2VmaWxlCj4g\n" - "aW5kZXggYzQ4Zjk4Ny4uNDE3NGIwNyAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2h3bW9uL01ha2Vm\n" - "aWxlCj4gKysrIGIvZHJpdmVycy9od21vbi9NYWtlZmlsZQo+IEBAIC00OSw2ICs0OSw3IEBAIG9i\n" - "ai0kKENPTkZJR19TRU5TT1JTX0FUWFAxKQkrPSBhdHhwMS5vCj4gIG9iai0kKENPTkZJR19TRU5T\n" - "T1JTX0NPUkVURU1QKQkrPSBjb3JldGVtcC5vCj4gIG9iai0kKENPTkZJR19TRU5TT1JTX0RBOTA1\n" - "Ml9BREMpKz0gZGE5MDUyLWh3bW9uLm8KPiAgb2JqLSQoQ09ORklHX1NFTlNPUlNfREE5MDU1KSs9\n" - "IGRhOTA1NS1od21vbi5vCj4gK29iai0kKENPTkZJR19TRU5TT1JTX0RBOTA2MykJKz0gZGE5MDYz\n" - "LWh3bW9uLm8KPiAgb2JqLSQoQ09ORklHX1NFTlNPUlNfRE1FMTczNykJKz0gZG1lMTczNy5vCj4g\n" - "IG9iai0kKENPTkZJR19TRU5TT1JTX0RTNjIwKQkrPSBkczYyMC5vCj4gIG9iai0kKENPTkZJR19T\n" - "RU5TT1JTX0RTMTYyMSkJKz0gZHMxNjIxLm8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9od21vbi9k\n" - "YTkwNjMtaHdtb24uYyBiL2RyaXZlcnMvaHdtb24vZGE5MDYzLWh3bW9uLmMKPiBuZXcgZmlsZSBt\n" - "b2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjc3NTZjYjIKPiAtLS0gL2Rldi9udWxsCj4gKysr\n" - "IGIvZHJpdmVycy9od21vbi9kYTkwNjMtaHdtb24uYwo+IEBAIC0wLDAgKzEsNDU2IEBACj4gKy8q\n" - "IGRhOTA2My1od21vbi5jIC0gSGFyZHdhcmUgbW9uaXRvciBzdXBwb3J0IGZvciBEQTkwNjMKPiAr\n" - "ICogQ29weXJpZ2h0IChDKSAyMDE0IERpYWxvZyBTZW1pY29uZHVjdG9yIEx0ZC4KPiArICoKPiAr\n" - "ICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0\n" - "IGFuZC9vcgo+ICsgKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGlicmFy\n" - "eSBHZW5lcmFsIFB1YmxpYwo+ICsgKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBT\n" - "b2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKPiArICogdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNl\n" - "LCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgo+ICsgKgo+ICsgKiBUaGlz\n" - "IGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1\n" - "bCwKPiArICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxp\n" - "ZWQgd2FycmFudHkgb2YKPiArICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFS\n" - "VElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKPiArICogTGlicmFyeSBHZW5lcmFsIFB1Ymxp\n" - "YyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4\n" - "L2tlcm5lbC5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51\n" - "eC9lcnIuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9p\n" - "bml0Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zdHJp\n" - "bmcuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8\n" - "bGludXgvaHdtb24uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2h3bW9uLXN5c2ZzLmg+Cj4gKyNpbmNs\n" - "dWRlIDxsaW51eC9yZWdtYXAuaD4KPiArI2luY2x1ZGUgPGxpbnV4L21mZC9kYTkwNjMvY29yZS5o\n" - "Pgo+ICsjaW5jbHVkZSA8bGludXgvbWZkL2RhOTA2My9wZGF0YS5oPgo+ICsKPiArI2RlZmluZSBE\n" - "QTkwNjNfQURDX1JFUwkoMSA8PCAoREE5MDYzX0FEQ19SRVNfTF9CSVRTICsgREE5MDYzX0FEQ19S\n" - "RVNfTV9CSVRTKSkKPiArI2RlZmluZSBEQTkwNjNfQURDX01BWAkoREE5MDYzX0FEQ19SRVMgLSAx\n" - "KQo+ICsjZGVmaW5lIERBOTA2M18yVjUJMjUwMAo+ICsjZGVmaW5lIERBOTA2M181VjAJNTAwMAo+\n" - "ICsjZGVmaW5lIERBOTA2M181VjUJNTUwMAo+ICsjZGVmaW5lIERBOTA2M19USlVOQ19NCS00MjAK\n" - "PiArI2RlZmluZSBEQTkwNjNfVEpVTkNfQwktODEyCj4gKyNkZWZpbmUgREE5MDYzX1ZCQkFUX00J\n" - "MjA0OAo+ICsKPiArZW51bSBkYTkwNjNfYWRjIHsKPiArCURBOTA2M19DSEFOX1ZTWVMgPSBEQTkw\n" - "NjNfQURDX01VWF9WU1lTLAo+ICsJREE5MDYzX0NIQU5fQURDSU4xID0gREE5MDYzX0FEQ19NVVhf\n" - "QURDSU4xLAo+ICsJREE5MDYzX0NIQU5fQURDSU4yID0gREE5MDYzX0FEQ19NVVhfQURDSU4yLAo+\n" - "ICsJREE5MDYzX0NIQU5fQURDSU4zID0gREE5MDYzX0FEQ19NVVhfQURDSU4zLAo+ICsJREE5MDYz\n" - "X0NIQU5fVEpVTkMgPSBEQTkwNjNfQURDX01VWF9UX1NFTlNFLAo+ICsJREE5MDYzX0NIQU5fVkJC\n" - "QVQgPSBEQTkwNjNfQURDX01VWF9WQkJBVCwKPiArCURBOTA2M19DSEFOX0xET19HMSA9IERBOTA2\n" - "M19BRENfTVVYX0xET19HMSwKPiArCURBOTA2M19DSEFOX0xET19HMiA9IERBOTA2M19BRENfTVVY\n" - "X0xET19HMiwKPiArCURBOTA2M19DSEFOX0xET19HMyA9IERBOTA2M19BRENfTVVYX0xET19HMwo+\n" - "ICt9Owo+ICsKPiArc3RydWN0IGRhOTA2M19od21vbiB7Cj4gKwlzdHJ1Y3QgZGE5MDYzICpkYTkw\n" - "NjM7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpjbGFzc2RldjsKPiArCXN0cnVjdCBtdXRleCBod21vbl9t\n" - "dXRleDsKPiArCXN0cnVjdCBjb21wbGV0aW9uIGFkY19yZWFkeTsKPiArCXNpZ25lZCBjaGFyIHRq\n" - "dW5jX29mZnNldDsKPiArCWludCBpcnE7Cj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IGRhOTA2M19h\n" - "ZGNfY29udmVydChzdHJ1Y3QgZGE5MDYzX2h3bW9uICpod21vbiwgaW50IGNoYW5uZWwsCj4gKwkJ\n" - "CSAgICAgIGludCAqdmFsdWUpCj4gK3sKPiArCWludCB2YWwgPSAqdmFsdWU7Cj4gKwlpbnQgcmV0\n" - "ID0gMDsKPiArCj4gKwlzd2l0Y2ggKGNoYW5uZWwpIHsKPiArCWNhc2UgREE5MDYzX0NIQU5fQURD\n" - "SU4xOgo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9BRENJTjI6Cj4gKwljYXNlIERBOTA2M19DSEFOX0FE\n" - "Q0lOMzoKPiArCQl2YWwgPSAoREE5MDYzXzJWNSAqIHZhbCkgLyBEQTkwNjNfQURDX01BWDsKPiAr\n" - "CQlicmVhazsKPiArCWNhc2UgREE5MDYzX0NIQU5fVlNZUzoKPiArCQl2YWwgPSAoKERBOTA2M181\n" - "VjUgLSBEQTkwNjNfMlY1KSAqIHZhbCkgLyBEQTkwNjNfQURDX01BWCArCj4gKwkJCURBOTA2M18y\n" - "VjU7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIERBOTA2M19DSEFOX1RKVU5DOgo+ICsJCXZhbCAtPSBo\n" - "d21vbi0+dGp1bmNfb2Zmc2V0Owo+ICsJCXZhbCA9IChEQTkwNjNfVEpVTkNfTSAqICh2YWwgKyBE\n" - "QTkwNjNfVEpVTkNfQykpID4+IDEwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9W\n" - "QkJBVDoKPiArCQl2YWwgPSAoREE5MDYzXzVWMCAqIHZhbCkgLyBEQTkwNjNfQURDX01BWDsKPiAr\n" - "CQlicmVhazsKPiArCWRlZmF1bHQ6Cj4gKwkJcmV0ID0gLUVJTlZBTDsKPiArCQlnb3RvIGVycl9j\n" - "b252ZXJ0Owo+ICsJfQo+ICsKPiArCSp2YWx1ZSA9IHZhbDsKPiArZXJyX2NvbnZlcnQ6Cj4gKwly\n" - "ZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGRhOTA2M19hZGNfY3VycmVudF9zd2l0\n" - "Y2goc3RydWN0IGRhOTA2M19od21vbiAqaHdtb24sIGludCBjaGFubmVsLAo+ICsJCQkJICAgICBi\n" - "b29sIG9uKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsJdW5zaWduZWQgaW50IHZhbDsKPiArCXVuc2ln\n" - "bmVkIGludCBtYXNrOwo+ICsKPiArCXN3aXRjaCAoY2hhbm5lbCkgewo+ICsJY2FzZSBEQTkwNjNf\n" - "Q0hBTl9BRENJTjE6Cj4gKwkJbWFzayA9IERBOTA2M19BRENfQUQxX0lTUkNfRU47Cj4gKwkJYnJl\n" - "YWs7Cj4gKwljYXNlIERBOTA2M19DSEFOX0FEQ0lOMjoKPiArCQltYXNrID0gREE5MDYzX0FEQ19B\n" - "RDJfSVNSQ19FTjsKPiArCQlicmVhazsKPiArCWNhc2UgREE5MDYzX0NIQU5fQURDSU4zOgo+ICsJ\n" - "CW1hc2sgPSBEQTkwNjNfQURDX0FEM19JU1JDX0VOOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoK\n" - "PiArCQlyZXQgPSAtRUlOVkFMOwo+ICsJCWdvdG8gZXJyX3N3aXRjaDsKPiArCX0KPiArCj4gKwlp\n" - "ZiAob24pCj4gKwkJdmFsID0gbWFzazsKPiArCWVsc2UKPiArCQl2YWwgPSB+bWFzazsKPiArCj4g\n" - "KwlyZXQgPSByZWdtYXBfdXBkYXRlX2JpdHMoaHdtb24tPmRhOTA2My0+cmVnbWFwLCBEQTkwNjNf\n" - "UkVHX0FEQ19DT05ULAo+ICsJCQkJIG1hc2ssIHZhbCk7Cj4gK2Vycl9zd2l0Y2g6Cj4gKwlyZXR1\n" - "cm4gcmV0Owo+ICsKPiArfQo+ICsKPiArc3RhdGljIGludCBkYTkwNjNfYWRjX21hbnVhbF9yZWFk\n" - "KHN0cnVjdCBkYTkwNjNfaHdtb24gKmh3bW9uLCBpbnQgY2hhbm5lbCkKPiArewo+ICsJaW50IHJl\n" - "dDsKPiArCXVuc2lnbmVkIGNoYXIgdmFsOwo+ICsJdW5zaWduZWQgY2hhciBkYXRhWzJdOwo+ICsJ\n" - "aW50IGFkY19tYW47Cj4gKwo+ICsJbXV0ZXhfbG9jaygmaHdtb24tPmh3bW9uX211dGV4KTsKPiAr\n" - "Cj4gKwlpbml0X2NvbXBsZXRpb24oJmh3bW9uLT5hZGNfcmVhZHkpOwo+ICsKPiArCXZhbCA9IChj\n" - "aGFubmVsICYgREE5MDYzX0FEQ19NVVhfTUFTSykgfCBEQTkwNjNfQURDX01BTjsKPiArCXJldCA9\n" - "IHJlZ21hcF91cGRhdGVfYml0cyhod21vbi0+ZGE5MDYzLT5yZWdtYXAsIERBOTA2M19SRUdfQURD\n" - "X01BTiwKPiArCQkJCSBEQTkwNjNfQURDX01VWF9NQVNLIHwgREE5MDYzX0FEQ19NQU4sIHZhbCk7\n" - "Cj4gKwlpZiAocmV0IDwgMCkKPiArCQlnb3RvIGVycl9tcmVhZDsKPiArCj4gKwlyZXQgPSB3YWl0\n" - "X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoJmh3bW9uLT5hZGNfcmVhZHksCj4gKwkJCQkJICBtc2Vj\n" - "c190b19qaWZmaWVzKDEwMDApKTsKPiArCWlmIChyZXQgPT0gMCkgewo+ICsJCXJldCA9IC1FVElN\n" - "RURPVVQ7Cj4gKwkJZ290byBlcnJfbXJlYWQ7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX3Jl\n" - "YWQoaHdtb24tPmRhOTA2My0+cmVnbWFwLCBEQTkwNjNfUkVHX0FEQ19NQU4sICZhZGNfbWFuKTsK\n" - "PiArCWlmIChyZXQgPCAwKQo+ICsJCWdvdG8gZXJyX21yZWFkOwo+ICsKPiArCS8qIGRhdGEgdmFs\n" - "dWUgaXMgbm90IHJlYWR5ICovCj4gKwlpZiAoYWRjX21hbiAmIERBOTA2M19BRENfTUFOID09IDAp\n" - "IHsKPiArCQlyZXQgPSAtRUlOVkFMOwo+ICsJCWdvdG8gZXJyX21yZWFkOwo+ICsJfQo+ICsKPiAr\n" - "CXJldCA9IHJlZ21hcF9idWxrX3JlYWQoaHdtb24tPmRhOTA2My0+cmVnbWFwLAo+ICsJCQkgICAg\n" - "ICAgREE5MDYzX1JFR19BRENfUkVTX0wsIGRhdGEsIDIpOwo+ICsJaWYgKHJldCA8IDApCj4gKwkJ\n" - "Z290byBlcnJfbXJlYWQ7Cj4gKwo+ICsJcmV0ID0gKGRhdGFbMF0gJiBEQTkwNjNfQURDX1JFU19M\n" - "X01BU0spID4+IERBOTA2M19BRENfUkVTX0xfU0hJRlQ7Cj4gKwlyZXQgfD0gZGF0YVsxXSA8PCBE\n" - "QTkwNjNfQURDX1JFU19MX0JJVFM7Cj4gK2Vycl9tcmVhZDoKPiArCW11dGV4X3VubG9jaygmaHdt\n" - "b24tPmh3bW9uX211dGV4KTsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBpcnFy\n" - "ZXR1cm5fdCBkYTkwNjNfaHdtb25faXJxX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqaXJxX2RhdGEp\n" - "Cj4gK3sKPiArCXN0cnVjdCBkYTkwNjNfaHdtb24gKmh3bW9uID0gaXJxX2RhdGE7Cj4gKwljb21w\n" - "bGV0ZSgmaHdtb24tPmFkY19yZWFkeSk7Cj4gKwlyZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gK30KPiAr\n" - "Cj4gK3N0YXRpYyBzc2l6ZV90IGRhOTA2M19hZGNfcmVhZChzdHJ1Y3QgZGV2aWNlICpkZXYsCj4g\n" - "KwkJCSAgICAgICBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqZGV2YXR0ciwgY2hhciAqYnVmKQo+\n" - "ICt7Cj4gKwlzdHJ1Y3QgZGE5MDYzX2h3bW9uICpod21vbiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYp\n" - "Owo+ICsJaW50IGNoYW5uZWwgPSB0b19zZW5zb3JfZGV2X2F0dHIoZGV2YXR0ciktPmluZGV4Owo+\n" - "ICsJaW50IHZhbDsKPiArCWludCByZXQ7Cj4gKwo+ICsJc3dpdGNoIChjaGFubmVsKSB7Cj4gKwlj\n" - "YXNlIERBOTA2M19DSEFOX0FEQ0lOMToKPiArCWNhc2UgREE5MDYzX0NIQU5fQURDSU4yOgo+ICsJ\n" - "Y2FzZSBEQTkwNjNfQ0hBTl9BRENJTjM6Cj4gKwkJLyogZmFsbHRocm91Z2ggZm9yIEFEQyBtZWFz\n" - "dXJlcyAqLwo+ICsJCXJldCA9IGRhOTA2M19hZGNfY3VycmVudF9zd2l0Y2goaHdtb24sIGNoYW5u\n" - "ZWwsIHRydWUpOwo+ICsJCWlmIChyZXQgPCAwKQo+ICsJCQlnb3RvIGVycl9yZWFkOwo+ICsKPiAr\n" - "CQl2YWwgPSBkYTkwNjNfYWRjX21hbnVhbF9yZWFkKGh3bW9uLCBjaGFubmVsKTsKPiArCQlpZiAo\n" - "dmFsIDwgMCkgewo+ICsJCQlyZXQgPSB2YWw7Cj4gKwkJCWlmIChyZXQgPT0gLUVJTlZBTCkKPiAr\n" - "CQkJCWRldl9lcnIoZGV2LCAiQ29udmVyc2lvbiB3YXMgbm90IGNvbXBsZXRlZFxuIik7Cj4gKwkJ\n" - "CWVsc2UKPiArCQkJCWRldl9lcnIoZGV2LCAiQURDIHJlYWQgZXJyb3IgJWRcbiIsIHJldCk7Cj4g\n" - "KwkJCWdvdG8gZXJyX3JlYWQ7Cj4gKwkJfQo+ICsKPiArCQlyZXQgPSBkYTkwNjNfYWRjX2N1cnJl\n" - "bnRfc3dpdGNoKGh3bW9uLCBjaGFubmVsLCBmYWxzZSk7Cj4gKwkJaWYgKHJldCA8IDApIHsKPiAr\n" - "CQkJZGV2X2VycihkZXYsICJDb3VsZCBub3Qgc3dpdGNoIGN1cnJlbnRcbiIpOwo+ICsJCQlnb3Rv\n" - "IGVycl9yZWFkOwo+ICsJCX0KPiArCQlicmVhazsKPiArCj4gKwljYXNlIERBOTA2M19DSEFOX1ZT\n" - "WVM6Cj4gKwljYXNlIERBOTA2M19DSEFOX1RKVU5DOgo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9WQkJB\n" - "VDoKPiArCQkvKiBmYWxsdGhyb3VnaCBmb3IgaW50ZXJuYWwgbWVhc3VyZXMgKi8KPiArCQl2YWwg\n" - "PSBkYTkwNjNfYWRjX21hbnVhbF9yZWFkKGh3bW9uLCBjaGFubmVsKTsKPiArCQlpZiAodmFsIDwg\n" - "MCkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkFEQyByZWFkIGVycm9yICVkXG4iLCB2YWwpOwo+ICsJ\n" - "CQlyZXR1cm4gdmFsOwo+ICsJCX0KPiArCQlicmVhazsKPiArCj4gKwlkZWZhdWx0Ogo+ICsJCS8q\n" - "IGVycm9yIGNhc2UgKi8KPiArCQlyZXQgPSAtRUlOVkFMOwo+ICsJCWdvdG8gZXJyX3JlYWQ7Cj4g\n" - "Kwl9Cj4gKwo+ICsJcmV0ID0gZGE5MDYzX2FkY19jb252ZXJ0KGh3bW9uLCBjaGFubmVsLCAmdmFs\n" - "KTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2VycihkZXYsICJGYWlsZWQgdG8gY29udmVy\n" - "dCBBREMgdmFsdWUgJWRcbiIsIHJldCk7Cj4gKwkJZ290byBlcnJfcmVhZDsKPiArCX0KPiArCj4g\n" - "KwlyZXR1cm4gc3ByaW50ZihidWYsICIlZFxuIiwgdmFsKTsKPiArZXJyX3JlYWQ6Cj4gKwlyZXR1\n" - "cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgc3NpemVfdCBkYTkwNjNfc2hvd19uYW1lKHN0cnVj\n" - "dCBkZXZpY2UgKmRldiwKPiArCQkJCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFy\n" - "ICpidWYpCj4gK3sKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgREE5MDYzX0RSVk5BTUVfSFdNT04g\n" - "IlxuIik7Cj4gK30KPiArCj4gK3N0YXRpYyBzc2l6ZV90IGRhOTA2M19zaG93X2xhYmVsKHN0cnVj\n" - "dCBkZXZpY2UgKmRldiwKPiArCQkJCSBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqZGV2YXR0ciwg\n" - "Y2hhciAqYnVmKQo+ICt7Cj4gKwlpbnQgY2hhbm5lbCA9IHRvX3NlbnNvcl9kZXZfYXR0cihkZXZh\n" - "dHRyKS0+aW5kZXg7Cj4gKwljaGFyICpsYWJlbDsKPiArCj4gKwlzd2l0Y2ggKGNoYW5uZWwpIHsK\n" - "PiArCWNhc2UgREE5MDYzX0NIQU5fVlNZUzoKPiArCQlsYWJlbCA9ICJWU1lTIjsKPiArCQlicmVh\n" - "azsKPiArCWNhc2UgREE5MDYzX0NIQU5fQURDSU4xOgo+ICsJCWxhYmVsID0gIkFEQ0lOMSI7Cj4g\n" - "KwkJYnJlYWs7Cj4gKwljYXNlIERBOTA2M19DSEFOX0FEQ0lOMjoKPiArCQlsYWJlbCA9ICJBRENJ\n" - "TjIiOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9BRENJTjM6Cj4gKwkJbGFiZWwg\n" - "PSAiQURDSU4zIjsKPiArCQlicmVhazsKPiArCWNhc2UgREE5MDYzX0NIQU5fVEpVTkM6Cj4gKwkJ\n" - "bGFiZWwgPSAiVEpVTkMiOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBEQTkwNjNfQ0hBTl9WQkJBVDoK\n" - "PiArCQlsYWJlbCA9ICJWQkJBVCI7Cj4gKwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ICsJCWxhYmVs\n" - "ID0gIlVOS05PV04iOwo+ICsJfQo+ICsKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBs\n" - "YWJlbCk7Cj4gK30KPiArCj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2lucHV0LCBT\n" - "X0lSVUdPLAo+ICsJCQkgIGRhOTA2M19hZGNfcmVhZCwgTlVMTCwgREE5MDYzX0NIQU5fVlNZUyk7\n" - "Cj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4wX2xhYmVsLCBTX0lSVUdPLAo+ICsJCQkg\n" - "IGRhOTA2M19zaG93X2xhYmVsLCBOVUxMLCBEQTkwNjNfQ0hBTl9WU1lTKTsKPiArCj4gK3N0YXRp\n" - "YyBTRU5TT1JfREVWSUNFX0FUVFIoaW4xX2lucHV0LCBTX0lSVUdPLAo+ICsJCQkgIGRhOTA2M19h\n" - "ZGNfcmVhZCwgTlVMTCwgREE5MDYzX0NIQU5fQURDSU4xKTsKPiArc3RhdGljIFNFTlNPUl9ERVZJ\n" - "Q0VfQVRUUihpbjFfbGFiZWwsIFNfSVJVR08sCj4gKwkJCSAgZGE5MDYzX3Nob3dfbGFiZWwsIE5V\n" - "TEwsIERBOTA2M19DSEFOX0FEQ0lOMSk7Cj4gKwo+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9BVFRS\n" - "KGluMl9pbnB1dCwgU19JUlVHTywKPiArCQkJICBkYTkwNjNfYWRjX3JlYWQsIE5VTEwsIERBOTA2\n" - "M19DSEFOX0FEQ0lOMik7Cj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIoaW4yX2xhYmVsLCBT\n" - "X0lSVUdPLAo+ICsJCQkgIGRhOTA2M19zaG93X2xhYmVsLCBOVUxMLCBEQTkwNjNfQ0hBTl9BRENJ\n" - "TjIpOwo+ICsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUihpbjNfaW5wdXQsIFNfSVJVR08s\n" - "Cj4gKwkJCSAgZGE5MDYzX2FkY19yZWFkLCBOVUxMLCBEQTkwNjNfQ0hBTl9BRENJTjMpOwo+ICtz\n" - "dGF0aWMgU0VOU09SX0RFVklDRV9BVFRSKGluM19sYWJlbCwgU19JUlVHTywKPiArCQkJICBkYTkw\n" - "NjNfc2hvd19sYWJlbCwgTlVMTCwgREE5MDYzX0NIQU5fQURDSU4zKTsKPiArCj4gK3N0YXRpYyBT\n" - "RU5TT1JfREVWSUNFX0FUVFIoaW40X2lucHV0LCBTX0lSVUdPLAo+ICsJCQkgIGRhOTA2M19hZGNf\n" - "cmVhZCwgTlVMTCwgREE5MDYzX0NIQU5fVkJCQVQpOwo+ICtzdGF0aWMgU0VOU09SX0RFVklDRV9B\n" - "VFRSKGluNF9sYWJlbCwgU19JUlVHTywKPiArCQkJICBkYTkwNjNfc2hvd19sYWJlbCwgTlVMTCwg\n" - "REE5MDYzX0NIQU5fVkJCQVQpOwo+ICsKPiArc3RhdGljIFNFTlNPUl9ERVZJQ0VfQVRUUih0ZW1w\n" - "MV9pbnB1dCwgU19JUlVHTywKPiArCQkJICBkYTkwNjNfYWRjX3JlYWQsIE5VTEwsIERBOTA2M19D\n" - "SEFOX1RKVU5DKTsKPiArCj4gK3N0YXRpYyBTRU5TT1JfREVWSUNFX0FUVFIodGVtcDFfbGFiZWws\n" - "IFNfSVJVR08sCj4gKwkJCSAgZGE5MDYzX3Nob3dfbGFiZWwsIE5VTEwsIERBOTA2M19DSEFOX1RK\n" - "VU5DKTsKPiArCj4gK3N0YXRpYyBERVZJQ0VfQVRUUihuYW1lLCBTX0lSVUdPLCBkYTkwNjNfc2hv\n" - "d19uYW1lLCBOVUxMKTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpkYTkwNjNfYXR0\n" - "cmlidXRlc1tdID0gewo+ICsJJmRldl9hdHRyX25hbWUuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0\n" - "dHJfaW4wX2lucHV0LmRldl9hdHRyLmF0dHIsCj4gKwkmc2Vuc29yX2Rldl9hdHRyX2luMF9sYWJl\n" - "bC5kZXZfYXR0ci5hdHRyLAo+ICsJJnNlbnNvcl9kZXZfYXR0cl9pbjFfaW5wdXQuZGV2X2F0dHIu\n" - "YXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfaW4xX2xhYmVsLmRldl9hdHRyLmF0dHIsCj4gKwkm\n" - "c2Vuc29yX2Rldl9hdHRyX2luMl9pbnB1dC5kZXZfYXR0ci5hdHRyLAo+ICsJJnNlbnNvcl9kZXZf\n" - "YXR0cl9pbjJfbGFiZWwuZGV2X2F0dHIuYXR0ciwKPiArCSZzZW5zb3JfZGV2X2F0dHJfaW4zX2lu\n" - "cHV0LmRldl9hdHRyLmF0dHIsCj4gKwkmc2Vuc29yX2Rldl9hdHRyX2luM19sYWJlbC5kZXZfYXR0\n" - "ci5hdHRyLAo+ICsJJnNlbnNvcl9kZXZfYXR0cl9pbjRfaW5wdXQuZGV2X2F0dHIuYXR0ciwKPiAr\n" - "CSZzZW5zb3JfZGV2X2F0dHJfaW40X2xhYmVsLmRldl9hdHRyLmF0dHIsCj4gKwkmc2Vuc29yX2Rl\n" - "dl9hdHRyX3RlbXAxX2lucHV0LmRldl9hdHRyLmF0dHIsCj4gKwkmc2Vuc29yX2Rldl9hdHRyX3Rl\n" - "bXAxX2xhYmVsLmRldl9hdHRyLmF0dHIsCj4gKwlOVUxMCj4gK307Cj4gKwo+ICtzdGF0aWMgY29u\n" - "c3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBkYTkwNjNfYXR0cl9ncm91cCA9IHsKPiArCS5hdHRy\n" - "cyA9IGRhOTA2M19hdHRyaWJ1dGVzLAo+ICt9Owo+ICsKPiArc3RhdGljIGludCBkYTkwNjNfaHdt\n" - "b25fcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IGRh\n" - "OTA2MyAqZGE5MDYzID0gZGV2X2dldF9kcnZkYXRhKHBkZXYtPmRldi5wYXJlbnQpOwo+ICsJc3Ry\n" - "dWN0IGRhOTA2M19wZGF0YSAqcGRhdGEgPSBkYTkwNjMtPmRldi0+cGxhdGZvcm1fZGF0YTsKPiAr\n" - "CXN0cnVjdCBkYTkwNjNfaHdtb24gKmh3bW9uOwo+ICsJaW50IHJldDsKPiArCXVuc2lnbmVkIGlu\n" - "dCB2YWw7Cj4gKwo+ICsJaHdtb24gPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgc2l6ZW9mKHN0\n" - "cnVjdCBkYTkwNjNfaHdtb24pLAo+ICsJCQkgICAgIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFod21v\n" - "bikKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwltdXRleF9pbml0KCZod21vbi0+aHdtb25f\n" - "bXV0ZXgpOwo+ICsJaW5pdF9jb21wbGV0aW9uKCZod21vbi0+YWRjX3JlYWR5KTsKPiArCWh3bW9u\n" - "LT5kYTkwNjMgPSBkYTkwNjM7Cj4gKwo+ICsJLyogZW5hYmxlIHRoZSBBREMgZnVuY3Rpb25zIGZv\n" - "ciBHUElPIDAsMSwyICovCj4gKwl2YWwgPSAoREE5MDYzX0dQSU8wX1BJTl9BRENJTjEgPDwgREE5\n" - "MDYzX0dQSU8wX1BJTl9NQVNLX1NISUZUIHwKPiArCSAgICAgICBEQTkwNjNfR1BJTzFfUElOX0FE\n" - "Q0lOMl9DT01QIDw8IERBOTA2M19HUElPMV9QSU5fTUFTS19TSElGVCk7Cj4gKwlyZXQgPSByZWdt\n" - "YXBfdXBkYXRlX2JpdHMoaHdtb24tPmRhOTA2My0+cmVnbWFwLCBEQTkwNjNfUkVHX0dQSU9fMF8x\n" - "LAo+ICsJCQkJIChEQTkwNjNfR1BJTzBfUElOX01BU0sgfAo+ICsJCQkJICBEQTkwNjNfR1BJTzFf\n" - "UElOX01BU0spLCB2YWwpOwo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKCZwZGV2LT5k\n" - "ZXYsCj4gKwkJCSJGYWlsZWQgdG8gYWx0ZXIgdGhlIEFEQ0lOIDEsMiBiaXRzIGZvciB0aGUgR1BJ\n" - "TyAwLDEgcmVnaXN0ZXJcbiIpOwo+ICsJCXJldHVybiAtRUlPOwo+ICsJfQo+ICsKPiArCXZhbCA9\n" - "IERBOTA2M19HUElPMl9QSU5fQURDSU4zIDw8IERBOTA2M19HUElPMl9QSU5fTUFTS19TSElGVDsK\n" - "PiArCXJldCA9IHJlZ21hcF91cGRhdGVfYml0cyhod21vbi0+ZGE5MDYzLT5yZWdtYXAsIERBOTA2\n" - "M19SRUdfR1BJT18yXzMsCj4gKwkJCQkgREE5MDYzX0dQSU8yX1BJTl9NQVNLLCB2YWwpOwo+ICsJ\n" - "aWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsCj4gKwkJCSJGYWlsZWQgdG8g\n" - "YWx0ZXIgdGhlIEFEQ0lOIDMgYml0cyBmb3IgdGhlIEdQSU8gMiwzIHJlZ2lzdGVyXG4iKTsKPiAr\n" - "CQlyZXR1cm4gLUVJTzsKPiArCX0KPiArCj4gKwkvKiBkZWJvdW5jZSBBREMgSSBzZXR0aW5ncyAq\n" - "Lwo+ICsJdmFsID0gKERBOTA2M19BRENJTjFfREVCX09OIDw8IERBOTA2M19SRUdfQURDSU4xX0RF\n" - "Ql9TSElGVCB8Cj4gKwkgICAgICAgREE5MDYzX0FEQ0lOMl9ERUJfT04gPDwgREE5MDYzX1JFR19B\n" - "RENJTjJfREVCX1NISUZUIHwKPiArCSAgICAgICBEQTkwNjNfQURDSU4zX0RFQl9PTiA8PCBEQTkw\n" - "NjNfUkVHX0FEQ0lOM19ERUJfU0hJRlQpOwo+ICsJcmV0ID0gcmVnbWFwX3VwZGF0ZV9iaXRzKGh3\n" - "bW9uLT5kYTkwNjMtPnJlZ21hcCwgREE5MDYzX1JFR19BRENfQ0ZHLAo+ICsJCQkJIChEQTkwNjNf\n" - "UkVHX0FEQ0lOMV9ERUJfTUFTSyB8Cj4gKwkJCQkgIERBOTA2M19SRUdfQURDSU4yX0RFQl9NQVNL\n" - "IHwKPiArCQkJCSAgREE5MDYzX1JFR19BRENJTjNfREVCX01BU0spLCB2YWwpOwo+ICsJaWYgKHJl\n" - "dCA8IDApIHsKPiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsCj4gKwkJCSJGYWlsZWQgdG8gYWx0ZXIg\n" - "dGhlIEFEQyBjb25maWd1cmF0aW9uIHJlZ2lzdGVyXG4iKTsKPiArCQlyZXR1cm4gLUVJTzsKPiAr\n" - "CX0KPiArCj4gKwkvKiBzZXQgdXAgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbnMgKi8KPiArCXZh\n" - "bCA9IChwZGF0YS0+aHdtb25fcGRhdGEtPmFkY2luMV9jdXIgPDwgREE5MDYzX1JFR19BRENJTjFf\n" - "Q1VSX1NISUZUIHwKPiArCSAgICAgICBwZGF0YS0+aHdtb25fcGRhdGEtPmFkY2luMl9jdXIgPDwg\n" - "REE5MDYzX1JFR19BRENJTjJfQ1VSX1NISUZUIHwKPiArCSAgICAgICBwZGF0YS0+aHdtb25fcGRh\n" - "dGEtPmFkY2luM19jdXIgPDwgREE5MDYzX1JFR19BRENJTjNfQ1VSX1NISUZUKTsKPiArCXJldCA9\n" - "IHJlZ21hcF91cGRhdGVfYml0cyhod21vbi0+ZGE5MDYzLT5yZWdtYXAsIERBOTA2M19SRUdfQURD\n" - "X0NGRywKPiArCQkJCSAoREE5MDYzX1JFR19BRENJTjFfQ1VSX01BU0sgfAo+ICsJCQkJICBEQTkw\n" - "NjNfUkVHX0FEQ0lOMl9DVVJfTUFTSyB8Cj4gKwkJCQkgIERBOTA2M19SRUdfQURDSU4zX0NVUl9N\n" - "QVNLKSwgdmFsKTsKPiArCj4gKwlyZXQgPSByZWdtYXBfcmVhZChkYTkwNjMtPnJlZ21hcCwgREE5\n" - "MDYzX1JFR19BRENfQ0ZHLCAmdmFsKTsKPiArCWlmIChyZXQgPCAwKSB7Cj4gKwkJZGV2X2Vycigm\n" - "cGRldi0+ZGV2LAo+ICsJCQkiRmFpbGVkIHRvIHJlYWQgcmVhZCB0aGUgQURDIGNvbmZpZ3VyYXRp\n" - "b24gcmVnaXN0ZXJcbiIpOwo+ICsJCXJldHVybiAtRUlPOwo+ICsJfQo+ICsKPiArCWh3bW9uLT5p\n" - "cnEgPSBwbGF0Zm9ybV9nZXRfaXJxX2J5bmFtZShwZGV2LCBEQTkwNjNfRFJWTkFNRV9IV01PTik7\n" - "Cj4gKwlpZiAoaHdtb24tPmlycSA8IDApCj4gKwkJcmV0dXJuIGh3bW9uLT5pcnE7Cj4gKwo+ICsJ\n" - "cmV0ID0gZGV2bV9yZXF1ZXN0X3RocmVhZGVkX2lycSgmcGRldi0+ZGV2LCBod21vbi0+aXJxLCBO\n" - "VUxMLAo+ICsJCQkJCWRhOTA2M19od21vbl9pcnFfaGFuZGxlciwKPiArCQkJCQlJUlFGX1RSSUdH\n" - "RVJfTE9XIHwgSVJRRl9PTkVTSE9ULAo+ICsJCQkJCSJIV01PTiIsIGh3bW9uKTsKPiArCWlmIChy\n" - "ZXQpIHsKPiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJGYWlsZWQgdG8gcmVxdWVzdCBJUlEuXG4i\n" - "KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBk\n" - "ZXYsIGh3bW9uKTsKPiArCj4gKwkvKiBzZXQgdHJpbSB0ZW1wZXJhdHVyZSBvZmZzZXQgdG8gdmFs\n" - "dWUgcmVhZCBhdCBzdGFydHVwICovCj4gKwlod21vbi0+dGp1bmNfb2Zmc2V0ID0gKHNpZ25lZCBj\n" - "aGFyKWh3bW9uLT5kYTkwNjMtPnRfb2Zmc2V0Owo+ICsKPiArCXJldCA9IHN5c2ZzX2NyZWF0ZV9n\n" - "cm91cCgmcGRldi0+ZGV2LmtvYmosICZkYTkwNjNfYXR0cl9ncm91cCk7Cj4gKwlpZiAocmV0KQo+\n" - "ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJaHdtb24tPmNsYXNzZGV2ID0gaHdtb25fZGV2aWNlX3Jl\n" - "Z2lzdGVyKCZwZGV2LT5kZXYpOwo+ICsJaWYgKElTX0VSUihod21vbi0+Y2xhc3NkZXYpKSB7Cj4g\n" - "KwkJc3lzZnNfcmVtb3ZlX2dyb3VwKCZwZGV2LT5kZXYua29iaiwgJmRhOTA2M19hdHRyX2dyb3Vw\n" - "KTsKPiArCQlyZXR1cm4gUFRSX0VSUihod21vbi0+Y2xhc3NkZXYpOwo+ICsJfQo+ICsKPiArCXJl\n" - "dHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGRhOTA2M19od21vbl9yZW1vdmUoc3RydWN0\n" - "IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IGRhOTA2M19od21vbiAqaHdt\n" - "b24gPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKPiArCj4gKwlod21vbl9kZXZpY2VfdW5y\n" - "ZWdpc3Rlcihod21vbi0+Y2xhc3NkZXYpOwo+ICsJc3lzZnNfcmVtb3ZlX2dyb3VwKCZwZGV2LT5k\n" - "ZXYua29iaiwgJmRhOTA2M19hdHRyX2dyb3VwKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK\n" - "PiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgZGE5MDYzX2h3bW9uX2RyaXZlciA9IHsK\n" - "PiArCS5wcm9iZSA9IGRhOTA2M19od21vbl9wcm9iZSwKPiArCS5yZW1vdmUgPSBkYTkwNjNfaHdt\n" - "b25fcmVtb3ZlLAo+ICsJLmRyaXZlciA9IHsKPiArCQkgICAubmFtZSA9IERBOTA2M19EUlZOQU1F\n" - "X0hXTU9OLAo+ICsJCSAgIC5vd25lciA9IFRISVNfTU9EVUxFLAo+ICsJCSAgIH0sCj4gK307Cj4g\n" - "Kwo+ICttb2R1bGVfcGxhdGZvcm1fZHJpdmVyKGRhOTA2M19od21vbl9kcml2ZXIpOwo+ICsKPiAr\n" - "TU9EVUxFX0RFU0NSSVBUSU9OKCJIYXJkd2FyZSBtb25pdG9yIHN1cHBvcnQgZGV2aWNlIGRyaXZl\n" - "ciBmb3IgRGlhbG9nIERBOTA2MyIpOwo+ICtNT0RVTEVfQVVUSE9SKCJTIFR3aXNzIDxzdHdpc3Mu\n" - "b3BlbnNvdXJjZUBkaWFzZW1pLmNvbT4iKTsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+\n" - "ICtNT0RVTEVfQUxJQVMoInBsYXRmb3JtOiIgREE5MDYzX0RSVk5BTUVfSFdNT04pOwo+IGRpZmYg\n" - "LS1naXQgYS9pbmNsdWRlL2xpbnV4L21mZC9kYTkwNjMvcmVnaXN0ZXJzLmggYi9pbmNsdWRlL2xp\n" - "bnV4L21mZC9kYTkwNjMvcmVnaXN0ZXJzLmgKPiBpbmRleCAwOWE4NWM2Li45MjIzNzFiIDEwMDY0\n" - "NAo+IC0tLSBhL2luY2x1ZGUvbGludXgvbWZkL2RhOTA2My9yZWdpc3RlcnMuaAo+ICsrKyBiL2lu\n" - "Y2x1ZGUvbGludXgvbWZkL2RhOTA2My9yZWdpc3RlcnMuaAo+IEBAIC00NzQsNiArNDc0LDcgQEAK\n" - "PiAgCj4gIC8qIERBOTA2M19SRUdfR1BJT18wXzEgKGFkZHI9MHgxNSkgKi8KPiAgI2RlZmluZQlE\n" - "QTkwNjNfR1BJTzBfUElOX01BU0sJCQkweDAzCj4gKyNkZWZpbmUJREE5MDYzX0dQSU8wX1BJTl9N\n" - "QVNLX1NISUZUCQkwCj4gICNkZWZpbmUJCURBOTA2M19HUElPMF9QSU5fQURDSU4xCQkweDAwCj4g\n" - "ICNkZWZpbmUJCURBOTA2M19HUElPMF9QSU5fR1BJCQkweDAxCj4gICNkZWZpbmUJCURBOTA2M19H\n" - "UElPMF9QSU5fR1BPX09ECQkweDAyCj4gQEAgLTQ4NSw2ICs0ODYsNyBAQAo+ICAjZGVmaW5lCQlE\n" - "QTkwNjNfR1BJTzBfVFlQRV9HUE9fVkREX0lPMgkweDA0Cj4gICNkZWZpbmUJREE5MDYzX0dQSU8w\n" - "X05PX1dBS0VVUAkJCTB4MDgKPiAgI2RlZmluZQlEQTkwNjNfR1BJTzFfUElOX01BU0sJCQkweDMw\n" - "Cj4gKyNkZWZpbmUJREE5MDYzX0dQSU8xX1BJTl9NQVNLX1NISUZUCQk0Cj4gICNkZWZpbmUJCURB\n" - "OTA2M19HUElPMV9QSU5fQURDSU4yX0NPTVAJMHgwMAo+ICAjZGVmaW5lCQlEQTkwNjNfR1BJTzFf\n" - "UElOX0dQSQkJMHgxMAo+ICAjZGVmaW5lCQlEQTkwNjNfR1BJTzFfUElOX0dQT19PRAkJMHgyMAo+\n" - "IEBAIC00OTgsNiArNTAwLDcgQEAKPiAgCj4gIC8qIERBOTA2M19SRUdfR1BJT18yXzMgKGFkZHI9\n" - "MHgxNikgKi8KPiAgI2RlZmluZQlEQTkwNjNfR1BJTzJfUElOX01BU0sJCQkweDAzCj4gKyNkZWZp\n" - "bmUJREE5MDYzX0dQSU8yX1BJTl9NQVNLX1NISUZUCQkwCj4gICNkZWZpbmUJCURBOTA2M19HUElP\n" - "Ml9QSU5fQURDSU4zCQkweDAwCj4gICNkZWZpbmUJCURBOTA2M19HUElPMl9QSU5fR1BJCQkweDAx\n" - "Cj4gICNkZWZpbmUJCURBOTA2M19HUElPMl9QSU5fR1BPX1BTUwkweDAyCj4gQEAgLTgxMyw2ICs4\n" - "MTYsNyBAQAo+ICAjZGVmaW5lCURBOTA2M19WU1lTX1ZBTF9CQVNFCQkJMHgwMAo+ICAKPiAgLyog\n" - "REE5MDYzX1JFR19BRENfUkVTX0wgKGFkZHI9MHgzNykgKi8KPiArI2RlZmluZQlEQTkwNjNfQURD\n" - "X1JFU19MX1NISUZUCQkJNgo+ICAjZGVmaW5lCURBOTA2M19BRENfUkVTX0xfQklUUwkJCTIKPiAg\n" - "I2RlZmluZQlEQTkwNjNfQURDX1JFU19MX01BU0sJCQkweEMwCj4gIAo+IEBAIC05NzksNiArOTgz\n" - "LDM2IEBACj4gICNkZWZpbmUgREE5MDYzX0dQSU9fRElNCQkJCTB4ODAKPiAgI2RlZmluZSBEQTkw\n" - "NjNfR1BJT19QV01fTUFTSwkJCTB4N0YKPiAgCj4gKy8qIERBOTA2M19SRUdfQURDX0NGRyAoYWRk\n" - "cj0weEM5KSAqLwo+ICsjZGVmaW5lIERBOTA2M19SRUdfQURDSU4xX0NVUl9NQVNLCQkweDAzCj4g\n" - "KyNkZWZpbmUgREE5MDYzX1JFR19BRENJTjFfQ1VSX1NISUZUCQkwCj4gKyNkZWZpbmUJCURBOTA2\n" - "M19BRENJTjFfQ1VSXzFVQQkJMHgwMAo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4xX0NVUl8yVUEJ\n" - "CTB4MDEKPiArI2RlZmluZQkJREE5MDYzX0FEQ0lOMV9DVVJfMTBVQQkJMHgwMgo+ICsjZGVmaW5l\n" - "CQlEQTkwNjNfQURDSU4xX0NVUl80MFVBCQkweDAzCj4gKyNkZWZpbmUgREE5MDYzX1JFR19BRENJ\n" - "TjJfQ1VSX01BU0sJCTB4MEMKPiArI2RlZmluZSBEQTkwNjNfUkVHX0FEQ0lOMl9DVVJfU0hJRlQJ\n" - "CTIKPiArI2RlZmluZQkJREE5MDYzX0FEQ0lOMl9DVVJfMVVBCQkweDAwCj4gKyNkZWZpbmUJCURB\n" - "OTA2M19BRENJTjJfQ1VSXzJVQQkJMHgwMQo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4yX0NVUl8x\n" - "MFVBCQkweDAyCj4gKyNkZWZpbmUJCURBOTA2M19BRENJTjJfQ1VSXzQwVUEJCTB4MDMKPiArI2Rl\n" - "ZmluZSBEQTkwNjNfUkVHX0FEQ0lOM19DVVJfTUFTSwkJMHgxMAo+ICsjZGVmaW5lIERBOTA2M19S\n" - "RUdfQURDSU4zX0NVUl9TSElGVAkJNAo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4zX0NVUl8xMFVB\n" - "CQkweDAwCj4gKyNkZWZpbmUJCURBOTA2M19BRENJTjNfQ1VSXzQwVUEJCTB4MDEKPiArI2RlZmlu\n" - "ZSBEQTkwNjNfUkVHX0FEQ0lOMV9ERUJfTUFTSwkJMHgyMAo+ICsjZGVmaW5lIERBOTA2M19SRUdf\n" - "QURDSU4xX0RFQl9TSElGVAkJNQo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4xX0RFQl9PRkYJCTB4\n" - "MDAKPiArI2RlZmluZQkJREE5MDYzX0FEQ0lOMV9ERUJfT04JCTB4MDEKPiArI2RlZmluZSBEQTkw\n" - "NjNfUkVHX0FEQ0lOMl9ERUJfTUFTSwkJMHg0MAo+ICsjZGVmaW5lIERBOTA2M19SRUdfQURDSU4y\n" - "X0RFQl9TSElGVAkJNgo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4yX0RFQl9PRkYJCTB4MDAKPiAr\n" - "I2RlZmluZQkJREE5MDYzX0FEQ0lOMl9ERUJfT04JCTB4MDEKPiArI2RlZmluZSBEQTkwNjNfUkVH\n" - "X0FEQ0lOM19ERUJfTUFTSwkJMHg4MAo+ICsjZGVmaW5lIERBOTA2M19SRUdfQURDSU4zX0RFQl9T\n" - "SElGVAkJNwo+ICsjZGVmaW5lCQlEQTkwNjNfQURDSU4zX0RFQl9PRkYJCTB4MDAKPiArI2RlZmlu\n" - "ZQkJREE5MDYzX0FEQ0lOM19ERUJfT04JCTB4MDEKPiArCj4gIC8qIERBOTA2M19SRUdfQ09ORklH\n" - "X0ggKGFkZHI9MHgxMEQpICovCj4gICNkZWZpbmUgREE5MDYzX1BXTV9DTEtfTUFTSwkJCTB4MDEK\n" - "PiAgI2RlZmluZQkJREE5MDYzX1BXTV9DTEtfUFdNMk1IWgkJMHgwMAoKLS0gCkxlZSBKb25lcwpM\n" - "aW5hcm8gU1RNaWNyb2VsZWN0cm9uaWNzIExhbmRpbmcgVGVhbSBMZWFkCkxpbmFyby5vcmcg4pSC\n" - "IE9wZW4gc291cmNlIHNvZnR3YXJlIGZvciBBUk0gU29DcwpGb2xsb3cgTGluYXJvOiBGYWNlYm9v\n" - "ayB8IFR3aXR0ZXIgfCBCbG9nCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f\n" - "X19fX19fX19fXwpsbS1zZW5zb3JzIG1haWxpbmcgbGlzdApsbS1zZW5zb3JzQGxtLXNlbnNvcnMu\n" - "b3JnCmh0dHA6Ly9saXN0cy5sbS1zZW5zb3JzLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xtLXNlbnNv\n" - cnM + "> From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com>\n" + "> \n" + "> Add the HWMON driver for DA9063\n" + "> \n" + "> Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com>\n" + "> ---\n" + "> \n" + "> drivers/hwmon/Kconfig | 10 +\n" + "> drivers/hwmon/Makefile | 1 +\n" + "> drivers/hwmon/da9063-hwmon.c | 456 ++++++++++++++++++++++++++++++++++\n" + "> include/linux/mfd/da9063/registers.h | 34 +++\n" + "\n" + "I'd prefer to see all values in hex, but this probably a preference\n" + "thing rather than something which would prevent acceptance.\n" + "\n" + "For the MFD header changes:\n" + " Acked-by: Lee Jones <lee.jones@linaro.org>\n" + "\n" + "> 4 files changed, 501 insertions(+)\n" + "> create mode 100644 drivers/hwmon/da9063-hwmon.c\n" + "> \n" + "> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig\n" + "> index f288b60..68aa886 100644\n" + "> --- a/drivers/hwmon/Kconfig\n" + "> +++ b/drivers/hwmon/Kconfig\n" + "> @@ -391,6 +391,16 @@ config SENSORS_DA9055\n" + "> \t This driver can also be built as a module. If so, the module\n" + "> \t will be called da9055-hwmon.\n" + "> \n" + "> +config SENSORS_DA9063\n" + "> +\ttristate \"Dialog Semiconductor DA9063\"\n" + "> +\tdepends on MFD_DA9063\n" + "> +\thelp\n" + "> +\t If you say yes here you get support for the hardware\n" + "> +\t monitoring features of the DA9063 Power Management IC.\n" + "> +\n" + "> +\t This driver can also be built as a module. If so, the module\n" + "> +\t will be called da9063-hwmon.\n" + "> +\n" + "> config SENSORS_I5K_AMB\n" + "> \ttristate \"FB-DIMM AMB temperature sensor on Intel 5000 series chipsets\"\n" + "> \tdepends on PCI\n" + "> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile\n" + "> index c48f987..4174b07 100644\n" + "> --- a/drivers/hwmon/Makefile\n" + "> +++ b/drivers/hwmon/Makefile\n" + "> @@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_ATXP1)\t+= atxp1.o\n" + "> obj-$(CONFIG_SENSORS_CORETEMP)\t+= coretemp.o\n" + "> obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o\n" + "> obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o\n" + "> +obj-$(CONFIG_SENSORS_DA9063)\t+= da9063-hwmon.o\n" + "> obj-$(CONFIG_SENSORS_DME1737)\t+= dme1737.o\n" + "> obj-$(CONFIG_SENSORS_DS620)\t+= ds620.o\n" + "> obj-$(CONFIG_SENSORS_DS1621)\t+= ds1621.o\n" + "> diff --git a/drivers/hwmon/da9063-hwmon.c b/drivers/hwmon/da9063-hwmon.c\n" + "> new file mode 100644\n" + "> index 0000000..7756cb2\n" + "> --- /dev/null\n" + "> +++ b/drivers/hwmon/da9063-hwmon.c\n" + "> @@ -0,0 +1,456 @@\n" + "> +/* da9063-hwmon.c - Hardware monitor support for DA9063\n" + "> + * Copyright (C) 2014 Dialog Semiconductor Ltd.\n" + "> + *\n" + "> + * This library is free software; you can redistribute it and/or\n" + "> + * modify it under the terms of the GNU Library General Public\n" + "> + * License as published by the Free Software Foundation; either\n" + "> + * version 2 of the License, or (at your option) any later version.\n" + "> + *\n" + "> + * This library is distributed in the hope that it will be useful,\n" + "> + * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" + "> + * Library General Public License for more details.\n" + "> + */\n" + "> +\n" + "> +#include <linux/kernel.h>\n" + "> +#include <linux/module.h>\n" + "> +#include <linux/err.h>\n" + "> +#include <linux/delay.h>\n" + "> +#include <linux/init.h>\n" + "> +#include <linux/slab.h>\n" + "> +#include <linux/string.h>\n" + "> +#include <linux/platform_device.h>\n" + "> +#include <linux/hwmon.h>\n" + "> +#include <linux/hwmon-sysfs.h>\n" + "> +#include <linux/regmap.h>\n" + "> +#include <linux/mfd/da9063/core.h>\n" + "> +#include <linux/mfd/da9063/pdata.h>\n" + "> +\n" + "> +#define DA9063_ADC_RES\t(1 << (DA9063_ADC_RES_L_BITS + DA9063_ADC_RES_M_BITS))\n" + "> +#define DA9063_ADC_MAX\t(DA9063_ADC_RES - 1)\n" + "> +#define DA9063_2V5\t2500\n" + "> +#define DA9063_5V0\t5000\n" + "> +#define DA9063_5V5\t5500\n" + "> +#define DA9063_TJUNC_M\t-420\n" + "> +#define DA9063_TJUNC_C\t-812\n" + "> +#define DA9063_VBBAT_M\t2048\n" + "> +\n" + "> +enum da9063_adc {\n" + "> +\tDA9063_CHAN_VSYS = DA9063_ADC_MUX_VSYS,\n" + "> +\tDA9063_CHAN_ADCIN1 = DA9063_ADC_MUX_ADCIN1,\n" + "> +\tDA9063_CHAN_ADCIN2 = DA9063_ADC_MUX_ADCIN2,\n" + "> +\tDA9063_CHAN_ADCIN3 = DA9063_ADC_MUX_ADCIN3,\n" + "> +\tDA9063_CHAN_TJUNC = DA9063_ADC_MUX_T_SENSE,\n" + "> +\tDA9063_CHAN_VBBAT = DA9063_ADC_MUX_VBBAT,\n" + "> +\tDA9063_CHAN_LDO_G1 = DA9063_ADC_MUX_LDO_G1,\n" + "> +\tDA9063_CHAN_LDO_G2 = DA9063_ADC_MUX_LDO_G2,\n" + "> +\tDA9063_CHAN_LDO_G3 = DA9063_ADC_MUX_LDO_G3\n" + "> +};\n" + "> +\n" + "> +struct da9063_hwmon {\n" + "> +\tstruct da9063 *da9063;\n" + "> +\tstruct device *classdev;\n" + "> +\tstruct mutex hwmon_mutex;\n" + "> +\tstruct completion adc_ready;\n" + "> +\tsigned char tjunc_offset;\n" + "> +\tint irq;\n" + "> +};\n" + "> +\n" + "> +static int da9063_adc_convert(struct da9063_hwmon *hwmon, int channel,\n" + "> +\t\t\t int *value)\n" + "> +{\n" + "> +\tint val = *value;\n" + "> +\tint ret = 0;\n" + "> +\n" + "> +\tswitch (channel) {\n" + "> +\tcase DA9063_CHAN_ADCIN1:\n" + "> +\tcase DA9063_CHAN_ADCIN2:\n" + "> +\tcase DA9063_CHAN_ADCIN3:\n" + "> +\t\tval = (DA9063_2V5 * val) / DA9063_ADC_MAX;\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_VSYS:\n" + "> +\t\tval = ((DA9063_5V5 - DA9063_2V5) * val) / DA9063_ADC_MAX +\n" + "> +\t\t\tDA9063_2V5;\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_TJUNC:\n" + "> +\t\tval -= hwmon->tjunc_offset;\n" + "> +\t\tval = (DA9063_TJUNC_M * (val + DA9063_TJUNC_C)) >> 10;\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_VBBAT:\n" + "> +\t\tval = (DA9063_5V0 * val) / DA9063_ADC_MAX;\n" + "> +\t\tbreak;\n" + "> +\tdefault:\n" + "> +\t\tret = -EINVAL;\n" + "> +\t\tgoto err_convert;\n" + "> +\t}\n" + "> +\n" + "> +\t*value = val;\n" + "> +err_convert:\n" + "> +\treturn ret;\n" + "> +}\n" + "> +\n" + "> +static int da9063_adc_current_switch(struct da9063_hwmon *hwmon, int channel,\n" + "> +\t\t\t\t bool on)\n" + "> +{\n" + "> +\tint ret;\n" + "> +\tunsigned int val;\n" + "> +\tunsigned int mask;\n" + "> +\n" + "> +\tswitch (channel) {\n" + "> +\tcase DA9063_CHAN_ADCIN1:\n" + "> +\t\tmask = DA9063_ADC_AD1_ISRC_EN;\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_ADCIN2:\n" + "> +\t\tmask = DA9063_ADC_AD2_ISRC_EN;\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_ADCIN3:\n" + "> +\t\tmask = DA9063_ADC_AD3_ISRC_EN;\n" + "> +\t\tbreak;\n" + "> +\tdefault:\n" + "> +\t\tret = -EINVAL;\n" + "> +\t\tgoto err_switch;\n" + "> +\t}\n" + "> +\n" + "> +\tif (on)\n" + "> +\t\tval = mask;\n" + "> +\telse\n" + "> +\t\tval = ~mask;\n" + "> +\n" + "> +\tret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CONT,\n" + "> +\t\t\t\t mask, val);\n" + "> +err_switch:\n" + "> +\treturn ret;\n" + "> +\n" + "> +}\n" + "> +\n" + "> +static int da9063_adc_manual_read(struct da9063_hwmon *hwmon, int channel)\n" + "> +{\n" + "> +\tint ret;\n" + "> +\tunsigned char val;\n" + "> +\tunsigned char data[2];\n" + "> +\tint adc_man;\n" + "> +\n" + "> +\tmutex_lock(&hwmon->hwmon_mutex);\n" + "> +\n" + "> +\tinit_completion(&hwmon->adc_ready);\n" + "> +\n" + "> +\tval = (channel & DA9063_ADC_MUX_MASK) | DA9063_ADC_MAN;\n" + "> +\tret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_MAN,\n" + "> +\t\t\t\t DA9063_ADC_MUX_MASK | DA9063_ADC_MAN, val);\n" + "> +\tif (ret < 0)\n" + "> +\t\tgoto err_mread;\n" + "> +\n" + "> +\tret = wait_for_completion_timeout(&hwmon->adc_ready,\n" + "> +\t\t\t\t\t msecs_to_jiffies(1000));\n" + "> +\tif (ret == 0) {\n" + "> +\t\tret = -ETIMEDOUT;\n" + "> +\t\tgoto err_mread;\n" + "> +\t}\n" + "> +\n" + "> +\tret = regmap_read(hwmon->da9063->regmap, DA9063_REG_ADC_MAN, &adc_man);\n" + "> +\tif (ret < 0)\n" + "> +\t\tgoto err_mread;\n" + "> +\n" + "> +\t/* data value is not ready */\n" + "> +\tif (adc_man & DA9063_ADC_MAN == 0) {\n" + "> +\t\tret = -EINVAL;\n" + "> +\t\tgoto err_mread;\n" + "> +\t}\n" + "> +\n" + "> +\tret = regmap_bulk_read(hwmon->da9063->regmap,\n" + "> +\t\t\t DA9063_REG_ADC_RES_L, data, 2);\n" + "> +\tif (ret < 0)\n" + "> +\t\tgoto err_mread;\n" + "> +\n" + "> +\tret = (data[0] & DA9063_ADC_RES_L_MASK) >> DA9063_ADC_RES_L_SHIFT;\n" + "> +\tret |= data[1] << DA9063_ADC_RES_L_BITS;\n" + "> +err_mread:\n" + "> +\tmutex_unlock(&hwmon->hwmon_mutex);\n" + "> +\treturn ret;\n" + "> +}\n" + "> +\n" + "> +static irqreturn_t da9063_hwmon_irq_handler(int irq, void *irq_data)\n" + "> +{\n" + "> +\tstruct da9063_hwmon *hwmon = irq_data;\n" + "> +\tcomplete(&hwmon->adc_ready);\n" + "> +\treturn IRQ_HANDLED;\n" + "> +}\n" + "> +\n" + "> +static ssize_t da9063_adc_read(struct device *dev,\n" + "> +\t\t\t struct device_attribute *devattr, char *buf)\n" + "> +{\n" + "> +\tstruct da9063_hwmon *hwmon = dev_get_drvdata(dev);\n" + "> +\tint channel = to_sensor_dev_attr(devattr)->index;\n" + "> +\tint val;\n" + "> +\tint ret;\n" + "> +\n" + "> +\tswitch (channel) {\n" + "> +\tcase DA9063_CHAN_ADCIN1:\n" + "> +\tcase DA9063_CHAN_ADCIN2:\n" + "> +\tcase DA9063_CHAN_ADCIN3:\n" + "> +\t\t/* fallthrough for ADC measures */\n" + "> +\t\tret = da9063_adc_current_switch(hwmon, channel, true);\n" + "> +\t\tif (ret < 0)\n" + "> +\t\t\tgoto err_read;\n" + "> +\n" + "> +\t\tval = da9063_adc_manual_read(hwmon, channel);\n" + "> +\t\tif (val < 0) {\n" + "> +\t\t\tret = val;\n" + "> +\t\t\tif (ret == -EINVAL)\n" + "> +\t\t\t\tdev_err(dev, \"Conversion was not completed\\n\");\n" + "> +\t\t\telse\n" + "> +\t\t\t\tdev_err(dev, \"ADC read error %d\\n\", ret);\n" + "> +\t\t\tgoto err_read;\n" + "> +\t\t}\n" + "> +\n" + "> +\t\tret = da9063_adc_current_switch(hwmon, channel, false);\n" + "> +\t\tif (ret < 0) {\n" + "> +\t\t\tdev_err(dev, \"Could not switch current\\n\");\n" + "> +\t\t\tgoto err_read;\n" + "> +\t\t}\n" + "> +\t\tbreak;\n" + "> +\n" + "> +\tcase DA9063_CHAN_VSYS:\n" + "> +\tcase DA9063_CHAN_TJUNC:\n" + "> +\tcase DA9063_CHAN_VBBAT:\n" + "> +\t\t/* fallthrough for internal measures */\n" + "> +\t\tval = da9063_adc_manual_read(hwmon, channel);\n" + "> +\t\tif (val < 0) {\n" + "> +\t\t\tdev_err(dev, \"ADC read error %d\\n\", val);\n" + "> +\t\t\treturn val;\n" + "> +\t\t}\n" + "> +\t\tbreak;\n" + "> +\n" + "> +\tdefault:\n" + "> +\t\t/* error case */\n" + "> +\t\tret = -EINVAL;\n" + "> +\t\tgoto err_read;\n" + "> +\t}\n" + "> +\n" + "> +\tret = da9063_adc_convert(hwmon, channel, &val);\n" + "> +\tif (ret < 0) {\n" + "> +\t\tdev_err(dev, \"Failed to convert ADC value %d\\n\", ret);\n" + "> +\t\tgoto err_read;\n" + "> +\t}\n" + "> +\n" + "> +\treturn sprintf(buf, \"%d\\n\", val);\n" + "> +err_read:\n" + "> +\treturn ret;\n" + "> +}\n" + "> +\n" + "> +static ssize_t da9063_show_name(struct device *dev,\n" + "> +\t\t\t\tstruct device_attribute *attr, char *buf)\n" + "> +{\n" + "> +\treturn sprintf(buf, DA9063_DRVNAME_HWMON \"\\n\");\n" + "> +}\n" + "> +\n" + "> +static ssize_t da9063_show_label(struct device *dev,\n" + "> +\t\t\t\t struct device_attribute *devattr, char *buf)\n" + "> +{\n" + "> +\tint channel = to_sensor_dev_attr(devattr)->index;\n" + "> +\tchar *label;\n" + "> +\n" + "> +\tswitch (channel) {\n" + "> +\tcase DA9063_CHAN_VSYS:\n" + "> +\t\tlabel = \"VSYS\";\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_ADCIN1:\n" + "> +\t\tlabel = \"ADCIN1\";\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_ADCIN2:\n" + "> +\t\tlabel = \"ADCIN2\";\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_ADCIN3:\n" + "> +\t\tlabel = \"ADCIN3\";\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_TJUNC:\n" + "> +\t\tlabel = \"TJUNC\";\n" + "> +\t\tbreak;\n" + "> +\tcase DA9063_CHAN_VBBAT:\n" + "> +\t\tlabel = \"VBBAT\";\n" + "> +\t\tbreak;\n" + "> +\tdefault:\n" + "> +\t\tlabel = \"UNKNOWN\";\n" + "> +\t}\n" + "> +\n" + "> +\treturn sprintf(buf, \"%s\\n\", label);\n" + "> +}\n" + "> +\n" + "> +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO,\n" + "> +\t\t\t da9063_adc_read, NULL, DA9063_CHAN_VSYS);\n" + "> +static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO,\n" + "> +\t\t\t da9063_show_label, NULL, DA9063_CHAN_VSYS);\n" + "> +\n" + "> +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO,\n" + "> +\t\t\t da9063_adc_read, NULL, DA9063_CHAN_ADCIN1);\n" + "> +static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO,\n" + "> +\t\t\t da9063_show_label, NULL, DA9063_CHAN_ADCIN1);\n" + "> +\n" + "> +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO,\n" + "> +\t\t\t da9063_adc_read, NULL, DA9063_CHAN_ADCIN2);\n" + "> +static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO,\n" + "> +\t\t\t da9063_show_label, NULL, DA9063_CHAN_ADCIN2);\n" + "> +\n" + "> +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO,\n" + "> +\t\t\t da9063_adc_read, NULL, DA9063_CHAN_ADCIN3);\n" + "> +static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO,\n" + "> +\t\t\t da9063_show_label, NULL, DA9063_CHAN_ADCIN3);\n" + "> +\n" + "> +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO,\n" + "> +\t\t\t da9063_adc_read, NULL, DA9063_CHAN_VBBAT);\n" + "> +static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO,\n" + "> +\t\t\t da9063_show_label, NULL, DA9063_CHAN_VBBAT);\n" + "> +\n" + "> +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,\n" + "> +\t\t\t da9063_adc_read, NULL, DA9063_CHAN_TJUNC);\n" + "> +\n" + "> +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO,\n" + "> +\t\t\t da9063_show_label, NULL, DA9063_CHAN_TJUNC);\n" + "> +\n" + "> +static DEVICE_ATTR(name, S_IRUGO, da9063_show_name, NULL);\n" + "> +\n" + "> +static struct attribute *da9063_attributes[] = {\n" + "> +\t&dev_attr_name.attr,\n" + "> +\t&sensor_dev_attr_in0_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in0_label.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in1_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in1_label.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in2_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in2_label.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in3_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in3_label.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in4_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_in4_label.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_temp1_input.dev_attr.attr,\n" + "> +\t&sensor_dev_attr_temp1_label.dev_attr.attr,\n" + "> +\tNULL\n" + "> +};\n" + "> +\n" + "> +static const struct attribute_group da9063_attr_group = {\n" + "> +\t.attrs = da9063_attributes,\n" + "> +};\n" + "> +\n" + "> +static int da9063_hwmon_probe(struct platform_device *pdev)\n" + "> +{\n" + "> +\tstruct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent);\n" + "> +\tstruct da9063_pdata *pdata = da9063->dev->platform_data;\n" + "> +\tstruct da9063_hwmon *hwmon;\n" + "> +\tint ret;\n" + "> +\tunsigned int val;\n" + "> +\n" + "> +\thwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9063_hwmon),\n" + "> +\t\t\t GFP_KERNEL);\n" + "> +\tif (!hwmon)\n" + "> +\t\treturn -ENOMEM;\n" + "> +\n" + "> +\tmutex_init(&hwmon->hwmon_mutex);\n" + "> +\tinit_completion(&hwmon->adc_ready);\n" + "> +\thwmon->da9063 = da9063;\n" + "> +\n" + "> +\t/* enable the ADC functions for GPIO 0,1,2 */\n" + "> +\tval = (DA9063_GPIO0_PIN_ADCIN1 << DA9063_GPIO0_PIN_MASK_SHIFT |\n" + "> +\t DA9063_GPIO1_PIN_ADCIN2_COMP << DA9063_GPIO1_PIN_MASK_SHIFT);\n" + "> +\tret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_GPIO_0_1,\n" + "> +\t\t\t\t (DA9063_GPIO0_PIN_MASK |\n" + "> +\t\t\t\t DA9063_GPIO1_PIN_MASK), val);\n" + "> +\tif (ret < 0) {\n" + "> +\t\tdev_err(&pdev->dev,\n" + "> +\t\t\t\"Failed to alter the ADCIN 1,2 bits for the GPIO 0,1 register\\n\");\n" + "> +\t\treturn -EIO;\n" + "> +\t}\n" + "> +\n" + "> +\tval = DA9063_GPIO2_PIN_ADCIN3 << DA9063_GPIO2_PIN_MASK_SHIFT;\n" + "> +\tret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_GPIO_2_3,\n" + "> +\t\t\t\t DA9063_GPIO2_PIN_MASK, val);\n" + "> +\tif (ret < 0) {\n" + "> +\t\tdev_err(&pdev->dev,\n" + "> +\t\t\t\"Failed to alter the ADCIN 3 bits for the GPIO 2,3 register\\n\");\n" + "> +\t\treturn -EIO;\n" + "> +\t}\n" + "> +\n" + "> +\t/* debounce ADC I settings */\n" + "> +\tval = (DA9063_ADCIN1_DEB_ON << DA9063_REG_ADCIN1_DEB_SHIFT |\n" + "> +\t DA9063_ADCIN2_DEB_ON << DA9063_REG_ADCIN2_DEB_SHIFT |\n" + "> +\t DA9063_ADCIN3_DEB_ON << DA9063_REG_ADCIN3_DEB_SHIFT);\n" + "> +\tret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CFG,\n" + "> +\t\t\t\t (DA9063_REG_ADCIN1_DEB_MASK |\n" + "> +\t\t\t\t DA9063_REG_ADCIN2_DEB_MASK |\n" + "> +\t\t\t\t DA9063_REG_ADCIN3_DEB_MASK), val);\n" + "> +\tif (ret < 0) {\n" + "> +\t\tdev_err(&pdev->dev,\n" + "> +\t\t\t\"Failed to alter the ADC configuration register\\n\");\n" + "> +\t\treturn -EIO;\n" + "> +\t}\n" + "> +\n" + "> +\t/* set up the current configurations */\n" + "> +\tval = (pdata->hwmon_pdata->adcin1_cur << DA9063_REG_ADCIN1_CUR_SHIFT |\n" + "> +\t pdata->hwmon_pdata->adcin2_cur << DA9063_REG_ADCIN2_CUR_SHIFT |\n" + "> +\t pdata->hwmon_pdata->adcin3_cur << DA9063_REG_ADCIN3_CUR_SHIFT);\n" + "> +\tret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CFG,\n" + "> +\t\t\t\t (DA9063_REG_ADCIN1_CUR_MASK |\n" + "> +\t\t\t\t DA9063_REG_ADCIN2_CUR_MASK |\n" + "> +\t\t\t\t DA9063_REG_ADCIN3_CUR_MASK), val);\n" + "> +\n" + "> +\tret = regmap_read(da9063->regmap, DA9063_REG_ADC_CFG, &val);\n" + "> +\tif (ret < 0) {\n" + "> +\t\tdev_err(&pdev->dev,\n" + "> +\t\t\t\"Failed to read read the ADC configuration register\\n\");\n" + "> +\t\treturn -EIO;\n" + "> +\t}\n" + "> +\n" + "> +\thwmon->irq = platform_get_irq_byname(pdev, DA9063_DRVNAME_HWMON);\n" + "> +\tif (hwmon->irq < 0)\n" + "> +\t\treturn hwmon->irq;\n" + "> +\n" + "> +\tret = devm_request_threaded_irq(&pdev->dev, hwmon->irq, NULL,\n" + "> +\t\t\t\t\tda9063_hwmon_irq_handler,\n" + "> +\t\t\t\t\tIRQF_TRIGGER_LOW | IRQF_ONESHOT,\n" + "> +\t\t\t\t\t\"HWMON\", hwmon);\n" + "> +\tif (ret) {\n" + "> +\t\tdev_err(&pdev->dev, \"Failed to request IRQ.\\n\");\n" + "> +\t\treturn ret;\n" + "> +\t}\n" + "> +\n" + "> +\tplatform_set_drvdata(pdev, hwmon);\n" + "> +\n" + "> +\t/* set trim temperature offset to value read at startup */\n" + "> +\thwmon->tjunc_offset = (signed char)hwmon->da9063->t_offset;\n" + "> +\n" + "> +\tret = sysfs_create_group(&pdev->dev.kobj, &da9063_attr_group);\n" + "> +\tif (ret)\n" + "> +\t\treturn ret;\n" + "> +\n" + "> +\thwmon->classdev = hwmon_device_register(&pdev->dev);\n" + "> +\tif (IS_ERR(hwmon->classdev)) {\n" + "> +\t\tsysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group);\n" + "> +\t\treturn PTR_ERR(hwmon->classdev);\n" + "> +\t}\n" + "> +\n" + "> +\treturn 0;\n" + "> +}\n" + "> +\n" + "> +static int da9063_hwmon_remove(struct platform_device *pdev)\n" + "> +{\n" + "> +\tstruct da9063_hwmon *hwmon = platform_get_drvdata(pdev);\n" + "> +\n" + "> +\thwmon_device_unregister(hwmon->classdev);\n" + "> +\tsysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group);\n" + "> +\n" + "> +\treturn 0;\n" + "> +}\n" + "> +\n" + "> +static struct platform_driver da9063_hwmon_driver = {\n" + "> +\t.probe = da9063_hwmon_probe,\n" + "> +\t.remove = da9063_hwmon_remove,\n" + "> +\t.driver = {\n" + "> +\t\t .name = DA9063_DRVNAME_HWMON,\n" + "> +\t\t .owner = THIS_MODULE,\n" + "> +\t\t },\n" + "> +};\n" + "> +\n" + "> +module_platform_driver(da9063_hwmon_driver);\n" + "> +\n" + "> +MODULE_DESCRIPTION(\"Hardware monitor support device driver for Dialog DA9063\");\n" + "> +MODULE_AUTHOR(\"S Twiss <stwiss.opensource@diasemi.com>\");\n" + "> +MODULE_LICENSE(\"GPL v2\");\n" + "> +MODULE_ALIAS(\"platform:\" DA9063_DRVNAME_HWMON);\n" + "> diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h\n" + "> index 09a85c6..922371b 100644\n" + "> --- a/include/linux/mfd/da9063/registers.h\n" + "> +++ b/include/linux/mfd/da9063/registers.h\n" + "> @@ -474,6 +474,7 @@\n" + "> \n" + "> /* DA9063_REG_GPIO_0_1 (addr=0x15) */\n" + "> #define\tDA9063_GPIO0_PIN_MASK\t\t\t0x03\n" + "> +#define\tDA9063_GPIO0_PIN_MASK_SHIFT\t\t0\n" + "> #define\t\tDA9063_GPIO0_PIN_ADCIN1\t\t0x00\n" + "> #define\t\tDA9063_GPIO0_PIN_GPI\t\t0x01\n" + "> #define\t\tDA9063_GPIO0_PIN_GPO_OD\t\t0x02\n" + "> @@ -485,6 +486,7 @@\n" + "> #define\t\tDA9063_GPIO0_TYPE_GPO_VDD_IO2\t0x04\n" + "> #define\tDA9063_GPIO0_NO_WAKEUP\t\t\t0x08\n" + "> #define\tDA9063_GPIO1_PIN_MASK\t\t\t0x30\n" + "> +#define\tDA9063_GPIO1_PIN_MASK_SHIFT\t\t4\n" + "> #define\t\tDA9063_GPIO1_PIN_ADCIN2_COMP\t0x00\n" + "> #define\t\tDA9063_GPIO1_PIN_GPI\t\t0x10\n" + "> #define\t\tDA9063_GPIO1_PIN_GPO_OD\t\t0x20\n" + "> @@ -498,6 +500,7 @@\n" + "> \n" + "> /* DA9063_REG_GPIO_2_3 (addr=0x16) */\n" + "> #define\tDA9063_GPIO2_PIN_MASK\t\t\t0x03\n" + "> +#define\tDA9063_GPIO2_PIN_MASK_SHIFT\t\t0\n" + "> #define\t\tDA9063_GPIO2_PIN_ADCIN3\t\t0x00\n" + "> #define\t\tDA9063_GPIO2_PIN_GPI\t\t0x01\n" + "> #define\t\tDA9063_GPIO2_PIN_GPO_PSS\t0x02\n" + "> @@ -813,6 +816,7 @@\n" + "> #define\tDA9063_VSYS_VAL_BASE\t\t\t0x00\n" + "> \n" + "> /* DA9063_REG_ADC_RES_L (addr=0x37) */\n" + "> +#define\tDA9063_ADC_RES_L_SHIFT\t\t\t6\n" + "> #define\tDA9063_ADC_RES_L_BITS\t\t\t2\n" + "> #define\tDA9063_ADC_RES_L_MASK\t\t\t0xC0\n" + "> \n" + "> @@ -979,6 +983,36 @@\n" + "> #define DA9063_GPIO_DIM\t\t\t\t0x80\n" + "> #define DA9063_GPIO_PWM_MASK\t\t\t0x7F\n" + "> \n" + "> +/* DA9063_REG_ADC_CFG (addr=0xC9) */\n" + "> +#define DA9063_REG_ADCIN1_CUR_MASK\t\t0x03\n" + "> +#define DA9063_REG_ADCIN1_CUR_SHIFT\t\t0\n" + "> +#define\t\tDA9063_ADCIN1_CUR_1UA\t\t0x00\n" + "> +#define\t\tDA9063_ADCIN1_CUR_2UA\t\t0x01\n" + "> +#define\t\tDA9063_ADCIN1_CUR_10UA\t\t0x02\n" + "> +#define\t\tDA9063_ADCIN1_CUR_40UA\t\t0x03\n" + "> +#define DA9063_REG_ADCIN2_CUR_MASK\t\t0x0C\n" + "> +#define DA9063_REG_ADCIN2_CUR_SHIFT\t\t2\n" + "> +#define\t\tDA9063_ADCIN2_CUR_1UA\t\t0x00\n" + "> +#define\t\tDA9063_ADCIN2_CUR_2UA\t\t0x01\n" + "> +#define\t\tDA9063_ADCIN2_CUR_10UA\t\t0x02\n" + "> +#define\t\tDA9063_ADCIN2_CUR_40UA\t\t0x03\n" + "> +#define DA9063_REG_ADCIN3_CUR_MASK\t\t0x10\n" + "> +#define DA9063_REG_ADCIN3_CUR_SHIFT\t\t4\n" + "> +#define\t\tDA9063_ADCIN3_CUR_10UA\t\t0x00\n" + "> +#define\t\tDA9063_ADCIN3_CUR_40UA\t\t0x01\n" + "> +#define DA9063_REG_ADCIN1_DEB_MASK\t\t0x20\n" + "> +#define DA9063_REG_ADCIN1_DEB_SHIFT\t\t5\n" + "> +#define\t\tDA9063_ADCIN1_DEB_OFF\t\t0x00\n" + "> +#define\t\tDA9063_ADCIN1_DEB_ON\t\t0x01\n" + "> +#define DA9063_REG_ADCIN2_DEB_MASK\t\t0x40\n" + "> +#define DA9063_REG_ADCIN2_DEB_SHIFT\t\t6\n" + "> +#define\t\tDA9063_ADCIN2_DEB_OFF\t\t0x00\n" + "> +#define\t\tDA9063_ADCIN2_DEB_ON\t\t0x01\n" + "> +#define DA9063_REG_ADCIN3_DEB_MASK\t\t0x80\n" + "> +#define DA9063_REG_ADCIN3_DEB_SHIFT\t\t7\n" + "> +#define\t\tDA9063_ADCIN3_DEB_OFF\t\t0x00\n" + "> +#define\t\tDA9063_ADCIN3_DEB_ON\t\t0x01\n" + "> +\n" + "> /* DA9063_REG_CONFIG_H (addr=0x10D) */\n" + "> #define DA9063_PWM_CLK_MASK\t\t\t0x01\n" + "> #define\t\tDA9063_PWM_CLK_PWM2MHZ\t\t0x00\n" + "\n" + "-- \n" + "Lee Jones\n" + "Linaro STMicroelectronics Landing Team Lead\n" + "Linaro.org \342\224\202 Open source software for ARM SoCs\n" + Follow Linaro: Facebook | Twitter | Blog -1ed89b27e1bc2a544439bf5de768659396120c677ba261d0a77f00ffabca4a2a +b8b878f41a5f5bd7b38da59a5cc598ba2b2c9ac15d5373163c80060c32e5b66d
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.