Blame view
drivers/mfd/davinci_voicecodec.c
3.24 KB
1a59d1b8e treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
ca26308c2 MFD: DaVinci Voic... |
2 3 4 5 6 7 |
/* * DaVinci Voice Codec Core Interface for TI platforms * * Copyright (C) 2010 Texas Instruments, Inc * * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> |
ca26308c2 MFD: DaVinci Voic... |
8 9 10 11 12 |
*/ #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> |
8c0d8fa26 mfd: update gfp/s... |
13 |
#include <linux/slab.h> |
ca26308c2 MFD: DaVinci Voic... |
14 15 16 |
#include <linux/delay.h> #include <linux/io.h> #include <linux/clk.h> |
921a2c870 mfd: davinci_voic... |
17 |
#include <linux/regmap.h> |
ca26308c2 MFD: DaVinci Voic... |
18 19 20 21 |
#include <sound/pcm.h> #include <linux/mfd/davinci_voicecodec.h> |
b8d12eac2 mfd: davinci_voic... |
22 |
static const struct regmap_config davinci_vc_regmap = { |
921a2c870 mfd: davinci_voic... |
23 24 25 |
.reg_bits = 32, .val_bits = 32, }; |
ca26308c2 MFD: DaVinci Voic... |
26 27 28 |
static int __init davinci_vc_probe(struct platform_device *pdev) { struct davinci_vc *davinci_vc; |
c8eaed458 mfd: davinci_voic... |
29 |
struct resource *res; |
ca26308c2 MFD: DaVinci Voic... |
30 |
struct mfd_cell *cell = NULL; |
b5e29aa88 mfd: davinci_voic... |
31 |
dma_addr_t fifo_base; |
ca26308c2 MFD: DaVinci Voic... |
32 |
int ret; |
099053a49 mfd: davinci_voic... |
33 34 |
davinci_vc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_vc), GFP_KERNEL); |
9fb411660 mfd: davinci_voic... |
35 |
if (!davinci_vc) |
ca26308c2 MFD: DaVinci Voic... |
36 |
return -ENOMEM; |
ca26308c2 MFD: DaVinci Voic... |
37 |
|
c8eaed458 mfd: davinci_voic... |
38 |
davinci_vc->clk = devm_clk_get(&pdev->dev, NULL); |
ca26308c2 MFD: DaVinci Voic... |
39 40 41 42 |
if (IS_ERR(davinci_vc->clk)) { dev_dbg(&pdev->dev, "could not get the clock for voice codec "); |
099053a49 mfd: davinci_voic... |
43 |
return -ENODEV; |
ca26308c2 MFD: DaVinci Voic... |
44 45 46 47 |
} clk_enable(davinci_vc->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
ca26308c2 MFD: DaVinci Voic... |
48 |
|
b5e29aa88 mfd: davinci_voic... |
49 |
fifo_base = (dma_addr_t)res->start; |
c8eaed458 mfd: davinci_voic... |
50 51 52 53 |
davinci_vc->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(davinci_vc->base)) { ret = PTR_ERR(davinci_vc->base); goto fail; |
ca26308c2 MFD: DaVinci Voic... |
54 |
} |
921a2c870 mfd: davinci_voic... |
55 56 57 58 59 60 61 |
davinci_vc->regmap = devm_regmap_init_mmio(&pdev->dev, davinci_vc->base, &davinci_vc_regmap); if (IS_ERR(davinci_vc->regmap)) { ret = PTR_ERR(davinci_vc->regmap); goto fail; } |
ca26308c2 MFD: DaVinci Voic... |
62 63 64 65 |
res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { dev_err(&pdev->dev, "no DMA resource "); |
e2bde7871 mfd: Fix davinci ... |
66 |
ret = -ENXIO; |
c8eaed458 mfd: davinci_voic... |
67 |
goto fail; |
ca26308c2 MFD: DaVinci Voic... |
68 69 70 |
} davinci_vc->davinci_vcif.dma_tx_channel = res->start; |
b5e29aa88 mfd: davinci_voic... |
71 |
davinci_vc->davinci_vcif.dma_tx_addr = fifo_base + DAVINCI_VC_WFIFO; |
ca26308c2 MFD: DaVinci Voic... |
72 73 74 75 76 |
res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) { dev_err(&pdev->dev, "no DMA resource "); |
e2bde7871 mfd: Fix davinci ... |
77 |
ret = -ENXIO; |
c8eaed458 mfd: davinci_voic... |
78 |
goto fail; |
ca26308c2 MFD: DaVinci Voic... |
79 80 81 |
} davinci_vc->davinci_vcif.dma_rx_channel = res->start; |
b5e29aa88 mfd: davinci_voic... |
82 |
davinci_vc->davinci_vcif.dma_rx_addr = fifo_base + DAVINCI_VC_RFIFO; |
ca26308c2 MFD: DaVinci Voic... |
83 84 85 86 87 88 |
davinci_vc->dev = &pdev->dev; davinci_vc->pdev = pdev; /* Voice codec interface client */ cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; |
73ee6524d mfd: Fix DaVinci ... |
89 |
cell->name = "davinci-vcif"; |
cb5811cf3 mfd: Use mfd cell... |
90 91 |
cell->platform_data = davinci_vc; cell->pdata_size = sizeof(*davinci_vc); |
ca26308c2 MFD: DaVinci Voic... |
92 93 94 |
/* Voice codec CQ93VC client */ cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; |
73ee6524d mfd: Fix DaVinci ... |
95 |
cell->name = "cq93vc-codec"; |
cb5811cf3 mfd: Use mfd cell... |
96 97 |
cell->platform_data = davinci_vc; cell->pdata_size = sizeof(*davinci_vc); |
ca26308c2 MFD: DaVinci Voic... |
98 99 |
ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, |
0848c94fb mfd: core: Push i... |
100 |
DAVINCI_VC_CELLS, NULL, 0, NULL); |
ca26308c2 MFD: DaVinci Voic... |
101 102 103 |
if (ret != 0) { dev_err(&pdev->dev, "fail to register client devices "); |
c8eaed458 mfd: davinci_voic... |
104 |
goto fail; |
ca26308c2 MFD: DaVinci Voic... |
105 106 107 |
} return 0; |
c8eaed458 mfd: davinci_voic... |
108 |
fail: |
ca26308c2 MFD: DaVinci Voic... |
109 |
clk_disable(davinci_vc->clk); |
ca26308c2 MFD: DaVinci Voic... |
110 111 112 |
return ret; } |
4740f73fe mfd: remove use o... |
113 |
static int davinci_vc_remove(struct platform_device *pdev) |
ca26308c2 MFD: DaVinci Voic... |
114 115 116 117 |
{ struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); mfd_remove_devices(&pdev->dev); |
ca26308c2 MFD: DaVinci Voic... |
118 |
clk_disable(davinci_vc->clk); |
ca26308c2 MFD: DaVinci Voic... |
119 |
|
ca26308c2 MFD: DaVinci Voic... |
120 121 122 123 124 125 |
return 0; } static struct platform_driver davinci_vc_driver = { .driver = { .name = "davinci_voicecodec", |
ca26308c2 MFD: DaVinci Voic... |
126 |
}, |
84449216b mfd: remove use o... |
127 |
.remove = davinci_vc_remove, |
ca26308c2 MFD: DaVinci Voic... |
128 |
}; |
3de764d4a mfd: davinci_voic... |
129 |
module_platform_driver_probe(davinci_vc_driver, davinci_vc_probe); |
ca26308c2 MFD: DaVinci Voic... |
130 131 132 133 |
MODULE_AUTHOR("Miguel Aguilar"); MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface"); MODULE_LICENSE("GPL"); |