Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/sound/cs8403.h
26278 views
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
#ifndef __SOUND_CS8403_H
3
#define __SOUND_CS8403_H
4
5
/*
6
* Routines for Cirrus Logic CS8403/CS8404A IEC958 (S/PDIF) Transmitter
7
* Copyright (c) by Jaroslav Kysela <[email protected]>,
8
* Takashi Iwai <[email protected]>
9
*/
10
11
#ifdef SND_CS8403
12
13
#ifndef SND_CS8403_DECL
14
#define SND_CS8403_DECL static
15
#endif
16
#ifndef SND_CS8403_DECODE
17
#define SND_CS8403_DECODE snd_cs8403_decode_spdif_bits
18
#endif
19
#ifndef SND_CS8403_ENCODE
20
#define SND_CS8403_ENCODE snd_cs8403_encode_spdif_bits
21
#endif
22
23
24
SND_CS8403_DECL void SND_CS8403_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
25
{
26
if (bits & 0x01) { /* consumer */
27
if (!(bits & 0x02))
28
diga->status[0] |= IEC958_AES0_NONAUDIO;
29
if (!(bits & 0x08))
30
diga->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
31
switch (bits & 0x10) {
32
case 0x10: diga->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE; break;
33
case 0x00: diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015; break;
34
}
35
if (!(bits & 0x80))
36
diga->status[1] |= IEC958_AES1_CON_ORIGINAL;
37
switch (bits & 0x60) {
38
case 0x00: diga->status[1] |= IEC958_AES1_CON_MAGNETIC_ID; break;
39
case 0x20: diga->status[1] |= IEC958_AES1_CON_DIGDIGCONV_ID; break;
40
case 0x40: diga->status[1] |= IEC958_AES1_CON_LASEROPT_ID; break;
41
case 0x60: diga->status[1] |= IEC958_AES1_CON_GENERAL; break;
42
}
43
switch (bits & 0x06) {
44
case 0x00: diga->status[3] |= IEC958_AES3_CON_FS_44100; break;
45
case 0x02: diga->status[3] |= IEC958_AES3_CON_FS_48000; break;
46
case 0x04: diga->status[3] |= IEC958_AES3_CON_FS_32000; break;
47
}
48
} else {
49
diga->status[0] = IEC958_AES0_PROFESSIONAL;
50
switch (bits & 0x18) {
51
case 0x00: diga->status[0] |= IEC958_AES0_PRO_FS_32000; break;
52
case 0x10: diga->status[0] |= IEC958_AES0_PRO_FS_44100; break;
53
case 0x08: diga->status[0] |= IEC958_AES0_PRO_FS_48000; break;
54
case 0x18: diga->status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
55
}
56
switch (bits & 0x60) {
57
case 0x20: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NONE; break;
58
case 0x40: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; break;
59
case 0x00: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_CCITT; break;
60
case 0x60: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NOTID; break;
61
}
62
if (bits & 0x80)
63
diga->status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
64
}
65
}
66
67
SND_CS8403_DECL unsigned char SND_CS8403_ENCODE(struct snd_aes_iec958 *diga)
68
{
69
unsigned char bits;
70
71
if (!(diga->status[0] & IEC958_AES0_PROFESSIONAL)) {
72
bits = 0x01; /* consumer mode */
73
if (diga->status[0] & IEC958_AES0_NONAUDIO)
74
bits &= ~0x02;
75
else
76
bits |= 0x02;
77
if (diga->status[0] & IEC958_AES0_CON_NOT_COPYRIGHT)
78
bits &= ~0x08;
79
else
80
bits |= 0x08;
81
switch (diga->status[0] & IEC958_AES0_CON_EMPHASIS) {
82
default:
83
case IEC958_AES0_CON_EMPHASIS_NONE: bits |= 0x10; break;
84
case IEC958_AES0_CON_EMPHASIS_5015: bits |= 0x00; break;
85
}
86
if (diga->status[1] & IEC958_AES1_CON_ORIGINAL)
87
bits &= ~0x80;
88
else
89
bits |= 0x80;
90
if ((diga->status[1] & IEC958_AES1_CON_CATEGORY) == IEC958_AES1_CON_GENERAL)
91
bits |= 0x60;
92
else {
93
switch(diga->status[1] & IEC958_AES1_CON_MAGNETIC_MASK) {
94
case IEC958_AES1_CON_MAGNETIC_ID:
95
bits |= 0x00; break;
96
case IEC958_AES1_CON_DIGDIGCONV_ID:
97
bits |= 0x20; break;
98
default:
99
case IEC958_AES1_CON_LASEROPT_ID:
100
bits |= 0x40; break;
101
}
102
}
103
switch (diga->status[3] & IEC958_AES3_CON_FS) {
104
default:
105
case IEC958_AES3_CON_FS_44100: bits |= 0x00; break;
106
case IEC958_AES3_CON_FS_48000: bits |= 0x02; break;
107
case IEC958_AES3_CON_FS_32000: bits |= 0x04; break;
108
}
109
} else {
110
bits = 0x00; /* professional mode */
111
if (diga->status[0] & IEC958_AES0_NONAUDIO)
112
bits &= ~0x02;
113
else
114
bits |= 0x02;
115
/* CHECKME: I'm not sure about the bit order in val here */
116
switch (diga->status[0] & IEC958_AES0_PRO_FS) {
117
case IEC958_AES0_PRO_FS_32000: bits |= 0x00; break;
118
case IEC958_AES0_PRO_FS_44100: bits |= 0x10; break; /* 44.1kHz */
119
case IEC958_AES0_PRO_FS_48000: bits |= 0x08; break; /* 48kHz */
120
default:
121
case IEC958_AES0_PRO_FS_NOTID: bits |= 0x18; break;
122
}
123
switch (diga->status[0] & IEC958_AES0_PRO_EMPHASIS) {
124
case IEC958_AES0_PRO_EMPHASIS_NONE: bits |= 0x20; break;
125
case IEC958_AES0_PRO_EMPHASIS_5015: bits |= 0x40; break;
126
case IEC958_AES0_PRO_EMPHASIS_CCITT: bits |= 0x00; break;
127
default:
128
case IEC958_AES0_PRO_EMPHASIS_NOTID: bits |= 0x60; break;
129
}
130
switch (diga->status[1] & IEC958_AES1_PRO_MODE) {
131
case IEC958_AES1_PRO_MODE_TWO:
132
case IEC958_AES1_PRO_MODE_STEREOPHONIC: bits |= 0x00; break;
133
default: bits |= 0x80; break;
134
}
135
}
136
return bits;
137
}
138
139
#endif /* SND_CS8403 */
140
141
#ifdef SND_CS8404
142
143
#ifndef SND_CS8404_DECL
144
#define SND_CS8404_DECL static
145
#endif
146
#ifndef SND_CS8404_DECODE
147
#define SND_CS8404_DECODE snd_cs8404_decode_spdif_bits
148
#endif
149
#ifndef SND_CS8404_ENCODE
150
#define SND_CS8404_ENCODE snd_cs8404_encode_spdif_bits
151
#endif
152
153
154
SND_CS8404_DECL void SND_CS8404_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
155
{
156
if (bits & 0x10) { /* consumer */
157
if (!(bits & 0x20))
158
diga->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
159
if (!(bits & 0x40))
160
diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
161
if (!(bits & 0x80))
162
diga->status[1] |= IEC958_AES1_CON_ORIGINAL;
163
switch (bits & 0x03) {
164
case 0x00: diga->status[1] |= IEC958_AES1_CON_DAT; break;
165
case 0x03: diga->status[1] |= IEC958_AES1_CON_GENERAL; break;
166
}
167
switch (bits & 0x06) {
168
case 0x02: diga->status[3] |= IEC958_AES3_CON_FS_32000; break;
169
case 0x04: diga->status[3] |= IEC958_AES3_CON_FS_48000; break;
170
case 0x06: diga->status[3] |= IEC958_AES3_CON_FS_44100; break;
171
}
172
} else {
173
diga->status[0] = IEC958_AES0_PROFESSIONAL;
174
if (!(bits & 0x04))
175
diga->status[0] |= IEC958_AES0_NONAUDIO;
176
switch (bits & 0x60) {
177
case 0x00: diga->status[0] |= IEC958_AES0_PRO_FS_32000; break;
178
case 0x40: diga->status[0] |= IEC958_AES0_PRO_FS_44100; break;
179
case 0x20: diga->status[0] |= IEC958_AES0_PRO_FS_48000; break;
180
case 0x60: diga->status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
181
}
182
switch (bits & 0x03) {
183
case 0x02: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NONE; break;
184
case 0x01: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; break;
185
case 0x00: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_CCITT; break;
186
case 0x03: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NOTID; break;
187
}
188
if (!(bits & 0x80))
189
diga->status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
190
}
191
}
192
193
SND_CS8404_DECL unsigned char SND_CS8404_ENCODE(struct snd_aes_iec958 *diga)
194
{
195
unsigned char bits;
196
197
if (!(diga->status[0] & IEC958_AES0_PROFESSIONAL)) {
198
bits = 0x10; /* consumer mode */
199
if (!(diga->status[0] & IEC958_AES0_CON_NOT_COPYRIGHT))
200
bits |= 0x20;
201
if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_NONE)
202
bits |= 0x40;
203
if (!(diga->status[1] & IEC958_AES1_CON_ORIGINAL))
204
bits |= 0x80;
205
if ((diga->status[1] & IEC958_AES1_CON_CATEGORY) == IEC958_AES1_CON_GENERAL)
206
bits |= 0x03;
207
switch (diga->status[3] & IEC958_AES3_CON_FS) {
208
default:
209
case IEC958_AES3_CON_FS_44100: bits |= 0x06; break;
210
case IEC958_AES3_CON_FS_48000: bits |= 0x04; break;
211
case IEC958_AES3_CON_FS_32000: bits |= 0x02; break;
212
}
213
} else {
214
bits = 0x00; /* professional mode */
215
if (!(diga->status[0] & IEC958_AES0_NONAUDIO))
216
bits |= 0x04;
217
switch (diga->status[0] & IEC958_AES0_PRO_FS) {
218
case IEC958_AES0_PRO_FS_32000: bits |= 0x00; break;
219
case IEC958_AES0_PRO_FS_44100: bits |= 0x40; break; /* 44.1kHz */
220
case IEC958_AES0_PRO_FS_48000: bits |= 0x20; break; /* 48kHz */
221
default:
222
case IEC958_AES0_PRO_FS_NOTID: bits |= 0x00; break;
223
}
224
switch (diga->status[0] & IEC958_AES0_PRO_EMPHASIS) {
225
case IEC958_AES0_PRO_EMPHASIS_NONE: bits |= 0x02; break;
226
case IEC958_AES0_PRO_EMPHASIS_5015: bits |= 0x01; break;
227
case IEC958_AES0_PRO_EMPHASIS_CCITT: bits |= 0x00; break;
228
default:
229
case IEC958_AES0_PRO_EMPHASIS_NOTID: bits |= 0x03; break;
230
}
231
switch (diga->status[1] & IEC958_AES1_PRO_MODE) {
232
case IEC958_AES1_PRO_MODE_TWO:
233
case IEC958_AES1_PRO_MODE_STEREOPHONIC: bits |= 0x00; break;
234
default: bits |= 0x80; break;
235
}
236
}
237
return bits;
238
}
239
240
#endif /* SND_CS8404 */
241
242
#endif /* __SOUND_CS8403_H */
243
244