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