aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMiguel Aguilar <miguel.aguilar@ridgerun.com>2010-03-11 10:32:21 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-12 06:12:21 -0500
commitca26308c2223cb424c297a70fb7b6c7530a563ba (patch)
tree29895f9e1ef49f0161df8887d272d7beaa92bc9e /drivers/mfd
parentd9ad6296ec3b4a55ba25f2c5e4824be487242e1f (diff)
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>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig4
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/davinci_voicecodec.c189
3 files changed, 194 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 951fa9b93fbe..20e322912a59 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -53,6 +53,10 @@ config MFD_SH_MOBILE_SDHI
53 This driver supports the SDHI hardware block found in many 53 This driver supports the SDHI hardware block found in many
54 SuperH Mobile SoCs. 54 SuperH Mobile SoCs.
55 55
56config MFD_DAVINCI_VOICECODEC
57 tristate
58 select MFD_CORE
59
56config MFD_DM355EVM_MSP 60config MFD_DM355EVM_MSP
57 bool "DaVinci DM355 EVM microcontroller" 61 bool "DaVinci DM355 EVM microcontroller"
58 depends on I2C && MACH_DAVINCI_DM355_EVM 62 depends on I2C && MACH_DAVINCI_DM355_EVM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 22715add99a7..4fbf8f89a49b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
12obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 12obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
13obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o 13obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
14 14
15obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
15obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o 16obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
16 17
17obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o 18obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
new file mode 100644
index 000000000000..9886aa8de250
--- /dev/null
+++ b/drivers/mfd/davinci_voicecodec.c
@@ -0,0 +1,189 @@
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
34u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg)
35{
36 return __raw_readl(davinci_vc->base + reg);
37}
38
39void davinci_vc_write(struct davinci_vc *davinci_vc,
40 int reg, u32 val)
41{
42 __raw_writel(val, davinci_vc->base + reg);
43}
44
45static 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
135fail4:
136 iounmap(davinci_vc->base);
137fail3:
138 release_mem_region(davinci_vc->pbase, davinci_vc->base_size);
139fail2:
140 clk_disable(davinci_vc->clk);
141 clk_put(davinci_vc->clk);
142 davinci_vc->clk = NULL;
143fail1:
144 kfree(davinci_vc);
145
146 return ret;
147}
148
149static 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
167static 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
175static int __init davinci_vc_init(void)
176{
177 return platform_driver_probe(&davinci_vc_driver, davinci_vc_probe);
178}
179module_init(davinci_vc_init);
180
181static void __exit davinci_vc_exit(void)
182{
183 platform_driver_unregister(&davinci_vc_driver);
184}
185module_exit(davinci_vc_exit);
186
187MODULE_AUTHOR("Miguel Aguilar");
188MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface");
189MODULE_LICENSE("GPL");