From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 13A7EC55178 for ; Sat, 24 Oct 2020 08:04:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A97C922281 for ; Sat, 24 Oct 2020 08:04:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="VpVocS8P" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756292AbgJXIEc (ORCPT ); Sat, 24 Oct 2020 04:04:32 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:60626 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1756276AbgJXIEa (ORCPT ); Sat, 24 Oct 2020 04:04:30 -0400 X-UUID: c4ad25634ee94b019308c8fc3d69139b-20201024 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=1w2R910WjXYg2yiL2x05QYtuAGfRi8PuUHhC5wcblhY=; b=VpVocS8PBd528FM88hbTn8NI53pqMhTaGN+Vmc+rExvWxVou2h/IQON4Ye3l37+t8vpx1pOuF8YVJwhXRYMn0xfz+p0TRPRk0ipz/cwYj8rUe2ifCToRhPCcxCpRog9qoSS2Tk6idPopfSH5Rgd2h7lDOMTbUD9mE76LsvbJWZo=; X-UUID: c4ad25634ee94b019308c8fc3d69139b-20201024 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.14 Build 0819 with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 278918667; Sat, 24 Oct 2020 15:59:06 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs06n2.mediatek.inc (172.21.101.130) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 24 Oct 2020 15:59:05 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sat, 24 Oct 2020 15:59:02 +0800 From: Jiaxin Yu To: , , , , , , , , , CC: , , , , Jiaxin Yu Subject: [PATCH v3 4/9] ASoC: mediatek: mt8192: support add in platform driver Date: Sat, 24 Oct 2020 15:58:54 +0800 Message-ID: <1603526339-15005-5-git-send-email-jiaxin.yu@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1603526339-15005-1-git-send-email-jiaxin.yu@mediatek.com> References: <1603526339-15005-1-git-send-email-jiaxin.yu@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-SNTS-SMTP: 135DBFC313CC6BC3E7DF51BECFA222AD739BB5ABC37619AA951B923F72B44DC42000:8 X-MTK: N Content-Transfer-Encoding: base64 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org VGhpcyBwYXRjaCBhZGRzIG10ODE5MiBhZGRhIGRhaSBkcml2ZXIuDQoNClNpZ25lZC1vZmYtYnk6 IEppYXhpbiBZdSA8amlheGluLnl1QG1lZGlhdGVrLmNvbT4NCi0tLQ0KIHNvdW5kL3NvYy9tZWRp YXRlay9tdDgxOTIvbXQ4MTkyLWRhaS1hZGRhLmMgfCAxNDg5ICsrKysrKysrKysrKysrKysrKysN CiAxIGZpbGUgY2hhbmdlZCwgMTQ4OSBpbnNlcnRpb25zKCspDQogY3JlYXRlIG1vZGUgMTAwNjQ0 IHNvdW5kL3NvYy9tZWRpYXRlay9tdDgxOTIvbXQ4MTkyLWRhaS1hZGRhLmMNCg0KZGlmZiAtLWdp dCBhL3NvdW5kL3NvYy9tZWRpYXRlay9tdDgxOTIvbXQ4MTkyLWRhaS1hZGRhLmMgYi9zb3VuZC9z b2MvbWVkaWF0ZWsvbXQ4MTkyL210ODE5Mi1kYWktYWRkYS5jDQpuZXcgZmlsZSBtb2RlIDEwMDY0 NA0KaW5kZXggMDAwMDAwMDAwMDAwMC4uYzQ5YTAyZDM0ZjI2YQ0KLS0tIC9kZXYvbnVsbA0KKysr IGIvc291bmQvc29jL21lZGlhdGVrL210ODE5Mi9tdDgxOTItZGFpLWFkZGEuYw0KQEAgLTAsMCAr MSwxNDg5IEBADQorLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjANCisvLw0KKy8v IE1lZGlhVGVrIEFMU0EgU29DIEF1ZGlvIERBSSBBRERBIENvbnRyb2wNCisvLw0KKy8vIENvcHly aWdodCAoYykgMjAyMCBNZWRpYVRlayBJbmMuDQorLy8gQXV0aG9yOiBTaGFuZSBDaGllbiA8c2hh bmUuY2hpZW5AbWVkaWF0ZWsuY29tPg0KKy8vDQorDQorI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+ DQorI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPg0KKw0KKyNpbmNsdWRlICJtdDgxOTItYWZlLWNs ay5oIg0KKyNpbmNsdWRlICJtdDgxOTItYWZlLWNvbW1vbi5oIg0KKyNpbmNsdWRlICJtdDgxOTIt YWZlLWdwaW8uaCINCisjaW5jbHVkZSAibXQ4MTkyLWludGVyY29ubmVjdGlvbi5oIg0KKw0KK2Vu dW0gew0KKwlVTF9JSVJfU1cgPSAwLA0KKwlVTF9JSVJfNUhaLA0KKwlVTF9JSVJfMTBIWiwNCisJ VUxfSUlSXzI1SFosDQorCVVMX0lJUl81MEhaLA0KKwlVTF9JSVJfNzVIWiwNCit9Ow0KKw0KK2Vu dW0gew0KKwlBVURJT19TRE1fTEVWRUxfTVVURSA9IDAsDQorCUFVRElPX1NETV9MRVZFTF9OT1JN QUwgPSAweDFkLA0KKwkvKiBpZiB5b3UgY2hhbmdlIGxldmVsIG5vcm1hbCAqLw0KKwkvKiB5b3Ug bmVlZCB0byBjaGFuZ2UgZm9ybXVsYSBvZiBocCBpbXBlZGFuY2UgYW5kIGRjIHRyaW0gdG9vICov DQorfTsNCisNCitlbnVtIHsNCisJQVVESU9fU0RNXzJORCA9IDAsDQorCUFVRElPX1NETV8zUkQs DQorfTsNCisNCitlbnVtIHsNCisJREVMQVlfREFUQV9NSVNPMSA9IDAsDQorCURFTEFZX0RBVEFf TUlTTzIsDQorfTsNCisNCitlbnVtIHsNCisJTVRLX0FGRV9BRERBX0RMX1JBVEVfOEsgPSAwLA0K KwlNVEtfQUZFX0FEREFfRExfUkFURV8xMUsgPSAxLA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV8x MksgPSAyLA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV8xNksgPSAzLA0KKwlNVEtfQUZFX0FEREFf RExfUkFURV8yMksgPSA0LA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV8yNEsgPSA1LA0KKwlNVEtf QUZFX0FEREFfRExfUkFURV8zMksgPSA2LA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV80NEsgPSA3 LA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV80OEsgPSA4LA0KKwlNVEtfQUZFX0FEREFfRExfUkFU RV85NksgPSA5LA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV8xOTJLID0gMTAsDQorfTsNCisNCitl bnVtIHsNCisJTVRLX0FGRV9BRERBX1VMX1JBVEVfOEsgPSAwLA0KKwlNVEtfQUZFX0FEREFfVUxf UkFURV8xNksgPSAxLA0KKwlNVEtfQUZFX0FEREFfVUxfUkFURV8zMksgPSAyLA0KKwlNVEtfQUZF X0FEREFfVUxfUkFURV80OEsgPSAzLA0KKwlNVEtfQUZFX0FEREFfVUxfUkFURV85NksgPSA0LA0K KwlNVEtfQUZFX0FEREFfVUxfUkFURV8xOTJLID0gNSwNCisJTVRLX0FGRV9BRERBX1VMX1JBVEVf NDhLX0hEID0gNiwNCit9Ow0KKw0KKyNkZWZpbmUgU0RNX0FVVE9fUkVTRVRfVEhSRVNIT0xEIDB4 MTkwMDAwDQorDQorc3RhdGljIHVuc2lnbmVkIGludCBhZGRhX2RsX3JhdGVfdHJhbnNmb3JtKHN0 cnVjdCBtdGtfYmFzZV9hZmUgKmFmZSwNCisJCQkJCSAgIHVuc2lnbmVkIGludCByYXRlKQ0KK3sN CisJc3dpdGNoIChyYXRlKSB7DQorCWNhc2UgODAwMDoNCisJCXJldHVybiBNVEtfQUZFX0FEREFf RExfUkFURV84SzsNCisJY2FzZSAxMTAyNToNCisJCXJldHVybiBNVEtfQUZFX0FEREFfRExfUkFU RV8xMUs7DQorCWNhc2UgMTIwMDA6DQorCQlyZXR1cm4gTVRLX0FGRV9BRERBX0RMX1JBVEVfMTJL Ow0KKwljYXNlIDE2MDAwOg0KKwkJcmV0dXJuIE1US19BRkVfQUREQV9ETF9SQVRFXzE2SzsNCisJ Y2FzZSAyMjA1MDoNCisJCXJldHVybiBNVEtfQUZFX0FEREFfRExfUkFURV8yMks7DQorCWNhc2Ug MjQwMDA6DQorCQlyZXR1cm4gTVRLX0FGRV9BRERBX0RMX1JBVEVfMjRLOw0KKwljYXNlIDMyMDAw Og0KKwkJcmV0dXJuIE1US19BRkVfQUREQV9ETF9SQVRFXzMySzsNCisJY2FzZSA0NDEwMDoNCisJ CXJldHVybiBNVEtfQUZFX0FEREFfRExfUkFURV80NEs7DQorCWNhc2UgNDgwMDA6DQorCQlyZXR1 cm4gTVRLX0FGRV9BRERBX0RMX1JBVEVfNDhLOw0KKwljYXNlIDk2MDAwOg0KKwkJcmV0dXJuIE1U S19BRkVfQUREQV9ETF9SQVRFXzk2SzsNCisJY2FzZSAxOTIwMDA6DQorCQlyZXR1cm4gTVRLX0FG RV9BRERBX0RMX1JBVEVfMTkySzsNCisJZGVmYXVsdDoNCisJCWRldl93YXJuKGFmZS0+ZGV2LCAi JXMoKSwgcmF0ZSAlZCBpbnZhbGlkLCB1c2UgNDhrSHohISFcbiIsDQorCQkJIF9fZnVuY19fLCBy YXRlKTsNCisJCXJldHVybiBNVEtfQUZFX0FEREFfRExfUkFURV80OEs7DQorCX0NCit9DQorDQor c3RhdGljIHVuc2lnbmVkIGludCBhZGRhX3VsX3JhdGVfdHJhbnNmb3JtKHN0cnVjdCBtdGtfYmFz ZV9hZmUgKmFmZSwNCisJCQkJCSAgIHVuc2lnbmVkIGludCByYXRlKQ0KK3sNCisJc3dpdGNoIChy YXRlKSB7DQorCWNhc2UgODAwMDoNCisJCXJldHVybiBNVEtfQUZFX0FEREFfVUxfUkFURV84SzsN CisJY2FzZSAxNjAwMDoNCisJCXJldHVybiBNVEtfQUZFX0FEREFfVUxfUkFURV8xNks7DQorCWNh c2UgMzIwMDA6DQorCQlyZXR1cm4gTVRLX0FGRV9BRERBX1VMX1JBVEVfMzJLOw0KKwljYXNlIDQ4 MDAwOg0KKwkJcmV0dXJuIE1US19BRkVfQUREQV9VTF9SQVRFXzQ4SzsNCisJY2FzZSA5NjAwMDoN CisJCXJldHVybiBNVEtfQUZFX0FEREFfVUxfUkFURV85Nks7DQorCWNhc2UgMTkyMDAwOg0KKwkJ cmV0dXJuIE1US19BRkVfQUREQV9VTF9SQVRFXzE5Mks7DQorCWRlZmF1bHQ6DQorCQlkZXZfd2Fy bihhZmUtPmRldiwgIiVzKCksIHJhdGUgJWQgaW52YWxpZCwgdXNlIDQ4a0h6ISEhXG4iLA0KKwkJ CSBfX2Z1bmNfXywgcmF0ZSk7DQorCQlyZXR1cm4gTVRLX0FGRV9BRERBX1VMX1JBVEVfNDhLOw0K Kwl9DQorfQ0KKw0KKy8qIGRhaSBjb21wb25lbnQgKi8NCitzdGF0aWMgY29uc3Qgc3RydWN0IHNu ZF9rY29udHJvbF9uZXcgbXRrX2FkZGFfZGxfY2gxX21peFtdID0gew0KKwlTT0NfREFQTV9TSU5H TEVfQVVUT0RJU0FCTEUoIkRMMV9DSDEiLCBBRkVfQ09OTjMsIElfREwxX0NIMSwgMSwgMCksDQor CVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwxMl9DSDEiLCBBRkVfQ09OTjMsIElfREwx Ml9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMMl9DSDEiLCBB RkVfQ09OTjMsIElfREwyX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJM RSgiREwzX0NIMSIsIEFGRV9DT05OMywgSV9ETDNfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lO R0xFX0FVVE9ESVNBQkxFKCJETDRfQ0gxIiwgQUZFX0NPTk4zXzEsIElfREw0X0NIMSwgMSwgMCks DQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREw1X0NIMSIsIEFGRV9DT05OM18xLCBJ X0RMNV9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMNl9DSDEi LCBBRkVfQ09OTjNfMSwgSV9ETDZfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9E SVNBQkxFKCJETDhfQ0gxIiwgQUZFX0NPTk4zXzEsIElfREw4X0NIMSwgMSwgMCksDQorCVNPQ19E QVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiQUREQV9VTF9DSDMiLCBBRkVfQ09OTjMsDQorCQkJCSAg ICBJX0FEREFfVUxfQ0gzLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJB RERBX1VMX0NIMiIsIEFGRV9DT05OMywNCisJCQkJICAgIElfQUREQV9VTF9DSDIsIDEsIDApLA0K KwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkFEREFfVUxfQ0gxIiwgQUZFX0NPTk4zLA0K KwkJCQkgICAgSV9BRERBX1VMX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElT QUJMRSgiR0FJTjFfT1VUX0NIMSIsIEFGRV9DT05OMywNCisJCQkJICAgIElfR0FJTjFfT1VUX0NI MSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiUENNXzFfQ0FQX0NIMSIs IEFGRV9DT05OMywNCisJCQkJICAgIElfUENNXzFfQ0FQX0NIMSwgMSwgMCksDQorCVNPQ19EQVBN X1NJTkdMRV9BVVRPRElTQUJMRSgiUENNXzJfQ0FQX0NIMSIsIEFGRV9DT05OMywNCisJCQkJICAg IElfUENNXzJfQ0FQX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgi U1JDXzFfT1VUX0NIMSIsIEFGRV9DT05OM18xLA0KKwkJCQkgICAgSV9TUkNfMV9PVVRfQ0gxLCAx LCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJTUkNfMl9PVVRfQ0gxIiwgQUZF X0NPTk4zXzEsDQorCQkJCSAgICBJX1NSQ18yX09VVF9DSDEsIDEsIDApLA0KK307DQorDQorc3Rh dGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IG10a19hZGRhX2RsX2NoMl9taXhbXSA9 IHsNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDFfQ0gxIiwgQUZFX0NPTk40LCBJ X0RMMV9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMMV9DSDIi LCBBRkVfQ09OTjQsIElfREwxX0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElT QUJMRSgiREwxMl9DSDIiLCBBRkVfQ09OTjQsIElfREwxMl9DSDIsIDEsIDApLA0KKwlTT0NfREFQ TV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMMl9DSDEiLCBBRkVfQ09OTjQsIElfREwyX0NIMSwgMSwg MCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwyX0NIMiIsIEFGRV9DT05ONCwg SV9ETDJfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDNfQ0gx IiwgQUZFX0NPTk40LCBJX0RMM19DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJ U0FCTEUoIkRMM19DSDIiLCBBRkVfQ09OTjQsIElfREwzX0NIMiwgMSwgMCksDQorCVNPQ19EQVBN X1NJTkdMRV9BVVRPRElTQUJMRSgiREw0X0NIMiIsIEFGRV9DT05ONF8xLCBJX0RMNF9DSDIsIDEs IDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMNV9DSDIiLCBBRkVfQ09OTjRf MSwgSV9ETDVfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDZf Q0gyIiwgQUZFX0NPTk40XzEsIElfREw2X0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9B VVRPRElTQUJMRSgiREw4X0NIMiIsIEFGRV9DT05ONF8xLCBJX0RMOF9DSDIsIDEsIDApLA0KKwlT T0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkFEREFfVUxfQ0gzIiwgQUZFX0NPTk40LA0KKwkJ CQkgICAgSV9BRERBX1VMX0NIMywgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJM RSgiQUREQV9VTF9DSDIiLCBBRkVfQ09OTjQsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gyLCAxLCAw KSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERBX1VMX0NIMSIsIEFGRV9DT05O NCwNCisJCQkJICAgIElfQUREQV9VTF9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVU T0RJU0FCTEUoIkdBSU4xX09VVF9DSDIiLCBBRkVfQ09OTjQsDQorCQkJCSAgICBJX0dBSU4xX09V VF9DSDIsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBDTV8xX0NBUF9D SDEiLCBBRkVfQ09OTjQsDQorCQkJCSAgICBJX1BDTV8xX0NBUF9DSDEsIDEsIDApLA0KKwlTT0Nf REFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBDTV8yX0NBUF9DSDEiLCBBRkVfQ09OTjQsDQorCQkJ CSAgICBJX1BDTV8yX0NBUF9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FC TEUoIlBDTV8xX0NBUF9DSDIiLCBBRkVfQ09OTjQsDQorCQkJCSAgICBJX1BDTV8xX0NBUF9DSDIs IDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBDTV8yX0NBUF9DSDIiLCBB RkVfQ09OTjQsDQorCQkJCSAgICBJX1BDTV8yX0NBUF9DSDIsIDEsIDApLA0KKwlTT0NfREFQTV9T SU5HTEVfQVVUT0RJU0FCTEUoIlNSQ18xX09VVF9DSDIiLCBBRkVfQ09OTjRfMSwNCisJCQkJICAg IElfU1JDXzFfT1VUX0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgi U1JDXzJfT1VUX0NIMiIsIEFGRV9DT05ONF8xLA0KKwkJCQkgICAgSV9TUkNfMl9PVVRfQ0gyLCAx LCAwKSwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc25kX2tjb250cm9sX25ldyBtdGtf YWRkYV9kbF9jaDNfbWl4W10gPSB7DQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwx X0NIMSIsIEFGRV9DT05ONTIsIElfREwxX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9B VVRPRElTQUJMRSgiREwxMl9DSDEiLCBBRkVfQ09OTjUyLCBJX0RMMTJfQ0gxLCAxLCAwKSwNCisJ U09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDJfQ0gxIiwgQUZFX0NPTk41MiwgSV9ETDJf Q0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDNfQ0gxIiwgQUZF X0NPTk41MiwgSV9ETDNfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxF KCJETDRfQ0gxIiwgQUZFX0NPTk41Ml8xLCBJX0RMNF9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9T SU5HTEVfQVVUT0RJU0FCTEUoIkRMNV9DSDEiLCBBRkVfQ09OTjUyXzEsIElfREw1X0NIMSwgMSwg MCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREw2X0NIMSIsIEFGRV9DT05ONTJf MSwgSV9ETDZfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERB X1VMX0NIMyIsIEFGRV9DT05ONTIsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gzLCAxLCAwKSwNCisJ U09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERBX1VMX0NIMiIsIEFGRV9DT05ONTIsDQor CQkJCSAgICBJX0FEREFfVUxfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNB QkxFKCJBRERBX1VMX0NIMSIsIEFGRV9DT05ONTIsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gxLCAx LCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJHQUlOMV9PVVRfQ0gxIiwgQUZF X0NPTk41MiwNCisJCQkJICAgIElfR0FJTjFfT1VUX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJ TkdMRV9BVVRPRElTQUJMRSgiUENNXzFfQ0FQX0NIMSIsIEFGRV9DT05ONTIsDQorCQkJCSAgICBJ X1BDTV8xX0NBUF9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBD TV8yX0NBUF9DSDEiLCBBRkVfQ09OTjUyLA0KKwkJCQkgICAgSV9QQ01fMl9DQVBfQ0gxLCAxLCAw KSwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc25kX2tjb250cm9sX25ldyBtdGtfYWRk YV9kbF9jaDRfbWl4W10gPSB7DQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwxX0NI MSIsIEFGRV9DT05ONTMsIElfREwxX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRP RElTQUJMRSgiREwxX0NIMiIsIEFGRV9DT05ONTMsIElfREwxX0NIMiwgMSwgMCksDQorCVNPQ19E QVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwxMl9DSDIiLCBBRkVfQ09OTjUzLCBJX0RMMTJfQ0gy LCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDJfQ0gxIiwgQUZFX0NP Tk41MywgSV9ETDJfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJE TDJfQ0gyIiwgQUZFX0NPTk41MywgSV9ETDJfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xF X0FVVE9ESVNBQkxFKCJETDNfQ0gxIiwgQUZFX0NPTk41MywgSV9ETDNfQ0gxLCAxLCAwKSwNCisJ U09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDNfQ0gyIiwgQUZFX0NPTk41MywgSV9ETDNf Q0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDRfQ0gyIiwgQUZF X0NPTk41M18xLCBJX0RMNF9DSDIsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FC TEUoIkRMNV9DSDIiLCBBRkVfQ09OTjUzXzEsIElfREw1X0NIMiwgMSwgMCksDQorCVNPQ19EQVBN X1NJTkdMRV9BVVRPRElTQUJMRSgiREw2X0NIMiIsIEFGRV9DT05ONTNfMSwgSV9ETDZfQ0gxLCAx LCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERBX1VMX0NIMyIsIEFGRV9D T05ONTMsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gzLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xF X0FVVE9ESVNBQkxFKCJBRERBX1VMX0NIMiIsIEFGRV9DT05ONTMsDQorCQkJCSAgICBJX0FEREFf VUxfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERBX1VMX0NI MSIsIEFGRV9DT05ONTMsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gxLCAxLCAwKSwNCisJU09DX0RB UE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJHQUlOMV9PVVRfQ0gyIiwgQUZFX0NPTk41MywNCisJCQkJ ICAgIElfR0FJTjFfT1VUX0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJM RSgiUENNXzFfQ0FQX0NIMSIsIEFGRV9DT05ONTMsDQorCQkJCSAgICBJX1BDTV8xX0NBUF9DSDEs IDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBDTV8yX0NBUF9DSDEiLCBB RkVfQ09OTjUzLA0KKwkJCQkgICAgSV9QQ01fMl9DQVBfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1f U0lOR0xFX0FVVE9ESVNBQkxFKCJQQ01fMV9DQVBfQ0gyIiwgQUZFX0NPTk41MywNCisJCQkJICAg IElfUENNXzFfQ0FQX0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgi UENNXzJfQ0FQX0NIMiIsIEFGRV9DT05ONTMsDQorCQkJCSAgICBJX1BDTV8yX0NBUF9DSDIsIDEs IDApLA0KK307DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IG10a19z dGZfY2gxX21peFtdID0gew0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkFEREFfVUxf Q0gxIiwgQUZFX0NPTk4xOSwNCisJCQkJICAgIElfQUREQV9VTF9DSDEsIDEsIDApLA0KK307DQor DQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IG10a19zdGZfY2gyX21peFtd ID0gew0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkFEREFfVUxfQ0gyIiwgQUZFX0NP Tk4yMCwNCisJCQkJICAgIElfQUREQV9VTF9DSDIsIDEsIDApLA0KK307DQorDQorZW51bSB7DQor CVNVUFBMWV9TRVFfQUREQV9BRkVfT04sDQorCVNVUFBMWV9TRVFfQUREQV9ETF9PTiwNCisJU1VQ UExZX1NFUV9BRERBX0FVRF9QQURfVE9QLA0KKwlTVVBQTFlfU0VRX0FEREFfTVRLQUlGX0NGRywN CisJU1VQUExZX1NFUV9BRERBNl9NVEtBSUZfQ0ZHLA0KKwlTVVBQTFlfU0VRX0FEREFfRklGTywN CisJU1VQUExZX1NFUV9BRERBX0FQX0RNSUMsDQorCVNVUFBMWV9TRVFfQUREQV9VTF9PTiwNCit9 Ow0KKw0KK3N0YXRpYyBpbnQgbXRrX2FkZGFfdWxfc3JjX2RtaWMoc3RydWN0IG10a19iYXNlX2Fm ZSAqYWZlLCBpbnQgaWQpDQorew0KKwl1bnNpZ25lZCBpbnQgcmVnOw0KKw0KKwlzd2l0Y2ggKGlk KSB7DQorCWNhc2UgTVQ4MTkyX0RBSV9BRERBOg0KKwljYXNlIE1UODE5Ml9EQUlfQVBfRE1JQzoN CisJCXJlZyA9IEFGRV9BRERBX1VMX1NSQ19DT04wOw0KKwkJYnJlYWs7DQorCWNhc2UgTVQ4MTky X0RBSV9BRERBX0NIMzQ6DQorCWNhc2UgTVQ4MTkyX0RBSV9BUF9ETUlDX0NIMzQ6DQorCQlyZWcg PSBBRkVfQUREQTZfVUxfU1JDX0NPTjA7DQorCQlicmVhazsNCisJZGVmYXVsdDoNCisJCXJldHVy biAtRUlOVkFMOw0KKwl9DQorDQorCS8qIGRtaWMgbW9kZSwgMy4yNU0qLw0KKwlyZWdtYXBfdXBk YXRlX2JpdHMoYWZlLT5yZWdtYXAsIHJlZywNCisJCQkgICBESUdNSUNfM1AyNU1fMVA2MjVNX1NF TF9DVExfTUFTS19TRlQsDQorCQkJICAgMHgwKTsNCisJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+ cmVnbWFwLCByZWcsDQorCQkJICAgRE1JQ19MT1dfUE9XRVJfTU9ERV9DVExfTUFTS19TRlQsDQor CQkJICAgMHgwKTsNCisNCisJLyogdHVybiBvbiBkbWljLCBjaDEsIGNoMiAqLw0KKwlyZWdtYXBf dXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsIHJlZywNCisJCQkgICBVTF9TRE1fM19MRVZFTF9DVExf TUFTS19TRlQsDQorCQkJICAgMHgxIDw8IFVMX1NETV8zX0xFVkVMX0NUTF9TRlQpOw0KKwlyZWdt YXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsIHJlZywNCisJCQkgICBVTF9NT0RFXzNQMjVNX0NI MV9DVExfTUFTS19TRlQsDQorCQkJICAgMHgxIDw8IFVMX01PREVfM1AyNU1fQ0gxX0NUTF9TRlQp Ow0KKwlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsIHJlZywNCisJCQkgICBVTF9NT0RF XzNQMjVNX0NIMl9DVExfTUFTS19TRlQsDQorCQkJICAgMHgxIDw8IFVMX01PREVfM1AyNU1fQ0gy X0NUTF9TRlQpOw0KKwlyZXR1cm4gMDsNCit9DQorDQorc3RhdGljIGludCBtdGtfYWRkYV91bF9l dmVudChzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCAqdywNCisJCQkgICAgIHN0cnVjdCBzbmRf a2NvbnRyb2wgKmtjb250cm9sLA0KKwkJCSAgICAgaW50IGV2ZW50KQ0KK3sNCisJc3RydWN0IHNu ZF9zb2NfY29tcG9uZW50ICpjbXBudCA9IHNuZF9zb2NfZGFwbV90b19jb21wb25lbnQody0+ZGFw bSk7DQorCXN0cnVjdCBtdGtfYmFzZV9hZmUgKmFmZSA9IHNuZF9zb2NfY29tcG9uZW50X2dldF9k cnZkYXRhKGNtcG50KTsNCisJc3RydWN0IG10ODE5Ml9hZmVfcHJpdmF0ZSAqYWZlX3ByaXYgPSBh ZmUtPnBsYXRmb3JtX3ByaXY7DQorCWludCBtdGthaWZfZG1pYyA9IGFmZV9wcml2LT5tdGthaWZf ZG1pYzsNCisNCisJZGV2X2luZm8oYWZlLT5kZXYsICIlcygpLCBuYW1lICVzLCBldmVudCAweCV4 LCBtdGthaWZfZG1pYyAlZFxuIiwNCisJCSBfX2Z1bmNfXywgdy0+bmFtZSwgZXZlbnQsIG10a2Fp Zl9kbWljKTsNCisNCisJc3dpdGNoIChldmVudCkgew0KKwljYXNlIFNORF9TT0NfREFQTV9QUkVf UE1VOg0KKwkJbXQ4MTkyX2FmZV9ncGlvX3JlcXVlc3QoYWZlLT5kZXYsIHRydWUsIE1UODE5Ml9E QUlfQUREQSwgMSk7DQorDQorCQkvKiB1cGRhdGUgc2V0dGluZyB0byBkbWljICovDQorCQlpZiAo bXRrYWlmX2RtaWMpIHsNCisJCQkvKiBtdGthaWZfcnhpZl9kYXRhX21vZGUgPSAxLCBkbWljICov DQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLCBBRkVfQUREQV9NVEtBSUZfUlhf Q0ZHMCwNCisJCQkJCSAgIDB4MSwgMHgxKTsNCisNCisJCQkvKiBkbWljIG1vZGUsIDMuMjVNKi8N CisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsIEFGRV9BRERBX01US0FJRl9SWF9D RkcwLA0KKwkJCQkJICAgTVRLQUlGX1JYSUZfVk9JQ0VfTU9ERV9NQVNLX1NGVCwNCisJCQkJCSAg IDB4MCk7DQorCQkJbXRrX2FkZGFfdWxfc3JjX2RtaWMoYWZlLCBNVDgxOTJfREFJX0FEREEpOw0K KwkJfQ0KKwkJYnJlYWs7DQorCWNhc2UgU05EX1NPQ19EQVBNX1BPU1RfUE1EOg0KKwkJLyogc2hv dWxkIGRlbGF5ZWQgMS9mcyhzbWFsbGVzdCBpcyA4aykgPSAxMjV1cyBiZWZvcmUgYWZlIG9mZiAq Lw0KKwkJdXNsZWVwX3JhbmdlKDEyNSwgMTM1KTsNCisJCW10ODE5Ml9hZmVfZ3Bpb19yZXF1ZXN0 KGFmZS0+ZGV2LCBmYWxzZSwgTVQ4MTkyX0RBSV9BRERBLCAxKTsNCisJCWJyZWFrOw0KKwlkZWZh dWx0Og0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBpbnQg bXRrX2FkZGFfY2gzNF91bF9ldmVudChzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCAqdywNCisJ CQkJICBzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJCQkJICBpbnQgZXZlbnQpDQor ew0KKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19kYXBtX3RvX2Nv bXBvbmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19j b21wb25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRl ICphZmVfcHJpdiA9IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisJaW50IG10a2FpZl9kbWljID0gYWZl X3ByaXYtPm10a2FpZl9kbWljX2NoMzQ7DQorCWludCBtdGthaWZfYWRkYTZfb25seSA9IGFmZV9w cml2LT5tdGthaWZfYWRkYTZfb25seTsNCisNCisJZGV2X2luZm8oYWZlLT5kZXYsDQorCQkgIiVz KCksIG5hbWUgJXMsIGV2ZW50IDB4JXgsIG10a2FpZl9kbWljICVkLCBtdGthaWZfYWRkYTZfb25s eSAlZFxuIiwNCisJCSBfX2Z1bmNfXywgdy0+bmFtZSwgZXZlbnQsIG10a2FpZl9kbWljLCBtdGth aWZfYWRkYTZfb25seSk7DQorDQorCXN3aXRjaCAoZXZlbnQpIHsNCisJY2FzZSBTTkRfU09DX0RB UE1fUFJFX1BNVToNCisJCW10ODE5Ml9hZmVfZ3Bpb19yZXF1ZXN0KGFmZS0+ZGV2LCB0cnVlLCBN VDgxOTJfREFJX0FEREFfQ0gzNCwNCisJCQkJCTEpOw0KKw0KKwkJLyogdXBkYXRlIHNldHRpbmcg dG8gZG1pYyAqLw0KKwkJaWYgKG10a2FpZl9kbWljKSB7DQorCQkJLyogbXRrYWlmX3J4aWZfZGF0 YV9tb2RlID0gMSwgZG1pYyAqLw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwN CisJCQkJCSAgIEFGRV9BRERBNl9NVEtBSUZfUlhfQ0ZHMCwNCisJCQkJCSAgIDB4MSwgMHgxKTsN CisNCisJCQkvKiBkbWljIG1vZGUsIDMuMjVNKi8NCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZl LT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQTZfTVRLQUlGX1JYX0NGRzAsDQorCQkJCQkgICBN VEtBSUZfUlhJRl9WT0lDRV9NT0RFX01BU0tfU0ZULA0KKwkJCQkJICAgMHgwKTsNCisJCQltdGtf YWRkYV91bF9zcmNfZG1pYyhhZmUsIE1UODE5Ml9EQUlfQUREQV9DSDM0KTsNCisJCX0NCisNCisJ CS8qIHdoZW4gdXNpbmcgYWRkYTYgd2l0aG91dCBhZGRhIGVuYWJsZWQsDQorCQkgKiBSR19BRERB Nl9NVEtBSUZfUlhfU1lOQ19XT1JEMl9ESVNBQkxFX1NGVCBuZWVkIHRvIGJlIHNldCBvcg0KKwkJ ICogZGF0YSBjYW5ub3QgYmUgcmVjZWl2ZWQuDQorCQkgKi8NCisJCWlmIChtdGthaWZfYWRkYTZf b25seSkgew0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJCSAgIEFG RV9BRERBX01US0FJRl9TWU5DV09SRF9DRkcsDQorCQkJCQkgICAweDEgPDwgMjMsIDB4MSA8PCAy Myk7DQorCQl9DQorCQlicmVhazsNCisJY2FzZSBTTkRfU09DX0RBUE1fUE9TVF9QTUQ6DQorCQkv KiBzaG91bGQgZGVsYXllZCAxL2ZzKHNtYWxsZXN0IGlzIDhrKSA9IDEyNXVzIGJlZm9yZSBhZmUg b2ZmICovDQorCQl1c2xlZXBfcmFuZ2UoMTI1LCAxMzUpOw0KKwkJbXQ4MTkyX2FmZV9ncGlvX3Jl cXVlc3QoYWZlLT5kZXYsIGZhbHNlLCBNVDgxOTJfREFJX0FEREFfQ0gzNCwNCisJCQkJCTEpOw0K Kw0KKwkJLyogcmVzZXQgZG1pYyAqLw0KKwkJYWZlX3ByaXYtPm10a2FpZl9kbWljX2NoMzQgPSAw Ow0KKw0KKwkJaWYgKG10a2FpZl9hZGRhNl9vbmx5KSB7DQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRz KGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgQUZFX0FEREFfTVRLQUlGX1NZTkNXT1JEX0NGRywNCisJ CQkJCSAgIDB4MSA8PCAyMywgMHgwIDw8IDIzKTsNCisJCX0NCisJCWJyZWFrOw0KKwlkZWZhdWx0 Og0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBpbnQgbXRr X2FkZGFfcGFkX3RvcF9ldmVudChzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCAqdywNCisJCQkJ ICBzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJCQkJICBpbnQgZXZlbnQpDQorew0K KwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19kYXBtX3RvX2NvbXBv bmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19jb21w b25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRlICph ZmVfcHJpdiA9IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisNCisJc3dpdGNoIChldmVudCkgew0KKwlj YXNlIFNORF9TT0NfREFQTV9QUkVfUE1VOg0KKwkJaWYgKGFmZV9wcml2LT5tdGthaWZfcHJvdG9j b2wgPT0gTVRLQUlGX1BST1RPQ09MXzJfQ0xLX1AyKQ0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJl Z21hcCwgQUZFX0FVRF9QQURfVE9QLCAweDM4KTsNCisJCWVsc2UgaWYgKGFmZV9wcml2LT5tdGth aWZfcHJvdG9jb2wgPT0gTVRLQUlGX1BST1RPQ09MXzIpDQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+ cmVnbWFwLCBBRkVfQVVEX1BBRF9UT1AsIDB4MzApOw0KKwkJZWxzZQ0KKwkJCXJlZ21hcF93cml0 ZShhZmUtPnJlZ21hcCwgQUZFX0FVRF9QQURfVE9QLCAweDMwKTsNCisJCWJyZWFrOw0KKwlkZWZh dWx0Og0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBpbnQg bXRrX2FkZGFfbXRrYWlmX2NmZ19ldmVudChzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCAqdywN CisJCQkJICAgICBzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJCQkJICAgICBpbnQg ZXZlbnQpDQorew0KKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19k YXBtX3RvX2NvbXBvbmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0g c25kX3NvY19jb21wb25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2Fm ZV9wcml2YXRlICphZmVfcHJpdiA9IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisJaW50IGRlbGF5X2Rh dGE7DQorCWludCBkZWxheV9jeWNsZTsNCisNCisJc3dpdGNoIChldmVudCkgew0KKwljYXNlIFNO RF9TT0NfREFQTV9QUkVfUE1VOg0KKwkJaWYgKGFmZV9wcml2LT5tdGthaWZfcHJvdG9jb2wgPT0g TVRLQUlGX1BST1RPQ09MXzJfQ0xLX1AyKSB7DQorCQkJLyogc2V0IHByb3RvY29sIDIgKi8NCisJ CQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsIEFGRV9BRERBX01US0FJRl9DRkcwLA0KKwkJCQkg ICAgIDB4MDAwMTAwMDApOw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwgQUZFX0FEREE2 X01US0FJRl9DRkcwLA0KKwkJCQkgICAgIDB4MDAwMTAwMDApOw0KKw0KKwkJCWlmIChzdHJjbXAo dy0+bmFtZSwgIkFEREFfTVRLQUlGX0NGRyIpID09IDAgJiYNCisJCQkgICAgKGFmZV9wcml2LT5t dGthaWZfY2hvc2VuX3BoYXNlWzBdIDwgMCB8fA0KKwkJCSAgICAgYWZlX3ByaXYtPm10a2FpZl9j aG9zZW5fcGhhc2VbMV0gPCAwKSkgew0KKwkJCQlkZXZfd2FybihhZmUtPmRldiwNCisJCQkJCSAi JXMoKSwgbXRrYWlmX2Nob3Nlbl9waGFzZVswLzFdOiVkLyVkXG4iLA0KKwkJCQkJIF9fZnVuY19f LA0KKwkJCQkJIGFmZV9wcml2LT5tdGthaWZfY2hvc2VuX3BoYXNlWzBdLA0KKwkJCQkJIGFmZV9w cml2LT5tdGthaWZfY2hvc2VuX3BoYXNlWzFdKTsNCisJCQkJYnJlYWs7DQorCQkJfSBlbHNlIGlm IChzdHJjbXAody0+bmFtZSwgIkFEREE2X01US0FJRl9DRkciKSA9PSAwICYmDQorCQkJCSAgIGFm ZV9wcml2LT5tdGthaWZfY2hvc2VuX3BoYXNlWzJdIDwgMCkgew0KKwkJCQlkZXZfd2FybihhZmUt PmRldiwNCisJCQkJCSAiJXMoKSwgbXRrYWlmX2Nob3Nlbl9waGFzZVsyXTolZFxuIiwNCisJCQkJ CSBfX2Z1bmNfXywNCisJCQkJCSBhZmVfcHJpdi0+bXRrYWlmX2Nob3Nlbl9waGFzZVsyXSk7DQor CQkJCWJyZWFrOw0KKwkJCX0NCisNCisJCQkvKiBtdGthaWZfcnhpZl9jbGtpbnZfYWRjIGludmVy c2UgZm9yIGNhbGlicmF0aW9uICovDQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFw LCBBRkVfQUREQV9NVEtBSUZfQ0ZHMCwNCisJCQkJCSAgIE1US0FJRl9SWElGX0NMS0lOVl9BRENf TUFTS19TRlQsDQorCQkJCQkgICAweDEgPDwgTVRLQUlGX1JYSUZfQ0xLSU5WX0FEQ19TRlQpOw0K KwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwgQUZFX0FEREE2X01US0FJRl9DRkcw LA0KKwkJCQkJICAgTVRLQUlGX1JYSUZfQ0xLSU5WX0FEQ19NQVNLX1NGVCwNCisJCQkJCSAgIDB4 MSA8PCBNVEtBSUZfUlhJRl9DTEtJTlZfQURDX1NGVCk7DQorDQorCQkJLyogc2V0IGRlbGF5IGZv ciBjaDEyICovDQorCQkJaWYgKGFmZV9wcml2LT5tdGthaWZfcGhhc2VfY3ljbGVbMF0gPj0NCisJ CQkgICAgYWZlX3ByaXYtPm10a2FpZl9waGFzZV9jeWNsZVsxXSkgew0KKwkJCQlkZWxheV9kYXRh ID0gREVMQVlfREFUQV9NSVNPMTsNCisJCQkJZGVsYXlfY3ljbGUgPSBhZmVfcHJpdi0+bXRrYWlm X3BoYXNlX2N5Y2xlWzBdIC0NCisJCQkJCSAgICAgIGFmZV9wcml2LT5tdGthaWZfcGhhc2VfY3lj bGVbMV07DQorCQkJfSBlbHNlIHsNCisJCQkJZGVsYXlfZGF0YSA9IERFTEFZX0RBVEFfTUlTTzI7 DQorCQkJCWRlbGF5X2N5Y2xlID0gYWZlX3ByaXYtPm10a2FpZl9waGFzZV9jeWNsZVsxXSAtDQor CQkJCQkgICAgICBhZmVfcHJpdi0+bXRrYWlmX3BoYXNlX2N5Y2xlWzBdOw0KKwkJCX0NCisNCisJ CQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQV9NVEtB SUZfUlhfQ0ZHMiwNCisJCQkJCSAgIE1US0FJRl9SWElGX0RFTEFZX0RBVEFfTUFTS19TRlQsDQor CQkJCQkgICBkZWxheV9kYXRhIDw8DQorCQkJCQkgICBNVEtBSUZfUlhJRl9ERUxBWV9EQVRBX1NG VCk7DQorDQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgQUZF X0FEREFfTVRLQUlGX1JYX0NGRzIsDQorCQkJCQkgICBNVEtBSUZfUlhJRl9ERUxBWV9DWUNMRV9N QVNLX1NGVCwNCisJCQkJCSAgIGRlbGF5X2N5Y2xlIDw8DQorCQkJCQkgICBNVEtBSUZfUlhJRl9E RUxBWV9DWUNMRV9TRlQpOw0KKw0KKwkJCS8qIHNldCBkZWxheSBiZXR3ZWVuIGNoMyBhbmQgY2gy ICovDQorCQkJaWYgKGFmZV9wcml2LT5tdGthaWZfcGhhc2VfY3ljbGVbMl0gPj0NCisJCQkgICAg YWZlX3ByaXYtPm10a2FpZl9waGFzZV9jeWNsZVsxXSkgew0KKwkJCQlkZWxheV9kYXRhID0gREVM QVlfREFUQV9NSVNPMTsJLyogY2gzICovDQorCQkJCWRlbGF5X2N5Y2xlID0gYWZlX3ByaXYtPm10 a2FpZl9waGFzZV9jeWNsZVsyXSAtDQorCQkJCQkgICAgICBhZmVfcHJpdi0+bXRrYWlmX3BoYXNl X2N5Y2xlWzFdOw0KKwkJCX0gZWxzZSB7DQorCQkJCWRlbGF5X2RhdGEgPSBERUxBWV9EQVRBX01J U08yOwkvKiBjaDIgKi8NCisJCQkJZGVsYXlfY3ljbGUgPSBhZmVfcHJpdi0+bXRrYWlmX3BoYXNl X2N5Y2xlWzFdIC0NCisJCQkJCSAgICAgIGFmZV9wcml2LT5tdGthaWZfcGhhc2VfY3ljbGVbMl07 DQorCQkJfQ0KKw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJCSAg IEFGRV9BRERBNl9NVEtBSUZfUlhfQ0ZHMiwNCisJCQkJCSAgIE1US0FJRl9SWElGX0RFTEFZX0RB VEFfTUFTS19TRlQsDQorCQkJCQkgICBkZWxheV9kYXRhIDw8DQorCQkJCQkgICBNVEtBSUZfUlhJ Rl9ERUxBWV9EQVRBX1NGVCk7DQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0K KwkJCQkJICAgQUZFX0FEREE2X01US0FJRl9SWF9DRkcyLA0KKwkJCQkJICAgTVRLQUlGX1JYSUZf REVMQVlfQ1lDTEVfTUFTS19TRlQsDQorCQkJCQkgICBkZWxheV9jeWNsZSA8PA0KKwkJCQkJICAg TVRLQUlGX1JYSUZfREVMQVlfQ1lDTEVfU0ZUKTsNCisJCX0gZWxzZSBpZiAoYWZlX3ByaXYtPm10 a2FpZl9wcm90b2NvbCA9PSBNVEtBSUZfUFJPVE9DT0xfMikgew0KKwkJCXJlZ21hcF93cml0ZShh ZmUtPnJlZ21hcCwgQUZFX0FEREFfTVRLQUlGX0NGRzAsDQorCQkJCSAgICAgMHgwMDAxMDAwMCk7 DQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLCBBRkVfQUREQTZfTVRLQUlGX0NGRzAsDQor CQkJCSAgICAgMHgwMDAxMDAwMCk7DQorCQl9IGVsc2Ugew0KKwkJCXJlZ21hcF93cml0ZShhZmUt PnJlZ21hcCwgQUZFX0FEREFfTVRLQUlGX0NGRzAsIDB4MCk7DQorCQkJcmVnbWFwX3dyaXRlKGFm ZS0+cmVnbWFwLCBBRkVfQUREQTZfTVRLQUlGX0NGRzAsIDB4MCk7DQorCQl9DQorCQlicmVhazsN CisJZGVmYXVsdDoNCisJCWJyZWFrOw0KKwl9DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0 aWMgaW50IG10a19hZGRhX2RsX2V2ZW50KHN0cnVjdCBzbmRfc29jX2RhcG1fd2lkZ2V0ICp3LA0K KwkJCSAgICAgc3RydWN0IHNuZF9rY29udHJvbCAqa2NvbnRyb2wsDQorCQkJICAgICBpbnQgZXZl bnQpDQorew0KKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19kYXBt X3RvX2NvbXBvbmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25k X3NvY19jb21wb25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKw0KKwlkZXZfaW5mbyhhZmUtPmRl diwgIiVzKCksIG5hbWUgJXMsIGV2ZW50IDB4JXhcbiIsDQorCQkgX19mdW5jX18sIHctPm5hbWUs IGV2ZW50KTsNCisNCisJc3dpdGNoIChldmVudCkgew0KKwljYXNlIFNORF9TT0NfREFQTV9QUkVf UE1VOg0KKwkJbXQ4MTkyX2FmZV9ncGlvX3JlcXVlc3QoYWZlLT5kZXYsIHRydWUsIE1UODE5Ml9E QUlfQUREQSwgMCk7DQorCQlicmVhazsNCisJY2FzZSBTTkRfU09DX0RBUE1fUE9TVF9QTUQ6DQor CQkvKiBzaG91bGQgZGVsYXllZCAxL2ZzKHNtYWxsZXN0IGlzIDhrKSA9IDEyNXVzIGJlZm9yZSBh ZmUgb2ZmICovDQorCQl1c2xlZXBfcmFuZ2UoMTI1LCAxMzUpOw0KKwkJbXQ4MTkyX2FmZV9ncGlv X3JlcXVlc3QoYWZlLT5kZXYsIGZhbHNlLCBNVDgxOTJfREFJX0FEREEsIDApOw0KKwkJYnJlYWs7 DQorCWRlZmF1bHQ6DQorCQlicmVhazsNCisJfQ0KKw0KKwlyZXR1cm4gMDsNCit9DQorDQorc3Rh dGljIGludCBtdGtfYWRkYV9jaDM0X2RsX2V2ZW50KHN0cnVjdCBzbmRfc29jX2RhcG1fd2lkZ2V0 ICp3LA0KKwkJCQkgIHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtjb250cm9sLA0KKwkJCQkgIGludCBl dmVudCkNCit7DQorCXN0cnVjdCBzbmRfc29jX2NvbXBvbmVudCAqY21wbnQgPSBzbmRfc29jX2Rh cG1fdG9fY29tcG9uZW50KHctPmRhcG0pOw0KKwlzdHJ1Y3QgbXRrX2Jhc2VfYWZlICphZmUgPSBz bmRfc29jX2NvbXBvbmVudF9nZXRfZHJ2ZGF0YShjbXBudCk7DQorDQorCWRldl9pbmZvKGFmZS0+ ZGV2LCAiJXMoKSwgbmFtZSAlcywgZXZlbnQgMHgleFxuIiwNCisJCSBfX2Z1bmNfXywgdy0+bmFt ZSwgZXZlbnQpOw0KKw0KKwlzd2l0Y2ggKGV2ZW50KSB7DQorCWNhc2UgU05EX1NPQ19EQVBNX1BS RV9QTVU6DQorCQltdDgxOTJfYWZlX2dwaW9fcmVxdWVzdChhZmUtPmRldiwgdHJ1ZSwgTVQ4MTky X0RBSV9BRERBX0NIMzQsDQorCQkJCQkwKTsNCisJCWJyZWFrOw0KKwljYXNlIFNORF9TT0NfREFQ TV9QT1NUX1BNRDoNCisJCS8qIHNob3VsZCBkZWxheWVkIDEvZnMoc21hbGxlc3QgaXMgOGspID0g MTI1dXMgYmVmb3JlIGFmZSBvZmYgKi8NCisJCXVzbGVlcF9yYW5nZSgxMjUsIDEzNSk7DQorCQlt dDgxOTJfYWZlX2dwaW9fcmVxdWVzdChhZmUtPmRldiwgZmFsc2UsIE1UODE5Ml9EQUlfQUREQV9D SDM0LA0KKwkJCQkJMCk7DQorCQlicmVhazsNCisJZGVmYXVsdDoNCisJCWJyZWFrOw0KKwl9DQor DQorCXJldHVybiAwOw0KK30NCisNCisvKiBzdGYgKi8NCitzdGF0aWMgaW50IHN0Zl9wb3NpdGl2 ZV9nYWluX2dldChzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJCQkJIHN0cnVjdCBz bmRfY3RsX2VsZW1fdmFsdWUgKnVjb250cm9sKQ0KK3sNCisJc3RydWN0IHNuZF9zb2NfY29tcG9u ZW50ICpjbXBudCA9IHNuZF9zb2Nfa2NvbnRyb2xfY29tcG9uZW50KGtjb250cm9sKTsNCisJc3Ry dWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19jb21wb25lbnRfZ2V0X2RydmRhdGEoY21w bnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRlICphZmVfcHJpdiA9IGFmZS0+cGxhdGZv cm1fcHJpdjsNCisNCisJdWNvbnRyb2wtPnZhbHVlLmludGVnZXIudmFsdWVbMF0gPSBhZmVfcHJp di0+c3RmX3Bvc2l0aXZlX2dhaW5fZGI7DQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgaW50 IHN0Zl9wb3NpdGl2ZV9nYWluX3NldChzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJ CQkJIHN0cnVjdCBzbmRfY3RsX2VsZW1fdmFsdWUgKnVjb250cm9sKQ0KK3sNCisJc3RydWN0IHNu ZF9zb2NfY29tcG9uZW50ICpjbXBudCA9IHNuZF9zb2Nfa2NvbnRyb2xfY29tcG9uZW50KGtjb250 cm9sKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19jb21wb25lbnRfZ2V0 X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRlICphZmVfcHJpdiA9 IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisJaW50IGdhaW5fZGIgPSB1Y29udHJvbC0+dmFsdWUuaW50 ZWdlci52YWx1ZVswXTsNCisNCisJYWZlX3ByaXYtPnN0Zl9wb3NpdGl2ZV9nYWluX2RiID0gZ2Fp bl9kYjsNCisNCisJaWYgKGdhaW5fZGIgPj0gMCAmJiBnYWluX2RiIDw9IDI0KSB7DQorCQlyZWdt YXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCSAgIEFGRV9TSURFVE9ORV9HQUlOLA0K KwkJCQkgICBQT1NJVElWRV9HQUlOX01BU0tfU0ZULA0KKwkJCQkgICAoZ2Fpbl9kYiAvIDYpIDw8 IFBPU0lUSVZFX0dBSU5fU0ZUKTsNCisJfSBlbHNlIHsNCisJCWRldl93YXJuKGFmZS0+ZGV2LCAi JXMoKSwgZ2Fpbl9kYiAlZCBpbnZhbGlkXG4iLA0KKwkJCSBfX2Z1bmNfXywgZ2Fpbl9kYik7DQor CX0NCisJcmV0dXJuIDA7DQorfQ0KKw0KKy8qIG10a2FpZiBkbWljICovDQorc3RhdGljIGNvbnN0 IGNoYXIgKiBjb25zdCBtdDgxOTJfYWRkYV9vZmZfb25fc3RyW10gPSB7DQorCSJPZmYiLCAiT24i DQorfTsNCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IHNvY19lbnVtIG10ODE5Ml9hZGRhX2VudW1b XSA9IHsNCisJU09DX0VOVU1fU0lOR0xFX0VYVChBUlJBWV9TSVpFKG10ODE5Ml9hZGRhX29mZl9v bl9zdHIpLA0KKwkJCSAgICBtdDgxOTJfYWRkYV9vZmZfb25fc3RyKSwNCit9Ow0KKw0KK3N0YXRp YyBpbnQgbXQ4MTkyX2FkZGFfZG1pY19nZXQoc3RydWN0IHNuZF9rY29udHJvbCAqa2NvbnRyb2ws DQorCQkJCXN0cnVjdCBzbmRfY3RsX2VsZW1fdmFsdWUgKnVjb250cm9sKQ0KK3sNCisJc3RydWN0 IHNuZF9zb2NfY29tcG9uZW50ICpjbXBudCA9IHNuZF9zb2Nfa2NvbnRyb2xfY29tcG9uZW50KGtj b250cm9sKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19jb21wb25lbnRf Z2V0X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRlICphZmVfcHJp diA9IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisNCisJdWNvbnRyb2wtPnZhbHVlLmludGVnZXIudmFs dWVbMF0gPSBhZmVfcHJpdi0+bXRrYWlmX2RtaWM7DQorCXJldHVybiAwOw0KK30NCisNCitzdGF0 aWMgaW50IG10ODE5Ml9hZGRhX2RtaWNfc2V0KHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtjb250cm9s LA0KKwkJCQlzdHJ1Y3Qgc25kX2N0bF9lbGVtX3ZhbHVlICp1Y29udHJvbCkNCit7DQorCXN0cnVj dCBzbmRfc29jX2NvbXBvbmVudCAqY21wbnQgPSBzbmRfc29jX2tjb250cm9sX2NvbXBvbmVudChr Y29udHJvbCk7DQorCXN0cnVjdCBtdGtfYmFzZV9hZmUgKmFmZSA9IHNuZF9zb2NfY29tcG9uZW50 X2dldF9kcnZkYXRhKGNtcG50KTsNCisJc3RydWN0IG10ODE5Ml9hZmVfcHJpdmF0ZSAqYWZlX3By aXYgPSBhZmUtPnBsYXRmb3JtX3ByaXY7DQorCXN0cnVjdCBzb2NfZW51bSAqZSA9IChzdHJ1Y3Qg c29jX2VudW0gKilrY29udHJvbC0+cHJpdmF0ZV92YWx1ZTsNCisJaW50IGRtaWNfb247DQorDQor CWlmICh1Y29udHJvbC0+dmFsdWUuZW51bWVyYXRlZC5pdGVtWzBdID49IGUtPml0ZW1zKQ0KKwkJ cmV0dXJuIC1FSU5WQUw7DQorDQorCWRtaWNfb24gPSB1Y29udHJvbC0+dmFsdWUuaW50ZWdlci52 YWx1ZVswXTsNCisNCisJZGV2X2luZm8oYWZlLT5kZXYsICIlcygpLCBrY29udHJvbCBuYW1lICVz LCBkbWljX29uICVkXG4iLA0KKwkJIF9fZnVuY19fLCBrY29udHJvbC0+aWQubmFtZSwgZG1pY19v bik7DQorDQorCWFmZV9wcml2LT5tdGthaWZfZG1pYyA9IGRtaWNfb247DQorCWFmZV9wcml2LT5t dGthaWZfZG1pY19jaDM0ID0gZG1pY19vbjsNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBp bnQgbXQ4MTkyX2FkZGE2X29ubHlfZ2V0KHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtjb250cm9sLA0K KwkJCQkgc3RydWN0IHNuZF9jdGxfZWxlbV92YWx1ZSAqdWNvbnRyb2wpDQorew0KKwlzdHJ1Y3Qg c25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19rY29udHJvbF9jb21wb25lbnQoa2Nv bnRyb2wpOw0KKwlzdHJ1Y3QgbXRrX2Jhc2VfYWZlICphZmUgPSBzbmRfc29jX2NvbXBvbmVudF9n ZXRfZHJ2ZGF0YShjbXBudCk7DQorCXN0cnVjdCBtdDgxOTJfYWZlX3ByaXZhdGUgKmFmZV9wcml2 ID0gYWZlLT5wbGF0Zm9ybV9wcml2Ow0KKw0KKwl1Y29udHJvbC0+dmFsdWUuaW50ZWdlci52YWx1 ZVswXSA9IGFmZV9wcml2LT5tdGthaWZfYWRkYTZfb25seTsNCisJcmV0dXJuIDA7DQorfQ0KKw0K K3N0YXRpYyBpbnQgbXQ4MTkyX2FkZGE2X29ubHlfc2V0KHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtj b250cm9sLA0KKwkJCQkgc3RydWN0IHNuZF9jdGxfZWxlbV92YWx1ZSAqdWNvbnRyb2wpDQorew0K KwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19rY29udHJvbF9jb21w b25lbnQoa2NvbnRyb2wpOw0KKwlzdHJ1Y3QgbXRrX2Jhc2VfYWZlICphZmUgPSBzbmRfc29jX2Nv bXBvbmVudF9nZXRfZHJ2ZGF0YShjbXBudCk7DQorCXN0cnVjdCBtdDgxOTJfYWZlX3ByaXZhdGUg KmFmZV9wcml2ID0gYWZlLT5wbGF0Zm9ybV9wcml2Ow0KKwlzdHJ1Y3Qgc29jX2VudW0gKmUgPSAo c3RydWN0IHNvY19lbnVtICopa2NvbnRyb2wtPnByaXZhdGVfdmFsdWU7DQorCWludCBtdGthaWZf YWRkYTZfb25seTsNCisNCisJaWYgKHVjb250cm9sLT52YWx1ZS5lbnVtZXJhdGVkLml0ZW1bMF0g Pj0gZS0+aXRlbXMpDQorCQlyZXR1cm4gLUVJTlZBTDsNCisNCisJbXRrYWlmX2FkZGE2X29ubHkg PSB1Y29udHJvbC0+dmFsdWUuaW50ZWdlci52YWx1ZVswXTsNCisNCisJZGV2X2luZm8oYWZlLT5k ZXYsICIlcygpLCBrY29udHJvbCBuYW1lICVzLCBtdGthaWZfYWRkYTZfb25seSAlZFxuIiwNCisJ CSBfX2Z1bmNfXywga2NvbnRyb2wtPmlkLm5hbWUsIG10a2FpZl9hZGRhNl9vbmx5KTsNCisNCisJ YWZlX3ByaXYtPm10a2FpZl9hZGRhNl9vbmx5ID0gbXRrYWlmX2FkZGE2X29ubHk7DQorCXJldHVy biAwOw0KK30NCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IHNuZF9rY29udHJvbF9uZXcgbXRrX2Fk ZGFfY29udHJvbHNbXSA9IHsNCisJU09DX1NJTkdMRSgiU2lkZXRvbmVfR2FpbiIsIEFGRV9TSURF VE9ORV9HQUlOLA0KKwkJICAgU0lERV9UT05FX0dBSU5fU0ZULCBTSURFX1RPTkVfR0FJTl9NQVNL LCAwKSwNCisJU09DX1NJTkdMRV9FWFQoIlNpZGV0b25lX1Bvc2l0aXZlX0dhaW5fZEIiLCBTTkRf U09DX05PUE0sIDAsIDEwMCwgMCwNCisJCSAgICAgICBzdGZfcG9zaXRpdmVfZ2Fpbl9nZXQsIHN0 Zl9wb3NpdGl2ZV9nYWluX3NldCksDQorCVNPQ19TSU5HTEUoIkFEREFfRExfR0FJTiIsIEFGRV9B RERBX0RMX1NSQzJfQ09OMSwNCisJCSAgIERMXzJfR0FJTl9DVExfUFJFX1NGVCwgRExfMl9HQUlO X0NUTF9QUkVfTUFTSywgMCksDQorCVNPQ19FTlVNX0VYVCgiTVRLQUlGX0RNSUMiLCBtdDgxOTJf YWRkYV9lbnVtWzBdLA0KKwkJICAgICBtdDgxOTJfYWRkYV9kbWljX2dldCwgbXQ4MTkyX2FkZGFf ZG1pY19zZXQpLA0KKwlTT0NfRU5VTV9FWFQoIk1US0FJRl9BRERBNl9PTkxZIiwgbXQ4MTkyX2Fk ZGFfZW51bVswXSwNCisJCSAgICAgbXQ4MTkyX2FkZGE2X29ubHlfZ2V0LCBtdDgxOTJfYWRkYTZf b25seV9zZXQpLA0KK307DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3 IHN0Zl9jdGwgPQ0KKwlTT0NfREFQTV9TSU5HTEUoIlN3aXRjaCIsIFNORF9TT0NfTk9QTSwgMCwg MSwgMCk7DQorDQorc3RhdGljIGNvbnN0IHUxNiBzdGZfY29lZmZfdGFibGVfMTZrW10gPSB7DQor CTB4MDQ5QywgMHgwOUU4LCAweDA5RTAsIDB4MDg5QywNCisJMHhGRjU0LCAweEY0ODgsIDB4RUFG QywgMHhFQkFDLA0KKwkweGZBNDAsIDB4MTdBQywgMHgzRDFDLCAweDYwMjgsDQorCTB4NzUzOA0K K307DQorDQorc3RhdGljIGNvbnN0IHUxNiBzdGZfY29lZmZfdGFibGVfMzJrW10gPSB7DQorCTB4 RkU1MiwgMHgwMDQyLCAweDAwQzUsIDB4MDE5NCwNCisJMHgwMjlBLCAweDAzQjcsIDB4MDRCRiwg MHgwNTdELA0KKwkweDA1QkUsIDB4MDU1NSwgMHgwNDI2LCAweDAyMzAsDQorCTB4RkY5MiwgMHhG Qzg5LCAweEY5NzMsIDB4RjZDNiwNCisJMHhGNTAwLCAweEY0OUQsIDB4RjYwMywgMHhGOTcwLA0K KwkweEZFRjMsIDB4MDY1RiwgMHgwRjRGLCAweDE5MjgsDQorCTB4MjMyOSwgMHgyQzgwLCAweDM0 NUUsIDB4M0EwRCwNCisJMHgzRDA4DQorfTsNCisNCitzdGF0aWMgY29uc3QgdTE2IHN0Zl9jb2Vm Zl90YWJsZV80OGtbXSA9IHsNCisJMHgwNDAxLCAweEZGQjAsIDB4RkY1QSwgMHhGRUNFLA0KKwkw eEZFMTAsIDB4RkQyOCwgMHhGQzIxLCAweEZCMDgsDQorCTB4RjlFRiwgMHhGOEU4LCAweEY4MEEs IDB4Rjc2QywNCisJMHhGNzI0LCAweEY3NDYsIDB4RjdFNiwgMHhGOTBGLA0KKwkweEZBQ0MsIDB4 RkQxRSwgMHhGRkZGLCAweDAzNjQsDQorCTB4MDczNywgMHgwQjYyLCAweDBGQzEsIDB4MTQzMSwN CisJMHgxODhBLCAweDFDQTQsIDB4MjA1NiwgMHgyMzdELA0KKwkweDI1RjksIDB4MjdCMCwgMHgy ODkwDQorfTsNCisNCitzdGF0aWMgaW50IG10a19zdGZfZXZlbnQoc3RydWN0IHNuZF9zb2NfZGFw bV93aWRnZXQgKncsDQorCQkJIHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtjb250cm9sLA0KKwkJCSBp bnQgZXZlbnQpDQorew0KKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3Nv Y19kYXBtX3RvX2NvbXBvbmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZl ID0gc25kX3NvY19jb21wb25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKw0KKwlzaXplX3QgaGFs Zl90YXBfbnVtOw0KKwljb25zdCB1MTYgKnN0Zl9jb2VmZl90YWJsZTsNCisJdW5zaWduZWQgaW50 IHVsX3JhdGUsIHJlZ192YWx1ZTsNCisJc2l6ZV90IGNvZWZfYWRkcjsNCisNCisJcmVnbWFwX3Jl YWQoYWZlLT5yZWdtYXAsIEFGRV9BRERBX1VMX1NSQ19DT04wLCAmdWxfcmF0ZSk7DQorCXVsX3Jh dGUgPSB1bF9yYXRlID4+IFVMX1ZPSUNFX01PREVfQ0gxX0NIMl9DVExfU0ZUOw0KKwl1bF9yYXRl ID0gdWxfcmF0ZSAmIFVMX1ZPSUNFX01PREVfQ0gxX0NIMl9DVExfTUFTSzsNCisNCisJaWYgKHVs X3JhdGUgPT0gTVRLX0FGRV9BRERBX1VMX1JBVEVfNDhLKSB7DQorCQloYWxmX3RhcF9udW0gPSBB UlJBWV9TSVpFKHN0Zl9jb2VmZl90YWJsZV80OGspOw0KKwkJc3RmX2NvZWZmX3RhYmxlID0gc3Rm X2NvZWZmX3RhYmxlXzQ4azsNCisJfSBlbHNlIGlmICh1bF9yYXRlID09IE1US19BRkVfQUREQV9V TF9SQVRFXzMySykgew0KKwkJaGFsZl90YXBfbnVtID0gQVJSQVlfU0laRShzdGZfY29lZmZfdGFi bGVfMzJrKTsNCisJCXN0Zl9jb2VmZl90YWJsZSA9IHN0Zl9jb2VmZl90YWJsZV8zMms7DQorCX0g ZWxzZSB7DQorCQloYWxmX3RhcF9udW0gPSBBUlJBWV9TSVpFKHN0Zl9jb2VmZl90YWJsZV8xNmsp Ow0KKwkJc3RmX2NvZWZmX3RhYmxlID0gc3RmX2NvZWZmX3RhYmxlXzE2azsNCisJfQ0KKw0KKwly ZWdtYXBfcmVhZChhZmUtPnJlZ21hcCwgQUZFX1NJREVUT05FX0NPTjEsICZyZWdfdmFsdWUpOw0K Kw0KKwlkZXZfaW5mbyhhZmUtPmRldiwgIiVzKCksIG5hbWUgJXMsIGV2ZW50IDB4JXgsIHVsX3Jh dGUgMHgleCwgQUZFX1NJREVUT05FX0NPTjEgMHgleFxuIiwNCisJCSBfX2Z1bmNfXywgdy0+bmFt ZSwgZXZlbnQsIHVsX3JhdGUsIHJlZ192YWx1ZSk7DQorDQorCXN3aXRjaCAoZXZlbnQpIHsNCisJ Y2FzZSBTTkRfU09DX0RBUE1fUFJFX1BNVToNCisJCS8qIHNldCBzaWRlIHRvbmUgZ2FpbiA9IDAg Ki8NCisJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJICAgQUZFX1NJREVU T05FX0dBSU4sDQorCQkJCSAgIFNJREVfVE9ORV9HQUlOX01BU0tfU0ZULA0KKwkJCQkgICAwKTsN CisJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJICAgQUZFX1NJREVUT05F X0dBSU4sDQorCQkJCSAgIFBPU0lUSVZFX0dBSU5fTUFTS19TRlQsDQorCQkJCSAgIDApOw0KKwkJ LyogZG9uJ3QgYnlwYXNzIHN0ZiAqLw0KKwkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFw LA0KKwkJCQkgICBBRkVfU0lERVRPTkVfQ09OMSwNCisJCQkJICAgMHgxZiA8PCAyNywNCisJCQkJ ICAgMHgwKTsNCisJCS8qIHNldCBzdGYgaGFsZiB0YXAgbnVtICovDQorCQlyZWdtYXBfdXBkYXRl X2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCSAgIEFGRV9TSURFVE9ORV9DT04xLA0KKwkJCQkgICBT SURFX1RPTkVfSEFMRl9UQVBfTlVNX01BU0tfU0ZULA0KKwkJCQkgICBoYWxmX3RhcF9udW0gPDwg U0lERV9UT05FX0hBTEZfVEFQX05VTV9TRlQpOw0KKw0KKwkJLyogc2V0IHNpZGUgdG9uZSBjb2Vm ZmljaWVudCAqLw0KKwkJcmVnbWFwX3JlYWQoYWZlLT5yZWdtYXAsIEFGRV9TSURFVE9ORV9DT04w LCAmcmVnX3ZhbHVlKTsNCisJCWZvciAoY29lZl9hZGRyID0gMDsgY29lZl9hZGRyIDwgaGFsZl90 YXBfbnVtOyBjb2VmX2FkZHIrKykgew0KKwkJCWJvb2wgb2xkX3dfcmVhZHkgPSAocmVnX3ZhbHVl ID4+IFdfUkRZX1NGVCkgJiAweDE7DQorCQkJYm9vbCBuZXdfd19yZWFkeSA9IDA7DQorCQkJaW50 IHRyeV9jbnQgPSAwOw0KKw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJ CQkJCSAgIEFGRV9TSURFVE9ORV9DT04wLA0KKwkJCQkJICAgMHgzOUZGRkZGLA0KKwkJCQkJICAg KDEgPDwgUl9XX0VOX1NGVCkgfA0KKwkJCQkJICAgKDEgPDwgUl9XX1NFTF9TRlQpIHwNCisJCQkJ CSAgICgwIDw8IFNFTF9DSDJfU0ZUKSB8DQorCQkJCQkgICAoY29lZl9hZGRyIDw8DQorCQkJCQkg ICBTSURFX1RPTkVfQ09FRkZJQ0lFTlRfQUREUl9TRlQpIHwNCisJCQkJCSAgIHN0Zl9jb2VmZl90 YWJsZVtjb2VmX2FkZHJdKTsNCisNCisJCQkvKiB3YWl0IHVudGlsIGZsYWcgd3JpdGVfcmVhZHkg Y2hhbmdlZCAqLw0KKwkJCWZvciAodHJ5X2NudCA9IDA7IHRyeV9jbnQgPCAxMDsgdHJ5X2NudCsr KSB7DQorCQkJCXJlZ21hcF9yZWFkKGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgIEFGRV9TSURFVE9O RV9DT04wLCAmcmVnX3ZhbHVlKTsNCisJCQkJbmV3X3dfcmVhZHkgPSAocmVnX3ZhbHVlID4+IFdf UkRZX1NGVCkgJiAweDE7DQorDQorCQkJCS8qIGZsaXAgPT4gb2sgKi8NCisJCQkJaWYgKG5ld193 X3JlYWR5ID09IG9sZF93X3JlYWR5KSB7DQorCQkJCQl1ZGVsYXkoMyk7DQorCQkJCQlpZiAodHJ5 X2NudCA9PSA5KSB7DQorCQkJCQkJZGV2X3dhcm4oYWZlLT5kZXYsDQorCQkJCQkJCSAiJXMoKSwg d3JpdGUgY29lZmYgbm90IHJlYWR5IiwNCisJCQkJCQkJIF9fZnVuY19fKTsNCisJCQkJCX0NCisJ CQkJfSBlbHNlIHsNCisJCQkJCWJyZWFrOw0KKwkJCQl9DQorCQkJfQ0KKwkJCS8qIG5lZWQgd3Jp dGUgLT4gcmVhZCAtPiB3cml0ZSB0byB3cml0ZSBuZXh0IGNvZWZmICovDQorCQkJcmVnbWFwX3Vw ZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgQUZFX1NJREVUT05FX0NPTjAsDQorCQkJ CQkgICBSX1dfU0VMX01BU0tfU0ZULA0KKwkJCQkJICAgMHgwKTsNCisJCX0NCisJCWJyZWFrOw0K KwljYXNlIFNORF9TT0NfREFQTV9QT1NUX1BNRDoNCisJCS8qIGJ5cGFzcyBzdGYgKi8NCisJCXJl Z21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJICAgQUZFX1NJREVUT05FX0NPTjEs DQorCQkJCSAgIDB4MWYgPDwgMjcsDQorCQkJCSAgIDB4MWYgPDwgMjcpOw0KKw0KKwkJLyogc2V0 IHNpZGUgdG9uZSBnYWluID0gMCAqLw0KKwkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFw LA0KKwkJCQkgICBBRkVfU0lERVRPTkVfR0FJTiwNCisJCQkJICAgU0lERV9UT05FX0dBSU5fTUFT S19TRlQsDQorCQkJCSAgIDApOw0KKwkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0K KwkJCQkgICBBRkVfU0lERVRPTkVfR0FJTiwNCisJCQkJICAgUE9TSVRJVkVfR0FJTl9NQVNLX1NG VCwNCisJCQkJICAgMCk7DQorCQlicmVhazsNCisJZGVmYXVsdDoNCisJCWJyZWFrOw0KKwl9DQor DQorCXJldHVybiAwOw0KK30NCisNCisvKiBzdGYgbXV4ICovDQorZW51bSB7DQorCVNURl9TUkNf QUREQV9BRERBNiA9IDAsDQorCVNURl9TUkNfTzE5TzIwLA0KK307DQorDQorc3RhdGljIGNvbnN0 IGNoYXIgKmNvbnN0IHN0Zl9vMTlvMjBfbXV4X21hcFtdID0gew0KKwkiQUREQV9BRERBNiIsDQor CSJPMTlPMjAiLA0KK307DQorDQorc3RhdGljIGludCBzdGZfbzE5bzIwX211eF9tYXBfdmFsdWVb XSA9IHsNCisJU1RGX1NSQ19BRERBX0FEREE2LA0KKwlTVEZfU1JDX08xOU8yMCwNCit9Ow0KKw0K K3N0YXRpYyBTT0NfVkFMVUVfRU5VTV9TSU5HTEVfREVDTChzdGZfbzE5bzIwX211eF9tYXBfZW51 bSwNCisJCQkJICBBRkVfU0lERVRPTkVfQ09OMSwNCisJCQkJICBTVEZfU09VUkNFX0ZST01fTzE5 TzIwX1NGVCwNCisJCQkJICBTVEZfU09VUkNFX0ZST01fTzE5TzIwX01BU0ssDQorCQkJCSAgc3Rm X28xOW8yMF9tdXhfbWFwLA0KKwkJCQkgIHN0Zl9vMTlvMjBfbXV4X21hcF92YWx1ZSk7DQorDQor c3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IHN0Zl9vMTlPMjBfbXV4X2NvbnRy b2wgPQ0KKwlTT0NfREFQTV9FTlVNKCJTVEZfTzE5TzIwX01VWCIsIHN0Zl9vMTlvMjBfbXV4X21h cF9lbnVtKTsNCisNCitlbnVtIHsNCisJU1RGX1NSQ19BRERBID0gMCwNCisJU1RGX1NSQ19BRERB NiwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBjaGFyICpjb25zdCBzdGZfYWRkYV9tdXhfbWFwW10g PSB7DQorCSJBRERBIiwNCisJIkFEREE2IiwNCit9Ow0KKw0KK3N0YXRpYyBpbnQgc3RmX2FkZGFf bXV4X21hcF92YWx1ZVtdID0gew0KKwlTVEZfU1JDX0FEREEsDQorCVNURl9TUkNfQUREQTYsDQor fTsNCisNCitzdGF0aWMgU09DX1ZBTFVFX0VOVU1fU0lOR0xFX0RFQ0woc3RmX2FkZGFfbXV4X21h cF9lbnVtLA0KKwkJCQkgIEFGRV9TSURFVE9ORV9DT04xLA0KKwkJCQkgIFNURl9PMTlPMjBfT1VU X0VOX1NFTF9TRlQsDQorCQkJCSAgU1RGX08xOU8yMF9PVVRfRU5fU0VMX01BU0ssDQorCQkJCSAg c3RmX2FkZGFfbXV4X21hcCwNCisJCQkJICBzdGZfYWRkYV9tdXhfbWFwX3ZhbHVlKTsNCisNCitz dGF0aWMgY29uc3Qgc3RydWN0IHNuZF9rY29udHJvbF9uZXcgc3RmX2FkZGFfbXV4X2NvbnRyb2wg PQ0KKwlTT0NfREFQTV9FTlVNKCJTVEZfQUREQV9NVVgiLCBzdGZfYWRkYV9tdXhfbWFwX2VudW0p Ow0KKw0KKy8qIEFEREEgVUwgTVVYICovDQorZW51bSB7DQorCUFEREFfVUxfTVVYX01US0FJRiA9 IDAsDQorCUFEREFfVUxfTVVYX0FQX0RNSUMsDQorCUFEREFfVUxfTVVYX01BU0sgPSAweDEsDQor fTsNCisNCitzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGFkZGFfdWxfbXV4X21hcFtdID0gew0K KwkiTVRLQUlGIiwgIkFQX0RNSUMiDQorfTsNCisNCitzdGF0aWMgaW50IGFkZGFfdWxfbWFwX3Zh bHVlW10gPSB7DQorCUFEREFfVUxfTVVYX01US0FJRiwNCisJQUREQV9VTF9NVVhfQVBfRE1JQywN Cit9Ow0KKw0KK3N0YXRpYyBTT0NfVkFMVUVfRU5VTV9TSU5HTEVfREVDTChhZGRhX3VsX211eF9t YXBfZW51bSwNCisJCQkJICBTTkRfU09DX05PUE0sDQorCQkJCSAgMCwNCisJCQkJICBBRERBX1VM X01VWF9NQVNLLA0KKwkJCQkgIGFkZGFfdWxfbXV4X21hcCwNCisJCQkJICBhZGRhX3VsX21hcF92 YWx1ZSk7DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IGFkZGFfdWxf bXV4X2NvbnRyb2wgPQ0KKwlTT0NfREFQTV9FTlVNKCJBRERBX1VMX01VWCBTZWxlY3QiLCBhZGRh X3VsX211eF9tYXBfZW51bSk7DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xf bmV3IGFkZGFfY2gzNF91bF9tdXhfY29udHJvbCA9DQorCVNPQ19EQVBNX0VOVU0oIkFEREFfQ0gz NF9VTF9NVVggU2VsZWN0IiwgYWRkYV91bF9tdXhfbWFwX2VudW0pOw0KKw0KK3N0YXRpYyBjb25z dCBzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCBtdGtfZGFpX2FkZGFfd2lkZ2V0c1tdID0gew0K KwkvKiBpbnRlci1jb25uZWN0aW9ucyAqLw0KKwlTTkRfU09DX0RBUE1fTUlYRVIoIkFEREFfRExf Q0gxIiwgU05EX1NPQ19OT1BNLCAwLCAwLA0KKwkJCSAgIG10a19hZGRhX2RsX2NoMV9taXgsDQor CQkJICAgQVJSQVlfU0laRShtdGtfYWRkYV9kbF9jaDFfbWl4KSksDQorCVNORF9TT0NfREFQTV9N SVhFUigiQUREQV9ETF9DSDIiLCBTTkRfU09DX05PUE0sIDAsIDAsDQorCQkJICAgbXRrX2FkZGFf ZGxfY2gyX21peCwNCisJCQkgICBBUlJBWV9TSVpFKG10a19hZGRhX2RsX2NoMl9taXgpKSwNCisN CisJU05EX1NPQ19EQVBNX01JWEVSKCJBRERBX0RMX0NIMyIsIFNORF9TT0NfTk9QTSwgMCwgMCwN CisJCQkgICBtdGtfYWRkYV9kbF9jaDNfbWl4LA0KKwkJCSAgIEFSUkFZX1NJWkUobXRrX2FkZGFf ZGxfY2gzX21peCkpLA0KKwlTTkRfU09DX0RBUE1fTUlYRVIoIkFEREFfRExfQ0g0IiwgU05EX1NP Q19OT1BNLCAwLCAwLA0KKwkJCSAgIG10a19hZGRhX2RsX2NoNF9taXgsDQorCQkJICAgQVJSQVlf U0laRShtdGtfYWRkYV9kbF9jaDRfbWl4KSksDQorDQorCVNORF9TT0NfREFQTV9TVVBQTFlfUygi QUREQSBFbmFibGUiLCBTVVBQTFlfU0VRX0FEREFfQUZFX09OLA0KKwkJCSAgICAgIEFGRV9BRERB X1VMX0RMX0NPTjAsIEFEREFfQUZFX09OX1NGVCwgMCwNCisJCQkgICAgICBOVUxMLCAwKSwNCisN CisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJBRERBIFBsYXliYWNrIEVuYWJsZSIsIFNVUFBMWV9T RVFfQUREQV9ETF9PTiwNCisJCQkgICAgICBBRkVfQUREQV9ETF9TUkMyX0NPTjAsDQorCQkJICAg ICAgRExfMl9TUkNfT05fVE1QX0NUTF9QUkVfU0ZULCAwLA0KKwkJCSAgICAgIG10a19hZGRhX2Rs X2V2ZW50LA0KKwkJCSAgICAgIFNORF9TT0NfREFQTV9QUkVfUE1VIHwgU05EX1NPQ19EQVBNX1BP U1RfUE1EKSwNCisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJBRERBIENIMzQgUGxheWJhY2sgRW5h YmxlIiwNCisJCQkgICAgICBTVVBQTFlfU0VRX0FEREFfRExfT04sDQorCQkJICAgICAgQUZFX0FE REFfM1JEX0RBQ19ETF9TUkMyX0NPTjAsDQorCQkJICAgICAgRExfMl9TUkNfT05fVE1QX0NUTF9Q UkVfU0ZULCAwLA0KKwkJCSAgICAgIG10a19hZGRhX2NoMzRfZGxfZXZlbnQsDQorCQkJICAgICAg U05EX1NPQ19EQVBNX1BSRV9QTVUgfCBTTkRfU09DX0RBUE1fUE9TVF9QTUQpLA0KKw0KKwlTTkRf U09DX0RBUE1fU1VQUExZX1MoIkFEREEgQ2FwdHVyZSBFbmFibGUiLCBTVVBQTFlfU0VRX0FEREFf VUxfT04sDQorCQkJICAgICAgQUZFX0FEREFfVUxfU1JDX0NPTjAsDQorCQkJICAgICAgVUxfU1JD X09OX1RNUF9DVExfU0ZULCAwLA0KKwkJCSAgICAgIG10a19hZGRhX3VsX2V2ZW50LA0KKwkJCSAg ICAgIFNORF9TT0NfREFQTV9QUkVfUE1VIHwgU05EX1NPQ19EQVBNX1BPU1RfUE1EKSwNCisJU05E X1NPQ19EQVBNX1NVUFBMWV9TKCJBRERBIENIMzQgQ2FwdHVyZSBFbmFibGUiLCBTVVBQTFlfU0VR X0FEREFfVUxfT04sDQorCQkJICAgICAgQUZFX0FEREE2X1VMX1NSQ19DT04wLA0KKwkJCSAgICAg IFVMX1NSQ19PTl9UTVBfQ1RMX1NGVCwgMCwNCisJCQkgICAgICBtdGtfYWRkYV9jaDM0X3VsX2V2 ZW50LA0KKwkJCSAgICAgIFNORF9TT0NfREFQTV9QUkVfUE1VIHwgU05EX1NPQ19EQVBNX1BPU1Rf UE1EKSwNCisNCisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJBVURfUEFEX1RPUCIsIFNVUFBMWV9T RVFfQUREQV9BVURfUEFEX1RPUCwNCisJCQkgICAgICBBRkVfQVVEX1BBRF9UT1AsDQorCQkJICAg ICAgUkdfUlhfRklGT19PTl9TRlQsIDAsDQorCQkJICAgICAgbXRrX2FkZGFfcGFkX3RvcF9ldmVu dCwNCisJCQkgICAgICBTTkRfU09DX0RBUE1fUFJFX1BNVSksDQorCVNORF9TT0NfREFQTV9TVVBQ TFlfUygiQUREQV9NVEtBSUZfQ0ZHIiwgU1VQUExZX1NFUV9BRERBX01US0FJRl9DRkcsDQorCQkJ ICAgICAgU05EX1NPQ19OT1BNLCAwLCAwLA0KKwkJCSAgICAgIG10a19hZGRhX210a2FpZl9jZmdf ZXZlbnQsDQorCQkJICAgICAgU05EX1NPQ19EQVBNX1BSRV9QTVUpLA0KKwlTTkRfU09DX0RBUE1f U1VQUExZX1MoIkFEREE2X01US0FJRl9DRkciLCBTVVBQTFlfU0VRX0FEREE2X01US0FJRl9DRkcs DQorCQkJICAgICAgU05EX1NPQ19OT1BNLCAwLCAwLA0KKwkJCSAgICAgIG10a19hZGRhX210a2Fp Zl9jZmdfZXZlbnQsDQorCQkJICAgICAgU05EX1NPQ19EQVBNX1BSRV9QTVUpLA0KKw0KKwlTTkRf U09DX0RBUE1fU1VQUExZX1MoIkFQX0RNSUNfRU4iLCBTVVBQTFlfU0VRX0FEREFfQVBfRE1JQywN CisJCQkgICAgICBBRkVfQUREQV9VTF9TUkNfQ09OMCwNCisJCQkgICAgICBVTF9BUF9ETUlDX09O X1NGVCwgMCwNCisJCQkgICAgICBOVUxMLCAwKSwNCisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJB UF9ETUlDX0NIMzRfRU4iLCBTVVBQTFlfU0VRX0FEREFfQVBfRE1JQywNCisJCQkgICAgICBBRkVf QUREQTZfVUxfU1JDX0NPTjAsDQorCQkJICAgICAgVUxfQVBfRE1JQ19PTl9TRlQsIDAsDQorCQkJ ICAgICAgTlVMTCwgMCksDQorDQorCVNORF9TT0NfREFQTV9TVVBQTFlfUygiQUREQV9GSUZPIiwg U1VQUExZX1NFUV9BRERBX0ZJRk8sDQorCQkJICAgICAgQUZFX0FEREFfVUxfRExfQ09OMCwNCisJ CQkgICAgICBBRkVfQUREQV9GSUZPX0FVVE9fUlNUX1NGVCwgMSwNCisJCQkgICAgICBOVUxMLCAw KSwNCisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJBRERBX0NIMzRfRklGTyIsIFNVUFBMWV9TRVFf QUREQV9GSUZPLA0KKwkJCSAgICAgIEFGRV9BRERBX1VMX0RMX0NPTjAsDQorCQkJICAgICAgQUZF X0FEREE2X0ZJRk9fQVVUT19SU1RfU0ZULCAxLA0KKwkJCSAgICAgIE5VTEwsIDApLA0KKw0KKwlT TkRfU09DX0RBUE1fTVVYKCJBRERBX1VMX011eCIsIFNORF9TT0NfTk9QTSwgMCwgMCwNCisJCQkg JmFkZGFfdWxfbXV4X2NvbnRyb2wpLA0KKwlTTkRfU09DX0RBUE1fTVVYKCJBRERBX0NIMzRfVUxf TXV4IiwgU05EX1NPQ19OT1BNLCAwLCAwLA0KKwkJCSAmYWRkYV9jaDM0X3VsX211eF9jb250cm9s KSwNCisNCisJU05EX1NPQ19EQVBNX0lOUFVUKCJBUF9ETUlDX0lOUFVUIiksDQorCVNORF9TT0Nf REFQTV9JTlBVVCgiQVBfRE1JQ19DSDM0X0lOUFVUIiksDQorDQorCS8qIHN0ZiAqLw0KKwlTTkRf U09DX0RBUE1fU1dJVENIX0UoIlNpZGV0b25lIEZpbHRlciIsDQorCQkJICAgICAgQUZFX1NJREVU T05FX0NPTjEsIFNJREVfVE9ORV9PTl9TRlQsIDAsDQorCQkJICAgICAgJnN0Zl9jdGwsDQorCQkJ ICAgICAgbXRrX3N0Zl9ldmVudCwNCisJCQkgICAgICBTTkRfU09DX0RBUE1fUFJFX1BNVSB8DQor CQkJICAgICAgU05EX1NPQ19EQVBNX1BPU1RfUE1EKSwNCisJU05EX1NPQ19EQVBNX01VWCgiU1RG X08xOU8yMF9NVVgiLCBTTkRfU09DX05PUE0sIDAsIDAsDQorCQkJICZzdGZfbzE5TzIwX211eF9j b250cm9sKSwNCisJU05EX1NPQ19EQVBNX01VWCgiU1RGX0FEREFfTVVYIiwgU05EX1NPQ19OT1BN LCAwLCAwLA0KKwkJCSAmc3RmX2FkZGFfbXV4X2NvbnRyb2wpLA0KKwlTTkRfU09DX0RBUE1fTUlY RVIoIlNURl9DSDEiLCBTTkRfU09DX05PUE0sIDAsIDAsDQorCQkJICAgbXRrX3N0Zl9jaDFfbWl4 LA0KKwkJCSAgIEFSUkFZX1NJWkUobXRrX3N0Zl9jaDFfbWl4KSksDQorCVNORF9TT0NfREFQTV9N SVhFUigiU1RGX0NIMiIsIFNORF9TT0NfTk9QTSwgMCwgMCwNCisJCQkgICBtdGtfc3RmX2NoMl9t aXgsDQorCQkJICAgQVJSQVlfU0laRShtdGtfc3RmX2NoMl9taXgpKSwNCisJU05EX1NPQ19EQVBN X09VVFBVVCgiU1RGX09VVFBVVCIpLA0KKw0KKwkvKiBjbG9jayAqLw0KKwlTTkRfU09DX0RBUE1f Q0xPQ0tfU1VQUExZKCJ0b3BfbXV4X2F1ZGlvX2giKSwNCisNCisJU05EX1NPQ19EQVBNX0NMT0NL X1NVUFBMWSgiYXVkX2RhY19jbGsiKSwNCisJU05EX1NPQ19EQVBNX0NMT0NLX1NVUFBMWSgiYXVk X2RhY19wcmVkaXNfY2xrIiksDQorCVNORF9TT0NfREFQTV9DTE9DS19TVVBQTFkoImF1ZF8zcmRf ZGFjX2NsayIpLA0KKwlTTkRfU09DX0RBUE1fQ0xPQ0tfU1VQUExZKCJhdWRfM3JkX2RhY19wcmVk aXNfY2xrIiksDQorDQorCVNORF9TT0NfREFQTV9DTE9DS19TVVBQTFkoImF1ZF9hZGNfY2xrIiks DQorCVNORF9TT0NfREFQTV9DTE9DS19TVVBQTFkoImF1ZF9hZGRhNl9hZGNfY2xrIiksDQorfTsN CisNCitzdGF0aWMgY29uc3Qgc3RydWN0IHNuZF9zb2NfZGFwbV9yb3V0ZSBtdGtfZGFpX2FkZGFf cm91dGVzW10gPSB7DQorCS8qIHBsYXliYWNrICovDQorCXsiQUREQV9ETF9DSDEiLCAiREwxX0NI MSIsICJETDEifSwNCisJeyJBRERBX0RMX0NIMiIsICJETDFfQ0gxIiwgIkRMMSJ9LA0KKwl7IkFE REFfRExfQ0gyIiwgIkRMMV9DSDIiLCAiREwxIn0sDQorDQorCXsiQUREQV9ETF9DSDEiLCAiREwx Ml9DSDEiLCAiREwxMiJ9LA0KKwl7IkFEREFfRExfQ0gyIiwgIkRMMTJfQ0gyIiwgIkRMMTIifSwN CisNCisJeyJBRERBX0RMX0NIMSIsICJETDZfQ0gxIiwgIkRMNiJ9LA0KKwl7IkFEREFfRExfQ0gy IiwgIkRMNl9DSDIiLCAiREw2In0sDQorDQorCXsiQUREQV9ETF9DSDEiLCAiREw4X0NIMSIsICJE TDgifSwNCisJeyJBRERBX0RMX0NIMiIsICJETDhfQ0gyIiwgIkRMOCJ9LA0KKw0KKwl7IkFEREFf RExfQ0gxIiwgIkRMMl9DSDEiLCAiREwyIn0sDQorCXsiQUREQV9ETF9DSDIiLCAiREwyX0NIMSIs ICJETDIifSwNCisJeyJBRERBX0RMX0NIMiIsICJETDJfQ0gyIiwgIkRMMiJ9LA0KKw0KKwl7IkFE REFfRExfQ0gxIiwgIkRMM19DSDEiLCAiREwzIn0sDQorCXsiQUREQV9ETF9DSDIiLCAiREwzX0NI MSIsICJETDMifSwNCisJeyJBRERBX0RMX0NIMiIsICJETDNfQ0gyIiwgIkRMMyJ9LA0KKw0KKwl7 IkFEREFfRExfQ0gxIiwgIkRMNF9DSDEiLCAiREw0In0sDQorCXsiQUREQV9ETF9DSDIiLCAiREw0 X0NIMiIsICJETDQifSwNCisNCisJeyJBRERBX0RMX0NIMSIsICJETDVfQ0gxIiwgIkRMNSJ9LA0K Kwl7IkFEREFfRExfQ0gyIiwgIkRMNV9DSDIiLCAiREw1In0sDQorDQorCXsiQUREQSBQbGF5YmFj ayIsIE5VTEwsICJBRERBX0RMX0NIMSJ9LA0KKwl7IkFEREEgUGxheWJhY2siLCBOVUxMLCAiQURE QV9ETF9DSDIifSwNCisNCisJeyJBRERBIFBsYXliYWNrIiwgTlVMTCwgIkFEREEgRW5hYmxlIn0s DQorCXsiQUREQSBQbGF5YmFjayIsIE5VTEwsICJBRERBIFBsYXliYWNrIEVuYWJsZSJ9LA0KKw0K Kwl7IkFEREFfRExfQ0gzIiwgIkRMMV9DSDEiLCAiREwxIn0sDQorCXsiQUREQV9ETF9DSDQiLCAi REwxX0NIMSIsICJETDEifSwNCisJeyJBRERBX0RMX0NINCIsICJETDFfQ0gyIiwgIkRMMSJ9LA0K Kw0KKwl7IkFEREFfRExfQ0gzIiwgIkRMMTJfQ0gxIiwgIkRMMTIifSwNCisJeyJBRERBX0RMX0NI NCIsICJETDEyX0NIMiIsICJETDEyIn0sDQorDQorCXsiQUREQV9ETF9DSDMiLCAiREw2X0NIMSIs ICJETDYifSwNCisJeyJBRERBX0RMX0NINCIsICJETDZfQ0gyIiwgIkRMNiJ9LA0KKw0KKwl7IkFE REFfRExfQ0gzIiwgIkRMMl9DSDEiLCAiREwyIn0sDQorCXsiQUREQV9ETF9DSDQiLCAiREwyX0NI MSIsICJETDIifSwNCisJeyJBRERBX0RMX0NINCIsICJETDJfQ0gyIiwgIkRMMiJ9LA0KKw0KKwl7 IkFEREFfRExfQ0gzIiwgIkRMM19DSDEiLCAiREwzIn0sDQorCXsiQUREQV9ETF9DSDQiLCAiREwz X0NIMSIsICJETDMifSwNCisJeyJBRERBX0RMX0NINCIsICJETDNfQ0gyIiwgIkRMMyJ9LA0KKw0K Kwl7IkFEREFfRExfQ0gzIiwgIkRMNF9DSDEiLCAiREw0In0sDQorCXsiQUREQV9ETF9DSDQiLCAi REw0X0NIMiIsICJETDQifSwNCisNCisJeyJBRERBX0RMX0NIMyIsICJETDVfQ0gxIiwgIkRMNSJ9 LA0KKwl7IkFEREFfRExfQ0g0IiwgIkRMNV9DSDIiLCAiREw1In0sDQorDQorCXsiQUREQSBDSDM0 IFBsYXliYWNrIiwgTlVMTCwgIkFEREFfRExfQ0gzIn0sDQorCXsiQUREQSBDSDM0IFBsYXliYWNr IiwgTlVMTCwgIkFEREFfRExfQ0g0In0sDQorDQorCXsiQUREQSBDSDM0IFBsYXliYWNrIiwgTlVM TCwgIkFEREEgRW5hYmxlIn0sDQorCXsiQUREQSBDSDM0IFBsYXliYWNrIiwgTlVMTCwgIkFEREEg Q0gzNCBQbGF5YmFjayBFbmFibGUifSwNCisNCisJLyogY2FwdHVyZSAqLw0KKwl7IkFEREFfVUxf TXV4IiwgIk1US0FJRiIsICJBRERBIENhcHR1cmUifSwNCisJeyJBRERBX1VMX011eCIsICJBUF9E TUlDIiwgIkFQIERNSUMgQ2FwdHVyZSJ9LA0KKw0KKwl7IkFEREFfQ0gzNF9VTF9NdXgiLCAiTVRL QUlGIiwgIkFEREEgQ0gzNCBDYXB0dXJlIn0sDQorCXsiQUREQV9DSDM0X1VMX011eCIsICJBUF9E TUlDIiwgIkFQIERNSUMgQ0gzNCBDYXB0dXJlIn0sDQorDQorCXsiQUREQSBDYXB0dXJlIiwgTlVM TCwgIkFEREEgRW5hYmxlIn0sDQorCXsiQUREQSBDYXB0dXJlIiwgTlVMTCwgIkFEREEgQ2FwdHVy ZSBFbmFibGUifSwNCisJeyJBRERBIENhcHR1cmUiLCBOVUxMLCAiQVVEX1BBRF9UT1AifSwNCisJ eyJBRERBIENhcHR1cmUiLCBOVUxMLCAiQUREQV9NVEtBSUZfQ0ZHIn0sDQorDQorCXsiQVAgRE1J QyBDYXB0dXJlIiwgTlVMTCwgIkFEREEgRW5hYmxlIn0sDQorCXsiQVAgRE1JQyBDYXB0dXJlIiwg TlVMTCwgIkFEREEgQ2FwdHVyZSBFbmFibGUifSwNCisJeyJBUCBETUlDIENhcHR1cmUiLCBOVUxM LCAiQUREQV9GSUZPIn0sDQorCXsiQVAgRE1JQyBDYXB0dXJlIiwgTlVMTCwgIkFQX0RNSUNfRU4i fSwNCisNCisJeyJBRERBIENIMzQgQ2FwdHVyZSIsIE5VTEwsICJBRERBIEVuYWJsZSJ9LA0KKwl7 IkFEREEgQ0gzNCBDYXB0dXJlIiwgTlVMTCwgIkFEREEgQ0gzNCBDYXB0dXJlIEVuYWJsZSJ9LA0K Kwl7IkFEREEgQ0gzNCBDYXB0dXJlIiwgTlVMTCwgIkFVRF9QQURfVE9QIn0sDQorCXsiQUREQSBD SDM0IENhcHR1cmUiLCBOVUxMLCAiQUREQTZfTVRLQUlGX0NGRyJ9LA0KKw0KKwl7IkFQIERNSUMg Q0gzNCBDYXB0dXJlIiwgTlVMTCwgIkFEREEgRW5hYmxlIn0sDQorCXsiQVAgRE1JQyBDSDM0IENh cHR1cmUiLCBOVUxMLCAiQUREQSBDSDM0IENhcHR1cmUgRW5hYmxlIn0sDQorCXsiQVAgRE1JQyBD SDM0IENhcHR1cmUiLCBOVUxMLCAiQUREQV9DSDM0X0ZJRk8ifSwNCisJeyJBUCBETUlDIENIMzQg Q2FwdHVyZSIsIE5VTEwsICJBUF9ETUlDX0NIMzRfRU4ifSwNCisNCisJeyJBUCBETUlDIENhcHR1 cmUiLCBOVUxMLCAiQVBfRE1JQ19JTlBVVCJ9LA0KKwl7IkFQIERNSUMgQ0gzNCBDYXB0dXJlIiwg TlVMTCwgIkFQX0RNSUNfQ0gzNF9JTlBVVCJ9LA0KKw0KKwkvKiBzaWRldG9uZSBmaWx0ZXIgKi8N CisJeyJTVEZfQUREQV9NVVgiLCAiQUREQSIsICJBRERBX1VMX011eCJ9LA0KKwl7IlNURl9BRERB X01VWCIsICJBRERBNiIsICJBRERBX0NIMzRfVUxfTXV4In0sDQorDQorCXsiU1RGX08xOU8yMF9N VVgiLCAiQUREQV9BRERBNiIsICJTVEZfQUREQV9NVVgifSwNCisJeyJTVEZfTzE5TzIwX01VWCIs ICJPMTlPMjAiLCAiU1RGX0NIMSJ9LA0KKwl7IlNURl9PMTlPMjBfTVVYIiwgIk8xOU8yMCIsICJT VEZfQ0gyIn0sDQorDQorCXsiU2lkZXRvbmUgRmlsdGVyIiwgIlN3aXRjaCIsICJTVEZfTzE5TzIw X01VWCJ9LA0KKwl7IlNURl9PVVRQVVQiLCBOVUxMLCAiU2lkZXRvbmUgRmlsdGVyIn0sDQorCXsi QUREQSBQbGF5YmFjayIsIE5VTEwsICJTaWRldG9uZSBGaWx0ZXIifSwNCisJeyJBRERBIENIMzQg UGxheWJhY2siLCBOVUxMLCAiU2lkZXRvbmUgRmlsdGVyIn0sDQorDQorCS8qIGNsayAqLw0KKwl7 IkFEREEgUGxheWJhY2siLCBOVUxMLCAiYXVkX2RhY19jbGsifSwNCisJeyJBRERBIFBsYXliYWNr IiwgTlVMTCwgImF1ZF9kYWNfcHJlZGlzX2NsayJ9LA0KKw0KKwl7IkFEREEgQ0gzNCBQbGF5YmFj ayIsIE5VTEwsICJhdWRfM3JkX2RhY19jbGsifSwNCisJeyJBRERBIENIMzQgUGxheWJhY2siLCBO VUxMLCAiYXVkXzNyZF9kYWNfcHJlZGlzX2NsayJ9LA0KKw0KKwl7IkFEREEgQ2FwdHVyZSBFbmFi bGUiLCBOVUxMLCAiYXVkX2FkY19jbGsifSwNCisJeyJBRERBIENIMzQgQ2FwdHVyZSBFbmFibGUi LCBOVUxMLCAiYXVkX2FkZGE2X2FkY19jbGsifSwNCit9Ow0KKw0KKy8qIGRhaSBvcHMgKi8NCitz dGF0aWMgaW50IG10a19kYWlfYWRkYV9od19wYXJhbXMoc3RydWN0IHNuZF9wY21fc3Vic3RyZWFt ICpzdWJzdHJlYW0sDQorCQkJCSAgc3RydWN0IHNuZF9wY21faHdfcGFyYW1zICpwYXJhbXMsDQor CQkJCSAgc3RydWN0IHNuZF9zb2NfZGFpICpkYWkpDQorew0KKwlzdHJ1Y3QgbXRrX2Jhc2VfYWZl ICphZmUgPSBzbmRfc29jX2RhaV9nZXRfZHJ2ZGF0YShkYWkpOw0KKwl1bnNpZ25lZCBpbnQgcmF0 ZSA9IHBhcmFtc19yYXRlKHBhcmFtcyk7DQorCWludCBpZCA9IGRhaS0+aWQ7DQorDQorCWRldl9p bmZvKGFmZS0+ZGV2LCAiJXMoKSwgaWQgJWQsIHN0cmVhbSAlZCwgcmF0ZSAlZFxuIiwNCisJCSBf X2Z1bmNfXywNCisJCSBpZCwNCisJCSBzdWJzdHJlYW0tPnN0cmVhbSwNCisJCSByYXRlKTsNCisN CisJaWYgKHN1YnN0cmVhbS0+c3RyZWFtID09IFNORFJWX1BDTV9TVFJFQU1fUExBWUJBQ0spIHsN CisJCXVuc2lnbmVkIGludCBkbF9zcmMyX2NvbjAgPSAwOw0KKwkJdW5zaWduZWQgaW50IGRsX3Ny YzJfY29uMSA9IDA7DQorDQorCQkvKiBzZXQgc2FtcGxpbmcgcmF0ZSAqLw0KKwkJZGxfc3JjMl9j b24wID0gYWRkYV9kbF9yYXRlX3RyYW5zZm9ybShhZmUsIHJhdGUpIDw8DQorCQkJICAgICAgIERM XzJfSU5QVVRfTU9ERV9DVExfU0ZUOw0KKw0KKwkJLyogc2V0IG91dHB1dCBtb2RlLCBVUF9TQU1Q TElOR19SQVRFX1g4ICovDQorCQlkbF9zcmMyX2NvbjAgfD0gKDB4MyA8PCBETF8yX09VVFBVVF9T RUxfQ1RMX1NGVCk7DQorDQorCQkvKiB0dXJuIG9mZiBtdXRlIGZ1bmN0aW9uICovDQorCQlkbF9z cmMyX2NvbjAgfD0gKDB4MDEgPDwgRExfMl9NVVRFX0NIMl9PRkZfQ1RMX1BSRV9TRlQpOw0KKwkJ ZGxfc3JjMl9jb24wIHw9ICgweDAxIDw8IERMXzJfTVVURV9DSDFfT0ZGX0NUTF9QUkVfU0ZUKTsN CisNCisJCS8qIHNldCB2b2ljZSBpbnB1dCBkYXRhIGlmIGlucHV0IHNhbXBsZSByYXRlIGlzIDhr IG9yIDE2ayAqLw0KKwkJaWYgKHJhdGUgPT0gODAwMCB8fCByYXRlID09IDE2MDAwKQ0KKwkJCWRs X3NyYzJfY29uMCB8PSAweDAxIDw8IERMXzJfVk9JQ0VfTU9ERV9DVExfUFJFX1NGVDsNCisNCisJ CS8qIFNBIHN1Z2dlc3QgYXBwbHkgLTAuM2RiIHRvIGF1ZGlvL3NwZWVjaCBwYXRoICovDQorCQlk bF9zcmMyX2NvbjEgPSBNVEtfQUZFX0FEREFfRExfR0FJTl9OT1JNQUwgPDwNCisJCQkgICAgICAg RExfMl9HQUlOX0NUTF9QUkVfU0ZUOw0KKw0KKwkJLyogdHVybiBvbiBkb3duLWxpbmsgZ2FpbiAq Lw0KKwkJZGxfc3JjMl9jb24wIHw9ICgweDAxIDw8IERMXzJfR0FJTl9PTl9DVExfUFJFX1NGVCk7 DQorDQorCQlpZiAoaWQgPT0gTVQ4MTkyX0RBSV9BRERBKSB7DQorCQkJLyogY2xlYW4gcHJlZGlz dG9ydGlvbiAqLw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwgQUZFX0FEREFfUFJFRElT X0NPTjAsIDApOw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwgQUZFX0FEREFfUFJFRElT X0NPTjEsIDApOw0KKw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwNCisJCQkJICAgICBB RkVfQUREQV9ETF9TUkMyX0NPTjAsIGRsX3NyYzJfY29uMCk7DQorCQkJcmVnbWFwX3dyaXRlKGFm ZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBX0RMX1NSQzJfQ09OMSwgZGxfc3JjMl9jb24x KTsNCisNCisJCQkvKiBzZXQgc2RtIGdhaW4gKi8NCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZl LT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQV9ETF9TRE1fRENDT01QX0NPTiwNCisJCQkJCSAg IEFUVEdBSU5fQ1RMX01BU0tfU0ZULA0KKwkJCQkJICAgQVVESU9fU0RNX0xFVkVMX05PUk1BTCA8 PA0KKwkJCQkJICAgQVRUR0FJTl9DVExfU0ZUKTsNCisNCisJCQkvKiAybmQgc2RtICovDQorCQkJ cmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgQUZFX0FEREFfRExfU0RN X0RDQ09NUF9DT04sDQorCQkJCQkgICBVU0VfM1JEX1NETV9NQVNLX1NGVCwNCisJCQkJCSAgIEFV RElPX1NETV8yTkQgPDwgVVNFXzNSRF9TRE1fU0ZUKTsNCisNCisJCQkvKiBzZG0gYXV0byByZXNl dCAqLw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwNCisJCQkJICAgICBBRkVfQUREQV9E TF9TRE1fQVVUT19SRVNFVF9DT04sDQorCQkJCSAgICAgU0RNX0FVVE9fUkVTRVRfVEhSRVNIT0xE KTsNCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQURE QV9ETF9TRE1fQVVUT19SRVNFVF9DT04sDQorCQkJCQkgICBBRERBX1NETV9BVVRPX1JFU0VUX09O T0ZGX01BU0tfU0ZULA0KKwkJCQkJICAgMHgxIDw8IEFEREFfU0RNX0FVVE9fUkVTRVRfT05PRkZf U0ZUKTsNCisJCX0gZWxzZSB7DQorCQkJLyogY2xlYW4gcHJlZGlzdG9ydGlvbiAqLw0KKwkJCXJl Z21hcF93cml0ZShhZmUtPnJlZ21hcCwNCisJCQkJICAgICBBRkVfQUREQV8zUkRfREFDX1BSRURJ U19DT04wLCAwKTsNCisJCQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsDQorCQkJCSAgICAgQUZF X0FEREFfM1JEX0RBQ19QUkVESVNfQ09OMSwgMCk7DQorDQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+ cmVnbWFwLCBBRkVfQUREQV8zUkRfREFDX0RMX1NSQzJfQ09OMCwNCisJCQkJICAgICBkbF9zcmMy X2NvbjApOw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwgQUZFX0FEREFfM1JEX0RBQ19E TF9TUkMyX0NPTjEsDQorCQkJCSAgICAgZGxfc3JjMl9jb24xKTsNCisNCisJCQkvKiBzZXQgc2Rt IGdhaW4gKi8NCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBB RkVfQUREQV8zUkRfREFDX0RMX1NETV9EQ0NPTVBfQ09OLA0KKwkJCQkJICAgQVRUR0FJTl9DVExf TUFTS19TRlQsDQorCQkJCQkgICBBVURJT19TRE1fTEVWRUxfTk9STUFMIDw8DQorCQkJCQkgICBB VFRHQUlOX0NUTF9TRlQpOw0KKw0KKwkJCS8qIDJuZCBzZG0gKi8NCisJCQlyZWdtYXBfdXBkYXRl X2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQV8zUkRfREFDX0RMX1NETV9EQ0NP TVBfQ09OLA0KKwkJCQkJICAgVVNFXzNSRF9TRE1fTUFTS19TRlQsDQorCQkJCQkgICBBVURJT19T RE1fMk5EIDw8IFVTRV8zUkRfU0RNX1NGVCk7DQorDQorCQkJLyogc2RtIGF1dG8gcmVzZXQgKi8N CisJCQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsDQorCQkJCSAgICAgQUZFX0FEREFfM1JEX0RB Q19ETF9TRE1fQVVUT19SRVNFVF9DT04sDQorCQkJCSAgICAgU0RNX0FVVE9fUkVTRVRfVEhSRVNI T0xEKTsNCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVf QUREQV8zUkRfREFDX0RMX1NETV9BVVRPX1JFU0VUX0NPTiwNCisJCQkJCSAgIEFEREFfM1JEX0RB Q19TRE1fQVVUT19SRVNFVF9PTk9GRl9NQVNLX1NGVCwNCisJCQkJCSAgIDB4MSA8PCBBRERBXzNS RF9EQUNfU0RNX0FVVE9fUkVTRVRfT05PRkZfU0ZUKTsNCisJCX0NCisJfSBlbHNlIHsNCisJCXVu c2lnbmVkIGludCB2b2ljZV9tb2RlID0gMDsNCisJCXVuc2lnbmVkIGludCB1bF9zcmNfY29uMCA9 IDA7CS8qIGRlZmF1bHQgdmFsdWUgKi8NCisNCisJCXZvaWNlX21vZGUgPSBhZGRhX3VsX3JhdGVf dHJhbnNmb3JtKGFmZSwgcmF0ZSk7DQorDQorCQl1bF9zcmNfY29uMCB8PSAodm9pY2VfbW9kZSA8 PCAxNykgJiAoMHg3IDw8IDE3KTsNCisNCisJCS8qIGVuYWJsZSBpaXIgKi8NCisJCXVsX3NyY19j b24wIHw9ICgxIDw8IFVMX0lJUl9PTl9UTVBfQ1RMX1NGVCkgJg0KKwkJCSAgICAgICBVTF9JSVJf T05fVE1QX0NUTF9NQVNLX1NGVDsNCisJCXVsX3NyY19jb24wIHw9IChVTF9JSVJfU1cgPDwgVUxf SUlSTU9ERV9DVExfU0ZUKSAmDQorCQkJICAgICAgIFVMX0lJUk1PREVfQ1RMX01BU0tfU0ZUOw0K Kw0KKwkJc3dpdGNoIChpZCkgew0KKwkJY2FzZSBNVDgxOTJfREFJX0FEREE6DQorCQljYXNlIE1U ODE5Ml9EQUlfQVBfRE1JQzoNCisJCQkvKiAzNUh6IEAgNDhrICovDQorCQkJcmVnbWFwX3dyaXRl KGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBX0lJUl9DT0VGXzAyXzAxLCAweDAwMDAw MDAwKTsNCisJCQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsDQorCQkJCSAgICAgQUZFX0FEREFf SUlSX0NPRUZfMDRfMDMsIDB4MDAwMDNGQjgpOw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21h cCwNCisJCQkJICAgICBBRkVfQUREQV9JSVJfQ09FRl8wNl8wNSwgMHgzRkI4MDAwMCk7DQorCQkJ cmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBX0lJUl9DT0VGXzA4 XzA3LCAweDNGQjgwMDAwKTsNCisJCQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsDQorCQkJCSAg ICAgQUZFX0FEREFfSUlSX0NPRUZfMTBfMDksIDB4MDAwMEMwNDgpOw0KKw0KKwkJCXJlZ21hcF93 cml0ZShhZmUtPnJlZ21hcCwNCisJCQkJICAgICBBRkVfQUREQV9VTF9TUkNfQ09OMCwgdWxfc3Jj X2NvbjApOw0KKw0KKwkJCS8qIFVzaW5nIEludGVybmFsIEFEQyAqLw0KKwkJCXJlZ21hcF91cGRh dGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJCSAgIEFGRV9BRERBX1RPUF9DT04wLA0KKwkJCQkJ ICAgMHgxIDw8IDAsDQorCQkJCQkgICAweDAgPDwgMCk7DQorDQorCQkJLyogbXRrYWlmX3J4aWZf ZGF0YV9tb2RlID0gMCwgYW1pYyAqLw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21h cCwNCisJCQkJCSAgIEFGRV9BRERBX01US0FJRl9SWF9DRkcwLA0KKwkJCQkJICAgMHgxIDw8IDAs DQorCQkJCQkgICAweDAgPDwgMCk7DQorCQkJYnJlYWs7DQorCQljYXNlIE1UODE5Ml9EQUlfQURE QV9DSDM0Og0KKwkJY2FzZSBNVDgxOTJfREFJX0FQX0RNSUNfQ0gzNDoNCisJCQkvKiAzNUh6IEAg NDhrICovDQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERB Nl9JSVJfQ09FRl8wMl8wMSwgMHgwMDAwMDAwMCk7DQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVn bWFwLA0KKwkJCQkgICAgIEFGRV9BRERBNl9JSVJfQ09FRl8wNF8wMywgMHgwMDAwM0ZCOCk7DQor CQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBNl9JSVJfQ09F Rl8wNl8wNSwgMHgzRkI4MDAwMCk7DQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJ CQkgICAgIEFGRV9BRERBNl9JSVJfQ09FRl8wOF8wNywgMHgzRkI4MDAwMCk7DQorCQkJcmVnbWFw X3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBNl9JSVJfQ09FRl8xMF8wOSwg MHgwMDAwQzA0OCk7DQorDQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAg IEFGRV9BRERBNl9VTF9TUkNfQ09OMCwgdWxfc3JjX2NvbjApOw0KKw0KKwkJCS8qIFVzaW5nIElu dGVybmFsIEFEQyAqLw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJ CSAgIEFGRV9BRERBNl9UT1BfQ09OMCwNCisJCQkJCSAgIDB4MSA8PCAwLA0KKwkJCQkJICAgMHgw IDw8IDApOw0KKw0KKwkJCS8qIG10a2FpZl9yeGlmX2RhdGFfbW9kZSA9IDAsIGFtaWMgKi8NCisJ CQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQTZfTVRL QUlGX1JYX0NGRzAsDQorCQkJCQkgICAweDEgPDwgMCwNCisJCQkJCSAgIDB4MCA8PCAwKTsNCisJ CQlicmVhazsNCisJCWRlZmF1bHQ6DQorCQkJYnJlYWs7DQorCQl9DQorDQorCQkvKiBhcCBkbWlj ICovDQorCQlzd2l0Y2ggKGlkKSB7DQorCQljYXNlIE1UODE5Ml9EQUlfQVBfRE1JQzoNCisJCWNh c2UgTVQ4MTkyX0RBSV9BUF9ETUlDX0NIMzQ6DQorCQkJbXRrX2FkZGFfdWxfc3JjX2RtaWMoYWZl LCBpZCk7DQorCQkJYnJlYWs7DQorCQlkZWZhdWx0Og0KKwkJCWJyZWFrOw0KKwkJfQ0KKwl9DQor DQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IHNuZF9zb2NfZGFpX29w cyBtdGtfZGFpX2FkZGFfb3BzID0gew0KKwkuaHdfcGFyYW1zID0gbXRrX2RhaV9hZGRhX2h3X3Bh cmFtcywNCit9Ow0KKw0KKy8qIGRhaSBkcml2ZXIgKi8NCisjZGVmaW5lIE1US19BRERBX1BMQVlC QUNLX1JBVEVTIChTTkRSVl9QQ01fUkFURV84MDAwXzQ4MDAwIHxcDQorCQkJCSBTTkRSVl9QQ01f UkFURV85NjAwMCB8XA0KKwkJCQkgU05EUlZfUENNX1JBVEVfMTkyMDAwKQ0KKw0KKyNkZWZpbmUg TVRLX0FEREFfQ0FQVFVSRV9SQVRFUyAoU05EUlZfUENNX1JBVEVfODAwMCB8XA0KKwkJCQlTTkRS Vl9QQ01fUkFURV8xNjAwMCB8XA0KKwkJCQlTTkRSVl9QQ01fUkFURV8zMjAwMCB8XA0KKwkJCQlT TkRSVl9QQ01fUkFURV80ODAwMCB8XA0KKwkJCQlTTkRSVl9QQ01fUkFURV85NjAwMCB8XA0KKwkJ CQlTTkRSVl9QQ01fUkFURV8xOTIwMDApDQorDQorI2RlZmluZSBNVEtfQUREQV9GT1JNQVRTIChT TkRSVl9QQ01fRk1UQklUX1MxNl9MRSB8XA0KKwkJCSAgU05EUlZfUENNX0ZNVEJJVF9TMjRfTEUg fFwNCisJCQkgIFNORFJWX1BDTV9GTVRCSVRfUzMyX0xFKQ0KKw0KK3N0YXRpYyBzdHJ1Y3Qgc25k X3NvY19kYWlfZHJpdmVyIG10a19kYWlfYWRkYV9kcml2ZXJbXSA9IHsNCisJew0KKwkJLm5hbWUg PSAiQUREQSIsDQorCQkuaWQgPSBNVDgxOTJfREFJX0FEREEsDQorCQkucGxheWJhY2sgPSB7DQor CQkJLnN0cmVhbV9uYW1lID0gIkFEREEgUGxheWJhY2siLA0KKwkJCS5jaGFubmVsc19taW4gPSAx LA0KKwkJCS5jaGFubmVsc19tYXggPSAyLA0KKwkJCS5yYXRlcyA9IE1US19BRERBX1BMQVlCQUNL X1JBVEVTLA0KKwkJCS5mb3JtYXRzID0gTVRLX0FEREFfRk9STUFUUywNCisJCX0sDQorCQkuY2Fw dHVyZSA9IHsNCisJCQkuc3RyZWFtX25hbWUgPSAiQUREQSBDYXB0dXJlIiwNCisJCQkuY2hhbm5l bHNfbWluID0gMSwNCisJCQkuY2hhbm5lbHNfbWF4ID0gMiwNCisJCQkucmF0ZXMgPSBNVEtfQURE QV9DQVBUVVJFX1JBVEVTLA0KKwkJCS5mb3JtYXRzID0gTVRLX0FEREFfRk9STUFUUywNCisJCX0s DQorCQkub3BzID0gJm10a19kYWlfYWRkYV9vcHMsDQorCX0sDQorCXsNCisJCS5uYW1lID0gIkFE REFfQ0gzNCIsDQorCQkuaWQgPSBNVDgxOTJfREFJX0FEREFfQ0gzNCwNCisJCS5wbGF5YmFjayA9 IHsNCisJCQkuc3RyZWFtX25hbWUgPSAiQUREQSBDSDM0IFBsYXliYWNrIiwNCisJCQkuY2hhbm5l bHNfbWluID0gMSwNCisJCQkuY2hhbm5lbHNfbWF4ID0gMiwNCisJCQkucmF0ZXMgPSBNVEtfQURE QV9QTEFZQkFDS19SQVRFUywNCisJCQkuZm9ybWF0cyA9IE1US19BRERBX0ZPUk1BVFMsDQorCQl9 LA0KKwkJLmNhcHR1cmUgPSB7DQorCQkJLnN0cmVhbV9uYW1lID0gIkFEREEgQ0gzNCBDYXB0dXJl IiwNCisJCQkuY2hhbm5lbHNfbWluID0gMSwNCisJCQkuY2hhbm5lbHNfbWF4ID0gMiwNCisJCQku cmF0ZXMgPSBNVEtfQUREQV9DQVBUVVJFX1JBVEVTLA0KKwkJCS5mb3JtYXRzID0gTVRLX0FEREFf Rk9STUFUUywNCisJCX0sDQorCQkub3BzID0gJm10a19kYWlfYWRkYV9vcHMsDQorCX0sDQorCXsN CisJCS5uYW1lID0gIkFQX0RNSUMiLA0KKwkJLmlkID0gTVQ4MTkyX0RBSV9BUF9ETUlDLA0KKwkJ LmNhcHR1cmUgPSB7DQorCQkJLnN0cmVhbV9uYW1lID0gIkFQIERNSUMgQ2FwdHVyZSIsDQorCQkJ LmNoYW5uZWxzX21pbiA9IDEsDQorCQkJLmNoYW5uZWxzX21heCA9IDIsDQorCQkJLnJhdGVzID0g TVRLX0FEREFfQ0FQVFVSRV9SQVRFUywNCisJCQkuZm9ybWF0cyA9IE1US19BRERBX0ZPUk1BVFMs DQorCQl9LA0KKwkJLm9wcyA9ICZtdGtfZGFpX2FkZGFfb3BzLA0KKwl9LA0KKwl7DQorCQkubmFt ZSA9ICJBUF9ETUlDX0NIMzQiLA0KKwkJLmlkID0gTVQ4MTkyX0RBSV9BUF9ETUlDX0NIMzQsDQor CQkuY2FwdHVyZSA9IHsNCisJCQkuc3RyZWFtX25hbWUgPSAiQVAgRE1JQyBDSDM0IENhcHR1cmUi LA0KKwkJCS5jaGFubmVsc19taW4gPSAxLA0KKwkJCS5jaGFubmVsc19tYXggPSAyLA0KKwkJCS5y YXRlcyA9IE1US19BRERBX0NBUFRVUkVfUkFURVMsDQorCQkJLmZvcm1hdHMgPSBNVEtfQUREQV9G T1JNQVRTLA0KKwkJfSwNCisJCS5vcHMgPSAmbXRrX2RhaV9hZGRhX29wcywNCisJfSwNCit9Ow0K Kw0KK2ludCBtdDgxOTJfZGFpX2FkZGFfcmVnaXN0ZXIoc3RydWN0IG10a19iYXNlX2FmZSAqYWZl KQ0KK3sNCisJc3RydWN0IG10a19iYXNlX2FmZV9kYWkgKmRhaTsNCisJc3RydWN0IG10ODE5Ml9h ZmVfcHJpdmF0ZSAqYWZlX3ByaXYgPSBhZmUtPnBsYXRmb3JtX3ByaXY7DQorDQorCWRldl9pbmZv KGFmZS0+ZGV2LCAiJXMoKVxuIiwgX19mdW5jX18pOw0KKw0KKwlkYWkgPSBkZXZtX2t6YWxsb2Mo YWZlLT5kZXYsIHNpemVvZigqZGFpKSwgR0ZQX0tFUk5FTCk7DQorCWlmICghZGFpKQ0KKwkJcmV0 dXJuIC1FTk9NRU07DQorDQorCWxpc3RfYWRkKCZkYWktPmxpc3QsICZhZmUtPnN1Yl9kYWlzKTsN CisNCisJZGFpLT5kYWlfZHJpdmVycyA9IG10a19kYWlfYWRkYV9kcml2ZXI7DQorCWRhaS0+bnVt X2RhaV9kcml2ZXJzID0gQVJSQVlfU0laRShtdGtfZGFpX2FkZGFfZHJpdmVyKTsNCisNCisJZGFp LT5jb250cm9scyA9IG10a19hZGRhX2NvbnRyb2xzOw0KKwlkYWktPm51bV9jb250cm9scyA9IEFS UkFZX1NJWkUobXRrX2FkZGFfY29udHJvbHMpOw0KKwlkYWktPmRhcG1fd2lkZ2V0cyA9IG10a19k YWlfYWRkYV93aWRnZXRzOw0KKwlkYWktPm51bV9kYXBtX3dpZGdldHMgPSBBUlJBWV9TSVpFKG10 a19kYWlfYWRkYV93aWRnZXRzKTsNCisJZGFpLT5kYXBtX3JvdXRlcyA9IG10a19kYWlfYWRkYV9y b3V0ZXM7DQorCWRhaS0+bnVtX2RhcG1fcm91dGVzID0gQVJSQVlfU0laRShtdGtfZGFpX2FkZGFf cm91dGVzKTsNCisNCisJLyogYXAgZG1pYyBwcml2IHNoYXJlIHdpdGggYWRkYSAqLw0KKwlhZmVf cHJpdi0+ZGFpX3ByaXZbTVQ4MTkyX0RBSV9BUF9ETUlDXSA9DQorCQlhZmVfcHJpdi0+ZGFpX3By aXZbTVQ4MTkyX0RBSV9BRERBXTsNCisJYWZlX3ByaXYtPmRhaV9wcml2W01UODE5Ml9EQUlfQVBf RE1JQ19DSDM0XSA9DQorCQlhZmVfcHJpdi0+ZGFpX3ByaXZbTVQ4MTkyX0RBSV9BRERBX0NIMzRd Ow0KKw0KKwlyZXR1cm4gMDsNCit9DQotLSANCjIuMTguMA0K From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MIME_BASE64_TEXT,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 617D9C2D0A3 for ; Sat, 24 Oct 2020 08:03:42 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8A7DB22281 for ; Sat, 24 Oct 2020 08:03:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="qkkP7zzw"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="VpVocS8P" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8A7DB22281 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id EA7161841; Sat, 24 Oct 2020 10:02:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EA7161841 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1603526620; bh=1w2R910WjXYg2yiL2x05QYtuAGfRi8PuUHhC5wcblhY=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=qkkP7zzwf18h7N+CQewi2bWMoLaS25SPObD8MD+yCRBH0/LwFWJQ0k941Yhl/y8XP rhKpbiZt/n774QFb7geTJD0CjFipu7fL+ziHMD16SDlx2mg+BluUmT3Twnhz8OsWaI 7ozdSGeSbbeyrfZ/KZg9qv5NkhzzwI8jd7pa3+JM= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 477A1F80508; Sat, 24 Oct 2020 09:59:40 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 63E9FF804E7; Sat, 24 Oct 2020 09:59:33 +0200 (CEST) Received: from mailgw01.mediatek.com (unknown [210.61.82.183]) by alsa1.perex.cz (Postfix) with ESMTP id 06AF8F804AA for ; Sat, 24 Oct 2020 09:59:14 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 06AF8F804AA Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="VpVocS8P" X-UUID: c4ad25634ee94b019308c8fc3d69139b-20201024 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=1w2R910WjXYg2yiL2x05QYtuAGfRi8PuUHhC5wcblhY=; b=VpVocS8PBd528FM88hbTn8NI53pqMhTaGN+Vmc+rExvWxVou2h/IQON4Ye3l37+t8vpx1pOuF8YVJwhXRYMn0xfz+p0TRPRk0ipz/cwYj8rUe2ifCToRhPCcxCpRog9qoSS2Tk6idPopfSH5Rgd2h7lDOMTbUD9mE76LsvbJWZo=; X-UUID: c4ad25634ee94b019308c8fc3d69139b-20201024 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.14 Build 0819 with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 278918667; Sat, 24 Oct 2020 15:59:06 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs06n2.mediatek.inc (172.21.101.130) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 24 Oct 2020 15:59:05 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sat, 24 Oct 2020 15:59:02 +0800 From: Jiaxin Yu To: , , , , , , , , , Subject: [PATCH v3 4/9] ASoC: mediatek: mt8192: support add in platform driver Date: Sat, 24 Oct 2020 15:58:54 +0800 Message-ID: <1603526339-15005-5-git-send-email-jiaxin.yu@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1603526339-15005-1-git-send-email-jiaxin.yu@mediatek.com> References: <1603526339-15005-1-git-send-email-jiaxin.yu@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-SNTS-SMTP: 135DBFC313CC6BC3E7DF51BECFA222AD739BB5ABC37619AA951B923F72B44DC42000:8 X-MTK: N Content-Transfer-Encoding: base64 Cc: shane.chien@mediatek.com, Bicycle.Tsai@mediatek.com, Jiaxin Yu , Trevor.Wu@mediatek.com, kuninori.morimoto.gx@renesas.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" VGhpcyBwYXRjaCBhZGRzIG10ODE5MiBhZGRhIGRhaSBkcml2ZXIuDQoNClNpZ25lZC1vZmYtYnk6 IEppYXhpbiBZdSA8amlheGluLnl1QG1lZGlhdGVrLmNvbT4NCi0tLQ0KIHNvdW5kL3NvYy9tZWRp YXRlay9tdDgxOTIvbXQ4MTkyLWRhaS1hZGRhLmMgfCAxNDg5ICsrKysrKysrKysrKysrKysrKysN CiAxIGZpbGUgY2hhbmdlZCwgMTQ4OSBpbnNlcnRpb25zKCspDQogY3JlYXRlIG1vZGUgMTAwNjQ0 IHNvdW5kL3NvYy9tZWRpYXRlay9tdDgxOTIvbXQ4MTkyLWRhaS1hZGRhLmMNCg0KZGlmZiAtLWdp dCBhL3NvdW5kL3NvYy9tZWRpYXRlay9tdDgxOTIvbXQ4MTkyLWRhaS1hZGRhLmMgYi9zb3VuZC9z b2MvbWVkaWF0ZWsvbXQ4MTkyL210ODE5Mi1kYWktYWRkYS5jDQpuZXcgZmlsZSBtb2RlIDEwMDY0 NA0KaW5kZXggMDAwMDAwMDAwMDAwMC4uYzQ5YTAyZDM0ZjI2YQ0KLS0tIC9kZXYvbnVsbA0KKysr IGIvc291bmQvc29jL21lZGlhdGVrL210ODE5Mi9tdDgxOTItZGFpLWFkZGEuYw0KQEAgLTAsMCAr MSwxNDg5IEBADQorLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjANCisvLw0KKy8v IE1lZGlhVGVrIEFMU0EgU29DIEF1ZGlvIERBSSBBRERBIENvbnRyb2wNCisvLw0KKy8vIENvcHly aWdodCAoYykgMjAyMCBNZWRpYVRlayBJbmMuDQorLy8gQXV0aG9yOiBTaGFuZSBDaGllbiA8c2hh bmUuY2hpZW5AbWVkaWF0ZWsuY29tPg0KKy8vDQorDQorI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+ DQorI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPg0KKw0KKyNpbmNsdWRlICJtdDgxOTItYWZlLWNs ay5oIg0KKyNpbmNsdWRlICJtdDgxOTItYWZlLWNvbW1vbi5oIg0KKyNpbmNsdWRlICJtdDgxOTIt YWZlLWdwaW8uaCINCisjaW5jbHVkZSAibXQ4MTkyLWludGVyY29ubmVjdGlvbi5oIg0KKw0KK2Vu dW0gew0KKwlVTF9JSVJfU1cgPSAwLA0KKwlVTF9JSVJfNUhaLA0KKwlVTF9JSVJfMTBIWiwNCisJ VUxfSUlSXzI1SFosDQorCVVMX0lJUl81MEhaLA0KKwlVTF9JSVJfNzVIWiwNCit9Ow0KKw0KK2Vu dW0gew0KKwlBVURJT19TRE1fTEVWRUxfTVVURSA9IDAsDQorCUFVRElPX1NETV9MRVZFTF9OT1JN QUwgPSAweDFkLA0KKwkvKiBpZiB5b3UgY2hhbmdlIGxldmVsIG5vcm1hbCAqLw0KKwkvKiB5b3Ug bmVlZCB0byBjaGFuZ2UgZm9ybXVsYSBvZiBocCBpbXBlZGFuY2UgYW5kIGRjIHRyaW0gdG9vICov DQorfTsNCisNCitlbnVtIHsNCisJQVVESU9fU0RNXzJORCA9IDAsDQorCUFVRElPX1NETV8zUkQs DQorfTsNCisNCitlbnVtIHsNCisJREVMQVlfREFUQV9NSVNPMSA9IDAsDQorCURFTEFZX0RBVEFf TUlTTzIsDQorfTsNCisNCitlbnVtIHsNCisJTVRLX0FGRV9BRERBX0RMX1JBVEVfOEsgPSAwLA0K KwlNVEtfQUZFX0FEREFfRExfUkFURV8xMUsgPSAxLA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV8x MksgPSAyLA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV8xNksgPSAzLA0KKwlNVEtfQUZFX0FEREFf RExfUkFURV8yMksgPSA0LA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV8yNEsgPSA1LA0KKwlNVEtf QUZFX0FEREFfRExfUkFURV8zMksgPSA2LA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV80NEsgPSA3 LA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV80OEsgPSA4LA0KKwlNVEtfQUZFX0FEREFfRExfUkFU RV85NksgPSA5LA0KKwlNVEtfQUZFX0FEREFfRExfUkFURV8xOTJLID0gMTAsDQorfTsNCisNCitl bnVtIHsNCisJTVRLX0FGRV9BRERBX1VMX1JBVEVfOEsgPSAwLA0KKwlNVEtfQUZFX0FEREFfVUxf UkFURV8xNksgPSAxLA0KKwlNVEtfQUZFX0FEREFfVUxfUkFURV8zMksgPSAyLA0KKwlNVEtfQUZF X0FEREFfVUxfUkFURV80OEsgPSAzLA0KKwlNVEtfQUZFX0FEREFfVUxfUkFURV85NksgPSA0LA0K KwlNVEtfQUZFX0FEREFfVUxfUkFURV8xOTJLID0gNSwNCisJTVRLX0FGRV9BRERBX1VMX1JBVEVf NDhLX0hEID0gNiwNCit9Ow0KKw0KKyNkZWZpbmUgU0RNX0FVVE9fUkVTRVRfVEhSRVNIT0xEIDB4 MTkwMDAwDQorDQorc3RhdGljIHVuc2lnbmVkIGludCBhZGRhX2RsX3JhdGVfdHJhbnNmb3JtKHN0 cnVjdCBtdGtfYmFzZV9hZmUgKmFmZSwNCisJCQkJCSAgIHVuc2lnbmVkIGludCByYXRlKQ0KK3sN CisJc3dpdGNoIChyYXRlKSB7DQorCWNhc2UgODAwMDoNCisJCXJldHVybiBNVEtfQUZFX0FEREFf RExfUkFURV84SzsNCisJY2FzZSAxMTAyNToNCisJCXJldHVybiBNVEtfQUZFX0FEREFfRExfUkFU RV8xMUs7DQorCWNhc2UgMTIwMDA6DQorCQlyZXR1cm4gTVRLX0FGRV9BRERBX0RMX1JBVEVfMTJL Ow0KKwljYXNlIDE2MDAwOg0KKwkJcmV0dXJuIE1US19BRkVfQUREQV9ETF9SQVRFXzE2SzsNCisJ Y2FzZSAyMjA1MDoNCisJCXJldHVybiBNVEtfQUZFX0FEREFfRExfUkFURV8yMks7DQorCWNhc2Ug MjQwMDA6DQorCQlyZXR1cm4gTVRLX0FGRV9BRERBX0RMX1JBVEVfMjRLOw0KKwljYXNlIDMyMDAw Og0KKwkJcmV0dXJuIE1US19BRkVfQUREQV9ETF9SQVRFXzMySzsNCisJY2FzZSA0NDEwMDoNCisJ CXJldHVybiBNVEtfQUZFX0FEREFfRExfUkFURV80NEs7DQorCWNhc2UgNDgwMDA6DQorCQlyZXR1 cm4gTVRLX0FGRV9BRERBX0RMX1JBVEVfNDhLOw0KKwljYXNlIDk2MDAwOg0KKwkJcmV0dXJuIE1U S19BRkVfQUREQV9ETF9SQVRFXzk2SzsNCisJY2FzZSAxOTIwMDA6DQorCQlyZXR1cm4gTVRLX0FG RV9BRERBX0RMX1JBVEVfMTkySzsNCisJZGVmYXVsdDoNCisJCWRldl93YXJuKGFmZS0+ZGV2LCAi JXMoKSwgcmF0ZSAlZCBpbnZhbGlkLCB1c2UgNDhrSHohISFcbiIsDQorCQkJIF9fZnVuY19fLCBy YXRlKTsNCisJCXJldHVybiBNVEtfQUZFX0FEREFfRExfUkFURV80OEs7DQorCX0NCit9DQorDQor c3RhdGljIHVuc2lnbmVkIGludCBhZGRhX3VsX3JhdGVfdHJhbnNmb3JtKHN0cnVjdCBtdGtfYmFz ZV9hZmUgKmFmZSwNCisJCQkJCSAgIHVuc2lnbmVkIGludCByYXRlKQ0KK3sNCisJc3dpdGNoIChy YXRlKSB7DQorCWNhc2UgODAwMDoNCisJCXJldHVybiBNVEtfQUZFX0FEREFfVUxfUkFURV84SzsN CisJY2FzZSAxNjAwMDoNCisJCXJldHVybiBNVEtfQUZFX0FEREFfVUxfUkFURV8xNks7DQorCWNh c2UgMzIwMDA6DQorCQlyZXR1cm4gTVRLX0FGRV9BRERBX1VMX1JBVEVfMzJLOw0KKwljYXNlIDQ4 MDAwOg0KKwkJcmV0dXJuIE1US19BRkVfQUREQV9VTF9SQVRFXzQ4SzsNCisJY2FzZSA5NjAwMDoN CisJCXJldHVybiBNVEtfQUZFX0FEREFfVUxfUkFURV85Nks7DQorCWNhc2UgMTkyMDAwOg0KKwkJ cmV0dXJuIE1US19BRkVfQUREQV9VTF9SQVRFXzE5Mks7DQorCWRlZmF1bHQ6DQorCQlkZXZfd2Fy bihhZmUtPmRldiwgIiVzKCksIHJhdGUgJWQgaW52YWxpZCwgdXNlIDQ4a0h6ISEhXG4iLA0KKwkJ CSBfX2Z1bmNfXywgcmF0ZSk7DQorCQlyZXR1cm4gTVRLX0FGRV9BRERBX1VMX1JBVEVfNDhLOw0K Kwl9DQorfQ0KKw0KKy8qIGRhaSBjb21wb25lbnQgKi8NCitzdGF0aWMgY29uc3Qgc3RydWN0IHNu ZF9rY29udHJvbF9uZXcgbXRrX2FkZGFfZGxfY2gxX21peFtdID0gew0KKwlTT0NfREFQTV9TSU5H TEVfQVVUT0RJU0FCTEUoIkRMMV9DSDEiLCBBRkVfQ09OTjMsIElfREwxX0NIMSwgMSwgMCksDQor CVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwxMl9DSDEiLCBBRkVfQ09OTjMsIElfREwx Ml9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMMl9DSDEiLCBB RkVfQ09OTjMsIElfREwyX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJM RSgiREwzX0NIMSIsIEFGRV9DT05OMywgSV9ETDNfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lO R0xFX0FVVE9ESVNBQkxFKCJETDRfQ0gxIiwgQUZFX0NPTk4zXzEsIElfREw0X0NIMSwgMSwgMCks DQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREw1X0NIMSIsIEFGRV9DT05OM18xLCBJ X0RMNV9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMNl9DSDEi LCBBRkVfQ09OTjNfMSwgSV9ETDZfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9E SVNBQkxFKCJETDhfQ0gxIiwgQUZFX0NPTk4zXzEsIElfREw4X0NIMSwgMSwgMCksDQorCVNPQ19E QVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiQUREQV9VTF9DSDMiLCBBRkVfQ09OTjMsDQorCQkJCSAg ICBJX0FEREFfVUxfQ0gzLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJB RERBX1VMX0NIMiIsIEFGRV9DT05OMywNCisJCQkJICAgIElfQUREQV9VTF9DSDIsIDEsIDApLA0K KwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkFEREFfVUxfQ0gxIiwgQUZFX0NPTk4zLA0K KwkJCQkgICAgSV9BRERBX1VMX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElT QUJMRSgiR0FJTjFfT1VUX0NIMSIsIEFGRV9DT05OMywNCisJCQkJICAgIElfR0FJTjFfT1VUX0NI MSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiUENNXzFfQ0FQX0NIMSIs IEFGRV9DT05OMywNCisJCQkJICAgIElfUENNXzFfQ0FQX0NIMSwgMSwgMCksDQorCVNPQ19EQVBN X1NJTkdMRV9BVVRPRElTQUJMRSgiUENNXzJfQ0FQX0NIMSIsIEFGRV9DT05OMywNCisJCQkJICAg IElfUENNXzJfQ0FQX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgi U1JDXzFfT1VUX0NIMSIsIEFGRV9DT05OM18xLA0KKwkJCQkgICAgSV9TUkNfMV9PVVRfQ0gxLCAx LCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJTUkNfMl9PVVRfQ0gxIiwgQUZF X0NPTk4zXzEsDQorCQkJCSAgICBJX1NSQ18yX09VVF9DSDEsIDEsIDApLA0KK307DQorDQorc3Rh dGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IG10a19hZGRhX2RsX2NoMl9taXhbXSA9 IHsNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDFfQ0gxIiwgQUZFX0NPTk40LCBJ X0RMMV9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMMV9DSDIi LCBBRkVfQ09OTjQsIElfREwxX0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElT QUJMRSgiREwxMl9DSDIiLCBBRkVfQ09OTjQsIElfREwxMl9DSDIsIDEsIDApLA0KKwlTT0NfREFQ TV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMMl9DSDEiLCBBRkVfQ09OTjQsIElfREwyX0NIMSwgMSwg MCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwyX0NIMiIsIEFGRV9DT05ONCwg SV9ETDJfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDNfQ0gx IiwgQUZFX0NPTk40LCBJX0RMM19DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJ U0FCTEUoIkRMM19DSDIiLCBBRkVfQ09OTjQsIElfREwzX0NIMiwgMSwgMCksDQorCVNPQ19EQVBN X1NJTkdMRV9BVVRPRElTQUJMRSgiREw0X0NIMiIsIEFGRV9DT05ONF8xLCBJX0RMNF9DSDIsIDEs IDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkRMNV9DSDIiLCBBRkVfQ09OTjRf MSwgSV9ETDVfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDZf Q0gyIiwgQUZFX0NPTk40XzEsIElfREw2X0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9B VVRPRElTQUJMRSgiREw4X0NIMiIsIEFGRV9DT05ONF8xLCBJX0RMOF9DSDIsIDEsIDApLA0KKwlT T0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkFEREFfVUxfQ0gzIiwgQUZFX0NPTk40LA0KKwkJ CQkgICAgSV9BRERBX1VMX0NIMywgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJM RSgiQUREQV9VTF9DSDIiLCBBRkVfQ09OTjQsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gyLCAxLCAw KSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERBX1VMX0NIMSIsIEFGRV9DT05O NCwNCisJCQkJICAgIElfQUREQV9VTF9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVU T0RJU0FCTEUoIkdBSU4xX09VVF9DSDIiLCBBRkVfQ09OTjQsDQorCQkJCSAgICBJX0dBSU4xX09V VF9DSDIsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBDTV8xX0NBUF9D SDEiLCBBRkVfQ09OTjQsDQorCQkJCSAgICBJX1BDTV8xX0NBUF9DSDEsIDEsIDApLA0KKwlTT0Nf REFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBDTV8yX0NBUF9DSDEiLCBBRkVfQ09OTjQsDQorCQkJ CSAgICBJX1BDTV8yX0NBUF9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FC TEUoIlBDTV8xX0NBUF9DSDIiLCBBRkVfQ09OTjQsDQorCQkJCSAgICBJX1BDTV8xX0NBUF9DSDIs IDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBDTV8yX0NBUF9DSDIiLCBB RkVfQ09OTjQsDQorCQkJCSAgICBJX1BDTV8yX0NBUF9DSDIsIDEsIDApLA0KKwlTT0NfREFQTV9T SU5HTEVfQVVUT0RJU0FCTEUoIlNSQ18xX09VVF9DSDIiLCBBRkVfQ09OTjRfMSwNCisJCQkJICAg IElfU1JDXzFfT1VUX0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgi U1JDXzJfT1VUX0NIMiIsIEFGRV9DT05ONF8xLA0KKwkJCQkgICAgSV9TUkNfMl9PVVRfQ0gyLCAx LCAwKSwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc25kX2tjb250cm9sX25ldyBtdGtf YWRkYV9kbF9jaDNfbWl4W10gPSB7DQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwx X0NIMSIsIEFGRV9DT05ONTIsIElfREwxX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9B VVRPRElTQUJMRSgiREwxMl9DSDEiLCBBRkVfQ09OTjUyLCBJX0RMMTJfQ0gxLCAxLCAwKSwNCisJ U09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDJfQ0gxIiwgQUZFX0NPTk41MiwgSV9ETDJf Q0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDNfQ0gxIiwgQUZF X0NPTk41MiwgSV9ETDNfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxF KCJETDRfQ0gxIiwgQUZFX0NPTk41Ml8xLCBJX0RMNF9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9T SU5HTEVfQVVUT0RJU0FCTEUoIkRMNV9DSDEiLCBBRkVfQ09OTjUyXzEsIElfREw1X0NIMSwgMSwg MCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREw2X0NIMSIsIEFGRV9DT05ONTJf MSwgSV9ETDZfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERB X1VMX0NIMyIsIEFGRV9DT05ONTIsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gzLCAxLCAwKSwNCisJ U09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERBX1VMX0NIMiIsIEFGRV9DT05ONTIsDQor CQkJCSAgICBJX0FEREFfVUxfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNB QkxFKCJBRERBX1VMX0NIMSIsIEFGRV9DT05ONTIsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gxLCAx LCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJHQUlOMV9PVVRfQ0gxIiwgQUZF X0NPTk41MiwNCisJCQkJICAgIElfR0FJTjFfT1VUX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJ TkdMRV9BVVRPRElTQUJMRSgiUENNXzFfQ0FQX0NIMSIsIEFGRV9DT05ONTIsDQorCQkJCSAgICBJ X1BDTV8xX0NBUF9DSDEsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBD TV8yX0NBUF9DSDEiLCBBRkVfQ09OTjUyLA0KKwkJCQkgICAgSV9QQ01fMl9DQVBfQ0gxLCAxLCAw KSwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc25kX2tjb250cm9sX25ldyBtdGtfYWRk YV9kbF9jaDRfbWl4W10gPSB7DQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwxX0NI MSIsIEFGRV9DT05ONTMsIElfREwxX0NIMSwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRP RElTQUJMRSgiREwxX0NIMiIsIEFGRV9DT05ONTMsIElfREwxX0NIMiwgMSwgMCksDQorCVNPQ19E QVBNX1NJTkdMRV9BVVRPRElTQUJMRSgiREwxMl9DSDIiLCBBRkVfQ09OTjUzLCBJX0RMMTJfQ0gy LCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDJfQ0gxIiwgQUZFX0NP Tk41MywgSV9ETDJfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJE TDJfQ0gyIiwgQUZFX0NPTk41MywgSV9ETDJfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xF X0FVVE9ESVNBQkxFKCJETDNfQ0gxIiwgQUZFX0NPTk41MywgSV9ETDNfQ0gxLCAxLCAwKSwNCisJ U09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDNfQ0gyIiwgQUZFX0NPTk41MywgSV9ETDNf Q0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJETDRfQ0gyIiwgQUZF X0NPTk41M18xLCBJX0RMNF9DSDIsIDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FC TEUoIkRMNV9DSDIiLCBBRkVfQ09OTjUzXzEsIElfREw1X0NIMiwgMSwgMCksDQorCVNPQ19EQVBN X1NJTkdMRV9BVVRPRElTQUJMRSgiREw2X0NIMiIsIEFGRV9DT05ONTNfMSwgSV9ETDZfQ0gxLCAx LCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERBX1VMX0NIMyIsIEFGRV9D T05ONTMsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gzLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xF X0FVVE9ESVNBQkxFKCJBRERBX1VMX0NIMiIsIEFGRV9DT05ONTMsDQorCQkJCSAgICBJX0FEREFf VUxfQ0gyLCAxLCAwKSwNCisJU09DX0RBUE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJBRERBX1VMX0NI MSIsIEFGRV9DT05ONTMsDQorCQkJCSAgICBJX0FEREFfVUxfQ0gxLCAxLCAwKSwNCisJU09DX0RB UE1fU0lOR0xFX0FVVE9ESVNBQkxFKCJHQUlOMV9PVVRfQ0gyIiwgQUZFX0NPTk41MywNCisJCQkJ ICAgIElfR0FJTjFfT1VUX0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJM RSgiUENNXzFfQ0FQX0NIMSIsIEFGRV9DT05ONTMsDQorCQkJCSAgICBJX1BDTV8xX0NBUF9DSDEs IDEsIDApLA0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIlBDTV8yX0NBUF9DSDEiLCBB RkVfQ09OTjUzLA0KKwkJCQkgICAgSV9QQ01fMl9DQVBfQ0gxLCAxLCAwKSwNCisJU09DX0RBUE1f U0lOR0xFX0FVVE9ESVNBQkxFKCJQQ01fMV9DQVBfQ0gyIiwgQUZFX0NPTk41MywNCisJCQkJICAg IElfUENNXzFfQ0FQX0NIMiwgMSwgMCksDQorCVNPQ19EQVBNX1NJTkdMRV9BVVRPRElTQUJMRSgi UENNXzJfQ0FQX0NIMiIsIEFGRV9DT05ONTMsDQorCQkJCSAgICBJX1BDTV8yX0NBUF9DSDIsIDEs IDApLA0KK307DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IG10a19z dGZfY2gxX21peFtdID0gew0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkFEREFfVUxf Q0gxIiwgQUZFX0NPTk4xOSwNCisJCQkJICAgIElfQUREQV9VTF9DSDEsIDEsIDApLA0KK307DQor DQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IG10a19zdGZfY2gyX21peFtd ID0gew0KKwlTT0NfREFQTV9TSU5HTEVfQVVUT0RJU0FCTEUoIkFEREFfVUxfQ0gyIiwgQUZFX0NP Tk4yMCwNCisJCQkJICAgIElfQUREQV9VTF9DSDIsIDEsIDApLA0KK307DQorDQorZW51bSB7DQor CVNVUFBMWV9TRVFfQUREQV9BRkVfT04sDQorCVNVUFBMWV9TRVFfQUREQV9ETF9PTiwNCisJU1VQ UExZX1NFUV9BRERBX0FVRF9QQURfVE9QLA0KKwlTVVBQTFlfU0VRX0FEREFfTVRLQUlGX0NGRywN CisJU1VQUExZX1NFUV9BRERBNl9NVEtBSUZfQ0ZHLA0KKwlTVVBQTFlfU0VRX0FEREFfRklGTywN CisJU1VQUExZX1NFUV9BRERBX0FQX0RNSUMsDQorCVNVUFBMWV9TRVFfQUREQV9VTF9PTiwNCit9 Ow0KKw0KK3N0YXRpYyBpbnQgbXRrX2FkZGFfdWxfc3JjX2RtaWMoc3RydWN0IG10a19iYXNlX2Fm ZSAqYWZlLCBpbnQgaWQpDQorew0KKwl1bnNpZ25lZCBpbnQgcmVnOw0KKw0KKwlzd2l0Y2ggKGlk KSB7DQorCWNhc2UgTVQ4MTkyX0RBSV9BRERBOg0KKwljYXNlIE1UODE5Ml9EQUlfQVBfRE1JQzoN CisJCXJlZyA9IEFGRV9BRERBX1VMX1NSQ19DT04wOw0KKwkJYnJlYWs7DQorCWNhc2UgTVQ4MTky X0RBSV9BRERBX0NIMzQ6DQorCWNhc2UgTVQ4MTkyX0RBSV9BUF9ETUlDX0NIMzQ6DQorCQlyZWcg PSBBRkVfQUREQTZfVUxfU1JDX0NPTjA7DQorCQlicmVhazsNCisJZGVmYXVsdDoNCisJCXJldHVy biAtRUlOVkFMOw0KKwl9DQorDQorCS8qIGRtaWMgbW9kZSwgMy4yNU0qLw0KKwlyZWdtYXBfdXBk YXRlX2JpdHMoYWZlLT5yZWdtYXAsIHJlZywNCisJCQkgICBESUdNSUNfM1AyNU1fMVA2MjVNX1NF TF9DVExfTUFTS19TRlQsDQorCQkJICAgMHgwKTsNCisJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+ cmVnbWFwLCByZWcsDQorCQkJICAgRE1JQ19MT1dfUE9XRVJfTU9ERV9DVExfTUFTS19TRlQsDQor CQkJICAgMHgwKTsNCisNCisJLyogdHVybiBvbiBkbWljLCBjaDEsIGNoMiAqLw0KKwlyZWdtYXBf dXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsIHJlZywNCisJCQkgICBVTF9TRE1fM19MRVZFTF9DVExf TUFTS19TRlQsDQorCQkJICAgMHgxIDw8IFVMX1NETV8zX0xFVkVMX0NUTF9TRlQpOw0KKwlyZWdt YXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsIHJlZywNCisJCQkgICBVTF9NT0RFXzNQMjVNX0NI MV9DVExfTUFTS19TRlQsDQorCQkJICAgMHgxIDw8IFVMX01PREVfM1AyNU1fQ0gxX0NUTF9TRlQp Ow0KKwlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsIHJlZywNCisJCQkgICBVTF9NT0RF XzNQMjVNX0NIMl9DVExfTUFTS19TRlQsDQorCQkJICAgMHgxIDw8IFVMX01PREVfM1AyNU1fQ0gy X0NUTF9TRlQpOw0KKwlyZXR1cm4gMDsNCit9DQorDQorc3RhdGljIGludCBtdGtfYWRkYV91bF9l dmVudChzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCAqdywNCisJCQkgICAgIHN0cnVjdCBzbmRf a2NvbnRyb2wgKmtjb250cm9sLA0KKwkJCSAgICAgaW50IGV2ZW50KQ0KK3sNCisJc3RydWN0IHNu ZF9zb2NfY29tcG9uZW50ICpjbXBudCA9IHNuZF9zb2NfZGFwbV90b19jb21wb25lbnQody0+ZGFw bSk7DQorCXN0cnVjdCBtdGtfYmFzZV9hZmUgKmFmZSA9IHNuZF9zb2NfY29tcG9uZW50X2dldF9k cnZkYXRhKGNtcG50KTsNCisJc3RydWN0IG10ODE5Ml9hZmVfcHJpdmF0ZSAqYWZlX3ByaXYgPSBh ZmUtPnBsYXRmb3JtX3ByaXY7DQorCWludCBtdGthaWZfZG1pYyA9IGFmZV9wcml2LT5tdGthaWZf ZG1pYzsNCisNCisJZGV2X2luZm8oYWZlLT5kZXYsICIlcygpLCBuYW1lICVzLCBldmVudCAweCV4 LCBtdGthaWZfZG1pYyAlZFxuIiwNCisJCSBfX2Z1bmNfXywgdy0+bmFtZSwgZXZlbnQsIG10a2Fp Zl9kbWljKTsNCisNCisJc3dpdGNoIChldmVudCkgew0KKwljYXNlIFNORF9TT0NfREFQTV9QUkVf UE1VOg0KKwkJbXQ4MTkyX2FmZV9ncGlvX3JlcXVlc3QoYWZlLT5kZXYsIHRydWUsIE1UODE5Ml9E QUlfQUREQSwgMSk7DQorDQorCQkvKiB1cGRhdGUgc2V0dGluZyB0byBkbWljICovDQorCQlpZiAo bXRrYWlmX2RtaWMpIHsNCisJCQkvKiBtdGthaWZfcnhpZl9kYXRhX21vZGUgPSAxLCBkbWljICov DQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLCBBRkVfQUREQV9NVEtBSUZfUlhf Q0ZHMCwNCisJCQkJCSAgIDB4MSwgMHgxKTsNCisNCisJCQkvKiBkbWljIG1vZGUsIDMuMjVNKi8N CisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsIEFGRV9BRERBX01US0FJRl9SWF9D RkcwLA0KKwkJCQkJICAgTVRLQUlGX1JYSUZfVk9JQ0VfTU9ERV9NQVNLX1NGVCwNCisJCQkJCSAg IDB4MCk7DQorCQkJbXRrX2FkZGFfdWxfc3JjX2RtaWMoYWZlLCBNVDgxOTJfREFJX0FEREEpOw0K KwkJfQ0KKwkJYnJlYWs7DQorCWNhc2UgU05EX1NPQ19EQVBNX1BPU1RfUE1EOg0KKwkJLyogc2hv dWxkIGRlbGF5ZWQgMS9mcyhzbWFsbGVzdCBpcyA4aykgPSAxMjV1cyBiZWZvcmUgYWZlIG9mZiAq Lw0KKwkJdXNsZWVwX3JhbmdlKDEyNSwgMTM1KTsNCisJCW10ODE5Ml9hZmVfZ3Bpb19yZXF1ZXN0 KGFmZS0+ZGV2LCBmYWxzZSwgTVQ4MTkyX0RBSV9BRERBLCAxKTsNCisJCWJyZWFrOw0KKwlkZWZh dWx0Og0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBpbnQg bXRrX2FkZGFfY2gzNF91bF9ldmVudChzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCAqdywNCisJ CQkJICBzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJCQkJICBpbnQgZXZlbnQpDQor ew0KKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19kYXBtX3RvX2Nv bXBvbmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19j b21wb25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRl ICphZmVfcHJpdiA9IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisJaW50IG10a2FpZl9kbWljID0gYWZl X3ByaXYtPm10a2FpZl9kbWljX2NoMzQ7DQorCWludCBtdGthaWZfYWRkYTZfb25seSA9IGFmZV9w cml2LT5tdGthaWZfYWRkYTZfb25seTsNCisNCisJZGV2X2luZm8oYWZlLT5kZXYsDQorCQkgIiVz KCksIG5hbWUgJXMsIGV2ZW50IDB4JXgsIG10a2FpZl9kbWljICVkLCBtdGthaWZfYWRkYTZfb25s eSAlZFxuIiwNCisJCSBfX2Z1bmNfXywgdy0+bmFtZSwgZXZlbnQsIG10a2FpZl9kbWljLCBtdGth aWZfYWRkYTZfb25seSk7DQorDQorCXN3aXRjaCAoZXZlbnQpIHsNCisJY2FzZSBTTkRfU09DX0RB UE1fUFJFX1BNVToNCisJCW10ODE5Ml9hZmVfZ3Bpb19yZXF1ZXN0KGFmZS0+ZGV2LCB0cnVlLCBN VDgxOTJfREFJX0FEREFfQ0gzNCwNCisJCQkJCTEpOw0KKw0KKwkJLyogdXBkYXRlIHNldHRpbmcg dG8gZG1pYyAqLw0KKwkJaWYgKG10a2FpZl9kbWljKSB7DQorCQkJLyogbXRrYWlmX3J4aWZfZGF0 YV9tb2RlID0gMSwgZG1pYyAqLw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwN CisJCQkJCSAgIEFGRV9BRERBNl9NVEtBSUZfUlhfQ0ZHMCwNCisJCQkJCSAgIDB4MSwgMHgxKTsN CisNCisJCQkvKiBkbWljIG1vZGUsIDMuMjVNKi8NCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZl LT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQTZfTVRLQUlGX1JYX0NGRzAsDQorCQkJCQkgICBN VEtBSUZfUlhJRl9WT0lDRV9NT0RFX01BU0tfU0ZULA0KKwkJCQkJICAgMHgwKTsNCisJCQltdGtf YWRkYV91bF9zcmNfZG1pYyhhZmUsIE1UODE5Ml9EQUlfQUREQV9DSDM0KTsNCisJCX0NCisNCisJ CS8qIHdoZW4gdXNpbmcgYWRkYTYgd2l0aG91dCBhZGRhIGVuYWJsZWQsDQorCQkgKiBSR19BRERB Nl9NVEtBSUZfUlhfU1lOQ19XT1JEMl9ESVNBQkxFX1NGVCBuZWVkIHRvIGJlIHNldCBvcg0KKwkJ ICogZGF0YSBjYW5ub3QgYmUgcmVjZWl2ZWQuDQorCQkgKi8NCisJCWlmIChtdGthaWZfYWRkYTZf b25seSkgew0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJCSAgIEFG RV9BRERBX01US0FJRl9TWU5DV09SRF9DRkcsDQorCQkJCQkgICAweDEgPDwgMjMsIDB4MSA8PCAy Myk7DQorCQl9DQorCQlicmVhazsNCisJY2FzZSBTTkRfU09DX0RBUE1fUE9TVF9QTUQ6DQorCQkv KiBzaG91bGQgZGVsYXllZCAxL2ZzKHNtYWxsZXN0IGlzIDhrKSA9IDEyNXVzIGJlZm9yZSBhZmUg b2ZmICovDQorCQl1c2xlZXBfcmFuZ2UoMTI1LCAxMzUpOw0KKwkJbXQ4MTkyX2FmZV9ncGlvX3Jl cXVlc3QoYWZlLT5kZXYsIGZhbHNlLCBNVDgxOTJfREFJX0FEREFfQ0gzNCwNCisJCQkJCTEpOw0K Kw0KKwkJLyogcmVzZXQgZG1pYyAqLw0KKwkJYWZlX3ByaXYtPm10a2FpZl9kbWljX2NoMzQgPSAw Ow0KKw0KKwkJaWYgKG10a2FpZl9hZGRhNl9vbmx5KSB7DQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRz KGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgQUZFX0FEREFfTVRLQUlGX1NZTkNXT1JEX0NGRywNCisJ CQkJCSAgIDB4MSA8PCAyMywgMHgwIDw8IDIzKTsNCisJCX0NCisJCWJyZWFrOw0KKwlkZWZhdWx0 Og0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBpbnQgbXRr X2FkZGFfcGFkX3RvcF9ldmVudChzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCAqdywNCisJCQkJ ICBzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJCQkJICBpbnQgZXZlbnQpDQorew0K KwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19kYXBtX3RvX2NvbXBv bmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19jb21w b25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRlICph ZmVfcHJpdiA9IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisNCisJc3dpdGNoIChldmVudCkgew0KKwlj YXNlIFNORF9TT0NfREFQTV9QUkVfUE1VOg0KKwkJaWYgKGFmZV9wcml2LT5tdGthaWZfcHJvdG9j b2wgPT0gTVRLQUlGX1BST1RPQ09MXzJfQ0xLX1AyKQ0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJl Z21hcCwgQUZFX0FVRF9QQURfVE9QLCAweDM4KTsNCisJCWVsc2UgaWYgKGFmZV9wcml2LT5tdGth aWZfcHJvdG9jb2wgPT0gTVRLQUlGX1BST1RPQ09MXzIpDQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+ cmVnbWFwLCBBRkVfQVVEX1BBRF9UT1AsIDB4MzApOw0KKwkJZWxzZQ0KKwkJCXJlZ21hcF93cml0 ZShhZmUtPnJlZ21hcCwgQUZFX0FVRF9QQURfVE9QLCAweDMwKTsNCisJCWJyZWFrOw0KKwlkZWZh dWx0Og0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBpbnQg bXRrX2FkZGFfbXRrYWlmX2NmZ19ldmVudChzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCAqdywN CisJCQkJICAgICBzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJCQkJICAgICBpbnQg ZXZlbnQpDQorew0KKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19k YXBtX3RvX2NvbXBvbmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0g c25kX3NvY19jb21wb25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2Fm ZV9wcml2YXRlICphZmVfcHJpdiA9IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisJaW50IGRlbGF5X2Rh dGE7DQorCWludCBkZWxheV9jeWNsZTsNCisNCisJc3dpdGNoIChldmVudCkgew0KKwljYXNlIFNO RF9TT0NfREFQTV9QUkVfUE1VOg0KKwkJaWYgKGFmZV9wcml2LT5tdGthaWZfcHJvdG9jb2wgPT0g TVRLQUlGX1BST1RPQ09MXzJfQ0xLX1AyKSB7DQorCQkJLyogc2V0IHByb3RvY29sIDIgKi8NCisJ CQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsIEFGRV9BRERBX01US0FJRl9DRkcwLA0KKwkJCQkg ICAgIDB4MDAwMTAwMDApOw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwgQUZFX0FEREE2 X01US0FJRl9DRkcwLA0KKwkJCQkgICAgIDB4MDAwMTAwMDApOw0KKw0KKwkJCWlmIChzdHJjbXAo dy0+bmFtZSwgIkFEREFfTVRLQUlGX0NGRyIpID09IDAgJiYNCisJCQkgICAgKGFmZV9wcml2LT5t dGthaWZfY2hvc2VuX3BoYXNlWzBdIDwgMCB8fA0KKwkJCSAgICAgYWZlX3ByaXYtPm10a2FpZl9j aG9zZW5fcGhhc2VbMV0gPCAwKSkgew0KKwkJCQlkZXZfd2FybihhZmUtPmRldiwNCisJCQkJCSAi JXMoKSwgbXRrYWlmX2Nob3Nlbl9waGFzZVswLzFdOiVkLyVkXG4iLA0KKwkJCQkJIF9fZnVuY19f LA0KKwkJCQkJIGFmZV9wcml2LT5tdGthaWZfY2hvc2VuX3BoYXNlWzBdLA0KKwkJCQkJIGFmZV9w cml2LT5tdGthaWZfY2hvc2VuX3BoYXNlWzFdKTsNCisJCQkJYnJlYWs7DQorCQkJfSBlbHNlIGlm IChzdHJjbXAody0+bmFtZSwgIkFEREE2X01US0FJRl9DRkciKSA9PSAwICYmDQorCQkJCSAgIGFm ZV9wcml2LT5tdGthaWZfY2hvc2VuX3BoYXNlWzJdIDwgMCkgew0KKwkJCQlkZXZfd2FybihhZmUt PmRldiwNCisJCQkJCSAiJXMoKSwgbXRrYWlmX2Nob3Nlbl9waGFzZVsyXTolZFxuIiwNCisJCQkJ CSBfX2Z1bmNfXywNCisJCQkJCSBhZmVfcHJpdi0+bXRrYWlmX2Nob3Nlbl9waGFzZVsyXSk7DQor CQkJCWJyZWFrOw0KKwkJCX0NCisNCisJCQkvKiBtdGthaWZfcnhpZl9jbGtpbnZfYWRjIGludmVy c2UgZm9yIGNhbGlicmF0aW9uICovDQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFw LCBBRkVfQUREQV9NVEtBSUZfQ0ZHMCwNCisJCQkJCSAgIE1US0FJRl9SWElGX0NMS0lOVl9BRENf TUFTS19TRlQsDQorCQkJCQkgICAweDEgPDwgTVRLQUlGX1JYSUZfQ0xLSU5WX0FEQ19TRlQpOw0K KwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwgQUZFX0FEREE2X01US0FJRl9DRkcw LA0KKwkJCQkJICAgTVRLQUlGX1JYSUZfQ0xLSU5WX0FEQ19NQVNLX1NGVCwNCisJCQkJCSAgIDB4 MSA8PCBNVEtBSUZfUlhJRl9DTEtJTlZfQURDX1NGVCk7DQorDQorCQkJLyogc2V0IGRlbGF5IGZv ciBjaDEyICovDQorCQkJaWYgKGFmZV9wcml2LT5tdGthaWZfcGhhc2VfY3ljbGVbMF0gPj0NCisJ CQkgICAgYWZlX3ByaXYtPm10a2FpZl9waGFzZV9jeWNsZVsxXSkgew0KKwkJCQlkZWxheV9kYXRh ID0gREVMQVlfREFUQV9NSVNPMTsNCisJCQkJZGVsYXlfY3ljbGUgPSBhZmVfcHJpdi0+bXRrYWlm X3BoYXNlX2N5Y2xlWzBdIC0NCisJCQkJCSAgICAgIGFmZV9wcml2LT5tdGthaWZfcGhhc2VfY3lj bGVbMV07DQorCQkJfSBlbHNlIHsNCisJCQkJZGVsYXlfZGF0YSA9IERFTEFZX0RBVEFfTUlTTzI7 DQorCQkJCWRlbGF5X2N5Y2xlID0gYWZlX3ByaXYtPm10a2FpZl9waGFzZV9jeWNsZVsxXSAtDQor CQkJCQkgICAgICBhZmVfcHJpdi0+bXRrYWlmX3BoYXNlX2N5Y2xlWzBdOw0KKwkJCX0NCisNCisJ CQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQV9NVEtB SUZfUlhfQ0ZHMiwNCisJCQkJCSAgIE1US0FJRl9SWElGX0RFTEFZX0RBVEFfTUFTS19TRlQsDQor CQkJCQkgICBkZWxheV9kYXRhIDw8DQorCQkJCQkgICBNVEtBSUZfUlhJRl9ERUxBWV9EQVRBX1NG VCk7DQorDQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgQUZF X0FEREFfTVRLQUlGX1JYX0NGRzIsDQorCQkJCQkgICBNVEtBSUZfUlhJRl9ERUxBWV9DWUNMRV9N QVNLX1NGVCwNCisJCQkJCSAgIGRlbGF5X2N5Y2xlIDw8DQorCQkJCQkgICBNVEtBSUZfUlhJRl9E RUxBWV9DWUNMRV9TRlQpOw0KKw0KKwkJCS8qIHNldCBkZWxheSBiZXR3ZWVuIGNoMyBhbmQgY2gy ICovDQorCQkJaWYgKGFmZV9wcml2LT5tdGthaWZfcGhhc2VfY3ljbGVbMl0gPj0NCisJCQkgICAg YWZlX3ByaXYtPm10a2FpZl9waGFzZV9jeWNsZVsxXSkgew0KKwkJCQlkZWxheV9kYXRhID0gREVM QVlfREFUQV9NSVNPMTsJLyogY2gzICovDQorCQkJCWRlbGF5X2N5Y2xlID0gYWZlX3ByaXYtPm10 a2FpZl9waGFzZV9jeWNsZVsyXSAtDQorCQkJCQkgICAgICBhZmVfcHJpdi0+bXRrYWlmX3BoYXNl X2N5Y2xlWzFdOw0KKwkJCX0gZWxzZSB7DQorCQkJCWRlbGF5X2RhdGEgPSBERUxBWV9EQVRBX01J U08yOwkvKiBjaDIgKi8NCisJCQkJZGVsYXlfY3ljbGUgPSBhZmVfcHJpdi0+bXRrYWlmX3BoYXNl X2N5Y2xlWzFdIC0NCisJCQkJCSAgICAgIGFmZV9wcml2LT5tdGthaWZfcGhhc2VfY3ljbGVbMl07 DQorCQkJfQ0KKw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJCSAg IEFGRV9BRERBNl9NVEtBSUZfUlhfQ0ZHMiwNCisJCQkJCSAgIE1US0FJRl9SWElGX0RFTEFZX0RB VEFfTUFTS19TRlQsDQorCQkJCQkgICBkZWxheV9kYXRhIDw8DQorCQkJCQkgICBNVEtBSUZfUlhJ Rl9ERUxBWV9EQVRBX1NGVCk7DQorCQkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0K KwkJCQkJICAgQUZFX0FEREE2X01US0FJRl9SWF9DRkcyLA0KKwkJCQkJICAgTVRLQUlGX1JYSUZf REVMQVlfQ1lDTEVfTUFTS19TRlQsDQorCQkJCQkgICBkZWxheV9jeWNsZSA8PA0KKwkJCQkJICAg TVRLQUlGX1JYSUZfREVMQVlfQ1lDTEVfU0ZUKTsNCisJCX0gZWxzZSBpZiAoYWZlX3ByaXYtPm10 a2FpZl9wcm90b2NvbCA9PSBNVEtBSUZfUFJPVE9DT0xfMikgew0KKwkJCXJlZ21hcF93cml0ZShh ZmUtPnJlZ21hcCwgQUZFX0FEREFfTVRLQUlGX0NGRzAsDQorCQkJCSAgICAgMHgwMDAxMDAwMCk7 DQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLCBBRkVfQUREQTZfTVRLQUlGX0NGRzAsDQor CQkJCSAgICAgMHgwMDAxMDAwMCk7DQorCQl9IGVsc2Ugew0KKwkJCXJlZ21hcF93cml0ZShhZmUt PnJlZ21hcCwgQUZFX0FEREFfTVRLQUlGX0NGRzAsIDB4MCk7DQorCQkJcmVnbWFwX3dyaXRlKGFm ZS0+cmVnbWFwLCBBRkVfQUREQTZfTVRLQUlGX0NGRzAsIDB4MCk7DQorCQl9DQorCQlicmVhazsN CisJZGVmYXVsdDoNCisJCWJyZWFrOw0KKwl9DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0 aWMgaW50IG10a19hZGRhX2RsX2V2ZW50KHN0cnVjdCBzbmRfc29jX2RhcG1fd2lkZ2V0ICp3LA0K KwkJCSAgICAgc3RydWN0IHNuZF9rY29udHJvbCAqa2NvbnRyb2wsDQorCQkJICAgICBpbnQgZXZl bnQpDQorew0KKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19kYXBt X3RvX2NvbXBvbmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25k X3NvY19jb21wb25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKw0KKwlkZXZfaW5mbyhhZmUtPmRl diwgIiVzKCksIG5hbWUgJXMsIGV2ZW50IDB4JXhcbiIsDQorCQkgX19mdW5jX18sIHctPm5hbWUs IGV2ZW50KTsNCisNCisJc3dpdGNoIChldmVudCkgew0KKwljYXNlIFNORF9TT0NfREFQTV9QUkVf UE1VOg0KKwkJbXQ4MTkyX2FmZV9ncGlvX3JlcXVlc3QoYWZlLT5kZXYsIHRydWUsIE1UODE5Ml9E QUlfQUREQSwgMCk7DQorCQlicmVhazsNCisJY2FzZSBTTkRfU09DX0RBUE1fUE9TVF9QTUQ6DQor CQkvKiBzaG91bGQgZGVsYXllZCAxL2ZzKHNtYWxsZXN0IGlzIDhrKSA9IDEyNXVzIGJlZm9yZSBh ZmUgb2ZmICovDQorCQl1c2xlZXBfcmFuZ2UoMTI1LCAxMzUpOw0KKwkJbXQ4MTkyX2FmZV9ncGlv X3JlcXVlc3QoYWZlLT5kZXYsIGZhbHNlLCBNVDgxOTJfREFJX0FEREEsIDApOw0KKwkJYnJlYWs7 DQorCWRlZmF1bHQ6DQorCQlicmVhazsNCisJfQ0KKw0KKwlyZXR1cm4gMDsNCit9DQorDQorc3Rh dGljIGludCBtdGtfYWRkYV9jaDM0X2RsX2V2ZW50KHN0cnVjdCBzbmRfc29jX2RhcG1fd2lkZ2V0 ICp3LA0KKwkJCQkgIHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtjb250cm9sLA0KKwkJCQkgIGludCBl dmVudCkNCit7DQorCXN0cnVjdCBzbmRfc29jX2NvbXBvbmVudCAqY21wbnQgPSBzbmRfc29jX2Rh cG1fdG9fY29tcG9uZW50KHctPmRhcG0pOw0KKwlzdHJ1Y3QgbXRrX2Jhc2VfYWZlICphZmUgPSBz bmRfc29jX2NvbXBvbmVudF9nZXRfZHJ2ZGF0YShjbXBudCk7DQorDQorCWRldl9pbmZvKGFmZS0+ ZGV2LCAiJXMoKSwgbmFtZSAlcywgZXZlbnQgMHgleFxuIiwNCisJCSBfX2Z1bmNfXywgdy0+bmFt ZSwgZXZlbnQpOw0KKw0KKwlzd2l0Y2ggKGV2ZW50KSB7DQorCWNhc2UgU05EX1NPQ19EQVBNX1BS RV9QTVU6DQorCQltdDgxOTJfYWZlX2dwaW9fcmVxdWVzdChhZmUtPmRldiwgdHJ1ZSwgTVQ4MTky X0RBSV9BRERBX0NIMzQsDQorCQkJCQkwKTsNCisJCWJyZWFrOw0KKwljYXNlIFNORF9TT0NfREFQ TV9QT1NUX1BNRDoNCisJCS8qIHNob3VsZCBkZWxheWVkIDEvZnMoc21hbGxlc3QgaXMgOGspID0g MTI1dXMgYmVmb3JlIGFmZSBvZmYgKi8NCisJCXVzbGVlcF9yYW5nZSgxMjUsIDEzNSk7DQorCQlt dDgxOTJfYWZlX2dwaW9fcmVxdWVzdChhZmUtPmRldiwgZmFsc2UsIE1UODE5Ml9EQUlfQUREQV9D SDM0LA0KKwkJCQkJMCk7DQorCQlicmVhazsNCisJZGVmYXVsdDoNCisJCWJyZWFrOw0KKwl9DQor DQorCXJldHVybiAwOw0KK30NCisNCisvKiBzdGYgKi8NCitzdGF0aWMgaW50IHN0Zl9wb3NpdGl2 ZV9nYWluX2dldChzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJCQkJIHN0cnVjdCBz bmRfY3RsX2VsZW1fdmFsdWUgKnVjb250cm9sKQ0KK3sNCisJc3RydWN0IHNuZF9zb2NfY29tcG9u ZW50ICpjbXBudCA9IHNuZF9zb2Nfa2NvbnRyb2xfY29tcG9uZW50KGtjb250cm9sKTsNCisJc3Ry dWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19jb21wb25lbnRfZ2V0X2RydmRhdGEoY21w bnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRlICphZmVfcHJpdiA9IGFmZS0+cGxhdGZv cm1fcHJpdjsNCisNCisJdWNvbnRyb2wtPnZhbHVlLmludGVnZXIudmFsdWVbMF0gPSBhZmVfcHJp di0+c3RmX3Bvc2l0aXZlX2dhaW5fZGI7DQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgaW50 IHN0Zl9wb3NpdGl2ZV9nYWluX3NldChzdHJ1Y3Qgc25kX2tjb250cm9sICprY29udHJvbCwNCisJ CQkJIHN0cnVjdCBzbmRfY3RsX2VsZW1fdmFsdWUgKnVjb250cm9sKQ0KK3sNCisJc3RydWN0IHNu ZF9zb2NfY29tcG9uZW50ICpjbXBudCA9IHNuZF9zb2Nfa2NvbnRyb2xfY29tcG9uZW50KGtjb250 cm9sKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19jb21wb25lbnRfZ2V0 X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRlICphZmVfcHJpdiA9 IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisJaW50IGdhaW5fZGIgPSB1Y29udHJvbC0+dmFsdWUuaW50 ZWdlci52YWx1ZVswXTsNCisNCisJYWZlX3ByaXYtPnN0Zl9wb3NpdGl2ZV9nYWluX2RiID0gZ2Fp bl9kYjsNCisNCisJaWYgKGdhaW5fZGIgPj0gMCAmJiBnYWluX2RiIDw9IDI0KSB7DQorCQlyZWdt YXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCSAgIEFGRV9TSURFVE9ORV9HQUlOLA0K KwkJCQkgICBQT1NJVElWRV9HQUlOX01BU0tfU0ZULA0KKwkJCQkgICAoZ2Fpbl9kYiAvIDYpIDw8 IFBPU0lUSVZFX0dBSU5fU0ZUKTsNCisJfSBlbHNlIHsNCisJCWRldl93YXJuKGFmZS0+ZGV2LCAi JXMoKSwgZ2Fpbl9kYiAlZCBpbnZhbGlkXG4iLA0KKwkJCSBfX2Z1bmNfXywgZ2Fpbl9kYik7DQor CX0NCisJcmV0dXJuIDA7DQorfQ0KKw0KKy8qIG10a2FpZiBkbWljICovDQorc3RhdGljIGNvbnN0 IGNoYXIgKiBjb25zdCBtdDgxOTJfYWRkYV9vZmZfb25fc3RyW10gPSB7DQorCSJPZmYiLCAiT24i DQorfTsNCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IHNvY19lbnVtIG10ODE5Ml9hZGRhX2VudW1b XSA9IHsNCisJU09DX0VOVU1fU0lOR0xFX0VYVChBUlJBWV9TSVpFKG10ODE5Ml9hZGRhX29mZl9v bl9zdHIpLA0KKwkJCSAgICBtdDgxOTJfYWRkYV9vZmZfb25fc3RyKSwNCit9Ow0KKw0KK3N0YXRp YyBpbnQgbXQ4MTkyX2FkZGFfZG1pY19nZXQoc3RydWN0IHNuZF9rY29udHJvbCAqa2NvbnRyb2ws DQorCQkJCXN0cnVjdCBzbmRfY3RsX2VsZW1fdmFsdWUgKnVjb250cm9sKQ0KK3sNCisJc3RydWN0 IHNuZF9zb2NfY29tcG9uZW50ICpjbXBudCA9IHNuZF9zb2Nfa2NvbnRyb2xfY29tcG9uZW50KGtj b250cm9sKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZlID0gc25kX3NvY19jb21wb25lbnRf Z2V0X2RydmRhdGEoY21wbnQpOw0KKwlzdHJ1Y3QgbXQ4MTkyX2FmZV9wcml2YXRlICphZmVfcHJp diA9IGFmZS0+cGxhdGZvcm1fcHJpdjsNCisNCisJdWNvbnRyb2wtPnZhbHVlLmludGVnZXIudmFs dWVbMF0gPSBhZmVfcHJpdi0+bXRrYWlmX2RtaWM7DQorCXJldHVybiAwOw0KK30NCisNCitzdGF0 aWMgaW50IG10ODE5Ml9hZGRhX2RtaWNfc2V0KHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtjb250cm9s LA0KKwkJCQlzdHJ1Y3Qgc25kX2N0bF9lbGVtX3ZhbHVlICp1Y29udHJvbCkNCit7DQorCXN0cnVj dCBzbmRfc29jX2NvbXBvbmVudCAqY21wbnQgPSBzbmRfc29jX2tjb250cm9sX2NvbXBvbmVudChr Y29udHJvbCk7DQorCXN0cnVjdCBtdGtfYmFzZV9hZmUgKmFmZSA9IHNuZF9zb2NfY29tcG9uZW50 X2dldF9kcnZkYXRhKGNtcG50KTsNCisJc3RydWN0IG10ODE5Ml9hZmVfcHJpdmF0ZSAqYWZlX3By aXYgPSBhZmUtPnBsYXRmb3JtX3ByaXY7DQorCXN0cnVjdCBzb2NfZW51bSAqZSA9IChzdHJ1Y3Qg c29jX2VudW0gKilrY29udHJvbC0+cHJpdmF0ZV92YWx1ZTsNCisJaW50IGRtaWNfb247DQorDQor CWlmICh1Y29udHJvbC0+dmFsdWUuZW51bWVyYXRlZC5pdGVtWzBdID49IGUtPml0ZW1zKQ0KKwkJ cmV0dXJuIC1FSU5WQUw7DQorDQorCWRtaWNfb24gPSB1Y29udHJvbC0+dmFsdWUuaW50ZWdlci52 YWx1ZVswXTsNCisNCisJZGV2X2luZm8oYWZlLT5kZXYsICIlcygpLCBrY29udHJvbCBuYW1lICVz LCBkbWljX29uICVkXG4iLA0KKwkJIF9fZnVuY19fLCBrY29udHJvbC0+aWQubmFtZSwgZG1pY19v bik7DQorDQorCWFmZV9wcml2LT5tdGthaWZfZG1pYyA9IGRtaWNfb247DQorCWFmZV9wcml2LT5t dGthaWZfZG1pY19jaDM0ID0gZG1pY19vbjsNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRpYyBp bnQgbXQ4MTkyX2FkZGE2X29ubHlfZ2V0KHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtjb250cm9sLA0K KwkJCQkgc3RydWN0IHNuZF9jdGxfZWxlbV92YWx1ZSAqdWNvbnRyb2wpDQorew0KKwlzdHJ1Y3Qg c25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19rY29udHJvbF9jb21wb25lbnQoa2Nv bnRyb2wpOw0KKwlzdHJ1Y3QgbXRrX2Jhc2VfYWZlICphZmUgPSBzbmRfc29jX2NvbXBvbmVudF9n ZXRfZHJ2ZGF0YShjbXBudCk7DQorCXN0cnVjdCBtdDgxOTJfYWZlX3ByaXZhdGUgKmFmZV9wcml2 ID0gYWZlLT5wbGF0Zm9ybV9wcml2Ow0KKw0KKwl1Y29udHJvbC0+dmFsdWUuaW50ZWdlci52YWx1 ZVswXSA9IGFmZV9wcml2LT5tdGthaWZfYWRkYTZfb25seTsNCisJcmV0dXJuIDA7DQorfQ0KKw0K K3N0YXRpYyBpbnQgbXQ4MTkyX2FkZGE2X29ubHlfc2V0KHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtj b250cm9sLA0KKwkJCQkgc3RydWN0IHNuZF9jdGxfZWxlbV92YWx1ZSAqdWNvbnRyb2wpDQorew0K KwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3NvY19rY29udHJvbF9jb21w b25lbnQoa2NvbnRyb2wpOw0KKwlzdHJ1Y3QgbXRrX2Jhc2VfYWZlICphZmUgPSBzbmRfc29jX2Nv bXBvbmVudF9nZXRfZHJ2ZGF0YShjbXBudCk7DQorCXN0cnVjdCBtdDgxOTJfYWZlX3ByaXZhdGUg KmFmZV9wcml2ID0gYWZlLT5wbGF0Zm9ybV9wcml2Ow0KKwlzdHJ1Y3Qgc29jX2VudW0gKmUgPSAo c3RydWN0IHNvY19lbnVtICopa2NvbnRyb2wtPnByaXZhdGVfdmFsdWU7DQorCWludCBtdGthaWZf YWRkYTZfb25seTsNCisNCisJaWYgKHVjb250cm9sLT52YWx1ZS5lbnVtZXJhdGVkLml0ZW1bMF0g Pj0gZS0+aXRlbXMpDQorCQlyZXR1cm4gLUVJTlZBTDsNCisNCisJbXRrYWlmX2FkZGE2X29ubHkg PSB1Y29udHJvbC0+dmFsdWUuaW50ZWdlci52YWx1ZVswXTsNCisNCisJZGV2X2luZm8oYWZlLT5k ZXYsICIlcygpLCBrY29udHJvbCBuYW1lICVzLCBtdGthaWZfYWRkYTZfb25seSAlZFxuIiwNCisJ CSBfX2Z1bmNfXywga2NvbnRyb2wtPmlkLm5hbWUsIG10a2FpZl9hZGRhNl9vbmx5KTsNCisNCisJ YWZlX3ByaXYtPm10a2FpZl9hZGRhNl9vbmx5ID0gbXRrYWlmX2FkZGE2X29ubHk7DQorCXJldHVy biAwOw0KK30NCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IHNuZF9rY29udHJvbF9uZXcgbXRrX2Fk ZGFfY29udHJvbHNbXSA9IHsNCisJU09DX1NJTkdMRSgiU2lkZXRvbmVfR2FpbiIsIEFGRV9TSURF VE9ORV9HQUlOLA0KKwkJICAgU0lERV9UT05FX0dBSU5fU0ZULCBTSURFX1RPTkVfR0FJTl9NQVNL LCAwKSwNCisJU09DX1NJTkdMRV9FWFQoIlNpZGV0b25lX1Bvc2l0aXZlX0dhaW5fZEIiLCBTTkRf U09DX05PUE0sIDAsIDEwMCwgMCwNCisJCSAgICAgICBzdGZfcG9zaXRpdmVfZ2Fpbl9nZXQsIHN0 Zl9wb3NpdGl2ZV9nYWluX3NldCksDQorCVNPQ19TSU5HTEUoIkFEREFfRExfR0FJTiIsIEFGRV9B RERBX0RMX1NSQzJfQ09OMSwNCisJCSAgIERMXzJfR0FJTl9DVExfUFJFX1NGVCwgRExfMl9HQUlO X0NUTF9QUkVfTUFTSywgMCksDQorCVNPQ19FTlVNX0VYVCgiTVRLQUlGX0RNSUMiLCBtdDgxOTJf YWRkYV9lbnVtWzBdLA0KKwkJICAgICBtdDgxOTJfYWRkYV9kbWljX2dldCwgbXQ4MTkyX2FkZGFf ZG1pY19zZXQpLA0KKwlTT0NfRU5VTV9FWFQoIk1US0FJRl9BRERBNl9PTkxZIiwgbXQ4MTkyX2Fk ZGFfZW51bVswXSwNCisJCSAgICAgbXQ4MTkyX2FkZGE2X29ubHlfZ2V0LCBtdDgxOTJfYWRkYTZf b25seV9zZXQpLA0KK307DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3 IHN0Zl9jdGwgPQ0KKwlTT0NfREFQTV9TSU5HTEUoIlN3aXRjaCIsIFNORF9TT0NfTk9QTSwgMCwg MSwgMCk7DQorDQorc3RhdGljIGNvbnN0IHUxNiBzdGZfY29lZmZfdGFibGVfMTZrW10gPSB7DQor CTB4MDQ5QywgMHgwOUU4LCAweDA5RTAsIDB4MDg5QywNCisJMHhGRjU0LCAweEY0ODgsIDB4RUFG QywgMHhFQkFDLA0KKwkweGZBNDAsIDB4MTdBQywgMHgzRDFDLCAweDYwMjgsDQorCTB4NzUzOA0K K307DQorDQorc3RhdGljIGNvbnN0IHUxNiBzdGZfY29lZmZfdGFibGVfMzJrW10gPSB7DQorCTB4 RkU1MiwgMHgwMDQyLCAweDAwQzUsIDB4MDE5NCwNCisJMHgwMjlBLCAweDAzQjcsIDB4MDRCRiwg MHgwNTdELA0KKwkweDA1QkUsIDB4MDU1NSwgMHgwNDI2LCAweDAyMzAsDQorCTB4RkY5MiwgMHhG Qzg5LCAweEY5NzMsIDB4RjZDNiwNCisJMHhGNTAwLCAweEY0OUQsIDB4RjYwMywgMHhGOTcwLA0K KwkweEZFRjMsIDB4MDY1RiwgMHgwRjRGLCAweDE5MjgsDQorCTB4MjMyOSwgMHgyQzgwLCAweDM0 NUUsIDB4M0EwRCwNCisJMHgzRDA4DQorfTsNCisNCitzdGF0aWMgY29uc3QgdTE2IHN0Zl9jb2Vm Zl90YWJsZV80OGtbXSA9IHsNCisJMHgwNDAxLCAweEZGQjAsIDB4RkY1QSwgMHhGRUNFLA0KKwkw eEZFMTAsIDB4RkQyOCwgMHhGQzIxLCAweEZCMDgsDQorCTB4RjlFRiwgMHhGOEU4LCAweEY4MEEs IDB4Rjc2QywNCisJMHhGNzI0LCAweEY3NDYsIDB4RjdFNiwgMHhGOTBGLA0KKwkweEZBQ0MsIDB4 RkQxRSwgMHhGRkZGLCAweDAzNjQsDQorCTB4MDczNywgMHgwQjYyLCAweDBGQzEsIDB4MTQzMSwN CisJMHgxODhBLCAweDFDQTQsIDB4MjA1NiwgMHgyMzdELA0KKwkweDI1RjksIDB4MjdCMCwgMHgy ODkwDQorfTsNCisNCitzdGF0aWMgaW50IG10a19zdGZfZXZlbnQoc3RydWN0IHNuZF9zb2NfZGFw bV93aWRnZXQgKncsDQorCQkJIHN0cnVjdCBzbmRfa2NvbnRyb2wgKmtjb250cm9sLA0KKwkJCSBp bnQgZXZlbnQpDQorew0KKwlzdHJ1Y3Qgc25kX3NvY19jb21wb25lbnQgKmNtcG50ID0gc25kX3Nv Y19kYXBtX3RvX2NvbXBvbmVudCh3LT5kYXBtKTsNCisJc3RydWN0IG10a19iYXNlX2FmZSAqYWZl ID0gc25kX3NvY19jb21wb25lbnRfZ2V0X2RydmRhdGEoY21wbnQpOw0KKw0KKwlzaXplX3QgaGFs Zl90YXBfbnVtOw0KKwljb25zdCB1MTYgKnN0Zl9jb2VmZl90YWJsZTsNCisJdW5zaWduZWQgaW50 IHVsX3JhdGUsIHJlZ192YWx1ZTsNCisJc2l6ZV90IGNvZWZfYWRkcjsNCisNCisJcmVnbWFwX3Jl YWQoYWZlLT5yZWdtYXAsIEFGRV9BRERBX1VMX1NSQ19DT04wLCAmdWxfcmF0ZSk7DQorCXVsX3Jh dGUgPSB1bF9yYXRlID4+IFVMX1ZPSUNFX01PREVfQ0gxX0NIMl9DVExfU0ZUOw0KKwl1bF9yYXRl ID0gdWxfcmF0ZSAmIFVMX1ZPSUNFX01PREVfQ0gxX0NIMl9DVExfTUFTSzsNCisNCisJaWYgKHVs X3JhdGUgPT0gTVRLX0FGRV9BRERBX1VMX1JBVEVfNDhLKSB7DQorCQloYWxmX3RhcF9udW0gPSBB UlJBWV9TSVpFKHN0Zl9jb2VmZl90YWJsZV80OGspOw0KKwkJc3RmX2NvZWZmX3RhYmxlID0gc3Rm X2NvZWZmX3RhYmxlXzQ4azsNCisJfSBlbHNlIGlmICh1bF9yYXRlID09IE1US19BRkVfQUREQV9V TF9SQVRFXzMySykgew0KKwkJaGFsZl90YXBfbnVtID0gQVJSQVlfU0laRShzdGZfY29lZmZfdGFi bGVfMzJrKTsNCisJCXN0Zl9jb2VmZl90YWJsZSA9IHN0Zl9jb2VmZl90YWJsZV8zMms7DQorCX0g ZWxzZSB7DQorCQloYWxmX3RhcF9udW0gPSBBUlJBWV9TSVpFKHN0Zl9jb2VmZl90YWJsZV8xNmsp Ow0KKwkJc3RmX2NvZWZmX3RhYmxlID0gc3RmX2NvZWZmX3RhYmxlXzE2azsNCisJfQ0KKw0KKwly ZWdtYXBfcmVhZChhZmUtPnJlZ21hcCwgQUZFX1NJREVUT05FX0NPTjEsICZyZWdfdmFsdWUpOw0K Kw0KKwlkZXZfaW5mbyhhZmUtPmRldiwgIiVzKCksIG5hbWUgJXMsIGV2ZW50IDB4JXgsIHVsX3Jh dGUgMHgleCwgQUZFX1NJREVUT05FX0NPTjEgMHgleFxuIiwNCisJCSBfX2Z1bmNfXywgdy0+bmFt ZSwgZXZlbnQsIHVsX3JhdGUsIHJlZ192YWx1ZSk7DQorDQorCXN3aXRjaCAoZXZlbnQpIHsNCisJ Y2FzZSBTTkRfU09DX0RBUE1fUFJFX1BNVToNCisJCS8qIHNldCBzaWRlIHRvbmUgZ2FpbiA9IDAg Ki8NCisJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJICAgQUZFX1NJREVU T05FX0dBSU4sDQorCQkJCSAgIFNJREVfVE9ORV9HQUlOX01BU0tfU0ZULA0KKwkJCQkgICAwKTsN CisJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJICAgQUZFX1NJREVUT05F X0dBSU4sDQorCQkJCSAgIFBPU0lUSVZFX0dBSU5fTUFTS19TRlQsDQorCQkJCSAgIDApOw0KKwkJ LyogZG9uJ3QgYnlwYXNzIHN0ZiAqLw0KKwkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFw LA0KKwkJCQkgICBBRkVfU0lERVRPTkVfQ09OMSwNCisJCQkJICAgMHgxZiA8PCAyNywNCisJCQkJ ICAgMHgwKTsNCisJCS8qIHNldCBzdGYgaGFsZiB0YXAgbnVtICovDQorCQlyZWdtYXBfdXBkYXRl X2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCSAgIEFGRV9TSURFVE9ORV9DT04xLA0KKwkJCQkgICBT SURFX1RPTkVfSEFMRl9UQVBfTlVNX01BU0tfU0ZULA0KKwkJCQkgICBoYWxmX3RhcF9udW0gPDwg U0lERV9UT05FX0hBTEZfVEFQX05VTV9TRlQpOw0KKw0KKwkJLyogc2V0IHNpZGUgdG9uZSBjb2Vm ZmljaWVudCAqLw0KKwkJcmVnbWFwX3JlYWQoYWZlLT5yZWdtYXAsIEFGRV9TSURFVE9ORV9DT04w LCAmcmVnX3ZhbHVlKTsNCisJCWZvciAoY29lZl9hZGRyID0gMDsgY29lZl9hZGRyIDwgaGFsZl90 YXBfbnVtOyBjb2VmX2FkZHIrKykgew0KKwkJCWJvb2wgb2xkX3dfcmVhZHkgPSAocmVnX3ZhbHVl ID4+IFdfUkRZX1NGVCkgJiAweDE7DQorCQkJYm9vbCBuZXdfd19yZWFkeSA9IDA7DQorCQkJaW50 IHRyeV9jbnQgPSAwOw0KKw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJ CQkJCSAgIEFGRV9TSURFVE9ORV9DT04wLA0KKwkJCQkJICAgMHgzOUZGRkZGLA0KKwkJCQkJICAg KDEgPDwgUl9XX0VOX1NGVCkgfA0KKwkJCQkJICAgKDEgPDwgUl9XX1NFTF9TRlQpIHwNCisJCQkJ CSAgICgwIDw8IFNFTF9DSDJfU0ZUKSB8DQorCQkJCQkgICAoY29lZl9hZGRyIDw8DQorCQkJCQkg ICBTSURFX1RPTkVfQ09FRkZJQ0lFTlRfQUREUl9TRlQpIHwNCisJCQkJCSAgIHN0Zl9jb2VmZl90 YWJsZVtjb2VmX2FkZHJdKTsNCisNCisJCQkvKiB3YWl0IHVudGlsIGZsYWcgd3JpdGVfcmVhZHkg Y2hhbmdlZCAqLw0KKwkJCWZvciAodHJ5X2NudCA9IDA7IHRyeV9jbnQgPCAxMDsgdHJ5X2NudCsr KSB7DQorCQkJCXJlZ21hcF9yZWFkKGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgIEFGRV9TSURFVE9O RV9DT04wLCAmcmVnX3ZhbHVlKTsNCisJCQkJbmV3X3dfcmVhZHkgPSAocmVnX3ZhbHVlID4+IFdf UkRZX1NGVCkgJiAweDE7DQorDQorCQkJCS8qIGZsaXAgPT4gb2sgKi8NCisJCQkJaWYgKG5ld193 X3JlYWR5ID09IG9sZF93X3JlYWR5KSB7DQorCQkJCQl1ZGVsYXkoMyk7DQorCQkJCQlpZiAodHJ5 X2NudCA9PSA5KSB7DQorCQkJCQkJZGV2X3dhcm4oYWZlLT5kZXYsDQorCQkJCQkJCSAiJXMoKSwg d3JpdGUgY29lZmYgbm90IHJlYWR5IiwNCisJCQkJCQkJIF9fZnVuY19fKTsNCisJCQkJCX0NCisJ CQkJfSBlbHNlIHsNCisJCQkJCWJyZWFrOw0KKwkJCQl9DQorCQkJfQ0KKwkJCS8qIG5lZWQgd3Jp dGUgLT4gcmVhZCAtPiB3cml0ZSB0byB3cml0ZSBuZXh0IGNvZWZmICovDQorCQkJcmVnbWFwX3Vw ZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgQUZFX1NJREVUT05FX0NPTjAsDQorCQkJ CQkgICBSX1dfU0VMX01BU0tfU0ZULA0KKwkJCQkJICAgMHgwKTsNCisJCX0NCisJCWJyZWFrOw0K KwljYXNlIFNORF9TT0NfREFQTV9QT1NUX1BNRDoNCisJCS8qIGJ5cGFzcyBzdGYgKi8NCisJCXJl Z21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJICAgQUZFX1NJREVUT05FX0NPTjEs DQorCQkJCSAgIDB4MWYgPDwgMjcsDQorCQkJCSAgIDB4MWYgPDwgMjcpOw0KKw0KKwkJLyogc2V0 IHNpZGUgdG9uZSBnYWluID0gMCAqLw0KKwkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFw LA0KKwkJCQkgICBBRkVfU0lERVRPTkVfR0FJTiwNCisJCQkJICAgU0lERV9UT05FX0dBSU5fTUFT S19TRlQsDQorCQkJCSAgIDApOw0KKwkJcmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0K KwkJCQkgICBBRkVfU0lERVRPTkVfR0FJTiwNCisJCQkJICAgUE9TSVRJVkVfR0FJTl9NQVNLX1NG VCwNCisJCQkJICAgMCk7DQorCQlicmVhazsNCisJZGVmYXVsdDoNCisJCWJyZWFrOw0KKwl9DQor DQorCXJldHVybiAwOw0KK30NCisNCisvKiBzdGYgbXV4ICovDQorZW51bSB7DQorCVNURl9TUkNf QUREQV9BRERBNiA9IDAsDQorCVNURl9TUkNfTzE5TzIwLA0KK307DQorDQorc3RhdGljIGNvbnN0 IGNoYXIgKmNvbnN0IHN0Zl9vMTlvMjBfbXV4X21hcFtdID0gew0KKwkiQUREQV9BRERBNiIsDQor CSJPMTlPMjAiLA0KK307DQorDQorc3RhdGljIGludCBzdGZfbzE5bzIwX211eF9tYXBfdmFsdWVb XSA9IHsNCisJU1RGX1NSQ19BRERBX0FEREE2LA0KKwlTVEZfU1JDX08xOU8yMCwNCit9Ow0KKw0K K3N0YXRpYyBTT0NfVkFMVUVfRU5VTV9TSU5HTEVfREVDTChzdGZfbzE5bzIwX211eF9tYXBfZW51 bSwNCisJCQkJICBBRkVfU0lERVRPTkVfQ09OMSwNCisJCQkJICBTVEZfU09VUkNFX0ZST01fTzE5 TzIwX1NGVCwNCisJCQkJICBTVEZfU09VUkNFX0ZST01fTzE5TzIwX01BU0ssDQorCQkJCSAgc3Rm X28xOW8yMF9tdXhfbWFwLA0KKwkJCQkgIHN0Zl9vMTlvMjBfbXV4X21hcF92YWx1ZSk7DQorDQor c3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IHN0Zl9vMTlPMjBfbXV4X2NvbnRy b2wgPQ0KKwlTT0NfREFQTV9FTlVNKCJTVEZfTzE5TzIwX01VWCIsIHN0Zl9vMTlvMjBfbXV4X21h cF9lbnVtKTsNCisNCitlbnVtIHsNCisJU1RGX1NSQ19BRERBID0gMCwNCisJU1RGX1NSQ19BRERB NiwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBjaGFyICpjb25zdCBzdGZfYWRkYV9tdXhfbWFwW10g PSB7DQorCSJBRERBIiwNCisJIkFEREE2IiwNCit9Ow0KKw0KK3N0YXRpYyBpbnQgc3RmX2FkZGFf bXV4X21hcF92YWx1ZVtdID0gew0KKwlTVEZfU1JDX0FEREEsDQorCVNURl9TUkNfQUREQTYsDQor fTsNCisNCitzdGF0aWMgU09DX1ZBTFVFX0VOVU1fU0lOR0xFX0RFQ0woc3RmX2FkZGFfbXV4X21h cF9lbnVtLA0KKwkJCQkgIEFGRV9TSURFVE9ORV9DT04xLA0KKwkJCQkgIFNURl9PMTlPMjBfT1VU X0VOX1NFTF9TRlQsDQorCQkJCSAgU1RGX08xOU8yMF9PVVRfRU5fU0VMX01BU0ssDQorCQkJCSAg c3RmX2FkZGFfbXV4X21hcCwNCisJCQkJICBzdGZfYWRkYV9tdXhfbWFwX3ZhbHVlKTsNCisNCitz dGF0aWMgY29uc3Qgc3RydWN0IHNuZF9rY29udHJvbF9uZXcgc3RmX2FkZGFfbXV4X2NvbnRyb2wg PQ0KKwlTT0NfREFQTV9FTlVNKCJTVEZfQUREQV9NVVgiLCBzdGZfYWRkYV9tdXhfbWFwX2VudW0p Ow0KKw0KKy8qIEFEREEgVUwgTVVYICovDQorZW51bSB7DQorCUFEREFfVUxfTVVYX01US0FJRiA9 IDAsDQorCUFEREFfVUxfTVVYX0FQX0RNSUMsDQorCUFEREFfVUxfTVVYX01BU0sgPSAweDEsDQor fTsNCisNCitzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGFkZGFfdWxfbXV4X21hcFtdID0gew0K KwkiTVRLQUlGIiwgIkFQX0RNSUMiDQorfTsNCisNCitzdGF0aWMgaW50IGFkZGFfdWxfbWFwX3Zh bHVlW10gPSB7DQorCUFEREFfVUxfTVVYX01US0FJRiwNCisJQUREQV9VTF9NVVhfQVBfRE1JQywN Cit9Ow0KKw0KK3N0YXRpYyBTT0NfVkFMVUVfRU5VTV9TSU5HTEVfREVDTChhZGRhX3VsX211eF9t YXBfZW51bSwNCisJCQkJICBTTkRfU09DX05PUE0sDQorCQkJCSAgMCwNCisJCQkJICBBRERBX1VM X01VWF9NQVNLLA0KKwkJCQkgIGFkZGFfdWxfbXV4X21hcCwNCisJCQkJICBhZGRhX3VsX21hcF92 YWx1ZSk7DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xfbmV3IGFkZGFfdWxf bXV4X2NvbnRyb2wgPQ0KKwlTT0NfREFQTV9FTlVNKCJBRERBX1VMX01VWCBTZWxlY3QiLCBhZGRh X3VsX211eF9tYXBfZW51bSk7DQorDQorc3RhdGljIGNvbnN0IHN0cnVjdCBzbmRfa2NvbnRyb2xf bmV3IGFkZGFfY2gzNF91bF9tdXhfY29udHJvbCA9DQorCVNPQ19EQVBNX0VOVU0oIkFEREFfQ0gz NF9VTF9NVVggU2VsZWN0IiwgYWRkYV91bF9tdXhfbWFwX2VudW0pOw0KKw0KK3N0YXRpYyBjb25z dCBzdHJ1Y3Qgc25kX3NvY19kYXBtX3dpZGdldCBtdGtfZGFpX2FkZGFfd2lkZ2V0c1tdID0gew0K KwkvKiBpbnRlci1jb25uZWN0aW9ucyAqLw0KKwlTTkRfU09DX0RBUE1fTUlYRVIoIkFEREFfRExf Q0gxIiwgU05EX1NPQ19OT1BNLCAwLCAwLA0KKwkJCSAgIG10a19hZGRhX2RsX2NoMV9taXgsDQor CQkJICAgQVJSQVlfU0laRShtdGtfYWRkYV9kbF9jaDFfbWl4KSksDQorCVNORF9TT0NfREFQTV9N SVhFUigiQUREQV9ETF9DSDIiLCBTTkRfU09DX05PUE0sIDAsIDAsDQorCQkJICAgbXRrX2FkZGFf ZGxfY2gyX21peCwNCisJCQkgICBBUlJBWV9TSVpFKG10a19hZGRhX2RsX2NoMl9taXgpKSwNCisN CisJU05EX1NPQ19EQVBNX01JWEVSKCJBRERBX0RMX0NIMyIsIFNORF9TT0NfTk9QTSwgMCwgMCwN CisJCQkgICBtdGtfYWRkYV9kbF9jaDNfbWl4LA0KKwkJCSAgIEFSUkFZX1NJWkUobXRrX2FkZGFf ZGxfY2gzX21peCkpLA0KKwlTTkRfU09DX0RBUE1fTUlYRVIoIkFEREFfRExfQ0g0IiwgU05EX1NP Q19OT1BNLCAwLCAwLA0KKwkJCSAgIG10a19hZGRhX2RsX2NoNF9taXgsDQorCQkJICAgQVJSQVlf U0laRShtdGtfYWRkYV9kbF9jaDRfbWl4KSksDQorDQorCVNORF9TT0NfREFQTV9TVVBQTFlfUygi QUREQSBFbmFibGUiLCBTVVBQTFlfU0VRX0FEREFfQUZFX09OLA0KKwkJCSAgICAgIEFGRV9BRERB X1VMX0RMX0NPTjAsIEFEREFfQUZFX09OX1NGVCwgMCwNCisJCQkgICAgICBOVUxMLCAwKSwNCisN CisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJBRERBIFBsYXliYWNrIEVuYWJsZSIsIFNVUFBMWV9T RVFfQUREQV9ETF9PTiwNCisJCQkgICAgICBBRkVfQUREQV9ETF9TUkMyX0NPTjAsDQorCQkJICAg ICAgRExfMl9TUkNfT05fVE1QX0NUTF9QUkVfU0ZULCAwLA0KKwkJCSAgICAgIG10a19hZGRhX2Rs X2V2ZW50LA0KKwkJCSAgICAgIFNORF9TT0NfREFQTV9QUkVfUE1VIHwgU05EX1NPQ19EQVBNX1BP U1RfUE1EKSwNCisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJBRERBIENIMzQgUGxheWJhY2sgRW5h YmxlIiwNCisJCQkgICAgICBTVVBQTFlfU0VRX0FEREFfRExfT04sDQorCQkJICAgICAgQUZFX0FE REFfM1JEX0RBQ19ETF9TUkMyX0NPTjAsDQorCQkJICAgICAgRExfMl9TUkNfT05fVE1QX0NUTF9Q UkVfU0ZULCAwLA0KKwkJCSAgICAgIG10a19hZGRhX2NoMzRfZGxfZXZlbnQsDQorCQkJICAgICAg U05EX1NPQ19EQVBNX1BSRV9QTVUgfCBTTkRfU09DX0RBUE1fUE9TVF9QTUQpLA0KKw0KKwlTTkRf U09DX0RBUE1fU1VQUExZX1MoIkFEREEgQ2FwdHVyZSBFbmFibGUiLCBTVVBQTFlfU0VRX0FEREFf VUxfT04sDQorCQkJICAgICAgQUZFX0FEREFfVUxfU1JDX0NPTjAsDQorCQkJICAgICAgVUxfU1JD X09OX1RNUF9DVExfU0ZULCAwLA0KKwkJCSAgICAgIG10a19hZGRhX3VsX2V2ZW50LA0KKwkJCSAg ICAgIFNORF9TT0NfREFQTV9QUkVfUE1VIHwgU05EX1NPQ19EQVBNX1BPU1RfUE1EKSwNCisJU05E X1NPQ19EQVBNX1NVUFBMWV9TKCJBRERBIENIMzQgQ2FwdHVyZSBFbmFibGUiLCBTVVBQTFlfU0VR X0FEREFfVUxfT04sDQorCQkJICAgICAgQUZFX0FEREE2X1VMX1NSQ19DT04wLA0KKwkJCSAgICAg IFVMX1NSQ19PTl9UTVBfQ1RMX1NGVCwgMCwNCisJCQkgICAgICBtdGtfYWRkYV9jaDM0X3VsX2V2 ZW50LA0KKwkJCSAgICAgIFNORF9TT0NfREFQTV9QUkVfUE1VIHwgU05EX1NPQ19EQVBNX1BPU1Rf UE1EKSwNCisNCisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJBVURfUEFEX1RPUCIsIFNVUFBMWV9T RVFfQUREQV9BVURfUEFEX1RPUCwNCisJCQkgICAgICBBRkVfQVVEX1BBRF9UT1AsDQorCQkJICAg ICAgUkdfUlhfRklGT19PTl9TRlQsIDAsDQorCQkJICAgICAgbXRrX2FkZGFfcGFkX3RvcF9ldmVu dCwNCisJCQkgICAgICBTTkRfU09DX0RBUE1fUFJFX1BNVSksDQorCVNORF9TT0NfREFQTV9TVVBQ TFlfUygiQUREQV9NVEtBSUZfQ0ZHIiwgU1VQUExZX1NFUV9BRERBX01US0FJRl9DRkcsDQorCQkJ ICAgICAgU05EX1NPQ19OT1BNLCAwLCAwLA0KKwkJCSAgICAgIG10a19hZGRhX210a2FpZl9jZmdf ZXZlbnQsDQorCQkJICAgICAgU05EX1NPQ19EQVBNX1BSRV9QTVUpLA0KKwlTTkRfU09DX0RBUE1f U1VQUExZX1MoIkFEREE2X01US0FJRl9DRkciLCBTVVBQTFlfU0VRX0FEREE2X01US0FJRl9DRkcs DQorCQkJICAgICAgU05EX1NPQ19OT1BNLCAwLCAwLA0KKwkJCSAgICAgIG10a19hZGRhX210a2Fp Zl9jZmdfZXZlbnQsDQorCQkJICAgICAgU05EX1NPQ19EQVBNX1BSRV9QTVUpLA0KKw0KKwlTTkRf U09DX0RBUE1fU1VQUExZX1MoIkFQX0RNSUNfRU4iLCBTVVBQTFlfU0VRX0FEREFfQVBfRE1JQywN CisJCQkgICAgICBBRkVfQUREQV9VTF9TUkNfQ09OMCwNCisJCQkgICAgICBVTF9BUF9ETUlDX09O X1NGVCwgMCwNCisJCQkgICAgICBOVUxMLCAwKSwNCisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJB UF9ETUlDX0NIMzRfRU4iLCBTVVBQTFlfU0VRX0FEREFfQVBfRE1JQywNCisJCQkgICAgICBBRkVf QUREQTZfVUxfU1JDX0NPTjAsDQorCQkJICAgICAgVUxfQVBfRE1JQ19PTl9TRlQsIDAsDQorCQkJ ICAgICAgTlVMTCwgMCksDQorDQorCVNORF9TT0NfREFQTV9TVVBQTFlfUygiQUREQV9GSUZPIiwg U1VQUExZX1NFUV9BRERBX0ZJRk8sDQorCQkJICAgICAgQUZFX0FEREFfVUxfRExfQ09OMCwNCisJ CQkgICAgICBBRkVfQUREQV9GSUZPX0FVVE9fUlNUX1NGVCwgMSwNCisJCQkgICAgICBOVUxMLCAw KSwNCisJU05EX1NPQ19EQVBNX1NVUFBMWV9TKCJBRERBX0NIMzRfRklGTyIsIFNVUFBMWV9TRVFf QUREQV9GSUZPLA0KKwkJCSAgICAgIEFGRV9BRERBX1VMX0RMX0NPTjAsDQorCQkJICAgICAgQUZF X0FEREE2X0ZJRk9fQVVUT19SU1RfU0ZULCAxLA0KKwkJCSAgICAgIE5VTEwsIDApLA0KKw0KKwlT TkRfU09DX0RBUE1fTVVYKCJBRERBX1VMX011eCIsIFNORF9TT0NfTk9QTSwgMCwgMCwNCisJCQkg JmFkZGFfdWxfbXV4X2NvbnRyb2wpLA0KKwlTTkRfU09DX0RBUE1fTVVYKCJBRERBX0NIMzRfVUxf TXV4IiwgU05EX1NPQ19OT1BNLCAwLCAwLA0KKwkJCSAmYWRkYV9jaDM0X3VsX211eF9jb250cm9s KSwNCisNCisJU05EX1NPQ19EQVBNX0lOUFVUKCJBUF9ETUlDX0lOUFVUIiksDQorCVNORF9TT0Nf REFQTV9JTlBVVCgiQVBfRE1JQ19DSDM0X0lOUFVUIiksDQorDQorCS8qIHN0ZiAqLw0KKwlTTkRf U09DX0RBUE1fU1dJVENIX0UoIlNpZGV0b25lIEZpbHRlciIsDQorCQkJICAgICAgQUZFX1NJREVU T05FX0NPTjEsIFNJREVfVE9ORV9PTl9TRlQsIDAsDQorCQkJICAgICAgJnN0Zl9jdGwsDQorCQkJ ICAgICAgbXRrX3N0Zl9ldmVudCwNCisJCQkgICAgICBTTkRfU09DX0RBUE1fUFJFX1BNVSB8DQor CQkJICAgICAgU05EX1NPQ19EQVBNX1BPU1RfUE1EKSwNCisJU05EX1NPQ19EQVBNX01VWCgiU1RG X08xOU8yMF9NVVgiLCBTTkRfU09DX05PUE0sIDAsIDAsDQorCQkJICZzdGZfbzE5TzIwX211eF9j b250cm9sKSwNCisJU05EX1NPQ19EQVBNX01VWCgiU1RGX0FEREFfTVVYIiwgU05EX1NPQ19OT1BN LCAwLCAwLA0KKwkJCSAmc3RmX2FkZGFfbXV4X2NvbnRyb2wpLA0KKwlTTkRfU09DX0RBUE1fTUlY RVIoIlNURl9DSDEiLCBTTkRfU09DX05PUE0sIDAsIDAsDQorCQkJICAgbXRrX3N0Zl9jaDFfbWl4 LA0KKwkJCSAgIEFSUkFZX1NJWkUobXRrX3N0Zl9jaDFfbWl4KSksDQorCVNORF9TT0NfREFQTV9N SVhFUigiU1RGX0NIMiIsIFNORF9TT0NfTk9QTSwgMCwgMCwNCisJCQkgICBtdGtfc3RmX2NoMl9t aXgsDQorCQkJICAgQVJSQVlfU0laRShtdGtfc3RmX2NoMl9taXgpKSwNCisJU05EX1NPQ19EQVBN X09VVFBVVCgiU1RGX09VVFBVVCIpLA0KKw0KKwkvKiBjbG9jayAqLw0KKwlTTkRfU09DX0RBUE1f Q0xPQ0tfU1VQUExZKCJ0b3BfbXV4X2F1ZGlvX2giKSwNCisNCisJU05EX1NPQ19EQVBNX0NMT0NL X1NVUFBMWSgiYXVkX2RhY19jbGsiKSwNCisJU05EX1NPQ19EQVBNX0NMT0NLX1NVUFBMWSgiYXVk X2RhY19wcmVkaXNfY2xrIiksDQorCVNORF9TT0NfREFQTV9DTE9DS19TVVBQTFkoImF1ZF8zcmRf ZGFjX2NsayIpLA0KKwlTTkRfU09DX0RBUE1fQ0xPQ0tfU1VQUExZKCJhdWRfM3JkX2RhY19wcmVk aXNfY2xrIiksDQorDQorCVNORF9TT0NfREFQTV9DTE9DS19TVVBQTFkoImF1ZF9hZGNfY2xrIiks DQorCVNORF9TT0NfREFQTV9DTE9DS19TVVBQTFkoImF1ZF9hZGRhNl9hZGNfY2xrIiksDQorfTsN CisNCitzdGF0aWMgY29uc3Qgc3RydWN0IHNuZF9zb2NfZGFwbV9yb3V0ZSBtdGtfZGFpX2FkZGFf cm91dGVzW10gPSB7DQorCS8qIHBsYXliYWNrICovDQorCXsiQUREQV9ETF9DSDEiLCAiREwxX0NI MSIsICJETDEifSwNCisJeyJBRERBX0RMX0NIMiIsICJETDFfQ0gxIiwgIkRMMSJ9LA0KKwl7IkFE REFfRExfQ0gyIiwgIkRMMV9DSDIiLCAiREwxIn0sDQorDQorCXsiQUREQV9ETF9DSDEiLCAiREwx Ml9DSDEiLCAiREwxMiJ9LA0KKwl7IkFEREFfRExfQ0gyIiwgIkRMMTJfQ0gyIiwgIkRMMTIifSwN CisNCisJeyJBRERBX0RMX0NIMSIsICJETDZfQ0gxIiwgIkRMNiJ9LA0KKwl7IkFEREFfRExfQ0gy IiwgIkRMNl9DSDIiLCAiREw2In0sDQorDQorCXsiQUREQV9ETF9DSDEiLCAiREw4X0NIMSIsICJE TDgifSwNCisJeyJBRERBX0RMX0NIMiIsICJETDhfQ0gyIiwgIkRMOCJ9LA0KKw0KKwl7IkFEREFf RExfQ0gxIiwgIkRMMl9DSDEiLCAiREwyIn0sDQorCXsiQUREQV9ETF9DSDIiLCAiREwyX0NIMSIs ICJETDIifSwNCisJeyJBRERBX0RMX0NIMiIsICJETDJfQ0gyIiwgIkRMMiJ9LA0KKw0KKwl7IkFE REFfRExfQ0gxIiwgIkRMM19DSDEiLCAiREwzIn0sDQorCXsiQUREQV9ETF9DSDIiLCAiREwzX0NI MSIsICJETDMifSwNCisJeyJBRERBX0RMX0NIMiIsICJETDNfQ0gyIiwgIkRMMyJ9LA0KKw0KKwl7 IkFEREFfRExfQ0gxIiwgIkRMNF9DSDEiLCAiREw0In0sDQorCXsiQUREQV9ETF9DSDIiLCAiREw0 X0NIMiIsICJETDQifSwNCisNCisJeyJBRERBX0RMX0NIMSIsICJETDVfQ0gxIiwgIkRMNSJ9LA0K Kwl7IkFEREFfRExfQ0gyIiwgIkRMNV9DSDIiLCAiREw1In0sDQorDQorCXsiQUREQSBQbGF5YmFj ayIsIE5VTEwsICJBRERBX0RMX0NIMSJ9LA0KKwl7IkFEREEgUGxheWJhY2siLCBOVUxMLCAiQURE QV9ETF9DSDIifSwNCisNCisJeyJBRERBIFBsYXliYWNrIiwgTlVMTCwgIkFEREEgRW5hYmxlIn0s DQorCXsiQUREQSBQbGF5YmFjayIsIE5VTEwsICJBRERBIFBsYXliYWNrIEVuYWJsZSJ9LA0KKw0K Kwl7IkFEREFfRExfQ0gzIiwgIkRMMV9DSDEiLCAiREwxIn0sDQorCXsiQUREQV9ETF9DSDQiLCAi REwxX0NIMSIsICJETDEifSwNCisJeyJBRERBX0RMX0NINCIsICJETDFfQ0gyIiwgIkRMMSJ9LA0K Kw0KKwl7IkFEREFfRExfQ0gzIiwgIkRMMTJfQ0gxIiwgIkRMMTIifSwNCisJeyJBRERBX0RMX0NI NCIsICJETDEyX0NIMiIsICJETDEyIn0sDQorDQorCXsiQUREQV9ETF9DSDMiLCAiREw2X0NIMSIs ICJETDYifSwNCisJeyJBRERBX0RMX0NINCIsICJETDZfQ0gyIiwgIkRMNiJ9LA0KKw0KKwl7IkFE REFfRExfQ0gzIiwgIkRMMl9DSDEiLCAiREwyIn0sDQorCXsiQUREQV9ETF9DSDQiLCAiREwyX0NI MSIsICJETDIifSwNCisJeyJBRERBX0RMX0NINCIsICJETDJfQ0gyIiwgIkRMMiJ9LA0KKw0KKwl7 IkFEREFfRExfQ0gzIiwgIkRMM19DSDEiLCAiREwzIn0sDQorCXsiQUREQV9ETF9DSDQiLCAiREwz X0NIMSIsICJETDMifSwNCisJeyJBRERBX0RMX0NINCIsICJETDNfQ0gyIiwgIkRMMyJ9LA0KKw0K Kwl7IkFEREFfRExfQ0gzIiwgIkRMNF9DSDEiLCAiREw0In0sDQorCXsiQUREQV9ETF9DSDQiLCAi REw0X0NIMiIsICJETDQifSwNCisNCisJeyJBRERBX0RMX0NIMyIsICJETDVfQ0gxIiwgIkRMNSJ9 LA0KKwl7IkFEREFfRExfQ0g0IiwgIkRMNV9DSDIiLCAiREw1In0sDQorDQorCXsiQUREQSBDSDM0 IFBsYXliYWNrIiwgTlVMTCwgIkFEREFfRExfQ0gzIn0sDQorCXsiQUREQSBDSDM0IFBsYXliYWNr IiwgTlVMTCwgIkFEREFfRExfQ0g0In0sDQorDQorCXsiQUREQSBDSDM0IFBsYXliYWNrIiwgTlVM TCwgIkFEREEgRW5hYmxlIn0sDQorCXsiQUREQSBDSDM0IFBsYXliYWNrIiwgTlVMTCwgIkFEREEg Q0gzNCBQbGF5YmFjayBFbmFibGUifSwNCisNCisJLyogY2FwdHVyZSAqLw0KKwl7IkFEREFfVUxf TXV4IiwgIk1US0FJRiIsICJBRERBIENhcHR1cmUifSwNCisJeyJBRERBX1VMX011eCIsICJBUF9E TUlDIiwgIkFQIERNSUMgQ2FwdHVyZSJ9LA0KKw0KKwl7IkFEREFfQ0gzNF9VTF9NdXgiLCAiTVRL QUlGIiwgIkFEREEgQ0gzNCBDYXB0dXJlIn0sDQorCXsiQUREQV9DSDM0X1VMX011eCIsICJBUF9E TUlDIiwgIkFQIERNSUMgQ0gzNCBDYXB0dXJlIn0sDQorDQorCXsiQUREQSBDYXB0dXJlIiwgTlVM TCwgIkFEREEgRW5hYmxlIn0sDQorCXsiQUREQSBDYXB0dXJlIiwgTlVMTCwgIkFEREEgQ2FwdHVy ZSBFbmFibGUifSwNCisJeyJBRERBIENhcHR1cmUiLCBOVUxMLCAiQVVEX1BBRF9UT1AifSwNCisJ eyJBRERBIENhcHR1cmUiLCBOVUxMLCAiQUREQV9NVEtBSUZfQ0ZHIn0sDQorDQorCXsiQVAgRE1J QyBDYXB0dXJlIiwgTlVMTCwgIkFEREEgRW5hYmxlIn0sDQorCXsiQVAgRE1JQyBDYXB0dXJlIiwg TlVMTCwgIkFEREEgQ2FwdHVyZSBFbmFibGUifSwNCisJeyJBUCBETUlDIENhcHR1cmUiLCBOVUxM LCAiQUREQV9GSUZPIn0sDQorCXsiQVAgRE1JQyBDYXB0dXJlIiwgTlVMTCwgIkFQX0RNSUNfRU4i fSwNCisNCisJeyJBRERBIENIMzQgQ2FwdHVyZSIsIE5VTEwsICJBRERBIEVuYWJsZSJ9LA0KKwl7 IkFEREEgQ0gzNCBDYXB0dXJlIiwgTlVMTCwgIkFEREEgQ0gzNCBDYXB0dXJlIEVuYWJsZSJ9LA0K Kwl7IkFEREEgQ0gzNCBDYXB0dXJlIiwgTlVMTCwgIkFVRF9QQURfVE9QIn0sDQorCXsiQUREQSBD SDM0IENhcHR1cmUiLCBOVUxMLCAiQUREQTZfTVRLQUlGX0NGRyJ9LA0KKw0KKwl7IkFQIERNSUMg Q0gzNCBDYXB0dXJlIiwgTlVMTCwgIkFEREEgRW5hYmxlIn0sDQorCXsiQVAgRE1JQyBDSDM0IENh cHR1cmUiLCBOVUxMLCAiQUREQSBDSDM0IENhcHR1cmUgRW5hYmxlIn0sDQorCXsiQVAgRE1JQyBD SDM0IENhcHR1cmUiLCBOVUxMLCAiQUREQV9DSDM0X0ZJRk8ifSwNCisJeyJBUCBETUlDIENIMzQg Q2FwdHVyZSIsIE5VTEwsICJBUF9ETUlDX0NIMzRfRU4ifSwNCisNCisJeyJBUCBETUlDIENhcHR1 cmUiLCBOVUxMLCAiQVBfRE1JQ19JTlBVVCJ9LA0KKwl7IkFQIERNSUMgQ0gzNCBDYXB0dXJlIiwg TlVMTCwgIkFQX0RNSUNfQ0gzNF9JTlBVVCJ9LA0KKw0KKwkvKiBzaWRldG9uZSBmaWx0ZXIgKi8N CisJeyJTVEZfQUREQV9NVVgiLCAiQUREQSIsICJBRERBX1VMX011eCJ9LA0KKwl7IlNURl9BRERB X01VWCIsICJBRERBNiIsICJBRERBX0NIMzRfVUxfTXV4In0sDQorDQorCXsiU1RGX08xOU8yMF9N VVgiLCAiQUREQV9BRERBNiIsICJTVEZfQUREQV9NVVgifSwNCisJeyJTVEZfTzE5TzIwX01VWCIs ICJPMTlPMjAiLCAiU1RGX0NIMSJ9LA0KKwl7IlNURl9PMTlPMjBfTVVYIiwgIk8xOU8yMCIsICJT VEZfQ0gyIn0sDQorDQorCXsiU2lkZXRvbmUgRmlsdGVyIiwgIlN3aXRjaCIsICJTVEZfTzE5TzIw X01VWCJ9LA0KKwl7IlNURl9PVVRQVVQiLCBOVUxMLCAiU2lkZXRvbmUgRmlsdGVyIn0sDQorCXsi QUREQSBQbGF5YmFjayIsIE5VTEwsICJTaWRldG9uZSBGaWx0ZXIifSwNCisJeyJBRERBIENIMzQg UGxheWJhY2siLCBOVUxMLCAiU2lkZXRvbmUgRmlsdGVyIn0sDQorDQorCS8qIGNsayAqLw0KKwl7 IkFEREEgUGxheWJhY2siLCBOVUxMLCAiYXVkX2RhY19jbGsifSwNCisJeyJBRERBIFBsYXliYWNr IiwgTlVMTCwgImF1ZF9kYWNfcHJlZGlzX2NsayJ9LA0KKw0KKwl7IkFEREEgQ0gzNCBQbGF5YmFj ayIsIE5VTEwsICJhdWRfM3JkX2RhY19jbGsifSwNCisJeyJBRERBIENIMzQgUGxheWJhY2siLCBO VUxMLCAiYXVkXzNyZF9kYWNfcHJlZGlzX2NsayJ9LA0KKw0KKwl7IkFEREEgQ2FwdHVyZSBFbmFi bGUiLCBOVUxMLCAiYXVkX2FkY19jbGsifSwNCisJeyJBRERBIENIMzQgQ2FwdHVyZSBFbmFibGUi LCBOVUxMLCAiYXVkX2FkZGE2X2FkY19jbGsifSwNCit9Ow0KKw0KKy8qIGRhaSBvcHMgKi8NCitz dGF0aWMgaW50IG10a19kYWlfYWRkYV9od19wYXJhbXMoc3RydWN0IHNuZF9wY21fc3Vic3RyZWFt ICpzdWJzdHJlYW0sDQorCQkJCSAgc3RydWN0IHNuZF9wY21faHdfcGFyYW1zICpwYXJhbXMsDQor CQkJCSAgc3RydWN0IHNuZF9zb2NfZGFpICpkYWkpDQorew0KKwlzdHJ1Y3QgbXRrX2Jhc2VfYWZl ICphZmUgPSBzbmRfc29jX2RhaV9nZXRfZHJ2ZGF0YShkYWkpOw0KKwl1bnNpZ25lZCBpbnQgcmF0 ZSA9IHBhcmFtc19yYXRlKHBhcmFtcyk7DQorCWludCBpZCA9IGRhaS0+aWQ7DQorDQorCWRldl9p bmZvKGFmZS0+ZGV2LCAiJXMoKSwgaWQgJWQsIHN0cmVhbSAlZCwgcmF0ZSAlZFxuIiwNCisJCSBf X2Z1bmNfXywNCisJCSBpZCwNCisJCSBzdWJzdHJlYW0tPnN0cmVhbSwNCisJCSByYXRlKTsNCisN CisJaWYgKHN1YnN0cmVhbS0+c3RyZWFtID09IFNORFJWX1BDTV9TVFJFQU1fUExBWUJBQ0spIHsN CisJCXVuc2lnbmVkIGludCBkbF9zcmMyX2NvbjAgPSAwOw0KKwkJdW5zaWduZWQgaW50IGRsX3Ny YzJfY29uMSA9IDA7DQorDQorCQkvKiBzZXQgc2FtcGxpbmcgcmF0ZSAqLw0KKwkJZGxfc3JjMl9j b24wID0gYWRkYV9kbF9yYXRlX3RyYW5zZm9ybShhZmUsIHJhdGUpIDw8DQorCQkJICAgICAgIERM XzJfSU5QVVRfTU9ERV9DVExfU0ZUOw0KKw0KKwkJLyogc2V0IG91dHB1dCBtb2RlLCBVUF9TQU1Q TElOR19SQVRFX1g4ICovDQorCQlkbF9zcmMyX2NvbjAgfD0gKDB4MyA8PCBETF8yX09VVFBVVF9T RUxfQ1RMX1NGVCk7DQorDQorCQkvKiB0dXJuIG9mZiBtdXRlIGZ1bmN0aW9uICovDQorCQlkbF9z cmMyX2NvbjAgfD0gKDB4MDEgPDwgRExfMl9NVVRFX0NIMl9PRkZfQ1RMX1BSRV9TRlQpOw0KKwkJ ZGxfc3JjMl9jb24wIHw9ICgweDAxIDw8IERMXzJfTVVURV9DSDFfT0ZGX0NUTF9QUkVfU0ZUKTsN CisNCisJCS8qIHNldCB2b2ljZSBpbnB1dCBkYXRhIGlmIGlucHV0IHNhbXBsZSByYXRlIGlzIDhr IG9yIDE2ayAqLw0KKwkJaWYgKHJhdGUgPT0gODAwMCB8fCByYXRlID09IDE2MDAwKQ0KKwkJCWRs X3NyYzJfY29uMCB8PSAweDAxIDw8IERMXzJfVk9JQ0VfTU9ERV9DVExfUFJFX1NGVDsNCisNCisJ CS8qIFNBIHN1Z2dlc3QgYXBwbHkgLTAuM2RiIHRvIGF1ZGlvL3NwZWVjaCBwYXRoICovDQorCQlk bF9zcmMyX2NvbjEgPSBNVEtfQUZFX0FEREFfRExfR0FJTl9OT1JNQUwgPDwNCisJCQkgICAgICAg RExfMl9HQUlOX0NUTF9QUkVfU0ZUOw0KKw0KKwkJLyogdHVybiBvbiBkb3duLWxpbmsgZ2FpbiAq Lw0KKwkJZGxfc3JjMl9jb24wIHw9ICgweDAxIDw8IERMXzJfR0FJTl9PTl9DVExfUFJFX1NGVCk7 DQorDQorCQlpZiAoaWQgPT0gTVQ4MTkyX0RBSV9BRERBKSB7DQorCQkJLyogY2xlYW4gcHJlZGlz dG9ydGlvbiAqLw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwgQUZFX0FEREFfUFJFRElT X0NPTjAsIDApOw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwgQUZFX0FEREFfUFJFRElT X0NPTjEsIDApOw0KKw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwNCisJCQkJICAgICBB RkVfQUREQV9ETF9TUkMyX0NPTjAsIGRsX3NyYzJfY29uMCk7DQorCQkJcmVnbWFwX3dyaXRlKGFm ZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBX0RMX1NSQzJfQ09OMSwgZGxfc3JjMl9jb24x KTsNCisNCisJCQkvKiBzZXQgc2RtIGdhaW4gKi8NCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZl LT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQV9ETF9TRE1fRENDT01QX0NPTiwNCisJCQkJCSAg IEFUVEdBSU5fQ1RMX01BU0tfU0ZULA0KKwkJCQkJICAgQVVESU9fU0RNX0xFVkVMX05PUk1BTCA8 PA0KKwkJCQkJICAgQVRUR0FJTl9DVExfU0ZUKTsNCisNCisJCQkvKiAybmQgc2RtICovDQorCQkJ cmVnbWFwX3VwZGF0ZV9iaXRzKGFmZS0+cmVnbWFwLA0KKwkJCQkJICAgQUZFX0FEREFfRExfU0RN X0RDQ09NUF9DT04sDQorCQkJCQkgICBVU0VfM1JEX1NETV9NQVNLX1NGVCwNCisJCQkJCSAgIEFV RElPX1NETV8yTkQgPDwgVVNFXzNSRF9TRE1fU0ZUKTsNCisNCisJCQkvKiBzZG0gYXV0byByZXNl dCAqLw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwNCisJCQkJICAgICBBRkVfQUREQV9E TF9TRE1fQVVUT19SRVNFVF9DT04sDQorCQkJCSAgICAgU0RNX0FVVE9fUkVTRVRfVEhSRVNIT0xE KTsNCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQURE QV9ETF9TRE1fQVVUT19SRVNFVF9DT04sDQorCQkJCQkgICBBRERBX1NETV9BVVRPX1JFU0VUX09O T0ZGX01BU0tfU0ZULA0KKwkJCQkJICAgMHgxIDw8IEFEREFfU0RNX0FVVE9fUkVTRVRfT05PRkZf U0ZUKTsNCisJCX0gZWxzZSB7DQorCQkJLyogY2xlYW4gcHJlZGlzdG9ydGlvbiAqLw0KKwkJCXJl Z21hcF93cml0ZShhZmUtPnJlZ21hcCwNCisJCQkJICAgICBBRkVfQUREQV8zUkRfREFDX1BSRURJ U19DT04wLCAwKTsNCisJCQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsDQorCQkJCSAgICAgQUZF X0FEREFfM1JEX0RBQ19QUkVESVNfQ09OMSwgMCk7DQorDQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+ cmVnbWFwLCBBRkVfQUREQV8zUkRfREFDX0RMX1NSQzJfQ09OMCwNCisJCQkJICAgICBkbF9zcmMy X2NvbjApOw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21hcCwgQUZFX0FEREFfM1JEX0RBQ19E TF9TUkMyX0NPTjEsDQorCQkJCSAgICAgZGxfc3JjMl9jb24xKTsNCisNCisJCQkvKiBzZXQgc2Rt IGdhaW4gKi8NCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBB RkVfQUREQV8zUkRfREFDX0RMX1NETV9EQ0NPTVBfQ09OLA0KKwkJCQkJICAgQVRUR0FJTl9DVExf TUFTS19TRlQsDQorCQkJCQkgICBBVURJT19TRE1fTEVWRUxfTk9STUFMIDw8DQorCQkJCQkgICBB VFRHQUlOX0NUTF9TRlQpOw0KKw0KKwkJCS8qIDJuZCBzZG0gKi8NCisJCQlyZWdtYXBfdXBkYXRl X2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQV8zUkRfREFDX0RMX1NETV9EQ0NP TVBfQ09OLA0KKwkJCQkJICAgVVNFXzNSRF9TRE1fTUFTS19TRlQsDQorCQkJCQkgICBBVURJT19T RE1fMk5EIDw8IFVTRV8zUkRfU0RNX1NGVCk7DQorDQorCQkJLyogc2RtIGF1dG8gcmVzZXQgKi8N CisJCQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsDQorCQkJCSAgICAgQUZFX0FEREFfM1JEX0RB Q19ETF9TRE1fQVVUT19SRVNFVF9DT04sDQorCQkJCSAgICAgU0RNX0FVVE9fUkVTRVRfVEhSRVNI T0xEKTsNCisJCQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVf QUREQV8zUkRfREFDX0RMX1NETV9BVVRPX1JFU0VUX0NPTiwNCisJCQkJCSAgIEFEREFfM1JEX0RB Q19TRE1fQVVUT19SRVNFVF9PTk9GRl9NQVNLX1NGVCwNCisJCQkJCSAgIDB4MSA8PCBBRERBXzNS RF9EQUNfU0RNX0FVVE9fUkVTRVRfT05PRkZfU0ZUKTsNCisJCX0NCisJfSBlbHNlIHsNCisJCXVu c2lnbmVkIGludCB2b2ljZV9tb2RlID0gMDsNCisJCXVuc2lnbmVkIGludCB1bF9zcmNfY29uMCA9 IDA7CS8qIGRlZmF1bHQgdmFsdWUgKi8NCisNCisJCXZvaWNlX21vZGUgPSBhZGRhX3VsX3JhdGVf dHJhbnNmb3JtKGFmZSwgcmF0ZSk7DQorDQorCQl1bF9zcmNfY29uMCB8PSAodm9pY2VfbW9kZSA8 PCAxNykgJiAoMHg3IDw8IDE3KTsNCisNCisJCS8qIGVuYWJsZSBpaXIgKi8NCisJCXVsX3NyY19j b24wIHw9ICgxIDw8IFVMX0lJUl9PTl9UTVBfQ1RMX1NGVCkgJg0KKwkJCSAgICAgICBVTF9JSVJf T05fVE1QX0NUTF9NQVNLX1NGVDsNCisJCXVsX3NyY19jb24wIHw9IChVTF9JSVJfU1cgPDwgVUxf SUlSTU9ERV9DVExfU0ZUKSAmDQorCQkJICAgICAgIFVMX0lJUk1PREVfQ1RMX01BU0tfU0ZUOw0K Kw0KKwkJc3dpdGNoIChpZCkgew0KKwkJY2FzZSBNVDgxOTJfREFJX0FEREE6DQorCQljYXNlIE1U ODE5Ml9EQUlfQVBfRE1JQzoNCisJCQkvKiAzNUh6IEAgNDhrICovDQorCQkJcmVnbWFwX3dyaXRl KGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBX0lJUl9DT0VGXzAyXzAxLCAweDAwMDAw MDAwKTsNCisJCQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsDQorCQkJCSAgICAgQUZFX0FEREFf SUlSX0NPRUZfMDRfMDMsIDB4MDAwMDNGQjgpOw0KKwkJCXJlZ21hcF93cml0ZShhZmUtPnJlZ21h cCwNCisJCQkJICAgICBBRkVfQUREQV9JSVJfQ09FRl8wNl8wNSwgMHgzRkI4MDAwMCk7DQorCQkJ cmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBX0lJUl9DT0VGXzA4 XzA3LCAweDNGQjgwMDAwKTsNCisJCQlyZWdtYXBfd3JpdGUoYWZlLT5yZWdtYXAsDQorCQkJCSAg ICAgQUZFX0FEREFfSUlSX0NPRUZfMTBfMDksIDB4MDAwMEMwNDgpOw0KKw0KKwkJCXJlZ21hcF93 cml0ZShhZmUtPnJlZ21hcCwNCisJCQkJICAgICBBRkVfQUREQV9VTF9TUkNfQ09OMCwgdWxfc3Jj X2NvbjApOw0KKw0KKwkJCS8qIFVzaW5nIEludGVybmFsIEFEQyAqLw0KKwkJCXJlZ21hcF91cGRh dGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJCSAgIEFGRV9BRERBX1RPUF9DT04wLA0KKwkJCQkJ ICAgMHgxIDw8IDAsDQorCQkJCQkgICAweDAgPDwgMCk7DQorDQorCQkJLyogbXRrYWlmX3J4aWZf ZGF0YV9tb2RlID0gMCwgYW1pYyAqLw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21h cCwNCisJCQkJCSAgIEFGRV9BRERBX01US0FJRl9SWF9DRkcwLA0KKwkJCQkJICAgMHgxIDw8IDAs DQorCQkJCQkgICAweDAgPDwgMCk7DQorCQkJYnJlYWs7DQorCQljYXNlIE1UODE5Ml9EQUlfQURE QV9DSDM0Og0KKwkJY2FzZSBNVDgxOTJfREFJX0FQX0RNSUNfQ0gzNDoNCisJCQkvKiAzNUh6IEAg NDhrICovDQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERB Nl9JSVJfQ09FRl8wMl8wMSwgMHgwMDAwMDAwMCk7DQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVn bWFwLA0KKwkJCQkgICAgIEFGRV9BRERBNl9JSVJfQ09FRl8wNF8wMywgMHgwMDAwM0ZCOCk7DQor CQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBNl9JSVJfQ09F Rl8wNl8wNSwgMHgzRkI4MDAwMCk7DQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJ CQkgICAgIEFGRV9BRERBNl9JSVJfQ09FRl8wOF8wNywgMHgzRkI4MDAwMCk7DQorCQkJcmVnbWFw X3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAgIEFGRV9BRERBNl9JSVJfQ09FRl8xMF8wOSwg MHgwMDAwQzA0OCk7DQorDQorCQkJcmVnbWFwX3dyaXRlKGFmZS0+cmVnbWFwLA0KKwkJCQkgICAg IEFGRV9BRERBNl9VTF9TUkNfQ09OMCwgdWxfc3JjX2NvbjApOw0KKw0KKwkJCS8qIFVzaW5nIElu dGVybmFsIEFEQyAqLw0KKwkJCXJlZ21hcF91cGRhdGVfYml0cyhhZmUtPnJlZ21hcCwNCisJCQkJ CSAgIEFGRV9BRERBNl9UT1BfQ09OMCwNCisJCQkJCSAgIDB4MSA8PCAwLA0KKwkJCQkJICAgMHgw IDw8IDApOw0KKw0KKwkJCS8qIG10a2FpZl9yeGlmX2RhdGFfbW9kZSA9IDAsIGFtaWMgKi8NCisJ CQlyZWdtYXBfdXBkYXRlX2JpdHMoYWZlLT5yZWdtYXAsDQorCQkJCQkgICBBRkVfQUREQTZfTVRL QUlGX1JYX0NGRzAsDQorCQkJCQkgICAweDEgPDwgMCwNCisJCQkJCSAgIDB4MCA8PCAwKTsNCisJ CQlicmVhazsNCisJCWRlZmF1bHQ6DQorCQkJYnJlYWs7DQorCQl9DQorDQorCQkvKiBhcCBkbWlj ICovDQorCQlzd2l0Y2ggKGlkKSB7DQorCQljYXNlIE1UODE5Ml9EQUlfQVBfRE1JQzoNCisJCWNh c2UgTVQ4MTkyX0RBSV9BUF9ETUlDX0NIMzQ6DQorCQkJbXRrX2FkZGFfdWxfc3JjX2RtaWMoYWZl LCBpZCk7DQorCQkJYnJlYWs7DQorCQlkZWZhdWx0Og0KKwkJCWJyZWFrOw0KKwkJfQ0KKwl9DQor DQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IHNuZF9zb2NfZGFpX29w cyBtdGtfZGFpX2FkZGFfb3BzID0gew0KKwkuaHdfcGFyYW1zID0gbXRrX2RhaV9hZGRhX2h3X3Bh cmFtcywNCit9Ow0KKw0KKy8qIGRhaSBkcml2ZXIgKi8NCisjZGVmaW5lIE1US19BRERBX1BMQVlC QUNLX1JBVEVTIChTTkRSVl9QQ01fUkFURV84MDAwXzQ4MDAwIHxcDQorCQkJCSBTTkRSVl9QQ01f UkFURV85NjAwMCB8XA0KKwkJCQkgU05EUlZfUENNX1JBVEVfMTkyMDAwKQ0KKw0KKyNkZWZpbmUg TVRLX0FEREFfQ0FQVFVSRV9SQVRFUyAoU05EUlZfUENNX1JBVEVfODAwMCB8XA0KKwkJCQlTTkRS Vl9QQ01fUkFURV8xNjAwMCB8XA0KKwkJCQlTTkRSVl9QQ01fUkFURV8zMjAwMCB8XA0KKwkJCQlT TkRSVl9QQ01fUkFURV80ODAwMCB8XA0KKwkJCQlTTkRSVl9QQ01fUkFURV85NjAwMCB8XA0KKwkJ CQlTTkRSVl9QQ01fUkFURV8xOTIwMDApDQorDQorI2RlZmluZSBNVEtfQUREQV9GT1JNQVRTIChT TkRSVl9QQ01fRk1UQklUX1MxNl9MRSB8XA0KKwkJCSAgU05EUlZfUENNX0ZNVEJJVF9TMjRfTEUg fFwNCisJCQkgIFNORFJWX1BDTV9GTVRCSVRfUzMyX0xFKQ0KKw0KK3N0YXRpYyBzdHJ1Y3Qgc25k X3NvY19kYWlfZHJpdmVyIG10a19kYWlfYWRkYV9kcml2ZXJbXSA9IHsNCisJew0KKwkJLm5hbWUg PSAiQUREQSIsDQorCQkuaWQgPSBNVDgxOTJfREFJX0FEREEsDQorCQkucGxheWJhY2sgPSB7DQor CQkJLnN0cmVhbV9uYW1lID0gIkFEREEgUGxheWJhY2siLA0KKwkJCS5jaGFubmVsc19taW4gPSAx LA0KKwkJCS5jaGFubmVsc19tYXggPSAyLA0KKwkJCS5yYXRlcyA9IE1US19BRERBX1BMQVlCQUNL X1JBVEVTLA0KKwkJCS5mb3JtYXRzID0gTVRLX0FEREFfRk9STUFUUywNCisJCX0sDQorCQkuY2Fw dHVyZSA9IHsNCisJCQkuc3RyZWFtX25hbWUgPSAiQUREQSBDYXB0dXJlIiwNCisJCQkuY2hhbm5l bHNfbWluID0gMSwNCisJCQkuY2hhbm5lbHNfbWF4ID0gMiwNCisJCQkucmF0ZXMgPSBNVEtfQURE QV9DQVBUVVJFX1JBVEVTLA0KKwkJCS5mb3JtYXRzID0gTVRLX0FEREFfRk9STUFUUywNCisJCX0s DQorCQkub3BzID0gJm10a19kYWlfYWRkYV9vcHMsDQorCX0sDQorCXsNCisJCS5uYW1lID0gIkFE REFfQ0gzNCIsDQorCQkuaWQgPSBNVDgxOTJfREFJX0FEREFfQ0gzNCwNCisJCS5wbGF5YmFjayA9 IHsNCisJCQkuc3RyZWFtX25hbWUgPSAiQUREQSBDSDM0IFBsYXliYWNrIiwNCisJCQkuY2hhbm5l bHNfbWluID0gMSwNCisJCQkuY2hhbm5lbHNfbWF4ID0gMiwNCisJCQkucmF0ZXMgPSBNVEtfQURE QV9QTEFZQkFDS19SQVRFUywNCisJCQkuZm9ybWF0cyA9IE1US19BRERBX0ZPUk1BVFMsDQorCQl9 LA0KKwkJLmNhcHR1cmUgPSB7DQorCQkJLnN0cmVhbV9uYW1lID0gIkFEREEgQ0gzNCBDYXB0dXJl IiwNCisJCQkuY2hhbm5lbHNfbWluID0gMSwNCisJCQkuY2hhbm5lbHNfbWF4ID0gMiwNCisJCQku cmF0ZXMgPSBNVEtfQUREQV9DQVBUVVJFX1JBVEVTLA0KKwkJCS5mb3JtYXRzID0gTVRLX0FEREFf Rk9STUFUUywNCisJCX0sDQorCQkub3BzID0gJm10a19kYWlfYWRkYV9vcHMsDQorCX0sDQorCXsN CisJCS5uYW1lID0gIkFQX0RNSUMiLA0KKwkJLmlkID0gTVQ4MTkyX0RBSV9BUF9ETUlDLA0KKwkJ LmNhcHR1cmUgPSB7DQorCQkJLnN0cmVhbV9uYW1lID0gIkFQIERNSUMgQ2FwdHVyZSIsDQorCQkJ LmNoYW5uZWxzX21pbiA9IDEsDQorCQkJLmNoYW5uZWxzX21heCA9IDIsDQorCQkJLnJhdGVzID0g TVRLX0FEREFfQ0FQVFVSRV9SQVRFUywNCisJCQkuZm9ybWF0cyA9IE1US19BRERBX0ZPUk1BVFMs DQorCQl9LA0KKwkJLm9wcyA9ICZtdGtfZGFpX2FkZGFfb3BzLA0KKwl9LA0KKwl7DQorCQkubmFt ZSA9ICJBUF9ETUlDX0NIMzQiLA0KKwkJLmlkID0gTVQ4MTkyX0RBSV9BUF9ETUlDX0NIMzQsDQor CQkuY2FwdHVyZSA9IHsNCisJCQkuc3RyZWFtX25hbWUgPSAiQVAgRE1JQyBDSDM0IENhcHR1cmUi LA0KKwkJCS5jaGFubmVsc19taW4gPSAxLA0KKwkJCS5jaGFubmVsc19tYXggPSAyLA0KKwkJCS5y YXRlcyA9IE1US19BRERBX0NBUFRVUkVfUkFURVMsDQorCQkJLmZvcm1hdHMgPSBNVEtfQUREQV9G T1JNQVRTLA0KKwkJfSwNCisJCS5vcHMgPSAmbXRrX2RhaV9hZGRhX29wcywNCisJfSwNCit9Ow0K Kw0KK2ludCBtdDgxOTJfZGFpX2FkZGFfcmVnaXN0ZXIoc3RydWN0IG10a19iYXNlX2FmZSAqYWZl KQ0KK3sNCisJc3RydWN0IG10a19iYXNlX2FmZV9kYWkgKmRhaTsNCisJc3RydWN0IG10ODE5Ml9h ZmVfcHJpdmF0ZSAqYWZlX3ByaXYgPSBhZmUtPnBsYXRmb3JtX3ByaXY7DQorDQorCWRldl9pbmZv KGFmZS0+ZGV2LCAiJXMoKVxuIiwgX19mdW5jX18pOw0KKw0KKwlkYWkgPSBkZXZtX2t6YWxsb2Mo YWZlLT5kZXYsIHNpemVvZigqZGFpKSwgR0ZQX0tFUk5FTCk7DQorCWlmICghZGFpKQ0KKwkJcmV0 dXJuIC1FTk9NRU07DQorDQorCWxpc3RfYWRkKCZkYWktPmxpc3QsICZhZmUtPnN1Yl9kYWlzKTsN CisNCisJZGFpLT5kYWlfZHJpdmVycyA9IG10a19kYWlfYWRkYV9kcml2ZXI7DQorCWRhaS0+bnVt X2RhaV9kcml2ZXJzID0gQVJSQVlfU0laRShtdGtfZGFpX2FkZGFfZHJpdmVyKTsNCisNCisJZGFp LT5jb250cm9scyA9IG10a19hZGRhX2NvbnRyb2xzOw0KKwlkYWktPm51bV9jb250cm9scyA9IEFS UkFZX1NJWkUobXRrX2FkZGFfY29udHJvbHMpOw0KKwlkYWktPmRhcG1fd2lkZ2V0cyA9IG10a19k YWlfYWRkYV93aWRnZXRzOw0KKwlkYWktPm51bV9kYXBtX3dpZGdldHMgPSBBUlJBWV9TSVpFKG10 a19kYWlfYWRkYV93aWRnZXRzKTsNCisJZGFpLT5kYXBtX3JvdXRlcyA9IG10a19kYWlfYWRkYV9y b3V0ZXM7DQorCWRhaS0+bnVtX2RhcG1fcm91dGVzID0gQVJSQVlfU0laRShtdGtfZGFpX2FkZGFf cm91dGVzKTsNCisNCisJLyogYXAgZG1pYyBwcml2IHNoYXJlIHdpdGggYWRkYSAqLw0KKwlhZmVf cHJpdi0+ZGFpX3ByaXZbTVQ4MTkyX0RBSV9BUF9ETUlDXSA9DQorCQlhZmVfcHJpdi0+ZGFpX3By aXZbTVQ4MTkyX0RBSV9BRERBXTsNCisJYWZlX3ByaXYtPmRhaV9wcml2W01UODE5Ml9EQUlfQVBf RE1JQ19DSDM0XSA9DQorCQlhZmVfcHJpdi0+ZGFpX3ByaXZbTVQ4MTkyX0RBSV9BRERBX0NIMzRd Ow0KKw0KKwlyZXR1cm4gMDsNCit9DQotLSANCjIuMTguMA0K From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C3E2C2D0A3 for ; Sat, 24 Oct 2020 07:59:53 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0231B22281 for ; Sat, 24 Oct 2020 07:59:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="i2QbIT5o"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="VpVocS8P" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0231B22281 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=q6xA8E0RrmTBx6+mtmSTSi6yiWfiFxryIcD9N6uaCB0=; b=i2QbIT5o+TTn2q+1gAbPoEEhd 3F38wq1dD76rvbmq+JJMQaeXnOnATBv6TwmjHeXYf8IbrPka9KqO0VnmwpPVgYARyWIVLKn4jXbAT j0EVZAbxFf8FY2dVyK5kRVfIb7coLYwkOz0m8kcrnzUunJhrnf5m3LQ2cxl0lXW14UbAweUK3sJJo h81uC+grXV7RKppELmhPO4hjy8UZMq9HbVTaJuC9mxco0isHs+mMBI0M/+705q1+i7TQgB66rvfyA jclQsAVtCJOIrSyMHjjqymgpwATvOBvcL1S8zlJEzi9ci042KdQQQpp+wmpIona4RXkqUjFAl1js3 2uB+wpBYw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kWESj-0000MG-NU; Sat, 24 Oct 2020 07:59:41 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kWESI-00009h-UL; Sat, 24 Oct 2020 07:59:27 +0000 X-UUID: 68218a3b152b494489b2b78e56027091-20201023 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=1w2R910WjXYg2yiL2x05QYtuAGfRi8PuUHhC5wcblhY=; b=VpVocS8PBd528FM88hbTn8NI53pqMhTaGN+Vmc+rExvWxVou2h/IQON4Ye3l37+t8vpx1pOuF8YVJwhXRYMn0xfz+p0TRPRk0ipz/cwYj8rUe2ifCToRhPCcxCpRog9qoSS2Tk6idPopfSH5Rgd2h7lDOMTbUD9mE76LsvbJWZo=; X-UUID: 68218a3b152b494489b2b78e56027091-20201023 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 70565948; Fri, 23 Oct 2020 23:59:07 -0800 Received: from MTKMBS06N2.mediatek.inc (172.21.101.130) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 24 Oct 2020 00:59:06 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs06n2.mediatek.inc (172.21.101.130) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 24 Oct 2020 15:59:05 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sat, 24 Oct 2020 15:59:02 +0800 From: Jiaxin Yu To: , , , , , , , , , Subject: [PATCH v3 4/9] ASoC: mediatek: mt8192: support add in platform driver Date: Sat, 24 Oct 2020 15:58:54 +0800 Message-ID: <1603526339-15005-5-git-send-email-jiaxin.yu@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1603526339-15005-1-git-send-email-jiaxin.yu@mediatek.com> References: <1603526339-15005-1-git-send-email-jiaxin.yu@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: 135DBFC313CC6BC3E7DF51BECFA222AD739BB5ABC37619AA951B923F72B44DC42000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201024_035915_408137_0AE44955 X-CRM114-Status: GOOD ( 15.07 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: shane.chien@mediatek.com, Bicycle.Tsai@mediatek.com, Jiaxin Yu , Trevor.Wu@mediatek.com, kuninori.morimoto.gx@renesas.com Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org This patch adds mt8192 adda dai driver. Signed-off-by: Jiaxin Yu --- sound/soc/mediatek/mt8192/mt8192-dai-adda.c | 1489 +++++++++++++++++++ 1 file changed, 1489 insertions(+) create mode 100644 sound/soc/mediatek/mt8192/mt8192-dai-adda.c diff --git a/sound/soc/mediatek/mt8192/mt8192-dai-adda.c b/sound/soc/mediatek/mt8192/mt8192-dai-adda.c new file mode 100644 index 0000000000000..c49a02d34f26a --- /dev/null +++ b/sound/soc/mediatek/mt8192/mt8192-dai-adda.c @@ -0,0 +1,1489 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI ADDA Control +// +// Copyright (c) 2020 MediaTek Inc. +// Author: Shane Chien +// + +#include +#include + +#include "mt8192-afe-clk.h" +#include "mt8192-afe-common.h" +#include "mt8192-afe-gpio.h" +#include "mt8192-interconnection.h" + +enum { + UL_IIR_SW = 0, + UL_IIR_5HZ, + UL_IIR_10HZ, + UL_IIR_25HZ, + UL_IIR_50HZ, + UL_IIR_75HZ, +}; + +enum { + AUDIO_SDM_LEVEL_MUTE = 0, + AUDIO_SDM_LEVEL_NORMAL = 0x1d, + /* if you change level normal */ + /* you need to change formula of hp impedance and dc trim too */ +}; + +enum { + AUDIO_SDM_2ND = 0, + AUDIO_SDM_3RD, +}; + +enum { + DELAY_DATA_MISO1 = 0, + DELAY_DATA_MISO2, +}; + +enum { + MTK_AFE_ADDA_DL_RATE_8K = 0, + MTK_AFE_ADDA_DL_RATE_11K = 1, + MTK_AFE_ADDA_DL_RATE_12K = 2, + MTK_AFE_ADDA_DL_RATE_16K = 3, + MTK_AFE_ADDA_DL_RATE_22K = 4, + MTK_AFE_ADDA_DL_RATE_24K = 5, + MTK_AFE_ADDA_DL_RATE_32K = 6, + MTK_AFE_ADDA_DL_RATE_44K = 7, + MTK_AFE_ADDA_DL_RATE_48K = 8, + MTK_AFE_ADDA_DL_RATE_96K = 9, + MTK_AFE_ADDA_DL_RATE_192K = 10, +}; + +enum { + MTK_AFE_ADDA_UL_RATE_8K = 0, + MTK_AFE_ADDA_UL_RATE_16K = 1, + MTK_AFE_ADDA_UL_RATE_32K = 2, + MTK_AFE_ADDA_UL_RATE_48K = 3, + MTK_AFE_ADDA_UL_RATE_96K = 4, + MTK_AFE_ADDA_UL_RATE_192K = 5, + MTK_AFE_ADDA_UL_RATE_48K_HD = 6, +}; + +#define SDM_AUTO_RESET_THRESHOLD 0x190000 + +static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_DL_RATE_8K; + case 11025: + return MTK_AFE_ADDA_DL_RATE_11K; + case 12000: + return MTK_AFE_ADDA_DL_RATE_12K; + case 16000: + return MTK_AFE_ADDA_DL_RATE_16K; + case 22050: + return MTK_AFE_ADDA_DL_RATE_22K; + case 24000: + return MTK_AFE_ADDA_DL_RATE_24K; + case 32000: + return MTK_AFE_ADDA_DL_RATE_32K; + case 44100: + return MTK_AFE_ADDA_DL_RATE_44K; + case 48000: + return MTK_AFE_ADDA_DL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_DL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_DL_RATE_192K; + default: + dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_DL_RATE_48K; + } +} + +static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_UL_RATE_8K; + case 16000: + return MTK_AFE_ADDA_UL_RATE_16K; + case 32000: + return MTK_AFE_ADDA_UL_RATE_32K; + case 48000: + return MTK_AFE_ADDA_UL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_UL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_UL_RATE_192K; + default: + dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_UL_RATE_48K; + } +} + +/* dai component */ +static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1", AFE_CONN3, I_DL12_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN3_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN3_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN3_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN3_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN3, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1", AFE_CONN3, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3, + I_PCM_2_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1", AFE_CONN3_1, + I_SRC_1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_2_OUT_CH1", AFE_CONN3_1, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2", AFE_CONN4, I_DL12_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN4_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN4_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN4_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN4_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN4, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2", AFE_CONN4, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4, + I_PCM_2_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4, + I_PCM_2_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2", AFE_CONN4_1, + I_SRC_1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_2_OUT_CH2", AFE_CONN4_1, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN52, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1", AFE_CONN52, I_DL12_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN52, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN52, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN52_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN52_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN52_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN52, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN52, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN52, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1", AFE_CONN52, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN52, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN52, + I_PCM_2_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN53, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN53, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2", AFE_CONN53, I_DL12_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN53, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN53, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN53, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN53, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN53_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN53_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN53_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN53, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN53, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN53, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2", AFE_CONN53, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN53, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN53, + I_PCM_2_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN53, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN53, + I_PCM_2_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_stf_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN19, + I_ADDA_UL_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_stf_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN20, + I_ADDA_UL_CH2, 1, 0), +}; + +enum { + SUPPLY_SEQ_ADDA_AFE_ON, + SUPPLY_SEQ_ADDA_DL_ON, + SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SUPPLY_SEQ_ADDA_FIFO, + SUPPLY_SEQ_ADDA_AP_DMIC, + SUPPLY_SEQ_ADDA_UL_ON, +}; + +static int mtk_adda_ul_src_dmic(struct mtk_base_afe *afe, int id) +{ + unsigned int reg; + + switch (id) { + case MT8192_DAI_ADDA: + case MT8192_DAI_AP_DMIC: + reg = AFE_ADDA_UL_SRC_CON0; + break; + case MT8192_DAI_ADDA_CH34: + case MT8192_DAI_AP_DMIC_CH34: + reg = AFE_ADDA6_UL_SRC_CON0; + break; + default: + return -EINVAL; + } + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, reg, + DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT, + 0x0); + regmap_update_bits(afe->regmap, reg, + DMIC_LOW_POWER_MODE_CTL_MASK_SFT, + 0x0); + + /* turn on dmic, ch1, ch2 */ + regmap_update_bits(afe->regmap, reg, + UL_SDM_3_LEVEL_CTL_MASK_SFT, + 0x1 << UL_SDM_3_LEVEL_CTL_SFT); + regmap_update_bits(afe->regmap, reg, + UL_MODE_3P25M_CH1_CTL_MASK_SFT, + 0x1 << UL_MODE_3P25M_CH1_CTL_SFT); + regmap_update_bits(afe->regmap, reg, + UL_MODE_3P25M_CH2_CTL_MASK_SFT, + 0x1 << UL_MODE_3P25M_CH2_CTL_SFT); + return 0; +} + +static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic; + + dev_info(afe->dev, "%s(), name %s, event 0x%x, mtkaif_dmic %d\n", + __func__, w->name, event, mtkaif_dmic); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 1); + + /* update setting to dmic */ + if (mtkaif_dmic) { + /* mtkaif_rxif_data_mode = 1, dmic */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, + 0x1, 0x1); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, + MTKAIF_RXIF_VOICE_MODE_MASK_SFT, + 0x0); + mtk_adda_ul_src_dmic(afe, MT8192_DAI_ADDA); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8192_afe_gpio_request(afe->dev, false, MT8192_DAI_ADDA, 1); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_ch34_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic_ch34; + int mtkaif_adda6_only = afe_priv->mtkaif_adda6_only; + + dev_info(afe->dev, + "%s(), name %s, event 0x%x, mtkaif_dmic %d, mtkaif_adda6_only %d\n", + __func__, w->name, event, mtkaif_dmic, mtkaif_adda6_only); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34, + 1); + + /* update setting to dmic */ + if (mtkaif_dmic) { + /* mtkaif_rxif_data_mode = 1, dmic */ + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG0, + 0x1, 0x1); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG0, + MTKAIF_RXIF_VOICE_MODE_MASK_SFT, + 0x0); + mtk_adda_ul_src_dmic(afe, MT8192_DAI_ADDA_CH34); + } + + /* when using adda6 without adda enabled, + * RG_ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE_SFT need to be set or + * data cannot be received. + */ + if (mtkaif_adda6_only) { + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_SYNCWORD_CFG, + 0x1 << 23, 0x1 << 23); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8192_afe_gpio_request(afe->dev, false, MT8192_DAI_ADDA_CH34, + 1); + + /* reset dmic */ + afe_priv->mtkaif_dmic_ch34 = 0; + + if (mtkaif_adda6_only) { + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_SYNCWORD_CFG, + 0x1 << 23, 0x0 << 23); + } + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_pad_top_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x38); + else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x30); + else + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x30); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + int delay_data; + int delay_cycle; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) { + /* set protocol 2 */ + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, + 0x00010000); + regmap_write(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, + 0x00010000); + + if (strcmp(w->name, "ADDA_MTKAIF_CFG") == 0 && + (afe_priv->mtkaif_chosen_phase[0] < 0 || + afe_priv->mtkaif_chosen_phase[1] < 0)) { + dev_warn(afe->dev, + "%s(), mtkaif_chosen_phase[0/1]:%d/%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[0], + afe_priv->mtkaif_chosen_phase[1]); + break; + } else if (strcmp(w->name, "ADDA6_MTKAIF_CFG") == 0 && + afe_priv->mtkaif_chosen_phase[2] < 0) { + dev_warn(afe->dev, + "%s(), mtkaif_chosen_phase[2]:%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[2]); + break; + } + + /* mtkaif_rxif_clkinv_adc inverse for calibration */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, + MTKAIF_RXIF_CLKINV_ADC_MASK_SFT, + 0x1 << MTKAIF_RXIF_CLKINV_ADC_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, + MTKAIF_RXIF_CLKINV_ADC_MASK_SFT, + 0x1 << MTKAIF_RXIF_CLKINV_ADC_SFT); + + /* set delay for ch12 */ + if (afe_priv->mtkaif_phase_cycle[0] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = afe_priv->mtkaif_phase_cycle[0] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[0]; + } + + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + MTKAIF_RXIF_DELAY_DATA_SFT); + + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + MTKAIF_RXIF_DELAY_CYCLE_SFT); + + /* set delay between ch3 and ch2 */ + if (afe_priv->mtkaif_phase_cycle[2] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; /* ch3 */ + delay_cycle = afe_priv->mtkaif_phase_cycle[2] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; /* ch2 */ + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[2]; + } + + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + MTKAIF_RXIF_DELAY_DATA_SFT); + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + MTKAIF_RXIF_DELAY_CYCLE_SFT); + } else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) { + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, + 0x00010000); + regmap_write(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, + 0x00010000); + } else { + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x0); + regmap_write(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, 0x0); + } + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_info(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 0); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8192_afe_gpio_request(afe->dev, false, MT8192_DAI_ADDA, 0); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_ch34_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_info(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34, + 0); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8192_afe_gpio_request(afe->dev, false, MT8192_DAI_ADDA_CH34, + 0); + break; + default: + break; + } + + return 0; +} + +/* stf */ +static int stf_positive_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->stf_positive_gain_db; + return 0; +} + +static int stf_positive_gain_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + int gain_db = ucontrol->value.integer.value[0]; + + afe_priv->stf_positive_gain_db = gain_db; + + if (gain_db >= 0 && gain_db <= 24) { + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + POSITIVE_GAIN_MASK_SFT, + (gain_db / 6) << POSITIVE_GAIN_SFT); + } else { + dev_warn(afe->dev, "%s(), gain_db %d invalid\n", + __func__, gain_db); + } + return 0; +} + +/* mtkaif dmic */ +static const char * const mt8192_adda_off_on_str[] = { + "Off", "On" +}; + +static const struct soc_enum mt8192_adda_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8192_adda_off_on_str), + mt8192_adda_off_on_str), +}; + +static int mt8192_adda_dmic_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->mtkaif_dmic; + return 0; +} + +static int mt8192_adda_dmic_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int dmic_on; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + dmic_on = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n", + __func__, kcontrol->id.name, dmic_on); + + afe_priv->mtkaif_dmic = dmic_on; + afe_priv->mtkaif_dmic_ch34 = dmic_on; + return 0; +} + +static int mt8192_adda6_only_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->mtkaif_adda6_only; + return 0; +} + +static int mt8192_adda6_only_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int mtkaif_adda6_only; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + mtkaif_adda6_only = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n", + __func__, kcontrol->id.name, mtkaif_adda6_only); + + afe_priv->mtkaif_adda6_only = mtkaif_adda6_only; + return 0; +} + +static const struct snd_kcontrol_new mtk_adda_controls[] = { + SOC_SINGLE("Sidetone_Gain", AFE_SIDETONE_GAIN, + SIDE_TONE_GAIN_SFT, SIDE_TONE_GAIN_MASK, 0), + SOC_SINGLE_EXT("Sidetone_Positive_Gain_dB", SND_SOC_NOPM, 0, 100, 0, + stf_positive_gain_get, stf_positive_gain_set), + SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1, + DL_2_GAIN_CTL_PRE_SFT, DL_2_GAIN_CTL_PRE_MASK, 0), + SOC_ENUM_EXT("MTKAIF_DMIC", mt8192_adda_enum[0], + mt8192_adda_dmic_get, mt8192_adda_dmic_set), + SOC_ENUM_EXT("MTKAIF_ADDA6_ONLY", mt8192_adda_enum[0], + mt8192_adda6_only_get, mt8192_adda6_only_set), +}; + +static const struct snd_kcontrol_new stf_ctl = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const u16 stf_coeff_table_16k[] = { + 0x049C, 0x09E8, 0x09E0, 0x089C, + 0xFF54, 0xF488, 0xEAFC, 0xEBAC, + 0xfA40, 0x17AC, 0x3D1C, 0x6028, + 0x7538 +}; + +static const u16 stf_coeff_table_32k[] = { + 0xFE52, 0x0042, 0x00C5, 0x0194, + 0x029A, 0x03B7, 0x04BF, 0x057D, + 0x05BE, 0x0555, 0x0426, 0x0230, + 0xFF92, 0xFC89, 0xF973, 0xF6C6, + 0xF500, 0xF49D, 0xF603, 0xF970, + 0xFEF3, 0x065F, 0x0F4F, 0x1928, + 0x2329, 0x2C80, 0x345E, 0x3A0D, + 0x3D08 +}; + +static const u16 stf_coeff_table_48k[] = { + 0x0401, 0xFFB0, 0xFF5A, 0xFECE, + 0xFE10, 0xFD28, 0xFC21, 0xFB08, + 0xF9EF, 0xF8E8, 0xF80A, 0xF76C, + 0xF724, 0xF746, 0xF7E6, 0xF90F, + 0xFACC, 0xFD1E, 0xFFFF, 0x0364, + 0x0737, 0x0B62, 0x0FC1, 0x1431, + 0x188A, 0x1CA4, 0x2056, 0x237D, + 0x25F9, 0x27B0, 0x2890 +}; + +static int mtk_stf_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + size_t half_tap_num; + const u16 *stf_coeff_table; + unsigned int ul_rate, reg_value; + size_t coef_addr; + + regmap_read(afe->regmap, AFE_ADDA_UL_SRC_CON0, &ul_rate); + ul_rate = ul_rate >> UL_VOICE_MODE_CH1_CH2_CTL_SFT; + ul_rate = ul_rate & UL_VOICE_MODE_CH1_CH2_CTL_MASK; + + if (ul_rate == MTK_AFE_ADDA_UL_RATE_48K) { + half_tap_num = ARRAY_SIZE(stf_coeff_table_48k); + stf_coeff_table = stf_coeff_table_48k; + } else if (ul_rate == MTK_AFE_ADDA_UL_RATE_32K) { + half_tap_num = ARRAY_SIZE(stf_coeff_table_32k); + stf_coeff_table = stf_coeff_table_32k; + } else { + half_tap_num = ARRAY_SIZE(stf_coeff_table_16k); + stf_coeff_table = stf_coeff_table_16k; + } + + regmap_read(afe->regmap, AFE_SIDETONE_CON1, ®_value); + + dev_info(afe->dev, "%s(), name %s, event 0x%x, ul_rate 0x%x, AFE_SIDETONE_CON1 0x%x\n", + __func__, w->name, event, ul_rate, reg_value); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* set side tone gain = 0 */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + SIDE_TONE_GAIN_MASK_SFT, + 0); + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + POSITIVE_GAIN_MASK_SFT, + 0); + /* don't bypass stf */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON1, + 0x1f << 27, + 0x0); + /* set stf half tap num */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON1, + SIDE_TONE_HALF_TAP_NUM_MASK_SFT, + half_tap_num << SIDE_TONE_HALF_TAP_NUM_SFT); + + /* set side tone coefficient */ + regmap_read(afe->regmap, AFE_SIDETONE_CON0, ®_value); + for (coef_addr = 0; coef_addr < half_tap_num; coef_addr++) { + bool old_w_ready = (reg_value >> W_RDY_SFT) & 0x1; + bool new_w_ready = 0; + int try_cnt = 0; + + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON0, + 0x39FFFFF, + (1 << R_W_EN_SFT) | + (1 << R_W_SEL_SFT) | + (0 << SEL_CH2_SFT) | + (coef_addr << + SIDE_TONE_COEFFICIENT_ADDR_SFT) | + stf_coeff_table[coef_addr]); + + /* wait until flag write_ready changed */ + for (try_cnt = 0; try_cnt < 10; try_cnt++) { + regmap_read(afe->regmap, + AFE_SIDETONE_CON0, ®_value); + new_w_ready = (reg_value >> W_RDY_SFT) & 0x1; + + /* flip => ok */ + if (new_w_ready == old_w_ready) { + udelay(3); + if (try_cnt == 9) { + dev_warn(afe->dev, + "%s(), write coeff not ready", + __func__); + } + } else { + break; + } + } + /* need write -> read -> write to write next coeff */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON0, + R_W_SEL_MASK_SFT, + 0x0); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* bypass stf */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON1, + 0x1f << 27, + 0x1f << 27); + + /* set side tone gain = 0 */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + SIDE_TONE_GAIN_MASK_SFT, + 0); + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + POSITIVE_GAIN_MASK_SFT, + 0); + break; + default: + break; + } + + return 0; +} + +/* stf mux */ +enum { + STF_SRC_ADDA_ADDA6 = 0, + STF_SRC_O19O20, +}; + +static const char *const stf_o19o20_mux_map[] = { + "ADDA_ADDA6", + "O19O20", +}; + +static int stf_o19o20_mux_map_value[] = { + STF_SRC_ADDA_ADDA6, + STF_SRC_O19O20, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(stf_o19o20_mux_map_enum, + AFE_SIDETONE_CON1, + STF_SOURCE_FROM_O19O20_SFT, + STF_SOURCE_FROM_O19O20_MASK, + stf_o19o20_mux_map, + stf_o19o20_mux_map_value); + +static const struct snd_kcontrol_new stf_o19O20_mux_control = + SOC_DAPM_ENUM("STF_O19O20_MUX", stf_o19o20_mux_map_enum); + +enum { + STF_SRC_ADDA = 0, + STF_SRC_ADDA6, +}; + +static const char *const stf_adda_mux_map[] = { + "ADDA", + "ADDA6", +}; + +static int stf_adda_mux_map_value[] = { + STF_SRC_ADDA, + STF_SRC_ADDA6, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(stf_adda_mux_map_enum, + AFE_SIDETONE_CON1, + STF_O19O20_OUT_EN_SEL_SFT, + STF_O19O20_OUT_EN_SEL_MASK, + stf_adda_mux_map, + stf_adda_mux_map_value); + +static const struct snd_kcontrol_new stf_adda_mux_control = + SOC_DAPM_ENUM("STF_ADDA_MUX", stf_adda_mux_map_enum); + +/* ADDA UL MUX */ +enum { + ADDA_UL_MUX_MTKAIF = 0, + ADDA_UL_MUX_AP_DMIC, + ADDA_UL_MUX_MASK = 0x1, +}; + +static const char * const adda_ul_mux_map[] = { + "MTKAIF", "AP_DMIC" +}; + +static int adda_ul_map_value[] = { + ADDA_UL_MUX_MTKAIF, + ADDA_UL_MUX_AP_DMIC, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(adda_ul_mux_map_enum, + SND_SOC_NOPM, + 0, + ADDA_UL_MUX_MASK, + adda_ul_mux_map, + adda_ul_map_value); + +static const struct snd_kcontrol_new adda_ul_mux_control = + SOC_DAPM_ENUM("ADDA_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_kcontrol_new adda_ch34_ul_mux_control = + SOC_DAPM_ENUM("ADDA_CH34_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch1_mix, + ARRAY_SIZE(mtk_adda_dl_ch1_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch2_mix, + ARRAY_SIZE(mtk_adda_dl_ch2_mix)), + + SND_SOC_DAPM_MIXER("ADDA_DL_CH3", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch3_mix, + ARRAY_SIZE(mtk_adda_dl_ch3_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH4", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch4_mix, + ARRAY_SIZE(mtk_adda_dl_ch4_mix)), + + SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, + AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, + AFE_ADDA_DL_SRC2_CON0, + DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, + mtk_adda_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ADDA CH34 Playback Enable", + SUPPLY_SEQ_ADDA_DL_ON, + AFE_ADDA_3RD_DAC_DL_SRC2_CON0, + DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, + mtk_adda_ch34_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_UL_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + mtk_adda_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ADDA CH34 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA6_UL_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + mtk_adda_ch34_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("AUD_PAD_TOP", SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + AFE_AUD_PAD_TOP, + RG_RX_FIFO_ON_SFT, 0, + mtk_adda_pad_top_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA6_MTKAIF_CFG", SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA_UL_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_CH34_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA6_UL_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_UL_DL_CON0, + AFE_ADDA_FIFO_AUTO_RST_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADDA_CH34_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_UL_DL_CON0, + AFE_ADDA6_FIFO_AUTO_RST_SFT, 1, + NULL, 0), + + SND_SOC_DAPM_MUX("ADDA_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ul_mux_control), + SND_SOC_DAPM_MUX("ADDA_CH34_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ch34_ul_mux_control), + + SND_SOC_DAPM_INPUT("AP_DMIC_INPUT"), + SND_SOC_DAPM_INPUT("AP_DMIC_CH34_INPUT"), + + /* stf */ + SND_SOC_DAPM_SWITCH_E("Sidetone Filter", + AFE_SIDETONE_CON1, SIDE_TONE_ON_SFT, 0, + &stf_ctl, + mtk_stf_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("STF_O19O20_MUX", SND_SOC_NOPM, 0, 0, + &stf_o19O20_mux_control), + SND_SOC_DAPM_MUX("STF_ADDA_MUX", SND_SOC_NOPM, 0, 0, + &stf_adda_mux_control), + SND_SOC_DAPM_MIXER("STF_CH1", SND_SOC_NOPM, 0, 0, + mtk_stf_ch1_mix, + ARRAY_SIZE(mtk_stf_ch1_mix)), + SND_SOC_DAPM_MIXER("STF_CH2", SND_SOC_NOPM, 0, 0, + mtk_stf_ch2_mix, + ARRAY_SIZE(mtk_stf_ch2_mix)), + SND_SOC_DAPM_OUTPUT("STF_OUTPUT"), + + /* clock */ + SND_SOC_DAPM_CLOCK_SUPPLY("top_mux_audio_h"), + + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_predis_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_3rd_dac_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_3rd_dac_predis_clk"), + + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc_clk"), +}; + +static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { + /* playback */ + {"ADDA_DL_CH1", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH2", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH2", "DL1_CH2", "DL1"}, + + {"ADDA_DL_CH1", "DL12_CH1", "DL12"}, + {"ADDA_DL_CH2", "DL12_CH2", "DL12"}, + + {"ADDA_DL_CH1", "DL6_CH1", "DL6"}, + {"ADDA_DL_CH2", "DL6_CH2", "DL6"}, + + {"ADDA_DL_CH1", "DL8_CH1", "DL8"}, + {"ADDA_DL_CH2", "DL8_CH2", "DL8"}, + + {"ADDA_DL_CH1", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH2", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH2", "DL2_CH2", "DL2"}, + + {"ADDA_DL_CH1", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH2", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH2", "DL3_CH2", "DL3"}, + + {"ADDA_DL_CH1", "DL4_CH1", "DL4"}, + {"ADDA_DL_CH2", "DL4_CH2", "DL4"}, + + {"ADDA_DL_CH1", "DL5_CH1", "DL5"}, + {"ADDA_DL_CH2", "DL5_CH2", "DL5"}, + + {"ADDA Playback", NULL, "ADDA_DL_CH1"}, + {"ADDA Playback", NULL, "ADDA_DL_CH2"}, + + {"ADDA Playback", NULL, "ADDA Enable"}, + {"ADDA Playback", NULL, "ADDA Playback Enable"}, + + {"ADDA_DL_CH3", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH4", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH4", "DL1_CH2", "DL1"}, + + {"ADDA_DL_CH3", "DL12_CH1", "DL12"}, + {"ADDA_DL_CH4", "DL12_CH2", "DL12"}, + + {"ADDA_DL_CH3", "DL6_CH1", "DL6"}, + {"ADDA_DL_CH4", "DL6_CH2", "DL6"}, + + {"ADDA_DL_CH3", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH4", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH4", "DL2_CH2", "DL2"}, + + {"ADDA_DL_CH3", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH4", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH4", "DL3_CH2", "DL3"}, + + {"ADDA_DL_CH3", "DL4_CH1", "DL4"}, + {"ADDA_DL_CH4", "DL4_CH2", "DL4"}, + + {"ADDA_DL_CH3", "DL5_CH1", "DL5"}, + {"ADDA_DL_CH4", "DL5_CH2", "DL5"}, + + {"ADDA CH34 Playback", NULL, "ADDA_DL_CH3"}, + {"ADDA CH34 Playback", NULL, "ADDA_DL_CH4"}, + + {"ADDA CH34 Playback", NULL, "ADDA Enable"}, + {"ADDA CH34 Playback", NULL, "ADDA CH34 Playback Enable"}, + + /* capture */ + {"ADDA_UL_Mux", "MTKAIF", "ADDA Capture"}, + {"ADDA_UL_Mux", "AP_DMIC", "AP DMIC Capture"}, + + {"ADDA_CH34_UL_Mux", "MTKAIF", "ADDA CH34 Capture"}, + {"ADDA_CH34_UL_Mux", "AP_DMIC", "AP DMIC CH34 Capture"}, + + {"ADDA Capture", NULL, "ADDA Enable"}, + {"ADDA Capture", NULL, "ADDA Capture Enable"}, + {"ADDA Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"}, + + {"AP DMIC Capture", NULL, "ADDA Enable"}, + {"AP DMIC Capture", NULL, "ADDA Capture Enable"}, + {"AP DMIC Capture", NULL, "ADDA_FIFO"}, + {"AP DMIC Capture", NULL, "AP_DMIC_EN"}, + + {"ADDA CH34 Capture", NULL, "ADDA Enable"}, + {"ADDA CH34 Capture", NULL, "ADDA CH34 Capture Enable"}, + {"ADDA CH34 Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA CH34 Capture", NULL, "ADDA6_MTKAIF_CFG"}, + + {"AP DMIC CH34 Capture", NULL, "ADDA Enable"}, + {"AP DMIC CH34 Capture", NULL, "ADDA CH34 Capture Enable"}, + {"AP DMIC CH34 Capture", NULL, "ADDA_CH34_FIFO"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_CH34_EN"}, + + {"AP DMIC Capture", NULL, "AP_DMIC_INPUT"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_CH34_INPUT"}, + + /* sidetone filter */ + {"STF_ADDA_MUX", "ADDA", "ADDA_UL_Mux"}, + {"STF_ADDA_MUX", "ADDA6", "ADDA_CH34_UL_Mux"}, + + {"STF_O19O20_MUX", "ADDA_ADDA6", "STF_ADDA_MUX"}, + {"STF_O19O20_MUX", "O19O20", "STF_CH1"}, + {"STF_O19O20_MUX", "O19O20", "STF_CH2"}, + + {"Sidetone Filter", "Switch", "STF_O19O20_MUX"}, + {"STF_OUTPUT", NULL, "Sidetone Filter"}, + {"ADDA Playback", NULL, "Sidetone Filter"}, + {"ADDA CH34 Playback", NULL, "Sidetone Filter"}, + + /* clk */ + {"ADDA Playback", NULL, "aud_dac_clk"}, + {"ADDA Playback", NULL, "aud_dac_predis_clk"}, + + {"ADDA CH34 Playback", NULL, "aud_3rd_dac_clk"}, + {"ADDA CH34 Playback", NULL, "aud_3rd_dac_predis_clk"}, + + {"ADDA Capture Enable", NULL, "aud_adc_clk"}, + {"ADDA CH34 Capture Enable", NULL, "aud_adda6_adc_clk"}, +}; + +/* dai ops */ +static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + unsigned int rate = params_rate(params); + int id = dai->id; + + dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, + id, + substream->stream, + rate); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + unsigned int dl_src2_con0 = 0; + unsigned int dl_src2_con1 = 0; + + /* set sampling rate */ + dl_src2_con0 = adda_dl_rate_transform(afe, rate) << + DL_2_INPUT_MODE_CTL_SFT; + + /* set output mode, UP_SAMPLING_RATE_X8 */ + dl_src2_con0 |= (0x3 << DL_2_OUTPUT_SEL_CTL_SFT); + + /* turn off mute function */ + dl_src2_con0 |= (0x01 << DL_2_MUTE_CH2_OFF_CTL_PRE_SFT); + dl_src2_con0 |= (0x01 << DL_2_MUTE_CH1_OFF_CTL_PRE_SFT); + + /* set voice input data if input sample rate is 8k or 16k */ + if (rate == 8000 || rate == 16000) + dl_src2_con0 |= 0x01 << DL_2_VOICE_MODE_CTL_PRE_SFT; + + /* SA suggest apply -0.3db to audio/speech path */ + dl_src2_con1 = MTK_AFE_ADDA_DL_GAIN_NORMAL << + DL_2_GAIN_CTL_PRE_SFT; + + /* turn on down-link gain */ + dl_src2_con0 |= (0x01 << DL_2_GAIN_ON_CTL_PRE_SFT); + + if (id == MT8192_DAI_ADDA) { + /* clean predistortion */ + regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0); + regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0); + + regmap_write(afe->regmap, + AFE_ADDA_DL_SRC2_CON0, dl_src2_con0); + regmap_write(afe->regmap, + AFE_ADDA_DL_SRC2_CON1, dl_src2_con1); + + /* set sdm gain */ + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DCCOMP_CON, + ATTGAIN_CTL_MASK_SFT, + AUDIO_SDM_LEVEL_NORMAL << + ATTGAIN_CTL_SFT); + + /* 2nd sdm */ + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DCCOMP_CON, + USE_3RD_SDM_MASK_SFT, + AUDIO_SDM_2ND << USE_3RD_SDM_SFT); + + /* sdm auto reset */ + regmap_write(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + SDM_AUTO_RESET_THRESHOLD); + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + ADDA_SDM_AUTO_RESET_ONOFF_MASK_SFT, + 0x1 << ADDA_SDM_AUTO_RESET_ONOFF_SFT); + } else { + /* clean predistortion */ + regmap_write(afe->regmap, + AFE_ADDA_3RD_DAC_PREDIS_CON0, 0); + regmap_write(afe->regmap, + AFE_ADDA_3RD_DAC_PREDIS_CON1, 0); + + regmap_write(afe->regmap, AFE_ADDA_3RD_DAC_DL_SRC2_CON0, + dl_src2_con0); + regmap_write(afe->regmap, AFE_ADDA_3RD_DAC_DL_SRC2_CON1, + dl_src2_con1); + + /* set sdm gain */ + regmap_update_bits(afe->regmap, + AFE_ADDA_3RD_DAC_DL_SDM_DCCOMP_CON, + ATTGAIN_CTL_MASK_SFT, + AUDIO_SDM_LEVEL_NORMAL << + ATTGAIN_CTL_SFT); + + /* 2nd sdm */ + regmap_update_bits(afe->regmap, + AFE_ADDA_3RD_DAC_DL_SDM_DCCOMP_CON, + USE_3RD_SDM_MASK_SFT, + AUDIO_SDM_2ND << USE_3RD_SDM_SFT); + + /* sdm auto reset */ + regmap_write(afe->regmap, + AFE_ADDA_3RD_DAC_DL_SDM_AUTO_RESET_CON, + SDM_AUTO_RESET_THRESHOLD); + regmap_update_bits(afe->regmap, + AFE_ADDA_3RD_DAC_DL_SDM_AUTO_RESET_CON, + ADDA_3RD_DAC_SDM_AUTO_RESET_ONOFF_MASK_SFT, + 0x1 << ADDA_3RD_DAC_SDM_AUTO_RESET_ONOFF_SFT); + } + } else { + unsigned int voice_mode = 0; + unsigned int ul_src_con0 = 0; /* default value */ + + voice_mode = adda_ul_rate_transform(afe, rate); + + ul_src_con0 |= (voice_mode << 17) & (0x7 << 17); + + /* enable iir */ + ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) & + UL_IIR_ON_TMP_CTL_MASK_SFT; + ul_src_con0 |= (UL_IIR_SW << UL_IIRMODE_CTL_SFT) & + UL_IIRMODE_CTL_MASK_SFT; + + switch (id) { + case MT8192_DAI_ADDA: + case MT8192_DAI_AP_DMIC: + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA_UL_SRC_CON0, ul_src_con0); + + /* Using Internal ADC */ + regmap_update_bits(afe->regmap, + AFE_ADDA_TOP_CON0, + 0x1 << 0, + 0x0 << 0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_RX_CFG0, + 0x1 << 0, + 0x0 << 0); + break; + case MT8192_DAI_ADDA_CH34: + case MT8192_DAI_AP_DMIC_CH34: + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA6_UL_SRC_CON0, ul_src_con0); + + /* Using Internal ADC */ + regmap_update_bits(afe->regmap, + AFE_ADDA6_TOP_CON0, + 0x1 << 0, + 0x0 << 0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG0, + 0x1 << 0, + 0x0 << 0); + break; + default: + break; + } + + /* ap dmic */ + switch (id) { + case MT8192_DAI_AP_DMIC: + case MT8192_DAI_AP_DMIC_CH34: + mtk_adda_ul_src_dmic(afe, id); + break; + default: + break; + } + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_adda_ops = { + .hw_params = mtk_dai_adda_hw_params, +}; + +/* dai driver */ +#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { + { + .name = "ADDA", + .id = MT8192_DAI_ADDA, + .playback = { + .stream_name = "ADDA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .capture = { + .stream_name = "ADDA Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "ADDA_CH34", + .id = MT8192_DAI_ADDA_CH34, + .playback = { + .stream_name = "ADDA CH34 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .capture = { + .stream_name = "ADDA CH34 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC", + .id = MT8192_DAI_AP_DMIC, + .capture = { + .stream_name = "AP DMIC Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC_CH34", + .id = MT8192_DAI_AP_DMIC_CH34, + .capture = { + .stream_name = "AP DMIC CH34 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, +}; + +int mt8192_dai_adda_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + dev_info(afe->dev, "%s()\n", __func__); + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_adda_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); + + dai->controls = mtk_adda_controls; + dai->num_controls = ARRAY_SIZE(mtk_adda_controls); + dai->dapm_widgets = mtk_dai_adda_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); + dai->dapm_routes = mtk_dai_adda_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); + + /* ap dmic priv share with adda */ + afe_priv->dai_priv[MT8192_DAI_AP_DMIC] = + afe_priv->dai_priv[MT8192_DAI_ADDA]; + afe_priv->dai_priv[MT8192_DAI_AP_DMIC_CH34] = + afe_priv->dai_priv[MT8192_DAI_ADDA_CH34]; + + return 0; +} -- 2.18.0 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F358BC2D0A3 for ; Sat, 24 Oct 2020 08:01:40 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8E17022281 for ; Sat, 24 Oct 2020 08:01:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="rrVxbgx1"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="VpVocS8P" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8E17022281 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=CAlZ/oFjWeMwBr306GatiybHxCYtGBApfdTtgWJdIhM=; b=rrVxbgx1Y4HEDmJXWAvpOjJYl jdysxiksyn3hU3whBFhSEXMak9gR4An0A2FetP1Z+1nqUTUHfyMFALW9/ZxE1LnOUsM1KsM9kkkxb os0MoYkwNvw9A6gcHJsFZw0heA0M0h6p0VIQ9eypsKh9XkM34P5vIpTWgH3bNV/Cm2bOHqDgq98ng DrpgrtlSP6JBC8ITmHdYH4QGRAofSRPgFPFEF7NCvcvi/1/UPjwQ+iOcMFaj7DF9pkD+rlEY+1bcH ce7h/DqbReAKYh4xsSUqOssfsniFW9uQcBPXN0gFs2bKc6M7X7mJhKFF99+kVsD0VbhbygsIb/YCs FY19uW7bA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kWESg-0000LL-TR; Sat, 24 Oct 2020 07:59:38 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kWESI-00009h-UL; Sat, 24 Oct 2020 07:59:27 +0000 X-UUID: 68218a3b152b494489b2b78e56027091-20201023 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=1w2R910WjXYg2yiL2x05QYtuAGfRi8PuUHhC5wcblhY=; b=VpVocS8PBd528FM88hbTn8NI53pqMhTaGN+Vmc+rExvWxVou2h/IQON4Ye3l37+t8vpx1pOuF8YVJwhXRYMn0xfz+p0TRPRk0ipz/cwYj8rUe2ifCToRhPCcxCpRog9qoSS2Tk6idPopfSH5Rgd2h7lDOMTbUD9mE76LsvbJWZo=; X-UUID: 68218a3b152b494489b2b78e56027091-20201023 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 70565948; Fri, 23 Oct 2020 23:59:07 -0800 Received: from MTKMBS06N2.mediatek.inc (172.21.101.130) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 24 Oct 2020 00:59:06 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs06n2.mediatek.inc (172.21.101.130) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 24 Oct 2020 15:59:05 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sat, 24 Oct 2020 15:59:02 +0800 From: Jiaxin Yu To: , , , , , , , , , Subject: [PATCH v3 4/9] ASoC: mediatek: mt8192: support add in platform driver Date: Sat, 24 Oct 2020 15:58:54 +0800 Message-ID: <1603526339-15005-5-git-send-email-jiaxin.yu@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1603526339-15005-1-git-send-email-jiaxin.yu@mediatek.com> References: <1603526339-15005-1-git-send-email-jiaxin.yu@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: 135DBFC313CC6BC3E7DF51BECFA222AD739BB5ABC37619AA951B923F72B44DC42000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201024_035915_408137_0AE44955 X-CRM114-Status: GOOD ( 15.07 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: shane.chien@mediatek.com, Bicycle.Tsai@mediatek.com, Jiaxin Yu , Trevor.Wu@mediatek.com, kuninori.morimoto.gx@renesas.com Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds mt8192 adda dai driver. Signed-off-by: Jiaxin Yu --- sound/soc/mediatek/mt8192/mt8192-dai-adda.c | 1489 +++++++++++++++++++ 1 file changed, 1489 insertions(+) create mode 100644 sound/soc/mediatek/mt8192/mt8192-dai-adda.c diff --git a/sound/soc/mediatek/mt8192/mt8192-dai-adda.c b/sound/soc/mediatek/mt8192/mt8192-dai-adda.c new file mode 100644 index 0000000000000..c49a02d34f26a --- /dev/null +++ b/sound/soc/mediatek/mt8192/mt8192-dai-adda.c @@ -0,0 +1,1489 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI ADDA Control +// +// Copyright (c) 2020 MediaTek Inc. +// Author: Shane Chien +// + +#include +#include + +#include "mt8192-afe-clk.h" +#include "mt8192-afe-common.h" +#include "mt8192-afe-gpio.h" +#include "mt8192-interconnection.h" + +enum { + UL_IIR_SW = 0, + UL_IIR_5HZ, + UL_IIR_10HZ, + UL_IIR_25HZ, + UL_IIR_50HZ, + UL_IIR_75HZ, +}; + +enum { + AUDIO_SDM_LEVEL_MUTE = 0, + AUDIO_SDM_LEVEL_NORMAL = 0x1d, + /* if you change level normal */ + /* you need to change formula of hp impedance and dc trim too */ +}; + +enum { + AUDIO_SDM_2ND = 0, + AUDIO_SDM_3RD, +}; + +enum { + DELAY_DATA_MISO1 = 0, + DELAY_DATA_MISO2, +}; + +enum { + MTK_AFE_ADDA_DL_RATE_8K = 0, + MTK_AFE_ADDA_DL_RATE_11K = 1, + MTK_AFE_ADDA_DL_RATE_12K = 2, + MTK_AFE_ADDA_DL_RATE_16K = 3, + MTK_AFE_ADDA_DL_RATE_22K = 4, + MTK_AFE_ADDA_DL_RATE_24K = 5, + MTK_AFE_ADDA_DL_RATE_32K = 6, + MTK_AFE_ADDA_DL_RATE_44K = 7, + MTK_AFE_ADDA_DL_RATE_48K = 8, + MTK_AFE_ADDA_DL_RATE_96K = 9, + MTK_AFE_ADDA_DL_RATE_192K = 10, +}; + +enum { + MTK_AFE_ADDA_UL_RATE_8K = 0, + MTK_AFE_ADDA_UL_RATE_16K = 1, + MTK_AFE_ADDA_UL_RATE_32K = 2, + MTK_AFE_ADDA_UL_RATE_48K = 3, + MTK_AFE_ADDA_UL_RATE_96K = 4, + MTK_AFE_ADDA_UL_RATE_192K = 5, + MTK_AFE_ADDA_UL_RATE_48K_HD = 6, +}; + +#define SDM_AUTO_RESET_THRESHOLD 0x190000 + +static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_DL_RATE_8K; + case 11025: + return MTK_AFE_ADDA_DL_RATE_11K; + case 12000: + return MTK_AFE_ADDA_DL_RATE_12K; + case 16000: + return MTK_AFE_ADDA_DL_RATE_16K; + case 22050: + return MTK_AFE_ADDA_DL_RATE_22K; + case 24000: + return MTK_AFE_ADDA_DL_RATE_24K; + case 32000: + return MTK_AFE_ADDA_DL_RATE_32K; + case 44100: + return MTK_AFE_ADDA_DL_RATE_44K; + case 48000: + return MTK_AFE_ADDA_DL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_DL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_DL_RATE_192K; + default: + dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_DL_RATE_48K; + } +} + +static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_UL_RATE_8K; + case 16000: + return MTK_AFE_ADDA_UL_RATE_16K; + case 32000: + return MTK_AFE_ADDA_UL_RATE_32K; + case 48000: + return MTK_AFE_ADDA_UL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_UL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_UL_RATE_192K; + default: + dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_UL_RATE_48K; + } +} + +/* dai component */ +static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1", AFE_CONN3, I_DL12_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN3_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN3_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN3_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN3_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN3, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1", AFE_CONN3, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3, + I_PCM_2_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1", AFE_CONN3_1, + I_SRC_1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_2_OUT_CH1", AFE_CONN3_1, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2", AFE_CONN4, I_DL12_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN4_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN4_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN4_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN4_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN4, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2", AFE_CONN4, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4, + I_PCM_2_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4, + I_PCM_2_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2", AFE_CONN4_1, + I_SRC_1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_2_OUT_CH2", AFE_CONN4_1, + I_SRC_2_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch3_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN52, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1", AFE_CONN52, I_DL12_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN52, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN52, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN52_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN52_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN52_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN52, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN52, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN52, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1", AFE_CONN52, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN52, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN52, + I_PCM_2_CAP_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch4_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN53, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN53, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2", AFE_CONN53, I_DL12_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN53, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN53, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN53, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN53, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN53_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN53_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN53_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3", AFE_CONN53, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN53, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN53, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2", AFE_CONN53, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN53, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN53, + I_PCM_2_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN53, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN53, + I_PCM_2_CAP_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_stf_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN19, + I_ADDA_UL_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_stf_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN20, + I_ADDA_UL_CH2, 1, 0), +}; + +enum { + SUPPLY_SEQ_ADDA_AFE_ON, + SUPPLY_SEQ_ADDA_DL_ON, + SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SUPPLY_SEQ_ADDA_FIFO, + SUPPLY_SEQ_ADDA_AP_DMIC, + SUPPLY_SEQ_ADDA_UL_ON, +}; + +static int mtk_adda_ul_src_dmic(struct mtk_base_afe *afe, int id) +{ + unsigned int reg; + + switch (id) { + case MT8192_DAI_ADDA: + case MT8192_DAI_AP_DMIC: + reg = AFE_ADDA_UL_SRC_CON0; + break; + case MT8192_DAI_ADDA_CH34: + case MT8192_DAI_AP_DMIC_CH34: + reg = AFE_ADDA6_UL_SRC_CON0; + break; + default: + return -EINVAL; + } + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, reg, + DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT, + 0x0); + regmap_update_bits(afe->regmap, reg, + DMIC_LOW_POWER_MODE_CTL_MASK_SFT, + 0x0); + + /* turn on dmic, ch1, ch2 */ + regmap_update_bits(afe->regmap, reg, + UL_SDM_3_LEVEL_CTL_MASK_SFT, + 0x1 << UL_SDM_3_LEVEL_CTL_SFT); + regmap_update_bits(afe->regmap, reg, + UL_MODE_3P25M_CH1_CTL_MASK_SFT, + 0x1 << UL_MODE_3P25M_CH1_CTL_SFT); + regmap_update_bits(afe->regmap, reg, + UL_MODE_3P25M_CH2_CTL_MASK_SFT, + 0x1 << UL_MODE_3P25M_CH2_CTL_SFT); + return 0; +} + +static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic; + + dev_info(afe->dev, "%s(), name %s, event 0x%x, mtkaif_dmic %d\n", + __func__, w->name, event, mtkaif_dmic); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 1); + + /* update setting to dmic */ + if (mtkaif_dmic) { + /* mtkaif_rxif_data_mode = 1, dmic */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, + 0x1, 0x1); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, + MTKAIF_RXIF_VOICE_MODE_MASK_SFT, + 0x0); + mtk_adda_ul_src_dmic(afe, MT8192_DAI_ADDA); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8192_afe_gpio_request(afe->dev, false, MT8192_DAI_ADDA, 1); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_ch34_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic_ch34; + int mtkaif_adda6_only = afe_priv->mtkaif_adda6_only; + + dev_info(afe->dev, + "%s(), name %s, event 0x%x, mtkaif_dmic %d, mtkaif_adda6_only %d\n", + __func__, w->name, event, mtkaif_dmic, mtkaif_adda6_only); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34, + 1); + + /* update setting to dmic */ + if (mtkaif_dmic) { + /* mtkaif_rxif_data_mode = 1, dmic */ + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG0, + 0x1, 0x1); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG0, + MTKAIF_RXIF_VOICE_MODE_MASK_SFT, + 0x0); + mtk_adda_ul_src_dmic(afe, MT8192_DAI_ADDA_CH34); + } + + /* when using adda6 without adda enabled, + * RG_ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE_SFT need to be set or + * data cannot be received. + */ + if (mtkaif_adda6_only) { + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_SYNCWORD_CFG, + 0x1 << 23, 0x1 << 23); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8192_afe_gpio_request(afe->dev, false, MT8192_DAI_ADDA_CH34, + 1); + + /* reset dmic */ + afe_priv->mtkaif_dmic_ch34 = 0; + + if (mtkaif_adda6_only) { + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_SYNCWORD_CFG, + 0x1 << 23, 0x0 << 23); + } + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_pad_top_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x38); + else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x30); + else + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x30); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + int delay_data; + int delay_cycle; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) { + /* set protocol 2 */ + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, + 0x00010000); + regmap_write(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, + 0x00010000); + + if (strcmp(w->name, "ADDA_MTKAIF_CFG") == 0 && + (afe_priv->mtkaif_chosen_phase[0] < 0 || + afe_priv->mtkaif_chosen_phase[1] < 0)) { + dev_warn(afe->dev, + "%s(), mtkaif_chosen_phase[0/1]:%d/%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[0], + afe_priv->mtkaif_chosen_phase[1]); + break; + } else if (strcmp(w->name, "ADDA6_MTKAIF_CFG") == 0 && + afe_priv->mtkaif_chosen_phase[2] < 0) { + dev_warn(afe->dev, + "%s(), mtkaif_chosen_phase[2]:%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[2]); + break; + } + + /* mtkaif_rxif_clkinv_adc inverse for calibration */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, + MTKAIF_RXIF_CLKINV_ADC_MASK_SFT, + 0x1 << MTKAIF_RXIF_CLKINV_ADC_SFT); + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, + MTKAIF_RXIF_CLKINV_ADC_MASK_SFT, + 0x1 << MTKAIF_RXIF_CLKINV_ADC_SFT); + + /* set delay for ch12 */ + if (afe_priv->mtkaif_phase_cycle[0] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = afe_priv->mtkaif_phase_cycle[0] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[0]; + } + + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + MTKAIF_RXIF_DELAY_DATA_SFT); + + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + MTKAIF_RXIF_DELAY_CYCLE_SFT); + + /* set delay between ch3 and ch2 */ + if (afe_priv->mtkaif_phase_cycle[2] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; /* ch3 */ + delay_cycle = afe_priv->mtkaif_phase_cycle[2] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; /* ch2 */ + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[2]; + } + + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + MTKAIF_RXIF_DELAY_DATA_SFT); + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + MTKAIF_RXIF_DELAY_CYCLE_SFT); + } else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) { + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, + 0x00010000); + regmap_write(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, + 0x00010000); + } else { + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x0); + regmap_write(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, 0x0); + } + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_info(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 0); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8192_afe_gpio_request(afe->dev, false, MT8192_DAI_ADDA, 0); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_ch34_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_info(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34, + 0); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8192_afe_gpio_request(afe->dev, false, MT8192_DAI_ADDA_CH34, + 0); + break; + default: + break; + } + + return 0; +} + +/* stf */ +static int stf_positive_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->stf_positive_gain_db; + return 0; +} + +static int stf_positive_gain_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + int gain_db = ucontrol->value.integer.value[0]; + + afe_priv->stf_positive_gain_db = gain_db; + + if (gain_db >= 0 && gain_db <= 24) { + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + POSITIVE_GAIN_MASK_SFT, + (gain_db / 6) << POSITIVE_GAIN_SFT); + } else { + dev_warn(afe->dev, "%s(), gain_db %d invalid\n", + __func__, gain_db); + } + return 0; +} + +/* mtkaif dmic */ +static const char * const mt8192_adda_off_on_str[] = { + "Off", "On" +}; + +static const struct soc_enum mt8192_adda_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8192_adda_off_on_str), + mt8192_adda_off_on_str), +}; + +static int mt8192_adda_dmic_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->mtkaif_dmic; + return 0; +} + +static int mt8192_adda_dmic_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int dmic_on; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + dmic_on = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n", + __func__, kcontrol->id.name, dmic_on); + + afe_priv->mtkaif_dmic = dmic_on; + afe_priv->mtkaif_dmic_ch34 = dmic_on; + return 0; +} + +static int mt8192_adda6_only_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->mtkaif_adda6_only; + return 0; +} + +static int mt8192_adda6_only_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8192_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int mtkaif_adda6_only; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + mtkaif_adda6_only = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n", + __func__, kcontrol->id.name, mtkaif_adda6_only); + + afe_priv->mtkaif_adda6_only = mtkaif_adda6_only; + return 0; +} + +static const struct snd_kcontrol_new mtk_adda_controls[] = { + SOC_SINGLE("Sidetone_Gain", AFE_SIDETONE_GAIN, + SIDE_TONE_GAIN_SFT, SIDE_TONE_GAIN_MASK, 0), + SOC_SINGLE_EXT("Sidetone_Positive_Gain_dB", SND_SOC_NOPM, 0, 100, 0, + stf_positive_gain_get, stf_positive_gain_set), + SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1, + DL_2_GAIN_CTL_PRE_SFT, DL_2_GAIN_CTL_PRE_MASK, 0), + SOC_ENUM_EXT("MTKAIF_DMIC", mt8192_adda_enum[0], + mt8192_adda_dmic_get, mt8192_adda_dmic_set), + SOC_ENUM_EXT("MTKAIF_ADDA6_ONLY", mt8192_adda_enum[0], + mt8192_adda6_only_get, mt8192_adda6_only_set), +}; + +static const struct snd_kcontrol_new stf_ctl = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); + +static const u16 stf_coeff_table_16k[] = { + 0x049C, 0x09E8, 0x09E0, 0x089C, + 0xFF54, 0xF488, 0xEAFC, 0xEBAC, + 0xfA40, 0x17AC, 0x3D1C, 0x6028, + 0x7538 +}; + +static const u16 stf_coeff_table_32k[] = { + 0xFE52, 0x0042, 0x00C5, 0x0194, + 0x029A, 0x03B7, 0x04BF, 0x057D, + 0x05BE, 0x0555, 0x0426, 0x0230, + 0xFF92, 0xFC89, 0xF973, 0xF6C6, + 0xF500, 0xF49D, 0xF603, 0xF970, + 0xFEF3, 0x065F, 0x0F4F, 0x1928, + 0x2329, 0x2C80, 0x345E, 0x3A0D, + 0x3D08 +}; + +static const u16 stf_coeff_table_48k[] = { + 0x0401, 0xFFB0, 0xFF5A, 0xFECE, + 0xFE10, 0xFD28, 0xFC21, 0xFB08, + 0xF9EF, 0xF8E8, 0xF80A, 0xF76C, + 0xF724, 0xF746, 0xF7E6, 0xF90F, + 0xFACC, 0xFD1E, 0xFFFF, 0x0364, + 0x0737, 0x0B62, 0x0FC1, 0x1431, + 0x188A, 0x1CA4, 0x2056, 0x237D, + 0x25F9, 0x27B0, 0x2890 +}; + +static int mtk_stf_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + size_t half_tap_num; + const u16 *stf_coeff_table; + unsigned int ul_rate, reg_value; + size_t coef_addr; + + regmap_read(afe->regmap, AFE_ADDA_UL_SRC_CON0, &ul_rate); + ul_rate = ul_rate >> UL_VOICE_MODE_CH1_CH2_CTL_SFT; + ul_rate = ul_rate & UL_VOICE_MODE_CH1_CH2_CTL_MASK; + + if (ul_rate == MTK_AFE_ADDA_UL_RATE_48K) { + half_tap_num = ARRAY_SIZE(stf_coeff_table_48k); + stf_coeff_table = stf_coeff_table_48k; + } else if (ul_rate == MTK_AFE_ADDA_UL_RATE_32K) { + half_tap_num = ARRAY_SIZE(stf_coeff_table_32k); + stf_coeff_table = stf_coeff_table_32k; + } else { + half_tap_num = ARRAY_SIZE(stf_coeff_table_16k); + stf_coeff_table = stf_coeff_table_16k; + } + + regmap_read(afe->regmap, AFE_SIDETONE_CON1, ®_value); + + dev_info(afe->dev, "%s(), name %s, event 0x%x, ul_rate 0x%x, AFE_SIDETONE_CON1 0x%x\n", + __func__, w->name, event, ul_rate, reg_value); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* set side tone gain = 0 */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + SIDE_TONE_GAIN_MASK_SFT, + 0); + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + POSITIVE_GAIN_MASK_SFT, + 0); + /* don't bypass stf */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON1, + 0x1f << 27, + 0x0); + /* set stf half tap num */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON1, + SIDE_TONE_HALF_TAP_NUM_MASK_SFT, + half_tap_num << SIDE_TONE_HALF_TAP_NUM_SFT); + + /* set side tone coefficient */ + regmap_read(afe->regmap, AFE_SIDETONE_CON0, ®_value); + for (coef_addr = 0; coef_addr < half_tap_num; coef_addr++) { + bool old_w_ready = (reg_value >> W_RDY_SFT) & 0x1; + bool new_w_ready = 0; + int try_cnt = 0; + + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON0, + 0x39FFFFF, + (1 << R_W_EN_SFT) | + (1 << R_W_SEL_SFT) | + (0 << SEL_CH2_SFT) | + (coef_addr << + SIDE_TONE_COEFFICIENT_ADDR_SFT) | + stf_coeff_table[coef_addr]); + + /* wait until flag write_ready changed */ + for (try_cnt = 0; try_cnt < 10; try_cnt++) { + regmap_read(afe->regmap, + AFE_SIDETONE_CON0, ®_value); + new_w_ready = (reg_value >> W_RDY_SFT) & 0x1; + + /* flip => ok */ + if (new_w_ready == old_w_ready) { + udelay(3); + if (try_cnt == 9) { + dev_warn(afe->dev, + "%s(), write coeff not ready", + __func__); + } + } else { + break; + } + } + /* need write -> read -> write to write next coeff */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON0, + R_W_SEL_MASK_SFT, + 0x0); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* bypass stf */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_CON1, + 0x1f << 27, + 0x1f << 27); + + /* set side tone gain = 0 */ + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + SIDE_TONE_GAIN_MASK_SFT, + 0); + regmap_update_bits(afe->regmap, + AFE_SIDETONE_GAIN, + POSITIVE_GAIN_MASK_SFT, + 0); + break; + default: + break; + } + + return 0; +} + +/* stf mux */ +enum { + STF_SRC_ADDA_ADDA6 = 0, + STF_SRC_O19O20, +}; + +static const char *const stf_o19o20_mux_map[] = { + "ADDA_ADDA6", + "O19O20", +}; + +static int stf_o19o20_mux_map_value[] = { + STF_SRC_ADDA_ADDA6, + STF_SRC_O19O20, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(stf_o19o20_mux_map_enum, + AFE_SIDETONE_CON1, + STF_SOURCE_FROM_O19O20_SFT, + STF_SOURCE_FROM_O19O20_MASK, + stf_o19o20_mux_map, + stf_o19o20_mux_map_value); + +static const struct snd_kcontrol_new stf_o19O20_mux_control = + SOC_DAPM_ENUM("STF_O19O20_MUX", stf_o19o20_mux_map_enum); + +enum { + STF_SRC_ADDA = 0, + STF_SRC_ADDA6, +}; + +static const char *const stf_adda_mux_map[] = { + "ADDA", + "ADDA6", +}; + +static int stf_adda_mux_map_value[] = { + STF_SRC_ADDA, + STF_SRC_ADDA6, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(stf_adda_mux_map_enum, + AFE_SIDETONE_CON1, + STF_O19O20_OUT_EN_SEL_SFT, + STF_O19O20_OUT_EN_SEL_MASK, + stf_adda_mux_map, + stf_adda_mux_map_value); + +static const struct snd_kcontrol_new stf_adda_mux_control = + SOC_DAPM_ENUM("STF_ADDA_MUX", stf_adda_mux_map_enum); + +/* ADDA UL MUX */ +enum { + ADDA_UL_MUX_MTKAIF = 0, + ADDA_UL_MUX_AP_DMIC, + ADDA_UL_MUX_MASK = 0x1, +}; + +static const char * const adda_ul_mux_map[] = { + "MTKAIF", "AP_DMIC" +}; + +static int adda_ul_map_value[] = { + ADDA_UL_MUX_MTKAIF, + ADDA_UL_MUX_AP_DMIC, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(adda_ul_mux_map_enum, + SND_SOC_NOPM, + 0, + ADDA_UL_MUX_MASK, + adda_ul_mux_map, + adda_ul_map_value); + +static const struct snd_kcontrol_new adda_ul_mux_control = + SOC_DAPM_ENUM("ADDA_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_kcontrol_new adda_ch34_ul_mux_control = + SOC_DAPM_ENUM("ADDA_CH34_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch1_mix, + ARRAY_SIZE(mtk_adda_dl_ch1_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch2_mix, + ARRAY_SIZE(mtk_adda_dl_ch2_mix)), + + SND_SOC_DAPM_MIXER("ADDA_DL_CH3", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch3_mix, + ARRAY_SIZE(mtk_adda_dl_ch3_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH4", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch4_mix, + ARRAY_SIZE(mtk_adda_dl_ch4_mix)), + + SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, + AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, + AFE_ADDA_DL_SRC2_CON0, + DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, + mtk_adda_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ADDA CH34 Playback Enable", + SUPPLY_SEQ_ADDA_DL_ON, + AFE_ADDA_3RD_DAC_DL_SRC2_CON0, + DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, + mtk_adda_ch34_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_UL_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + mtk_adda_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ADDA CH34 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA6_UL_SRC_CON0, + UL_SRC_ON_TMP_CTL_SFT, 0, + mtk_adda_ch34_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("AUD_PAD_TOP", SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + AFE_AUD_PAD_TOP, + RG_RX_FIFO_ON_SFT, 0, + mtk_adda_pad_top_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA6_MTKAIF_CFG", SUPPLY_SEQ_ADDA6_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA_UL_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_CH34_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA6_UL_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_UL_DL_CON0, + AFE_ADDA_FIFO_AUTO_RST_SFT, 1, + NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ADDA_CH34_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_UL_DL_CON0, + AFE_ADDA6_FIFO_AUTO_RST_SFT, 1, + NULL, 0), + + SND_SOC_DAPM_MUX("ADDA_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ul_mux_control), + SND_SOC_DAPM_MUX("ADDA_CH34_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ch34_ul_mux_control), + + SND_SOC_DAPM_INPUT("AP_DMIC_INPUT"), + SND_SOC_DAPM_INPUT("AP_DMIC_CH34_INPUT"), + + /* stf */ + SND_SOC_DAPM_SWITCH_E("Sidetone Filter", + AFE_SIDETONE_CON1, SIDE_TONE_ON_SFT, 0, + &stf_ctl, + mtk_stf_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("STF_O19O20_MUX", SND_SOC_NOPM, 0, 0, + &stf_o19O20_mux_control), + SND_SOC_DAPM_MUX("STF_ADDA_MUX", SND_SOC_NOPM, 0, 0, + &stf_adda_mux_control), + SND_SOC_DAPM_MIXER("STF_CH1", SND_SOC_NOPM, 0, 0, + mtk_stf_ch1_mix, + ARRAY_SIZE(mtk_stf_ch1_mix)), + SND_SOC_DAPM_MIXER("STF_CH2", SND_SOC_NOPM, 0, 0, + mtk_stf_ch2_mix, + ARRAY_SIZE(mtk_stf_ch2_mix)), + SND_SOC_DAPM_OUTPUT("STF_OUTPUT"), + + /* clock */ + SND_SOC_DAPM_CLOCK_SUPPLY("top_mux_audio_h"), + + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_predis_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_3rd_dac_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_3rd_dac_predis_clk"), + + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc_clk"), +}; + +static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { + /* playback */ + {"ADDA_DL_CH1", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH2", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH2", "DL1_CH2", "DL1"}, + + {"ADDA_DL_CH1", "DL12_CH1", "DL12"}, + {"ADDA_DL_CH2", "DL12_CH2", "DL12"}, + + {"ADDA_DL_CH1", "DL6_CH1", "DL6"}, + {"ADDA_DL_CH2", "DL6_CH2", "DL6"}, + + {"ADDA_DL_CH1", "DL8_CH1", "DL8"}, + {"ADDA_DL_CH2", "DL8_CH2", "DL8"}, + + {"ADDA_DL_CH1", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH2", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH2", "DL2_CH2", "DL2"}, + + {"ADDA_DL_CH1", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH2", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH2", "DL3_CH2", "DL3"}, + + {"ADDA_DL_CH1", "DL4_CH1", "DL4"}, + {"ADDA_DL_CH2", "DL4_CH2", "DL4"}, + + {"ADDA_DL_CH1", "DL5_CH1", "DL5"}, + {"ADDA_DL_CH2", "DL5_CH2", "DL5"}, + + {"ADDA Playback", NULL, "ADDA_DL_CH1"}, + {"ADDA Playback", NULL, "ADDA_DL_CH2"}, + + {"ADDA Playback", NULL, "ADDA Enable"}, + {"ADDA Playback", NULL, "ADDA Playback Enable"}, + + {"ADDA_DL_CH3", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH4", "DL1_CH1", "DL1"}, + {"ADDA_DL_CH4", "DL1_CH2", "DL1"}, + + {"ADDA_DL_CH3", "DL12_CH1", "DL12"}, + {"ADDA_DL_CH4", "DL12_CH2", "DL12"}, + + {"ADDA_DL_CH3", "DL6_CH1", "DL6"}, + {"ADDA_DL_CH4", "DL6_CH2", "DL6"}, + + {"ADDA_DL_CH3", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH4", "DL2_CH1", "DL2"}, + {"ADDA_DL_CH4", "DL2_CH2", "DL2"}, + + {"ADDA_DL_CH3", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH4", "DL3_CH1", "DL3"}, + {"ADDA_DL_CH4", "DL3_CH2", "DL3"}, + + {"ADDA_DL_CH3", "DL4_CH1", "DL4"}, + {"ADDA_DL_CH4", "DL4_CH2", "DL4"}, + + {"ADDA_DL_CH3", "DL5_CH1", "DL5"}, + {"ADDA_DL_CH4", "DL5_CH2", "DL5"}, + + {"ADDA CH34 Playback", NULL, "ADDA_DL_CH3"}, + {"ADDA CH34 Playback", NULL, "ADDA_DL_CH4"}, + + {"ADDA CH34 Playback", NULL, "ADDA Enable"}, + {"ADDA CH34 Playback", NULL, "ADDA CH34 Playback Enable"}, + + /* capture */ + {"ADDA_UL_Mux", "MTKAIF", "ADDA Capture"}, + {"ADDA_UL_Mux", "AP_DMIC", "AP DMIC Capture"}, + + {"ADDA_CH34_UL_Mux", "MTKAIF", "ADDA CH34 Capture"}, + {"ADDA_CH34_UL_Mux", "AP_DMIC", "AP DMIC CH34 Capture"}, + + {"ADDA Capture", NULL, "ADDA Enable"}, + {"ADDA Capture", NULL, "ADDA Capture Enable"}, + {"ADDA Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"}, + + {"AP DMIC Capture", NULL, "ADDA Enable"}, + {"AP DMIC Capture", NULL, "ADDA Capture Enable"}, + {"AP DMIC Capture", NULL, "ADDA_FIFO"}, + {"AP DMIC Capture", NULL, "AP_DMIC_EN"}, + + {"ADDA CH34 Capture", NULL, "ADDA Enable"}, + {"ADDA CH34 Capture", NULL, "ADDA CH34 Capture Enable"}, + {"ADDA CH34 Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA CH34 Capture", NULL, "ADDA6_MTKAIF_CFG"}, + + {"AP DMIC CH34 Capture", NULL, "ADDA Enable"}, + {"AP DMIC CH34 Capture", NULL, "ADDA CH34 Capture Enable"}, + {"AP DMIC CH34 Capture", NULL, "ADDA_CH34_FIFO"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_CH34_EN"}, + + {"AP DMIC Capture", NULL, "AP_DMIC_INPUT"}, + {"AP DMIC CH34 Capture", NULL, "AP_DMIC_CH34_INPUT"}, + + /* sidetone filter */ + {"STF_ADDA_MUX", "ADDA", "ADDA_UL_Mux"}, + {"STF_ADDA_MUX", "ADDA6", "ADDA_CH34_UL_Mux"}, + + {"STF_O19O20_MUX", "ADDA_ADDA6", "STF_ADDA_MUX"}, + {"STF_O19O20_MUX", "O19O20", "STF_CH1"}, + {"STF_O19O20_MUX", "O19O20", "STF_CH2"}, + + {"Sidetone Filter", "Switch", "STF_O19O20_MUX"}, + {"STF_OUTPUT", NULL, "Sidetone Filter"}, + {"ADDA Playback", NULL, "Sidetone Filter"}, + {"ADDA CH34 Playback", NULL, "Sidetone Filter"}, + + /* clk */ + {"ADDA Playback", NULL, "aud_dac_clk"}, + {"ADDA Playback", NULL, "aud_dac_predis_clk"}, + + {"ADDA CH34 Playback", NULL, "aud_3rd_dac_clk"}, + {"ADDA CH34 Playback", NULL, "aud_3rd_dac_predis_clk"}, + + {"ADDA Capture Enable", NULL, "aud_adc_clk"}, + {"ADDA CH34 Capture Enable", NULL, "aud_adda6_adc_clk"}, +}; + +/* dai ops */ +static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + unsigned int rate = params_rate(params); + int id = dai->id; + + dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, + id, + substream->stream, + rate); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + unsigned int dl_src2_con0 = 0; + unsigned int dl_src2_con1 = 0; + + /* set sampling rate */ + dl_src2_con0 = adda_dl_rate_transform(afe, rate) << + DL_2_INPUT_MODE_CTL_SFT; + + /* set output mode, UP_SAMPLING_RATE_X8 */ + dl_src2_con0 |= (0x3 << DL_2_OUTPUT_SEL_CTL_SFT); + + /* turn off mute function */ + dl_src2_con0 |= (0x01 << DL_2_MUTE_CH2_OFF_CTL_PRE_SFT); + dl_src2_con0 |= (0x01 << DL_2_MUTE_CH1_OFF_CTL_PRE_SFT); + + /* set voice input data if input sample rate is 8k or 16k */ + if (rate == 8000 || rate == 16000) + dl_src2_con0 |= 0x01 << DL_2_VOICE_MODE_CTL_PRE_SFT; + + /* SA suggest apply -0.3db to audio/speech path */ + dl_src2_con1 = MTK_AFE_ADDA_DL_GAIN_NORMAL << + DL_2_GAIN_CTL_PRE_SFT; + + /* turn on down-link gain */ + dl_src2_con0 |= (0x01 << DL_2_GAIN_ON_CTL_PRE_SFT); + + if (id == MT8192_DAI_ADDA) { + /* clean predistortion */ + regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0); + regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0); + + regmap_write(afe->regmap, + AFE_ADDA_DL_SRC2_CON0, dl_src2_con0); + regmap_write(afe->regmap, + AFE_ADDA_DL_SRC2_CON1, dl_src2_con1); + + /* set sdm gain */ + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DCCOMP_CON, + ATTGAIN_CTL_MASK_SFT, + AUDIO_SDM_LEVEL_NORMAL << + ATTGAIN_CTL_SFT); + + /* 2nd sdm */ + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DCCOMP_CON, + USE_3RD_SDM_MASK_SFT, + AUDIO_SDM_2ND << USE_3RD_SDM_SFT); + + /* sdm auto reset */ + regmap_write(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + SDM_AUTO_RESET_THRESHOLD); + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + ADDA_SDM_AUTO_RESET_ONOFF_MASK_SFT, + 0x1 << ADDA_SDM_AUTO_RESET_ONOFF_SFT); + } else { + /* clean predistortion */ + regmap_write(afe->regmap, + AFE_ADDA_3RD_DAC_PREDIS_CON0, 0); + regmap_write(afe->regmap, + AFE_ADDA_3RD_DAC_PREDIS_CON1, 0); + + regmap_write(afe->regmap, AFE_ADDA_3RD_DAC_DL_SRC2_CON0, + dl_src2_con0); + regmap_write(afe->regmap, AFE_ADDA_3RD_DAC_DL_SRC2_CON1, + dl_src2_con1); + + /* set sdm gain */ + regmap_update_bits(afe->regmap, + AFE_ADDA_3RD_DAC_DL_SDM_DCCOMP_CON, + ATTGAIN_CTL_MASK_SFT, + AUDIO_SDM_LEVEL_NORMAL << + ATTGAIN_CTL_SFT); + + /* 2nd sdm */ + regmap_update_bits(afe->regmap, + AFE_ADDA_3RD_DAC_DL_SDM_DCCOMP_CON, + USE_3RD_SDM_MASK_SFT, + AUDIO_SDM_2ND << USE_3RD_SDM_SFT); + + /* sdm auto reset */ + regmap_write(afe->regmap, + AFE_ADDA_3RD_DAC_DL_SDM_AUTO_RESET_CON, + SDM_AUTO_RESET_THRESHOLD); + regmap_update_bits(afe->regmap, + AFE_ADDA_3RD_DAC_DL_SDM_AUTO_RESET_CON, + ADDA_3RD_DAC_SDM_AUTO_RESET_ONOFF_MASK_SFT, + 0x1 << ADDA_3RD_DAC_SDM_AUTO_RESET_ONOFF_SFT); + } + } else { + unsigned int voice_mode = 0; + unsigned int ul_src_con0 = 0; /* default value */ + + voice_mode = adda_ul_rate_transform(afe, rate); + + ul_src_con0 |= (voice_mode << 17) & (0x7 << 17); + + /* enable iir */ + ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) & + UL_IIR_ON_TMP_CTL_MASK_SFT; + ul_src_con0 |= (UL_IIR_SW << UL_IIRMODE_CTL_SFT) & + UL_IIRMODE_CTL_MASK_SFT; + + switch (id) { + case MT8192_DAI_ADDA: + case MT8192_DAI_AP_DMIC: + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA_UL_SRC_CON0, ul_src_con0); + + /* Using Internal ADC */ + regmap_update_bits(afe->regmap, + AFE_ADDA_TOP_CON0, + 0x1 << 0, + 0x0 << 0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_RX_CFG0, + 0x1 << 0, + 0x0 << 0); + break; + case MT8192_DAI_ADDA_CH34: + case MT8192_DAI_AP_DMIC_CH34: + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_02_01, 0x00000000); + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_04_03, 0x00003FB8); + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_06_05, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_08_07, 0x3FB80000); + regmap_write(afe->regmap, + AFE_ADDA6_IIR_COEF_10_09, 0x0000C048); + + regmap_write(afe->regmap, + AFE_ADDA6_UL_SRC_CON0, ul_src_con0); + + /* Using Internal ADC */ + regmap_update_bits(afe->regmap, + AFE_ADDA6_TOP_CON0, + 0x1 << 0, + 0x0 << 0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, + AFE_ADDA6_MTKAIF_RX_CFG0, + 0x1 << 0, + 0x0 << 0); + break; + default: + break; + } + + /* ap dmic */ + switch (id) { + case MT8192_DAI_AP_DMIC: + case MT8192_DAI_AP_DMIC_CH34: + mtk_adda_ul_src_dmic(afe, id); + break; + default: + break; + } + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_adda_ops = { + .hw_params = mtk_dai_adda_hw_params, +}; + +/* dai driver */ +#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { + { + .name = "ADDA", + .id = MT8192_DAI_ADDA, + .playback = { + .stream_name = "ADDA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .capture = { + .stream_name = "ADDA Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "ADDA_CH34", + .id = MT8192_DAI_ADDA_CH34, + .playback = { + .stream_name = "ADDA CH34 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .capture = { + .stream_name = "ADDA CH34 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC", + .id = MT8192_DAI_AP_DMIC, + .capture = { + .stream_name = "AP DMIC Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC_CH34", + .id = MT8192_DAI_AP_DMIC_CH34, + .capture = { + .stream_name = "AP DMIC CH34 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, +}; + +int mt8192_dai_adda_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + struct mt8192_afe_private *afe_priv = afe->platform_priv; + + dev_info(afe->dev, "%s()\n", __func__); + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_adda_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); + + dai->controls = mtk_adda_controls; + dai->num_controls = ARRAY_SIZE(mtk_adda_controls); + dai->dapm_widgets = mtk_dai_adda_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); + dai->dapm_routes = mtk_dai_adda_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); + + /* ap dmic priv share with adda */ + afe_priv->dai_priv[MT8192_DAI_AP_DMIC] = + afe_priv->dai_priv[MT8192_DAI_ADDA]; + afe_priv->dai_priv[MT8192_DAI_AP_DMIC_CH34] = + afe_priv->dai_priv[MT8192_DAI_ADDA_CH34]; + + return 0; +} -- 2.18.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel