From patchwork Sat Dec 14 05:51:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 3346511 Return-Path: X-Original-To: patchwork-ltsi-dev@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 7F6CA9F243 for ; Sat, 14 Dec 2013 06:25:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 689B620608 for ; Sat, 14 Dec 2013 06:25:49 +0000 (UTC) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) by mail.kernel.org (Postfix) with ESMTP id 2BD8220035 for ; Sat, 14 Dec 2013 06:25:48 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [IPv6:::1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 6AF35B9F; Sat, 14 Dec 2013 06:23:27 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp2.linuxfoundation.org (smtp2.linux-foundation.org [172.17.192.36]) by mail.linuxfoundation.org (Postfix) with ESMTP id 08248BAD for ; Sat, 14 Dec 2013 06:23:16 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from kirsty.vergenet.net (kirsty.vergenet.net [202.4.237.240]) by smtp2.linuxfoundation.org (Postfix) with ESMTP id ABA581DD76 for ; Sat, 14 Dec 2013 06:23:14 +0000 (UTC) Received: from penelope.isobedori.kobe.vergenet.net (g1-27-253-251-111.bmobile.ne.jp [27.253.251.111]) by kirsty.vergenet.net (Postfix) with ESMTP id 8C8012671D5; Sat, 14 Dec 2013 16:58:29 +1100 (EST) Received: by penelope.isobedori.kobe.vergenet.net (Postfix, from userid 7100) id C70467C0391; Sat, 14 Dec 2013 14:53:56 +0900 (JST) From: Simon Horman To: ltsi-dev@lists.linuxfoundation.org Date: Sat, 14 Dec 2013 14:51:58 +0900 Message-Id: <1387000406-29111-150-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1387000406-29111-1-git-send-email-horms+renesas@verge.net.au> References: <1387000406-29111-1-git-send-email-horms+renesas@verge.net.au> X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,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 Cc: Magnus Damm Subject: [LTSI-dev] [PATCH 149/237] ARM: shmobile: bockw: add R-Car sound support (PIO) X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuninori Morimoto This patch enables R-Car sound, AK4643 (CN19) and AK4554 (CN20/CN21) codec chip on Bock-W. But, it supports PIO transfer only at this point. User can check sound settings (Dip-switch/PFC etc) via this patch, but will get under/over flow error when playback/capture. Because PIO transfer via SSI will be interrupted "sampling rate" times per 1 second. DMA transfer will be supported when HPB-DMAC was enabled on r8a7778. You will notice strange ALSA sound card HW numbering on Bock-W board. This came from AK4554 strange format on playback/capture. The format on playback/capture is same on "normal" codec chip, but AK4554 was different. Because of that, AK4554 playback/capture are registered as a different sound card. Signed-off-by: Kuninori Morimoto [horms+renesas@verge.net.au: squashed cleanup of SND_SOC_xxx in Kconfig by Kuninori Morimoto] Signed-off-by: Simon Horman (cherry picked from commit 688e6a6df880ee70e76f6ec1991dd0f186c25329) Signed-off-by: Simon Horman Conflicts: arch/arm/mach-shmobile/board-bockw.c --- arch/arm/mach-shmobile/Kconfig | 2 + arch/arm/mach-shmobile/board-bockw.c | 274 ++++++++++++++++++++++++++++++++++- 2 files changed, 275 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index b452405..d01e427 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -168,6 +168,8 @@ config MACH_BOCKW select RENESAS_INTC_IRQPIN select REGULATOR_FIXED_VOLTAGE if REGULATOR select USE_OF + select SND_SOC_AK4554 if SND_SIMPLE_CARD + select SND_SOC_AK4642 if SND_SIMPLE_CARD config MACH_BOCKW_REFERENCE bool "BOCK-W - Reference Device Tree Implementation" diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index 97e1f5e..dffaf68 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c @@ -37,9 +37,12 @@ #include #include #include +#include +#include #define FPGA 0x18200000 #define IRQ0MR 0x30 +#define COMCTLR 0x101c static void __iomem *fpga; /* @@ -67,6 +70,35 @@ static void __iomem *fpga; * SW19 (MMC) 1 pin */ +/* + * SSI settings + * + * SW45: 1-4 side (SSI5 out, ROUT/LOUT CN19 Mid) + * SW46: 1101 (SSI6 Recorde) + * SW47: 1110 (SSI5 Playback) + * SW48: 11 (Recorde power) + * SW49: 1 (SSI slave mode) + * SW50: 1111 (SSI7, SSI8) + * SW51: 1111 (SSI3, SSI4) + * SW54: 1pin (ak4554 FPGA control) + * SW55: 1 (CLKB is 24.5760MHz) + * SW60: 1pin (ak4554 FPGA control) + * SW61: 3pin (use X11 clock) + * SW78: 3-6 (ak4642 connects I2C0) + * + * You can use sound as + * + * hw0: CN19: SSI56-AK4643 + * hw1: CN21: SSI3-AK4554(playback) + * hw2: CN21: SSI4-AK4554(capture) + * hw3: CN20: SSI7-AK4554(playback) + * hw4: CN20: SSI8-AK4554(capture) + * + * this command is required when playback on hw0. + * + * # amixer set "LINEOUT Mixer DACL" on + */ + /* Dummy supplies, where voltage doesn't matter */ static struct regulator_consumer_supply dummy_supplies[] = { REGULATOR_SUPPLY("vddvario", "smsc911x"), @@ -128,7 +160,9 @@ static struct sh_eth_plat_data ether_platform_data __initdata = { static struct i2c_board_info i2c0_devices[] = { { I2C_BOARD_INFO("rx8581", 0x51), - }, + }, { + I2C_BOARD_INFO("ak4643", 0x12), + } }; /* HSPI*/ @@ -211,7 +245,213 @@ static struct platform_device_info vin##idx##_info __initdata = { \ R8A7778_VIN(0); R8A7778_VIN(1); +/* Sound */ +static struct resource rsnd_resources[] __initdata = { + [RSND_GEN1_SRU] = DEFINE_RES_MEM(0xffd90000, 0x1000), + [RSND_GEN1_SSI] = DEFINE_RES_MEM(0xffd91000, 0x1240), + [RSND_GEN1_ADG] = DEFINE_RES_MEM(0xfffe0000, 0x24), +}; + +static struct rsnd_ssi_platform_info rsnd_ssi[] = { + RSND_SSI_UNUSED, /* SSI 0 */ + RSND_SSI_UNUSED, /* SSI 1 */ + RSND_SSI_UNUSED, /* SSI 2 */ + RSND_SSI_SET(1, 0, gic_iid(0x85), RSND_SSI_PLAY), + RSND_SSI_SET(2, 0, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE | RSND_SSI_CLK_FROM_ADG), + RSND_SSI_SET(0, 0, gic_iid(0x86), RSND_SSI_PLAY), + RSND_SSI_SET(0, 0, gic_iid(0x86), 0), + RSND_SSI_SET(3, 0, gic_iid(0x86), RSND_SSI_PLAY), + RSND_SSI_SET(4, 0, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE | RSND_SSI_CLK_FROM_ADG), +}; + +static struct rsnd_scu_platform_info rsnd_scu[9] = { + /* no member at this point */ +}; + +enum { + AK4554_34 = 0, + AK4643_56, + AK4554_78, + SOUND_MAX, +}; + +static int rsnd_codec_power(int id, int enable) +{ + static int sound_user[SOUND_MAX] = {0, 0, 0}; + int *usr = NULL; + u32 bit; + + switch (id) { + case 3: + case 4: + usr = sound_user + AK4554_34; + bit = (1 << 10); + break; + case 5: + case 6: + usr = sound_user + AK4643_56; + bit = (1 << 6); + break; + case 7: + case 8: + usr = sound_user + AK4554_78; + bit = (1 << 7); + break; + } + + if (!usr) + return -EIO; + + if (enable) { + if (*usr == 0) { + u32 val = ioread16(fpga + COMCTLR); + val &= ~bit; + iowrite16(val, fpga + COMCTLR); + } + + (*usr)++; + } else { + if (*usr == 0) + return 0; + + (*usr)--; + + if (*usr == 0) { + u32 val = ioread16(fpga + COMCTLR); + val |= bit; + iowrite16(val, fpga + COMCTLR); + } + } + + return 0; +} + +static int rsnd_start(int id) +{ + return rsnd_codec_power(id, 1); +} + +static int rsnd_stop(int id) +{ + return rsnd_codec_power(id, 0); +} + +static struct rcar_snd_info rsnd_info = { + .flags = RSND_GEN1, + .ssi_info = rsnd_ssi, + .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), + .scu_info = rsnd_scu, + .scu_info_nr = ARRAY_SIZE(rsnd_scu), + .start = rsnd_start, + .stop = rsnd_stop, +}; + +static struct asoc_simple_card_info rsnd_card_info[] = { + /* SSI5, SSI6 */ + { + .name = "AK4643", + .card = "SSI56-AK4643", + .codec = "ak4642-codec.0-0012", + .platform = "rcar_sound", + .daifmt = SND_SOC_DAIFMT_LEFT_J, + .cpu_dai = { + .name = "rsnd-dai.0", + .fmt = SND_SOC_DAIFMT_CBS_CFS, + }, + .codec_dai = { + .name = "ak4642-hifi", + .fmt = SND_SOC_DAIFMT_CBM_CFM, + .sysclk = 11289600, + }, + }, + /* SSI3 */ + { + .name = "AK4554", + .card = "SSI3-AK4554(playback)", + .codec = "ak4554-adc-dac.0", + .platform = "rcar_sound", + .cpu_dai = { + .name = "rsnd-dai.1", + .fmt = SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_RIGHT_J, + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI4 */ + { + .name = "AK4554", + .card = "SSI4-AK4554(capture)", + .codec = "ak4554-adc-dac.0", + .platform = "rcar_sound", + .cpu_dai = { + .name = "rsnd-dai.2", + .fmt = SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_LEFT_J, + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI7 */ + { + .name = "AK4554", + .card = "SSI7-AK4554(playback)", + .codec = "ak4554-adc-dac.1", + .platform = "rcar_sound", + .cpu_dai = { + .name = "rsnd-dai.3", + .fmt = SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_RIGHT_J, + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + }, + /* SSI8 */ + { + .name = "AK4554", + .card = "SSI8-AK4554(capture)", + .codec = "ak4554-adc-dac.1", + .platform = "rcar_sound", + .cpu_dai = { + .name = "rsnd-dai.4", + .fmt = SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_LEFT_J, + }, + .codec_dai = { + .name = "ak4554-hifi", + }, + } +}; + static const struct pinctrl_map bockw_pinctrl_map[] = { + /* AUDIO */ + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "audio_clk_a", "audio_clk"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "audio_clk_b", "audio_clk"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi34_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi3_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi4_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi5_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi5_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi6_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi6_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi78_ctrl", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi7_data", "ssi"), + PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", + "ssi8_data", "ssi"), /* Ether */ PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778", "ether_rmii", "ether"), @@ -259,6 +499,8 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { static void __init bockw_init(void) { void __iomem *base; + struct clk *clk; + int i; r8a7778_clock_init(); r8a7778_init_irq_extpin(1); @@ -341,6 +583,36 @@ static void __init bockw_init(void) sdhi0_resources, ARRAY_SIZE(sdhi0_resources), &sdhi0_info, sizeof(struct sh_mobile_sdhi_info)); } + + /* for Audio */ + clk = clk_get(NULL, "audio_clk_b"); + clk_set_rate(clk, 24576000); + clk_put(clk); + rsnd_codec_power(5, 1); /* enable ak4642 */ + + platform_device_register_simple( + "ak4554-adc-dac", 0, NULL, 0); + + platform_device_register_simple( + "ak4554-adc-dac", 1, NULL, 0); + + platform_device_register_resndata( + &platform_bus, "rcar_sound", -1, + rsnd_resources, ARRAY_SIZE(rsnd_resources), + &rsnd_info, sizeof(rsnd_info)); + + for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) { + struct platform_device_info cardinfo = { + .parent = &platform_bus, + .name = "asoc-simple-card", + .id = i, + .data = &rsnd_card_info[i], + .size_data = sizeof(struct asoc_simple_card_info), + .dma_mask = ~0, + }; + + platform_device_register_full(&cardinfo); + } } static const char *bockw_boards_compat_dt[] __initdata = {