linux/sound/core/pcm_iec958.c
<<
>>
Prefs
   1/*
   2 *  PCM DRM helpers
   3 *
   4 *   This program is free software; you can redistribute it and/or modify
   5 *   it under the terms of the GNU General Public License version 2 as
   6 *   published by the Free Software Foundation.
   7 */
   8#include <linux/export.h>
   9#include <linux/types.h>
  10#include <sound/asoundef.h>
  11#include <sound/pcm.h>
  12#include <sound/pcm_params.h>
  13#include <sound/pcm_iec958.h>
  14
  15static int create_iec958_consumer(uint rate, uint sample_width,
  16                                  u8 *cs, size_t len)
  17{
  18        unsigned int fs, ws;
  19
  20        if (len < 4)
  21                return -EINVAL;
  22
  23        switch (rate) {
  24        case 32000:
  25                fs = IEC958_AES3_CON_FS_32000;
  26                break;
  27        case 44100:
  28                fs = IEC958_AES3_CON_FS_44100;
  29                break;
  30        case 48000:
  31                fs = IEC958_AES3_CON_FS_48000;
  32                break;
  33        case 88200:
  34                fs = IEC958_AES3_CON_FS_88200;
  35                break;
  36        case 96000:
  37                fs = IEC958_AES3_CON_FS_96000;
  38                break;
  39        case 176400:
  40                fs = IEC958_AES3_CON_FS_176400;
  41                break;
  42        case 192000:
  43                fs = IEC958_AES3_CON_FS_192000;
  44                break;
  45        default:
  46                return -EINVAL;
  47        }
  48
  49        if (len > 4) {
  50                switch (sample_width) {
  51                case 16:
  52                        ws = IEC958_AES4_CON_WORDLEN_20_16;
  53                        break;
  54                case 18:
  55                        ws = IEC958_AES4_CON_WORDLEN_22_18;
  56                        break;
  57                case 20:
  58                        ws = IEC958_AES4_CON_WORDLEN_20_16 |
  59                             IEC958_AES4_CON_MAX_WORDLEN_24;
  60                        break;
  61                case 24:
  62                case 32: /* Assume 24-bit width for 32-bit samples. */
  63                        ws = IEC958_AES4_CON_WORDLEN_24_20 |
  64                             IEC958_AES4_CON_MAX_WORDLEN_24;
  65                        break;
  66
  67                default:
  68                        return -EINVAL;
  69                }
  70        }
  71
  72        memset(cs, 0, len);
  73
  74        cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE;
  75        cs[1] = IEC958_AES1_CON_GENERAL;
  76        cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC;
  77        cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | fs;
  78
  79        if (len > 4)
  80                cs[4] = ws;
  81
  82        return len;
  83}
  84
  85/**
  86 * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
  87 * @runtime: pcm runtime structure with ->rate filled in
  88 * @cs: channel status buffer, at least four bytes
  89 * @len: length of channel status buffer
  90 *
  91 * Create the consumer format channel status data in @cs of maximum size
  92 * @len corresponding to the parameters of the PCM runtime @runtime.
  93 *
  94 * Drivers may wish to tweak the contents of the buffer after creation.
  95 *
  96 * Returns: length of buffer, or negative error code if something failed.
  97 */
  98int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
  99        size_t len)
 100{
 101        return create_iec958_consumer(runtime->rate,
 102                                      snd_pcm_format_width(runtime->format),
 103                                      cs, len);
 104}
 105EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);
 106
 107/**
 108 * snd_pcm_create_iec958_consumer_hw_params - create IEC958 channel status
 109 * @hw_params: the hw_params instance for extracting rate and sample format
 110 * @cs: channel status buffer, at least four bytes
 111 * @len: length of channel status buffer
 112 *
 113 * Create the consumer format channel status data in @cs of maximum size
 114 * @len corresponding to the parameters of the PCM runtime @runtime.
 115 *
 116 * Drivers may wish to tweak the contents of the buffer after creation.
 117 *
 118 * Returns: length of buffer, or negative error code if something failed.
 119 */
 120int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
 121                                             u8 *cs, size_t len)
 122{
 123        return create_iec958_consumer(params_rate(params), params_width(params),
 124                                      cs, len);
 125}
 126EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params);
 127