1808db4a4SRichard Purdie /* 2808db4a4SRichard Purdie * linux/sound/soc.h -- ALSA SoC Layer 3808db4a4SRichard Purdie * 4808db4a4SRichard Purdie * Author: Liam Girdwood 5808db4a4SRichard Purdie * Created: Aug 11th 2005 6808db4a4SRichard Purdie * Copyright: Wolfson Microelectronics. PLC. 7808db4a4SRichard Purdie * 8808db4a4SRichard Purdie * This program is free software; you can redistribute it and/or modify 9808db4a4SRichard Purdie * it under the terms of the GNU General Public License version 2 as 10808db4a4SRichard Purdie * published by the Free Software Foundation. 11808db4a4SRichard Purdie */ 12808db4a4SRichard Purdie 13808db4a4SRichard Purdie #ifndef __LINUX_SND_SOC_H 14808db4a4SRichard Purdie #define __LINUX_SND_SOC_H 15808db4a4SRichard Purdie 16808db4a4SRichard Purdie #include <linux/platform_device.h> 17808db4a4SRichard Purdie #include <linux/types.h> 184484bb2eSAndrew Morton #include <linux/workqueue.h> 19808db4a4SRichard Purdie #include <sound/core.h> 20808db4a4SRichard Purdie #include <sound/pcm.h> 21808db4a4SRichard Purdie #include <sound/control.h> 22808db4a4SRichard Purdie #include <sound/ac97_codec.h> 23808db4a4SRichard Purdie 240a22b87dSMark Brown #define SND_SOC_VERSION "0.13.2" 25808db4a4SRichard Purdie 26808db4a4SRichard Purdie /* 27808db4a4SRichard Purdie * Convenience kcontrol builders 28808db4a4SRichard Purdie */ 294eaa9819SJon Smirl #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ 304eaa9819SJon Smirl ((unsigned long)&(struct soc_mixer_control) \ 31*762b8df7SMark Brown {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ 32*762b8df7SMark Brown .invert = xinvert}) 334eaa9819SJon Smirl #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ 344eaa9819SJon Smirl ((unsigned long)&(struct soc_mixer_control) \ 354eaa9819SJon Smirl {.reg = xreg, .max = xmax, .invert = xinvert}) 36a7a4ac86SPhilipp Zabel #define SOC_SINGLE(xname, reg, shift, max, invert) \ 37808db4a4SRichard Purdie { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 38808db4a4SRichard Purdie .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 39808db4a4SRichard Purdie .put = snd_soc_put_volsw, \ 40a7a4ac86SPhilipp Zabel .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } 41a7a4ac86SPhilipp Zabel #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ 42a7a4ac86SPhilipp Zabel { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 43a7a4ac86SPhilipp Zabel .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 44a7a4ac86SPhilipp Zabel SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 45a7a4ac86SPhilipp Zabel .tlv.p = (tlv_array), \ 46a7a4ac86SPhilipp Zabel .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 47a7a4ac86SPhilipp Zabel .put = snd_soc_put_volsw, \ 48a7a4ac86SPhilipp Zabel .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } 494eaa9819SJon Smirl #define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \ 50808db4a4SRichard Purdie { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 51808db4a4SRichard Purdie .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ 52808db4a4SRichard Purdie .put = snd_soc_put_volsw, \ 534eaa9819SJon Smirl .private_value = (unsigned long)&(struct soc_mixer_control) \ 544eaa9819SJon Smirl {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 554eaa9819SJon Smirl .max = xmax, .invert = xinvert} } 564eaa9819SJon Smirl #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ 57808db4a4SRichard Purdie { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 58808db4a4SRichard Purdie .info = snd_soc_info_volsw_2r, \ 59808db4a4SRichard Purdie .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 604eaa9819SJon Smirl .private_value = (unsigned long)&(struct soc_mixer_control) \ 614eaa9819SJon Smirl {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 624eaa9819SJon Smirl .max = xmax, .invert = xinvert} } 634eaa9819SJon Smirl #define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \ 64a7a4ac86SPhilipp Zabel { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 65a7a4ac86SPhilipp Zabel .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 66a7a4ac86SPhilipp Zabel SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 67a7a4ac86SPhilipp Zabel .tlv.p = (tlv_array), \ 68a7a4ac86SPhilipp Zabel .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ 69a7a4ac86SPhilipp Zabel .put = snd_soc_put_volsw, \ 704eaa9819SJon Smirl .private_value = (unsigned long)&(struct soc_mixer_control) \ 714eaa9819SJon Smirl {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ 724eaa9819SJon Smirl .max = xmax, .invert = xinvert} } 734eaa9819SJon Smirl #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ 74a7a4ac86SPhilipp Zabel { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 75a7a4ac86SPhilipp Zabel .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 76a7a4ac86SPhilipp Zabel SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 77a7a4ac86SPhilipp Zabel .tlv.p = (tlv_array), \ 78a7a4ac86SPhilipp Zabel .info = snd_soc_info_volsw_2r, \ 79a7a4ac86SPhilipp Zabel .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 804eaa9819SJon Smirl .private_value = (unsigned long)&(struct soc_mixer_control) \ 814eaa9819SJon Smirl {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 824eaa9819SJon Smirl .max = xmax, .invert = xinvert} } 834eaa9819SJon Smirl #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ 84e13ac2e9SMark Brown { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 85e13ac2e9SMark Brown .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 86e13ac2e9SMark Brown SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 87e13ac2e9SMark Brown .tlv.p = (tlv_array), \ 88e13ac2e9SMark Brown .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ 89e13ac2e9SMark Brown .put = snd_soc_put_volsw_s8, \ 904eaa9819SJon Smirl .private_value = (unsigned long)&(struct soc_mixer_control) \ 914eaa9819SJon Smirl {.reg = xreg, .min = xmin, .max = xmax} } 92f8ba0b7bSJon Smirl #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \ 93808db4a4SRichard Purdie { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ 94f8ba0b7bSJon Smirl .max = xmax, .texts = xtexts } 95f8ba0b7bSJon Smirl #define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \ 96f8ba0b7bSJon Smirl SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts) 97f8ba0b7bSJon Smirl #define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \ 98f8ba0b7bSJon Smirl { .max = xmax, .texts = xtexts } 99808db4a4SRichard Purdie #define SOC_ENUM(xname, xenum) \ 100808db4a4SRichard Purdie { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\ 101808db4a4SRichard Purdie .info = snd_soc_info_enum_double, \ 102808db4a4SRichard Purdie .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \ 103808db4a4SRichard Purdie .private_value = (unsigned long)&xenum } 104f8ba0b7bSJon Smirl #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\ 105808db4a4SRichard Purdie xhandler_get, xhandler_put) \ 106808db4a4SRichard Purdie { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 1071c433fbdSGraeme Gregory .info = snd_soc_info_volsw, \ 108808db4a4SRichard Purdie .get = xhandler_get, .put = xhandler_put, \ 109f8ba0b7bSJon Smirl .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } 110f8ba0b7bSJon Smirl #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ 11110144c09SMike Montour xhandler_get, xhandler_put, tlv_array) \ 11210144c09SMike Montour { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 11310144c09SMike Montour .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 11410144c09SMike Montour SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 11510144c09SMike Montour .tlv.p = (tlv_array), \ 11610144c09SMike Montour .info = snd_soc_info_volsw, \ 11710144c09SMike Montour .get = xhandler_get, .put = xhandler_put, \ 118f8ba0b7bSJon Smirl .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } 119808db4a4SRichard Purdie #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ 120808db4a4SRichard Purdie { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 121808db4a4SRichard Purdie .info = snd_soc_info_bool_ext, \ 122808db4a4SRichard Purdie .get = xhandler_get, .put = xhandler_put, \ 123808db4a4SRichard Purdie .private_value = xdata } 124808db4a4SRichard Purdie #define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \ 125808db4a4SRichard Purdie { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 126808db4a4SRichard Purdie .info = snd_soc_info_enum_ext, \ 127808db4a4SRichard Purdie .get = xhandler_get, .put = xhandler_put, \ 128808db4a4SRichard Purdie .private_value = (unsigned long)&xenum } 129808db4a4SRichard Purdie 130808db4a4SRichard Purdie /* 1310be9898aSMark Brown * Bias levels 1320be9898aSMark Brown * 1330be9898aSMark Brown * @ON: Bias is fully on for audio playback and capture operations. 1340be9898aSMark Brown * @PREPARE: Prepare for audio operations. Called before DAPM switching for 1350be9898aSMark Brown * stream start and stop operations. 1360be9898aSMark Brown * @STANDBY: Low power standby state when no playback/capture operations are 1370be9898aSMark Brown * in progress. NOTE: The transition time between STANDBY and ON 1380be9898aSMark Brown * should be as fast as possible and no longer than 10ms. 1390be9898aSMark Brown * @OFF: Power Off. No restrictions on transition times. 1400be9898aSMark Brown */ 1410be9898aSMark Brown enum snd_soc_bias_level { 1420be9898aSMark Brown SND_SOC_BIAS_ON, 1430be9898aSMark Brown SND_SOC_BIAS_PREPARE, 1440be9898aSMark Brown SND_SOC_BIAS_STANDBY, 1450be9898aSMark Brown SND_SOC_BIAS_OFF, 1460be9898aSMark Brown }; 1470be9898aSMark Brown 1480be9898aSMark Brown /* 149808db4a4SRichard Purdie * Digital Audio Interface (DAI) types 150808db4a4SRichard Purdie */ 151808db4a4SRichard Purdie #define SND_SOC_DAI_AC97 0x1 152808db4a4SRichard Purdie #define SND_SOC_DAI_I2S 0x2 153808db4a4SRichard Purdie #define SND_SOC_DAI_PCM 0x4 154a68660e0SLiam Girdwood #define SND_SOC_DAI_AC97_BUS 0x8 /* for custom i.e. non ac97_codec.c */ 155808db4a4SRichard Purdie 156808db4a4SRichard Purdie /* 157808db4a4SRichard Purdie * DAI hardware audio formats 158808db4a4SRichard Purdie */ 1591c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_I2S 0 /* I2S mode */ 1601c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_RIGHT_J 1 /* Right justified mode */ 1611c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */ 1621c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_DSP_A 3 /* L data msb after FRM or LRC */ 1631c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_DSP_B 4 /* L data msb during FRM or LRC */ 1641c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_AC97 5 /* AC97 */ 1651c433fbdSGraeme Gregory 1661c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J 1671c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_LSB SND_SOC_DAIFMT_RIGHT_J 1681c433fbdSGraeme Gregory 1691c433fbdSGraeme Gregory /* 1701c433fbdSGraeme Gregory * DAI Gating 1711c433fbdSGraeme Gregory */ 1721c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */ 1731c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated when not Tx/Rx */ 174808db4a4SRichard Purdie 175808db4a4SRichard Purdie /* 176a7a4ac86SPhilipp Zabel * DAI Sync 177a7a4ac86SPhilipp Zabel * Synchronous LR (Left Right) clocks and Frame signals. 178a7a4ac86SPhilipp Zabel */ 179a7a4ac86SPhilipp Zabel #define SND_SOC_DAIFMT_SYNC (0 << 5) /* Tx FRM = Rx FRM */ 180a7a4ac86SPhilipp Zabel #define SND_SOC_DAIFMT_ASYNC (1 << 5) /* Tx FRM ~ Rx FRM */ 181a7a4ac86SPhilipp Zabel 182a7a4ac86SPhilipp Zabel /* 183a7a4ac86SPhilipp Zabel * TDM 184a7a4ac86SPhilipp Zabel */ 185a7a4ac86SPhilipp Zabel #define SND_SOC_DAIFMT_TDM (1 << 6) 186a7a4ac86SPhilipp Zabel 187a7a4ac86SPhilipp Zabel /* 188808db4a4SRichard Purdie * DAI hardware signal inversions 189808db4a4SRichard Purdie */ 190a7a4ac86SPhilipp Zabel #define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bclk + frm */ 1911c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal bclk + inv frm */ 1921c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert bclk + nor frm */ 1931c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert bclk + frm */ 194808db4a4SRichard Purdie 195808db4a4SRichard Purdie /* 196808db4a4SRichard Purdie * DAI hardware clock masters 197808db4a4SRichard Purdie * This is wrt the codec, the inverse is true for the interface 198808db4a4SRichard Purdie * i.e. if the codec is clk and frm master then the interface is 199808db4a4SRichard Purdie * clk and frame slave. 200808db4a4SRichard Purdie */ 2011c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & frm master */ 2021c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & frm master */ 2031c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */ 2041c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & frm slave */ 205808db4a4SRichard Purdie 2061c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_FORMAT_MASK 0x000f 2071c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0 208808db4a4SRichard Purdie #define SND_SOC_DAIFMT_INV_MASK 0x0f00 2091c433fbdSGraeme Gregory #define SND_SOC_DAIFMT_MASTER_MASK 0xf000 2101c433fbdSGraeme Gregory 211808db4a4SRichard Purdie 212808db4a4SRichard Purdie /* 2131c433fbdSGraeme Gregory * Master Clock Directions 214808db4a4SRichard Purdie */ 2151c433fbdSGraeme Gregory #define SND_SOC_CLOCK_IN 0 2161c433fbdSGraeme Gregory #define SND_SOC_CLOCK_OUT 1 217808db4a4SRichard Purdie 218808db4a4SRichard Purdie /* 219808db4a4SRichard Purdie * AC97 codec ID's bitmask 220808db4a4SRichard Purdie */ 221808db4a4SRichard Purdie #define SND_SOC_DAI_AC97_ID0 (1 << 0) 222808db4a4SRichard Purdie #define SND_SOC_DAI_AC97_ID1 (1 << 1) 223808db4a4SRichard Purdie #define SND_SOC_DAI_AC97_ID2 (1 << 2) 224808db4a4SRichard Purdie #define SND_SOC_DAI_AC97_ID3 (1 << 3) 225808db4a4SRichard Purdie 226808db4a4SRichard Purdie struct snd_soc_device; 227808db4a4SRichard Purdie struct snd_soc_pcm_stream; 228808db4a4SRichard Purdie struct snd_soc_ops; 229808db4a4SRichard Purdie struct snd_soc_dai_mode; 230808db4a4SRichard Purdie struct snd_soc_pcm_runtime; 2313c4b266fSLiam Girdwood struct snd_soc_dai; 232808db4a4SRichard Purdie struct snd_soc_codec; 233808db4a4SRichard Purdie struct snd_soc_machine_config; 234808db4a4SRichard Purdie struct soc_enum; 235808db4a4SRichard Purdie struct snd_soc_ac97_ops; 236808db4a4SRichard Purdie struct snd_soc_clock_info; 237808db4a4SRichard Purdie 238808db4a4SRichard Purdie typedef int (*hw_write_t)(void *,const char* ,int); 239808db4a4SRichard Purdie typedef int (*hw_read_t)(void *,char* ,int); 240808db4a4SRichard Purdie 241808db4a4SRichard Purdie extern struct snd_ac97_bus_ops soc_ac97_ops; 242808db4a4SRichard Purdie 243808db4a4SRichard Purdie /* pcm <-> DAI connect */ 244808db4a4SRichard Purdie void snd_soc_free_pcms(struct snd_soc_device *socdev); 245808db4a4SRichard Purdie int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid); 246808db4a4SRichard Purdie int snd_soc_register_card(struct snd_soc_device *socdev); 247808db4a4SRichard Purdie 248808db4a4SRichard Purdie /* set runtime hw params */ 249808db4a4SRichard Purdie int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, 250808db4a4SRichard Purdie const struct snd_pcm_hardware *hw); 251808db4a4SRichard Purdie 252808db4a4SRichard Purdie /* codec IO */ 253808db4a4SRichard Purdie #define snd_soc_read(codec, reg) codec->read(codec, reg) 254808db4a4SRichard Purdie #define snd_soc_write(codec, reg, value) codec->write(codec, reg, value) 255808db4a4SRichard Purdie 256808db4a4SRichard Purdie /* codec register bit access */ 257808db4a4SRichard Purdie int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 258808db4a4SRichard Purdie unsigned short mask, unsigned short value); 259808db4a4SRichard Purdie int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, 260808db4a4SRichard Purdie unsigned short mask, unsigned short value); 261808db4a4SRichard Purdie 262808db4a4SRichard Purdie int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, 263808db4a4SRichard Purdie struct snd_ac97_bus_ops *ops, int num); 264808db4a4SRichard Purdie void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); 265808db4a4SRichard Purdie 2668c6529dbSLiam Girdwood /* Digital Audio Interface clocking API.*/ 2678c6529dbSLiam Girdwood int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 2688c6529dbSLiam Girdwood unsigned int freq, int dir); 2698c6529dbSLiam Girdwood 2708c6529dbSLiam Girdwood int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, 2718c6529dbSLiam Girdwood int div_id, int div); 2728c6529dbSLiam Girdwood 2738c6529dbSLiam Girdwood int snd_soc_dai_set_pll(struct snd_soc_dai *dai, 2748c6529dbSLiam Girdwood int pll_id, unsigned int freq_in, unsigned int freq_out); 2758c6529dbSLiam Girdwood 2768c6529dbSLiam Girdwood /* Digital Audio interface formatting */ 2778c6529dbSLiam Girdwood int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt); 2788c6529dbSLiam Girdwood 2798c6529dbSLiam Girdwood int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 2808c6529dbSLiam Girdwood unsigned int mask, int slots); 2818c6529dbSLiam Girdwood 2828c6529dbSLiam Girdwood int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate); 2838c6529dbSLiam Girdwood 2848c6529dbSLiam Girdwood /* Digital Audio Interface mute */ 2858c6529dbSLiam Girdwood int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute); 2868c6529dbSLiam Girdwood 287808db4a4SRichard Purdie /* 288808db4a4SRichard Purdie *Controls 289808db4a4SRichard Purdie */ 290808db4a4SRichard Purdie struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, 291808db4a4SRichard Purdie void *data, char *long_name); 292808db4a4SRichard Purdie int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, 293808db4a4SRichard Purdie struct snd_ctl_elem_info *uinfo); 294808db4a4SRichard Purdie int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol, 295808db4a4SRichard Purdie struct snd_ctl_elem_info *uinfo); 296808db4a4SRichard Purdie int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, 297808db4a4SRichard Purdie struct snd_ctl_elem_value *ucontrol); 298808db4a4SRichard Purdie int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, 299808db4a4SRichard Purdie struct snd_ctl_elem_value *ucontrol); 300808db4a4SRichard Purdie int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, 301808db4a4SRichard Purdie struct snd_ctl_elem_info *uinfo); 302808db4a4SRichard Purdie int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, 303808db4a4SRichard Purdie struct snd_ctl_elem_info *uinfo); 304392abe9cSPhilipp Zabel #define snd_soc_info_bool_ext snd_ctl_boolean_mono_info 305808db4a4SRichard Purdie int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, 306808db4a4SRichard Purdie struct snd_ctl_elem_value *ucontrol); 307808db4a4SRichard Purdie int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, 308808db4a4SRichard Purdie struct snd_ctl_elem_value *ucontrol); 309808db4a4SRichard Purdie int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, 310808db4a4SRichard Purdie struct snd_ctl_elem_info *uinfo); 311808db4a4SRichard Purdie int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, 312808db4a4SRichard Purdie struct snd_ctl_elem_value *ucontrol); 313808db4a4SRichard Purdie int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, 314808db4a4SRichard Purdie struct snd_ctl_elem_value *ucontrol); 315e13ac2e9SMark Brown int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, 316e13ac2e9SMark Brown struct snd_ctl_elem_info *uinfo); 317e13ac2e9SMark Brown int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, 318e13ac2e9SMark Brown struct snd_ctl_elem_value *ucontrol); 319e13ac2e9SMark Brown int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, 320e13ac2e9SMark Brown struct snd_ctl_elem_value *ucontrol); 321808db4a4SRichard Purdie 322808db4a4SRichard Purdie /* SoC PCM stream information */ 323808db4a4SRichard Purdie struct snd_soc_pcm_stream { 324808db4a4SRichard Purdie char *stream_name; 3251c433fbdSGraeme Gregory u64 formats; /* SNDRV_PCM_FMTBIT_* */ 3261c433fbdSGraeme Gregory unsigned int rates; /* SNDRV_PCM_RATE_* */ 327808db4a4SRichard Purdie unsigned int rate_min; /* min rate */ 328808db4a4SRichard Purdie unsigned int rate_max; /* max rate */ 329808db4a4SRichard Purdie unsigned int channels_min; /* min channels */ 330808db4a4SRichard Purdie unsigned int channels_max; /* max channels */ 331808db4a4SRichard Purdie unsigned int active:1; /* stream is in use */ 332808db4a4SRichard Purdie }; 333808db4a4SRichard Purdie 334808db4a4SRichard Purdie /* SoC audio ops */ 335808db4a4SRichard Purdie struct snd_soc_ops { 336808db4a4SRichard Purdie int (*startup)(struct snd_pcm_substream *); 337808db4a4SRichard Purdie void (*shutdown)(struct snd_pcm_substream *); 338808db4a4SRichard Purdie int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); 339808db4a4SRichard Purdie int (*hw_free)(struct snd_pcm_substream *); 340808db4a4SRichard Purdie int (*prepare)(struct snd_pcm_substream *); 341808db4a4SRichard Purdie int (*trigger)(struct snd_pcm_substream *, int); 342808db4a4SRichard Purdie }; 343808db4a4SRichard Purdie 3441ef6ab75SMark Brown /* ASoC DAI ops */ 3451ef6ab75SMark Brown struct snd_soc_dai_ops { 3461ef6ab75SMark Brown /* DAI clocking configuration */ 3473c4b266fSLiam Girdwood int (*set_sysclk)(struct snd_soc_dai *dai, 3481c433fbdSGraeme Gregory int clk_id, unsigned int freq, int dir); 3493c4b266fSLiam Girdwood int (*set_pll)(struct snd_soc_dai *dai, 3501c433fbdSGraeme Gregory int pll_id, unsigned int freq_in, unsigned int freq_out); 3513c4b266fSLiam Girdwood int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div); 3521c433fbdSGraeme Gregory 3531ef6ab75SMark Brown /* DAI format configuration */ 3543c4b266fSLiam Girdwood int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); 3553c4b266fSLiam Girdwood int (*set_tdm_slot)(struct snd_soc_dai *dai, 3561c433fbdSGraeme Gregory unsigned int mask, int slots); 3573c4b266fSLiam Girdwood int (*set_tristate)(struct snd_soc_dai *dai, int tristate); 3581c433fbdSGraeme Gregory 3591c433fbdSGraeme Gregory /* digital mute */ 3603c4b266fSLiam Girdwood int (*digital_mute)(struct snd_soc_dai *dai, int mute); 361808db4a4SRichard Purdie }; 362808db4a4SRichard Purdie 3633c4b266fSLiam Girdwood /* SoC DAI (Digital Audio Interface) */ 3643c4b266fSLiam Girdwood struct snd_soc_dai { 365808db4a4SRichard Purdie /* DAI description */ 366808db4a4SRichard Purdie char *name; 367808db4a4SRichard Purdie unsigned int id; 368808db4a4SRichard Purdie unsigned char type; 369808db4a4SRichard Purdie 370808db4a4SRichard Purdie /* DAI callbacks */ 371bdb92876SMark Brown int (*probe)(struct platform_device *pdev, 3723c4b266fSLiam Girdwood struct snd_soc_dai *dai); 373bdb92876SMark Brown void (*remove)(struct platform_device *pdev, 3743c4b266fSLiam Girdwood struct snd_soc_dai *dai); 375808db4a4SRichard Purdie int (*suspend)(struct platform_device *pdev, 3763c4b266fSLiam Girdwood struct snd_soc_dai *dai); 377808db4a4SRichard Purdie int (*resume)(struct platform_device *pdev, 3783c4b266fSLiam Girdwood struct snd_soc_dai *dai); 3791c433fbdSGraeme Gregory 3801c433fbdSGraeme Gregory /* ops */ 3811c433fbdSGraeme Gregory struct snd_soc_ops ops; 3821ef6ab75SMark Brown struct snd_soc_dai_ops dai_ops; 383808db4a4SRichard Purdie 384808db4a4SRichard Purdie /* DAI capabilities */ 385808db4a4SRichard Purdie struct snd_soc_pcm_stream capture; 386808db4a4SRichard Purdie struct snd_soc_pcm_stream playback; 387808db4a4SRichard Purdie 388808db4a4SRichard Purdie /* DAI runtime info */ 389808db4a4SRichard Purdie struct snd_pcm_runtime *runtime; 3903c4b266fSLiam Girdwood struct snd_soc_codec *codec; 3913c4b266fSLiam Girdwood unsigned int active; 3923c4b266fSLiam Girdwood unsigned char pop_wait:1; 393808db4a4SRichard Purdie void *dma_data; 394808db4a4SRichard Purdie 395808db4a4SRichard Purdie /* DAI private data */ 396808db4a4SRichard Purdie void *private_data; 397808db4a4SRichard Purdie }; 398808db4a4SRichard Purdie 399808db4a4SRichard Purdie /* SoC Audio Codec */ 400808db4a4SRichard Purdie struct snd_soc_codec { 401808db4a4SRichard Purdie char *name; 402808db4a4SRichard Purdie struct module *owner; 403808db4a4SRichard Purdie struct mutex mutex; 404808db4a4SRichard Purdie 405808db4a4SRichard Purdie /* callbacks */ 4060be9898aSMark Brown int (*set_bias_level)(struct snd_soc_codec *, 4070be9898aSMark Brown enum snd_soc_bias_level level); 408808db4a4SRichard Purdie 409808db4a4SRichard Purdie /* runtime */ 410808db4a4SRichard Purdie struct snd_card *card; 411808db4a4SRichard Purdie struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 412808db4a4SRichard Purdie unsigned int active; 413808db4a4SRichard Purdie unsigned int pcm_devs; 414808db4a4SRichard Purdie void *private_data; 415808db4a4SRichard Purdie 416808db4a4SRichard Purdie /* codec IO */ 417808db4a4SRichard Purdie void *control_data; /* codec control (i2c/3wire) data */ 418808db4a4SRichard Purdie unsigned int (*read)(struct snd_soc_codec *, unsigned int); 419808db4a4SRichard Purdie int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); 42058cd33c0SMark Brown int (*display_register)(struct snd_soc_codec *, char *, 42158cd33c0SMark Brown size_t, unsigned int); 422808db4a4SRichard Purdie hw_write_t hw_write; 423808db4a4SRichard Purdie hw_read_t hw_read; 424808db4a4SRichard Purdie void *reg_cache; 425808db4a4SRichard Purdie short reg_cache_size; 426808db4a4SRichard Purdie short reg_cache_step; 427808db4a4SRichard Purdie 428808db4a4SRichard Purdie /* dapm */ 429808db4a4SRichard Purdie struct list_head dapm_widgets; 430808db4a4SRichard Purdie struct list_head dapm_paths; 4310be9898aSMark Brown enum snd_soc_bias_level bias_level; 4320be9898aSMark Brown enum snd_soc_bias_level suspend_bias_level; 4331321b160STakashi Iwai struct delayed_work delayed_work; 434808db4a4SRichard Purdie 435808db4a4SRichard Purdie /* codec DAI's */ 4363c4b266fSLiam Girdwood struct snd_soc_dai *dai; 437808db4a4SRichard Purdie unsigned int num_dai; 438808db4a4SRichard Purdie }; 439808db4a4SRichard Purdie 440808db4a4SRichard Purdie /* codec device */ 441808db4a4SRichard Purdie struct snd_soc_codec_device { 442808db4a4SRichard Purdie int (*probe)(struct platform_device *pdev); 443808db4a4SRichard Purdie int (*remove)(struct platform_device *pdev); 444808db4a4SRichard Purdie int (*suspend)(struct platform_device *pdev, pm_message_t state); 445808db4a4SRichard Purdie int (*resume)(struct platform_device *pdev); 446808db4a4SRichard Purdie }; 447808db4a4SRichard Purdie 448808db4a4SRichard Purdie /* SoC platform interface */ 449808db4a4SRichard Purdie struct snd_soc_platform { 450808db4a4SRichard Purdie char *name; 451808db4a4SRichard Purdie 452808db4a4SRichard Purdie int (*probe)(struct platform_device *pdev); 453808db4a4SRichard Purdie int (*remove)(struct platform_device *pdev); 454808db4a4SRichard Purdie int (*suspend)(struct platform_device *pdev, 4553c4b266fSLiam Girdwood struct snd_soc_dai *dai); 456808db4a4SRichard Purdie int (*resume)(struct platform_device *pdev, 4573c4b266fSLiam Girdwood struct snd_soc_dai *dai); 458808db4a4SRichard Purdie 459808db4a4SRichard Purdie /* pcm creation and destruction */ 4603c4b266fSLiam Girdwood int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, 461808db4a4SRichard Purdie struct snd_pcm *); 462808db4a4SRichard Purdie void (*pcm_free)(struct snd_pcm *); 463808db4a4SRichard Purdie 464808db4a4SRichard Purdie /* platform stream ops */ 465808db4a4SRichard Purdie struct snd_pcm_ops *pcm_ops; 466808db4a4SRichard Purdie }; 467808db4a4SRichard Purdie 468808db4a4SRichard Purdie /* SoC machine DAI configuration, glues a codec and cpu DAI together */ 469808db4a4SRichard Purdie struct snd_soc_dai_link { 470808db4a4SRichard Purdie char *name; /* Codec name */ 471808db4a4SRichard Purdie char *stream_name; /* Stream name */ 472808db4a4SRichard Purdie 473808db4a4SRichard Purdie /* DAI */ 4743c4b266fSLiam Girdwood struct snd_soc_dai *codec_dai; 4753c4b266fSLiam Girdwood struct snd_soc_dai *cpu_dai; 4761c433fbdSGraeme Gregory 4771c433fbdSGraeme Gregory /* machine stream operations */ 4781c433fbdSGraeme Gregory struct snd_soc_ops *ops; 479808db4a4SRichard Purdie 480808db4a4SRichard Purdie /* codec/machine specific init - e.g. add machine controls */ 481808db4a4SRichard Purdie int (*init)(struct snd_soc_codec *codec); 4824ccab3e7SLiam Girdwood 4834ccab3e7SLiam Girdwood /* DAI pcm */ 4844ccab3e7SLiam Girdwood struct snd_pcm *pcm; 485808db4a4SRichard Purdie }; 486808db4a4SRichard Purdie 487808db4a4SRichard Purdie /* SoC machine */ 488808db4a4SRichard Purdie struct snd_soc_machine { 489808db4a4SRichard Purdie char *name; 490808db4a4SRichard Purdie 491808db4a4SRichard Purdie int (*probe)(struct platform_device *pdev); 492808db4a4SRichard Purdie int (*remove)(struct platform_device *pdev); 493808db4a4SRichard Purdie 494808db4a4SRichard Purdie /* the pre and post PM functions are used to do any PM work before and 495808db4a4SRichard Purdie * after the codec and DAI's do any PM work. */ 496808db4a4SRichard Purdie int (*suspend_pre)(struct platform_device *pdev, pm_message_t state); 497808db4a4SRichard Purdie int (*suspend_post)(struct platform_device *pdev, pm_message_t state); 498808db4a4SRichard Purdie int (*resume_pre)(struct platform_device *pdev); 499808db4a4SRichard Purdie int (*resume_post)(struct platform_device *pdev); 500808db4a4SRichard Purdie 5010b4d221bSLiam Girdwood /* callbacks */ 5020be9898aSMark Brown int (*set_bias_level)(struct snd_soc_machine *, 5030be9898aSMark Brown enum snd_soc_bias_level level); 5040b4d221bSLiam Girdwood 505808db4a4SRichard Purdie /* CPU <--> Codec DAI links */ 506808db4a4SRichard Purdie struct snd_soc_dai_link *dai_link; 507808db4a4SRichard Purdie int num_links; 508808db4a4SRichard Purdie }; 509808db4a4SRichard Purdie 510808db4a4SRichard Purdie /* SoC Device - the audio subsystem */ 511808db4a4SRichard Purdie struct snd_soc_device { 512808db4a4SRichard Purdie struct device *dev; 513808db4a4SRichard Purdie struct snd_soc_machine *machine; 514808db4a4SRichard Purdie struct snd_soc_platform *platform; 515808db4a4SRichard Purdie struct snd_soc_codec *codec; 516808db4a4SRichard Purdie struct snd_soc_codec_device *codec_dev; 5174484bb2eSAndrew Morton struct delayed_work delayed_work; 5186ed25978SAndy Green struct work_struct deferred_resume_work; 519808db4a4SRichard Purdie void *codec_data; 520808db4a4SRichard Purdie }; 521808db4a4SRichard Purdie 522808db4a4SRichard Purdie /* runtime channel data */ 523808db4a4SRichard Purdie struct snd_soc_pcm_runtime { 5241c433fbdSGraeme Gregory struct snd_soc_dai_link *dai; 525808db4a4SRichard Purdie struct snd_soc_device *socdev; 526808db4a4SRichard Purdie }; 527808db4a4SRichard Purdie 5284eaa9819SJon Smirl /* mixer control */ 5294eaa9819SJon Smirl struct soc_mixer_control { 5304eaa9819SJon Smirl int min, max; 531815ecf8dSJon Smirl unsigned int reg, rreg, shift, rshift, invert; 5324eaa9819SJon Smirl }; 5334eaa9819SJon Smirl 534808db4a4SRichard Purdie /* enumerated kcontrol */ 535808db4a4SRichard Purdie struct soc_enum { 536808db4a4SRichard Purdie unsigned short reg; 537808db4a4SRichard Purdie unsigned short reg2; 538808db4a4SRichard Purdie unsigned char shift_l; 539808db4a4SRichard Purdie unsigned char shift_r; 540f8ba0b7bSJon Smirl unsigned int max; 541808db4a4SRichard Purdie const char **texts; 542808db4a4SRichard Purdie void *dapm; 543808db4a4SRichard Purdie }; 544808db4a4SRichard Purdie 545808db4a4SRichard Purdie #endif 546