Path: blob/master/drivers/mfd/davinci_voicecodec.c
15109 views
/*1* DaVinci Voice Codec Core Interface for TI platforms2*3* Copyright (C) 2010 Texas Instruments, Inc4*5* Author: Miguel Aguilar <[email protected]>6*7* This program is free software; you can redistribute it and/or modify8* it under the terms of the GNU General Public License as published by9* the Free Software Foundation; either version 2 of the License, or10* (at your option) any later version.11*12* This program is distributed in the hope that it will be useful,13* but WITHOUT ANY WARRANTY; without even the implied warranty of14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15* GNU General Public License for more details.16*17* You should have received a copy of the GNU General Public License18* along with this program; if not, write to the Free Software19* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA20*/2122#include <linux/init.h>23#include <linux/module.h>24#include <linux/device.h>25#include <linux/slab.h>26#include <linux/delay.h>27#include <linux/io.h>28#include <linux/clk.h>2930#include <sound/pcm.h>3132#include <linux/mfd/davinci_voicecodec.h>3334u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg)35{36return __raw_readl(davinci_vc->base + reg);37}3839void davinci_vc_write(struct davinci_vc *davinci_vc,40int reg, u32 val)41{42__raw_writel(val, davinci_vc->base + reg);43}4445static int __init davinci_vc_probe(struct platform_device *pdev)46{47struct davinci_vc *davinci_vc;48struct resource *res, *mem;49struct mfd_cell *cell = NULL;50int ret;5152davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL);53if (!davinci_vc) {54dev_dbg(&pdev->dev,55"could not allocate memory for private data\n");56return -ENOMEM;57}5859davinci_vc->clk = clk_get(&pdev->dev, NULL);60if (IS_ERR(davinci_vc->clk)) {61dev_dbg(&pdev->dev,62"could not get the clock for voice codec\n");63ret = -ENODEV;64goto fail1;65}66clk_enable(davinci_vc->clk);6768res = platform_get_resource(pdev, IORESOURCE_MEM, 0);69if (!res) {70dev_err(&pdev->dev, "no mem resource\n");71ret = -ENODEV;72goto fail2;73}7475davinci_vc->pbase = res->start;76davinci_vc->base_size = resource_size(res);7778mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size,79pdev->name);80if (!mem) {81dev_err(&pdev->dev, "VCIF region already claimed\n");82ret = -EBUSY;83goto fail2;84}8586davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size);87if (!davinci_vc->base) {88dev_err(&pdev->dev, "can't ioremap mem resource.\n");89ret = -ENOMEM;90goto fail3;91}9293res = platform_get_resource(pdev, IORESOURCE_DMA, 0);94if (!res) {95dev_err(&pdev->dev, "no DMA resource\n");96ret = -ENXIO;97goto fail4;98}99100davinci_vc->davinci_vcif.dma_tx_channel = res->start;101davinci_vc->davinci_vcif.dma_tx_addr =102(dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO);103104res = platform_get_resource(pdev, IORESOURCE_DMA, 1);105if (!res) {106dev_err(&pdev->dev, "no DMA resource\n");107ret = -ENXIO;108goto fail4;109}110111davinci_vc->davinci_vcif.dma_rx_channel = res->start;112davinci_vc->davinci_vcif.dma_rx_addr =113(dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO);114115davinci_vc->dev = &pdev->dev;116davinci_vc->pdev = pdev;117118/* Voice codec interface client */119cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL];120cell->name = "davinci-vcif";121cell->platform_data = davinci_vc;122cell->pdata_size = sizeof(*davinci_vc);123124/* Voice codec CQ93VC client */125cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL];126cell->name = "cq93vc-codec";127cell->platform_data = davinci_vc;128cell->pdata_size = sizeof(*davinci_vc);129130ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells,131DAVINCI_VC_CELLS, NULL, 0);132if (ret != 0) {133dev_err(&pdev->dev, "fail to register client devices\n");134goto fail4;135}136137return 0;138139fail4:140iounmap(davinci_vc->base);141fail3:142release_mem_region(davinci_vc->pbase, davinci_vc->base_size);143fail2:144clk_disable(davinci_vc->clk);145clk_put(davinci_vc->clk);146davinci_vc->clk = NULL;147fail1:148kfree(davinci_vc);149150return ret;151}152153static int __devexit davinci_vc_remove(struct platform_device *pdev)154{155struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);156157mfd_remove_devices(&pdev->dev);158159iounmap(davinci_vc->base);160release_mem_region(davinci_vc->pbase, davinci_vc->base_size);161162clk_disable(davinci_vc->clk);163clk_put(davinci_vc->clk);164davinci_vc->clk = NULL;165166kfree(davinci_vc);167168return 0;169}170171static struct platform_driver davinci_vc_driver = {172.driver = {173.name = "davinci_voicecodec",174.owner = THIS_MODULE,175},176.remove = __devexit_p(davinci_vc_remove),177};178179static int __init davinci_vc_init(void)180{181return platform_driver_probe(&davinci_vc_driver, davinci_vc_probe);182}183module_init(davinci_vc_init);184185static void __exit davinci_vc_exit(void)186{187platform_driver_unregister(&davinci_vc_driver);188}189module_exit(davinci_vc_exit);190191MODULE_AUTHOR("Miguel Aguilar");192MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface");193MODULE_LICENSE("GPL");194195196