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/slab.h> 27 #include <linux/delay.h> 28 #include <linux/io.h> 29 #include <linux/clk.h> 30 #include <linux/regmap.h> 31 32 #include <sound/pcm.h> 33 34 #include <linux/mfd/davinci_voicecodec.h> 35 #include <mach/hardware.h> 36 37 static const struct regmap_config davinci_vc_regmap = { 38 .reg_bits = 32, 39 .val_bits = 32, 40 }; 41 davinci_vc_probe(struct platform_device * pdev)42 static int __init davinci_vc_probe(struct platform_device *pdev) 43 { 44 struct davinci_vc *davinci_vc; 45 struct resource *res; 46 struct mfd_cell *cell = NULL; 47 int ret; 48 49 davinci_vc = devm_kzalloc(&pdev->dev, 50 sizeof(struct davinci_vc), GFP_KERNEL); 51 if (!davinci_vc) 52 return -ENOMEM; 53 54 davinci_vc->clk = devm_clk_get(&pdev->dev, NULL); 55 if (IS_ERR(davinci_vc->clk)) { 56 dev_dbg(&pdev->dev, 57 "could not get the clock for voice codec\n"); 58 return -ENODEV; 59 } 60 clk_enable(davinci_vc->clk); 61 62 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 63 64 davinci_vc->base = devm_ioremap_resource(&pdev->dev, res); 65 if (IS_ERR(davinci_vc->base)) { 66 ret = PTR_ERR(davinci_vc->base); 67 goto fail; 68 } 69 70 davinci_vc->regmap = devm_regmap_init_mmio(&pdev->dev, 71 davinci_vc->base, 72 &davinci_vc_regmap); 73 if (IS_ERR(davinci_vc->regmap)) { 74 ret = PTR_ERR(davinci_vc->regmap); 75 goto fail; 76 } 77 78 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 79 if (!res) { 80 dev_err(&pdev->dev, "no DMA resource\n"); 81 ret = -ENXIO; 82 goto fail; 83 } 84 85 davinci_vc->davinci_vcif.dma_tx_channel = res->start; 86 davinci_vc->davinci_vcif.dma_tx_addr = 87 (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO); 88 89 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 90 if (!res) { 91 dev_err(&pdev->dev, "no DMA resource\n"); 92 ret = -ENXIO; 93 goto fail; 94 } 95 96 davinci_vc->davinci_vcif.dma_rx_channel = res->start; 97 davinci_vc->davinci_vcif.dma_rx_addr = 98 (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO); 99 100 davinci_vc->dev = &pdev->dev; 101 davinci_vc->pdev = pdev; 102 103 /* Voice codec interface client */ 104 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; 105 cell->name = "davinci-vcif"; 106 cell->platform_data = davinci_vc; 107 cell->pdata_size = sizeof(*davinci_vc); 108 109 /* Voice codec CQ93VC client */ 110 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; 111 cell->name = "cq93vc-codec"; 112 cell->platform_data = davinci_vc; 113 cell->pdata_size = sizeof(*davinci_vc); 114 115 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, 116 DAVINCI_VC_CELLS, NULL, 0, NULL); 117 if (ret != 0) { 118 dev_err(&pdev->dev, "fail to register client devices\n"); 119 goto fail; 120 } 121 122 return 0; 123 124 fail: 125 clk_disable(davinci_vc->clk); 126 127 return ret; 128 } 129 davinci_vc_remove(struct platform_device * pdev)130 static int davinci_vc_remove(struct platform_device *pdev) 131 { 132 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); 133 134 mfd_remove_devices(&pdev->dev); 135 136 clk_disable(davinci_vc->clk); 137 138 return 0; 139 } 140 141 static struct platform_driver davinci_vc_driver = { 142 .driver = { 143 .name = "davinci_voicecodec", 144 }, 145 .remove = davinci_vc_remove, 146 }; 147 148 module_platform_driver_probe(davinci_vc_driver, davinci_vc_probe); 149 150 MODULE_AUTHOR("Miguel Aguilar"); 151 MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface"); 152 MODULE_LICENSE("GPL"); 153