1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
From 76555728aef75deb4d96360cbf80bac7fe5c3282 Mon Sep 17 00:00:00 2001
From: Sebastien Guiriec <s-guiriec@ti.com>
Date: Sat, 22 Jan 2011 16:31:55 +0100
Subject: [PATCH 39/60] ASoC: McPDM: Update the control of the channels for SW reset
commit 06d0342ce9feeb0fc1bb4309cdfeb824bbdafbd3 upstream
McPDM channels management need to be control in a specific way
in order to reset the internal digital filter of the IP for
Uplink and downlink channels.
Perform a Software reset when we are requestig the module.
Change-Id: Ie5d351604d4162eafca0b4ed2ea0d557d6e90998
Signed-off-by: Sebastien Guiriec <s-guiriec@ti.com>
Integrated-by: Jingdong Lu <jingdong.lu@windriver.com>
---
sound/soc/omap/omap-mcpdm.c | 47 +++++++++++++++++++++++++++++++++++-------
sound/soc/omap/omap-mcpdm.h | 5 ++++
2 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index a976382..80858e0 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -208,12 +208,21 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm, int stream)
{
int ctrl = omap_mcpdm_read(mcpdm, MCPDM_CTRL);
- if (stream)
+ if (stream) {
+ ctrl |= SW_UP_RST;
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
ctrl |= mcpdm->up_channels;
- else
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ ctrl &= ~SW_UP_RST;
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ } else {
+ ctrl |= SW_DN_RST;
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
ctrl |= mcpdm->dn_channels;
-
- omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ ctrl &= ~SW_DN_RST;
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ }
}
/*
@@ -224,12 +233,21 @@ static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm, int stream)
{
int ctrl = omap_mcpdm_read(mcpdm, MCPDM_CTRL);
- if (stream)
+ if (stream) {
+ ctrl |= SW_UP_RST;
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
ctrl &= ~mcpdm->up_channels;
- else
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ ctrl &= ~SW_UP_RST;
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ } else {
+ ctrl |= SW_DN_RST;
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
ctrl &= ~mcpdm->dn_channels;
-
- omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ ctrl &= ~SW_DN_RST;
+ omap_mcpdm_write(mcpdm, MCPDM_CTRL, ctrl);
+ }
}
/*
@@ -401,6 +419,7 @@ static int omap_mcpdm_request(struct omap_mcpdm *mcpdm)
struct omap_mcpdm_platform_data *pdata;
int ret;
int ctrl;
+ int attemps = 0;
pdev = to_platform_device(mcpdm->dev);
pdata = pdev->dev.platform_data;
@@ -414,6 +433,18 @@ static int omap_mcpdm_request(struct omap_mcpdm *mcpdm)
}
mcpdm->free = 0;
+ /* Perform SW RESET of McPDM IP */
+ ctrl = omap_mcpdm_read(mcpdm, MCPDM_SYSCONFIG);
+ ctrl |= MCPDM_SOFTRESET;
+ omap_mcpdm_write(mcpdm, MCPDM_SYSCONFIG, ctrl);
+ /* Wait completion of SW RESET */
+ while ((omap_mcpdm_read(mcpdm, MCPDM_SYSCONFIG) & MCPDM_SOFTRESET)) {
+ if (attemps++ > 10000) {
+ udelay(10);
+ dev_err(mcpdm->dev, "Could not RESET McPDM\n");
+ }
+ }
+
/* Disable lines while request is ongoing */
omap_mcpdm_write(mcpdm, MCPDM_CTRL, 0x00);
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h
index 4f2d292..16c29ac 100644
--- a/sound/soc/omap/omap-mcpdm.h
+++ b/sound/soc/omap/omap-mcpdm.h
@@ -69,6 +69,11 @@
#define DMA_UP_ENABLE 0x2
/*
+ * MCPDM_SYSCONFIG bit fields
+ */
+#define MCPDM_SOFTRESET 0x1
+
+/*
* MCPDM_CTRL bit fields
*/
--
1.7.4.1
|