aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/sirf-audio-codec.c74
-rw-r--r--sound/soc/codecs/sirf-audio-codec.h50
-rw-r--r--sound/soc/sirf/sirf-audio-port.c107
-rw-r--r--sound/soc/sirf/sirf-audio-port.h62
4 files changed, 116 insertions, 177 deletions
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c
index 58e7c1f23771..c5177bc5df82 100644
--- a/sound/soc/codecs/sirf-audio-codec.c
+++ b/sound/soc/codecs/sirf-audio-codec.c
@@ -279,13 +279,63 @@ static const struct snd_soc_dapm_route sirf_audio_codec_map[] = {
279 {"Mic input mode mux", "Differential", "MICIN1"}, 279 {"Mic input mode mux", "Differential", "MICIN1"},
280}; 280};
281 281
282static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec)
283{
284 regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
285 AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
286 regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
287 AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
288 regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0);
289 regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
290 regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
291 AUDIO_FIFO_START, AUDIO_FIFO_START);
292 regmap_update_bits(sirf_audio_codec->regmap,
293 AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE);
294}
295
296static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec)
297{
298 regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
299 regmap_update_bits(sirf_audio_codec->regmap,
300 AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE);
301}
302
303static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec,
304 int channels)
305{
306 regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
307 AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
308 regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
309 AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
310 regmap_write(sirf_audio_codec->regmap,
311 AUDIO_PORT_IC_RXFIFO_INT_MSK, 0);
312 regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0);
313 regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
314 AUDIO_FIFO_START, AUDIO_FIFO_START);
315 if (channels == 1)
316 regmap_update_bits(sirf_audio_codec->regmap,
317 AUDIO_PORT_IC_CODEC_RX_CTRL,
318 IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO);
319 else
320 regmap_update_bits(sirf_audio_codec->regmap,
321 AUDIO_PORT_IC_CODEC_RX_CTRL,
322 IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO);
323}
324
325static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec)
326{
327 regmap_update_bits(sirf_audio_codec->regmap,
328 AUDIO_PORT_IC_CODEC_RX_CTRL,
329 IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO);
330}
331
282static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, 332static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
283 int cmd, 333 int cmd,
284 struct snd_soc_dai *dai) 334 struct snd_soc_dai *dai)
285{ 335{
286 int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
287 struct snd_soc_codec *codec = dai->codec; 336 struct snd_soc_codec *codec = dai->codec;
288 u32 val = 0; 337 struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
338 int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
289 339
290 /* 340 /*
291 * This is a workaround, When stop playback, 341 * This is a workaround, When stop playback,
@@ -295,20 +345,28 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
295 case SNDRV_PCM_TRIGGER_STOP: 345 case SNDRV_PCM_TRIGGER_STOP:
296 case SNDRV_PCM_TRIGGER_SUSPEND: 346 case SNDRV_PCM_TRIGGER_SUSPEND:
297 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 347 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
348 if (playback) {
349 snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
350 IC_HSLEN | IC_HSREN, 0);
351 sirf_audio_codec_tx_disable(sirf_audio_codec);
352 } else
353 sirf_audio_codec_rx_disable(sirf_audio_codec);
298 break; 354 break;
299 case SNDRV_PCM_TRIGGER_START: 355 case SNDRV_PCM_TRIGGER_START:
300 case SNDRV_PCM_TRIGGER_RESUME: 356 case SNDRV_PCM_TRIGGER_RESUME:
301 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 357 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
302 if (playback) 358 if (playback) {
303 val = IC_HSLEN | IC_HSREN; 359 sirf_audio_codec_tx_enable(sirf_audio_codec);
360 snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
361 IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN);
362 } else
363 sirf_audio_codec_rx_enable(sirf_audio_codec,
364 substream->runtime->channels);
304 break; 365 break;
305 default: 366 default:
306 return -EINVAL; 367 return -EINVAL;
307 } 368 }
308 369
309 if (playback)
310 snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
311 IC_HSLEN | IC_HSREN, val);
312 return 0; 370 return 0;
313} 371}
314 372
@@ -392,7 +450,7 @@ static const struct regmap_config sirf_audio_codec_regmap_config = {
392 .reg_bits = 32, 450 .reg_bits = 32,
393 .reg_stride = 4, 451 .reg_stride = 4,
394 .val_bits = 32, 452 .val_bits = 32,
395 .max_register = AUDIO_IC_CODEC_CTRL3, 453 .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK,
396 .cache_type = REGCACHE_NONE, 454 .cache_type = REGCACHE_NONE,
397}; 455};
398 456
diff --git a/sound/soc/codecs/sirf-audio-codec.h b/sound/soc/codecs/sirf-audio-codec.h
index d4c187b8e54a..ba1adc03839f 100644
--- a/sound/soc/codecs/sirf-audio-codec.h
+++ b/sound/soc/codecs/sirf-audio-codec.h
@@ -72,4 +72,54 @@
72#define IC_RXPGAR 0x7B 72#define IC_RXPGAR 0x7B
73#define IC_RXPGAL 0x7B 73#define IC_RXPGAL 0x7B
74 74
75#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F
76#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0
77#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10
78#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20
79
80#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
81 << AUDIO_PORT_TX_FIFO_SC_OFFSET)
82#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
83 << AUDIO_PORT_TX_FIFO_LC_OFFSET)
84#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
85 << AUDIO_PORT_TX_FIFO_HC_OFFSET)
86
87#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F
88#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0
89#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10
90#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20
91
92#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
93 << AUDIO_PORT_RX_FIFO_SC_OFFSET)
94#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
95 << AUDIO_PORT_RX_FIFO_LC_OFFSET)
96#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
97 << AUDIO_PORT_RX_FIFO_HC_OFFSET)
98#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4)
99#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8)
100
101#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC)
102#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100)
103#define AUDIO_PORT_IC_TXFIFO_STS (0x0104)
104#define AUDIO_PORT_IC_TXFIFO_INT (0x0108)
105#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C)
106
107#define AUDIO_PORT_IC_RXFIFO_OP (0x0110)
108#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114)
109#define AUDIO_PORT_IC_RXFIFO_STS (0x0118)
110#define AUDIO_PORT_IC_RXFIFO_INT (0x011C)
111#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120)
112
113#define AUDIO_FIFO_START (1 << 0)
114#define AUDIO_FIFO_RESET (1 << 1)
115
116#define AUDIO_FIFO_FULL (1 << 0)
117#define AUDIO_FIFO_EMPTY (1 << 1)
118#define AUDIO_FIFO_OFLOW (1 << 2)
119#define AUDIO_FIFO_UFLOW (1 << 3)
120
121#define IC_TX_ENABLE (0x03)
122#define IC_RX_ENABLE_MONO (0x01)
123#define IC_RX_ENABLE_STEREO (0x03)
124
75#endif /*__SIRF_AUDIO_CODEC_H*/ 125#endif /*__SIRF_AUDIO_CODEC_H*/
diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c
index b04a53f2b4f6..b4afa31b2bc1 100644
--- a/sound/soc/sirf/sirf-audio-port.c
+++ b/sound/soc/sirf/sirf-audio-port.c
@@ -6,60 +6,15 @@
6 * Licensed under GPLv2 or later. 6 * Licensed under GPLv2 or later.
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/io.h>
10#include <linux/regmap.h>
11#include <sound/soc.h> 9#include <sound/soc.h>
12#include <sound/dmaengine_pcm.h> 10#include <sound/dmaengine_pcm.h>
13 11
14#include "sirf-audio-port.h"
15
16struct sirf_audio_port { 12struct sirf_audio_port {
17 struct regmap *regmap; 13 struct regmap *regmap;
18 struct snd_dmaengine_dai_dma_data playback_dma_data; 14 struct snd_dmaengine_dai_dma_data playback_dma_data;
19 struct snd_dmaengine_dai_dma_data capture_dma_data; 15 struct snd_dmaengine_dai_dma_data capture_dma_data;
20}; 16};
21 17
22static void sirf_audio_port_tx_enable(struct sirf_audio_port *port)
23{
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);
32}
33
34static void sirf_audio_port_tx_disable(struct sirf_audio_port *port)
35{
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);
39}
40
41static void sirf_audio_port_rx_enable(struct sirf_audio_port *port,
42 int channels)
43{
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);
50 if (channels == 1)
51 regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
52 IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO);
53 else
54 regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
55 IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO);
56}
57
58static void sirf_audio_port_rx_disable(struct sirf_audio_port *port)
59{
60 regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
61 IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO);
62}
63 18
64static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) 19static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai)
65{ 20{
@@ -69,41 +24,6 @@ static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai)
69 return 0; 24 return 0;
70} 25}
71 26
72static int sirf_audio_port_trigger(struct snd_pcm_substream *substream, int cmd,
73 struct snd_soc_dai *dai)
74{
75 struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai);
76 int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
77
78 switch (cmd) {
79 case SNDRV_PCM_TRIGGER_STOP:
80 case SNDRV_PCM_TRIGGER_SUSPEND:
81 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
82 if (playback)
83 sirf_audio_port_tx_disable(port);
84 else
85 sirf_audio_port_rx_disable(port);
86 break;
87 case SNDRV_PCM_TRIGGER_START:
88 case SNDRV_PCM_TRIGGER_RESUME:
89 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
90 if (playback)
91 sirf_audio_port_tx_enable(port);
92 else
93 sirf_audio_port_rx_enable(port,
94 substream->runtime->channels);
95 break;
96 default:
97 return -EINVAL;
98 }
99
100 return 0;
101}
102
103static const struct snd_soc_dai_ops sirf_audio_port_dai_ops = {
104 .trigger = sirf_audio_port_trigger,
105};
106
107static struct snd_soc_dai_driver sirf_audio_port_dai = { 27static struct snd_soc_dai_driver sirf_audio_port_dai = {
108 .probe = sirf_audio_port_dai_probe, 28 .probe = sirf_audio_port_dai_probe,
109 .name = "sirf-audio-port", 29 .name = "sirf-audio-port",
@@ -120,49 +40,22 @@ static struct snd_soc_dai_driver sirf_audio_port_dai = {
120 .rates = SNDRV_PCM_RATE_48000, 40 .rates = SNDRV_PCM_RATE_48000,
121 .formats = SNDRV_PCM_FMTBIT_S16_LE, 41 .formats = SNDRV_PCM_FMTBIT_S16_LE,
122 }, 42 },
123 .ops = &sirf_audio_port_dai_ops,
124}; 43};
125 44
126static const struct snd_soc_component_driver sirf_audio_port_component = { 45static const struct snd_soc_component_driver sirf_audio_port_component = {
127 .name = "sirf-audio-port", 46 .name = "sirf-audio-port",
128}; 47};
129 48
130static const struct regmap_config sirf_audio_port_regmap_config = {
131 .reg_bits = 32,
132 .reg_stride = 4,
133 .val_bits = 32,
134 .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK,
135 .cache_type = REGCACHE_NONE,
136};
137
138static int sirf_audio_port_probe(struct platform_device *pdev) 49static int sirf_audio_port_probe(struct platform_device *pdev)
139{ 50{
140 int ret; 51 int ret;
141 struct sirf_audio_port *port; 52 struct sirf_audio_port *port;
142 void __iomem *base;
143 struct resource *mem_res;
144 53
145 port = devm_kzalloc(&pdev->dev, 54 port = devm_kzalloc(&pdev->dev,
146 sizeof(struct sirf_audio_port), GFP_KERNEL); 55 sizeof(struct sirf_audio_port), GFP_KERNEL);
147 if (!port) 56 if (!port)
148 return -ENOMEM; 57 return -ENOMEM;
149 58
150 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
151 if (!mem_res) {
152 dev_err(&pdev->dev, "no mem resource?\n");
153 return -ENODEV;
154 }
155
156 base = devm_ioremap(&pdev->dev, mem_res->start,
157 resource_size(mem_res));
158 if (base == NULL)
159 return -ENOMEM;
160
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);
165
166 ret = devm_snd_soc_register_component(&pdev->dev, 59 ret = devm_snd_soc_register_component(&pdev->dev,
167 &sirf_audio_port_component, &sirf_audio_port_dai, 1); 60 &sirf_audio_port_component, &sirf_audio_port_dai, 1);
168 if (ret) 61 if (ret)
diff --git a/sound/soc/sirf/sirf-audio-port.h b/sound/soc/sirf/sirf-audio-port.h
deleted file mode 100644
index f32dc54f4499..000000000000
--- a/sound/soc/sirf/sirf-audio-port.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * SiRF Audio port controllers define
3 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#ifndef _SIRF_AUDIO_PORT_H
10#define _SIRF_AUDIO_PORT_H
11
12#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F
13#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0
14#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10
15#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20
16
17#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
18 << AUDIO_PORT_TX_FIFO_SC_OFFSET)
19#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
20 << AUDIO_PORT_TX_FIFO_LC_OFFSET)
21#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
22 << AUDIO_PORT_TX_FIFO_HC_OFFSET)
23
24#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F
25#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0
26#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10
27#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20
28
29#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
30 << AUDIO_PORT_RX_FIFO_SC_OFFSET)
31#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
32 << AUDIO_PORT_RX_FIFO_LC_OFFSET)
33#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
34 << AUDIO_PORT_RX_FIFO_HC_OFFSET)
35#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4)
36#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8)
37
38#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC)
39#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100)
40#define AUDIO_PORT_IC_TXFIFO_STS (0x0104)
41#define AUDIO_PORT_IC_TXFIFO_INT (0x0108)
42#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C)
43
44#define AUDIO_PORT_IC_RXFIFO_OP (0x0110)
45#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114)
46#define AUDIO_PORT_IC_RXFIFO_STS (0x0118)
47#define AUDIO_PORT_IC_RXFIFO_INT (0x011C)
48#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120)
49
50#define AUDIO_FIFO_START (1 << 0)
51#define AUDIO_FIFO_RESET (1 << 1)
52
53#define AUDIO_FIFO_FULL (1 << 0)
54#define AUDIO_FIFO_EMPTY (1 << 1)
55#define AUDIO_FIFO_OFLOW (1 << 2)
56#define AUDIO_FIFO_UFLOW (1 << 3)
57
58#define IC_TX_ENABLE (0x03)
59#define IC_RX_ENABLE_MONO (0x01)
60#define IC_RX_ENABLE_STEREO (0x03)
61
62#endif /*__SIRF_AUDIO_PORT_H*/