From patchwork Thu Mar 11 15:32:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: miguel.aguilar@ridgerun.com X-Patchwork-Id: 84929 Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2BFYFf7003909 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 11 Mar 2010 15:34:56 GMT Received: from dlep34.itg.ti.com ([157.170.170.115]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id o2BFWkvn021530 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 11 Mar 2010 09:32:46 -0600 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep34.itg.ti.com (8.13.7/8.13.7) with ESMTP id o2BFWj5N007588; Thu, 11 Mar 2010 09:32:45 -0600 (CST) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 0B90480627; Thu, 11 Mar 2010 09:32:45 -0600 (CST) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp51.itg.ti.com (dflp51.itg.ti.com [128.247.22.94]) by linux.omap.com (Postfix) with ESMTP id 77DE180626 for ; Thu, 11 Mar 2010 09:32:43 -0600 (CST) Received: from white.ext.ti.com (localhost [127.0.0.1]) by dflp51.itg.ti.com (8.13.7/8.13.7) with ESMTP id o2BFWhGC003764 for ; Thu, 11 Mar 2010 09:32:43 -0600 (CST) Received: from psmtp.com (na3sys009amx226.postini.com [74.125.149.110]) by white.ext.ti.com (8.13.7/8.13.7) with SMTP id o2BFWfEX001773 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 11 Mar 2010 09:32:42 -0600 Received: from source ([74.208.67.6]) (using TLSv1) by na3sys009amx226.postini.com ([74.125.148.10]) with SMTP; Thu, 11 Mar 2010 10:32:42 EST Received: from [201.198.127.70] (helo=localhost.localdomain) by mail.navvo.net with esmtpa (Exim 4.63) (envelope-from ) id 1NpkNK-0001yH-TQ; Thu, 11 Mar 2010 09:32:40 -0600 From: miguel.aguilar@ridgerun.com To: davinci-linux-open-source@linux.davincidsp.com Date: Thu, 11 Mar 2010 09:32:42 -0600 Message-Id: <1268321562-18951-1-git-send-email-miguel.aguilar@ridgerun.com> X-Mailer: git-send-email 1.6.0.4 X-SA-Exim-Connect-IP: 201.198.127.70 X-SA-Exim-Mail-From: miguel.aguilar@ridgerun.com X-Spam-Checker-Version: SpamAssassin 3.1.7-deb (2006-10-05) on mail.navvo.net X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00, NO_REAL_NAME autolearn=ham version=3.1.7-deb Subject: [PATCH v2 2/5] ASoC: DaVinci: Voice Codec Interface X-SA-Exim-Version: 4.2.1 (built Tue, 09 Jan 2007 17:23:22 +0000) X-SA-Exim-Scanned: Yes (on mail.navvo.net) X-pstn-neptune: 0/0/0.00/0 X-pstn-levels: (S:33.23438/99.90000 CV:99.9000 FC:95.5390 LC:95.5390 R:95.9108 P:95.9108 M:97.0282 C:98.6951 ) X-pstn-settings: 2 (0.5000:0.5000) s cv gt3 gt2 gt1 r p m c X-pstn-addresses: from [db-null] Cc: alsa-devel@alsa-project.org, broonie@opensource.wolfsonmicro.com, Miguel Aguilar X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com X-Greylist: Sender succeeded STARTTLS authentication, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 11 Mar 2010 15:34:56 +0000 (UTC) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 047ee39..47e7cce 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -12,6 +12,9 @@ config SND_DAVINCI_SOC_I2S config SND_DAVINCI_SOC_MCASP tristate +config SND_DAVINCI_SOC_VCIF + tristate + config SND_DAVINCI_SOC_EVM tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" depends on SND_DAVINCI_SOC diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile index a6939d7..a93679d 100644 --- a/sound/soc/davinci/Makefile +++ b/sound/soc/davinci/Makefile @@ -2,10 +2,12 @@ snd-soc-davinci-objs := davinci-pcm.o snd-soc-davinci-i2s-objs := davinci-i2s.o snd-soc-davinci-mcasp-objs:= davinci-mcasp.o +snd-soc-davinci-vcif-objs:= davinci-vcif.o obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o +obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o # DAVINCI Machine Support snd-soc-evm-objs := davinci-evm.o diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c new file mode 100644 index 0000000..03f3feb --- /dev/null +++ b/sound/soc/davinci/davinci-vcif.c @@ -0,0 +1,272 @@ +/* + * ALSA SoC Voice Codec Interface for TI DAVINCI processor + * + * Copyright (C) 2010 Texas Instruments. + * + * Author: Miguel Aguilar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "davinci-pcm.h" +#include "davinci-i2s.h" +#include "davinci-vcif.h" + +#define MOD_REG_BIT(val, mask, set) do { \ + if (set) { \ + val |= mask; \ + } else { \ + val &= ~mask; \ + } \ +} while (0) + +struct davinci_vcif_dev { + struct davinci_vc *davinci_vc; + struct davinci_pcm_dma_params dma_params[2]; +}; + +static void davinci_vcif_start(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct davinci_vcif_dev *davinci_vcif_dev = + rtd->dai->cpu_dai->private_data; + struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; + u32 w; + + /* Start the sample generator and enable transmitter/receiver */ + w = readl(davinci_vc->base + DAVINCI_VC_CTRL); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1); + else + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1); + + writel(w, davinci_vc->base + DAVINCI_VC_CTRL); +} + +static void davinci_vcif_stop(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct davinci_vcif_dev *davinci_vcif_dev = + rtd->dai->cpu_dai->private_data; + struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; + u32 w; + + /* Reset transmitter/receiver and sample rate/frame sync generators */ + w = readl(davinci_vc->base + DAVINCI_VC_CTRL); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0); + else + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0); + + writel(w, davinci_vc->base + DAVINCI_VC_CTRL); +} + +static int davinci_vcif_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct davinci_vcif_dev *davinci_vcif_dev = dai->private_data; + struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; + struct davinci_pcm_dma_params *dma_params = + &davinci_vcif_dev->dma_params[substream->stream]; + u32 w; + + /* Restart the codec before setup */ + davinci_vcif_stop(substream); + davinci_vcif_start(substream); + + /* General line settings */ + writel(DAVINCI_VC_CTRL_MASK, davinci_vc->base + DAVINCI_VC_CTRL); + + writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTCLR); + + writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTEN); + + w = readl(davinci_vc->base + DAVINCI_VC_CTRL); + + /* Determine xfer data type */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_U8: + dma_params->data_type = 0; + + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | + DAVINCI_VC_CTRL_RD_UNSIGNED | + DAVINCI_VC_CTRL_WD_BITS_8 | + DAVINCI_VC_CTRL_WD_UNSIGNED, 1); + break; + case SNDRV_PCM_FORMAT_S8: + dma_params->data_type = 1; + + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | + DAVINCI_VC_CTRL_WD_BITS_8, 1); + + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_UNSIGNED | + DAVINCI_VC_CTRL_WD_UNSIGNED, 0); + break; + case SNDRV_PCM_FORMAT_S16_LE: + dma_params->data_type = 2; + + MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | + DAVINCI_VC_CTRL_RD_UNSIGNED | + DAVINCI_VC_CTRL_WD_BITS_8 | + DAVINCI_VC_CTRL_WD_UNSIGNED, 0); + break; + default: + printk(KERN_WARNING "davinci-vcif: unsupported PCM format"); + return -EINVAL; + } + + dma_params->acnt = dma_params->data_type; + + writel(w, davinci_vc->base + DAVINCI_VC_CTRL); + + return 0; +} + +static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + davinci_vcif_start(substream); + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + davinci_vcif_stop(substream); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000 + +static struct snd_soc_dai_ops davinci_vcif_dai_ops = { + .trigger = davinci_vcif_trigger, + .hw_params = davinci_vcif_hw_params, +}; + +struct snd_soc_dai davinci_vcif_dai = { + .name = "davinci-vcif", + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = DAVINCI_VCIF_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = DAVINCI_VCIF_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &davinci_vcif_dai_ops, + +}; +EXPORT_SYMBOL_GPL(davinci_vcif_dai); + +static int davinci_vcif_probe(struct platform_device *pdev) +{ + struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); + struct davinci_vcif_dev *davinci_vcif_dev; + int ret; + + davinci_vcif_dev = kzalloc(sizeof(struct davinci_vcif_dev), GFP_KERNEL); + if (!davinci_vc) { + dev_dbg(&pdev->dev, + "could not allocate memory for private data\n"); + return -ENOMEM; + } + + /* DMA tx params */ + davinci_vcif_dev->davinci_vc = davinci_vc; + davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = + davinci_vc->davinci_vcif.dma_tx_channel; + davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = + davinci_vc->davinci_vcif.dma_tx_addr; + + /* DMA rx params */ + davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = + davinci_vc->davinci_vcif.dma_rx_channel; + davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = + davinci_vc->davinci_vcif.dma_rx_addr; + + davinci_vcif_dai.dev = &pdev->dev; + davinci_vcif_dai.dma_data = davinci_vcif_dev->dma_params; + davinci_vcif_dai.private_data = davinci_vcif_dev; + + ret = snd_soc_register_dai(&davinci_vcif_dai); + if (ret != 0) { + dev_err(&pdev->dev, "could not register dai\n"); + goto fail; + } + + return 0; + +fail: + kfree(davinci_vcif_dev); + + return ret; +} + +static int davinci_vcif_remove(struct platform_device *pdev) +{ + snd_soc_unregister_dai(&davinci_vcif_dai); + + return 0; +} + +static struct platform_driver davinci_vcif_driver = { + .probe = davinci_vcif_probe, + .remove = davinci_vcif_remove, + .driver = { + .name = "davinci_vcif", + .owner = THIS_MODULE, + }, +}; + +static int __init davinci_vcif_init(void) +{ + return platform_driver_probe(&davinci_vcif_driver, davinci_vcif_probe); +} +module_init(davinci_vcif_init); + +static void __exit davinci_vcif_exit(void) +{ + platform_driver_unregister(&davinci_vcif_driver); +} +module_exit(davinci_vcif_exit); + +MODULE_AUTHOR("Miguel Aguilar"); +MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/davinci/davinci-vcif.h b/sound/soc/davinci/davinci-vcif.h new file mode 100644 index 0000000..571c994 --- /dev/null +++ b/sound/soc/davinci/davinci-vcif.h @@ -0,0 +1,28 @@ +/* + * ALSA SoC Voice Codec Interface for TI DAVINCI processor + * + * Copyright (C) 2010 Texas Instruments. + * + * Author: Miguel Aguilar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _DAVINCI_VCIF_H +#define _DAVINCI_VCIF_H + +extern struct snd_soc_dai davinci_vcif_dai; + +#endif