From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752823AbcKOVKw (ORCPT ); Tue, 15 Nov 2016 16:10:52 -0500 Received: from mail-he1eur01on0099.outbound.protection.outlook.com ([104.47.0.99]:35184 "EHLO EUR01-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752745AbcKOVKt (ORCPT ); Tue, 15 Nov 2016 16:10:49 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=peda@axentia.se; From: Peter Rosin To: CC: Peter Rosin , Liam Girdwood , "Mark Brown" , Rob Herring , Mark Rutland , Nicolas Ferre , "Jaroslav Kysela" , Takashi Iwai , , Subject: [PATCH v4 1/3] ASoC: atmel_ssc_dai: if not provided, default to sensible dividers Date: Tue, 15 Nov 2016 19:38:13 +0100 Message-ID: <1479235095-13441-2-git-send-email-peda@axentia.se> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1479235095-13441-1-git-send-email-peda@axentia.se> References: <1479235095-13441-1-git-send-email-peda@axentia.se> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [217.210.101.82] X-ClientProxiedBy: DB4PR01CA0059.eurprd01.prod.exchangelabs.com (10.242.152.49) To AM5PR0201MB2308.eurprd02.prod.outlook.com (10.169.243.7) X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;2:FfkepLqAj71PPaEwMkJLD+qUCvIfaeNA3fMDXFng57LQ9QB0gEok4kcRXyXfyOJ2AvcJEBFXo9irawj+ofqQhkLqP7/m4XiK/CAhpo9YZOLScx3AlayKyPir8/FY7Us5t3lCMg+QIHSGHmC4iR/tYMwIsf5ZbjwUSVdR6jeiUCc=;3:ydB3KRe70LwT6C+gaqo9PYEvCpPiPYNgC3i8xUraLif9RF40ExcsLTtFZWOXpDl4agrW9mFoywIUFkIE7dGMxq8yTBk0QojVwyL9NyF8F3dy6cacK6JHbKdipzogfDKdbG/kHdJMJwj1GYud8YJn6vK05YvwQ1PmbYqlZYfRfbE= X-MS-Office365-Filtering-Correlation-Id: 7ab07924-01a5-4ae9-f2ba-08d40d86a1bc X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:AM5PR0201MB2308; X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;25:DZY755FAtDRzuVq8q6rUX1NYtoOKLjia3yBiEbPkoyr23EBqkDW0UyN4D/GdC+fT0ZG6GVbYPg/EmQL3hHkaZgU6Bd7+jHjfbbrHiAMiELgC+eh8WVR38MglGrwcAz7FTMw2Iihb9uiLa/cEM5pSVFBm1LKG6CvJVycmb8ttmLaCTVo9w37v7XKIW13JN9RgPXSRpN6vPY72VtQ2HORJnhtb/5AWBzV+wu4dGIoSYPBBtyea0f2nxGaZTY7KMZYHs/UrY2X7gtQyfM0EUb+HDotBpaLrBxbZTQMDFB7mhKV/Dcp3MfeOnYv4vv9O/yOBqvhCmu9pw75fNGNY6jgjy7nptTZXnG/eq1Q1ZOQMZgDAkgOZ3CzYtRlPRN5DzHo8EowH1aLbBTy7GO5DPzPiq1OVlleHHt1rrz+roozO643Ad8L1rL3hmnIN7Zys1fiz/urUYrlW75tJ5DM+Fr2Bnh5M8ie2ve+ACvHsJfHKUG8lrvUMMSGbL+3cJehVNXYiiBKOwPljOMi8kNpwnOSWfK4mcD8fWIYLQql5//YMh2hPRbqEVz8lzwYvt7w7PPSntPozCrlnRSzO/NLRy5mc0MN2p6i0Y8ixvLG6nfSiZHmjIAYnicSQD68ktSNt+r2McXUU6JnkEO4TehLRbRE0WRXkswe+2YPiSETdvxt8yZy46xzCSTTLqd8OrYPwQ0+jtjEBxFxtN/X2Czjraz9kBaVqE0ROqaxgYHrwTqahHfVwzk1WEI+aRQP08K6sL2wB X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;31:KTUdQuYsHFuk3mobOkiAGmEwGA53vNq44+qlnm5PpdMaqg2KtBGqW32SKRgLGkQCIR6WZhMKmvV/F8y27Oeeqqt9+sUwVnqra6dpSeO+xd5r2yyeuV12krP22ll6BDc/3L0SD66YbVCjWTl6r/gbmgMhMulJpvKe+cPSlEouUrh/cGWsuZ3XUK7TvC0kZWZ0eFKsUYoNK8fwrOTbsKfVALidimg0DYH7T/XlRlvpS/iu1e8J9LrDyOERAQ7h52rH;4:FfmZ4sER3HK31aW53WJbA+4LsXmcOwHht1nwIRnD0LnaHERc8hKAEJjF9ngved2Qd6bU4zACBLUIAND5GR6YKCw2RMbaeovjUqYdM1uZJiTGs/5CSOvlfgLiV0y5JPhdTlx92CxkqHBscR1W9aR8dQK6TJkPZb3bExej42c1hY3gH36sQ0laPt2UAnXKdV1FmI0FMY5ZEPNBDGMi0BIlcUMjDHlv8WImFnqciAlJjXOsvK4MvfI3VbrxSTnmDfdH8bzyv7XfwCq595bIDEY1FG+PkTIaDUfRl7JcM742vFrAL/hk6c/QZuJjX00/VI9vGiYVXv+JSVpXpnn44KQF9LvEqHCekcGH1iw84fW0qpUwxEjWDEp6cBqJUXhqiubKCM+NhVMpenm69cwEdTZ73HC4/KeAGW6DLapvAddcheVclT/axaWAKm4IyIRRASNk X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6060326)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6061324)(6043046);SRVR:AM5PR0201MB2308;BCL:0;PCL:0;RULEID:;SRVR:AM5PR0201MB2308; X-Forefront-PRVS: 012792EC17 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6069001)(6009001)(7916002)(199003)(189002)(81166006)(81156014)(7416002)(8676002)(42186005)(68736007)(2906002)(50226002)(305945005)(50466002)(110136003)(7846002)(47776003)(7736002)(2950100002)(86362001)(5660300001)(66066001)(5003940100001)(6916009)(6666003)(48376002)(76176999)(33646002)(50986999)(189998001)(6116002)(101416001)(3846002)(36756003)(2351001)(106356001)(77096005)(97736004)(105586002)(4326007)(92566002)(74482002)(42262002);DIR:OUT;SFP:1102;SCL:1;SRVR:AM5PR0201MB2308;H:localhost.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM5PR0201MB2308;23:03ddCrZ6EPsngIYbwNitCvT8nWdxCAGnf+KsWYd?= =?us-ascii?Q?6ld1fAXd2QeaiAEMOz/dsPleOFLgFMujm0ltUhxzF/eCuI6zw20FbeKM/7Hu?= =?us-ascii?Q?1MnjxCEk/AkyCPvXkhl3EPuWcoCXhRvCJ3IziTSD4+OPPXsJ+yx4St5Rnv8b?= =?us-ascii?Q?Vwr8/qj7i1KHGqefHkOmrscoF9nMhLtSC16aQ1SrkM959CPU1bsAxZUrrXtQ?= =?us-ascii?Q?UbE3cNEX/bqcJT3Sv41pdF0ECrRVKhg5t1/3+tlfo2Y0BwF2FIPOVFIUSs7t?= =?us-ascii?Q?1jsQyS7ewEhcZFbEtYHSmIYATHzIBgkDs24FsbNyiTRkBiAIOTSSUSF4TsaK?= =?us-ascii?Q?BTidvGZCvoE+/K5VHg+vQ5KofQTWCkwv4OBcuU1M8Kjd6MQ1A9/qx+6Uhj9/?= =?us-ascii?Q?bWb5wmSFhIwTgkh6QuRpLCNgoOCwHRMwlkKBMa/oxv6QbokY80Z5Eg+Sd/Mk?= =?us-ascii?Q?h2WKT2kSYt2w/MxOwsdEHik3QSqVzUpZz2amYQFyNwv8A8h3u0WTszJyrf+M?= =?us-ascii?Q?b7V/1dhkKjMh7RJxu0+vSv5YGV7h7kkRsWpUVnPOMlUUheyicyJYtcHnR/V8?= =?us-ascii?Q?Sfs/sIGZD15+1cSuJd5bHl3ZeM0jI2EorewLexbbRm66sh2ZHXzrKwMkPQBv?= =?us-ascii?Q?+KeVwP7sgMzu3fTqVolWb5lXys/I3JQd+zdZ31p7itqImMBKTLPgChThwPn8?= =?us-ascii?Q?97h8FLaztyhKyQ7xpNFKvgTyBAD4+fXYNDb4xRjzuSDfP96ry/+dasxLkyj5?= =?us-ascii?Q?UcqubPKqtn8v9o9RgeM6067ztb3gc3D3hkYYoNabCu4Je6w46js2MzQLX0N7?= =?us-ascii?Q?D/H/ukNJfd3/r1EKIwN46tPMF0kwveyj56AsNE+lgnZvZID2P4mQlfalEB/k?= =?us-ascii?Q?tXWl8X8O9/ZNNCd+vw9E6nimJ2EujtRxetFIxypm5uCaql0GCOzH9lDNTmiV?= =?us-ascii?Q?wnS3rFOE2AgO1ZbcZCYtRh1MP5LkrWE0HgTpNSa9GaByxoSrxoIXNR5wbphz?= =?us-ascii?Q?vqa2QD+ex6Gl+9VubEFG33HzERu/n/smSWCxE6JfkzC/BNu7hC8bNZlakJc4?= =?us-ascii?Q?AVHIjD6pAC/QBLHmkuy6Bwmbb5i2q?= X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;6:s2gvyuu2T5l9kBzU5q3JxuwbIg8x++BF/kDUcbtn58LEMWRTqcfNQSBCx6I6sejx9IKnxPVMzDk9ZijdnHt+eRtxvKQLXWFYTMztTgHu9QQONM8+/oAmacI96HioA5Hbp4o5PizSuxfTZO7nNhmGg0VSi7gjxypRTGEvguEZZjppgEyL77//oygylIL0cuXHjX2Qh+9Vhw+XiiaC7HBX45dwBZ//QJMd/S8+xN8MGvDpK6MjX3b2wBRwem2wZS+4E/AS+K7OAJguoRcJl9JXEFAv6/pz1zyRoyORFngHmin92n27XaeqpwmVNjuNjUAHPF5HOpdmy0eY3p+sn1zkwWaHaG4UEbh/LPMD6aiWsIOVWgcbGOnFUj4Su3INWlxi;5:8ZblqWZoVbtZunLeUD6qzNtL/SSuU5Oc6lYxtoxEvkXa/0Z0u10mOFPlTPm8bdscoe5k7ZJqTYJKOBO/Lhzsw3wbzgLuLcKRYk3VcmAZupFEsUQkBB7LAeuTQzny8YMv+7cWSCXXZehelJ5PrGmaUA==;24:x1IAQLEBhpic0CB8J5HVqFtsHM1RyxCmIzzv0XShKosodB9s8dIToDfFpqF4nlqLl7XBp22mYD+Ibbjrz6uBytyDfAE/xEeidCsFu1XjV/Q= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;7:i6a0fBmFVVNBee7kkCTHDZfqLnFdbWP1DIGxriHdA9dxn9ZToW4M2z6NkDJSokiiGheGkoHW+P/ybw9lnkc/F7b983+n+0utNwPmUsEY0tDucu1NsOIiWJ8QupaFVO9WcfyVqHYx+JDuQflsUnCqmAe2kd1J7xtJmEIlllMJSf1ysZVmuV7e9ED7/eMQyScbIywMj8YZsOfySLt8yj0I5QF9OuTxUBS0qatURpSN5zE5sKU8Q+cgE+Ce4X9maeVPdiaqaLjorvQIr+bxOLJGau7kLzy53FXWjojJ1M8aOeumgyid6jLgpRzaw/OOUeniuGYbXh1Fm/qFqa0g94AKRhkw/i3SuBxgRxcRl3MmP68= X-OriginatorOrg: axentia.se X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Nov 2016 18:38:44.1523 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0201MB2308 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When this driver masters BCLK and/or LRCLK, and noone has stated differently, assume that all the bits of a frame are used. This relieves the cpu dai users from the duty to fill in the dividers for the common case. Signed-off-by: Peter Rosin --- sound/soc/atmel/atmel_ssc_dai.c | 83 +++++++++++++++++++++++++++++++++++++---- sound/soc/atmel/atmel_ssc_dai.h | 1 + 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 16e459aedffe..a1e2c5682dcd 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -380,6 +380,7 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); /* Clear the SSC dividers */ ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0; + ssc_p->forced_divider = 0; } spin_unlock_irq(&ssc_p->lock); @@ -426,14 +427,17 @@ static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, else if (div != ssc_p->cmr_div) return -EBUSY; + ssc_p->forced_divider |= BIT(ATMEL_SSC_CMR_DIV); break; case ATMEL_SSC_TCMR_PERIOD: ssc_p->tcmr_period = div; + ssc_p->forced_divider |= BIT(ATMEL_SSC_TCMR_PERIOD); break; case ATMEL_SSC_RCMR_PERIOD: ssc_p->rcmr_period = div; + ssc_p->forced_divider |= BIT(ATMEL_SSC_RCMR_PERIOD); break; default: @@ -443,6 +447,28 @@ static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, return 0; } +/* Is the cpu-dai master of the frame clock? */ +static int atmel_ssc_cfs(struct atmel_ssc_info *ssc_p) +{ + switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBS_CFS: + return 1; + } + return 0; +} + +/* Is the cpu-dai master of the bit clock? */ +static int atmel_ssc_cbs(struct atmel_ssc_info *ssc_p) +{ + switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBS_CFS: + return 1; + } + return 0; +} + /* * Configure the SSC. */ @@ -459,6 +485,9 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, u32 tfmr, rfmr, tcmr, rcmr; int ret; int fslen, fslen_ext; + u32 cmr_div; + u32 tcmr_period; + u32 rcmr_period; /* * Currently, there is only one set of dma params for @@ -470,6 +499,46 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, else dir = 1; + /* + * If the cpu dai should provide BCLK, but noone has provided the + * divider needed for that to work, fall back to something sensible. + */ + cmr_div = ssc_p->cmr_div; + if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_CMR_DIV)) && + atmel_ssc_cbs(ssc_p)) { + int bclk_rate = snd_soc_params_to_bclk(params); + + if (bclk_rate < 0) { + dev_err(dai->dev, "unable to calculate cmr_div: %d\n", + bclk_rate); + return bclk_rate; + } + + cmr_div = DIV_ROUND_CLOSEST(ssc_p->mck_rate, 2 * bclk_rate); + } + + /* + * If the cpu dai should provide LRCLK, but noone has provided the + * dividers needed for that to work, fall back to something sensible. + */ + tcmr_period = ssc_p->tcmr_period; + rcmr_period = ssc_p->rcmr_period; + if (atmel_ssc_cfs(ssc_p)) { + int frame_size = snd_soc_params_to_frame_size(params); + + if (frame_size < 0) { + dev_err(dai->dev, + "unable to calculate tx/rx cmr_period: %d\n", + frame_size); + return frame_size; + } + + if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_TCMR_PERIOD))) + tcmr_period = frame_size / 2 - 1; + if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_RCMR_PERIOD))) + rcmr_period = frame_size / 2 - 1; + } + dma_params = ssc_p->dma_params[dir]; channels = params_channels(params); @@ -524,7 +593,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, fslen_ext = (bits - 1) / 16; fslen = (bits - 1) % 16; - rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) + rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) | SSC_BF(RCMR_STTDLY, START_DELAY) | SSC_BF(RCMR_START, SSC_START_FALLING_RF) | SSC_BF(RCMR_CKI, SSC_CKI_RISING) @@ -540,7 +609,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | SSC_BF(RFMR_LOOP, 0) | SSC_BF(RFMR_DATLEN, (bits - 1)); - tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) + tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) | SSC_BF(TCMR_STTDLY, START_DELAY) | SSC_BF(TCMR_START, SSC_START_FALLING_RF) | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) @@ -606,7 +675,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, fslen_ext = (bits - 1) / 16; fslen = (bits - 1) % 16; - rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) + rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) | SSC_BF(RCMR_STTDLY, START_DELAY) | SSC_BF(RCMR_START, SSC_START_FALLING_RF) | SSC_BF(RCMR_CKI, SSC_CKI_RISING) @@ -623,7 +692,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | SSC_BF(RFMR_LOOP, 0) | SSC_BF(RFMR_DATLEN, (bits - 1)); - tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) + tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) | SSC_BF(TCMR_STTDLY, START_DELAY) | SSC_BF(TCMR_START, SSC_START_FALLING_RF) | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) @@ -650,7 +719,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, * MCK divider, and the BCLK signal is output * on the SSC TK line. */ - rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) + rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) | SSC_BF(RCMR_STTDLY, 1) | SSC_BF(RCMR_START, SSC_START_RISING_RF) | SSC_BF(RCMR_CKI, SSC_CKI_RISING) @@ -665,7 +734,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | SSC_BF(RFMR_LOOP, 0) | SSC_BF(RFMR_DATLEN, (bits - 1)); - tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) + tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) | SSC_BF(TCMR_STTDLY, 1) | SSC_BF(TCMR_START, SSC_START_RISING_RF) | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) @@ -760,7 +829,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, } /* set SSC clock mode register */ - ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div); + ssc_writel(ssc_p->ssc->regs, CMR, cmr_div); /* set receive clock mode and format */ ssc_writel(ssc_p->ssc->regs, RCMR, rcmr); diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h index 80b153857a88..75194f582131 100644 --- a/sound/soc/atmel/atmel_ssc_dai.h +++ b/sound/soc/atmel/atmel_ssc_dai.h @@ -113,6 +113,7 @@ struct atmel_ssc_info { unsigned short cmr_div; unsigned short tcmr_period; unsigned short rcmr_period; + unsigned int forced_divider; struct atmel_pcm_dma_params *dma_params[2]; struct atmel_ssc_state ssc_state; unsigned long mck_rate; -- 2.1.4