Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 #ifndef __SOUND_CS8403_H
0003 #define __SOUND_CS8403_H
0004 
0005 /*
0006  *  Routines for Cirrus Logic CS8403/CS8404A IEC958 (S/PDIF) Transmitter
0007  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
0008  *           Takashi Iwai <tiwai@suse.de>
0009  */
0010 
0011 #ifdef SND_CS8403
0012 
0013 #ifndef SND_CS8403_DECL
0014 #define SND_CS8403_DECL static
0015 #endif
0016 #ifndef SND_CS8403_DECODE
0017 #define SND_CS8403_DECODE snd_cs8403_decode_spdif_bits
0018 #endif
0019 #ifndef SND_CS8403_ENCODE
0020 #define SND_CS8403_ENCODE snd_cs8403_encode_spdif_bits
0021 #endif
0022 
0023 
0024 SND_CS8403_DECL void SND_CS8403_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
0025 {
0026     if (bits & 0x01) {  /* consumer */
0027         if (!(bits & 0x02))
0028             diga->status[0] |= IEC958_AES0_NONAUDIO;
0029         if (!(bits & 0x08))
0030             diga->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
0031         switch (bits & 0x10) {
0032         case 0x10: diga->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE; break;
0033         case 0x00: diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015; break;
0034         }
0035         if (!(bits & 0x80))
0036             diga->status[1] |= IEC958_AES1_CON_ORIGINAL;
0037         switch (bits & 0x60) {
0038         case 0x00: diga->status[1] |= IEC958_AES1_CON_MAGNETIC_ID; break;
0039         case 0x20: diga->status[1] |= IEC958_AES1_CON_DIGDIGCONV_ID; break;
0040         case 0x40: diga->status[1] |= IEC958_AES1_CON_LASEROPT_ID; break;
0041         case 0x60: diga->status[1] |= IEC958_AES1_CON_GENERAL; break;
0042         }
0043         switch (bits & 0x06) {
0044         case 0x00: diga->status[3] |= IEC958_AES3_CON_FS_44100; break;
0045         case 0x02: diga->status[3] |= IEC958_AES3_CON_FS_48000; break;
0046         case 0x04: diga->status[3] |= IEC958_AES3_CON_FS_32000; break;
0047         }
0048     } else {
0049         diga->status[0] = IEC958_AES0_PROFESSIONAL;
0050         switch (bits & 0x18) {
0051         case 0x00: diga->status[0] |= IEC958_AES0_PRO_FS_32000; break;
0052         case 0x10: diga->status[0] |= IEC958_AES0_PRO_FS_44100; break;
0053         case 0x08: diga->status[0] |= IEC958_AES0_PRO_FS_48000; break;
0054         case 0x18: diga->status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
0055         }
0056         switch (bits & 0x60) {
0057         case 0x20: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NONE; break;
0058         case 0x40: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; break;
0059         case 0x00: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_CCITT; break;
0060         case 0x60: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NOTID; break;
0061         }
0062         if (bits & 0x80)
0063             diga->status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
0064     }
0065 }
0066 
0067 SND_CS8403_DECL unsigned char SND_CS8403_ENCODE(struct snd_aes_iec958 *diga)
0068 {
0069     unsigned char bits;
0070 
0071     if (!(diga->status[0] & IEC958_AES0_PROFESSIONAL)) {
0072         bits = 0x01;    /* consumer mode */
0073         if (diga->status[0] & IEC958_AES0_NONAUDIO)
0074             bits &= ~0x02;
0075         else
0076             bits |= 0x02;
0077         if (diga->status[0] & IEC958_AES0_CON_NOT_COPYRIGHT)
0078             bits &= ~0x08;
0079         else
0080             bits |= 0x08;
0081         switch (diga->status[0] & IEC958_AES0_CON_EMPHASIS) {
0082         default:
0083         case IEC958_AES0_CON_EMPHASIS_NONE: bits |= 0x10; break;
0084         case IEC958_AES0_CON_EMPHASIS_5015: bits |= 0x00; break;
0085         }
0086         if (diga->status[1] & IEC958_AES1_CON_ORIGINAL)
0087             bits &= ~0x80;
0088         else
0089             bits |= 0x80;
0090         if ((diga->status[1] & IEC958_AES1_CON_CATEGORY) == IEC958_AES1_CON_GENERAL)
0091             bits |= 0x60;
0092         else {
0093             switch(diga->status[1] & IEC958_AES1_CON_MAGNETIC_MASK) {
0094             case IEC958_AES1_CON_MAGNETIC_ID:
0095                 bits |= 0x00; break;
0096             case IEC958_AES1_CON_DIGDIGCONV_ID:
0097                 bits |= 0x20; break;
0098             default:
0099             case IEC958_AES1_CON_LASEROPT_ID:
0100                 bits |= 0x40; break;
0101             }
0102         }
0103         switch (diga->status[3] & IEC958_AES3_CON_FS) {
0104         default:
0105         case IEC958_AES3_CON_FS_44100: bits |= 0x00; break;
0106         case IEC958_AES3_CON_FS_48000: bits |= 0x02; break;
0107         case IEC958_AES3_CON_FS_32000: bits |= 0x04; break;
0108         }
0109     } else {
0110         bits = 0x00;    /* professional mode */
0111         if (diga->status[0] & IEC958_AES0_NONAUDIO)
0112             bits &= ~0x02;
0113         else
0114             bits |= 0x02;
0115         /* CHECKME: I'm not sure about the bit order in val here */
0116         switch (diga->status[0] & IEC958_AES0_PRO_FS) {
0117         case IEC958_AES0_PRO_FS_32000:  bits |= 0x00; break;
0118         case IEC958_AES0_PRO_FS_44100:  bits |= 0x10; break;    /* 44.1kHz */
0119         case IEC958_AES0_PRO_FS_48000:  bits |= 0x08; break;    /* 48kHz */
0120         default:
0121         case IEC958_AES0_PRO_FS_NOTID: bits |= 0x18; break;
0122         }
0123         switch (diga->status[0] & IEC958_AES0_PRO_EMPHASIS) {
0124         case IEC958_AES0_PRO_EMPHASIS_NONE: bits |= 0x20; break;
0125         case IEC958_AES0_PRO_EMPHASIS_5015: bits |= 0x40; break;
0126         case IEC958_AES0_PRO_EMPHASIS_CCITT: bits |= 0x00; break;
0127         default:
0128         case IEC958_AES0_PRO_EMPHASIS_NOTID: bits |= 0x60; break;
0129         }
0130         switch (diga->status[1] & IEC958_AES1_PRO_MODE) {
0131         case IEC958_AES1_PRO_MODE_TWO:
0132         case IEC958_AES1_PRO_MODE_STEREOPHONIC: bits |= 0x00; break;
0133         default: bits |= 0x80; break;
0134         }
0135     }
0136     return bits;
0137 }
0138 
0139 #endif /* SND_CS8403 */
0140 
0141 #ifdef SND_CS8404
0142 
0143 #ifndef SND_CS8404_DECL
0144 #define SND_CS8404_DECL static
0145 #endif
0146 #ifndef SND_CS8404_DECODE
0147 #define SND_CS8404_DECODE snd_cs8404_decode_spdif_bits
0148 #endif
0149 #ifndef SND_CS8404_ENCODE
0150 #define SND_CS8404_ENCODE snd_cs8404_encode_spdif_bits
0151 #endif
0152 
0153 
0154 SND_CS8404_DECL void SND_CS8404_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
0155 {
0156     if (bits & 0x10) {  /* consumer */
0157         if (!(bits & 0x20))
0158             diga->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
0159         if (!(bits & 0x40))
0160             diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
0161         if (!(bits & 0x80))
0162             diga->status[1] |= IEC958_AES1_CON_ORIGINAL;
0163         switch (bits & 0x03) {
0164         case 0x00: diga->status[1] |= IEC958_AES1_CON_DAT; break;
0165         case 0x03: diga->status[1] |= IEC958_AES1_CON_GENERAL; break;
0166         }
0167         switch (bits & 0x06) {
0168         case 0x02: diga->status[3] |= IEC958_AES3_CON_FS_32000; break;
0169         case 0x04: diga->status[3] |= IEC958_AES3_CON_FS_48000; break;
0170         case 0x06: diga->status[3] |= IEC958_AES3_CON_FS_44100; break;
0171         }
0172     } else {
0173         diga->status[0] = IEC958_AES0_PROFESSIONAL;
0174         if (!(bits & 0x04))
0175             diga->status[0] |= IEC958_AES0_NONAUDIO;
0176         switch (bits & 0x60) {
0177         case 0x00: diga->status[0] |= IEC958_AES0_PRO_FS_32000; break;
0178         case 0x40: diga->status[0] |= IEC958_AES0_PRO_FS_44100; break;
0179         case 0x20: diga->status[0] |= IEC958_AES0_PRO_FS_48000; break;
0180         case 0x60: diga->status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
0181         }
0182         switch (bits & 0x03) {
0183         case 0x02: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NONE; break;
0184         case 0x01: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; break;
0185         case 0x00: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_CCITT; break;
0186         case 0x03: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NOTID; break;
0187         }
0188         if (!(bits & 0x80))
0189             diga->status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
0190     }
0191 }
0192 
0193 SND_CS8404_DECL unsigned char SND_CS8404_ENCODE(struct snd_aes_iec958 *diga)
0194 {
0195     unsigned char bits;
0196 
0197     if (!(diga->status[0] & IEC958_AES0_PROFESSIONAL)) {
0198         bits = 0x10;    /* consumer mode */
0199         if (!(diga->status[0] & IEC958_AES0_CON_NOT_COPYRIGHT))
0200             bits |= 0x20;
0201         if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_NONE)
0202             bits |= 0x40;
0203         if (!(diga->status[1] & IEC958_AES1_CON_ORIGINAL))
0204             bits |= 0x80;
0205         if ((diga->status[1] & IEC958_AES1_CON_CATEGORY) == IEC958_AES1_CON_GENERAL)
0206             bits |= 0x03;
0207         switch (diga->status[3] & IEC958_AES3_CON_FS) {
0208         default:
0209         case IEC958_AES3_CON_FS_44100: bits |= 0x06; break;
0210         case IEC958_AES3_CON_FS_48000: bits |= 0x04; break;
0211         case IEC958_AES3_CON_FS_32000: bits |= 0x02; break;
0212         }
0213     } else {
0214         bits = 0x00;    /* professional mode */
0215         if (!(diga->status[0] & IEC958_AES0_NONAUDIO))
0216             bits |= 0x04;
0217         switch (diga->status[0] & IEC958_AES0_PRO_FS) {
0218         case IEC958_AES0_PRO_FS_32000:  bits |= 0x00; break;
0219         case IEC958_AES0_PRO_FS_44100:  bits |= 0x40; break;    /* 44.1kHz */
0220         case IEC958_AES0_PRO_FS_48000:  bits |= 0x20; break;    /* 48kHz */
0221         default:
0222         case IEC958_AES0_PRO_FS_NOTID:  bits |= 0x00; break;
0223         }
0224         switch (diga->status[0] & IEC958_AES0_PRO_EMPHASIS) {
0225         case IEC958_AES0_PRO_EMPHASIS_NONE: bits |= 0x02; break;
0226         case IEC958_AES0_PRO_EMPHASIS_5015: bits |= 0x01; break;
0227         case IEC958_AES0_PRO_EMPHASIS_CCITT: bits |= 0x00; break;
0228         default:
0229         case IEC958_AES0_PRO_EMPHASIS_NOTID: bits |= 0x03; break;
0230         }
0231         switch (diga->status[1] & IEC958_AES1_PRO_MODE) {
0232         case IEC958_AES1_PRO_MODE_TWO:
0233         case IEC958_AES1_PRO_MODE_STEREOPHONIC: bits |= 0x00; break;
0234         default: bits |= 0x80; break;
0235         }
0236     }
0237     return bits;
0238 }
0239 
0240 #endif /* SND_CS8404 */
0241 
0242 #endif /* __SOUND_CS8403_H */