From patchwork Thu Sep 10 06:40:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 7151091 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8CCFD9F39B for ; Thu, 10 Sep 2015 06:41:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6A7EC208BF for ; Thu, 10 Sep 2015 06:41:22 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id C464A208BD for ; Thu, 10 Sep 2015 06:41:20 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 2C4A4265824; Thu, 10 Sep 2015 08:41:19 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Status: No, score=-2.6 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, RCVD_IN_DNSWL_LOW, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 7052D2612D0; Thu, 10 Sep 2015 08:40:43 +0200 (CEST) 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 3E8152614D4; Thu, 10 Sep 2015 08:40:42 +0200 (CEST) Received: from relmlie3.idc.renesas.com (relmlor4.renesas.com [210.160.252.174]) by alsa0.perex.cz (Postfix) with ESMTP id 2AB2E2612D0 for ; Thu, 10 Sep 2015 08:40:22 +0200 (CEST) Received: from unknown (HELO relmlir2.idc.renesas.com) ([10.200.68.152]) by relmlie3.idc.renesas.com with ESMTP; 10 Sep 2015 15:40:21 +0900 Received: from relmlac4.idc.renesas.com (relmlac4.idc.renesas.com [10.200.69.24]) by relmlir2.idc.renesas.com (Postfix) with ESMTP id A12214CE16; Thu, 10 Sep 2015 15:40:21 +0900 (JST) Received: by relmlac4.idc.renesas.com (Postfix, from userid 0) id 8B641480A5; Thu, 10 Sep 2015 15:40:21 +0900 (JST) Received: from relmlac4.idc.renesas.com (localhost [127.0.0.1]) by relmlac4.idc.renesas.com (Postfix) with ESMTP id 864ED480A3; Thu, 10 Sep 2015 15:40:21 +0900 (JST) Received: from relmlii2.idc.renesas.com [10.200.68.66] by relmlac4.idc.renesas.com with ESMTP id RAC31026; Thu, 10 Sep 2015 15:40:21 +0900 X-IronPort-AV: E=Sophos;i="5.17,502,1437404400"; d="scan'";a="195339388" Received: from mail-hk2apc01lp0215.outbound.protection.outlook.com (HELO APC01-HK2-obe.outbound.protection.outlook.com) ([65.55.88.215]) by relmlii2.idc.renesas.com with ESMTP/TLS/AES256-SHA; 10 Sep 2015 15:40:21 +0900 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=kuninori.morimoto.gx@renesas.com; Received: from morimoto-PC.renesas.com (211.11.155.144) by HK2PR06MB0594.apcprd06.prod.outlook.com (10.161.187.145) with Microsoft SMTP Server (TLS) id 15.1.262.15; Thu, 10 Sep 2015 06:40:19 +0000 Message-ID: <87io7iok6c.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto User-Agent: Wanderlust/2.15.9 Emacs/24.3 Mule/6.0 To: Mark Brown In-Reply-To: <87lhceok83.wl%kuninori.morimoto.gx@renesas.com> References: <87lhceok83.wl%kuninori.morimoto.gx@renesas.com> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Date: Thu, 10 Sep 2015 06:40:19 +0000 X-Originating-IP: [211.11.155.144] X-ClientProxiedBy: TY1PR01CA0014.jpnprd01.prod.outlook.com (25.161.131.152) To HK2PR06MB0594.apcprd06.prod.outlook.com (25.161.187.145) X-Microsoft-Exchange-Diagnostics: 1; HK2PR06MB0594; 2:6hSWWUaU2AIHCnkhbRW6HCC1QO9HUZl5BqZXGpf6oYi9QpLt39tiKhU56owFk6pTJdFWv7TUmmuMURLIfPZkiCDMqLqpUarb6fL4x6q2f6YFCr1b53csNcEZRfqyLH3xpzQfGSS6yDomAm8Zm0pdmg+yl95s6K1okrdYt19E+DY=; 3:S7tRT+/hFy5dBerX6LQkFmlg2m6UXC0tGeMwcmC6BMMfOeke9ae715uWUsyLSMSZ0tqTpNvy9XN2uy7gvbub5znmik7Xt8aFBRpihQnRfYdckg29aQdE4oBuuQWrn4+Tfu20v177NNc5gNxHNB7qrg==; 25:7Wd+iqEM168HyiynBJ3JyzpK8fE1UyFP+wfH/mdksJdMskqeLoh7Xkk00QarQd/0WNcJXecSgW3Qg1cCXKZ/Kxx1fZeFj/Hmk9aE+R+W+lyYnlqjv8aTwJgxdxiKhW76SY9/CWYfeQeVGMEuEt3R4lb4yj8loG3D1M5yxDHSEOVq+pSVrt/kkcIbDRFeVkmQfzuIG0JB9lpBvtsi6FfmSO+KuCEKt7fczwW96uErxYB5Ra4SI7AJA6JP+pg2hUnH X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HK2PR06MB0594; X-Microsoft-Exchange-Diagnostics: 1; HK2PR06MB0594; 20:LXUv0scqHOlGtKto2W23d/2KrwQKf21glWP8TEXJcFTOgBMRf1jJS+JemSpBmSNNcjV3N2owA368wK6ZhGoiT0ubvlU0gx+3KBHIlZSUPedjyMlJ32hS4d1E85VdfaceFb0465n6hw/m7dsTX4jKK72XFW/t8BoF6f97dTe/0ZI2Kr08lFjJ/sKO4IB8T0KPoJyCIjh31v6EjHcQJIRxZURLbL3ZjJbGTyzUGUV3aG5Ox19ZedbaSUfenRTsAthTN8Ic1RURTdrnB0pugiBLq2RXZlWLyjszLpgcvc22k94y8DJqVmxrVVSn8o/DLuUjyGLGQ1yfpPYfPoY7TJV6fzcOkRVFj4seJVzM4YzwZjTp6bqs1VaEN6zOHkGmEsTUux1CIyUSna+Bz0r1KoiIV+JoVtNByW15Oay1WBhRraP27oiqxiHOqhO8pMWzZPjyjoGBJ5n70j15mnklTGoHE1gwDuLQwi69P16NCylKwU0oFb3Zp3e+aypSguY4hd++; 4:rJnILneBqo23H00wnt7/Q5IdmG7q3fcFFca4y7uQNtt73QKGgbUtv++DuhXQEOqis8QuwtX37cZPQfPrpvqVJFdA9ca8sz+BX8m3gETAezbS1Ysnl1VkV88GOFR4nMWQuXJne7oR4pMYkiZeuAdlhpGieCcmWN2rEnN+oNXNWwNDBJoCghIFl8ONtO5BtoxtpxHt+DSY64uX5JbEuSNN8zRyFyYdhszNG+Drwrx5D0/oVW3D/mJBa5zC1vtJB8SWS3gUz1Coz/OSGpPLHtaaa2pNgg5ZTdXtAkhLMkhnqHuRB1O+v4aSzh+okwPRysAw X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(8121501046)(3002001); SRVR:HK2PR06MB0594; BCL:0; PCL:0; RULEID:; SRVR:HK2PR06MB0594; X-Forefront-PRVS: 06952FC175 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(6009001)(189002)(199003)(5001860100001)(5001830100001)(87976001)(40100003)(50466002)(19580395003)(83506001)(122386002)(69596002)(189998001)(64706001)(36756003)(110136002)(19580405001)(66066001)(5001960100002)(5004730100002)(23726002)(92566002)(50986999)(54356999)(76176999)(77156002)(47776003)(46406003)(33646002)(106356001)(46102003)(53416004)(229853001)(105586002)(2950100001)(4001350100001)(97736004)(42186005)(4001540100001)(68736005)(86362001)(62966003)(77096005)(81156007)(5007970100001)(101416001); DIR:OUT; SFP:1102; SCL:1; SRVR:HK2PR06MB0594; H:morimoto-PC.renesas.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; HK2PR06MB0594; 23:lsl6FWZKm91raAYPOmsomAKSq/UgZ44mz1HIOoC7a?= =?us-ascii?Q?mcAFNbq4wf1M6ybY1Z/JfBDhXsDyKlGyqlVNh6jqBaPcRWhEaSvw7ycVljD0?= =?us-ascii?Q?MiyPJbWytQ4OPtF7ict8Kky6f90/zg3OEl38gJ+ID0yH4sl2APqCjsoUHiAg?= =?us-ascii?Q?wHOUaklF7FgJxS0405hu52LBBtlfe4yWYkxNBQo/0tB7aqSnfsQF093OUmbz?= =?us-ascii?Q?+1wrQxtOCR9yGOw3c04cWALvk6vAdJxA9SgbvQtyXN/gNVJyFeg56ZiUgzzE?= =?us-ascii?Q?cwXjROunAarNXwViMss76M4mJFrLjUYAzX3zjqh9hfv60he/79Xz/YZUijRa?= =?us-ascii?Q?BWGm1d1s5eBcpGrCyzYVVCSOkrWfd+ueGicYf8nenbNbZZcKou9U+aNTCSEE?= =?us-ascii?Q?kex1IgQRAGygEz8fdBLZ0/HArs5Bu1+zmIBapY+2J4El+NY+FYzlG3EijVNO?= =?us-ascii?Q?28wqtPKP7bbsPW+WK/WgyjhlqJFLkKurV+1pq2HCWoeaqlqB6Rn/ZshYQS99?= =?us-ascii?Q?Iu+AXXP7NOJB+nJFYgVuH3vTZzIEooGpVl+NNQuMSO+gzXFkUev+9oNx/vHm?= =?us-ascii?Q?xo54wapuEZ9O1XGM9wATFjlrf22KdYj51bLwUFxtY1iz7yD2ga+180CJUAdo?= =?us-ascii?Q?o8a1DJDBJB6pIMiqD+lnPrdUGYXgKpzInfcLm91PSEmwqZsBWeFEAJrnvQum?= =?us-ascii?Q?Z53Thop5vbJiZc2mip13sXklk2LHYQmL+57sLwoA1JXiWjo5lwjq2s95jE36?= =?us-ascii?Q?QbFnkJHauZ9ELbK08sqhdOrHIBPEYR+NnFYqzyBWrqiIex28R/1QoEoRs07b?= =?us-ascii?Q?Qh/Spg2I3o1g457/U2Qia4GO06S2GrM9mZMp8Q4yyQ6WfJ6AZmimX7t8EczM?= =?us-ascii?Q?kaa2c9FOGlscwWeju0WS2kdt2mDVnDAr8c1K96szLsxHB0EwVTkVjGyI0FIx?= =?us-ascii?Q?LLVXGQT71h5HWUv5A54GVApBIMdPHOc/lAb8u4z5pllPH1eTJIATmG5OhBEy?= =?us-ascii?Q?vW1hyII+vdBmyyy7Y0OCZhNAmjV1soIt29v9HsRUuR2SZqeSFYkuOkQFKXq2?= =?us-ascii?Q?wwGM3DourvPVoKDY/UZCT71NyITlcfWd1GdMw6wFz9q9DduUoCb2/ORcc328?= =?us-ascii?Q?BYDC4uMwSxEuAedg2G4AeMDz2CI7idlHGwpTuDDVfZ8PyhCo/41Rx3dPc9Fl?= =?us-ascii?Q?831Qa00QeD3lnmSVa5f3Z6KNJDcsaKkIUgppX2SwLSfMiaUiVN9sKPA64SAZ?= =?us-ascii?Q?1yKqRUSJ/SHWUlcJJc=3D?= X-Microsoft-Exchange-Diagnostics: 1; HK2PR06MB0594; 5:Z4BseYjD8YQiUWCHEy8KfB3dehC4UcAOLOGy5PVbjmAwuVRkeiSZtF1+Mi46LYBZhi6rm6IvcRy73wBIApMynxflHDzbDbkcv2Lae5tS4OjBSpmvN/5KEbcAkb7ICDKRpl+I/cw4xg0yXSEC6OQiHg==; 24:kY2JvQzSKHhwepo2mbdvC6MmB5wbZFfnRMCVyJ3ZuJ906wv7vNRppT3j0GxygPCj2qVmkhkRfOvVIUc5enIZ7a/r341hzabjY06PCVo2/l8=; 20:pDHdoTAGB0HeydzIW65rUAlCGoOHXOeBVXVA0NoyIKX/dIiYgTmYnuF0qqLIYRbo60MgOat5i0L79/BLOUeLu6XM2vQsaTXVHBQi7yBxX92YBsiWEj1I/cazaWmkjVGD2ZTIihkT7Ga3j43Elpfa4XSExOISG5vRY/scHmFcgoI= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Sep 2015 06:40:19.6093 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HK2PR06MB0594 Cc: Linux-ALSA , Simon , Liam Girdwood Subject: [alsa-devel] [PATCH 2/2] ASoC: ak4642: enable to use MCKO as fixed rate output pin on DT 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 From: Kuninori Morimoto ak4642 chip can output clock via MCKO pin as audio reference clock. This patch supports it on DT Signed-off-by: Kuninori Morimoto --- Documentation/devicetree/bindings/sound/ak4642.txt | 22 +++- sound/soc/codecs/ak4642.c | 141 ++++++++++++++------- 2 files changed, 114 insertions(+), 49 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/ak4642.txt b/Documentation/devicetree/bindings/sound/ak4642.txt index 623d4e7..340784d 100644 --- a/Documentation/devicetree/bindings/sound/ak4642.txt +++ b/Documentation/devicetree/bindings/sound/ak4642.txt @@ -7,7 +7,14 @@ Required properties: - compatible : "asahi-kasei,ak4642" or "asahi-kasei,ak4643" or "asahi-kasei,ak4648" - reg : The chip select number on the I2C bus -Example: +Optional properties: + + - #clock-cells : common clock binding; shall be set to 0 + - clocks : common clock binding; MCKI clock + - clock-frequency : common clock binding; frequency of MCKO + - clock-output-names : common clock binding; MCKO clock name + +Example 1: &i2c { ak4648: ak4648@0x12 { @@ -15,3 +22,16 @@ Example: reg = <0x12>; }; }; + +Example 2: + +&i2c { + ak4643: codec@12 { + compatible = "asahi-kasei,ak4643"; + reg = <0x12>; + #clock-cells = <0>; + clocks = <&audio_clock>; + clock-frequency = <12288000>; + clock-output-names = "ak4643_mcko"; + }; +}; diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 9af06d3..b5c4981 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -23,6 +23,8 @@ * AK4648 is tested. */ +#include +#include #include #include #include @@ -128,11 +130,8 @@ #define I2S (3 << 0) /* MD_CTL2 */ -#define FS0 (1 << 0) -#define FS1 (1 << 1) -#define FS2 (1 << 2) -#define FS3 (1 << 5) -#define FS_MASK (FS0 | FS1 | FS2 | FS3) +#define FS(val) (((val & 0x7) << 0) | ((val & 0x8) << 2)) +#define PS(val) ((val & 0x3) << 6) /* MD_CTL3 */ #define BST1 (1 << 3) @@ -147,6 +146,7 @@ struct ak4642_drvdata { struct ak4642_priv { const struct ak4642_drvdata *drvdata; + struct clk *mcko; }; /* @@ -430,56 +430,55 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } +static int ak4642_set_mcko(struct snd_soc_codec *codec, + u32 frequency) +{ + u32 fs_list[] = { + [0] = 8000, + [1] = 12000, + [2] = 16000, + [3] = 24000, + [4] = 7350, + [5] = 11025, + [6] = 14700, + [7] = 22050, + [10] = 32000, + [11] = 48000, + [14] = 29400, + [15] = 44100, + }; + u32 ps_list[] = { + [0] = 256, + [1] = 128, + [2] = 64, + [3] = 32 + }; + int ps, fs; + + for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) { + for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) { + if (frequency == ps_list[ps] * fs_list[fs]) { + snd_soc_write(codec, MD_CTL2, PS(ps) | FS(fs)); + return 0; + } + } + } + + return 0; +} + static int ak4642_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; - u8 rate; + struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec); + u32 rate = clk_get_rate(priv->mcko); - switch (params_rate(params)) { - case 7350: - rate = FS2; - break; - case 8000: - rate = 0; - break; - case 11025: - rate = FS2 | FS0; - break; - case 12000: - rate = FS0; - break; - case 14700: - rate = FS2 | FS1; - break; - case 16000: - rate = FS1; - break; - case 22050: - rate = FS2 | FS1 | FS0; - break; - case 24000: - rate = FS1 | FS0; - break; - case 29400: - rate = FS3 | FS2 | FS1; - break; - case 32000: - rate = FS3 | FS1; - break; - case 44100: - rate = FS3 | FS2 | FS1 | FS0; - break; - case 48000: - rate = FS3 | FS1 | FS0; - break; - default: - return -EINVAL; - } - snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate); + if (!rate) + rate = params_rate(params) * 256; - return 0; + return ak4642_set_mcko(codec, rate); } static int ak4642_set_bias_level(struct snd_soc_codec *codec, @@ -532,7 +531,18 @@ static int ak4642_resume(struct snd_soc_codec *codec) return 0; } +static int ak4642_probe(struct snd_soc_codec *codec) +{ + struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec); + + if (priv->mcko) + ak4642_set_mcko(codec, clk_get_rate(priv->mcko)); + + return 0; +} + static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { + .probe = ak4642_probe, .resume = ak4642_resume, .set_bias_level = ak4642_set_bias_level, .controls = ak4642_snd_controls, @@ -580,6 +590,35 @@ static const struct ak4642_drvdata ak4648_drvdata = { .extended_frequencies = 1, }; +#ifdef CONFIG_COMMON_CLK +static struct clk *ak4642_of_parse_mcko(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct clk *clk; + const char *clk_name = np->name; + const char *parent_clk_name = NULL; + u32 rate; + + if (of_property_read_u32(np, "clock-frequency", &rate)) + return NULL; + + if (of_property_read_bool(np, "clocks")) + parent_clk_name = of_clk_get_parent_name(np, 0); + + of_property_read_string(np, "clock-output-names", &clk_name); + + clk = clk_register_fixed_rate(dev, clk_name, parent_clk_name, + (parent_clk_name) ? 0 : CLK_IS_ROOT, + rate); + if (!IS_ERR(clk)) + of_clk_add_provider(np, of_clk_src_simple_get, clk); + + return clk; +} +#else +#define ak4642_of_parse_mcko(d) 0 +#endif + static const struct of_device_id ak4642_of_match[]; static int ak4642_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) @@ -589,10 +628,15 @@ static int ak4642_i2c_probe(struct i2c_client *i2c, const struct ak4642_drvdata *drvdata = NULL; struct regmap *regmap; struct ak4642_priv *priv; + struct clk *mcko = NULL; if (np) { const struct of_device_id *of_id; + mcko = ak4642_of_parse_mcko(dev); + if (IS_ERR(mcko)) + mcko = NULL; + of_id = of_match_device(ak4642_of_match, dev); if (of_id) drvdata = of_id->data; @@ -610,6 +654,7 @@ static int ak4642_i2c_probe(struct i2c_client *i2c, return -ENOMEM; priv->drvdata = drvdata; + priv->mcko = mcko; i2c_set_clientdata(i2c, priv);