From patchwork Mon Aug 12 09:49:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Padmavathi Venna X-Patchwork-Id: 2842940 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 816909F271 for ; Mon, 12 Aug 2013 09:48:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8C50C2022D for ; Mon, 12 Aug 2013 09:48:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8989F20211 for ; Mon, 12 Aug 2013 09:48:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756029Ab3HLJsk (ORCPT ); Mon, 12 Aug 2013 05:48:40 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:44951 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756027Ab3HLJsj (ORCPT ); Mon, 12 Aug 2013 05:48:39 -0400 Received: from epcpsbgr3.samsung.com (u143.gpu120.samsung.co.kr [203.254.230.143]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MRE00FD6WJJ9ZY0@mailout2.samsung.com>; Mon, 12 Aug 2013 18:48:38 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.122]) by epcpsbgr3.samsung.com (EPCPMTA) with SMTP id CE.D6.03969.67FA8025; Mon, 12 Aug 2013 18:48:38 +0900 (KST) X-AuditID: cbfee68f-b7f436d000000f81-26-5208af766448 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 83.BA.31505.67FA8025; Mon, 12 Aug 2013 18:48:38 +0900 (KST) Received: from padma-linuxpc.sisodomain.com ([107.108.83.35]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MRE00B1GWKR7O30@mmp2.samsung.com>; Mon, 12 Aug 2013 18:48:37 +0900 (KST) From: Padmavathi Venna To: linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, alsa-devel@alsa-project.org, devicetree@vger.kernel.org, padma.v@samsung.com, padma.kvr@gmail.com Cc: broonie@kernel.org, kgene.kim@samsung.com, tomasz.figa@gmail.com, abrestic@chromium.org Subject: [PATCH V4 2/4] ASoC: Samsung: I2S: Modify the I2S driver to support I2S on Exynos5420 Date: Mon, 12 Aug 2013 15:19:52 +0530 Message-id: <1376300994-1679-3-git-send-email-padma.v@samsung.com> X-Mailer: git-send-email 1.7.4.4 In-reply-to: <1376300994-1679-1-git-send-email-padma.v@samsung.com> References: <1376300994-1679-1-git-send-email-padma.v@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42JZI2JSpVu2niPIoKVJ2GLl+7+MFlcuHmKy mPrwCZvF/CPnWC16F1xls9j0+BqrxYzz+5gs2pfNYbX4ffM7m8WqXX8YHbg8NnxuYvOY3XCR xWPnrLvsHptWdbJ5bF5S79G3ZRWjx+dNcgHsUVw2Kak5mWWpRfp2CVwZE58fZS74Y1Xx/ew/ xgbGg/pdjJwcEgImEpe+r2CGsMUkLtxbzwZiCwksZZS4eMYRpub1pRPsXYxcQPHpjBKnDi5g hnB6mCTmfFnH1MXIwcEmoCPRctYFJC4isIlRYsqGz6wg3cwCsRIbmxeCTRUWSJB4snMhC4jN IqAqcWnGHbAaXgEniZv9J9kgtilIHJv6FSzOKeAs8f7IcRaIi5wkDs5rYQRZICFwiF1i3cfT 7BCDBCS+TT7EAnKEhICsxKYDUN9IShxccYNlAqPwAkaGVYyiqQXJBcVJ6UXGesWJucWleel6 yfm5mxiBcXH637P+HYx3D1gfYkwGGjeRWUo0OR8YV3kl8YbGZkYWpiamxkbmlmakCSuJ86q1 WAcKCaQnlqRmp6YWpBbFF5XmpBYfYmTi4JRqYIzcrjdX9dHK/kDVy//kuzdLNkTtkq0Rnh0Y 7Xcj583aFOku5592NzYY3s1csTnza/3hX9da+bOtJS4yPzh9cpralf/x+7xeHX/eq9q69MTC HVMnXDPmFliR5PSO28//UaWZY9zGRt3L31rnzIz61qYbUnJwfj9/ydUdczLMal/u7uo/Netr 9gclluKMREMt5qLiRAAs+PYVoQIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrDIsWRmVeSWpSXmKPExsVy+t9jQd2y9RxBBjsPc1isfP+X0eLKxUNM FlMfPmGzmH/kHKtF74KrbBabHl9jtZhxfh+TRfuyOawWv29+Z7NYtesPowOXx4bPTWwesxsu snjsnHWX3WPTqk42j81L6j36tqxi9Pi8SS6APaqB0SYjNTEltUghNS85PyUzL91WyTs43jne 1MzAUNfQ0sJcSSEvMTfVVsnFJ0DXLTMH6D4lhbLEnFKgUEBicbGSvh2mCaEhbroWMI0Rur4h QXA9RgZoIGENY8bE50eZC/5YVXw/+4+xgfGgfhcjJ4eEgInE60sn2CFsMYkL99azdTFycQgJ TGeUOHVwATOE08MkMefLOqYuRg4ONgEdiZazLiBxEYFNjBJTNnxmBelmFoiV2Ni8kA3EFhZI kHiycyELiM0ioCpxacYdsBpeASeJm/0n2SC2KUgcm/oVLM4p4Czx/shxsHohoJqD81oYJzDy LmBkWMUomlqQXFCclJ5rpFecmFtcmpeul5yfu4kRHHfPpHcwrmqwOMQowMGoxMPr8YU9SIg1 say4MvcQowQHs5IIr9o8jiAh3pTEyqrUovz4otKc1OJDjMlAV01klhJNzgemhLySeENjE3NT Y1NLEwsTM0vShJXEeQ+2WgcKCaQnlqRmp6YWpBbBbGHi4JRqYIwr8b38s3TWww2J+escWr40 7O26qsGbUX6q5apByR6NDKYly9qy7819kxq6nsvQlSf4Plv566cf2rrlZJnzb1/cU8E7IeZ8 8/UGkczg2vLVrs9ucf0XXCfo33Dv3uptyy13daTqBLG8e7Xt5q7umKf7djvkHOcv/d/Wc/gF j7XFJW1H45KQViWW4oxEQy3mouJEAF4xxD3/AgAA DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-9.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Exynos5420 added support for I2S TDM mode. For this, there are some register changes in the I2S controller. This patch adds the relevant register changes to support I2S in normal mode. This patch adds a quirk for TDM mode and if TDM mode is present all the relevent changes will be applied. Signed-off-by: Padmavathi Venna Reviewed-by: Tomasz Figa --- .../devicetree/bindings/sound/samsung-i2s.txt | 4 + include/linux/platform_data/asoc-s3c.h | 1 + sound/soc/samsung/i2s-regs.h | 15 ++++ sound/soc/samsung/i2s.c | 81 ++++++++++++++++++-- 4 files changed, 93 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/samsung-i2s.txt b/Documentation/devicetree/bindings/sound/samsung-i2s.txt index 25a0024..7386d44 100644 --- a/Documentation/devicetree/bindings/sound/samsung-i2s.txt +++ b/Documentation/devicetree/bindings/sound/samsung-i2s.txt @@ -6,6 +6,10 @@ Required SoC Specific Properties: - samsung,s3c6410-i2s: for 8/16/24bit stereo I2S. - samsung,s5pv210-i2s: for 8/16/24bit multichannel(5.1) I2S with secondary fifo, s/w reset control and internal mux for root clk src. + - samsung,exynos5420-i2s: for 8/16/24bit multichannel(7.1) I2S with + secondary fifo, s/w reset control, internal mux for root clk src and + TDM support. TDM (Time division multiplexing) is to allow transfer of + multiple channel audio data on single data line. - reg: physical base address of the controller and length of memory mapped region. diff --git a/include/linux/platform_data/asoc-s3c.h b/include/linux/platform_data/asoc-s3c.h index 8827259..9efc04d 100644 --- a/include/linux/platform_data/asoc-s3c.h +++ b/include/linux/platform_data/asoc-s3c.h @@ -36,6 +36,7 @@ struct samsung_i2s { */ #define QUIRK_NO_MUXPSR (1 << 2) #define QUIRK_NEED_RSTCLR (1 << 3) +#define QUIRK_SUPPORTS_TDM (1 << 4) /* Quirks of the I2S controller */ u32 quirks; dma_addr_t idma_addr; diff --git a/sound/soc/samsung/i2s-regs.h b/sound/soc/samsung/i2s-regs.h index 30513b7..821a502 100644 --- a/sound/soc/samsung/i2s-regs.h +++ b/sound/soc/samsung/i2s-regs.h @@ -31,6 +31,10 @@ #define I2SLVL1ADDR 0x34 #define I2SLVL2ADDR 0x38 #define I2SLVL3ADDR 0x3c +#define I2SSTR1 0x40 +#define I2SVER 0x44 +#define I2SFIC2 0x48 +#define I2STDM 0x4c #define CON_RSTCLR (1 << 31) #define CON_FRXOFSTATUS (1 << 26) @@ -117,6 +121,17 @@ #define MOD_BCLK_MASK 3 #define MOD_8BIT (1 << 0) +#define EXYNOS5420_MOD_LRP_SHIFT 15 +#define EXYNOS5420_MOD_SDF_SHIFT 6 +#define EXYNOS5420_MOD_RCLK_SHIFT 4 +#define EXYNOS5420_MOD_BCLK_SHIFT 0 +#define EXYNOS5420_MOD_BCLK_64FS 4 +#define EXYNOS5420_MOD_BCLK_96FS 5 +#define EXYNOS5420_MOD_BCLK_128FS 6 +#define EXYNOS5420_MOD_BCLK_192FS 7 +#define EXYNOS5420_MOD_BCLK_256FS 8 +#define EXYNOS5420_MOD_BCLK_MASK 0xf + #define MOD_CDCLKCON (1 << 12) #define PSR_PSREN (1 << 15) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 1671d9b..ce487c2 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -199,7 +199,12 @@ static inline bool is_manager(struct i2s_dai *i2s) /* Read RCLK of I2S (in multiples of LRCLK) */ static inline unsigned get_rfs(struct i2s_dai *i2s) { - u32 rfs = (readl(i2s->addr + I2SMOD) >> MOD_RCLK_SHIFT); + u32 rfs; + + if (i2s->quirks & QUIRK_SUPPORTS_TDM) + rfs = readl(i2s->addr + I2SMOD) >> EXYNOS5420_MOD_RCLK_SHIFT; + else + rfs = (readl(i2s->addr + I2SMOD) >> MOD_RCLK_SHIFT); rfs &= MOD_RCLK_MASK; switch (rfs) { @@ -214,8 +219,12 @@ static inline unsigned get_rfs(struct i2s_dai *i2s) static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) { u32 mod = readl(i2s->addr + I2SMOD); - int rfs_shift = MOD_RCLK_SHIFT; + int rfs_shift; + if (i2s->quirks & QUIRK_SUPPORTS_TDM) + rfs_shift = EXYNOS5420_MOD_RCLK_SHIFT; + else + rfs_shift = MOD_RCLK_SHIFT; mod &= ~(MOD_RCLK_MASK << rfs_shift); switch (rfs) { @@ -239,10 +248,22 @@ static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) /* Read Bit-Clock of I2S (in multiples of LRCLK) */ static inline unsigned get_bfs(struct i2s_dai *i2s) { - u32 bfs = readl(i2s->addr + I2SMOD) >> MOD_BCLK_SHIFT; - bfs &= MOD_BCLK_MASK; + u32 bfs; + + if (i2s->quirks & QUIRK_SUPPORTS_TDM) { + bfs = readl(i2s->addr + I2SMOD) >> EXYNOS5420_MOD_BCLK_SHIFT; + bfs &= EXYNOS5420_MOD_BCLK_MASK; + } else { + bfs = readl(i2s->addr + I2SMOD) >> MOD_BCLK_SHIFT; + bfs &= MOD_BCLK_MASK; + } switch (bfs) { + case 8: return 256; + case 7: return 192; + case 6: return 128; + case 5: return 96; + case 4: return 64; case 3: return 24; case 2: return 16; case 1: return 48; @@ -254,9 +275,22 @@ static inline unsigned get_bfs(struct i2s_dai *i2s) static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) { u32 mod = readl(i2s->addr + I2SMOD); - int bfs_shift = MOD_BCLK_SHIFT; + int bfs_shift; + int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM; - mod &= ~(MOD_BCLK_MASK << bfs_shift); + if (i2s->quirks & QUIRK_SUPPORTS_TDM) { + bfs_shift = EXYNOS5420_MOD_BCLK_SHIFT; + mod &= ~(EXYNOS5420_MOD_BCLK_MASK << bfs_shift); + } else { + bfs_shift = MOD_BCLK_SHIFT; + mod &= ~(MOD_BCLK_MASK << bfs_shift); + } + + /* Non-TDM I2S controllers do not support BCLK > 48 * FS */ + if (!tdm && bfs > 48) { + dev_err(&i2s->pdev->dev, "Unsupported BCLK divider\n"); + return; + } switch (bfs) { case 48: @@ -271,6 +305,21 @@ static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) case 16: mod |= (MOD_BCLK_16FS << bfs_shift); break; + case 64: + mod |= (EXYNOS5420_MOD_BCLK_64FS << bfs_shift); + break; + case 96: + mod |= (EXYNOS5420_MOD_BCLK_96FS << bfs_shift); + break; + case 128: + mod |= (EXYNOS5420_MOD_BCLK_128FS << bfs_shift); + break; + case 192: + mod |= (EXYNOS5420_MOD_BCLK_192FS << bfs_shift); + break; + case 256: + mod |= (EXYNOS5420_MOD_BCLK_256FS << bfs_shift); + break; default: dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n"); return; @@ -496,10 +545,17 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, { struct i2s_dai *i2s = to_info(dai); u32 mod = readl(i2s->addr + I2SMOD); - int lrp_shift = MOD_LRP_SHIFT, sdf_shift = MOD_SDF_SHIFT; - int sdf_mask, lrp_rlow; + int lrp_shift, sdf_shift, sdf_mask, lrp_rlow; u32 tmp = 0; + if (i2s->quirks & QUIRK_SUPPORTS_TDM) { + lrp_shift = EXYNOS5420_MOD_LRP_SHIFT; + sdf_shift = EXYNOS5420_MOD_SDF_SHIFT; + } else { + lrp_shift = MOD_LRP_SHIFT; + sdf_shift = MOD_SDF_SHIFT; + } + sdf_mask = MOD_SDF_MASK << sdf_shift; lrp_rlow = MOD_LR_RLOW << lrp_shift; @@ -1253,6 +1309,12 @@ static const struct samsung_i2s_dai_data i2sv5_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR, }; +static const struct samsung_i2s_dai_data i2sv6_dai_type = { + .dai_type = TYPE_PRI, + .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | + QUIRK_SUPPORTS_TDM, +}; + static const struct samsung_i2s_dai_data samsung_dai_type_pri = { .dai_type = TYPE_PRI, }; @@ -1281,6 +1343,9 @@ static const struct of_device_id exynos_i2s_match[] = { }, { .compatible = "samsung,s5pv210-i2s", .data = &i2sv5_dai_type, + }, { + .compatible = "samsung,exynos5420-i2s", + .data = &i2sv6_dai_type, }, {}, };