h6. [[Hardware Abstraction Layer]] h6(. » [[HAL Device API]] h6((. » [[List of HAL devices]] h6(((. » 16-bit sound input/output controller h2. 16-bit sound input/output controller h5. (HALDeviceAudio_AudC) h4. Device API API versions 0, 1, 2 and 3 are currently defined. h5. API version 0 API version 0 is a simplistic version of the API, where most of the work is performed directly by the [[SoundDMA]] module. <pre> struct haldeviceaudio_audc { struct device; struct haldeviceaudio_mixer *mixer; unsigned int channels_out; unsigned int channels_in; } </pre> _mixer_ points to the [[HALDeviceAudio_Mixer|mixer device]] associated with this sound output device. _channels_out_ and _channels_in_ contain the number of output and input channels supported by the device. h5. API version 1 API version 1 extends the _haldevice_audc_ struct, allowing the HAL device to implement all the device-specific functionality that was previously in SoundDMA. <pre> struct haldevice_audc_1 { /* Version 0 interface */ struct haldevice_audc dev; /* 1.0 extension */ uint32_t dmaparams[5]; void (*PreEnable)(struct haldevice_audc_1 *, uint32_t dmabufsize); void (*PostEnable)(struct haldevice_audc_1 *, uint32_t dmabufsize); void (*PreDisable)(struct haldevice_audc_1 *); void (*PostDisable)(struct haldevice_audc_1 *); uint32_t (*IRQHandle)(struct haldevice_audc_1 *); uint32_t numrates; struct audioratetable *ratetable; void (*SetRate)(struct haldevice_audc_1 *, uint32_t index); }; </pre> The _dmaparams_ array contains the values of R0, R1, R2, R3 and R7 to provide to [[DMA_RegisterChannel]] when SoundDMA module registers itself with [[DMAManager]]. The _PreEnable_ and _PostEnable_ calls are made when audio is being enabled. They are both called with IRQs enabled, and with _dmabufsize_ specifying the size of the DMA buffer that is in use (in bytes). The driver should use _dmabufsize_ to program the controller as required, e.g. setting FIFO threshold levels. _PreEnable_ will be called before DMA is enabled, and _PostEnable_ will be called after DMA is enabled. The _PreDisable_ and _PostDisable_ calls are made when audio is being disabled. As with the _Enable_ calls, IRQs will be enabled, and _PreDisable_ will be called before DMA is disabled, while _PostDisable_ will be called after DMA has been disabled. If the device specifies an IRQ device number, then _IRQHandle_ will be called whenever an interrupt is received from the device, whether audio is currently enabled or not. The return code of _IRQHandle_ indicates what action the SoundDMA module should take: |_<. Return code |_<. Meaning | |0 |No action necessary | |1 |Audio reset required (i.e. turn audio off and then on again). This return code has no effect if audio is already off. | |Other values |Reserved | _numrates_ specifies the number of entries in the sample rate table. The sample rate table, pointed to by _ratetable_ is an array of _audioratetable_ structures: <pre> struct audioratetable { uint32_t frequency; // Frequency in Hz * 1024 uint8_t period; // Period in usec uint8_t reserved[3]; // Reserved - can be used by audio device }; </pre> The entries in the sample rate table must be in order of increasing frequency. _SetRate_ is used to set the current sample rate. The _index_ parameter is a 0-based index into _ratetable_, indicating the sample rate to use. The sample rate will only be modified while audio is turned off. h5. API version 2 API version 2 extends the _haldevice_audc_1_ struct, adding support for: * Devices which don't use DMAManager for transferring data * Control over whether stereo reversal is required * Control over buffer minimum size and alignment/granularity <pre> struct haldevice_audc_2 { /* Version 1 interface */ struct haldevice_audc_1 dev; /* 2.0 extension */ _kernel_oserror *(*CustomDMAEnable)(struct haldevice_audc_2 *dev, uint32_t dmabufsize, void *buff0, void *buff1, void *cbparam, void (*dmacallback)(uint32_t reason,void *cbparam)); uint32_t Flags; uint32_t MinBuffSize; uint32_t MinBuffAlign; }; </pre> h6. CustomDMAEnable _CustomDMAEnable_ is an optional entry, for use by devices which don't use DMAManager for handling data transfers. If this function is present then behaviour will be as follows: * _PreEnable_ and _PostEnable_ won't be called. _CustomDMAEnable_ will be called instead. * _PreDisable_ and _PostDisable_ will still be called; however as there will be no [[DMA_TerminateTransfer]] call between them, there is no difference in specification of the two functions. It's recommended that _PreDisable_ is implemented to disable sound/DMA, and _PostDisable_ is implemented as a NOP. * _dmaparams_ will not be used The _buff0_ and _buff1_ arguments to _CustomDMAEnable_ specify the logical addresses of both of the audio buffers. Playback should start with _buff0_ followed by _buff1_. _dmabuffsize_ is the size of each buffer. If _CustomDMAEnable_ is unable to start playback, a standard RISC OS error block can be returned describing the problem. _dmacallback_ is a callback function that must be called in certain situations: |_<. Parameter |_<^. Description | |reason |Reason code (see below) | |cbparam |_cbparam_ value that was passed to _CustomDMAEnable_ | Currently the only defined reason code is 0. This reason code must be used when a buffer has finished playback and is ready for re-filling by SoundDMA. The callback function must be called in a privileged processor mode, where it's safe to call SWIs (i.e. if in IRQ mode, SVC_lr has been preserved by caller). IRQs must be disabled if called in IRQ mode, otherwise IRQ state is unrestricted. h6. Other features _Flags_ is a flags word allowing specification of additional properties: |_^. Bit |_<^. Description | |0 |Stereo reversal required (Hardware uses L-R-L-R sample ordering instead of VIDC/RISC OS R-L-R-L ordering) | |\2. Other bits reserved, should be 0 | _MinBuffSize_ allows the device to specify the minimum buffer size that it supports, in bytes. _MinBuffAlign_ allows the device to specify the minimum buffer alignment/granularity, in bytes. This value must be a power of 2. Currently there is a maximum value of 4KB for both values. h5. API version 3 API version 3 adds support for the following additional features. The device struct is the same as with API version 2. * Non-power of two _MinBuffAlign_ values are now supported * _Flags_ has been extended with a new flag bit: |_^. Bit |_<^. Description | |1 |For _CustomDMAEnable_ mode: If set, SoundDMA should perform its processing in a synchronous manner from within the _dmacallback_ function, rather than postponing to an [[RTSupport]] routine. | Typically you would set this flag if you need to perform post-processing of the filled buffer on the CPU. h4. Support in RISC OS The _Sound0Trid_ version of the SoundDMA module only supports API version 0.x. The _Sound0HAL_ version of the SoundDMA module supports API version 1.x - 3.x. h4. Known implementations |_<. Device ID |_<. Description |_<. Implemented in | |HALDeviceID_AudC_M5451 |Acer M5451 AC'97 controller |HAL.Tungsten.s.Audio | |HALDeviceID_AudC_TPS65950 |TPS65950-compatible audio controller |HAL.OMAP3.s.Audio | |HALDeviceID_AudC_TWL6040 |TWL6040-compatible audio controller |HAL.OMAP4.s.Audio | |HALDeviceID_AudC_VCHIQ |VCHIQ audio service controller |HWSupport.Sound.BCMSound.s.Module | |HALDeviceID_AudC_Pandora |Pandora audio controller |HAL.OMAP3.s.PAudio | h6. Information sources: Kernel.Hdr.HALDevice, HWSupport.Sound.Sound0Trid.hdr.AudioDevice, HWSupport.Sound.Sound0HAL.hdr.AudioDevice in CVS