Path: blob/master/sound/soc/intel/atom/sst-atom-controls.h
26493 views
/* SPDX-License-Identifier: GPL-2.0-only */1/*2* sst-atom-controls.h - Intel MID Platform driver header file3*4* Copyright (C) 2013-14 Intel Corp5* Author: Ramesh Babu <[email protected]>6* Omair M Abdullah <[email protected]>7* Samreen Nilofer <[email protected]>8* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~9*10* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~11*/1213#ifndef __SST_ATOM_CONTROLS_H__14#define __SST_ATOM_CONTROLS_H__1516#include <sound/soc.h>17#include <sound/tlv.h>1819enum {20MERR_DPCM_AUDIO = 0,21MERR_DPCM_DEEP_BUFFER,22MERR_DPCM_COMPR,23};2425/* define a bit for each mixer input */26#define SST_MIX_IP(x) (x)2728#define SST_IP_MODEM SST_MIX_IP(0)29#define SST_IP_BT SST_MIX_IP(1)30#define SST_IP_CODEC0 SST_MIX_IP(2)31#define SST_IP_CODEC1 SST_MIX_IP(3)32#define SST_IP_LOOP0 SST_MIX_IP(4)33#define SST_IP_LOOP1 SST_MIX_IP(5)34#define SST_IP_LOOP2 SST_MIX_IP(6)35#define SST_IP_PROBE SST_MIX_IP(7)36#define SST_IP_VOIP SST_MIX_IP(12)37#define SST_IP_PCM0 SST_MIX_IP(13)38#define SST_IP_PCM1 SST_MIX_IP(14)39#define SST_IP_MEDIA0 SST_MIX_IP(17)40#define SST_IP_MEDIA1 SST_MIX_IP(18)41#define SST_IP_MEDIA2 SST_MIX_IP(19)42#define SST_IP_MEDIA3 SST_MIX_IP(20)4344#define SST_IP_LAST SST_IP_MEDIA34546#define SST_SWM_INPUT_COUNT (SST_IP_LAST + 1)47#define SST_CMD_SWM_MAX_INPUTS 64849#define SST_PATH_ID_SHIFT 850#define SST_DEFAULT_LOCATION_ID 0xFFFF51#define SST_DEFAULT_CELL_NBR 0xFF52#define SST_DEFAULT_MODULE_ID 0xFFFF5354/*55* Audio DSP Path Ids. Specified by the audio DSP FW56*/57enum sst_path_index {58SST_PATH_INDEX_MODEM_OUT = (0x00 << SST_PATH_ID_SHIFT),59SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT),60SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT),6162SST_PATH_INDEX_SPROT_LOOP_OUT = (0x04 << SST_PATH_ID_SHIFT),63SST_PATH_INDEX_MEDIA_LOOP1_OUT = (0x05 << SST_PATH_ID_SHIFT),64SST_PATH_INDEX_MEDIA_LOOP2_OUT = (0x06 << SST_PATH_ID_SHIFT),6566SST_PATH_INDEX_VOIP_OUT = (0x0C << SST_PATH_ID_SHIFT),67SST_PATH_INDEX_PCM0_OUT = (0x0D << SST_PATH_ID_SHIFT),68SST_PATH_INDEX_PCM1_OUT = (0x0E << SST_PATH_ID_SHIFT),69SST_PATH_INDEX_PCM2_OUT = (0x0F << SST_PATH_ID_SHIFT),7071SST_PATH_INDEX_MEDIA0_OUT = (0x12 << SST_PATH_ID_SHIFT),72SST_PATH_INDEX_MEDIA1_OUT = (0x13 << SST_PATH_ID_SHIFT),737475/* Start of input paths */76SST_PATH_INDEX_MODEM_IN = (0x80 << SST_PATH_ID_SHIFT),77SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT),78SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT),7980SST_PATH_INDEX_SPROT_LOOP_IN = (0x84 << SST_PATH_ID_SHIFT),81SST_PATH_INDEX_MEDIA_LOOP1_IN = (0x85 << SST_PATH_ID_SHIFT),82SST_PATH_INDEX_MEDIA_LOOP2_IN = (0x86 << SST_PATH_ID_SHIFT),8384SST_PATH_INDEX_VOIP_IN = (0x8C << SST_PATH_ID_SHIFT),8586SST_PATH_INDEX_PCM0_IN = (0x8D << SST_PATH_ID_SHIFT),87SST_PATH_INDEX_PCM1_IN = (0x8E << SST_PATH_ID_SHIFT),8889SST_PATH_INDEX_MEDIA0_IN = (0x8F << SST_PATH_ID_SHIFT),90SST_PATH_INDEX_MEDIA1_IN = (0x90 << SST_PATH_ID_SHIFT),91SST_PATH_INDEX_MEDIA2_IN = (0x91 << SST_PATH_ID_SHIFT),9293SST_PATH_INDEX_MEDIA3_IN = (0x9C << SST_PATH_ID_SHIFT),9495SST_PATH_INDEX_RESERVED = (0xFF << SST_PATH_ID_SHIFT),96};9798/*99* path IDs100*/101enum sst_swm_inputs {102SST_SWM_IN_MODEM = (SST_PATH_INDEX_MODEM_IN | SST_DEFAULT_CELL_NBR),103SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR),104SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR),105SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR),106SST_SWM_IN_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_IN | SST_DEFAULT_CELL_NBR),107SST_SWM_IN_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_IN | SST_DEFAULT_CELL_NBR),108SST_SWM_IN_VOIP = (SST_PATH_INDEX_VOIP_IN | SST_DEFAULT_CELL_NBR),109SST_SWM_IN_PCM0 = (SST_PATH_INDEX_PCM0_IN | SST_DEFAULT_CELL_NBR),110SST_SWM_IN_PCM1 = (SST_PATH_INDEX_PCM1_IN | SST_DEFAULT_CELL_NBR),111SST_SWM_IN_MEDIA0 = (SST_PATH_INDEX_MEDIA0_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */112SST_SWM_IN_MEDIA1 = (SST_PATH_INDEX_MEDIA1_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */113SST_SWM_IN_MEDIA2 = (SST_PATH_INDEX_MEDIA2_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */114SST_SWM_IN_MEDIA3 = (SST_PATH_INDEX_MEDIA3_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */115SST_SWM_IN_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR)116};117118/*119* path IDs120*/121enum sst_swm_outputs {122SST_SWM_OUT_MODEM = (SST_PATH_INDEX_MODEM_OUT | SST_DEFAULT_CELL_NBR),123SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR),124SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR),125SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR),126SST_SWM_OUT_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_OUT | SST_DEFAULT_CELL_NBR),127SST_SWM_OUT_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_OUT | SST_DEFAULT_CELL_NBR),128SST_SWM_OUT_VOIP = (SST_PATH_INDEX_VOIP_OUT | SST_DEFAULT_CELL_NBR),129SST_SWM_OUT_PCM0 = (SST_PATH_INDEX_PCM0_OUT | SST_DEFAULT_CELL_NBR),130SST_SWM_OUT_PCM1 = (SST_PATH_INDEX_PCM1_OUT | SST_DEFAULT_CELL_NBR),131SST_SWM_OUT_PCM2 = (SST_PATH_INDEX_PCM2_OUT | SST_DEFAULT_CELL_NBR),132SST_SWM_OUT_MEDIA0 = (SST_PATH_INDEX_MEDIA0_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */133SST_SWM_OUT_MEDIA1 = (SST_PATH_INDEX_MEDIA1_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */134SST_SWM_OUT_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR),135};136137enum sst_ipc_msg {138SST_IPC_IA_CMD = 1,139SST_IPC_IA_SET_PARAMS,140SST_IPC_IA_GET_PARAMS,141};142143enum sst_cmd_type {144SST_CMD_BYTES_SET = 1,145SST_CMD_BYTES_GET = 2,146};147148enum sst_task {149SST_TASK_SBA = 1,150SST_TASK_MMX = 3,151};152153enum sst_type {154SST_TYPE_CMD = 1,155SST_TYPE_PARAMS,156};157158enum sst_flag {159SST_FLAG_BLOCKED = 1,160SST_FLAG_NONBLOCK,161};162163/*164* Enumeration for indexing the gain cells in VB_SET_GAIN DSP command165*/166enum sst_gain_index {167/* GAIN IDs for SB task start here */168SST_GAIN_INDEX_CODEC_OUT0,169SST_GAIN_INDEX_CODEC_OUT1,170SST_GAIN_INDEX_CODEC_IN0,171SST_GAIN_INDEX_CODEC_IN1,172173SST_GAIN_INDEX_SPROT_LOOP_OUT,174SST_GAIN_INDEX_MEDIA_LOOP1_OUT,175SST_GAIN_INDEX_MEDIA_LOOP2_OUT,176177SST_GAIN_INDEX_PCM0_IN_LEFT,178SST_GAIN_INDEX_PCM0_IN_RIGHT,179180SST_GAIN_INDEX_PCM1_OUT_LEFT,181SST_GAIN_INDEX_PCM1_OUT_RIGHT,182SST_GAIN_INDEX_PCM1_IN_LEFT,183SST_GAIN_INDEX_PCM1_IN_RIGHT,184SST_GAIN_INDEX_PCM2_OUT_LEFT,185186SST_GAIN_INDEX_PCM2_OUT_RIGHT,187SST_GAIN_INDEX_VOIP_OUT,188SST_GAIN_INDEX_VOIP_IN,189190/* Gain IDs for MMX task start here */191SST_GAIN_INDEX_MEDIA0_IN_LEFT,192SST_GAIN_INDEX_MEDIA0_IN_RIGHT,193SST_GAIN_INDEX_MEDIA1_IN_LEFT,194SST_GAIN_INDEX_MEDIA1_IN_RIGHT,195196SST_GAIN_INDEX_MEDIA2_IN_LEFT,197SST_GAIN_INDEX_MEDIA2_IN_RIGHT,198199SST_GAIN_INDEX_GAIN_END200};201202/*203* Audio DSP module IDs specified by FW spec204* TODO: Update with all modules205*/206enum sst_module_id {207SST_MODULE_ID_PCM = 0x0001,208SST_MODULE_ID_MP3 = 0x0002,209SST_MODULE_ID_MP24 = 0x0003,210SST_MODULE_ID_AAC = 0x0004,211SST_MODULE_ID_AACP = 0x0005,212SST_MODULE_ID_EAACP = 0x0006,213SST_MODULE_ID_WMA9 = 0x0007,214SST_MODULE_ID_WMA10 = 0x0008,215SST_MODULE_ID_WMA10P = 0x0009,216SST_MODULE_ID_RA = 0x000A,217SST_MODULE_ID_DDAC3 = 0x000B,218SST_MODULE_ID_TRUE_HD = 0x000C,219SST_MODULE_ID_HD_PLUS = 0x000D,220221SST_MODULE_ID_SRC = 0x0064,222SST_MODULE_ID_DOWNMIX = 0x0066,223SST_MODULE_ID_GAIN_CELL = 0x0067,224SST_MODULE_ID_SPROT = 0x006D,225SST_MODULE_ID_BASS_BOOST = 0x006E,226SST_MODULE_ID_STEREO_WDNG = 0x006F,227SST_MODULE_ID_AV_REMOVAL = 0x0070,228SST_MODULE_ID_MIC_EQ = 0x0071,229SST_MODULE_ID_SPL = 0x0072,230SST_MODULE_ID_ALGO_VTSV = 0x0073,231SST_MODULE_ID_NR = 0x0076,232SST_MODULE_ID_BWX = 0x0077,233SST_MODULE_ID_DRP = 0x0078,234SST_MODULE_ID_MDRP = 0x0079,235236SST_MODULE_ID_ANA = 0x007A,237SST_MODULE_ID_AEC = 0x007B,238SST_MODULE_ID_NR_SNS = 0x007C,239SST_MODULE_ID_SER = 0x007D,240SST_MODULE_ID_AGC = 0x007E,241242SST_MODULE_ID_CNI = 0x007F,243SST_MODULE_ID_CONTEXT_ALGO_AWARE = 0x0080,244SST_MODULE_ID_FIR_24 = 0x0081,245SST_MODULE_ID_IIR_24 = 0x0082,246247SST_MODULE_ID_ASRC = 0x0083,248SST_MODULE_ID_TONE_GEN = 0x0084,249SST_MODULE_ID_BMF = 0x0086,250SST_MODULE_ID_EDL = 0x0087,251SST_MODULE_ID_GLC = 0x0088,252253SST_MODULE_ID_FIR_16 = 0x0089,254SST_MODULE_ID_IIR_16 = 0x008A,255SST_MODULE_ID_DNR = 0x008B,256257SST_MODULE_ID_VIRTUALIZER = 0x008C,258SST_MODULE_ID_VISUALIZATION = 0x008D,259SST_MODULE_ID_LOUDNESS_OPTIMIZER = 0x008E,260SST_MODULE_ID_REVERBERATION = 0x008F,261262SST_MODULE_ID_CNI_TX = 0x0090,263SST_MODULE_ID_REF_LINE = 0x0091,264SST_MODULE_ID_VOLUME = 0x0092,265SST_MODULE_ID_FILT_DCR = 0x0094,266SST_MODULE_ID_SLV = 0x009A,267SST_MODULE_ID_NLF = 0x009B,268SST_MODULE_ID_TNR = 0x009C,269SST_MODULE_ID_WNR = 0x009D,270271SST_MODULE_ID_LOG = 0xFF00,272273SST_MODULE_ID_TASK = 0xFFFF,274};275276enum sst_cmd {277SBA_IDLE = 14,278SBA_VB_SET_SPEECH_PATH = 26,279MMX_SET_GAIN = 33,280SBA_VB_SET_GAIN = 33,281FBA_VB_RX_CNI = 35,282MMX_SET_GAIN_TIMECONST = 36,283SBA_VB_SET_TIMECONST = 36,284SBA_VB_START = 85,285SBA_SET_SWM = 114,286SBA_SET_MDRP = 116,287SBA_HW_SET_SSP = 117,288SBA_SET_MEDIA_LOOP_MAP = 118,289SBA_SET_MEDIA_PATH = 119,290MMX_SET_MEDIA_PATH = 119,291SBA_VB_LPRO = 126,292SBA_VB_SET_FIR = 128,293SBA_VB_SET_IIR = 129,294SBA_SET_SSP_SLOT_MAP = 130,295};296297enum sst_dsp_switch {298SST_SWITCH_OFF = 0,299SST_SWITCH_ON = 3,300};301302enum sst_path_switch {303SST_PATH_OFF = 0,304SST_PATH_ON = 1,305};306307enum sst_swm_state {308SST_SWM_OFF = 0,309SST_SWM_ON = 3,310};311312#define SST_FILL_LOCATION_IDS(dst, cell_idx, pipe_id) do { \313dst.location_id.p.cell_nbr_idx = (cell_idx); \314dst.location_id.p.path_id = (pipe_id); \315} while (0)316#define SST_FILL_LOCATION_ID(dst, loc_id) (\317dst.location_id.f = (loc_id))318#define SST_FILL_MODULE_ID(dst, mod_id) (\319dst.module_id = (mod_id))320321#define SST_FILL_DESTINATION1(dst, id) do { \322SST_FILL_LOCATION_ID(dst, (id) & 0xFFFF); \323SST_FILL_MODULE_ID(dst, ((id) & 0xFFFF0000) >> 16); \324} while (0)325#define SST_FILL_DESTINATION2(dst, loc_id, mod_id) do { \326SST_FILL_LOCATION_ID(dst, loc_id); \327SST_FILL_MODULE_ID(dst, mod_id); \328} while (0)329#define SST_FILL_DESTINATION3(dst, cell_idx, path_id, mod_id) do { \330SST_FILL_LOCATION_IDS(dst, cell_idx, path_id); \331SST_FILL_MODULE_ID(dst, mod_id); \332} while (0)333334#define SST_FILL_DESTINATION(level, dst, ...) \335SST_FILL_DESTINATION##level(dst, __VA_ARGS__)336#define SST_FILL_DEFAULT_DESTINATION(dst) \337SST_FILL_DESTINATION(2, dst, SST_DEFAULT_LOCATION_ID, SST_DEFAULT_MODULE_ID)338339struct sst_destination_id {340union sst_location_id {341struct {342u8 cell_nbr_idx; /* module index */343u8 path_id; /* pipe_id */344} __packed p; /* part */345u16 f; /* full */346} __packed location_id;347u16 module_id;348} __packed;349struct sst_dsp_header {350struct sst_destination_id dst;351u16 command_id;352u16 length;353} __packed;354355/*356*357* Common Commands358*359*/360struct sst_cmd_generic {361struct sst_dsp_header header;362} __packed;363364struct swm_input_ids {365struct sst_destination_id input_id;366} __packed;367368struct sst_cmd_set_swm {369struct sst_dsp_header header;370struct sst_destination_id output_id;371u16 switch_state;372u16 nb_inputs;373struct swm_input_ids input[SST_CMD_SWM_MAX_INPUTS];374} __packed;375376struct sst_cmd_set_media_path {377struct sst_dsp_header header;378u16 switch_state;379} __packed;380381struct pcm_cfg {382u8 s_length:2;383u8 rate:3;384u8 format:3;385} __packed;386387struct sst_cmd_set_speech_path {388struct sst_dsp_header header;389u16 switch_state;390struct {391u16 rsvd:8;392struct pcm_cfg cfg;393} config;394} __packed;395396struct gain_cell {397struct sst_destination_id dest;398s16 cell_gain_left;399s16 cell_gain_right;400u16 gain_time_constant;401} __packed;402403#define NUM_GAIN_CELLS 1404struct sst_cmd_set_gain_dual {405struct sst_dsp_header header;406u16 gain_cell_num;407struct gain_cell cell_gains[NUM_GAIN_CELLS];408} __packed;409struct sst_cmd_set_params {410struct sst_destination_id dst;411u16 command_id;412char params[];413} __packed;414415416struct sst_cmd_sba_vb_start {417struct sst_dsp_header header;418} __packed;419420union sba_media_loop_params {421struct {422u16 rsvd:8;423struct pcm_cfg cfg;424} part;425u16 full;426} __packed;427428struct sst_cmd_sba_set_media_loop_map {429struct sst_dsp_header header;430u16 switch_state;431union sba_media_loop_params param;432u16 map;433} __packed;434435struct sst_cmd_tone_stop {436struct sst_dsp_header header;437u16 switch_state;438} __packed;439440enum sst_ssp_mode {441SSP_MODE_PROVIDER = 0,442SSP_MODE_CONSUMER = 1,443};444445enum sst_ssp_pcm_mode {446SSP_PCM_MODE_NORMAL = 0,447SSP_PCM_MODE_NETWORK = 1,448};449450enum sst_ssp_duplex {451SSP_DUPLEX = 0,452SSP_RX = 1,453SSP_TX = 2,454};455456enum sst_ssp_fs_frequency {457SSP_FS_8_KHZ = 0,458SSP_FS_16_KHZ = 1,459SSP_FS_44_1_KHZ = 2,460SSP_FS_48_KHZ = 3,461};462463enum sst_ssp_fs_polarity {464SSP_FS_ACTIVE_LOW = 0,465SSP_FS_ACTIVE_HIGH = 1,466};467468enum sst_ssp_protocol {469SSP_MODE_PCM = 0,470SSP_MODE_I2S = 1,471};472473enum sst_ssp_port_id {474SSP_MODEM = 0,475SSP_BT = 1,476SSP_FM = 2,477SSP_CODEC = 3,478};479480struct sst_cmd_sba_hw_set_ssp {481struct sst_dsp_header header;482u16 selection; /* 0:SSP0(def), 1:SSP1, 2:SSP2 */483484u16 switch_state;485486u16 nb_bits_per_slots:6; /* 0-32 bits, 24 (def) */487u16 nb_slots:4; /* 0-8: slots per frame */488u16 mode:3; /* 0:Master, 1: Slave */489u16 duplex:3;490491u16 active_tx_slot_map:8; /* Bit map, 0:off, 1:on */492u16 reserved1:8;493494u16 active_rx_slot_map:8; /* Bit map 0: Off, 1:On */495u16 reserved2:8;496497u16 frame_sync_frequency;498499u16 frame_sync_polarity:8;500u16 data_polarity:8;501502u16 frame_sync_width; /* 1 to N clocks */503u16 ssp_protocol:8;504u16 start_delay:8; /* Start delay in terms of clock ticks */505} __packed;506507#define SST_MAX_TDM_SLOTS 8508509struct sst_param_sba_ssp_slot_map {510struct sst_dsp_header header;511512u16 param_id;513u16 param_len;514u16 ssp_index;515516u8 rx_slot_map[SST_MAX_TDM_SLOTS];517u8 tx_slot_map[SST_MAX_TDM_SLOTS];518} __packed;519520enum {521SST_PROBE_EXTRACTOR = 0,522SST_PROBE_INJECTOR = 1,523};524525/**** widget defines *****/526527#define SST_MODULE_GAIN 1528#define SST_MODULE_ALGO 2529530#define SST_FMT_MONO 0531#define SST_FMT_STEREO 3532533/* physical SSP numbers */534enum {535SST_SSP0 = 0,536SST_SSP1,537SST_SSP2,538SST_SSP_LAST = SST_SSP2,539};540541#define SST_NUM_SSPS (SST_SSP_LAST + 1) /* physical SSPs */542#define SST_MAX_SSP_MUX 2 /* single SSP muxed between pipes */543#define SST_MAX_SSP_DOMAINS 2 /* domains present in each pipe */544545struct sst_module {546struct snd_kcontrol *kctl;547struct list_head node;548};549550struct sst_ssp_config {551u8 ssp_id;552u8 bits_per_slot;553u8 slots;554u8 ssp_mode;555u8 pcm_mode;556u8 duplex;557u8 ssp_protocol;558u8 fs_frequency;559u8 active_slot_map;560u8 start_delay;561u16 fs_width;562u8 frame_sync_polarity;563u8 data_polarity;564};565566struct sst_ssp_cfg {567const u8 ssp_number;568const int *mux_shift;569const int (*domain_shift)[SST_MAX_SSP_MUX];570const struct sst_ssp_config (*ssp_config)[SST_MAX_SSP_MUX][SST_MAX_SSP_DOMAINS];571};572573struct sst_ids {574u16 location_id;575u16 module_id;576u8 task_id;577u8 format;578u8 reg;579const char *parent_wname;580struct snd_soc_dapm_widget *parent_w;581struct list_head algo_list;582struct list_head gain_list;583const struct sst_pcm_format *pcm_fmt;584};585586587#define SST_AIF_IN(wname, wevent) \588{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = NULL, \589.reg = SND_SOC_NOPM, .shift = 0, \590.on_val = 1, .off_val = 0, \591.event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \592.priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \593}594595#define SST_AIF_OUT(wname, wevent) \596{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = NULL, \597.reg = SND_SOC_NOPM, .shift = 0, \598.on_val = 1, .off_val = 0, \599.event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \600.priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \601}602603#define SST_INPUT(wname, wevent) \604{ .id = snd_soc_dapm_input, .name = wname, .sname = NULL, \605.reg = SND_SOC_NOPM, .shift = 0, \606.on_val = 1, .off_val = 0, \607.event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \608.priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \609}610611#define SST_OUTPUT(wname, wevent) \612{ .id = snd_soc_dapm_output, .name = wname, .sname = NULL, \613.reg = SND_SOC_NOPM, .shift = 0, \614.on_val = 1, .off_val = 0, \615.event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \616.priv = (void *)&(struct sst_ids) { .task_id = 0, .location_id = 0 } \617}618619#define SST_DAPM_OUTPUT(wname, wloc_id, wtask_id, wformat, wevent) \620{ .id = snd_soc_dapm_output, .name = wname, .sname = NULL, \621.reg = SND_SOC_NOPM, .shift = 0, \622.on_val = 1, .off_val = 0, \623.event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \624.priv = (void *)&(struct sst_ids) { .location_id = wloc_id, .task_id = wtask_id,\625.pcm_fmt = wformat, } \626}627628#define SST_PATH(wname, wtask, wloc_id, wevent, wflags) \629{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \630.kcontrol_news = NULL, .num_kcontrols = 0, \631.on_val = 1, .off_val = 0, \632.event = wevent, .event_flags = wflags, \633.priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, } \634}635636#define SST_LINKED_PATH(wname, wtask, wloc_id, linked_wname, wevent, wflags) \637{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \638.kcontrol_news = NULL, .num_kcontrols = 0, \639.on_val = 1, .off_val = 0, \640.event = wevent, .event_flags = wflags, \641.priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \642.parent_wname = linked_wname} \643}644645#define SST_PATH_MEDIA_LOOP(wname, wtask, wloc_id, wformat, wevent, wflags) \646{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \647.kcontrol_news = NULL, .num_kcontrols = 0, \648.event = wevent, .event_flags = wflags, \649.priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \650.format = wformat,} \651}652653/* output is triggered before input */654#define SST_PATH_INPUT(name, task_id, loc_id, event) \655SST_PATH(name, task_id, loc_id, event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)656657#define SST_PATH_LINKED_INPUT(name, task_id, loc_id, linked_wname, event) \658SST_LINKED_PATH(name, task_id, loc_id, linked_wname, event, \659SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)660661#define SST_PATH_OUTPUT(name, task_id, loc_id, event) \662SST_PATH(name, task_id, loc_id, event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)663664#define SST_PATH_LINKED_OUTPUT(name, task_id, loc_id, linked_wname, event) \665SST_LINKED_PATH(name, task_id, loc_id, linked_wname, event, \666SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)667668#define SST_PATH_MEDIA_LOOP_OUTPUT(name, task_id, loc_id, format, event) \669SST_PATH_MEDIA_LOOP(name, task_id, loc_id, format, event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)670671672#define SST_SWM_MIXER(wname, wreg, wtask, wloc_id, wcontrols, wevent) \673{ .id = snd_soc_dapm_mixer, .name = wname, .reg = SND_SOC_NOPM, .shift = 0, \674.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols),\675.event = wevent, .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD | \676SND_SOC_DAPM_POST_REG, \677.priv = (void *)&(struct sst_ids) { .task_id = wtask, .location_id = wloc_id, \678.reg = wreg } \679}680681enum sst_gain_kcontrol_type {682SST_GAIN_TLV,683SST_GAIN_MUTE,684SST_GAIN_RAMP_DURATION,685};686687struct sst_gain_mixer_control {688bool stereo;689enum sst_gain_kcontrol_type type;690struct sst_gain_value *gain_val;691int max;692int min;693u16 instance_id;694u16 module_id;695u16 pipe_id;696u16 task_id;697char pname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];698struct snd_soc_dapm_widget *w;699};700701struct sst_gain_value {702u16 ramp_duration;703s16 l_gain;704s16 r_gain;705bool mute;706};707#define SST_GAIN_VOLUME_DEFAULT (-1440)708#define SST_GAIN_RAMP_DURATION_DEFAULT 5 /* timeconstant */709#define SST_GAIN_MUTE_DEFAULT true710711#define SST_GAIN_KCONTROL_TLV(xname, xhandler_get, xhandler_put, \712xmod, xpipe, xinstance, xtask, tlv_array, xgain_val, \713xmin, xmax, xpname) \714.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \715.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \716SNDRV_CTL_ELEM_ACCESS_READWRITE, \717.tlv.p = (tlv_array), \718.info = sst_gain_ctl_info,\719.get = xhandler_get, .put = xhandler_put, \720.private_value = (unsigned long)&(struct sst_gain_mixer_control) \721{ .stereo = true, .max = xmax, .min = xmin, .type = SST_GAIN_TLV, \722.module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\723.instance_id = xinstance, .gain_val = xgain_val, .pname = xpname}724725#define SST_GAIN_KCONTROL_INT(xname, xhandler_get, xhandler_put, \726xmod, xpipe, xinstance, xtask, xtype, xgain_val, \727xmin, xmax, xpname) \728.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \729.info = sst_gain_ctl_info, \730.get = xhandler_get, .put = xhandler_put, \731.private_value = (unsigned long)&(struct sst_gain_mixer_control) \732{ .stereo = false, .max = xmax, .min = xmin, .type = xtype, \733.module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\734.instance_id = xinstance, .gain_val = xgain_val, .pname = xpname}735736#define SST_GAIN_KCONTROL_BOOL(xname, xhandler_get, xhandler_put,\737xmod, xpipe, xinstance, xtask, xgain_val, xpname) \738.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \739.info = snd_soc_info_bool_ext, \740.get = xhandler_get, .put = xhandler_put, \741.private_value = (unsigned long)&(struct sst_gain_mixer_control) \742{ .stereo = false, .type = SST_GAIN_MUTE, \743.module_id = xmod, .pipe_id = xpipe, .task_id = xtask,\744.instance_id = xinstance, .gain_val = xgain_val, .pname = xpname}745#define SST_CONTROL_NAME(xpname, xmname, xinstance, xtype) \746xpname " " xmname " " #xinstance " " xtype747748#define SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, xtype, xsubmodule) \749xpname " " xmname " " #xinstance " " xtype " " xsubmodule750751/*752* 3 Controls for each Gain module753* e.g. - pcm0_in Gain 0 Volume754* - pcm0_in Gain 0 Ramp Delay755* - pcm0_in Gain 0 Switch756*/757#define SST_GAIN_KCONTROLS(xpname, xmname, xmin_gain, xmax_gain, xmin_tc, xmax_tc, \758xhandler_get, xhandler_put, \759xmod, xpipe, xinstance, xtask, tlv_array, xgain_val) \760{ SST_GAIN_KCONTROL_INT(SST_CONTROL_NAME(xpname, xmname, xinstance, "Ramp Delay"), \761xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, SST_GAIN_RAMP_DURATION, \762xgain_val, xmin_tc, xmax_tc, xpname) }, \763{ SST_GAIN_KCONTROL_BOOL(SST_CONTROL_NAME(xpname, xmname, xinstance, "Switch"), \764xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, \765xgain_val, xpname) } ,\766{ SST_GAIN_KCONTROL_TLV(SST_CONTROL_NAME(xpname, xmname, xinstance, "Volume"), \767xhandler_get, xhandler_put, xmod, xpipe, xinstance, xtask, tlv_array, \768xgain_val, xmin_gain, xmax_gain, xpname) }769770#define SST_GAIN_TC_MIN 5771#define SST_GAIN_TC_MAX 5000772#define SST_GAIN_MIN_VALUE -1440 /* in 0.1 DB units */773#define SST_GAIN_MAX_VALUE 360774775enum sst_algo_kcontrol_type {776SST_ALGO_PARAMS,777SST_ALGO_BYPASS,778};779780struct sst_algo_control {781enum sst_algo_kcontrol_type type;782int max;783u16 module_id;784u16 pipe_id;785u16 task_id;786u16 cmd_id;787bool bypass;788unsigned char *params;789struct snd_soc_dapm_widget *w;790};791792/* size of the control = size of params + size of length field */793#define SST_ALGO_CTL_VALUE(xcount, xtype, xpipe, xmod, xtask, xcmd) \794(struct sst_algo_control){ \795.max = xcount + sizeof(u16), .type = xtype, .module_id = xmod, \796.pipe_id = xpipe, .task_id = xtask, .cmd_id = xcmd, \797}798799#define SST_ALGO_KCONTROL(xname, xcount, xmod, xpipe, \800xtask, xcmd, xtype, xinfo, xget, xput) \801{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \802.name = xname, \803.info = xinfo, .get = xget, .put = xput, \804.private_value = (unsigned long)& \805SST_ALGO_CTL_VALUE(xcount, xtype, xpipe, \806xmod, xtask, xcmd), \807}808809#define SST_ALGO_KCONTROL_BYTES(xpname, xmname, xcount, xmod, \810xpipe, xinstance, xtask, xcmd) \811SST_ALGO_KCONTROL(SST_CONTROL_NAME(xpname, xmname, xinstance, "params"), \812xcount, xmod, xpipe, xtask, xcmd, SST_ALGO_PARAMS, \813sst_algo_bytes_ctl_info, \814sst_algo_control_get, sst_algo_control_set)815816#define SST_ALGO_KCONTROL_BOOL(xpname, xmname, xmod, xpipe, xinstance, xtask) \817SST_ALGO_KCONTROL(SST_CONTROL_NAME(xpname, xmname, xinstance, "bypass"), \8180, xmod, xpipe, xtask, 0, SST_ALGO_BYPASS, \819snd_soc_info_bool_ext, \820sst_algo_control_get, sst_algo_control_set)821822#define SST_ALGO_BYPASS_PARAMS(xpname, xmname, xcount, xmod, xpipe, \823xinstance, xtask, xcmd) \824SST_ALGO_KCONTROL_BOOL(xpname, xmname, xmod, xpipe, xinstance, xtask), \825SST_ALGO_KCONTROL_BYTES(xpname, xmname, xcount, xmod, xpipe, xinstance, xtask, xcmd)826827#define SST_COMBO_ALGO_KCONTROL_BYTES(xpname, xmname, xsubmod, xcount, xmod, \828xpipe, xinstance, xtask, xcmd) \829SST_ALGO_KCONTROL(SST_COMBO_CONTROL_NAME(xpname, xmname, xinstance, "params", \830xsubmod), \831xcount, xmod, xpipe, xtask, xcmd, SST_ALGO_PARAMS, \832sst_algo_bytes_ctl_info, \833sst_algo_control_get, sst_algo_control_set)834835836struct sst_enum {837bool tx;838unsigned short reg;839unsigned int max;840const char * const *texts;841struct snd_soc_dapm_widget *w;842};843844/* only 4 slots/channels supported atm */845#define SST_SSP_SLOT_ENUM(s_ch_no, is_tx, xtexts) \846(struct sst_enum){ .reg = s_ch_no, .tx = is_tx, .max = 4+1, .texts = xtexts, }847848#define SST_SLOT_CTL_NAME(xpname, xmname, s_ch_name) \849xpname " " xmname " " s_ch_name850851#define SST_SSP_SLOT_CTL(xpname, xmname, s_ch_name, s_ch_no, is_tx, xtexts, xget, xput) \852{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \853.name = SST_SLOT_CTL_NAME(xpname, xmname, s_ch_name), \854.info = sst_slot_enum_info, \855.get = xget, .put = xput, \856.private_value = (unsigned long)&SST_SSP_SLOT_ENUM(s_ch_no, is_tx, xtexts), \857}858859#define SST_MUX_CTL_NAME(xpname, xinstance) \860xpname " " #xinstance861862#define SST_SSP_MUX_ENUM(xreg, xshift, xtexts) \863(struct soc_enum) SOC_ENUM_DOUBLE(xreg, xshift, xshift, ARRAY_SIZE(xtexts), xtexts)864865#define SST_SSP_MUX_CTL(xpname, xinstance, xreg, xshift, xtexts) \866SOC_DAPM_ENUM(SST_MUX_CTL_NAME(xpname, xinstance), \867SST_SSP_MUX_ENUM(xreg, xshift, xtexts))868869int sst_fill_ssp_slot(struct snd_soc_dai *dai, unsigned int tx_mask,870unsigned int rx_mask, int slots, int slot_width);871int sst_fill_ssp_config(struct snd_soc_dai *dai, unsigned int fmt);872void sst_fill_ssp_defaults(struct snd_soc_dai *dai);873874#endif875876877