From patchwork Wed Nov 23 04:57:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Lee X-Patchwork-Id: 9448525 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EBBCC6071C for ; Sat, 26 Nov 2016 19:51:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CDD5326CF9 for ; Sat, 26 Nov 2016 19:51:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ADF5C26E51; Sat, 26 Nov 2016 19:51:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.8 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED, RCVD_IN_DNSWL_NONE, T_DKIM_INVALID autolearn=no version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E94726CF9 for ; Sat, 26 Nov 2016 19:51:37 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 9529F266522; Sat, 26 Nov 2016 20:51:31 +0100 (CET) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 9EA5B26581B; Sat, 26 Nov 2016 20:49:06 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id B553B2667DB; Wed, 23 Nov 2016 05:58:11 +0100 (CET) Received: from NAM01-SN1-obe.outbound.protection.outlook.com (mail-sn1nam01on0131.outbound.protection.outlook.com [104.47.32.131]) by alsa0.perex.cz (Postfix) with ESMTP id 1149E266671 for ; Wed, 23 Nov 2016 05:58:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maximintegrated.onmicrosoft.com; s=selector1-maximintegrated-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=vfOCwk2a++LTKPtwgH1Wwef0yQSYoxfvEDSION9/q84=; b=OJLF1NwnFHSfmCs11Zk7Ysz9/E9VmocD6vd/0w3C0CmWuPlPhWA3cwVhFLTeOY7HbGXSnhZohZBEjyfMHcVBdvC9O9Bh5YFB1ZkM41AzAQKEQNC0KWGpwjiWA2XLU13/l4rS1IfFc7Gs/DvXgvwMFiqrL9I9WwW4oF67O1nTm3Y= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=RyanS.Lee@maximintegrated.com; Received: from MAXSJHREL03.maxim-ic.internal (211.110.156.158) by CY4PR11MB1368.namprd11.prod.outlook.com (10.173.16.150) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.734.8; Wed, 23 Nov 2016 04:57:49 +0000 From: Ryan Lee To: , , , , , , , , , , , , , , , , , , , , Date: Wed, 23 Nov 2016 13:57:06 +0900 Message-ID: <1479877026-5172-1-git-send-email-RyanS.Lee@maximintegrated.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 X-Originating-IP: [211.110.156.158] X-ClientProxiedBy: SG2PR06CA0054.apcprd06.prod.outlook.com (10.167.73.150) To CY4PR11MB1368.namprd11.prod.outlook.com (10.173.16.150) X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1368; 2:ztej2BHVjRMY1BE1PIsDOEKUcrFW/7d6SNMUW+J7a/ERjBVuCJZBZjyhCSSA+Ccq26FfOM9O6q5VzHpDyjYup/Nd71dH0BuSufzUk97LN6QYwF034JdsX5E/oVMH6Em/KdHiv8pJfndJ962DdIwwTNiFI/rt6bixOANGfKzXFyw=; 3:B+AR2cqIOgcK6f80bjFIvHTt8DYRvOFDOTDJeDH0HjFyYX/NgbF9sbAWAToEgD9QDQvOtAfYItWLM00hJNIAew6f2iuQfodrdWD/uJWA8HB6UKrgcinsyDb2DR99d68hnIkdwDxb2h/Delteq+kJNzLyGTFRUMI4pj1kujglvM4= X-MS-Office365-Filtering-Correlation-Id: ac757150-84fb-4657-0327-08d4135d4cd6 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:CY4PR11MB1368; X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1368; 25:AC8qdcaLdafnhwlVCHHNHCXPJ24prCZxljZYxrJnn+PJ0wI1pauV2xwgcuAYz3Kd3ap9RB0vwyALqb4ZXgKhg6ag8U8YTmWlXLhBRCDYMOJ/xxETOjkQpKqlmtsONh5/j5v+ODm6+eln5sQmQzUZ9LlBUXzJKKZcu3aTAQJYYYt/hj+U5NSSnu6CJUXHkmqFBQl1UBGS6YNJBoIm8Mhpp7hifzuJvwDEg9gEqb2odxy+rgLL4aULYlH6EeniqpUXrWWVoiv7Y8s95W9w+T7ziLW7Zo1LwmxQ+5tX2iyhtgEG4XoTfNQ1C2MerKvzc+iQ1XjaqihAi1zTa3phTTatF608HakxYtKHmji76UPHs9sVwBwKxcCBCJlWlFEw2cdIa9xzBha9KYqAmZwCju7v7Y7a+eZj//YD4yOLdSGB7gX/pFu84zij/nIWUkC2u5LUdi+ZnBSL+wexvtZMLvzl0g6hLgQFuFnK4EGZ7kLGw0Q0C2oOmHafmqi0jYmq/gPh2fSWNjpr3oqDHwvctkeGOaLmbcn9LDdnwpDxTl8vogI7TK3Eh9y8+TpmyojjaaRPeVP41Vj6kNLi2azZ+pX6MX1sZe6snO+2/3LiiybgobuhczK/+4xb3P/MwTGyFiV2zZ0FLQw1rf7EwhwMkIJ+G3dWYS5iC8bqjwvehJc7vu/RsjfA9Ibhj4jTisHcb4R1tnSz2t8h4N5wB/m07v0acRdzRPOcaaFFYa8+PbIAZ51Hun1ZkSRSkt7yy2NR2ERHTwFeiUBMSaEyjXBvq9TGq6HiOMGVoLxfjbevatQvPF8= X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1368; 31:alpTu++Sz3ePcFm1UUBpHmHhJ+4msQuv19eEW+sBQLakUcOKDLWmuE8kJNgKNVi2pocbiIsp2NCvKI0exPKNRPRyGZB6RZ+IgXFpqiTrzLIuSMCU8uF/FccoZ+e90wIFE2zlyvCmkvjmr/HFlRhFXL5UpdMHH+fwKAyzYnd0G+iv1Y0L/+UTimJJiN2zeY1gawIc9idQ13xinnZvubY7X9WmwJ2zbMobG7N0B/gb/ADadCEBnS89hlAjdRP2AP+P; 20:RNrUt4fZqywwqYxeAZv82AI1e0YEC3FNl01jqOjzuz9834sEKRbAWj6/mlMF6LR6tEo2wUj7wGvqqp4oHH8/+rvJRsdiiQmuPH1AKYp1QFhkpifMbQVCZZX6VfdXoAH2BH3Sy83xsXWh5ZGjG98D7n68NCeQF1NHZlXhgfxrbBWCYotyMPlVnrPWzsSOCSwnzsBaGvj61xqmzxapcTABfhYiASPJnlCQJjYkvNPOnnHpj+M2mMOUDAJvzkyd6++8gzvLShs+h2O+7wSkhTMIgUV3A13u0SySVTP/T0p31TOVFxLUCa5Uh5m+3MVIZVO4Vuhkn893W8u6jvjp6Bu10uSJmsxb24z7sjSUeKF2YWEqBknbMdusopMtKG4cX926p4jP5WghQL/MQ03f4I4JvtQsYwo5+pHYPAKKmJXYtgzjN8Pd9wGOUn8xNsypjTjGMfYey0q/dlhb5N5ljI27vhGfN96Is5BRL62rKqciCLh+RwCNUh6e8XDsY6/69P7c X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(108721460000369); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040307)(6060326)(6045199)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026)(6041248)(6061324); SRVR:CY4PR11MB1368; BCL:0; PCL:0; RULEID:; SRVR:CY4PR11MB1368; X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1368; 4:M6jDqRt64bduDTHdzgWDTv11RX9u3/f4Inbj9JJf7iR3+H+FY1QlL6n33Htavg1hZT4P4DeatXMqY1E6VNpyYfOKBp4yWhGBabEXDPXDgybBdwajAz0hxO7/6gWXIOy6jymsTmRONrbGYdeRLmU8ZAq3OWspQhc+WwXgl2YCmfBxPJ0yxau9IFobP5/fHXfZ4BJu9kGha/to2mpbi9GefIEPhdPUhF4ybiMrEytuHX7yOCAYa5TwFjyDMMMWf7uC8rpff+nrXr03WxkFk7qEpPglU+RqR/gF/SdjvF2KqjY+1nDGDITX8UFvooYg+8LUp1XQgczwd3xOXMxYRfmH81cMef+yatKaVqQSzNqBn6Q6n5Wa96f1Vfr/a1flKveL8o2pL9KIt8sU5pCam3GFaSr6GgUeiNMSEFNCbDOO8dkyCAgYdr7Ad+BOxzb2FHYI95SULpcD63QgI6XtlOLAXUUG85i0XeSqZWRsxel9FrQbIRnqcIxlvBX2d9HsvMleSqJiCXoM+WPeDg51Gqo48nOXbUDTS3iaJFIwks0JvJM= X-Forefront-PRVS: 013568035E X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(6116002)(50986999)(8676002)(86362001)(6666003)(38730400001)(92566002)(5001770100001)(97736004)(2201001)(68736007)(5003940100001)(5660300001)(305945005)(47776003)(48376002)(107886002)(4001430100002)(106356001)(2906002)(189998001)(36756003)(7736002)(7846002)(77096005)(81166006)(42186005)(3846002)(66066001)(81156014)(101416001)(7416002)(4326007)(50226002)(50466002)(39060400001)(105586002)(2004002)(921003)(1121003)(569005); DIR:OUT; SFP:1102; SCL:1; SRVR:CY4PR11MB1368; H:MAXSJHREL03.maxim-ic.internal; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: maximintegrated.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY4PR11MB1368; 23:iZGc0iy42chE+9u050WWtMcDFDfwpFaQLzeWFe41K?= =?us-ascii?Q?YmIaXPp+TbjXHi9zlwjY6hJLvdp9tanZ5AuVrocbOLnDCna3lvzW0a3r0miN?= =?us-ascii?Q?WsGqfR9LJtOJWAUHh2XMQeEoUotFym0OMlK8FpOwT3y9243AMGTvSkPktCWd?= =?us-ascii?Q?L0kgrBDeAgDm8P/KHVzlnAKjkCmxvgcH9qqndTiDN9Ox7ojdfsPVGZimaNLP?= =?us-ascii?Q?fE8pTJNYhJ6CQSzS5PFerWwVjOwljfvBJz2oe6/p1/TrXuQPjwzqY3AGAiyR?= =?us-ascii?Q?9xVyrJ0EwlwQYV/GdlYUqtw7Xeut8QuLWUxOp3oBKEFknzG398GNq/jk8Mif?= =?us-ascii?Q?ulq4/7oeFCNUyNonBjbJ5pzmfUfES0a1Ldjjg3P8/enuAB82MlSqoIMttAKm?= =?us-ascii?Q?GTHfdaXuUMu556OjADdJCcEY8MT/51QnAtVxrs6rFvx+qFpTLtK3LVRJQLtD?= =?us-ascii?Q?9gYH6Twpz1ltpVz1u+WDvOxxP628SDS4wMqotYO7/rbuznUTiczwaSCpfmgP?= =?us-ascii?Q?GipdwAS9McPvF9jcuUuzFEhlM+4Dr8QmUM4vmNf4NVgsxxQ75izpOSGDfTAk?= =?us-ascii?Q?iLQYfy5tiMtpzbXXtv69pA+PpRm6i4ixS6386tn65W9q6mq1+/Ezq4pwW19o?= =?us-ascii?Q?5auJHSmA6lJej8MR2BeJmYC3EPojC3sc2mtquD7UH7Or1gwQLzS3c1KnRO6Z?= =?us-ascii?Q?aI4AZsHuILBX/O8mjpjmgPQOEoF4WCLJDxqD1vObxeOFIejlQuqwWxYuDitQ?= =?us-ascii?Q?Kqv6J/k4PKMACJ9I3nYUwUfoyc/TdCAhbgYiGX8R3Yki1MaH3lIbnXMzyZn0?= =?us-ascii?Q?41VxJ9Ei2EAR0z2kByjBJb8tCTbhasJ7AosfJ3CJwG35HBvdABjp4OjUlZgP?= =?us-ascii?Q?ls5tom3tOMixoc5PI1iJ/Z/QOsMOp9p9xw3KWyQuV64z7Sv8bjLy6wvqZWbv?= =?us-ascii?Q?CCQxVCpxb+v20NbqTPhMzFrQIm0sAQruT3f7n6GPpvKdtnBA9NXE/dsbSlz8?= =?us-ascii?Q?nZ1e08Q1Zco3gmmtEqrBTzB2x+70OzLGm+n9GumpphpjrSgez9Tvoqe8RLk/?= =?us-ascii?Q?Cu2x5vM6wVVvfG46Fon2rH1BKOh6DqqklU2bsGtMk3e7OAxYMg2xysGNFtY7?= =?us-ascii?Q?x0F3h/fdLVVWWz8Qxuusao9i3+f/sMGR7WzvDqh7288qR9JSREO1Q=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1368; 6:K5aviVT/PdcK1CDJFCPeQUL+BqQPW6XROjnv+BgiCDQw4V3rqOAUI51Cwu3K3USeiFMfI9JOnBtvIW0aWlIKKnHU0dkcLRdeSq8wlZh1KejX/l3GXautwtcoRMvGJlPICeLS6CcGeSL2olaoySXmjJeRjLixrIin14V7fRHIv7+IkOK4WMsA6sZ5Byubx7FSACX79kd5SCMTdVwh1/WgzdO1EbFEBz/Ev/MSRfeSqqBF5wqzpvJaDmtOzGVVv6UqBPCwfZncIEEn6ycqpLKXPLup6eK7Q/zEYXJKq4YnnPe+Wy/lgIL04tM/fTigiQaBZicDIQ6GB0RCe0GYOOdmIIuYDuioF2NFuTAcTUKXB4nHp96KJtFLibblB5yI3Z8D; 5:a89mC4z6gDrB7Nu6tHEMrPwsLqySD5zjSKhgxLUcB/LJrG/yX26rptTXmR8086D6J+CE9rY6OozQefXZMkKTdpsO2RTOCrD+V5+w9kjfsO21z4iz9sphL/lnNr5mgyGkafy9SvxbaSp9eHo10G2NLA==; 24:fQFzy+6DvYleb2XDV/Gf4LNaPKciO6Xe+53rH/kEq3qC9ournSM9TtDm8yl6Uxt8ijLNMvBbzOW6BgdCTCYQmL9oMjxXolyUe4xN9xiT3dg= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1368; 7:e/RPrdLMTcEEO8zau1IM4lT/iI1RD9r/tKRo5za0qnX3yGpUX/HPqPwYrR7jcrPFwcIqd/FU524zS6R76TeRZ7fmGsWsOWLnweo0hyNvichvzzwGppJWiTlz5opYqH6x0A3qJqOjWDp8S9SlMU3HpazHfQuB+4Cmw34aohhqzZdnieFD501AJtb+gO3iKulWE3k814SHVTqjL9El9poctIHmZvicXgVa6rLe3kB81dIYMsv/rqCM/Nxh4nUIXYNKfnBN805pNPra/tsoWAydzyTAUjAvG7phD6t4Yy4F1cu8r7xiYNQM6xldcJJijPPJ5B/mpZuQHTRsO8qqOnpu880cC+BP+QJt8oi1eyh8+mE= X-OriginatorOrg: maximintegrated.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Nov 2016 04:57:49.2493 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR11MB1368 X-Mailman-Approved-At: Sat, 26 Nov 2016 20:48:57 +0100 Cc: Ryan Lee Subject: [alsa-devel] [PATCH] ALSA SoC MAX98927 driver - Initial release X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 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-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Ryan Lee --- .../devicetree/bindings/sound/max98927.txt | 32 + sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/max98927.c | 954 +++++++++++++++ sound/soc/codecs/max98927.h | 1253 ++++++++++++++++++++ 5 files changed, 2246 insertions(+) create mode 100755 Documentation/devicetree/bindings/sound/max98927.txt mode change 100644 => 100755 sound/soc/codecs/Kconfig mode change 100644 => 100755 sound/soc/codecs/Makefile create mode 100755 sound/soc/codecs/max98927.c create mode 100755 sound/soc/codecs/max98927.h diff --git a/Documentation/devicetree/bindings/sound/max98927.txt b/Documentation/devicetree/bindings/sound/max98927.txt new file mode 100755 index 0000000..ddcd332 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98927.txt @@ -0,0 +1,32 @@ +max98927 audio CODEC + +This device supports I2C. + +Required properties: + + - compatible : "maxim,max98927" + + - vmon-slot-no : slot number used to send voltage information + or in inteleave mode this will be used as + interleave slot. + + - imon-slot-no : slot number used to send current information + + - interleave-mode : When using two MAX98927 in a system it is + possible to create ADC data that that will + overflow the frame size. Digital Audio Interleave + mode provides a means to output VMON and IMON data + from two devices on a single DOUT line when running + smaller frames sizes such as 32 BCLKS per LRCLK or + 48 BCLKS per LRCLK. + + - reg : the I2C address of the device for I2C + +Example: + +codec: max98927@3a { + compatible = "maxim,max98927"; + vmon-slot-no = <1>; + imon-slot-no = <0>; + reg = <0x3a>; +}; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig old mode 100644 new mode 100755 index c67667b..45f21ca --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -86,6 +86,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_MAX9867 if I2C select SND_SOC_MAX98925 if I2C select SND_SOC_MAX98926 if I2C + select SND_SOC_MAX98927 if I2C select SND_SOC_MAX9850 if I2C select SND_SOC_MAX9860 if I2C select SND_SOC_MAX9768 if I2C @@ -573,6 +574,10 @@ config SND_SOC_MAX98925 config SND_SOC_MAX98926 tristate +config SND_SOC_MAX98927 + tristate "Maxim Integrated MAX98927 Speaker Amplifier" + depends on I2C + config SND_SOC_MAX9850 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile old mode 100644 new mode 100755 index 958cd49..1f5fe2c --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -82,6 +82,7 @@ snd-soc-max98371-objs := max98371.o snd-soc-max9867-objs := max9867.o snd-soc-max98925-objs := max98925.o snd-soc-max98926-objs := max98926.o +snd-soc-max98927-objs := max98927.o snd-soc-max9850-objs := max9850.o snd-soc-max9860-objs := max9860.o snd-soc-mc13783-objs := mc13783.o @@ -306,6 +307,7 @@ obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o +obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c new file mode 100755 index 0000000..d85c84f --- /dev/null +++ b/sound/soc/codecs/max98927.c @@ -0,0 +1,954 @@ +/* + * max98927.c -- MAX98927 ALSA Soc Audio driver + * + * Copyright 2013-15 Maxim Integrated Products + * Author: Ryan Lee + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "max98927.h" + +static struct reg_default max98927_reg_map[] = { + {0x0014, 0x78}, + {0x0015, 0xFF}, + {0x0043, 0x04}, + {0x0017, 0x55}, + /* For mono driver we are just enabling one channel*/ + {MAX98927_PCM_Rx_Enables_A, 0x03}, + {MAX98927_PCM_Tx_HiZ_Control_A, 0xfc}, + {MAX98927_PCM_Tx_HiZ_Control_B, 0xff}, + {MAX98927_PCM_Tx_Channel_Sources_A, 0x01}, + {MAX98927_PCM_Tx_Channel_Sources_B, 0x01}, + {MAX98927_Measurement_DSP_Config, 0xf7}, + {0x0025, 0x80}, + {0x0026, 0x01}, + {0x0035, 0x40}, + {0x0036, 0x40}, + {0x0037, 0x02}, + {0x0039, 0x01}, + {0x003c, 0x44}, + {0x003d, 0x04}, + {0x0040, 0x10}, + {0x0042, 0x3f}, + {0x0044, 0x00}, + {0x0045, 0x24}, + {0x007f, 0x06}, + {0x0087, 0x1c}, + {0x0089, 0x03}, + {0x009f, 0x01}, +}; + +void max98927_wrapper_write(struct max98927_priv *max98927, + unsigned int reg, unsigned int val) +{ + if (max98927->regmap) + regmap_write(max98927->regmap, reg, val); + if (max98927->sub_regmap) + regmap_write(max98927->sub_regmap, reg, val); +} + +void max98927_wrap_update_bits(struct max98927_priv *max98927, + unsigned int reg, unsigned int mask, unsigned int val) +{ + if (max98927->regmap) + regmap_update_bits(max98927->regmap, reg, mask, val); + if (max98927->sub_regmap) + regmap_update_bits(max98927->sub_regmap, reg, mask, val); +} + +static int max98927_reg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, unsigned int reg, + unsigned int mask, unsigned int shift) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + int data; + + regmap_read(max98927->regmap, reg, &data); + ucontrol->value.integer.value[0] = + (data & mask) >> shift; + return 0; +} + +static int max98927_reg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, unsigned int reg, + unsigned int mask, unsigned int shift) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + unsigned int sel = ucontrol->value.integer.value[0]; + + max98927_wrap_update_bits(max98927, reg, mask, sel << shift); + dev_dbg(codec->dev, "%s: register 0x%02X, value 0x%02X\n", + __func__, reg, sel); + return 0; +} + +static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + unsigned int invert = 0; + + dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt); + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode, + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask, + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_SLAVE); + break; + case SND_SOC_DAIFMT_CBM_CFM: + max98927->master = true; + max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode, + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask, + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_MASTER); + break; + case SND_SOC_DAIFMT_CBS_CFM: + max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode, + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask, + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_HYBRID); + default: + dev_err(codec->dev, "DAI clock mode unsupported"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + invert = MAX98927_PCM_Mode_Config_PCM_BCLKEDGE; + break; + default: + dev_err(codec->dev, "DAI invert mode unsupported"); + return -EINVAL; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + max98927->iface |= SND_SOC_DAIFMT_I2S; + max98927_wrap_update_bits(max98927, + MAX98927_PCM_Mode_Config, + max98927->iface, max98927->iface); + break; + case SND_SOC_DAIFMT_LEFT_J: + max98927->iface |= SND_SOC_DAIFMT_LEFT_J; + max98927_wrap_update_bits(max98927, + MAX98927_PCM_Mode_Config, + max98927->iface, max98927->iface); + break; + default: + return -EINVAL; + } + + /* pcm channel configuration */ + if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) { + max98927_wrapper_write(max98927, + MAX98927_PCM_Rx_Enables_A, + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH0_EN| + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH1_EN); + max98927_wrapper_write(max98927, + MAX98927_PCM_Tx_Enables_A, + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH0_EN| + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH1_EN); + } + max98927_wrap_update_bits(max98927, MAX98927_PCM_Mode_Config, + MAX98927_PCM_Mode_Config_PCM_BCLKEDGE, invert); + return 0; +} + +/* codec MCLK rate in master mode */ +static const int rate_table[] = { + 5644800, 6000000, 6144000, 6500000, + 9600000, 11289600, 12000000, 12288000, + 13000000, 19200000, +}; + +static int max98927_set_clock(struct max98927_priv *max98927, + struct snd_pcm_hw_params *params) +{ + /* BCLK/LRCLK ratio calculation */ + int blr_clk_ratio = params_channels(params) * max98927->ch_size; + int reg = MAX98927_PCM_Clock_setup; + int mask = MAX98927_PCM_Clock_setup_PCM_BSEL_Mask; + int value; + + if (max98927->master) { + int i; + /* match rate to closest value */ + for (i = 0; i < ARRAY_SIZE(rate_table); i++) { + if (rate_table[i] >= max98927->sysclk) + break; + } + if (i == ARRAY_SIZE(rate_table)) { + pr_err("%s couldn't get the MCLK to match codec\n", + __func__); + return -EINVAL; + } + max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode, + MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_Mask, + i << MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_SHIFT); + } + + switch (blr_clk_ratio) { + case 32: + value = 2; + break; + case 48: + value = 3; + break; + case 64: + value = 4; + break; + default: + return -EINVAL; + } + max98927_wrap_update_bits(max98927, + reg, mask, value); + return 0; +} + +static int max98927_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + int sampling_rate = 0; + + /* pcm mode configuration */ + switch (snd_pcm_format_width(params_format(params))) { + case 16: + max98927_wrap_update_bits(max98927, + MAX98927_PCM_Mode_Config, + MAX98927_PCM_Mode_Config_PCM_CHANSZ_16, + MAX98927_PCM_Mode_Config_PCM_CHANSZ_16); + max98927->ch_size = 16; + break; + case 24: + max98927_wrap_update_bits(max98927, + MAX98927_PCM_Mode_Config, + MAX98927_PCM_Mode_Config_PCM_CHANSZ_24, + MAX98927_PCM_Mode_Config_PCM_CHANSZ_24); + max98927->ch_size = 24; + break; + case 32: + max98927_wrap_update_bits(max98927, + MAX98927_PCM_Mode_Config, + MAX98927_PCM_Mode_Config_PCM_CHANSZ_32, + MAX98927_PCM_Mode_Config_PCM_CHANSZ_32); + max98927->ch_size = 32; + break; + default: + pr_err("%s: format unsupported %d", + __func__, params_format(params)); + goto err; + } + dev_dbg(codec->dev, "%s: format supported %d", + __func__, params_format(params)); + + /* sampling rate configuration */ + switch (params_rate(params)) { + case 8000: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_8000; + break; + case 11025: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_11025; + break; + case 12000: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_12000; + break; + case 16000: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_16000; + break; + case 22050: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_22050; + break; + case 24000: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_24000; + break; + case 32000: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_32000; + break; + case 44100: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_44100; + break; + case 48000: + sampling_rate |= + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_48000; + break; + default: + pr_err("%s rate %d not supported\n", + __func__, params_rate(params)); + goto err; + } + /* set DAI_SR to correct LRCLK frequency */ + max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_1, + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_Mask, sampling_rate); + max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_2, + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_Mask, sampling_rate<<4); + max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_2, + MAX98927_PCM_Sample_rate_setup_2_IVADC_SR_Mask, sampling_rate); + return max98927_set_clock(max98927, params); +err: + return -EINVAL; +} + +#define MAX98927_RATES SNDRV_PCM_RATE_8000_48000 + +#define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static int max98927_dai_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + + max98927->sysclk = freq; + return 0; +} + +static const struct snd_soc_dai_ops max98927_dai_ops = { + .set_sysclk = max98927_dai_set_sysclk, + .set_fmt = max98927_dai_set_fmt, + .hw_params = max98927_dai_hw_params, +}; + +static void max98927_handle_pdata(struct snd_soc_codec *codec) +{ + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + struct max98927_reg_default *regInfo; + int cfg_size = 0; + int x; + + if (max98927->regcfg != NULL) + cfg_size = max98927->regcfg_sz / sizeof(uint32_t); + + if (cfg_size <= 0) { + dev_dbg(codec->dev, + "Register configuration is not required.\n"); + return; + } + + /* direct configuration from device tree */ + for (x = 0; x < cfg_size; x += 3) { + regInfo = (struct max98927_reg_default *)&max98927->regcfg[x]; + dev_info(codec->dev, "CH:%d, reg:0x%02x, value:0x%02x\n", + be32_to_cpu(regInfo->ch), + be32_to_cpu(regInfo->reg), + be32_to_cpu(regInfo->def)); + if (be32_to_cpu(regInfo->ch) == PRI_MAX98927 + && max98927->regmap) + regmap_write(max98927->regmap, + be32_to_cpu(regInfo->reg), + be32_to_cpu(regInfo->def)); + else if (be32_to_cpu(regInfo->ch) == SEC_MAX98927 + && max98927->sub_regmap) + regmap_write(max98927->sub_regmap, + be32_to_cpu(regInfo->reg), + be32_to_cpu(regInfo->def)); + } +} + +static int max98927_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + max98927_wrap_update_bits(max98927, + MAX98927_AMP_enables, 1, 1); + /* enable the v and i for vi feedback */ + max98927_wrap_update_bits(max98927, + MAX98927_Measurement_enables, + MAX98927_Measurement_enables_IVADC_V_EN, + MAX98927_Measurement_enables_IVADC_V_EN); + max98927_wrap_update_bits(max98927, + MAX98927_Measurement_enables, + MAX98927_Measurement_enables_IVADC_I_EN, + MAX98927_Measurement_enables_IVADC_I_EN); + max98927_wrap_update_bits(max98927, + MAX98927_Global_Enable, 1, 1); + break; + case SND_SOC_DAPM_POST_PMD: + max98927_wrap_update_bits(max98927, + MAX98927_Global_Enable, 1, 0); + max98927_wrap_update_bits(max98927, + MAX98927_AMP_enables, 1, 0); + /* disable the v and i for vi feedback */ + max98927_wrap_update_bits(max98927, + MAX98927_Measurement_enables, + MAX98927_Measurement_enables_IVADC_V_EN, + 0); + max98927_wrap_update_bits(max98927, + MAX98927_Measurement_enables, + MAX98927_Measurement_enables_IVADC_I_EN, + 0); + break; + default: + return 0; + } + return 0; +} + +static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_AMP_enables, + 0, 0, max98927_dac_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUTPUT("BE_OUT"), +}; + +static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0); +static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0); + +static int max98927_spk_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = max98927->spk_gain; + dev_dbg(codec->dev, "%s: spk_gain setting returned %d\n", __func__, + (int) ucontrol->value.integer.value[0]); + return 0; +} + +static int max98927_spk_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + unsigned int sel = ucontrol->value.integer.value[0]; + + if (sel < ((1 << MAX98927_Speaker_Gain_Width) - 1)) { + max98927_wrap_update_bits(max98927, MAX98927_Speaker_Gain, + MAX98927_Speaker_Gain_SPK_PCM_GAIN_Mask, sel); + max98927->spk_gain = sel; + } + return 0; +} + +static int max98927_digital_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = max98927->digital_gain; + dev_dbg(codec->dev, "%s: spk_gain setting returned %d\n", __func__, + (int) ucontrol->value.integer.value[0]); + return 0; +} + +static int max98927_digital_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + unsigned int sel = ucontrol->value.integer.value[0]; + + if (sel < ((1 << MAX98927_AMP_VOL_WIDTH) - 1)) { + max98927_wrap_update_bits(max98927, MAX98927_AMP_volume_control, + MAX98927_AMP_volume_control_AMP_VOL_Mask, sel); + max98927->digital_gain = sel; + } + return 0; +} + +static int max98927_boost_voltage_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_get(kcontrol, ucontrol, MAX98927_Boost_Control_0, + MAX98927_Boost_Control_0_BST_VOUT_Mask, 0); +} + +static int max98927_boost_voltage_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_put(kcontrol, ucontrol, MAX98927_Boost_Control_0, + MAX98927_Boost_Control_0_BST_VOUT_Mask, 0); +} + +static int max98927_amp_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_get(kcontrol, ucontrol, MAX98927_Boost_Control_0, + MAX98927_Boost_Control_0_BST_VOUT_Mask, + MAX98927_AMP_VOL_LOCATION_SHIFT); +} + +static int max98927_amp_dsp_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_put(kcontrol, ucontrol, MAX98927_Brownout_enables, + MAX98927_Brownout_enables_AMP_DSP_EN, MAX98927_BDE_DSP_SHIFT); +} + +static int max98927_amp_dsp_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_get(kcontrol, ucontrol, MAX98927_Brownout_enables, + MAX98927_Brownout_enables_AMP_DSP_EN, MAX98927_BDE_DSP_SHIFT); +} + +static int max98927_ramp_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_put(kcontrol, ucontrol, MAX98927_AMP_DSP_Config, + MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS, + MAX98927_SPK_RMP_EN_SHIFT); +} +static int max98927_ramp_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_get(kcontrol, ucontrol, MAX98927_AMP_DSP_Config, + MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS, + MAX98927_SPK_RMP_EN_SHIFT); +} + +static int max98927_dre_en_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_put(kcontrol, ucontrol, MAX98927_DRE_Control, + MAX98927_DRE_Control_DRE_EN, 0); +} +static int max98927_dre_en_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_get(kcontrol, ucontrol, MAX98927_DRE_Control, + MAX98927_DRE_Control_DRE_EN, 0); +} +static int max98927_amp_vol_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_put(kcontrol, ucontrol, + MAX98927_AMP_volume_control, + MAX98927_AMP_volume_control_AMP_VOL_SEL, + MAX98927_AMP_VOL_LOCATION_SHIFT); +} +static int max98927_spk_src_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_get(kcontrol, ucontrol, + MAX98927_Speaker_source_select, + MAX98927_Speaker_source_select_SPK_SOURCE_Mask, 0); +} + +static int max98927_spk_src_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_put(kcontrol, ucontrol, + MAX98927_Speaker_source_select, + MAX98927_Speaker_source_select_SPK_SOURCE_Mask, 0); +} + +static int max98927_mono_out_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_get(kcontrol, ucontrol, + MAX98927_PCM_to_speaker_monomix_A, + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask, + MAX98927_PCM_to_speaker_monomix_A_SHIFT); +} + +static int max98927_mono_out_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return max98927_reg_put(kcontrol, ucontrol, + MAX98927_PCM_to_speaker_monomix_A, + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask, + MAX98927_PCM_to_speaker_monomix_A_SHIFT); +} + +static bool max98927_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0x0001 ... 0x0028: + case 0x002B ... 0x004E: + case 0x0051 ... 0x0055: + case 0x005A ... 0x0061: + case 0x0072 ... 0x0087: + case 0x00FF: + case 0x0100: + case 0x01FF: + return true; + } + return false; +}; + +static const char * const max98927_boost_voltage_text[] = { + "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V", + "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V", + "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V", + "9.5V", "9.625V", "9.75V", "9.875V", "10V" +}; + +static const char * const max98927_speaker_source_text[] = { + "i2s", "reserved", "tone", "pdm" +}; + +static const char * const max98927_monomix_output_text[] = { + "ch_0", "ch_1", "ch_1_2_div" +}; + +static const struct soc_enum max98927_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_monomix_output_text), + max98927_monomix_output_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_speaker_source_text), + max98927_speaker_source_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_boost_voltage_text), + max98927_boost_voltage_text), +}; + +static const struct snd_kcontrol_new max98927_snd_controls[] = { + SOC_SINGLE_EXT_TLV("Speaker Volume", MAX98927_Speaker_Gain, + 0, (1<codec = codec; + codec->control_data = max98927->regmap; + codec->cache_bypass = 1; + + /* Software Reset */ + max98927_wrapper_write(max98927, + MAX98927_Software_Reset, MAX98927_Software_Reset_RST); + + /* Check Revision ID for the primary MAX98927*/ + ret = regmap_read(max98927->regmap, MAX98927_REV_ID, ®); + if (ret < 0) + dev_err(codec->dev, + "Failed to read: 0x%02X\n", MAX98927_REV_ID); + else + dev_info(codec->dev, + "MAX98927 revisionID: 0x%02X\n", reg); + + /* Check Revision ID for the secondary MAX98927*/ + if (max98927->sub_regmap) { + ret = regmap_read(max98927->sub_regmap, MAX98927_REV_ID, ®); + if (ret < 0) + dev_err(codec->dev, + "Failed to read: 0x%02X from secodnary device\n" + , MAX98927_REV_ID); + else + dev_info(codec->dev, + "Secondary device revisionID: 0x%02X\n", reg); + } + + /* Register initialization */ + for (i = 0; i < sizeof(max98927_reg_map)/ + sizeof(max98927_reg_map[0]); i++) + max98927_wrapper_write(max98927, + max98927_reg_map[i].reg, + max98927_reg_map[i].def); + + if (max98927->regmap) + regmap_write(max98927->regmap, + MAX98927_PCM_Tx_Channel_Sources_A, + (max98927->i_l_slot + <v_l_slot)&0xFF); + if (max98927->sub_regmap) + regmap_write(max98927->sub_regmap, + MAX98927_PCM_Tx_Channel_Sources_A, + (max98927->i_r_slot + <v_r_slot)&0xFF); + + /* Set interleave mode */ + if (max98927->interleave_mode) + max98927_wrap_update_bits(max98927, + MAX98927_PCM_Tx_Channel_Sources_B, + MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask, + MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask); + + max98927_handle_pdata(codec); + + return ret; +} + +static const struct snd_soc_codec_driver soc_codec_dev_max98927 = { + .probe = max98927_probe, + .dapm_routes = max98927_audio_map, + .num_dapm_routes = ARRAY_SIZE(max98927_audio_map), + .dapm_widgets = max98927_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets), + .controls = max98927_snd_controls, + .num_controls = ARRAY_SIZE(max98927_snd_controls), +}; + +static const struct regmap_config max98927_regmap = { + .reg_bits = 16, + .val_bits = 8, + .max_register = MAX98927_REV_ID, + .reg_defaults = max98927_reg_map, + .num_reg_defaults = ARRAY_SIZE(max98927_reg_map), + .readable_reg = max98927_readable_register, + .cache_type = REGCACHE_RBTREE, +}; + +static struct i2c_board_info max98927_i2c_sub_board[] = { + { + I2C_BOARD_INFO("max98927_sub", 0x39), + } +}; + +static struct i2c_driver max98927_i2c_sub_driver = { + .driver = { + .name = "max98927_sub", + .owner = THIS_MODULE, + }, +}; + +struct i2c_client *max98927_add_sub_device(int bus_id, int slave_addr) +{ + struct i2c_client *i2c = NULL; + struct i2c_adapter *adapter; + + max98927_i2c_sub_board[0].addr = slave_addr; + + adapter = i2c_get_adapter(bus_id); + if (adapter) { + i2c = i2c_new_device(adapter, max98927_i2c_sub_board); + if (i2c) + i2c->dev.driver = &max98927_i2c_sub_driver.driver; + } + + return i2c; +} + +int probe_common(struct i2c_client *i2c, struct max98927_priv *max98927) +{ + int ret = 0, value; + + if (!of_property_read_u32(i2c->dev.of_node, "vmon-l-slot", &value)) + max98927->v_l_slot = value & 0xF; + else + max98927->v_l_slot = 0; + if (!of_property_read_u32(i2c->dev.of_node, "imon-l-slot", &value)) + max98927->i_l_slot = value & 0xF; + else + max98927->i_l_slot = 1; + if (!of_property_read_u32(i2c->dev.of_node, "vmon-r-slot", &value)) + max98927->v_r_slot = value & 0xF; + else + max98927->v_r_slot = 2; + if (!of_property_read_u32(i2c->dev.of_node, "imon-r-slot", &value)) + max98927->i_r_slot = value & 0xF; + else + max98927->i_r_slot = 3; + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927, + max98927_dai, ARRAY_SIZE(max98927_dai)); + if (ret < 0) + dev_err(&i2c->dev, + "Failed to register codec: %d\n", ret); + return ret; +} + +static int max98927_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + + int ret = 0, value; + struct max98927_priv *max98927 = NULL; + + max98927 = devm_kzalloc(&i2c->dev, + sizeof(*max98927), GFP_KERNEL); + + if (!max98927) { + ret = -ENOMEM; + goto err; + } + i2c_set_clientdata(i2c, max98927); + + /* update interleave mode info */ + if (!of_property_read_u32(i2c->dev.of_node, + "interleave_mode", &value)) { + if (value > 0) + max98927->interleave_mode = 1; + else + max98927->interleave_mode = 0; + } else + max98927->interleave_mode = 0; + + /* update direct configuration info */ + max98927->regcfg = of_get_property(i2c->dev.of_node, + "maxim,regcfg", &max98927->regcfg_sz); + + /* check for secondary MAX98927 */ + ret = of_property_read_u32(i2c->dev.of_node, + "maxim,sub_reg", &max98927->sub_reg); + if (ret) { + dev_err(&i2c->dev, "Sub-device slave address was not found.\n"); + max98927->sub_reg = -1; + } + ret = of_property_read_u32(i2c->dev.of_node, + "maxim,sub_bus", &max98927->sub_bus); + if (ret) { + dev_err(&i2c->dev, "Sub-device bus information was not found.\n"); + max98927->sub_bus = i2c->adapter->nr; + } + + /* regmap initialization for primary device */ + max98927->regmap + = devm_regmap_init_i2c(i2c, &max98927_regmap); + if (IS_ERR(max98927->regmap)) { + ret = PTR_ERR(max98927->regmap); + dev_err(&i2c->dev, + "Failed to allocate regmap: %d\n", ret); + goto err; + } + + /* regmap initialization for secondary device */ + if (max98927->sub_reg > 0) { + max98927->sub_i2c = max98927_add_sub_device(max98927->sub_bus, + max98927->sub_reg); + if (IS_ERR(max98927->sub_i2c)) { + dev_err(&max98927->sub_i2c->dev, + "Second MAX98927 was not found\n"); + ret = PTR_ERR(max98927->regmap); + goto err; + } else { + max98927->sub_regmap = regmap_init_i2c( + max98927->sub_i2c, &max98927_regmap); + if (IS_ERR(max98927->sub_regmap)) { + ret = PTR_ERR(max98927->sub_regmap); + dev_err(&max98927->sub_i2c->dev, + "Failed to allocate sub_regmap: %d\n", + ret); + goto err; + } + } + } + + /* codec registeration */ + ret = probe_common(i2c, max98927); + + return ret; + +err: + if (max98927) + devm_kfree(&i2c->dev, max98927); + return ret; +} + +static int max98927_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + return 0; +} + +static const struct i2c_device_id max98927_i2c_id[] = { + { "max98927", 0}, + { }, +}; + +MODULE_DEVICE_TABLE(i2c, max98927_i2c_id); + +static const struct of_device_id max98927_of_match[] = { + { .compatible = "maxim,max98927", }, + { } +}; +MODULE_DEVICE_TABLE(of, max98927_of_match); + +static struct i2c_driver max98927_i2c_driver = { + .driver = { + .name = "max98927", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(max98927_of_match), + .pm = NULL, + }, + .probe = max98927_i2c_probe, + .remove = max98927_i2c_remove, + .id_table = max98927_i2c_id, +}; + +module_i2c_driver(max98927_i2c_driver) + +MODULE_DESCRIPTION("ALSA SoC MAX98927 driver"); +MODULE_AUTHOR("Ryan Lee "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h new file mode 100755 index 0000000..2305185 --- /dev/null +++ b/sound/soc/codecs/max98927.h @@ -0,0 +1,1253 @@ +/* + * max98927.c -- MAX98927 ALSA Soc Audio driver + * + * Copyright 2008-11 Wolfson Microelectronics PLC. + * Author: Ryan Lee + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#ifndef __MAX98927_REGISTERDEFS_H +#define __MAX98927_REGISTERDEFS_H +#ifdef CONFIG_SND_SOC_MAXIM_DSM +#include +#endif /* CONFIG_SND_SOC_MAXIM_DSM */ + +enum { + PRI_MAX98927 = 0, + SEC_MAX98927 = 1, + MAX_DEV_ID_MAX98927, +} MAX98927deviceID; + +enum { + /*Interrupt Raw 1 (Address 0x0001)*/ + MAX98927_Interrupt_Raw_1 = 0x0001, + MAX98927_Interrupt_Raw_1_BDE_ACTIVE_END_RAW = (0x1 << 0), + MAX98927_Interrupt_Raw_1_BDE_ACTIVE_BGN_RAW = (0x1 << 1), + MAX98927_Interrupt_Raw_1_BDE_LEVEL_CHANGE_RAW = (0x1 << 2), + MAX98927_Interrupt_Raw_1_BDE_L8_RAW = (0x1 << 3), + MAX98927_Interrupt_Raw_1_THERMWARN_END_RAW = (0x1 << 4), + MAX98927_Interrupt_Raw_1_THERMWARN_START_RAW = (0x1 << 5), + MAX98927_Interrupt_Raw_1_THERMSHDN_END_RAW = (0x1 << 6), + MAX98927_Interrupt_Raw_1_THERMSHDN_START_RAW = (0x1 << 7), + + /* Interrupt Raw 2 (Address 0x0002)*/ + MAX98927_Interrupt_Raw_2 = 0x0002, + MAX98927_Interrupt_Raw_2_WATCHDOGWARN_RAW = (0x1 << 0), + MAX98927_Interrupt_Raw_2_WATCHDOGFAIL_RAW = (0x1 << 1), + MAX98927_Interrupt_Raw_2_BOOSTCURRLIM_RAW = (0x1 << 2), + MAX98927_Interrupt_Raw_2_CLKSTOP_RAW = (0x1 << 3), + MAX98927_Interrupt_Raw_2_CLKSTART_RAW = (0x1 << 4), + MAX98927_Interrupt_Raw_2_MEASADC_END_RAW = (0x1 << 5), + MAX98927_Interrupt_Raw_2_PWRDN_DONE_RAW = (0x1 << 6), + MAX98927_Interrupt_Raw_2_PWRUP_DONE_RAW = (0x1 << 7), + + /* Interrupt Raw 3 (Address 0x0003)*/ + MAX98927_Interrupt_Raw_3 = 0x0003, + MAX98927_Interrupt_Raw_3_PWRUP_FAIL_RAW = (0x1 << 0), + MAX98927_Interrupt_Raw_3_AUTH_DONE_RAW = (0x1 << 1), + MAX98927_Interrupt_Raw_3_SPK_OVC_RAW = (0x1 << 2), + MAX98927_Interrupt_Raw_3_BST_UVLO_RAW = (0x1 << 3), + + /* Interrupt State 1 (Address 0x0004)*/ + MAX98927_Interrupt_State_1 = 0x0004, + MAX98927_Interrupt_State_1_BDE_ACTIVE_END_STATE = (0x1 << 0), + MAX98927_Interrupt_State_1_BDE_ACTIVE_BGN_STATE = (0x1 << 1), + MAX98927_Interrupt_State_1_BDE_LEVEL_CHANGE_STATE = (0x1 << 2), + MAX98927_Interrupt_State_1_BDE_L8_STATE = (0x1 << 3), + MAX98927_Interrupt_State_1_THERMWARN_END_STATE = (0x1 << 4), + MAX98927_Interrupt_State_1_THERMWARN_START_STATE = (0x1 << 5), + MAX98927_Interrupt_State_1_THERMSHDN_END_STATE = (0x1 << 6), + MAX98927_Interrupt_State_1_THERMSHDN_START_STATE = (0x1 << 7), + + /* Interrupt State 2 (Address 0x0005)*/ + MAX98927_Interrupt_State_2 = 0x0005, + MAX98927_Interrupt_State_2_WATCHDOGWARN_STATE = (0x1 << 0), + MAX98927_Interrupt_State_2_WATCHDOGFAIL_STATE = (0x1 << 1), + MAX98927_Interrupt_State_2_BOOSTCURRLIM_STATE = (0x1 << 2), + MAX98927_Interrupt_State_2_CLKSTOP_STATE = (0x1 << 3), + MAX98927_Interrupt_State_2_CLKSTART_STATE = (0x1 << 4), + MAX98927_Interrupt_State_2_MEASADC_END_STATE = (0x1 << 5), + MAX98927_Interrupt_State_2_PWRDN_DONE_STATE = (0x1 << 6), + MAX98927_Interrupt_State_2_PWRUP_DONE_STATE = (0x1 << 7), + + /* Interrupt State 3 (Address 0x0006)*/ + MAX98927_Interrupt_State_3 = 0x0006, + MAX98927_Interrupt_State_3_PWRUP_FAIL_STATE = (0x1 << 0), + MAX98927_Interrupt_State_3_AUTH_DONE_STATE = (0x1 << 1), + MAX98927_Interrupt_State_3_SPK_OVC_STATE = (0x1 << 2), + MAX98927_Interrupt_State_3_BST_UVLO_STATE = (0x1 << 3), + + /* Interrupt Flag 1 (Address 0x0007)*/ + MAX98927_Interrupt_Flag_1 = 0x0007, + MAX98927_Interrupt_Flag_1_BDE_ACTIVE_END_FLAG = (0x1 << 0), + MAX98927_Interrupt_Flag_1_BDE_ACTIVE_BGN_FLAG = (0x1 << 1), + MAX98927_Interrupt_Flag_1_BDE_LEVEL_CHANGE_FLAG = (0x1 << 2), + MAX98927_Interrupt_Flag_1_BDE_L8_FLAG = (0x1 << 3), + MAX98927_Interrupt_Flag_1_THERMWARN_END_FLAG = (0x1 << 4), + MAX98927_Interrupt_Flag_1_THERMWARN_START_FLAG = (0x1 << 5), + MAX98927_Interrupt_Flag_1_THERMSHDN_END_FLAG = (0x1 << 6), + MAX98927_Interrupt_Flag_1_THERMSHDN_START_FLAG = (0x1 << 7), + + /* Interrupt Flag 2 (Address 0x0008)*/ + MAX98927_Interrupt_Flag_2 = 0x0008, + MAX98927_Interrupt_Flag_2_WATCHDOGWARN_FLAG = (0x1 << 0), + MAX98927_Interrupt_Flag_2_WATCHDOGFAIL_FLAG = (0x1 << 1), + MAX98927_Interrupt_Flag_2_BOOSTCURRLIM_FLAG = (0x1 << 2), + MAX98927_Interrupt_Flag_2_CLKSTOP_FLAG = (0x1 << 3), + MAX98927_Interrupt_Flag_2_CLKSTART_FLAG = (0x1 << 4), + MAX98927_Interrupt_Flag_2_MEASADC_END_FLAG = (0x1 << 5), + MAX98927_Interrupt_Flag_2_PWRDN_DONE_FLAG = (0x1 << 6), + MAX98927_Interrupt_Flag_2_PWRUP_DONE_FLAG = (0x1 << 7), + + /* Interrupt Flag 3 (Address 0x0009)*/ + MAX98927_Interrupt_Flag_3 = 0x0009, + MAX98927_Interrupt_Flag_3_PWRUP_FAIL_FLAG = (0x1 << 0), + MAX98927_Interrupt_Flag_3_AUTH_DONE_FLAG = (0x1 << 1), + MAX98927_Interrupt_Flag_3_SPK_OVC_FLAG = (0x1 << 2), + MAX98927_Interrupt_Flag_3_BST_UVLO_FLAG = (0x1 << 3), + + /* Interrupt Enable 1 (Address 0x000a)*/ + MAX98927_Interrupt_Enable_1 = 0x000a, + MAX98927_Interrupt_Enable_1_BDE_ACTIVE_END_EN = (0x1 << 0), + MAX98927_Interrupt_Enable_1_BDE_ACTIVE_BGN_EN = (0x1 << 1), + MAX98927_Interrupt_Enable_1_BDE_LEVEL_CHANGE_EN = (0x1 << 2), + MAX98927_Interrupt_Enable_1_BDE_L8_EN = (0x1 << 3), + MAX98927_Interrupt_Enable_1_THERMWARN_END_EN = (0x1 << 4), + MAX98927_Interrupt_Enable_1_THERMWARN_START_EN = (0x1 << 5), + MAX98927_Interrupt_Enable_1_THERMSHDN_END_EN = (0x1 << 6), + MAX98927_Interrupt_Enable_1_THERMSHDN_START_EN = (0x1 << 7), + + /* Interrupt Enable 2 (Address 0x000b)*/ + MAX98927_Interrupt_Enable_2 = 0x000b, + MAX98927_Interrupt_Enable_2_WATCHDOGWARN_EN = (0x1 << 0), + MAX98927_Interrupt_Enable_2_WATCHDOGFAIL_EN = (0x1 << 1), + MAX98927_Interrupt_Enable_2_BOOSTCURRLIM_EN = (0x1 << 2), + MAX98927_Interrupt_Enable_2_CLKSTOP_EN = (0x1 << 3), + MAX98927_Interrupt_Enable_2_CLKSTART_EN = (0x1 << 4), + MAX98927_Interrupt_Enable_2_MEASADC_END_EN = (0x1 << 5), + MAX98927_Interrupt_Enable_2_PWRDN_DONE_EN = (0x1 << 6), + MAX98927_Interrupt_Enable_2_PWRUP_DONE_EN = (0x1 << 7), + + /* Interrupt Enable 3 (Address 0x000c)*/ + MAX98927_Interrupt_Enable_3 = 0x000c, + MAX98927_Interrupt_Enable_3_PWRUP_FAIL_EN = (0x1 << 0), + MAX98927_Interrupt_Enable_3_AUTH_DONE_EN = (0x1 << 1), + MAX98927_Interrupt_Enable_3_SPK_OVC_EN = (0x1 << 2), + MAX98927_Interrupt_Enable_3_BST_UVLO_EN = (0x1 << 3), + + /* Interrupt Flag Clear 1 (Address 0x000d)*/ + MAX98927_Interrupt_Flag_Clear_1 = 0x000d, + MAX98927_Interrupt_Flag_Clear_1_BDE_ACTIVE_END_CLR = (0x1 << 0), + MAX98927_Interrupt_Flag_Clear_1_BDE_ACTIVE_BGN_CLR = (0x1 << 1), + MAX98927_Interrupt_Flag_Clear_1_BDE_LEVEL_CHANGE_CLR = (0x1 << 2), + MAX98927_Interrupt_Flag_Clear_1_BDE_L8_CLR = (0x1 << 3), + MAX98927_Interrupt_Flag_Clear_1_THERMWARN_END_CLR = (0x1 << 4), + MAX98927_Interrupt_Flag_Clear_1_THERMWARN_START_CLR = (0x1 << 5), + MAX98927_Interrupt_Flag_Clear_1_THERMSHDN_END_CLR = (0x1 << 6), + MAX98927_Interrupt_Flag_Clear_1_THERMSHDN_START_CLR = (0x1 << 7), + + /* Interrupt Flag Clear 2 (Address 0x000e)*/ + MAX98927_Interrupt_Flag_Clear_2 = 0x000e, + MAX98927_Interrupt_Flag_Clear_2_WATCHDOGWARN_CLR = (0x1 << 0), + MAX98927_Interrupt_Flag_Clear_2_WATCHDOGFAIL_CLR = (0x1 << 1), + MAX98927_Interrupt_Flag_Clear_2_BOOSTCURRLIM_CLR = (0x1 << 2), + MAX98927_Interrupt_Flag_Clear_2_CLKSTOP_CLR = (0x1 << 3), + MAX98927_Interrupt_Flag_Clear_2_CLKSTART_CLR = (0x1 << 4), + MAX98927_Interrupt_Flag_Clear_2_MEASADC_END_CLR = (0x1 << 5), + MAX98927_Interrupt_Flag_Clear_2_PWRDN_DONE_CLR = (0x1 << 6), + MAX98927_Interrupt_Flag_Clear_2_PWRUP_DONE_CLR = (0x1 << 7), + + /* Interrupt Flag Clear 3 (Address 0x000f)*/ + MAX98927_Interrupt_Flag_Clear_3 = 0x000f, + MAX98927_Interrupt_Flag_Clear_3_PWRUP_FAIL_CLR = (0x1 << 0), + MAX98927_Interrupt_Flag_Clear_3_AUTH_DONE_CLR = (0x1 << 1), + MAX98927_Interrupt_Flag_Clear_3_SPK_OVC_CLR = (0x1 << 2), + MAX98927_Interrupt_Flag_Clear_3_BST_UVLO_CLR = (0x1 << 3), + + /* IRQ Control (Address 0x0010)*/ + MAX98927_IRQ_Control = 0x0010, + MAX98927_IRQ_Control_IRQ_EN = (0x1 << 0), + MAX98927_IRQ_Control_IRQ_POL = (0x1 << 1), + MAX98927_IRQ_Control_IRQ_MODE = (0x1 << 2), + + /* Clock monitor enable (Address 0x0011)*/ + MAX98927_Clock_monitor_enable = 0x0011, + MAX98927_Clock_monitor_enable_CMON_ENA = (0x1 << 0), + MAX98927_Clock_monitor_enable_CMON_AUTORESTART_ENA = (0x1 << 1), + + /* Watchdog Control (Address 0x0012)*/ + MAX98927_Watchdog_Control = 0x0012, + MAX98927_Watchdog_Control_WDT_ENA = (0x1 << 0), + MAX98927_Watchdog_Control_WDT_MODE = (0x1 << 1), + MAX98927_Watchdog_Control_WDT_TO_SEL_Mask = (0x3 << 2), + MAX98927_Watchdog_Control_WDT_TO_SEL_5 = (0x0 << 2), + MAX98927_Watchdog_Control_WDT_TO_SEL_10 = (0x1 << 2), + MAX98927_Watchdog_Control_WDT_TO_SEL_35 = (0x2 << 2), + MAX98927_Watchdog_Control_WDT_TO_SEL_50 = (0x3 << 2), + MAX98927_Watchdog_Control_WDT_HW_SOURCE = (0x1 << 4), + + /* Watchdog SW Reset (Address 0x0013)*/ + MAX98927_Watchdog_SW_Reset = 0x0013, + MAX98927_Watchdog_SW_Reset_WDT_SW_RST_Mask = (0xff << 0), + + /* Meas ADC Thermal Warning Threshhold (Address 0x0014)*/ + MAX98927_Meas_ADC_TW_Threshhold = 0x0014, + MAX98927_Meas_ADC_TW_Threshhold_MEAS_ADC_WARN_THRESH_Mask + = (0xff << 0), + + /* Meas ADC Thermal Shutdown Threshhold (Address 0x0015)*/ + MAX98927_Meas_ADC_TS_Threshhold = 0x0015, + MAX98927_Meas_ADC_TS_Threshhold_MEAS_ADC_SHDN_THRESH_Mask + = (0xff << 0), + + /* Meas ADC Thermal Hysteresis (Address 0x0016)*/ + MAX98927_Meas_ADC_Thermal_Hysteresis = 0x0016, + MAX98927_Meas_ADC_TH_MEAS_ADC_THERM_HYST_Mask = (0x1f << 0), + + /* Pin Config (Address 0x0017)*/ + MAX98927_Pin_Config = 0x0017, + MAX98927_Pin_Config_DOUT_DRV_Mask = (0x3 << 0), + MAX98927_Pin_Config_DOUT_DRV_01 = (0x0 << 0), + MAX98927_Pin_Config_DOUT_DRV_11 = (0x2 << 0), + MAX98927_Pin_Config_BCLK_DRV_Mask = (0x3 << 2), + MAX98927_Pin_Config_BCLK_DRV_01 = (0x0 << 2), + MAX98927_Pin_Config_BCLK_DRV_11 = (0x2 << 2), + MAX98927_Pin_Config_LRCLK_DRV_Mask = (0x3 << 4), + MAX98927_Pin_Config_LRCLK_DRV_01 = (0x0 << 4), + MAX98927_Pin_Config_LRCLK_DRV_11 = (0x2 << 4), + MAX98927_Pin_Config_ICC_DRV_Mask = (0x3 << 6), + MAX98927_Pin_Config_ICC_DRV_01 = (0x0 << 6), + MAX98927_Pin_Config_ICC_DRV_11 = (0x2 << 6), + + /* PCM Rx Enables A (Address 0x0018)*/ + MAX98927_PCM_Rx_Enables_A = 0x0018, + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH0_EN = (0x1 << 0), + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH1_EN = (0x1 << 1), + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH2_EN = (0x1 << 2), + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH3_EN = (0x1 << 3), + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH4_EN = (0x1 << 4), + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH5_EN = (0x1 << 5), + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH6_EN = (0x1 << 6), + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH7_EN = (0x1 << 7), + + /* PCM Rx Enables B (Address 0x0019)*/ + MAX98927_PCM_Rx_Enables_B = 0x0019, + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH8_EN = (0x1 << 0), + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH9_EN = (0x1 << 1), + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH10_EN = (0x1 << 2), + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH11_EN = (0x1 << 3), + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH12_EN = (0x1 << 4), + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH13_EN = (0x1 << 5), + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH14_EN = (0x1 << 6), + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH15_EN = (0x1 << 7), + + /* PCM Tx Enables A (Address 0x001a)*/ + MAX98927_PCM_Tx_Enables_A = 0x001a, + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH0_EN = (0x1 << 0), + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH1_EN = (0x1 << 1), + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH2_EN = (0x1 << 2), + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH3_EN = (0x1 << 3), + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH4_EN = (0x1 << 4), + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH5_EN = (0x1 << 5), + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH6_EN = (0x1 << 6), + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH7_EN = (0x1 << 7), + + /* PCM Tx Enables B (Address 0x001b)*/ + MAX98927_PCM_Tx_Enables_B = 0x001b, + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH8_EN = (0x1 << 0), + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH9_EN = (0x1 << 1), + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH10_EN = (0x1 << 2), + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH11_EN = (0x1 << 3), + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH12_EN = (0x1 << 4), + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH13_EN = (0x1 << 5), + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH14_EN = (0x1 << 6), + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH15_EN = (0x1 << 7), + + /* PCM Tx HiZ Control A (Address 0x001c)*/ + MAX98927_PCM_Tx_HiZ_Control_A = 0x001c, + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH0_HIZ = (0x1 << 0), + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH1_HIZ = (0x1 << 1), + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH2_HIZ = (0x1 << 2), + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH3_HIZ = (0x1 << 3), + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH4_HIZ = (0x1 << 4), + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH5_HIZ = (0x1 << 5), + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH6_HIZ = (0x1 << 6), + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH7_HIZ = (0x1 << 7), + + /* PCM Tx HiZ Control B (Address 0x001d)*/ + MAX98927_PCM_Tx_HiZ_Control_B = 0x001d, + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH8_HIZ = (0x1 << 0), + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH9_HIZ = (0x1 << 1), + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH10_HIZ = (0x1 << 2), + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH11_HIZ = (0x1 << 3), + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH12_HIZ = (0x1 << 4), + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH13_HIZ = (0x1 << 5), + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH14_HIZ = (0x1 << 6), + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH15_HIZ = (0x1 << 7), + + /* PCM Tx Channel Sources A (Address 0x001e)*/ + MAX98927_PCM_Tx_Channel_Sources_A = 0x001e, + MAX98927_PCM_Tx_Channel_Sources_A_PCM_IVADC_V_DEST_Mask = (0xf << 0), + MAX98927_PCM_Tx_Channel_Sources_A_PCM_IVADC_I_DEST_Mask = (0xf << 4), + + /* PCM Tx Channel Sources B (Address 0x001f)*/ + MAX98927_PCM_Tx_Channel_Sources_B = 0x001f, + MAX98927_PCM_Tx_Channel_Sources_B_PCM_AMP_DSP_DEST_Mask = (0xf << 0), + MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask = (0x1 << 5), + + /* PCM Mode Config (Address 0x0020)*/ + MAX98927_PCM_Mode_Config = 0x0020, + MAX98927_PCM_Mode_Config_PCM_TX_EXTRA_HIZ = (0x1 << 0), + MAX98927_PCM_Mode_Config_PCM_CHANSEL = (0x1 << 1), + MAX98927_PCM_Mode_Config_PCM_BCLKEDGE = (0x1 << 2), + MAX98927_PCM_Mode_Config_PCM_FORMAT_Mask = (0x7 << 3), + MAX98927_PCM_Mode_Config_PCM_FORMAT_I2S = (0x0 << 3), + MAX98927_PCM_Mode_Config_PCM_FORMAT_LEFT = (0x1 << 3), + MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_0 = (0x3 << 3), + MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_1 = (0x4 << 3), + MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_2 = (0x5 << 3), + MAX98927_PCM_Mode_Config_PCM_FORMAT_ = (0x6 << 3), + MAX98927_PCM_Mode_Config_PCM_CHANSZ_Mask = (0x3 << 6), + MAX98927_PCM_Mode_Config_PCM_CHANSZ_16 = (0x1 << 6), + MAX98927_PCM_Mode_Config_PCM_CHANSZ_24 = (0x2 << 6), + MAX98927_PCM_Mode_Config_PCM_CHANSZ_32 = (0x3 << 6), + + /* PCM Master Mode (Address 0x0021)*/ + MAX98927_PCM_Master_Mode = 0x0021, + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask = (0x3 << 0), + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_SLAVE = (0x0 << 0), + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_MASTER = (0x3 << 0), + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_HYBRID = (0x1 << 0), + MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_Mask = (0xf << 2), + MAX98927_PCM_Master_Mode_PCM_CLK_SOURCE = (0x1 << 6), + + /* PCM Clock setup (Address 0x0022)*/ + MAX98927_PCM_Clock_setup = 0x0022, + MAX98927_PCM_Clock_setup_PCM_BSEL_Mask = (0xf << 0), + MAX98927_PCM_Clock_setup_PCM_MSEL_Mask = (0xf << 4), + + /* PCM Sample rate setup 1 (Address 0x0023)*/ + MAX98927_PCM_Sample_rate_setup_1 = 0x0023, + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_Mask = (0xf << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_8000 = (0x0 << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_11025 = (0x1 << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_12000 = (0x2 << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_16000 = (0x3 << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_22050 = (0x4 << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_24000 = (0x5 << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_32000 = (0x6 << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_44100 = (0x7 << 0), + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_48000 = (0x8 << 0), + + /* PCM Sample rate setup 1 (Address 0x0024)*/ + MAX98927_PCM_Sample_rate_setup_2 = 0x0024, + MAX98927_PCM_Sample_rate_setup_2_IVADC_SR_Mask = (0xf << 0), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_Mask = (0xf << 4), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0001 = (0x0 << 4), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0011 = (0x2 << 4), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0101 = (0x4 << 4), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0111 = (0x6 << 4), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1001 = (0x8 << 4), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1011 = (0xa << 4), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1101 = (0xc << 4), + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_ = (0xf << 4), + + /* PCM to speaker monomix A (Address 0x0025)*/ + MAX98927_PCM_to_speaker_monomix_A = 0x0025, + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CH0_SOURCE_Mask = (0xf << 0), + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask = (0x3 << 6), + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_1 = (0x0 << 6), + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_3 = (0x0 << 6), + + /* PCM to speaker monomix B (Address 0x0026)*/ + MAX98927_PCM_to_spkmonomix_B = 0x0026, + MAX98927_PCM_to_spkmonomix_B_DMONOMIX_CH1_SOURCE_Mask = (0xf << 0), + + /* ICC RX Enables A (Address 0x0027)*/ + MAX98927_ICC_RX_Enables_A = 0x0027, + MAX98927_ICC_RX_Enables_A_ICC_RX_CH0_EN = (0x1 << 0), + MAX98927_ICC_RX_Enables_A_ICC_RX_CH1_EN = (0x1 << 1), + MAX98927_ICC_RX_Enables_A_ICC_RX_CH2_EN = (0x1 << 2), + MAX98927_ICC_RX_Enables_A_ICC_RX_CH3_EN = (0x1 << 3), + MAX98927_ICC_RX_Enables_A_ICC_RX_CH4_EN = (0x1 << 4), + MAX98927_ICC_RX_Enables_A_ICC_RX_CH5_EN = (0x1 << 5), + MAX98927_ICC_RX_Enables_A_ICC_RX_CH6_EN = (0x1 << 6), + MAX98927_ICC_RX_Enables_A_ICC_RX_CH7_EN = (0x1 << 7), + + /* ICC RX Enables B (Address 0x0028)*/ + MAX98927_ICC_RX_Enables_B = 0x0028, + MAX98927_ICC_RX_Enables_B_ICC_RX_CH8_EN = (0x1 << 0), + MAX98927_ICC_RX_Enables_B_ICC_RX_CH9_EN = (0x1 << 1), + MAX98927_ICC_RX_Enables_B_ICC_RX_CH10_EN = (0x1 << 2), + MAX98927_ICC_RX_Enables_B_ICC_RX_CH11_EN = (0x1 << 3), + MAX98927_ICC_RX_Enables_B_ICC_RX_CH12_EN = (0x1 << 4), + MAX98927_ICC_RX_Enables_B_ICC_RX_CH13_EN = (0x1 << 5), + MAX98927_ICC_RX_Enables_B_ICC_RX_CH14_EN = (0x1 << 6), + MAX98927_ICC_RX_Enables_B_ICC_RX_CH15_EN = (0x1 << 7), + + /* ICC TX Enables A (Address 0x002b)*/ + MAX98927_ICC_TX_Enables_A = 0x002b, + MAX98927_ICC_TX_Enables_A_ICC_TX_CH0_EN = (0x1 << 0), + MAX98927_ICC_TX_Enables_A_ICC_TX_CH1_EN = (0x1 << 1), + MAX98927_ICC_TX_Enables_A_ICC_TX_CH2_EN = (0x1 << 2), + MAX98927_ICC_TX_Enables_A_ICC_TX_CH3_EN = (0x1 << 3), + MAX98927_ICC_TX_Enables_A_ICC_TX_CH4_EN = (0x1 << 4), + MAX98927_ICC_TX_Enables_A_ICC_TX_CH5_EN = (0x1 << 5), + MAX98927_ICC_TX_Enables_A_ICC_TX_CH6_EN = (0x1 << 6), + MAX98927_ICC_TX_Enables_A_ICC_TX_CH7_EN = (0x1 << 7), + + /* ICC TX Enables B (Address 0x002c)*/ + MAX98927_ICC_TX_Enables_B = 0x002c, + MAX98927_ICC_TX_Enables_B_ICC_TX_CH8_EN = (0x1 << 0), + MAX98927_ICC_TX_Enables_B_ICC_TX_CH9_EN = (0x1 << 1), + MAX98927_ICC_TX_Enables_B_ICC_TX_CH10_EN = (0x1 << 2), + MAX98927_ICC_TX_Enables_B_ICC_TX_CH11_EN = (0x1 << 3), + MAX98927_ICC_TX_Enables_B_ICC_TX_CH12_EN = (0x1 << 4), + MAX98927_ICC_TX_Enables_B_ICC_TX_CH13_EN = (0x1 << 5), + MAX98927_ICC_TX_Enables_B_ICC_TX_CH14_EN = (0x1 << 6), + MAX98927_ICC_TX_Enables_B_ICC_TX_CH15_EN = (0x1 << 7), + + /* ICC Data Order Select (Address 0x002d)*/ + MAX98927_ICC_Data_Order_Select = 0x002d, + MAX98927_ICC_Data_Order_Select_ICC_DRIVE_MODE = (0x1 << 3), + + /* ICC HiZ Manual Mode (Address 0x002e)*/ + MAX98927_ICC_HiZ_Manual_Mode = 0x002e, + MAX98927_ICC_HiZ_Manual_Mode_ICC_TX_HIZ_MANUAL = (0x1 << 0), + MAX98927_ICC_HiZ_Manual_Mode_ICC_TX_EXTRA_HIZ = (0x1 << 1), + + /* ICC TX HiZ Enables A (Address 0x002f)*/ + MAX98927_ICC_TX_HiZ_Enables_A = 0x002f, + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH0_HIZ = (0x1 << 0), + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH1_HIZ = (0x1 << 1), + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH2_HIZ = (0x1 << 2), + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH3_HIZ = (0x1 << 3), + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH4_HIZ = (0x1 << 4), + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH5_HIZ = (0x1 << 5), + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH6_HIZ = (0x1 << 6), + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH7_HIZ = (0x1 << 7), + + /* ICC TX HiZ Enables B (Address 0x0030)*/ + MAX98927_ICC_TX_HiZ_Enables_B = 0x0030, + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH8_HIZ = (0x1 << 0), + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH9_HIZ = (0x1 << 1), + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH10_HIZ = (0x1 << 2), + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH11_HIZ = (0x1 << 3), + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH12_HIZ = (0x1 << 4), + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH13_HIZ = (0x1 << 5), + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH14_HIZ = (0x1 << 6), + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH15_HIZ = (0x1 << 7), + + /* ICC Link Enables (Address 0x0031)*/ + MAX98927_ICC_Link_Enables = 0x0031, + MAX98927_ICC_Link_Enables_ICC_LINK_EN = (0x1 << 1), + + /* PDM Tx Enables (Address 0x0032)*/ + MAX98927_PDM_Tx_Enables = 0x0032, + MAX98927_PDM_Tx_Enables_PDM_TX_EN = (0x1 << 0), + MAX98927_PDM_Tx_Enables_PDM_TX_CLK_DIV2 = (0x1 << 1), + + /* PDM Tx HiZ Control (Address 0x0033)*/ + MAX98927_PDM_Tx_HiZ_Control = 0x0033, + MAX98927_PDM_Tx_HiZ_Control_PDM_TX_HIZ = (0x1 << 0), + + /* PDM Tx Control (Address 0x0034)*/ + MAX98927_PDM_Tx_Control = 0x0034, + MAX98927_PDM_Tx_Control_PDM_TX_CH0_SOURCE = (0x1 << 0), + MAX98927_PDM_Tx_Control_PDM_TX_CH1_SOURCE = (0x1 << 1), + + /* PDM Rx Enable (Address 0x0034)*/ + MAX98927_PDM_Rx_Enable = 0x0035, + MAX98927_PDM_Rx_Enable_PDM_RX_EN = (0x1 << 0), + MAX98927_PDM_Rx_Enable_PDM_DSP_EN = (0x1 << 1), + MAX98927_PDM_Rx_Enable_PDM_DITH_EN = (0x1 << 2), + MAX98927_PDM_Rx_Enable_PDM_RX_CH_SEL = (0x1 << 3), + MAX98927_PDM_Rx_Enable_PDM_FIFO_RDY_LVL_Mask = (0xf << 4), + + /* AMP volume control (Address 0x0036)*/ + MAX98927_AMP_volume_control = 0x0036, + MAX98927_AMP_volume_control_AMP_VOL_Mask = (0x7f << 0), + MAX98927_AMP_volume_control_AMP_VOL_SEL = (0x1 << 7), + + /* AMP DSP Config (Address 0x0037)*/ + MAX98927_AMP_DSP_Config = 0x0037, + MAX98927_AMP_DSP_Config_AMP_DCBLK_EN = (0x1 << 0), + MAX98927_AMP_DSP_Config_AMP_DITH_EN = (0x1 << 1), + MAX98927_AMP_DSP_Config_DAC_HALF_REF_CURRENT = (0x1 << 2), + MAX98927_AMP_DSP_Config_DAC_DOUBLE_RFB = (0x1 << 3), + MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS = (0x1 << 4), + MAX98927_AMP_DSP_Config_DAC_INVERT = (0x1 << 5), + + /* Tone Generator and DC Config (Address 0x0038)*/ + MAX98927_Tone_Generator_and_DC_Config = 0x0038, + MAX98927_Tone_Generator_and_DC_Config_TONE_CONFIG_Mask = (0xf << 0), + + /* DRE Control (Address 0x0039)*/ + MAX98927_DRE_Control = 0x0039, + MAX98927_DRE_Control_DRE_EN = (0x1 << 0), + + /* AMP enables (Address 0x003a)*/ + MAX98927_AMP_enables = 0x003a, + MAX98927_AMP_enables_SPK_EN = (0x1 << 0), + + /* Speaker source select (Address 0x003b)*/ + MAX98927_Speaker_source_select = 0x003b, + MAX98927_Speaker_source_select_SPK_SOURCE_Mask = (0x3 << 0), + MAX98927_Speaker_source_select_SPK_SOURCE_01 = (0x0 << 0), + MAX98927_Speaker_source_select_SPK_SOURCE_11 = (0x2 << 0), + + /* Speaker Gain (Address 0x003c)*/ + MAX98927_Speaker_Gain = 0x003c, + MAX98927_Speaker_Gain_SPK_PCM_GAIN_Mask = (0x7 << 0), + MAX98927_Speaker_Gain_SPK_PCM_GAIN_001 = (0x0 << 0), + MAX98927_Speaker_Gain_SPK_PCM_GAIN_011 = (0x2 << 0), + MAX98927_Speaker_Gain_SPK_PCM_GAIN_101 = (0x4 << 0), + MAX98927_Speaker_Gain_SPK_PCM_GAIN_111 = (0x6 << 0), + MAX98927_Speaker_Gain_SPK_PDM_GAIN_Mask = (0x7 << 4), + MAX98927_Speaker_Gain_SPK_PDM_GAIN_001 = (0x0 << 4), + MAX98927_Speaker_Gain_SPK_PDM_GAIN_011 = (0x2 << 4), + MAX98927_Speaker_Gain_SPK_PDM_GAIN_101 = (0x4 << 4), + MAX98927_Speaker_Gain_SPK_PDM_GAIN_111 = (0x6 << 4), + + /* SSM Configuration (Address 0x003d)*/ + MAX98927_SSM_Configuration = 0x003d, + MAX98927_SSM_Configuration_SSM_MOD_INDEX_Mask = (0x7 << 0), + MAX98927_SSM_Configuration_SSM_MOD_INDEX_001 = (0x0 << 0), + MAX98927_SSM_Configuration_SSM_MOD_INDEX_011 = (0x2 << 0), + MAX98927_SSM_Configuration_SSM_MOD_INDEX_101 = (0x4 << 0), + MAX98927_SSM_Configuration_SSM_MOD_INDEX_ = (0x6 << 0), + MAX98927_SSM_Configuration_SPK_FSW_SEL = (0x1 << 3), + MAX98927_SSM_Configuration_SSM_ENA = (0x1 << 7), + + /* Measurement enables (Address 0x003e)*/ + MAX98927_Measurement_enables = 0x003e, + MAX98927_Measurement_enables_IVADC_V_EN = (0x1 << 0), + MAX98927_Measurement_enables_IVADC_I_EN = (0x1 << 1), + + /* Measurement DSP Config (Address 0x003f)*/ + MAX98927_Measurement_DSP_Config = 0x003f, + MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_EN = (0x1 << 0), + MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_EN = (0x1 << 1), + MAX98927_Measurement_DSP_Config_MEAS_DITH_EN = (0x1 << 2), + MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_Mask = (0x3 << 4), + MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_01 = (0x0 << 4), + MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_11 = (0x2 << 4), + MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_Mask = (0x3 << 6), + MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_01 = (0x0 << 6), + MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_11 = (0x2 << 6), + + /* Boost Control 0 (Address 0x0040)*/ + MAX98927_Boost_Control_0 = 0x0040, + MAX98927_Boost_Control_0_BST_VOUT_Mask = (0x1f << 0), + MAX98927_Boost_Control_0_EXT_PVDD_EN = (0x1 << 7), + + /* Boost Control 3 (Address 0x0041)*/ + MAX98927_Boost_Control_3 = 0x0041, + MAX98927_Boost_Control_3_BST_SKIPLOAD_Mask = (0x3 << 0), + MAX98927_Boost_Control_3_BST_SKIPLOAD_01 = (0x0 << 0), + MAX98927_Boost_Control_3_BST_SKIPLOAD_11 = (0x2 << 0), + MAX98927_Boost_Control_3_BST_PHASE_Mask = (0x7 << 2), + MAX98927_Boost_Control_3_BST_PHASE_001 = (0x0 << 2), + MAX98927_Boost_Control_3_BST_PHASE_011 = (0x2 << 2), + MAX98927_Boost_Control_3_BST_PHASE_ = (0x1 << 2), + MAX98927_Boost_Control_3_BST_SLOWSTART = (0x1 << 5), + + /* Boost Control 1 (Address 0x0042)*/ + MAX98927_Boost_Control_1 = 0x0042, + /*#BYHAND width >= 5:*/ + MAX98927_Boost_Control_1_BST_ILIM_Mask = (0x3f << 0), + + /* Meas ADC Config (Address 0x0043)*/ + MAX98927_Meas_ADC_Config = 0x0043, + MAX98927_Meas_ADC_Config_MEAS_ADC_CH0_EN = (0x1 << 0), + MAX98927_Meas_ADC_Config_MEAS_ADC_CH1_EN = (0x1 << 1), + MAX98927_Meas_ADC_Config_MEAS_ADC_CH2_EN = (0x1 << 2), + + /* Meas ADC Base Divide MSByte (Address 0x0044)*/ + MAX98927_Meas_ADC_Base_Divide_MSByte = 0x0044, + /*#BYHAND width >= 5:*/ + MAX98927_Meas_ADC_Base_Divide_MSByte_MEAS_ADC_BASE_DIV_Mask + = (0xff << 0), + + /* Meas ADC Base Divide LSByte (Address 0x0045)*/ + MAX98927_Meas_ADC_Base_Divide_LSByte = 0x0045, + /*#BYHAND width >= 5:*/ + MAX98927_Meas_ADC_Base_Divide_LSByte_MEAS_ADC_BASE_DIV_Mask + = (0xff << 0), + + /* Meas ADC Chan 0 Divide (Address 0x0046)*/ + MAX98927_Meas_ADC_Chan_0_Divide = 0x0046, + /*#BYHAND width >= 5:*/ + MAX98927_Meas_ADC_Chan_0_Divide_MEAS_ADC_CH0_DIV_Mask = (0xff << 0), + + /* Meas ADC Chan 1 Divide (Address 0x0047)*/ + MAX98927_Meas_ADC_Chan_1_Divide = 0x0047, + /*#BYHAND width >= 5:*/ + MAX98927_Meas_ADC_Chan_1_Divide_MEAS_ADC_CH1_DIV_Mask = (0xff << 0), + + /* Meas ADC Chan 2 Divide (Address 0x0048)*/ + MAX98927_Meas_ADC_Chan_2_Divide = 0x0048, + /*#BYHAND width >= 5:*/ + MAX98927_Meas_ADC_Chan_2_Divide_MEAS_ADC_CH2_DIV_Mask = (0xff << 0), + + /* Meas ADC Chan 0 Filt Config (Address 0x0049)*/ + MAX98927_Meas_ADC_Chan_0_Filt_Config = 0x0049, + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_Mask + = (0x7 << 0), + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_001 + = (0x0 << 0), + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_011 + = (0x2 << 0), + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_101 + = (0x4 << 0), + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_EN + = (0x1 << 3), + + /* Meas ADC Chan 1 Filt Config (Address 0x004a)*/ + MAX98927_Meas_ADC_Chan_1_Filt_Config = 0x004a, + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_Mask + = (0x7 << 0), + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_001 + = (0x0 << 0), + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_011 + = (0x2 << 0), + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_101 + = (0x4 << 0), + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_EN + = (0x1 << 3), + + /* Meas ADC Chan 2 Filt Config (Address 0x004b)*/ + MAX98927_Meas_ADC_Chan_2_Filt_Config = 0x004b, + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_Mask + = (0x7 << 0), + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_001 + = (0x0 << 0), + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_011 + = (0x2 << 0), + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_101 + = (0x4 << 0), + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_EN + = (0x1 << 3), + + /* Meas ADC Chan 0 Readback (Address 0x004c)*/ + MAX98927_Meas_ADC_Chan_0_Readback = 0x004c, + /*#BYHAND width >= 5:*/ + MAX98927_Meas_ADC_Chan_0_Readback_MEAS_ADC_CH0_DATA_Mask + = (0xff << 0), + + /* Meas ADC Chan 1 Readback (Address 0x004d)*/ + MAX98927_Meas_ADC_Chan_1_Readback = 0x004d, + /*#BYHAND width >= 5:*/ + MAX98927_Meas_ADC_Chan_1_Readback_MEAS_ADC_CH1_DATA_Mask + = (0xff << 0), + + /* Meas ADC Chan 2 Readback (Address 0x004e)*/ + MAX98927_Meas_ADC_Chan_2_Readback = 0x004e, + /*#BYHAND width >= 5:*/ + MAX98927_Meas_ADC_Chan_2_Readback_MEAS_ADC_CH2_DATA_Mask + = (0xff << 0), + + /* Brownout status (Address 0x0051)*/ + MAX98927_Brownout_status = 0x0051, + MAX98927_Brownout_status_BDE_STATE_Mask = (0xf << 0), + + /* Brownout enables (Address 0x0052)*/ + MAX98927_Brownout_enables = 0x0052, + MAX98927_Brownout_enables_BDE_EN = (0x1 << 0), + MAX98927_Brownout_enables_BDE_AMP_EN = (0x1 << 1), + MAX98927_Brownout_enables_AMP_DSP_EN = (0x1 << 2), + + /* Brownout level infinite hold (Address 0x0053)*/ + MAX98927_Brownout_level_infinite_hold = 0x0053, + MAX98927_Brownout_level_infinite_hold_BDE_L8_INF_HLD = (0x1 << 1), + + /* Brownout level infinite hold clear (Address 0x0054)*/ + MAX98927_Brownout_level_infinite_hold_clear = 0x0054, + MAX98927_Brownout_level_infinite_hold_clear_BDE_L8_HLD_RLS + = (0x1 << 1), + + /* Brownout level hold (Address 0x0055)*/ + MAX98927_Brownout_level_hold = 0x0055, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout_level_hold_BDE_HLD_Mask = (0xff << 0), + + /* Brownout level 1 threshold (Address 0x0056)*/ + MAX98927_Brownout__level_1_threshold = 0x0056, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_1_threshold_BDE_L1_VTHRESH_Mask = (0xff << 0), + + /* Brownout level 2 threshold (Address 0x0057)*/ + MAX98927_Brownout__level_2_threshold = 0x0057, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_2_threshold_BDE_L2_VTHRESH_Mask = (0xff << 0), + + /* Brownout level 3 threshold (Address 0x0058)*/ + MAX98927_Brownout__level_3_threshold = 0x0058, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_3_threshold_BDE_L3_VTHRESH_Mask = (0xff << 0), + + /* Brownout level 4 threshold (Address 0x0059)*/ + MAX98927_Brownout__level_4_threshold = 0x0059, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_4_threshold_BDE_L4_VTHRESH_Mask = (0xff << 0), + + /* Brownout level 5 threshold (Address 0x005a)*/ + MAX98927_Brownout__level_5_threshold = 0x005a, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_5_threshold_BDE_L5_VTHRESH_Mask = (0xff << 0), + + /* Brownout level 6 threshold (Address 0x005b)*/ + MAX98927_Brownout__level_6_threshold = 0x005b, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_6_threshold_BDE_L6_VTHRESH_Mask = (0xff << 0), + + /* Brownout level 7 threshold (Address 0x005c)*/ + MAX98927_Brownout__level_7_threshold = 0x005c, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_7_threshold_BDE_L7_VTHRESH_Mask = (0xff << 0), + + /* Brownout level 8 threshold (Address 0x005d)*/ + MAX98927_Brownout__level_8_threshold = 0x005d, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_8_threshold_BDE_L8_VTHRESH_Mask = (0xff << 0), + + /* Brownout threshold hysterysis (Address 0x005e)*/ + MAX98927_Brownout_threshold_hysterysis = 0x005e, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout_threshold_hysterysis_BDE_VTHRESH_HYST_Mask + = (0xff << 0), + /* Brownout AMP limiter attack/release (Address 0x005f)*/ + MAX98927_Brownout_AMP_limiter_attack_release = 0x005f, + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_Mask + = (0xf << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0001 + = (0x0 << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0011 + = (0x2 << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0101 + = (0x4 << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0111 + = (0x6 << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1001 + = (0x8 << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1011 + = (0xa << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1101 + = (0xc << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1111 + = (0xe << 0), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_Mask + = (0xf << 4), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0001 + = (0x0 << 4), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0011 + = (0x2 << 4), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0101 + = (0x4 << 4), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0111 + = (0x6 << 4), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1001 + = (0x8 << 4), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1011 + = (0xa << 4), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1101 + = (0xc << 4), + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1111 + = (0xe << 4), + + /* Brownout AMP gain attack/release (Address 0x0060)*/ + MAX98927_Brownout_AMP_gain_attack_release = 0x0060, + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_Mask + = (0xf << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0001 + = (0x0 << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0011 + = (0x2 << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0101 + = (0x4 << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0111 + = (0x6 << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1001 + = (0x8 << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1011 + = (0xa << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1101 + = (0xc << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1111 + = (0xe << 0), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_Mask + = (0xf << 4), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0001 + = (0x0 << 4), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0011 + = (0x2 << 4), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0101 + = (0x4 << 4), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0111 + = (0x6 << 4), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1001 + = (0x8 << 4), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1011 + = (0xa << 4), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1101 + = (0xc << 4), + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1111 + = (0xe << 4), + + /* Brownout AMP1 clip mode (Address 0x0061)*/ + MAX98927_Brownout_AMP1_clip_mode = 0x0061, + MAX98927_Brownout_AMP1_clip_mode_AMP_CLIP_MODE = (0x1 << 0), + + /* Brownout level 1 current limit (Address 0x0062)*/ + MAX98927_Brownout__level_1_current_limit = 0x0062, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_1_current_limit_BDE_L1_ILIM_Mask + = (0x3f << 0), + + /* Brownout level 1 amp 1 control 1 (Address 0x0063)*/ + MAX98927_Brownout__level_1_amp_1_control_1 = 0x0063, + MAX98927_Brownout__level_1_amp_1_control_1_BDE_L1_AMP1_LIM_Mask + = (0xf << 0), + + /* Brownout level 1 amp 1 control 2 (Address 0x0064)*/ + MAX98927_Brownout__level_1_amp_1_control_2 = 0x0064, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_1_amp_1_control_2_BDE_L1_AMP1_CLIP_Mask + = (0x3f << 0), + + /* Brownout level 1 amp 1 control 3 (Address 0x0065)*/ + MAX98927_Brownout__level_1_amp_1_control_3 = 0x0065, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_1_amp_1_control_3_BDE_L1_AMP1_GAIN_Mask + = (0x3f << 0), + + /* Brownout level 2 current limit (Address 0x0066)*/ + MAX98927_Brownout__level_2_current_limit = 0x0066, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_2_current_limit_BDE_L2_ILIM_Mask = (0x3f << 0), + + /* Brownout level 2 amp 1 control 1 (Address 0x0067)*/ + MAX98927_Brownout__level_2_amp_1_control_1 = 0x0067, + MAX98927_Brownout__level_2_amp_1_control_1_BDE_L2_AMP1_LIM_Mask + = (0xf << 0), + + /* Brownout level 2 amp 1 control 2 (Address 0x0068)*/ + MAX98927_Brownout__level_2_amp_1_control_2 = 0x0068, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_2_amp_1_control_2_BDE_L2_AMP1_CLIP_Mask + = (0x3f << 0), + + /* Brownout level 2 amp 1 control 3 (Address 0x0069)*/ + MAX98927_Brownout__level_2_amp_1_control_3 = 0x0069, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_2_amp_1_control_3_BDE_L2_AMP1_GAIN_Mask + = (0x3f << 0), + + /* Brownout level 3 current limit (Address 0x006a)*/ + MAX98927_Brownout__level_3_current_limit = 0x006a, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_3_current_limit_BDE_L3_ILIM_Mask = (0x3f << 0), + + /* Brownout level 3 amp 1 control 1 (Address 0x006b)*/ + MAX98927_Brownout__level_3_amp_1_control_1 = 0x006b, + MAX98927_Brownout__level_3_amp_1_control_1_BDE_L3_AMP1_LIM_Mask + = (0xf << 0), + + /* Brownout level 3 amp 1 control 2 (Address 0x006c)*/ + MAX98927_Brownout__level_3_amp_1_control_2 = 0x006c, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_3_amp_1_control_2_BDE_L3_AMP1_CLIP_Mask + = (0x3f << 0), + + /* Brownout level 3 amp 1 control 3 (Address 0x006d)*/ + MAX98927_Brownout__level_3_amp_1_control_3 = 0x006d, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_3_amp_1_control_3_BDE_L3_AMP1_GAIN_Mask + = (0x3f << 0), + + /* Brownout level 4 current limit (Address 0x006e)*/ + MAX98927_Brownout__level_4_current_limit = 0x006e, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_4_current_limit_BDE_L4_ILIM_Mask = (0x3f << 0), + + /* Brownout level 4 amp 1 control 1 (Address 0x006f)*/ + MAX98927_Brownout__level_4_amp_1_control_1 = 0x006f, + MAX98927_Brownout__level_4_amp_1_control_1_BDE_L4_AMP1_LIM_Mask + = (0xf << 0), + + /* Brownout level 4 amp 1 control 2 (Address 0x0070)*/ + MAX98927_Brownout__level_4_amp_1_control_2 = 0x0070, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_4_amp_1_control_2_BDE_L4_AMP1_CLIP_Mask + = (0x3f << 0), + + /* Brownout level 4 amp 1 control 3 (Address 0x0071)*/ + MAX98927_Brownout__level_4_amp_1_control_3 = 0x0071, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_4_amp_1_control_3_BDE_L4_AMP1_GAIN_Mask + = (0x3f << 0), + + /* Brownout level 5 current limit (Address 0x0072)*/ + MAX98927_Brownout__level_5_current_limit = 0x0072, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_5_current_limit_BDE_L5_ILIM_Mask = (0x3f << 0), + + /* Brownout level 5 amp 1 control 1 (Address 0x0073)*/ + MAX98927_Brownout__level_5_amp_1_control_1 = 0x0073, + MAX98927_Brownout__level_5_amp_1_control_1_BDE_L5_AMP1_LIM_Mask + = (0xf << 0), + + /* Brownout level 5 amp 1 control 2 (Address 0x0074)*/ + MAX98927_Brownout__level_5_amp_1_control_2 = 0x0074, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_5_amp_1_control_2_BDE_L5_AMP1_CLIP_Mask + = (0x3f << 0), + + /* Brownout level 5 amp 1 control 3 (Address 0x0075)*/ + MAX98927_Brownout__level_5_amp_1_control_3 = 0x0075, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_5_amp_1_control_3_BDE_L5_AMP1_GAIN_Mask + = (0x3f << 0), + + /* Brownout level 6 current limit (Address 0x0076)*/ + MAX98927_Brownout__level_6_current_limit = 0x0076, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_6_current_limit_BDE_L6_ILIM_Mask = (0x3f << 0), + + /* Brownout level 6 amp 1 control 1 (Address 0x0077)*/ + MAX98927_Brownout__level_6_amp_1_control_1 = 0x0077, + MAX98927_Brownout__level_6_amp_1_control_1_BDE_L6_AMP1_LIM_Mask + = (0xf << 0), + + /* Brownout level 6 amp 1 control 2 (Address 0x0078)*/ + MAX98927_Brownout__level_6_amp_1_control_2 = 0x0078, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_6_amp_1_control_2_BDE_L6_AMP1_CLIP_Mask + = (0x3f << 0), + + /* Brownout level 6 amp 1 control 3 (Address 0x0079)*/ + MAX98927_Brownout__level_6_amp_1_control_3 = 0x0079, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_6_amp_1_control_3_BDE_L6_AMP1_GAIN_Mask + = (0x3f << 0), + + /* Brownout level 7 current limit (Address 0x007a)*/ + MAX98927_Brownout__level_7_current_limit = 0x007a, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_7_current_limit_BDE_L7_ILIM_Mask = (0x3f << 0), + + /* Brownout level 7 amp 1 control 1 (Address 0x007b)*/ + MAX98927_Brownout__level_7_amp_1_control_1 = 0x007b, + MAX98927_Brownout__level_7_amp_1_control_1_BDE_L7_AMP1_LIM_Mask + = (0xf << 0), + + /* Brownout level 7 amp 1 control 2 (Address 0x007c)*/ + MAX98927_Brownout__level_7_amp_1_control_2 = 0x007c, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_7_amp_1_control_2_BDE_L7_AMP1_CLIP_Mask + = (0x3f << 0), + + /* Brownout level 7 amp 1 control 3 (Address 0x007d)*/ + MAX98927_Brownout__level_7_amp_1_control_3 = 0x007d, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_7_amp_1_control_3_BDE_L7_AMP1_GAIN_Mask + = (0x3f << 0), + + /* Brownout level 8 current limit (Address 0x007e)*/ + MAX98927_Brownout__level_8_current_limit = 0x007e, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_8_current_limit_BDE_L8_ILIM_Mask = (0x3f << 0), + + /* Brownout level 8 amp 1 control 1 (Address 0x007f)*/ + MAX98927_Brownout__level_8_amp_1_control_1 = 0x007f, + MAX98927_Brownout__level_8_amp_1_control_1_BDE_L8_AMP1_LIM_Mask + = (0xf << 0), + + /* Brownout level 8 amp 1 control 2 (Address 0x0080)*/ + MAX98927_Brownout__lvl_8_amp_1_control_2 = 0x0080, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__lvl_8_amp_1_control_2_BDE_L8_AMP1_CLIP_Mask + = (0x3f << 0), + MAX98927_Brownout__lvl_8_amp_1_control_2_BDE_L8_AMP1_MUTE + = (0x1 << 7), + + /* Brownout level 8 amp 1 control 3 (Address 0x0081)*/ + MAX98927_Brownout__level_8_amp_1_control_3 = 0x0081, + /*#BYHAND width >= 5:*/ + MAX98927_Brownout__level_8_amp_1_control_3_BDE_L8_AMP1_GAIN_Mask + = (0x3f << 0), + + /* Env Tracker Vout Headroom (Address 0x0082)*/ + MAX98927_Env_Tracker_Vout_Headroom = 0x0082, + /*#BYHAND width >= 5:*/ + MAX98927_Env_Tracker_Vout_Head_ENV_TRACKER_BST_VOUT_HEADROOM_Mask + = (0x1f << 0), + + /* Env Tracker Boost Vout Delay (Address 0x0083)*/ + MAX98927_Env_Tracker_Boost_Vout_Delay = 0x0083, + /*#BYHAND width >= 5:*/ + MAX98927_Env_Tracker_Boost_V_Delay_ENV_TRACKER_BST_VOUT_DELAY_Mask + = (0x1f << 0), + MAX98927_Env_Tracker_Boost_Vout_Delay_ENV_TRACKER_BDE_MODE + = (0x1 << 7), + + /* Env Tracker Release Rate (Address 0x0084)*/ + MAX98927_Env_Tracker_Release_Rate = 0x0084, + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_Mask + = (0x7 << 0), + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_001 + = (0x0 << 0), + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_011 + = (0x2 << 0), + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_101 + = (0x4 << 0), + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_111 + = (0x6 << 0), + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_PEAK_DET_LPF_BYP_EN + = (0x1 << 3), + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_Mask + = (0x3 << 4), + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_01 + = (0x0 << 4), + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_11 + = (0x2 << 4), + + /* Env Tracker Hold Rate (Address 0x0085)*/ + MAX98927_Env_Tracker_Hold_Rate = 0x0085, + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_Mask + = (0x7 << 0), + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_001 + = (0x0 << 0), + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_011 + = (0x2 << 0), + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_101 + = (0x4 << 0), + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_111 + = (0x6 << 0), + + /* Env Tracker Control (Address 0x0086)*/ + MAX98927_Env_Tracker_Control = 0x0086, + MAX98927_Env_Tracker_Control_ENV_TRACKER_EN = (0x1 << 0), + + /* Env Tracker Boost Vout ReadBack (Address 0x0087)*/ + MAX98927_Env_Tracker__Boost_Vout_ReadBack = 0x0087, + /*#BYHAND width >= 5:*/ + MAX98927_Env_Tracker__Boost_Vout_RB_ENV_TRACKER_BST_VOUT_RD_Mask + = (0x1f << 0), + + /* Advanced Settings (Address 0x0089)*/ + MAX98927_Advanced_Settings = 0x0089, + MAX98927_Advanced_Settings_DAC_HALF_FIR = (0x1 << 0), + MAX98927_Advanced_Settings_PDM_MOD_SEL = (0x1 << 1), + MAX98927_Advanced_Settings_ISOCH_EN = (0x1 << 2), + + /* DAC Test 1 (Address 0x009f)*/ + MAX98927_DAC_Test_1 = 0x009f, + MAX98927_DAC_Test_1_DAC_PCM_TIMING = (0x1 << 0), + MAX98927_DAC_Test_1_DAC_HALFI_AMP = (0x1 << 1), + MAX98927_DAC_Test_1_DAC_LONG_HOLD = (0x1 << 3), + MAX98927_DAC_Test_1_DAC_DISABLE_CHOP = (0x1 << 4), + MAX98927_DAC_Test_1_DAC_TM = (0x1 << 5), + MAX98927_DAC_Test_1_DAC_INVERT_DACCLK = (0x1 << 6), + + /* Authentication key 0 (Address 0x00ea)*/ + MAX98927_Authentication_key_0 = 0x00ea, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_key_0_AUTH_KEY_Mask = (0xff << 0), + + /* Authentication key 1 (Address 0x00eb)*/ + MAX98927_Authentication_key_1 = 0x00eb, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_key_1_AUTH_KEY_Mask = (0xff << 0), + + /* Authentication key 2 (Address 0x00ec)*/ + MAX98927_Authentication_key_2 = 0x00ec, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_key_2_AUTH_KEY_Mask = (0xff << 0), + + /* Authentication key 3 (Address 0x00ed)*/ + MAX98927_Authentication_key_3 = 0x00ed, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_key_3_AUTH_KEY_Mask = (0xff << 0), + + /* Authentication enable (Address 0x00ee)*/ + MAX98927_Authentication_enable = 0x00ee, + MAX98927_Authentication_enable_AUTH_EN = (0x1 << 0), + + /* Authentication result 0 (Address 0x00ef)*/ + MAX98927_Authentication_result_0 = 0x00ef, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_0_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 1 (Address 0x00f0)*/ + MAX98927_Authentication_result_1 = 0x00f0, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_1_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 2 (Address 0x00f1)*/ + MAX98927_Authentication_result_2 = 0x00f1, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_2_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 3 (Address 0x00f2)*/ + MAX98927_Authentication_result_3 = 0x00f2, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_3_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 4 (Address 0x00f3)*/ + MAX98927_Authentication_result_4 = 0x00f3, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_4_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 5 (Address 0x00f4)*/ + MAX98927_Authentication_result_5 = 0x00f4, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_5_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 6 (Address 0x00f5)*/ + MAX98927_Authentication_result_6 = 0x00f5, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_6_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 7 (Address 0x00f6)*/ + MAX98927_Authentication_result_7 = 0x00f6, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_7_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 8 (Address 0x00f7)*/ + MAX98927_Authentication_result_8 = 0x00f7, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_8_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 9 (Address 0x00f8)*/ + MAX98927_Authentication_result_9 = 0x00f8, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_9_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 10 (Address 0x00f9)*/ + MAX98927_Authentication_result_10 = 0x00f9, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_10_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 11 (Address 0x00fa)*/ + MAX98927_Authentication_result_11 = 0x00fa, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_11_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 12 (Address 0x00fb)*/ + MAX98927_Authentication_result_12 = 0x00fb, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_12_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 13 (Address 0x00fc)*/ + MAX98927_Authentication_result_13 = 0x00fc, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_13_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 14 (Address 0x00fd)*/ + MAX98927_Authentication_result_14 = 0x00fd, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_14_AUTH_RESULT_Mask = (0xff << 0), + + /* Authentication result 15 (Address 0x00fe)*/ + MAX98927_Authentication_result_15 = 0x00fe, + /*#BYHAND width >= 5:*/ + MAX98927_Authentication_result_15_AUTH_RESULT_Mask = (0xff << 0), + + /* Global Enable (Address 0x00ff)*/ + MAX98927_Global_Enable = 0x00ff, + MAX98927_Global_Enable_EN = (0x1 << 0), + /* Software Reset (Address 0x0100)*/ + MAX98927_Software_Reset = 0x0100, + MAX98927_Software_Reset_RST = (0x1 << 0), + + /* REV ID (Address 0x01ff)*/ + MAX98927_REV_ID = 0x01ff, + /*#BYHAND width >= 5:*/ + MAX98927_REV_ID_REV_ID_Mask = (0xff << 0), +} MAX98927Registers; + +struct max98927_reg_default { + unsigned int ch; + unsigned int reg; + unsigned int def; +}; +struct max98927_priv { + struct regmap *regmap; + struct regmap *sub_regmap; + struct snd_soc_codec *codec; + struct max98927_pdata *pdata; + const uint32_t *regcfg; + uint32_t regcfg_sz; + unsigned int spk_gain; + unsigned int sysclk; + unsigned int v_l_slot; + unsigned int i_l_slot; + unsigned int v_r_slot; + unsigned int i_r_slot; + bool interleave_mode; + unsigned int ch_size; + unsigned int rate; + unsigned int iface; + unsigned int master; + unsigned int thres_hyste; + unsigned int level5_hold; + unsigned int level6_hold; + unsigned int level7_hold; + unsigned int level8_hold; + unsigned int amp_limit; + unsigned int amp_limit_rel; + unsigned int amp1_level; + unsigned int amp2_level; + unsigned int amp3_level; + unsigned int amp1_level8; + unsigned int amp2_level8; + unsigned int amp3_level8; + unsigned int amp1_level7; + unsigned int amp2_level7; + unsigned int amp3_level7; + unsigned int amp1_level6; + unsigned int amp2_level6; + unsigned int amp3_level6; + unsigned int amp1_level5; + unsigned int amp2_level5; + unsigned int amp3_level5; + unsigned int digital_gain; + unsigned int pdm_gain; + unsigned int level_hold; + struct i2c_client *sub_i2c; + int sub_reg; + int sub_bus; +}; + +#define MAX98927_GLOBAL_SHIFT 0 +#define M98927_DAI_MSEL_SHIFT 4 +#define M98927_DAI_BSEL_SHIFT 0 +#define M98927_DAI_BSEL_32 (2 << M98927_DAI_BSEL_SHIFT) +#define M98927_DAI_BSEL_48 (3 << M98927_DAI_BSEL_SHIFT) +#define M98927_DAI_BSEL_64 (4 << M98927_DAI_BSEL_SHIFT) +#define M98927_DAI_MSEL_32 (2 << M98927_DAI_MSEL_SHIFT) +#define M98927_DAI_MSEL_48 (3 << M98927_DAI_MSEL_SHIFT) +#define M98927_DAI_MSEL_64 (4 << M98927_DAI_MSEL_SHIFT) +#define MAX98927_Speaker_Gain_Width 3 +#define MAX98927_SPK_RMP_EN_SHIFT 4 +#define MAX98927_PDM_GAIN_SHIFT 4 +#define MAX98927_pdm_Gain_Width 3 +#define MAX98927_AMP_VOL_WIDTH 7 +#define MAX98927_AMP_VOL_LOCATION_SHIFT 7 +#define MAX98927_PDM_Rx_Enable_PDM_CH_SHIFT 3 +#define MAX98927_PCM_to_speaker_monomix_A_SHIFT 6 +#define MAX98927_PCM_Sample_rate_setup_2_DIG_IF_SR_48000 (0x8 << 4) +#define MAX98927_PCM_FORMAT_DSP_A (0x3 << 3) +#define MAX98927_DRE_Control_DRE_SHIFT 0x1 +#define MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_SHIFT (2) +#define MAX98927_Brownout_AMP_limiter_attack_release_shift 4 +#define MAX98927_BDE_DSP_SHIFT 2 +#define MAX98927_Speaker_Gain_SPK_PDM_GAIN_SHIFT (4) +#define MAX98927_BDE_AMP_SHIFT (1) +#define MAX98927_PCM_Tx_Ch_Sources_A_I_SHIFT (4) +#endif