2 * SiRF Audio port driver
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
6 * Licensed under GPLv2 or later.
8 #include <linux/module.h>
10 #include <linux/regmap.h>
11 #include <sound/soc.h>
12 #include <sound/dmaengine_pcm.h>
14 #include "sirf-audio-port.h"
16 struct sirf_audio_port
{
17 struct regmap
*regmap
;
18 struct snd_dmaengine_dai_dma_data playback_dma_data
;
19 struct snd_dmaengine_dai_dma_data capture_dma_data
;
22 static void sirf_audio_port_tx_enable(struct sirf_audio_port
*port
)
24 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
,
25 AUDIO_FIFO_RESET
, AUDIO_FIFO_RESET
);
26 regmap_write(port
->regmap
, AUDIO_PORT_IC_TXFIFO_INT_MSK
, 0);
27 regmap_write(port
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
, 0);
28 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
,
29 AUDIO_FIFO_START
, AUDIO_FIFO_START
);
30 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_CODEC_TX_CTRL
,
31 IC_TX_ENABLE
, IC_TX_ENABLE
);
34 static void sirf_audio_port_tx_disable(struct sirf_audio_port
*port
)
36 regmap_write(port
->regmap
, AUDIO_PORT_IC_TXFIFO_OP
, 0);
37 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_CODEC_TX_CTRL
,
38 IC_TX_ENABLE
, ~IC_TX_ENABLE
);
41 static void sirf_audio_port_rx_enable(struct sirf_audio_port
*port
,
44 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_RXFIFO_OP
,
45 AUDIO_FIFO_RESET
, AUDIO_FIFO_RESET
);
46 regmap_write(port
->regmap
, AUDIO_PORT_IC_RXFIFO_INT_MSK
, 0);
47 regmap_write(port
->regmap
, AUDIO_PORT_IC_RXFIFO_OP
, 0);
48 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_RXFIFO_OP
,
49 AUDIO_FIFO_START
, AUDIO_FIFO_START
);
51 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_CODEC_RX_CTRL
,
52 IC_RX_ENABLE_MONO
, IC_RX_ENABLE_MONO
);
54 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_CODEC_RX_CTRL
,
55 IC_RX_ENABLE_STEREO
, IC_RX_ENABLE_STEREO
);
58 static void sirf_audio_port_rx_disable(struct sirf_audio_port
*port
)
60 regmap_update_bits(port
->regmap
, AUDIO_PORT_IC_CODEC_RX_CTRL
,
61 IC_RX_ENABLE_STEREO
, ~IC_RX_ENABLE_STEREO
);
64 static int sirf_audio_port_dai_probe(struct snd_soc_dai
*dai
)
66 struct sirf_audio_port
*port
= snd_soc_dai_get_drvdata(dai
);
67 snd_soc_dai_init_dma_data(dai
, &port
->playback_dma_data
,
68 &port
->capture_dma_data
);
72 static int sirf_audio_port_trigger(struct snd_pcm_substream
*substream
, int cmd
,
73 struct snd_soc_dai
*dai
)
75 struct sirf_audio_port
*port
= snd_soc_dai_get_drvdata(dai
);
76 int playback
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
;
79 case SNDRV_PCM_TRIGGER_STOP
:
80 case SNDRV_PCM_TRIGGER_SUSPEND
:
81 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
83 sirf_audio_port_tx_disable(port
);
85 sirf_audio_port_rx_disable(port
);
87 case SNDRV_PCM_TRIGGER_START
:
88 case SNDRV_PCM_TRIGGER_RESUME
:
89 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
91 sirf_audio_port_tx_enable(port
);
93 sirf_audio_port_rx_enable(port
,
94 substream
->runtime
->channels
);
103 static const struct snd_soc_dai_ops sirf_audio_port_dai_ops
= {
104 .trigger
= sirf_audio_port_trigger
,
107 static struct snd_soc_dai_driver sirf_audio_port_dai
= {
108 .probe
= sirf_audio_port_dai_probe
,
109 .name
= "sirf-audio-port",
114 .rates
= SNDRV_PCM_RATE_48000
,
115 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
120 .rates
= SNDRV_PCM_RATE_48000
,
121 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
123 .ops
= &sirf_audio_port_dai_ops
,
126 static const struct snd_soc_component_driver sirf_audio_port_component
= {
127 .name
= "sirf-audio-port",
130 static const struct regmap_config sirf_audio_port_regmap_config
= {
134 .max_register
= AUDIO_PORT_IC_RXFIFO_INT_MSK
,
135 .cache_type
= REGCACHE_NONE
,
138 static int sirf_audio_port_probe(struct platform_device
*pdev
)
141 struct sirf_audio_port
*port
;
143 struct resource
*mem_res
;
145 port
= devm_kzalloc(&pdev
->dev
,
146 sizeof(struct sirf_audio_port
), GFP_KERNEL
);
150 mem_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
152 dev_err(&pdev
->dev
, "no mem resource?\n");
156 base
= devm_ioremap(&pdev
->dev
, mem_res
->start
,
157 resource_size(mem_res
));
161 port
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, base
,
162 &sirf_audio_port_regmap_config
);
163 if (IS_ERR(port
->regmap
))
164 return PTR_ERR(port
->regmap
);
166 ret
= devm_snd_soc_register_component(&pdev
->dev
,
167 &sirf_audio_port_component
, &sirf_audio_port_dai
, 1);
171 platform_set_drvdata(pdev
, port
);
172 return devm_snd_dmaengine_pcm_register(&pdev
->dev
, NULL
, 0);
175 static const struct of_device_id sirf_audio_port_of_match
[] = {
176 { .compatible
= "sirf,audio-port", },
179 MODULE_DEVICE_TABLE(of
, sirf_audio_port_of_match
);
181 static struct platform_driver sirf_audio_port_driver
= {
183 .name
= "sirf-audio-port",
184 .owner
= THIS_MODULE
,
185 .of_match_table
= sirf_audio_port_of_match
,
187 .probe
= sirf_audio_port_probe
,
190 module_platform_driver(sirf_audio_port_driver
);
192 MODULE_DESCRIPTION("SiRF Audio Port driver");
193 MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>");
194 MODULE_LICENSE("GPL v2");