From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Subject: [PATCH 2/3] auxadc: Add Mediatek auxadc driver for mt2701. Date: Fri, 24 Jun 2016 15:37:09 +0800 Message-ID: <1466753830-4542-3-git-send-email-zhiyong.tao@mediatek.com> In-Reply-To: <1466753830-4542-1-git-send-email-zhiyong.tao@mediatek.com> References: <1466753830-4542-1-git-send-email-zhiyong.tao@mediatek.com> MIME-Version: 1.0 Content-Type: multipart/related; boundary="__=_Part_Boundary_004_499596275.1659815320" To: robh+dt@kernel.org, jic23@kernel.org, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net Cc: srv_heupstream@mediatek.com, liguo.zhang@mediatek.com, yingjoe.chen@mediatek.com, eddie.huang@mediatek.com, erin.lo@mediatek.com, dawei.chien@mediatek.com, matthias.bgg@gmail.com, s.hauer@pengutronix.de, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-iio@vger.kernel.org, linux-mediatek@lists.infradead.org, Zhiyong Tao List-ID: --__=_Part_Boundary_004_499596275.1659815320 Content-Transfer-Encoding: base64 Content-Type: multipart/alternative; boundary="__=_Part_Boundary_005_949221731.443340628" --__=_Part_Boundary_005_949221731.443340628 Content-Type: text/html Content-Transfer-Encoding: base64 PHByZT4NCkZyb206IFpoaXlvbmcgVGFvICZsdDt6aGl5b25nLnRhb0BtZWRpYXRlay5jb20mZ3Q7 DQoNCkFkZCBNZWRpYXRlayBhdXhhZGMgZHJpdmVyIGluIGlpby4NCkl0IHdpbGwgcmVnaXN0ZXIg YSBkZXZpY2UgaW4gaWlvIGFuZCBzdXBwb3J0IGlpby4NClNvIHRoZXJtYWwgY2FuIHJlYWQgYXV4 YWRjIGNoYW5uZWwgdG8gc2FtcGxlIGRhdGEgYnkgaWlvIGRldmljZS4NCkl0IGlzIHRlc3RlZCBz dWNjZXNzZnVsbHkgb24gbXQyNzAxIHBsYXRmb3JtLg0KTXQ4MTczIHBsYXRmb3JtIGlzIG5vdCB0 ZXN0ZWQuIEJ1dCB0aGUgZXhwZWN0YXRpb24gaXMgY29tcGF0aWJsZS4NCg0KU2lnbmVkLW9mZi1i eTogWmhpeW9uZyBUYW8gJmx0O3poaXlvbmcudGFvQG1lZGlhdGVrLmNvbSZndDsNCi0tLQ0KIGRy aXZlcnMvaWlvL2FkYy9LY29uZmlnICAgICAgICAgfCAgIDExICsrDQogZHJpdmVycy9paW8vYWRj L01ha2VmaWxlICAgICAgICB8ICAgIDEgKw0KIGRyaXZlcnMvaWlvL2FkYy9tdDY1eHhfYXV4YWRj LmMgfCAgMjY5ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKw0KIDMgZmls ZXMgY2hhbmdlZCwgMjgxIGluc2VydGlvbnMoKykNCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy cy9paW8vYWRjL210NjV4eF9hdXhhZGMuYw0KDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9paW8vYWRj L0tjb25maWcgYi9kcml2ZXJzL2lpby9hZGMvS2NvbmZpZw0KaW5kZXggMjUzNzhjNS4uNzY4NDg0 OSAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvaWlvL2FkYy9LY29uZmlnDQorKysgYi9kcml2ZXJzL2lp by9hZGMvS2NvbmZpZw0KQEAgLTMxNSw2ICszMTUsMTcgQEAgY29uZmlnIE1FTl9aMTg4X0FEQw0K IAkgIFRoaXMgZHJpdmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhl IG1vZHVsZSB3aWxsIGJlDQogCSAgY2FsbGVkIG1lbl96MTg4X2FkYy4NCiANCitjb25maWcgTUVE SUFURUtfTVQ2NVhYX0FVWEFEQw0KKwl0cmlzdGF0ZSAmcXVvdDtNZWRpYVRlayBBVVhBREMgZHJp dmVyJnF1b3Q7DQorCWhlbHANCisJICBTYXkgeWVzIGhlcmUgdG8gZW5hYmxlIHN1cHBvcnQgZm9y IE1lZGlhVGVrIG10NjV4eCBBVVhBREMuDQorDQorCSAgVGhlIGRyaXZlciBzdXBwb3J0cyBpbW1l ZGlhdGUgbW9kZSBvcGVyYXRpb24gdG8gcmVhZCBmcm9tIG9uZSBvZiBzaXh0ZWVuDQorCSAgY2hh bm5lbHMgKGV4dGVybmFsIG9yIGludGVybmFsKS4NCisNCisJICBUaGlzIGRyaXZlciBjYW4gYWxz byBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1bGUgd2lsbCBiZQ0KKwkgIGNh bGxlZCBtdDY1eHhfYXV4YWRjLg0KKw0KIGNvbmZpZyBNWFNfTFJBREMNCiAgICAgICAgIHRyaXN0 YXRlICZxdW90O0ZyZWVzY2FsZSBpLk1YMjMvaS5NWDI4IExSQURDJnF1b3Q7DQogICAgICAgICBk ZXBlbmRzIG9uIChBUkNIX01YUyB8fCBDT01QSUxFX1RFU1QpICZhbXA7JmFtcDsgSEFTX0lPTUVN DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9paW8vYWRjL01ha2VmaWxlIGIvZHJpdmVycy9paW8vYWRj L01ha2VmaWxlDQppbmRleCAzODYzOGQ0Li5iYzYyMjA5IDEwMDY0NA0KLS0tIGEvZHJpdmVycy9p aW8vYWRjL01ha2VmaWxlDQorKysgYi9kcml2ZXJzL2lpby9hZGMvTWFrZWZpbGUNCkBAIC0zMSw2 ICszMSw3IEBAIG9iai0kKENPTkZJR19NQVgxMzYzKSArPSBtYXgxMzYzLm8NCiBvYmotJChDT05G SUdfTUNQMzIwWCkgKz0gbWNwMzIweC5vDQogb2JqLSQoQ09ORklHX01DUDM0MjIpICs9IG1jcDM0 MjIubw0KIG9iai0kKENPTkZJR19NRU5fWjE4OF9BREMpICs9IG1lbl96MTg4X2FkYy5vDQorb2Jq LSQoQ09ORklHX01FRElBVEVLX01UNjVYWF9BVVhBREMpICs9IG10NjV4eF9hdXhhZGMubw0KIG9i ai0kKENPTkZJR19NWFNfTFJBREMpICs9IG14cy1scmFkYy5vDQogb2JqLSQoQ09ORklHX05BVTc4 MDIpICs9IG5hdTc4MDIubw0KIG9iai0kKENPTkZJR19QQUxNQVNfR1BBREMpICs9IHBhbG1hc19n cGFkYy5vDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9paW8vYWRjL210NjV4eF9hdXhhZGMuYyBiL2Ry aXZlcnMvaWlvL2FkYy9tdDY1eHhfYXV4YWRjLmMNCm5ldyBmaWxlIG1vZGUgMTAwNjQ0DQppbmRl eCAwMDAwMDAwLi5iM2MwNTljDQotLS0gL2Rldi9udWxsDQorKysgYi9kcml2ZXJzL2lpby9hZGMv bXQ2NXh4X2F1eGFkYy5jDQpAQCAtMCwwICsxLDI2OSBAQA0KKy8qDQorICogQ29weXJpZ2h0IChj KSAyMDE2IE1lZGlhVGVrIEluYy4NCisgKiBBdXRob3I6IFpoaXlvbmcgVGFvICZsdDt6aGl5b25n LnRhb0BtZWRpYXRlay5jb20mZ3Q7DQorICoNCisgKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0 d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQ0KKyAqIGl0IHVuZGVy IHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFz DQorICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uDQorICoNCisg KiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJl IHVzZWZ1bCwNCisgKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUg aW1wbGllZCB3YXJyYW50eSBvZg0KKyAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBB IFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUNCisgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGlj ZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KKyAqLw0KKw0KKyNpbmNsdWRlICZsdDtsaW51eC9jbGsu aCZndDsNCisjaW5jbHVkZSAmbHQ7bGludXgvZGVsYXkuaCZndDsNCisjaW5jbHVkZSAmbHQ7bGlu dXgvZXJyLmgmZ3Q7DQorI2luY2x1ZGUgJmx0O2xpbnV4L2tlcm5lbC5oJmd0Ow0KKyNpbmNsdWRl ICZsdDtsaW51eC9tb2R1bGUuaCZndDsNCisjaW5jbHVkZSAmbHQ7bGludXgvb2YuaCZndDsNCisj aW5jbHVkZSAmbHQ7bGludXgvb2ZfZGV2aWNlLmgmZ3Q7DQorI2luY2x1ZGUgJmx0O2xpbnV4L3Bs YXRmb3JtX2RldmljZS5oJmd0Ow0KKyNpbmNsdWRlICZsdDtsaW51eC9pb3BvbGwuaCZndDsNCisj aW5jbHVkZSAmbHQ7bGludXgvaW8uaCZndDsNCisjaW5jbHVkZSAmbHQ7bGludXgvaWlvL2lpby5o Jmd0Ow0KKw0KKy8qIFJlZ2lzdGVycyAgZGVmaW5lKi8NCisjZGVmaW5lIE1UNjVYWF9BVVhBRENf Q09OMCAgICAgICAgICAgICAgICAgICAgMHgwMA0KKyNkZWZpbmUgTVQ2NVhYX0FVWEFEQ19DT04x ICAgICAgICAgICAgICAgICAgICAweDA0DQorI2RlZmluZSBNVDY1WFhfQVVYQURDX0NPTjIgICAg ICAgICAgICAgICAgICAgIDB4MTANCisjZGVmaW5lIE1UNjVYWF9BVVhBRENfU1RBICAgICAgICAg ICAgICAgICAgICAgQklUKDApDQorDQorI2RlZmluZSBNVDY1WFhfQVVYQURDX0RBVDAgICAgICAg ICAgICAgICAgICAgIDB4MTQNCisjZGVmaW5lIE1UNjVYWF9BVVhBRENfUkRZMCAgICAgICAgICAg ICAgICAgICAgQklUKDEyKQ0KKw0KKyNkZWZpbmUgTVQ2NVhYX0FVWEFEQ19NSVNDICAgICAgICAg ICAgICAgICAgICAweDk0DQorI2RlZmluZSBNVDY1WFhfQVVYQURDX1BETl9FTiAgICAgICAgICAg ICAgICAgIEJJVCgxNCkNCisNCisjZGVmaW5lIE1UNjVYWF9BVVhBRENfREFUX01BU0sgICAgICAg ICAgICAgICAgMHhmZmYNCisjZGVmaW5lIE1UNjVYWF9BVVhBRENfU0xFRVBfVVMgICAgICAgICAg ICAgICAgMTAwMA0KKyNkZWZpbmUgTVQ2NVhYX0FVWEFEQ19USU1FT1VUX1VTICAgICAgICAgICAg ICAxMDAwMA0KKyNkZWZpbmUgTVQ2NVhYX0FVWEFEQ19QT1dFUl9SRUFEWV9NUyAgICAgICAgICAx DQorI2RlZmluZSBNVDY1WFhfQVVYQURDX1NBTVBMRV9SRUFEWV9VUyAgICAgICAgIDI1DQorDQor c3RydWN0IG10NjV4eF9hdXhhZGNfZGV2aWNlIHsNCisJdm9pZCBfX2lvbWVtICpyZWdfYmFzZTsN CisJc3RydWN0IGNsayAqYWRjX2NsazsNCisJc3RydWN0IG11dGV4IGxvY2s7IC8qZ2VuZXJpYyBt dXRleCBmb3IgYXV4YWRjIGRyaXZlciovDQorCXVuc2lnbmVkIGludCBwb3dlcl9yZWFkeV9tczsN CisJdW5zaWduZWQgaW50IHNhbXBsZV9yZWFkeV91czsNCit9Ow0KKw0KKyNkZWZpbmUgTVQ2NXh4 X0FVWEFEQ19DSEFOTkVMKGlkeCkgewkJCQkgICAgICAgXA0KKwkJLnR5cGUgPSBJSU9fVk9MVEFH RSwJCQkJICAgICAgIFwNCisJCS5pbmRleGVkID0gMSwJCQkJCSAgICAgICBcDQorCQkuY2hhbm5l bCA9IChpZHgpLAkJCQkgICAgICAgXA0KKwkJLmluZm9fbWFza19zZXBhcmF0ZSA9IEJJVChJSU9f Q0hBTl9JTkZPX1JBVyksCSAgICAgICBcDQorCQkuaW5mb19tYXNrX3NoYXJlZF9ieV90eXBlID0g QklUKElJT19DSEFOX0lORk9fU0NBTEUpIHwgXA0KKwkJCQkJICAgIEJJVChJSU9fQ0hBTl9JTkZP X09GRlNFVCksIFwNCit9DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBpaW9fY2hhbl9zcGVjIG10 NjV4eF9hdXhhZGNfaWlvX2NoYW5uZWxzW10gPSB7DQorCU1UNjV4eF9BVVhBRENfQ0hBTk5FTCgw KSwNCisJTVQ2NXh4X0FVWEFEQ19DSEFOTkVMKDEpLA0KKwlNVDY1eHhfQVVYQURDX0NIQU5ORUwo MiksDQorCU1UNjV4eF9BVVhBRENfQ0hBTk5FTCgzKSwNCisJTVQ2NXh4X0FVWEFEQ19DSEFOTkVM KDQpLA0KKwlNVDY1eHhfQVVYQURDX0NIQU5ORUwoNSksDQorCU1UNjV4eF9BVVhBRENfQ0hBTk5F TCg2KSwNCisJTVQ2NXh4X0FVWEFEQ19DSEFOTkVMKDcpLA0KKwlNVDY1eHhfQVVYQURDX0NIQU5O RUwoOCksDQorCU1UNjV4eF9BVVhBRENfQ0hBTk5FTCg5KSwNCisJTVQ2NXh4X0FVWEFEQ19DSEFO TkVMKDEwKSwNCisJTVQ2NXh4X0FVWEFEQ19DSEFOTkVMKDExKSwNCisJTVQ2NXh4X0FVWEFEQ19D SEFOTkVMKDEyKSwNCisJTVQ2NXh4X0FVWEFEQ19DSEFOTkVMKDEzKSwNCisJTVQ2NXh4X0FVWEFE Q19DSEFOTkVMKDE0KSwNCisJTVQ2NXh4X0FVWEFEQ19DSEFOTkVMKDE1KSwNCit9Ow0KKw0KK3N0 YXRpYyBpbnQgbXQ2NXh4X2F1eGFkY19yZWFkKHN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYsDQor CQkJICAgICAgc3RydWN0IGlpb19jaGFuX3NwZWMgY29uc3QgKmNoYW4pDQorew0KKwl1MzIgcmF3 ZGF0YSwgdmFsOw0KKwl2b2lkIF9faW9tZW0gKnJlZ19jaGFubmVsOw0KKwlzdHJ1Y3QgbXQ2NXh4 X2F1eGFkY19kZXZpY2UgKmFkY19kZXYgPSBpaW9fcHJpdihpbmRpb19kZXYpOw0KKw0KKwlyZWdf Y2hhbm5lbCA9IGFkY19kZXYtJmd0O3JlZ19iYXNlICsgTVQ2NVhYX0FVWEFEQ19EQVQwICsNCisJ CSAgICAgIGNoYW4tJmd0O2NoYW5uZWwgKiAweDA0Ow0KKw0KKwltdXRleF9sb2NrKCZhbXA7YWRj X2Rldi0mZ3Q7bG9jayk7DQorDQorCXZhbCA9IHJlYWRsKGFkY19kZXYtJmd0O3JlZ19iYXNlICsg TVQ2NVhYX0FVWEFEQ19DT04xKTsNCisJdmFsICZhbXA7PSB+KDEgJmx0OyZsdDsgY2hhbi0mZ3Q7 Y2hhbm5lbCk7DQorCXdyaXRlbCh2YWwsIGFkY19kZXYtJmd0O3JlZ19iYXNlICsgTVQ2NVhYX0FV WEFEQ19DT04xKTsNCisNCisJLyogcmVhZCBjaGFubmVsIGFuZCBtYWtlIHN1cmUgb2xkIHJlYWR5 IGJpdCA9PTAgKi8NCisJcmVhZGxfcG9sbF90aW1lb3V0KHJlZ19jaGFubmVsLCB2YWwsDQorCQkJ ICAgKCh2YWwgJmFtcDsgTVQ2NVhYX0FVWEFEQ19SRFkwKSA9PSAwKSwNCisJCQkgICBNVDY1WFhf QVVYQURDX1NMRUVQX1VTLA0KKwkJCSAgIE1UNjVYWF9BVVhBRENfVElNRU9VVF9VUyk7DQorDQor CS8qIHNldCBiaXQgIHRvIHRyaWdnZXIgc2FtcGxlICovDQorCXZhbCA9IHJlYWRsKGFkY19kZXYt Jmd0O3JlZ19iYXNlICsgTVQ2NVhYX0FVWEFEQ19DT04xKTsNCisJdmFsIHw9IDEgJmx0OyZsdDsg Y2hhbi0mZ3Q7Y2hhbm5lbDsNCisJd3JpdGVsKHZhbCwgYWRjX2Rldi0mZ3Q7cmVnX2Jhc2UgKyBN VDY1WFhfQVVYQURDX0NPTjEpOw0KKw0KKwkvKiB3ZSBtdXN0IGRlbGF5IGhlcmUgZm9yIGhhcmR3 YXJlIHNhbXBsZSBjaGFubmVsIGRhdGEgKi8NCisJdWRlbGF5KGFkY19kZXYtJmd0O3NhbXBsZV9y ZWFkeV91cyk7DQorDQorCS8qIGNoZWNrIE1US19BVVhBRENfQ09OMiBpZiBhdXhhZGMgaXMgaWRs ZSAqLw0KKwlyZWFkbF9wb2xsX3RpbWVvdXQoYWRjX2Rldi0mZ3Q7cmVnX2Jhc2UgKyBNVDY1WFhf QVVYQURDX0NPTjIsIHZhbCwNCisJCQkgICAoKHZhbCAmYW1wOyBNVDY1WFhfQVVYQURDX1NUQSkg PT0gMCksDQorCQkJICAgTVQ2NVhYX0FVWEFEQ19TTEVFUF9VUywNCisJCQkgICBNVDY1WFhfQVVY QURDX1RJTUVPVVRfVVMpOw0KKw0KKwkvKiByZWFkIGNoYW5uZWwgYW5kIG1ha2Ugc3VyZSAgcmVh ZHkgYml0ID09MSAqLw0KKwlyZWFkbF9wb2xsX3RpbWVvdXQocmVnX2NoYW5uZWwsIHZhbCwNCisJ CQkgICAoKHZhbCAmYW1wOyBNVDY1WFhfQVVYQURDX1JEWTApID09IDEpLA0KKwkJCSAgIE1UNjVY WF9BVVhBRENfU0xFRVBfVVMsDQorCQkJICAgTVQ2NVhYX0FVWEFEQ19USU1FT1VUX1VTKTsNCisN CisJLyogcmVhZCBkYXRhICovDQorCXJhd2RhdGEgPSByZWFkbChyZWdfY2hhbm5lbCkgJmFtcDsg TVQ2NVhYX0FVWEFEQ19EQVRfTUFTSzsNCisNCisJbXV0ZXhfdW5sb2NrKCZhbXA7YWRjX2Rldi0m Z3Q7bG9jayk7DQorDQorCXJldHVybiByYXdkYXRhOw0KK30NCisNCitzdGF0aWMgaW50IG10NjV4 eF9hdXhhZGNfcmVhZF9yYXcoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiwNCisJCQkJICBzdHJ1 Y3QgaWlvX2NoYW5fc3BlYyBjb25zdCAqY2hhbiwNCisJCQkJICBpbnQgKnZhbCwNCisJCQkJICBp bnQgKnZhbDIsDQorCQkJCSAgbG9uZyBpbmZvKQ0KK3sNCisJaW50IHJldDsNCisNCisJc3dpdGNo IChpbmZvKSB7DQorCWNhc2UgSUlPX0NIQU5fSU5GT19SQVc6DQorCQkqdmFsID0gbXQ2NXh4X2F1 eGFkY19yZWFkKGluZGlvX2RldiwgY2hhbik7DQorCQlyZXQgPSBJSU9fVkFMX0lOVDsNCisJCWJy ZWFrOw0KKwljYXNlIElJT19DSEFOX0lORk9fU0NBTEU6DQorCQkqdmFsID0gMTsNCisJCXJldCA9 IElJT19WQUxfSU5UOw0KKwkJYnJlYWs7DQorCWNhc2UgSUlPX0NIQU5fSU5GT19PRkZTRVQ6DQor CQkqdmFsID0gMDsNCisJCXJldCA9IElJT19WQUxfSU5UOw0KKwkJYnJlYWs7DQorCWRlZmF1bHQ6 DQorCQlyZXQgPSAtRUlOVkFMOw0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIHJldDsNCit9 DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBpaW9faW5mbyBtdDY1eHhfYXV4YWRjX2luZm8gPSB7 DQorCS5kcml2ZXJfbW9kdWxlID0gVEhJU19NT0RVTEUsDQorCS5yZWFkX3JhdyA9ICZhbXA7bXQ2 NXh4X2F1eGFkY19yZWFkX3JhdywNCit9Ow0KKw0KK3N0YXRpYyBpbnQgbXQ2NXh4X2F1eGFkY19w cm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KK3sNCisJc3RydWN0IG10NjV4eF9h dXhhZGNfZGV2aWNlICphZGNfZGV2Ow0KKwl1bnNpZ25lZCBsb25nIGFkY19jbGtfcmF0ZTsNCisJ c3RydWN0IHJlc291cmNlICpyZXM7DQorCXN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXY7DQorCWlu dCByZXQ7DQorCXUzMiB2YWw7DQorDQorCWluZGlvX2RldiA9IGRldm1faWlvX2RldmljZV9hbGxv YygmYW1wO3BkZXYtJmd0O2Rldiwgc2l6ZW9mKCphZGNfZGV2KSk7DQorCWlmICghaW5kaW9fZGV2 KQ0KKwkJcmV0dXJuIC1FTk9NRU07DQorDQorCWFkY19kZXYgPSBpaW9fcHJpdihpbmRpb19kZXYp Ow0KKwlpbmRpb19kZXYtJmd0O2Rldi5wYXJlbnQgPSAmYW1wO3BkZXYtJmd0O2RldjsNCisJaW5k aW9fZGV2LSZndDtuYW1lID0gZGV2X25hbWUoJmFtcDtwZGV2LSZndDtkZXYpOw0KKwlpbmRpb19k ZXYtJmd0O2luZm8gPSAmYW1wO210NjV4eF9hdXhhZGNfaW5mbzsNCisJaW5kaW9fZGV2LSZndDtt b2RlcyA9IElORElPX0RJUkVDVF9NT0RFOw0KKwlpbmRpb19kZXYtJmd0O2NoYW5uZWxzID0gbXQ2 NXh4X2F1eGFkY19paW9fY2hhbm5lbHM7DQorCWluZGlvX2Rldi0mZ3Q7bnVtX2NoYW5uZWxzID0g QVJSQVlfU0laRShtdDY1eHhfYXV4YWRjX2lpb19jaGFubmVscyk7DQorDQorCXJlcyA9IHBsYXRm b3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7DQorCWFkY19kZXYtJmd0 O3JlZ19iYXNlID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZhbXA7cGRldi0mZ3Q7ZGV2LCByZXMp Ow0KKwlpZiAoSVNfRVJSKGFkY19kZXYtJmd0O3JlZ19iYXNlKSkgew0KKwkJZGV2X2VycigmYW1w O3BkZXYtJmd0O2RldiwgJnF1b3Q7ZmFpbGVkIHRvIGdldCBhdXhhZGMgYmFzZSBhZGRyZXNzLlxu JnF1b3Q7KTsNCisJCXJldHVybiBQVFJfRVJSKGFkY19kZXYtJmd0O3JlZ19iYXNlKTsNCisJfQ0K Kw0KKwlhZGNfZGV2LSZndDthZGNfY2xrID0gZGV2bV9jbGtfZ2V0KCZhbXA7cGRldi0mZ3Q7ZGV2 LCAmcXVvdDttYWluJnF1b3Q7KTsNCisJaWYgKElTX0VSUihhZGNfZGV2LSZndDthZGNfY2xrKSkg ew0KKwkJZGV2X2VycigmYW1wO3BkZXYtJmd0O2RldiwgJnF1b3Q7ZmFpbGVkIHRvIGdldCBheHVh ZGMgY2xvY2tcbiZxdW90Oyk7DQorCQlyZXR1cm4gUFRSX0VSUihhZGNfZGV2LSZndDthZGNfY2xr KTsNCisJfQ0KKw0KKwlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUoYWRjX2Rldi0mZ3Q7YWRjX2Ns ayk7DQorCWlmIChyZXQpIHsNCisJCWRldl9lcnIoJmFtcDtwZGV2LSZndDtkZXYsICZxdW90O2Zh aWxlZCB0byBlbmFibGUgYXV4YWRjIGNsb2NrXG4mcXVvdDspOw0KKwkJcmV0dXJuIHJldDsNCisJ fQ0KKw0KKwlhZGNfY2xrX3JhdGUgPSBjbGtfZ2V0X3JhdGUoYWRjX2Rldi0mZ3Q7YWRjX2Nsayk7 DQorCWlmICghYWRjX2Nsa19yYXRlKSB7DQorCQlkZXZfZXJyKCZhbXA7cGRldi0mZ3Q7ZGV2LCAm cXVvdDtudWxsIGNsb2NrIHJhdGUhXG4mcXVvdDspOw0KKwkJY2xrX2Rpc2FibGVfdW5wcmVwYXJl KGFkY19kZXYtJmd0O2FkY19jbGspOw0KKwkJcmV0dXJuIC1FSU5WQUw7DQorCX0NCisNCisJYWRj X2Rldi0mZ3Q7cG93ZXJfcmVhZHlfbXMgPSBNVDY1WFhfQVVYQURDX1BPV0VSX1JFQURZX01TOw0K KwlhZGNfZGV2LSZndDtzYW1wbGVfcmVhZHlfdXMgPSBNVDY1WFhfQVVYQURDX1NBTVBMRV9SRUFE WV9VUzsNCisNCisJbXV0ZXhfaW5pdCgmYW1wO2FkY19kZXYtJmd0O2xvY2spOw0KKw0KKwl2YWwg PSByZWFkbChhZGNfZGV2LSZndDtyZWdfYmFzZSArIE1UNjVYWF9BVVhBRENfTUlTQyk7DQorCXZh bCB8PSBNVDY1WFhfQVVYQURDX1BETl9FTjsNCisJd3JpdGVsKHZhbCwgYWRjX2Rldi0mZ3Q7cmVn X2Jhc2UgKyBNVDY1WFhfQVVYQURDX01JU0MpOw0KKwltZGVsYXkoYWRjX2Rldi0mZ3Q7cG93ZXJf cmVhZHlfbXMpOw0KKw0KKwlyZXQgPSBpaW9fZGV2aWNlX3JlZ2lzdGVyKGluZGlvX2Rldik7DQor CWlmIChyZXQgJmx0OyAwKSB7DQorCQlkZXZfZXJyKCZhbXA7cGRldi0mZ3Q7ZGV2LCAmcXVvdDtm YWlsZWQgdG8gcmVnaXN0ZXIgaWlvIGRldmljZSFcbiZxdW90Oyk7DQorCQlyZXR1cm4gcmV0Ow0K Kwl9DQorDQorCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGluZGlvX2Rldik7DQorDQorCXJl dHVybiAwOw0KK30NCisNCitzdGF0aWMgaW50IG10NjV4eF9hdXhhZGNfcmVtb3ZlKHN0cnVjdCBw bGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQorew0KKwlzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2ID0g cGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7DQorCXN0cnVjdCBtdDY1eHhfYXV4YWRjX2Rldmlj ZSAqYWRjX2RldiA9IGlpb19wcml2KGluZGlvX2Rldik7DQorCXUzMiB2YWw7DQorDQorCWlpb19k ZXZpY2VfdW5yZWdpc3RlcihpbmRpb19kZXYpOw0KKw0KKwl2YWwgPSByZWFkbChhZGNfZGV2LSZn dDtyZWdfYmFzZSArIE1UNjVYWF9BVVhBRENfTUlTQyk7DQorCXZhbCAmYW1wOz0gfk1UNjVYWF9B VVhBRENfUEROX0VOOw0KKwl3cml0ZWwodmFsLCBhZGNfZGV2LSZndDtyZWdfYmFzZSArIE1UNjVY WF9BVVhBRENfTUlTQyk7DQorDQorCWNsa19kaXNhYmxlX3VucHJlcGFyZShhZGNfZGV2LSZndDth ZGNfY2xrKTsNCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2Zf ZGV2aWNlX2lkIG10NjV4eF9hdXhhZGNfb2ZfbWF0Y2hbXSA9IHsNCisJeyAuY29tcGF0aWJsZSA9 ICZxdW90O21lZGlhdGVrLG10MjcwMS1hdXhhZGMmcXVvdDssIH0sDQorCXsgLmNvbXBhdGlibGUg PSAmcXVvdDttZWRpYXRlayxtdDgxNzMtYXV4YWRjJnF1b3Q7LCB9LA0KKwl7IH0NCit9Ow0KK01P RFVMRV9ERVZJQ0VfVEFCTEUob2YsIG10NjV4eF9hdXhhZGNfb2ZfbWF0Y2gpOw0KKw0KK3N0YXRp YyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIG10NjV4eF9hdXhhZGNfZHJpdmVyID0gew0KKwkuZHJp dmVyID0gew0KKwkJLm5hbWUgICA9ICZxdW90O210NjV4eC1hdXhhZGMmcXVvdDssDQorCQkub2Zf bWF0Y2hfdGFibGUgPSBtdDY1eHhfYXV4YWRjX29mX21hdGNoLA0KKwl9LA0KKwkucHJvYmUJPSBt dDY1eHhfYXV4YWRjX3Byb2JlLA0KKwkucmVtb3ZlCT0gbXQ2NXh4X2F1eGFkY19yZW1vdmUsDQor fTsNCittb2R1bGVfcGxhdGZvcm1fZHJpdmVyKG10NjV4eF9hdXhhZGNfZHJpdmVyKTsNCisNCitN T0RVTEVfQVVUSE9SKCZxdW90O1poaXlvbmcgVGFvICZsdDt6aGl5b25nLnRhb0BtZWRpYXRlay5j b20mZ3Q7JnF1b3Q7KTsNCitNT0RVTEVfREVTQ1JJUFRJT04oJnF1b3Q7TVRLIEFVWEFEQyBEZXZp Y2UgRHJpdmVyJnF1b3Q7KTsNCitNT0RVTEVfTElDRU5TRSgmcXVvdDtHUEwgdjImcXVvdDspOw0K LS0gDQoxLjcuOS41DQoNCjwvcHJlPjwhLS10eXBlOnRleHQtLT48IS0tey0tPjxwcmU+KioqKioq KioqKioqKiBFbWFpbCBDb25maWRlbnRpYWxpdHkgTm90aWNlDQogKioqKioqKioqKioqKioqKioq KioKVGhlIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBpbiB0aGlzIGUtbWFpbCBtZXNzYWdlIChpbmNs dWRpbmcgYW55IAphdHRhY2htZW50cykgbWF5IGJlIGNvbmZpZGVudGlhbCwgcHJvcHJpZXRhcnks IHByaXZpbGVnZWQsIG9yIG90aGVyd2lzZQpleGVtcHQgZnJvbSBkaXNjbG9zdXJlIHVuZGVyIGFw cGxpY2FibGUgbGF3cy4gSXQgaXMgaW50ZW5kZWQgdG8gYmUgCmNvbnZleWVkIG9ubHkgdG8gdGhl IGRlc2lnbmF0ZWQgcmVjaXBpZW50KHMpLiBBbnkgdXNlLCBkaXNzZW1pbmF0aW9uLCAKZGlzdHJp YnV0aW9uLCBwcmludGluZywgcmV0YWluaW5nIG9yIGNvcHlpbmcgb2YgdGhpcyBlLW1haWwgKGlu Y2x1ZGluZyBpdHMgCmF0dGFjaG1lbnRzKSBieSB1bmludGVuZGVkIHJlY2lwaWVudChzKSBpcyBz dHJpY3RseSBwcm9oaWJpdGVkIGFuZCBtYXkgCmJlIHVubGF3ZnVsLiBJZiB5b3UgYXJlIG5vdCBh biBpbnRlbmRlZCByZWNpcGllbnQgb2YgdGhpcyBlLW1haWwsIG9yIGJlbGlldmUNCiAKdGhhdCB5 b3UgaGF2ZSByZWNlaXZlZCB0aGlzIGUtbWFpbCBpbiBlcnJvciwgcGxlYXNlIG5vdGlmeSB0aGUg c2VuZGVyIAppbW1lZGlhdGVseSAoYnkgcmVwbHlpbmcgdG8gdGhpcyBlLW1haWwpLCBkZWxldGUg YW55IGFuZCBhbGwgY29waWVzIG9mIAp0aGlzIGUtbWFpbCAoaW5jbHVkaW5nIGFueSBhdHRhY2ht ZW50cykgZnJvbSB5b3VyIHN5c3RlbSwgYW5kIGRvIG5vdApkaXNjbG9zZSB0aGUgY29udGVudCBv ZiB0aGlzIGUtbWFpbCB0byBhbnkgb3RoZXIgcGVyc29uLiBUaGFuaw0KIHlvdSE8L3ByZT48IS0t fS0t --__=_Part_Boundary_005_949221731.443340628 Content-Type: text/plain From: Zhiyong Tao Add Mediatek auxadc driver in iio. It will register a device in iio and support iio. So thermal can read auxadc channel to sample data by iio device. It is tested successfully on mt2701 platform. Mt8173 platform is not tested. But the expectation is compatible. Signed-off-by: Zhiyong Tao --- drivers/iio/adc/Kconfig | 11 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/mt65xx_auxadc.c | 269 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 281 insertions(+) create mode 100644 drivers/iio/adc/mt65xx_auxadc.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 25378c5..7684849 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -315,6 +315,17 @@ config MEN_Z188_ADC This driver can also be built as a module. If so, the module will be called men_z188_adc. +config MEDIATEK_MT65XX_AUXADC + tristate "MediaTek AUXADC driver" + help + Say yes here to enable support for MediaTek mt65xx AUXADC. + + The driver supports immediate mode operation to read from one of sixteen + channels (external or internal). + + This driver can also be built as a module. If so, the module will be + called mt65xx_auxadc. + config MXS_LRADC tristate "Freescale i.MX23/i.MX28 LRADC" depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 38638d4..bc62209 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_MAX1363) += max1363.o obj-$(CONFIG_MCP320X) += mcp320x.o obj-$(CONFIG_MCP3422) += mcp3422.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o +obj-$(CONFIG_MEDIATEK_MT65XX_AUXADC) += mt65xx_auxadc.o obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_NAU7802) += nau7802.o obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o diff --git a/drivers/iio/adc/mt65xx_auxadc.c b/drivers/iio/adc/mt65xx_auxadc.c new file mode 100644 index 0000000..b3c059c --- /dev/null +++ b/drivers/iio/adc/mt65xx_auxadc.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: Zhiyong Tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers define*/ +#define MT65XX_AUXADC_CON0 0x00 +#define MT65XX_AUXADC_CON1 0x04 +#define MT65XX_AUXADC_CON2 0x10 +#define MT65XX_AUXADC_STA BIT(0) + +#define MT65XX_AUXADC_DAT0 0x14 +#define MT65XX_AUXADC_RDY0 BIT(12) + +#define MT65XX_AUXADC_MISC 0x94 +#define MT65XX_AUXADC_PDN_EN BIT(14) + +#define MT65XX_AUXADC_DAT_MASK 0xfff +#define MT65XX_AUXADC_SLEEP_US 1000 +#define MT65XX_AUXADC_TIMEOUT_US 10000 +#define MT65XX_AUXADC_POWER_READY_MS 1 +#define MT65XX_AUXADC_SAMPLE_READY_US 25 + +struct mt65xx_auxadc_device { + void __iomem *reg_base; + struct clk *adc_clk; + struct mutex lock; /*generic mutex for auxadc driver*/ + unsigned int power_ready_ms; + unsigned int sample_ready_us; +}; + +#define MT65xx_AUXADC_CHANNEL(idx) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (idx), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ +} + +static const struct iio_chan_spec mt65xx_auxadc_iio_channels[] = { + MT65xx_AUXADC_CHANNEL(0), + MT65xx_AUXADC_CHANNEL(1), + MT65xx_AUXADC_CHANNEL(2), + MT65xx_AUXADC_CHANNEL(3), + MT65xx_AUXADC_CHANNEL(4), + MT65xx_AUXADC_CHANNEL(5), + MT65xx_AUXADC_CHANNEL(6), + MT65xx_AUXADC_CHANNEL(7), + MT65xx_AUXADC_CHANNEL(8), + MT65xx_AUXADC_CHANNEL(9), + MT65xx_AUXADC_CHANNEL(10), + MT65xx_AUXADC_CHANNEL(11), + MT65xx_AUXADC_CHANNEL(12), + MT65xx_AUXADC_CHANNEL(13), + MT65xx_AUXADC_CHANNEL(14), + MT65xx_AUXADC_CHANNEL(15), +}; + +static int mt65xx_auxadc_read(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + u32 rawdata, val; + void __iomem *reg_channel; + struct mt65xx_auxadc_device *adc_dev = iio_priv(indio_dev); + + reg_channel = adc_dev->reg_base + MT65XX_AUXADC_DAT0 + + chan->channel * 0x04; + + mutex_lock(&adc_dev->lock); + + val = readl(adc_dev->reg_base + MT65XX_AUXADC_CON1); + val &= ~(1 << chan->channel); + writel(val, adc_dev->reg_base + MT65XX_AUXADC_CON1); + + /* read channel and make sure old ready bit ==0 */ + readl_poll_timeout(reg_channel, val, + ((val & MT65XX_AUXADC_RDY0) == 0), + MT65XX_AUXADC_SLEEP_US, + MT65XX_AUXADC_TIMEOUT_US); + + /* set bit to trigger sample */ + val = readl(adc_dev->reg_base + MT65XX_AUXADC_CON1); + val |= 1 << chan->channel; + writel(val, adc_dev->reg_base + MT65XX_AUXADC_CON1); + + /* we must delay here for hardware sample channel data */ + udelay(adc_dev->sample_ready_us); + + /* check MTK_AUXADC_CON2 if auxadc is idle */ + readl_poll_timeout(adc_dev->reg_base + MT65XX_AUXADC_CON2, val, + ((val & MT65XX_AUXADC_STA) == 0), + MT65XX_AUXADC_SLEEP_US, + MT65XX_AUXADC_TIMEOUT_US); + + /* read channel and make sure ready bit ==1 */ + readl_poll_timeout(reg_channel, val, + ((val & MT65XX_AUXADC_RDY0) == 1), + MT65XX_AUXADC_SLEEP_US, + MT65XX_AUXADC_TIMEOUT_US); + + /* read data */ + rawdata = readl(reg_channel) & MT65XX_AUXADC_DAT_MASK; + + mutex_unlock(&adc_dev->lock); + + return rawdata; +} + +static int mt65xx_auxadc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long info) +{ + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + *val = mt65xx_auxadc_read(indio_dev, chan); + ret = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: + *val = 1; + ret = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_OFFSET: + *val = 0; + ret = IIO_VAL_INT; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static const struct iio_info mt65xx_auxadc_info = { + .driver_module = THIS_MODULE, + .read_raw = &mt65xx_auxadc_read_raw, +}; + +static int mt65xx_auxadc_probe(struct platform_device *pdev) +{ + struct mt65xx_auxadc_device *adc_dev; + unsigned long adc_clk_rate; + struct resource *res; + struct iio_dev *indio_dev; + int ret; + u32 val; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); + if (!indio_dev) + return -ENOMEM; + + adc_dev = iio_priv(indio_dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->name = dev_name(&pdev->dev); + indio_dev->info = &mt65xx_auxadc_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = mt65xx_auxadc_iio_channels; + indio_dev->num_channels = ARRAY_SIZE(mt65xx_auxadc_iio_channels); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(adc_dev->reg_base)) { + dev_err(&pdev->dev, "failed to get auxadc base address.\n"); + return PTR_ERR(adc_dev->reg_base); + } + + adc_dev->adc_clk = devm_clk_get(&pdev->dev, "main"); + if (IS_ERR(adc_dev->adc_clk)) { + dev_err(&pdev->dev, "failed to get axuadc clock\n"); + return PTR_ERR(adc_dev->adc_clk); + } + + ret = clk_prepare_enable(adc_dev->adc_clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable auxadc clock\n"); + return ret; + } + + adc_clk_rate = clk_get_rate(adc_dev->adc_clk); + if (!adc_clk_rate) { + dev_err(&pdev->dev, "null clock rate!\n"); + clk_disable_unprepare(adc_dev->adc_clk); + return -EINVAL; + } + + adc_dev->power_ready_ms = MT65XX_AUXADC_POWER_READY_MS; + adc_dev->sample_ready_us = MT65XX_AUXADC_SAMPLE_READY_US; + + mutex_init(&adc_dev->lock); + + val = readl(adc_dev->reg_base + MT65XX_AUXADC_MISC); + val |= MT65XX_AUXADC_PDN_EN; + writel(val, adc_dev->reg_base + MT65XX_AUXADC_MISC); + mdelay(adc_dev->power_ready_ms); + + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "failed to register iio device!\n"); + return ret; + } + + platform_set_drvdata(pdev, indio_dev); + + return 0; +} + +static int mt65xx_auxadc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct mt65xx_auxadc_device *adc_dev = iio_priv(indio_dev); + u32 val; + + iio_device_unregister(indio_dev); + + val = readl(adc_dev->reg_base + MT65XX_AUXADC_MISC); + val &= ~MT65XX_AUXADC_PDN_EN; + writel(val, adc_dev->reg_base + MT65XX_AUXADC_MISC); + + clk_disable_unprepare(adc_dev->adc_clk); + + return 0; +} + +static const struct of_device_id mt65xx_auxadc_of_match[] = { + { .compatible = "mediatek,mt2701-auxadc", }, + { .compatible = "mediatek,mt8173-auxadc", }, + { } +}; +MODULE_DEVICE_TABLE(of, mt65xx_auxadc_of_match); + +static struct platform_driver mt65xx_auxadc_driver = { + .driver = { + .name = "mt65xx-auxadc", + .of_match_table = mt65xx_auxadc_of_match, + }, + .probe = mt65xx_auxadc_probe, + .remove = mt65xx_auxadc_remove, +}; +module_platform_driver(mt65xx_auxadc_driver); + +MODULE_AUTHOR("Zhiyong Tao "); +MODULE_DESCRIPTION("MTK AUXADC Device Driver"); +MODULE_LICENSE("GPL v2"); -- 1.7.9.5 --__=_Part_Boundary_005_949221731.443340628-- --__=_Part_Boundary_004_499596275.1659815320--