2008-07-23 17:03:07 +04:00
/*
* linux / sound / soc - dai . h - - ALSA SoC Layer
*
* Copyright : 2005 - 2008 Wolfson Microelectronics . PLC .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* Digital Audio Interface ( DAI ) API .
*/
# ifndef __LINUX_SND_SOC_DAI_H
# define __LINUX_SND_SOC_DAI_H
# include <linux/list.h>
struct snd_pcm_substream ;
2012-02-17 07:37:51 +04:00
struct snd_soc_dapm_widget ;
2012-08-16 15:40:40 +04:00
struct snd_compr_stream ;
2008-07-23 17:03:07 +04:00
/*
* DAI hardware audio formats .
*
* Describes the physical PCM data formating and clocking . Add new formats
* to the end .
*/
2011-09-27 19:41:01 +04:00
# define SND_SOC_DAIFMT_I2S 1 /* I2S mode */
# define SND_SOC_DAIFMT_RIGHT_J 2 /* Right Justified mode */
# define SND_SOC_DAIFMT_LEFT_J 3 /* Left Justified mode */
# define SND_SOC_DAIFMT_DSP_A 4 /* L data MSB after FRM LRC */
# define SND_SOC_DAIFMT_DSP_B 5 /* L data MSB during FRM LRC */
# define SND_SOC_DAIFMT_AC97 6 /* AC97 */
# define SND_SOC_DAIFMT_PDM 7 /* Pulse density modulation */
2008-07-23 17:03:07 +04:00
/* left and right justified also known as MSB and LSB respectively */
# define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J
# define SND_SOC_DAIFMT_LSB SND_SOC_DAIFMT_RIGHT_J
/*
* DAI Clock gating .
*
2009-07-14 02:05:11 +04:00
* DAI bit clocks can be be gated ( disabled ) when the DAI is not
2008-07-23 17:03:07 +04:00
* sending or receiving PCM data in a frame . This can be used to save power .
*/
2011-09-27 19:41:01 +04:00
# define SND_SOC_DAIFMT_CONT (1 << 4) /* continuous clock */
2013-01-30 09:03:13 +04:00
# define SND_SOC_DAIFMT_GATED (0 << 4) /* clock is gated */
2008-07-23 17:03:07 +04:00
/*
* DAI hardware signal inversions .
*
* Specifies whether the DAI can also support inverted clocks for the specified
* format .
*/
2013-01-16 08:18:23 +04:00
# define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */
2011-09-27 19:41:01 +04:00
# define SND_SOC_DAIFMT_NB_IF (2 << 8) /* normal BCLK + inv FRM */
# define SND_SOC_DAIFMT_IB_NF (3 << 8) /* invert BCLK + nor FRM */
# define SND_SOC_DAIFMT_IB_IF (4 << 8) /* invert BCLK + FRM */
2008-07-23 17:03:07 +04:00
/*
* DAI hardware clock masters .
*
* This is wrt the codec , the inverse is true for the interface
2009-07-14 02:05:11 +04:00
* i . e . if the codec is clk and FRM master then the interface is
2008-07-23 17:03:07 +04:00
* clk and frame slave .
*/
2011-09-27 19:41:01 +04:00
# define SND_SOC_DAIFMT_CBM_CFM (1 << 12) /* codec clk & FRM master */
# define SND_SOC_DAIFMT_CBS_CFM (2 << 12) /* codec clk slave & FRM master */
# define SND_SOC_DAIFMT_CBM_CFS (3 << 12) /* codec clk master & frame slave */
# define SND_SOC_DAIFMT_CBS_CFS (4 << 12) /* codec clk & FRM slave */
2008-07-23 17:03:07 +04:00
# define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
# define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
# define SND_SOC_DAIFMT_INV_MASK 0x0f00
# define SND_SOC_DAIFMT_MASTER_MASK 0xf000
/*
* Master Clock Directions
*/
# define SND_SOC_CLOCK_IN 0
# define SND_SOC_CLOCK_OUT 1
2009-08-09 23:08:31 +04:00
# define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S8 |\
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S16_BE | \
SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S20_3BE | \
SNDRV_PCM_FMTBIT_S24_3LE | \
SNDRV_PCM_FMTBIT_S24_3BE | \
2009-05-14 05:59:14 +04:00
SNDRV_PCM_FMTBIT_S32_LE | \
SNDRV_PCM_FMTBIT_S32_BE )
2009-05-02 15:24:55 +04:00
2010-03-17 23:15:21 +03:00
struct snd_soc_dai_driver ;
2008-07-23 17:03:07 +04:00
struct snd_soc_dai ;
struct snd_ac97_bus_ops ;
/* Digital Audio Interface clocking API.*/
int snd_soc_dai_set_sysclk ( struct snd_soc_dai * dai , int clk_id ,
unsigned int freq , int dir ) ;
int snd_soc_dai_set_clkdiv ( struct snd_soc_dai * dai ,
int div_id , int div ) ;
int snd_soc_dai_set_pll ( struct snd_soc_dai * dai ,
2009-09-05 21:52:16 +04:00
int pll_id , int source , unsigned int freq_in , unsigned int freq_out ) ;
2008-07-23 17:03:07 +04:00
2013-09-16 16:01:46 +04:00
int snd_soc_dai_set_bclk_ratio ( struct snd_soc_dai * dai , unsigned int ratio ) ;
2008-07-23 17:03:07 +04:00
/* Digital Audio interface formatting */
int snd_soc_dai_set_fmt ( struct snd_soc_dai * dai , unsigned int fmt ) ;
int snd_soc_dai_set_tdm_slot ( struct snd_soc_dai * dai ,
2009-06-16 04:44:31 +04:00
unsigned int tx_mask , unsigned int rx_mask , int slots , int slot_width ) ;
2008-07-23 17:03:07 +04:00
2009-09-11 21:16:29 +04:00
int snd_soc_dai_set_channel_map ( struct snd_soc_dai * dai ,
unsigned int tx_num , unsigned int * tx_slot ,
unsigned int rx_num , unsigned int * rx_slot ) ;
2008-07-23 17:03:07 +04:00
int snd_soc_dai_set_tristate ( struct snd_soc_dai * dai , int tristate ) ;
/* Digital Audio Interface mute */
2013-02-06 19:44:07 +04:00
int snd_soc_dai_digital_mute ( struct snd_soc_dai * dai , int mute ,
int direction ) ;
2008-07-23 17:03:07 +04:00
struct snd_soc_dai_ops {
/*
* DAI clocking configuration , all optional .
* Called by soc_card drivers , normally in their hw_params .
*/
int ( * set_sysclk ) ( struct snd_soc_dai * dai ,
int clk_id , unsigned int freq , int dir ) ;
2009-09-05 21:52:16 +04:00
int ( * set_pll ) ( struct snd_soc_dai * dai , int pll_id , int source ,
unsigned int freq_in , unsigned int freq_out ) ;
2008-07-23 17:03:07 +04:00
int ( * set_clkdiv ) ( struct snd_soc_dai * dai , int div_id , int div ) ;
2013-09-16 16:01:46 +04:00
int ( * set_bclk_ratio ) ( struct snd_soc_dai * dai , unsigned int ratio ) ;
2008-07-23 17:03:07 +04:00
/*
* DAI format configuration
* Called by soc_card drivers , normally in their hw_params .
*/
int ( * set_fmt ) ( struct snd_soc_dai * dai , unsigned int fmt ) ;
int ( * set_tdm_slot ) ( struct snd_soc_dai * dai ,
2009-06-16 04:44:31 +04:00
unsigned int tx_mask , unsigned int rx_mask ,
int slots , int slot_width ) ;
2009-09-11 21:16:29 +04:00
int ( * set_channel_map ) ( struct snd_soc_dai * dai ,
unsigned int tx_num , unsigned int * tx_slot ,
unsigned int rx_num , unsigned int * rx_slot ) ;
2008-07-23 17:03:07 +04:00
int ( * set_tristate ) ( struct snd_soc_dai * dai , int tristate ) ;
/*
* DAI digital mute - optional .
* Called by soc - core to minimise any pops .
*/
int ( * digital_mute ) ( struct snd_soc_dai * dai , int mute ) ;
2013-02-06 19:44:07 +04:00
int ( * mute_stream ) ( struct snd_soc_dai * dai , int mute , int stream ) ;
2008-11-19 01:11:38 +03:00
/*
* ALSA PCM audio operations - all optional .
* Called by soc - core during audio PCM operations .
*/
int ( * startup ) ( struct snd_pcm_substream * ,
struct snd_soc_dai * ) ;
void ( * shutdown ) ( struct snd_pcm_substream * ,
struct snd_soc_dai * ) ;
int ( * hw_params ) ( struct snd_pcm_substream * ,
struct snd_pcm_hw_params * , struct snd_soc_dai * ) ;
int ( * hw_free ) ( struct snd_pcm_substream * ,
struct snd_soc_dai * ) ;
int ( * prepare ) ( struct snd_pcm_substream * ,
struct snd_soc_dai * ) ;
2013-10-11 14:11:02 +04:00
/*
* NOTE : Commands passed to the trigger function are not necessarily
* compatible with the current state of the dai . For example this
* sequence of commands is possible : START STOP STOP .
* So do not unconditionally use refcounting functions in the trigger
* function , e . g . clk_enable / disable .
*/
2008-11-19 01:11:38 +03:00
int ( * trigger ) ( struct snd_pcm_substream * , int ,
struct snd_soc_dai * ) ;
2012-04-25 15:12:52 +04:00
int ( * bespoke_trigger ) ( struct snd_pcm_substream * , int ,
struct snd_soc_dai * ) ;
2010-03-03 16:08:07 +03:00
/*
* For hardware based FIFO caused delay reporting .
* Optional .
*/
snd_pcm_sframes_t ( * delay ) ( struct snd_pcm_substream * ,
struct snd_soc_dai * ) ;
2008-07-23 17:03:07 +04:00
} ;
/*
2010-03-17 23:15:21 +03:00
* Digital Audio Interface Driver .
2008-07-23 17:03:07 +04:00
*
2010-03-17 23:15:21 +03:00
* Describes the Digital Audio Interface in terms of its ALSA , DAI and AC97
* operations and capabilities . Codec and platform drivers will register this
* structure for every DAI they have .
*
* This structure covers the clocking , formating and ALSA operations for each
* interface .
2008-07-23 17:03:07 +04:00
*/
2010-03-17 23:15:21 +03:00
struct snd_soc_dai_driver {
2008-07-23 17:03:07 +04:00
/* DAI description */
2010-03-17 23:15:21 +03:00
const char * name ;
2008-07-23 17:03:07 +04:00
unsigned int id ;
2008-11-24 21:01:05 +03:00
int ac97_control ;
2012-05-01 23:03:32 +04:00
unsigned int base ;
2008-07-23 17:03:07 +04:00
2010-03-17 23:15:21 +03:00
/* DAI driver callbacks */
int ( * probe ) ( struct snd_soc_dai * dai ) ;
int ( * remove ) ( struct snd_soc_dai * dai ) ;
2008-12-03 21:21:52 +03:00
int ( * suspend ) ( struct snd_soc_dai * dai ) ;
int ( * resume ) ( struct snd_soc_dai * dai ) ;
2012-08-16 15:40:40 +04:00
/* compress dai */
bool compress_dai ;
2008-07-23 17:03:07 +04:00
/* ops */
2010-12-02 19:10:09 +03:00
const struct snd_soc_dai_ops * ops ;
2008-07-23 17:03:07 +04:00
/* DAI capabilities */
struct snd_soc_pcm_stream capture ;
struct snd_soc_pcm_stream playback ;
2009-04-07 21:10:13 +04:00
unsigned int symmetric_rates : 1 ;
2011-06-07 19:08:05 +04:00
/* probe ordering - for components with runtime dependencies */
int probe_order ;
int remove_order ;
2010-03-17 23:15:21 +03:00
} ;
/*
* Digital Audio Interface runtime data .
*
* Holds runtime data for a DAI .
*/
struct snd_soc_dai {
const char * name ;
int id ;
struct device * dev ;
void * ac97_pdata ; /* platform_data for the ac97 codec */
/* driver ops */
struct snd_soc_dai_driver * driver ;
2008-07-23 17:03:07 +04:00
/* DAI runtime info */
2010-03-17 23:15:21 +03:00
unsigned int capture_active : 1 ; /* stream is in use */
unsigned int playback_active : 1 ; /* stream is in use */
unsigned int symmetric_rates : 1 ;
struct snd_pcm_runtime * runtime ;
2008-07-23 17:03:07 +04:00
unsigned int active ;
2010-03-17 23:15:21 +03:00
unsigned char probed : 1 ;
2008-07-23 17:03:07 +04:00
2012-02-17 07:37:51 +04:00
struct snd_soc_dapm_widget * playback_widget ;
struct snd_soc_dapm_widget * capture_widget ;
2012-03-07 15:47:41 +04:00
struct snd_soc_dapm_context dapm ;
2012-02-17 07:37:51 +04:00
2010-03-17 23:15:21 +03:00
/* DAI DMA data */
void * playback_dma_data ;
void * capture_dma_data ;
2008-07-23 17:03:07 +04:00
2011-08-29 13:15:14 +04:00
/* Symmetry data - only valid if symmetry is being enforced */
unsigned int rate ;
2010-03-17 23:15:21 +03:00
/* parent platform/codec */
2012-03-02 20:18:30 +04:00
struct snd_soc_platform * platform ;
struct snd_soc_codec * codec ;
2010-03-17 23:15:21 +03:00
struct snd_soc_card * card ;
2008-07-23 17:03:07 +04:00
struct list_head list ;
2010-03-17 23:15:21 +03:00
struct list_head card_list ;
2008-07-23 17:03:07 +04:00
} ;
2010-03-19 17:52:55 +03:00
static inline void * snd_soc_dai_get_dma_data ( const struct snd_soc_dai * dai ,
const struct snd_pcm_substream * ss )
{
return ( ss - > stream = = SNDRV_PCM_STREAM_PLAYBACK ) ?
2010-03-17 23:15:21 +03:00
dai - > playback_dma_data : dai - > capture_dma_data ;
2010-03-19 17:52:55 +03:00
}
static inline void snd_soc_dai_set_dma_data ( struct snd_soc_dai * dai ,
const struct snd_pcm_substream * ss ,
void * data )
{
if ( ss - > stream = = SNDRV_PCM_STREAM_PLAYBACK )
2010-03-17 23:15:21 +03:00
dai - > playback_dma_data = data ;
2010-03-19 17:52:55 +03:00
else
2010-03-17 23:15:21 +03:00
dai - > capture_dma_data = data ;
}
2013-10-18 00:13:19 +04:00
static inline void snd_soc_dai_init_dma_data ( struct snd_soc_dai * dai ,
void * playback , void * capture )
{
dai - > playback_dma_data = playback ;
dai - > capture_dma_data = capture ;
}
2010-03-17 23:15:21 +03:00
static inline void snd_soc_dai_set_drvdata ( struct snd_soc_dai * dai ,
void * data )
{
dev_set_drvdata ( dai - > dev , data ) ;
}
static inline void * snd_soc_dai_get_drvdata ( struct snd_soc_dai * dai )
{
return dev_get_drvdata ( dai - > dev ) ;
2010-03-19 17:52:55 +03:00
}
2008-07-23 17:03:07 +04:00
# endif