From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751060AbdEERrO (ORCPT ); Fri, 5 May 2017 13:47:14 -0400 Received: from mail-co1nam03on0099.outbound.protection.outlook.com ([104.47.40.99]:16358 "EHLO NAM03-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750762AbdEERrM (ORCPT ); Fri, 5 May 2017 13:47:12 -0400 Authentication-Results: gmail.com; dkim=none (message not signed) header.d=none;gmail.com; dmarc=none action=none header.from=maximintegrated.com; From: Ryan Lee To: , , , , , , CC: Subject: [PATCH] ASoC: max98927: Adding support for TDM mode and Envelop tracking control Date: Fri, 5 May 2017 10:42:15 -0700 Message-ID: <1494006135-1178-1-git-send-email-ryans.lee@maximintegrated.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [204.17.143.20] X-ClientProxiedBy: BN6PR20CA0002.namprd20.prod.outlook.com (10.173.158.140) To CY1PR11MB0844.namprd11.prod.outlook.com (10.163.237.22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ca102bb9-eb3e-4389-bdc9-08d493dec08a X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(48565401081)(201703131423075)(201703031133081);SRVR:CY1PR11MB0844; X-Microsoft-Exchange-Diagnostics: 1;CY1PR11MB0844;3:mwfEzSccFnLaVeaynGNeQaqtinxxQ7fIYgtUOq5LpkOmc4qcQ+5g0H+vuQSZhMF3v1L1Lonc9WQ9PjANqKfUeciT92WtQR5KXMtK4p4wgU0gCJp1aKGYh0aOgDEGhKvX8jGCCMpw3IJFv/9INIr3satFxjjya2ryj+a05mPUgHj+Wh9A4Q3IpNKxYI7iZgqtVSYetAeuzA703Ou/NlYz04vAUvsPkNfUN9706kxjEZ6vHnUYOpjQdTLcDVj9oKER8UJHvVCsahePklfJiCqwK8adbVXhxqEh1VBGVbLTxrapLiNEgdMW5EfdwwnytHogsGziWXSyz+N6X6Q8gsjULJ68gVVL3KK3xkbhsI9E9tE=;25:iMMD0j9ouWHV6YRz7bppJStZ+/TVeIeG1rlg6KApdCXJmQs+K/oDbI2WQ60BQfwoXxQ/xL1gcKERNAAKSt8ts3mXDYS0Iv5ELSP4G1OxX8siAIahj9G/1rhvvQjC1AQQntgQ8HvQhWnxlzSeGaJ6Y6W5agM9zGDHqNc+ErHQnSDu24RRJZnrA/pokCDTdFB/xxynIG3TOcPxI6g9P0euRcQjIktD7i2bgyaiDo3xzJU7iY5Q9amPccVrwjswpkoeMFWj/7FQwCVNYvpsN+HzWWYY9Q7FXg/A6Ze2JsPlrdXO832h+SB7p8/hRRqqi0Ubz8DvqxDzGl61hIySuyq0yAkuP573fuuc6U+vXgHdFFviRxJcH1f5ocepD0bB08FsnMNETGuETTxvIoWkKuBFpSB4jNFwBDY4y59EXq6M41iJ/2IGiUqUt9oC5E6q3TQAaMVPK4wfK4Ma1ArItmgc4Ym1NCGL5eLF9xFtgIwr2YU= X-Microsoft-Exchange-Diagnostics: 1;CY1PR11MB0844;31:iiMcM8Sw5Usl9Lhf2NcK7tH6r/TJbudm/Me3PGiFY2ZjvjWy9hUwFZbW+9UAkhHRRYUBmRvroMpCBi/fsHICFMQ54gEkcUC50eIAHUzCoHw2ih1H9oZwWYZib7GeqVPLzrpCDJVnO4PcoOOEvVfsoGdOiV9AI65mnuh9lTnPWOKXMsw9ipnzVD6rYkwFy+KWrZ2HZf1dg8YeFJ0iJgT2Hyv8D4F8Vm6KaIZZi3VoYsSHxy5nCyLfSZFBe3tFbfxRYvwSskNJdiMuEjKN2fKccA==;20:J7MvrFidyion7hlfG+Wl+Fz6s8BC0Fl/sX1+cSWAMROwjWOBMo6CR5ZAijOgV1bBFWxdTVx8pP4wTH3Zu9d9adkWEROXD2Aco/RadPV9NSVq1L3PJ0neEcQ3xPJIZ04MgeYhBo8Ji3GvjZBnEA3Fi/eXS81yvnKTbQcRtj22kWuKnQKNT+Ind1TR3O09z0AeVznE6rHbpUI/sBkMK2WhWQ47kC9Pq/RDRPOf7FpW005Pk2lGxrdsQVeHAFbv/VXrfo+f1WeNjv0kvKvguPFllS98HG3zXWyUvhmEUeH20WZhdu+1RgghxR+EtucQu8sgx+OGqYWOASw6/YVzolcWHLl/34A3nb3SPaYihrku3t3Mo1VM8DXJLjDoNGGtQ3URJ8XVKdkpVZca1QrkX7i2LANU9UJbaMIE5Ze6BvAbMVCnUYHE8S4roHuvViK2AVHz7JHy1SAksT5Bhrl333ox68uknS5je0tuFXMnqmhA4iWSOLausApK2WbAsbUhXE2v X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(108721460000369); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040450)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(93006095)(93001095)(6055026)(6041248)(20161123562025)(20161123564025)(20161123555025)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(6072148);SRVR:CY1PR11MB0844;BCL:0;PCL:0;RULEID:;SRVR:CY1PR11MB0844; X-Microsoft-Exchange-Diagnostics: 1;CY1PR11MB0844;4:HH66uUsj3BPnXOVW+7I7kuOkQmuYEevZLiVuHX5YJl/TiCVSVZFNGxO7ZEYxvCldg8CaSl5tsgqz4JJe0RtWleCinubxq8tCvCRgb5l3NmyUnO/1ii2C1mDMeIw8IvYhTy5rrXLpebsVRNLceg0QzJv3yTqRZ6VD9CeN8B38DXiXusMgsERhbNdOkXKXN1YSe7FPPBbMiukOp8cCghj9ToEj5Gxfum6NjYNdrPxw/CrVQiQ/dmRCsC6e6P9roa3nn3WwRzXZ/37u1e4lnc8ONFXZhl1W5j2/e7ympBL470d/b+ZOP7gZbLgXC9e6WhIbqvL+6IJgHFn+OQYcJVIuoIfQsuKniw2o1CjBLdHLGmNB9BZU90+Ap95eandiyAQ1Et1D4J5EbmR/Fjld7cXSRkiuzYbRy1ghVHml/KzDm+hmx/PjT0oo73AEqBJ4HAIwaLXafKzABM+8wc25qoQCVf45Dcg8bV4wCO8vzZjwxbrVMKaZByPTUiOEtac/+77AzENOQmptawIBtnrHDsYdrbyIG3gI+ivt9slDXQ0Yw8pcX766kQXkzauzdgYXN8CS+nJI4WzzdGUb+VE37kDCYsxaq9uISb0kY3BcP5TXzzhhz/dnbmTEgUI3uwcSlgWtj93Q3ctB6oAIomephZVIn1wN8E8USzrFzI/7q+NOU85a8tZKAJpjssSBX8yb+a6Nklo+caFYl45XDmrriz67ZkoBgq3TseUVmTvTX3qMcCytIEYFcRUa2hD0nF+QW/0ZpXADsRAnaLhiEm8uUstO73aXLhr0ZQ6t1lXOU9F4/CKJkQONv3V+huWh4HWwsUmS2lXvDTSlN7VArNgufK55Znwc5stJ4aMzePLb4K4EA6s= X-Forefront-PRVS: 02981BE340 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(39850400002)(39400400002)(39860400002)(39410400002)(39450400003)(39840400002)(2906002)(3846002)(6116002)(50466002)(5003940100001)(5660300001)(47776003)(66066001)(6512007)(53936002)(8676002)(38730400002)(2201001)(478600001)(6486002)(48376002)(6506006)(575784001)(189998001)(86362001)(25786009)(53416004)(42186005)(33646002)(50986999)(36756003)(50226002)(81166006)(6666003)(4326008)(305945005)(7736002)(2004002);DIR:OUT;SFP:1102;SCL:1;SRVR:CY1PR11MB0844;H:ryan-linux.maxim-ic.com;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CY1PR11MB0844;23:rs9zbT0NF2TAWxRzp8WxgRJ5eP4KC7h+3IF7mKZtR?= =?us-ascii?Q?jCi/C5uukk6Mdo6AmWcWQi2oaPEVsyqxDFZ7EG2exbRw+JTqufKTg/xhsqu9?= =?us-ascii?Q?b9vOzPYDt5PB9j5viLAB7g/x9ASU2CL6kQgYjGFlj0DI6PuyrFgg1z+LsWWg?= =?us-ascii?Q?XRngZ2UXSQm7qdurfAfHd8tbR43RiDy/R0OgbKFIPd28+nBX3a6FyQaftQVk?= =?us-ascii?Q?iEAbHzWdA4thJQru5DkkoM0frQXTuZj8+08wYZQ74AxowzdhRffjxKu87680?= =?us-ascii?Q?XGHYAdTYaEbZxwDx9W3skwWoT2rwA2TnyKocK4vuvxg4WaRYCQoDHspY9vEm?= =?us-ascii?Q?JYUc66JEySn4QOrXG6TieT4Iwj3dDlloOFMWLc+agDrTsgS0GUSfj1dyCo2l?= =?us-ascii?Q?oi70kmWZlfohK80mIwSCzd/NMAN+PY2XcfkoVXDnzKflhYx4GgUq0iX6wVvJ?= =?us-ascii?Q?HzAIscySfhpvf8t63q3+/br3VB0DmovkltLSM92L7iB3bXpQXs/Hs+oJB5By?= =?us-ascii?Q?1ZIIryQoEYksmqowkwfO2Bbv8HX6WP3TxYxF7Xz/wJJbxUPXJjm8xZeHhMaT?= =?us-ascii?Q?558VF0KPX0V5XfFhIKILX42sNMYmCDobLp0WgRHTHRkuLmF9dgWAh9qmjzTI?= =?us-ascii?Q?x5PUjHcBZkC1MbaYy40i5rGoHChg10DcC1GDbzhog5d/iqEjqC9PYBTY5gIY?= =?us-ascii?Q?l3dHGVrQENGr4+Lf4C4WexW3K2LqYalaPwpbrvfwHkV9QcnWt/aI5xfGHTbh?= =?us-ascii?Q?EI4I3U/ZkzW1UBBYss/hXLFPldxGPuME4CIlE9yCrcF+Wx3GfFbO0oe88Rrj?= =?us-ascii?Q?Sik39iggF7RaWdFWYTaX8smlxCpobWtzho3Db7FJpiae/m9yKGUQQkKGDXR7?= =?us-ascii?Q?FeqNTrmfOuC2ZlLLezNMjF6LflJNb58COqYiQwfac5Sd/cJHCGkJao+9rtjV?= =?us-ascii?Q?T6JRCcI/a4lLLuKzC/lyyN9eJKFcsJaHBO9M/RDRLxcKrtGqhghVYQKyBBSj?= =?us-ascii?Q?DgQzWy26UvvG2o02TxkA+PTKPX37ncQ3CRy1rJBTrERd7Zp3fJeDV4FalXHi?= =?us-ascii?Q?CujCog=3D?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR11MB0844;6:gaOvid7nMQ+1RG/4MC4NDVS3/BlHHhwsfN7ed54bYa+sAZrdJtyRPj0NORQEkg1sLgMNdEfwQZf72jA6lZgmBxvCIWSbAFEMGFvLHKZLGW9tVQk32Ki0dQ4r/XWIafe9/F3NUbmYLuWHVAx8cMqpYDqcRwCM8cGm0qLQZ+iZixijXzNh/mskMaWbyb4MRYViTcXaEHwx/zz8ni1B5+pM3Fvw64cOcsJpz8cAd3r5xvYpkMxkhsdW2wjOgIr6yNj6JfqUF0+Y5AHXTrxxT+FvNLu/GfWEK/9p5QP4dV+Wr/fkEWZrVW9/uf6abw63TjpyirI0zvLUthZLg8sa5pgCjn3QX5lopIExBK4Lnt3l/tiT4M+vitrPbpAecz4RoT9Q5hsMfH1x8q9argPyL6asGxVRZVQqwjaj7tJbjCdceh/UYsJjIDMfyZtg5eho8WApYY7gEs8jgczji9F4me7za7MwJtPP3EJ/xAw1RJX9PFIXzm7vHqtmTaQkLTaQ+T80dDsUGC/sUyvquB9s/W3APdf/5BIdxo5ngG35ZUcFM0g=;5:z+RfaklW2WxrbTxDwy8REfK/Y0/hl/A65H3izSUl3uxZ1xOVUwloO1kapQPN+usW1LxmqP4VwWWgaCjrA0X6eMNYLPxjEX86a1WcqBN3EIL2WJv2Z8z2etRQNoekSIIK52nhiJkt/CLSrfXx7Ogbog==;24:eLj5TxsBFpbC0ZywbDvrEmXZdDpsj8fyZ6WKHj7aW94Q4mv+38bS7dVilKu0i0yrHOl4jL8SqobIscljl1SF01zfMdqmd5tHGTD7DKVfv1M= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY1PR11MB0844;7:B4GINuidt+nTs1HvAVrpQQW+EzxshwaaQRrA2nQg4zgd8UYcCditjFQRH8y2Lel4RFhVqzImf1pONx849lsaHqlpo0Y4sWejUj03CkJkmzh87HQGMtBzaVMnK5EIAjMEbB5DoPvbtQKecWgxdJKPEDghrjED2N061Ch9IOxreQxba6g8oBuWWfyt+tmfs+vp49829v5KrRNMPZ/UDlF1l9E3JDQiPYFJ6FiI/+OFUSDe4mpSjwigj0Tv+UmWOx28ZWdqos/IAKQyz71c8wOwP2THv66TBSB3DLUXgbYQBzpKLRdIEzRaaGf3jFTRruv8ebiOiXUsCmnQAdWNTEVgog== X-OriginatorOrg: maximintegrated.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 May 2017 17:47:07.6234 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR11MB0844 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: Ryan Lee --- Changes * Added code to support TDM mode. * Added "EnvTrack Switch" and "EnvTrack Headroom" controls. * Added six more registers into volatile register list. * Added missing \n to end of dev_err messages. * Removed an obsolete variable from 'max98927_priv'. sound/soc/codecs/max98927.c | 173 ++++++++++++++++++++++++++++++++++++-------- sound/soc/codecs/max98927.h | 17 +++-- 2 files changed, 152 insertions(+), 38 deletions(-) diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index b5ee294..9b864e2 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c @@ -1,7 +1,7 @@ /* * max98927.c -- MAX98927 ALSA Soc Audio driver * - * Copyright (C) 2016 Maxim Integrated Products + * Copyright (C) 2016-2017 Maxim Integrated Products * Author: Ryan Lee * * This program is free software; you can redistribute it and/or modify it @@ -146,6 +146,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); unsigned int mode = 0; unsigned int format = 0; + bool use_pdm = false; unsigned int invert = 0; dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt); @@ -159,7 +160,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) mode = MAX98927_PCM_MASTER_MODE_MASTER; break; default: - dev_err(codec->dev, "DAI clock mode unsupported"); + dev_err(codec->dev, "DAI clock mode unsupported\n"); return -EINVAL; } @@ -175,7 +176,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE; break; default: - dev_err(codec->dev, "DAI invert mode unsupported"); + dev_err(codec->dev, "DAI invert mode unsupported\n"); return -EINVAL; } @@ -187,22 +188,27 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) /* interface format */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - max98927->iface |= SND_SOC_DAIFMT_I2S; format = MAX98927_PCM_FORMAT_I2S; break; case SND_SOC_DAIFMT_LEFT_J: - max98927->iface |= SND_SOC_DAIFMT_LEFT_J; format = MAX98927_PCM_FORMAT_LJ; break; + case SND_SOC_DAIFMT_DSP_A: + format = MAX98927_PCM_FORMAT_TDM_MODE1; + break; + case SND_SOC_DAIFMT_DSP_B: + format = MAX98927_PCM_FORMAT_TDM_MODE0; + break; case SND_SOC_DAIFMT_PDM: - max98927->iface |= SND_SOC_DAIFMT_PDM; + use_pdm = true; break; default: return -EINVAL; } + max98927->iface = fmt & SND_SOC_DAIFMT_FORMAT_MASK; - /* pcm channel configuration */ - if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) { + if (!use_pdm) { + /* pcm channel configuration */ regmap_update_bits(max98927->regmap, MAX98927_R0018_PCM_RX_EN_A, MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, @@ -217,13 +223,12 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) MAX98927_R003B_SPK_SRC_SEL, MAX98927_SPK_SRC_MASK, 0); - } else regmap_update_bits(max98927->regmap, - MAX98927_R0018_PCM_RX_EN_A, - MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0); + MAX98927_R0035_PDM_RX_CTRL, + MAX98927_PDM_RX_EN_MASK, 0); - /* pdm channel configuration */ - if (max98927->iface & SND_SOC_DAIFMT_PDM) { + } else { + /* pdm channel configuration */ regmap_update_bits(max98927->regmap, MAX98927_R0035_PDM_RX_CTRL, MAX98927_PDM_RX_EN_MASK, 1); @@ -231,10 +236,12 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) regmap_update_bits(max98927->regmap, MAX98927_R003B_SPK_SRC_SEL, MAX98927_SPK_SRC_MASK, 3); - } else + regmap_update_bits(max98927->regmap, - MAX98927_R0035_PDM_RX_CTRL, - MAX98927_PDM_RX_EN_MASK, 0); + MAX98927_R0018_PCM_RX_EN_A, + MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0); + + } return 0; } @@ -245,6 +252,21 @@ static const int rate_table[] = { 13000000, 19200000, }; +/* BCLKs per LRCLK */ +static const int bclk_sel_table[] = { + 32, 48, 64, 96, 128, 192, 256, 384, 512, +}; + +static int max98927_get_bclk_sel(int bclk) +{ + int i; + /* match BCLKs per LRCLK */ + for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) { + if (bclk_sel_table[i] == bclk) + return i + 2; + } + return 0; +} static int max98927_set_clock(struct max98927_priv *max98927, struct snd_pcm_hw_params *params) { @@ -270,19 +292,17 @@ static int max98927_set_clock(struct max98927_priv *max98927, i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT); } - switch (blr_clk_ratio) { - case 32: - value = 2; - break; - case 48: - value = 3; - break; - case 64: - value = 4; - break; - default: + if ((max98927->iface == SND_SOC_DAIFMT_DSP_A) || + (max98927->iface == SND_SOC_DAIFMT_DSP_B)) + return 0; + + /* BCLK configuration */ + value = max98927_get_bclk_sel(blr_clk_ratio); + if (!value) { + dev_err(codec->dev, "BCLK %d not supported\n", blr_clk_ratio); return -EINVAL; } + regmap_update_bits(max98927->regmap, MAX98927_R0022_PCM_CLK_SETUP, MAX98927_PCM_CLK_SETUP_BSEL_MASK, @@ -311,7 +331,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream, chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32; break; default: - dev_err(codec->dev, "format unsupported %d", + dev_err(codec->dev, "format unsupported %d\n", params_format(params)); goto err; } @@ -386,6 +406,76 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } +static int max98927_dai_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, + int slots, int slot_width) +{ + struct snd_soc_codec *codec = dai->codec; + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); + int bsel = 0; + unsigned int chan_sz = 0; + + /* BCLK configuration */ + bsel = max98927_get_bclk_sel(slots * slot_width); + if (bsel == 0) { + dev_err(codec->dev, "BCLK %d not supported\n", + slots * slot_width); + return -EINVAL; + } + + regmap_update_bits(max98927->regmap, + MAX98927_R0022_PCM_CLK_SETUP, + MAX98927_PCM_CLK_SETUP_BSEL_MASK, + bsel); + + /* Channel size configuration */ + switch (slot_width) { + case 16: + chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16; + break; + case 24: + chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24; + break; + case 32: + chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32; + break; + default: + dev_err(codec->dev, "format unsupported %d\n", + slot_width); + return -EINVAL; + } + + regmap_update_bits(max98927->regmap, + MAX98927_R0020_PCM_MODE_CFG, + MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz); + + /* Rx slot configuration */ + regmap_write(max98927->regmap, + MAX98927_R0018_PCM_RX_EN_A, + rx_mask & 0xFF); + regmap_write(max98927->regmap, + MAX98927_R0019_PCM_RX_EN_B, + (rx_mask & 0xFF00) >> 8); + + /* Tx slot configuration */ + regmap_write(max98927->regmap, + MAX98927_R001A_PCM_TX_EN_A, + tx_mask & 0xFF); + regmap_write(max98927->regmap, + MAX98927_R001B_PCM_TX_EN_B, + (tx_mask & 0xFF00) >> 8); + + /* Tx slot Hi-Z configuration */ + regmap_write(max98927->regmap, + MAX98927_R001C_PCM_TX_HIZ_CTRL_A, + ~tx_mask & 0xFF); + regmap_write(max98927->regmap, + MAX98927_R001D_PCM_TX_HIZ_CTRL_B, + (~tx_mask & 0xFF00) >> 8); + + return 0; +} + #define MAX98927_RATES SNDRV_PCM_RATE_8000_48000 #define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ @@ -405,6 +495,7 @@ 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, + .set_tdm_slot = max98927_dai_tdm_slot, }; static int max98927_dac_event(struct snd_soc_dapm_widget *w, @@ -495,6 +586,12 @@ static bool max98927_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3: + case MAX98927_R004C_MEAS_ADC_CH0_READ: + case MAX98927_R004D_MEAS_ADC_CH1_READ: + case MAX98927_R004E_MEAS_ADC_CH2_READ: + case MAX98927_R0051_BROWNOUT_STATUS: + case MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ: + case MAX98927_R01FF_REV_ID: return true; default: return false; @@ -523,6 +620,18 @@ static SOC_ENUM_SINGLE_DECL(max98927_current_limit, MAX98927_R0042_BOOST_CTRL1, 1, max98927_current_limit_text); +static const char * const max98927_env_track_headroom_text[] = { + "0.000V", "0.125V", "0.250V", "0.375V", "0.500V", "0.625V", + "0.750V", "0.875V", "1.000V", "1.125V", "1.250V", "1.375V", + "1.500V", "1.625V", "1.750V", "1.875V", "2.000V", "2.125V", + "2.250V", "2.375V", "2.500V", "2.625V", "2.750V", "2.875V", + "3.000V", "3.125V", "3.250V", "3.375V", "3.500V" +}; + +static SOC_ENUM_SINGLE_DECL(max98927_env_track_headroom, + MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM, 0, + max98927_env_track_headroom_text); + static const struct snd_kcontrol_new max98927_snd_controls[] = { SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN, 0, 6, 0, @@ -540,6 +649,9 @@ static const struct snd_kcontrol_new max98927_snd_controls[] = { MAX98927_AMP_VOL_SEL_SHIFT, 1, 0), SOC_ENUM("Boost Output Voltage", max98927_boost_voltage), SOC_ENUM("Current Limit", max98927_current_limit), + SOC_SINGLE("EnvTrack Switch", MAX98927_R0086_ENV_TRACK_CTRL, + MAX98927_ENV_TRACKER_EN_SHIFT, 1, 0), + SOC_ENUM("EnvTrack Headroom", max98927_env_track_headroom), }; static const struct snd_soc_dapm_route max98927_audio_map[] = { @@ -635,13 +747,10 @@ static int max98927_probe(struct snd_soc_codec *codec) /* Envelope Tracking configuration */ regmap_write(max98927->regmap, MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM, - 0x08); + 0x0A); regmap_write(max98927->regmap, MAX98927_R0086_ENV_TRACK_CTRL, 0x01); - regmap_write(max98927->regmap, - MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ, - 0x10); /* voltage, current slot configuration */ regmap_write(max98927->regmap, diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h index ece6a60..43d3c74 100644 --- a/sound/soc/codecs/max98927.h +++ b/sound/soc/codecs/max98927.h @@ -1,7 +1,7 @@ /* * max98927.h -- MAX98927 ALSA Soc Audio driver * - * Copyright 2013-15 Maxim Integrated Products + * Copyright (C) 2016-2017 Maxim Integrated Products * Author: Ryan Lee * * This program is free software; you can redistribute it and/or modify it @@ -161,7 +161,9 @@ #define MAX98927_PCM_MODE_CFG_FORMAT_SHIFT (3) #define MAX98927_PCM_FORMAT_I2S (0x0 << 0) #define MAX98927_PCM_FORMAT_LJ (0x1 << 0) - +#define MAX98927_PCM_FORMAT_TDM_MODE0 (0x3 << 0) +#define MAX98927_PCM_FORMAT_TDM_MODE1 (0x4 << 0) +#define MAX98927_PCM_FORMAT_TDM_MODE2 (0x5 << 0) #define MAX98927_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6) #define MAX98927_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6) #define MAX98927_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6) @@ -194,7 +196,7 @@ /* MAX98927_R0024_PCM_SR_SETUP2 */ #define MAX98927_PCM_SR_SET2_SR_MASK (0xF << 4) #define MAX98927_PCM_SR_SET2_SR_SHIFT (4) -#define MAX98927_PCM_SR_SET2_IVADC_SR_MASK (0xf << 0) +#define MAX98927_PCM_SR_SET2_IVADC_SR_MASK (0xF << 0) /* MAX98927_R0025_PCM_TO_SPK_MONOMIX_A */ #define MAX98927_PCM_TO_SPK_MONOMIX_CFG_MASK (0x3 << 6) @@ -207,7 +209,7 @@ #define MAX98927_AMP_VOL_SEL (0x1 << 7) #define MAX98927_AMP_VOL_SEL_WIDTH (1) #define MAX98927_AMP_VOL_SEL_SHIFT (7) -#define MAX98927_AMP_VOL_MASK (0x7f << 0) +#define MAX98927_AMP_VOL_MASK (0x7F << 0) #define MAX98927_AMP_VOL_WIDTH (7) #define MAX98927_AMP_VOL_SHIFT (0) @@ -238,7 +240,7 @@ #define MAX98927_MEAS_I_EN (0x1 << 1) /* MAX98927_R0040_BOOST_CTRL0 */ -#define MAX98927_BOOST_CTRL0_VOUT_MASK (0x1f << 0) +#define MAX98927_BOOST_CTRL0_VOUT_MASK (0x1F << 0) #define MAX98927_BOOST_CTRL0_PVDD_MASK (0x1 << 7) #define MAX98927_BOOST_CTRL0_PVDD_EN_SHIFT (7) @@ -248,6 +250,10 @@ #define MAX98927_BROWNOUT_DSP_EN (0x1 << 2) #define MAX98927_BROWNOUT_DSP_SHIFT (2) +/* MAX98927_R0086_ENV_TRACK_CTRL */ +#define MAX98927_ENV_TRACKER_EN (0x1 << 0) +#define MAX98927_ENV_TRACKER_EN_SHIFT (0) + /* MAX98927_R0100_SOFT_RESET */ #define MAX98927_SOFT_RESET (0x1 << 0) @@ -257,7 +263,6 @@ struct max98927_priv { struct regmap *regmap; struct snd_soc_codec *codec; - struct max98927_pdata *pdata; unsigned int spk_gain; unsigned int sysclk; unsigned int v_l_slot; -- 2.7.4