diff --git a/sound/soc/tegra-alt/include/ahub_unit_fpga_clock.h b/sound/soc/tegra-alt/include/ahub_unit_fpga_clock.h new file mode 100644 index 00000000..c9d2f07c --- /dev/null +++ b/sound/soc/tegra-alt/include/ahub_unit_fpga_clock.h @@ -0,0 +1,481 @@ +/* + * ahub_unit_fpga_clock.h + * + * Copyright (c) 2013-2017, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __AHUB_UNIT_FPGA_CLOCK_H__ +#define __AHUB_UNIT_FPGA_CLOCK_H__ + +#define SYSTEM_FPGA 0 +#define DEBUG_FPGA 1 + +#define APE_FPGA_MISC_CLK_SOURCE_I2C1_0 0x68 +#define APE_FPGA_MISC_CLK_SOURCE_I2S1_0 0x28 +#define APE_FPGA_MISC_CLK_SOURCE_I2S2_0 0x20 +#define APE_FPGA_MISC_CLK_SOURCE_I2S3_0 0x24 +#define APE_FPGA_MISC_CLK_SOURCE_I2S4_0 0x2c +#define APE_FPGA_MISC_CLK_SOURCE_I2S5_0 0x30 +#define APE_FPGA_MISC_CLK_SOURCE_DMIC1_0 0x14 + +#define I2C_I2C_CMD_ADDR0_0 0x4 +#define I2C_I2C_CNFG_0 0x0 +#define I2C_I2C_CMD_DATA1_0 0xc +#define I2C_I2C_CONFIG_LOAD_0 0x8c +#define I2C_I2C_STATUS_0 0x1c + +#define I2C_I2C_CMD_ADDR1_0 0x8 +#define I2C_I2C_CMD_DATA1_0 0xc +#define I2C_I2C_CMD_DATA2_0 0x10 + +#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S1_0 0x1d8 +#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S2_0 0x100 +#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S3_0 0x104 +#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S4_0 0x3bc +#define CLK_RST_CONTROLLER_CLK_SOURCE_I2S5_0 0x3c0 + +#define CLK_RST_CONTROLLER_RST_DEVICES_L_0 0x4 +#define CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0 0x10 +#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C1_0 0x124 + +#define PINMUX_AUX_GEN1_I2C_SDA_0 0x30c0 +#define PINMUX_AUX_GEN1_I2C_SCL_0 0x30bc + +#define PINMUX_AUX_DAP1_SCLK_0 0x3130 +#define PINMUX_AUX_DAP1_FS_0 0x3124 +#define PINMUX_AUX_DAP1_DIN_0 0x3128 +#define PINMUX_AUX_DAP1_DOUT_0 0x312c +#define PINMUX_AUX_DAP2_SCLK_0 0x3140 +#define PINMUX_AUX_DAP2_FS_0 0x3134 +#define PINMUX_AUX_DAP2_DIN_0 0x3138 +#define PINMUX_AUX_DAP2_DOUT_0 0x313c + +#define PINMUX_AUX_DMIC1_CLK_0 0x30a4 /* DAP3_SCLK_0 */ +#define PINMUX_AUX_DMIC1_DAT_0 0x30a8 /* DAP3_FS_0 */ +#define PINMUX_AUX_DMIC2_CLK_0 0x30ac /* DAP3_DIN_0 */ +#define PINMUX_AUX_DMIC2_DAT_0 0x30b0 /* DAP3_DOUT_0 */ + +#define PINMUX_AUX_GPIO_PK0_0 0x3254 /* DAP5 */ +#define PINMUX_AUX_GPIO_PK1_0 0x3258 /* DAP5 */ +#define PINMUX_AUX_GPIO_PK2_0 0x325c /* DAP5 */ +#define PINMUX_AUX_GPIO_PK3_0 0x3260 /* DAP5 */ + +#define NV_ADDRESS_MAP_APE_AHUB_FPGA_CAR_BASE 1882050560 +#define NV_ADDRESS_MAP_APE_AHUB_FPGA_CAR_LIMIT 1882054655 +#define NV_ADDRESS_MAP_APE_AHUB_FPGA_CAR_SIZE 4096 +#define T210_NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_BASE 1882048512 +#define T186_NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_BASE 0x0290C800 +#define T210_NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_LIMIT 1882048767 +#define T186_NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_LIMIT 0x0290C8FF +#define NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_SIZE 256 + +#if SYSTEM_FPGA +#define T210_NV_ADDRESS_MAP_APE_AHUB_I2C_BASE 0x7000c000 +#else +#define T210_NV_ADDRESS_MAP_APE_AHUB_I2C_BASE 1882047744 +#define T186_NV_ADDRESS_MAP_APE_AHUB_I2C_BASE 0x0290c500 +#define NV_ADDRESS_MAP_APE_AHUB_GPIO_BASE 0x702DC700 +#define APE_AHUB_GPIO_CNF_0 0x0 +#define APE_AHUB_GPIO_OE_0 0x10 +#define APE_AHUB_GPIO_OUT_0 0x20 +#endif + +#define NV_ADDRESS_MAP_APE_AHUB_I2C_LIMIT 1882048255 +#define NV_ADDRESS_MAP_APE_AHUB_I2C_SIZE 512 + +#define NV_ADDRESS_MAP_APB_PP_BASE 1879048192 +#define NV_ADDRESS_MAP_PPSB_CLK_RST_BASE 1610637312 + +#define T210_NV_ADDRESS_MAP_APE_I2S5_BASE 0x702d1400 +#define T186_NV_ADDRESS_MAP_APE_I2S5_BASE 0x02901400 +#define I2S5_CYA_0 0xb0 +#define APE_FPGA_MISC_CLK_SOURCE_DSPK1_0 0x6c +#define APE_FPGA_MISC_CLK_SOURCE_DSPK2_0 0x70 + +#define CDCE906_04_0960_MHz 0 +#define CDCE906_06_1440_MHz 1 +#define CDCE906_08_1920_MHz 2 +#define CDCE906_11_2896_MHz 3 +#define CDCE906_12_2880_MHz 4 +#define CDCE906_16_3840_MHz 5 +#define CDCE906_22_5792_MHz 6 +#define CDCE906_24_5760_MHz 7 +#define CDCE906_09_2160_MHz 8 +#define CDCE906_16_9344_MHz 9 +#define CDCE906_18_4320_MHz 10 +#define CDCE906_33_8688_MHz 11 +#define CDCE906_36_8640_MHz 12 + +#define MAX9485_DEVICE_ADDRESS 0x60 + +#define MAX9485_MCLK_FREQ_163840 0x31 +#define MAX9485_MCLK_FREQ_112896 0x22 +#define MAX9485_MCLK_FREQ_122880 0x23 +#define MAX9485_MCLK_FREQ_225792 0x32 +#define MAX9485_MCLK_FREQ_245760 0x33 + +enum AUDIO_DAC_DATAWIDTH{ + AUDIO_DAC_DATAWIDTH_16 = 3, + AUDIO_DAC_DATAWIDTH_24 = 5 +}; + +enum AUDIO_SAMPLE_RATE{ + AUDIO_SAMPLE_RATE_8_00 = 8000, + AUDIO_SAMPLE_RATE_11_02 = 11020, + AUDIO_SAMPLE_RATE_12_00 = 12000, + AUDIO_SAMPLE_RATE_16_00 = 16000, + AUDIO_SAMPLE_RATE_22_05 = 22050, + AUDIO_SAMPLE_RATE_24_00 = 24000, + AUDIO_SAMPLE_RATE_32_00 = 32000, + AUDIO_SAMPLE_RATE_44_10 = 44100, + AUDIO_SAMPLE_RATE_48_00 = 48000, + AUDIO_SAMPLE_RATE_64_00 = 64000, + AUDIO_SAMPLE_RATE_88_20 = 88200, + AUDIO_SAMPLE_RATE_96_00 = 96000, + AUDIO_SAMPLE_RATE_128_00 = 128000, + AUDIO_SAMPLE_RATE_176_40 = 176000, + AUDIO_SAMPLE_RATE_192_00 = 192000 +}; + +enum I2S_ID{ + I2S1 = 0, + I2S2, + I2S3, + I2S4, + I2S5 +}; + +enum AUDIO_MASTER_CLK_FREQ{ + CLK_OUT_3_0720_MHZ = 0, + CLK_OUT_4_0960_MHZ, + CLK_OUT_4_6080_MHZ, + CLK_OUT_5_6448_MHZ, + CLK_OUT_6_1440_MHZ, + CLK_OUT_8_1920_MHZ, + CLK_OUT_11_2896_MHZ, + CLK_OUT_12_2888_MHZ, + CLK_OUT_16_3840_MHZ, + CLK_OUT_16_9344_MHZ, + CLK_OUT_18_4320_MHZ, + CLK_OUT_22_5792_MHZ, + CLK_OUT_24_5760_MHZ, + CLK_OUT_33_8688_MHZ, + CLK_OUT_36_8640_MHZ, + CLK_OUT_49_1520_MHZ, + CLK_OUT_73_7280_MHZ, + CLK_OUT_162_MHZ, + TOTAL_CLK_OUT +}; + +enum AUDIO_CLOCK_GEN_SELECT{ + CLK_OUT_FROM_TEGRA, + CLK_GEN_CDCE906, + CLK_GEN_MAX9485 +}; + +#define AD1937_X_ADDRESS 0x05 +#define AD1937_Y_ADDRESS 0x04 +#define AD1937_Z_ADDRESS 0x07 + +#define AD1937_PLL_CLK_CTRL_0 0x00 +#define AD1937_PLL_CLK_CTRL_1 0x01 +#define AD1937_DAC_CTRL_0 0x02 +#define AD1937_DAC_CTRL_1 0x03 +#define AD1937_DAC_CTRL_2 0x04 +#define AD1937_DAC_MUTE_CTRL 0x05 +#define AD1937_DAC_VOL_CTRL_DAC1L 0x06 +#define AD1937_DAC_VOL_CTRL_DAC1R 0x07 +#define AD1937_DAC_VOL_CTRL_DAC2L 0x08 +#define AD1937_DAC_VOL_CTRL_DAC2R 0x09 +#define AD1937_DAC_VOL_CTRL_DAC3L 0x0a +#define AD1937_DAC_VOL_CTRL_DAC3R 0x0b +#define AD1937_DAC_VOL_CTRL_DAC4L 0x0c +#define AD1937_DAC_VOL_CTRL_DAC4R 0x0d +#define AD1937_ADC_CTRL_0 0x0e +#define AD1937_ADC_CTRL_1 0x0f +#define AD1937_ADC_CTRL_2 0x10 + +#define AD1937_PLL_CLK_CTRL_0_PWR_MASK (1 << 0) +#define AD1937_PLL_CLK_CTRL_0_PWR_ON (0 << 0) +#define AD1937_PLL_CLK_CTRL_0_PWR_OFF (1 << 0) +#define AD1937_PLL_CLK_CTRL_0_MCLKI_MASK (3 << 1) +#define AD1937_PLL_CLK_CTRL_0_MCLKI_256 (0 << 1) +#define AD1937_PLL_CLK_CTRL_0_MCLKI_384 (1 << 1) +#define AD1937_PLL_CLK_CTRL_0_MCLKI_512 (2 << 1) +#define AD1937_PLL_CLK_CTRL_0_MCLKI_768 (3 << 1) +#define AD1937_PLL_CLK_CTRL_0_MCLKO_MASK (3 << 3) +#define AD1937_PLL_CLK_CTRL_0_MCLKO_XTAL (0 << 3) +#define AD1937_PLL_CLK_CTRL_0_MCLKO_256 (1 << 3) +#define AD1937_PLL_CLK_CTRL_0_MCLKO_512 (2 << 3) +#define AD1937_PLL_CLK_CTRL_0_MCLKO_OFF (3 << 3) +#define AD1937_PLL_CLK_CTRL_0_PLL_INPUT_MASK (3 << 5) +#define AD1937_PLL_CLK_CTRL_0_PLL_INPUT_MCLKI (0 << 5) +#define AD1937_PLL_CLK_CTRL_0_PLL_INPUT_DLRCLK (1 << 5) +#define AD1937_PLL_CLK_CTRL_0_PLL_INPUT_ALRCLK (2 << 5) +#define AD1937_PLL_CLK_CTRL_0_INTERNAL_MASTER_CLK_MASK (1 << 7) +#define AD1937_PLL_CLK_CTRL_0_INTERNAL_MASTER_CLK_DISABLE (0 << 7) +#define AD1937_PLL_CLK_CTRL_0_INTERNAL_MASTER_CLK_ENABLE (1 << 7) + + +#define AD1937_PLL_CLK_CTRL_1_DAC_CLK_MASK (1 << 0) +#define AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL (0 << 0) +#define AD1937_PLL_CLK_CTRL_1_DAC_CLK_MCLK (1 << 0) +#define AD1937_PLL_CLK_CTRL_1_ADC_CLK_MASK (1 << 1) +#define AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL (0 << 1) +#define AD1937_PLL_CLK_CTRL_1_ADC_CLK_MCLK (1 << 1) +#define AD1937_PLL_CLK_CTRL_1_VREF_MASK (1 << 2) +#define AD1937_PLL_CLK_CTRL_1_VREF_ENABLE (0 << 2) +#define AD1937_PLL_CLK_CTRL_1_VREF_DISABLE (1 << 2) +#define AD1937_PLL_CLK_CTRL_1_PLL_MASK (1 << 3) +#define AD1937_PLL_CLK_CTRL_1_PLL_NOT_LOCKED (0 << 3) +#define AD1937_PLL_CLK_CTRL_1_PLL_LOCKED (1 << 3) + +#define AD1937_DAC_CTRL_0_PWR_MASK (1 << 0) +#define AD1937_DAC_CTRL_0_PWR_ON (0 << 0) +#define AD1937_DAC_CTRL_0_PWR_OFF (1 << 0) +#define AD1937_DAC_CTRL_0_SAMPLE_RATE_MASK (3 << 1) +#define AD1937_DAC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ (0 << 1) +#define AD1937_DAC_CTRL_0_SAMPLE_RATE_64_88_2_96_KHZ (1 << 1) +#define AD1937_DAC_CTRL_0_SAMPLE_RATE_128_176_4_192_KHZ (2 << 1) +#define AD1937_DAC_CTRL_0_DSDATA_DELAY_MASK (7 << 3) +#define AD1937_DAC_CTRL_0_DSDATA_DELAY_1 (0 << 3) +#define AD1937_DAC_CTRL_0_DSDATA_DELAY_0 (1 << 3) +#define AD1937_DAC_CTRL_0_DSDATA_DELAY_8 (2 << 3) +#define AD1937_DAC_CTRL_0_DSDATA_DELAY_12 (3 << 3) +#define AD1937_DAC_CTRL_0_DSDATA_DELAY_16 (4 << 3) +#define AD1937_DAC_CTRL_0_FMT_MASK (3 << 6) +#define AD1937_DAC_CTRL_0_FMT_STEREO (0 << 6) +#define AD1937_DAC_CTRL_0_FMT_TDM_SINGLE_LINE (1 << 6) +#define AD1937_DAC_CTRL_0_FMT_TDM_AUX (2 << 6) +#define AD1937_DAC_CTRL_0_FMT_TDM_DUAL_LINE (3 << 6) + +#define AD1937_DAC_CTRL_1_DBCLK_ACTIVE_EDGE_MASK (1 << 0) +#define AD1937_DAC_CTRL_1_DBCLK_ACTIVE_EDGE_MIDCYCLE (0 << 0) +#define AD1937_DAC_CTRL_1_DBCLK_ACTIVE_EDGE_PIPELINE (1 << 0) +#define AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_MASK (3 << 1) +#define AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_64 (0 << 1) +#define AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_128 (1 << 1) +#define AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_256 (2 << 1) +#define AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_512 (3 << 1) +#define AD1937_DAC_CTRL_1_DLRCLK_POLARITY_MASK (1 << 3) +#define AD1937_DAC_CTRL_1_DLRCLK_POLARITY_LEFT_LOW (0 << 3) +#define AD1937_DAC_CTRL_1_DLRCLK_POLARITY_LEFT_HIGH (1 << 3) +#define AD1937_DAC_CTRL_1_DLRCLK_MASK (1 << 4) +#define AD1937_DAC_CTRL_1_DLRCLK_SLAVE (0 << 4) +#define AD1937_DAC_CTRL_1_DLRCLK_MASTER (1 << 4) +#define AD1937_DAC_CTRL_1_DBCLK_MASK (1 << 5) +#define AD1937_DAC_CTRL_1_DBCLK_SLAVE (0 << 5) +#define AD1937_DAC_CTRL_1_DBCLK_MASTER (1 << 5) +#define AD1937_DAC_CTRL_1_DBCLK_SOURCE_MASK (1 << 6) +#define AD1937_DAC_CTRL_1_DBCLK_SOURCE_DBCLK_PIN (0 << 6) +#define AD1937_DAC_CTRL_1_DBCLK_SOURCE_INTERNAL (1 << 6) +#define AD1937_DAC_CTRL_1_DBCLK_POLARITY_MASK (1 << 7) +#define AD1937_DAC_CTRL_1_DBCLK_POLARITY_NORMAL (0 << 7) +#define AD1937_DAC_CTRL_1_DBCLK_POLARITY_INVERTED (1 << 7) + +#define AD1937_DAC_CTRL_2_MASTER_MASK (1 << 0) +#define AD1937_DAC_CTRL_2_MASTER_UNMUTE (0 << 0) +#define AD1937_DAC_CTRL_2_MASTER_MUTE (1 << 0) +#define AD1937_DAC_CTRL_2_DEEMPHASIS_MASK (3 << 1) +#define AD1937_DAC_CTRL_2_DEEMPHASIS_FLAT (0 << 1) +#define AD1937_DAC_CTRL_2_DEEMPHASIS_48_KHZ (1 << 1) +#define AD1937_DAC_CTRL_2_DEEMPHASIS_44_1_KHZ (2 << 1) +#define AD1937_DAC_CTRL_2_DEEMPHASIS_32_KHZ (3 << 1) +#define AD1937_DAC_CTRL_2_WORD_WIDTH_MASK (3 << 3) +#define AD1937_DAC_CTRL_2_WORD_WIDTH_24_BITS (0 << 3) +#define AD1937_DAC_CTRL_2_WORD_WIDTH_20_BITS (1 << 3) +#define AD1937_DAC_CTRL_2_WORD_WIDTH_16_BITS (3 << 3) +#define AD1937_DAC_CTRL_2_DAC_OUTPUT_POLARITY_MASK (1 << 5) +#define AD1937_DAC_CTRL_2_DAC_OUTPUT_POLARITY_NORMAL (0 << 5) +#define AD1937_DAC_CTRL_2_DAC_OUTPUT_POLARITY_INVERTED (1 << 5) + +#define AD1937_DAC_MUTE_CTRL_DAC1L_MASK (1 << 0) +#define AD1937_DAC_MUTE_CTRL_DAC1L_UNMUTE (0 << 0) +#define AD1937_DAC_MUTE_CTRL_DAC1L_MUTE (1 << 0) +#define AD1937_DAC_MUTE_CTRL_DAC1R_MASK (1 << 1) +#define AD1937_DAC_MUTE_CTRL_DAC1R_UNMUTE (0 << 1) +#define AD1937_DAC_MUTE_CTRL_DAC1R_MUTE (1 << 1) +#define AD1937_DAC_MUTE_CTRL_DAC2L_MASK (1 << 2) +#define AD1937_DAC_MUTE_CTRL_DAC2L_UNMUTE (0 << 2) +#define AD1937_DAC_MUTE_CTRL_DAC2L_MUTE (1 << 2) +#define AD1937_DAC_MUTE_CTRL_DAC2R_MASK (1 << 3) +#define AD1937_DAC_MUTE_CTRL_DAC2R_UNMUTE (0 << 3) +#define AD1937_DAC_MUTE_CTRL_DAC2R_MUTE (1 << 3) +#define AD1937_DAC_MUTE_CTRL_DAC3L_MASK (1 << 4) +#define AD1937_DAC_MUTE_CTRL_DAC3L_UNMUTE (0 << 4) +#define AD1937_DAC_MUTE_CTRL_DAC3L_MUTE (1 << 4) +#define AD1937_DAC_MUTE_CTRL_DAC3R_MASK (1 << 5) +#define AD1937_DAC_MUTE_CTRL_DAC3R_UNMUTE (0 << 5) +#define AD1937_DAC_MUTE_CTRL_DAC3R_MUTE (1 << 5) +#define AD1937_DAC_MUTE_CTRL_DAC4L_MASK (1 << 6) +#define AD1937_DAC_MUTE_CTRL_DAC4L_UNMUTE (0 << 6) +#define AD1937_DAC_MUTE_CTRL_DAC4L_MUTE (1 << 6) +#define AD1937_DAC_MUTE_CTRL_DAC4R_MASK (1 << 7) +#define AD1937_DAC_MUTE_CTRL_DAC4R_UNMUTE (0 << 7) +#define AD1937_DAC_MUTE_CTRL_DAC4R_MUTE (1 << 7) + +#define AD1937_DAC_VOL_CTRL_DAC1L_MASK (0xff << 0) +#define AD1937_DAC_VOL_CTRL_DAC1R_MASK (0xff << 0) +#define AD1937_DAC_VOL_CTRL_DAC2L_MASK (0xff << 0) +#define AD1937_DAC_VOL_CTRL_DAC2R_MASK (0xff << 0) +#define AD1937_DAC_VOL_CTRL_DAC3L_MASK (0xff << 0) +#define AD1937_DAC_VOL_CTRL_DAC3R_MASK (0xff << 0) +#define AD1937_DAC_VOL_CTRL_DAC4L_MASK (0xff << 0) +#define AD1937_DAC_VOL_CTRL_DAC4R_MASK (0xff << 0) + +#define AD1937_ADC_CTRL_0_PWR_MASK (1 << 0) +#define AD1937_ADC_CTRL_0_PWR_ON (0 << 0) +#define AD1937_ADC_CTRL_0_PWR_OFF (1 << 0) +#define AD1937_ADC_CTRL_0_HIGH_PASS_FILTER_MASK (1 << 1) +#define AD1937_ADC_CTRL_0_HIGH_PASS_FILTER_OFF (0 << 1) +#define AD1937_ADC_CTRL_0_HIGH_PASS_FILTER_ON (1 << 1) +#define AD1937_ADC_CTRL_0_ADC1L_MASK (1 << 2) +#define AD1937_ADC_CTRL_0_ADC1L_UNMUTE (0 << 2) +#define AD1937_ADC_CTRL_0_ADC1L_MUTE (1 << 2) +#define AD1937_ADC_CTRL_0_ADC1R_MASK (1 << 3) +#define AD1937_ADC_CTRL_0_ADC1R_UNMUTE (0 << 3) +#define AD1937_ADC_CTRL_0_ADC1R_MUTE (1 << 3) +#define AD1937_ADC_CTRL_0_ADC2L_MASK (1 << 4) +#define AD1937_ADC_CTRL_0_ADC2L_UNMUTE (0 << 4) +#define AD1937_ADC_CTRL_0_ADC2L_MUTE (1 << 4) +#define AD1937_ADC_CTRL_0_ADC2R_MASK (1 << 5) +#define AD1937_ADC_CTRL_0_ADC2R_UNMUTE (0 << 5) +#define AD1937_ADC_CTRL_0_ADC2R_MUTE (1 << 5) +#define AD1937_ADC_CTRL_0_SAMPLE_RATE_MASK (3 << 6) +#define AD1937_ADC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ (0 << 6) +#define AD1937_ADC_CTRL_0_SAMPLE_RATE_64_88_2_96_KHZ (1 << 6) +#define AD1937_ADC_CTRL_0_SAMPLE_RATE_128_176_4_192_KHZ (2 << 6) + +#define AD1937_ADC_CTRL_1_WORD_WIDTH_MASK (3 << 0) +#define AD1937_ADC_CTRL_1_WORD_WIDTH_24_BITS (0 << 0) +#define AD1937_ADC_CTRL_1_WORD_WIDTH_20_BITS (1 << 0) +#define AD1937_ADC_CTRL_1_WORD_WIDTH_16_BITS (3 << 0) +#define AD1937_ADC_CTRL_1_ASDATA_DELAY_MASK (7 << 2) +#define AD1937_ADC_CTRL_1_ASDATA_DELAY_1 (0 << 2) +#define AD1937_ADC_CTRL_1_ASDATA_DELAY_0 (1 << 2) +#define AD1937_ADC_CTRL_1_ASDATA_DELAY_8 (2 << 2) +#define AD1937_ADC_CTRL_1_ASDATA_DELAY_12 (3 << 2) +#define AD1937_ADC_CTRL_1_ASDATA_DELAY_16 (4 << 2) +#define AD1937_ADC_CTRL_1_FMT_MASK (3 << 5) +#define AD1937_ADC_CTRL_1_FMT_STEREO (0 << 5) +#define AD1937_ADC_CTRL_1_FMT_TDM_SINGLE_LINE (1 << 5) +#define AD1937_ADC_CTRL_1_FMT_TDM_AUX (2 << 5) +#define AD1937_ADC_CTRL_1_ABCLK_ACTIVE_EDGE_MASK (1 << 7) +#define AD1937_ADC_CTRL_1_ABCLK_ACTIVE_EDGE_MIDCYCLE (0 << 7) +#define AD1937_ADC_CTRL_1_ABCLK_ACTIVE_EDGE_PIPELINE (1 << 7) + +#define AD1937_ADC_CTRL_2_ALRCLK_FMT_MASK (1 << 0) +#define AD1937_ADC_CTRL_2_ALRCLK_FMT_50_50 (0 << 0) +#define AD1937_ADC_CTRL_2_ALRCLK_FMT_PULSE (1 << 0) +#define AD1937_ADC_CTRL_2_ABCLK_POLARITY_MASK (1 << 1) +#define AD1937_ADC_CTRL_2_ABCLK_POLARITY_FALLING_EDGE (0 << 1) +#define AD1937_ADC_CTRL_2_ABCLK_POLARITY_RISING_EDGE (1 << 1) +#define AD1937_ADC_CTRL_2_ALRCLK_POLARITY_MASK (1 << 2) +#define AD1937_ADC_CTRL_2_ALRCLK_POLARITY_LEFT_LOW (0 << 2) +#define AD1937_ADC_CTRL_2_ALRCLK_POLARITY_LEFT_HIGH (1 << 2) +#define AD1937_ADC_CTRL_2_ALRCLK_MASK (1 << 3) +#define AD1937_ADC_CTRL_2_ALRCLK_SLAVE (0 << 3) +#define AD1937_ADC_CTRL_2_ALRCLK_MASTER (1 << 3) +#define AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_MASK (3 << 4) +#define AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_64 (0 << 4) +#define AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_128 (1 << 4) +#define AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_256 (2 << 4) +#define AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_512 (3 << 4) +#define AD1937_ADC_CTRL_2_ABCLK_MASK (1 << 6) +#define AD1937_ADC_CTRL_2_ABCLK_SLAVE (0 << 6) +#define AD1937_ADC_CTRL_2_ABCLK_MASTER (1 << 6) +#define AD1937_ADC_CTRL_2_ABCLK_SOURCE_MASK (1 << 7) +#define AD1937_ADC_CTRL_2_ABCLK_SOURCE_ABCLK_PIN (0 << 7) +#define AD1937_ADC_CTRL_2_ABCLK_SOURCE_INTERNAL (1 << 7) + +#define AUDIO_CODEC_SLAVE_MODE 1 +#define AUDIO_CODEC_MASTER_MODE 0 + +#define AUDIO_DAC_MASTER_MODE 1 +#define AUDIO_DAC_SLAVE_MODE 0 + +#define I2S_DATAWIDTH_04 0 +#define I2S_DATAWIDTH_08 1 +#define I2S_DATAWIDTH_12 2 +#define I2S_DATAWIDTH_16 3 +#define I2S_DATAWIDTH_20 4 +#define I2S_DATAWIDTH_24 5 +#define I2S_DATAWIDTH_28 6 +#define I2S_DATAWIDTH_32 7 + +#define AD1937_MCLK_PLL_INTERNAL_MODE 0 +#define AD1937_MCLK_DIRECT_MODE 1 + +enum AUDIO_INTERFACE_FORMAT{ + AUDIO_INTERFACE_I2S_FORMAT, + AUDIO_INTERFACE_LJM_FORMAT, + AUDIO_INTERFACE_RJM_FORMAT, + AUDIO_INTERFACE_DSP_FORMAT, + AUDIO_INTERFACE_PCM_FORMAT, + AUDIO_INTERFACE_NW_FORMAT, + AUDIO_INTERFACE_TDM_FORMAT, + AUDIO_INTERFACE_TOTAL_FORMAT +}; + +typedef struct AD1937_EXTRA_INFO{ + unsigned int codecId; + unsigned int clkgenId; + unsigned int dacMasterEn; + unsigned int daisyEn; + unsigned int mclk_mode; +} AD1937_EXTRA_INFO; + +struct ahub_unit_fpga { + unsigned int configured; + void __iomem *ape_fpga_misc_base; + void __iomem *ape_fpga_misc_i2s_clk_base[5]; + void __iomem *ape_i2c_base; + void __iomem *pinmux_base; + void __iomem *ape_gpio_base; + void __iomem *rst_clk_base; + void __iomem *i2s5_cya_base; +}; + +void i2c_write(u32 addr, u32 regAddrr, u32 regData, u32 NoBytes); +u32 i2c_read(u32 addr, u32 regAddrr); +void i2s_clk_divider(u32 i2s, u32 Divider); +void i2c_clk_divider(u32 Divider); +void program_max_codec(void); +void program_cdc_pll(u32 PLLno, u32 Freq); +void i2s_clk_setup(u32 i2s, u32 source, u32 divider); +void i2c_pinmux_setup(void); +void i2c_clk_setup(u32 divider); +void i2s_pinmux_setup(u32 i2s, u32 i2s_b); +void program_io_expander(void); +void program_dmic_gpio(void); +void program_dmic_clk(int dmic_clk); +void SetMax9485(int freq); +void ahub_unit_fpga_init_t210(void); +void ahub_unit_fpga_init_t186(void); +void ahub_unit_fpga_deinit(void); +struct ahub_unit_fpga *get_ahub_unit_fpga_private(void); +void program_dspk_clk(int dspk_clk); + +void OnAD1937CaptureAndPlayback(int mode, + int codec_data_format, + int codec_data_width, + int bitSize, + int polarity, + int bitclkInv, + int frameRate, + AD1937_EXTRA_INFO * extra_info); +#endif diff --git a/sound/soc/tegra-alt/include/tegra186_arad_alt.h b/sound/soc/tegra-alt/include/tegra186_arad_alt.h new file mode 100644 index 00000000..75c40e9c --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra186_arad_alt.h @@ -0,0 +1,119 @@ +/* + * tegra186_arad_alt.h - Definitions for Tegra186 ARAD driver + * + * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA186_ARAD_ALT_H__ +#define __TEGRA186_ARAD_ALT_H__ + +#define TEGRA186_ARAD_LANE_STRIDE 0x38 +#define TEGRA186_ARAD_LANE_START 0x40 +#define TEGRA186_ARAD_LANE_MAX 6 +#define TEGRA186_ARAD_LANE_LIMIT (TEGRA186_ARAD_LANE_START + (TEGRA186_ARAD_LANE_MAX * TEGRA186_ARAD_LANE_STRIDE)) + +#define TEGRA186_ARAD_LANE_ENABLE 0x0 +#define TEGRA186_ARAD_LANE_STATUS 0x4 +#define TEGRA186_ARAD_LANE_SOFT_RESET 0x8 +#define TEGRA186_ARAD_LANE_INT_STATUS 0xc +#define TEGRA186_ARAD_LANE_INT_MASK 0x10 +#define TEGRA186_ARAD_LANE_INT_SET 0x14 +#define TEGRA186_ARAD_LANE_INT_CLEAR 0x18 +#define TEGRA186_ARAD_LANE_INT_RATIO_CHANGE_MASK (0x3f<<16) +#define TEGRA186_ARAD_LANE_INT_LOCK_CHANGE_MASK 0x3f +#define TEGRA186_ARAD_LANE_INT_RATIO_CHANGE_SHIFT 16 +#define TEGRA186_ARAD_LANE_INT_LOCK_CHANGE_SHIFT 0 + +#define TEGRA186_ARAD_GLOBAL_SOFT_RESET 0x1c +#define TEGRA186_ARAD_CG 0x20 +#define TEGRA186_ARAD_STATUS 0x24 +#define TEGRA186_ARAD_SEND_RATIO 0x28 +#define TEGRA186_ARAD_CYA_GLOBAL 0x2c +#define TEGRA186_ARAD_TX_CIF_CTRL 0x190 + +#define TEGRA186_ARAD_LANE1_NUMERATOR_MUX_SEL 0x40 +#define TEGRA186_ARAD_LANE1_NUMERATOR_PRESCALAR 0x44 +#define TEGRA186_ARAD_LANE1_DENOMINATOR_MUX_SEL 0x48 +#define TEGRA186_ARAD_LANE1_DENOMINATOR_PRESCALAR 0x4c +#define TEGRA186_ARAD_LANE1_RATIO_INTEGER_PART 0x50 +#define TEGRA186_ARAD_LANE1_RATIO_FRACTIONAL_PART 0x54 +#define TEGRA186_ARAD_LANE1_PERIOD_COUNT 0x58 +#define TEGRA186_ARAD_LANE1_SERVO_LOOP_CONFIG 0x5c +#define TEGRA186_ARAD_LANE1_LOCK_UNLOCK_DETECTOR_CONFIG 0x60 +#define TEGRA186_ARAD_LANE1_ERROR_LOCK_THRESHOLD 0x64 +#define TEGRA186_ARAD_LANE1_ERROR_UNLOCK_THRESHOLD 0x68 +#define TEGRA186_ARAD_LANE1_RATIO_CALCULATOR_CONFIG 0x6c +#define TEGRA186_ARAD_LANE1_CYA 0x70 + +#define TEGRA186_ARAD_LANE2_NUMERATOR_MUX_SEL 0x78 +#define TEGRA186_ARAD_LANE2_DENOMINATOR_MUX_SEL 0x80 +#define TEGRA186_ARAD_LANE3_NUMERATOR_MUX_SEL 0xb0 +#define TEGRA186_ARAD_LANE3_DENOMINATOR_MUX_SEL 0xb8 +#define TEGRA186_ARAD_LANE4_NUMERATOR_MUX_SEL 0xe8 +#define TEGRA186_ARAD_LANE4_DENOMINATOR_MUX_SEL 0xf0 +#define TEGRA186_ARAD_LANE5_NUMERATOR_MUX_SEL 0x120 +#define TEGRA186_ARAD_LANE5_DENOMINATOR_MUX_SEL 0x128 +#define TEGRA186_ARAD_LANE6_NUMERATOR_MUX_SEL 0x158 +#define TEGRA186_ARAD_LANE6_DENOMINATOR_MUX_SEL 0x160 + +#define TEGRA186_ARAD_LANE2_RATIO_INTEGER_PART 0x88 +#define TEGRA186_ARAD_LANE2_RATIO_FRACTIONAL_PART 0x8c +#define TEGRA186_ARAD_LANE3_RATIO_INTEGER_PART 0xc0 +#define TEGRA186_ARAD_LANE3_RATIO_FRACTIONAL_PART 0xc4 +#define TEGRA186_ARAD_LANE4_RATIO_INTEGER_PART 0xf8 +#define TEGRA186_ARAD_LANE4_RATIO_FRACTIONAL_PART 0xfc +#define TEGRA186_ARAD_LANE5_RATIO_INTEGER_PART 0x130 +#define TEGRA186_ARAD_LANE5_RATIO_FRACTIONAL_PART 0x134 +#define TEGRA186_ARAD_LANE6_RATIO_INTEGER_PART 0x168 +#define TEGRA186_ARAD_LANE6_RATIO_FRACTIONAL_PART 0x16c + +#define TEGRA186_ARAD_LANE_ENABLE_SHIFT 0 +#define TEGRA186_ARAD_LANE_ENABLE_MASK (0x3f << TEGRA186_ARAD_LANE_ENABLE_SHIFT) +#define TEGRA186_ARAD_LANE1_ENABLE_SHIFT 0 +#define TEGRA186_ARAD_LANE1_ENABLE_MASK (0x1 << TEGRA186_ARAD_LANE1_ENABLE_SHIFT) +#define TEGRA186_ARAD_LANE2_ENABLE_SHIFT 1 +#define TEGRA186_ARAD_LANE2_ENABLE_MASK (0x1 << TEGRA186_ARAD_LANE2_ENABLE_SHIFT) +#define TEGRA186_ARAD_LANE3_ENABLE_SHIFT 2 +#define TEGRA186_ARAD_LANE3_ENABLE_MASK (0x1 << TEGRA186_ARAD_LANE3_ENABLE_SHIFT) +#define TEGRA186_ARAD_LANE4_ENABLE_SHIFT 3 +#define TEGRA186_ARAD_LANE4_ENABLE_MASK (0x1 << TEGRA186_ARAD_LANE4_ENABLE_SHIFT) +#define TEGRA186_ARAD_LANE5_ENABLE_SHIFT 4 +#define TEGRA186_ARAD_LANE5_ENABLE_MASK (0x1 << TEGRA186_ARAD_LANE5_ENABLE_SHIFT) +#define TEGRA186_ARAD_LANE6_ENABLE_SHIFT 5 +#define TEGRA186_ARAD_LANE6_ENABLE_MASK (0x1 << TEGRA186_ARAD_LANE6_ENABLE_SHIFT) + +#define TEGRA186_ARAD_LANE_LOCK_STATUS_SHIFT 16 +#define TEGRA186_ARAD_LANE_ENABLED_STATUS_SHIFT 0 + +#define TEGRA186_ARAD_LANE_RATIO_INTEGER_PART_MASK 0xFFFFFFFF +#define TEGRA186_ARAD_LANE_RATIO_FRAC_PART_MASK 0xFFFFFFFF + +struct tegra186_arad_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra186_arad { + struct regmap *regmap; + const struct tegra186_arad_soc_data *soc_data; +#if defined CONFIG_SND_SOC_TEGRA186_ARAD_WAR + unsigned int int_status; + spinlock_t status_lock; +#endif +}; +void tegra186_arad_send_ratio(void); + +#endif diff --git a/sound/soc/tegra-alt/include/tegra186_asrc_alt.h b/sound/soc/tegra-alt/include/tegra186_asrc_alt.h new file mode 100644 index 00000000..06808981 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra186_asrc_alt.h @@ -0,0 +1,189 @@ +/* + * tegra186_asrc_alt.h - Definitions for Tegra186 ASRC driver + * + * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA186_ASRC_ALT_H__ +#define __TEGRA186_ASRC_ALT_H__ + +#define TEGRA186_ASRC_STREAM_STRIDE 0x80 +#define TEGRA186_ASRC_STREAM_MAX 6 +#define TEGRA186_ASRC_STREAM_LIMIT 0x2f0 + +/* ASRC stream related offset */ +#define TEGRA186_ASRC_STREAM1_CONFIG 0x0 +#define TEGRA186_ASRC_STREAM1_RATIO_INTEGER_PART 0x4 +#define TEGRA186_ASRC_STREAM1_RATIO_FRAC_PART 0x8 +#define TEGRA186_ASRC_STREAM1_RATIO_LOCK_STATUS 0xc +#define TEGRA186_ASRC_STREAM1_MUTE_UNMUTE_DURATION 0x10 +#define TEGRA186_ASRC_STREAM1_TX_THRESHOLD 0x14 +#define TEGRA186_ASRC_STREAM1_RX_THRESHOLD 0x18 +#define TEGRA186_ASRC_STREAM1_RATIO_COMP 0x1C +#define TEGRA186_ASRC_STREAM1_RX_STATUS 0x20 +#define TEGRA186_ASRC_STREAM1_RX_CIF_CTRL 0x24 +#define TEGRA186_ASRC_STREAM1_TX_STATUS 0x2c +#define TEGRA186_ASRC_STREAM1_TX_CIF_CTRL 0x30 +#define TEGRA186_ASRC_STREAM1_ENABLE 0x38 +#define TEGRA186_ASRC_STREAM1_SOFT_RESET 0x3c +#define TEGRA186_ASRC_STREAM1_STATUS 0x4c +#define TEGRA186_ASRC_STREAM1_BUFFER_STATUS 0x50 +#define TEGRA186_ASRC_STREAM1_CONFIG_ERR_TYPE 0x54 +#define TEGRA186_ASRC_STREAM1_STATEBUF_ADDR 0x5c +#define TEGRA186_ASRC_STREAM1_STATEBUF_CONFIG 0x60 +#define TEGRA186_ASRC_STREAM1_INSAMPLEBUF_ADDR 0x64 +#define TEGRA186_ASRC_STREAM1_INSAMPLEBUF_CONFIG 0x68 +#define TEGRA186_ASRC_STREAM1_OUTSAMPLEBUF_ADDR 0x6c +#define TEGRA186_ASRC_STREAM1_OUTSAMPLEBUF_CONFIG 0x70 + +#define TEGRA186_ASRC_STREAM2_RATIO_INTEGER_PART 0x84 +#define TEGRA186_ASRC_STREAM2_RATIO_FRAC_PART 0x88 +#define TEGRA186_ASRC_STREAM3_RATIO_INTEGER_PART 0x104 +#define TEGRA186_ASRC_STREAM3_RATIO_FRAC_PART 0x108 +#define TEGRA186_ASRC_STREAM4_RATIO_INTEGER_PART 0x184 +#define TEGRA186_ASRC_STREAM4_RATIO_FRAC_PART 0x188 +#define TEGRA186_ASRC_STREAM5_RATIO_INTEGER_PART 0x204 +#define TEGRA186_ASRC_STREAM5_RATIO_FRAC_PART 0x208 +#define TEGRA186_ASRC_STREAM6_RATIO_INTEGER_PART 0x284 +#define TEGRA186_ASRC_STREAM6_RATIO_FRAC_PART 0x288 + +#define TEGRA186_ASRC_STREAM1_ENABLE 0x38 +#define TEGRA186_ASRC_STREAM2_ENABLE 0xb8 +#define TEGRA186_ASRC_STREAM3_ENABLE 0x138 +#define TEGRA186_ASRC_STREAM4_ENABLE 0x1b8 +#define TEGRA186_ASRC_STREAM5_ENABLE 0x238 +#define TEGRA186_ASRC_STREAM6_ENABLE 0x2b8 + +#define TEGRA186_ASRC_STREAM2_CONFIG 0x80 +#define TEGRA186_ASRC_STREAM3_CONFIG 0x100 +#define TEGRA186_ASRC_STREAM4_CONFIG 0x180 +#define TEGRA186_ASRC_STREAM5_CONFIG 0x200 +#define TEGRA186_ASRC_STREAM6_CONFIG 0x280 + +#define TEGRA186_ASRC_STREAM2_TX_THRESHOLD 0x94 +#define TEGRA186_ASRC_STREAM3_TX_THRESHOLD 0x114 +#define TEGRA186_ASRC_STREAM4_TX_THRESHOLD 0x194 +#define TEGRA186_ASRC_STREAM5_TX_THRESHOLD 0x214 +#define TEGRA186_ASRC_STREAM6_TX_THRESHOLD 0x294 +#define TEGRA186_ASRC_STREAM2_RX_THRESHOLD 0x98 +#define TEGRA186_ASRC_STREAM3_RX_THRESHOLD 0x118 +#define TEGRA186_ASRC_STREAM4_RX_THRESHOLD 0x198 +#define TEGRA186_ASRC_STREAM5_RX_THRESHOLD 0x218 +#define TEGRA186_ASRC_STREAM6_RX_THRESHOLD 0x298 + + + + + +/* ASRC UPD related offset */ +#define TEGRA186_ASRC_RATIO_UPD_RX_CIF_CTRL 0x30c +#define TEGRA186_ASRC_RATIO_UPD_RX_STATUS 0x310 + +/* ASRC Global registers offset */ +#define TEGRA186_ASRC_GLOBAL_ENB 0x2f4 +#define TEGRA186_ASRC_GLOBAL_SOFT_RESET 0x2f8 +#define TEGRA186_ASRC_GLOBAL_CG 0x2fc +#define TEGRA186_ASRC_GLOBAL_CONFIG 0x300 +#define TEGRA186_ASRC_GLOBAL_SCRATCH_ADDR 0x304 +#define TEGRA186_ASRC_GLOBAL_SCRATCH_CONFIG 0x308 +#define TEGRA186_ASRC_GLOBAL_STATUS 0x314 +#define TEGRA186_ASRC_GLOBAL_STREAM_ENABLE_STATUS 0x318 +#define TEGRA186_ASRC_GLOBAL_INT_STATUS 0x324 +#define TEGRA186_ASRC_GLOBAL_INT_MASK 0x328 +#define TEGRA186_ASRC_GLOBAL_INT_SET 0x32c +#define TEGRA186_ASRC_GLOBAL_INT_CLEAR 0x330 +#define TEGRA186_ASRC_GLOBAL_TRANSFER_ERROR_LOG 0x334 +#define TEGRA186_ASRC_GLOBAL_APR_CTRL 0x1000 +#define TEGRA186_ASRC_GLOBAL_APR_CTRL_ACCESS_CTRL 0x1004 +#define TEGRA186_ASRC_GLOBAL_DISARM_APR 0x1008 +#define TEGRA186_ASRC_GLOBAL_DISARM_APR_ACCESS_CTRL 0x100c +#define TEGRA186_ASRC_GLOBAL_RATIO_WR_ACCESS 0x1010 +#define TEGRA186_ASRC_GLOBAL_RATIO_WR_ACCESS_CTRL 0x1014 +#define TEGRA186_ASRC_CYA 0x1018 + +#define TEGRA186_ASRC_STREAM_DEFAULT_HW_COMP_BIAS_VALUE 0xaaaa +#define TEGRA186_ASRC_STREAM_DEFAULT_INPUT_HW_COMP_THRESH_CONFIG 0x00201002 +#define TEGRA186_ASRC_STREAM_DEFAULT_OUTPUT_HW_COMP_THRESH_CONFIG 0x00201002 + +#define TEGRA186_ASRC_STREAM_ENABLE_HW_RATIO_COMP_SHIFT 31 +#define TEGRA186_ASRC_STREAM_ENABLE_HW_RATIO_COMP_MASK (1 << TEGRA186_ASRC_STREAM_ENABLE_HW_RATIO_COMP_SHIFT) +#define TEGRA186_ASRC_STREAM_ENABLE_HW_RATIO_COMP_ENABLE (1 << TEGRA186_ASRC_STREAM_ENABLE_HW_RATIO_COMP_SHIFT) +#define TEGRA186_ASRC_STREAM_ENABLE_HW_RATIO_COMP_DISABLE (0 << TEGRA186_ASRC_STREAM_ENABLE_HW_RATIO_COMP_SHIFT) + +#define TEGRA186_ASRC_STREAM_RATIO_TYPE_SHIFT 0 +#define TEGRA186_ASRC_STREAM_RATIO_TYPE_MASK (1 << TEGRA186_ASRC_STREAM_RATIO_TYPE_SHIFT) + +#define TEGRA186_ASRC_STREAM_EN_SHIFT 0 +#define TEGRA186_ASRC_STREAM_EN (1 << TEGRA186_ASRC_STREAM_EN_SHIFT) +#define TEGRA186_ASRC_GLOBAL_EN_SHIFT 0 +#define TEGRA186_ASRC_GLOBAL_EN (1 << TEGRA186_ASRC_GLOBAL_EN_SHIFT) + +#define TEGRA186_ASRC_STREAM_STATEBUF_CONFIG_SIZE_SHIFT 0 +#define TEGRA186_ASRC_STREAM_STATEBUF_CONFIG_SIZE_MASK (0xFFFF << TEGRA186_ASRC_STREAM_STATEBUF_CONFIG_SIZE_SHIFT) +#define TEGRA186_ASRC_STREAM_INSAMPLEBUF_CONFIG_SIZE_SHIFT 0 +#define TEGRA186_ASRC_STREAM_INSAMPLEBUF_CONFIG_SIZE_MASK (0xFFFF << TEGRA186_ASRC_STREAM_INSAMPLEBUF_CONFIG_SIZE_SHIFT) +#define TEGRA186_ASRC_STREAM_OUTSAMPLEBUF_CONFIG_SIZE_SHIFT 0 +#define TEGRA186_ASRC_STREAM_OUTSAMPLEBUF_CONFIG_SIZE_MASK (0xFFFF << TEGRA186_ASRC_STREAM_OUTSAMPLEBUF_CONFIG_SIZE_SHIFT) + +#define TEGRA186_ASRC_GLOBAL_CONFIG_FRAC_28BIT_PRECISION 0 +#define TEGRA186_ASRC_GLOBAL_CONFIG_FRAC_32BIT_PRECISION 1 + +#define TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_MAX_CHANNELS_SHIFT 24 +#define TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_MAX_CHANNELS_MASK (0xFF << TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_MAX_CHANNELS_SHIFT) +#define TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_BLOCK_SIZE_SHIFT 16 +#define TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_BLOCK_SIZE_MASK (0xFF << TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_BLOCK_SIZE_SHIFT) +#define TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_SIZE_SHIFT 0 +#define TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_SIZE_MASK (0xFFFF << TEGRA186_ASRC_STREAM_GLOBAL_SCRATCH_CONFIG_SIZE_SHIFT) + +#define TEGRA186_ASRC_STREAM_RATIO_INTEGER_PART_MASK 0x1F +#define TEGRA186_ASRC_STREAM_RATIO_FRAC_PART_MASK 0xFFFFFFFF + +#define TEGRA186_ASRC_STREAM_RATIO_FRAC_PART_MAX 0x7FFFFFFF +enum asrc_task_event { + STREAM_DISABLE, + STREAM_ENABLE, +}; + +struct tegra210_xbar_cif_conf; + +struct tegra186_asrc_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra186_asrc_lane { + unsigned int int_part; + unsigned int frac_part; + int ratio_source; + unsigned int hwcomp_disable; + unsigned int input_thresh; + unsigned int output_thresh; +}; + +struct tegra186_asrc { + struct regmap *regmap; + struct tegra186_asrc_lane lane[6]; + const struct tegra186_asrc_soc_data *soc_data; + struct tasklet_struct tasklet; + struct list_head task_desc; + int active_dai_count; + bool is_shutdown; +}; +int tegra186_asrc_set_source(int id, int source); +int tegra186_asrc_event(int id, enum asrc_task_event event, int status); +int tegra186_asrc_update_ratio(int id, int inte, int frac); +void tegra186_asrc_handle_arad_unlock(int stream_id, int action); +#endif diff --git a/sound/soc/tegra-alt/include/tegra186_dspk_alt.h b/sound/soc/tegra-alt/include/tegra186_dspk_alt.h new file mode 100644 index 00000000..f150c0ea --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra186_dspk_alt.h @@ -0,0 +1,193 @@ +/* + * tegra186_dspk_alt.h - Definitions for Tegra186 DSPK driver + * + * Copyright (c) 2015-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA186_DSPK_ALT_H__ +#define __TEGRA186_DSPK_ALT_H__ + +/* Register offsets from DSPK BASE */ +#define TEGRA186_DSPK_AXBAR_RX_STATUS 0x0c +#define TEGRA186_DSPK_AXBAR_RX_INT_STATUS 0x10 +#define TEGRA186_DSPK_AXBAR_RX_INT_MASK 0x14 +#define TEGRA186_DSPK_AXBAR_RX_INT_SET 0x18 +#define TEGRA186_DSPK_AXBAR_RX_INT_CLEAR 0x1c +#define TEGRA186_DSPK_AXBAR_RX_CIF_CTRL 0x20 +#define TEGRA186_DSPK_AXBAR_RX_CYA 0x24 +#define TEGRA186_DSPK_AXBAR_RX_CIF_FIFO_STATUS 0x28 + +#define TEGRA186_DSPK_ENABLE 0x40 +#define TEGRA186_DSPK_SOFT_RESET 0x44 +#define TEGRA186_DSPK_CG 0x48 +#define TEGRA186_DSPK_STATUS 0x4c +#define TEGRA186_DSPK_INT_STATUS 0x50 +#define TEGRA186_DSPK_CORE_CTRL 0x60 +#define TEGRA186_DSPK_CODEC_CTRL 0x64 +#define TEGRA186_DSPK_CODEC_DATA 0x68 +#define TEGRA186_DSPK_CODEC_ENABLE 0x6c +#define TEGRA186_DSPK_CLK_TRIM 0x70 +#define TEGRA186_DSPK_SDM_COEF_A_2 0x74 +#define TEGRA186_DSPK_SDM_COEF_A_3 0x78 +#define TEGRA186_DSPK_SDM_COEF_A_4 0x7c +#define TEGRA186_DSPK_SDM_COEF_A_5 0x80 +#define TEGRA186_DSPK_SDM_COEF_C_1 0x84 +#define TEGRA186_DSPK_SDM_COEF_C_2 0x88 +#define TEGRA186_DSPK_SDM_COEF_C_3 0x8c +#define TEGRA186_DSPK_SDM_COEF_C_4 0x90 +#define TEGRA186_DSPK_SDM_COEF_G_1 0x94 +#define TEGRA186_DSPK_SDM_COEF_G_2 0x98 +#define TEGRA186_DSPK_DEBUG_STATUS 0x9c +#define TEGRA186_DSPK_DEBUG_CIF_CNTR 0xa0 +#define TEGRA186_DSPK_DEBUG_STAGE1_CNTR 0xa4 +#define TEGRA186_DSPK_DEBUG_STAGE2_CNTR 0xa8 +#define TEGRA186_DSPK_DEBUG_STAGE3_CNTR 0xac +#define TEGRA186_DSPK_DEBUG_STAGE4_CNTR 0xb0 + +/* Constants for DSPK */ +#define TEGRA186_DSPK_OSR_32 0 +#define TEGRA186_DSPK_OSR_64 1 +#define TEGRA186_DSPK_OSR_128 2 +#define TEGRA186_DSPK_OSR_256 3 + +/* DSPK ENABLE Register field */ +#define TEGRA186_DSPK_ENABLE_EN BIT(0) + +/* DSPK SOFT RESET field */ +#define TEGRA186_DSPK_SOFT_RESET_EN BIT(0) + +/* DSPK CG field */ +#define TEGRA186_DSPK_CG_SLCG_EN BIT(0) + +/* DSPK STATUS fields */ +#define TEGRA186_DSPK_CODEC_CONFIG_DONE_SHIFT 14 +#define TEGRA186_DSPK_CODEC_CONFIG_DONE_MASK (0x1 << TEGRA186_DSPK_CODEC_CONFIG_DONE_SHIFT) + +#define TEGRA186_DSPK_SLCG_CLKEN_SHIFT 12 +#define TEGRA186_DSPK_SLCG_CLKEN_MASK (0x1 << TEGRA186_DSPK_SLCG_CLKEN_SHIFT) + +#define TEGRA186_DSPK_RX_CIF_FULL_SHIFT 10 +#define TEGRA186_DSPK_RX_CIF_FULL_MASK (0x1 << TEGRA186_DSPK_RX_CIF_FULL_SHIFT) + +#define TEGRA186_DSPK_RX_CIF_EMPTY_SHIFT 9 +#define TEGRA186_DSPK_RX_CIF_EMPTY_MASK (0x1 << TEGRA186_DSPK_RX_CIF_EMPTY_SHIFT) + +#define TEGRA186_DSPK_RX_ENABLED_SHIFT 8 +#define TEGRA186_DSPK_RX_ENABLED_MASK (0x1 << TEGRA186_DSPK_RX_ENABLED_SHIFT) + +/* DSPK INT STATUS fields */ +#define TEGRA186_DSPK_INT_CODEC_CONFIG_DONE_SHIFT 12 +#define TEGRA186_DSPK_INT_CODEC_CONFIG_DONE_MASK (0x1 << TEGRA186_DSPK_INT_CODEC_CONFIG_DONE_SHIFT) + +#define TEGRA186_DSPK_RX_CIF_FIFO_UNDERRUN_SHIFT 9 +#define TEGRA186_DSPK_RX_CIF_FIFO_UNDERRUN_MASK (0x1 << TEGRA186_DSPK_RX_CIF_FIFO_UNDERRUN_SHIFT) + +#define TEGRA186_DSPK_RX_DONE_SHIFT 8 +#define TEGRA186_DSPK_RX_DONE_MASK (0x1 << TEGRA186_DSPK_RX_DONE_SHIFT) + +/* DSPK CORE CONTROL fields */ +#define TEGRA186_DSPK_GAIN1_SHIFT 28 +#define TEGRA186_DSPK_GAIN1_MASK (0x7 << TEGRA186_DSPK_GAIN1_SHIFT) + +#define TEGRA186_DSPK_GAIN2_SHIFT 24 +#define TEGRA186_DSPK_GAIN2_MASK (0x7 << TEGRA186_DSPK_GAIN2_SHIFT) + +#define TEGRA186_DSPK_GAIN3_SHIFT 20 +#define TEGRA186_DSPK_GAIN3_MASK (0x7 << TEGRA186_DSPK_GAIN3_SHIFT) + +#define TEGRA186_DSPK_FILTER_MODE_SHIFT 16 +#define TEGRA186_DSPK_FILTER_MODE_MASK (0x1 << TEGRA186_DSPK_FILTER_MODE_SHIFT) + +#define TEGRA186_DSPK_CHANNEL_SELECT_SHIFT 8 +#define TEGRA186_DSPK_CHANNEL_SELECT_MASK (0x3 << TEGRA186_DSPK_CHANNEL_SELECT_SHIFT) + +#define TEGRA186_DSPK_OSR_SHIFT 4 +#define TEGRA186_DSPK_OSR_MASK (0x3 << TEGRA186_DSPK_OSR_SHIFT) + +#define TEGRA186_DSPK_LRSEL_POLARITY_SHIFT 0 +#define TEGRA186_DSPK_LRSEL_POLARITY_MASK (0x1 << TEGRA186_DSPK_LRSEL_POLARITY_SHIFT) + +/* DSPK CODEC CONTROL fileds */ +#define TEGRA186_DSPK_CODEC_CHANNEL_SELECT_SHIFT 24 +#define TEGRA186_DSPK_CODEC_CHANNEL_SELECT_MASK (0x3 << TEGRA186_DSPK_CODEC_CHANNEL_SELECT_SHIFT) + +#define TEGRA186_DSPK_CODEC_BIT_ORDER_SHIFT 16 +#define TEGRA186_DSPK_CODEC_BIT_MASK (0x1 << TEGRA186_DSPK_CODEC_BIT_ORDER_SHIFT) + +#define TEGRA186_DSPK_CODEC_CONFIG_MODE_SHIFT 12 +#define TEGRA186_DSPK_CODEC_CONFIG_MODE_MASK (0x1 << TEGRA186_DSPK_CODEC_CONFIG_MODE_SHIFT) + +#define TEGRA186_DSPK_CODEC_CONFIG_REP_NUM_SHIFT 0 +#define TEGRA186_DSPK_CODEC_CONFIG_REP_NUM_MASK (0xff << TEGRA186_DSPK_CODEC_CONFIG_REP_NUM_SHIFT) + +/* DSPK CODEC ENABLE fields */ +#define TEGRA186_DSPK_CODEC_ENABLE_SHIFT 0 +#define TEGRA186_DSPK_CODEC_ENABLE_MASK (0x1 << TEGRA186_DSPK_CODEC_ENABLE_SHIFT) + +/* DSPL CLK TRIM field */ +#define TEGRA186_DSPK_CLK_TRIM_SHIFT 0 +#define TEGRA186_DSPK_CLK_TRIM_MASK (0x1f << TEGRA186_DSPK_CLK_TRIM_SHIFT) + +/* DSPK DEBUG Register fields*/ +#define TEGRA186_DSPK_DEBUG_STATUS_SHIFT 0 +#define TEGRA186_DSPK_DEBUG_STATUS_MASK (0xff << TEGRA186_DSPK_DEBUG_STATUS_SHIFT) + +#define TEGRA186_DSPK_DEBUG_CIF_CH0_SHIFT 16 +#define TEGRA186_DSPK_DEBUG_CIF_CH0_MASK (0xffff << TEGRA186_DSPK_DEBUG_CIF_CH0_SHIFT) +#define TEGRA186_DSPK_DEBUG_CIF_CH1_SHIFT 0 +#define TEGRA186_DSPK_DEBUG_CIF_CH1_MASK (0xffff << TEGRA186_DSPK_DEBUG_CIF_CH1_SHIFT) + +#define TEGRA186_DSPK_DEBUG_STAGE1_CH0_SHIFT 16 +#define TEGRA186_DSPK_DEBUG_STAGE1_CH0_MASK (0xffff << TEGRA186_DSPK_DEBUG_STAGE1_CH0_SHIFT) +#define TEGRA186_DSPK_DEBUG_STAGE1_CH1_SHIFT 0 +#define TEGRA186_DSPK_DEBUG_STAGE1_CH1_MASK (0xffff << TEGRA186_DSPK_DEBUG_STAGE1_CH1_SHIFT) + +#define TEGRA186_DSPK_DEBUG_STAGE2_CH0_SHIFT 16 +#define TEGRA186_DSPK_DEBUG_STAGE2_CH0_MASK (0xffff << TEGRA186_DSPK_DEBUG_STAGE2_CH0_SHIFT) +#define TEGRA186_DSPK_DEBUG_STAGE2_CH1_SHIFT 0 +#define TEGRA186_DSPK_DEBUG_STAGE2_CH1_MASK (0xffff << TEGRA186_DSPK_DEBUG_STAGE2_CH1_SHIFT) + +#define TEGRA186_DSPK_DEBUG_STAGE3_CH0_SHIFT 16 +#define TEGRA186_DSPK_DEBUG_STAGE3_CH0_MASK (0xffff << TEGRA186_DSPK_DEBUG_STAGE3_CH0_SHIFT) +#define TEGRA186_DSPK_DEBUG_STAGE3_CH1_SHIFT 0 +#define TEGRA186_DSPK_DEBUG_STAGE3_CH1_MASK (0xffff << TEGRA186_DSPK_DEBUG_STAGE3_CH1_SHIFT) + +#define TEGRA186_DSPK_DEBUG_STAGE4_CH0_SHIFT 16 +#define TEGRA186_DSPK_DEBUG_STAGE4_CH0_MASK (0xffff << TEGRA186_DSPK_DEBUG_STAGE4_CH0_SHIFT) +#define TEGRA186_DSPK_DEBUG_STAGE4_CH1_SHIFT 0 +#define TEGRA186_DSPK_DEBUG_STAGE4_CH1_MASK (0xffff << TEGRA186_DSPK_DEBUG_STAGE4_CH1_SHIFT) + +#define TEGRA186_DSPK_RX_FIFO_DEPTH 4 + +struct tegra186_dspk_soc_data { + void (*set_audio_cif) (struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra186_dspk { + struct clk *clk_dspk; + struct clk *clk_pll_a_out0; + struct regmap *regmap; + const struct tegra186_dspk_soc_data *soc_data; + int is_pinctrl; + struct pinctrl *pinctrl; + struct pinctrl_state *pin_active_state; + struct pinctrl_state *pin_idle_state; + unsigned int rx_fifo_th; /* threshold in terms of frames */ + bool is_shutdown; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_admaif_alt.h b/sound/soc/tegra-alt/include/tegra210_admaif_alt.h new file mode 100644 index 00000000..f989537e --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_admaif_alt.h @@ -0,0 +1,187 @@ +/* + * tegra210_admaif_alt.h - Tegra ADMAIF registers + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA_ADMAIF_ALT_H__ +#define __TEGRA_ADMAIF_ALT_H__ + +#define TEGRA_ADMAIF_CHANNEL_REG_STRIDE 0x40 + +#define TEGRA210_ADMAIF_LAST_REG 0x75f +#define TEGRA186_ADMAIF_LAST_REG 0xd5f + +#define TEGRA210_ADMAIF_CHANNEL_COUNT 10 +#define TEGRA186_ADMAIF_CHANNEL_COUNT 20 + +#define TEGRA210_ADMAIF_XBAR_TX_ENABLE 0x300 +#define TEGRA210_ADMAIF_GLOBAL_ENABLE 0x700 + +#define TEGRA186_ADMAIF_XBAR_TX_ENABLE 0x500 +#define TEGRA186_ADMAIF_GLOBAL_ENABLE 0xd00 + +#define TEGRA_ADMAIF_XBAR_RX_ENABLE 0x0 +#define TEGRA_ADMAIF_XBAR_RX_SOFT_RESET 0x4 +#define TEGRA_ADMAIF_XBAR_RX_STATUS 0xc +#define TEGRA_ADMAIF_XBAR_RX_INT_STATUS 0x10 +#define TEGRA_ADMAIF_XBAR_RX_INT_MASK 0x14 +#define TEGRA_ADMAIF_XBAR_RX_INT_SET 0x18 +#define TEGRA_ADMAIF_XBAR_RX_INT_CLEAR 0x1c +#define TEGRA_ADMAIF_CHAN_ACIF_RX_CTRL 0x20 +#define TEGRA_ADMAIF_XBAR_RX_FIFO_CTRL 0x28 +#define TEGRA_ADMAIF_XBAR_RX_FIFO_READ 0x2c +#define TEGRA_ADMAIF_GLOBAL_CG_0 (0x8) + +#define TEGRA_ADMAIF_XBAR_TX_SOFT_RESET (0x4) +#define TEGRA_ADMAIF_XBAR_TX_STATUS (0xc) +#define TEGRA_ADMAIF_XBAR_TX_INT_STATUS (0x10) +#define TEGRA_ADMAIF_XBAR_TX_INT_MASK (0x14) +#define TEGRA_ADMAIF_XBAR_TX_INT_SET (0x18) +#define TEGRA_ADMAIF_XBAR_TX_INT_CLEAR (0x1c) +#define TEGRA_ADMAIF_CHAN_ACIF_TX_CTRL (0x20) +#define TEGRA_ADMAIF_XBAR_TX_FIFO_CTRL (0x28) +#define TEGRA_ADMAIF_XBAR_TX_FIFO_WRITE (0x2c) + +#define TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN_SHIFT 31 +#define TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN_MASK \ + (1 << TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN_SHIFT) +#define TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN \ + (1 << TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN_SHIFT) +#define TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN_SHIFT 30 +#define TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN_MASK \ + (1 << TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN_SHIFT) +#define TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN \ + (1 << TEGRA_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN_SHIFT) + +#define TEGRA_ADMAIF_XBAR_TX_ENABLE_SHIFT 0 +#define TEGRA_ADMAIF_XBAR_TX_EN \ + (1 << TEGRA_ADMAIF_XBAR_TX_ENABLE_SHIFT) +#define TEGRA_ADMAIF_XBAR_TX_ENABLE_MASK \ + (1 << TEGRA_ADMAIF_XBAR_TX_ENABLE_SHIFT) + +#define TEGRA_ADMAIF_XBAR_RX_ENABLE_SHIFT 0 +#define TEGRA_ADMAIF_XBAR_RX_EN \ + (1 << TEGRA_ADMAIF_XBAR_RX_ENABLE_SHIFT) +#define TEGRA_ADMAIF_XBAR_RX_ENABLE_MASK \ + (1 << TEGRA_ADMAIF_XBAR_RX_ENABLE_SHIFT) + +#define TEGRA210_ADMAIF_RX1_FIFO_CTRL_REG_DEFAULT 0x00000300 +#define TEGRA210_ADMAIF_RX2_FIFO_CTRL_REG_DEFAULT 0x00000304 +#define TEGRA210_ADMAIF_RX3_FIFO_CTRL_REG_DEFAULT 0x00000208 +#define TEGRA210_ADMAIF_RX4_FIFO_CTRL_REG_DEFAULT 0x0000020b +#define TEGRA210_ADMAIF_RX5_FIFO_CTRL_REG_DEFAULT 0x0000020e +#define TEGRA210_ADMAIF_RX6_FIFO_CTRL_REG_DEFAULT 0x00000211 +#define TEGRA210_ADMAIF_RX7_FIFO_CTRL_REG_DEFAULT 0x00000214 +#define TEGRA210_ADMAIF_RX8_FIFO_CTRL_REG_DEFAULT 0x00000217 +#define TEGRA210_ADMAIF_RX9_FIFO_CTRL_REG_DEFAULT 0x0000021a +#define TEGRA210_ADMAIF_RX10_FIFO_CTRL_REG_DEFAULT 0x0000021d + +#define TEGRA210_ADMAIF_TX1_FIFO_CTRL_REG_DEFAULT 0x02000300 +#define TEGRA210_ADMAIF_TX2_FIFO_CTRL_REG_DEFAULT 0x02000304 +#define TEGRA210_ADMAIF_TX3_FIFO_CTRL_REG_DEFAULT 0x01800208 +#define TEGRA210_ADMAIF_TX4_FIFO_CTRL_REG_DEFAULT 0x0180020b +#define TEGRA210_ADMAIF_TX5_FIFO_CTRL_REG_DEFAULT 0x0180020e +#define TEGRA210_ADMAIF_TX6_FIFO_CTRL_REG_DEFAULT 0x01800211 +#define TEGRA210_ADMAIF_TX7_FIFO_CTRL_REG_DEFAULT 0x01800214 +#define TEGRA210_ADMAIF_TX8_FIFO_CTRL_REG_DEFAULT 0x01800217 +#define TEGRA210_ADMAIF_TX9_FIFO_CTRL_REG_DEFAULT 0x0180021a +#define TEGRA210_ADMAIF_TX10_FIFO_CTRL_REG_DEFAULT 0x0180021d + +#define TEGRA186_ADMAIF_RX1_FIFO_CTRL_REG_DEFAULT 0x00000300 +#define TEGRA186_ADMAIF_RX2_FIFO_CTRL_REG_DEFAULT 0x00000304 +#define TEGRA186_ADMAIF_RX3_FIFO_CTRL_REG_DEFAULT 0x00000308 +#define TEGRA186_ADMAIF_RX4_FIFO_CTRL_REG_DEFAULT 0x0000030c +#define TEGRA186_ADMAIF_RX5_FIFO_CTRL_REG_DEFAULT 0x00000210 +#define TEGRA186_ADMAIF_RX6_FIFO_CTRL_REG_DEFAULT 0x00000213 +#define TEGRA186_ADMAIF_RX7_FIFO_CTRL_REG_DEFAULT 0x00000216 +#define TEGRA186_ADMAIF_RX8_FIFO_CTRL_REG_DEFAULT 0x00000219 +#define TEGRA186_ADMAIF_RX9_FIFO_CTRL_REG_DEFAULT 0x0000021c +#define TEGRA186_ADMAIF_RX10_FIFO_CTRL_REG_DEFAULT 0x0000021f +#define TEGRA186_ADMAIF_RX11_FIFO_CTRL_REG_DEFAULT 0x00000222 +#define TEGRA186_ADMAIF_RX12_FIFO_CTRL_REG_DEFAULT 0x00000225 +#define TEGRA186_ADMAIF_RX13_FIFO_CTRL_REG_DEFAULT 0x00000228 +#define TEGRA186_ADMAIF_RX14_FIFO_CTRL_REG_DEFAULT 0x0000022b +#define TEGRA186_ADMAIF_RX15_FIFO_CTRL_REG_DEFAULT 0x0000022e +#define TEGRA186_ADMAIF_RX16_FIFO_CTRL_REG_DEFAULT 0x00000231 +#define TEGRA186_ADMAIF_RX17_FIFO_CTRL_REG_DEFAULT 0x00000234 +#define TEGRA186_ADMAIF_RX18_FIFO_CTRL_REG_DEFAULT 0x00000237 +#define TEGRA186_ADMAIF_RX19_FIFO_CTRL_REG_DEFAULT 0x0000023a +#define TEGRA186_ADMAIF_RX20_FIFO_CTRL_REG_DEFAULT 0x0000023d + +#define TEGRA186_ADMAIF_TX1_FIFO_CTRL_REG_DEFAULT 0x02000300 +#define TEGRA186_ADMAIF_TX2_FIFO_CTRL_REG_DEFAULT 0x02000304 +#define TEGRA186_ADMAIF_TX3_FIFO_CTRL_REG_DEFAULT 0x02000308 +#define TEGRA186_ADMAIF_TX4_FIFO_CTRL_REG_DEFAULT 0x0200030c +#define TEGRA186_ADMAIF_TX5_FIFO_CTRL_REG_DEFAULT 0x01800210 +#define TEGRA186_ADMAIF_TX6_FIFO_CTRL_REG_DEFAULT 0x01800213 +#define TEGRA186_ADMAIF_TX7_FIFO_CTRL_REG_DEFAULT 0x01800216 +#define TEGRA186_ADMAIF_TX8_FIFO_CTRL_REG_DEFAULT 0x01800219 +#define TEGRA186_ADMAIF_TX9_FIFO_CTRL_REG_DEFAULT 0x0180021c +#define TEGRA186_ADMAIF_TX10_FIFO_CTRL_REG_DEFAULT 0x0180021f +#define TEGRA186_ADMAIF_TX11_FIFO_CTRL_REG_DEFAULT 0x01800222 +#define TEGRA186_ADMAIF_TX12_FIFO_CTRL_REG_DEFAULT 0x01800225 +#define TEGRA186_ADMAIF_TX13_FIFO_CTRL_REG_DEFAULT 0x01800228 +#define TEGRA186_ADMAIF_TX14_FIFO_CTRL_REG_DEFAULT 0x0180022b +#define TEGRA186_ADMAIF_TX15_FIFO_CTRL_REG_DEFAULT 0x0180022e +#define TEGRA186_ADMAIF_TX16_FIFO_CTRL_REG_DEFAULT 0x01800231 +#define TEGRA186_ADMAIF_TX17_FIFO_CTRL_REG_DEFAULT 0x01800234 +#define TEGRA186_ADMAIF_TX18_FIFO_CTRL_REG_DEFAULT 0x01800237 +#define TEGRA186_ADMAIF_TX19_FIFO_CTRL_REG_DEFAULT 0x0180023a +#define TEGRA186_ADMAIF_TX20_FIFO_CTRL_REG_DEFAULT 0x0180023d + +enum { + DATA_8BIT, + DATA_16BIT, + DATA_32BIT +}; + + +struct admaif_reg_offsets { + unsigned int global_enable; + unsigned int tx_enable; +}; + +struct tegra_admaif_soc_data { + unsigned int num_ch; + struct admaif_reg_offsets reg_offsets; + struct snd_soc_dai_driver *codec_dais; + struct snd_soc_codec_driver *admaif_codec; + const struct regmap_config *regmap_conf; + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *cif_conf); + bool is_isomgr_client; +}; + +struct tegra_admaif { + /* regmap for admaif */ + struct regmap *regmap; + struct device *dev; + int refcnt; + struct tegra_alt_pcm_dma_params *capture_dma_data; + struct tegra_alt_pcm_dma_params *playback_dma_data; + const struct tegra_admaif_soc_data *soc_data; + int *override_channels; + int *tx_mono_to_stereo; + int *rx_stereo_to_mono; + bool is_shutdown; + int reg_dump_flag; + void __iomem *base_addr; +}; + +extern void tegra_adma_dump_ch_reg(void); + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_adsp_alt.h b/sound/soc/tegra-alt/include/tegra210_adsp_alt.h new file mode 100644 index 00000000..f5d810c8 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_adsp_alt.h @@ -0,0 +1,234 @@ +/* + * tegra210_adsp_alt.h - Tegra210 ADSP header + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_ADSP_ALT_H__ +#define __TEGRA210_ADSP_ALT_H__ + +/* This enum is linked with tegra210_adsp_mux_texts array. Any thing + changed in enum define should be also reflected in text array */ +enum tegra210_adsp_virt_regs { + TEGRA210_ADSP_NONE, + + /* End-point virtual regs */ + TEGRA210_ADSP_FRONT_END1, + TEGRA210_ADSP_FRONT_END2, + TEGRA210_ADSP_FRONT_END3, + TEGRA210_ADSP_FRONT_END4, + TEGRA210_ADSP_FRONT_END5, + TEGRA210_ADSP_FRONT_END6, + TEGRA210_ADSP_FRONT_END7, + TEGRA210_ADSP_FRONT_END8, + TEGRA210_ADSP_FRONT_END9, + TEGRA210_ADSP_FRONT_END10, + TEGRA210_ADSP_FRONT_END11, + TEGRA210_ADSP_FRONT_END12, + TEGRA210_ADSP_FRONT_END13, + TEGRA210_ADSP_FRONT_END14, + TEGRA210_ADSP_FRONT_END15, + + TEGRA210_ADSP_EAVB, + + TEGRA210_ADSP_ADMAIF1, + TEGRA210_ADSP_ADMAIF2, + TEGRA210_ADSP_ADMAIF3, + TEGRA210_ADSP_ADMAIF4, + TEGRA210_ADSP_ADMAIF5, + TEGRA210_ADSP_ADMAIF6, + TEGRA210_ADSP_ADMAIF7, + TEGRA210_ADSP_ADMAIF8, + TEGRA210_ADSP_ADMAIF9, + TEGRA210_ADSP_ADMAIF10, + TEGRA210_ADSP_ADMAIF11, + TEGRA210_ADSP_ADMAIF12, + TEGRA210_ADSP_ADMAIF13, + TEGRA210_ADSP_ADMAIF14, + TEGRA210_ADSP_ADMAIF15, + TEGRA210_ADSP_ADMAIF16, + TEGRA210_ADSP_ADMAIF17, + TEGRA210_ADSP_ADMAIF18, + TEGRA210_ADSP_ADMAIF19, + TEGRA210_ADSP_ADMAIF20, + + TEGRA210_ADSP_NULL_SINK1, + TEGRA210_ADSP_NULL_SINK2, + TEGRA210_ADSP_NULL_SINK3, + TEGRA210_ADSP_NULL_SINK4, + TEGRA210_ADSP_NULL_SINK5, + TEGRA210_ADSP_NULL_SINK6, + TEGRA210_ADSP_NULL_SINK7, + TEGRA210_ADSP_NULL_SINK8, + TEGRA210_ADSP_NULL_SINK9, + TEGRA210_ADSP_NULL_SINK10, + TEGRA210_ADSP_NULL_SINK11, + TEGRA210_ADSP_NULL_SINK12, + TEGRA210_ADSP_NULL_SINK13, + TEGRA210_ADSP_NULL_SINK14, + TEGRA210_ADSP_NULL_SINK15, + + /* Virtual regs for apps */ + TEGRA210_ADSP_APM_IN1, + TEGRA210_ADSP_APM_IN2, + TEGRA210_ADSP_APM_IN3, + TEGRA210_ADSP_APM_IN4, + TEGRA210_ADSP_APM_IN5, + TEGRA210_ADSP_APM_IN6, + TEGRA210_ADSP_APM_IN7, + TEGRA210_ADSP_APM_IN8, + TEGRA210_ADSP_APM_IN9, + TEGRA210_ADSP_APM_IN10, + TEGRA210_ADSP_APM_IN11, + TEGRA210_ADSP_APM_IN12, + TEGRA210_ADSP_APM_IN13, + TEGRA210_ADSP_APM_IN14, + TEGRA210_ADSP_APM_IN15, + + TEGRA210_ADSP_APM_OUT1, + TEGRA210_ADSP_APM_OUT2, + TEGRA210_ADSP_APM_OUT3, + TEGRA210_ADSP_APM_OUT4, + TEGRA210_ADSP_APM_OUT5, + TEGRA210_ADSP_APM_OUT6, + TEGRA210_ADSP_APM_OUT7, + TEGRA210_ADSP_APM_OUT8, + TEGRA210_ADSP_APM_OUT9, + TEGRA210_ADSP_APM_OUT10, + TEGRA210_ADSP_APM_OUT11, + TEGRA210_ADSP_APM_OUT12, + TEGRA210_ADSP_APM_OUT13, + TEGRA210_ADSP_APM_OUT14, + TEGRA210_ADSP_APM_OUT15, + + TEGRA210_ADSP_PLUGIN_ADMA1, + TEGRA210_ADSP_PLUGIN_ADMA2, + TEGRA210_ADSP_PLUGIN_ADMA3, + TEGRA210_ADSP_PLUGIN_ADMA4, + TEGRA210_ADSP_PLUGIN_ADMA5, + TEGRA210_ADSP_PLUGIN_ADMA6, + TEGRA210_ADSP_PLUGIN_ADMA7, + TEGRA210_ADSP_PLUGIN_ADMA8, + TEGRA210_ADSP_PLUGIN_ADMA9, + TEGRA210_ADSP_PLUGIN_ADMA10, + TEGRA210_ADSP_PLUGIN_ADMA11, + TEGRA210_ADSP_PLUGIN_ADMA12, + TEGRA210_ADSP_PLUGIN_ADMA13, + TEGRA210_ADSP_PLUGIN_ADMA14, + TEGRA210_ADSP_PLUGIN_ADMA15, + TEGRA210_ADSP_PLUGIN_ADMA1_TX, + TEGRA210_ADSP_PLUGIN_ADMA2_TX, + TEGRA210_ADSP_PLUGIN_ADMA3_TX, + TEGRA210_ADSP_PLUGIN_ADMA4_TX, + TEGRA210_ADSP_PLUGIN_ADMA5_TX, + TEGRA210_ADSP_PLUGIN_ADMA6_TX, + TEGRA210_ADSP_PLUGIN_ADMA7_TX, + TEGRA210_ADSP_PLUGIN_ADMA8_TX, + TEGRA210_ADSP_PLUGIN_ADMA9_TX, + TEGRA210_ADSP_PLUGIN_ADMA10_TX, + TEGRA210_ADSP_PLUGIN_ADMA11_TX, + TEGRA210_ADSP_PLUGIN_ADMA12_TX, + TEGRA210_ADSP_PLUGIN_ADMA13_TX, + TEGRA210_ADSP_PLUGIN_ADMA14_TX, + TEGRA210_ADSP_PLUGIN_ADMA15_TX, + + TEGRA210_ADSP_PLUGIN1, + TEGRA210_ADSP_PLUGIN2, + TEGRA210_ADSP_PLUGIN3, + TEGRA210_ADSP_PLUGIN4, + TEGRA210_ADSP_PLUGIN5, + TEGRA210_ADSP_PLUGIN6, + TEGRA210_ADSP_PLUGIN7, + TEGRA210_ADSP_PLUGIN8, + TEGRA210_ADSP_PLUGIN9, + TEGRA210_ADSP_PLUGIN10, + + TEGRA210_ADSP_VIRT_REG_MAX, +}; + +/* Supports widget id 0x0 - 0xFF */ +#define TEGRA210_ADSP_WIDGET_SOURCE_SHIFT 0 +#define TEGRA210_ADSP_WIDGET_SOURCE_MASK (0xff << TEGRA210_ADSP_WIDGET_SOURCE_SHIFT) + +#define TEGRA210_ADSP_WIDGET_EN_SHIFT 31 +#define TEGRA210_ADSP_WIDGET_EN_MASK (0x1 << TEGRA210_ADSP_WIDGET_EN_SHIFT) + +/* TODO : Check if we can remove these macros */ +#define ADSP_FE_START TEGRA210_ADSP_FRONT_END1 +#define ADSP_FE_END TEGRA210_ADSP_FRONT_END15 +#define ADSP_ADMAIF_START TEGRA210_ADSP_ADMAIF1 +#define ADSP_NULL_SINK_START TEGRA210_ADSP_NULL_SINK1 +#define ADSP_ADMAIF_END TEGRA210_ADSP_NULL_SINK15 +#define ADSP_EAVB_START TEGRA210_ADSP_EAVB +#define ADSP_FE_COUNT ADSP_EAVB_START +#define APM_IN_START TEGRA210_ADSP_APM_IN1 +#define APM_IN_END TEGRA210_ADSP_APM_IN15 +#define APM_OUT_START TEGRA210_ADSP_APM_OUT1 +#define APM_OUT_END TEGRA210_ADSP_APM_OUT15 +#define ADMA_START TEGRA210_ADSP_PLUGIN_ADMA1 +#define ADMA_END TEGRA210_ADSP_PLUGIN_ADMA15 +#define ADMA_TX_START TEGRA210_ADSP_PLUGIN_ADMA1_TX +#define ADMA_TX_END TEGRA210_ADSP_PLUGIN_ADMA15_TX +#define PLUGIN_START TEGRA210_ADSP_PLUGIN1 +#define PLUGIN_END TEGRA210_ADSP_PLUGIN10 +#define ADSP_MAX_NULL_SINK (ADSP_ADMAIF_END - ADSP_NULL_SINK_START + 1) + +#define IS_NULL_SINK(reg) ((reg >= ADSP_NULL_SINK_START) && \ + (reg <= ADSP_ADMAIF_END)) +#define IS_APM_IN(reg) ((reg >= APM_IN_START) && (reg <= APM_IN_END)) +#define IS_APM_OUT(reg) ((reg >= APM_OUT_START) && (reg <= APM_OUT_END)) +#define IS_APM(reg) (IS_APM_IN(reg) | IS_APM_OUT(reg)) +#define IS_PLUGIN(reg) ((reg >= PLUGIN_START) && (reg <= PLUGIN_END)) +#define IS_ADMA_RX(reg) ((reg >= ADMA_START) && (reg <= ADMA_END)) +#define IS_ADMA_TX(reg) ((reg >= ADMA_TX_START) && (reg <= ADMA_TX_END)) +#define IS_ADMA(reg) (IS_ADMA_RX(reg) || IS_ADMA_TX(reg)) +#define IS_ADSP_APP(reg) (IS_APM(reg) | IS_PLUGIN(reg) | IS_ADMA(reg)) +#define IS_ADSP_FE(reg) (((reg >= ADSP_FE_START) && (reg <= ADSP_FE_END)) || \ + (reg == ADSP_EAVB_START)) +#define IS_ADSP_ADMAIF(reg) ((reg >= ADSP_ADMAIF_START) && (reg <= ADSP_ADMAIF_END)) + +#define IS_VALID_INPUT(fe, mask) ((1 << (fe - 1)) & mask) +/* ADSP_MSG_FLAGs */ +#define TEGRA210_ADSP_MSG_FLAG_SEND 0x0 +#define TEGRA210_ADSP_MSG_FLAG_HOLD 0x1 +#define TEGRA210_ADSP_MSG_FLAG_NEED_ACK 0x2 + +#define MAX_ADSP_SWITCHES 3 +/* TODO : Remove hard-coding and get data from DTS */ +#define TEGRA210_ADSP_ADMA_CHANNEL_START 10 +#define TEGRA210_ADSP_ADMA_CHANNEL_COUNT 10 +#define TEGRA210_ADSP_ADMA_BITMAP_COUNT 64 +#define TEGRA210_MAX_ADMA_CHANNEL 22 +#define TEGRA186_MAX_ADMA_CHANNEL 32 + + +#define TEGRA210_ADSP_ADMA_CHANNEL_START_HV 16 + +/* ADSP base index for widget name update */ +#define TEGRA210_ADSP_ROUTE_BASE ((TEGRA210_ADSP_ADMAIF20 * 18) + \ + (ADSP_MAX_NULL_SINK * 17) + \ + (52 * (APM_OUT_START - APM_IN_START))) + + +#define TEGRA210_ADSP_WIDGET_BASE ((ADSP_ADMAIF_END * 3) + \ + ((TEGRA210_ADSP_PLUGIN1 - \ + TEGRA210_ADSP_APM_IN1) * 2) + \ + ADSP_MAX_NULL_SINK) + +#define IS_MMAP_ACCESS(access) \ + (access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) || \ + (access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) || \ + (access == SNDRV_PCM_ACCESS_MMAP_COMPLEX) +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_adx_alt.h b/sound/soc/tegra-alt/include/tegra210_adx_alt.h new file mode 100644 index 00000000..efb9a3d4 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_adx_alt.h @@ -0,0 +1,176 @@ +/* + * tegra210_adx_alt.h - Definitions for Tegra210 ADX driver + * + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_ADX_ALT_H__ +#define __TEGRA210_ADX_ALT_H__ + +#define TEGRA210_ADX_AUDIOCIF_CH_STRIDE 4 + +#define TEGRA210_ADX_AUDIOCIF_CH_STRIDE 4 + +/* Register offsets from TEGRA210_ADX*_BASE */ +#define TEGRA210_ADX_AXBAR_RX_STATUS 0x0c +#define TEGRA210_ADX_AXBAR_RX_INT_STATUS 0x10 +#define TEGRA210_ADX_AXBAR_RX_INT_MASK 0x14 +#define TEGRA210_ADX_AXBAR_RX_INT_SET 0x18 +#define TEGRA210_ADX_AXBAR_RX_INT_CLEAR 0x1c +#define TEGRA210_ADX_AXBAR_RX_CIF_CTRL 0x20 +#define TEGRA210_ADX_AXBAR_TX_STATUS 0x4c +#define TEGRA210_ADX_AXBAR_TX_INT_STATUS 0x50 +#define TEGRA210_ADX_AXBAR_TX_INT_MASK 0x54 +#define TEGRA210_ADX_AXBAR_TX_INT_SET 0x58 +#define TEGRA210_ADX_AXBAR_TX_INT_CLEAR 0x5c +#define TEGRA210_ADX_AXBAR_TX1_CIF_CTRL 0x60 +#define TEGRA210_ADX_AXBAR_TX2_CIF_CTRL 0x64 +#define TEGRA210_ADX_AXBAR_TX3_CIF_CTRL 0x68 +#define TEGRA210_ADX_AXBAR_TX4_CIF_CTRL 0x6c +#define TEGRA210_ADX_ENABLE 0x80 +#define TEGRA210_ADX_SOFT_RESET 0x84 +#define TEGRA210_ADX_CG 0x88 +#define TEGRA210_ADX_STATUS 0x8c +#define TEGRA210_ADX_INT_STATUS 0x90 +#define TEGRA210_ADX_CTRL 0xa4 +#define TEGRA210_ADX_IN_BYTE_EN0 0xa8 +#define TEGRA210_ADX_IN_BYTE_EN1 0xac +#define TEGRA210_ADX_CYA 0xb0 +#define TEGRA210_ADX_DBG 0xb4 +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL 0xb8 +#define TEGRA210_ADX_AHUBRAMCTL_ADX_DATA 0xbc + + +/* Fields in TEGRA210_ADX_AXBAR_RX_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_ADX_AXBAR_TX1_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_ADX_AXBAR_TX2_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_ADX_AXBAR_TX3_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_ADX_AXBAR_TX_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_ADX_ENABLE */ +#define TEGRA210_ADX_ENABLE_SHIFT 0 +#define TEGRA210_ADX_ENABLE_MASK (1 << TEGRA210_ADX_ENABLE_SHIFT) +#define TEGRA210_ADX_EN (1 << TEGRA210_ADX_ENABLE_SHIFT) + +/* Fields inTEGRA210_ADX_CTRL */ +#define TEGRA210_ADX_CTRL_TX4_FORCE_DISABLE_SHIFT 11 +#define TEGRA210_ADX_CTRL_TX4_FORCE_DISABLE_MASK (1 << TEGRA210_ADX_CTRL_TX4_FORCE_DISABLE_SHIFT) +#define TEGRA210_ADX_CTRL_TX4_FORCE_DISABLE_EN (1 << TEGRA210_ADX_CTRL_TX4_FORCE_DISABLE_SHIFT) + +#define TEGRA210_ADX_CTRL_TX3_FORCE_DISABLE_SHIFT 10 +#define TEGRA210_ADX_CTRL_TX3_FORCE_DISABLE_MASK (1 << TEGRA210_ADX_CTRL_TX3_FORCE_DISABLE_SHIFT) +#define TEGRA210_ADX_CTRL_TX3_FORCE_DISABLE_EN (1 << TEGRA210_ADX_CTRL_TX3_FORCE_DISABLE_SHIFT) + +#define TEGRA210_ADX_CTRL_TX2_FORCE_DISABLE_SHIFT 9 +#define TEGRA210_ADX_CTRL_TX2_FORCE_DISABLE_MASK (1 << TEGRA210_ADX_CTRL_TX2_FORCE_DISABLE_SHIFT) +#define TEGRA210_ADX_CTRL_TX2_FORCE_DISABLE_EN (1 << TEGRA210_ADX_CTRL_TX2_FORCE_DISABLE_SHIFT) + +#define TEGRA210_ADX_CTRL_TX1_FORCE_DISABLE_SHIFT 8 +#define TEGRA210_ADX_CTRL_TX1_FORCE_DISABLE_MASK (1 << TEGRA210_ADX_CTRL_TX1_FORCE_DISABLE_SHIFT) +#define TEGRA210_ADX_CTRL_TX1_FORCE_DISABLE_EN (1 << TEGRA210_ADX_CTRL_TX1_FORCE_DISABLE_SHIFT) + +#define TEGRA210_ADX_CTRL_TX4_ENABLE_SHIFT 3 +#define TEGRA210_ADX_CTRL_TX4_ENABLE_MASK (1 << TEGRA210_ADX_CTRL_TX4_ENABLE_SHIFT) +#define TEGRA210_ADX_CTRL_TX4_EN (1 << TEGRA210_ADX_CTRL_TX4_ENABLE_SHIFT) + +#define TEGRA210_ADX_CTRL_TX3_ENABLE_SHIFT 2 +#define TEGRA210_ADX_CTRL_TX3_ENABLE_MASK (1 << TEGRA210_ADX_CTRL_TX3_ENABLE_SHIFT) +#define TEGRA210_ADX_CTRL_TX3_EN (1 << TEGRA210_ADX_CTRL_TX3_ENABLE_SHIFT) + +#define TEGRA210_ADX_CTRL_TX2_ENABLE_SHIFT 1 +#define TEGRA210_ADX_CTRL_TX2_ENABLE_MASK (1 << TEGRA210_ADX_CTRL_TX2_ENABLE_SHIFT) +#define TEGRA210_ADX_CTRL_TX2_EN (1 << TEGRA210_ADX_CTRL_TX2_ENABLE_SHIFT) + +#define TEGRA210_ADX_CTRL_TX1_ENABLE_SHIFT 0 +#define TEGRA210_ADX_CTRL_TX1_ENABLE_MASK (1 << TEGRA210_ADX_CTRL_TX1_ENABLE_SHIFT) +#define TEGRA210_ADX_CTRL_TX1_EN (1 << TEGRA210_ADX_CTRL_TX1_ENABLE_SHIFT) + +/* Fields in TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL */ +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_READ_BUSY_SHIFT 31 +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_READ_BUSY_MASK (1 << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_READ_BUSY_SHIFT) +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_READ_BUSY (1 << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_READ_BUSY_SHIFT) + +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_SEQ_READ_COUNT_SHIFT 16 +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_SEQ_READ_COUNT_MASK (0xff << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_SEQ_READ_COUNT_SHIFT) + +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RW_SHIFT 14 +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RW_MASK (1 << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RW_SHIFT) +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RW_WRITE (1 << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RW_SHIFT) + +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_ADDR_INIT_EN_SHIFT 13 +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_ADDR_INIT_EN_MASK (1 << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_ADDR_INIT_EN_SHIFT) +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_ADDR_INIT_EN (1 << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_ADDR_INIT_EN_SHIFT) + +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_SEQ_ACCESS_EN_SHIFT 12 +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_SEQ_ACCESS_EN_MASK (1 << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_SEQ_ACCESS_EN_SHIFT) +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_SEQ_ACCESS_EN (1 << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_SEQ_ACCESS_EN_SHIFT) + +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RAM_ADDR_SHIFT 0 +#define TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RAM_ADDR_MASK (0xff << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RAM_ADDR_SHIFT) + +/* Fields in TEGRA210_ADX_SOFT_RESET */ +#define TEGRA210_ADX_SOFT_RESET_SOFT_RESET_SHIFT 0 +#define TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK (1 << TEGRA210_ADX_SOFT_RESET_SOFT_RESET_SHIFT) +#define TEGRA210_ADX_SOFT_RESET_SOFT_EN (1 << TEGRA210_ADX_SOFT_RESET_SOFT_RESET_SHIFT) +#define TEGRA210_ADX_SOFT_RESET_SOFT_DEFAULT (0 << TEGRA210_ADX_SOFT_RESET_SOFT_RESET_SHIFT) + +/* + * Those defines are not in register field. + */ +#define TEGRA210_ADX_RAM_DEPTH 16 +#define TEGRA210_ADX_MAP_STREAM_NUMBER_SHIFT 6 +#define TEGRA210_ADX_MAP_WORD_NUMBER_SHIFT 2 +#define TEGRA210_ADX_MAP_BYTE_NUMBER_SHIFT 0 + +enum { + TEGRA210_ADX_TX_DISABLE, + TEGRA210_ADX_TX_ENABLE, +}; + +enum { + /* Code assumes that OUT_STREAM values of ADX start at 0 */ + /* OUT_STREAM# is equilvant to hw OUT_CH# */ + TEGRA210_ADX_OUT_STREAM0 = 0, + TEGRA210_ADX_OUT_STREAM1, + TEGRA210_ADX_OUT_STREAM2, + TEGRA210_ADX_OUT_STREAM3, + TEGRA210_ADX_IN_STREAM, + TEGRA210_ADX_TOTAL_STREAM +}; + +struct tegra210_adx_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra210_adx { + struct regmap *regmap; + unsigned int map[16]; + unsigned int byte_mask[2]; + const struct tegra210_adx_soc_data *soc_data; + bool is_shutdown; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_afc_alt.h b/sound/soc/tegra-alt/include/tegra210_afc_alt.h new file mode 100644 index 00000000..ddf9098b --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_afc_alt.h @@ -0,0 +1,117 @@ +/* + * tegra210_afc_alt.h - Definitions for Tegra210 AFC driver + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_AFC_ALT_H__ +#define __TEGRA210_AFC_ALT_H__ + +/* + * AFC_AXBAR_RX registers are with respect to AXBAR. + * The data is coming from AXBAR to AFC for playback. + */ +#define TEGRA210_AFC_AXBAR_RX_STATUS 0xc +#define TEGRA210_AFC_AXBAR_RX_CIF_CTRL 0x20 +#define TEGRA210_AFC_AXBAR_RX_CYA 0x24 + +/* + * AFC_AXBAR_TX registers are with respect to AXBAR. + * The data is going out of AFC for playback. + */ +#define TEGRA210_AFC_AXBAR_TX_STATUS 0x4c +#define TEGRA210_AFC_AXBAR_TX_INT_STATUS 0x50 +#define TEGRA210_AFC_AXBAR_TX_INT_MASK 0x54 +#define TEGRA210_AFC_AXBAR_TX_INT_SET 0x58 +#define TEGRA210_AFC_AXBAR_TX_INT_CLEAR 0x5c +#define TEGRA210_AFC_AXBAR_TX_CIF_CTRL 0x60 +#define TEGRA210_AFC_AXBAR_TX_CYA 0x64 + +/* Register offsets from TEGRA210_AFC*_BASE */ +#define TEGRA210_AFC_ENABLE 0x80 +#define TEGRA210_AFC_SOFT_RESET 0x84 +#define TEGRA210_AFC_CG 0x88 +#define TEGRA210_AFC_STATUS 0x8c +#define TEGRA210_AFC_INT_STATUS 0x90 +#define TEGRA210_AFC_INT_MASK 0x94 +#define TEGRA210_AFC_INT_SET 0x98 +#define TEGRA210_AFC_INT_CLEAR 0x9c + +/* Miscellaneous AFC registers */ +#define TEGRA210_AFC_DEST_I2S_PARAMS 0xa4 +#define TEGRA210_AFC_TXCIF_FIFO_PARAMS 0xa8 +#define TEGRA210_AFC_CLK_PPM_DIFF 0xac +#define TEGRA210_AFC_DBG_CTRL 0xb0 +#define TEGRA210_AFC_TOTAL_SAMPLES 0xb4 +#define TEGRA210_AFC_DECIMATION_SAMPLES 0xb8 +#define TEGRA210_AFC_INTERPOLATION_SAMPLES 0xbc +#define TEGRA210_AFC_DBG_INTERNAL 0xc0 + +/* AFC coefficient registers */ +#define TEGRA210_AFC_LCOEF_1_4_0 0xc4 +#define TEGRA210_AFC_LCOEF_1_4_1 0xc8 +#define TEGRA210_AFC_LCOEF_1_4_2 0xcc +#define TEGRA210_AFC_LCOEF_1_4_3 0xd0 +#define TEGRA210_AFC_LCOEF_1_4_4 0xd4 +#define TEGRA210_AFC_LCOEF_1_4_5 0xd8 +#define TEGRA210_AFC_LCOEF_2_4_0 0xdc +#define TEGRA210_AFC_LCOEF_2_4_1 0xe0 +#define TEGRA210_AFC_LCOEF_2_4_2 0xe4 +#define TEGRA210_AFC_CYA 0xe8 + +/* Fields in TEGRA210_AFC_ENABLE */ +#define TEGRA210_AFC_EN_SHIFT 0 +#define TEGRA210_AFC_EN (1 << TEGRA210_AFC_EN_SHIFT) + +#define TEGRA186_AFC_MODULE_SELECT_SHIFT 27 + +#define TEGRA210_AFC_DEST_MODULE_ID_SHIFT 24 +#define TEGRA210_AFC_FIFO_HIGH_THRESHOLD_SHIFT 16 +#define TEGRA210_AFC_FIFO_START_THRESHOLD_SHIFT 8 + +#define AFC_CLK_PPM_DIFF 50 + +struct tegra210_afc_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); + unsigned int num_i2s; + bool flag_module_select; + const struct snd_soc_codec_driver *afc_codec; +}; + +enum tegra210_afc_threshold_type { + TH_DEFAULT, /* default thresholds */ + TH_NON_SFC, /* no SFC is in the path */ + TH_SFC, /* when SFC is in the path */ + TH_SFC_AMX, /* when both SFC and AMX in the path */ + TH_TYPE_COUNT, +}; + +struct tegra210_afc { + struct regmap *regmap; + const struct tegra210_afc_soc_data *soc_data; + bool is_shutdown; + + /* mandatory control to be set */ + unsigned int dest_module_num; + + unsigned int ppm_diff; + unsigned int src_burst; + unsigned int start_threshold; + unsigned int threshold_type; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_amx_alt.h b/sound/soc/tegra-alt/include/tegra210_amx_alt.h new file mode 100644 index 00000000..f0fd50bb --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_amx_alt.h @@ -0,0 +1,192 @@ +/* + * tegra210_amx_alt.h - Definitions for Tegra210 AMX driver + * + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHIN + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_AMX_ALT_H__ +#define __TEGRA210_AMX_ALT_H__ + +#define TEGRA210_AMX_AUDIOCIF_CH_STRIDE 4 + +/* Register offsets from TEGRA210_AMX*_BASE */ +#define TEGRA210_AMX_AXBAR_RX_STATUS 0x0c +#define TEGRA210_AMX_AXBAR_RX_INT_STATUS 0x10 +#define TEGRA210_AMX_AXBAR_RX_INT_MASK 0x14 +#define TEGRA210_AMX_AXBAR_RX_INT_SET 0x18 +#define TEGRA210_AMX_AXBAR_RX_INT_CLEAR 0x1c +#define TEGRA210_AMX_AXBAR_RX1_CIF_CTRL 0x20 +#define TEGRA210_AMX_AXBAR_RX2_CIF_CTRL 0x24 +#define TEGRA210_AMX_AXBAR_RX3_CIF_CTRL 0x28 +#define TEGRA210_AMX_AXBAR_RX4_CIF_CTRL 0x2c +#define TEGRA210_AMX_AXBAR_TX_STATUS 0x4c +#define TEGRA210_AMX_AXBAR_TX_INT_STATUS 0x50 +#define TEGRA210_AMX_AXBAR_TX_INT_MASK 0x54 +#define TEGRA210_AMX_AXBAR_TX_INT_SET 0x58 +#define TEGRA210_AMX_AXBAR_TX_INT_CLEAR 0x5c +#define TEGRA210_AMX_AXBAR_TX_CIF_CTRL 0x60 +#define TEGRA210_AMX_ENABLE 0x80 +#define TEGRA210_AMX_SOFT_RESET 0x84 +#define TEGRA210_AMX_CG 0x88 +#define TEGRA210_AMX_STATUS 0x8c +#define TEGRA210_AMX_INT_STATUS 0x90 +#define TEGRA210_AMX_CTRL 0xa4 +#define TEGRA210_AMX_OUT_BYTE_EN0 0xa8 +#define TEGRA210_AMX_OUT_BYTE_EN1 0xac +#define TEGRA210_AMX_CYA 0xb0 +#define TEGRA210_AMX_DBG 0xb4 +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL 0xb8 +#define TEGRA210_AMX_AHUBRAMCTL_AMX_DATA 0xbc + +/* Fields in TEGRA210_AMX_AXBAR_RX1_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_AMX_AXBAR_RX2_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_AMX_AXBAR_RX3_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_AMX_AXBAR_RX4_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_AMX_AXBAR_TX_CIF_CTRL */ +/* Uses field from TEGRA210_AUDIOCIF_CTRL_* in tegra210_xbar_alt.h */ + +/* Fields in TEGRA210_AMX_ENABLE */ +#define TEGRA210_AMX_ENABLE_SHIFT 0 +#define TEGRA210_AMX_ENABLE_MASK (1 << TEGRA210_AMX_ENABLE_SHIFT) +#define TEGRA210_AMX_EN (1 << TEGRA210_AMX_ENABLE_SHIFT) + +/* Fields in TEGRA210_AMX_CTRL */ +#define TEGRA210_AMX_CTRL_MSTR_RX_NUN_SHIFT 14 +#define TEGRA210_AMX_CTRL_MSTR_RX_NUM_MASK (3 << TEGRA210_AMX_CTRL_MSTR_RX_NUN_SHIFT) + +#define TEGRA210_AMX_CTRL_RX_DEP_SHIFT 12 +#define TEGRA210_AMX_CTRL_RX_DEP_MASK (3 << TEGRA210_AMX_CTRL_RX_DEP_SHIFT) +#define TEGRA210_AMX_CTRL_RX_DEP_WT_ON_ALL 0 +#define TEGRA210_AMX_CTRL_RX_DEP_WT_ON_ANY (1 << TEGRA210_AMX_CTRL_RX_DEP_SHIFT) +#define TEGRA210_AMX_CTRL_RX_DEP_RSVD (3 << TEGRA210_AMX_CTRL_RX_DEP_SHIFT) + +#define TEGRA210_AMX_CTRL_RX4_FORCE_DISABLE_SHIFT 11 +#define TEGRA210_AMX_CTRL_RX4_FORCE_DISABLE_MASK (1 << TEGRA210_AMX_CTRL_RX4_FORCE_DISABLE_SHIFT) +#define TEGRA210_AMX_CTRL_RX4_FORCE_DISABLE_EN (1 << TEGRA210_AMX_CTRL_RX4_FORCE_DISABLE_SHIFT) + +#define TEGRA210_AMX_CTRL_RX3_FORCE_DISABLE_SHIFT 10 +#define TEGRA210_AMX_CTRL_RX3_FORCE_DISABLE_MASK (1 << TEGRA210_AMX_CTRL_RX3_FORCE_DISABLE_SHIFT) +#define TEGRA210_AMX_CTRL_RX3_FORCE_DISABLE_EN (1 << TEGRA210_AMX_CTRL_RX3_FORCE_DISABLE_SHIFT) + +#define TEGRA210_AMX_CTRL_RX2_FORCE_DISABLE_SHIFT 9 +#define TEGRA210_AMX_CTRL_RX2_FORCE_DISABLE_MASK (1 << TEGRA210_AMX_CTRL_RX2_FORCE_DISABLE_SHIFT) +#define TEGRA210_AMX_CTRL_RX2_FORCE_DISABLE_EN (1 << TEGRA210_AMX_CTRL_RX2_FORCE_DISABLE_SHIFT) + +#define TEGRA210_AMX_CTRL_RX1_FORCE_DISABLE_SHIFT 8 +#define TEGRA210_AMX_CTRL_RX1_FORCE_DISABLE_MASK (1 << TEGRA210_AMX_CTRL_RX1_FORCE_DISABLE_SHIFT) +#define TEGRA210_AMX_CTRL_RX1_FORCE_DISABLE_EN (1 << TEGRA210_AMX_CTRL_RX1_FORCE_DISABLE_SHIFT) + +#define TEGRA210_AMX_CTRL_RX4_ENABLE_SHIFT 3 +#define TEGRA210_AMX_CTRL_RX4_ENABLE_MASK (1 << TEGRA210_AMX_CTRL_RX4_ENABLE_SHIFT) +#define TEGRA210_AMX_CTRL_RX4_EN (1 << TEGRA210_AMX_CTRL_RX4_ENABLE_SHIFT) + +#define TEGRA210_AMX_CTRL_RX3_ENABLE_SHIFT 2 +#define TEGRA210_AMX_CTRL_RX3_ENABLE_MASK (1 << TEGRA210_AMX_CTRL_RX3_ENABLE_SHIFT) +#define TEGRA210_AMX_CTRL_RX3_EN (1 << TEGRA210_AMX_CTRL_RX3_ENABLE_SHIFT) + +#define TEGRA210_AMX_CTRL_RX2_ENABLE_SHIFT 1 +#define TEGRA210_AMX_CTRL_RX2_ENABLE_MASK (1 << TEGRA210_AMX_CTRL_RX2_ENABLE_SHIFT) +#define TEGRA210_AMX_CTRL_RX2_EN (1 << TEGRA210_AMX_CTRL_RX2_ENABLE_SHIFT) + +#define TEGRA210_AMX_CTRL_RX1_ENABLE_SHIFT 0 +#define TEGRA210_AMX_CTRL_RX1_ENABLE_MASK (1 << TEGRA210_AMX_CTRL_RX1_ENABLE_SHIFT) +#define TEGRA210_AMX_CTRL_RX1_EN (1 << TEGRA210_AMX_CTRL_RX1_ENABLE_SHIFT) + +/* Fields in TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL */ +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_READ_BUSY_SHIFT 31 +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_READ_BUSY_MASK (1 << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_READ_BUSY_SHIFT) +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_READ_BUSY (1 << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_READ_BUSY_SHIFT) + +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RW_SHIFT 14 +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RW_MASK (1 << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RW_SHIFT) +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RW_WRITE (1 << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RW_SHIFT) + +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_ADDR_INIT_EN_SHIFT 13 +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_ADDR_INIT_EN_MASK (1 << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_ADDR_INIT_EN_SHIFT) +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_ADDR_INIT_EN (1 << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_ADDR_INIT_EN_SHIFT) + +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RAM_ADDR_SHIFT 0 +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RAM_ADDR_MASK (0xff << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RAM_ADDR_SHIFT) + +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_SEQ_ACCESS_EN_SHIFT 12 +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_SEQ_ACCESS_EN_MASK (1 << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_SEQ_ACCESS_EN_SHIFT) +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_SEQ_ACCESS_EN (1 << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_SEQ_ACCESS_EN_SHIFT) + +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_SEQ_READ_COUNT_SHIFT 16 +#define TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_SEQ_READ_COUNT_MASK (0xff << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_SEQ_READ_COUNT_SHIFT) + +/* Fields in TEGRA210_AMX_SOFT_RESET */ +#define TEGRA210_AMX_SOFT_RESET_SOFT_RESET_SHIFT 0 +#define TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK (1 << TEGRA210_AMX_SOFT_RESET_SOFT_RESET_SHIFT) +#define TEGRA210_AMX_SOFT_RESET_SOFT_EN (1 << TEGRA210_AMX_SOFT_RESET_SOFT_RESET_SHIFT) +#define TEGRA210_AMX_SOFT_RESET_SOFT_DEFAULT (0 << TEGRA210_AMX_SOFT_RESET_SOFT_RESET_SHIFT) + +/* + * Those defines are not in register field. + */ +#define TEGRA210_AMX_NUM_INPUTS 4 +#define TEGRA210_AMX_RAM_DEPTH 16 +#define TEGRA210_AMX_MAP_STREAM_NUMBER_SHIFT 6 +#define TEGRA210_AMX_MAP_STREAM_NUMBER_MASK (0x3 << TEGRA210_AMX_MAP_STREAM_NUMBER_SHIFT) +#define TEGRA210_AMX_MAP_WORD_NUMBER_SHIFT 2 +#define TEGRA210_AMX_MAP_WORD_NUMBER_MASK (0xF << TEGRA210_AMX_MAP_WORD_NUMBER_SHIFT) +#define TEGRA210_AMX_MAP_BYTE_NUMBER_SHIFT 0 +#define TEGRA210_AMX_MAP_BYTE_NUMBER_MASK (0x3 << TEGRA210_AMX_MAP_BYTE_NUMBER_SHIFT) + +enum { + TEGRA210_AMX_WAIT_ON_ALL, + TEGRA210_AMX_WAIT_ON_ANY, +}; + +enum { + /* Code assumes that IN_STREAM values of AMX start at 0 */ + TEGRA210_AMX_IN_STREAM0 = 0, + TEGRA210_AMX_IN_STREAM1, + TEGRA210_AMX_IN_STREAM2, + TEGRA210_AMX_IN_STREAM3, + TEGRA210_AMX_OUT_STREAM, + TEGRA210_AMX_TOTAL_STREAM +}; + +enum { + TEGRA210_AMX_RX_DISABLE, + TEGRA210_AMX_RX_ENABLE, +}; + +struct tegra210_amx_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra210_amx { + struct regmap *regmap; + unsigned int map[TEGRA210_AMX_RAM_DEPTH]; + unsigned int byte_mask[2]; + int input_channels[TEGRA210_AMX_NUM_INPUTS]; + int output_channels; + const struct tegra210_amx_soc_data *soc_data; + bool is_shutdown; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_dmic_alt.h b/sound/soc/tegra-alt/include/tegra210_dmic_alt.h new file mode 100644 index 00000000..7e41fd8d --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_dmic_alt.h @@ -0,0 +1,140 @@ +/* + * tegra210_dmic_alt.h - Definitions for Tegra210 DMIC driver + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_DMIC_ALT_H__ +#define __TEGRA210_DMIC_ALT_H__ + +/* Register offsets from DMIC BASE */ +#define TEGRA210_DMIC_TX_STATUS 0x0c +#define TEGRA210_DMIC_TX_INT_STATUS 0x10 +#define TEGRA210_DMIC_TX_INT_MASK 0x14 +#define TEGRA210_DMIC_TX_INT_SET 0x18 +#define TEGRA210_DMIC_TX_INT_CLEAR 0x1c +#define TEGRA210_DMIC_TX_CIF_CTRL 0x20 + +#define TEGRA210_DMIC_ENABLE 0x40 +#define TEGRA210_DMIC_SOFT_RESET 0x44 +#define TEGRA210_DMIC_CG 0x48 +#define TEGRA210_DMIC_STATUS 0x4c +#define TEGRA210_DMIC_INT_STATUS 0x50 +#define TEGRA210_DMIC_CTRL 0x64 + +#define TEGRA210_DMIC_DBG_CTRL 0x70 +#define TEGRA210_DMIC_DCR_FILTER_GAIN 0x74 +#define TEGRA210_DMIC_DCR_BIQUAD_0_COEF_0 0x78 +#define TEGRA210_DMIC_DCR_BIQUAD_0_COEF_1 0x7c +#define TEGRA210_DMIC_DCR_BIQUAD_0_COEF_2 0x80 +#define TEGRA210_DMIC_DCR_BIQUAD_0_COEF_3 0x84 +#define TEGRA210_DMIC_DCR_BIQUAD_0_COEF_4 0x88 +#define TEGRA210_DMIC_LP_FILTER_GAIN 0x8c +#define TEGRA210_DMIC_LP_BIQUAD_0_COEF_0 0x90 +#define TEGRA210_DMIC_LP_BIQUAD_0_COEF_1 0x94 +#define TEGRA210_DMIC_LP_BIQUAD_0_COEF_2 0x98 +#define TEGRA210_DMIC_LP_BIQUAD_0_COEF_3 0x9c +#define TEGRA210_DMIC_LP_BIQUAD_0_COEF_4 0xa0 +#define TEGRA210_DMIC_LP_BIQUAD_1_COEF_0 0xa4 +#define TEGRA210_DMIC_LP_BIQUAD_1_COEF_1 0xa8 +#define TEGRA210_DMIC_LP_BIQUAD_1_COEF_2 0xac +#define TEGRA210_DMIC_LP_BIQUAD_1_COEF_3 0xb0 +#define TEGRA210_DMIC_LP_BIQUAD_1_COEF_4 0xb4 +#define TEGRA210_DMIC_CORRECTION_FILTER_GAIN 0xb8 +#define TEGRA210_DMIC_CORRECTION_BIQUAD_0_COEF_0 0xbc +#define TEGRA210_DMIC_CORRECTION_BIQUAD_0_COEF_1 0xc0 +#define TEGRA210_DMIC_CORRECTION_BIQUAD_0_COEF_2 0xc4 +#define TEGRA210_DMIC_CORRECTION_BIQUAD_0_COEF_3 0xc8 +#define TEGRA210_DMIC_CORRECTION_BIQUAD_0_COEF_4 0xcc +#define TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_0 0xd0 +#define TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_1 0xd4 +#define TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_2 0xd8 +#define TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_3 0xdc +#define TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4 0xe0 + +/* Constants for DMIC */ +#define TEGRA210_DMIC_OSR_64 0 +#define TEGRA210_DMIC_OSR_128 1 +#define TEGRA210_DMIC_OSR_256 2 + +/* Fields in TEGRA210_DMIC_ENABLE */ +#define TEGRA210_DMIC_ENABLE_EN_SHIFT 0 +#define TEGRA210_DMIC_ENABLE_EN BIT(0) + +/* Fields in TEGRA210_DMIC_SOFT_RESET */ +#define TEGRA210_DMIC_SOFT_RESET_EN BIT(0) + +/* Fields in TEGRA210_DMIC_CG */ +#define TEGRA210_DMIC_CG_SLCG_EN BIT(0) + +/* Fields in TEGRA210_DMIC_STATUS */ +#define TEGRA210_DMIC_STATUS_CONFIG_ERROR_SHIFT 31 +#define TEGRA210_DMIC_STATUS_CONFIG_ERROR_MASK (0x1 << TEGRA210_DMIC_STATUS_CONFIG_ERROR_SHIFT) + +#define TEGRA210_DMIC_STATUS_SLCG_CLKEN_SHIFT 8 +#define TEGRA210_DMIC_STATUS_SLCG_CLKEN_MASK (0x1 << TEGRA210_DMIC_STATUS_SLCG_CLKEN_SHIFT) + +#define TEGRA210_DMIC_STATUS_ENABLE_STATUS_SHIFT 0 +#define TEGRA210_DMIC_STATUS_ENABLE_STATUS_MASK (0x1 << TEGRA210_DMIC_STATUS_ENABLE_STATUS_SHIFT) + +/* Fields in TEGRA210_DMIC_CTRL */ +#define TEGRA210_DMIC_CTRL_TRIMMER_SEL_SHIFT 12 +#define TEGRA210_DMIC_CTRL_TRIMMER_SEL_MASK (0x1f << TEGRA210_DMIC_CTRL_TRIMMER_SEL_SHIFT) + +#define TEGRA210_DMIC_CTRL_CHANNEL_SELECT_SHIFT 8 +#define TEGRA210_DMIC_CTRL_CHANNEL_SELECT_MASK (0x3 << TEGRA210_DMIC_CTRL_CHANNEL_SELECT_SHIFT) + +#define TEGRA210_DMIC_CTRL_LRSEL_POLARITY_SHIFT 4 +#define TEGRA210_DMIC_CTRL_LRSEL_POLARITY_MASK (0x1 << TEGRA210_DMIC_CTRL_LRSEL_POLARITY_SHIFT) + +#define TEGRA210_DMIC_CTRL_OSR_SHIFT 0 +#define TEGRA210_DMIC_CTRL_OSR_MASK (0x3 << TEGRA210_DMIC_CTRL_OSR_SHIFT) + +/* Fields in TEGRA210_DMIC_DBG_CTRL */ +#define TEGRA210_DMIC_DBG_CTRL_DCR_ENABLE BIT(3) +#define TEGRA210_DMIC_DBG_CTRL_LP_ENABLE BIT(2) +#define TEGRA210_DMIC_DBG_CTRL_SC_ENABLE BIT(1) +#define TEGRA210_DMIC_DBG_CTRL_BYPASS BIT(0) + +enum tegra_dmic_ch_select { + DMIC_CH_SELECT_NONE, + DMIC_CH_SELECT_LEFT, + DMIC_CH_SELECT_RIGHT, + DMIC_CH_SELECT_STEREO, +}; +struct tegra210_dmic_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra210_dmic { + struct clk *clk_dmic; + struct clk *clk_pll_a_out0; + struct regmap *regmap; + const struct tegra210_dmic_soc_data *soc_data; + int is_pinctrl; + struct pinctrl *pinctrl; + struct pinctrl_state *pin_active_state; + struct pinctrl_state *pin_idle_state; + int boost_gain; /* with 100x factor */ + int ch_select; + int tx_mono_to_stereo; + int sample_rate_via_control; + bool is_shutdown; + int format_out; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_i2s_alt.h b/sound/soc/tegra-alt/include/tegra210_i2s_alt.h new file mode 100644 index 00000000..500dbeb9 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_i2s_alt.h @@ -0,0 +1,240 @@ +/* + * tegra210_i2s_alt.h - Definitions for Tegra210 I2S driver + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_I2S_ALT_H__ +#define __TEGRA210_I2S_ALT_H__ + +/* Register offsets from TEGRA210_I2S*_BASE */ + +#define TEGRA210_I2S_AXBAR_RX_ENABLE 0x0 +#define TEGRA210_I2S_AXBAR_RX_SOFT_RESET 0x4 +#define TEGRA210_I2S_AXBAR_RX_STATUS 0x0c +#define TEGRA210_I2S_AXBAR_RX_INT_STATUS 0x10 +#define TEGRA210_I2S_AXBAR_RX_INT_MASK 0x14 +#define TEGRA210_I2S_AXBAR_RX_INT_SET 0x18 +#define TEGRA210_I2S_AXBAR_RX_INT_CLEAR 0x1c +#define TEGRA210_I2S_AXBAR_RX_CIF_CTRL 0x20 +#define TEGRA210_I2S_AXBAR_RX_CTRL 0x24 +#define TEGRA210_I2S_AXBAR_RX_SLOT_CTRL 0x28 +#define TEGRA210_I2S_AXBAR_RX_CLK_TRIM 0x2c +#define TEGRA210_I2S_AXBAR_RX_CYA 0x30 +#define TEGRA210_I2S_AXBAR_RX_CIF_FIFO_STATUS 0x34 +#define TEGRA210_I2S_AXBAR_TX_ENABLE 0x40 +#define TEGRA210_I2S_AXBAR_TX_SOFT_RESET 0x44 +#define TEGRA210_I2S_AXBAR_TX_STATUS 0x4c +#define TEGRA210_I2S_AXBAR_TX_INT_STATUS 0x50 +#define TEGRA210_I2S_AXBAR_TX_INT_MASK 0x54 +#define TEGRA210_I2S_AXBAR_TX_INT_SET 0x58 +#define TEGRA210_I2S_AXBAR_TX_INT_CLEAR 0x5c +#define TEGRA210_I2S_AXBAR_TX_CIF_CTRL 0x60 +#define TEGRA210_I2S_AXBAR_TX_CTRL 0x64 +#define TEGRA210_I2S_AXBAR_TX_SLOT_CTRL 0x68 +#define TEGRA210_I2S_AXBAR_TX_CLK_TRIM 0x6c +#define TEGRA210_I2S_AXBAR_TX_CYA 0x70 +#define TEGRA210_I2S_AXBAR_TX_CIF_FIFO_STATUS 0x74 +#define TEGRA210_I2S_ENABLE 0x80 +#define TEGRA210_I2S_SOFT_RESET 0x84 +#define TEGRA210_I2S_CG 0x88 +#define TEGRA210_I2S_STATUS 0x8c +#define TEGRA210_I2S_INT_STATUS 0x90 +#define TEGRA210_I2S_CTRL 0xa0 +#define TEGRA210_I2S_TIMING 0xa4 +#define TEGRA210_I2S_SLOT_CTRL 0xa8 +#define TEGRA210_I2S_CLK_TRIM 0xac +#define TEGRA210_I2S_CYA 0xb0 + +/* + * I2S_AXBAAR_RX registers are with respect to AXBAR. + * The data is coming from AXBAR to I2S for playback. + */ + +/* Fields in TEGRA210_I2S_AXBAR_RX_ENABLE */ +#define TEGRA210_I2S_AXBAR_RX_EN_SHIFT 0 +#define TEGRA210_I2S_AXBAR_RX_EN (1 << TEGRA210_I2S_AXBAR_RX_EN_SHIFT) + +/* Fields in TEGRA210_I2S_AXBAR_RX_CTRL */ +#define TEGRA210_I2S_AXBAR_RX_CTRL_DATA_OFFSET_SHIFT 8 +#define TEGRA210_I2S_AXBAR_RX_CTRL_DATA_OFFSET_MASK (0x7ff << TEGRA210_I2S_AXBAR_RX_CTRL_DATA_OFFSET_SHIFT) + +#define TEGRA210_I2S_AXBAR_RX_CTRL_MASK_BITS_SHIFT 4 + +#define TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_SHIFT 1 +#define TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_MASK (3 << TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_SHIFT) +#define TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_NOHIGHZ (0 << TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_SHIFT) +#define TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_HIGHZ (1 << TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_SHIFT) +#define TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_HIGHZ_ON_HALF_BIT_CLK (2 << TEGRA210_I2S_AXBAR_RX_CTRL_HIGHZ_CTRL_SHIFT) + +#define TEGRA210_I2S_AXBAR_RX_CTRL_BIT_ORDER_SHIFT 0 +#define TEGRA210_I2S_AXBAR_RX_CTRL_BIT_ORDER_MASK (1 << TEGRA210_I2S_AXBAR_RX_CTRL_BIT_ORDER_SHIFT) +#define TEGRA210_I2S_AXBAR_RX_CTRL_BIT_ORDER_MSB_FIRST (0 << TEGRA210_I2S_AXBAR_RX_CTRL_BIT_ORDER_SHIFT) +#define TEGRA210_I2S_AXBAR_RX_CTRL_BIT_ORDER_LSB_FIRST (1 << TEGRA210_I2S_AXBAR_RX_CTRL_BIT_ORDER_SHIFT) + +/* + * I2S_AXBAAR_TX registers are with respect to AXBAR. + * The data is goint to AXBAR from I2S for capture. + */ + +/* Fields in TEGRA210_I2S_AXBAR_TX_ENABLE */ +#define TEGRA210_I2S_AXBAR_TX_EN_SHIFT 0 +#define TEGRA210_I2S_AXBAR_TX_EN (1 << TEGRA210_I2S_AXBAR_TX_EN_SHIFT) + +/* Fields in TEGRA210_I2S_AXBAR_TX_CTRL */ +#define TEGRA210_I2S_AXBAR_TX_CTRL_DATA_OFFSET_SHIFT 8 +#define TEGRA210_I2S_AXBAR_TX_CTRL_DATA_OFFSET_MASK (0x7ff << TEGRA210_I2S_AXBAR_TX_CTRL_DATA_OFFSET_SHIFT) + +#define TEGRA210_I2S_AXBAR_TX_CTRL_MASK_BITS_SHIFT 4 + +#define TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_SHIFT 1 +#define TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_MASK (3 << TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_SHIFT) +#define TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_NOHIGHZ (0 << TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_SHIFT) +#define TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_HIGHZ (1 << TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_SHIFT) +#define TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_HIGHZ_ON_HALF_BIT_CLK (2 << TEGRA210_I2S_AXBAR_TX_CTRL_HIGHZ_CTRL_SHIFT) + +#define TEGRA210_I2S_AXBAR_TX_CTRL_BIT_ORDER_SHIFT 0 +#define TEGRA210_I2S_AXBAR_TX_CTRL_BIT_ORDER_MASK (1 << TEGRA210_I2S_AXBAR_TX_CTRL_BIT_ORDER_SHIFT) +#define TEGRA210_I2S_AXBAR_TX_CTRL_BIT_ORDER_MSB_FIRST (0 << TEGRA210_I2S_AXBAR_TX_CTRL_BIT_ORDER_SHIFT) +#define TEGRA210_I2S_AXBAR_TX_CTRL_BIT_ORDER_LSB_FIRST (1 << TEGRA210_I2S_AXBAR_TX_CTRL_BIT_ORDER_SHIFT) + +/* Fields in TEGRA210_I2S_ENABLE */ +#define TEGRA210_I2S_EN_SHIFT 0 +#define TEGRA210_I2S_EN_MASK (1 << TEGRA210_I2S_EN_SHIFT) +#define TEGRA210_I2S_EN (1 << TEGRA210_I2S_EN_SHIFT) + +/* Fields in TEGRA210_I2S_CTRL */ +#define TEGRA210_I2S_CTRL_FSYNC_WIDTH_SHIFT 24 +#define TEGRA210_I2S_CTRL_FSYNC_WIDTH_MASK (0xff << TEGRA210_I2S_CTRL_FSYNC_WIDTH_SHIFT) + +#define TEGRA210_I2S_POS_EDGE 0 +#define TEGRA210_I2S_NEG_EDGE 1 +#define TEGRA210_I2S_CTRL_EDGE_CTRL_SHIFT 20 +#define TEGRA210_I2S_CTRL_EDGE_CTRL_MASK (1 << TEGRA210_I2S_CTRL_EDGE_CTRL_SHIFT) +#define TEGRA210_I2S_CTRL_EDGE_CTRL_POS_EDGE (TEGRA210_I2S_POS_EDGE << TEGRA210_I2S_CTRL_EDGE_CTRL_SHIFT) +#define TEGRA210_I2S_CTRL_EDGE_CTRL_NEG_EDGE (TEGRA210_I2S_NEG_EDGE << TEGRA210_I2S_CTRL_EDGE_CTRL_SHIFT) + +#define TEGRA210_I2S_CTRL_PIPE_MACRO_EN_SHIFT 19 +#define TEGRA210_I2S_CTRL_PIPE_MACRO_EN (1 << TEGRA210_I2S_CTRL_PIPE_MACRO_EN_SHIFT) + +#define TEGRA210_I2S_FRAME_FORMAT_LRCK 0 +#define TEGRA210_I2S_FRAME_FORMAT_FSYNC 1 +#define TEGRA210_I2S_CTRL_FRAME_FORMAT_SHIFT 12 +#define TEGRA210_I2S_CTRL_FRAME_FORMAT_MASK (7 << TEGRA210_I2S_CTRL_FRAME_FORMAT_SHIFT) +#define TEGRA210_I2S_CTRL_FRAME_FORMAT_LRCK_MODE (TEGRA210_I2S_FRAME_FORMAT_LRCK << TEGRA210_I2S_CTRL_FRAME_FORMAT_SHIFT) +#define TEGRA210_I2S_CTRL_FRAME_FORMAT_FSYNC_MODE (TEGRA210_I2S_FRAME_FORMAT_FSYNC << TEGRA210_I2S_CTRL_FRAME_FORMAT_SHIFT) + +#define TEGRA210_I2S_CTRL_MASTER_EN_SHIFT 10 +#define TEGRA210_I2S_CTRL_MASTER_EN_MASK (1 << TEGRA210_I2S_CTRL_MASTER_EN_SHIFT) +#define TEGRA210_I2S_CTRL_MASTER_EN (1 << TEGRA210_I2S_CTRL_MASTER_EN_SHIFT) +#define TEGRA210_I2S_CTRL_SLAVE_EN (1 << TEGRA210_I2S_CTRL_MASTER_EN_SHIFT) + +#define TEGRA210_I2S_CTRL_LRCK_POLARITY_SHIFT 9 +#define TEGRA210_I2S_CTRL_LRCK_POLARITY_MASK (1 << TEGRA210_I2S_CTRL_LRCK_POLARITY_SHIFT) +#define TEGRA210_I2S_CTRL_LRCK_POLARITY_LOW (0 << TEGRA210_I2S_CTRL_LRCK_POLARITY_SHIFT) +#define TEGRA210_I2S_CTRL_LRCK_POLARITY_HIGH (1 << TEGRA210_I2S_CTRL_LRCK_POLARITY_SHIFT) + +#define TEGRA210_I2S_CTRL_LPBK_SHIFT 8 +#define TEGRA210_I2S_CTRL_LPBK_MASK (1 << TEGRA210_I2S_CTRL_LPBK_SHIFT) +#define TEGRA210_I2S_CTRL_LPBK_EN (1 << TEGRA210_I2S_CTRL_LPBK_SHIFT) + +#define TEGRA210_I2S_BITS_8 1 +#define TEGRA210_I2S_BITS_12 2 +#define TEGRA210_I2S_BITS_16 3 +#define TEGRA210_I2S_BITS_20 4 +#define TEGRA210_I2S_BITS_24 5 +#define TEGRA210_I2S_BITS_28 6 +#define TEGRA210_I2S_BITS_32 7 +#define TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT 0 +#define TEGRA210_I2S_CTRL_BIT_SIZE_MASK (7 << TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT) +#define TEGRA210_I2S_CTRL_BIT_SIZE_8 (TEGRA210_I2S_BITS_8 << TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT) +#define TEGRA210_I2S_CTRL_BIT_SIZE_12 (TEGRA210_I2S_BITS_12 << TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT) +#define TEGRA210_I2S_CTRL_BIT_SIZE_16 (TEGRA210_I2S_BITS_16 << TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT) +#define TEGRA210_I2S_CTRL_BIT_SIZE_20 (TEGRA210_I2S_BITS_20 << TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT) +#define TEGRA210_I2S_CTRL_BIT_SIZE_24 (TEGRA210_I2S_BITS_24 << TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT) +#define TEGRA210_I2S_CTRL_BIT_SIZE_28 (TEGRA210_I2S_BITS_28 << TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT) +#define TEGRA210_I2S_CTRL_BIT_SIZE_32 (TEGRA210_I2S_BITS_32 << TEGRA210_I2S_CTRL_BIT_SIZE_SHIFT) + +/* Fields in TEGRA210_I2S_TIMING */ +#define TEGRA210_I2S_TIMING_NON_SYM_EN_SHIFT 12 +#define TEGRA210_I2S_TIMING_NON_SYM_EN (1 << TEGRA210_I2S_TIMING_NON_SYM_EN_SHIFT) +#define TEGRA210_I2S_TIMING_CHANNEL_BIT_CNT_MASK 0x3ff +#define TEGRA210_I2S_TIMING_CHANNEL_BIT_CNT_SHIFT 0 + +/* Fields in TEGRA210_I2S_RX_SOFT_RESET */ +#define TEGRA210_I2S_AXBAR_RX_SOFT_RESET_SHIFT 0 +#define TEGRA210_I2S_AXBAR_RX_SOFT_RESET_MASK (1 << TEGRA210_I2S_AXBAR_RX_SOFT_RESET_SHIFT) +#define TEGRA210_I2S_AXBAR_RX_SOFT_RESET_EN (1 << TEGRA210_I2S_AXBAR_RX_SOFT_RESET_SHIFT) +#define TEGRA210_I2S_AXBAR_RX_SOFT_RESET_DEFAULT (0 << TEGRA210_I2S_AXBAR_RX_SOFT_RESET_SHIFT) + +/* Fields in TEGRA210_I2S_TX_SOFT_RESET */ +#define TEGRA210_I2S_AXBAR_TX_SOFT_RESET_SHIFT 0 +#define TEGRA210_I2S_AXBAR_TX_SOFT_RESET_MASK (1 << TEGRA210_I2S_AXBAR_TX_SOFT_RESET_SHIFT) +#define TEGRA210_I2S_AXBAR_TX_SOFT_RESET_EN (1 << TEGRA210_I2S_AXBAR_TX_SOFT_RESET_SHIFT) +#define TEGRA210_I2S_AXBAR_TX_SOFT_RESET_DEFAULT (0 << TEGRA210_I2S_AXBAR_TX_SOFT_RESET_SHIFT) + +/* Fields in TEGRA210_I2S_SLOT_CTRL */ +#define TEGRA210_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT 0 +#define TEGRA210_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK 0xf + +#define TEGRA210_I2S_RX_FIFO_DEPTH 64 + +struct tegra210_i2s_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); + void (*set_slot_ctrl)(struct regmap *map, + unsigned int total_slots, + unsigned int tx_slot_mask, + unsigned int rx_slot_mask); + bool is_soc_t210; +}; + +enum tegra210_i2s_path { + I2S_RX_PATH, + I2S_TX_PATH, + I2S_PATHS, +}; + +struct tegra210_i2s { + const struct tegra210_i2s_soc_data *soc_data; + struct clk *clk_i2s; + struct clk *clk_i2s_sync; + struct clk *clk_audio_sync; + struct clk *clk_i2s_source; + struct regmap *regmap; + struct pinctrl *pinctrl; + struct pinctrl_state *pin_default_state; + struct pinctrl_state *pin_idle_state; + struct regulator_bulk_data *supplies; + struct notifier_block slgc_notifier; + int num_supplies; + int bclk_ratio; + int format_in; + int codec_bit_format; + int sample_rate_via_control; + int channels_via_control; + int stereo_to_mono[I2S_PATHS]; + int mono_to_stereo[I2S_PATHS]; + unsigned int fsync_width; + unsigned int tx_mask; + unsigned int rx_mask; + unsigned int loopback; + bool enable_cya; + unsigned int rx_fifo_th; /* should be programmed interms of frames */ + bool is_shutdown; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_iqc_alt.h b/sound/soc/tegra-alt/include/tegra210_iqc_alt.h new file mode 100644 index 00000000..b315564e --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_iqc_alt.h @@ -0,0 +1,90 @@ +/* + * tegra210_iqc_alt.h - Definitions for Tegra210 IQC driver + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_IQC_ALT_H__ +#define __TEGRA210_IQC_ALT_H__ + +#define TEGRA210_IQC_AXBAR_TX_STRIDE 0x04 + +/* Register offsets from TEGRA210_IQC*_BASE */ + +/* + * IQC_AXBAR_TX registers are with respect to AXBAR. + * The data is coming from IQC for record. + */ +#define TEGRA210_IQC_AXBAR_TX_STATUS 0x0c +#define TEGRA210_IQC_AXBAR_TX_INT_STATUS 0x10 +#define TEGRA210_IQC_AXBAR_TX_INT_MASK 0x14 +#define TEGRA210_IQC_AXBAR_TX_INT_SET 0x18 +#define TEGRA210_IQC_AXBAR_TX_INT_CLEAR 0x1c +#define TEGRA210_IQC_AXBAR_TX_CIF_CTRL 0x20 + +#define TEGRA210_IQC_ENABLE 0x80 +#define TEGRA210_IQC_SOFT_RESET 0x84 +#define TEGRA210_IQC_CG 0x88 +#define TEGRA210_IQC_STATUS 0x8c +#define TEGRA210_IQC_INT_STATUS 0x90 +#define TEGRA210_IQC_CTRL 0xa0 +#define TEGRA210_IQC_TIME_STAMP_STATUS_0 0xa4 +#define TEGRA210_IQC_TIME_STAMP_STATUS_1 0xa8 +#define TEGRA210_IQC_WS_EDGE_STATUS 0xac +#define TEGRA210_IQC_CYA 0xb0 + +/* Fields in TEGRA210_IQC_ENABLE */ +#define TEGRA210_IQC_EN_SHIFT 0 +#define TEGRA210_IQC_EN_MASK (1 << TEGRA210_IQC_EN_SHIFT) +#define TEGRA210_IQC_EN (1 << TEGRA210_IQC_EN_SHIFT) + +/* Fields in TEGRA210_IQC_CTRL */ +#define TEGRA210_IQC_CTRL_EDGE_CTRL_SHIFT 4 +#define TEGRA210_IQC_CTRL_EDGE_CTRL_MASK (1 << TEGRA210_IQC_CTRL_EDGE_CTRL_SHIFT) +#define TEGRA210_IQC_CTRL_EDGE_CTRL_NEG_EDGE (1 << TEGRA210_IQC_CTRL_EDGE_CTRL_SHIFT) + +#define TEGRA210_IQC_TIMESTAMP_SHIFT 5 +#define TEGRA210_IQC_TIMESTAMP_MASK (1 << TEGRA210_IQC_TIMESTAMP_SHIFT) +#define TEGRA210_IQC_TIMESTAMP_EN (1 << TEGRA210_IQC_TIMESTAMP_SHIFT) + +#define TEGRA210_IQC_WORD_SIZE_SHIFT 8 +#define TEGRA210_IQC_WORD_SIZE_MASK (0xf << TEGRA210_IQC_WORD_SIZE_SHIFT) + +#define TEGRA210_IQC_WS_POLARITY_SHIFT 12 +#define TEGRA210_IQC_WS_POLARITY_MASK (1 << TEGRA210_IQC_WS_POLARITY_SHIFT) +#define TEGRA210_IQC_WS_POLARITY_HIGH (1 << TEGRA210_IQC_WS_POLARITY_SHIFT) + +#define TEGRA210_IQC_BIT_ORDER_SHIFT 16 +#define TEGRA210_IQC_BIT_ORDER_MASK (1 << TEGRA210_IQC_BIT_ORDER_SHIFT) +#define TEGRA210_IQC_LSB_FIRST (1 << TEGRA210_IQC_BIT_ORDER_SHIFT) + +#define TEGRA210_IQC_DATA_OFFSET_SHIFT 0 +#define TEGRA210_IQC_DATA_OFFSET_MASK (7 << TEGRA210_IQC_DATA_OFFSET_SHIFT) + +struct tegra210_iqc_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra210_iqc { + struct clk *clk_iqc; + struct regmap *regmap; + unsigned int timestamp_enable; + unsigned int data_offset; + const struct tegra210_iqc_soc_data *soc_data; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_mbdrc_alt.h b/sound/soc/tegra-alt/include/tegra210_mbdrc_alt.h new file mode 100644 index 00000000..238dc7e0 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_mbdrc_alt.h @@ -0,0 +1,247 @@ +/* + * tegra210_mbdrc_alt.h - Definitions for Tegra210 MBDRC driver + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_MBDRC_ALT_H__ +#define __TEGRA210_MBDRC_ALT_H__ + +/* Order of these enums are same as the order of band specific hw registers */ +enum { + MBDRC_LOW_BAND, + MBDRC_MID_BAND, + MBDRC_HIGH_BAND, + MBDRC_NUM_BAND, +}; + +/* Register offsets from TEGRA210_MBDRC*_BASE */ +#define TEGRA210_MBDRC_SOFT_RESET 0x4 +#define TEGRA210_MBDRC_CG 0x8 +#define TEGRA210_MBDRC_STATUS 0xc +#define TEGRA210_MBDRC_CONFIG 0x28 +#define TEGRA210_MBDRC_CHANNEL_MASK 0x2c +#define TEGRA210_MBDRC_MASTER_VOLUME 0x30 +#define TEGRA210_MBDRC_FAST_FACTOR 0x34 + +#define TEGRA210_MBDRC_FILTER_COUNT 3 +#define TEGRA210_MBDRC_FILTER_PARAM_STRIDE 0x4 + +#define TEGRA210_MBDRC_IIR_CONFIG 0x38 +#define TEGRA210_MBDRC_IN_ATTACK 0x44 +#define TEGRA210_MBDRC_IN_RELEASE 0x50 +#define TEGRA210_MBDRC_FAST_ATTACK 0x5c +#define TEGRA210_MBDRC_IN_THRESHOLD 0x68 +#define TEGRA210_MBDRC_OUT_THRESHOLD 0x74 +#define TEGRA210_MBDRC_RATIO_1ST 0x80 +#define TEGRA210_MBDRC_RATIO_2ND 0x8c +#define TEGRA210_MBDRC_RATIO_3RD 0x98 +#define TEGRA210_MBDRC_RATIO_4TH 0xa4 +#define TEGRA210_MBDRC_RATIO_5TH 0xb0 +#define TEGRA210_MBDRC_MAKEUP_GAIN 0xbc +#define TEGRA210_MBDRC_INIT_GAIN 0xc8 +#define TEGRA210_MBDRC_GAIN_ATTACK 0xd4 +#define TEGRA210_MBDRC_GAIN_RELEASE 0xe0 +#define TEGRA210_MBDRC_FAST_RELEASE 0xec +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL 0xf8 +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_DATA 0x104 + +#define TEGRA210_MBDRC_MAX_REG (TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_DATA + \ + (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * \ + (TEGRA210_MBDRC_FILTER_COUNT - 1))) + +/* Fields for TEGRA210_MBDRC_CONFIG */ +#define TEGRA210_MBDRC_CONFIG_RMS_OFFSET_SHIFT 16 +#define TEGRA210_MBDRC_CONFIG_RMS_OFFSET_MASK (0x1ff << TEGRA210_MBDRC_CONFIG_RMS_OFFSET_SHIFT) + +#define TEGRA210_MBDRC_CONFIG_PEAK_RMS_SHIFT 14 +#define TEGRA210_MBDRC_CONFIG_PEAK_RMS_MASK (0x1 << TEGRA210_MBDRC_CONFIG_PEAK_RMS_SHIFT) +#define TEGRA210_MBDRC_CONFIG_PEAK (1 << TEGRA210_MBDRC_CONFIG_PEAK_RMS_SHIFT) + +#define TEGRA210_MBDRC_CONFIG_FILTER_STRUCTURE_SHIFT 13 +#define TEGRA210_MBDRC_CONFIG_FILTER_STRUCTURE_MASK (0x1 << TEGRA210_MBDRC_CONFIG_FILTER_STRUCTURE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_FILTER_STRUCTURE_FLEX (1 << TEGRA210_MBDRC_CONFIG_FILTER_STRUCTURE_SHIFT) + +#define TEGRA210_MBDRC_CONFIG_SHIFT_CTRL_SHIFT 8 +#define TEGRA210_MBDRC_CONFIG_SHIFT_CTRL_MASK (0x1f << TEGRA210_MBDRC_CONFIG_SHIFT_CTRL_SHIFT) + +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT 4 +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_MASK (0xf << TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_N1 (0 << TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_N2 (1 << TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_N4 (2 << TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_N8 (3 << TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_N16 (4 << TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_N32 (5 << TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_FRAME_SIZE_N64 (6 << TEGRA210_MBDRC_CONFIG_FRAME_SIZE_SHIFT) + +#define TEGRA210_MBDRC_CONFIG_MBDRC_MODE_SHIFT 0 +#define TEGRA210_MBDRC_CONFIG_MBDRC_MODE_MASK (0x3 << TEGRA210_MBDRC_CONFIG_MBDRC_MODE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_MBDRC_MODE_BYPASS (0 << TEGRA210_MBDRC_CONFIG_MBDRC_MODE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_MBDRC_MODE_FULLBAND (1 << TEGRA210_MBDRC_CONFIG_MBDRC_MODE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_MBDRC_MODE_DUALBAND (2 << TEGRA210_MBDRC_CONFIG_MBDRC_MODE_SHIFT) +#define TEGRA210_MBDRC_CONFIG_MBDRC_MODE_MULTIBAND (3 << TEGRA210_MBDRC_CONFIG_MBDRC_MODE_SHIFT) + +/* Fields for TEGRA210_MBDRC_CHANNEL_MASK */ +#define TEGRA210_MBDRC_CHANNEL_MASK_SHIFT 0 +#define TEGRA210_MBDRC_CHANNEL_MASK_MASK (0xff << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT) + +/* Fields for TEGRA210_MBDRC_MASTER_VOLUME */ +#define TEGRA210_MBDRC_MASTER_VOLUME_SHIFT 0 +#define TEGRA210_MBDRC_MASTER_VOLUME_MASK (0xffffffff << TEGRA210_MBDRC_MASTER_VOLUME_SHIFT) + +/* Fields for TEGRA210_MBDRC_FAST_FACTOR */ +#define TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT 16 +#define TEGRA210_MBDRC_FAST_FACTOR_RELEASE_MASK (0xffff << TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT) + +#define TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT 0 +#define TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK (0xffff << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT) + +/* Fields for TEGRA210_MBDRC_IIR_CONFIG */ +#define TEGRA210_MBDRC_IIR_CONFIG_NUM_STAGES_SHIFT 0 +#define TEGRA210_MBDRC_IIR_CONFIG_NUM_STAGES_MASK (0xf << TEGRA210_MBDRC_IIR_CONFIG_NUM_STAGES_SHIFT) + +/* Fields for TEGRA210_MBDRC_IN_ATTACK */ +#define TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT 0 +#define TEGRA210_MBDRC_IN_ATTACK_TC_MASK (0xffffffff << TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT) + +/* Fields for TEGRA210_MBDRC_IN_RELEASE */ +#define TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT 0 +#define TEGRA210_MBDRC_IN_RELEASE_TC_MASK (0xffffffff << TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT) + +/* Fields for TEGRA210_MBDRC_FAST_ATTACK */ +#define TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT 0 +#define TEGRA210_MBDRC_FAST_ATTACK_TC_MASK (0xffffffff << TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT) + +/* Fields for TEGRA210_MBDRC_IN_THRESHOLD / TEGRA210_MBDRC_OUT_THRESHOLD */ +#define TEGRA210_MBDRC_THRESH_4TH_SHIFT 24 +#define TEGRA210_MBDRC_THRESH_4TH_MASK (0xff << TEGRA210_MBDRC_THRESH_4TH_SHIFT) + +#define TEGRA210_MBDRC_THRESH_3RD_SHIFT 16 +#define TEGRA210_MBDRC_THRESH_3RD_MASK (0xff << TEGRA210_MBDRC_THRESH_3RD_SHIFT) + +#define TEGRA210_MBDRC_THRESH_2ND_SHIFT 8 +#define TEGRA210_MBDRC_THRESH_2ND_MASK (0xff << TEGRA210_MBDRC_THRESH_2ND_SHIFT) + +#define TEGRA210_MBDRC_THRESH_1ST_SHIFT 0 +#define TEGRA210_MBDRC_THRESH_1ST_MASK (0xff << TEGRA210_MBDRC_THRESH_1ST_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_1ST */ +#define TEGRA210_MBDRC_RATIO_1ST_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_1ST_MASK (0xffff << TEGRA210_MBDRC_RATIO_1ST_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_2ND */ +#define TEGRA210_MBDRC_RATIO_2ND_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_2ND_MASK (0xffff << TEGRA210_MBDRC_RATIO_2ND_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_3RD */ +#define TEGRA210_MBDRC_RATIO_3RD_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_3RD_MASK (0xffff << TEGRA210_MBDRC_RATIO_3RD_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_4TH */ +#define TEGRA210_MBDRC_RATIO_4TH_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_4TH_MASK (0xffff << TEGRA210_MBDRC_RATIO_4TH_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_5TH */ +#define TEGRA210_MBDRC_RATIO_5TH_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_5TH_MASK (0xffff << TEGRA210_MBDRC_RATIO_5TH_SHIFT) + +/* Fields for TEGRA210_MBDRC_MAKEUP_GAIN */ +#define TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT 0 +#define TEGRA210_MBDRC_MAKEUP_GAIN_MASK (0x3f << TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT) + +/* Fields for TEGRA210_MBDRC_INIT_GAIN */ +#define TEGRA210_MBDRC_INIT_GAIN_SHIFT 0 +#define TEGRA210_MBDRC_INIT_GAIN_MASK (0xffffffff << TEGRA210_MBDRC_INIT_GAIN_SHIFT) + +/* Fields for TEGRA210_MBDRC_GAIN_ATTACK */ +#define TEGRA210_MBDRC_GAIN_ATTACK_SHIFT 0 +#define TEGRA210_MBDRC_GAIN_ATTACK_MASK (0xffffffff << TEGRA210_MBDRC_GAIN_ATTACK_SHIFT) + +/* Fields for TEGRA210_MBDRC_GAIN_RELEASE */ +#define TEGRA210_MBDRC_GAIN_RELEASE_SHIFT 0 +#define TEGRA210_MBDRC_GAIN_RELEASE_MASK (0xffffffff << TEGRA210_MBDRC_GAIN_RELEASE_SHIFT) + +/* Fields for TEGRA210_MBDRC_FAST_RELEASE */ +#define TEGRA210_MBDRC_FAST_RELEASE_SHIFT 0 +#define TEGRA210_MBDRC_FAST_RELEASE_MASK (0xffffffff << TEGRA210_MBDRC_FAST_RELEASE_SHIFT) + +/* Fields in TEGRA210_mbdrc ram ctrl */ +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY_SHIFT 31 +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY_MASK (1 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY_SHIFT) +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY (1 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY_SHIFT) + +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_READ_COUNT_SHIFT 16 +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_READ_COUNT_MASK (0xff << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_READ_COUNT_SHIFT) + +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_SHIFT 14 +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_MASK (1 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_SHIFT) +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_READ (0 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_SHIFT) +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_WRITE (1 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_SHIFT) + +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT 13 +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN_MASK (1 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT) +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN (1 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT) + +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT 12 +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_MASK (1 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT) +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN (1 << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT) + +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_SHIFT 0 +#define TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_MASK (0x1ff << TEGRA210_MBDRC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_SHIFT) +/* MBDRC register definition ends here */ + +/* order and size of each structure element for following structures should not + be altered size order of elements and their size are based on PEQ + co-eff ram and shift ram layout. +*/ +#define TEGRA210_MBDRC_THRESHOLD_NUM 4 +#define TEGRA210_MBDRC_RATIO_NUM (TEGRA210_MBDRC_THRESHOLD_NUM + 1) +#define TEGRA210_MBDRC_MAX_BIQUAD_STAGES 8 + +#define TEGRA210_MBDRC_BIQ_PARAMS_PER_STAGE 5 + +struct tegra210_mbdrc_band_params { + u32 band; + u32 iir_stages; + u32 in_attack_tc; + u32 in_release_tc; + u32 fast_attack_tc; + u32 in_threshold[TEGRA210_MBDRC_THRESHOLD_NUM]; + u32 out_threshold[TEGRA210_MBDRC_THRESHOLD_NUM]; + u32 ratio[TEGRA210_MBDRC_RATIO_NUM]; + u32 makeup_gain; + u32 gain_init; + u32 gain_attack_tc; + u32 gain_release_tc; + u32 fast_release_tc; + /* For biquad_params[][5] order of coeff is b0, b1, a0, a1, a2 */ + u32 biquad_params[TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5]; +}; + +struct tegra210_mbdrc_config { + unsigned int mode; + unsigned int rms_off; + unsigned int peak_rms_mode; + unsigned int fliter_structure; + unsigned int shift_ctrl; + unsigned int frame_size; + unsigned int channel_mask; + unsigned int fa_factor; /* Fast attack factor */ + unsigned int fr_factor; /* Fast release factor */ + struct tegra210_mbdrc_band_params band_params[MBDRC_NUM_BAND]; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_mixer_alt.h b/sound/soc/tegra-alt/include/tegra210_mixer_alt.h new file mode 100644 index 00000000..d4c80d39 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_mixer_alt.h @@ -0,0 +1,138 @@ +/* + * tegra210_mixer_alt.h - Definitions for Tegra210 MIXER driver + * + * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHIN + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_MIXER_ALT_H__ +#define __TEGRA210_MIXER_ALT_H__ + +#define TEGRA210_MIXER_AXBAR_RX_STRIDE 0x40 +#define TEGRA210_MIXER_AXBAR_RX_MAX 10 +#define TEGRA210_MIXER_AXBAR_RX_LIMIT (TEGRA210_MIXER_AXBAR_RX_MAX * TEGRA210_MIXER_AXBAR_RX_STRIDE) + +/* AXBAR_RX related MIXER offsets */ + +#define TEGRA210_MIXER_AXBAR_RX1_SOFT_RESET 0x04 +#define TEGRA210_MIXER_AXBAR_RX1_STATUS 0x10 +#define TEGRA210_MIXER_AXBAR_RX1_CIF_CTRL 0x24 +#define TEGRA210_MIXER_AXBAR_RX1_CTRL 0x28 +#define TEGRA210_MIXER_AXBAR_RX1_PEAK_CTRL 0x2c +#define TEGRA210_MIXER_AXBAR_RX1_SAMPLE_COUNT 0x30 +#define TEGRA210_MIXER_AXBAR_RX1_CYA 0x34 +#define TEGRA210_MIXER_AXBAR_RX1_DBG0 0x38 +#define TEGRA210_MIXER_AXBAR_RX1_DBG1 0x3c + +#define TEGRA210_MIXER_AXBAR_TX_STRIDE 0x40 +#define TEGRA210_MIXER_AXBAR_TX_MAX 5 +#define TEGRA210_MIXER_AXBAR_TX_LIMIT (TEGRA210_MIXER_AXBAR_RX_LIMIT + (TEGRA210_MIXER_AXBAR_TX_MAX * TEGRA210_MIXER_AXBAR_TX_STRIDE)) + +/* AXBAR_TX related MIXER offsets */ + +#define TEGRA210_MIXER_AXBAR_TX1_ENABLE 0x280 +#define TEGRA210_MIXER_AXBAR_TX1_SOFT_RESET 0x284 +#define TEGRA210_MIXER_AXBAR_TX1_STATUS 0x290 +#define TEGRA210_MIXER_AXBAR_TX1_INT_STATUS 0x294 +#define TEGRA210_MIXER_AXBAR_TX1_INT_MASK 0x298 +#define TEGRA210_MIXER_AXBAR_TX1_INT_SET 0x29c +#define TEGRA210_MIXER_AXBAR_TX1_INT_CLEAR 0x2a0 +#define TEGRA210_MIXER_AXBAR_TX1_CIF_CTRL 0x2a4 +#define TEGRA210_MIXER_AXBAR_TX1_ADDER_CONFIG 0x2a8 +#define TEGRA210_MIXER_AXBAR_TX1_CYA 0x2ac +#define TEGRA210_MIXER_AXBAR_TX1_DBG0 0x2b0 +#define TEGRA210_MIXER_AXBAR_TX1_DBG1 0x2b4 + +/* MIXER related offsets */ +#define TEGRA210_MIXER_ENABLE 0x400 +#define TEGRA210_MIXER_SOFT_RESET 0x404 +#define TEGRA210_MIXER_CG 0x408 +#define TEGRA210_MIXER_STATUS 0x410 +#define TEGRA210_MIXER_INT_STATUS 0x414 +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL 0x42c +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_DATA 0x430 +#define TEGRA210_MIXER_AHUBRAMCTL_PEAKM_RAM_CTRL 0x434 +#define TEGRA210_MIXER_AHUBRAMCTL_PEAKM_RAM_DATA 0x438 +#define TEGRA210_MIXER_CTRL 0x43c +#define TEGRA210_MIXER_CYA 0x440 +#define TEGRA210_MIXER_DBG 0x448 + +#define TEGRA210_MIXER_AXBAR_TX_ENABLE_SHIFT 0 +#define TEGRA210_MIXER_AXBAR_TX_EN (1 << TEGRA210_MIXER_AXBAR_TX_ENABLE_SHIFT) + +/* TODO Add fields for MIXER_AXBAR_TX1_ADDER_CONFIG register */ +#define TEGRA210_MIXER_AXBAR_TX2_ADDER_CONFIG (TEGRA210_MIXER_AXBAR_TX1_ADDER_CONFIG + TEGRA210_MIXER_AXBAR_TX_STRIDE) +#define TEGRA210_MIXER_AXBAR_TX3_ADDER_CONFIG (TEGRA210_MIXER_AXBAR_TX2_ADDER_CONFIG + TEGRA210_MIXER_AXBAR_TX_STRIDE) +#define TEGRA210_MIXER_AXBAR_TX4_ADDER_CONFIG (TEGRA210_MIXER_AXBAR_TX3_ADDER_CONFIG + TEGRA210_MIXER_AXBAR_TX_STRIDE) +#define TEGRA210_MIXER_AXBAR_TX5_ADDER_CONFIG (TEGRA210_MIXER_AXBAR_TX4_ADDER_CONFIG + TEGRA210_MIXER_AXBAR_TX_STRIDE) + +#define TEGRA210_MIXER_AXBAR_TX2_ENABLE (TEGRA210_MIXER_AXBAR_TX1_ENABLE + TEGRA210_MIXER_AXBAR_TX_STRIDE) +#define TEGRA210_MIXER_AXBAR_TX3_ENABLE (TEGRA210_MIXER_AXBAR_TX2_ENABLE + TEGRA210_MIXER_AXBAR_TX_STRIDE) +#define TEGRA210_MIXER_AXBAR_TX4_ENABLE (TEGRA210_MIXER_AXBAR_TX3_ENABLE + TEGRA210_MIXER_AXBAR_TX_STRIDE) +#define TEGRA210_MIXER_AXBAR_TX5_ENABLE (TEGRA210_MIXER_AXBAR_TX4_ENABLE + TEGRA210_MIXER_AXBAR_TX_STRIDE) + +/* Fields in TEGRA210_MIXER_ENABLE */ +#define TEGRA210_MIXER_ENABLE_SHIFT 0 +#define TEGRA210_MIXER_ENABLE_MASK (1 << TEGRA210_MIXER_ENABLE_SHIFT) +#define TEGRA210_MIXER_EN (1 << TEGRA210_MIXER_ENABLE_SHIFT) + +/* Fields in TEGRA210_MIXER_CTRL */ +#define TEGRA210_MIXER_CTRL_ENABLE_BYPASS_MODE 1 +#define TEGRA210_MIXER_CTRL_DISABLE_BYPASS_MODE 0 + +/* Fields in TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL */ +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_ADDR_0 0x0 +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_ADDR_STRIDE 0x10 + +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_READ_BUSY_SHIFT 31 +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_READ_BUSY_MASK (1 << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_READ_BUSY_SHIFT) +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_READ_BUSY (1 << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_READ_BUSY_SHIFT) + +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_READ_COUNT_SHIFT 16 +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_READ_COUNT_MASK (0xff << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_READ_COUNT_SHIFT) + +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RW_SHIFT 14 +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RW_MASK (1 << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RW_SHIFT) +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RW_WRITE (1 << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RW_SHIFT) + +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT 13 +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_ADDR_INIT_EN_MASK (1 << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT) +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_ADDR_INIT_EN (1 << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT) + +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT 12 +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_MASK (1 << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT) +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_ACCESS_EN (1 << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT) + +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RAM_ADDR_SHIFT 0 +#define TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RAM_ADDR_MASK (0x1ff << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RAM_ADDR_SHIFT) + +#define TEGRA210_MIXER_TOTAL_PATH (TEGRA210_MIXER_AXBAR_RX_MAX + \ + TEGRA210_MIXER_AXBAR_TX_MAX) + +struct tegra210_mixer_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra210_mixer { + struct regmap *regmap; + int gain_coeff[14]; + int gain_value[TEGRA210_MIXER_AXBAR_RX_MAX]; + const struct tegra210_mixer_soc_data *soc_data; + unsigned int channels_via_control[TEGRA210_MIXER_TOTAL_PATH]; + bool is_shutdown; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_mvc_alt.h b/sound/soc/tegra-alt/include/tegra210_mvc_alt.h new file mode 100644 index 00000000..523ecd9f --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_mvc_alt.h @@ -0,0 +1,152 @@ +/* + * tegra210_mvc_alt.h - Definitions for Tegra210 MVC driver + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_MVC_ALT_H__ +#define __TEGRA210_MVC_ALT_H__ + +/* + * MVC_AXBAR_RX registers are with respect to AXBAR. + * The data is coming from AXBAR to MVC for playback. + */ +#define TEGRA210_MVC_AXBAR_RX_STATUS 0x0c +#define TEGRA210_MVC_AXBAR_RX_INT_STATUS 0x10 +#define TEGRA210_MVC_AXBAR_RX_INT_MASK 0x14 +#define TEGRA210_MVC_AXBAR_RX_INT_SET 0x18 +#define TEGRA210_MVC_AXBAR_RX_INT_CLEAR 0x1c +#define TEGRA210_MVC_AXBAR_RX_CIF_CTRL 0x20 +#define TEGRA210_MVC_AXBAR_RX_CYA 0x24 +#define TEGRA210_MVC_AXBAR_RX_DBG 0x28 + +/* + * MVC_AXBAR_TX registers are with respect to AXBAR. + * The data is going out of MVC for playback. + */ +#define TEGRA210_MVC_AXBAR_TX_STATUS 0x4c +#define TEGRA210_MVC_AXBAR_TX_INT_STATUS 0x50 +#define TEGRA210_MVC_AXBAR_TX_INT_MASK 0x54 +#define TEGRA210_MVC_AXBAR_TX_INT_SET 0x58 +#define TEGRA210_MVC_AXBAR_TX_INT_CLEAR 0x5c +#define TEGRA210_MVC_AXBAR_TX_CIF_CTRL 0x60 +#define TEGRA210_MVC_AXBAR_TX_CYA 0x64 +#define TEGRA210_MVC_AXBAR_TX_DBG 0x68 + +/* Register offsets from TEGRA210_MVC*_BASE */ +#define TEGRA210_MVC_ENABLE 0x80 +#define TEGRA210_MVC_SOFT_RESET 0x84 +#define TEGRA210_MVC_CG 0x88 +#define TEGRA210_MVC_STATUS 0x90 +#define TEGRA210_MVC_INT_STATUS 0x94 +#define TEGRA210_MVC_CTRL 0xa8 +#define TEGRA210_MVC_SWITCH 0xac +#define TEGRA210_MVC_INIT_VOL 0xb0 +#define TEGRA210_MVC_TARGET_VOL 0xd0 +#define TEGRA210_MVC_DURATION 0xf0 +#define TEGRA210_MVC_DURATION_INV 0xf4 +#define TEGRA210_MVC_POLY_N1 0xf8 +#define TEGRA210_MVC_POLY_N2 0xfc +#define TEGRA210_MVC_PEAK_CTRL 0x100 +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL 0x104 +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_DATA 0x108 +#define TEGRA210_MVC_PEAK_VALUE 0x10c +#define TEGRA210_MVC_CONFIG_ERR_TYPE 0x12c +#define TEGRA210_MVC_CYA 0x130 +#define TEGRA210_MVC_DBG 0x138 + +/* Fields in TEGRA210_MVC_ENABLE */ +#define TEGRA210_MVC_EN_SHIFT 0 +#define TEGRA210_MVC_EN (1 << TEGRA210_MVC_EN_SHIFT) + +#define TEGRA210_MVC_MUTE_SHIFT 8 +#define TEGRA210_MVC_MUTE_MASK (0xff << TEGRA210_MVC_MUTE_SHIFT) +#define TEGRA210_MVC_MUTE_EN (0xff << TEGRA210_MVC_MUTE_SHIFT) + +#define TEGRA210_MVC_PER_CHAN_CTRL_EN_SHIFT 30 +#define TEGRA210_MVC_PER_CHAN_CTRL_EN_MASK (1 << TEGRA210_MVC_PER_CHAN_CTRL_EN_SHIFT) +#define TEGRA210_MVC_PER_CHAN_CTRL_EN (1 << TEGRA210_MVC_PER_CHAN_CTRL_EN_SHIFT) + +#define TEGRA210_MVC_CURVE_TYPE_SHIFT 1 +#define TEGRA210_MVC_CURVE_TYPE_MASK \ + (1 << TEGRA210_MVC_CURVE_TYPE_SHIFT) +#define TEGRA210_MVC_CURVE_TYPE_POLY \ + (0 << TEGRA210_MVC_CURVE_TYPE_SHIFT) +#define TEGRA210_MVC_CURVE_TYPE_LINEAR \ + (1 << TEGRA210_MVC_CURVE_TYPE_SHIFT) + +#define TEGRA210_MVC_VOLUME_SWITCH_SHIFT 2 +#define TEGRA210_MVC_VOLUME_SWITCH_MASK (1 << TEGRA210_MVC_VOLUME_SWITCH_SHIFT) +#define TEGRA210_MVC_VOLUME_SWITCH_TRIGGER (1 << TEGRA210_MVC_VOLUME_SWITCH_SHIFT) + +#define TEGRA210_MVC_COEFF_SWITCH_SHIFT 1 +#define TEGRA210_MVC_COEFF_SWITCH_MASK (1 << TEGRA210_MVC_COEFF_SWITCH_SHIFT) +#define TEGRA210_MVC_COEFF_SWITCH_TRIGGER (1 << TEGRA210_MVC_COEFF_SWITCH_SHIFT) + +#define TEGRA210_MVC_DURATION_SWITCH_SHIFT 0 +#define TEGRA210_MVC_DURATION_SWITCH_MASK (1 << TEGRA210_MVC_DURATION_SWITCH_SHIFT) +#define TEGRA210_MVC_DURATION_SWITCH_TRIGGER (1 << TEGRA210_MVC_DURATION_SWITCH_SHIFT) + +#define TEGRA210_MVC_INIT_VOL_DEFAULT_POLY 0x01000000 +#define TEGRA210_MVC_INIT_VOL_DEFAULT_LINEAR 0x00000000 + +/* Fields in TEGRA210_MVC ram ctrl */ +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY_SHIFT 31 +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY_MASK (1 << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY_SHIFT) +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY (1 << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_READ_BUSY_SHIFT) + +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_READ_COUNT_SHIFT 16 +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_READ_COUNT_MASK (0xff << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_READ_COUNT_SHIFT) + +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_SHIFT 14 +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_MASK (1 << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_SHIFT) +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_WRITE (1 << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_SHIFT) + +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT 13 +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN_MASK (1 << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT) +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN (1 << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN_SHIFT) + +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT 12 +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_MASK (1 << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT) +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN (1 << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT) + +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_SHIFT 0 +#define TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_MASK (0x1ff << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_SHIFT) + +enum { + CURVE_POLY, + CURVE_LINEAR, +}; + +struct tegra210_mvc_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra210_mvc { + struct regmap *regmap; + int poly_coeff[9]; + int poly_n1, poly_n2, duration, duration_inv; + int volume; + unsigned int curve_type; + unsigned int cif_channels; + unsigned int audio_bits; + unsigned int format_in; + const struct tegra210_mvc_soc_data *soc_data; + bool is_shutdown; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_ope_alt.h b/sound/soc/tegra-alt/include/tegra210_ope_alt.h new file mode 100644 index 00000000..07d7a652 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_ope_alt.h @@ -0,0 +1,96 @@ +/* + * tegra210_ope_alt.h - Definitions for Tegra210 OPE driver + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_OPE_ALT_H__ +#define __TEGRA210_OPE_ALT_H__ + +/* Register offsets from TEGRA210_OPE*_BASE */ +/* + * OPE_AXBAR_RX registers are with respect to AXBAR. + * The data is coming from AXBAR to OPE for playback. + */ +#define TEGRA210_OPE_AXBAR_RX_STATUS 0xc +#define TEGRA210_OPE_AXBAR_RX_INT_STATUS 0x10 +#define TEGRA210_OPE_AXBAR_RX_INT_MASK 0x14 +#define TEGRA210_OPE_AXBAR_RX_INT_SET 0x18 +#define TEGRA210_OPE_AXBAR_RX_INT_CLEAR 0x1c +#define TEGRA210_OPE_AXBAR_RX_CIF_CTRL 0x20 + +/* + * OPE_AXBAR_TX registers are with respect to AXBAR. + * The data is going out of OPE for playback. + */ +#define TEGRA210_OPE_AXBAR_TX_STATUS 0x4c +#define TEGRA210_OPE_AXBAR_TX_INT_STATUS 0x50 +#define TEGRA210_OPE_AXBAR_TX_INT_MASK 0x54 +#define TEGRA210_OPE_AXBAR_TX_INT_SET 0x58 +#define TEGRA210_OPE_AXBAR_TX_INT_CLEAR 0x5c +#define TEGRA210_OPE_AXBAR_TX_CIF_CTRL 0x60 + +/* OPE Gloabal registers */ +#define TEGRA210_OPE_ENABLE 0x80 +#define TEGRA210_OPE_SOFT_RESET 0x84 +#define TEGRA210_OPE_CG 0x88 +#define TEGRA210_OPE_STATUS 0x8c +#define TEGRA210_OPE_INT_STATUS 0x90 +#define TEGRA210_OPE_DIRECTION 0x94 + +/* Fields for TEGRA210_OPE_ENABLE */ +#define TEGRA210_OPE_EN_SHIFT 0 +#define TEGRA210_OPE_EN (1 << TEGRA210_OPE_EN_SHIFT) + +/* Fields for TEGRA210_OPE_SOFT_RESET */ +#define TEGRA210_OPE_SOFT_RESET_SHIFT 0 +#define TEGRA210_OPE_SOFT_RESET_EN (1 << TEGRA210_OPE_SOFT_RESET_SHIFT) + +/* Fields for TEGRA210_OPE_DIRECTION */ +#define TEGRA210_OPE_DIRECTION_SHIFT 0 +#define TEGRA210_OPE_DIRECTION_MASK (1 << TEGRA210_OPE_DIRECTION_SHIFT) +#define TEGRA210_OPE_DIRECTION_MBDRC_TO_PEQ (0 << TEGRA210_OPE_DIRECTION_SHIFT) +#define TEGRA210_OPE_DIRECTION_PEQ_TO_MBDRC (1 << TEGRA210_OPE_DIRECTION_SHIFT) +/* OPE register definitions end here */ + +#define TEGRA210_PEQ_IORESOURCE_MEM 1 +#define TEGRA210_MBDRC_IORESOURCE_MEM 2 + +struct tegra210_ope_module_soc_data { + int (*init)(struct platform_device *pdev, int id); + int (*codec_init)(struct snd_soc_codec *codec); +}; + +struct tegra210_ope_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); + struct tegra210_ope_module_soc_data peq_soc_data; + struct tegra210_ope_module_soc_data mbdrc_soc_data; +}; + +struct tegra210_ope { + struct regmap *regmap; + struct regmap *peq_regmap; + struct regmap *mbdrc_regmap; + const struct tegra210_ope_soc_data *soc_data; + bool is_shutdown; +}; + +extern int tegra210_peq_init(struct platform_device *pdev, int id); +extern int tegra210_peq_codec_init(struct snd_soc_codec *codec); +extern int tegra210_mbdrc_init(struct platform_device *pdev, int id); +extern int tegra210_mbdrc_codec_init(struct snd_soc_codec *codec); +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_peq_alt.h b/sound/soc/tegra-alt/include/tegra210_peq_alt.h new file mode 100644 index 00000000..f4982935 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_peq_alt.h @@ -0,0 +1,53 @@ +/* + * tegra210_peq_alt.h - Definitions for Tegra210 PEQ driver + * + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_PEQ_ALT_H__ +#define __TEGRA210_PEQ_ALT_H__ + +/* Register offsets from TEGRA210_PEQ*_BASE */ +#define TEGRA210_PEQ_SOFT_RESET 0x0 +#define TEGRA210_PEQ_CG 0x4 +#define TEGRA210_PEQ_STATUS 0x8 +#define TEGRA210_PEQ_CONFIG 0xc +#define TEGRA210_PEQ_AHUBRAMCTL_CONFIG_RAM_CTRL 0x10 +#define TEGRA210_PEQ_AHUBRAMCTL_CONFIG_RAM_DATA 0x14 +#define TEGRA210_PEQ_AHUBRAMCTL_CONFIG_RAM_SHIFT_CTRL 0x18 +#define TEGRA210_PEQ_AHUBRAMCTL_CONFIG_RAM_SHIFT_DATA 0x1c + +/* Fields in TEGRA210_PEQ_CONFIG */ +#define TEGRA210_PEQ_CONFIG_BIQUAD_STAGES_SHIFT 2 +#define TEGRA210_PEQ_CONfIG_BIQUAD_STAGES_MASK (0xf << TEGRA210_PEQ_CONFIG_BIQUAD_STAGES_SHIFT) +#define TEGRA210_PEQ_CONFIG_BIAS_SHIFT 1 +#define TEGRA210_PEQ_CONFIG_BIAS_MASK (0x1 << TEGRA210_PEQ_CONFIG_BIAS_SHIFT) +#define TEGRA210_PEQ_CONFIG_UNBIAS (1 << TEGRA210_PEQ_CONFIG_BIAS_SHIFT) + +#define TEGRA210_PEQ_CONFIG_MODE_SHIFT 0 +#define TEGRA210_PEQ_CONFIG_MODE_MASK (0x1 << TEGRA210_PEQ_CONFIG_MODE_SHIFT) +#define TEGRA210_PEQ_CONFIG_MODE_ACTIVE (1 << TEGRA210_PEQ_CONFIG_MODE_SHIFT) + +/* PEQ register definition ends here */ +#define TEGRA210_PEQ_MAX_BIQUAD_STAGES 12 + +#define TEGRA210_PEQ_MAX_CHANNELS 8 + +#define TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH \ + (2 + TEGRA210_PEQ_MAX_BIQUAD_STAGES * 5) +#define TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH \ + (2 + TEGRA210_PEQ_MAX_BIQUAD_STAGES) + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_sfc_alt.h b/sound/soc/tegra-alt/include/tegra210_sfc_alt.h new file mode 100644 index 00000000..818777c6 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_sfc_alt.h @@ -0,0 +1,787 @@ +/* + * tegra210_sfc_alt.h - Definitions for Tegra210 SFC driver + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_SFC_ALT_H__ +#define __TEGRA210_SFC_ALT_H__ + +/* + * SFC_AXBAR_RX registers are with respect to AXBAR. + * The data is coming from AXBAR to SFC for playback. + */ +#define TEGRA210_SFC_AXBAR_RX_STATUS 0x0c +#define TEGRA210_SFC_AXBAR_RX_INT_STATUS 0x10 +#define TEGRA210_SFC_AXBAR_RX_INT_MASK 0x14 +#define TEGRA210_SFC_AXBAR_RX_INT_SET 0x18 +#define TEGRA210_SFC_AXBAR_RX_INT_CLEAR 0x1c +#define TEGRA210_SFC_AXBAR_RX_CIF_CTRL 0x20 +#define TEGRA210_SFC_AXBAR_RX_FREQ 0x24 +#define TEGRA210_SFC_AXBAR_RX_CYA 0x28 +#define TEGRA210_SFC_AXBAR_RX_DBG 0x2c + +/* + * SFC_AXBAR_TX registers are with respect to AXBAR. + * The data is going out of SFC for playback. + */ +#define TEGRA210_SFC_AXBAR_TX_STATUS 0x4c +#define TEGRA210_SFC_AXBAR_TX_INT_STATUS 0x50 +#define TEGRA210_SFC_AXBAR_TX_INT_MASK 0x54 +#define TEGRA210_SFC_AXBAR_TX_INT_SET 0x58 +#define TEGRA210_SFC_AXBAR_TX_INT_CLEAR 0x5c +#define TEGRA210_SFC_AXBAR_TX_CIF_CTRL 0x60 +#define TEGRA210_SFC_AXBAR_TX_FREQ 0x64 +#define TEGRA210_SFC_AXBAR_TX_CYA 0x68 +#define TEGRA210_SFC_AXBAR_TX_DBG 0x6c + +/* Register offsets from TEGRA210_SFC*_BASE */ +#define TEGRA210_SFC_ENABLE 0x80 +#define TEGRA210_SFC_SOFT_RESET 0x84 +#define TEGRA210_SFC_CG 0x88 +#define TEGRA210_SFC_STATUS 0x8c +#define TEGRA210_SFC_INT_STATUS 0x90 +#define TEGRA210_SFC_CYA 0x94 +#define TEGRA210_SFC_DBG 0xac +#define TEGRA210_SFC_COEF_RAM 0xbc +#define TEGRA210_SFC_AHUBRAMCTL_SFC_CTRL 0xc0 +#define TEGRA210_SFC_AHUBRAMCTL_SFC_DATA 0xc4 + +/* Fields in TEGRA210_SFC_ENABLE */ +#define TEGRA210_SFC_EN_SHIFT 0 +#define TEGRA210_SFC_EN (1 << TEGRA210_SFC_EN_SHIFT) + +#define TEGRA210_SFC_BITS_8 1 +#define TEGRA210_SFC_BITS_12 2 +#define TEGRA210_SFC_BITS_16 3 +#define TEGRA210_SFC_BITS_20 4 +#define TEGRA210_SFC_BITS_24 5 +#define TEGRA210_SFC_BITS_28 6 +#define TEGRA210_SFC_BITS_32 7 +#define TEGRA210_SFC_FS8 0 +#define TEGRA210_SFC_FS11_025 1 +#define TEGRA210_SFC_FS16 2 +#define TEGRA210_SFC_FS22_05 3 +#define TEGRA210_SFC_FS24 4 +#define TEGRA210_SFC_FS32 5 +#define TEGRA210_SFC_FS44_1 6 +#define TEGRA210_SFC_FS48 7 +#define TEGRA210_SFC_FS64 8 +#define TEGRA210_SFC_FS88_2 9 +#define TEGRA210_SFC_FS96 10 +#define TEGRA210_SFC_FS176_4 11 +#define TEGRA210_SFC_FS192 12 + +/* Fields in TEGRA210_SFC_COEF_RAM */ +#define TEGRA210_SFC_COEF_RAM_COEF_RAM_EN BIT(0) + +#define TEGRA210_SFC_SOFT_RESET_EN BIT(0) + +/* SRC coefficients */ +#define TEGRA210_SFC_COEF_RAM_DEPTH 64 + +struct tegra210_sfc_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra210_sfc { + int srate_in; + int srate_out; + int format_in; + int format_out; + struct regmap *regmap; + struct snd_pcm_hw_params in_hw_params; + struct snd_pcm_hw_params out_hw_params; + int stereo_conv_input; + int mono_conv_output; + const struct tegra210_sfc_soc_data *soc_data; + unsigned int channels_via_control; + bool is_shutdown; +}; + +/* coeff RAM tables required for SFC */ + +static u32 coef_8to16[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00006102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002 /* output gain */ +}; + +static u32 coef_8to24[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x0000a105, /* header */ + 0x000005e1, /* input gain */ + 0x00dca92f, 0xff45647a, 0x0046b59c, + 0x00429d1e, 0xff4fec62, 0x00516d30, + 0xffdea779, 0xff5e08ba, 0x0060185e, + 0xffafbab2, 0xff698d5a, 0x006ce3ae, + 0xff9a82d2, 0xff704674, 0x007633c5, + 0xff923433, 0xff721128, 0x007cff42, + 0x00000003 /* output gain */ +}; + +static u32 coef_8to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x0156105, /* interpolation + IIR filter */ + 0x0000d649, /* input gain */ + 0x00e87afb, 0xff5f69d0, 0x003df3cf, + 0x007ce488, 0xff99a5c8, 0x0056a6a0, + 0x00344928, 0xffcba3e5, 0x006be470, + 0x00137aa7, 0xffe60276, 0x00773410, + 0x0005fa2a, 0xfff1ac11, 0x007c795b, + 0x00012d36, 0xfff5eca2, 0x007f10ef, + 0x00000002, /* ouptut gain */ + 0x0021a102, /* interpolation + IIR filter */ + 0x00000e00, /* input gain */ + 0x00e2e000, 0xff6e1a00, 0x002aaa00, + 0x00610a00, 0xff5dda00, 0x003ccc00, + 0x00163a00, 0xff3c0400, 0x00633200, + 0x00000003, /* Output gain */ + 0x00000204, /* Farrow filter */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000 +}; + +static u32 coef_8to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00156105, /* interpolation + IIR Filter */ + 0x0000d649, /* input gain */ + 0x00e87afb, 0xff5f69d0, 0x003df3cf, + 0x007ce488, 0xff99a5c8, 0x0056a6a0, + 0x00344928, 0xffcba3e5, 0x006be470, + 0x00137aa7, 0xffe60276, 0x00773410, + 0x0005fa2a, 0xfff1ac11, 0x007c795b, + 0x00012d36, 0xfff5eca2, 0x007f10ef, + 0x00000002, /* ouptut gain */ + 0x0000a102, /* interpolation + IIR filter */ + 0x00000e00, /* input gain */ + 0x00e2e000, 0xff6e1a00, 0x002aaa00, + 0x00610a00, 0xff5dda00, 0x003ccc00, + 0x00163a00, 0xff3c0400, 0x00633200, + 0x00000003 /* output gain */ +}; + +static u32 coef_11to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002, /* output gain */ + 0x00006102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000002 /* output gain */ +}; + +static u32 coef_11to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002, /* output gain */ + 0x00186102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000002, /* output gain */ + 0x00246102, /* header */ + 0x0000010a, /* input gain */ + 0x00c93dc4, 0xff26f5f6, 0x005d1041, + 0x001002c4, 0xff245b76, 0x00666002, + 0xffc30a45, 0xff1baecd, 0x00765921, + 0x00000002, /* output gain */ + 0x00005204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000 +}; + +static u32 coef_16to8[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_16to24[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x0015a105, /* header */ + 0x00000292, /* input gain */ + 0x00e4320a, 0xff41d2d9, 0x004911ac, + 0x005dd9e3, 0xff4c7d80, 0x0052103e, + 0xfff8ebef, 0xff5b6fab, 0x005f0a0d, + 0xffc4b414, 0xff68582c, 0x006b38e5, + 0xffabb861, 0xff704bec, 0x0074de52, + 0xffa19f4c, 0xff729059, 0x007c7e90, + 0x00000003, /* output gain */ + 0x00005105, /* header */ + 0x00000292, /* input gain */ + 0x00e4320a, 0xff41d2d9, 0x004911ac, + 0x005dd9e3, 0xff4c7d80, 0x0052103e, + 0xfff8ebef, 0xff5b6fab, 0x005f0a0d, + 0xffc4b414, 0xff68582c, 0x006b38e5, + 0xffabb861, 0xff704bec, 0x0074de52, + 0xffa19f4c, 0xff729059, 0x007c7e90, + 0x00000001 /* output gain */ +}; + +static u32 coef_16to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00156105, /* interpolation + IIR filter */ + 0x0000d649, /* input gain */ + 0x00e87afb, 0xff5f69d0, 0x003df3cf, + 0x007ce488, 0xff99a5c8, 0x0056a6a0, + 0x00344928, 0xffcba3e5, 0x006be470, + 0x00137aa7, 0xffe60276, 0x00773410, + 0x0005fa2a, 0xfff1ac11, 0x007c795b, + 0x00012d36, 0xfff5eca2, 0x007f10ef, + 0x00000002, /* output gain */ + 0x0021a102, /* interpolation + IIR filter */ + 0x00000e00, /* input gain */ + 0x00e2e000, 0xff6e1a00, 0x002aaa00, + 0x00610a00, 0xff5dda00, 0x003ccc00, + 0x00163a00, 0xff3c0400, 0x00633200, + 0x00000003, /* output gain */ + 0x002c0204, /* Farrow Filter */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005101, /* IIR Filter + Decimator */ + 0x0000203c, /* input gain */ + 0x00f52d35, 0xff2e2162, 0x005a21e0, + 0x00c6f0f0, 0xff2ecd69, 0x006fa78d, + 0x00000001 /* output gain */ +}; + +static u32 coef_16to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x0000a105, /* interpolation + IIR Filter */ + 0x00000784, /* input gain */ + 0x00cc516e, 0xff2c9639, 0x005ad5b3, + 0x0013ad0d, 0xff3d4799, 0x0063ce75, + 0xffb6f398, 0xff5138d1, 0x006e9e1f, + 0xff9186e5, 0xff5f96a4, 0x0076a86e, + 0xff82089c, 0xff676b81, 0x007b9f8a, + 0xff7c48a5, 0xff6a31e7, 0x007ebb7b, + 0x00000003 /* output gain */ +}; + +static u32 coef_22to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00006102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002 /* output gain */ +}; + +static u32 coef_22to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002, /* output gain */ + 0x00186102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000002, /* output gain */ + 0x00005204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000 +}; + +static u32 coef_24to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002, /* output gain */ + 0x00186102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000002, /* output gain */ + 0x00230204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005102, /* header */ + 0x00001685, /* input gain */ + 0x00f53ae9, 0xff52f196, 0x003e3e08, + 0x00b9f857, 0xff5d8985, 0x0050070a, + 0x008c3e86, 0xff6053f0, 0x006d98ef, + 0x00000001 /* output gain */ +}; + +static u32 coef_24to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00006102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002 /* output gain */ +}; + +static u32 coef_32to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002, /* output gain */ + 0x0018a102, /* header */ + 0x000005d6, /* input gain */ + 0x00c6543e, 0xff342935, 0x0052f116, + 0x000a1d78, 0xff3330c0, 0x005f88a3, + 0xffbee7c0, 0xff2b5ba5, 0x0073eb26, + 0x00000003, /* output gain */ + 0x00235204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005102, /* header */ + 0x0000015f, /* input gain */ + 0x00a7909c, 0xff241c71, 0x005f5e00, + 0xffca77f4, 0xff20dd50, 0x006855eb, + 0xff86c552, 0xff18137a, 0x00773648, + 0x00000001 /* output gain */ +}; + +static u32 coef_32to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x0015a105, /* header */ + 0x00000292, /* input gain */ + 0x00e4320a, 0xff41d2d9, 0x004911ac, + 0x005dd9e3, 0xff4c7d80, 0x0052103e, + 0xfff8ebef, 0xff5b6fab, 0x005f0a0d, + 0xffc4b414, 0xff68582c, 0x006b38e5, + 0xffabb861, 0xff704bec, 0x0074de52, + 0xffa19f4c, 0xff729059, 0x007c7e90, + 0x00000003, /* output gain */ + 0x00005105, /* header */ + 0x00000292, /* input gain */ + 0x00e4320a, 0xff41d2d9, 0x004911ac, + 0x005dd9e3, 0xff4c7d80, 0x0052103e, + 0xfff8ebef, 0xff5b6fab, 0x005f0a0d, + 0xffc4b414, 0xff68582c, 0x006b38e5, + 0xffabb861, 0xff704bec, 0x0074de52, + 0xffa19f4c, 0xff729059, 0x007c7e90, + 0x00000001 /* output gain */ +}; + +static u32 coef_44to8[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00120104, /* IIR Filter */ + 0x00000af2, /* input gain */ + 0x0057eebe, 0xff1e9863, 0x00652604, + 0xff7206ea, 0xff22ad7e, 0x006d47e1, + 0xff42a4d7, 0xff26e722, 0x0075fd83, + 0xff352f66, 0xff29312b, 0x007b986b, + 0xff310a07, 0xff296f51, 0x007eca7c, + 0x00000001, /* output gain */ + 0x001d9204, /* Farrow Filter + decimation */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005105, /* IIR Filter + Decimator */ + 0x0000d649, /* input gain */ + 0x00e87afb, 0xff5f69d0, 0x003df3cf, + 0x007ce488, 0xff99a5c8, 0x0056a6a0, + 0x00344928, 0xffcba3e5, 0x006be470, + 0x00137aa7, 0xffe60276, 0x00773410, + 0x0005fa2a, 0xfff1ac11, 0x007c795b, + 0x00012d36, 0xfff5eca2, 0x007f10ef, + 0x00000001 /* output gain */ +}; + +static u32 coef_44to16[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00126104, /* IIR Filter + interpolation */ + 0x00000af2, /* input gain */ + 0x0057eebe, 0xff1e9863, 0x00652604, + 0xff7206ea, 0xff22ad7e, 0x006d47e1, + 0xff42a4d7, 0xff26e722, 0x0075fd83, + 0xff352f66, 0xff29312b, 0x007b986b, + 0xff310a07, 0xff296f51, 0x007eca7c, + 0x00000002, /* output gain */ + 0x001d9204, /* Farrow Filter + Decimation */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005105, /* IIR Filter + Decimator */ + 0x0000d649, /* input gain */ + 0x00e87afb, 0xff5f69d0, 0x003df3cf, + 0x007ce488, 0xff99a5c8, 0x0056a6a0, + 0x00344928, 0xffcba3e5, 0x006be470, + 0x00137aa7, 0xffe60276, 0x00773410, + 0x0005fa2a, 0xfff1ac11, 0x007c795b, + 0x00012d36, 0xfff5eca2, 0x007f10ef, + 0x00000001 /* output gain */ +}; + +static u32 coef_48to24[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_44to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102,/* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002, /* output gain */ + 0x00186102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000002, /* output gain */ + 0x00235204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005102, /* header */ + 0x0001d029, /* input gain */ + 0x00f2a98b, 0xff92aa71, 0x001fcd16, + 0x00ae9004, 0xffb85140, 0x0041813a, + 0x007f8ed1, 0xffd585fc, 0x006a69e6, + 0x00000001 /* output gain */ +}; + +static u32 coef_48to8[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c9102, /* IIR Filter + Decimator */ + 0x00000e00, /* input gain */ + 0x00e2e000, 0xff6e1a00, 0x002aaa00, + 0x00610a00, 0xff5dda00, 0x003ccc00, + 0x00163a00, 0xff3c0400, 0x00633200, + 0x00000001, /* output gain */ + 0x00005105, /* IIR Filter + Decimator */ + 0x0000d649, /* input gain */ + 0x00e87afb, 0xff5f69d0, 0x003df3cf, + 0x007ce488, 0xff99a5c8, 0x0056a6a0, + 0x00344928, 0xffcba3e5, 0x006be470, + 0x00137aa7, 0xffe60276, 0x00773410, + 0x0005fa2a, 0xfff1ac11, 0x007c795b, + 0x00012d36, 0xfff5eca2, 0x007f10ef, + 0x00000001 /* ouptut gain */ +}; + +static u32 coef_48to16[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00009105, /* IIR Filter + Decimator */ + 0x00000784, /* input gain */ + 0x00cc516e, 0xff2c9639, 0x005ad5b3, + 0x0013ad0d, 0xff3d4799, 0x0063ce75, + 0xffb6f398, 0xff5138d1, 0x006e9e1f, + 0xff9186e5, 0xff5f96a4, 0x0076a86e, + 0xff82089c, 0xff676b81, 0x007b9f8a, + 0xff7c48a5, 0xff6a31e7, 0x007ebb7b, + 0x00000001 /* output gain */ +}; + +static u32 coef_48to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x0001d029, /* input gain */ + 0x00f2a98b, 0xff92aa71, 0x001fcd16, + 0x00ae9004, 0xffb85140, 0x0041813a, + 0x007f8ed1, 0xffd585fc, 0x006a69e6, + 0x00000002, /* output gain */ + 0x001b6103, /* header */ + 0x000001e0, /* input gain */ + 0x00de44c0, 0xff380b7f, 0x004ffc73, + 0x00494b44, 0xff3d493a, 0x005908bf, + 0xffe9a3c8, 0xff425647, 0x006745f7, + 0xffc42d61, 0xff40a6c7, 0x00776709, + 0x00000002, /* output gain */ + 0x00265204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_48to96[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00006102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002 /* output gain */ +}; + +static u32 coef_48to192[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000002, /* output gain */ + 0x00006102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000002 /* output gain */ +}; + +static u32 coef_88to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_88to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x00001685, /* input gain */ + 0x00f53ae9, 0xff52f196, 0x003e3e08, + 0x00b9f857, 0xff5d8985, 0x0050070a, + 0x008c3e86, 0xff6053f0, 0x006d98ef, + 0x00000002, /* output gain */ + 0x00175204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_96to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000f6103, /* header */ + 0x000001e0, /* input gain */ + 0x00de44c0, 0xff380b7f, 0x004ffc73, + 0x00494b44, 0xff3d493a, 0x005908bf, + 0xffe9a3c8, 0xff425647, 0x006745f7, + 0xffc42d61, 0xff40a6c7, 0x00776709, + 0x00000002, /* output gain */ + 0x001a5204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_96to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_176to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c5102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000001, /* output gain */ + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_176to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c0102, /* header */ + 0x00001685, /* input gain */ + 0x00f53ae9, 0xff52f196, 0x003e3e08, + 0x00b9f857, 0xff5d8985, 0x0050070a, + 0x008c3e86, 0xff6053f0, 0x006d98ef, + 0x00000001, /* output gain */ + 0x00175204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00005102,/* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_192to44[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c6102, /* header */ + 0x000000af, /* input gain */ + 0x00c65663, 0xff23d2ce, 0x005f97d6, + 0x00086ad6, 0xff20ec4f, 0x00683201, + 0xffbbbef6, 0xff184447, 0x00770963, + 0x00000002, /* output gain */ + 0x00175204, /* farrow */ + 0x000aaaab, + 0xffaaaaab, + 0xfffaaaab, + 0x00555555, + 0xff600000, + 0xfff55555, + 0x00155555, + 0x00055555, + 0xffeaaaab, + 0x00200000, + 0x00235102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000001, /* output gain */ + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +static u32 coef_192to48[TEGRA210_SFC_COEF_RAM_DEPTH] = { + 0x000c5102, /* header */ + 0x000013d9, /* input gain */ + 0x00ebd477, 0xff4ce383, 0x0042049d, + 0x0089c278, 0xff54414d, 0x00531ded, + 0x004a5e07, 0xff53cf41, 0x006efbdc, + 0x00000001, /* output gain */ + 0x00005102, /* header */ + 0x0001d727, /* input gain */ + 0x00fc2fc7, 0xff9bb27b, 0x001c564c, + 0x00e55557, 0xffcadd5b, 0x003d80ba, + 0x00d13397, 0xfff232f8, 0x00683337, + 0x00000001 /* output gain */ +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_spdif_alt.h b/sound/soc/tegra-alt/include/tegra210_spdif_alt.h new file mode 100644 index 00000000..970af7dd --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_spdif_alt.h @@ -0,0 +1,269 @@ +/* + * tegra210_spdif.h - Definitions for Tegra210 SPDIF driver + * + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_SPDIF_ALT_H__ +#define __TEGRA210_SPDIF_ALT_H__ + +/* Register offsets from TEGRA_SPDIF_BASE */ + +#define TEGRA210_SPDIF_CTRL 0x0 +#define TEGRA210_SPDIF_STROBE_CTRL 0x4 +#define TEGRA210_SPDIF_CIF_TXD_CTRL 0x08 +#define TEGRA210_SPDIF_CIF_RXD_CTRL 0x0C +#define TEGRA210_SPDIF_CIF_TXU_CTRL 0x10 +#define TEGRA210_SPDIF_CIF_RXU_CTRL 0x14 +#define TEGRA210_SPDIF_CH_STA_RX_A 0x18 +#define TEGRA210_SPDIF_CH_STA_RX_B 0x1C +#define TEGRA210_SPDIF_CH_STA_RX_C 0x20 +#define TEGRA210_SPDIF_CH_STA_RX_D 0x24 +#define TEGRA210_SPDIF_CH_STA_RX_E 0x28 +#define TEGRA210_SPDIF_CH_STA_RX_F 0x2C +#define TEGRA210_SPDIF_CH_STA_TX_A 0x30 +#define TEGRA210_SPDIF_CH_STA_TX_B 0x34 +#define TEGRA210_SPDIF_CH_STA_TX_C 0x38 +#define TEGRA210_SPDIF_CH_STA_TX_D 0x3C +#define TEGRA210_SPDIF_CH_STA_TX_E 0x40 +#define TEGRA210_SPDIF_CH_STA_TX_F 0x44 +#define TEGRA210_SPDIF_FLOWCTL_CTRL 0x70 +#define TEGRA210_SPDIF_TX_STEP 0x74 +#define TEGRA210_SPDIF_FLOW_STATUS 0x78 +#define TEGRA210_SPDIF_FLOW_TOTAL 0x7c +#define TEGRA210_SPDIF_FLOW_OVER 0x80 +#define TEGRA210_SPDIF_FLOW_UNDER 0x84 +#define TEGRA210_SPDIF_LCOEF_1_4_0 0x88 +#define TEGRA210_SPDIF_LCOEF_1_4_1 0x8c +#define TEGRA210_SPDIF_LCOEF_1_4_2 0x90 +#define TEGRA210_SPDIF_LCOEF_1_4_3 0x94 +#define TEGRA210_SPDIF_LCOEF_1_4_4 0x98 +#define TEGRA210_SPDIF_LCOEF_1_4_5 0x9c +#define TEGRA210_SPDIF_LCOEF_2_4_0 0xa0 +#define TEGRA210_SPDIF_LCOEF_2_4_1 0xa4 +#define TEGRA210_SPDIF_LCOEF_2_4_2 0xa8 + +/* Fields in TEGRA210_SPDIF_CTRL */ +#define TEGRA210_SPDIF_CTRL_FLOWCTL_EN_ENABLE (1<<31) +#define TEGRA210_SPDIF_CTRL_CAP_LC_LEFT_CH (1<<30) +#define TEGRA210_SPDIF_CTRL_RX_EN_ENABLE (1<<29) +#define TEGRA210_SPDIF_CTRL_TX_EN_ENABLE (1<<28) +#define TEGRA210_SPDIF_CTRL_TC_EN_ENABLE (1<<27) +#define TEGRA210_SPDIF_CTRL_TU_EN_ENABLE (1<<26) +#define TEGRA210_SPDIF_CTRL_IE_P_RSVD_ENABLE (1<<23) +#define TEGRA210_SPDIF_CTRL_IE_B_RSVD_ENABLE (1<<22) +#define TEGRA210_SPDIF_CTRL_IE_C_RSVD_ENABLE (1<<21) +#define TEGRA210_SPDIF_CTRL_IE_U_RSVD_ENABLE (1<<20) +#define TEGRA210_SPDIF_CTRL_LBK_EN_ENABLE_MASK (1<<15) +#define TEGRA210_SPDIF_CTRL_LBK_EN_ENABLE_SHIFT 15 +#define TEGRA210_SPDIF_CTRL_PACK_ENABLE (1<<14) + +#define TEGRA210_SPDIF_BIT_MODE16 0 +#define TEGRA210_SPDIF_BIT_MODE20 1 +#define TEGRA210_SPDIF_BIT_MODE24 2 +#define TEGRA210_SPDIF_BIT_MODERAW 3 + +#define TEGRA210_SPDIF_CTRL_BIT_MODE_SHIFT 12 +#define TEGRA210_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA210_SPDIF_CTRL_BIT_MODE_SHIFT) +#define TEGRA210_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA210_SPDIF_BIT_MODE16 << TEGRA210_SPDIF_CTRL_BIT_MODE_SHIFT) +#define TEGRA210_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA210_SPDIF_BIT_MODE20 << TEGRA210_SPDIF_CTRL_BIT_MODE_SHIFT) +#define TEGRA210_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA210_SPDIF_BIT_MODE24 << TEGRA210_SPDIF_CTRL_BIT_MODE_SHIFT) +#define TEGRA210_SPDIF_CTRL_BIT_MODE_RAW (TEGRA210_SPDIF_BIT_MODERAW << TEGRA210_SPDIF_CTRL_BIT_MODE_SHIFT) + +#define TEGRA210_SPDIF_CTRL_CG_EN_ENABLE (1<<11) + +#define TEGRA210_SPDIF_CTRL_OBS_SEL_SHIFT 8 +#define TEGRA210_SPDIF_CTRL_OBS_SEL_NASK (0x7 << TEGRA210_SPDIF_CTRL_OBS_SEL_SHIFT) + +#define TEGRA210_SPDIF_CTRL_SOFT_RESET_ENABLE (1<<7) + +/* Fields in TEGRA210_SPDIF_STROBE_CTRL */ +#define TEGRA210_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16 +#define TEGRA210_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA210_SPDIF_STROBE_CTRL_PERIOD_SHIFT) + +#define TEGRA210_SPDIF_STROBE_CTRL_STROBE (1<<15) + +#define TEGRA210_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8 +#define TEGRA210_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA210_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT) + +#define TEGRA210_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0 +#define TEGRA210_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA210_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT) + +/* + * The 6-word receive channel data page buffer holds a block (192 frames) of + * channel status information. The order of receive is from LSB to MSB + * bit, and from CH_STA_RX_A to CH_STA_RX_F then back to CH_STA_RX_A. + */ + +/* Fields in TEGRA210_SPDIF_CH_STA_TX_A */ +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_22050 0x4 +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_24000 0x6 +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_32000 0x3 +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_44100 0x0 +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_48000 0x2 +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_88200 0x8 +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_96000 0xA +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_176400 0xC +#define TEGRA210_SPDIF_CH_STA_TX_A_SF_192000 0xE + +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT 24 +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_MASK \ + (0xF << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_22050 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_22050 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_24000 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_24000 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_32000 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_32000 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_44100 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_44100 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_48000 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_48000 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_88200 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_88200 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_96000 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_96000 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_176400 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_176400 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_192000 \ + (TEGRA210_SPDIF_CH_STA_TX_A_SF_192000 << TEGRA210_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT) + +/* Fields in TEGRA210_SPDIF_CH_STA_TX_B */ +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_8000 0x6 +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_11025 0xA +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_12000 0x2 +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_16000 0x8 +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_22050 0xB +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_24000 0x9 +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_32000 0xC +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_44100 0xF +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_48000 0xD +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_88200 0x7 +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_96000 0x5 +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_176400 0x3 +#define TEGRA210_SPDIF_CH_STA_TX_B_SF_192000 0x1 + +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT 4 +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_MASK \ + (0xF << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_8000 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_8000 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_11025 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_11025 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_12000 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_12000 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_16000 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_16000 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_22050 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_22025 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_24000 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_24000 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_32000 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_32000 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_44100 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_44100 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_48000 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_48000 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_88200 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_88200 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_96000 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_96000 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_176400 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_176400 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) +#define TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_192000 \ + (TEGRA210_SPDIF_CH_STA_TX_B_SF_192000 << TEGRA210_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT) + +/* Fields in TEGRA210_SPDIF_CH_STA_TX_C */ +/* Fields in TEGRA210_SPDIF_CH_STA_TX_D */ +/* Fields in TEGRA210_SPDIF_CH_STA_TX_E */ +/* Fields in TEGRA210_SPDIF_CH_STA_TX_F */ + +/* Fields in TEGRA210_SPDIF_FLOWCTL_CTRL */ +#define TEGRA210_SPDIF_FLOWCTL_CTRL_FILTER_QUAD (1<<31) + +/* Fields in TEGRA210_SPDIF_TX_STEP */ +#define TEGRA210_SPDIF_TX_STEP_STEP_SIZE_SHIFT 0 +#define TEGRA210_SPDIF_TX_STEP_STEP_SIZE_MASK (0xffff << TEGRA210_SPDIF_TX_STEP_STEP_SIZE_SHIFT) + +/* Fields in TEGRA210_SPDIF_FLOW_STATUS */ +#define TEGRA210_SPDIF_FLOW_STATUS_COUNTER_EN_ENABLE (1<<1) +#define TEGRA210_SPDIF_FLOW_STATUS_MONITOR_CLR_CLEAR (1<<2) +#define TEGRA210_SPDIF_FLOW_STATUS_COUNTER_CLR_CLEAR (1<<3) +#define TEGRA210_SPDIF_FLOW_STATUS_MONITOR_INT_EN_ENABLE (1<<4) +#define TEGRA210_SPDIF_FLOW_STATUS_FLOW_OVERFLOW_OVER (1<<30) +#define TEGRA210_SPDIF_FLOW_STATUS_FLOW_UNDERFLOW_UNDER (1<<31) + +/* Fields in TEGRA210_SPDIF_FLOW_TOTAL */ +/* Fields in TEGRA210_SPDIF_FLOW_OVER */ +/* Fields in TEGRA210_SPDIF_FLOW_UNDER */ + +/* Fields in TEGRA210_SPDIF_LCOEF_1_4_0 */ +#define TEGRA210_SPDIF_LCOEF_1_4_0_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_1_4_0_COEF_MASK (0xffff << TEGRA30_TEGRA210_SPDIF_LCOEF_1_4_0_COEF_SHIFT) + +/* Fields in TEGRA210_SPDIF_LCOEF_1_4_1 */ +#define TEGRA210_SPDIF_LCOEF_1_4_1_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_1_4_1_COEF_MASK (0xffff << TEGRA210_SPDIF_LCOEF_1_4_1_COEF_SHIFT) + +/* Fields in TEGRA210_SPDIF_LCOEF_1_4_2 */ +#define TEGRA210_SPDIF_LCOEF_1_4_2_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_1_4_2_COEF_MASK (0xffff << TEGRA210_SPDIF_LCOEF_1_4_2_COEF_SHIFT) + +/* Fields in TEGRA210_SPDIF_LCOEF_1_4_3 */ +#define TEGRA210_SPDIF_LCOEF_1_4_3_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_1_4_3_COEF_MASK (0xffff << TEGRA210_SPDIF_LCOEF_1_4_3_COEF_SHIFT) + +/* Fields in TEGRA210_SPDIF_LCOEF_1_4_4 */ +#define TEGRA210_SPDIF_LCOEF_1_4_4_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_1_4_4_COEF_MASK (0xffff << TEGRA210_SPDIF_LCOEF_1_4_4_COEF_SHIFT) + +/* Fields in TEGRA210_SPDIF_LCOEF_1_4_5 */ +#define TEGRA210_SPDIF_LCOEF_1_4_5_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_1_4_5_COEF_MASK (0xffff << TEGRA210_SPDIF_LCOEF_1_4_5_COEF_SHIFT) + +/* Fields in TEGRA210_SPDIF_LCOEF_2_4_0 */ +#define TEGRA210_SPDIF_LCOEF_2_4_0_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_2_4_0_COEF_MASK (0xffff << TEGRA210_SPDIF_LCOEF_2_4_0_COEF_SHIFT) + +/* Fields in TEGRA210_SPDIF_LCOEF_2_4_1 */ +#define TEGRA210_SPDIF_LCOEF_2_4_1_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_2_4_1_COEF_MASK (0xffff << TEGRA210_SPDIF_LCOEF_2_4_1_COEF_SHIFT) + +/* Fields in TEGRA210_SPDIF_LCOEF_2_4_2 */ +#define TEGRA210_SPDIF_LCOEF_2_4_2_COEF_SHIFT 0 +#define TEGRA210_SPDIF_LCOEF_2_4_2_COEF_MASK (0xffff << TEGRA210_SPDIF_LCOEF_2_4_2_COEF_SHIFT) + +struct tegra210_spdif_soc_data { + void (*set_audio_cif)(struct regmap *map, + unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +}; + +struct tegra210_spdif { + struct clk *clk_spdif_out; + struct clk *clk_spdif_in; + struct clk *clk_pll_a_out0; + struct clk *clk_pll_p_out0; + struct regmap *regmap; + unsigned int loopback; + const struct tegra210_spdif_soc_data *soc_data; + int is_pinctrl; + struct pinctrl *pinctrl; + struct pinctrl_state *pin_active_state; + struct pinctrl_state *pin_idle_state; + bool is_shutdown; +}; + +#endif diff --git a/sound/soc/tegra-alt/include/tegra210_xbar_alt.h b/sound/soc/tegra-alt/include/tegra210_xbar_alt.h new file mode 100644 index 00000000..c0df3a72 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra210_xbar_alt.h @@ -0,0 +1,303 @@ +/* + * tegra210_xbar_alt.h - TEGRA210 XBAR registers + * + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA210_XBAR_ALT_H__ +#define __TEGRA210_XBAR_ALT_H__ + +#define TEGRA210_XBAR_PART0_RX 0x0 +#define TEGRA210_XBAR_PART1_RX 0x200 +#define TEGRA210_XBAR_PART2_RX 0x400 +#define TEGRA210_XBAR_RX_STRIDE 0x4 +#define TEGRA210_XBAR_AUDIO_RX_COUNT 90 + +/* This register repeats twice for each XBAR TX CIF */ +/* The fields in this register are 1 bit per XBAR RX CIF */ + +/* Fields in *_CIF_RX/TX_CTRL; used by AHUB FIFOs, and all other audio modules */ + +#define TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT 24 +#define TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US 0x3f +#define TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK (TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US << TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) + +/* Channel count minus 1 */ +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT 20 +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US 0xf +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK (TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US << TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) + +/* Channel count minus 1 */ +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT 16 +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US 0xf +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK (TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US << TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) + +#define TEGRA210_AUDIOCIF_BITS_RVDS 0 +#define TEGRA210_AUDIOCIF_BITS_8 1 +#define TEGRA210_AUDIOCIF_BITS_12 2 +#define TEGRA210_AUDIOCIF_BITS_16 3 +#define TEGRA210_AUDIOCIF_BITS_20 4 +#define TEGRA210_AUDIOCIF_BITS_24 5 +#define TEGRA210_AUDIOCIF_BITS_28 6 +#define TEGRA210_AUDIOCIF_BITS_32 7 + +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT 12 +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_MASK (7 << TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_8 (TEGRA210_AUDIOCIF_BITS_8 << TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_12 (TEGRA210_AUDIOCIF_BITS_12 << TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_16 (TEGRA210_AUDIOCIF_BITS_16 << TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_20 (TEGRA210_AUDIOCIF_BITS_20 << TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_24 (TEGRA210_AUDIOCIF_BITS_24 << TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_28 (TEGRA210_AUDIOCIF_BITS_28 << TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_32 (TEGRA210_AUDIOCIF_BITS_32 << TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) + +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT 8 +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_MASK (7 << TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_8 (TEGRA210_AUDIOCIF_BITS_8 << TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_12 (TEGRA210_AUDIOCIF_BITS_12 << TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_16 (TEGRA210_AUDIOCIF_BITS_16 << TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_20 (TEGRA210_AUDIOCIF_BITS_20 << TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_24 (TEGRA210_AUDIOCIF_BITS_24 << TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_28 (TEGRA210_AUDIOCIF_BITS_28 << TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_32 (TEGRA210_AUDIOCIF_BITS_32 << TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) + +#define TEGRA210_AUDIOCIF_EXPAND_ZERO 0 +#define TEGRA210_AUDIOCIF_EXPAND_ONE 1 +#define TEGRA210_AUDIOCIF_EXPAND_LFSR 2 + +#define TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT 6 +#define TEGRA210_AUDIOCIF_CTRL_EXPAND_MASK (3 << TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_EXPAND_ZERO (TEGRA210_AUDIOCIF_EXPAND_ZERO << TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_EXPAND_ONE (TEGRA210_AUDIOCIF_EXPAND_ONE << TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_EXPAND_LFSR (TEGRA210_AUDIOCIF_EXPAND_LFSR << TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT) + +#define TEGRA210_AUDIOCIF_STEREO_CONV_CH0 0 +#define TEGRA210_AUDIOCIF_STEREO_CONV_CH1 1 +#define TEGRA210_AUDIOCIF_STEREO_CONV_AVG 2 + +#define TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT 4 +#define TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_MASK (3 << TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_CH0 (TEGRA210_AUDIOCIF_STEREO_CONV_CH0 << TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_CH1 (TEGRA210_AUDIOCIF_STEREO_CONV_CH1 << TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_AVG (TEGRA210_AUDIOCIF_STEREO_CONV_AVG << TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) + +#define TEGRA210_AUDIOCIF_CTRL_REPLICATE_SHIFT 3 + +#define TEGRA210_AUDIOCIF_TRUNCATE_ROUND 0 +#define TEGRA210_AUDIOCIF_TRUNCATE_CHOP 1 + +#define TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT 1 +#define TEGRA210_AUDIOCIF_CTRL_TRUNCATE_MASK (1 << TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_TRUNCATE_ROUND (TEGRA210_AUDIOCIF_TRUNCATE_ROUND << TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_TRUNCATE_CHOP (TEGRA210_AUDIOCIF_TRUNCATE_CHOP << TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT) + +#define TEGRA210_AUDIOCIF_MONO_CONV_ZERO 0 +#define TEGRA210_AUDIOCIF_MONO_CONV_COPY 1 + +#define TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT 0 +#define TEGRA210_AUDIOCIF_CTRL_MONO_CONV_MASK (1 << TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_MONO_CONV_ZERO (TEGRA210_AUDIOCIF_MONO_CONV_ZERO << TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT) +#define TEGRA210_AUDIOCIF_CTRL_MONO_CONV_COPY (TEGRA210_AUDIOCIF_MONO_CONV_COPY << TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT) + +/* Fields in *AHUBRAMCTL_CTRL; used by different AHUB modules */ +#define TEGRA210_AHUBRAMCTL_CTRL_READ_BUSY_SHIFT 31 +#define TEGRA210_AHUBRAMCTL_CTRL_READ_BUSY_MASK (1 << TEGRA210_AHUBRAMCTL_CTRL_READ_BUSY_SHIFT) +#define TEGRA210_AHUBRAMCTL_CTRL_READ_BUSY (1 << TEGRA210_AHUBRAMCTL_CTRL_READ_BUSY_SHIFT) + +#define TEGRA210_AHUBRAMCTL_CTRL_SEQ_READ_COUNT_SHIFT 16 +#define TEGRA210_AHUBRAMCTL_CTRL_SEQ_READ_COUNT_MASK (0xff << TEGRA210_AHUBRAMCTL_CTRL_SEQ_READ_COUNT_SHIFT) + +#define TEGRA210_AHUBRAMCTL_CTRL_RW_SHIFT 14 +#define TEGRA210_AHUBRAMCTL_CTRL_RW_MASK (1 << TEGRA210_AHUBRAMCTL_CTRL_RW_SHIFT) +#define TEGRA210_AHUBRAMCTL_CTRL_RW_READ (0 << TEGRA210_AHUBRAMCTL_CTRL_RW_SHIFT) +#define TEGRA210_AHUBRAMCTL_CTRL_RW_WRITE (1 << TEGRA210_AHUBRAMCTL_CTRL_RW_SHIFT) + +#define TEGRA210_AHUBRAMCTL_CTRL_ADDR_INIT_EN_SHIFT 13 +#define TEGRA210_AHUBRAMCTL_CTRL_ADDR_INIT_EN_MASK (1 << TEGRA210_AHUBRAMCTL_CTRL_ADDR_INIT_EN_SHIFT) +#define TEGRA210_AHUBRAMCTL_CTRL_ADDR_INIT_EN (1 << TEGRA210_AHUBRAMCTL_CTRL_ADDR_INIT_EN_SHIFT) + +#define TEGRA210_AHUBRAMCTL_CTRL_SEQ_ACCESS_EN_SHIFT 12 +#define TEGRA210_AHUBRAMCTL_CTRL_SEQ_ACCESS_EN_MASK (1 << TEGRA210_AHUBRAMCTL_CTRL_SEQ_ACCESS_EN_SHIFT) +#define TEGRA210_AHUBRAMCTL_CTRL_SEQ_ACCESS_EN (1 << TEGRA210_AHUBRAMCTL_CTRL_SEQ_ACCESS_EN_SHIFT) + +#define TEGRA210_AHUBRAMCTL_CTRL_RAM_ADDR_SHIFT 0 +#define TEGRA210_AHUBRAMCTL_CTRL_RAM_ADDR_MASK (0x1ff << TEGRA210_AHUBRAMCTL_CTRL_RAM_ADDR_SHIFT) + +#define TEGRA210_NUM_DAIS 69 +#define TEGRA210_NUM_MUX_WIDGETS 52 +#define TEGRA210_NUM_MUX_INPUT 56 /* size of TEGRA210_ROUTES */ +#define TEGRA186_NUM_DAIS 110 +#define TEGRA186_NUM_MUX_WIDGETS 81 +#define TEGRA186_NUM_MUX_INPUT 84 /* size of TEGRA_ROUTES + TEGRA186_ROUTES */ + +#define TEGRA210_MAX_REGISTER_ADDR (TEGRA210_XBAR_PART2_RX +\ + (TEGRA210_XBAR_RX_STRIDE * (TEGRA210_XBAR_AUDIO_RX_COUNT - 1))) + +#define TEGRA186_XBAR_PART3_RX 0x600 +#define TEGRA186_XBAR_AUDIO_RX_COUNT 115 +#define TEGRA186_AUDIOCIF_CTRL_FIFO_SIZE_DOWNSHIFT_SHIFT 2 + +#define TEGRA186_MAX_REGISTER_ADDR (TEGRA186_XBAR_PART3_RX +\ + (TEGRA210_XBAR_RX_STRIDE * (TEGRA186_XBAR_AUDIO_RX_COUNT - 1))) + +#define TEGRA210_XBAR_REG_MASK_0 0xf1f03ff +#define TEGRA210_XBAR_REG_MASK_1 0x3f30031f +#define TEGRA210_XBAR_REG_MASK_2 0xff1cf313 +#define TEGRA210_XBAR_REG_MASK_3 0x0 +#define TEGRA210_XBAR_UPDATE_MAX_REG 3 + +#define TEGRA186_XBAR_REG_MASK_0 0xF3FFFFF +#define TEGRA186_XBAR_REG_MASK_1 0x3F310F1F +#define TEGRA186_XBAR_REG_MASK_2 0xFF3CF311 +#define TEGRA186_XBAR_REG_MASK_3 0x3F0F00FF +#define TEGRA186_XBAR_UPDATE_MAX_REG 4 + +#define TEGRA_XBAR_UPDATE_MAX_REG (TEGRA186_XBAR_UPDATE_MAX_REG) + +/* T210 Modules Base address */ +#define T210_ADMAIF_BASE_ADDR 0x702d0000 +#define T210_I2S1_BASE_ADDR 0x702d1000 +#define T210_I2S2_BASE_ADDR 0x702d1100 +#define T210_I2S3_BASE_ADDR 0x702d1200 +#define T210_I2S4_BASE_ADDR 0x702d1300 +#define T210_I2S5_BASE_ADDR 0x702d1400 +#define T210_AMX1_BASE_ADDR 0x702d3000 +#define T210_AMX2_BASE_ADDR 0x702d3100 +#define T210_ADX1_BASE_ADDR 0x702d3800 +#define T210_ADX2_BASE_ADDR 0x702d3900 +#define T210_AFC1_BASE_ADDR 0x702d7000 +#define T210_AFC2_BASE_ADDR 0x702d7100 +#define T210_AFC3_BASE_ADDR 0x702d7200 +#define T210_AFC4_BASE_ADDR 0x702d7300 +#define T210_AFC5_BASE_ADDR 0x702d7400 +#define T210_AFC6_BASE_ADDR 0x702d7500 +#define T210_SFC1_BASE_ADDR 0x702d2000 +#define T210_SFC2_BASE_ADDR 0x702d2200 +#define T210_SFC3_BASE_ADDR 0x702d2400 +#define T210_SFC4_BASE_ADDR 0x702d2600 +#define T210_MVC1_BASE_ADDR 0x702da000 +#define T210_MVC2_BASE_ADDR 0x702da200 +#define T210_IQC1_BASE_ADDR 0x702de000 +#define T210_IQC2_BASE_ADDR 0x702de200 +#define T210_DMIC1_BASE_ADDR 0x702d4000 +#define T210_DMIC2_BASE_ADDR 0x702d4100 +#define T210_DMIC3_BASE_ADDR 0x702d4200 +#define T210_OPE1_BASE_ADDR 0x702d8000 +#define T210_OPE2_BASE_ADDR 0x702d8400 +#define T210_AMIXER1_BASE_ADDR 0x702dbb00 +#define T210_SPDIF1_BASE_ADDR 0x702d6000 + +/* T186 Modules Base address */ +#define T186_ADMAIF_BASE_ADDR 0x0290F000 +#define T186_I2S1_BASE_ADDR 0x02901000 +#define T186_I2S2_BASE_ADDR 0x02901100 +#define T186_I2S3_BASE_ADDR 0x02901200 +#define T186_I2S4_BASE_ADDR 0x02901300 +#define T186_I2S5_BASE_ADDR 0x02901400 +#define T186_I2S6_BASE_ADDR 0x02901500 +#define T186_AMX1_BASE_ADDR 0x02903000 +#define T186_AMX2_BASE_ADDR 0x02903100 +#define T186_AMX3_BASE_ADDR 0x02903200 +#define T186_AMX4_BASE_ADDR 0x02903300 +#define T186_ADX1_BASE_ADDR 0x02903800 +#define T186_ADX2_BASE_ADDR 0x02903900 +#define T186_ADX3_BASE_ADDR 0x02903a00 +#define T186_ADX4_BASE_ADDR 0x02903b00 +#define T186_AFC1_BASE_ADDR 0x02907000 +#define T186_AFC2_BASE_ADDR 0x02907100 +#define T186_AFC3_BASE_ADDR 0x02907200 +#define T186_AFC4_BASE_ADDR 0x02907300 +#define T186_AFC5_BASE_ADDR 0x02907400 +#define T186_AFC6_BASE_ADDR 0x02907500 +#define T186_SFC1_BASE_ADDR 0x02902000 +#define T186_SFC2_BASE_ADDR 0x02902200 +#define T186_SFC3_BASE_ADDR 0x02902400 +#define T186_SFC4_BASE_ADDR 0x02902600 +#define T186_MVC1_BASE_ADDR 0x0290A000 +#define T186_MVC2_BASE_ADDR 0x0290A200 +#define T186_IQC1_BASE_ADDR 0x0290E000 +#define T186_IQC2_BASE_ADDR 0x0290E200 +#define T186_DMIC1_BASE_ADDR 0x02904000 +#define T186_DMIC2_BASE_ADDR 0x02904100 +#define T186_DMIC3_BASE_ADDR 0x02904200 +#define T186_DMIC4_BASE_ADDR 0x02904300 +#define T186_OPE1_BASE_ADDR 0x02908000 +#define T186_AMIXER1_BASE_ADDR 0x0290BB00 +#define T186_SPDIF1_BASE_ADDR 0x02906000 +#define T186_ASRC1_BASE_ADDR 0x02910000 +#define T186_ARAD1_BASE_ADDR 0x0290E400 +#define T186_DSPK1_BASE_ADDR 0x02905000 +#define T186_DSPK2_BASE_ADDR 0x02905100 + + +struct tegra210_xbar_cif_conf { + unsigned int threshold; + unsigned int audio_channels; + unsigned int client_channels; + unsigned int audio_bits; + unsigned int client_bits; + unsigned int expand; + unsigned int stereo_conv; + union { + unsigned int fifo_size_downshift; + unsigned int replicate; + }; + unsigned int truncate; + unsigned int mono_conv; +}; + +struct tegra_xbar_soc_data { + const struct regmap_config *regmap_config; + unsigned int mask[4]; + unsigned int reg_count; + unsigned int reg_offset; + int (*xbar_registration)(struct platform_device *pdev); +}; + +struct tegra_xbar { + struct clk *clk; + struct clk *clk_parent; + struct clk *clk_ape; + struct clk *clk_apb2ape; + struct regmap *regmap; + const struct tegra_xbar_soc_data *soc_data; + bool is_shutdown; +}; + +/* Extension of soc_bytes structure defined in sound/soc.h */ +struct tegra_soc_bytes { + struct soc_bytes soc; + u32 shift; /* Used as offset for ahub ram related programing */ +}; + +int tegra210_xbar_set_clock(unsigned long rate); +void tegra210_xbar_set_cif(struct regmap *regmap, unsigned int reg, + struct tegra210_xbar_cif_conf *conf); +void tegra210_xbar_write_ahubram(struct regmap *regmap, unsigned int reg_ctrl, + unsigned int reg_data, unsigned int ram_offset, + unsigned int *data, size_t size); +void tegra210_xbar_read_ahubram(struct regmap *regmap, unsigned int reg_ctrl, + unsigned int reg_data, unsigned int ram_offset, + unsigned int *data, size_t size); + +/* Utility structures for using mixer control of type snd_soc_bytes */ +#define TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, \ + xhandler_get, xhandler_put, xinfo) \ + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = xinfo, .get = xhandler_get, .put = xhandler_put, \ + .private_value = ((unsigned long)&(struct tegra_soc_bytes) \ + {.soc.base = xbase, .soc.num_regs = xregs, .soc.mask = xmask, \ + .shift = xshift })} +#endif diff --git a/sound/soc/tegra-alt/include/tegra_asoc_machine_alt.h b/sound/soc/tegra-alt/include/tegra_asoc_machine_alt.h new file mode 100644 index 00000000..8d6110b2 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra_asoc_machine_alt.h @@ -0,0 +1,441 @@ +/* + * tegra_asoc_machine_alt.h + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA_ASOC_MACHINE_ALT_H__ +#define __TEGRA_ASOC_MACHINE_ALT_H__ + +enum tegra210_xbar_dai_link { + TEGRA210_DAI_LINK_ADMAIF1, + TEGRA210_DAI_LINK_ADMAIF2, + TEGRA210_DAI_LINK_ADMAIF3, + TEGRA210_DAI_LINK_ADMAIF4, + TEGRA210_DAI_LINK_ADMAIF5, + TEGRA210_DAI_LINK_ADMAIF6, + TEGRA210_DAI_LINK_ADMAIF7, + TEGRA210_DAI_LINK_ADMAIF8, + TEGRA210_DAI_LINK_ADMAIF9, + TEGRA210_DAI_LINK_ADMAIF10, + TEGRA210_DAI_LINK_AMX1_1, + TEGRA210_DAI_LINK_AMX1_2, + TEGRA210_DAI_LINK_AMX1_3, + TEGRA210_DAI_LINK_AMX1_4, + TEGRA210_DAI_LINK_AMX1, + TEGRA210_DAI_LINK_AMX2_1, + TEGRA210_DAI_LINK_AMX2_2, + TEGRA210_DAI_LINK_AMX2_3, + TEGRA210_DAI_LINK_AMX2_4, + TEGRA210_DAI_LINK_AMX2, + TEGRA210_DAI_LINK_ADX1, + TEGRA210_DAI_LINK_ADX1_1, + TEGRA210_DAI_LINK_ADX1_2, + TEGRA210_DAI_LINK_ADX1_3, + TEGRA210_DAI_LINK_ADX1_4, + TEGRA210_DAI_LINK_ADX2, + TEGRA210_DAI_LINK_ADX2_1, + TEGRA210_DAI_LINK_ADX2_2, + TEGRA210_DAI_LINK_ADX2_3, + TEGRA210_DAI_LINK_ADX2_4, + TEGRA210_DAI_LINK_MIXER1_RX1, + TEGRA210_DAI_LINK_MIXER1_RX2, + TEGRA210_DAI_LINK_MIXER1_RX3, + TEGRA210_DAI_LINK_MIXER1_RX4, + TEGRA210_DAI_LINK_MIXER1_RX5, + TEGRA210_DAI_LINK_MIXER1_RX6, + TEGRA210_DAI_LINK_MIXER1_RX7, + TEGRA210_DAI_LINK_MIXER1_RX8, + TEGRA210_DAI_LINK_MIXER1_RX9, + TEGRA210_DAI_LINK_MIXER1_RX10, + TEGRA210_DAI_LINK_MIXER1_TX1, + TEGRA210_DAI_LINK_MIXER1_TX2, + TEGRA210_DAI_LINK_MIXER1_TX3, + TEGRA210_DAI_LINK_MIXER1_TX4, + TEGRA210_DAI_LINK_MIXER1_TX5, + TEGRA210_DAI_LINK_SFC1_RX, + TEGRA210_DAI_LINK_SFC1_TX, + TEGRA210_DAI_LINK_SFC2_RX, + TEGRA210_DAI_LINK_SFC2_TX, + TEGRA210_DAI_LINK_SFC3_RX, + TEGRA210_DAI_LINK_SFC3_TX, + TEGRA210_DAI_LINK_SFC4_RX, + TEGRA210_DAI_LINK_SFC4_TX, + TEGRA210_DAI_LINK_MVC1_RX, + TEGRA210_DAI_LINK_MVC1_TX, + TEGRA210_DAI_LINK_MVC2_RX, + TEGRA210_DAI_LINK_MVC2_TX, + TEGRA210_DAI_LINK_OPE1_RX, + TEGRA210_DAI_LINK_OPE1_TX, + TEGRA210_DAI_LINK_OPE2_RX, + TEGRA210_DAI_LINK_OPE2_TX, + TEGRA210_DAI_LINK_AFC1_RX, + TEGRA210_DAI_LINK_AFC1_TX, + TEGRA210_DAI_LINK_AFC2_RX, + TEGRA210_DAI_LINK_AFC2_TX, + TEGRA210_DAI_LINK_AFC3_RX, + TEGRA210_DAI_LINK_AFC3_TX, + TEGRA210_DAI_LINK_AFC4_RX, + TEGRA210_DAI_LINK_AFC4_TX, + TEGRA210_DAI_LINK_AFC5_RX, + TEGRA210_DAI_LINK_AFC5_TX, + TEGRA210_DAI_LINK_AFC6_RX, + TEGRA210_DAI_LINK_AFC6_TX, + TEGRA210_DAI_LINK_ADMAIF1_CODEC, + TEGRA210_DAI_LINK_ADMAIF2_CODEC, + TEGRA210_DAI_LINK_ADMAIF3_CODEC, + TEGRA210_DAI_LINK_ADMAIF4_CODEC, + TEGRA210_DAI_LINK_ADMAIF5_CODEC, + TEGRA210_DAI_LINK_ADMAIF6_CODEC, + TEGRA210_DAI_LINK_ADMAIF7_CODEC, + TEGRA210_DAI_LINK_ADMAIF8_CODEC, + TEGRA210_DAI_LINK_ADMAIF9_CODEC, + TEGRA210_DAI_LINK_ADMAIF10_CODEC, +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) + TEGRA210_DAI_LINK_ADSP_ADMAIF1, + TEGRA210_DAI_LINK_ADSP_ADMAIF2, + TEGRA210_DAI_LINK_ADSP_ADMAIF3, + TEGRA210_DAI_LINK_ADSP_ADMAIF4, + TEGRA210_DAI_LINK_ADSP_ADMAIF5, + TEGRA210_DAI_LINK_ADSP_ADMAIF6, + TEGRA210_DAI_LINK_ADSP_ADMAIF7, + TEGRA210_DAI_LINK_ADSP_ADMAIF8, + TEGRA210_DAI_LINK_ADSP_ADMAIF9, + TEGRA210_DAI_LINK_ADSP_ADMAIF10, + TEGRA210_DAI_LINK_ADSP_PCM1, + TEGRA210_DAI_LINK_ADSP_PCM2, + TEGRA210_DAI_LINK_ADSP_COMPR1, + TEGRA210_DAI_LINK_ADSP_COMPR2, +#endif + TEGRA210_XBAR_DAI_LINKS, /* Total number of xbar dai links */ +}; + +enum tegra210_xbar_codec_conf { + TEGRA210_CODEC_AMX1_CONF, + TEGRA210_CODEC_AMX2_CONF, + TEGRA210_CODEC_ADX1_CONF, + TEGRA210_CODEC_ADX2_CONF, + TEGRA210_CODEC_SFC1_CONF, + TEGRA210_CODEC_SFC2_CONF, + TEGRA210_CODEC_SFC3_CONF, + TEGRA210_CODEC_SFC4_CONF, + TEGRA210_CODEC_MVC1_CONF, + TEGRA210_CODEC_MVC2_CONF, + TEGRA210_CODEC_OPE1_CONF, + TEGRA210_CODEC_OPE2_CONF, + TEGRA210_CODEC_AFC1_CONF, + TEGRA210_CODEC_AFC2_CONF, + TEGRA210_CODEC_AFC3_CONF, + TEGRA210_CODEC_AFC4_CONF, + TEGRA210_CODEC_AFC5_CONF, + TEGRA210_CODEC_AFC6_CONF, + TEGRA210_CODEC_I2S1_CONF, + TEGRA210_CODEC_I2S2_CONF, + TEGRA210_CODEC_I2S3_CONF, + TEGRA210_CODEC_I2S4_CONF, + TEGRA210_CODEC_I2S5_CONF, + TEGRA210_CODEC_DMIC1_CONF, + TEGRA210_CODEC_DMIC2_CONF, + TEGRA210_CODEC_DMIC3_CONF, + TEGRA210_CODEC_SPDIF_CONF, + TEGRA210_XBAR_CODEC_CONF, /* Total number of xbar codec conf */ +}; + +enum tegra186_xbar_dai_link { + TEGRA186_DAI_LINK_ADMAIF1, + TEGRA186_DAI_LINK_ADMAIF2, + TEGRA186_DAI_LINK_ADMAIF3, + TEGRA186_DAI_LINK_ADMAIF4, + TEGRA186_DAI_LINK_ADMAIF5, + TEGRA186_DAI_LINK_ADMAIF6, + TEGRA186_DAI_LINK_ADMAIF7, + TEGRA186_DAI_LINK_ADMAIF8, + TEGRA186_DAI_LINK_ADMAIF9, + TEGRA186_DAI_LINK_ADMAIF10, + TEGRA186_DAI_LINK_ADMAIF11, + TEGRA186_DAI_LINK_ADMAIF12, + TEGRA186_DAI_LINK_ADMAIF13, + TEGRA186_DAI_LINK_ADMAIF14, + TEGRA186_DAI_LINK_ADMAIF15, + TEGRA186_DAI_LINK_ADMAIF16, + TEGRA186_DAI_LINK_ADMAIF17, + TEGRA186_DAI_LINK_ADMAIF18, + TEGRA186_DAI_LINK_ADMAIF19, + TEGRA186_DAI_LINK_ADMAIF20, + TEGRA186_DAI_LINK_ADMAIF1_CODEC, + TEGRA186_DAI_LINK_ADMAIF2_CODEC, + TEGRA186_DAI_LINK_ADMAIF3_CODEC, + TEGRA186_DAI_LINK_ADMAIF4_CODEC, + TEGRA186_DAI_LINK_ADMAIF5_CODEC, + TEGRA186_DAI_LINK_ADMAIF6_CODEC, + TEGRA186_DAI_LINK_ADMAIF7_CODEC, + TEGRA186_DAI_LINK_ADMAIF8_CODEC, + TEGRA186_DAI_LINK_ADMAIF9_CODEC, + TEGRA186_DAI_LINK_ADMAIF10_CODEC, + TEGRA186_DAI_LINK_ADMAIF11_CODEC, + TEGRA186_DAI_LINK_ADMAIF12_CODEC, + TEGRA186_DAI_LINK_ADMAIF13_CODEC, + TEGRA186_DAI_LINK_ADMAIF14_CODEC, + TEGRA186_DAI_LINK_ADMAIF15_CODEC, + TEGRA186_DAI_LINK_ADMAIF16_CODEC, + TEGRA186_DAI_LINK_ADMAIF17_CODEC, + TEGRA186_DAI_LINK_ADMAIF18_CODEC, + TEGRA186_DAI_LINK_ADMAIF19_CODEC, + TEGRA186_DAI_LINK_ADMAIF20_CODEC, + TEGRA186_DAI_LINK_AMX1_1, + TEGRA186_DAI_LINK_AMX1_2, + TEGRA186_DAI_LINK_AMX1_3, + TEGRA186_DAI_LINK_AMX1_4, + TEGRA186_DAI_LINK_AMX1, + TEGRA186_DAI_LINK_AMX2_1, + TEGRA186_DAI_LINK_AMX2_2, + TEGRA186_DAI_LINK_AMX2_3, + TEGRA186_DAI_LINK_AMX2_4, + TEGRA186_DAI_LINK_AMX2, + TEGRA186_DAI_LINK_AMX3_1, + TEGRA186_DAI_LINK_AMX3_2, + TEGRA186_DAI_LINK_AMX3_3, + TEGRA186_DAI_LINK_AMX3_4, + TEGRA186_DAI_LINK_AMX3, + TEGRA186_DAI_LINK_AMX4_1, + TEGRA186_DAI_LINK_AMX4_2, + TEGRA186_DAI_LINK_AMX4_3, + TEGRA186_DAI_LINK_AMX4_4, + TEGRA186_DAI_LINK_AMX4, + TEGRA186_DAI_LINK_ADX1, + TEGRA186_DAI_LINK_ADX1_1, + TEGRA186_DAI_LINK_ADX1_2, + TEGRA186_DAI_LINK_ADX1_3, + TEGRA186_DAI_LINK_ADX1_4, + TEGRA186_DAI_LINK_ADX2, + TEGRA186_DAI_LINK_ADX2_1, + TEGRA186_DAI_LINK_ADX2_2, + TEGRA186_DAI_LINK_ADX2_3, + TEGRA186_DAI_LINK_ADX2_4, + TEGRA186_DAI_LINK_ADX3, + TEGRA186_DAI_LINK_ADX3_1, + TEGRA186_DAI_LINK_ADX3_2, + TEGRA186_DAI_LINK_ADX3_3, + TEGRA186_DAI_LINK_ADX3_4, + TEGRA186_DAI_LINK_ADX4, + TEGRA186_DAI_LINK_ADX4_1, + TEGRA186_DAI_LINK_ADX4_2, + TEGRA186_DAI_LINK_ADX4_3, + TEGRA186_DAI_LINK_ADX4_4, + TEGRA186_DAI_LINK_MIXER1_RX1, + TEGRA186_DAI_LINK_MIXER1_RX2, + TEGRA186_DAI_LINK_MIXER1_RX3, + TEGRA186_DAI_LINK_MIXER1_RX4, + TEGRA186_DAI_LINK_MIXER1_RX5, + TEGRA186_DAI_LINK_MIXER1_RX6, + TEGRA186_DAI_LINK_MIXER1_RX7, + TEGRA186_DAI_LINK_MIXER1_RX8, + TEGRA186_DAI_LINK_MIXER1_RX9, + TEGRA186_DAI_LINK_MIXER1_RX10, + TEGRA186_DAI_LINK_MIXER1_TX1, + TEGRA186_DAI_LINK_MIXER1_TX2, + TEGRA186_DAI_LINK_MIXER1_TX3, + TEGRA186_DAI_LINK_MIXER1_TX4, + TEGRA186_DAI_LINK_MIXER1_TX5, + TEGRA186_DAI_LINK_SFC1_RX, + TEGRA186_DAI_LINK_SFC1_TX, + TEGRA186_DAI_LINK_SFC2_RX, + TEGRA186_DAI_LINK_SFC2_TX, + TEGRA186_DAI_LINK_SFC3_RX, + TEGRA186_DAI_LINK_SFC3_TX, + TEGRA186_DAI_LINK_SFC4_RX, + TEGRA186_DAI_LINK_SFC4_TX, + TEGRA186_DAI_LINK_MVC1_RX, + TEGRA186_DAI_LINK_MVC1_TX, + TEGRA186_DAI_LINK_MVC2_RX, + TEGRA186_DAI_LINK_MVC2_TX, + TEGRA186_DAI_LINK_OPE1_RX, + TEGRA186_DAI_LINK_OPE1_TX, + TEGRA186_DAI_LINK_AFC1_RX, + TEGRA186_DAI_LINK_AFC1_TX, + TEGRA186_DAI_LINK_AFC2_RX, + TEGRA186_DAI_LINK_AFC2_TX, + TEGRA186_DAI_LINK_AFC3_RX, + TEGRA186_DAI_LINK_AFC3_TX, + TEGRA186_DAI_LINK_AFC4_RX, + TEGRA186_DAI_LINK_AFC4_TX, + TEGRA186_DAI_LINK_AFC5_RX, + TEGRA186_DAI_LINK_AFC5_TX, + TEGRA186_DAI_LINK_AFC6_RX, + TEGRA186_DAI_LINK_AFC6_TX, + TEGRA186_DAI_LINK_ASRC1_RX1, + TEGRA186_DAI_LINK_ASRC1_RX2, + TEGRA186_DAI_LINK_ASRC1_RX3, + TEGRA186_DAI_LINK_ASRC1_RX4, + TEGRA186_DAI_LINK_ASRC1_RX5, + TEGRA186_DAI_LINK_ASRC1_RX6, + TEGRA186_DAI_LINK_ASRC1_RX7, + TEGRA186_DAI_LINK_ASRC1_TX1, + TEGRA186_DAI_LINK_ASRC1_TX2, + TEGRA186_DAI_LINK_ASRC1_TX3, + TEGRA186_DAI_LINK_ASRC1_TX4, + TEGRA186_DAI_LINK_ASRC1_TX5, + TEGRA186_DAI_LINK_ASRC1_TX6, +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) + TEGRA186_DAI_LINK_ADSP_ADMAIF1, + TEGRA186_DAI_LINK_ADSP_ADMAIF2, + TEGRA186_DAI_LINK_ADSP_ADMAIF3, + TEGRA186_DAI_LINK_ADSP_ADMAIF4, + TEGRA186_DAI_LINK_ADSP_ADMAIF5, + TEGRA186_DAI_LINK_ADSP_ADMAIF6, + TEGRA186_DAI_LINK_ADSP_ADMAIF7, + TEGRA186_DAI_LINK_ADSP_ADMAIF8, + TEGRA186_DAI_LINK_ADSP_ADMAIF9, + TEGRA186_DAI_LINK_ADSP_ADMAIF10, + TEGRA186_DAI_LINK_ADSP_ADMAIF11, + TEGRA186_DAI_LINK_ADSP_ADMAIF12, + TEGRA186_DAI_LINK_ADSP_ADMAIF13, + TEGRA186_DAI_LINK_ADSP_ADMAIF14, + TEGRA186_DAI_LINK_ADSP_ADMAIF15, + TEGRA186_DAI_LINK_ADSP_ADMAIF16, + TEGRA186_DAI_LINK_ADSP_ADMAIF17, + TEGRA186_DAI_LINK_ADSP_ADMAIF18, + TEGRA186_DAI_LINK_ADSP_ADMAIF19, + TEGRA186_DAI_LINK_ADSP_ADMAIF20, + TEGRA186_DAI_LINK_ADSP_PCM1, + TEGRA186_DAI_LINK_ADSP_PCM2, + TEGRA186_DAI_LINK_ADSP_COMPR1, + TEGRA186_DAI_LINK_ADSP_COMPR2, +#endif + TEGRA186_XBAR_DAI_LINKS, /* Total number of xbar dai links */ +}; + +enum tegra186_xbar_codec_conf { + TEGRA186_CODEC_AMX1_CONF, + TEGRA186_CODEC_AMX2_CONF, + TEGRA186_CODEC_AMX3_CONF, + TEGRA186_CODEC_AMX4_CONF, + TEGRA186_CODEC_ADX1_CONF, + TEGRA186_CODEC_ADX2_CONF, + TEGRA186_CODEC_ADX3_CONF, + TEGRA186_CODEC_ADX4_CONF, + TEGRA186_CODEC_SFC1_CONF, + TEGRA186_CODEC_SFC2_CONF, + TEGRA186_CODEC_SFC3_CONF, + TEGRA186_CODEC_SFC4_CONF, + TEGRA186_CODEC_MVC1_CONF, + TEGRA186_CODEC_MVC2_CONF, + TEGRA186_CODEC_OPE1_CONF, + TEGRA186_CODEC_AFC1_CONF, + TEGRA186_CODEC_AFC2_CONF, + TEGRA186_CODEC_AFC3_CONF, + TEGRA186_CODEC_AFC4_CONF, + TEGRA186_CODEC_AFC5_CONF, + TEGRA186_CODEC_AFC6_CONF, + TEGRA186_CODEC_I2S1_CONF, + TEGRA186_CODEC_I2S2_CONF, + TEGRA186_CODEC_I2S3_CONF, + TEGRA186_CODEC_I2S4_CONF, + TEGRA186_CODEC_I2S5_CONF, + TEGRA186_CODEC_I2S6_CONF, + TEGRA186_CODEC_DMIC1_CONF, + TEGRA186_CODEC_DMIC2_CONF, + TEGRA186_CODEC_DMIC3_CONF, + TEGRA186_CODEC_DMIC4_CONF, + TEGRA186_CODEC_SPDIF_CONF, + TEGRA186_CODEC_DSPK1_CONF, + TEGRA186_CODEC_DSPK2_CONF, + TEGRA186_CODEC_ASRC1_CONF, + TEGRA186_XBAR_CODEC_CONF, /* Total number of xbar codec conf */ +}; + +struct snd_soc_dai_link *tegra_machine_get_dai_link(void); + +void tegra_machine_remove_dai_link(void); + +int tegra_machine_append_dai_link(struct snd_soc_dai_link *link, + unsigned int link_size); + +void tegra_machine_set_dai_ops(int link, struct snd_soc_ops *ops); + +void tegra_machine_set_dai_compr_ops(int link, struct snd_soc_compr_ops *ops); + +void tegra_machine_set_dai_init(int link, void *ptr); + +void tegra_machine_set_dai_params(int link, + struct snd_soc_pcm_stream *params); + +void tegra_machine_set_dai_fmt(int link, unsigned int fmt); + +struct snd_soc_codec_conf *tegra_machine_get_codec_conf(void); + +void tegra_machine_remove_codec_conf(void); + +int tegra_machine_append_codec_conf(struct snd_soc_codec_conf *conf, + unsigned int conf_size); + +struct snd_soc_dai_link *tegra_machine_new_codec_links( + struct platform_device *pdev, + struct snd_soc_dai_link *tegra_codec_links, + unsigned int *pnum_codec_links); + +struct snd_soc_codec_conf *tegra_machine_new_codec_conf( + struct platform_device *pdev, + struct snd_soc_codec_conf *tegra_codec_conf, + unsigned int *pnum_codec_links); + +unsigned int tegra_machine_get_codec_dai_link_idx(const char *codec_name); + +unsigned int tegra_machine_get_bclk_ratio( + struct snd_soc_pcm_runtime *rtd); +unsigned int tegra_machine_get_rx_mask( + struct snd_soc_pcm_runtime *rtd); +unsigned int tegra_machine_get_tx_mask( + struct snd_soc_pcm_runtime *rtd); + +void tegra_machine_set_num_dai_links(unsigned int val); + +unsigned int tegra_machine_get_num_dai_links(void); + +void tegra_machine_set_machine_links(struct snd_soc_dai_link *links); + +struct snd_soc_dai_link *tegra_machine_get_machine_links(void); + +void tegra_machine_set_machine_codec_conf(struct snd_soc_codec_conf *codec_conf); + +struct snd_soc_codec_conf *tegra_machine_get_machine_codec_conf(void); + +unsigned int *tegra_machine_get_bclk_ratio_array(void); +unsigned int *tegra_machine_get_rx_mask_array(void); +unsigned int *tegra_machine_get_tx_mask_array(void); + +/* t18x specifc APIs */ +struct snd_soc_dai_link *tegra_machine_get_dai_link_t18x(void); + +int tegra_machine_append_dai_link_t18x(struct snd_soc_dai_link *link, + unsigned int link_size); + +struct snd_soc_codec_conf *tegra_machine_get_codec_conf_t18x(void); + +int tegra_machine_append_codec_conf_t18x(struct snd_soc_codec_conf *conf, + unsigned int conf_size); + +unsigned int tegra_machine_get_codec_dai_link_idx_t18x(const char *codec_name); + +unsigned int tegra_machine_get_bclk_ratio_t18x( + struct snd_soc_pcm_runtime *rtd); +unsigned int tegra_machine_get_rx_mask_t18x( + struct snd_soc_pcm_runtime *rtd); +unsigned int tegra_machine_get_tx_mask_t18x( + struct snd_soc_pcm_runtime *rtd); + +void tegra_machine_remove_adsp_links_t18x(void); + +#endif diff --git a/sound/soc/tegra-alt/include/tegra_asoc_utils_alt.h b/sound/soc/tegra-alt/include/tegra_asoc_utils_alt.h new file mode 100644 index 00000000..3459ae0b --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra_asoc_utils_alt.h @@ -0,0 +1,110 @@ +/* + * tegra_alt_asoc_utils.h - Definitions for MCLK and DAP Utility driver + * + * Author: Stephen Warren + * Copyright (c) 2011-2017 NVIDIA CORPORATION. All rights reserved. + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __TEGRA_ASOC_UTILS_ALT_H_ +#define __TEGRA_ASOC_UTILS_ALT_H_ + +#ifdef CONFIG_SWITCH +#include +#endif + +struct clk; +struct device; + +enum tegra_asoc_utils_soc { + TEGRA_ASOC_UTILS_SOC_TEGRA210, + TEGRA_ASOC_UTILS_SOC_TEGRA186, +}; + +/* Maintain same order in DT entry */ +enum tegra_asoc_utils_clkrate { + PLLA_x11025_RATE, + AUD_MCLK_x11025_RATE, + PLLA_OUT0_x11025_RATE, + AHUB_x11025_RATE, + PLLA_x8000_RATE, + AUD_MCLK_x8000_RATE, + PLLA_OUT0_x8000_RATE, + AHUB_x8000_RATE, + MAX_NUM_RATES, +}; + +/* These values are copied from WiredAccessoryObserver */ +enum headset_state { + BIT_NO_HEADSET = 0, + BIT_HEADSET = (1 << 0), + BIT_HEADSET_NO_MIC = (1 << 1), +}; + +struct tegra_asoc_audio_clock_info { + struct device *dev; + struct snd_soc_card *card; + enum tegra_asoc_utils_soc soc; + struct clk *clk_pll_a; + struct clk *clk_pll_a_out0; + struct clk *clk_cdev1; + struct clk *clk_ahub; + struct reset_control *clk_cdev1_rst; + int clk_cdev1_state; + struct clk *clk_m; + struct clk *clk_pll_p_out1; + int set_mclk; + int lock_count; + int set_baseclock; + int set_clk_out_rate; + int num_clk; + unsigned int clk_out_rate; + unsigned int mclk_scale; + u32 clk_rates[MAX_NUM_RATES]; +}; + +struct clk *tegra_alt_asoc_utils_get_clk(struct device *dev, + bool dev_id, + const char *clk_name); +void tegra_alt_asoc_utils_clk_put(struct device *dev, struct clk *clk); +int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data, + int srate, + int mclk, + int clk_out_rate); +void tegra_alt_asoc_utils_lock_clk_rate( + struct tegra_asoc_audio_clock_info *data, + int lock); +int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data, + struct device *dev, struct snd_soc_card *card); +void tegra_alt_asoc_utils_fini(struct tegra_asoc_audio_clock_info *data); + +int tegra_alt_asoc_utils_set_extern_parent( + struct tegra_asoc_audio_clock_info *data, const char *parent); +int tegra_alt_asoc_utils_set_parent(struct tegra_asoc_audio_clock_info *data, + int is_i2s_master); +int tegra_alt_asoc_utils_clk_enable(struct tegra_asoc_audio_clock_info *data); +int tegra_alt_asoc_utils_clk_disable(struct tegra_asoc_audio_clock_info *data); +int tegra_alt_asoc_utils_register_ctls(struct tegra_asoc_audio_clock_info *data); + +int tegra_alt_asoc_utils_tristate_dap(int id, bool tristate); + +#ifdef CONFIG_SWITCH +int tegra_alt_asoc_switch_register(struct switch_dev *sdev); +void tegra_alt_asoc_switch_unregister(struct switch_dev *sdev); +#endif + +#endif diff --git a/sound/soc/tegra-alt/include/tegra_isomgr_bw_alt.h b/sound/soc/tegra-alt/include/tegra_isomgr_bw_alt.h new file mode 100644 index 00000000..b4a9fc36 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra_isomgr_bw_alt.h @@ -0,0 +1,35 @@ +/* + * tegra_isomgr_bw_alt.h + * + * Copyright (c) 2016-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRA_ISOMGR_BW_ALT_H__ +#define __TEGRA_ISOMGR_BW_ALT_H__ + +#if defined(CONFIG_TEGRA_ISOMGR) +void tegra_isomgr_adma_register(void); +void tegra_isomgr_adma_unregister(void); +void tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream, + bool is_running); +void tegra_isomgr_adma_renegotiate(void *p, u32 avail_bw); +#else +static inline void tegra_isomgr_adma_register(void) { return; } +static inline void tegra_isomgr_adma_unregister(void) { return; } +static inline void tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream, + bool is_running) { return; } +#endif + +#endif diff --git a/sound/soc/tegra-alt/include/tegra_pcm_alt.h b/sound/soc/tegra-alt/include/tegra_pcm_alt.h new file mode 100644 index 00000000..165b1263 --- /dev/null +++ b/sound/soc/tegra-alt/include/tegra_pcm_alt.h @@ -0,0 +1,48 @@ +/* + * tegra_pcm_alt.h - Definitions for Tegra PCM driver + * + * Author: Stephen Warren + * Copyright (c) 2011-2017 NVIDIA CORPORATION. All rights reserved. + * + * Based on code copyright/by: + * + * Copyright (c) 2009-2010, NVIDIA Corporation. + * Scott Peterson + * + * Copyright (C) 2010 Google, Inc. + * Iliyan Malchev + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __TEGRA_PCM_ALT_H__ +#define __TEGRA_PCM_ALT_H__ + +#define MAX_DMA_REQ_COUNT 2 + +struct tegra_alt_pcm_dma_params { + unsigned long addr; + unsigned long wrap; + unsigned long width; + unsigned long req_sel; + const char *chan_name; + size_t buffer_size; +}; + +int tegra_alt_pcm_platform_register(struct device *dev); +void tegra_alt_pcm_platform_unregister(struct device *dev); + +#endif diff --git a/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c b/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c new file mode 100644 index 00000000..c87e8a4d --- /dev/null +++ b/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c @@ -0,0 +1,1325 @@ +/* + * tegra_machine_driver_mobile.c - Tegra ASoC Machine driver for mobile + * + * Copyright (c) 2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rt5659.h" +#include "tegra_asoc_utils_alt.h" +#include "tegra_asoc_machine_alt.h" +#include "tegra210_xbar_alt.h" + +#ifdef CONFIG_SWITCH +#include +#endif + +#define DRV_NAME "tegra-asoc:" + +#define GPIO_SPKR_EN BIT(0) +#define GPIO_HP_MUTE BIT(1) +#define GPIO_INT_MIC_EN BIT(2) +#define GPIO_EXT_MIC_EN BIT(3) +#define GPIO_HP_DET BIT(4) + +#define PARAMS(sformat, channels) \ + { \ + .formats = sformat, \ + .rate_min = 48000, \ + .rate_max = 48000, \ + .channels_min = channels, \ + .channels_max = channels, \ + } + +/* machine structure which holds sound card */ +struct tegra_machine { + struct tegra_asoc_platform_data *pdata; + struct tegra_asoc_audio_clock_info audio_clock; + unsigned int num_codec_links; + int gpio_requested; + struct snd_soc_card *pcard; + int rate_via_kcontrol; + int is_codec_dummy; + int fmt_via_kcontrol; + struct tegra_machine_soc_data *soc_data; + struct regulator *digital_reg; + struct regulator *spk_reg; + struct regulator *dmic_reg; +#ifdef CONFIG_SWITCH + int jack_status; +#endif +}; + +/* used for soc specific data */ +struct tegra_machine_soc_data { + unsigned int num_xbar_dai_links, + /* dai link indexes */ + admaif_dai_link_start, + admaif_dai_link_end, + adsp_pcm_dai_link_start, + adsp_pcm_dai_link_end, + adsp_compr_dai_link_start, + adsp_compr_dai_link_end, + sfc_dai_link; + + bool is_asrc_available, + is_clk_rate_via_dt, + write_cdev1_state, + write_idle_bias_off_state; + + /* call back APIs */ + unsigned int (*get_bclk_ratio)(struct snd_soc_pcm_runtime *rtd); + struct snd_soc_dai_link *(*get_dai_link)(void); + struct snd_soc_codec_conf *(*get_codec_conf)(void); + int (*append_dai_link)(struct snd_soc_dai_link *link, + unsigned int link_size); + int (*append_codec_conf)(struct snd_soc_codec_conf *conf, + unsigned int conf_size); +}; + +/* function prototypes */ +static int tegra_machine_driver_remove(struct platform_device *); +static int tegra_machine_driver_probe(struct platform_device *); +static void dai_link_setup(struct platform_device *); +static int tegra_machine_sfc_init(struct snd_soc_pcm_runtime *); +static int tegra_machine_ext_codec_init(struct snd_soc_pcm_runtime *); + +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) +static int tegra_machine_compr_set_params(struct snd_compr_stream *); +static void tegra_machine_compr_shutdown(struct snd_compr_stream *); +static int tegra_machine_compr_startup(struct snd_compr_stream *); +#endif + +static void tegra_machine_pcm_shutdown(struct snd_pcm_substream *); +static int tegra_machine_pcm_startup(struct snd_pcm_substream *); +static void tegra_machine_pcm_shutdown(struct snd_pcm_substream *); +static int tegra_machine_suspend_pre(struct snd_soc_card *); +static int tegra_machine_pcm_hw_params(struct snd_pcm_substream *, + struct snd_pcm_hw_params *); +static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *, + int, int, u64, bool); +static int tegra_machine_set_params(struct snd_soc_card *, + struct tegra_machine *, int, int, u64); +static int tegra_machine_jack_notifier(struct notifier_block *, + unsigned long, void *); +static int tegra_machine_codec_get_rate(struct snd_kcontrol *, + struct snd_ctl_elem_value *); +static int tegra_machine_codec_put_rate(struct snd_kcontrol *, + struct snd_ctl_elem_value *); +static int tegra_machine_codec_get_format(struct snd_kcontrol *, + struct snd_ctl_elem_value *); +static int tegra_machine_codec_put_format(struct snd_kcontrol *, + struct snd_ctl_elem_value *); +static int tegra_machine_codec_get_jack_state(struct snd_kcontrol *, + struct snd_ctl_elem_value *); +static int tegra_machine_codec_put_jack_state(struct snd_kcontrol *, + struct snd_ctl_elem_value *); + +/* rt565x specific APIs */ +static int tegra_rt565x_event_int_spk(struct snd_soc_dapm_widget *, + struct snd_kcontrol *, int); +static int tegra_rt565x_event_int_mic(struct snd_soc_dapm_widget *, + struct snd_kcontrol *, int); +static int tegra_rt565x_event_ext_mic(struct snd_soc_dapm_widget *, + struct snd_kcontrol *, int); +static int tegra_rt565x_event_hp(struct snd_soc_dapm_widget *, + struct snd_kcontrol *, int); + +/* t210 soc data */ +static const struct tegra_machine_soc_data soc_data_tegra210 = { + .num_xbar_dai_links = TEGRA210_XBAR_DAI_LINKS, + + .admaif_dai_link_start = TEGRA210_DAI_LINK_ADMAIF1, + .admaif_dai_link_end = TEGRA210_DAI_LINK_ADMAIF10, +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) + .adsp_pcm_dai_link_start = TEGRA210_DAI_LINK_ADSP_PCM1, + .adsp_pcm_dai_link_end = TEGRA210_DAI_LINK_ADSP_PCM2, + .adsp_compr_dai_link_start = TEGRA210_DAI_LINK_ADSP_COMPR1, + .adsp_compr_dai_link_end = TEGRA210_DAI_LINK_ADSP_COMPR2, +#endif + .sfc_dai_link = TEGRA210_DAI_LINK_SFC1_RX, + + .is_asrc_available = false, + .is_clk_rate_via_dt = false, + .write_cdev1_state = false, + .write_idle_bias_off_state = false, + + .get_bclk_ratio = &tegra_machine_get_bclk_ratio, + .get_dai_link = &tegra_machine_get_dai_link, + .get_codec_conf = &tegra_machine_get_codec_conf, + .append_dai_link = &tegra_machine_append_dai_link, + .append_codec_conf = &tegra_machine_append_codec_conf, +}; + +/* t186 soc data */ +static const struct tegra_machine_soc_data soc_data_tegra186 = { + .num_xbar_dai_links = TEGRA186_XBAR_DAI_LINKS, + + .admaif_dai_link_start = TEGRA186_DAI_LINK_ADMAIF1, + .admaif_dai_link_end = TEGRA186_DAI_LINK_ADMAIF10, +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) + .adsp_pcm_dai_link_start = TEGRA186_DAI_LINK_ADSP_PCM1, + .adsp_pcm_dai_link_end = TEGRA186_DAI_LINK_ADSP_PCM2, + .adsp_compr_dai_link_start = TEGRA186_DAI_LINK_ADSP_COMPR1, + .adsp_compr_dai_link_end = TEGRA186_DAI_LINK_ADSP_COMPR2, +#endif + .sfc_dai_link = TEGRA186_DAI_LINK_SFC1_RX, + + .is_asrc_available = true, + .is_clk_rate_via_dt = true, + .write_cdev1_state = true, + .write_idle_bias_off_state = true, + + .get_bclk_ratio = &tegra_machine_get_bclk_ratio_t18x, + .get_dai_link = &tegra_machine_get_dai_link_t18x, + .get_codec_conf = &tegra_machine_get_codec_conf_t18x, + .append_dai_link = &tegra_machine_append_dai_link_t18x, + .append_codec_conf = &tegra_machine_append_codec_conf_t18x, +}; + +/* structure to match device tree node */ +static const struct of_device_id tegra_machine_of_match[] = { + { .compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x", + .data = &soc_data_tegra186 }, + { .compatible = "nvidia,tegra-audio-t210ref-mobile-rt565x", + .data = &soc_data_tegra210 }, + {}, +}; + +static const char * const tegra_machine_srate_text[] = { + "None", + "8kHz", + "16kHz", + "44kHz", + "48kHz", + "11kHz", + "22kHz", + "24kHz", + "32kHz", + "88kHz", + "96kHz", + "176kHz", + "192kHz", +}; + +static const char * const tegra_machine_format_text[] = { + "None", + "16", + "32", +}; + +static const struct soc_enum tegra_machine_codec_rate = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tegra_machine_srate_text), + tegra_machine_srate_text); + +static const struct soc_enum tegra_machine_codec_format = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tegra_machine_format_text), + tegra_machine_format_text); + +static const int tegra_machine_srate_values[] = { + 0, + 8000, + 16000, + 44100, + 48000, + 11025, + 22050, + 24000, + 32000, + 88200, + 96000, + 176400, + 192000, +}; + +static struct snd_soc_jack tegra_machine_hp_jack; + +static struct snd_soc_ops tegra_machine_pcm_ops = { + .hw_params = tegra_machine_pcm_hw_params, + .startup = tegra_machine_pcm_startup, + .shutdown = tegra_machine_pcm_shutdown, +}; + +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) +static struct snd_soc_compr_ops tegra_machine_compr_ops = { + .set_params = tegra_machine_compr_set_params, + .startup = tegra_machine_compr_startup, + .shutdown = tegra_machine_compr_shutdown, +}; +#endif + +static const struct snd_soc_dapm_widget tegra_machine_dapm_widgets[] = { + SND_SOC_DAPM_SPK("x Int Spk", tegra_rt565x_event_int_spk), + SND_SOC_DAPM_HP("x Headphone Jack", tegra_rt565x_event_hp), + SND_SOC_DAPM_MIC("x Int Mic", tegra_rt565x_event_int_mic), + SND_SOC_DAPM_MIC("x Mic Jack", tegra_rt565x_event_ext_mic), + + SND_SOC_DAPM_SPK("d1 Headphone", NULL), + SND_SOC_DAPM_SPK("d2 Headphone", NULL), + + SND_SOC_DAPM_HP("x Headphone", NULL), + SND_SOC_DAPM_HP("y Headphone", NULL), + SND_SOC_DAPM_HP("z Headphone", NULL), + SND_SOC_DAPM_HP("m Headphone", NULL), + SND_SOC_DAPM_HP("n Headphone", NULL), + SND_SOC_DAPM_HP("o Headphone", NULL), + SND_SOC_DAPM_HP("e Headphone", NULL), + SND_SOC_DAPM_HP("s Headphone", NULL), + + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_MIC("x Mic", NULL), + SND_SOC_DAPM_MIC("y Mic", NULL), + SND_SOC_DAPM_MIC("z Mic", NULL), + SND_SOC_DAPM_MIC("m Mic", NULL), + SND_SOC_DAPM_MIC("n Mic", NULL), + SND_SOC_DAPM_MIC("o Mic", NULL), + SND_SOC_DAPM_MIC("a Mic", NULL), + SND_SOC_DAPM_MIC("b Mic", NULL), + SND_SOC_DAPM_MIC("c Mic", NULL), + SND_SOC_DAPM_MIC("d Mic", NULL), + SND_SOC_DAPM_MIC("e Mic", NULL), + SND_SOC_DAPM_MIC("s Mic", NULL), +}; + +static const struct snd_soc_dapm_route tegra_machine_audio_map[] = { +}; + +#ifdef CONFIG_SWITCH +static const char * const tegra_machine_jack_state_text[] = { + "None", + "HS", + "HP", +}; +static struct switch_dev tegra_machine_headset_switch = { + .name = "h2w", +}; +static struct notifier_block tegra_machine_jack_detect_nb = { + .notifier_call = tegra_machine_jack_notifier, +}; +static const struct soc_enum tegra_machine_jack_state = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tegra_machine_jack_state_text), + tegra_machine_jack_state_text); +#else +static struct snd_soc_jack_pin tegra_machine_hp_jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, +}; +#endif + +static const struct snd_kcontrol_new tegra_machine_controls[] = { + SOC_DAPM_PIN_SWITCH("x Int Spk"), + SOC_DAPM_PIN_SWITCH("x Headphone Jack"), + SOC_DAPM_PIN_SWITCH("x Mic Jack"), + SOC_DAPM_PIN_SWITCH("x Int Mic"), + SOC_ENUM_EXT("codec-x rate", tegra_machine_codec_rate, + tegra_machine_codec_get_rate, tegra_machine_codec_put_rate), + SOC_ENUM_EXT("codec-x format", tegra_machine_codec_format, + tegra_machine_codec_get_format, tegra_machine_codec_put_format), +#ifdef CONFIG_SWITCH + SOC_ENUM_EXT("Jack-state", tegra_machine_jack_state, + tegra_machine_codec_get_jack_state, + tegra_machine_codec_put_jack_state), +#endif +}; + +static struct snd_soc_card snd_soc_tegra_card = { + .owner = THIS_MODULE, + .suspend_pre = tegra_machine_suspend_pre, + .controls = tegra_machine_controls, + .num_controls = ARRAY_SIZE(tegra_machine_controls), + .dapm_widgets = tegra_machine_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tegra_machine_dapm_widgets), + .fully_routed = true, +}; + +static struct snd_soc_pcm_stream tegra_machine_asrc_link_params[] = { + PARAMS(SNDRV_PCM_FMTBIT_S32_LE, 8), + PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2), + PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2), + PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2), + PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2), + PARAMS(SNDRV_PCM_FMTBIT_S16_LE, 2), +}; + +static int tegra_rt565x_event_int_spk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + struct tegra_asoc_platform_data *pdata = machine->pdata; + int err; + + if (machine->spk_reg) { + if (SND_SOC_DAPM_EVENT_ON(event)) + err = regulator_enable(machine->spk_reg); + else + regulator_disable(machine->spk_reg); + } + + if (!(machine->gpio_requested & GPIO_SPKR_EN)) + return 0; + + gpio_set_value_cansleep(pdata->gpio_spkr_en, + !!SND_SOC_DAPM_EVENT_ON(event)); + + return 0; +} + +static int tegra_rt565x_event_hp(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + struct tegra_asoc_platform_data *pdata = machine->pdata; + + if (!(machine->gpio_requested & GPIO_HP_MUTE)) + return 0; + + gpio_set_value_cansleep(pdata->gpio_hp_mute, + !SND_SOC_DAPM_EVENT_ON(event)); + return 0; +} + +static int tegra_rt565x_event_int_mic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + struct tegra_asoc_platform_data *pdata = machine->pdata; + int ret = 0; + + if (machine->dmic_reg) { + if (SND_SOC_DAPM_EVENT_ON(event)) + ret = regulator_enable(machine->dmic_reg); + else + regulator_disable(machine->dmic_reg); + } + + if (!(machine->gpio_requested & GPIO_INT_MIC_EN)) + return 0; + + gpio_set_value_cansleep(pdata->gpio_int_mic_en, + !!SND_SOC_DAPM_EVENT_ON(event)); + + return 0; +} + +static int tegra_rt565x_event_ext_mic(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + struct tegra_asoc_platform_data *pdata = machine->pdata; + + if (!(machine->gpio_requested & GPIO_EXT_MIC_EN)) + return 0; + + gpio_set_value_cansleep(pdata->gpio_ext_mic_en, + !SND_SOC_DAPM_EVENT_ON(event)); + + return 0; +} + + +static int tegra_machine_codec_get_rate(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + + ucontrol->value.integer.value[0] = machine->rate_via_kcontrol; + + return 0; +} + +static int tegra_machine_codec_put_rate(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + + /* set the rate control flag */ + machine->rate_via_kcontrol = ucontrol->value.integer.value[0]; + + return 0; +} + +static int tegra_machine_codec_get_format(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + + ucontrol->value.integer.value[0] = machine->fmt_via_kcontrol; + + return 0; +} + +static int tegra_machine_codec_put_format(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + + /* set the format control flag */ + machine->fmt_via_kcontrol = ucontrol->value.integer.value[0]; + + return 0; +} + +#ifdef CONFIG_SWITCH +static int tegra_machine_codec_get_jack_state(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = tegra_machine_headset_switch.state; + return 0; +} + +static int tegra_machine_codec_put_jack_state(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + if (ucontrol->value.integer.value[0] == 0) + switch_set_state(&tegra_machine_headset_switch, BIT_NO_HEADSET); + else if (ucontrol->value.integer.value[0] == 1) + switch_set_state(&tegra_machine_headset_switch, BIT_HEADSET); + else if (ucontrol->value.integer.value[0] == 2) + switch_set_state(&tegra_machine_headset_switch, + BIT_HEADSET_NO_MIC); + return 0; +} + +static int tegra_machine_jack_notifier(struct notifier_block *self, + unsigned long action, void *dev) +{ + struct snd_soc_jack *jack = dev; + struct snd_soc_card *card = jack->card; + + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + enum headset_state state = BIT_NO_HEADSET; + static bool button_pressed; + struct snd_soc_pcm_runtime *rtd; + + if (machine->is_codec_dummy) + return NOTIFY_OK; + + rtd = snd_soc_get_pcm_runtime(card, "rt565x-playback"); + if (!rtd) { + /* spurious interrupt */ + dev_dbg(card->dev, "rt565x dai-link not found\n"); + return -EINVAL; + } + + dev_dbg(card->dev, "jack status = %d", jack->status); + if (jack->status & (SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3)) { + button_pressed = true; + return NOTIFY_OK; + } else if ((jack->status & SND_JACK_HEADSET) && button_pressed) { + button_pressed = false; + return NOTIFY_OK; + } + + switch (jack->status) { + case SND_JACK_HEADPHONE: + state = BIT_HEADSET_NO_MIC; + break; + case SND_JACK_HEADSET: + state = BIT_HEADSET; + break; + case SND_JACK_MICROPHONE: + /* mic: would not report */ + default: + state = BIT_NO_HEADSET; + } + + dev_dbg(card->dev, "switch state to %x\n", state); + switch_set_state(&tegra_machine_headset_switch, state); + return NOTIFY_OK; +} +#endif + +static int tegra_machine_set_params(struct snd_soc_card *card, + struct tegra_machine *machine, + int rate, + int channels, + u64 formats) +{ + unsigned int tx_mask = (1 << channels) - 1; + unsigned int rx_mask = (1 << channels) - 1; + int idx = 0, err = 0; + u64 format_k; + + int num_of_dai_links = machine->soc_data->num_xbar_dai_links + + machine->num_codec_links; + struct snd_soc_pcm_runtime *rtd; + + format_k = (machine->fmt_via_kcontrol == 2) ? + (1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats; + + /* update dai link hw_params */ +#if KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE + for (idx = 0; idx < num_of_dai_links;) { + rtd = &card->rtd[idx]; + +#else + list_for_each_entry(rtd, &card->rtd_list, list) { +#endif + if (rtd->dai_link->params) { + struct snd_soc_pcm_stream *dai_params; + + dai_params = + (struct snd_soc_pcm_stream *) + rtd->dai_link->params; + + dai_params->rate_min = rate; + dai_params->channels_min = channels; + dai_params->formats = format_k; + + if ((idx >= machine->soc_data->num_xbar_dai_links) + && (idx < num_of_dai_links)) { + unsigned int fmt; + int bclk_ratio; + + err = 0; + /* TODO: why below overrite is needed */ + dai_params->formats = formats; + + fmt = rtd->dai_link->dai_fmt; + bclk_ratio = + machine->soc_data->get_bclk_ratio(rtd); + + if (bclk_ratio >= 0) { + err = snd_soc_dai_set_bclk_ratio( + rtd->cpu_dai, + bclk_ratio); + } + + if (err < 0) { + dev_err(card->dev, + "Failed to set cpu dai bclk ratio for %s\n", + rtd->dai_link->name); + } + + /* set TDM slot mask */ + if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == + SND_SOC_DAIFMT_DSP_A) { + err = snd_soc_dai_set_tdm_slot( + rtd->cpu_dai, + tx_mask, rx_mask, 0, 0); + if (err < 0) { + dev_err(card->dev, + "%s cpu DAI slot mask not set\n", + rtd->cpu_dai->name); + } + } + } + } + idx++; + } + return 0; +} +static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime, + int rate, + int channels, + u64 formats, + bool is_playback) +{ + struct snd_soc_card *card = runtime->card; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + struct snd_soc_pcm_stream *dai_params; + unsigned int clk_out_rate = 0, mclk = 0; + int err, codec_rate, clk_rate; + struct snd_soc_pcm_runtime *rtd; + + codec_rate = tegra_machine_srate_values[machine->rate_via_kcontrol]; + clk_rate = (machine->rate_via_kcontrol) ? codec_rate : rate; + + if (!machine->soc_data->is_clk_rate_via_dt) { + /* TODO remove this hardcoding */ + /* aud_mclk, 256 times the sample rate */ + clk_out_rate = clk_rate << 8; + switch (clk_rate) { + case 11025: + mclk = 22579200; + break; + case 22050: + case 44100: + case 88200: + case 176400: + mclk = 45158400; + break; + case 8000: + mclk = 24576000; + break; + case 16000: + case 32000: + case 48000: + case 64000: + case 96000: + case 192000: + default: + mclk = 49152000; + break; + } + + err = tegra210_xbar_set_clock(mclk); + if (err < 0) { + dev_err(card->dev, + "Can't configure xbar clock = %d Hz\n", mclk); + return err; + } + } + + err = tegra_alt_asoc_utils_set_rate(&machine->audio_clock, clk_rate, + mclk, clk_out_rate); + if (err < 0) { + dev_err(card->dev, "Can't configure clocks\n"); + return err; + } + + if (machine->soc_data->is_clk_rate_via_dt) + clk_out_rate = machine->audio_clock.clk_out_rate; + + pr_debug("pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n", + machine->audio_clock.set_mclk, clk_out_rate, clk_rate); + + /* TODO: should we pass here clk_rate ? */ + tegra_machine_set_params(card, machine, rate, channels, formats); + + rtd = snd_soc_get_pcm_runtime(card, "rt565x-playback"); + if (rtd) { + dai_params = + (struct snd_soc_pcm_stream *)rtd->dai_link->params; + + dai_params->rate_min = clk_rate; + dai_params->formats = (machine->fmt_via_kcontrol == 2) ? + (1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats; + + if (!machine->is_codec_dummy) { + err = snd_soc_dai_set_sysclk(rtd->codec_dai, + RT5659_SCLK_S_MCLK, clk_out_rate, SND_SOC_CLOCK_IN); + if (err < 0) { + dev_err(card->dev, "codec_dai clock not set\n"); + return err; + } + } + } + + /* TODO: remove below spdif links if clk_rate is passed + * in tegra_machine_set_params + */ + rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-1"); + if (rtd) { + dai_params = + (struct snd_soc_pcm_stream *)rtd->dai_link->params; + + dai_params->rate_min = clk_rate; + } + + /* set clk rate for i2s3 dai link*/ + rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-2"); + if (rtd) { + dai_params = + (struct snd_soc_pcm_stream *)rtd->dai_link->params; + + dai_params->rate_min = clk_rate; + } + + rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-3"); + if (rtd) { + dai_params = + (struct snd_soc_pcm_stream *)rtd->dai_link->params; + + dai_params->rate_min = clk_rate; + } + + rtd = snd_soc_get_pcm_runtime(card, "dspk-playback-r"); + if (rtd) { + dai_params = + (struct snd_soc_pcm_stream *)rtd->dai_link->params; + + if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) { + err = snd_soc_dai_set_sysclk(rtd->codec_dai, + TAS2552_PDM_CLK_IVCLKIN, clk_out_rate, + SND_SOC_CLOCK_IN); + if (err < 0) { + dev_err(card->dev, "codec_dai clock not set\n"); + return err; + } + } + } + + rtd = snd_soc_get_pcm_runtime(card, "dspk-playback-l"); + if (rtd) { + dai_params = + (struct snd_soc_pcm_stream *)rtd->dai_link->params; + + if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) { + err = snd_soc_dai_set_sysclk(rtd->codec_dai, + TAS2552_PDM_CLK_IVCLKIN, clk_out_rate, + SND_SOC_CLOCK_IN); + if (err < 0) { + dev_err(card->dev, "codec_dai clock not set\n"); + return err; + } + } + } + + rtd = snd_soc_get_pcm_runtime(card, "spdif-playback"); + if (rtd && (clk_rate >= 32000)) { + dai_params = + (struct snd_soc_pcm_stream *)rtd->dai_link->params; + + if (is_playback) { + err = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, + clk_rate, SND_SOC_CLOCK_OUT); + if (err < 0) { + dev_err(card->dev, "cpu_dai out clock not set\n"); + return err; + } + } else { + err = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, + clk_rate, SND_SOC_CLOCK_IN); + if (err < 0) { + dev_err(card->dev, "cpu_dai in clock not set\n"); + return err; + } + } + } + + return 0; +} + +static int tegra_machine_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + int err; + bool is_playback; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + is_playback = true; + else + is_playback = false; + + err = tegra_machine_dai_init(rtd, params_rate(params), + params_channels(params), + (1ULL << (params_format(params))), + is_playback); + if (err < 0) { + dev_err(card->dev, "Failed dai init\n"); + return err; + } + + return 0; +} + +static int tegra_machine_pcm_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct tegra_machine *machine = snd_soc_card_get_drvdata(rtd->card); + + tegra_alt_asoc_utils_clk_enable(&machine->audio_clock); + + return 0; +} + +static void tegra_machine_pcm_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct tegra_machine *machine = snd_soc_card_get_drvdata(rtd->card); + + tegra_alt_asoc_utils_clk_disable(&machine->audio_clock); +} + +static int tegra_machine_suspend_pre(struct snd_soc_card *card) +{ + struct snd_soc_pcm_runtime *rtd; + + /* DAPM dai link stream work for non pcm links */ +#if KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE + unsigned int idx; + + for (idx = 0; idx < card->num_rtd; idx++) { + rtd = &card->rtd[idx]; +#else + list_for_each_entry(rtd, &card->rtd_list, list) { +#endif + if (rtd->dai_link->params) + INIT_DELAYED_WORK(&rtd->delayed_work, NULL); + } + + return 0; +} + +static int tegra_machine_dspk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = &card->dapm; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + int err; + + err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock, + "pll_a_out0"); + if (err < 0) + dev_err(card->dev, "Failed to set extern clk parent\n"); + + snd_soc_dapm_sync(dapm); + return err; +} + +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) +static int tegra_machine_compr_startup(struct snd_compr_stream *cstream) +{ + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct snd_soc_card *card = rtd->card; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + + tegra_alt_asoc_utils_clk_enable(&machine->audio_clock); + + return 0; +} + +static void tegra_machine_compr_shutdown(struct snd_compr_stream *cstream) +{ + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct snd_soc_card *card = rtd->card; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + + tegra_alt_asoc_utils_clk_disable(&machine->audio_clock); +} + +static int tegra_machine_compr_set_params(struct snd_compr_stream *cstream) +{ + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_platform *platform = rtd->platform; + struct snd_codec codec_params; + int err; + bool is_playback; + + if (platform->driver->compr_ops && + platform->driver->compr_ops->get_params) { + err = platform->driver->compr_ops->get_params(cstream, + &codec_params); + if (err < 0) { + dev_err(card->dev, "Failed to get compr params\n"); + return err; + } + } else { + dev_err(card->dev, "compr ops not set\n"); + return -EINVAL; + } + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + is_playback = true; + else + is_playback = false; + + err = tegra_machine_dai_init(rtd, codec_params.sample_rate, + codec_params.ch_out, SNDRV_PCM_FMTBIT_S16_LE, + is_playback); + if (err < 0) { + dev_err(card->dev, "Failed dai init\n"); + return err; + } + + return 0; +} +#endif + +static int tegra_machine_ext_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + int err; + + err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock, + "pll_a_out0"); + if (err < 0) { + dev_err(card->dev, "Failed to set extern clk parent\n"); + return err; + } + + err = snd_soc_card_jack_new(card, "Headphone Jack", SND_JACK_HEADPHONE, + &tegra_machine_hp_jack, NULL, 0); + if (err) { + dev_err(card->dev, "Headset Jack creation failed %d\n", err); + return err; + } + +#ifndef CONFIG_SWITCH + err = snd_soc_jack_add_pins(&tegra_machine_hp_jack, + ARRAY_SIZE(tegra_machine_hp_jack_pins), + tegra_machine_hp_jack_pins); + if (err) { + dev_err(card->dev, "snd_soc_jack_add_pins failed %d\n", err); + return err; + } +#else + snd_soc_jack_notifier_register(&tegra_machine_hp_jack, + &tegra_machine_jack_detect_nb); +#endif + + /* single button supporting play/pause */ + snd_jack_set_key(tegra_machine_hp_jack.jack, + SND_JACK_BTN_0, KEY_MEDIA); + + /* multiple buttons supporting play/pause and volume up/down */ + snd_jack_set_key(tegra_machine_hp_jack.jack, + SND_JACK_BTN_1, KEY_MEDIA); + snd_jack_set_key(tegra_machine_hp_jack.jack, + SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(tegra_machine_hp_jack.jack, + SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + snd_soc_dapm_sync(&card->dapm); + + return 0; +} + +static int tegra_machine_sfc_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int in_srate, out_srate; + int err; + + in_srate = 48000; + out_srate = 8000; + + err = snd_soc_dai_set_sysclk(codec_dai, 0, out_srate, + SND_SOC_CLOCK_OUT); + err = snd_soc_dai_set_sysclk(codec_dai, 0, in_srate, + SND_SOC_CLOCK_IN); + + return err; +} + +static void dai_link_setup(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + struct snd_soc_codec_conf *tegra_machine_codec_conf = NULL; + struct snd_soc_codec_conf *tegra_new_codec_conf = NULL; + struct snd_soc_dai_link *tegra_machine_dai_links = NULL; + struct snd_soc_dai_link *tegra_machine_codec_links = NULL; + int i; + + /* set new codec links and conf */ + tegra_machine_codec_links = tegra_machine_new_codec_links(pdev, + tegra_machine_codec_links, + &machine->num_codec_links); + if (!tegra_machine_codec_links) + goto err_alloc_dai_link; + + /* set codec init */ + for (i = 0; i < machine->num_codec_links; i++) { + if (tegra_machine_codec_links[i].name) { + if (strstr(tegra_machine_codec_links[i].name, + "rt565x-playback")) + tegra_machine_codec_links[i].init = + tegra_machine_ext_codec_init; + else if (strstr(tegra_machine_codec_links[i].name, + "dspk-playback-r")) + tegra_machine_codec_links[i].init = + tegra_machine_dspk_init; + else if (strstr(tegra_machine_codec_links[i].name, + "dspk-playback-l")) + tegra_machine_codec_links[i].init = + tegra_machine_dspk_init; + } + } + + tegra_new_codec_conf = tegra_machine_new_codec_conf(pdev, + tegra_new_codec_conf, + &machine->num_codec_links); + if (!tegra_new_codec_conf) + goto err_alloc_dai_link; + + /* get the xbar dai link/codec conf structure */ + tegra_machine_dai_links = machine->soc_data->get_dai_link(); + if (!tegra_machine_dai_links) + goto err_alloc_dai_link; + + tegra_machine_codec_conf = machine->soc_data->get_codec_conf(); + if (!tegra_machine_codec_conf) + goto err_alloc_dai_link; + + /* set ADMAIF dai_ops */ + for (i = machine->soc_data->admaif_dai_link_start; + i <= machine->soc_data->admaif_dai_link_end; i++) + tegra_machine_set_dai_ops(i, &tegra_machine_pcm_ops); + + /* set sfc dai_init */ + tegra_machine_set_dai_init(machine->soc_data->sfc_dai_link, + &tegra_machine_sfc_init); +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) + /* set ADSP PCM/COMPR */ + for (i = machine->soc_data->adsp_pcm_dai_link_start; + i <= machine->soc_data->adsp_pcm_dai_link_end; i++) { + tegra_machine_set_dai_ops(i, &tegra_machine_pcm_ops); + } + + /* set ADSP COMPR */ + for (i = machine->soc_data->adsp_compr_dai_link_start; + i <= machine->soc_data->adsp_compr_dai_link_end; i++) { + tegra_machine_set_dai_compr_ops(i, + &tegra_machine_compr_ops); + } +#endif + + if (machine->soc_data->is_asrc_available) { + /* set ASRC params. The default is 2 channels */ + for (i = 0; i < 6; i++) { + tegra_machine_set_dai_params(TEGRA186_DAI_LINK_ASRC1_TX1 + + i, (struct snd_soc_pcm_stream *) + &tegra_machine_asrc_link_params[i]); + tegra_machine_set_dai_params(TEGRA186_DAI_LINK_ASRC1_RX1 + + i, (struct snd_soc_pcm_stream *) + &tegra_machine_asrc_link_params[i]); + } + } + + /* append machine specific dai_links */ + card->num_links = machine->soc_data->append_dai_link( + tegra_machine_codec_links, 2 * machine->num_codec_links); + tegra_machine_dai_links = machine->soc_data->get_dai_link(); + card->dai_link = tegra_machine_dai_links; + + /* append machine specific codec_conf */ + card->num_configs = machine->soc_data->append_codec_conf( + tegra_new_codec_conf, machine->num_codec_links); + tegra_machine_codec_conf = machine->soc_data->get_codec_conf(); + card->codec_conf = tegra_machine_codec_conf; + + return; + +err_alloc_dai_link: + tegra_machine_remove_dai_link(); + tegra_machine_remove_codec_conf(); +} + +static int tegra_machine_driver_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct snd_soc_card *card = &snd_soc_tegra_card; + struct tegra_machine *machine; + struct tegra_asoc_platform_data *pdata = NULL; + struct snd_soc_codec *codec = NULL; + int ret = 0; + const char *codec_dai_name; + struct snd_soc_pcm_runtime *rtd; + const struct of_device_id *match; + + card->dev = &pdev->dev; + /* parse card name first to log errors with proper device name */ + ret = snd_soc_of_parse_card_name(card, "nvidia,model"); + if (ret) + goto err; + + /* update device name with card name */ + if (dev_set_name(&pdev->dev, "%s", card->name) < 0) { + dev_err(&pdev->dev, "error in setting machine driver device name\n"); + ret = -ENODEV; + goto err; + } + + match = of_match_device(tegra_machine_of_match, &pdev->dev); + if (!match) { + dev_err(&pdev->dev, "Error: No device match found\n"); + return -ENODEV; + } + + if (!np) { + dev_err(&pdev->dev, "No device tree node for tegra machine driver"); + return -ENODEV; + } + + machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_machine), + GFP_KERNEL); + if (!machine) { + ret = -ENOMEM; + dev_err(&pdev->dev, "Can't allocate struct for tegra_machine\n"); + goto err; + } + + machine->soc_data = (struct tegra_machine_soc_data *)match->data; + + if (!machine->soc_data->get_dai_link || + !machine->soc_data->get_bclk_ratio || + !machine->soc_data->get_codec_conf || + !machine->soc_data->append_dai_link || + !machine->soc_data->append_codec_conf) { + ret = -ENODEV; + dev_err(&pdev->dev, "Error: callback APIs are missing\n"); + goto err; + } + + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, machine); + machine->is_codec_dummy = 0; + + if (machine->soc_data->write_cdev1_state) + machine->audio_clock.clk_cdev1_state = 0; + + if (machine->soc_data->write_idle_bias_off_state) + card->dapm.idle_bias_off = true; + + ret = snd_soc_of_parse_audio_routing(card, + "nvidia,audio-routing"); + if (ret) + goto err; + + if (machine->soc_data->is_clk_rate_via_dt) { + if (of_property_read_u32(np, "nvidia,num-clk", + &machine->audio_clock.num_clk) < 0) { + dev_err(&pdev->dev, + "Missing property nvidia,num-clk\n"); + ret = -ENODEV; + goto err; + } + + if (of_property_read_u32_array(np, "nvidia,clk-rates", + (u32 *)&machine->audio_clock.clk_rates, + machine->audio_clock.num_clk) < 0) { + dev_err(&pdev->dev, + "Missing property nvidia,clk-rates\n"); + ret = -ENODEV; + goto err; + } + } + + dai_link_setup(pdev); + +#ifdef CONFIG_SWITCH + /* Addd h2w swith class support */ + ret = tegra_alt_asoc_switch_register(&tegra_machine_headset_switch); + if (ret < 0) + goto err_alloc_dai_link; +#endif + + pdata = devm_kzalloc(&pdev->dev, + sizeof(struct tegra_asoc_platform_data), + GFP_KERNEL); + if (!pdata) { + dev_err(&pdev->dev, + "Can't allocate tegra_asoc_platform_data struct\n"); + return -ENOMEM; + } + + pdata->gpio_codec1 = pdata->gpio_codec2 = pdata->gpio_codec3 = + pdata->gpio_spkr_en = pdata->gpio_hp_mute = + pdata->gpio_int_mic_en = pdata->gpio_ext_mic_en = -1; + + machine->pdata = pdata; + machine->pcard = card; + + ret = tegra_alt_asoc_utils_init(&machine->audio_clock, + &pdev->dev, + card); + if (ret) + goto err_alloc_dai_link; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err_fini_utils; + } + + rtd = snd_soc_get_pcm_runtime(card, "rt565x-playback"); + if (!rtd) + dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card"); + else { + codec = rtd->codec; + codec_dai_name = rtd->dai_link->codec_dai_name; + + dev_info(&pdev->dev, + "codec-dai \"%s\" registered\n", codec_dai_name); + if (!strcmp("dit-hifi", codec_dai_name)) { + dev_info(&pdev->dev, "This is a dummy codec\n"); + machine->is_codec_dummy = 1; + } + } + + if (!machine->is_codec_dummy) { + /* setup for jack detection only in non-dummy case */ + rt5659_set_jack_detect(codec, &tegra_machine_hp_jack); + } + + return 0; + +err_fini_utils: + tegra_alt_asoc_utils_fini(&machine->audio_clock); +err_alloc_dai_link: + tegra_machine_remove_dai_link(); + tegra_machine_remove_codec_conf(); +err: + return ret; +} + +static int tegra_machine_driver_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct tegra_machine *machine = snd_soc_card_get_drvdata(card); + + snd_soc_unregister_card(card); + + tegra_machine_remove_dai_link(); + tegra_machine_remove_codec_conf(); + tegra_alt_asoc_utils_fini(&machine->audio_clock); + + return 0; +} + +static struct platform_driver tegra_asoc_machine_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = tegra_machine_of_match, + }, + .probe = tegra_machine_driver_probe, + .remove = tegra_machine_driver_remove, +}; +module_platform_driver(tegra_asoc_machine_driver); + +MODULE_AUTHOR("Mohan Kumar , Sameer Pujar "); +MODULE_DESCRIPTION("Tegra ASoC machine driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, tegra_machine_of_match); diff --git a/sound/soc/tegra-alt/utils/ahub_unit_fpga_clock.c b/sound/soc/tegra-alt/utils/ahub_unit_fpga_clock.c new file mode 100644 index 00000000..7f024377 --- /dev/null +++ b/sound/soc/tegra-alt/utils/ahub_unit_fpga_clock.c @@ -0,0 +1,1424 @@ +/* + * ahub_unit_fpga_clock.c + * + * Author: Dara Ramesh + * + * Copyright (c) 2013-2017, NVIDIA CORPORATION. All rights reserved. + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; If not, see . + */ + + +#define VERBOSE_DEBUG +#define DEBUG +#include +#include +#include <../arch/arm/mach-tegra/iomap.h> +#include +#include +#include "ahub_unit_fpga_clock.h" + +static struct ahub_unit_fpga ahub_unit_fpga_private; + +static void __iomem *pinmux_base = IO_ADDRESS(NV_ADDRESS_MAP_APB_PP_BASE); +static void __iomem *ahub_gpio_base = + IO_ADDRESS(NV_ADDRESS_MAP_APE_AHUB_GPIO_BASE); +static void __iomem *rst_clk_base = + IO_ADDRESS(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE); +static void __iomem *t210_i2s5_base = + IO_ADDRESS(T210_NV_ADDRESS_MAP_APE_I2S5_BASE); +static void __iomem *t186_i2s5_base = + IO_ADDRESS(T186_NV_ADDRESS_MAP_APE_I2S5_BASE); + +static bool t210_chip; +static bool t186_chip; + +static unsigned int ahub_fpga_misc_i2s_offset[5] = { + APE_FPGA_MISC_CLK_SOURCE_I2S1_0, + APE_FPGA_MISC_CLK_SOURCE_I2S2_0, + APE_FPGA_MISC_CLK_SOURCE_I2S3_0, + APE_FPGA_MISC_CLK_SOURCE_I2S4_0, + APE_FPGA_MISC_CLK_SOURCE_I2S5_0 +}; + +static unsigned int i2s_source_clock[5] = { + CLK_RST_CONTROLLER_CLK_SOURCE_I2S1_0, + CLK_RST_CONTROLLER_CLK_SOURCE_I2S2_0, + CLK_RST_CONTROLLER_CLK_SOURCE_I2S3_0, + CLK_RST_CONTROLLER_CLK_SOURCE_I2S4_0, + CLK_RST_CONTROLLER_CLK_SOURCE_I2S5_0, +}; + +static unsigned char cdce906_setting[27] = { + 0, + 0x77, + 0x20, + 0x6d, + 1, + 1, + 0x80, + 1, + 1, + 0x20, + 0x0F, + 0x0, + 0x0, + 0x5, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x38, + 0x31, + 0x31, + 0x31, + 0x31, + 0x31, + 0x0, + 0x0, +}; +void i2s_clk_divider(u32 i2s, u32 divider) +{ + void __iomem *ape_fpga_misc_i2s_offset = + ahub_unit_fpga_private.ape_fpga_misc_i2s_clk_base[i2s]; + void __iomem *ape_fpga_misc_i2s5_cya_offset = + ahub_unit_fpga_private.i2s5_cya_base; + u32 write_data, read_data; + + write_data = ((divider << 1) | (1 << 28)); + writel(write_data, ape_fpga_misc_i2s_offset); + read_data = readl(ape_fpga_misc_i2s_offset); + if (i2s == I2S5) + writel(1, ape_fpga_misc_i2s5_cya_offset); +#if DEBUG_FPGA + if (read_data == write_data) + pr_err("\n DATA MATCH I2S%d 0x%x\n", i2s+1, read_data); + else + pr_err("DATA MISMATCH APE_FPGA_MISC_CLK_SOURCE_I2S%d_0 Actual data: 0x%x expected data: 0x%x\n", + i2s+1, read_data, write_data); +#endif +} +EXPORT_SYMBOL(i2s_clk_divider); + +void i2s_clk_setup(u32 i2s, u32 source, u32 divider) +{ + u32 write_data; + + write_data = (source << 29) | (divider); + writel(write_data, rst_clk_base + i2s_source_clock[i2s]); +} +EXPORT_SYMBOL(i2s_clk_setup); + +void i2c_pinmux_setup(void) +{ + /* Pin mux */ + writel(0x40, pinmux_base + PINMUX_AUX_GEN1_I2C_SDA_0); + writel(0x40, pinmux_base + PINMUX_AUX_GEN1_I2C_SCL_0); +} +EXPORT_SYMBOL(i2c_pinmux_setup); + +void i2s_pinmux_setup(u32 i2s, u32 i2s_b) +{ + switch (i2s) { + case I2S1: + writel(0x40, pinmux_base + PINMUX_AUX_DAP1_SCLK_0); + writel(0x40, pinmux_base + PINMUX_AUX_DAP1_FS_0); + writel(0x40, pinmux_base + PINMUX_AUX_DAP1_DOUT_0); + writel(0x40, pinmux_base + PINMUX_AUX_DAP1_DIN_0); + break; + case I2S2: + writel(0x40, pinmux_base + PINMUX_AUX_DAP2_SCLK_0); + writel(0x40, pinmux_base + PINMUX_AUX_DAP2_FS_0); + writel(0x40, pinmux_base + PINMUX_AUX_DAP2_DOUT_0); + writel(0x40, pinmux_base + PINMUX_AUX_DAP2_DIN_0); + break; + case I2S3: + case I2S4: + default: + break; + case I2S5: + writel(0x41, pinmux_base + PINMUX_AUX_GPIO_PK0_0); + writel(0x41, pinmux_base + PINMUX_AUX_GPIO_PK1_0); + writel(0x41, pinmux_base + PINMUX_AUX_GPIO_PK2_0); + writel(0x41, pinmux_base + PINMUX_AUX_GPIO_PK3_0); + if (i2s_b) { + if (t210_chip) + writel(1, t210_i2s5_base + I2S5_CYA_0); + else if (t186_chip) + writel(1, t186_i2s5_base + I2S5_CYA_0); + } + break; + } +} +EXPORT_SYMBOL(i2s_pinmux_setup); + +void i2c_clk_setup(u32 divider) +{ + u32 reg_val; + + /* de-assert clk reset */ + reg_val = readl(rst_clk_base + CLK_RST_CONTROLLER_RST_DEVICES_L_0); + reg_val &= ~(1 << 12); + writel(reg_val, rst_clk_base + CLK_RST_CONTROLLER_RST_DEVICES_L_0); + + /* enable i2c1 clock */ + reg_val = readl(rst_clk_base + CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0); + reg_val |= (1 << 12); + writel(reg_val, rst_clk_base + CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0); + + reg_val = divider << 1; + writel(reg_val, rst_clk_base + CLK_RST_CONTROLLER_CLK_SOURCE_I2C1_0); +} +EXPORT_SYMBOL(i2c_clk_setup); + +void i2c_clk_divider(u32 divider) +{ + u32 write_data, read_data; + void __iomem *ape_fpga_misc_base = + ahub_unit_fpga_private.ape_fpga_misc_base; + + write_data = divider << 1; + writel(write_data, + ape_fpga_misc_base + APE_FPGA_MISC_CLK_SOURCE_I2C1_0); + read_data = readl(ape_fpga_misc_base + APE_FPGA_MISC_CLK_SOURCE_I2C1_0); +} +EXPORT_SYMBOL(i2c_clk_divider); + +void i2c_write(u32 addr, u32 reg_addr, u32 regData, u32 no_bytes) +{ + u32 write_data, read_data; + u32 data; + void __iomem *ape_i2c_base = ahub_unit_fpga_private.ape_i2c_base; + + if (no_bytes == 3) { + data = (reg_addr & 0xFF) | ((regData & 0xFF) << 16) | + (((regData & 0xFF00) >> 8) << 8); + } else { + data = regData << 8 | reg_addr; + } + + write_data = addr << 1; + writel(write_data, ape_i2c_base + I2C_I2C_CMD_ADDR0_0); + + write_data = (no_bytes - 1) << 1; + writel(write_data, ape_i2c_base + I2C_I2C_CNFG_0); + + write_data = data; + writel(write_data, ape_i2c_base + I2C_I2C_CMD_DATA1_0); + + write_data = 0x01; + writel(write_data, ape_i2c_base + I2C_I2C_CONFIG_LOAD_0); + + read_data = readl(ape_i2c_base + I2C_I2C_CONFIG_LOAD_0); + + while (read_data != 0x0) { + read_data = readl(ape_i2c_base + I2C_I2C_CONFIG_LOAD_0); + } + + write_data = 0x200 | (no_bytes - 1) << 1; + writel(write_data, ape_i2c_base + I2C_I2C_CNFG_0); + + /* CHECKING STATUS for Busy status */ + read_data = readl(ape_i2c_base + I2C_I2C_STATUS_0); + + while (read_data & 0x100) { /* wait for master busy LOW */ + pr_err("\n status before %9x\n", read_data); + read_data = readl(ape_i2c_base + I2C_I2C_STATUS_0); + } + + + read_data = readl(ape_i2c_base + I2C_I2C_STATUS_0); + read_data = read_data & 0xFF; + if (read_data) + pr_err("\n FAIL NoaCK Received for Reg_add %08x before %9x Byte\n", + reg_addr, read_data); +} +EXPORT_SYMBOL(i2c_write); + +u32 i2c_read(u32 addr, u32 reg_addr) +{ + u32 write_data, read_data; + void __iomem *ape_i2c_base = ahub_unit_fpga_private.ape_i2c_base; + + write_data = 0x1 << 11 | (0x1 << 4) | (0 << 6) | (1 << 7); + writel(write_data, ape_i2c_base + I2C_I2C_CNFG_0); + + write_data = addr << 1; + writel(write_data, ape_i2c_base + I2C_I2C_CMD_ADDR0_0); + + write_data = addr << 1 | 1; + writel(write_data, ape_i2c_base + I2C_I2C_CMD_ADDR1_0); + + write_data = reg_addr; + writel(write_data, ape_i2c_base + I2C_I2C_CMD_DATA1_0); + + write_data = 0x1 << 11 | (0x1 << 4) | (0 << 6) | (1 << 7) | (1 << 9); + writel(write_data, ape_i2c_base + I2C_I2C_CNFG_0); /* Go */ + + /* CHECKING STATUS for Busy status */ + read_data = readl(ape_i2c_base + I2C_I2C_STATUS_0); + + while (read_data & 0x100) { /* wait for master busy LOW */ + pr_err("\n status before %9x\n", read_data); + read_data = readl(ape_i2c_base + I2C_I2C_STATUS_0); + } + + read_data = readl(ape_i2c_base + I2C_I2C_STATUS_0); + read_data = read_data & 0xFF; + + if (read_data) + pr_err("\nNoaCK Received for addr %d before %9x Byte\n", + reg_addr, read_data); + + read_data = readl(ape_i2c_base + I2C_I2C_CMD_DATA2_0); + + return read_data; +} +EXPORT_SYMBOL(i2c_read); + +void program_cdc_pll(u32 pll_no, u32 freq) +{ + unsigned int p = 0, n = 0, m = 0, i = 0; + u32 slv_add = 0; + u32 reg_add; + + if (pll_no == 1) + slv_add = 0x68; + else if (pll_no == 2) + slv_add = 0x69; + else if (pll_no == 3) + slv_add = 0x6a; + else if (pll_no == 4) + slv_add = 0x6b; + + switch (freq) { + case CLK_OUT_3_0720_MHZ: + m = 125; + n = 768; + p = 54; + break; + case CLK_OUT_4_0960_MHZ: + m = 375; + n = 2048; + p = 36; + break; + case CLK_OUT_5_6448_MHZ: + m = 75; + n = 392; + p = 25; + break; + case CLK_OUT_6_1440_MHZ: + m = 125; + n = 768; + p = 27; + break; + case CLK_OUT_8_1920_MHZ: + m = 375; + n = 2048; + p = 18; + break; + case CLK_OUT_11_2896_MHZ: + m = 375; + n = 1568; + p = 10; + break; + case CLK_OUT_12_2888_MHZ: + m = 375; + n = 2048; + p = 12; + break; + case CLK_OUT_16_3840_MHZ: + m = 375; + n = 2048; + p = 9; + break; + case CLK_OUT_16_9344_MHZ: + m = 125; + n = 784; + p = 10; + break; + case CLK_OUT_18_4320_MHZ: + m = 125; + n = 768; + p = 9; + break; + case CLK_OUT_22_5792_MHZ: + m = 375; + n = 1568; + p = 5; + break; + case CLK_OUT_24_5760_MHZ: + m = 375; + n = 2048; + p = 6; + break; + case CLK_OUT_33_8688_MHZ: + m = 125; + n = 784; + p = 5; + break; + case CLK_OUT_36_8640_MHZ: + m = 375; + n = 2048; + p = 4; + break; + case CLK_OUT_49_1520_MHZ: + m = 375; + n = 2048; + p = 3; + break; + case CLK_OUT_73_7280_MHZ: + m = 375; + n = 2048; + p = 2; + break; + case CLK_OUT_162_MHZ: + m = 1; + n = 6; + p = 1; + break; + + default: + m = 1; + break; + } + + pr_err("\n PLL Parems SLV_ADD 0x%x, freq %d M %d N %d P %d\n", + slv_add, freq, m, n, p); + + i2c_write(slv_add, (10 | 1 << 7), 0xff, 2); + + cdce906_setting[1] = (unsigned char)m & 0xff; + cdce906_setting[2] = (unsigned char)n & 0xff; + cdce906_setting[3] &= ~(0x1f); + cdce906_setting[3] |= (unsigned char)((((n >> 8) & 0xf) << 1) | ((m >> 8) & 1)); + cdce906_setting[12] |= (0<<6); /* 0 : power on, 1 : power off */ + cdce906_setting[13] = p; + + for (i = 1; i < 25; i++) { + pr_err("\n I2C_PLL_PRJ SLV_ADD 0x%x, REG_ADD 0x%x REG_DATA 0x%x\n", + slv_add, i, cdce906_setting[i]); + reg_add = i | (1 << 7); + i2c_write(slv_add, reg_add, cdce906_setting[i], 2); + } +} +EXPORT_SYMBOL(program_cdc_pll); + +void program_io_expander(void) +{ + i2c_write(0x20, 0x2, 0x99, 2); + i2c_write(0x20, 0x6, 0x00, 2); + i2c_write(0x20, 0x3, 0x99, 2); + i2c_write(0x20, 0x7, 0x00, 2); + i2c_write(0x21, 0x2, 0x09, 2); + i2c_write(0x21, 0x6, 0x00, 2); +} +EXPORT_SYMBOL(program_io_expander); + +void program_max_codec(void) +{ + unsigned int i; + unsigned char read_data; + /* mclk_freq(system clock) - 0x10 : 12.288Mhz, 0x8 : 12Mhz */ + unsigned char mclk_freq = 0x10; + /* frame_rate - 0x1 : 8khz, 0x2 : 16khz, 0x10 : 32khz, + 0x4 : 44.1khz, 0x8 : 48khz, 0x20 : 96khz */ + unsigned char frame_rate = 0x1; + /* codec_data_format - 1 : codec slave, 2 : codec master */ + unsigned char codec_data_format = 1; + unsigned char codec_slv_add = 0x10; + unsigned char loopback = 0; /* DIN -> DOUT */ + unsigned int power = 1; /* 1 : on, 0 : off */ + +#if DEBUG_FPGA + pr_err("Audio maxim 98090/98091 codec programming\n"); +#endif + i2c_write(codec_slv_add, 0x03, 0x04, 2); + i2c_write(codec_slv_add, 0x04, mclk_freq, 2); + i2c_write(codec_slv_add, 0x05, frame_rate, 2); + i2c_write(codec_slv_add, 0x06, codec_data_format, 2); + i2c_write(codec_slv_add, 0x07, 0x80, 2); + i2c_write(codec_slv_add, 0x08, 0x80, 2); + i2c_write(codec_slv_add, 0x09, 0x80, 2); + i2c_write(codec_slv_add, 0x07, 0x80, 2); + i2c_write(codec_slv_add, 0x08, 0x00, 2); + i2c_write(codec_slv_add, 0x09, 0x20, 2); + i2c_write(codec_slv_add, 0x0a, 0x00, 2); + i2c_write(codec_slv_add, 0x0b, 0x00, 2); + i2c_write(codec_slv_add, 0x0d, 0x03, 2); + i2c_write(codec_slv_add, 0x0e, 0x1b, 2); + i2c_write(codec_slv_add, 0x0f, 0x00, 2); + i2c_write(codec_slv_add, 0x10, 0x00, 2); + i2c_write(codec_slv_add, 0x11, 0x00, 2); + i2c_write(codec_slv_add, 0x12, 0x00, 2); + i2c_write(codec_slv_add, 0x13, 0x00, 2); + i2c_write(codec_slv_add, 0x14, 0x00, 2); + i2c_write(codec_slv_add, 0x15, 0x08, 2); + i2c_write(codec_slv_add, 0x16, 0x10, 2); + i2c_write(codec_slv_add, 0x17, 0x03, 2); + i2c_write(codec_slv_add, 0x18, 0x03, 2); + i2c_write(codec_slv_add, 0x19, 0x00, 2); + i2c_write(codec_slv_add, 0x1a, 0x00, 2); + i2c_write(codec_slv_add, 0x1b, 0x10, 2); + i2c_write(codec_slv_add, 0x1c, 0x00, 2); + i2c_write(codec_slv_add, 0x1d, 0x00, 2); + i2c_write(codec_slv_add, 0x1e, 0x00, 2); + i2c_write(codec_slv_add, 0x1f, 0x00, 2); + i2c_write(codec_slv_add, 0x20, 0x00, 2); + i2c_write(codec_slv_add, 0x21, + ((codec_data_format == 1) ? 0x03 : 0x83), 2); + i2c_write(codec_slv_add, 0x22, 0x04, 2); + i2c_write(codec_slv_add, 0x23, 0x00, 2); + i2c_write(codec_slv_add, 0x24, 0x00, 2); + i2c_write(codec_slv_add, 0x25, (loopback<<4)|0x03, 2); + i2c_write(codec_slv_add, 0x26, 0x00, 2); + i2c_write(codec_slv_add, 0x27, 0x00, 2); + i2c_write(codec_slv_add, 0x28, 0x00, 2); + i2c_write(codec_slv_add, 0x29, 0x01, 2); + i2c_write(codec_slv_add, 0x2a, 0x02, 2); + i2c_write(codec_slv_add, 0x2b, 0x00, 2); + i2c_write(codec_slv_add, 0x2c, 0x1a, 2); + i2c_write(codec_slv_add, 0x2d, 0x1a, 2); + /* speaker settings */ + i2c_write(codec_slv_add, 0x2e, 0x01, 2); + i2c_write(codec_slv_add, 0x2f, 0x02, 2); + i2c_write(codec_slv_add, 0x30, 0x00, 2); + i2c_write(codec_slv_add, 0x31, 0x2c, 2); + i2c_write(codec_slv_add, 0x32, 0x2c, 2); + + /* head phone settings */ + /* i2c_write(codec_slv_add, 0x2e, 0x20,2, 2); */ + /* i2c_write(codec_slv_add, 0x2f, 0x50,2, 2); */ + /* i2c_write(codec_slv_add, 0x30, 0x00,2, 2); */ + /* i2c_write(codec_slv_add, 0x31, 0x2c,2, 2); */ + /* i2c_write(codec_slv_add, 0x32, 0x2c,2, 2); */ + + i2c_write(codec_slv_add, 0x33, 0x00, 2); + i2c_write(codec_slv_add, 0x34, 0x00, 2); + i2c_write(codec_slv_add, 0x35, 0x00, 2); + i2c_write(codec_slv_add, 0x36, 0x00, 2); + i2c_write(codec_slv_add, 0x37, 0x00, 2); + i2c_write(codec_slv_add, 0x38, 0x00, 2); + i2c_write(codec_slv_add, 0x39, 0x95, 2); + i2c_write(codec_slv_add, 0x3a, 0x00, 2); + i2c_write(codec_slv_add, 0x3b, 0x00, 2); + i2c_write(codec_slv_add, 0x3c, 0x15, 2); + i2c_write(codec_slv_add, 0x3d, 0x00, 2); + i2c_write(codec_slv_add, 0x3e, 0x0f, 2); + i2c_write(codec_slv_add, 0x3f, 0xff, 2); + i2c_write(codec_slv_add, 0x40, 0x00, 2); + i2c_write(codec_slv_add, 0x41, 0x00, 2); + i2c_write(codec_slv_add, 0x42, 0x00, 2); + i2c_write(codec_slv_add, 0x43, 0x01, 2); + i2c_write(codec_slv_add, 0x44, 0x01, 2); + i2c_write(codec_slv_add, 0x45, power<<7, 2); + + for (i = 1; i < 0x50; i++) { + read_data = i2c_read(codec_slv_add, i); +#if DEBUG_FPGA + pr_err( + "I2C_MAX_CODEC_READ Reg_Value 0x%x, ADD 0x%x Value 0x%x\n", + codec_slv_add, i, read_data); +#endif + } +} +EXPORT_SYMBOL(program_max_codec); +/* DMIC */ + +void program_dmic_gpio(void) +{ +#if !SYSTEM_FPGA + writel(0x1, ahub_gpio_base + APE_AHUB_GPIO_CNF_0); + writel(0x1, ahub_gpio_base + APE_AHUB_GPIO_OE_0); + writel(0x1, ahub_gpio_base + APE_AHUB_GPIO_OUT_0); +#endif +} +EXPORT_SYMBOL(program_dmic_gpio); +void program_dmic_clk(int dmic_clk) +{ + void __iomem *misc_base = ahub_unit_fpga_private.ape_fpga_misc_base; +#if !SYSTEM_FPGA + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_I2C1_0); + + switch (dmic_clk) { + case 256000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0xf, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 512000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0x7, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 1024000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0x3, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 1411200: + program_cdc_pll(2, CLK_OUT_5_6448_MHZ); + writel(0x3, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 1536000: + program_cdc_pll(2, CLK_OUT_6_1440_MHZ); + writel(0x3, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 2048000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 2822400: + program_cdc_pll(2, CLK_OUT_5_6448_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 3072000: + program_cdc_pll(2, CLK_OUT_6_1440_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 4096000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0x0, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 5644800: + program_cdc_pll(2, CLK_OUT_11_2896_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 6144000: + program_cdc_pll(2, CLK_OUT_12_2888_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 11289600: + program_cdc_pll(2, CLK_OUT_11_2896_MHZ); + writel(0x0, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + case 12288000: + program_cdc_pll(2, CLK_OUT_12_2888_MHZ); + writel(0x0, misc_base + APE_FPGA_MISC_CLK_SOURCE_DMIC1_0); + break; + default: + pr_err("Unsupported sample rate and OSR combination\n"); + } + #endif +} +EXPORT_SYMBOL(program_dmic_clk); + +void program_dspk_clk(int dspk_clk) +{ + void __iomem *misc_base; + struct ahub_unit_fpga *ahub_unit_fpga_private; + + ahub_unit_fpga_private = get_ahub_unit_fpga_private(); + misc_base = ahub_unit_fpga_private->ape_fpga_misc_base; +#if !SYSTEM_FPGA + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_I2C1_0); + + switch (dspk_clk) { + case 256000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0xf, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 512000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0x7, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 1024000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0x3, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 1411200: + program_cdc_pll(2, CLK_OUT_5_6448_MHZ); + writel(0x3, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 1536000: + program_cdc_pll(2, CLK_OUT_6_1440_MHZ); + writel(0x3, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 2048000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 2822400: + program_cdc_pll(2, CLK_OUT_5_6448_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 3072000: + program_cdc_pll(2, CLK_OUT_6_1440_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 4096000: + program_cdc_pll(2, CLK_OUT_4_0960_MHZ); + writel(0x0, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 5644800: + program_cdc_pll(2, CLK_OUT_11_2896_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 6144000: + program_cdc_pll(2, CLK_OUT_12_2888_MHZ); + writel(0x1, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 11289600: + program_cdc_pll(2, CLK_OUT_11_2896_MHZ); + writel(0x0, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + case 12288000: + program_cdc_pll(2, CLK_OUT_12_2888_MHZ); + writel(0x0, misc_base + APE_FPGA_MISC_CLK_SOURCE_DSPK1_0); + break; + default: + pr_err("Unsupported sample rate and OSR combination\n"); + } +#endif +} +EXPORT_SYMBOL(program_dspk_clk); + +/** + * AD1937 + */ +static unsigned char ad1937x_enable[17] = { + /* AD1937_PLL_CLK_CTRL_0 */ + AD1937_PLL_CLK_CTRL_0_PWR_OFF | + AD1937_PLL_CLK_CTRL_0_MCLKI_512 | + AD1937_PLL_CLK_CTRL_0_MCLKO_OFF | + AD1937_PLL_CLK_CTRL_0_PLL_INPUT_MCLKI | + AD1937_PLL_CLK_CTRL_0_INTERNAL_MASTER_CLK_ENABLE, + + /* AD1937_PLL_CLK_CTRL_1 */ + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL | + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL | + AD1937_PLL_CLK_CTRL_1_VREF_ENABLE, + + /* AD1937_DAC_CTRL_0 */ + AD1937_DAC_CTRL_0_PWR_ON | + AD1937_DAC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ | + AD1937_DAC_CTRL_0_DSDATA_DELAY_1 | + AD1937_DAC_CTRL_0_FMT_STEREO, + + /* AD1937_DAC_CTRL_1 */ + AD1937_DAC_CTRL_1_DBCLK_ACTIVE_EDGE_MIDCYCLE | + AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_256 | + AD1937_DAC_CTRL_1_DLRCLK_POLARITY_LEFT_LOW | + AD1937_DAC_CTRL_1_DLRCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SOURCE_DBCLK_PIN | + AD1937_DAC_CTRL_1_DBCLK_POLARITY_NORMAL, + + /* AD1937_DAC_CTRL_2 */ + AD1937_DAC_CTRL_2_MASTER_UNMUTE | + AD1937_DAC_CTRL_2_DEEMPHASIS_FLAT | + AD1937_DAC_CTRL_2_WORD_WIDTH_16_BITS | /* sample size */ + AD1937_DAC_CTRL_2_DAC_OUTPUT_POLARITY_NORMAL, + + /* AD1937_DAC_MUTE_CTRL */ + AD1937_DAC_MUTE_CTRL_DAC1L_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC1R_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC2L_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC2R_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC3L_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC3R_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC4L_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC4R_UNMUTE, + + /* AD1937_DAC_VOL_CTRL_DAC1L */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC1R */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC2L */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC2R */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC3L */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC3R */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC4L */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC4R */ + 0, + + /* AD1937_ADC_CTRL_0 */ + AD1937_ADC_CTRL_0_PWR_OFF | + AD1937_ADC_CTRL_0_HIGH_PASS_FILTER_ON | + AD1937_ADC_CTRL_0_ADC1L_MUTE | + AD1937_ADC_CTRL_0_ADC1R_MUTE | + AD1937_ADC_CTRL_0_ADC2L_MUTE | + AD1937_ADC_CTRL_0_ADC2R_MUTE | + AD1937_ADC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ, + + /* AD1937_ADC_CTRL_1 */ + AD1937_ADC_CTRL_1_WORD_WIDTH_16_BITS | /* sample size */ + AD1937_ADC_CTRL_1_ASDATA_DELAY_1 | + AD1937_ADC_CTRL_1_FMT_STEREO | + AD1937_ADC_CTRL_1_ABCLK_ACTIVE_EDGE_PIPELINE, + + /* AD1937_ADC_CTRL_2 */ + AD1937_ADC_CTRL_2_ALRCLK_FMT_50_50 | + AD1937_ADC_CTRL_2_ABCLK_POLARITY_RISING_EDGE | + AD1937_ADC_CTRL_2_ALRCLK_POLARITY_LEFT_LOW | + AD1937_ADC_CTRL_2_ALRCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_64 | + AD1937_ADC_CTRL_2_ABCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_SOURCE_ABCLK_PIN +}; + +/** + * AD1937 + */ +static unsigned char ad1937y_enable[17] = { + /* AD1937_PLL_CLK_CTRL_0 */ + AD1937_PLL_CLK_CTRL_0_PWR_OFF | + AD1937_PLL_CLK_CTRL_0_MCLKI_512 | + AD1937_PLL_CLK_CTRL_0_MCLKO_OFF | + AD1937_PLL_CLK_CTRL_0_PLL_INPUT_MCLKI | + AD1937_PLL_CLK_CTRL_0_INTERNAL_MASTER_CLK_ENABLE, + + /* AD1937_PLL_CLK_CTRL_1 */ + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL | + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL | + AD1937_PLL_CLK_CTRL_1_VREF_ENABLE, + + /* AD1937_DAC_CTRL_0 */ + AD1937_DAC_CTRL_0_PWR_ON | + AD1937_DAC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ | + AD1937_DAC_CTRL_0_DSDATA_DELAY_1 | + AD1937_DAC_CTRL_0_FMT_STEREO, + + /* AD1937_DAC_CTRL_1 */ + AD1937_DAC_CTRL_1_DBCLK_ACTIVE_EDGE_MIDCYCLE | + AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_256 | + AD1937_DAC_CTRL_1_DLRCLK_POLARITY_LEFT_LOW | + AD1937_DAC_CTRL_1_DLRCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SOURCE_DBCLK_PIN | + AD1937_DAC_CTRL_1_DBCLK_POLARITY_NORMAL, + + /* AD1937_DAC_CTRL_2 */ + AD1937_DAC_CTRL_2_MASTER_UNMUTE | + AD1937_DAC_CTRL_2_DEEMPHASIS_FLAT | + AD1937_DAC_CTRL_2_WORD_WIDTH_16_BITS | /* sample size */ + AD1937_DAC_CTRL_2_DAC_OUTPUT_POLARITY_NORMAL, + + /* AD1937_DAC_MUTE_CTRL */ + AD1937_DAC_MUTE_CTRL_DAC1L_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC1R_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC2L_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC2R_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC3L_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC3R_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC4L_UNMUTE | + AD1937_DAC_MUTE_CTRL_DAC4R_UNMUTE, + + /* AD1937_DAC_VOL_CTRL_DAC1L */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC1R */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC2L */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC2R */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC3L */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC3R */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC4L */ + 0, + + /* AD1937_DAC_VOL_CTRL_DAC4R */ + 0, + + /* AD1937_ADC_CTRL_0 */ + AD1937_ADC_CTRL_0_PWR_OFF | + AD1937_ADC_CTRL_0_HIGH_PASS_FILTER_OFF | + AD1937_ADC_CTRL_0_ADC1L_MUTE | + AD1937_ADC_CTRL_0_ADC1R_MUTE | + AD1937_ADC_CTRL_0_ADC2L_MUTE | + AD1937_ADC_CTRL_0_ADC2R_MUTE | + AD1937_ADC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ, + + /* AD1937_ADC_CTRL_1 */ + AD1937_ADC_CTRL_1_WORD_WIDTH_16_BITS | /* sample size */ + AD1937_ADC_CTRL_1_ASDATA_DELAY_1 | + AD1937_ADC_CTRL_1_FMT_STEREO | + AD1937_ADC_CTRL_1_ABCLK_ACTIVE_EDGE_MIDCYCLE, + + /* AD1937_ADC_CTRL_2 */ + AD1937_ADC_CTRL_2_ALRCLK_FMT_50_50 | + AD1937_ADC_CTRL_2_ABCLK_POLARITY_RISING_EDGE | + AD1937_ADC_CTRL_2_ALRCLK_POLARITY_LEFT_LOW | + AD1937_ADC_CTRL_2_ALRCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_64 | + AD1937_ADC_CTRL_2_ABCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_SOURCE_ABCLK_PIN +}; + +static unsigned char *ad1937_enable[2] = {ad1937x_enable, ad1937y_enable}; + +void SetMax9485(int freq) +{ + unsigned char max9485_value; + + switch (freq) { + default: + case CLK_OUT_12_2888_MHZ: + max9485_value = MAX9485_MCLK_FREQ_122880; + break; + case CLK_OUT_11_2896_MHZ: + max9485_value = MAX9485_MCLK_FREQ_112896; + break; + case CLK_OUT_24_5760_MHZ: + max9485_value = MAX9485_MCLK_FREQ_245760; + break; + case CLK_OUT_22_5792_MHZ: + max9485_value = MAX9485_MCLK_FREQ_225792; + break; + } + + i2c_write(MAX9485_DEVICE_ADDRESS, max9485_value, 0, 1); +} +EXPORT_SYMBOL(SetMax9485); + +void OnAD1937CaptureAndPlayback(int mode, + int codec_data_format, + int codec_data_width, + int bit_size, + int polarity, + int bitclk_inv, + int frame_rate, + AD1937_EXTRA_INFO *pExtraInfo) +{ + int i; + int target_freq = CLK_OUT_24_5760_MHZ; /* default */ + int codec_idx; + + codec_idx = (pExtraInfo->codecId == AD1937_X_ADDRESS) ? 0 : 1; + + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] &= ~(AD1937_PLL_CLK_CTRL_0_MCLKI_MASK); + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] &= ~(AD1937_PLL_CLK_CTRL_0_PWR_MASK); + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] &= ~(AD1937_PLL_CLK_CTRL_1_DAC_CLK_MASK); + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] &= ~(AD1937_PLL_CLK_CTRL_1_ADC_CLK_MASK); + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] &= ~(AD1937_DAC_CTRL_0_SAMPLE_RATE_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] &= ~(AD1937_ADC_CTRL_0_SAMPLE_RATE_MASK); + + switch (frame_rate) { + case AUDIO_SAMPLE_RATE_8_00: + target_freq = CLK_OUT_4_0960_MHZ; /* direct MCLK mode */ + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_OFF; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_MCLK; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_MCLK; + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + break; + case AUDIO_SAMPLE_RATE_16_00: + target_freq = CLK_OUT_8_1920_MHZ; /* direct MCLK mode */ + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_OFF; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_MCLK; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_MCLK; + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + break; + case AUDIO_SAMPLE_RATE_32_00: + if (pExtraInfo->mclk_mode == AD1937_MCLK_DIRECT_MODE) { + /* direct MCLK mode */ + target_freq = CLK_OUT_16_3840_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_OFF; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_MCLK; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_MCLK; + } else { + /* internal PLL mode */ + target_freq = CLK_OUT_8_1920_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_MCLKI_256; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + } + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + break; + case AUDIO_SAMPLE_RATE_44_10: + if (pExtraInfo->mclk_mode == AD1937_MCLK_DIRECT_MODE) { + /* direct MCLK mode */ + target_freq = CLK_OUT_22_5792_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_OFF; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_MCLK; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_MCLK; + } else { + /* internal PLL mode */ + target_freq = CLK_OUT_11_2896_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_MCLKI_256; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + } + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + break; + case AUDIO_SAMPLE_RATE_48_00: + if (pExtraInfo->mclk_mode == AD1937_MCLK_DIRECT_MODE) { + /* direct MCLK mode */ + target_freq = CLK_OUT_24_5760_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_OFF; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + (bit_size != 512) ? 0 : + AD1937_PLL_CLK_CTRL_0_MCLKI_512; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_MCLK; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_MCLK; + } else { + /* internal PLL mode */ + target_freq = CLK_OUT_12_2888_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PLL_INPUT_DLRCLK; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + } + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_32_44_1_48_KHZ; + break; + case AUDIO_SAMPLE_RATE_64_00: + /* internal PLL mode */ + target_freq = CLK_OUT_16_3840_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_MCLKI_512; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_64_88_2_96_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_64_88_2_96_KHZ; + break; + case AUDIO_SAMPLE_RATE_88_20: + /* internal PLL mode */ + target_freq = CLK_OUT_22_5792_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_MCLKI_512; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_64_88_2_96_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_64_88_2_96_KHZ; + break; + case AUDIO_SAMPLE_RATE_96_00: + /* internal PLL mode */ + target_freq = CLK_OUT_24_5760_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_MCLKI_512; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_64_88_2_96_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_64_88_2_96_KHZ; + break; + case AUDIO_SAMPLE_RATE_128_00: + /* internal PLL mode */ + target_freq = CLK_OUT_16_3840_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_MCLKI_512; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_128_176_4_192_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_128_176_4_192_KHZ; + break; + case AUDIO_SAMPLE_RATE_176_40: + /* internal PLL mode */ + target_freq = CLK_OUT_22_5792_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_MCLKI_512; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_128_176_4_192_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_128_176_4_192_KHZ; + break; + case AUDIO_SAMPLE_RATE_192_00: + /* internal PLL mode */ + target_freq = CLK_OUT_24_5760_MHZ; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= + AD1937_PLL_CLK_CTRL_0_MCLKI_512; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_DAC_CLK_PLL; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_1] |= + AD1937_PLL_CLK_CTRL_1_ADC_CLK_PLL; + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= + AD1937_DAC_CTRL_0_SAMPLE_RATE_128_176_4_192_KHZ; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= + AD1937_ADC_CTRL_0_SAMPLE_RATE_128_176_4_192_KHZ; + break; + default: + break; + } + + { + /* slave mode clock setting */ + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] &= + ~(AD1937_DAC_CTRL_1_DLRCLK_MASK | + AD1937_DAC_CTRL_1_DBCLK_MASK | + AD1937_DAC_CTRL_1_DBCLK_SOURCE_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] &= + ~(AD1937_ADC_CTRL_2_ALRCLK_MASK | + AD1937_ADC_CTRL_2_ABCLK_MASK | + AD1937_ADC_CTRL_2_ABCLK_SOURCE_MASK); + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] |= + (AD1937_DAC_CTRL_1_DLRCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SOURCE_DBCLK_PIN); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= + (AD1937_ADC_CTRL_2_ALRCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_SOURCE_ABCLK_PIN); + } + + if (pExtraInfo->daisyEn) { + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] &= ~(AD1937_PLL_CLK_CTRL_0_PWR_MASK); + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= AD1937_PLL_CLK_CTRL_0_PWR_ON; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= AD1937_PLL_CLK_CTRL_0_MCLKI_512; + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] &= ~(AD1937_PLL_CLK_CTRL_0_MCLKO_MASK); + ad1937_enable[codec_idx][AD1937_PLL_CLK_CTRL_0] |= AD1937_PLL_CLK_CTRL_0_MCLKO_512; + } + + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] &= ~(AD1937_DAC_CTRL_1_DLRCLK_MASK | + AD1937_DAC_CTRL_1_DBCLK_MASK | + AD1937_DAC_CTRL_1_DBCLK_SOURCE_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] &= ~(AD1937_ADC_CTRL_2_ALRCLK_MASK | + AD1937_ADC_CTRL_2_ABCLK_MASK | + AD1937_ADC_CTRL_2_ABCLK_SOURCE_MASK); + + if (mode == AUDIO_CODEC_MASTER_MODE) { + if (pExtraInfo->dacMasterEn) { /* DAC is master */ + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] |= (AD1937_DAC_CTRL_1_DLRCLK_MASTER | + AD1937_DAC_CTRL_1_DBCLK_MASTER | + AD1937_DAC_CTRL_1_DBCLK_SOURCE_INTERNAL); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= (AD1937_ADC_CTRL_2_ALRCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_SOURCE_ABCLK_PIN); + } else { /* ADC is master */ + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] |= (AD1937_DAC_CTRL_1_DLRCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SOURCE_DBCLK_PIN); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= (AD1937_ADC_CTRL_2_ALRCLK_MASTER | + AD1937_ADC_CTRL_2_ABCLK_MASTER | + AD1937_ADC_CTRL_2_ABCLK_SOURCE_INTERNAL); + } + } else { + pr_err("++AD1937 Slave\n"); + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] |= (AD1937_DAC_CTRL_1_DLRCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SLAVE | + AD1937_DAC_CTRL_1_DBCLK_SOURCE_INTERNAL); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= (AD1937_ADC_CTRL_2_ALRCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_SLAVE | + AD1937_ADC_CTRL_2_ABCLK_SOURCE_INTERNAL); + } + + /* Bit width */ + ad1937_enable[codec_idx][AD1937_DAC_CTRL_2] &= ~(AD1937_DAC_CTRL_2_WORD_WIDTH_MASK); + if (codec_data_width == I2S_DATAWIDTH_16) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_2] |= AD1937_DAC_CTRL_2_WORD_WIDTH_16_BITS; + else if (codec_data_width == I2S_DATAWIDTH_20) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_2] |= AD1937_DAC_CTRL_2_WORD_WIDTH_20_BITS; + else if (codec_data_width == I2S_DATAWIDTH_24) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_2] |= AD1937_DAC_CTRL_2_WORD_WIDTH_24_BITS; + else + pr_err("Not support this codec data width\r\n"); + + /* Delay & Serial Format */ + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] &= ~(AD1937_DAC_CTRL_0_DSDATA_DELAY_MASK | + AD1937_DAC_CTRL_0_FMT_MASK); + switch (codec_data_format) { + case AUDIO_INTERFACE_LJM_FORMAT: + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_FMT_STEREO; + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_DSDATA_DELAY_0; + break; + case AUDIO_INTERFACE_RJM_FORMAT: + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_FMT_STEREO; + if (codec_data_width == I2S_DATAWIDTH_16) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_DSDATA_DELAY_16; + else if (codec_data_width == I2S_DATAWIDTH_20) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_DSDATA_DELAY_12; + else if (codec_data_width == I2S_DATAWIDTH_24) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_DSDATA_DELAY_8; + break; + case AUDIO_INTERFACE_TDM_FORMAT: + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_FMT_TDM_SINGLE_LINE; + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_DSDATA_DELAY_1; + break; + case AUDIO_INTERFACE_I2S_FORMAT: + default: + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_FMT_STEREO; + ad1937_enable[codec_idx][AD1937_DAC_CTRL_0] |= AD1937_DAC_CTRL_0_DSDATA_DELAY_1; + break; + break; + } + + /* BCLKs per frame */ + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] &= ~(AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_MASK); + if (bit_size == 64) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] |= AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_64; + else if (bit_size == 128) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] |= AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_128; + else if (bit_size == 256) + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] |= AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_256; + else + ad1937_enable[codec_idx][AD1937_DAC_CTRL_1] |= AD1937_DAC_CTRL_1_DBCLK_PER_FRAME_512; + + /* Bit width */ + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] &= ~(AD1937_ADC_CTRL_1_WORD_WIDTH_MASK); + + if (codec_data_width == I2S_DATAWIDTH_16) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_WORD_WIDTH_16_BITS; + else if (codec_data_width == I2S_DATAWIDTH_20) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_WORD_WIDTH_20_BITS; + else if (codec_data_width == I2S_DATAWIDTH_24) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_WORD_WIDTH_24_BITS; + else + pr_err("Not support this codec data width\r\n"); + + /* Delay & Serial Format */ + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] &= ~(AD1937_ADC_CTRL_1_ASDATA_DELAY_MASK | + AD1937_ADC_CTRL_1_FMT_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] &= ~(AD1937_ADC_CTRL_2_ALRCLK_FMT_MASK); + switch (codec_data_format) { + case AUDIO_INTERFACE_LJM_FORMAT: + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_FMT_STEREO; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_ASDATA_DELAY_0; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ALRCLK_FMT_50_50; + break; + case AUDIO_INTERFACE_RJM_FORMAT: + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_DAC_CTRL_0_FMT_STEREO; + if (codec_data_width == I2S_DATAWIDTH_16) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_ASDATA_DELAY_16; + else if (codec_data_width == I2S_DATAWIDTH_20) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_ASDATA_DELAY_12; + else if (codec_data_width == I2S_DATAWIDTH_24) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_ASDATA_DELAY_8; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ALRCLK_FMT_50_50; + break; + case AUDIO_INTERFACE_TDM_FORMAT: + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_FMT_TDM_SINGLE_LINE; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_ASDATA_DELAY_1; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ALRCLK_FMT_50_50; + + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] &= ~(AD1937_ADC_CTRL_2_ABCLK_POLARITY_MASK); + if (mode == AUDIO_CODEC_MASTER_MODE) { + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ABCLK_POLARITY_FALLING_EDGE; + } else { + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ABCLK_POLARITY_RISING_EDGE; + } + break; + case AUDIO_INTERFACE_I2S_FORMAT: + default: + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_FMT_STEREO; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_1] |= AD1937_ADC_CTRL_1_ASDATA_DELAY_1; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ALRCLK_FMT_50_50; + + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] &= ~(AD1937_ADC_CTRL_2_ABCLK_POLARITY_MASK); + if (mode == AUDIO_CODEC_MASTER_MODE) { + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ABCLK_POLARITY_FALLING_EDGE; + } else { + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ABCLK_POLARITY_RISING_EDGE; + } + break; + } + + /* BCLKs per frame */ + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] &= ~(AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_MASK); + if (bit_size == 64) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_64; + else if (bit_size == 128) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_128; + else if (bit_size == 256) + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_256; + else + ad1937_enable[codec_idx][AD1937_ADC_CTRL_2] |= AD1937_ADC_CTRL_2_ABCLK_PER_FRAME_512; + + /* Power On ADC */ + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] &= (~AD1937_ADC_CTRL_0_PWR_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= AD1937_ADC_CTRL_0_PWR_ON; + + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] &= (~AD1937_ADC_CTRL_0_ADC1L_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= AD1937_ADC_CTRL_0_ADC1L_UNMUTE; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] &= (~AD1937_ADC_CTRL_0_ADC1R_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= AD1937_ADC_CTRL_0_ADC1R_UNMUTE; + + + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] &= (~AD1937_ADC_CTRL_0_ADC2L_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= AD1937_ADC_CTRL_0_ADC2L_UNMUTE; + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] &= (~AD1937_ADC_CTRL_0_ADC2R_MASK); + ad1937_enable[codec_idx][AD1937_ADC_CTRL_0] |= AD1937_ADC_CTRL_0_ADC2R_UNMUTE; + + for (i = 0; i < 17; i++) { + unsigned char val[4]; + val[0] = i; + val[1] = ad1937_enable[codec_idx][i]; + val[2] = i; + + i2c_write(pExtraInfo->codecId, val[0], val[1], 2); /*wri2c 0x20 0x00 0x00 */ + val[3] = i2c_read(pExtraInfo->codecId, val[2]); + pr_err("::Reg Addr 0x%02x 0x%02x : 0x%02x \r\n", i, ad1937_enable[codec_idx][i], val[3]); + } +} +EXPORT_SYMBOL(OnAD1937CaptureAndPlayback); + +struct ahub_unit_fpga *get_ahub_unit_fpga_private(void) +{ + return &ahub_unit_fpga_private; +} +EXPORT_SYMBOL(get_ahub_unit_fpga_private); + +void ahub_unit_fpga_init_t210(void) +{ + unsigned int i; + + t210_chip = true; + ahub_unit_fpga_private.ape_fpga_misc_base = + ioremap(T210_NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_BASE, 256); + for (i = 0; i < 5; i++) + ahub_unit_fpga_private.ape_fpga_misc_i2s_clk_base[i] = + ioremap(T210_NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_BASE + + ahub_fpga_misc_i2s_offset[i], 0x4); + ahub_unit_fpga_private.ape_i2c_base = + ioremap(T210_NV_ADDRESS_MAP_APE_AHUB_I2C_BASE, 512); + ahub_unit_fpga_private.pinmux_base = + ioremap(NV_ADDRESS_MAP_APB_PP_BASE, 512); + ahub_unit_fpga_private.ape_gpio_base = + ioremap(NV_ADDRESS_MAP_APE_AHUB_GPIO_BASE, 256); + ahub_unit_fpga_private.rst_clk_base = + ioremap(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE, 512); + ahub_unit_fpga_private.i2s5_cya_base = + ioremap(T210_NV_ADDRESS_MAP_APE_I2S5_BASE + I2S5_CYA_0, 0x10); +} +EXPORT_SYMBOL(ahub_unit_fpga_init_t210); + +void ahub_unit_fpga_init_t186(void) +{ + unsigned int i; + + t186_chip = true; + ahub_unit_fpga_private.ape_fpga_misc_base = + ioremap(T186_NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_BASE, 256); + for (i = 0; i < 5; i++) + ahub_unit_fpga_private.ape_fpga_misc_i2s_clk_base[i] = + ioremap(T186_NV_ADDRESS_MAP_APE_AHUB_FPGA_MISC_BASE + + ahub_fpga_misc_i2s_offset[i], 0x4); + ahub_unit_fpga_private.ape_i2c_base = + ioremap(T186_NV_ADDRESS_MAP_APE_AHUB_I2C_BASE, 512); + ahub_unit_fpga_private.pinmux_base = + ioremap(NV_ADDRESS_MAP_APB_PP_BASE, 512); + ahub_unit_fpga_private.ape_gpio_base = + ioremap(NV_ADDRESS_MAP_APE_AHUB_GPIO_BASE, 256); + ahub_unit_fpga_private.rst_clk_base = + ioremap(NV_ADDRESS_MAP_PPSB_CLK_RST_BASE, 512); + ahub_unit_fpga_private.i2s5_cya_base = + ioremap(T186_NV_ADDRESS_MAP_APE_I2S5_BASE + I2S5_CYA_0, 0x10); +} +EXPORT_SYMBOL(ahub_unit_fpga_init_t186); + +void ahub_unit_fpga_deinit(void) +{ + unsigned int i; + + t210_chip = false; + t186_chip = false; + iounmap(ahub_unit_fpga_private.ape_fpga_misc_base); + for (i = 0; i < 5; i++) + iounmap(ahub_unit_fpga_private.ape_fpga_misc_i2s_clk_base[i]); + iounmap(ahub_unit_fpga_private.ape_i2c_base); + iounmap(ahub_unit_fpga_private.pinmux_base); + iounmap(ahub_unit_fpga_private.ape_gpio_base); + iounmap(ahub_unit_fpga_private.rst_clk_base); + iounmap(ahub_unit_fpga_private.i2s5_cya_base); +} +EXPORT_SYMBOL(ahub_unit_fpga_deinit); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra-alt/utils/tegra210_xbar_utils_alt.c b/sound/soc/tegra-alt/utils/tegra210_xbar_utils_alt.c new file mode 100644 index 00000000..de181741 --- /dev/null +++ b/sound/soc/tegra-alt/utils/tegra210_xbar_utils_alt.c @@ -0,0 +1,473 @@ +/* + * tegra210_xbar_utils_alt.c - Tegra XBAR driver utils + * + * Copyright (c) 2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tegra210_xbar_alt.h" +#include "tegra210_xbar_utils_alt.h" + +static struct tegra_xbar *xbar; + +int tegra210_xbar_set_clock(unsigned long rate) +{ + int ret = 0; + + ret = clk_set_rate(xbar->clk_parent, rate); + if (ret) + pr_info("Failed to set clock rate of pll_a_out0\n"); + + ret = clk_set_rate(xbar->clk, rate); + if (ret) + pr_info("Failed to set clock rate of ahub\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(tegra210_xbar_set_clock); + +void tegra210_xbar_set_cif(struct regmap *regmap, unsigned int reg, + struct tegra210_xbar_cif_conf *conf) +{ + unsigned int value; + + value = (conf->threshold << + TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | + ((conf->audio_channels - 1) << + TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | + ((conf->client_channels - 1) << + TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) | + (conf->audio_bits << + TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) | + (conf->client_bits << + TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) | + (conf->expand << + TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT) | + (conf->stereo_conv << + TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) | + (conf->replicate << + TEGRA210_AUDIOCIF_CTRL_REPLICATE_SHIFT) | + (conf->truncate << + TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT) | + (conf->mono_conv << + TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT); + + regmap_update_bits(regmap, reg, 0x3fffffff, value); +} +EXPORT_SYMBOL_GPL(tegra210_xbar_set_cif); + +void tegra210_xbar_write_ahubram(struct regmap *regmap, unsigned int reg_ctrl, + unsigned int reg_data, unsigned int ram_offset, + unsigned int *data, size_t size) +{ + unsigned int val = 0; + int i = 0; + + val = (ram_offset << TEGRA210_AHUBRAMCTL_CTRL_RAM_ADDR_SHIFT) & + TEGRA210_AHUBRAMCTL_CTRL_RAM_ADDR_MASK; + val |= TEGRA210_AHUBRAMCTL_CTRL_ADDR_INIT_EN; + val |= TEGRA210_AHUBRAMCTL_CTRL_SEQ_ACCESS_EN; + val |= TEGRA210_AHUBRAMCTL_CTRL_RW_WRITE; + + regmap_write(regmap, reg_ctrl, val); + for (i = 0; i < size; i++) + regmap_write(regmap, reg_data, data[i]); + + return; +} +EXPORT_SYMBOL_GPL(tegra210_xbar_write_ahubram); + +void tegra210_xbar_read_ahubram(struct regmap *regmap, unsigned int reg_ctrl, + unsigned int reg_data, unsigned int ram_offset, + unsigned int *data, size_t size) +{ + unsigned int val = 0; + int i = 0; + + val = (ram_offset << TEGRA210_AHUBRAMCTL_CTRL_RAM_ADDR_SHIFT) & + TEGRA210_AHUBRAMCTL_CTRL_RAM_ADDR_MASK; + val |= TEGRA210_AHUBRAMCTL_CTRL_ADDR_INIT_EN; + val |= TEGRA210_AHUBRAMCTL_CTRL_SEQ_ACCESS_EN; + val |= TEGRA210_AHUBRAMCTL_CTRL_RW_READ; + + regmap_write(regmap, reg_ctrl, val); + /* Since all ahub non-io modules work under same ahub clock it is not + necessary to check ahub read busy bit after every read */ + for (i = 0; i < size; i++) + regmap_read(regmap, reg_data, &data[i]); + + return; +} +EXPORT_SYMBOL_GPL(tegra210_xbar_read_ahubram); + +int tegra210_xbar_read_reg (unsigned int reg, unsigned int *val) +{ + int ret; + + ret = regmap_read (xbar->regmap, reg, val); + return ret; +} +EXPORT_SYMBOL_GPL(tegra210_xbar_read_reg); + +int tegra_xbar_get_value_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int reg_count, reg_val, val, bit_pos = 0, i; + unsigned int reg[TEGRA_XBAR_UPDATE_MAX_REG]; + + reg_count = xbar->soc_data->reg_count; + + if (reg_count > TEGRA_XBAR_UPDATE_MAX_REG) + return -EINVAL; + + for (i = 0; i < reg_count; i++) { + reg[i] = (e->reg + + xbar->soc_data->reg_offset * i); + reg_val = snd_soc_read(codec, reg[i]); + val = reg_val & xbar->soc_data->mask[i]; + if (val != 0) { + bit_pos = ffs(val) + + (8*codec->component.val_bytes * i); + break; + } + } + + for (i = 0; i < e->items; i++) { + if (bit_pos == e->values[i]) { + ucontrol->value.enumerated.item[0] = i; + break; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_xbar_get_value_enum); + +int tegra_xbar_put_value_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); + struct snd_soc_dapm_context *dapm = + snd_soc_dapm_kcontrol_dapm(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int *item = ucontrol->value.enumerated.item; + unsigned int change = 0, reg_idx = 0, value, *mask, bit_pos = 0; + unsigned int i, reg_count, reg_val = 0, update_idx = 0; + unsigned int reg[TEGRA_XBAR_UPDATE_MAX_REG]; + struct snd_soc_dapm_update update[TEGRA_XBAR_UPDATE_MAX_REG]; + + /* initialize the reg_count and mask from soc_data */ + reg_count = xbar->soc_data->reg_count; + mask = (unsigned int *)xbar->soc_data->mask; + + if (item[0] >= e->items || reg_count > TEGRA_XBAR_UPDATE_MAX_REG) + return -EINVAL; + + value = e->values[item[0]]; + + if (value) { + /* get the register index and value to set */ + reg_idx = (value - 1) / (8 * codec->component.val_bytes); + bit_pos = (value - 1) % (8 * codec->component.val_bytes); + reg_val = BIT(bit_pos); + } + + for (i = 0; i < reg_count; i++) { + reg[i] = e->reg + xbar->soc_data->reg_offset * i; + if (i == reg_idx) { + change |= snd_soc_test_bits(codec, reg[i], + mask[i], reg_val); + /* set the selected register */ + update[reg_count - 1].reg = reg[reg_idx]; + update[reg_count - 1].mask = mask[reg_idx]; + update[reg_count - 1].val = reg_val; + } else { + /* accumulate the change to update the DAPM path + when none is selected */ + change |= snd_soc_test_bits(codec, reg[i], + mask[i], 0); + + /* clear the register when not selected */ + update[update_idx].reg = reg[i]; + update[update_idx].mask = mask[i]; + update[update_idx++].val = 0; + } + } + + /* power the widgets */ + if (change) { + for (i = 0; i < reg_count; i++) { + update[i].kcontrol = kcontrol; + snd_soc_dapm_mux_update_power(dapm, + kcontrol, item[0], e, &update[i]); + } + } + + return change; +} +EXPORT_SYMBOL_GPL(tegra_xbar_put_value_enum); + +bool tegra_xbar_volatile_reg(struct device *dev, unsigned int reg) +{ + return false; +} +EXPORT_SYMBOL_GPL(tegra_xbar_volatile_reg); + +int tegra_xbar_runtime_suspend(struct device *dev) +{ + +#ifdef CONFIG_TEGRA186_AHC + tegra186_free_ahc_interrupts(); +#endif + regcache_cache_only(xbar->regmap, true); + regcache_mark_dirty(xbar->regmap); + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + clk_disable_unprepare(xbar->clk); + clk_disable_unprepare(xbar->clk_ape); + clk_disable_unprepare(xbar->clk_apb2ape); + } + return 0; +} +EXPORT_SYMBOL_GPL(tegra_xbar_runtime_suspend); + +int tegra_xbar_runtime_resume(struct device *dev) +{ + int ret; + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + ret = clk_prepare_enable(xbar->clk_ape); + if (ret) { + dev_err(dev, "clk_prepare_enable failed: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(xbar->clk_apb2ape); + if (ret) { + dev_err(dev, "clk_prepare_enable failed: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(xbar->clk); + if (ret) { + dev_err(dev, "clk_prepare_enable failed: %d\n", ret); + return ret; + } + } +#ifdef CONFIG_TEGRA186_AHC + tegra186_setup_ahc_interrupts(); +#endif + regcache_cache_only(xbar->regmap, false); + + if (!xbar->is_shutdown) + regcache_sync(xbar->regmap); + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_xbar_runtime_resume); + +#ifdef CONFIG_PM_SLEEP +int tegra_xbar_suspend(struct device *dev) +{ + if (pm_runtime_status_suspended(dev)) + return 0; + + return tegra_xbar_runtime_suspend(dev); +} +EXPORT_SYMBOL_GPL(tegra_xbar_suspend); + +int tegra_xbar_resume(struct device *dev) +{ + if (pm_runtime_status_suspended(dev)) + return 0; + + return tegra_xbar_runtime_resume(dev); +} +EXPORT_SYMBOL_GPL(tegra_xbar_resume); +#endif + +void tegra_xbar_shutdown(struct platform_device *pdev) +{ + xbar->is_shutdown = true; +} +EXPORT_SYMBOL_GPL(tegra_xbar_shutdown); + +int tegra_xbar_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + tegra_xbar_runtime_suspend(&pdev->dev); + + tegra_pd_remove_device(&pdev->dev); + + devm_clk_put(&pdev->dev, xbar->clk); + devm_clk_put(&pdev->dev, xbar->clk_parent); + devm_clk_put(&pdev->dev, xbar->clk_ape); + devm_clk_put(&pdev->dev, xbar->clk_apb2ape); + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_xbar_remove); + +int tegra_xbar_codec_probe(struct snd_soc_codec *codec) +{ + codec->control_data = xbar->regmap; + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_xbar_codec_probe); + + +int tegra_xbar_probe(struct platform_device *pdev, + struct tegra_xbar_soc_data *soc_data) +{ + void __iomem *regs; + struct resource *res; + struct clk *parent_clk; + int ret; + + xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL); + if (!xbar) { + dev_err(&pdev->dev, "Can't allocate xbar\n"); + ret = -ENOMEM; + goto err; + } + + xbar->soc_data = soc_data; + xbar->is_shutdown = false; + + platform_set_drvdata(pdev, xbar); + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + xbar->clk = devm_clk_get(&pdev->dev, "ahub"); + if (IS_ERR(xbar->clk)) { + dev_err(&pdev->dev, "Can't retrieve ahub clock\n"); + ret = PTR_ERR(xbar->clk); + goto err; + } + + xbar->clk_parent = devm_clk_get(&pdev->dev, "pll_a_out0"); + if (IS_ERR(xbar->clk_parent)) { + dev_err(&pdev->dev, "Can't retrieve pll_a_out0 clock\n"); + ret = PTR_ERR(xbar->clk_parent); + goto err_clk_put; + } + + xbar->clk_apb2ape = devm_clk_get(&pdev->dev, "apb2ape"); + if (IS_ERR(xbar->clk_apb2ape)) { + dev_err(&pdev->dev, "Can't retrieve apb2ape clock\n"); + ret = PTR_ERR(xbar->clk_apb2ape); + goto err_clk_put_parent; + } + + xbar->clk_ape = devm_clk_get(&pdev->dev, "xbar.ape"); + if (IS_ERR(xbar->clk_ape)) { + dev_err(&pdev->dev, "Can't retrieve ape clock\n"); + ret = PTR_ERR(xbar->clk_ape); + goto err_clk_put_apb2ape; + } + } + + parent_clk = clk_get_parent(xbar->clk); + if (IS_ERR(parent_clk)) { + dev_err(&pdev->dev, "Can't get parent clock for xbar\n"); + ret = PTR_ERR(parent_clk); + goto err_clk_put_ape; + } + + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { + ret = clk_set_parent(xbar->clk, xbar->clk_parent); + if (ret) { + dev_err(&pdev->dev, "Failed to set parent clock with pll_a_out0\n"); + goto err_clk_put_ape; + } + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "No memory resource for admaif\n"); + ret = -ENODEV; + goto err; + } + + regs = devm_ioremap_resource(&pdev->dev, res); + if (!regs) { + dev_err(&pdev->dev, "request/iomap region failed\n"); + ret = -ENODEV; + goto err_clk_set_parent; + } + + xbar->regmap = devm_regmap_init_mmio(&pdev->dev, regs, + soc_data->regmap_config); + if (IS_ERR(xbar->regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + ret = PTR_ERR(xbar->regmap); + goto err_clk_set_parent; + } + regcache_cache_only(xbar->regmap, true); + + tegra_pd_add_device(&pdev->dev); + + pm_runtime_enable(&pdev->dev); + if (!pm_runtime_enabled(&pdev->dev)) { + ret = tegra_xbar_runtime_resume(&pdev->dev); + if (ret) + goto err_pm_disable; + } + + ret = soc_data->xbar_registration(pdev); + if (ret == -EBUSY) + goto err_suspend; + + return 0; + +err_suspend: + if (!pm_runtime_status_suspended(&pdev->dev)) + tegra_xbar_runtime_suspend(&pdev->dev); +err_pm_disable: + pm_runtime_disable(&pdev->dev); + tegra_pd_remove_device(&pdev->dev); +err_clk_set_parent: + clk_set_parent(xbar->clk, parent_clk); +err_clk_put_ape: + devm_clk_put(&pdev->dev, xbar->clk_ape); +err_clk_put_apb2ape: + devm_clk_put(&pdev->dev, xbar->clk_apb2ape); +err_clk_put_parent: + if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) + devm_clk_put(&pdev->dev, xbar->clk_parent); +err_clk_put: + devm_clk_put(&pdev->dev, xbar->clk); +err: + return ret; +} +EXPORT_SYMBOL_GPL(tegra_xbar_probe); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra-alt/utils/tegra_asoc_machine_alt.c b/sound/soc/tegra-alt/utils/tegra_asoc_machine_alt.c new file mode 100644 index 00000000..e1cfc35b --- /dev/null +++ b/sound/soc/tegra-alt/utils/tegra_asoc_machine_alt.c @@ -0,0 +1,3836 @@ +/* + * tegra_asoc_machine_alt.c - Tegra xbar dai link for machine drivers + * + * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "tegra_asoc_machine_alt.h" + +#define MAX_STR_SIZE 20 + +static struct snd_soc_dai_link *tegra_asoc_machine_links; +static struct snd_soc_codec_conf *tegra_asoc_codec_conf; +static unsigned int *bclk_ratio; +static unsigned int *tx_mask; +static unsigned int *rx_mask; +static unsigned int num_dai_links; + +/* used by only t18x specific APIs */ +static int num_links = TEGRA186_XBAR_DAI_LINKS; + +static struct snd_soc_pcm_stream default_link_params = { + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, +}; + +static struct snd_soc_pcm_stream tdm_link_params = { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 8, + .channels_max = 8, +}; + +static const char * const bit_format[] = { + "s8", "u8", "s16_le", "s16_be", + "u16_le", "u16_be", "s24_le", "s24_be", + "u24_le", "u24_be", "s32_le", "s32_be", + "u32_le", "u32_be", "float_le", "float_be", + + "float64_le", "float64_be", "iec958_subframe_le", "iec958_subframe_be", + "mu_law", "a_law", "ima_adpcm", "mpeg", + "gsm", "", "", "", + "", "", "", "special", + + "s24_3l", "s24_3be", "u24_3le", "u24_3be", + "s20_3le", "s20_3be", "u20_3le", "u20_3be", + "s18_3le", "s18_3b", "u18_3le", "u18_3be", + "g723_24", "g723_24_1b", "g723_40", "g723_40_1b", + + "dsd_u8", "dsd_u16_le", +}; + +static struct snd_soc_dai_link + tegra210_xbar_dai_links[TEGRA210_XBAR_DAI_LINKS] = { + [TEGRA210_DAI_LINK_ADMAIF1] = { + .name = "ADMAIF1 CIF", + .stream_name = "ADMAIF1 CIF", + .cpu_dai_name = "ADMAIF1", + .codec_dai_name = "ADMAIF1", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF2] = { + .name = "ADMAIF2 CIF", + .stream_name = "ADMAIF2 CIF", + .cpu_dai_name = "ADMAIF2", + .codec_dai_name = "ADMAIF2", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF3] = { + .name = "ADMAIF3 CIF", + .stream_name = "ADMAIF3 CIF", + .cpu_dai_name = "ADMAIF3", + .codec_dai_name = "ADMAIF3", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF4] = { + .name = "ADMAIF4 CIF", + .stream_name = "ADMAIF4 CIF", + .cpu_dai_name = "ADMAIF4", + .codec_dai_name = "ADMAIF4", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF5] = { + .name = "ADMAIF5 CIF", + .stream_name = "ADMAIF5 CIF", + .cpu_dai_name = "ADMAIF5", + .codec_dai_name = "ADMAIF5", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF6] = { + .name = "ADMAIF6 CIF", + .stream_name = "ADMAIF6 CIF", + .cpu_dai_name = "ADMAIF6", + .codec_dai_name = "ADMAIF6", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF7] = { + .name = "ADMAIF7 CIF", + .stream_name = "ADMAIF7 CIF", + .cpu_dai_name = "ADMAIF7", + .codec_dai_name = "ADMAIF7", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF8] = { + .name = "ADMAIF8 CIF", + .stream_name = "ADMAIF8 CIF", + .cpu_dai_name = "ADMAIF8", + .codec_dai_name = "ADMAIF8", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF9] = { + .name = "ADMAIF9 CIF", + .stream_name = "ADMAIF9 CIF", + .cpu_dai_name = "ADMAIF9", + .codec_dai_name = "ADMAIF9", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF10] = { + .name = "ADMAIF10 CIF", + .stream_name = "ADMAIF10 CIF", + .cpu_dai_name = "ADMAIF10", + .codec_dai_name = "ADMAIF10", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX1_1] = { + .name = "AMX1 IN1", + .stream_name = "AMX1 IN", + .cpu_dai_name = "AMX1-1", + .codec_dai_name = "IN1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX1_2] = { + .name = "AMX1 IN2", + .stream_name = "AMX1 IN", + .cpu_dai_name = "AMX1-2", + .codec_dai_name = "IN2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX1_3] = { + .name = "AMX1 IN3", + .stream_name = "AMX1 IN", + .cpu_dai_name = "AMX1-3", + .codec_dai_name = "IN3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX1_4] = { + .name = "AMX1 IN4", + .stream_name = "AMX1 IN", + .cpu_dai_name = "AMX1-4", + .codec_dai_name = "IN4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX1] = { + .name = "AMX1 CIF", + .stream_name = "AMX1 CIF", + .cpu_dai_name = "OUT", + .codec_dai_name = "AMX1", + .cpu_name = "tegra210-amx.0", + .codec_name = "tegra210-axbar", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX2_1] = { + .name = "AMX2 IN1", + .stream_name = "AMX2 IN", + .cpu_dai_name = "AMX2-1", + .codec_dai_name = "IN1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX2_2] = { + .name = "AMX2 IN2", + .stream_name = "AMX2 IN", + .cpu_dai_name = "AMX2-2", + .codec_dai_name = "IN2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX2_3] = { + .name = "AMX2 IN3", + .stream_name = "AMX2 IN", + .cpu_dai_name = "AMX2-3", + .codec_dai_name = "IN3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX2_4] = { + .name = "AMX2 IN4", + .stream_name = "AMX2 IN", + .cpu_dai_name = "AMX2-4", + .codec_dai_name = "IN4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AMX2] = { + .name = "AMX2 CIF", + .stream_name = "AMX2 CIF", + .cpu_dai_name = "OUT", + .codec_dai_name = "AMX2", + .cpu_name = "tegra210-amx.1", + .codec_name = "tegra210-axbar", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX1] = { + .name = "ADX1 CIF", + .stream_name = "ADX1 IN", + .cpu_dai_name = "ADX1", + .codec_dai_name = "IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-adx.0", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX1_1] = { + .name = "ADX1 OUT1", + .stream_name = "ADX1 OUT", + .cpu_dai_name = "OUT1", + .codec_dai_name = "ADX1-1", + .cpu_name = "tegra210-adx.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX1_2] = { + .name = "ADX1 OUT2", + .stream_name = "ADX1 OUT", + .cpu_dai_name = "OUT2", + .codec_dai_name = "ADX1-2", + .cpu_name = "tegra210-adx.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX1_3] = { + .name = "ADX1 OUT3", + .stream_name = "ADX1 OUT", + .cpu_dai_name = "OUT3", + .codec_dai_name = "ADX1-3", + .cpu_name = "tegra210-adx.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX1_4] = { + .name = "ADX1 OUT4", + .stream_name = "ADX1 OUT", + .cpu_dai_name = "OUT4", + .codec_dai_name = "ADX1-4", + .cpu_name = "tegra210-adx.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX2] = { + .name = "ADX2 CIF", + .stream_name = "ADX2 IN", + .cpu_dai_name = "ADX2", + .codec_dai_name = "IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-adx.1", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX2_1] = { + .name = "ADX2 OUT1", + .stream_name = "ADX2 OUT", + .cpu_dai_name = "OUT1", + .codec_dai_name = "ADX2-1", + .cpu_name = "tegra210-adx.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX2_2] = { + .name = "ADX2 OUT2", + .stream_name = "ADX2 OUT", + .cpu_dai_name = "OUT2", + .codec_dai_name = "ADX2-2", + .cpu_name = "tegra210-adx.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX2_3] = { + .name = "ADX2 OUT3", + .stream_name = "ADX2 OUT", + .cpu_dai_name = "OUT3", + .codec_dai_name = "ADX2-3", + .cpu_name = "tegra210-adx.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADX2_4] = { + .name = "ADX2 OUT4", + .stream_name = "ADX2 OUT", + .cpu_dai_name = "OUT4", + .codec_dai_name = "ADX2-4", + .cpu_name = "tegra210-adx.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX1] = { + .name = "MIXER1 RX1", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-1", + .codec_dai_name = "RX1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX2] = { + .name = "MIXER1 RX2", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-2", + .codec_dai_name = "RX2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX3] = { + .name = "MIXER1 RX3", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-3", + .codec_dai_name = "RX3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX4] = { + .name = "MIXER1 RX4", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-4", + .codec_dai_name = "RX4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX5] = { + .name = "MIXER1 RX5", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-5", + .codec_dai_name = "RX5", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX6] = { + .name = "MIXER1 RX6", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-6", + .codec_dai_name = "RX6", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX7] = { + .name = "MIXER1 RX7", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-7", + .codec_dai_name = "RX7", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX8] = { + .name = "MIXER1 RX8", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-8", + .codec_dai_name = "RX8", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX9] = { + .name = "MIXER1 RX9", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-9", + .codec_dai_name = "RX9", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_RX10] = { + .name = "MIXER1 RX10", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-10", + .codec_dai_name = "RX10", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_TX1] = { + .name = "MIXER1 TX1", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX1", + .codec_dai_name = "MIXER1-1", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_TX2] = { + .name = "MIXER1 TX2", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX2", + .codec_dai_name = "MIXER1-2", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_TX3] = { + .name = "MIXER1 TX3", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX3", + .codec_dai_name = "MIXER1-3", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_TX4] = { + .name = "MIXER1 TX4", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX4", + .codec_dai_name = "MIXER1-4", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MIXER1_TX5] = { + .name = "MIXER1 TX5", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX5", + .codec_dai_name = "MIXER1-5", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_SFC1_RX] = { + .name = "SFC1 RX", + .stream_name = "SFC1 RX", + .cpu_dai_name = "SFC1", + .codec_dai_name = "CIF", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-sfc.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_SFC1_TX] = { + .name = "SFC1 TX", + .stream_name = "SFC1 TX", + .cpu_dai_name = "DAP", + .codec_dai_name = "SFC1", + .cpu_name = "tegra210-sfc.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_SFC2_RX] = { + .name = "SFC2 RX", + .stream_name = "SFC2 RX", + .cpu_dai_name = "SFC2", + .codec_dai_name = "CIF", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-sfc.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_SFC2_TX] = { + .name = "SFC2 TX", + .stream_name = "SFC2 TX", + .cpu_dai_name = "DAP", + .codec_dai_name = "SFC2", + .cpu_name = "tegra210-sfc.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_SFC3_RX] = { + .name = "SFC3 RX", + .stream_name = "SFC3 RX", + .cpu_dai_name = "SFC3", + .codec_dai_name = "CIF", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-sfc.2", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_SFC3_TX] = { + .name = "SFC3 TX", + .stream_name = "SFC3 TX", + .cpu_dai_name = "DAP", + .codec_dai_name = "SFC3", + .cpu_name = "tegra210-sfc.2", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_SFC4_RX] = { + .name = "SFC4 RX", + .stream_name = "SFC4 RX", + .cpu_dai_name = "SFC4", + .codec_dai_name = "CIF", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-sfc.3", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_SFC4_TX] = { + .name = "SFC4 TX", + .stream_name = "SFC4 TX", + .cpu_dai_name = "DAP", + .codec_dai_name = "SFC4", + .cpu_name = "tegra210-sfc.3", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC1_RX] = { + .name = "AFC1 RX", + .stream_name = "AFC1 RX", + .cpu_dai_name = "AFC1", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-afc.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC1_TX] = { + .name = "AFC1 TX", + .stream_name = "AFC1 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC1", + .cpu_name = "tegra210-afc.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC2_RX] = { + .name = "AFC2 RX", + .stream_name = "AFC2 RX", + .cpu_dai_name = "AFC2", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-afc.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC2_TX] = { + .name = "AFC2 TX", + .stream_name = "AFC2 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC2", + .cpu_name = "tegra210-afc.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC3_RX] = { + .name = "AFC3 RX", + .stream_name = "AFC3 RX", + .cpu_dai_name = "AFC3", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-afc.2", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC3_TX] = { + .name = "AFC3 TX", + .stream_name = "AFC3 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC3", + .cpu_name = "tegra210-afc.2", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC4_RX] = { + .name = "AFC4 RX", + .stream_name = "AFC4 RX", + .cpu_dai_name = "AFC4", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-afc.3", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC4_TX] = { + .name = "AFC4 TX", + .stream_name = "AFC4 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC4", + .cpu_name = "tegra210-afc.3", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC5_RX] = { + .name = "AFC5 RX", + .stream_name = "AFC5 RX", + .cpu_dai_name = "AFC5", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-afc.4", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC5_TX] = { + .name = "AFC5 TX", + .stream_name = "AFC5 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC5", + .cpu_name = "tegra210-afc.4", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC6_RX] = { + .name = "AFC6 RX", + .stream_name = "AFC6 RX", + .cpu_dai_name = "AFC6", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-afc.5", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_AFC6_TX] = { + .name = "AFC6 TX", + .stream_name = "AFC6 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC6", + .cpu_name = "tegra210-afc.5", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MVC1_RX] = { + .name = "MVC1 RX", + .stream_name = "MVC1 RX", + .cpu_dai_name = "MVC1", + .codec_dai_name = "MVC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mvc.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MVC1_TX] = { + .name = "MVC1 TX", + .stream_name = "MVC1 TX", + .cpu_dai_name = "MVC OUT", + .codec_dai_name = "MVC1", + .cpu_name = "tegra210-mvc.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MVC2_RX] = { + .name = "MVC2 RX", + .stream_name = "MVC2 RX", + .cpu_dai_name = "MVC2", + .codec_dai_name = "MVC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mvc.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_MVC2_TX] = { + .name = "MVC2 TX", + .stream_name = "AFC2 TX", + .cpu_dai_name = "MVC OUT", + .codec_dai_name = "MVC2", + .cpu_name = "tegra210-mvc.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_OPE1_RX] = { + .name = "OPE1 RX", + .stream_name = "OPE1 RX", + .cpu_dai_name = "OPE1", + .codec_dai_name = "OPE IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-ope.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_OPE1_TX] = { + .name = "OPE1 TX", + .stream_name = "OPE1 TX", + .cpu_dai_name = "OPE OUT", + .codec_dai_name = "OPE1", + .cpu_name = "tegra210-ope.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_OPE2_RX] = { + .name = "OPE2 RX", + .stream_name = "OPE2 RX", + .cpu_dai_name = "OPE2", + .codec_dai_name = "OPE IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-ope.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_OPE2_TX] = { + .name = "OPE2 TX", + .stream_name = "OPE2 TX", + .cpu_dai_name = "OPE OUT", + .codec_dai_name = "OPE2", + .cpu_name = "tegra210-ope.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF1_CODEC] = { + .name = "ADMAIF1 CODEC", + .stream_name = "ADMAIF1 CODEC", + .cpu_dai_name = "ADMAIF1 CIF", + .codec_dai_name = "ADMAIF1", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF2_CODEC] = { + .name = "ADMAIF2 CODEC", + .stream_name = "ADMAIF2 CODEC", + .cpu_dai_name = "ADMAIF2 CIF", + .codec_dai_name = "ADMAIF2", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF3_CODEC] = { + .name = "ADMAIF3 CODEC", + .stream_name = "ADMAIF3 CODEC", + .cpu_dai_name = "ADMAIF3 CIF", + .codec_dai_name = "ADMAIF3", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF4_CODEC] = { + .name = "ADMAIF4 CODEC", + .stream_name = "ADMAIF4 CODEC", + .cpu_dai_name = "ADMAIF4 CIF", + .codec_dai_name = "ADMAIF4", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF5_CODEC] = { + .name = "ADMAIF5 CODEC", + .stream_name = "ADMAIF5 CODEC", + .cpu_dai_name = "ADMAIF5 CIF", + .codec_dai_name = "ADMAIF5", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF6_CODEC] = { + .name = "ADMAIF6 CODEC", + .stream_name = "ADMAIF6 CODEC", + .cpu_dai_name = "ADMAIF6 CIF", + .codec_dai_name = "ADMAIF6", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF7_CODEC] = { + .name = "ADMAIF7 CODEC", + .stream_name = "ADMAIF7 CODEC", + .cpu_dai_name = "ADMAIF7 CIF", + .codec_dai_name = "ADMAIF7", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF8_CODEC] = { + .name = "ADMAIF8 CODEC", + .stream_name = "ADMAIF8 CODEC", + .cpu_dai_name = "ADMAIF8 CIF", + .codec_dai_name = "ADMAIF8", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF9_CODEC] = { + .name = "ADMAIF9 CODEC", + .stream_name = "ADMAIF9 CODEC", + .cpu_dai_name = "ADMAIF9 CIF", + .codec_dai_name = "ADMAIF9", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADMAIF10_CODEC] = { + .name = "ADMAIF10 CODEC", + .stream_name = "ADMAIF10 CODEC", + .cpu_dai_name = "ADMAIF10 CIF", + .codec_dai_name = "ADMAIF10", + .cpu_name = "tegra210-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra210-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) + [TEGRA210_DAI_LINK_ADSP_ADMAIF1] = { + .name = "ADSP ADMAIF1", + .stream_name = "ADSP ADMAIF1", + .cpu_dai_name = "ADSP-ADMAIF1", + .codec_dai_name = "ADMAIF1 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF2] = { + .name = "ADSP ADMAIF2", + .stream_name = "ADSP ADMAIF2", + .cpu_dai_name = "ADSP-ADMAIF2", + .codec_dai_name = "ADMAIF2 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF3] = { + .name = "ADSP ADMAIF3", + .stream_name = "ADSP ADMAIF3", + .cpu_dai_name = "ADSP-ADMAIF3", + .codec_dai_name = "ADMAIF3 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF4] = { + .name = "ADSP ADMAIF4", + .stream_name = "ADSP ADMAIF4", + .cpu_dai_name = "ADSP-ADMAIF4", + .codec_dai_name = "ADMAIF4 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF5] = { + .name = "ADSP ADMAIF5", + .stream_name = "ADSP ADMAIF5", + .cpu_dai_name = "ADSP-ADMAIF5", + .codec_dai_name = "ADMAIF5 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF6] = { + .name = "ADSP ADMAIF6", + .stream_name = "ADSP ADMAIF6", + .cpu_dai_name = "ADSP-ADMAIF6", + .codec_dai_name = "ADMAIF6 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF7] = { + .name = "ADSP ADMAIF7", + .stream_name = "ADSP ADMAIF7", + .cpu_dai_name = "ADSP-ADMAIF7", + .codec_dai_name = "ADMAIF7 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF8] = { + .name = "ADSP ADMAIF8", + .stream_name = "ADSP ADMAIF8", + .cpu_dai_name = "ADSP-ADMAIF8", + .codec_dai_name = "ADMAIF8 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF9] = { + .name = "ADSP ADMAIF9", + .stream_name = "ADSP ADMAIF9", + .cpu_dai_name = "ADSP-ADMAIF9", + .codec_dai_name = "ADMAIF9 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_ADMAIF10] = { + .name = "ADSP ADMAIF10", + .stream_name = "ADSP ADMAIF10", + .cpu_dai_name = "ADSP-ADMAIF10", + .codec_dai_name = "ADMAIF10 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_PCM1] = { + .name = "ADSP PCM1", + .stream_name = "ADSP PCM1", + .cpu_dai_name = "ADSP PCM1", + .codec_dai_name = "ADSP-FE1", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-adsp", + .platform_name = "tegra210-adsp", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_PCM2] = { + .name = "ADSP PCM2", + .stream_name = "ADSP PCM2", + .cpu_dai_name = "ADSP PCM2", + .codec_dai_name = "ADSP-FE2", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-adsp", + .platform_name = "tegra210-adsp", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_COMPR1] = { + .name = "ADSP COMPR1", + .stream_name = "ADSP COMPR1", + .cpu_dai_name = "ADSP COMPR1", + .codec_dai_name = "ADSP-FE3", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-adsp", + .platform_name = "tegra210-adsp", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA210_DAI_LINK_ADSP_COMPR2] = { + .name = "ADSP COMPR2", + .stream_name = "ADSP COMPR2", + .cpu_dai_name = "ADSP COMPR2", + .codec_dai_name = "ADSP-FE4", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-adsp", + .platform_name = "tegra210-adsp", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +#endif +}; + +static struct snd_soc_codec_conf + tegra210_xbar_codec_conf[TEGRA210_XBAR_CODEC_CONF] = { + [TEGRA210_CODEC_AMX1_CONF] = { + .dev_name = "tegra210-amx.0", + .name_prefix = "AMX1", + }, + [TEGRA210_CODEC_AMX2_CONF] = { + .dev_name = "tegra210-amx.1", + .name_prefix = "AMX2", + }, + [TEGRA210_CODEC_ADX1_CONF] = { + .dev_name = "tegra210-adx.0", + .name_prefix = "ADX1", + }, + [TEGRA210_CODEC_ADX2_CONF] = { + .dev_name = "tegra210-adx.1", + .name_prefix = "ADX2", + }, + [TEGRA210_CODEC_SFC1_CONF] = { + .dev_name = "tegra210-sfc.0", + .name_prefix = "SFC1", + }, + [TEGRA210_CODEC_SFC2_CONF] = { + .dev_name = "tegra210-sfc.1", + .name_prefix = "SFC2", + }, + [TEGRA210_CODEC_SFC3_CONF] = { + .dev_name = "tegra210-sfc.2", + .name_prefix = "SFC3", + }, + [TEGRA210_CODEC_SFC4_CONF] = { + .dev_name = "tegra210-sfc.3", + .name_prefix = "SFC4", + }, + [TEGRA210_CODEC_MVC1_CONF] = { + .dev_name = "tegra210-mvc.0", + .name_prefix = "MVC1", + }, + [TEGRA210_CODEC_MVC2_CONF] = { + .dev_name = "tegra210-mvc.1", + .name_prefix = "MVC2", + }, + [TEGRA210_CODEC_OPE1_CONF] = { + .dev_name = "tegra210-ope.0", + .name_prefix = "OPE1", + }, + [TEGRA210_CODEC_OPE2_CONF] = { + .dev_name = "tegra210-ope.1", + .name_prefix = "OPE2", + }, + [TEGRA210_CODEC_AFC1_CONF] = { + .dev_name = "tegra210-afc.0", + .name_prefix = "AFC1", + }, + [TEGRA210_CODEC_AFC2_CONF] = { + .dev_name = "tegra210-afc.1", + .name_prefix = "AFC2", + }, + [TEGRA210_CODEC_AFC3_CONF] = { + .dev_name = "tegra210-afc.2", + .name_prefix = "AFC3", + }, + [TEGRA210_CODEC_AFC4_CONF] = { + .dev_name = "tegra210-afc.3", + .name_prefix = "AFC4", + }, + [TEGRA210_CODEC_AFC5_CONF] = { + .dev_name = "tegra210-afc.4", + .name_prefix = "AFC5", + }, + [TEGRA210_CODEC_AFC6_CONF] = { + .dev_name = "tegra210-afc.5", + .name_prefix = "AFC6", + }, + [TEGRA210_CODEC_I2S1_CONF] = { + .dev_name = "tegra210-i2s.0", + .name_prefix = "I2S1", + }, + [TEGRA210_CODEC_I2S2_CONF] = { + .dev_name = "tegra210-i2s.1", + .name_prefix = "I2S2", + }, + [TEGRA210_CODEC_I2S3_CONF] = { + .dev_name = "tegra210-i2s.2", + .name_prefix = "I2S3", + }, + [TEGRA210_CODEC_I2S4_CONF] = { + .dev_name = "tegra210-i2s.3", + .name_prefix = "I2S4", + }, + [TEGRA210_CODEC_I2S5_CONF] = { + .dev_name = "tegra210-i2s.4", + .name_prefix = "I2S5", + }, + [TEGRA210_CODEC_DMIC1_CONF] = { + .dev_name = "tegra210-dmic.0", + .name_prefix = "DMIC1", + }, + [TEGRA210_CODEC_DMIC2_CONF] = { + .dev_name = "tegra210-dmic.1", + .name_prefix = "DMIC2", + }, + [TEGRA210_CODEC_DMIC3_CONF] = { + .dev_name = "tegra210-dmic.2", + .name_prefix = "DMIC3", + }, + [TEGRA210_CODEC_SPDIF_CONF] = { + .dev_name = "tegra210-spdif", + .name_prefix = "SPDIF", + }, +}; + +static struct snd_soc_dai_link + tegra186_xbar_dai_links[TEGRA186_XBAR_DAI_LINKS] = { + [TEGRA186_DAI_LINK_ADMAIF1] = { + .name = "ADMAIF1 CIF", + .stream_name = "ADMAIF1 CIF", + .cpu_dai_name = "ADMAIF1", + .codec_dai_name = "ADMAIF1", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF2] = { + .name = "ADMAIF2 CIF", + .stream_name = "ADMAIF2 CIF", + .cpu_dai_name = "ADMAIF2", + .codec_dai_name = "ADMAIF2", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF3] = { + .name = "ADMAIF3 CIF", + .stream_name = "ADMAIF3 CIF", + .cpu_dai_name = "ADMAIF3", + .codec_dai_name = "ADMAIF3", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF4] = { + .name = "ADMAIF4 CIF", + .stream_name = "ADMAIF4 CIF", + .cpu_dai_name = "ADMAIF4", + .codec_dai_name = "ADMAIF4", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF5] = { + .name = "ADMAIF5 CIF", + .stream_name = "ADMAIF5 CIF", + .cpu_dai_name = "ADMAIF5", + .codec_dai_name = "ADMAIF5", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF6] = { + .name = "ADMAIF6 CIF", + .stream_name = "ADMAIF6 CIF", + .cpu_dai_name = "ADMAIF6", + .codec_dai_name = "ADMAIF6", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF7] = { + .name = "ADMAIF7 CIF", + .stream_name = "ADMAIF7 CIF", + .cpu_dai_name = "ADMAIF7", + .codec_dai_name = "ADMAIF7", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF8] = { + .name = "ADMAIF8 CIF", + .stream_name = "ADMAIF8 CIF", + .cpu_dai_name = "ADMAIF8", + .codec_dai_name = "ADMAIF8", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF9] = { + .name = "ADMAIF9 CIF", + .stream_name = "ADMAIF9 CIF", + .cpu_dai_name = "ADMAIF9", + .codec_dai_name = "ADMAIF9", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF10] = { + .name = "ADMAIF10 CIF", + .stream_name = "ADMAIF10 CIF", + .cpu_dai_name = "ADMAIF10", + .codec_dai_name = "ADMAIF10", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF11] = { + .name = "ADMAIF11 CIF", + .stream_name = "ADMAIF11 CIF", + .cpu_dai_name = "ADMAIF11", + .codec_dai_name = "ADMAIF11", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF12] = { + .name = "ADMAIF12 CIF", + .stream_name = "ADMAIF12 CIF", + .cpu_dai_name = "ADMAIF12", + .codec_dai_name = "ADMAIF12", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF13] = { + .name = "ADMAIF13 CIF", + .stream_name = "ADMAIF13 CIF", + .cpu_dai_name = "ADMAIF13", + .codec_dai_name = "ADMAIF13", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF14] = { + .name = "ADMAIF14 CIF", + .stream_name = "ADMAIF14 CIF", + .cpu_dai_name = "ADMAIF14", + .codec_dai_name = "ADMAIF14", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF15] = { + .name = "ADMAIF15 CIF", + .stream_name = "ADMAIF15 CIF", + .cpu_dai_name = "ADMAIF15", + .codec_dai_name = "ADMAIF15", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF16] = { + .name = "ADMAIF16 CIF", + .stream_name = "ADMAIF16 CIF", + .cpu_dai_name = "ADMAIF16", + .codec_dai_name = "ADMAIF16", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF17] = { + .name = "ADMAIF17 CIF", + .stream_name = "ADMAIF17 CIF", + .cpu_dai_name = "ADMAIF17", + .codec_dai_name = "ADMAIF17", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF18] = { + .name = "ADMAIF18 CIF", + .stream_name = "ADMAIF18 CIF", + .cpu_dai_name = "ADMAIF18", + .codec_dai_name = "ADMAIF18", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF19] = { + .name = "ADMAIF19 CIF", + .stream_name = "ADMAIF19 CIF", + .cpu_dai_name = "ADMAIF19", + .codec_dai_name = "ADMAIF19", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF20] = { + .name = "ADMAIF20 CIF", + .stream_name = "ADMAIF20 CIF", + .cpu_dai_name = "ADMAIF20", + .codec_dai_name = "ADMAIF20", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF1_CODEC] = { + .name = "ADMAIF1 CODEC", + .stream_name = "ADMAIF1 CODEC", + .cpu_dai_name = "ADMAIF1 CIF", + .codec_dai_name = "ADMAIF1", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF2_CODEC] = { + .name = "ADMAIF2 CODEC", + .stream_name = "ADMAIF2 CODEC", + .cpu_dai_name = "ADMAIF2 CIF", + .codec_dai_name = "ADMAIF2", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF3_CODEC] = { + .name = "ADMAIF3 CODEC", + .stream_name = "ADMAIF3 CODEC", + .cpu_dai_name = "ADMAIF3 CIF", + .codec_dai_name = "ADMAIF3", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF4_CODEC] = { + .name = "ADMAIF4 CODEC", + .stream_name = "ADMAIF4 CODEC", + .cpu_dai_name = "ADMAIF4 CIF", + .codec_dai_name = "ADMAIF4", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF5_CODEC] = { + .name = "ADMAIF5 CODEC", + .stream_name = "ADMAIF5 CODEC", + .cpu_dai_name = "ADMAIF5 CIF", + .codec_dai_name = "ADMAIF5", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF6_CODEC] = { + .name = "ADMAIF6 CODEC", + .stream_name = "ADMAIF6 CODEC", + .cpu_dai_name = "ADMAIF6 CIF", + .codec_dai_name = "ADMAIF6", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF7_CODEC] = { + .name = "ADMAIF7 CODEC", + .stream_name = "ADMAIF7 CODEC", + .cpu_dai_name = "ADMAIF7 CIF", + .codec_dai_name = "ADMAIF7", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF8_CODEC] = { + .name = "ADMAIF8 CODEC", + .stream_name = "ADMAIF8 CODEC", + .cpu_dai_name = "ADMAIF8 CIF", + .codec_dai_name = "ADMAIF8", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF9_CODEC] = { + .name = "ADMAIF9 CODEC", + .stream_name = "ADMAIF9 CODEC", + .cpu_dai_name = "ADMAIF9 CIF", + .codec_dai_name = "ADMAIF9", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF10_CODEC] = { + .name = "ADMAIF10 CODEC", + .stream_name = "ADMAIF10 CODEC", + .cpu_dai_name = "ADMAIF10 CIF", + .codec_dai_name = "ADMAIF10", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF11_CODEC] = { + .name = "ADMAIF11 CODEC", + .stream_name = "ADMAIF11 CODEC", + .cpu_dai_name = "ADMAIF11 CIF", + .codec_dai_name = "ADMAIF11", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF12_CODEC] = { + .name = "ADMAIF12 CODEC", + .stream_name = "ADMAIF12 CODEC", + .cpu_dai_name = "ADMAIF12 CIF", + .codec_dai_name = "ADMAIF12", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF13_CODEC] = { + .name = "ADMAIF13 CODEC", + .stream_name = "ADMAIF13 CODEC", + .cpu_dai_name = "ADMAIF13 CIF", + .codec_dai_name = "ADMAIF13", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF14_CODEC] = { + .name = "ADMAIF14 CODEC", + .stream_name = "ADMAIF14 CODEC", + .cpu_dai_name = "ADMAIF14 CIF", + .codec_dai_name = "ADMAIF14", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF15_CODEC] = { + .name = "ADMAIF15 CODEC", + .stream_name = "ADMAIF15 CODEC", + .cpu_dai_name = "ADMAIF15 CIF", + .codec_dai_name = "ADMAIF15", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF16_CODEC] = { + .name = "ADMAIF16 CODEC", + .stream_name = "ADMAIF16 CODEC", + .cpu_dai_name = "ADMAIF16 CIF", + .codec_dai_name = "ADMAIF16", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF17_CODEC] = { + .name = "ADMAIF17 CODEC", + .stream_name = "ADMAIF17 CODEC", + .cpu_dai_name = "ADMAIF17 CIF", + .codec_dai_name = "ADMAIF17", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF18_CODEC] = { + .name = "ADMAIF18 CODEC", + .stream_name = "ADMAIF18 CODEC", + .cpu_dai_name = "ADMAIF18 CIF", + .codec_dai_name = "ADMAIF18", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF19_CODEC] = { + .name = "ADMAIF19 CODEC", + .stream_name = "ADMAIF19 CODEC", + .cpu_dai_name = "ADMAIF19 CIF", + .codec_dai_name = "ADMAIF19", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADMAIF20_CODEC] = { + .name = "ADMAIF20 CODEC", + .stream_name = "ADMAIF20 CODEC", + .cpu_dai_name = "ADMAIF20 CIF", + .codec_dai_name = "ADMAIF20", + .cpu_name = "tegra186-admaif", + .codec_name = "tegra210-axbar", + .platform_name = "tegra186-admaif", + .ignore_pmdown_time = 1, + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX1_1] = { + .name = "AMX1 IN1", + .stream_name = "AMX1 IN", + .cpu_dai_name = "AMX1-1", + .codec_dai_name = "IN1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX1_2] = { + .name = "AMX1 IN2", + .stream_name = "AMX1 IN", + .cpu_dai_name = "AMX1-2", + .codec_dai_name = "IN2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX1_3] = { + .name = "AMX1 IN3", + .stream_name = "AMX1 IN", + .cpu_dai_name = "AMX1-3", + .codec_dai_name = "IN3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX1_4] = { + .name = "AMX1 IN4", + .stream_name = "AMX1 IN", + .cpu_dai_name = "AMX1-4", + .codec_dai_name = "IN4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX1] = { + .name = "AMX1 CIF", + .stream_name = "AMX1 CIF", + .cpu_dai_name = "OUT", + .codec_dai_name = "AMX1", + .cpu_name = "tegra210-amx.0", + .codec_name = "tegra210-axbar", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX2_1] = { + .name = "AMX2 IN1", + .stream_name = "AMX2 IN", + .cpu_dai_name = "AMX2-1", + .codec_dai_name = "IN1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX2_2] = { + .name = "AMX2 IN2", + .stream_name = "AMX2 IN", + .cpu_dai_name = "AMX2-2", + .codec_dai_name = "IN2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX2_3] = { + .name = "AMX2 IN3", + .stream_name = "AMX2 IN", + .cpu_dai_name = "AMX2-3", + .codec_dai_name = "IN3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX2_4] = { + .name = "AMX2 IN4", + .stream_name = "AMX2 IN", + .cpu_dai_name = "AMX2-4", + .codec_dai_name = "IN4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX2] = { + .name = "AMX2 CIF", + .stream_name = "AMX2 CIF", + .cpu_dai_name = "OUT", + .codec_dai_name = "AMX2", + .cpu_name = "tegra210-amx.1", + .codec_name = "tegra210-axbar", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX3_1] = { + .name = "AMX3 IN1", + .stream_name = "AMX3 IN", + .cpu_dai_name = "AMX3-1", + .codec_dai_name = "IN1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.2", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX3_2] = { + .name = "AMX3 IN2", + .stream_name = "AMX3 IN", + .cpu_dai_name = "AMX3-2", + .codec_dai_name = "IN2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.2", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX3_3] = { + .name = "AMX3 IN3", + .stream_name = "AMX3 IN", + .cpu_dai_name = "AMX3-3", + .codec_dai_name = "IN3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.2", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX3_4] = { + .name = "AMX3 IN4", + .stream_name = "AMX3 IN", + .cpu_dai_name = "AMX3-4", + .codec_dai_name = "IN4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.2", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX3] = { + .name = "AMX3 CIF", + .stream_name = "AMX3 CIF", + .cpu_dai_name = "OUT", + .codec_dai_name = "AMX3", + .cpu_name = "tegra210-amx.2", + .codec_name = "tegra210-axbar", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX4_1] = { + .name = "AMX4 IN1", + .stream_name = "AMX4 IN", + .cpu_dai_name = "AMX4-1", + .codec_dai_name = "IN1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.3", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX4_2] = { + .name = "AMX4 IN2", + .stream_name = "AMX4 IN", + .cpu_dai_name = "AMX4-2", + .codec_dai_name = "IN2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.3", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX4_3] = { + .name = "AMX4 IN3", + .stream_name = "AMX4 IN", + .cpu_dai_name = "AMX4-3", + .codec_dai_name = "IN3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.3", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX4_4] = { + .name = "AMX4 IN4", + .stream_name = "AMX4 IN", + .cpu_dai_name = "AMX4-4", + .codec_dai_name = "IN4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-amx.3", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AMX4] = { + .name = "AMX4 CIF", + .stream_name = "AMX4 CIF", + .cpu_dai_name = "OUT", + .codec_dai_name = "AMX4", + .cpu_name = "tegra210-amx.3", + .codec_name = "tegra210-axbar", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX1] = { + .name = "ADX1 CIF", + .stream_name = "ADX1 IN", + .cpu_dai_name = "ADX1", + .codec_dai_name = "IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-adx.0", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX1_1] = { + .name = "ADX1 OUT1", + .stream_name = "ADX1 OUT", + .cpu_dai_name = "OUT1", + .codec_dai_name = "ADX1-1", + .cpu_name = "tegra210-adx.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX1_2] = { + .name = "ADX1 OUT2", + .stream_name = "ADX1 OUT", + .cpu_dai_name = "OUT2", + .codec_dai_name = "ADX1-2", + .cpu_name = "tegra210-adx.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX1_3] = { + .name = "ADX1 OUT3", + .stream_name = "ADX1 OUT", + .cpu_dai_name = "OUT3", + .codec_dai_name = "ADX1-3", + .cpu_name = "tegra210-adx.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX1_4] = { + .name = "ADX1 OUT4", + .stream_name = "ADX1 OUT", + .cpu_dai_name = "OUT4", + .codec_dai_name = "ADX1-4", + .cpu_name = "tegra210-adx.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX2] = { + .name = "ADX2 CIF", + .stream_name = "ADX2 IN", + .cpu_dai_name = "ADX2", + .codec_dai_name = "IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-adx.1", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX2_1] = { + .name = "ADX2 OUT1", + .stream_name = "ADX2 OUT", + .cpu_dai_name = "OUT1", + .codec_dai_name = "ADX2-1", + .cpu_name = "tegra210-adx.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX2_2] = { + .name = "ADX2 OUT2", + .stream_name = "ADX2 OUT", + .cpu_dai_name = "OUT2", + .codec_dai_name = "ADX2-2", + .cpu_name = "tegra210-adx.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX2_3] = { + .name = "ADX2 OUT3", + .stream_name = "ADX2 OUT", + .cpu_dai_name = "OUT3", + .codec_dai_name = "ADX2-3", + .cpu_name = "tegra210-adx.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX2_4] = { + .name = "ADX2 OUT4", + .stream_name = "ADX2 OUT", + .cpu_dai_name = "OUT4", + .codec_dai_name = "ADX2-4", + .cpu_name = "tegra210-adx.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX3] = { + .name = "ADX3 CIF", + .stream_name = "ADX3 IN", + .cpu_dai_name = "ADX3", + .codec_dai_name = "IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-adx.2", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX3_1] = { + .name = "ADX3 OUT1", + .stream_name = "ADX3 OUT", + .cpu_dai_name = "OUT1", + .codec_dai_name = "ADX3-1", + .cpu_name = "tegra210-adx.2", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX3_2] = { + .name = "ADX3 OUT2", + .stream_name = "ADX3 OUT", + .cpu_dai_name = "OUT2", + .codec_dai_name = "ADX3-2", + .cpu_name = "tegra210-adx.2", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX3_3] = { + .name = "ADX3 OUT3", + .stream_name = "ADX3 OUT", + .cpu_dai_name = "OUT3", + .codec_dai_name = "ADX3-3", + .cpu_name = "tegra210-adx.2", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX3_4] = { + .name = "ADX3 OUT4", + .stream_name = "ADX3 OUT", + .cpu_dai_name = "OUT4", + .codec_dai_name = "ADX3-4", + .cpu_name = "tegra210-adx.2", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX4] = { + .name = "ADX4 CIF", + .stream_name = "ADX4 IN", + .cpu_dai_name = "ADX4", + .codec_dai_name = "IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-adx.3", + .params = &tdm_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX4_1] = { + .name = "ADX4 OUT1", + .stream_name = "ADX4 OUT", + .cpu_dai_name = "OUT1", + .codec_dai_name = "ADX4-1", + .cpu_name = "tegra210-adx.3", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX4_2] = { + .name = "ADX4 OUT2", + .stream_name = "ADX4 OUT", + .cpu_dai_name = "OUT2", + .codec_dai_name = "ADX4-2", + .cpu_name = "tegra210-adx.3", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX4_3] = { + .name = "ADX4 OUT3", + .stream_name = "ADX4 OUT", + .cpu_dai_name = "OUT3", + .codec_dai_name = "ADX4-3", + .cpu_name = "tegra210-adx.3", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADX4_4] = { + .name = "ADX4 OUT4", + .stream_name = "ADX4 OUT", + .cpu_dai_name = "OUT4", + .codec_dai_name = "ADX4-4", + .cpu_name = "tegra210-adx.3", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX1] = { + .name = "MIXER1 RX1", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-1", + .codec_dai_name = "RX1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX2] = { + .name = "MIXER1 RX2", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-2", + .codec_dai_name = "RX2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX3] = { + .name = "MIXER1 RX3", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-3", + .codec_dai_name = "RX3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX4] = { + .name = "MIXER1 RX4", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-4", + .codec_dai_name = "RX4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX5] = { + .name = "MIXER1 RX5", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-5", + .codec_dai_name = "RX5", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX6] = { + .name = "MIXER1 RX6", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-6", + .codec_dai_name = "RX6", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX7] = { + .name = "MIXER1 RX7", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-7", + .codec_dai_name = "RX7", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX8] = { + .name = "MIXER1 RX8", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-8", + .codec_dai_name = "RX8", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX9] = { + .name = "MIXER1 RX9", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-9", + .codec_dai_name = "RX9", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_RX10] = { + .name = "MIXER1 RX10", + .stream_name = "MIXER1 RX", + .cpu_dai_name = "MIXER1-10", + .codec_dai_name = "RX10", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mixer", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_TX1] = { + .name = "MIXER1 TX1", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX1", + .codec_dai_name = "MIXER1-1", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_TX2] = { + .name = "MIXER1 TX2", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX2", + .codec_dai_name = "MIXER1-2", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_TX3] = { + .name = "MIXER1 TX3", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX3", + .codec_dai_name = "MIXER1-3", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_TX4] = { + .name = "MIXER1 TX4", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX4", + .codec_dai_name = "MIXER1-4", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MIXER1_TX5] = { + .name = "MIXER1 TX5", + .stream_name = "MIXER1 TX", + .cpu_dai_name = "TX5", + .codec_dai_name = "MIXER1-5", + .cpu_name = "tegra210-mixer", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_SFC1_RX] = { + .name = "SFC1 RX", + .stream_name = "SFC1 RX", + .cpu_dai_name = "SFC1", + .codec_dai_name = "CIF", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-sfc.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_SFC1_TX] = { + .name = "SFC1 TX", + .stream_name = "SFC1 TX", + .cpu_dai_name = "DAP", + .codec_dai_name = "SFC1", + .cpu_name = "tegra210-sfc.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_SFC2_RX] = { + .name = "SFC2 RX", + .stream_name = "SFC2 RX", + .cpu_dai_name = "SFC2", + .codec_dai_name = "CIF", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-sfc.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_SFC2_TX] = { + .name = "SFC2 TX", + .stream_name = "SFC2 TX", + .cpu_dai_name = "DAP", + .codec_dai_name = "SFC2", + .cpu_name = "tegra210-sfc.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_SFC3_RX] = { + .name = "SFC3 RX", + .stream_name = "SFC3 RX", + .cpu_dai_name = "SFC3", + .codec_dai_name = "CIF", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-sfc.2", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_SFC3_TX] = { + .name = "SFC3 TX", + .stream_name = "SFC3 TX", + .cpu_dai_name = "DAP", + .codec_dai_name = "SFC3", + .cpu_name = "tegra210-sfc.2", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_SFC4_RX] = { + .name = "SFC4 RX", + .stream_name = "SFC4 RX", + .cpu_dai_name = "SFC4", + .codec_dai_name = "CIF", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-sfc.3", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_SFC4_TX] = { + .name = "SFC4 TX", + .stream_name = "SFC4 TX", + .cpu_dai_name = "DAP", + .codec_dai_name = "SFC4", + .cpu_name = "tegra210-sfc.3", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC1_RX] = { + .name = "AFC1 RX", + .stream_name = "AFC1 RX", + .cpu_dai_name = "AFC1", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-afc.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC1_TX] = { + .name = "AFC1 TX", + .stream_name = "AFC1 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC1", + .cpu_name = "tegra186-afc.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC2_RX] = { + .name = "AFC2 RX", + .stream_name = "AFC2 RX", + .cpu_dai_name = "AFC2", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-afc.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC2_TX] = { + .name = "AFC2 TX", + .stream_name = "AFC2 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC2", + .cpu_name = "tegra186-afc.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC3_RX] = { + .name = "AFC3 RX", + .stream_name = "AFC3 RX", + .cpu_dai_name = "AFC3", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-afc.2", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC3_TX] = { + .name = "AFC3 TX", + .stream_name = "AFC3 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC3", + .cpu_name = "tegra186-afc.2", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC4_RX] = { + .name = "AFC4 RX", + .stream_name = "AFC4 RX", + .cpu_dai_name = "AFC4", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-afc.3", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC4_TX] = { + .name = "AFC4 TX", + .stream_name = "AFC4 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC4", + .cpu_name = "tegra186-afc.3", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC5_RX] = { + .name = "AFC5 RX", + .stream_name = "AFC5 RX", + .cpu_dai_name = "AFC5", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-afc.4", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC5_TX] = { + .name = "AFC5 TX", + .stream_name = "AFC5 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC5", + .cpu_name = "tegra186-afc.4", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC6_RX] = { + .name = "AFC6 RX", + .stream_name = "AFC6 RX", + .cpu_dai_name = "AFC6", + .codec_dai_name = "AFC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-afc.5", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_AFC6_TX] = { + .name = "AFC6 TX", + .stream_name = "AFC6 TX", + .cpu_dai_name = "AFC OUT", + .codec_dai_name = "AFC6", + .cpu_name = "tegra186-afc.5", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MVC1_RX] = { + .name = "MVC1 RX", + .stream_name = "MVC1 RX", + .cpu_dai_name = "MVC1", + .codec_dai_name = "MVC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mvc.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MVC1_TX] = { + .name = "MVC1 TX", + .stream_name = "MVC1 TX", + .cpu_dai_name = "MVC OUT", + .codec_dai_name = "MVC1", + .cpu_name = "tegra210-mvc.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MVC2_RX] = { + .name = "MVC2 RX", + .stream_name = "MVC2 RX", + .cpu_dai_name = "MVC2", + .codec_dai_name = "MVC IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-mvc.1", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_MVC2_TX] = { + .name = "MVC2 TX", + .stream_name = "MVC2 TX", + .cpu_dai_name = "MVC OUT", + .codec_dai_name = "MVC2", + .cpu_name = "tegra210-mvc.1", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_OPE1_RX] = { + .name = "OPE1 RX", + .stream_name = "OPE1 RX", + .cpu_dai_name = "OPE1", + .codec_dai_name = "OPE IN", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra210-ope.0", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_OPE1_TX] = { + .name = "OPE1 TX", + .stream_name = "OPE1 TX", + .cpu_dai_name = "OPE OUT", + .codec_dai_name = "OPE1", + .cpu_name = "tegra210-ope.0", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_RX1] = { + .name = "ASRC1 RX1", + .stream_name = "ASRC1 RX", + .cpu_dai_name = "ASRC1-1", + .codec_dai_name = "RX1", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-asrc", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_RX2] = { + .name = "ASRC1 RX2", + .stream_name = "ASRC1 RX", + .cpu_dai_name = "ASRC1-2", + .codec_dai_name = "RX2", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-asrc", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_RX3] = { + .name = "ASRC1 RX3", + .stream_name = "ASRC1 RX", + .cpu_dai_name = "ASRC1-3", + .codec_dai_name = "RX3", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-asrc", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_RX4] = { + .name = "ASRC1 RX4", + .stream_name = "ASRC1 RX", + .cpu_dai_name = "ASRC1-4", + .codec_dai_name = "RX4", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-asrc", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_RX5] = { + .name = "ASRC1 RX5", + .stream_name = "ASRC1 RX", + .cpu_dai_name = "ASRC1-5", + .codec_dai_name = "RX5", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-asrc", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_RX6] = { + .name = "ASRC1 RX6", + .stream_name = "ASRC1 RX", + .cpu_dai_name = "ASRC1-6", + .codec_dai_name = "RX6", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-asrc", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_RX7] = { + .name = "ASRC1 RX7", + .stream_name = "ASRC1 RX", + .cpu_dai_name = "ASRC1-7", + .codec_dai_name = "RX7", + .cpu_name = "tegra210-axbar", + .codec_name = "tegra186-asrc", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_TX1] = { + .name = "ASRC1 TX1", + .stream_name = "ASRC1 TX", + .cpu_dai_name = "TX1", + .codec_dai_name = "ASRC1-1", + .cpu_name = "tegra186-asrc", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_TX2] = { + .name = "ASRC1 TX2", + .stream_name = "ASRC1 TX", + .cpu_dai_name = "TX2", + .codec_dai_name = "ASRC1-2", + .cpu_name = "tegra186-asrc", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_TX3] = { + .name = "ASRC1 TX3", + .stream_name = "ASRC1 TX", + .cpu_dai_name = "TX3", + .codec_dai_name = "ASRC1-3", + .cpu_name = "tegra186-asrc", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_TX4] = { + .name = "ASRC1 TX4", + .stream_name = "ASRC1 TX", + .cpu_dai_name = "TX4", + .codec_dai_name = "ASRC1-4", + .cpu_name = "tegra186-asrc", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_TX5] = { + .name = "ASRC1 TX5", + .stream_name = "ASRC1 TX", + .cpu_dai_name = "TX5", + .codec_dai_name = "ASRC1-5", + .cpu_name = "tegra186-asrc", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ASRC1_TX6] = { + .name = "ASRC1 TX6", + .stream_name = "ASRC1 TX", + .cpu_dai_name = "TX6", + .codec_dai_name = "ASRC1-6", + .cpu_name = "tegra186-asrc", + .codec_name = "tegra210-axbar", + .params = &default_link_params, + .ignore_suspend = 1, + }, +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) + [TEGRA186_DAI_LINK_ADSP_ADMAIF1] = { + .name = "ADSP ADMAIF1", + .stream_name = "ADSP ADMAIF1", + .cpu_dai_name = "ADSP-ADMAIF1", + .codec_dai_name = "ADMAIF1 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF2] = { + .name = "ADSP ADMAIF2", + .stream_name = "ADSP ADMAIF2", + .cpu_dai_name = "ADSP-ADMAIF2", + .codec_dai_name = "ADMAIF2 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF3] = { + .name = "ADSP ADMAIF3", + .stream_name = "ADSP ADMAIF3", + .cpu_dai_name = "ADSP-ADMAIF3", + .codec_dai_name = "ADMAIF3 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF4] = { + .name = "ADSP ADMAIF4", + .stream_name = "ADSP ADMAIF4", + .cpu_dai_name = "ADSP-ADMAIF4", + .codec_dai_name = "ADMAIF4 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF5] = { + .name = "ADSP ADMAIF5", + .stream_name = "ADSP ADMAIF5", + .cpu_dai_name = "ADSP-ADMAIF5", + .codec_dai_name = "ADMAIF5 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF6] = { + .name = "ADSP ADMAIF6", + .stream_name = "ADSP ADMAIF6", + .cpu_dai_name = "ADSP-ADMAIF6", + .codec_dai_name = "ADMAIF6 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF7] = { + .name = "ADSP ADMAIF7", + .stream_name = "ADSP ADMAIF7", + .cpu_dai_name = "ADSP-ADMAIF7", + .codec_dai_name = "ADMAIF7 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF8] = { + .name = "ADSP ADMAIF8", + .stream_name = "ADSP ADMAIF8", + .cpu_dai_name = "ADSP-ADMAIF8", + .codec_dai_name = "ADMAIF8 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF9] = { + .name = "ADSP ADMAIF9", + .stream_name = "ADSP ADMAIF9", + .cpu_dai_name = "ADSP-ADMAIF9", + .codec_dai_name = "ADMAIF9 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF10] = { + .name = "ADSP ADMAIF10", + .stream_name = "ADSP ADMAIF10", + .cpu_dai_name = "ADSP-ADMAIF10", + .codec_dai_name = "ADMAIF10 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF11] = { + .name = "ADSP ADMAIF11", + .stream_name = "ADSP ADMAIF11", + .cpu_dai_name = "ADSP-ADMAIF11", + .codec_dai_name = "ADMAIF11 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF12] = { + .name = "ADSP ADMAIF12", + .stream_name = "ADSP ADMAIF12", + .cpu_dai_name = "ADSP-ADMAIF12", + .codec_dai_name = "ADMAIF12 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF13] = { + .name = "ADSP ADMAIF13", + .stream_name = "ADSP ADMAIF13", + .cpu_dai_name = "ADSP-ADMAIF13", + .codec_dai_name = "ADMAIF13 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF14] = { + .name = "ADSP ADMAIF14", + .stream_name = "ADSP ADMAIF14", + .cpu_dai_name = "ADSP-ADMAIF14", + .codec_dai_name = "ADMAIF14 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF15] = { + .name = "ADSP ADMAIF15", + .stream_name = "ADSP ADMAIF15", + .cpu_dai_name = "ADSP-ADMAIF15", + .codec_dai_name = "ADMAIF15 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF16] = { + .name = "ADSP ADMAIF16", + .stream_name = "ADSP ADMAIF16", + .cpu_dai_name = "ADSP-ADMAIF16", + .codec_dai_name = "ADMAIF16 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF17] = { + .name = "ADSP ADMAIF17", + .stream_name = "ADSP ADMAIF17", + .cpu_dai_name = "ADSP-ADMAIF17", + .codec_dai_name = "ADMAIF17 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF18] = { + .name = "ADSP ADMAIF18", + .stream_name = "ADSP ADMAIF18", + .cpu_dai_name = "ADSP-ADMAIF18", + .codec_dai_name = "ADMAIF18 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF19] = { + .name = "ADSP ADMAIF19", + .stream_name = "ADSP ADMAIF19", + .cpu_dai_name = "ADSP-ADMAIF19", + .codec_dai_name = "ADMAIF19 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_ADMAIF20] = { + .name = "ADSP ADMAIF20", + .stream_name = "ADSP ADMAIF20", + .cpu_dai_name = "ADSP-ADMAIF20", + .codec_dai_name = "ADMAIF20 FIFO", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra186-admaif", + .params = &default_link_params, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_PCM1] = { + .name = "ADSP PCM1", + .stream_name = "ADSP PCM1", + .cpu_dai_name = "ADSP PCM1", + .codec_dai_name = "ADSP-FE1", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-adsp", + .platform_name = "tegra210-adsp", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_PCM2] = { + .name = "ADSP PCM2", + .stream_name = "ADSP PCM2", + .cpu_dai_name = "ADSP PCM2", + .codec_dai_name = "ADSP-FE2", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-adsp", + .platform_name = "tegra210-adsp", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_COMPR1] = { + .name = "ADSP COMPR1", + .stream_name = "ADSP COMPR1", + .cpu_dai_name = "ADSP COMPR1", + .codec_dai_name = "ADSP-FE3", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-adsp", + .platform_name = "tegra210-adsp", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + [TEGRA186_DAI_LINK_ADSP_COMPR2] = { + .name = "ADSP COMPR2", + .stream_name = "ADSP COMPR2", + .cpu_dai_name = "ADSP COMPR2", + .codec_dai_name = "ADSP-FE4", + .cpu_name = "tegra210-adsp", + .codec_name = "tegra210-adsp", + .platform_name = "tegra210-adsp", + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, +#endif +}; + +static struct snd_soc_codec_conf + tegra186_xbar_codec_conf[TEGRA186_XBAR_CODEC_CONF] = { + [TEGRA186_CODEC_AMX1_CONF] = { + .dev_name = "tegra210-amx.0", + .name_prefix = "AMX1", + }, + [TEGRA186_CODEC_AMX2_CONF] = { + .dev_name = "tegra210-amx.1", + .name_prefix = "AMX2", + }, + [TEGRA186_CODEC_AMX3_CONF] = { + .dev_name = "tegra210-amx.2", + .name_prefix = "AMX3", + }, + [TEGRA186_CODEC_AMX4_CONF] = { + .dev_name = "tegra210-amx.3", + .name_prefix = "AMX4", + }, + [TEGRA186_CODEC_ADX1_CONF] = { + .dev_name = "tegra210-adx.0", + .name_prefix = "ADX1", + }, + [TEGRA186_CODEC_ADX2_CONF] = { + .dev_name = "tegra210-adx.1", + .name_prefix = "ADX2", + }, + [TEGRA186_CODEC_ADX3_CONF] = { + .dev_name = "tegra210-adx.2", + .name_prefix = "ADX3", + }, + [TEGRA186_CODEC_ADX4_CONF] = { + .dev_name = "tegra210-adx.3", + .name_prefix = "ADX4", + }, + [TEGRA186_CODEC_SFC1_CONF] = { + .dev_name = "tegra210-sfc.0", + .name_prefix = "SFC1", + }, + [TEGRA186_CODEC_SFC2_CONF] = { + .dev_name = "tegra210-sfc.1", + .name_prefix = "SFC2", + }, + [TEGRA186_CODEC_SFC3_CONF] = { + .dev_name = "tegra210-sfc.2", + .name_prefix = "SFC3", + }, + [TEGRA186_CODEC_SFC4_CONF] = { + .dev_name = "tegra210-sfc.3", + .name_prefix = "SFC4", + }, + [TEGRA186_CODEC_MVC1_CONF] = { + .dev_name = "tegra210-mvc.0", + .name_prefix = "MVC1", + }, + [TEGRA186_CODEC_MVC2_CONF] = { + .dev_name = "tegra210-mvc.1", + .name_prefix = "MVC2", + }, + [TEGRA186_CODEC_OPE1_CONF] = { + .dev_name = "tegra210-ope.0", + .name_prefix = "OPE1", + }, + [TEGRA186_CODEC_AFC1_CONF] = { + .dev_name = "tegra186-afc.0", + .name_prefix = "AFC1", + }, + [TEGRA186_CODEC_AFC2_CONF] = { + .dev_name = "tegra186-afc.1", + .name_prefix = "AFC2", + }, + [TEGRA186_CODEC_AFC3_CONF] = { + .dev_name = "tegra186-afc.2", + .name_prefix = "AFC3", + }, + [TEGRA186_CODEC_AFC4_CONF] = { + .dev_name = "tegra186-afc.3", + .name_prefix = "AFC4", + }, + [TEGRA186_CODEC_AFC5_CONF] = { + .dev_name = "tegra186-afc.4", + .name_prefix = "AFC5", + }, + [TEGRA186_CODEC_AFC6_CONF] = { + .dev_name = "tegra186-afc.5", + .name_prefix = "AFC6", + }, + [TEGRA186_CODEC_I2S1_CONF] = { + .dev_name = "tegra186-i2s.0", + .name_prefix = "I2S1", + }, + [TEGRA186_CODEC_I2S2_CONF] = { + .dev_name = "tegra186-i2s.1", + .name_prefix = "I2S2", + }, + [TEGRA186_CODEC_I2S3_CONF] = { + .dev_name = "tegra186-i2s.2", + .name_prefix = "I2S3", + }, + [TEGRA186_CODEC_I2S4_CONF] = { + .dev_name = "tegra186-i2s.3", + .name_prefix = "I2S4", + }, + [TEGRA186_CODEC_I2S5_CONF] = { + .dev_name = "tegra186-i2s.4", + .name_prefix = "I2S5", + }, + [TEGRA186_CODEC_I2S6_CONF] = { + .dev_name = "tegra186-i2s.5", + .name_prefix = "I2S6", + }, + [TEGRA186_CODEC_DMIC1_CONF] = { + .dev_name = "tegra210-dmic.0", + .name_prefix = "DMIC1", + }, + [TEGRA186_CODEC_DMIC2_CONF] = { + .dev_name = "tegra210-dmic.1", + .name_prefix = "DMIC2", + }, + [TEGRA186_CODEC_DMIC3_CONF] = { + .dev_name = "tegra210-dmic.2", + .name_prefix = "DMIC3", + }, + [TEGRA186_CODEC_DMIC4_CONF] = { + .dev_name = "tegra210-dmic.3", + .name_prefix = "DMIC4", + }, + [TEGRA186_CODEC_SPDIF_CONF] = { + .dev_name = "tegra210-spdif", + .name_prefix = "SPDIF", + }, + [TEGRA186_CODEC_DSPK1_CONF] = { + .dev_name = "tegra186-dspk.0", + .name_prefix = "DSPK1", + }, + [TEGRA186_CODEC_DSPK2_CONF] = { + .dev_name = "tegra186-dspk.1", + .name_prefix = "DSPK2", + }, + [TEGRA186_CODEC_ASRC1_CONF] = { + .dev_name = "tegra186-asrc", + .name_prefix = "ASRC1", + }, +}; + +void tegra_machine_set_machine_links( + struct snd_soc_dai_link *links) +{ + tegra_asoc_machine_links = links; +} +EXPORT_SYMBOL_GPL(tegra_machine_set_machine_links); + +struct snd_soc_dai_link *tegra_machine_get_machine_links(void) +{ + return tegra_asoc_machine_links; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_machine_links); + +void tegra_machine_set_machine_codec_conf( + struct snd_soc_codec_conf *codec_conf) +{ + tegra_asoc_codec_conf = codec_conf; +} +EXPORT_SYMBOL_GPL(tegra_machine_set_machine_codec_conf); + +struct snd_soc_codec_conf *tegra_machine_get_machine_codec_conf(void) +{ + return tegra_asoc_codec_conf; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_machine_codec_conf); + +struct snd_soc_dai_link *tegra_machine_get_dai_link(void) +{ + struct snd_soc_dai_link *link; + unsigned int size = 0; + + if (of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) { + link = tegra210_xbar_dai_links; + size = TEGRA210_XBAR_DAI_LINKS; + } + + if (tegra_asoc_machine_links) + return tegra_asoc_machine_links; + + num_dai_links = size; + + tegra_asoc_machine_links = kzalloc(size * + sizeof(struct snd_soc_dai_link), GFP_KERNEL); + + memcpy(tegra_asoc_machine_links, link, + size * sizeof(struct snd_soc_dai_link)); + + return tegra_asoc_machine_links; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_dai_link); + +void tegra_machine_remove_dai_link(void) +{ + kfree(tegra_asoc_machine_links); + tegra_asoc_machine_links = NULL; + bclk_ratio = NULL; + tx_mask = NULL; + rx_mask = NULL; +} +EXPORT_SYMBOL_GPL(tegra_machine_remove_dai_link); + +/* @link: input structure to append + * @link_size: size of the input structure + * Returns the total size after appending + */ +int tegra_machine_append_dai_link(struct snd_soc_dai_link *link, + unsigned int link_size) +{ + unsigned int size1 = (of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) ? + TEGRA210_XBAR_DAI_LINKS : 0; + unsigned int size2 = link_size; + + if (!tegra_asoc_machine_links) { + if (link) { + tegra_asoc_machine_links = link; + num_dai_links = size2; + return size2; + } else { + return 0; + } + } else { + if (link) { + tegra_asoc_machine_links = + (struct snd_soc_dai_link *) krealloc( + tegra_asoc_machine_links, (size1 + size2) * + sizeof(struct snd_soc_dai_link), GFP_KERNEL); + memcpy(&tegra_asoc_machine_links[size1], link, + size2 * sizeof(struct snd_soc_dai_link)); + num_dai_links = size1+size2; + return size1+size2; + } else { + num_dai_links = size1; + return size1; + } + } +} +EXPORT_SYMBOL_GPL(tegra_machine_append_dai_link); + +void tegra_machine_set_dai_ops(int link, struct snd_soc_ops *ops) +{ + if (tegra_asoc_machine_links) + tegra_asoc_machine_links[link].ops = ops; +} +EXPORT_SYMBOL_GPL(tegra_machine_set_dai_ops); + +void tegra_machine_set_dai_compr_ops(int link, struct snd_soc_compr_ops *ops) +{ + if (tegra_asoc_machine_links) + tegra_asoc_machine_links[link].compr_ops = ops; +} +EXPORT_SYMBOL_GPL(tegra_machine_set_dai_compr_ops); + +void tegra_machine_set_dai_init(int link, void *ptr) +{ + if (tegra_asoc_machine_links) + tegra_asoc_machine_links[link].init = ptr; +} +EXPORT_SYMBOL_GPL(tegra_machine_set_dai_init); + +void tegra_machine_set_dai_params(int link, + struct snd_soc_pcm_stream *params) +{ + if (tegra_asoc_machine_links && (NULL == params)) + tegra_asoc_machine_links[link].params = &default_link_params; + else if (tegra_asoc_machine_links) + tegra_asoc_machine_links[link].params = params; +} +EXPORT_SYMBOL_GPL(tegra_machine_set_dai_params); + +void tegra_machine_set_dai_fmt(int link, unsigned int fmt) +{ + if (tegra_asoc_machine_links) + tegra_asoc_machine_links[link].dai_fmt = fmt; +} +EXPORT_SYMBOL_GPL(tegra_machine_set_dai_fmt); + +struct snd_soc_codec_conf *tegra_machine_get_codec_conf(void) +{ + struct snd_soc_codec_conf *conf; + unsigned int size = 0; + + if (of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) { + conf = tegra210_xbar_codec_conf; + size = TEGRA210_XBAR_CODEC_CONF; + } + + if (tegra_asoc_codec_conf) + return tegra_asoc_codec_conf; + + tegra_asoc_codec_conf = kzalloc(size * + sizeof(struct snd_soc_codec_conf), GFP_KERNEL); + + memcpy(tegra_asoc_codec_conf, conf, + size * sizeof(struct snd_soc_codec_conf)); + + return tegra_asoc_codec_conf; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_codec_conf); + +void tegra_machine_remove_codec_conf(void) +{ + kfree(tegra_asoc_codec_conf); + tegra_asoc_codec_conf = NULL; +} +EXPORT_SYMBOL_GPL(tegra_machine_remove_codec_conf); + +/* @link: input structure to append + * @link_size: size of the input structure + * Returns the total size after appending + */ +int tegra_machine_append_codec_conf(struct snd_soc_codec_conf *conf, + unsigned int conf_size) +{ + unsigned int size1 = (of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) ? + TEGRA210_XBAR_CODEC_CONF : 0; + unsigned int size2 = conf_size; + + if (!tegra_asoc_codec_conf) { + if (conf) { + tegra_asoc_codec_conf = conf; + return size2; + } else { + return 0; + } + } else { + if (conf) { + tegra_asoc_codec_conf = + (struct snd_soc_codec_conf *) krealloc( + tegra_asoc_codec_conf, (size1 + size2) * + sizeof(struct snd_soc_codec_conf), GFP_KERNEL); + memcpy(&tegra_asoc_codec_conf[size1], conf, + size2 * sizeof(struct snd_soc_codec_conf)); + return size1+size2; + } else { + return size1; + } + } +} +EXPORT_SYMBOL_GPL(tegra_machine_append_codec_conf); + + +static int tegra_machine_get_format(u64 *p_formats, char *fmt) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bit_format); i++) { + if (strcmp(bit_format[i], fmt) == 0) { + *p_formats = (u64)1 << i; + return 0; + } + } + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_format); + +struct snd_soc_dai_link *tegra_machine_new_codec_links( + struct platform_device *pdev, + struct snd_soc_dai_link *tegra_codec_links, + unsigned int *pnum_codec_links) +{ + unsigned int i, j, num_codec_links; + struct device_node *np = pdev->dev.of_node, *subnp; + struct snd_soc_pcm_stream *params; + char dai_link_name[MAX_STR_SIZE]; + char *str; + const char *prefix; + struct device_node *bitclkmaster = NULL, *framemaster = NULL; + + if (tegra_codec_links) + return tegra_codec_links; + + if (!np) + goto err; + + if (of_property_read_u32(np, + "nvidia,num-codec-link", (u32 *)&num_codec_links)) { + dev_err(&pdev->dev, + "Property 'nvidia,num-codec-link' missing or invalid\n"); + goto err; + } + + tegra_codec_links = devm_kzalloc(&pdev->dev, 2 * num_codec_links * + sizeof(struct snd_soc_dai_link), GFP_KERNEL); + if (!tegra_codec_links) { + dev_err(&pdev->dev, "Can't allocate tegra_codec_links\n"); + goto err; + } + + if (bclk_ratio == NULL) { + bclk_ratio = devm_kzalloc(&pdev->dev, num_codec_links * + sizeof(unsigned int), GFP_KERNEL); + if (!bclk_ratio) { + dev_err(&pdev->dev, "Can't allocate bclk_ratio\n"); + goto err; + } + } + + if (rx_mask == NULL) { + rx_mask = devm_kzalloc(&pdev->dev, num_codec_links * + sizeof(unsigned int), GFP_KERNEL); + if (!rx_mask) { + dev_err(&pdev->dev, "Can't allocate rx_mask\n"); + goto err; + } + } + + if (tx_mask == NULL) { + tx_mask = devm_kzalloc(&pdev->dev, num_codec_links * + sizeof(unsigned int), GFP_KERNEL); + if (!tx_mask) { + dev_err(&pdev->dev, "Can't allocate tx_mask\n"); + goto err; + } + } + /* variable i is for DAP and j is for CIF */ + for (i = 0, j = num_codec_links; i < num_codec_links; i++, j++) { + memset((void *)dai_link_name, '\0', MAX_STR_SIZE); + sprintf(dai_link_name, "nvidia,dai-link-%d", i+1); + subnp = of_get_child_by_name(np, dai_link_name); + if (subnp) { + tegra_codec_links[i].codec_of_node = + of_parse_phandle(subnp, "codec-dai", 0); + if (!tegra_codec_links[i].codec_of_node) { + dev_err(&pdev->dev, + "Property '%s.codec-dai' missing or invalid\n", + dai_link_name); + goto err; + } + + tegra_codec_links[i].cpu_of_node + = of_parse_phandle(subnp, "cpu-dai", 0); + if (!tegra_codec_links[i].cpu_of_node) { + dev_err(&pdev->dev, + "Property '%s.cpu-dai' missing or invalid\n", + dai_link_name); + goto err; + } + + /* DAP configuration */ + if (of_property_read_string(subnp, "name-prefix", + &prefix)) { + dev_err(&pdev->dev, + "Property 'name-prefix' missing or invalid\n"); + goto err; + } + + if (of_property_read_string(subnp, "link-name", + &tegra_codec_links[i].name)) { + dev_err(&pdev->dev, + "Property 'link-name' missing or invalid\n"); + goto err; + } + + tegra_codec_links[i].stream_name = "Playback"; + tegra_codec_links[i].ignore_suspend = + of_property_read_bool(subnp, "ignore_suspend"); + + /* special case to handle specifically for dspk, connected to + two mono amplifiers */ + if (!strcmp(tegra_codec_links[i].name, "dspk-playback-r")) + tegra_codec_links[i].cpu_dai_name = "DAP Right"; + else if (!strcmp(tegra_codec_links[i].name, "dspk-playback-l")) + tegra_codec_links[i].cpu_dai_name = "DAP Left"; + else + tegra_codec_links[i].cpu_dai_name = "DAP"; + + if (of_property_read_string(subnp, "codec-dai-name", + &tegra_codec_links[i].codec_dai_name)) { + dev_err(&pdev->dev, + "Property 'codec-dai-name' missing or invalid\n"); + goto err; + } + tegra_codec_links[i].dai_fmt = + snd_soc_of_parse_daifmt(subnp, NULL, + &bitclkmaster, &framemaster); + + params = devm_kzalloc(&pdev->dev, + sizeof(struct snd_soc_pcm_stream), GFP_KERNEL); + + if (of_property_read_string(subnp, + "bit-format", (const char **)&str)) { + dev_err(&pdev->dev, + "Property 'bit-format' missing or invalid\n"); + goto err; + } + if (tegra_machine_get_format(¶ms->formats, str)) { + dev_err(&pdev->dev, + "Wrong codec format\n"); + goto err; + } + + if (of_property_read_u32(subnp, + "srate", ¶ms->rate_min)) { + dev_err(&pdev->dev, + "Property 'srate' missing or invalid\n"); + goto err; + } + params->rate_max = params->rate_min; + + if (of_property_read_u32(subnp, + "num-channel", ¶ms->channels_min)) { + dev_err(&pdev->dev, + "Property 'num-channel' missing or invalid\n"); + goto err; + } + params->channels_max = params->channels_min; + tegra_codec_links[i].params = params; + + of_property_read_u32(subnp, + "bclk_ratio", (u32 *)&bclk_ratio[i]); + + of_property_read_u32(subnp, + "rx-mask", (u32 *)&rx_mask[i]); + of_property_read_u32(subnp, + "tx-mask", (u32 *)&tx_mask[i]); + + /* CIF configuration */ + tegra_codec_links[j].codec_of_node = + tegra_codec_links[i].cpu_of_node; + tegra_codec_links[j].cpu_of_node = + of_parse_phandle(np, "nvidia,xbar", 0); + if (!tegra_codec_links[j].cpu_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,xbar' missing or invalid\n"); + goto err; + } + + if (!strcmp(tegra_codec_links[i].name, "dspk-playback-r")) + tegra_codec_links[j].codec_dai_name = "CIF Right"; + else if (!strcmp(tegra_codec_links[i].name, "dspk-playback-l")) + tegra_codec_links[j].codec_dai_name = "CIF Left"; + else + tegra_codec_links[j].codec_dai_name = "CIF"; + + if (of_property_read_string(subnp, "cpu-dai-name", + &tegra_codec_links[j].cpu_dai_name)) { + dev_err(&pdev->dev, + "Property 'cpu-dai-name' missing or invalid\n"); + goto err; + } + + str = devm_kzalloc(&pdev->dev, + sizeof(tegra_codec_links[j].cpu_dai_name) + + 1 + sizeof(tegra_codec_links[j].codec_dai_name), + GFP_KERNEL); + str = strcat(str, tegra_codec_links[j].cpu_dai_name); + str = strcat(str, " "); + str = strcat(str, tegra_codec_links[j].codec_dai_name); + + tegra_codec_links[j].name = + tegra_codec_links[j].stream_name = str; + tegra_codec_links[j].params = + tegra_codec_links[i].params; + tegra_codec_links[j].ignore_suspend = 1; + } else { + dev_err(&pdev->dev, + "Property '%s' missing or invalid\n", + dai_link_name); + goto err; + } + } + + *pnum_codec_links = num_codec_links; + + return tegra_codec_links; +err: + return NULL; +} +EXPORT_SYMBOL_GPL(tegra_machine_new_codec_links); + + +struct snd_soc_codec_conf *tegra_machine_new_codec_conf( + struct platform_device *pdev, + struct snd_soc_codec_conf *tegra_codec_conf, + unsigned int *pnum_codec_links) +{ + unsigned int i, num_codec_links; + struct device_node *np = pdev->dev.of_node, *subnp; + struct device_node *of_node; + char dai_link_name[MAX_STR_SIZE]; + + if (tegra_codec_conf) + return tegra_codec_conf; + + if (!np) + goto err; + + if (of_property_read_u32(np, + "nvidia,num-codec-link", (u32 *)&num_codec_links)) { + dev_err(&pdev->dev, + "Property 'nvidia,num-codec-link' missing or invalid\n"); + goto err; + } + + tegra_codec_conf = devm_kzalloc(&pdev->dev, num_codec_links * + sizeof(struct snd_soc_codec_conf), GFP_KERNEL); + + for (i = 0; i < num_codec_links; i++) { + memset((void *)dai_link_name, '\0', MAX_STR_SIZE); + sprintf(dai_link_name, "nvidia,dai-link-%d", i+1); + subnp = of_get_child_by_name(np, dai_link_name); + if (subnp) { + of_node = of_parse_phandle(subnp, "codec-dai", 0); + + /* specify device by DT/OF node, + rather than device name */ + tegra_codec_conf[i].dev_name = NULL; + tegra_codec_conf[i].of_node = of_node; + + if (of_property_read_string(subnp, "name-prefix", + &tegra_codec_conf[i].name_prefix)) { + dev_err(&pdev->dev, + "Property 'name-prefix' missing or invalid\n"); + goto err; + } + } + } + + *pnum_codec_links = num_codec_links; + + return tegra_codec_conf; +err: + return NULL; +} +EXPORT_SYMBOL_GPL(tegra_machine_new_codec_conf); + +/* This function is valid when dai_link is initiated from the DT */ +unsigned int tegra_machine_get_codec_dai_link_idx(const char *codec_name) +{ + unsigned int idx = (of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) ? + TEGRA210_XBAR_DAI_LINKS : 0; + + if (num_dai_links <= idx) + goto err; + + while (idx < num_dai_links) { + if (tegra_asoc_machine_links[idx].name) + if (!strcmp(tegra_asoc_machine_links[idx].name, + codec_name)) + return idx; + idx++; + } + +err: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_codec_dai_link_idx); + +unsigned int tegra_machine_get_bclk_ratio( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai_link *codec_dai_link = rtd->dai_link; + char *codec_name = (char *)codec_dai_link->name; + unsigned int idx = + tegra_machine_get_codec_dai_link_idx(codec_name); + + if (idx == -EINVAL) + goto err; + + if (!bclk_ratio) + goto err; + + idx = idx - ((of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) ? + TEGRA210_XBAR_DAI_LINKS : 0); + + return bclk_ratio[idx]; + +err: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_bclk_ratio); + +unsigned int tegra_machine_get_rx_mask( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai_link *codec_dai_link = rtd->dai_link; + char *codec_name = (char *)codec_dai_link->name; + unsigned int idx = + tegra_machine_get_codec_dai_link_idx(codec_name); + + if (idx == -EINVAL) + goto err; + + if (!rx_mask) + goto err; + + idx = idx - ((of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) ? + TEGRA210_XBAR_DAI_LINKS : 0); + + return rx_mask[idx]; + +err: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_rx_mask); + +unsigned int tegra_machine_get_tx_mask( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai_link *codec_dai_link = rtd->dai_link; + char *codec_name = (char *)codec_dai_link->name; + unsigned int idx = + tegra_machine_get_codec_dai_link_idx(codec_name); + + if (idx == -EINVAL) + goto err; + + if (!tx_mask) + goto err; + + idx = idx - ((of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) ? + TEGRA210_XBAR_DAI_LINKS : 0); + + return tx_mask[idx]; + +err: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_tx_mask); + +void tegra_machine_set_num_dai_links(unsigned int val) +{ + num_dai_links = val; +} +EXPORT_SYMBOL_GPL(tegra_machine_set_num_dai_links); + +unsigned int tegra_machine_get_num_dai_links(void) +{ + return num_dai_links; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_num_dai_links); + +unsigned int *tegra_machine_get_bclk_ratio_array(void) +{ + return bclk_ratio; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_bclk_ratio_array); + +unsigned int *tegra_machine_get_rx_mask_array(void) +{ + return rx_mask; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_rx_mask_array); +unsigned int *tegra_machine_get_tx_mask_array(void) +{ + return tx_mask; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_tx_mask_array); + +static int tegra_machine_get_num_links_t18x(void) +{ + return num_links; +} + +#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT) +void tegra_machine_remove_adsp_links_t18x(void) +{ + num_links = TEGRA186_DAI_LINK_ADSP_ADMAIF1; +} +#else +void tegra_machine_remove_adsp_links_t18x(void) +{ +} +#endif + +EXPORT_SYMBOL_GPL(tegra_machine_remove_adsp_links_t18x); + +/* t18x specific APIs*/ +struct snd_soc_dai_link *tegra_machine_get_dai_link_t18x(void) +{ + struct snd_soc_dai_link *link = tegra186_xbar_dai_links; + unsigned int size = tegra_machine_get_num_links_t18x(); + struct snd_soc_dai_link *tegra_asoc_machine_links_t18x = + tegra_machine_get_machine_links(); + + if (tegra_asoc_machine_links_t18x) + return tegra_asoc_machine_links_t18x; + + tegra_machine_set_num_dai_links(size); + + tegra_asoc_machine_links_t18x = kzalloc(size * + sizeof(struct snd_soc_dai_link), GFP_KERNEL); + + memcpy(tegra_asoc_machine_links_t18x, link, + size * sizeof(struct snd_soc_dai_link)); + + tegra_machine_set_machine_links(tegra_asoc_machine_links_t18x); + + return tegra_asoc_machine_links_t18x; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_dai_link_t18x); + +int tegra_machine_append_dai_link_t18x(struct snd_soc_dai_link *link, + unsigned int link_size) +{ + unsigned int size1 = tegra_machine_get_num_dai_links(); + unsigned int size2 = link_size; + struct snd_soc_dai_link *tegra_asoc_machine_links_t18x = + tegra_machine_get_machine_links(); + + if (!tegra_asoc_machine_links_t18x) { + if (link) { + tegra_machine_set_machine_links(link); + tegra_machine_set_num_dai_links(size2); + return size2; + } else { + return 0; + } + } else { + if (link) { + tegra_asoc_machine_links_t18x = + (struct snd_soc_dai_link *) krealloc( + tegra_asoc_machine_links_t18x, (size1 + size2) * + sizeof(struct snd_soc_dai_link), GFP_KERNEL); + tegra_machine_set_machine_links( + tegra_asoc_machine_links_t18x); + memcpy(&tegra_asoc_machine_links_t18x[size1], link, + size2 * sizeof(struct snd_soc_dai_link)); + tegra_machine_set_num_dai_links(size1+size2); + return size1+size2; + } else { + tegra_machine_set_num_dai_links(size1); + return size1; + } + } +} +EXPORT_SYMBOL_GPL(tegra_machine_append_dai_link_t18x); + +struct snd_soc_codec_conf *tegra_machine_get_codec_conf_t18x(void) +{ + struct snd_soc_codec_conf *conf = tegra186_xbar_codec_conf; + struct snd_soc_codec_conf *tegra_asoc_codec_conf_t18x = + tegra_machine_get_machine_codec_conf(); + unsigned int size = TEGRA186_XBAR_CODEC_CONF; + + if (tegra_asoc_codec_conf_t18x) + return tegra_asoc_codec_conf_t18x; + + tegra_asoc_codec_conf_t18x = kzalloc(size * + sizeof(struct snd_soc_codec_conf), GFP_KERNEL); + + memcpy(tegra_asoc_codec_conf_t18x, conf, + size * sizeof(struct snd_soc_codec_conf)); + + tegra_machine_set_machine_codec_conf(tegra_asoc_codec_conf_t18x); + + return tegra_asoc_codec_conf_t18x; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_codec_conf_t18x); + +int tegra_machine_append_codec_conf_t18x(struct snd_soc_codec_conf *conf, + unsigned int conf_size) +{ + unsigned int size1 = TEGRA186_XBAR_CODEC_CONF; + unsigned int size2 = conf_size; + struct snd_soc_codec_conf *tegra_asoc_codec_conf_t18x = + tegra_machine_get_machine_codec_conf(); + + if (!tegra_asoc_codec_conf_t18x) { + if (conf) { + tegra_machine_set_machine_codec_conf(conf); + return size2; + } else { + return 0; + } + } else { + if (conf) { + tegra_asoc_codec_conf_t18x = + (struct snd_soc_codec_conf *) krealloc( + tegra_asoc_codec_conf_t18x, (size1 + size2) * + sizeof(struct snd_soc_codec_conf), GFP_KERNEL); + tegra_machine_set_machine_codec_conf( + tegra_asoc_codec_conf_t18x); + memcpy(&tegra_asoc_codec_conf_t18x[size1], conf, + size2 * sizeof(struct snd_soc_codec_conf)); + return size1+size2; + } else + return size1; + } +} +EXPORT_SYMBOL_GPL(tegra_machine_append_codec_conf_t18x); + +unsigned int tegra_machine_get_codec_dai_link_idx_t18x(const char *codec_name) +{ + unsigned int idx = tegra_machine_get_num_links_t18x(); + struct snd_soc_dai_link *tegra_asoc_machine_links_t18x = + tegra_machine_get_machine_links(); + + if (tegra_machine_get_num_dai_links() <= idx) + goto err; + + while (idx < tegra_machine_get_num_dai_links()) { + if (tegra_asoc_machine_links_t18x[idx].name) + if (!strcmp(tegra_asoc_machine_links_t18x[idx].name, + codec_name)) + return idx; + idx++; + } + +err: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_codec_dai_link_idx_t18x); + +unsigned int tegra_machine_get_bclk_ratio_t18x( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai_link *codec_dai_link = rtd->dai_link; + char *codec_name = (char *)codec_dai_link->name; + unsigned int idx = + tegra_machine_get_codec_dai_link_idx_t18x(codec_name); + unsigned int *bclk_ratio_t18x = + tegra_machine_get_bclk_ratio_array(); + + if (idx == -EINVAL) + goto err; + + if (!bclk_ratio_t18x) + goto err; + + idx = idx - tegra_machine_get_num_links_t18x(); + + return bclk_ratio_t18x[idx]; + +err: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_bclk_ratio_t18x); + +unsigned int tegra_machine_get_rx_mask_t18x( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai_link *codec_dai_link = rtd->dai_link; + char *codec_name = (char *)codec_dai_link->name; + unsigned int idx = + tegra_machine_get_codec_dai_link_idx_t18x(codec_name); + unsigned int *rx_mask_t18x = + tegra_machine_get_rx_mask_array(); + if (idx == -EINVAL) + goto err; + + if (!rx_mask_t18x) + goto err; + + idx = idx - tegra_machine_get_num_links_t18x(); + + return rx_mask_t18x[idx]; + +err: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_rx_mask_t18x); + +unsigned int tegra_machine_get_tx_mask_t18x( + struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai_link *codec_dai_link = rtd->dai_link; + char *codec_name = (char *)codec_dai_link->name; + unsigned int idx = + tegra_machine_get_codec_dai_link_idx_t18x(codec_name); + unsigned int *tx_mask_t18x = + tegra_machine_get_tx_mask_array(); + + if (idx == -EINVAL) + goto err; + + if (!tx_mask_t18x) + goto err; + + idx = idx - tegra_machine_get_num_links_t18x(); + + return tx_mask_t18x[idx]; + +err: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(tegra_machine_get_tx_mask_t18x); + +MODULE_AUTHOR("Arun Shamanna Lakshmi "); +MODULE_AUTHOR("Junghyun Kim "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra-alt/utils/tegra_asoc_utils_alt.c b/sound/soc/tegra-alt/utils/tegra_asoc_utils_alt.c new file mode 100644 index 00000000..df1b6dca --- /dev/null +++ b/sound/soc/tegra-alt/utils/tegra_asoc_utils_alt.c @@ -0,0 +1,441 @@ +/* + * tegra_asoc_utils_alt.c - MCLK and DAP Utility driver + * + * Author: Stephen Warren + * Copyright (c) 2010-2017 NVIDIA CORPORATION. All rights reserved. + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "tegra_asoc_utils_alt.h" + +#ifdef CONFIG_SWITCH +static bool is_switch_registered; +#endif + +struct clk *tegra_alt_asoc_utils_get_clk(struct device *dev, + bool dev_id, + const char *clk_name) +{ + struct clk *clk; + + clk = devm_clk_get(dev, clk_name); + + return clk; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_get_clk); + +void tegra_alt_asoc_utils_clk_put(struct device *dev, struct clk *clk) +{ + devm_clk_put(dev, clk); +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_clk_put); + +int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data, + int srate, + int mclk, + int clk_out_rate) +{ + int new_baseclock; + int ahub_rate = 0; + bool clk_change; + int err; + + switch (srate) { + case 11025: + case 22050: + case 44100: + case 88200: + case 176400: + if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA186) + new_baseclock = 338688000; + else { + new_baseclock = data->clk_rates[PLLA_x11025_RATE]; + mclk = data->clk_rates[PLLA_OUT0_x11025_RATE]; + ahub_rate = data->clk_rates[AHUB_x11025_RATE]; + + if (srate <= 11025) { + /* half the pll_a_out0 to support lower + * sampling rate divider + */ + mclk = mclk >> 1; + ahub_rate = ahub_rate >> 1; + } + + clk_out_rate = srate * data->mclk_scale; + data->clk_out_rate = clk_out_rate; + } + break; + case 8000: + case 16000: + case 32000: + case 48000: + case 64000: + case 96000: + case 192000: + if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA186) + new_baseclock = 368640000; + else { + new_baseclock = data->clk_rates[PLLA_x8000_RATE]; + mclk = data->clk_rates[PLLA_OUT0_x8000_RATE]; + ahub_rate = data->clk_rates[AHUB_x8000_RATE]; + + if (srate <= 8000) { + /* half the pll_a_out0 to support lower + * sampling rate divider + */ + mclk = mclk >> 1; + ahub_rate = ahub_rate >> 1; + } + + clk_out_rate = srate * data->mclk_scale; + data->clk_out_rate = clk_out_rate; + } + break; + default: + return -EINVAL; + } + + clk_change = ((new_baseclock != data->set_baseclock) || + (mclk != data->set_mclk) || + (clk_out_rate != data->set_clk_out_rate)); + + if (!clk_change) + return 0; + + /* Don't change rate if already one dai-link is using it */ + if (data->lock_count) + return -EINVAL; + + data->set_baseclock = 0; + data->set_mclk = 0; + + err = clk_set_rate(data->clk_pll_a, new_baseclock); + if (err) { + dev_err(data->dev, "Can't set pll_a rate: %d\n", err); + return err; + } + + err = clk_set_rate(data->clk_pll_a_out0, mclk); + if (err) { + dev_err(data->dev, "Can't set clk_pll_a_out0 rate: %d\n", err); + return err; + } + + if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) { + err = clk_set_rate(data->clk_ahub, ahub_rate); + if (err) { + dev_err(data->dev, "Can't set clk_cdev1 rate: %d\n", + err); + return err; + } + } + + err = clk_set_rate(data->clk_cdev1, clk_out_rate); + if (err) { + dev_err(data->dev, "Can't set clk_cdev1 rate: %d\n", err); + return err; + } + + data->set_baseclock = new_baseclock; + data->set_mclk = mclk; + data->set_clk_out_rate = clk_out_rate; + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_set_rate); + +void tegra_alt_asoc_utils_lock_clk_rate(struct tegra_asoc_audio_clock_info *data, + int lock) +{ + if (lock) + data->lock_count++; + else if (data->lock_count) + data->lock_count--; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_lock_clk_rate); + +int tegra_alt_asoc_utils_clk_enable(struct tegra_asoc_audio_clock_info *data) +{ + int err; + +#if defined(CONFIG_COMMON_CLK) + if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) + reset_control_reset(data->clk_cdev1_rst); +#endif + err = clk_prepare_enable(data->clk_cdev1); + if (err) { + dev_err(data->dev, "Can't enable cdev1: %d\n", err); + return err; + } + data->clk_cdev1_state = 1; + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_clk_enable); + +int tegra_alt_asoc_utils_clk_disable(struct tegra_asoc_audio_clock_info *data) +{ + clk_disable_unprepare(data->clk_cdev1); + data->clk_cdev1_state = 0; + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_clk_disable); + +int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data, + struct device *dev, struct snd_soc_card *card) +{ + int ret; + + data->dev = dev; + data->card = card; + data->mclk_scale = 256; + + if (of_machine_is_compatible("nvidia,tegra210") || + of_machine_is_compatible("nvidia,tegra210b01")) + data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA210; + else if (of_machine_is_compatible("nvidia,tegra186")) + data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA186; + else + /* DT boot, but unknown SoC */ + return -EINVAL; + + /* pll_p_out1 is not used for ahub for T210,T186 */ + if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210) { + data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1"); + if (IS_ERR(data->clk_pll_p_out1)) { + dev_err(data->dev, "Can't retrieve clk pll_p_out1\n"); + ret = PTR_ERR(data->clk_pll_p_out1); + goto err; + } + } + + data->clk_m = tegra_alt_asoc_utils_get_clk(dev, false, "clk_m"); + if (IS_ERR(data->clk_m)) { + dev_err(data->dev, "Can't retrieve clk clk_m\n"); + ret = PTR_ERR(data->clk_m); + goto err; + } + + data->clk_pll_a = tegra_alt_asoc_utils_get_clk(dev, false, "pll_a"); + if (IS_ERR(data->clk_pll_a)) { + dev_err(data->dev, "Can't retrieve clk pll_a\n"); + ret = PTR_ERR(data->clk_pll_a); + goto err_put_pll_p_out1; + } + + data->clk_pll_a_out0 = tegra_alt_asoc_utils_get_clk(dev, false, + "pll_a_out0"); + if (IS_ERR(data->clk_pll_a_out0)) { + dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); + ret = PTR_ERR(data->clk_pll_a_out0); + goto err_put_pll_a; + } + + data->clk_cdev1 = tegra_alt_asoc_utils_get_clk(dev, true, + "extern1"); + + if (IS_ERR(data->clk_cdev1)) { + dev_err(data->dev, "Can't retrieve clk cdev1\n"); + ret = PTR_ERR(data->clk_cdev1); + goto err_put_pll_a_out0; + } + + if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) { + data->clk_ahub = tegra_alt_asoc_utils_get_clk(dev, false, + "ahub"); + if (IS_ERR(data->clk_ahub)) { + dev_err(data->dev, "Can't retrieve clk ahub\n"); + ret = PTR_ERR(data->clk_ahub); + goto err_put_cdev1; + } + +#if defined(CONFIG_COMMON_CLK) + data->clk_cdev1_rst = devm_reset_control_get(dev, + "extern1_rst"); + if (IS_ERR(data->clk_cdev1_rst)) { + dev_err(dev, "Reset control is not found, err: %ld\n", + PTR_ERR(data->clk_cdev1_rst)); + return PTR_ERR(data->clk_cdev1_rst); + } + + reset_control_reset(data->clk_cdev1_rst); +#endif + } + + if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210) { + ret = tegra_alt_asoc_utils_set_rate(data, 48000, + 256 * 48000, 256 * 48000); + if (ret) + goto err_put_ahub; + } + + if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA186) { + ret = clk_prepare_enable(data->clk_cdev1); + if (ret) { + dev_err(data->dev, "Can't enable clk cdev1/extern1"); + goto err_put_ahub; + } + data->clk_cdev1_state = 1; + } + + return 0; + +err_put_ahub: + if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) + tegra_alt_asoc_utils_clk_put(dev, data->clk_ahub); +err_put_cdev1: + tegra_alt_asoc_utils_clk_put(dev, data->clk_cdev1); +err_put_pll_a_out0: + tegra_alt_asoc_utils_clk_put(dev, data->clk_pll_a_out0); +err_put_pll_a: + tegra_alt_asoc_utils_clk_put(dev, data->clk_pll_a); +err_put_pll_p_out1: + if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210) + clk_put(data->clk_pll_p_out1); +err: + return ret; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_init); + +int tegra_alt_asoc_utils_set_parent(struct tegra_asoc_audio_clock_info *data, + int is_i2s_master) +{ + int ret = -ENODEV; + + if (is_i2s_master) { + ret = clk_set_parent(data->clk_cdev1, data->clk_pll_a_out0); + if (ret) { + dev_err(data->dev, "Can't set clk cdev1/extern1 parent"); + return ret; + } + } else { + ret = clk_set_parent(data->clk_cdev1, data->clk_m); + if (ret) { + dev_err(data->dev, "Can't set clk cdev1/extern1 parent"); + return ret; + } + + ret = clk_set_rate(data->clk_cdev1, 13000000); + if (ret) { + dev_err(data->dev, "Can't set clk rate"); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_set_parent); + +int tegra_alt_asoc_utils_set_extern_parent( + struct tegra_asoc_audio_clock_info *data, const char *parent) +{ + unsigned long rate; + int err; + + rate = clk_get_rate(data->clk_cdev1); + if (!strcmp(parent, "clk_m")) { + err = clk_set_parent(data->clk_cdev1, data->clk_m); + if (err) { + dev_err(data->dev, "Can't set clk extern1 parent"); + return err; + } + } else if (!strcmp(parent, "pll_a_out0")) { + err = clk_set_parent(data->clk_cdev1, data->clk_pll_a_out0); + if (err) { + dev_err(data->dev, "Can't set clk cdev1/extern1 parent"); + return err; + } + } + + err = clk_set_rate(data->clk_cdev1, rate); + if (err) { + dev_err(data->dev, "Can't set clk rate"); + return err; + } + + return 0; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_set_extern_parent); + +void tegra_alt_asoc_utils_fini(struct tegra_asoc_audio_clock_info *data) +{ + if (data->clk_cdev1_state) + clk_disable_unprepare(data->clk_cdev1); + + if (data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA210) + if (!IS_ERR(data->clk_ahub)) + tegra_alt_asoc_utils_clk_put(data->dev, data->clk_ahub); + + if (!IS_ERR(data->clk_pll_a_out0)) + tegra_alt_asoc_utils_clk_put(data->dev, data->clk_pll_a_out0); + + if (!IS_ERR(data->clk_pll_a)) + tegra_alt_asoc_utils_clk_put(data->dev, data->clk_pll_a); + + if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210) + if (!IS_ERR(data->clk_pll_p_out1)) + clk_put(data->clk_pll_p_out1); +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_fini); + +#ifdef CONFIG_SWITCH +int tegra_alt_asoc_switch_register(struct switch_dev *sdev) +{ + int ret; + + if (is_switch_registered) + return -EBUSY; + + ret = switch_dev_register(sdev); + + if (ret >= 0) + is_switch_registered = true; + + return ret; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_switch_register); + +void tegra_alt_asoc_switch_unregister(struct switch_dev *sdev) +{ + if (!is_switch_registered) + return; + + switch_dev_unregister(sdev); + is_switch_registered = false; +} +EXPORT_SYMBOL_GPL(tegra_alt_asoc_switch_unregister); +#endif + +MODULE_AUTHOR("Stephen Warren "); +MODULE_DESCRIPTION("Tegra ASoC utility code"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra-alt/utils/tegra_isomgr_bw_alt.c b/sound/soc/tegra-alt/utils/tegra_isomgr_bw_alt.c new file mode 100644 index 00000000..72e68da4 --- /dev/null +++ b/sound/soc/tegra-alt/utils/tegra_isomgr_bw_alt.c @@ -0,0 +1,203 @@ +/* + * tegra_isomgr_bw_alt.c - ADMA bandwidth calculation + * + * Copyright (c) 2016-2017 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include +#include "tegra_isomgr_bw_alt.h" + +#if defined(CONFIG_TEGRA_ISOMGR) + +#define MAX_BW 393216 /*Maximum KiloByte*/ +#define MAX_DEV_NUM 256 + +static long tegra_adma_calc_min_bandwidth(void); + +static struct adma_isomgr { + int current_bandwidth; + bool device_number[MAX_DEV_NUM]; + int bw_per_device[MAX_DEV_NUM]; + struct mutex mutex; + /* iso manager handle */ + tegra_isomgr_handle isomgr_handle; +} *adma; + +static long tegra_adma_calc_min_bandwidth(void) +{ + int max_srate = 192; /*Khz*/ + int max_bpp = 4; /* Bytes per sample*/ + int slot = 8; /* Max Channel per stream*/ + int num_streams = 4; /* Min simultaneous usecase consideration*/ + long min_bw; + + min_bw = max_srate * max_bpp * slot * num_streams; + + return min_bw; +} + +static int adma_isomgr_request(uint adma_bw, uint lt) +{ + int ret; + + if (!adma->isomgr_handle) { + pr_err("%s: adma iso handle not initialized\n", __func__); + return -1; + } + + /* return value of tegra_isomgr_reserve is dvfs latency in usec */ + ret = tegra_isomgr_reserve(adma->isomgr_handle, + adma_bw, /* KB/sec */ + lt); /* usec */ + if (!ret) { + pr_err("%s: failed to reserve %u KBps\n", __func__, adma_bw); + return -1; + } + + /* return value of tegra_isomgr_realize is dvfs latency in usec */ + ret = tegra_isomgr_realize(adma->isomgr_handle); + if (!ret) { + pr_err("%s: failed to realize %u KBps\n", __func__, adma_bw); + return -1; + } + + return 0; +} + +void tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream, + bool is_running) +{ + int bandwidth, sample_bytes; + int ret; + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_pcm *pcm = substream->pcm; + + if (!adma || !runtime || !pcm) + return; + + if (pcm->device >= MAX_DEV_NUM) { + pr_err("%s: PCM device number is greater than %d\n", __func__, + MAX_DEV_NUM); + return; + } + + if (((adma->device_number[pcm->device] == true) && is_running) || + ((adma->device_number[pcm->device] == false) && !is_running) + ) + return; + + mutex_lock(&adma->mutex); + + if (is_running) { + sample_bytes = snd_pcm_format_width(runtime->format)/8; + if (sample_bytes < 0) + sample_bytes = 0; + + /* KB/s kilo bytes per sec */ + bandwidth = runtime->channels * (runtime->rate/1000) * + sample_bytes; + + adma->device_number[pcm->device] = true; + adma->current_bandwidth += bandwidth; + adma->bw_per_device[pcm->device] = bandwidth; + } else { + adma->device_number[pcm->device] = false; + adma->current_bandwidth -= adma->bw_per_device[pcm->device]; + adma->bw_per_device[pcm->device] = 0; + } + + mutex_unlock(&adma->mutex); + + if (adma->current_bandwidth < 0) { + pr_err("%s: ADMA ISO BW can't be less than zero\n", __func__); + adma->current_bandwidth = 0; + } else if (adma->current_bandwidth > MAX_BW) { + pr_err("%s: ADMA ISO BW can't be more than %d\n", __func__, + MAX_BW); + adma->current_bandwidth = MAX_BW; + } + + ret = adma_isomgr_request(adma->current_bandwidth, 1000); + if (!ret) { + /* Call LA/PTSA driver which will configure the Memory + controller to support APEDMA's new BW requirement in MBps*/ + ret = tegra_set_latency_allowance(TEGRA_LA_APEDMAW, + ((adma->current_bandwidth + 999)/1000)); + if (ret) + pr_err("%s: LA/PTSA setting Failed\n", __func__); + } +} +EXPORT_SYMBOL(tegra_isomgr_adma_setbw); + +void tegra_isomgr_adma_renegotiate(void *p, u32 avail_bw) +{ + /* For Audio usecase there is no possibility of renegotiation + as it may lead to glitches. So currently dummy renegotiate call + is added to support bandwidth request more than registered bw which + got initialized during register call */ +} +EXPORT_SYMBOL(tegra_isomgr_adma_renegotiate); + +void tegra_isomgr_adma_register(void) +{ + adma = kzalloc(sizeof(struct adma_isomgr), GFP_KERNEL); + if (!adma) { + pr_err("%s: Failed to allocate adma isomgr struct\n", __func__); + return; + } + + adma->current_bandwidth = 0; + memset(&adma->device_number, 0, sizeof(bool) * MAX_DEV_NUM); + memset(&adma->bw_per_device, 0, sizeof(int) * MAX_DEV_NUM); + + mutex_init(&adma->mutex); + + /* Register the required BW for adma usecases.*/ + adma->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_APE_ADMA, + tegra_adma_calc_min_bandwidth(), + tegra_isomgr_adma_renegotiate, + adma); + if (IS_ERR(adma->isomgr_handle)) { + pr_err("%s: Failed to register adma isomgr client. err=%ld\n", + __func__, PTR_ERR(adma->isomgr_handle)); + adma->isomgr_handle = NULL; + mutex_destroy(&adma->mutex); + kfree(adma); + adma = NULL; + } +} +EXPORT_SYMBOL(tegra_isomgr_adma_register); +void tegra_isomgr_adma_unregister(void) +{ + if (!adma) + return; + + mutex_destroy(&adma->mutex); + + if (adma->isomgr_handle) { + tegra_isomgr_unregister(adma->isomgr_handle); + adma->isomgr_handle = NULL; + } + + kfree(adma); + adma = NULL; +} +EXPORT_SYMBOL(tegra_isomgr_adma_unregister); +#endif + +MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra-alt/utils/tegra_pcm_alt.c b/sound/soc/tegra-alt/utils/tegra_pcm_alt.c new file mode 100644 index 00000000..2b4f8593 --- /dev/null +++ b/sound/soc/tegra-alt/utils/tegra_pcm_alt.c @@ -0,0 +1,319 @@ +/* + * tegra_alt_pcm.c - Tegra PCM driver + * + * Author: Stephen Warren + * Copyright (c) 2011-2017 NVIDIA CORPORATION. All rights reserved. + * + * Based on code copyright/by: + * + * Copyright (c) 2009-2010, NVIDIA Corporation. + * Scott Peterson + * Vijay Mali + * + * Copyright (C) 2010 Google, Inc. + * Iliyan Malchev + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ +#include +#include +#include +#include +#include +#include + +#include "tegra_pcm_alt.h" + +static const struct snd_pcm_hardware tegra_alt_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_INTERLEAVED, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S32_LE, + .period_bytes_min = 128, + .period_bytes_max = PAGE_SIZE * 4, + .periods_min = 1, + .periods_max = 8, + .buffer_bytes_max = PAGE_SIZE * 8, + .fifo_size = 4, +}; + +static int tegra_alt_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct device *dev = rtd->platform->dev; + struct tegra_alt_pcm_dma_params *dmap; + int ret; + + if (rtd->dai_link->no_pcm) + return 0; + + dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + + /* Set HW params now that initialization is complete */ + snd_soc_set_runtime_hwparams(substream, &tegra_alt_pcm_hardware); + + /* Update buffer size from device tree */ + if (dmap->buffer_size > substream->runtime->hw.buffer_bytes_max) + substream->runtime->hw.buffer_bytes_max = dmap->buffer_size; + + /* Ensure period size is multiple of 8 */ + ret = snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 0x8); + if (ret) { + dev_err(dev, "failed to set constraint %d\n", ret); + return ret; + } + + ret = snd_dmaengine_pcm_open(substream, + dma_request_slave_channel(dev, dmap->chan_name)); + if (ret) { + dev_err(dev, "dmaengine pcm open failed with err %d\n", ret); + return ret; + } + + return 0; +} + +static int tegra_alt_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + if (rtd->dai_link->no_pcm) + return 0; + + snd_dmaengine_pcm_close_release_chan(substream); + + return 0; +} + +static int tegra_alt_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct device *dev = rtd->platform->dev; + struct dma_chan *chan; + struct tegra_alt_pcm_dma_params *dmap; + struct dma_slave_config slave_config; + int ret; + + if (rtd->dai_link->no_pcm) + return 0; + + dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + if (!dmap) + return 0; + + chan = snd_dmaengine_pcm_get_chan(substream); + + ret = snd_hwparams_to_dma_slave_config(substream, params, + &slave_config); + if (ret) { + dev_err(dev, "hw params config failed with err %d\n", ret); + return ret; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + slave_config.dst_addr = dmap->addr; + slave_config.dst_maxburst = 8; + } else { + slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + slave_config.src_addr = dmap->addr; + slave_config.src_maxburst = 8; + } + slave_config.slave_id = dmap->req_sel; + + ret = dmaengine_slave_config(chan, &slave_config); + if (ret < 0) { + dev_err(dev, "dma slave config failed with err %d\n", ret); + return ret; + } + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + return 0; +} + +static int tegra_alt_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + if (rtd->dai_link->no_pcm) + return 0; + + snd_pcm_set_runtime_buffer(substream, NULL); + return 0; +} + +static int tegra_alt_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + + if (rtd->dai_link->no_pcm) + return 0; + + return dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); +} + +static struct snd_pcm_ops tegra_alt_pcm_ops = { + .open = tegra_alt_pcm_open, + .close = tegra_alt_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = tegra_alt_pcm_hw_params, + .hw_free = tegra_alt_pcm_hw_free, + .trigger = snd_dmaengine_pcm_trigger, + .pointer = snd_dmaengine_pcm_pointer, + .mmap = tegra_alt_pcm_mmap, +}; + +static int tegra_alt_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, + int stream , size_t size) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *buf = &substream->dma_buffer; + buf->area = dma_alloc_writecombine(pcm->card->dev, size, + &buf->addr, GFP_KERNEL); + if (!buf->area) + return -ENOMEM; + buf->private_data = NULL; + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = pcm->card->dev; + buf->bytes = size; + + return 0; +} + +static void tegra_alt_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + + substream = pcm->streams[stream].substream; + if (!substream) + return; + + buf = &substream->dma_buffer; + if (!buf->area) + return; + + dma_free_writecombine(pcm->card->dev, buf->bytes, + buf->area, buf->addr); + buf->area = NULL; +} + +#if defined(CONFIG_ARCH_TEGRA_APE) +static u64 tegra_dma_mask = DMA_BIT_MASK(64); +#else +static u64 tegra_dma_mask = DMA_BIT_MASK(32); +#endif + +static int tegra_alt_pcm_dma_allocate(struct snd_soc_pcm_runtime *rtd, + size_t size) +{ + struct snd_card *card = rtd->card->snd_card; + struct snd_pcm *pcm = rtd->pcm; + struct tegra_alt_pcm_dma_params *dmap; + size_t buffer_size = size; + int ret = 0; + + if (!card->dev->dma_mask) + card->dev->dma_mask = &tegra_dma_mask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = tegra_dma_mask; + + dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, + pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream); + if (dmap->buffer_size > size) + buffer_size = dmap->buffer_size; + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { + ret = tegra_alt_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK, + buffer_size); + if (ret) + goto err; + } + + dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, + pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); + if (dmap->buffer_size > size) + buffer_size = dmap->buffer_size; + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { + ret = tegra_alt_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE, + buffer_size); + if (ret) + goto err_free_play; + } + + return 0; + +err_free_play: + tegra_alt_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); +err: + return ret; +} + +static int tegra_alt_pcm_new(struct snd_soc_pcm_runtime *rtd) +{ + return tegra_alt_pcm_dma_allocate(rtd, + tegra_alt_pcm_hardware.buffer_bytes_max); +} + +static void tegra_alt_pcm_free(struct snd_pcm *pcm) +{ + tegra_alt_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); + tegra_alt_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); +} + +static int tegra_alt_pcm_probe(struct snd_soc_platform *platform) +{ + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(&platform->component); + dapm->idle_bias_off = 1; + return 0; +} + +static struct snd_soc_platform_driver tegra_alt_pcm_platform = { + .ops = &tegra_alt_pcm_ops, + .pcm_new = tegra_alt_pcm_new, + .pcm_free = tegra_alt_pcm_free, + .probe = tegra_alt_pcm_probe, +}; + +int tegra_alt_pcm_platform_register(struct device *dev) +{ + return snd_soc_register_platform(dev, &tegra_alt_pcm_platform); +} +EXPORT_SYMBOL_GPL(tegra_alt_pcm_platform_register); + +void tegra_alt_pcm_platform_unregister(struct device *dev) +{ + snd_soc_unregister_platform(dev); +} +EXPORT_SYMBOL_GPL(tegra_alt_pcm_platform_unregister); + +MODULE_AUTHOR("Stephen Warren "); +MODULE_DESCRIPTION("Tegra Alt PCM ASoC driver"); +MODULE_LICENSE("GPL");