Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MFD: DaVinci Voice Codec

This is the MFD driver for the DaVinci Voice codec, it has two clients:

* Voice codec interface
* Voice codec CQ93VC

Signed-off-by: Miguel Aguilar <miguel.aguilar@ridgerun.com>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Miguel Aguilar and committed by
Mark Brown
ca26308c d9ad6296

+320
+4
drivers/mfd/Kconfig
··· 53 53 This driver supports the SDHI hardware block found in many 54 54 SuperH Mobile SoCs. 55 55 56 + config MFD_DAVINCI_VOICECODEC 57 + tristate 58 + select MFD_CORE 59 + 56 60 config MFD_DM355EVM_MSP 57 61 bool "DaVinci DM355 EVM microcontroller" 58 62 depends on I2C && MACH_DAVINCI_DM355_EVM
+1
drivers/mfd/Makefile
··· 12 12 obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 13 13 obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o 14 14 15 + obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o 15 16 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o 16 17 17 18 obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o
+189
drivers/mfd/davinci_voicecodec.c
··· 1 + /* 2 + * DaVinci Voice Codec Core Interface for TI platforms 3 + * 4 + * Copyright (C) 2010 Texas Instruments, Inc 5 + * 6 + * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; either version 2 of the License, or 11 + * (at your option) any later version. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + * 18 + * You should have received a copy of the GNU General Public License 19 + * along with this program; if not, write to the Free Software 20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 + */ 22 + 23 + #include <linux/init.h> 24 + #include <linux/module.h> 25 + #include <linux/device.h> 26 + #include <linux/delay.h> 27 + #include <linux/io.h> 28 + #include <linux/clk.h> 29 + 30 + #include <sound/pcm.h> 31 + 32 + #include <linux/mfd/davinci_voicecodec.h> 33 + 34 + u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg) 35 + { 36 + return __raw_readl(davinci_vc->base + reg); 37 + } 38 + 39 + void davinci_vc_write(struct davinci_vc *davinci_vc, 40 + int reg, u32 val) 41 + { 42 + __raw_writel(val, davinci_vc->base + reg); 43 + } 44 + 45 + static int __init davinci_vc_probe(struct platform_device *pdev) 46 + { 47 + struct davinci_vc *davinci_vc; 48 + struct resource *res, *mem; 49 + struct mfd_cell *cell = NULL; 50 + int ret; 51 + 52 + davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL); 53 + if (!davinci_vc) { 54 + dev_dbg(&pdev->dev, 55 + "could not allocate memory for private data\n"); 56 + return -ENOMEM; 57 + } 58 + 59 + davinci_vc->clk = clk_get(&pdev->dev, NULL); 60 + if (IS_ERR(davinci_vc->clk)) { 61 + dev_dbg(&pdev->dev, 62 + "could not get the clock for voice codec\n"); 63 + ret = -ENODEV; 64 + goto fail1; 65 + } 66 + clk_enable(davinci_vc->clk); 67 + 68 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 69 + if (!res) { 70 + dev_err(&pdev->dev, "no mem resource\n"); 71 + ret = -ENODEV; 72 + goto fail2; 73 + } 74 + 75 + davinci_vc->pbase = res->start; 76 + davinci_vc->base_size = resource_size(res); 77 + 78 + mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size, 79 + pdev->name); 80 + if (!mem) { 81 + dev_err(&pdev->dev, "VCIF region already claimed\n"); 82 + ret = -EBUSY; 83 + goto fail2; 84 + } 85 + 86 + davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size); 87 + if (!davinci_vc->base) { 88 + dev_err(&pdev->dev, "can't ioremap mem resource.\n"); 89 + ret = -ENOMEM; 90 + goto fail3; 91 + } 92 + 93 + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 94 + if (!res) { 95 + dev_err(&pdev->dev, "no DMA resource\n"); 96 + return -ENXIO; 97 + } 98 + 99 + davinci_vc->davinci_vcif.dma_tx_channel = res->start; 100 + davinci_vc->davinci_vcif.dma_tx_addr = 101 + (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO); 102 + 103 + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 104 + if (!res) { 105 + dev_err(&pdev->dev, "no DMA resource\n"); 106 + return -ENXIO; 107 + } 108 + 109 + davinci_vc->davinci_vcif.dma_rx_channel = res->start; 110 + davinci_vc->davinci_vcif.dma_rx_addr = 111 + (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO); 112 + 113 + davinci_vc->dev = &pdev->dev; 114 + davinci_vc->pdev = pdev; 115 + 116 + /* Voice codec interface client */ 117 + cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; 118 + cell->name = "davinci_vcif"; 119 + cell->driver_data = davinci_vc; 120 + 121 + /* Voice codec CQ93VC client */ 122 + cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; 123 + cell->name = "cq93vc"; 124 + cell->driver_data = davinci_vc; 125 + 126 + ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, 127 + DAVINCI_VC_CELLS, NULL, 0); 128 + if (ret != 0) { 129 + dev_err(&pdev->dev, "fail to register client devices\n"); 130 + goto fail4; 131 + } 132 + 133 + return 0; 134 + 135 + fail4: 136 + iounmap(davinci_vc->base); 137 + fail3: 138 + release_mem_region(davinci_vc->pbase, davinci_vc->base_size); 139 + fail2: 140 + clk_disable(davinci_vc->clk); 141 + clk_put(davinci_vc->clk); 142 + davinci_vc->clk = NULL; 143 + fail1: 144 + kfree(davinci_vc); 145 + 146 + return ret; 147 + } 148 + 149 + static int __devexit davinci_vc_remove(struct platform_device *pdev) 150 + { 151 + struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); 152 + 153 + mfd_remove_devices(&pdev->dev); 154 + 155 + iounmap(davinci_vc->base); 156 + release_mem_region(davinci_vc->pbase, davinci_vc->base_size); 157 + 158 + clk_disable(davinci_vc->clk); 159 + clk_put(davinci_vc->clk); 160 + davinci_vc->clk = NULL; 161 + 162 + kfree(davinci_vc); 163 + 164 + return 0; 165 + } 166 + 167 + static struct platform_driver davinci_vc_driver = { 168 + .driver = { 169 + .name = "davinci_voicecodec", 170 + .owner = THIS_MODULE, 171 + }, 172 + .remove = __devexit_p(davinci_vc_remove), 173 + }; 174 + 175 + static int __init davinci_vc_init(void) 176 + { 177 + return platform_driver_probe(&davinci_vc_driver, davinci_vc_probe); 178 + } 179 + module_init(davinci_vc_init); 180 + 181 + static void __exit davinci_vc_exit(void) 182 + { 183 + platform_driver_unregister(&davinci_vc_driver); 184 + } 185 + module_exit(davinci_vc_exit); 186 + 187 + MODULE_AUTHOR("Miguel Aguilar"); 188 + MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface"); 189 + MODULE_LICENSE("GPL");
+126
include/linux/mfd/davinci_voicecodec.h
··· 1 + /* 2 + * DaVinci Voice Codec Core Interface for TI platforms 3 + * 4 + * Copyright (C) 2010 Texas Instruments, Inc 5 + * 6 + * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; either version 2 of the License, or 11 + * (at your option) any later version. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + * 18 + * You should have received a copy of the GNU General Public License 19 + * along with this program; if not, write to the Free Software 20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 + */ 22 + 23 + #ifndef __LINUX_MFD_DAVINCI_VOICECODEC_H_ 24 + #define __LINUX_MFD_DAVINIC_VOICECODEC_H_ 25 + 26 + #include <linux/kernel.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/mfd/core.h> 29 + 30 + #include <mach/edma.h> 31 + 32 + /* 33 + * Register values. 34 + */ 35 + #define DAVINCI_VC_PID 0x00 36 + #define DAVINCI_VC_CTRL 0x04 37 + #define DAVINCI_VC_INTEN 0x08 38 + #define DAVINCI_VC_INTSTATUS 0x0c 39 + #define DAVINCI_VC_INTCLR 0x10 40 + #define DAVINCI_VC_EMUL_CTRL 0x14 41 + #define DAVINCI_VC_RFIFO 0x20 42 + #define DAVINCI_VC_WFIFO 0x24 43 + #define DAVINCI_VC_FIFOSTAT 0x28 44 + #define DAVINCI_VC_TST_CTRL 0x2C 45 + #define DAVINCI_VC_REG05 0x94 46 + #define DAVINCI_VC_REG09 0xA4 47 + #define DAVINCI_VC_REG12 0xB0 48 + 49 + /* DAVINCI_VC_CTRL bit fields */ 50 + #define DAVINCI_VC_CTRL_MASK 0x5500 51 + #define DAVINCI_VC_CTRL_RSTADC BIT(0) 52 + #define DAVINCI_VC_CTRL_RSTDAC BIT(1) 53 + #define DAVINCI_VC_CTRL_RD_BITS_8 BIT(4) 54 + #define DAVINCI_VC_CTRL_RD_UNSIGNED BIT(5) 55 + #define DAVINCI_VC_CTRL_WD_BITS_8 BIT(6) 56 + #define DAVINCI_VC_CTRL_WD_UNSIGNED BIT(7) 57 + #define DAVINCI_VC_CTRL_RFIFOEN BIT(8) 58 + #define DAVINCI_VC_CTRL_RFIFOCL BIT(9) 59 + #define DAVINCI_VC_CTRL_RFIFOMD_WORD_1 BIT(10) 60 + #define DAVINCI_VC_CTRL_WFIFOEN BIT(12) 61 + #define DAVINCI_VC_CTRL_WFIFOCL BIT(13) 62 + #define DAVINCI_VC_CTRL_WFIFOMD_WORD_1 BIT(14) 63 + 64 + /* DAVINCI_VC_INT bit fields */ 65 + #define DAVINCI_VC_INT_MASK 0x3F 66 + #define DAVINCI_VC_INT_RDRDY_MASK BIT(0) 67 + #define DAVINCI_VC_INT_RERROVF_MASK BIT(1) 68 + #define DAVINCI_VC_INT_RERRUDR_MASK BIT(2) 69 + #define DAVINCI_VC_INT_WDREQ_MASK BIT(3) 70 + #define DAVINCI_VC_INT_WERROVF_MASKBIT BIT(4) 71 + #define DAVINCI_VC_INT_WERRUDR_MASK BIT(5) 72 + 73 + /* DAVINCI_VC_REG05 bit fields */ 74 + #define DAVINCI_VC_REG05_PGA_GAIN 0x07 75 + 76 + /* DAVINCI_VC_REG09 bit fields */ 77 + #define DAVINCI_VC_REG09_MUTE 0x40 78 + #define DAVINCI_VC_REG09_DIG_ATTEN 0x3F 79 + 80 + /* DAVINCI_VC_REG12 bit fields */ 81 + #define DAVINCI_VC_REG12_POWER_ALL_ON 0xFD 82 + #define DAVINCI_VC_REG12_POWER_ALL_OFF 0x00 83 + 84 + #define DAVINCI_VC_CELLS 2 85 + 86 + enum davinci_vc_cells { 87 + DAVINCI_VC_VCIF_CELL, 88 + DAVINCI_VC_CQ93VC_CELL, 89 + }; 90 + 91 + struct davinci_vcif { 92 + struct platform_device *pdev; 93 + u32 dma_tx_channel; 94 + u32 dma_rx_channel; 95 + dma_addr_t dma_tx_addr; 96 + dma_addr_t dma_rx_addr; 97 + }; 98 + 99 + struct cq93vc { 100 + struct platform_device *pdev; 101 + struct snd_soc_codec *codec; 102 + u32 sysclk; 103 + }; 104 + 105 + struct davinci_vc; 106 + 107 + struct davinci_vc { 108 + /* Device data */ 109 + struct device *dev; 110 + struct platform_device *pdev; 111 + struct clk *clk; 112 + 113 + /* Memory resources */ 114 + void __iomem *base; 115 + resource_size_t pbase; 116 + size_t base_size; 117 + 118 + /* MFD cells */ 119 + struct mfd_cell cells[DAVINCI_VC_CELLS]; 120 + 121 + /* Client devices */ 122 + struct davinci_vcif davinci_vcif; 123 + struct cq93vc cq93vc; 124 + }; 125 + 126 + #endif