xref: /linux/include/sound/cs8403.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*1a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds #ifndef __SOUND_CS8403_H
31da177e4SLinus Torvalds #define __SOUND_CS8403_H
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds /*
61da177e4SLinus Torvalds  *  Routines for Cirrus Logic CS8403/CS8404A IEC958 (S/PDIF) Transmitter
7c1017a4cSJaroslav Kysela  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
81da177e4SLinus Torvalds  *		     Takashi Iwai <tiwai@suse.de>
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #ifdef SND_CS8403
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds #ifndef SND_CS8403_DECL
141da177e4SLinus Torvalds #define SND_CS8403_DECL static
151da177e4SLinus Torvalds #endif
161da177e4SLinus Torvalds #ifndef SND_CS8403_DECODE
171da177e4SLinus Torvalds #define SND_CS8403_DECODE snd_cs8403_decode_spdif_bits
181da177e4SLinus Torvalds #endif
191da177e4SLinus Torvalds #ifndef SND_CS8403_ENCODE
201da177e4SLinus Torvalds #define SND_CS8403_ENCODE snd_cs8403_encode_spdif_bits
211da177e4SLinus Torvalds #endif
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds 
SND_CS8403_DECODE(struct snd_aes_iec958 * diga,unsigned char bits)2497f02e05STakashi Iwai SND_CS8403_DECL void SND_CS8403_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
251da177e4SLinus Torvalds {
261da177e4SLinus Torvalds 	if (bits & 0x01) {	/* consumer */
271da177e4SLinus Torvalds 		if (!(bits & 0x02))
281da177e4SLinus Torvalds 			diga->status[0] |= IEC958_AES0_NONAUDIO;
291da177e4SLinus Torvalds 		if (!(bits & 0x08))
301da177e4SLinus Torvalds 			diga->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
311da177e4SLinus Torvalds 		switch (bits & 0x10) {
321da177e4SLinus Torvalds 		case 0x10: diga->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE; break;
331da177e4SLinus Torvalds 		case 0x00: diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015; break;
341da177e4SLinus Torvalds 		}
351da177e4SLinus Torvalds 		if (!(bits & 0x80))
361da177e4SLinus Torvalds 			diga->status[1] |= IEC958_AES1_CON_ORIGINAL;
371da177e4SLinus Torvalds 		switch (bits & 0x60) {
381da177e4SLinus Torvalds 		case 0x00: diga->status[1] |= IEC958_AES1_CON_MAGNETIC_ID; break;
391da177e4SLinus Torvalds 		case 0x20: diga->status[1] |= IEC958_AES1_CON_DIGDIGCONV_ID; break;
401da177e4SLinus Torvalds 		case 0x40: diga->status[1] |= IEC958_AES1_CON_LASEROPT_ID; break;
411da177e4SLinus Torvalds 		case 0x60: diga->status[1] |= IEC958_AES1_CON_GENERAL; break;
421da177e4SLinus Torvalds 		}
431da177e4SLinus Torvalds 		switch (bits & 0x06) {
441da177e4SLinus Torvalds 		case 0x00: diga->status[3] |= IEC958_AES3_CON_FS_44100; break;
451da177e4SLinus Torvalds 		case 0x02: diga->status[3] |= IEC958_AES3_CON_FS_48000; break;
461da177e4SLinus Torvalds 		case 0x04: diga->status[3] |= IEC958_AES3_CON_FS_32000; break;
471da177e4SLinus Torvalds 		}
481da177e4SLinus Torvalds 	} else {
491da177e4SLinus Torvalds 		diga->status[0] = IEC958_AES0_PROFESSIONAL;
501da177e4SLinus Torvalds 		switch (bits & 0x18) {
511da177e4SLinus Torvalds 		case 0x00: diga->status[0] |= IEC958_AES0_PRO_FS_32000; break;
521da177e4SLinus Torvalds 		case 0x10: diga->status[0] |= IEC958_AES0_PRO_FS_44100; break;
531da177e4SLinus Torvalds 		case 0x08: diga->status[0] |= IEC958_AES0_PRO_FS_48000; break;
541da177e4SLinus Torvalds 		case 0x18: diga->status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
551da177e4SLinus Torvalds 		}
561da177e4SLinus Torvalds 		switch (bits & 0x60) {
571da177e4SLinus Torvalds 		case 0x20: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NONE; break;
581da177e4SLinus Torvalds 		case 0x40: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; break;
591da177e4SLinus Torvalds 		case 0x00: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_CCITT; break;
601da177e4SLinus Torvalds 		case 0x60: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NOTID; break;
611da177e4SLinus Torvalds 		}
621da177e4SLinus Torvalds 		if (bits & 0x80)
631da177e4SLinus Torvalds 			diga->status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
641da177e4SLinus Torvalds 	}
651da177e4SLinus Torvalds }
661da177e4SLinus Torvalds 
SND_CS8403_ENCODE(struct snd_aes_iec958 * diga)6797f02e05STakashi Iwai SND_CS8403_DECL unsigned char SND_CS8403_ENCODE(struct snd_aes_iec958 *diga)
681da177e4SLinus Torvalds {
691da177e4SLinus Torvalds 	unsigned char bits;
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds 	if (!(diga->status[0] & IEC958_AES0_PROFESSIONAL)) {
721da177e4SLinus Torvalds 		bits = 0x01;	/* consumer mode */
731da177e4SLinus Torvalds 		if (diga->status[0] & IEC958_AES0_NONAUDIO)
741da177e4SLinus Torvalds 			bits &= ~0x02;
751da177e4SLinus Torvalds 		else
761da177e4SLinus Torvalds 			bits |= 0x02;
771da177e4SLinus Torvalds 		if (diga->status[0] & IEC958_AES0_CON_NOT_COPYRIGHT)
781da177e4SLinus Torvalds 			bits &= ~0x08;
791da177e4SLinus Torvalds 		else
801da177e4SLinus Torvalds 			bits |= 0x08;
811da177e4SLinus Torvalds 		switch (diga->status[0] & IEC958_AES0_CON_EMPHASIS) {
821da177e4SLinus Torvalds 		default:
831da177e4SLinus Torvalds 		case IEC958_AES0_CON_EMPHASIS_NONE: bits |= 0x10; break;
841da177e4SLinus Torvalds 		case IEC958_AES0_CON_EMPHASIS_5015: bits |= 0x00; break;
851da177e4SLinus Torvalds 		}
861da177e4SLinus Torvalds 		if (diga->status[1] & IEC958_AES1_CON_ORIGINAL)
871da177e4SLinus Torvalds 			bits &= ~0x80;
881da177e4SLinus Torvalds 		else
891da177e4SLinus Torvalds 			bits |= 0x80;
901da177e4SLinus Torvalds 		if ((diga->status[1] & IEC958_AES1_CON_CATEGORY) == IEC958_AES1_CON_GENERAL)
911da177e4SLinus Torvalds 			bits |= 0x60;
921da177e4SLinus Torvalds 		else {
931da177e4SLinus Torvalds 			switch(diga->status[1] & IEC958_AES1_CON_MAGNETIC_MASK) {
941da177e4SLinus Torvalds 			case IEC958_AES1_CON_MAGNETIC_ID:
951da177e4SLinus Torvalds 				bits |= 0x00; break;
961da177e4SLinus Torvalds 			case IEC958_AES1_CON_DIGDIGCONV_ID:
971da177e4SLinus Torvalds 				bits |= 0x20; break;
981da177e4SLinus Torvalds 			default:
991da177e4SLinus Torvalds 			case IEC958_AES1_CON_LASEROPT_ID:
1001da177e4SLinus Torvalds 				bits |= 0x40; break;
1011da177e4SLinus Torvalds 			}
1021da177e4SLinus Torvalds 		}
1031da177e4SLinus Torvalds 		switch (diga->status[3] & IEC958_AES3_CON_FS) {
1041da177e4SLinus Torvalds 		default:
1051da177e4SLinus Torvalds 		case IEC958_AES3_CON_FS_44100: bits |= 0x00; break;
1061da177e4SLinus Torvalds 		case IEC958_AES3_CON_FS_48000: bits |= 0x02; break;
1071da177e4SLinus Torvalds 		case IEC958_AES3_CON_FS_32000: bits |= 0x04; break;
1081da177e4SLinus Torvalds 		}
1091da177e4SLinus Torvalds 	} else {
1101da177e4SLinus Torvalds 		bits = 0x00;	/* professional mode */
1111da177e4SLinus Torvalds 		if (diga->status[0] & IEC958_AES0_NONAUDIO)
1121da177e4SLinus Torvalds 			bits &= ~0x02;
1131da177e4SLinus Torvalds 		else
1141da177e4SLinus Torvalds 			bits |= 0x02;
1151da177e4SLinus Torvalds 		/* CHECKME: I'm not sure about the bit order in val here */
1161da177e4SLinus Torvalds 		switch (diga->status[0] & IEC958_AES0_PRO_FS) {
1171da177e4SLinus Torvalds 		case IEC958_AES0_PRO_FS_32000:	bits |= 0x00; break;
1181da177e4SLinus Torvalds 		case IEC958_AES0_PRO_FS_44100:	bits |= 0x10; break;	/* 44.1kHz */
1191da177e4SLinus Torvalds 		case IEC958_AES0_PRO_FS_48000:	bits |= 0x08; break;	/* 48kHz */
1201da177e4SLinus Torvalds 		default:
1211da177e4SLinus Torvalds 		case IEC958_AES0_PRO_FS_NOTID: bits |= 0x18; break;
1221da177e4SLinus Torvalds 		}
1231da177e4SLinus Torvalds 		switch (diga->status[0] & IEC958_AES0_PRO_EMPHASIS) {
1241da177e4SLinus Torvalds 		case IEC958_AES0_PRO_EMPHASIS_NONE: bits |= 0x20; break;
1251da177e4SLinus Torvalds 		case IEC958_AES0_PRO_EMPHASIS_5015: bits |= 0x40; break;
1261da177e4SLinus Torvalds 		case IEC958_AES0_PRO_EMPHASIS_CCITT: bits |= 0x00; break;
1271da177e4SLinus Torvalds 		default:
1281da177e4SLinus Torvalds 		case IEC958_AES0_PRO_EMPHASIS_NOTID: bits |= 0x60; break;
1291da177e4SLinus Torvalds 		}
1301da177e4SLinus Torvalds 		switch (diga->status[1] & IEC958_AES1_PRO_MODE) {
1311da177e4SLinus Torvalds 		case IEC958_AES1_PRO_MODE_TWO:
1321da177e4SLinus Torvalds 		case IEC958_AES1_PRO_MODE_STEREOPHONIC: bits |= 0x00; break;
1331da177e4SLinus Torvalds 		default: bits |= 0x80; break;
1341da177e4SLinus Torvalds 		}
1351da177e4SLinus Torvalds 	}
1361da177e4SLinus Torvalds 	return bits;
1371da177e4SLinus Torvalds }
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds #endif /* SND_CS8403 */
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds #ifdef SND_CS8404
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds #ifndef SND_CS8404_DECL
1441da177e4SLinus Torvalds #define SND_CS8404_DECL static
1451da177e4SLinus Torvalds #endif
1461da177e4SLinus Torvalds #ifndef SND_CS8404_DECODE
1471da177e4SLinus Torvalds #define SND_CS8404_DECODE snd_cs8404_decode_spdif_bits
1481da177e4SLinus Torvalds #endif
1491da177e4SLinus Torvalds #ifndef SND_CS8404_ENCODE
1501da177e4SLinus Torvalds #define SND_CS8404_ENCODE snd_cs8404_encode_spdif_bits
1511da177e4SLinus Torvalds #endif
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds 
SND_CS8404_DECODE(struct snd_aes_iec958 * diga,unsigned char bits)15497f02e05STakashi Iwai SND_CS8404_DECL void SND_CS8404_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
1551da177e4SLinus Torvalds {
1561da177e4SLinus Torvalds 	if (bits & 0x10) {	/* consumer */
1571da177e4SLinus Torvalds 		if (!(bits & 0x20))
1581da177e4SLinus Torvalds 			diga->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
1591da177e4SLinus Torvalds 		if (!(bits & 0x40))
1601da177e4SLinus Torvalds 			diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
1611da177e4SLinus Torvalds 		if (!(bits & 0x80))
1621da177e4SLinus Torvalds 			diga->status[1] |= IEC958_AES1_CON_ORIGINAL;
1631da177e4SLinus Torvalds 		switch (bits & 0x03) {
1641da177e4SLinus Torvalds 		case 0x00: diga->status[1] |= IEC958_AES1_CON_DAT; break;
1651da177e4SLinus Torvalds 		case 0x03: diga->status[1] |= IEC958_AES1_CON_GENERAL; break;
1661da177e4SLinus Torvalds 		}
1671da177e4SLinus Torvalds 		switch (bits & 0x06) {
1681da177e4SLinus Torvalds 		case 0x02: diga->status[3] |= IEC958_AES3_CON_FS_32000; break;
1691da177e4SLinus Torvalds 		case 0x04: diga->status[3] |= IEC958_AES3_CON_FS_48000; break;
1701da177e4SLinus Torvalds 		case 0x06: diga->status[3] |= IEC958_AES3_CON_FS_44100; break;
1711da177e4SLinus Torvalds 		}
1721da177e4SLinus Torvalds 	} else {
1731da177e4SLinus Torvalds 		diga->status[0] = IEC958_AES0_PROFESSIONAL;
1741da177e4SLinus Torvalds 		if (!(bits & 0x04))
1751da177e4SLinus Torvalds 			diga->status[0] |= IEC958_AES0_NONAUDIO;
1761da177e4SLinus Torvalds 		switch (bits & 0x60) {
1771da177e4SLinus Torvalds 		case 0x00: diga->status[0] |= IEC958_AES0_PRO_FS_32000; break;
1781da177e4SLinus Torvalds 		case 0x40: diga->status[0] |= IEC958_AES0_PRO_FS_44100; break;
1791da177e4SLinus Torvalds 		case 0x20: diga->status[0] |= IEC958_AES0_PRO_FS_48000; break;
1801da177e4SLinus Torvalds 		case 0x60: diga->status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
1811da177e4SLinus Torvalds 		}
1821da177e4SLinus Torvalds 		switch (bits & 0x03) {
1831da177e4SLinus Torvalds 		case 0x02: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NONE; break;
1841da177e4SLinus Torvalds 		case 0x01: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; break;
1851da177e4SLinus Torvalds 		case 0x00: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_CCITT; break;
1861da177e4SLinus Torvalds 		case 0x03: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NOTID; break;
1871da177e4SLinus Torvalds 		}
1881da177e4SLinus Torvalds 		if (!(bits & 0x80))
1891da177e4SLinus Torvalds 			diga->status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
1901da177e4SLinus Torvalds 	}
1911da177e4SLinus Torvalds }
1921da177e4SLinus Torvalds 
SND_CS8404_ENCODE(struct snd_aes_iec958 * diga)19397f02e05STakashi Iwai SND_CS8404_DECL unsigned char SND_CS8404_ENCODE(struct snd_aes_iec958 *diga)
1941da177e4SLinus Torvalds {
1951da177e4SLinus Torvalds 	unsigned char bits;
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds 	if (!(diga->status[0] & IEC958_AES0_PROFESSIONAL)) {
1981da177e4SLinus Torvalds 		bits = 0x10;	/* consumer mode */
1991da177e4SLinus Torvalds 		if (!(diga->status[0] & IEC958_AES0_CON_NOT_COPYRIGHT))
2001da177e4SLinus Torvalds 			bits |= 0x20;
2011da177e4SLinus Torvalds 		if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_NONE)
2021da177e4SLinus Torvalds 			bits |= 0x40;
2031da177e4SLinus Torvalds 		if (!(diga->status[1] & IEC958_AES1_CON_ORIGINAL))
2041da177e4SLinus Torvalds 			bits |= 0x80;
2051da177e4SLinus Torvalds 		if ((diga->status[1] & IEC958_AES1_CON_CATEGORY) == IEC958_AES1_CON_GENERAL)
2061da177e4SLinus Torvalds 			bits |= 0x03;
2071da177e4SLinus Torvalds 		switch (diga->status[3] & IEC958_AES3_CON_FS) {
2081da177e4SLinus Torvalds 		default:
2091da177e4SLinus Torvalds 		case IEC958_AES3_CON_FS_44100: bits |= 0x06; break;
2101da177e4SLinus Torvalds 		case IEC958_AES3_CON_FS_48000: bits |= 0x04; break;
2111da177e4SLinus Torvalds 		case IEC958_AES3_CON_FS_32000: bits |= 0x02; break;
2121da177e4SLinus Torvalds 		}
2131da177e4SLinus Torvalds 	} else {
2141da177e4SLinus Torvalds 		bits = 0x00;	/* professional mode */
2151da177e4SLinus Torvalds 		if (!(diga->status[0] & IEC958_AES0_NONAUDIO))
2161da177e4SLinus Torvalds 			bits |= 0x04;
2171da177e4SLinus Torvalds 		switch (diga->status[0] & IEC958_AES0_PRO_FS) {
2181da177e4SLinus Torvalds 		case IEC958_AES0_PRO_FS_32000:	bits |= 0x00; break;
2191da177e4SLinus Torvalds 		case IEC958_AES0_PRO_FS_44100:	bits |= 0x40; break;	/* 44.1kHz */
2201da177e4SLinus Torvalds 		case IEC958_AES0_PRO_FS_48000:	bits |= 0x20; break;	/* 48kHz */
2211da177e4SLinus Torvalds 		default:
2221da177e4SLinus Torvalds 		case IEC958_AES0_PRO_FS_NOTID:	bits |= 0x00; break;
2231da177e4SLinus Torvalds 		}
2241da177e4SLinus Torvalds 		switch (diga->status[0] & IEC958_AES0_PRO_EMPHASIS) {
2251da177e4SLinus Torvalds 		case IEC958_AES0_PRO_EMPHASIS_NONE: bits |= 0x02; break;
2261da177e4SLinus Torvalds 		case IEC958_AES0_PRO_EMPHASIS_5015: bits |= 0x01; break;
2271da177e4SLinus Torvalds 		case IEC958_AES0_PRO_EMPHASIS_CCITT: bits |= 0x00; break;
2281da177e4SLinus Torvalds 		default:
2291da177e4SLinus Torvalds 		case IEC958_AES0_PRO_EMPHASIS_NOTID: bits |= 0x03; break;
2301da177e4SLinus Torvalds 		}
2311da177e4SLinus Torvalds 		switch (diga->status[1] & IEC958_AES1_PRO_MODE) {
2321da177e4SLinus Torvalds 		case IEC958_AES1_PRO_MODE_TWO:
2331da177e4SLinus Torvalds 		case IEC958_AES1_PRO_MODE_STEREOPHONIC: bits |= 0x00; break;
2341da177e4SLinus Torvalds 		default: bits |= 0x80; break;
2351da177e4SLinus Torvalds 		}
2361da177e4SLinus Torvalds 	}
2371da177e4SLinus Torvalds 	return bits;
2381da177e4SLinus Torvalds }
2391da177e4SLinus Torvalds 
2401da177e4SLinus Torvalds #endif /* SND_CS8404 */
2411da177e4SLinus Torvalds 
2421da177e4SLinus Torvalds #endif /* __SOUND_CS8403_H */
243