linux/include/sound/cs8403.h
<<
>>
Prefs
   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 <perex@perex.cz>,
   8 *                   Takashi Iwai <tiwai@suse.de>
   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
  24SND_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
  67SND_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
 154SND_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
 193SND_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