From mboxrd@z Thu Jan 1 00:00:00 1970 From: jassi brar Subject: Re: [PATCH 2/3] ASoC: AC97: S3C: Add controller driver Date: Tue, 26 Jan 2010 20:03:09 +0900 Message-ID: <1b68c6791001260303m38e6e689p2ee8c2c4c6ac2af3@mail.gmail.com> References: <1264485101-13782-1-git-send-email-jassisinghbrar@gmail.com> <1264485101-13782-2-git-send-email-jassisinghbrar@gmail.com> <20100126102343.GA24843@trinity.fluff.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20100126102343.GA24843@trinity.fluff.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: alsa-devel-bounces@alsa-project.org Errors-To: alsa-devel-bounces@alsa-project.org To: Ben Dooks Cc: alsa-devel@alsa-project.org, linux-samsung-soc@vger.kernel.org, Jassi Brar , broonie@opensource.wolfsonmicro.com, linux-arm-kernel@lists.infradead.org, lrg@slimlogic.co.uk List-Id: linux-samsung-soc@vger.kernel.org T24gVHVlLCBKYW4gMjYsIDIwMTAgYXQgNzoyMyBQTSwgQmVuIERvb2tzIDxiZW4tbGludXhAZmx1 ZmYub3JnPiB3cm90ZToKPiBPbiBUdWUsIEphbiAyNiwgMjAxMCBhdCAwMjo1MTo0MFBNICswOTAw LCBqYXNzaXNpbmdoYnJhckBnbWFpbC5jb20gd3JvdGU6Cj4+IEZyb206IEphc3NpIEJyYXIgPGph c3NpLmJyYXJAc2Ftc3VuZy5jb20+Cj4+Cj4+IEFkZCB0aGUgQUM5NyBjb250cm9sbGVyIGRyaXZl ciBmb3IgU2Ftc3VuZyBTb0NzIHRoYXQgaGF2ZSBvbmUuCj4+Cj4+IFNpZ25lZC1vZmYtYnk6IEph c3NpIEJyYXIgPGphc3NpLmJyYXJAc2Ftc3VuZy5jb20+Cj4+IC0tLQo+PiDCoHNvdW5kL3NvYy9z M2MyNHh4L0tjb25maWcgwqAgwqB8IMKgIMKgNiArLQo+PiDCoHNvdW5kL3NvYy9zM2MyNHh4L01h a2VmaWxlIMKgIHwgwqAgwqAzICstCj4+IMKgc291bmQvc29jL3MzYzI0eHgvczNjLWFjOTcuYyB8 IMKgNTM1ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+PiDCoHNv dW5kL3NvYy9zM2MyNHh4L3MzYy1hYzk3LmggfCDCoCAyMyArKwo+PiDCoDQgZmlsZXMgY2hhbmdl ZCwgNTY1IGluc2VydGlvbnMoKyksIDIgZGVsZXRpb25zKC0pCj4+IMKgY3JlYXRlIG1vZGUgMTAw NjQ0IHNvdW5kL3NvYy9zM2MyNHh4L3MzYy1hYzk3LmMKPj4gwqBjcmVhdGUgbW9kZSAxMDA2NDQg c291bmQvc29jL3MzYzI0eHgvczNjLWFjOTcuaAo+Pgo+PiBkaWZmIC0tZ2l0IGEvc291bmQvc29j L3MzYzI0eHgvS2NvbmZpZyBiL3NvdW5kL3NvYy9zM2MyNHh4L0tjb25maWcKPj4gaW5kZXggYjQ4 OWYxYS4uYWQzNjkwZSAxMDA2NDQKPj4gLS0tIGEvc291bmQvc29jL3MzYzI0eHgvS2NvbmZpZwo+ PiArKysgYi9zb3VuZC9zb2MvczNjMjR4eC9LY29uZmlnCj4+IEBAIC0zMiw3ICszMiwxMSBAQCBj b25maWcgU05EX1MzQzI0NDNfU09DX0FDOTcKPj4gwqAgwqAgwqAgc2VsZWN0IFMzQzI0MTBfRE1B Cj4+IMKgIMKgIMKgIHNlbGVjdCBBQzk3X0JVUwo+PiDCoCDCoCDCoCBzZWxlY3QgU05EX1NPQ19B Qzk3X0JVUwo+PiAtCj4+ICsKPj4gK2NvbmZpZyBTTkRfUzNDX1NPQ19BQzk3Cj4+ICsgwqAgwqAg dHJpc3RhdGUKPj4gKyDCoCDCoCBzZWxlY3QgU05EX1NPQ19BQzk3X0JVUwo+PiArCj4+IMKgY29u ZmlnIFNORF9TM0MyNFhYX1NPQ19ORU8xOTczX1dNODc1Mwo+PiDCoCDCoCDCoCB0cmlzdGF0ZSAi U29DIEkyUyBBdWRpbyBzdXBwb3J0IGZvciBORU8xOTczIC0gV004NzUzIgo+PiDCoCDCoCDCoCBk ZXBlbmRzIG9uIFNORF9TM0MyNFhYX1NPQyAmJiBNQUNIX05FTzE5NzNfR1RBMDEKPj4gZGlmZiAt LWdpdCBhL3NvdW5kL3NvYy9zM2MyNHh4L01ha2VmaWxlIGIvc291bmQvc29jL3MzYzI0eHgvTWFr ZWZpbGUKPj4gaW5kZXggYjc0NDY1Ny4uYjc0MTFiZCAxMDA2NDQKPj4gLS0tIGEvc291bmQvc29j L3MzYzI0eHgvTWFrZWZpbGUKPj4gKysrIGIvc291bmQvc29jL3MzYzI0eHgvTWFrZWZpbGUKPj4g QEAgLTQsMTIgKzQsMTQgQEAgc25kLXNvYy1zM2MyNHh4LWkycy1vYmpzIDo9IHMzYzI0eHgtaTJz Lm8KPj4gwqBzbmQtc29jLXMzYzI0MTItaTJzLW9ianMgOj0gczNjMjQxMi1pMnMubwo+PiDCoHNu ZC1zb2MtczNjNjR4eC1pMnMtb2JqcyA6PSBzM2M2NHh4LWkycy5vCj4+IMKgc25kLXNvYy1zM2My NDQzLWFjOTctb2JqcyA6PSBzM2MyNDQzLWFjOTcubwo+PiArc25kLXNvYy1zM2MtYWM5Ny1vYmpz IDo9IHMzYy1hYzk3Lm8KPj4gwqBzbmQtc29jLXMzYy1pMnMtdjItb2JqcyA6PSBzM2MtaTJzLXYy Lm8KPj4gwqBzbmQtc29jLXMzYy1wY20tb2JqcyA6PSBzM2MtcGNtLm8KPj4KPj4gwqBvYmotJChD T05GSUdfU05EX1MzQzI0WFhfU09DKSArPSBzbmQtc29jLXMzYzI0eHgubwo+PiDCoG9iai0kKENP TkZJR19TTkRfUzNDMjRYWF9TT0NfSTJTKSArPSBzbmQtc29jLXMzYzI0eHgtaTJzLm8KPj4gwqBv YmotJChDT05GSUdfU05EX1MzQzI0NDNfU09DX0FDOTcpICs9IHNuZC1zb2MtczNjMjQ0My1hYzk3 Lm8KPj4gK29iai0kKENPTkZJR19TTkRfUzNDX1NPQ19BQzk3KSArPSBzbmQtc29jLXMzYy1hYzk3 Lm8KPj4gwqBvYmotJChDT05GSUdfU05EX1MzQzI0MTJfU09DX0kyUykgKz0gc25kLXNvYy1zM2My NDEyLWkycy5vCj4+IMKgb2JqLSQoQ09ORklHX1NORF9TM0M2NFhYX1NPQ19JMlMpICs9IHNuZC1z b2MtczNjNjR4eC1pMnMubwo+PiDCoG9iai0kKENPTkZJR19TTkRfUzNDX0kyU1YyX1NPQykgKz0g c25kLXNvYy1zM2MtaTJzLXYyLm8KPj4gQEAgLTM3LDQgKzM5LDMgQEAgb2JqLSQoQ09ORklHX1NO RF9TM0MyNFhYX1NPQ19TSU1URUMpICs9IHNuZC1zb2MtczNjMjR4eC1zaW10ZWMubwo+PiDCoG9i ai0kKENPTkZJR19TTkRfUzNDMjRYWF9TT0NfU0lNVEVDX0hFUk1FUykgKz0gc25kLXNvYy1zM2My NHh4LXNpbXRlYy1oZXJtZXMubwo+PiDCoG9iai0kKENPTkZJR19TTkRfUzNDMjRYWF9TT0NfU0lN VEVDX1RMVjMyMEFJQzIzKSArPSBzbmQtc29jLXMzYzI0eHgtc2ltdGVjLXRsdjMyMGFpYzIzLm8K Pj4gwqBvYmotJChDT05GSUdfU05EX1MzQzY0WFhfU09DX1dNODU4MCkgKz0gc25kLXNvYy1zbWRr NjR4eC13bTg1ODAubwo+PiAtCj4+IGRpZmYgLS1naXQgYS9zb3VuZC9zb2MvczNjMjR4eC9zM2Mt YWM5Ny5jIGIvc291bmQvc29jL3MzYzI0eHgvczNjLWFjOTcuYwo+PiBuZXcgZmlsZSBtb2RlIDEw MDY0NAo+PiBpbmRleCAwMDAwMDAwLi5hY2I4ZjUxCj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIv c291bmQvc29jL3MzYzI0eHgvczNjLWFjOTcuYwo+PiBAQCAtMCwwICsxLDUzNSBAQAo+PiArLyog c291bmQvc29jL3MzYzI0eHgvczNjLWFjOTcuYwo+PiArICoKPj4gKyAqIEFMU0EgU29DIEF1ZGlv IExheWVyIC0gUzNDIEFDOTcgQ29udHJvbGxlciBkcml2ZXIKPj4gKyAqIMKgIEV2b2x2ZWQgZnJv bSBzM2MyNDQzLWFjOTcuYwo+PiArICoKPj4gKyAqIENvcHlyaWdodCAoYykgMjAxMCBTYW1zdW5n IEVsZWN0cm9uaWNzIENvLiBMdGQKPj4gKyAqIMKgIEF1dGhvcjogSmFzd2luZGVyIFNpbmdoIDxq YXNzaS5icmFyQHNhbXN1bmcuY29tPgo+PiArICogwqAgQ3JlZGl0czogR3JhZW1lIEdyZWdvcnks IFNlYW4gQ2hvaQo+PiArICoKPj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5 b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cj4+ICsgKiBpdCB1bmRlciB0aGUg dGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcwo+PiAr ICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCj4+ICsgKi8KPj4g Kwo+PiArI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KPj4gKyNpbmNsdWRlIDxsaW51eC9pby5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+ Cj4+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4+ICsKPj4gKyNpbmNsdWRlIDxzb3VuZC9zb2Mu aD4KPj4gKwo+PiArI2luY2x1ZGUgPHBsYXQvcmVncy1hYzk3Lmg+Cj4+ICsjaW5jbHVkZSA8bWFj aC9kbWEuaD4KPj4gKyNpbmNsdWRlIDxwbGF0L2F1ZGlvLmg+Cj4+ICsKPj4gKyNpbmNsdWRlICJz M2MtZG1hLmgiCj4+ICsjaW5jbHVkZSAiczNjLWFjOTcuaCIKPj4gKwo+PiArI2RlZmluZSBBQ19D TURfQUREUih4KSAoeCA8PCAxNikKPj4gKyNkZWZpbmUgQUNfQ01EX0RBVEEoeCkgKHggJiAweGZm ZmYpCj4+ICsKPj4gK3N0cnVjdCBzM2NfYWM5N19pbmZvIHsKPj4gKyDCoCDCoCB1bnNpZ25lZCDC oCDCoCDCoCDCoCDCoCBzdGF0ZTsKPj4gKyDCoCDCoCBzdHJ1Y3QgY2xrIMKgIMKgIMKgIMKgICph Yzk3X2NsazsKPj4gKyDCoCDCoCB2b2lkIF9faW9tZW0gwqAgwqAgwqAgKnJlZ3M7Cj4+ICsgwqAg wqAgc3RydWN0IG11dGV4IMKgIMKgIMKgIGxvY2s7Cj4+ICsgwqAgwqAgc3RydWN0IGNvbXBsZXRp b24gwqBkb25lOwo+PiArfTsKPj4gK3N0YXRpYyBzdHJ1Y3QgczNjX2FjOTdfaW5mbyBzM2NfYWM5 NzsKPj4gKwo+PiArc3RhdGljIHN0cnVjdCBzM2MyNDEwX2RtYV9jbGllbnQgczNjX2RtYV9jbGll bnRfb3V0ID0gewo+PiArIMKgIMKgIC5uYW1lID0gIkFDOTcgUENNT3V0Igo+PiArfTsKPj4gKwo+ PiArc3RhdGljIHN0cnVjdCBzM2MyNDEwX2RtYV9jbGllbnQgczNjX2RtYV9jbGllbnRfaW4gPSB7 Cj4+ICsgwqAgwqAgLm5hbWUgPSAiQUM5NyBQQ01JbiIKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBz dHJ1Y3QgczNjMjQxMF9kbWFfY2xpZW50IHMzY19kbWFfY2xpZW50X21pY2luID0gewo+PiArIMKg IMKgIC5uYW1lID0gIkFDOTcgTWljSW4iCj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHMz Y19kbWFfcGFyYW1zIHMzY19hYzk3X3BjbV9vdXQgPSB7Cj4+ICsgwqAgwqAgLmNsaWVudCDCoCDC oCDCoCDCoCA9ICZzM2NfZG1hX2NsaWVudF9vdXQsCj4+ICsgwqAgwqAgLmRtYV9zaXplIMKgIMKg IMKgID0gNCwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgczNjX2RtYV9wYXJhbXMgczNj X2FjOTdfcGNtX2luID0gewo+PiArIMKgIMKgIC5jbGllbnQgwqAgwqAgwqAgwqAgPSAmczNjX2Rt YV9jbGllbnRfaW4sCj4+ICsgwqAgwqAgLmRtYV9zaXplIMKgIMKgIMKgID0gNCwKPj4gK307Cj4+ ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgczNjX2RtYV9wYXJhbXMgczNjX2FjOTdfbWljX2luID0gewo+ PiArIMKgIMKgIC5jbGllbnQgwqAgwqAgwqAgwqAgPSAmczNjX2RtYV9jbGllbnRfbWljaW4sCj4+ ICsgwqAgwqAgLmRtYV9zaXplIMKgIMKgIMKgID0gNCwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyB2 b2lkIHMzY19hYzk3X2NvbGRfcmVzZXQoc3RydWN0IHNuZF9hYzk3ICphYzk3KQo+PiArewo+PiAr IMKgIMKgIHdyaXRlbChTM0NfQUM5N19HTEJDVFJMX0NPTERSRVNFVCwKPj4gKyDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCBzM2NfYWM5Ny5yZWdzICsgUzNDX0FDOTdfR0xCQ1RSTCk7Cj4+ ICsgwqAgwqAgbXNsZWVwKDEpOwo+PiArCj4+ICsgwqAgwqAgd3JpdGVsKDAsIHMzY19hYzk3LnJl Z3MgKyBTM0NfQUM5N19HTEJDVFJMKTsKPj4gKyDCoCDCoCBtc2xlZXAoMSk7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyB2b2lkIHMzY19hYzk3X3dhcm1fcmVzZXQoc3RydWN0IHNuZF9hYzk3ICphYzk3 KQo+PiArewo+PiArIMKgIMKgIHdyaXRlbChTM0NfQUM5N19HTEJDVFJMX1dBUk1SRVNFVCwgczNj X2FjOTcucmVncyArIFMzQ19BQzk3X0dMQkNUUkwpOwo+PiArIMKgIMKgIG1zbGVlcCgxKTsKPj4g Kwo+PiArIMKgIMKgIHdyaXRlbCgwLCBzM2NfYWM5Ny5yZWdzICsgUzNDX0FDOTdfR0xCQ1RSTCk7 Cj4+ICsgwqAgwqAgbXNsZWVwKDEpOwo+PiArfQo+Cj4gSXQgd291bGQgYmUgbmljZSB0IG9zZWUg c29tZXRoaW5nIHRvIGNvbnZlcnQgYSAnc3RydWN0IHNuZF9hYzk3JyB0byBhCj4gJ3N0cnVjdCBz M2NfYWM5N19pbmZvJyBhcyB0aGlzIGlzIGJlaW5nIHBhc3NlZCBpbiB0byBtb3N0IHBsYWNlIGFu ZAo+IHdvdWxkIGFsc28gaGVscCBpZiB0aGVyZSBpcyBldmVyID4xIGJsb2NrLgpvaywgd2lsbCBm aW5kIGEgd2F5IHRvIGRvIHRoYXQuCgo+PiArc3RhdGljIHZvaWQgczNjX2FjOTdfYWN0aXZhdGUo c3RydWN0IHNuZF9hYzk3ICphYzk3KQo+PiArewo+PiArIMKgIMKgIHUzMiBhY19nbGJjdHJsLCBz dGF0Owo+PiArCj4+ICsgwqAgwqAgc3RhdCA9IHJlYWRsKHMzY19hYzk3LnJlZ3MgKyBTM0NfQUM5 N19HTEJTVEFUKSAmIDB4NzsKPj4gKyDCoCDCoCBzd2l0Y2ggKHN0YXQpIHsKPj4gKyDCoCDCoCBj YXNlIFMzQ19BQzk3X0dMQlNUQVRfTUFJTlNUQVRFX0FDVElWRToKPj4gKyDCoCDCoCDCoCDCoCDC oCDCoCByZXR1cm47Cj4+ICsgwqAgwqAgY2FzZSBTM0NfQUM5N19HTEJTVEFUX01BSU5TVEFURV9S RUFEWToKPj4gKyDCoCDCoCBjYXNlIFMzQ19BQzk3X0dMQlNUQVRfTUFJTlNUQVRFX0lOSVQ6Cj4+ ICsgwqAgwqAgwqAgwqAgwqAgwqAgYnJlYWs7Cj4+ICsgwqAgwqAgZGVmYXVsdDoKPj4gKyDCoCDC oCDCoCDCoCDCoCDCoCBzM2NfYWM5N19jb2xkX3Jlc2V0KGFjOTcpOwo+PiArIMKgIMKgIMKgIMKg IMKgIMKgIHMzY19hYzk3X3dhcm1fcmVzZXQoYWM5Nyk7Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAg YnJlYWs7Cj4+ICsgwqAgwqAgfQo+PiArCj4+ICsgwqAgwqAgYWNfZ2xiY3RybCA9IHJlYWRsKHMz Y19hYzk3LnJlZ3MgKyBTM0NfQUM5N19HTEJDVFJMKTsKPj4gKyDCoCDCoCBhY19nbGJjdHJsID0g UzNDX0FDOTdfR0xCQ1RSTF9BQ0xJTktPTjsKPj4gKyDCoCDCoCB3cml0ZWwoYWNfZ2xiY3RybCwg czNjX2FjOTcucmVncyArIFMzQ19BQzk3X0dMQkNUUkwpOwo+PiArIMKgIMKgIG1zbGVlcCgxKTsK Pj4gKwo+PiArIMKgIMKgIGFjX2dsYmN0cmwgfD0gUzNDX0FDOTdfR0xCQ1RSTF9UUkFOU0ZFUkRB VEFFTkFCTEU7Cj4+ICsgwqAgwqAgd3JpdGVsKGFjX2dsYmN0cmwsIHMzY19hYzk3LnJlZ3MgKyBT M0NfQUM5N19HTEJDVFJMKTsKPj4gKyDCoCDCoCBtc2xlZXAoMSk7Cj4+ICsKPj4gKyDCoCDCoCBh Y19nbGJjdHJsID0gcmVhZGwoczNjX2FjOTcucmVncyArIFMzQ19BQzk3X0dMQkNUUkwpOwo+PiAr IMKgIMKgIGFjX2dsYmN0cmwgfD0gUzNDX0FDOTdfR0xCQ1RSTF9DT0RFQ1JFQURZSUU7Cj4+ICsg wqAgwqAgd3JpdGVsKGFjX2dsYmN0cmwsIHMzY19hYzk3LnJlZ3MgKyBTM0NfQUM5N19HTEJDVFJM KTsKPj4gKwo+PiArIMKgIMKgIElOSVRfQ09NUExFVElPTihzM2NfYWM5Ny5kb25lKTsKPj4gKwo+ PiArIMKgIMKgIGlmICghd2FpdF9mb3JfY29tcGxldGlvbl90aW1lb3V0KCZzM2NfYWM5Ny5kb25l LCBIWikpCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgcHJpbnRrKEtFUk5fRVJSICJBQzk3OiBVbmFi bGUgdG8gYWN0aXZhdGUhIik7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB1bnNpZ25lZCBzaG9ydCBz M2NfYWM5N19yZWFkKHN0cnVjdCBzbmRfYWM5NyAqYWM5NywKPj4gKyDCoCDCoCB1bnNpZ25lZCBz aG9ydCByZWcpCj4+ICt7Cj4+ICsgwqAgwqAgdTMyIGFjX2dsYmN0cmwsIGFjX2NvZGVjX2NtZDsK Pj4gKyDCoCDCoCB1MzIgc3RhdCwgYWRkciwgZGF0YTsKPj4gKwo+PiArIMKgIMKgIG11dGV4X2xv Y2soJnMzY19hYzk3LmxvY2spOwo+PiArCj4+ICsgwqAgwqAgczNjX2FjOTdfYWN0aXZhdGUoYWM5 Nyk7Cj4+ICsKPj4gKyDCoCDCoCBhY19jb2RlY19jbWQgPSByZWFkbChzM2NfYWM5Ny5yZWdzICsg UzNDX0FDOTdfQ09ERUNfQ01EKTsKPj4gKyDCoCDCoCBhY19jb2RlY19jbWQgPSBTM0NfQUM5N19D T0RFQ19DTURfUkVBRCB8IEFDX0NNRF9BRERSKHJlZyk7Cj4+ICsgwqAgwqAgd3JpdGVsKGFjX2Nv ZGVjX2NtZCwgczNjX2FjOTcucmVncyArIFMzQ19BQzk3X0NPREVDX0NNRCk7Cj4+ICsKPj4gKyDC oCDCoCB1ZGVsYXkoNTApOwo+PiArCj4+ICsgwqAgwqAgYWNfZ2xiY3RybCA9IHJlYWRsKHMzY19h Yzk3LnJlZ3MgKyBTM0NfQUM5N19HTEJDVFJMKTsKPj4gKyDCoCDCoCBhY19nbGJjdHJsIHw9IFMz Q19BQzk3X0dMQkNUUkxfQ09ERUNSRUFEWUlFOwo+PiArIMKgIMKgIHdyaXRlbChhY19nbGJjdHJs LCBzM2NfYWM5Ny5yZWdzICsgUzNDX0FDOTdfR0xCQ1RSTCk7Cj4+ICsKPj4gKyDCoCDCoCBJTklU X0NPTVBMRVRJT04oczNjX2FjOTcuZG9uZSk7Cj4+ICsKPj4gKyDCoCDCoCBpZiAoIXdhaXRfZm9y X2NvbXBsZXRpb25fdGltZW91dCgmczNjX2FjOTcuZG9uZSwgSFopKQo+PiArIMKgIMKgIMKgIMKg IMKgIMKgIHByaW50ayhLRVJOX0VSUiAiQUM5NzogVW5hYmxlIHRvIHJlYWQhIik7Cj4+ICsKPj4g KyDCoCDCoCBzdGF0ID0gcmVhZGwoczNjX2FjOTcucmVncyArIFMzQ19BQzk3X1NUQVQpOwo+PiAr IMKgIMKgIGFkZHIgPSAoc3RhdCA+PiAxNikgJiAweDdmOwo+PiArIMKgIMKgIGRhdGEgPSAoc3Rh dCAmIDB4ZmZmZik7Cj4+ICsKPj4gKyDCoCDCoCBpZiAoYWRkciAhPSByZWcpCj4+ICsgwqAgwqAg wqAgwqAgwqAgwqAgcHJpbnRrKEtFUk5fRVJSICJzM2MtYWM5NzogcmVxIGFkZHIgPSAlMDJ4LCIK Pj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAiIHJlcCBhZGRy ID0gJTAyeFxuIiwgcmVnLCBhZGRyKTsKPj4gKwo+PiArIMKgIMKgIG11dGV4X3VubG9jaygmczNj X2FjOTcubG9jayk7Cj4+ICsKPj4gKyDCoCDCoCByZXR1cm4gKHVuc2lnbmVkIHNob3J0KWRhdGE7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHMzY19hYzk3X3dyaXRlKHN0cnVjdCBzbmRfYWM5 NyAqYWM5NywgdW5zaWduZWQgc2hvcnQgcmVnLAo+PiArIMKgIMKgIHVuc2lnbmVkIHNob3J0IHZh bCkKPj4gK3sKPj4gKyDCoCDCoCB1MzIgYWNfZ2xiY3RybCwgYWNfY29kZWNfY21kOwo+PiArCj4+ ICsgwqAgwqAgbXV0ZXhfbG9jaygmczNjX2FjOTcubG9jayk7Cj4+ICsKPj4gKyDCoCDCoCBzM2Nf YWM5N19hY3RpdmF0ZShhYzk3KTsKPj4gKwo+PiArIMKgIMKgIGFjX2NvZGVjX2NtZCA9IHJlYWRs KHMzY19hYzk3LnJlZ3MgKyBTM0NfQUM5N19DT0RFQ19DTUQpOwo+PiArIMKgIMKgIGFjX2NvZGVj X2NtZCA9IEFDX0NNRF9BRERSKHJlZykgfCBBQ19DTURfREFUQSh2YWwpOwo+PiArIMKgIMKgIHdy aXRlbChhY19jb2RlY19jbWQsIHMzY19hYzk3LnJlZ3MgKyBTM0NfQUM5N19DT0RFQ19DTUQpOwo+ PiArCj4+ICsgwqAgwqAgdWRlbGF5KDUwKTsKPj4gKwo+PiArIMKgIMKgIGFjX2dsYmN0cmwgPSBy ZWFkbChzM2NfYWM5Ny5yZWdzICsgUzNDX0FDOTdfR0xCQ1RSTCk7Cj4+ICsgwqAgwqAgYWNfZ2xi Y3RybCB8PSBTM0NfQUM5N19HTEJDVFJMX0NPREVDUkVBRFlJRTsKPj4gKyDCoCDCoCB3cml0ZWwo YWNfZ2xiY3RybCwgczNjX2FjOTcucmVncyArIFMzQ19BQzk3X0dMQkNUUkwpOwo+PiArCj4+ICsg wqAgwqAgSU5JVF9DT01QTEVUSU9OKHMzY19hYzk3LmRvbmUpOwo+PiArCj4+ICsgwqAgwqAgaWYg KCF3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoJnMzY19hYzk3LmRvbmUsIEhaKSkKPj4gKyDC oCDCoCDCoCDCoCDCoCDCoCBwcmludGsoS0VSTl9FUlIgIkFDOTc6IFVuYWJsZSB0byB3cml0ZSEi KTsKPj4gKwo+PiArIMKgIMKgIGFjX2NvZGVjX2NtZCA9IHJlYWRsKHMzY19hYzk3LnJlZ3MgKyBT M0NfQUM5N19DT0RFQ19DTUQpOwo+PiArIMKgIMKgIGFjX2NvZGVjX2NtZCB8PSBTM0NfQUM5N19D T0RFQ19DTURfUkVBRDsKPj4gKyDCoCDCoCB3cml0ZWwoYWNfY29kZWNfY21kLCBzM2NfYWM5Ny5y ZWdzICsgUzNDX0FDOTdfQ09ERUNfQ01EKTsKPj4gKwo+PiArIMKgIMKgIG11dGV4X3VubG9jaygm czNjX2FjOTcubG9jayk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBzM2NfYWM5 N19pcnEoaW50IGlycSwgdm9pZCAqZGV2X2lkKQo+PiArewo+PiArIMKgIMKgIHUzMiBhY19nbGJj dHJsLCBhY19nbGJzdGF0Owo+PiArCj4+ICsgwqAgwqAgYWNfZ2xic3RhdCA9IHJlYWRsKHMzY19h Yzk3LnJlZ3MgKyBTM0NfQUM5N19HTEJTVEFUKTsKPj4gKwo+PiArIMKgIMKgIGlmIChhY19nbGJz dGF0ICYgUzNDX0FDOTdfR0xCU1RBVF9DT0RFQ1JFQURZKSB7Cj4+ICsKPj4gKyDCoCDCoCDCoCDC oCDCoCDCoCBhY19nbGJjdHJsID0gcmVhZGwoczNjX2FjOTcucmVncyArIFMzQ19BQzk3X0dMQkNU UkwpOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGFjX2dsYmN0cmwgJj0gflMzQ19BQzk3X0dMQkNU UkxfQ09ERUNSRUFEWUlFOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIHdyaXRlbChhY19nbGJjdHJs LCBzM2NfYWM5Ny5yZWdzICsgUzNDX0FDOTdfR0xCQ1RSTCk7Cj4+ICsKPj4gKyDCoCDCoCDCoCDC oCDCoCDCoCBhY19nbGJjdHJsID0gcmVhZGwoczNjX2FjOTcucmVncyArIFMzQ19BQzk3X0dMQkNU UkwpOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGFjX2dsYmN0cmwgfD0gKDE8PDMwKTsgLyogQ2xl YXIgaW50ZXJydXB0ICovCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgd3JpdGVsKGFjX2dsYmN0cmws IHMzY19hYzk3LnJlZ3MgKyBTM0NfQUM5N19HTEJDVFJMKTsKPj4gKwo+PiArIMKgIMKgIMKgIMKg IMKgIMKgIGNvbXBsZXRlKCZzM2NfYWM5Ny5kb25lKTsKPj4gKyDCoCDCoCB9Cj4+ICsKPj4gKyDC oCDCoCByZXR1cm4gSVJRX0hBTkRMRUQ7Cj4+ICt9Cj4+ICsKPj4gK3N0cnVjdCBzbmRfYWM5N19i dXNfb3BzIHNvY19hYzk3X29wcyA9IHsKPj4gKyDCoCDCoCAucmVhZCDCoCDCoCDCoCA9IHMzY19h Yzk3X3JlYWQsCj4+ICsgwqAgwqAgLndyaXRlIMKgIMKgIMKgPSBzM2NfYWM5N193cml0ZSwKPj4g KyDCoCDCoCAud2FybV9yZXNldCA9IHMzY19hYzk3X3dhcm1fcmVzZXQsCj4+ICsgwqAgwqAgLnJl c2V0IMKgIMKgIMKgPSBzM2NfYWM5N19jb2xkX3Jlc2V0LAo+PiArfTsKPj4gK0VYUE9SVF9TWU1C T0xfR1BMKHNvY19hYzk3X29wcyk7Cj4+ICsKPj4gK3N0YXRpYyBpbnQgczNjX2FjOTdfaHdfcGFy YW1zKHN0cnVjdCBzbmRfcGNtX3N1YnN0cmVhbSAqc3Vic3RyZWFtLAo+PiArIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHN0cnVjdCBzbmRfcGNtX2h3X3BhcmFt cyAqcGFyYW1zLAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIHN0cnVjdCBzbmRfc29jX2RhaSAqZGFpKQo+PiArewo+PiArIMKgIMKgIHN0cnVjdCBzbmRf c29jX3BjbV9ydW50aW1lICpydGQgPSBzdWJzdHJlYW0tPnByaXZhdGVfZGF0YTsKPj4gKyDCoCDC oCBzdHJ1Y3Qgc25kX3NvY19kYWkgKmNwdV9kYWkgPSBydGQtPmRhaS0+Y3B1X2RhaTsKPj4gKwo+ PiArIMKgIMKgIGlmIChzdWJzdHJlYW0tPnN0cmVhbSA9PSBTTkRSVl9QQ01fU1RSRUFNX1BMQVlC QUNLKQo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGNwdV9kYWktPmRtYV9kYXRhID0gJnMzY19hYzk3 X3BjbV9vdXQ7Cj4+ICsgwqAgwqAgZWxzZQo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGNwdV9kYWkt PmRtYV9kYXRhID0gJnMzY19hYzk3X3BjbV9pbjsKPj4gKwo+PiArIMKgIMKgIHJldHVybiAwOwo+ PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHMzY19hYzk3X3RyaWdnZXIoc3RydWN0IHNuZF9wY21f c3Vic3RyZWFtICpzdWJzdHJlYW0sIGludCBjbWQsCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgc3RydWN0IHNuZF9zb2NfZGFpICpkYWkpCj4+ICt7Cj4+ICsg wqAgwqAgdTMyIGFjX2dsYmN0cmw7Cj4+ICsgwqAgwqAgc3RydWN0IHNuZF9zb2NfcGNtX3J1bnRp bWUgKnJ0ZCA9IHN1YnN0cmVhbS0+cHJpdmF0ZV9kYXRhOwo+PiArIMKgIMKgIGludCBjaGFubmVs ID0gKChzdHJ1Y3QgczNjX2RtYV9wYXJhbXMgKikKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBy dGQtPmRhaS0+Y3B1X2RhaS0+ZG1hX2RhdGEpLT5jaGFubmVsOwo+PiArCj4+ICsgwqAgwqAgYWNf Z2xiY3RybCA9IHJlYWRsKHMzY19hYzk3LnJlZ3MgKyBTM0NfQUM5N19HTEJDVFJMKTsKPj4gKyDC oCDCoCBpZiAoc3Vic3RyZWFtLT5zdHJlYW0gPT0gU05EUlZfUENNX1NUUkVBTV9DQVBUVVJFKQo+ PiArIMKgIMKgIMKgIMKgIMKgIMKgIGFjX2dsYmN0cmwgJj0gflMzQ19BQzk3X0dMQkNUUkxfUENN SU5UTV9NQVNLOwo+PiArIMKgIMKgIGVsc2UKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCBhY19nbGJj dHJsICY9IH5TM0NfQUM5N19HTEJDVFJMX1BDTU9VVFRNX01BU0s7Cj4+ICsKPj4gKyDCoCDCoCBz d2l0Y2ggKGNtZCkgewo+PiArIMKgIMKgIGNhc2UgU05EUlZfUENNX1RSSUdHRVJfU1RBUlQ6Cj4+ ICsgwqAgwqAgY2FzZSBTTkRSVl9QQ01fVFJJR0dFUl9SRVNVTUU6Cj4+ICsgwqAgwqAgY2FzZSBT TkRSVl9QQ01fVFJJR0dFUl9QQVVTRV9SRUxFQVNFOgo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGlm IChzdWJzdHJlYW0tPnN0cmVhbSA9PSBTTkRSVl9QQ01fU1RSRUFNX0NBUFRVUkUpCj4+ICsgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYWNfZ2xiY3RybCB8PSBTM0NfQUM5N19HTEJDVFJM X1BDTUlOVE1fRE1BOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGVsc2UKPj4gKyDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCBhY19nbGJjdHJsIHw9IFMzQ19BQzk3X0dMQkNUUkxfUENNT1VU VE1fRE1BOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFrOwo+PiArCj4+ICsgwqAgwqAgY2Fz ZSBTTkRSVl9QQ01fVFJJR0dFUl9TVE9QOgo+PiArIMKgIMKgIGNhc2UgU05EUlZfUENNX1RSSUdH RVJfU1VTUEVORDoKPj4gKyDCoCDCoCBjYXNlIFNORFJWX1BDTV9UUklHR0VSX1BBVVNFX1BVU0g6 Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgYnJlYWs7Cj4+ICsgwqAgwqAgfQo+PiArCj4+ICsgwqAg wqAgd3JpdGVsKGFjX2dsYmN0cmwsIHMzY19hYzk3LnJlZ3MgKyBTM0NfQUM5N19HTEJDVFJMKTsK Pj4gKwo+PiArIMKgIMKgIHMzYzI0MTBfZG1hX2N0cmwoY2hhbm5lbCwgUzNDMjQxMF9ETUFPUF9T VEFSVEVEKTsKPj4gKwo+PiArIMKgIMKgIHJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMg aW50IHMzY19hYzk3X2h3X21pY19wYXJhbXMoc3RydWN0IHNuZF9wY21fc3Vic3RyZWFtICpzdWJz dHJlYW0sCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgc3RydWN0IHNuZF9wY21faHdfcGFyYW1zICpwYXJhbXMsCj4+ICsgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3RydWN0IHNuZF9zb2NfZGFp ICpkYWkpCj4+ICt7Cj4+ICsgwqAgwqAgc3RydWN0IHNuZF9zb2NfcGNtX3J1bnRpbWUgKnJ0ZCA9 IHN1YnN0cmVhbS0+cHJpdmF0ZV9kYXRhOwo+PiArIMKgIMKgIHN0cnVjdCBzbmRfc29jX2RhaSAq Y3B1X2RhaSA9IHJ0ZC0+ZGFpLT5jcHVfZGFpOwo+PiArCj4+ICsgwqAgwqAgaWYgKHN1YnN0cmVh bS0+c3RyZWFtID09IFNORFJWX1BDTV9TVFJFQU1fUExBWUJBQ0spCj4+ICsgwqAgwqAgwqAgwqAg wqAgwqAgcmV0dXJuIC1FTk9ERVY7Cj4+ICsgwqAgwqAgZWxzZQo+PiArIMKgIMKgIMKgIMKgIMKg IMKgIGNwdV9kYWktPmRtYV9kYXRhID0gJnMzY19hYzk3X21pY19pbjsKPj4gKwo+PiArIMKgIMKg IHJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHMzY19hYzk3X21pY190cmlnZ2Vy KHN0cnVjdCBzbmRfcGNtX3N1YnN0cmVhbSAqc3Vic3RyZWFtLAo+PiArIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGludCBjbWQsIHN0cnVjdCBzbmRfc29j X2RhaSAqZGFpKQo+PiArewo+PiArIMKgIMKgIHUzMiBhY19nbGJjdHJsOwo+PiArIMKgIMKgIHN0 cnVjdCBzbmRfc29jX3BjbV9ydW50aW1lICpydGQgPSBzdWJzdHJlYW0tPnByaXZhdGVfZGF0YTsK Pj4gKyDCoCDCoCBpbnQgY2hhbm5lbCA9ICgoc3RydWN0IHMzY19kbWFfcGFyYW1zICopCj4+ICsg wqAgwqAgwqAgwqAgwqAgwqAgwqAgcnRkLT5kYWktPmNwdV9kYWktPmRtYV9kYXRhKS0+Y2hhbm5l bDsKPj4gKwo+PiArIMKgIMKgIGFjX2dsYmN0cmwgPSByZWFkbChzM2NfYWM5Ny5yZWdzICsgUzND X0FDOTdfR0xCQ1RSTCk7Cj4+ICsgwqAgwqAgYWNfZ2xiY3RybCAmPSB+UzNDX0FDOTdfR0xCQ1RS TF9NSUNJTlRNX01BU0s7Cj4+ICsKPj4gKyDCoCDCoCBzd2l0Y2ggKGNtZCkgewo+PiArIMKgIMKg IGNhc2UgU05EUlZfUENNX1RSSUdHRVJfU1RBUlQ6Cj4+ICsgwqAgwqAgY2FzZSBTTkRSVl9QQ01f VFJJR0dFUl9SRVNVTUU6Cj4+ICsgwqAgwqAgY2FzZSBTTkRSVl9QQ01fVFJJR0dFUl9QQVVTRV9S RUxFQVNFOgo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGFjX2dsYmN0cmwgfD0gUzNDX0FDOTdfR0xC Q1RSTF9NSUNJTlRNX0RNQTsKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCBicmVhazsKPj4gKwo+PiAr IMKgIMKgIGNhc2UgU05EUlZfUENNX1RSSUdHRVJfU1RPUDoKPj4gKyDCoCDCoCBjYXNlIFNORFJW X1BDTV9UUklHR0VSX1NVU1BFTkQ6Cj4+ICsgwqAgwqAgY2FzZSBTTkRSVl9QQ01fVFJJR0dFUl9Q QVVTRV9QVVNIOgo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFrOwo+PiArIMKgIMKgIH0KPj4g Kwo+PiArIMKgIMKgIHdyaXRlbChhY19nbGJjdHJsLCBzM2NfYWM5Ny5yZWdzICsgUzNDX0FDOTdf R0xCQ1RSTCk7Cj4+ICsKPj4gKyDCoCDCoCBzM2MyNDEwX2RtYV9jdHJsKGNoYW5uZWwsIFMzQzI0 MTBfRE1BT1BfU1RBUlRFRCk7Cj4+ICsKPj4gKyDCoCDCoCByZXR1cm4gMDsKPj4gK30KPj4gKwo+ PiArI2RlZmluZSBTM0NfQUM5N19SQVRFUyAoU05EUlZfUENNX1JBVEVfODAwMCB8IFNORFJWX1BD TV9SQVRFXzExMDI1IHxcCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgU05EUlZfUENNX1JBVEVfMTYw MDAgfCBTTkRSVl9QQ01fUkFURV8yMjA1MCB8IFwKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCBTTkRS Vl9QQ01fUkFURV8zMjAwMCB8IFNORFJWX1BDTV9SQVRFXzQ0MTAwIHwgXAo+PiArIMKgIMKgIMKg IMKgIMKgIMKgIFNORFJWX1BDTV9SQVRFXzQ4MDAwKQo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHNu ZF9zb2NfZGFpX29wcyBzM2NfYWM5N19kYWlfb3BzID0gewo+PiArIMKgIMKgIC5od19wYXJhbXMg wqAgwqAgwqA9IHMzY19hYzk3X2h3X3BhcmFtcywKPj4gKyDCoCDCoCAudHJpZ2dlciDCoCDCoCDC oCDCoD0gczNjX2FjOTdfdHJpZ2dlciwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3Qgc25k X3NvY19kYWlfb3BzIHMzY19hYzk3X21pY19kYWlfb3BzID0gewo+PiArIMKgIMKgIC5od19wYXJh bXMgwqAgwqAgwqA9IHMzY19hYzk3X2h3X21pY19wYXJhbXMsCj4+ICsgwqAgwqAgLnRyaWdnZXIg wqAgwqAgwqAgwqA9IHMzY19hYzk3X21pY190cmlnZ2VyLAo+PiArfTsKPj4gKwo+PiArc3RydWN0 IHNuZF9zb2NfZGFpIHMzY19hYzk3X2RhaVtdID0gewo+PiArIMKgIMKgIFtTM0NfQUM5N19EQUlf UENNXSA9IHsKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCAubmFtZSA9ICJzM2MtYWM5NyIsCj4+ICsg wqAgwqAgwqAgwqAgwqAgwqAgLmlkID0gUzNDX0FDOTdfREFJX1BDTSwKPj4gKyDCoCDCoCDCoCDC oCDCoCDCoCAuYWM5N19jb250cm9sID0gMSwKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCAucGxheWJh Y2sgPSB7Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLnN0cmVhbV9uYW1lID0g IkFDOTcgUGxheWJhY2siLAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5jaGFu bmVsc19taW4gPSAyLAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5jaGFubmVs c19tYXggPSAyLAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5yYXRlcyA9IFMz Q19BQzk3X1JBVEVTLAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5mb3JtYXRz ID0gU05EUlZfUENNX0ZNVEJJVF9TMTZfTEUsfSwKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCAuY2Fw dHVyZSA9IHsKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAuc3RyZWFtX25hbWUg PSAiQUM5NyBDYXB0dXJlIiwKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAvKiBO T1RFOiBJZiB0aGUgY29kZWMgb3VwdXRzIGp1c3Qgb25lIHNsb3QsCj4+ICsgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAqIGl0ICpzZWVtcyogb3VyIEFDOTcgY29udHJvbGxlciByZWFk cyB0aGUgb25seQo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKiB2YWxpZCBz bG90KGlmIGVpdGhlciAzIG9yIDQpIGZvciBQQ00tSW4uCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAqIEZvciBzdWNoIGNhc2VzLCB3ZSByZWNvcmQgTW9uby4KPj4gKyDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCovCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgLmNoYW5uZWxzX21pbiA9IDEsCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgLmNoYW5uZWxzX21heCA9IDIsCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgLnJhdGVzID0gUzNDX0FDOTdfUkFURVMsCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgLmZvcm1hdHMgPSBTTkRSVl9QQ01fRk1UQklUX1MxNl9MRSx9LAo+PiArIMKgIMKgIMKg IMKgIMKgIMKgIC5vcHMgPSAmczNjX2FjOTdfZGFpX29wcywKPj4gKyDCoCDCoCB9LAo+PiArIMKg IMKgIFtTM0NfQUM5N19EQUlfTUlDXSA9IHsKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCAubmFtZSA9 ICJzM2MtYWM5Ny1taWMiLAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIC5pZCA9IFMzQ19BQzk3X0RB SV9NSUMsCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgLmFjOTdfY29udHJvbCA9IDEsCj4+ICsgwqAg wqAgwqAgwqAgwqAgwqAgLmNhcHR1cmUgPSB7Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgLnN0cmVhbV9uYW1lID0gIkFDOTcgTWljIENhcHR1cmUiLAo+PiArIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIC5jaGFubmVsc19taW4gPSAxLAo+PiArIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIC8qIE5PVEU6IElmIHRoZSBjb2RlYyhsaWtlIFdNOTcxMykgY2FuJ3Qg b3VwdXQganVzdAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKiBvbmUgc2xv dCwgaXQgKnNlZW1zKiBvdXIgQUM5NyBjb250cm9sbGVyIHJlYWRzCj4+ICsgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAqIHR3byBzbG90cyhpZiBvbmUgb2YgdGhlbSBpcyBTbG90LTYp IGZvciBNSUMgYWxzby4KPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCogRm9y IHN1Y2ggY2FzZXMsIHdlIHJlY29yZCBTdGVyZW8uCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAqLwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5jaGFubmVs c19tYXggPSAyLAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5yYXRlcyA9IFMz Q19BQzk3X1JBVEVTLAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5mb3JtYXRz ID0gU05EUlZfUENNX0ZNVEJJVF9TMTZfTEUsfSwKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCAub3Bz ID0gJnMzY19hYzk3X21pY19kYWlfb3BzLAo+PiArIMKgIMKgIH0sCj4+ICt9Owo+PiArRVhQT1JU X1NZTUJPTF9HUEwoczNjX2FjOTdfZGFpKTsKPj4gKwo+PiArc3RhdGljIF9fZGV2aW5pdCBpbnQg czNjX2FjOTdfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPj4gK3sKPj4gKyDC oCDCoCBzdHJ1Y3QgcmVzb3VyY2UgKm1lbV9yZXMsICpkbWF0eF9yZXMsICpkbWFyeF9yZXMsICpk bWFtaWNfcmVzLCAqaXJxX3JlczsKPj4gKyDCoCDCoCBzdHJ1Y3QgczNjX2F1ZGlvX3BkYXRhICph Yzk3X3BkYXRhOwo+PiArIMKgIMKgIGludCByZXQ7Cj4+ICsKPj4gKyDCoCDCoCBhYzk3X3BkYXRh ID0gcGRldi0+ZGV2LnBsYXRmb3JtX2RhdGE7Cj4+ICsgwqAgwqAgaWYgKCFhYzk3X3BkYXRhIHx8 ICFhYzk3X3BkYXRhLT5jZmdfZ3Bpbykgewo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGRldl9lcnIo JnBkZXYtPmRldiwgImNmZ19ncGlvIGNhbGxiYWNrIG5vdCBwcm92aWRlZCFcbiIpOwo+PiArIMKg IMKgIMKgIMKgIMKgIMKgIHJldHVybiAtRUlOVkFMOwo+PiArIMKgIMKgIH0KPj4gKwo+PiArIMKg IMKgIC8qIENoZWNrIGZvciBhdmFpbGFiaWxpdHkgb2YgbmVjZXNzYXJ5IHJlc291cmNlICovCj4+ ICsgwqAgwqAgZG1hdHhfcmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VS Q0VfRE1BLCAwKTsKPj4gKyDCoCDCoCBpZiAoIWRtYXR4X3Jlcykgewo+PiArIMKgIMKgIMKgIMKg IMKgIMKgIGRldl9lcnIoJnBkZXYtPmRldiwgIlVuYWJsZSB0byBnZXQgQUM5Ny1UWCBkbWEgcmVz b3VyY2VcbiIpOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiAtRU5YSU87Cj4+ICsgwqAg wqAgfQo+PiArCj4+ICsgwqAgwqAgZG1hcnhfcmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBk ZXYsIElPUkVTT1VSQ0VfRE1BLCAxKTsKPj4gKyDCoCDCoCBpZiAoIWRtYXJ4X3Jlcykgewo+PiAr IMKgIMKgIMKgIMKgIMKgIMKgIGRldl9lcnIoJnBkZXYtPmRldiwgIlVuYWJsZSB0byBnZXQgQUM5 Ny1SWCBkbWEgcmVzb3VyY2VcbiIpOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiAtRU5Y SU87Cj4+ICsgwqAgwqAgfQo+PiArCj4+ICsgwqAgwqAgZG1hbWljX3JlcyA9IHBsYXRmb3JtX2dl dF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX0RNQSwgMik7Cj4+ICsgwqAgwqAgaWYgKCFkbWFt aWNfcmVzKSB7Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgZGV2X2VycigmcGRldi0+ZGV2LCAiVW5h YmxlIHRvIGdldCBBQzk3LU1JQyBkbWEgcmVzb3VyY2VcbiIpOwo+PiArIMKgIMKgIMKgIMKgIMKg IMKgIHJldHVybiAtRU5YSU87Cj4+ICsgwqAgwqAgfQo+PiArCj4+ICsgwqAgwqAgbWVtX3JlcyA9 IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7Cj4+ICsgwqAg wqAgaWYgKCFtZW1fcmVzKSB7Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgZGV2X2VycigmcGRldi0+ ZGV2LCAiVW5hYmxlIHRvIGdldCByZWdpc3RlciByZXNvdXJjZVxuIik7Cj4+ICsgwqAgwqAgwqAg wqAgwqAgwqAgcmV0dXJuIC1FTlhJTzsKPj4gKyDCoCDCoCB9Cj4+ICsKPj4gKyDCoCDCoCBpcnFf cmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfSVJRLCAwKTsKPj4g KyDCoCDCoCBpZiAoIWlycV9yZXMpIHsKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCBkZXZfZXJyKCZw ZGV2LT5kZXYsICJBQzk3IElSUSBub3QgcHJvdmlkZWQhXG4iKTsKPj4gKyDCoCDCoCDCoCDCoCDC oCDCoCByZXR1cm4gLUVOWElPOwo+PiArIMKgIMKgIH0KPj4gKwo+PiArIMKgIMKgIGlmICghcmVx dWVzdF9tZW1fcmVnaW9uKG1lbV9yZXMtPnN0YXJ0LAo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJlc291cmNlX3NpemUobWVtX3JlcyksICJzM2MtYWM5NyIp KSB7Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgZGV2X2VycigmcGRldi0+ZGV2LCAiVW5hYmxlIHRv IHJlcXVlc3QgcmVnaXN0ZXIgcmVnaW9uXG4iKTsKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCByZXR1 cm4gLUVCVVNZOwo+PiArIMKgIMKgIH0KPj4gKwo+PiArIMKgIMKgIHMzY19hYzk3X3BjbV9vdXQu Y2hhbm5lbCA9IGRtYXR4X3Jlcy0+c3RhcnQ7Cj4+ICsgwqAgwqAgczNjX2FjOTdfcGNtX291dC5k bWFfYWRkciA9IG1lbV9yZXMtPnN0YXJ0ICsgUzNDX0FDOTdfUENNX0RBVEE7Cj4+ICsgwqAgwqAg czNjX2FjOTdfcGNtX2luLmNoYW5uZWwgPSBkbWFyeF9yZXMtPnN0YXJ0Owo+PiArIMKgIMKgIHMz Y19hYzk3X3BjbV9pbi5kbWFfYWRkciA9IG1lbV9yZXMtPnN0YXJ0ICsgUzNDX0FDOTdfUENNX0RB VEE7Cj4+ICsgwqAgwqAgczNjX2FjOTdfbWljX2luLmNoYW5uZWwgPSBkbWFtaWNfcmVzLT5zdGFy dDsKPj4gKyDCoCDCoCBzM2NfYWM5N19taWNfaW4uZG1hX2FkZHIgPSBtZW1fcmVzLT5zdGFydCAr IFMzQ19BQzk3X01JQ19EQVRBOwo+PiArCj4+ICsgwqAgwqAgaW5pdF9jb21wbGV0aW9uKCZzM2Nf YWM5Ny5kb25lKTsKPj4gKyDCoCDCoCBtdXRleF9pbml0KCZzM2NfYWM5Ny5sb2NrKTsKPj4gKwo+ PiArIMKgIMKgIHMzY19hYzk3LnJlZ3MgPSBpb3JlbWFwKG1lbV9yZXMtPnN0YXJ0LCByZXNvdXJj ZV9zaXplKG1lbV9yZXMpKTsKPj4gKyDCoCDCoCBpZiAoczNjX2FjOTcucmVncyA9PSBOVUxMKSB7 Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgZGV2X2VycigmcGRldi0+ZGV2LCAiVW5hYmxlIHRvIGlv cmVtYXAgcmVnaXN0ZXIgcmVnaW9uXG4iKTsKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCByZXQgPSAt RU5YSU87Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgZ290byBsYjE7Cj4+ICsgwqAgwqAgfQo+PiAr Cj4+ICsgwqAgwqAgczNjX2FjOTcuYWM5N19jbGsgPSBjbGtfZ2V0KCZwZGV2LT5kZXYsICJhYzk3 Iik7Cj4+ICsgwqAgwqAgaWYgKElTX0VSUihzM2NfYWM5Ny5hYzk3X2NsaykpIHsKPj4gKyDCoCDC oCDCoCDCoCDCoCDCoCBkZXZfZXJyKCZwZGV2LT5kZXYsICJzM2MtYWM5NyBmYWlsZWQgdG8gZ2V0 IGFjOTdfY2xvY2tcbiIpOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIHJldCA9IC1FTk9ERVY7Cj4+ ICsgwqAgwqAgwqAgwqAgwqAgwqAgZ290byBsYjI7Cj4+ICsgwqAgwqAgfQo+PiArIMKgIMKgIGNs a19lbmFibGUoczNjX2FjOTcuYWM5N19jbGspOwo+PiArCj4+ICsgwqAgwqAgaWYgKGFjOTdfcGRh dGEtPmNmZ19ncGlvKHBkZXYpKSB7Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgZGV2X2VycigmcGRl di0+ZGV2LCAiVW5hYmxlIHRvIGNvbmZpZ3VyZSBncGlvXG4iKTsKPj4gKyDCoCDCoCDCoCDCoCDC oCDCoCByZXQgPSAtRUlOVkFMOwo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGdvdG8gbGIzOwo+PiAr IMKgIMKgIH0KPj4gKwo+PiArIMKgIMKgIHJldCA9IHJlcXVlc3RfaXJxKGlycV9yZXMtPnN0YXJ0 LCBzM2NfYWM5N19pcnEsCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgSVJRRl9ESVNBQkxFRCwgIkFDOTciLCBOVUxMKTsKPj4gKyDCoCDC oCBpZiAocmV0IDwgMCkgewo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIHByaW50ayhLRVJOX0VSUiAi czNjLWFjOTc6IGludGVycnVwdCByZXF1ZXN0IGZhaWxlZC5cbiIpOwo+PiArIMKgIMKgIMKgIMKg IMKgIMKgIGdvdG8gbGI0Owo+PiArIMKgIMKgIH0KPj4gKwo+PiArIMKgIMKgIHMzY19hYzk3X2Rh aVtTM0NfQUM5N19EQUlfUENNXS5kZXYgPSAmcGRldi0+ZGV2Owo+PiArIMKgIMKgIHMzY19hYzk3 X2RhaVtTM0NfQUM5N19EQUlfTUlDXS5kZXYgPSAmcGRldi0+ZGV2Owo+PiArCj4+ICsgwqAgwqAg cmV0ID0gc25kX3NvY19yZWdpc3Rlcl9kYWlzKHMzY19hYzk3X2RhaSwgQVJSQVlfU0laRShzM2Nf YWM5N19kYWkpKTsKPj4gKyDCoCDCoCBpZiAocmV0KQo+PiArIMKgIMKgIMKgIMKgIMKgIMKgIGdv dG8gbGI1Owo+PiArCj4+ICsgwqAgwqAgcmV0dXJuIDA7Cj4+ICsKPj4gK2xiNToKPj4gKyDCoCDC oCBmcmVlX2lycShpcnFfcmVzLT5zdGFydCwgTlVMTCk7Cj4+ICtsYjQ6Cj4+ICtsYjM6Cj4+ICsg wqAgwqAgY2xrX2Rpc2FibGUoczNjX2FjOTcuYWM5N19jbGspOwo+PiArIMKgIMKgIGNsa19wdXQo czNjX2FjOTcuYWM5N19jbGspOwo+PiArbGIyOgo+PiArIMKgIMKgIGlvdW5tYXAoczNjX2FjOTcu cmVncyk7Cj4+ICtsYjE6Cj4+ICsgwqAgwqAgcmVsZWFzZV9tZW1fcmVnaW9uKG1lbV9yZXMtPnN0 YXJ0LCByZXNvdXJjZV9zaXplKG1lbV9yZXMpKTsKPj4gKwo+PiArIMKgIMKgIHJldHVybiByZXQ7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBfX2RldmV4aXQgaW50IHMzY19hYzk3X3JlbW92ZShzdHJ1 Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+PiArewo+PiArIMKgIMKgIHN0cnVjdCByZXNvdXJj ZSAqbWVtX3JlcywgKmlycV9yZXM7Cj4+ICsKPj4gKyDCoCDCoCBzbmRfc29jX3VucmVnaXN0ZXJf ZGFpcyhzM2NfYWM5N19kYWksIEFSUkFZX1NJWkUoczNjX2FjOTdfZGFpKSk7Cj4+ICsKPj4gKyDC oCDCoCBpcnFfcmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfSVJR LCAwKTsKPj4gKyDCoCDCoCBpZiAoaXJxX3JlcykKPj4gKyDCoCDCoCDCoCDCoCDCoCDCoCBmcmVl X2lycShpcnFfcmVzLT5zdGFydCwgTlVMTCk7Cj4+ICsKPj4gKyDCoCDCoCBjbGtfZGlzYWJsZShz M2NfYWM5Ny5hYzk3X2Nsayk7Cj4+ICsgwqAgwqAgY2xrX3B1dChzM2NfYWM5Ny5hYzk3X2Nsayk7 Cj4+ICsKPj4gKyDCoCDCoCBpb3VubWFwKHMzY19hYzk3LnJlZ3MpOwo+PiArCj4+ICsgwqAgwqAg bWVtX3JlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7 Cj4+ICsgwqAgwqAgaWYgKG1lbV9yZXMpCj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgcmVsZWFzZV9t ZW1fcmVnaW9uKG1lbV9yZXMtPnN0YXJ0LCByZXNvdXJjZV9zaXplKG1lbV9yZXMpKTsKPj4gKwo+ PiArIMKgIMKgIHJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3Jt X2RyaXZlciBzM2NfYWM5N19kcml2ZXIgPSB7Cj4+ICsgwqAgwqAgLnByb2JlIMKgPSBzM2NfYWM5 N19wcm9iZSwKPj4gKyDCoCDCoCAucmVtb3ZlID0gczNjX2FjOTdfcmVtb3ZlLAo+PiArIMKgIMKg IC5kcml2ZXIgPSB7Cj4+ICsgwqAgwqAgwqAgwqAgwqAgwqAgLm5hbWUgPSAiczNjLWFjOTciLAo+ PiArIMKgIMKgIMKgIMKgIMKgIMKgIC5vd25lciA9IFRISVNfTU9EVUxFLAo+PiArIMKgIMKgIH0s Cj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgaW50IF9faW5pdCBzM2NfYWM5N19pbml0KHZvaWQpCj4+ ICt7Cj4+ICsgwqAgwqAgcmV0dXJuIHBsYXRmb3JtX2RyaXZlcl9yZWdpc3RlcigmczNjX2FjOTdf ZHJpdmVyKTsKPj4gK30KPj4gK21vZHVsZV9pbml0KHMzY19hYzk3X2luaXQpOwo+PiArCj4+ICtz dGF0aWMgdm9pZCBfX2V4aXQgczNjX2FjOTdfZXhpdCh2b2lkKQo+PiArewo+PiArIMKgIMKgIHBs YXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZzM2NfYWM5N19kcml2ZXIpOwo+PiArfQo+PiArbW9k dWxlX2V4aXQoczNjX2FjOTdfZXhpdCk7Cj4+ICsKPj4gK01PRFVMRV9BVVRIT1IoIkphc3dpbmRl ciBTaW5naCwgPGphc3NpLmJyYXJAc2Ftc3VuZy5jb20+Iik7Cj4+ICtNT0RVTEVfREVTQ1JJUFRJ T04oIkFDOTcgZHJpdmVyIGZvciB0aGUgU2Ftc3VuZyBTb0MiKTsKPj4gK01PRFVMRV9MSUNFTlNF KCJHUEwiKTsKPj4gZGlmZiAtLWdpdCBhL3NvdW5kL3NvYy9zM2MyNHh4L3MzYy1hYzk3LmggYi9z b3VuZC9zb2MvczNjMjR4eC9zM2MtYWM5Ny5oCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGlu ZGV4IDAwMDAwMDAuLjI3ODE5ODMKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9zb3VuZC9zb2Mv czNjMjR4eC9zM2MtYWM5Ny5oCj4+IEBAIC0wLDAgKzEsMjMgQEAKPj4gKy8qIHNvdW5kL3NvYy9z M2MyNHh4L3MzYy1hYzk3LmgKPj4gKyAqCj4+ICsgKiBBTFNBIFNvQyBBdWRpbyBMYXllciAtIFMz QyBBQzk3IENvbnRyb2xsZXIgZHJpdmVyCj4+ICsgKiDCoCBFdm9sdmVkIGZyb20gczNjMjQ0My1h Yzk3LmgKPj4gKyAqCj4+ICsgKiBDb3B5cmlnaHQgKGMpIDIwMTAgU2Ftc3VuZyBFbGVjdHJvbmlj cyBDby4gTHRkCj4+ICsgKiDCoCBBdXRob3I6IEphc3dpbmRlciBTaW5naCA8amFzc2kuYnJhckBz YW1zdW5nLmNvbT4KPj4gKyAqIMKgIENyZWRpdHM6IEdyYWVtZSBHcmVnb3J5LCBTZWFuIENob2kK Pj4gKyAqCj4+ICsgKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRp c3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQo+PiArICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRo ZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKPj4gKyAqIHB1Ymxpc2hl ZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgo+PiArICovCj4+ICsKPj4gKyNpZm5k ZWYgX19TM0NfQUM5N19IXwo+PiArI2RlZmluZSBfX1MzQ19BQzk3X0hfCj4+ICsKPj4gKyNkZWZp bmUgUzNDX0FDOTdfREFJX1BDTSAwCj4+ICsjZGVmaW5lIFMzQ19BQzk3X0RBSV9NSUMgMQo+PiAr Cj4+ICtleHRlcm4gc3RydWN0IHNuZF9zb2NfZGFpIHMzY19hYzk3X2RhaVtdOwo+PiArCj4+ICsj ZW5kaWYgLyogX19TM0NfQUM5N19IXyAqLwo+PiAtLQo+PiAxLjYuMi41Cj4+Cj4+IC0tCj4+IFRv IHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBs aW51eC1zYW1zdW5nLXNvYyIgaW4KPj4gdGhlIGJvZHkgb2YgYSBtZXNzYWdlIHRvIG1ham9yZG9t b0B2Z2VyLmtlcm5lbC5vcmcKPj4gTW9yZSBtYWpvcmRvbW8gaW5mbyBhdCDCoGh0dHA6Ly92Z2Vy Lmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRtbAo+Cj4KPiBPdXQgb2YgaW50ZXJlc3QsIGhv dyBzaW1pbGFyIGFyZSB0aGUgdHdvIGJsb2NrcyBhbmQgY291bGQgdGhlIHMzYzI0NDMKPiBjYXNl IGJlIGVsaWRlZCBpbnRvIHRoaXMgb25lIHdpdGggc29tZSBtaW5pbWFsIGNoZWNrcyBmb3Igd2hp Y2ggb25lIGlzCj4gY3VycmVudGx5IGluIHVzZT8KU2FtZSBleGNlcHQgZm9yIGEgZmV3ICdkZWFk JyBiaXRzIGluIDI0NDMuClRoZSBvbmx5IHJlYXNvbiBJIGRpZG4ndCBzdWJtaXQgcGF0Y2ggdG8g ZGVsZXRlIHMzYzI0NDMtYWM5Ny5jIGlzIHRoYXQgbXkKIHNtZGsyNDQzIGRpZG4ndCBwcm9kdWNl IGFueSBzb3VuZC4gKGJ0dyB0aGUgczNjMjQ0My1hYzk3LmMgYWxzbyBmYWlscyB0byBkbyBzbykK X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KQWxzYS1kZXZl bCBtYWlsaW5nIGxpc3QKQWxzYS1kZXZlbEBhbHNhLXByb2plY3Qub3JnCmh0dHA6Ly9tYWlsbWFu LmFsc2EtcHJvamVjdC5vcmcvbWFpbG1hbi9saXN0aW5mby9hbHNhLWRldmVsCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: jassisinghbrar@gmail.com (jassi brar) Date: Tue, 26 Jan 2010 20:03:09 +0900 Subject: [PATCH 2/3] ASoC: AC97: S3C: Add controller driver In-Reply-To: <20100126102343.GA24843@trinity.fluff.org> References: <1264485101-13782-1-git-send-email-jassisinghbrar@gmail.com> <1264485101-13782-2-git-send-email-jassisinghbrar@gmail.com> <20100126102343.GA24843@trinity.fluff.org> Message-ID: <1b68c6791001260303m38e6e689p2ee8c2c4c6ac2af3@mail.gmail.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Tue, Jan 26, 2010 at 7:23 PM, Ben Dooks wrote: > On Tue, Jan 26, 2010 at 02:51:40PM +0900, jassisinghbrar at gmail.com wrote: >> From: Jassi Brar >> >> Add the AC97 controller driver for Samsung SoCs that have one. >> >> Signed-off-by: Jassi Brar >> --- >> ?sound/soc/s3c24xx/Kconfig ? ?| ? ?6 +- >> ?sound/soc/s3c24xx/Makefile ? | ? ?3 +- >> ?sound/soc/s3c24xx/s3c-ac97.c | ?535 ++++++++++++++++++++++++++++++++++++++++++ >> ?sound/soc/s3c24xx/s3c-ac97.h | ? 23 ++ >> ?4 files changed, 565 insertions(+), 2 deletions(-) >> ?create mode 100644 sound/soc/s3c24xx/s3c-ac97.c >> ?create mode 100644 sound/soc/s3c24xx/s3c-ac97.h >> >> diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig >> index b489f1a..ad3690e 100644 >> --- a/sound/soc/s3c24xx/Kconfig >> +++ b/sound/soc/s3c24xx/Kconfig >> @@ -32,7 +32,11 @@ config SND_S3C2443_SOC_AC97 >> ? ? ? select S3C2410_DMA >> ? ? ? select AC97_BUS >> ? ? ? select SND_SOC_AC97_BUS >> - >> + >> +config SND_S3C_SOC_AC97 >> + ? ? tristate >> + ? ? select SND_SOC_AC97_BUS >> + >> ?config SND_S3C24XX_SOC_NEO1973_WM8753 >> ? ? ? tristate "SoC I2S Audio support for NEO1973 - WM8753" >> ? ? ? depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 >> diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile >> index b744657..b7411bd 100644 >> --- a/sound/soc/s3c24xx/Makefile >> +++ b/sound/soc/s3c24xx/Makefile >> @@ -4,12 +4,14 @@ snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o >> ?snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o >> ?snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o >> ?snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o >> +snd-soc-s3c-ac97-objs := s3c-ac97.o >> ?snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o >> ?snd-soc-s3c-pcm-objs := s3c-pcm.o >> >> ?obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o >> ?obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o >> ?obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o >> +obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o >> ?obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o >> ?obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o >> ?obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o >> @@ -37,4 +39,3 @@ obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o >> ?obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o >> ?obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o >> ?obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o >> - >> diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c >> new file mode 100644 >> index 0000000..acb8f51 >> --- /dev/null >> +++ b/sound/soc/s3c24xx/s3c-ac97.c >> @@ -0,0 +1,535 @@ >> +/* sound/soc/s3c24xx/s3c-ac97.c >> + * >> + * ALSA SoC Audio Layer - S3C AC97 Controller driver >> + * ? Evolved from s3c2443-ac97.c >> + * >> + * Copyright (c) 2010 Samsung Electronics Co. Ltd >> + * ? Author: Jaswinder Singh >> + * ? Credits: Graeme Gregory, Sean Choi >> + * >> + * 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. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> + >> +#include >> +#include >> +#include >> + >> +#include "s3c-dma.h" >> +#include "s3c-ac97.h" >> + >> +#define AC_CMD_ADDR(x) (x << 16) >> +#define AC_CMD_DATA(x) (x & 0xffff) >> + >> +struct s3c_ac97_info { >> + ? ? unsigned ? ? ? ? ? state; >> + ? ? struct clk ? ? ? ? *ac97_clk; >> + ? ? void __iomem ? ? ? *regs; >> + ? ? struct mutex ? ? ? lock; >> + ? ? struct completion ?done; >> +}; >> +static struct s3c_ac97_info s3c_ac97; >> + >> +static struct s3c2410_dma_client s3c_dma_client_out = { >> + ? ? .name = "AC97 PCMOut" >> +}; >> + >> +static struct s3c2410_dma_client s3c_dma_client_in = { >> + ? ? .name = "AC97 PCMIn" >> +}; >> + >> +static struct s3c2410_dma_client s3c_dma_client_micin = { >> + ? ? .name = "AC97 MicIn" >> +}; >> + >> +static struct s3c_dma_params s3c_ac97_pcm_out = { >> + ? ? .client ? ? ? ? = &s3c_dma_client_out, >> + ? ? .dma_size ? ? ? = 4, >> +}; >> + >> +static struct s3c_dma_params s3c_ac97_pcm_in = { >> + ? ? .client ? ? ? ? = &s3c_dma_client_in, >> + ? ? .dma_size ? ? ? = 4, >> +}; >> + >> +static struct s3c_dma_params s3c_ac97_mic_in = { >> + ? ? .client ? ? ? ? = &s3c_dma_client_micin, >> + ? ? .dma_size ? ? ? = 4, >> +}; >> + >> +static void s3c_ac97_cold_reset(struct snd_ac97 *ac97) >> +{ >> + ? ? writel(S3C_AC97_GLBCTRL_COLDRESET, >> + ? ? ? ? ? ? ? ? ? ? s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? msleep(1); >> + >> + ? ? writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? msleep(1); >> +} >> + >> +static void s3c_ac97_warm_reset(struct snd_ac97 *ac97) >> +{ >> + ? ? writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? msleep(1); >> + >> + ? ? writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? msleep(1); >> +} > > It would be nice t osee something to convert a 'struct snd_ac97' to a > 'struct s3c_ac97_info' as this is being passed in to most place and > would also help if there is ever >1 block. ok, will find a way to do that. >> +static void s3c_ac97_activate(struct snd_ac97 *ac97) >> +{ >> + ? ? u32 ac_glbctrl, stat; >> + >> + ? ? stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; >> + ? ? switch (stat) { >> + ? ? case S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE: >> + ? ? ? ? ? ? return; >> + ? ? case S3C_AC97_GLBSTAT_MAINSTATE_READY: >> + ? ? case S3C_AC97_GLBSTAT_MAINSTATE_INIT: >> + ? ? ? ? ? ? break; >> + ? ? default: >> + ? ? ? ? ? ? s3c_ac97_cold_reset(ac97); >> + ? ? ? ? ? ? s3c_ac97_warm_reset(ac97); >> + ? ? ? ? ? ? break; >> + ? ? } >> + >> + ? ? ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; >> + ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? msleep(1); >> + >> + ? ? ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; >> + ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? msleep(1); >> + >> + ? ? ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; >> + ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + >> + ? ? INIT_COMPLETION(s3c_ac97.done); >> + >> + ? ? if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) >> + ? ? ? ? ? ? printk(KERN_ERR "AC97: Unable to activate!"); >> +} >> + >> +static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, >> + ? ? unsigned short reg) >> +{ >> + ? ? u32 ac_glbctrl, ac_codec_cmd; >> + ? ? u32 stat, addr, data; >> + >> + ? ? mutex_lock(&s3c_ac97.lock); >> + >> + ? ? s3c_ac97_activate(ac97); >> + >> + ? ? ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); >> + ? ? ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); >> + ? ? writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); >> + >> + ? ? udelay(50); >> + >> + ? ? ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; >> + ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + >> + ? ? INIT_COMPLETION(s3c_ac97.done); >> + >> + ? ? if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) >> + ? ? ? ? ? ? printk(KERN_ERR "AC97: Unable to read!"); >> + >> + ? ? stat = readl(s3c_ac97.regs + S3C_AC97_STAT); >> + ? ? addr = (stat >> 16) & 0x7f; >> + ? ? data = (stat & 0xffff); >> + >> + ? ? if (addr != reg) >> + ? ? ? ? ? ? printk(KERN_ERR "s3c-ac97: req addr = %02x," >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? " rep addr = %02x\n", reg, addr); >> + >> + ? ? mutex_unlock(&s3c_ac97.lock); >> + >> + ? ? return (unsigned short)data; >> +} >> + >> +static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, >> + ? ? unsigned short val) >> +{ >> + ? ? u32 ac_glbctrl, ac_codec_cmd; >> + >> + ? ? mutex_lock(&s3c_ac97.lock); >> + >> + ? ? s3c_ac97_activate(ac97); >> + >> + ? ? ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); >> + ? ? ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); >> + ? ? writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); >> + >> + ? ? udelay(50); >> + >> + ? ? ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; >> + ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + >> + ? ? INIT_COMPLETION(s3c_ac97.done); >> + >> + ? ? if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) >> + ? ? ? ? ? ? printk(KERN_ERR "AC97: Unable to write!"); >> + >> + ? ? ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); >> + ? ? ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; >> + ? ? writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); >> + >> + ? ? mutex_unlock(&s3c_ac97.lock); >> +} >> + >> +static irqreturn_t s3c_ac97_irq(int irq, void *dev_id) >> +{ >> + ? ? u32 ac_glbctrl, ac_glbstat; >> + >> + ? ? ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT); >> + >> + ? ? if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) { >> + >> + ? ? ? ? ? ? ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? ? ? ? ? ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; >> + ? ? ? ? ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + >> + ? ? ? ? ? ? ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? ? ? ? ? ac_glbctrl |= (1<<30); /* Clear interrupt */ >> + ? ? ? ? ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + >> + ? ? ? ? ? ? complete(&s3c_ac97.done); >> + ? ? } >> + >> + ? ? return IRQ_HANDLED; >> +} >> + >> +struct snd_ac97_bus_ops soc_ac97_ops = { >> + ? ? .read ? ? ? = s3c_ac97_read, >> + ? ? .write ? ? ?= s3c_ac97_write, >> + ? ? .warm_reset = s3c_ac97_warm_reset, >> + ? ? .reset ? ? ?= s3c_ac97_cold_reset, >> +}; >> +EXPORT_SYMBOL_GPL(soc_ac97_ops); >> + >> +static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct snd_pcm_hw_params *params, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct snd_soc_dai *dai) >> +{ >> + ? ? struct snd_soc_pcm_runtime *rtd = substream->private_data; >> + ? ? struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; >> + >> + ? ? if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) >> + ? ? ? ? ? ? cpu_dai->dma_data = &s3c_ac97_pcm_out; >> + ? ? else >> + ? ? ? ? ? ? cpu_dai->dma_data = &s3c_ac97_pcm_in; >> + >> + ? ? return 0; >> +} >> + >> +static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct snd_soc_dai *dai) >> +{ >> + ? ? u32 ac_glbctrl; >> + ? ? struct snd_soc_pcm_runtime *rtd = substream->private_data; >> + ? ? int channel = ((struct s3c_dma_params *) >> + ? ? ? ? ? ? ? rtd->dai->cpu_dai->dma_data)->channel; >> + >> + ? ? ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) >> + ? ? ? ? ? ? ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; >> + ? ? else >> + ? ? ? ? ? ? ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; >> + >> + ? ? switch (cmd) { >> + ? ? case SNDRV_PCM_TRIGGER_START: >> + ? ? case SNDRV_PCM_TRIGGER_RESUME: >> + ? ? case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: >> + ? ? ? ? ? ? if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) >> + ? ? ? ? ? ? ? ? ? ? ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; >> + ? ? ? ? ? ? else >> + ? ? ? ? ? ? ? ? ? ? ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; >> + ? ? ? ? ? ? break; >> + >> + ? ? case SNDRV_PCM_TRIGGER_STOP: >> + ? ? case SNDRV_PCM_TRIGGER_SUSPEND: >> + ? ? case SNDRV_PCM_TRIGGER_PAUSE_PUSH: >> + ? ? ? ? ? ? break; >> + ? ? } >> + >> + ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + >> + ? ? s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); >> + >> + ? ? return 0; >> +} >> + >> +static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct snd_pcm_hw_params *params, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct snd_soc_dai *dai) >> +{ >> + ? ? struct snd_soc_pcm_runtime *rtd = substream->private_data; >> + ? ? struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; >> + >> + ? ? if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) >> + ? ? ? ? ? ? return -ENODEV; >> + ? ? else >> + ? ? ? ? ? ? cpu_dai->dma_data = &s3c_ac97_mic_in; >> + >> + ? ? return 0; >> +} >> + >> +static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int cmd, struct snd_soc_dai *dai) >> +{ >> + ? ? u32 ac_glbctrl; >> + ? ? struct snd_soc_pcm_runtime *rtd = substream->private_data; >> + ? ? int channel = ((struct s3c_dma_params *) >> + ? ? ? ? ? ? ? rtd->dai->cpu_dai->dma_data)->channel; >> + >> + ? ? ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + ? ? ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; >> + >> + ? ? switch (cmd) { >> + ? ? case SNDRV_PCM_TRIGGER_START: >> + ? ? case SNDRV_PCM_TRIGGER_RESUME: >> + ? ? case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: >> + ? ? ? ? ? ? ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA; >> + ? ? ? ? ? ? break; >> + >> + ? ? case SNDRV_PCM_TRIGGER_STOP: >> + ? ? case SNDRV_PCM_TRIGGER_SUSPEND: >> + ? ? case SNDRV_PCM_TRIGGER_PAUSE_PUSH: >> + ? ? ? ? ? ? break; >> + ? ? } >> + >> + ? ? writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); >> + >> + ? ? s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); >> + >> + ? ? return 0; >> +} >> + >> +#define S3C_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ >> + ? ? ? ? ? ? SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ >> + ? ? ? ? ? ? SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ >> + ? ? ? ? ? ? SNDRV_PCM_RATE_48000) >> + >> +static struct snd_soc_dai_ops s3c_ac97_dai_ops = { >> + ? ? .hw_params ? ? ?= s3c_ac97_hw_params, >> + ? ? .trigger ? ? ? ?= s3c_ac97_trigger, >> +}; >> + >> +static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { >> + ? ? .hw_params ? ? ?= s3c_ac97_hw_mic_params, >> + ? ? .trigger ? ? ? ?= s3c_ac97_mic_trigger, >> +}; >> + >> +struct snd_soc_dai s3c_ac97_dai[] = { >> + ? ? [S3C_AC97_DAI_PCM] = { >> + ? ? ? ? ? ? .name = "s3c-ac97", >> + ? ? ? ? ? ? .id = S3C_AC97_DAI_PCM, >> + ? ? ? ? ? ? .ac97_control = 1, >> + ? ? ? ? ? ? .playback = { >> + ? ? ? ? ? ? ? ? ? ? .stream_name = "AC97 Playback", >> + ? ? ? ? ? ? ? ? ? ? .channels_min = 2, >> + ? ? ? ? ? ? ? ? ? ? .channels_max = 2, >> + ? ? ? ? ? ? ? ? ? ? .rates = S3C_AC97_RATES, >> + ? ? ? ? ? ? ? ? ? ? .formats = SNDRV_PCM_FMTBIT_S16_LE,}, >> + ? ? ? ? ? ? .capture = { >> + ? ? ? ? ? ? ? ? ? ? .stream_name = "AC97 Capture", >> + ? ? ? ? ? ? ? ? ? ? /* NOTE: If the codec ouputs just one slot, >> + ? ? ? ? ? ? ? ? ? ? ?* it *seems* our AC97 controller reads the only >> + ? ? ? ? ? ? ? ? ? ? ?* valid slot(if either 3 or 4) for PCM-In. >> + ? ? ? ? ? ? ? ? ? ? ?* For such cases, we record Mono. >> + ? ? ? ? ? ? ? ? ? ? ?*/ >> + ? ? ? ? ? ? ? ? ? ? .channels_min = 1, >> + ? ? ? ? ? ? ? ? ? ? .channels_max = 2, >> + ? ? ? ? ? ? ? ? ? ? .rates = S3C_AC97_RATES, >> + ? ? ? ? ? ? ? ? ? ? .formats = SNDRV_PCM_FMTBIT_S16_LE,}, >> + ? ? ? ? ? ? .ops = &s3c_ac97_dai_ops, >> + ? ? }, >> + ? ? [S3C_AC97_DAI_MIC] = { >> + ? ? ? ? ? ? .name = "s3c-ac97-mic", >> + ? ? ? ? ? ? .id = S3C_AC97_DAI_MIC, >> + ? ? ? ? ? ? .ac97_control = 1, >> + ? ? ? ? ? ? .capture = { >> + ? ? ? ? ? ? ? ? ? ? .stream_name = "AC97 Mic Capture", >> + ? ? ? ? ? ? ? ? ? ? .channels_min = 1, >> + ? ? ? ? ? ? ? ? ? ? /* NOTE: If the codec(like WM9713) can't ouput just >> + ? ? ? ? ? ? ? ? ? ? ?* one slot, it *seems* our AC97 controller reads >> + ? ? ? ? ? ? ? ? ? ? ?* two slots(if one of them is Slot-6) for MIC also. >> + ? ? ? ? ? ? ? ? ? ? ?* For such cases, we record Stereo. >> + ? ? ? ? ? ? ? ? ? ? ?*/ >> + ? ? ? ? ? ? ? ? ? ? .channels_max = 2, >> + ? ? ? ? ? ? ? ? ? ? .rates = S3C_AC97_RATES, >> + ? ? ? ? ? ? ? ? ? ? .formats = SNDRV_PCM_FMTBIT_S16_LE,}, >> + ? ? ? ? ? ? .ops = &s3c_ac97_mic_dai_ops, >> + ? ? }, >> +}; >> +EXPORT_SYMBOL_GPL(s3c_ac97_dai); >> + >> +static __devinit int s3c_ac97_probe(struct platform_device *pdev) >> +{ >> + ? ? struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; >> + ? ? struct s3c_audio_pdata *ac97_pdata; >> + ? ? int ret; >> + >> + ? ? ac97_pdata = pdev->dev.platform_data; >> + ? ? if (!ac97_pdata || !ac97_pdata->cfg_gpio) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "cfg_gpio callback not provided!\n"); >> + ? ? ? ? ? ? return -EINVAL; >> + ? ? } >> + >> + ? ? /* Check for availability of necessary resource */ >> + ? ? dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); >> + ? ? if (!dmatx_res) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n"); >> + ? ? ? ? ? ? return -ENXIO; >> + ? ? } >> + >> + ? ? dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); >> + ? ? if (!dmarx_res) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n"); >> + ? ? ? ? ? ? return -ENXIO; >> + ? ? } >> + >> + ? ? dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2); >> + ? ? if (!dmamic_res) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n"); >> + ? ? ? ? ? ? return -ENXIO; >> + ? ? } >> + >> + ? ? mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> + ? ? if (!mem_res) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "Unable to get register resource\n"); >> + ? ? ? ? ? ? return -ENXIO; >> + ? ? } >> + >> + ? ? irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); >> + ? ? if (!irq_res) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); >> + ? ? ? ? ? ? return -ENXIO; >> + ? ? } >> + >> + ? ? if (!request_mem_region(mem_res->start, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? resource_size(mem_res), "s3c-ac97")) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "Unable to request register region\n"); >> + ? ? ? ? ? ? return -EBUSY; >> + ? ? } >> + >> + ? ? s3c_ac97_pcm_out.channel = dmatx_res->start; >> + ? ? s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; >> + ? ? s3c_ac97_pcm_in.channel = dmarx_res->start; >> + ? ? s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; >> + ? ? s3c_ac97_mic_in.channel = dmamic_res->start; >> + ? ? s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; >> + >> + ? ? init_completion(&s3c_ac97.done); >> + ? ? mutex_init(&s3c_ac97.lock); >> + >> + ? ? s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); >> + ? ? if (s3c_ac97.regs == NULL) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "Unable to ioremap register region\n"); >> + ? ? ? ? ? ? ret = -ENXIO; >> + ? ? ? ? ? ? goto lb1; >> + ? ? } >> + >> + ? ? s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); >> + ? ? if (IS_ERR(s3c_ac97.ac97_clk)) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n"); >> + ? ? ? ? ? ? ret = -ENODEV; >> + ? ? ? ? ? ? goto lb2; >> + ? ? } >> + ? ? clk_enable(s3c_ac97.ac97_clk); >> + >> + ? ? if (ac97_pdata->cfg_gpio(pdev)) { >> + ? ? ? ? ? ? dev_err(&pdev->dev, "Unable to configure gpio\n"); >> + ? ? ? ? ? ? ret = -EINVAL; >> + ? ? ? ? ? ? goto lb3; >> + ? ? } >> + >> + ? ? ret = request_irq(irq_res->start, s3c_ac97_irq, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED, "AC97", NULL); >> + ? ? if (ret < 0) { >> + ? ? ? ? ? ? printk(KERN_ERR "s3c-ac97: interrupt request failed.\n"); >> + ? ? ? ? ? ? goto lb4; >> + ? ? } >> + >> + ? ? s3c_ac97_dai[S3C_AC97_DAI_PCM].dev = &pdev->dev; >> + ? ? s3c_ac97_dai[S3C_AC97_DAI_MIC].dev = &pdev->dev; >> + >> + ? ? ret = snd_soc_register_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); >> + ? ? if (ret) >> + ? ? ? ? ? ? goto lb5; >> + >> + ? ? return 0; >> + >> +lb5: >> + ? ? free_irq(irq_res->start, NULL); >> +lb4: >> +lb3: >> + ? ? clk_disable(s3c_ac97.ac97_clk); >> + ? ? clk_put(s3c_ac97.ac97_clk); >> +lb2: >> + ? ? iounmap(s3c_ac97.regs); >> +lb1: >> + ? ? release_mem_region(mem_res->start, resource_size(mem_res)); >> + >> + ? ? return ret; >> +} >> + >> +static __devexit int s3c_ac97_remove(struct platform_device *pdev) >> +{ >> + ? ? struct resource *mem_res, *irq_res; >> + >> + ? ? snd_soc_unregister_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); >> + >> + ? ? irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); >> + ? ? if (irq_res) >> + ? ? ? ? ? ? free_irq(irq_res->start, NULL); >> + >> + ? ? clk_disable(s3c_ac97.ac97_clk); >> + ? ? clk_put(s3c_ac97.ac97_clk); >> + >> + ? ? iounmap(s3c_ac97.regs); >> + >> + ? ? mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> + ? ? if (mem_res) >> + ? ? ? ? ? ? release_mem_region(mem_res->start, resource_size(mem_res)); >> + >> + ? ? return 0; >> +} >> + >> +static struct platform_driver s3c_ac97_driver = { >> + ? ? .probe ?= s3c_ac97_probe, >> + ? ? .remove = s3c_ac97_remove, >> + ? ? .driver = { >> + ? ? ? ? ? ? .name = "s3c-ac97", >> + ? ? ? ? ? ? .owner = THIS_MODULE, >> + ? ? }, >> +}; >> + >> +static int __init s3c_ac97_init(void) >> +{ >> + ? ? return platform_driver_register(&s3c_ac97_driver); >> +} >> +module_init(s3c_ac97_init); >> + >> +static void __exit s3c_ac97_exit(void) >> +{ >> + ? ? platform_driver_unregister(&s3c_ac97_driver); >> +} >> +module_exit(s3c_ac97_exit); >> + >> +MODULE_AUTHOR("Jaswinder Singh, "); >> +MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); >> +MODULE_LICENSE("GPL"); >> diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/s3c24xx/s3c-ac97.h >> new file mode 100644 >> index 0000000..2781983 >> --- /dev/null >> +++ b/sound/soc/s3c24xx/s3c-ac97.h >> @@ -0,0 +1,23 @@ >> +/* sound/soc/s3c24xx/s3c-ac97.h >> + * >> + * ALSA SoC Audio Layer - S3C AC97 Controller driver >> + * ? Evolved from s3c2443-ac97.h >> + * >> + * Copyright (c) 2010 Samsung Electronics Co. Ltd >> + * ? Author: Jaswinder Singh >> + * ? Credits: Graeme Gregory, Sean Choi >> + * >> + * 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. >> + */ >> + >> +#ifndef __S3C_AC97_H_ >> +#define __S3C_AC97_H_ >> + >> +#define S3C_AC97_DAI_PCM 0 >> +#define S3C_AC97_DAI_MIC 1 >> + >> +extern struct snd_soc_dai s3c_ac97_dai[]; >> + >> +#endif /* __S3C_AC97_H_ */ >> -- >> 1.6.2.5 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in >> the body of a message to majordomo at vger.kernel.org >> More majordomo info at ?http://vger.kernel.org/majordomo-info.html > > > Out of interest, how similar are the two blocks and could the s3c2443 > case be elided into this one with some minimal checks for which one is > currently in use? Same except for a few 'dead' bits in 2443. The only reason I didn't submit patch to delete s3c2443-ac97.c is that my smdk2443 didn't produce any sound. (btw the s3c2443-ac97.c also fails to do so)