From patchwork Fri Jan 22 18:17:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 74711 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0MIH7sF023977 for ; Fri, 22 Jan 2010 18:17:07 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756029Ab0AVSRG (ORCPT ); Fri, 22 Jan 2010 13:17:06 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756105Ab0AVSRG (ORCPT ); Fri, 22 Jan 2010 13:17:06 -0500 Received: from mail.gmx.net ([213.165.64.20]:53994 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1756029Ab0AVSRB (ORCPT ); Fri, 22 Jan 2010 13:17:01 -0500 Received: (qmail invoked by alias); 22 Jan 2010 18:16:55 -0000 Received: from p57BD1D86.dip0.t-ipconnect.de (EHLO axis700.grange) [87.189.29.134] by mail.gmx.net (mp015) with SMTP; 22 Jan 2010 19:16:55 +0100 X-Authenticated: #20450766 X-Provags-ID: V01U2FsdGVkX19VE7wNop1Vf5HlJ98uvLzxj8AFPXOpj9u52nIFmb YnLH5ip+Ype7dw Received: from lyakh (helo=localhost) by axis700.grange with local-esmtp (Exim 4.63) (envelope-from ) id 1NYO4E-0002Im-0q; Fri, 22 Jan 2010 19:17:10 +0100 Date: Fri, 22 Jan 2010 19:17:09 +0100 (CET) From: Guennadi Liakhovetski To: alsa-devel@alsa-project.org cc: linux-sh@vger.kernel.org, Liam Girdwood , Kuninori Morimoto , Mark Brown , Magnus Damm Subject: [PATCH 2b/4 v2] ASoC: add support for the sh7722 Migo-R board In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Y-GMX-Trusted: 0 X-FuHaFi: 0.39000000000000001 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 8072a6d..a86696b 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -55,4 +61,12 @@ config SND_FSI_DA7210 This option enables generic sound support for the FSI - DA7210 unit +config SND_SIU_MIGOR + tristate "SIU sound support on Migo-R" + depends on SH_MIGOR + select SND_SOC_SH4_SIU + select SND_SOC_WM8978 + help + This option enables sound support for the SH7722 Migo-R board + endmenu diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile index 1d0ec0a..8a5a192 100644 --- a/sound/soc/sh/Makefile +++ b/sound/soc/sh/Makefile @@ -6,7 +6,9 @@ obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o snd-soc-sh7760-ac97-objs := sh7760-ac97.o snd-soc-fsi-ak4642-objs := fsi-ak4642.o snd-soc-fsi-da7210-objs := fsi-da7210.o +snd-soc-migor-objs := migor.o obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o +obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c new file mode 100644 index 0000000..cae832d --- /dev/null +++ b/sound/soc/sh/migor.c @@ -0,0 +1,227 @@ +/* + * ALSA SoC driver for Migo-R + * + * Copyright (C) 2009-2010 Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "../codecs/wm8978.h" +#include "siu.h" + +/* Default 8000Hz sampling frequency */ +static unsigned long codec_freq = 8000 * 512; + +/* External clock, sourced from the codec at the SIUMCKB pin */ +static unsigned long siumckb_recalc(struct clk *clk) +{ + return codec_freq; +} + +static struct clk_ops siumckb_clk_ops = { + .recalc = siumckb_recalc, +}; + +static struct clk siumckb_clk = { + .name = "siumckb_clk", + .id = -1, + .ops = &siumckb_clk_ops, + .rate = 0, /* initialised at run-time */ +}; + +static int migor_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + unsigned int opclk_div; + int ret; + unsigned int rate = params_rate(params); + + /* Configure f_out = rate * 512 */ + switch (rate) { + case 48000: + opclk_div = 0; + break; + case 44100: + opclk_div = 0; + break; + case 32000: + opclk_div = 0x010; + break; + case 24000: + opclk_div = 0x010; + break; + case 22050: + opclk_div = 0x010; + break; + case 16000: + opclk_div = 0x020; + break; + case 11025: + opclk_div = 0x010; + break; + default: + case 8000: + opclk_div = 0x020; + break; + } + + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_OPCLKDIV, opclk_div); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_DACCLK, 8); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, 13000000, rate * 512); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_NB_IF | + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_fmt(rtd->dai->cpu_dai, SND_SOC_DAIFMT_NB_IF | + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + codec_freq = rate * 512; + /* + * This propagates the parent frequency change to children and + * recalculates the frequency table + */ + clk_set_rate(&siumckb_clk, codec_freq); + dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq); + + snd_soc_dai_set_sysclk(rtd->dai->cpu_dai, SIU_CLKB_EXT, codec_freq / 2, + SND_SOC_CLOCK_IN); + + return ret; +} + +static struct snd_soc_ops migor_dai_ops = { + .hw_params = migor_hw_params, +}; + +static const struct snd_soc_dapm_widget migor_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Onboard Microphone", NULL), + SND_SOC_DAPM_MIC("External Microphone", NULL), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + /* Headphone output connected to LHP/RHP, enable OUT4 for VMID */ + { "Headphone", NULL, "OUT4 VMID" }, + { "OUT4 VMID", NULL, "LHP" }, + { "OUT4 VMID", NULL, "RHP" }, + + /* On-board microphone */ + { "RMICN", NULL, "Mic Bias" }, + { "RMICP", NULL, "Mic Bias" }, + { "Mic Bias", NULL, "Onboard Microphone" }, + + /* External microphone */ + { "LMICN", NULL, "Mic Bias" }, + { "LMICP", NULL, "Mic Bias" }, + { "Mic Bias", NULL, "External Microphone" }, +}; + +static int migor_dai_init(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, migor_dapm_widgets, + ARRAY_SIZE(migor_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + + return 0; +} + +/* migor digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link migor_dai = { + .name = "wm8978", + .stream_name = "WM8978", + .cpu_dai = &siu_i2s_dai, + .codec_dai = &wm8978_dai, + .ops = &migor_dai_ops, + .init = migor_dai_init, +}; + +/* migor audio machine driver */ +static struct snd_soc_card snd_soc_migor = { + .name = "Migo-R", + .platform = &siu_platform, + .dai_link = &migor_dai, + .num_links = 1, +}; + +/* migor audio subsystem */ +static struct snd_soc_device migor_snd_devdata = { + .card = &snd_soc_migor, + .codec_dev = &soc_codec_dev_wm8978, +}; + +static struct platform_device *migor_snd_device; + +static int __init migor_init(void) +{ + int ret; + + ret = clk_register(&siumckb_clk); + if (ret < 0) + return ret; + + /* Port number used on this machine: port B */ + migor_snd_device = platform_device_alloc("soc-audio", 1); + if (!migor_snd_device) { + ret = -ENOMEM; + goto epdevalloc; + } + + platform_set_drvdata(migor_snd_device, &migor_snd_devdata); + + migor_snd_devdata.dev = &migor_snd_device->dev; + + ret = platform_device_add(migor_snd_device); + if (ret) + goto epdevadd; + + return 0; + +epdevadd: + platform_device_put(migor_snd_device); +epdevalloc: + clk_unregister(&siumckb_clk); + return ret; +} + +static void __exit migor_exit(void) +{ + clk_unregister(&siumckb_clk); + platform_device_unregister(migor_snd_device); +} + +module_init(migor_init); +module_exit(migor_exit); + +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_DESCRIPTION("ALSA SoC Migor"); +MODULE_LICENSE("GPL v2");