Tux
Communication
Mailing lists
Documentation
User Manual
Target board info.
Target chip info.
Support
Linux support
Bugzilla
Downloads
STLinux
Updates
Search
Google


The web
stlinux.com
Distribution Guide
Device drivers
Advanced Linux Sound Architecture (ALSA) drivers
ST Logo
Previous   Contents   Next

Note that this section only applies to STLinux distribution release 2.2. A new section which describes ALSA for the 2.3 release is currently being written.

Index

Introduction

ALSA (Advanced Linux Sound Architecture) output drivers are now included in the STLinux2.0 and LDDE2.2 distributions for the STm8000 and STb710x series CPU's. Although for the STLinux2.0 distribution no feature additions or feature parity maintenance to LDDE2.2 are expected. Currently PCM input is not supported. We recommend a working understanding of the ALSA model, and further information here assumes such a knowledge.

For those using an STb7109 CPU, there is no support in the STlinux2.0 distribution, only the STb7100 is supported here, please upgrade to LDDE2.2!

These drivers support output of analoug and digital audio, through the on and off-chip DACs, HDMI (High Definition Media Interface, and the TOSLink and COAX connectors in the case of SPDIF.

Boards / CPU's currently supported by each distribution are shown below.

ALSA driver CPU/Board support
CPU Board STLinux2.0 LDDE2.2
STM8000 ST22Eval (mb392) yes unofficial
STi7100 STb7100Reference - Coco (mb442) yes yes
STb7100 Validation Board (mb411) yes yes
SD HMS1 yes yes
STi7109 STb7100Reference - Coco (mb442) no yes
STb7100 Validation Board (mb411) no yes
SD HMS1 no unofficial
STb7109e Reference Board (mb448) no yes

In order to understand how you can use the kernel ALSA support in your application, please refer to the ALSA API or Sound section of the Linux Kernel documentation (/Documentation/sound/*).

Kernel Configuration and install

For generic ALSA support the following options must be configured. Built-in and loadable module versions are available. To enable the ALSA drivers, the following kernel configuration options are required, a working audio system is part of the default configuration files for both STLinux2.0 and LDDE2.2. For notes on configuring and building the Linux kernel please refer to the Kernel Configuration page.

The following options are mandatory.
  • /Sound/Sound Support
  • /Sound/Advanced Linux Sound Architecture Support
  • /Sound/Advanced Linux Sound Architecture/OSS Sound System/OSS PCM

The drivers must be able to allocate large physically contiguous regions for use in sample buffering. The CONFIG_BIGPHYS_AREA flag must be on in the kernel. It is enabled in CONFIG_BIGPHYS_AREA support. This is found in :

  • /System Type/Big Phys Area Support

The exact amount of memory that will be required will depend on number of samples that the ALSA device configured to allocate, and the playback format of the audio. This is a user definable operation, so this value will change. The maximal case of a 10 channel PCM playback in 32bit audio at 96Khz would yield a buffer of approximately 3.75 MB x ((10 * 96000)*4) for a 1 second buffer.

So The number of 4k pages reserved by bigphysarea should reflect the likely playback scenario in your system. This number is specified as a boot parameter to the kernel. Follow the instructions here and add the following to the command line.

bigphysmem=x \
	
	where x -  the number of 4k pages to reserve for the bigphysarea system

As well as the generic ALSA subsystem setup, it is also necessary to enable one of the STMicrolectronics platform specific drivers. Once again this is done by default in the def_config setup files. Otherwise one of the following should be achieved.

For the STm8000

  • /Sound/Advanced Linux Sound Architecture/ST PCM ALSA driver/STm8000 ALSA driver

For the STb710x

  • /Sound/Advanced Linux Sound Architecture/ST PCM ALSA driver/STb710x ALSA driver

The STMicorelectronics DMA API driver is required to enable the DMA subsystem, which is vital for audio playback as it performs the copy of PCM data from ALSA buffers into the player FIFO's.

Depending on your board / board revision it may be necessary to alter some jumpers please see the Target Boards page to see if this is necessary for your board.

ALSA on the Target Filesystem

For the STlinux2.0 distribution it is also necessary to configure your target filesystem for ALSA devices. This is achieved by running the "snddevices" script as root from your target board. This creates the necessary /dev nodes for the ALSA library. It can be found here This is not necessary for the LDDE2.2 Distribution.

Once booted, ALSA exports details of its active devices to /proc/asound/, here you can find a large amount of information about the setup and current state of each ALSA device. First it is necessary to understand the information exported here. On bootup, assuming all audio outputs are enabled, a list of four devices is registered, these are :

	6 Advanced Linux Sound Architecture Driver Version 1.0.11rc4.
	6 ALSA device list:
	6   #0: STb7100_PCM0
	6   #1: STb7100_PCM1
	6   #2: STb7100_SPDIF0
	6   #3: STb7100_CNV

These are mapped to card0 - card3 respectively, and the directory structure below these can be interrogated for relevant information, such as supported formats, playback state etc. ALSA devices can have several substreams - additional outputs slaved onto a single card, the STMicroelectronics ALSA devices do not use this mechanism, each is presented as a separate card, as they are in reality, all distinct devices.

To address the card properly either the hw:a,b or the plughw:a,b is used. Here a and b refer to the major and minor device number. Major numbers are allocated to devices, minors to substreams, hence to address the STM devices correctly, you would use the card number 0 to address PCM player 0, eg #0: STb7100_PCM0. So the form will be:

	/*address device through sw conversion layer*/
 	plughw:0,0 /*STb7100_PCM0*/
 	plughw:1,0 /*STb7100_PCM1*/
 	
	/*or with no sw conversion*/
 	hw:2,0 /*STb7100_SPDIF*/
 	hw:3,0 /*STb7100_CNV*/

Features

Audio output from the in-kernel ALSA drivers can now take place through four distinct output devices. Connectors for some of which may, or may not be included on certain boards. This represents a guide to the capabilities of the ALSA driver, not a particular board or CPU. The ALSA driver presents four audio devices.

  • PCM Player 0 - Analoug PCM player connected to off-chip DAC
  • PCM Player 1 - Analoug PCM player connected to on-chip DAC
  • SPDIF Player - Digital PCM Player connected to COAX and TOSLINK
  • HDMI Converter - Clocks data from PCM0 or SPDIF through the HDMI + formatting

Given that functionality for the Stm8000 series CPU's in not actively supported in LDDE2.2, from now on, unless otherwise stated, the features here are for the STb710x CPU's only. It can be assumed at present (release-2.6.17.13_stm22_0035) that STLinux2.0 ALSA and LDDE2.2 have equivalent functionality for the STb7100.

Supported Audio Formats

The ALSA driver natively supports both 32 and 16 bit PCM on all of its outputs. These correspond to the ALSA formats of SND_PCM_FORMAT_S32_LE(Signed 32 bit little endian) and SND_PCM_FORMAT_S16_LE(Signed 16 bit little endian). Playback is also possible at other bit-depths, through the plughw:n,n access, more on this later, but only the two aforementioned are available for direct access without software conversion, through the hw:n,n interface. A table showing available sampling frequencies for each output device is below.

Sample Frequency PCM_0 player PCM_1 player SPDIF player HDMI player
32000 yes yes yes yes
44100 yes yes yes yes
48000 yes yes yes yes
96000 yes yes no no

If the driver does not support the sample rate or sample format you specify, it will be necessary to utilize the plughw:n,n interface. The input bitstream will be then automatically sample rate / width and channel converted by the ALSA Software emulation layer to match the capabilities available in HW.

ALSA Controls

The STLinux ALSA drivers make use of the standard ALSA control mechanism for communicating setup parameters and mode changes from user to kernel-driver space. For the STMicroelectronics ALSA driver, controls are exported for SPDIF formatting, and dynamic adjustment of the playback clocks, and device playback synchronization.

Controls can be manipulated in two ways, via an alsautils( amixer) command line app, or via the ALSA library. To get an overview of the options available for each try a:

root@pauli:~# amixer -c2 contents

which will give control elements for card 2 (SPDIF player) for example.


numid=5,iface=MIXER,name='IEC958 Playback Con Mask'
  ; type=IEC958,access=r----,values=1
  : values=?
numid=2,iface=MIXER,name='IEC958 Playback PCM Sync'
  ; type=BOOLEAN,access=rw---,values=1
  : values=off
numid=7,iface=MIXER,name='IEC958 Playback Pro Mask'
  ; type=IEC958,access=r----,values=1
  : values=?
numid=8,iface=MIXER,name='IEC958 Playback Encoding'
  ; type=ENUMERATED,access=rw---,values=1,items=12
  ; Item #0 'IEC60958'
  ; Item #1 'IEC61937_AC3'
  ; Item #2 'IEC61937_DTS1'
  ; Item #3 'IEC61937_DTS2'
  ; Item #4 'IEC61937_DTS3'
  ; Item #5 'IEC61937_MPEG_384'
  ; Item #6 'IEC61937_MPEG_1152'
  ; Item #7 'IEC61937_MPEG_1024'
  ; Item #8 'IEC61937_MPEG_2304'
  ; Item #9 'IEC61937_MPEG_768'
  ; Item #10 'IEC61937_MPEG_2304_LSF'
  ; Item #11 'IEC61937_MPEG_768_LSF'
  : values=0
numid=6,iface=MIXER,name='IEC958 Playback Mask'
  ; type=IEC958,access=r----,values=1
  : values=?
numid=1,iface=MIXER,name='IEC958 Playback RAW'
  ; type=BOOLEAN,access=rw---,values=1
  : values=off
numid=3,iface=PCM,name='IEC958 Playback Default'
  ; type=IEC958,access=rw---,values=1
  : values=?
numid=4,iface=PCM,name='IEC958 Playback PCM Stream'
  ; type=IEC958,access=rw---,values=1
  : values=?
numid=9,iface=PCM,name='PLAYBACK Clock Adjust'
  ; type=INTEGER,access=rw---,values=0,min=-10000,max=10000,step=0
amixer: Control hw:2 element read error: Operation not permitted

This will list all of the controls and associated values available for a device. As we see from the above most of the controls relate to setup of the SPDIF stream parameters, these controls will be exported only for the HDMI protocol converter and the SPDIF player. Common to all devices however is the dynamic clock adjuster.

The only generic (non-SPDIF) control is the PLAYBACK Clock Adjust mechanism. This allows the user to dynamically adjust the playback clock of individual ALSA devices. It is intended to present a mechanism to facilitate Audio - Audio stream sync from the application. It allows incremental adjustment of the clock to +/- 10% of the current frequency in .001 % increments, although this is subject to a +/- 1% error.

To access these controls from a userspace application, use the standard ALSA-lib 'control interface' functions. Good example code of how this is done can be found in the alsa-utils package in either amixer / alsamixer or iecset for spdif related controls. As will be obvious from the ALSA-lib API, functions used to set control values depend on their type eg: 'integer', 'boolean' controls etc. The example below is for STMicro integer control 'IEC958 Playback Default'

	const char *dev = "default";
	const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT);
	snd_ctl_t *ctl;
	snd_ctl_elem_id_t *cid;
	snd_ctl_elem_value_t *cval;
	snd_aes_iec958_t iec958;
	
	/*where dev is device number i.e #2 for spdif player*/
	
	if ((err = snd_ctl_open(&ctl, dev, 0)) < 0) {
		error("snd_ctl_open", err);
		return 1;
	}
	snd_ctl_elem_id_alloca(&cid);
	snd_ctl_elem_value_alloca(&cval);
	snd_ctl_elem_value_set_id(cval, cid);

	if ((err = snd_ctl_elem_read(ctl, cval)) > 0) {
		error("snd_ctl_elem_read", err);
		return 1;
	}

	snd_ctl_elem_value_get_iec958(cval,&iec958);

	/*set the non-audio mode and disable copyright protect*/
	iec958->status[0] |= IEC958_AES0_NONAUDIO;
	iec958->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;

	/* store the values */
	snd_ctl_elem_value_set_iec958(cval,&iec958);

	if ((err = snd_ctl_elem_write(ctl, cval)) < 0) {
		error("snd_ctl_elem_write", err);
		return 1;
	}

	if ((err = snd_ctl_elem_read(ctl, cval)) > 0) {
		error("snd_ctl_elem_write", err);
		return 1;
	}

	snd_ctl_close(ctl);
	return 0;
}

Analoug Audio (PCM)

Analoug audio players are present in two forms in the STb710x. There are two players, once of which is connected to the on-chip DAC, the other is not connected to any DAC, and depends on the board whether it will be connected to either an external(off-chip) DAC or nothing. Also depending on cpu type these players may be either 2,10 or a programmable(2-10) number of channels wide. The Table below gives the combinations.

CPU Player 0 (External DAC) channels Player 1 (Internal (DAC)channels
STm8000 10 not present
STb7100 > C3 10 10
STb7100 >=C3 2 - 10 2
STb7109 2 - 10 2

Digital Audio (SPDIF)

The SPDIF player hardware is capable of SPDIF PCM output in stereo. Processing btistreams of > 2 channels would be dealt with by surround sound SPDIF formatting. Therefore the SPDIF player is always a 2 channel player,even with a compressed audio bitstream (the protocol still distinguishes between L + R frames). The SPDIF player HW is capable of outputting surround sound bitstreams, but additional work must be done by the user to achieve conformity to the SPDIF non-audio specification.

PCM output on SPDIF however is supported as standard. That is output according to the iec60958-1(SPDIF) specification. This requires that non-audio data is muxed onto the pcm bitstream, and gives information about copyright, channel status, frame validity etc. A brief introduction on SPDIF PCM can be found here. These data can be applied to a PCM bitstream by the ALSA driver, and will be applied to all streams fed to the SPDIF player, unless it is explicitly disabled.

The default configuration should provide sound output on a typical digital decoder /receiver(In PCM mode). Although it is possible for the user to specify their own configuration in accordance with their application requirements. ALSA Controls are used to set these parameters.

The default setup is as follows ( defines from ALSA-lib):

	IEC958_AES0_CON_NOT_COPYRIGHT
	IEC958_AES0_CON_EMPHASIS_NONE
	IEC958_AES1_CON_NON_IEC908_DVD
	IEC958_AES1_CON_ORIGINAL
	IEC958_AES2_CON_SOURCE_UNSPEC
	IEC958_AES2_CON_CHANNEL_UNSPEC
	IEC958_AES3_CON_FS_*set to match input stream*
	IEC958_AES3_CON_CLOCK_VARIABLE
	IEC958_AES4_CON_WORDLEN_MAX_24
	IEC958_AES4_CON_WORDLEN_24_20

Several access points are provided for this:

  • IEC958 Playback Pro Mask
  • IEC958 Playback Con Mask
  • IEC958 Playback PCM Stream
  • IEC958 Playback Raw

The first two of these will set a default mode for Consumer or Professional Mode SPDIF ( which has different meanings applied to stream status bits). The IEC958 Playback Con Mask is the default setup.

The IEC958 Playback Mask control is the standard ALSA mechanism for specifying SPDIF control words manually. The ALSA-lib exports all the available data values from /include/control.h and /include/asounddef.h. An understanding of the SPDIF protocol is assumed, and so specific values are not detailed here. These values can be added, assuming the correct ordering to the snd_kcontrol_t structure as below.... Then set in the normal way.

	iec60958_control->value.iec958.status[0] =  
					IEC958_AES0_CON_NOT_COPYRIGHT|
					IEC958_AES0_CON_EMPHASIS_NONE;
	
	iec60958_control->value.iec958.status[1] |= 
					IEC958_AES1_CON_LASEROPT_ID|
					IEC958_AES1_CON_ORIGINAL;

The IEC958 Playback Raw control does not utilize the standard ALSA/IEC60958 definitions. This is intended for bespoke applications which need to supply non-standard stream formatting to their SPDIF streams. In this case the user must supply a complete bitmask for all IEC60958 control and status bits - none are added by the driver. However the 'p' parity bit will always be added by the SPDIF player HW, so must not be defined in the bitmask. Please refer to the SPDIF-PCM specification document for details of formats and parameters.

These stream parameters are dependent to some extent on the stream properties, and therefore it is necessary to specify the configuration of this non-audio data to the ALSA driver before playback begins. If values are set whilst playback is ongoing or paused, they will not be updated until the ALSA device has been closed.

One thing that is important to note is that if your application access' the ALSA subsystem through the mmap method to the ALSA buffer, none of this SPDIF formatting is available, as samples are written directly from user to hardware buffer, without the driver being able to apply any channel formatting. Therefore any IEC60958(SPDIF-PCM) or IEC61937(SPDIF-surround) formatted must be applied entirely by the user, with the exception of the parity bit.

For those wishing to use SPDIF in compressed (surround sound) mode, no implicit support is provided by the driver. An additional layer is formatting (iec61937-1) is required on top of the standard SPDIF PCM format(iec60958) this is not provided by the ALSA driver.

SPDIF in compressed mode represents frames of encoded audio, which represent varying numbers of audio samples ( depending on Fs and codec type), being packed into a secondary line protocol which is then applied on top of the standard PCM-SPDIF formatting(iec60958),albeit with values specifying that the bitstream is non-audio(ie encoded). The upper level (iec61937) format provides a header giving stream type and format info, the encoded audio frame, plus zero padding that equates the total size of a data burst to be equal to that of the audio frame decoded into PCM. The STMicroelectronics ALSA driver does not provide any support for this upper level formatting, and it must be completed before data enters the ALSA buffer in order to gain correct surround sound output.

There are two additional controls which are relevant in the SPDIF case, and warrant an explanation here as they are bespoke to STMicroelectronics devices. Both are to do with processing SPDIF in surround mode. For ST hardware it is possible to synchronize, to PCM frame accuracy the playback of both PCM players to either the triggering of playback on either the spdif player or the protocol converter. The reason is to do with latency in decoding an encoded frame at the digital receiver, and the timeslip that would create between an encoded bitstream and the same bitstream in PCM. We can therefore specify a time delay such that the encoded stream, once decoded, would then be in-sync with the original PCM stream. It is also important to set this value correctly so pausing is handled correctly in encoded mode.

This delay value will differ depending on the stream type being processed, be it AC3, MPEG, DTS etc. So one control IEC958 Playback Encoding specifies the stream type, the ALSA driver then calculates the correct delay to apply and programs the player HW accordingly. So when forwarding a compressed bitstream this control must be set to he value according to the stream type, and with IEC60958 (default) when a PCM bitstream is processed by the SPDIF player.

The second, which is to enable or disable the PCM player synchronization - PCM Sync also available from the SPDIF or HDMI converter players, sets a boolean value to enable/disable this synchronization mechanism, default is disabled. At this time it is not possible to synchronize one PCM player, but not the other. The bitswitch is a global enable/disable.

HDMI

HDMI audio can be generated in one of two ways, via an I2S protocol converter, which utilizes the PCM_0 player IP to clock and generates the correct HDMI protocol, or via the SPDIF player which can be routed to the HDMI output.

In the case of the protocol converter, only PCM bitstreams in I2S can be input, therefore no surround sound is possible when using this IP. Additionally because the PCM_0 player IP is used to generate the signal, when the converter device is enabled, the PCM_0 player is unavailable to playback another stream. However the original PCM input to the converter will also be output from the PCM_0 DAC's( if connected) and the HDMI connector.

The channel status and validity bits are set in the same method as above, except this time card #3 should be used.

If the SPDIF player is utilized surround sound is possible, providing the encoded stream is formatted in accordance with the surround sound format described above. In this instance the SPDIF player will be unavailable to process a separate stream, but will also output from both SPDIF and HDMI outputs.

HDMI in the system is mastered by the Video/Framebuffer driver(stgfb), therefore selection of which source the HDMI will be connected to must be done through this interface. Two methods are available ioctl and cli application.

A Linux framebuffer header must be included to access these ioctl codes. It can be included from either the framebuffer sources, where it lives in /Linux/video/stmfb.h , or from the kernel header package, where it can be accessed by including linux/stmfb.h

The framebuffer control application stfbcontrol can be invoked to wiggle this ioctl. from the command line try:

	
root@target:~# stfbcontrol i 

/*to enable HDMI through I2S converter*/

root@target:~# stfbcontrol s

/*to enable HDMI through SPDIF*/

To do the same programmatically try this example code for manipulating the framebuffer ioctls.

	
			
	int fbdb;
		
	if((fbfd  = open("/dev/fb0",   O_RDWR)) < 0)
	{
		perror("Unable to open framebuffer");
		exit(1);
	}
	
	/*enable SPDIF mode */
	int hdmiaudio = STMFBIO_HDMI_AUDIO_SPDIF;
	if(ioctl(fbfd, STMFBIO_SET_HDMI_AUDIO, &hdmiaudio) < 0)
	{
		perror("STMFBIO_SET_HDMI_AUDIO");
		exit(1);
	}
	/*enable I2S mode*/
		
	hdmiaudio = STMFBIO_HDMI_AUDIO_I2S;
	if(ioctl(fbfd, STMFBIO_SET_HDMI_AUDIO, &hdmiaudio) < 0)
	{
		perror("STMFBIO_SET_HDMI_AUDIO");
		exit(1);
	}
Previous   Contents   Next
Valid HTML 4.01! Last updated: 2008/01/18 12:16:47
© Copyright STMicroelectronics Limited, 2005
Printer