Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: pcm: add IEC958 channel status helper

Add a helper to create the IEC958 channel status from an ALSA
snd_pcm_runtime structure, taking account of the sample rate and
sample size.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Reviwed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Russell King and committed by
Takashi Iwai
9203dd01 838d1631

+108
+9
include/sound/pcm_iec958.h
··· 1 + #ifndef __SOUND_PCM_IEC958_H 2 + #define __SOUND_PCM_IEC958_H 3 + 4 + #include <linux/types.h> 5 + 6 + int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, 7 + size_t len); 8 + 9 + #endif
+3
sound/core/Kconfig
··· 9 9 config SND_PCM_ELD 10 10 bool 11 11 12 + config SND_PCM_IEC958 13 + bool 14 + 12 15 config SND_DMAENGINE_PCM 13 16 tristate 14 17
+1
sound/core/Makefile
··· 14 14 pcm_memory.o memalloc.o 15 15 snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o 16 16 snd-pcm-$(CONFIG_SND_PCM_ELD) += pcm_drm_eld.o 17 + snd-pcm-$(CONFIG_SND_PCM_IEC958) += pcm_iec958.o 17 18 18 19 # for trace-points 19 20 CFLAGS_pcm_lib.o := -I$(src)
+95
sound/core/pcm_iec958.c
··· 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_iec958.h> 13 + 14 + /** 15 + * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status 16 + * @runtime: pcm runtime structure with ->rate filled in 17 + * @cs: channel status buffer, at least four bytes 18 + * @len: length of channel status buffer 19 + * 20 + * Create the consumer format channel status data in @cs of maximum size 21 + * @len corresponding to the parameters of the PCM runtime @runtime. 22 + * 23 + * Drivers may wish to tweak the contents of the buffer after creation. 24 + * 25 + * Returns: length of buffer, or negative error code if something failed. 26 + */ 27 + int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, 28 + size_t len) 29 + { 30 + unsigned int fs, ws; 31 + 32 + if (len < 4) 33 + return -EINVAL; 34 + 35 + switch (runtime->rate) { 36 + case 32000: 37 + fs = IEC958_AES3_CON_FS_32000; 38 + break; 39 + case 44100: 40 + fs = IEC958_AES3_CON_FS_44100; 41 + break; 42 + case 48000: 43 + fs = IEC958_AES3_CON_FS_48000; 44 + break; 45 + case 88200: 46 + fs = IEC958_AES3_CON_FS_88200; 47 + break; 48 + case 96000: 49 + fs = IEC958_AES3_CON_FS_96000; 50 + break; 51 + case 176400: 52 + fs = IEC958_AES3_CON_FS_176400; 53 + break; 54 + case 192000: 55 + fs = IEC958_AES3_CON_FS_192000; 56 + break; 57 + default: 58 + return -EINVAL; 59 + } 60 + 61 + if (len > 4) { 62 + switch (snd_pcm_format_width(runtime->format)) { 63 + case 16: 64 + ws = IEC958_AES4_CON_WORDLEN_20_16; 65 + break; 66 + case 18: 67 + ws = IEC958_AES4_CON_WORDLEN_22_18; 68 + break; 69 + case 20: 70 + ws = IEC958_AES4_CON_WORDLEN_20_16 | 71 + IEC958_AES4_CON_MAX_WORDLEN_24; 72 + break; 73 + case 24: 74 + ws = IEC958_AES4_CON_WORDLEN_24_20 | 75 + IEC958_AES4_CON_MAX_WORDLEN_24; 76 + break; 77 + 78 + default: 79 + return -EINVAL; 80 + } 81 + } 82 + 83 + memset(cs, 0, len); 84 + 85 + cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE; 86 + cs[1] = IEC958_AES1_CON_GENERAL; 87 + cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC; 88 + cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | fs; 89 + 90 + if (len > 4) 91 + cs[4] = ws; 92 + 93 + return len; 94 + } 95 + EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);