diff --git a/lichee/linux-4.9/drivers/misc/Kconfig b/lichee/linux-4.9/drivers/misc/Kconfig index 6e5ba7fa2..6418a30e9 100644 --- a/lichee/linux-4.9/drivers/misc/Kconfig +++ b/lichee/linux-4.9/drivers/misc/Kconfig @@ -4,6 +4,29 @@ menu "Misc devices" +config ADAU1761 + tristate "ADI ADAU1761 DSP" + default n + ---help--- + ADI ADAU1761 DSP. + +config ADAU1761_ES1 + tristate "ADI ADAU1761 DSP FOR ES1" + default n + ---help--- + ADI ADAU1761 DSP FOR ES1. + +config ADAU1761_ES2 + tristate "ADI ADAU1761 DSP FOR ES2" + default n + ---help--- + ADI ADAU1761 DSP FOR ES2. + +config ADAU1761_R311_PV1 + tristate "ADI ADAU1761 DSP FOR R311 PV1" + default n + ---help--- + ADI ADAU1761 DSP FOR R311 PV1. config SENSORS_LIS3LV02D tristate depends on INPUT @@ -800,4 +823,5 @@ source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" source "drivers/misc/cxl/Kconfig" source "drivers/misc/sunxi-rf/Kconfig" +source "drivers/misc/xunfei/Kconfig" endmenu diff --git a/lichee/linux-4.9/drivers/misc/Makefile b/lichee/linux-4.9/drivers/misc/Makefile index b29d0a81c..92eb1c4c5 100644 --- a/lichee/linux-4.9/drivers/misc/Makefile +++ b/lichee/linux-4.9/drivers/misc/Makefile @@ -73,3 +73,8 @@ $(obj)/lkdtm_rodata_objcopy.o: $(obj)/lkdtm_rodata.o FORCE $(call if_changed,objcopy) obj-$(CONFIG_SUNXI_RFKILL) += sunxi-rf/ +obj-$(CONFIG_ADAU1761) += adau1761.o +obj-$(CONFIG_ADAU1761_ES1) += adau1761-es1.o +obj-$(CONFIG_ADAU1761_ES2) += adau1761-es2.o +obj-$(CONFIG_ADAU1761_R311_PV1) += adau1761-r311-pv1.o +obj-y += xunfei/ \ No newline at end of file diff --git a/lichee/linux-4.9/drivers/misc/adau1761-r311-pv1.c b/lichee/linux-4.9/drivers/misc/adau1761-r311-pv1.c new file mode 100755 index 000000000..e26da4bb6 --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/adau1761-r311-pv1.c @@ -0,0 +1,1988 @@ +/* + * Driver for ADAU1761 codec + * +* Copyright: (C) 2017 NetEase(Hangzhou) Network Co., Ltd. + * All rights reserved. + + * + * Licensed under the GPL-2 or later. + */ +#define DEBUG + +#ifdef DEBUG +#define DSP_DEBUG(...) \ + do { \ + printk("[ADAU1761]: "__VA_ARGS__); \ + } while (0) +#else +#define DSP_DEBUG(...) +#endif + +#include +#include +#include +#include /* guess what */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For put_user and get_user */ +#include + +#define SIGMA_MAGIC "ADISIGM" +#define ADAU1761_FIRMWARE "adau1761.bin" + +struct sigma_firmware_header { + unsigned char magic[7]; + u8 version; + __le32 crc; +} __packed; + +struct sigma_samprate_list { + __le32 samplist_len; + __le32 samplist_ind; + __le32 zeros; + __le32 sample_rate; +} __packed; + +enum { + SIGMA_ACTION_WRITEXBYTES = 0, + SIGMA_ACTION_CONTROL, + SIGMA_ACTION_END, +}; + +struct sigma_action { + __le32 len; // data chunk length + __le32 ind; // data to load, or control address? + __le32 mask; // do not care +} __packed; + +struct sigma_firmware { + const struct firmware *fw; + size_t pos; + void *control_data; +}; + +#define ADAU1761_DIGMIC_JACKDETECT 0x4008 +#define ADAU1761_REC_MIXER_LEFT0 0x400A +#define ADAU1761_REC_MIXER_LEFT1 0x400B +#define ADAU1761_REC_MIXER_RIGHT0 0x400C +#define ADAU1761_REC_MIXER_RIGHT1 0x400D +#define ADAU1761_LEFT_DIFF_INPUT_VOL 0x400E +#define ADAU1761_RIGHT_DIFF_INPUT_VOL 0x400F +#define ADAU1761_PLAY_LR_MIXER_LEFT 0x4020 +#define ADAU1761_PLAY_MIXER_LEFT0 0x401C +#define ADAU1761_PLAY_MIXER_LEFT1 0x401D +#define ADAU1761_PLAY_MIXER_RIGHT0 0x401E +#define ADAU1761_PLAY_MIXER_RIGHT1 0x401F +#define ADAU1761_PLAY_LR_MIXER_RIGHT 0x4021 +#define ADAU1761_PLAY_MIXER_MONO 0x4022 +#define ADAU1761_PLAY_HP_LEFT_VOL 0x4023 +#define ADAU1761_PLAY_HP_RIGHT_VOL 0x4024 +#define ADAU1761_PLAY_LINE_LEFT_VOL 0x4025 +#define ADAU1761_PLAY_LINE_RIGHT_VOL 0x4026 +#define ADAU1761_PLAY_MONO_OUTPUT_VOL 0x4027 +#define ADAU1761_POP_CLICK_SUPPRESS 0x4028 +#define ADAU1761_JACK_DETECT_PIN 0x4031 +#define ADAU1761_DEJITTER 0x4036 +#define ADAU1761_CLK_ENABLE0 0x40F9 +#define ADAU1761_CLK_ENABLE1 0x40FA + +/* 17x1 common registers */ +#define ADAU17X1_CLOCK_CONTROL 0x4000 +#define ADAU17X1_PLL_CONTROL 0x4002 +#define ADAU17X1_REC_POWER_MGMT 0x4009 +#define ADAU17X1_MICBIAS 0x4010 +#define ADAU17X1_SERIAL_PORT0 0x4015 +#define ADAU17X1_SERIAL_PORT1 0x4016 +#define ADAU17X1_CONVERTER0 0x4017 +#define ADAU17X1_CONVERTER1 0x4018 +#define ADAU17X1_LEFT_INPUT_DIGITAL_VOL 0x401A +#define ADAU17X1_RIGHT_INPUT_DIGITAL_VOL 0x401B +#define ADAU17X1_ADC_CONTROL 0x4019 +#define ADAU17X1_PLAY_POWER_MGMT 0x4029 +#define ADAU17X1_DAC_CONTROL0 0x402A +#define ADAU17X1_DAC_CONTROL1 0x402B +#define ADAU17X1_DAC_CONTROL2 0x402C +#define ADAU17X1_SERIAL_PORT_PAD 0x402D +#define ADAU17X1_CONTROL_PORT_PAD0 0x402F +#define ADAU17X1_CONTROL_PORT_PAD1 0x4030 +#define ADAU17X1_DSP_SAMPLING_RATE 0x40EB +#define ADAU17X1_SERIAL_INPUT_ROUTE 0x40F2 +#define ADAU17X1_SERIAL_OUTPUT_ROUTE 0x40F3 +#define ADAU17X1_DSP_ENABLE 0x40F5 +#define ADAU17X1_DSP_RUN 0x40F6 +#define ADAU17X1_SERIAL_SAMPLING_RATE 0x40F8 + +#define ADAU17X1_SERIAL_PORT0_BCLK_POL BIT(4) +#define ADAU17X1_SERIAL_PORT0_LRCLK_POL BIT(3) +#define ADAU17X1_SERIAL_PORT0_MASTER BIT(0) + +#define ADAU17X1_SERIAL_PORT1_DELAY1 0x00 +#define ADAU17X1_SERIAL_PORT1_DELAY0 0x01 +#define ADAU17X1_SERIAL_PORT1_DELAY8 0x02 +#define ADAU17X1_SERIAL_PORT1_DELAY16 0x03 +#define ADAU17X1_SERIAL_PORT1_DELAY_MASK 0x03 + +#define ADAU17X1_CLOCK_CONTROL_INFREQ_MASK 0x6 +#define ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL BIT(3) +#define ADAU17X1_CLOCK_CONTROL_SYSCLK_EN BIT(0) + +#define ADAU17X1_SERIAL_PORT1_BCLK64 (0x0 << 5) +#define ADAU17X1_SERIAL_PORT1_BCLK32 (0x1 << 5) +#define ADAU17X1_SERIAL_PORT1_BCLK48 (0x2 << 5) +#define ADAU17X1_SERIAL_PORT1_BCLK128 (0x3 << 5) +#define ADAU17X1_SERIAL_PORT1_BCLK256 (0x4 << 5) +#define ADAU17X1_SERIAL_PORT1_BCLK_MASK (0x7 << 5) + +#define ADAU17X1_SERIAL_PORT0_STEREO (0x0 << 1) +#define ADAU17X1_SERIAL_PORT0_TDM4 (0x1 << 1) +#define ADAU17X1_SERIAL_PORT0_TDM8 (0x2 << 1) +#define ADAU17X1_SERIAL_PORT0_TDM_MASK (0x3 << 1) +#define ADAU17X1_SERIAL_PORT0_PULSE_MODE BIT(5) + +#define ADAU17X1_CONVERTER0_DAC_PAIR(x) (((x)-1) << 5) +#define ADAU17X1_CONVERTER0_DAC_PAIR_MASK (0x3 << 5) +#define ADAU17X1_CONVERTER1_ADC_PAIR(x) ((x)-1) +#define ADAU17X1_CONVERTER1_ADC_PAIR_MASK 0x3 + +#define ADAU17X1_CONVERTER0_CONVSR_MASK 0x7 + +#define ADAU1761_DATA_PARAM_START_ADDR (0x0000) +#define ADAU1761_DATA_PARAM_END_ADDR (0x03FF) +#define ADAU1761_DATA_PARAM_WORD_LEN (4) + +#define ADAU1761_PROG_PARAM_START_ADDR (0x0800) +#define ADAU1761_PROG_PARAM_END_ADDR (0x0BFF) +#define ADAU1761_PROG_PARAM_WORD_LEN (5) + +#define ADAU1761_DEF_VOL_STEP (20) +#define VOL_CTL_ADDR (0x0009) +#define SRC_SW_ADDR (0x0008) + +/* safeload registers */ +#define SAFE_LOAD_DATA_1_REG (0x0001) +#define SAFE_LOAD_TARGET_ADDR_REG (0x0006) +#define SAFE_LOAD_WORD_NUM_REG (0x0007) +#define SAFE_LOAD_REG_NUM (SAFE_LOAD_WORD_NUM_REG - SAFE_LOAD_DATA_1_REG + 1) +#define SAFE_LOAD_WORD_NUM_MAX (5) +#define ADAU1761_DATA_COUNT (4) +#define SAFE_LOAD_EQ_SWITCH_REG (0x0047) + +const unsigned char adau1761_init_arr_00[] = { + 0x40, 0xEB, /* (0) IC 1.Sample Rate Setting */ + 0x7F}; + +const unsigned char adau1761_init_arr_01[] = { + 0x40, + 0xF6, /* (1) IC 1.DSP Run Register */ + 0x00, +}; + +const unsigned char adau1761_init_arr_02[] = { + 0x40, + 0x00, /* (2) IC 1.Clock Control Register */ + 0x0F, +}; + +const unsigned char adau1761_init_arr_03[] = { + 0x40, 0x02, /* (3) IC 1.PLL Control Register */ + 0x00, 0x7D, 0x00, 0x0C, 0x23, 0x01, +}; + +const unsigned char adau1761_init_arr_04[] = { + // 0x00, 0x00, /* (4) IC 1.Delay */ + // 0x00, 0x64, +}; + +const unsigned char adau1761_init_arr_05[] = { + 0x40, + 0x15, /* (5) IC 1.Serial Port Control Registers */ + 0x00, + 0x00, +}; + +const unsigned char adau1761_init_arr_06[] = { + 0x40, 0x11, /* (6) IC 1.ALC Control Registers */ + 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_07[] = { + 0x40, + 0x08, /* (7) IC 1.Microphone Control Register */ + 0x00, +}; + +const unsigned char adau1761_init_arr_08[] = { + 0x40, 0x09, /* (8) IC 1.Record Input Signal Path Registers */ + 0x00, 0x01, 0x08, 0x01, 0x08, 0x33, 0x33, 0x00, +}; + +const unsigned char adau1761_init_arr_09[] = { + 0x40, 0x19, /* (9) IC 1.ADC Control Registers */ + 0x13, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_10[] = { + 0x40, 0x1C, /* (10) IC 1.Playback Output Signal Path Registers */ + 0x21, 0x00, 0x41, 0x00, 0x03, 0x09, 0x00, + 0xE5, 0xE5, 0xE6, 0xE6, 0xE5, 0x00, 0x03, +}; + +const unsigned char adau1761_init_arr_11[] = { + 0x40, + 0x17, /* (11) IC 1.Converter Control Registers */ + 0x00, + 0x00, +}; + +const unsigned char adau1761_init_arr_12[] = { + 0x40, 0x2A, /* (12) IC 1.DAC Control Registers */ + 0x03, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_13[] = { + 0x40, + 0x2D, /* (13) IC 1.Serial Port Pad Control Registers */ + 0xAA, +}; + +const unsigned char adau1761_init_arr_14[] = { + 0x40, + 0x2F, /* (14) IC 1.Communication Port Pad Control Registers */ + 0xAA, + 0x00, +}; + +const unsigned char adau1761_init_arr_15[] = { + 0x40, + 0x31, /* (15) IC 1.Jack Detect Pad Control Register */ + 0x08, +}; + +const unsigned char adau1761_init_arr_16[] = { + 0x08, 0x00, /* (16) Program Clear Block 0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_17[] = { + 0x08, 0xCC, /* (17) Program Clear Block 1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_18[] = { + 0x09, 0x98, /* (18) Program Clear Block 2 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_19[] = { + 0x0A, 0x64, /* (19) Program Clear Block 3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_20[] = { + 0x0B, 0xFC, /* (20) Program Clear Block 4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_21[] = { + 0x40, + 0xF5, /* (21) IC 1.DSP ON Register */ + 0x01, +}; + +const unsigned char adau1761_init_arr_22[] = { + 0x40, 0xC0, /* (22) IC 1.CRC Registers */ + 0x7F, 0x7F, 0x7F, 0x7F, 0x01, +}; + +const unsigned char adau1761_init_arr_23[] = { + 0x40, 0xC6, /* (23) IC 1.GPIO Registers */ + 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_24[] = { + 0x40, + 0xE9, /* (24) IC 1.Non Modulo Registers */ + 0x0F, + 0xFC, +}; + +const unsigned char adau1761_init_arr_25[] = { + 0x40, 0xD0, /* (25) IC 1.Watchdog Registers */ + 0x00, 0x04, 0x00, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_26[] = { + 0x40, + 0xEB, /* (26) IC 1.Sampling Rate Setting Register */ + 0x7F, +}; + +const unsigned char adau1761_init_arr_27[] = { + 0x40, + 0xF2, /* (27) IC 1.Routing Matrix Inputs Register */ + 0x00, +}; + +const unsigned char adau1761_init_arr_28[] = { + 0x40, + 0xF3, /* (28) IC 1.Routing Matrix Outputs Register */ + 0x00, +}; + +const unsigned char adau1761_init_arr_29[] = { + 0x40, + 0xF4, /* (29) IC 1.Serial Data Configuration Register */ + 0x00, +}; + +const unsigned char adau1761_init_arr_30[] = { + 0x40, + 0xF7, /* (30) IC 1.DSP Slew Mode Register */ + 0x00, +}; + +const unsigned char adau1761_init_arr_31[] = { + 0x40, + 0xF8, /* (31) IC 1.Serial Port Sample Rate Register */ + 0x00, +}; + +const unsigned char adau1761_init_arr_32[] = { + 0x40, + 0xF9, /* (32) IC 1.Clock Enable Registers */ + 0x7F, + 0x03, +}; + +const unsigned char adau1761_init_arr_33[] = { + 0x08, 0x00, /* (33) Program Data */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0x34, + 0x00, 0x00, 0x00, 0xFF, 0x2C, 0x00, 0x00, 0x00, 0xFF, 0x54, 0x00, 0x00, + 0x00, 0xFF, 0x5C, 0x00, 0x00, 0x00, 0xFF, 0xF5, 0x08, 0x20, 0x00, 0xFF, + 0x38, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xE8, 0x0C, 0x00, 0x00, + 0xFE, 0x30, 0x00, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xE8, 0x07, 0x20, 0x08, 0x00, 0x00, 0x06, 0xA0, 0x00, 0xFF, 0xE0, 0x00, + 0xC0, 0x00, 0xFF, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0x22, 0x00, 0x27, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFE, 0xE8, 0x1E, 0x00, 0x00, 0xFF, 0xE8, 0x01, 0x20, + 0x00, 0xFF, 0xD8, 0x01, 0x03, 0x00, 0x00, 0x07, 0xC6, 0x00, 0x00, 0xFF, + 0x08, 0x00, 0x00, 0x00, 0xFF, 0xF4, 0x00, 0x20, 0x00, 0xFF, 0xD8, 0x07, + 0x02, 0x00, 0xFD, 0xA5, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x00, + 0xFD, 0xAD, 0x08, 0x20, 0x00, 0x00, 0x08, 0x00, 0xE2, 0x00, 0xFD, 0x25, + 0x08, 0x20, 0x00, 0x00, 0x10, 0x00, 0xE2, 0x00, 0xFD, 0x2D, 0x08, 0x20, + 0x00, 0x00, 0x18, 0x00, 0xE2, 0x00, 0xFF, 0xE8, 0x08, 0x20, 0x00, 0x00, + 0x58, 0x00, 0xE2, 0x00, 0x00, 0x05, 0x08, 0x20, 0x00, 0x00, 0x30, 0x00, + 0xE2, 0x00, 0x00, 0x0D, 0x08, 0x20, 0x00, 0x00, 0x40, 0x00, 0xE2, 0x00, + 0x00, 0x15, 0x08, 0x20, 0x00, 0x00, 0x38, 0x00, 0xE2, 0x00, 0x00, 0x1D, + 0x08, 0x20, 0x00, 0x00, 0x48, 0x00, 0xE2, 0x00, 0xFF, 0xF5, 0x08, 0x20, + 0x00, 0x00, 0xB0, 0x00, 0xE2, 0x00, 0x00, 0x55, 0x08, 0x20, 0x00, 0x00, + 0x5D, 0x08, 0x22, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xED, 0x08, + 0x20, 0x26, 0x00, 0xB0, 0x00, 0xE2, 0x00, 0x00, 0x75, 0x08, 0x20, 0x00, + 0xFF, 0xED, 0x13, 0x22, 0x48, 0x00, 0x55, 0x08, 0x20, 0x00, 0x00, 0x95, + 0x08, 0x20, 0x25, 0x00, 0x98, 0x00, 0xE2, 0x00, 0x00, 0x85, 0x08, 0x20, + 0x00, 0xFF, 0xED, 0x13, 0x22, 0x48, 0x00, 0x55, 0x08, 0x20, 0x00, 0x00, + 0xA5, 0x08, 0x20, 0x25, 0x00, 0xA8, 0x00, 0xE2, 0x00, 0x00, 0xBD, 0x08, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0xF0, 0x00, + 0x00, 0xCD, 0x08, 0x20, 0x00, 0xFF, 0xED, 0x13, 0x22, 0x48, 0x00, 0xB5, + 0x08, 0x20, 0x00, 0xFF, 0xF5, 0x08, 0x20, 0x25, 0x00, 0xB0, 0x00, 0xE2, + 0x00, 0x00, 0x55, 0x08, 0x20, 0x00, 0x00, 0x58, 0x00, 0xE2, 0x25, 0x00, + 0x65, 0x08, 0x20, 0x00, 0x00, 0x75, 0x08, 0x22, 0x40, 0x00, 0xC0, 0x00, + 0xE2, 0x00, 0x00, 0x75, 0x08, 0x20, 0x00, 0x00, 0xC5, 0x14, 0x22, 0x00, + 0x00, 0x78, 0x00, 0xE2, 0x00, 0x00, 0x98, 0x00, 0xC0, 0x00, 0x00, 0x07, + 0xFF, 0xA0, 0x00, 0x00, 0x78, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x37, 0xFF, 0x20, 0x80, 0x00, 0x20, 0x00, 0xE2, 0x00, 0x00, + 0x47, 0xFF, 0x40, 0x80, 0x00, 0x28, 0x00, 0xE4, 0x00, 0xFF, 0xED, 0x08, + 0x20, 0x00, 0xFF, 0xEF, 0xFF, 0x22, 0x40, 0x00, 0x88, 0x00, 0xE2, 0x00, + 0x00, 0xA8, 0x00, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xA0, 0x00, 0x00, 0x88, + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xFF, 0x20, + 0x80, 0x00, 0x25, 0x08, 0x22, 0x00, 0x00, 0x20, 0x00, 0xE2, 0x00, 0x00, + 0x47, 0xFF, 0x40, 0x80, 0x00, 0x2D, 0x08, 0x44, 0x00, 0x00, 0x28, 0x00, + 0xE4, 0x00, 0x00, 0x65, 0x08, 0x20, 0x00, 0x00, 0xB5, 0x08, 0x22, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xE8, 0x09, 0x20, 0x00, 0x00, 0xD5, 0x08, 0x22, + 0x40, 0x00, 0xF0, 0x00, 0xE2, 0x00, 0x00, 0xE5, 0x08, 0x20, 0x00, 0x00, + 0xD5, 0x08, 0x34, 0x00, 0x00, 0xF0, 0x0A, 0x22, 0x00, 0x00, 0xD8, 0x00, + 0xE2, 0x00, 0x00, 0xD8, 0x00, 0xC0, 0x00, 0x00, 0xE8, 0x00, 0xF2, 0x00, + 0x00, 0x27, 0xFF, 0x20, 0x00, 0x01, 0x08, 0x00, 0xE2, 0x00, 0x00, 0x2F, + 0xFF, 0x20, 0x00, 0x01, 0x50, 0x00, 0xE2, 0x00, 0x01, 0x18, 0x0E, 0x20, + 0x00, 0x01, 0x10, 0x0F, 0x22, 0x00, 0x01, 0x08, 0x0B, 0x22, 0x00, 0x01, + 0x00, 0x0C, 0x22, 0x00, 0x00, 0xF8, 0x0D, 0x22, 0x00, 0x01, 0x20, 0x00, + 0xE2, 0x00, 0x01, 0x30, 0x13, 0x20, 0x00, 0x01, 0x28, 0x14, 0x22, 0x00, + 0x01, 0x20, 0x10, 0x22, 0x00, 0x01, 0x18, 0x11, 0x22, 0x00, 0x01, 0x10, + 0x12, 0x22, 0x00, 0x01, 0x38, 0x00, 0xE2, 0x00, 0x01, 0x60, 0x0E, 0x20, + 0x00, 0x01, 0x58, 0x0F, 0x22, 0x00, 0x01, 0x50, 0x0B, 0x22, 0x00, 0x01, + 0x48, 0x0C, 0x22, 0x00, 0x01, 0x40, 0x0D, 0x22, 0x00, 0x01, 0x68, 0x00, + 0xE2, 0x00, 0x01, 0x78, 0x13, 0x20, 0x00, 0x01, 0x70, 0x14, 0x22, 0x00, + 0x01, 0x68, 0x10, 0x22, 0x00, 0x01, 0x60, 0x11, 0x22, 0x00, 0x01, 0x58, + 0x12, 0x22, 0x00, 0x01, 0x80, 0x00, 0xE2, 0x00, 0x01, 0x90, 0x18, 0x20, + 0x00, 0x01, 0x88, 0x19, 0x22, 0x00, 0x01, 0x38, 0x15, 0x22, 0x00, 0x01, + 0x30, 0x16, 0x22, 0x00, 0x01, 0x28, 0x17, 0x22, 0x00, 0x01, 0x98, 0x00, + 0xE2, 0x00, 0x01, 0xA8, 0x1D, 0x20, 0x00, 0x01, 0xA0, 0x1E, 0x22, 0x00, + 0x01, 0x98, 0x1A, 0x22, 0x00, 0x01, 0x90, 0x1B, 0x22, 0x00, 0x01, 0x88, + 0x1C, 0x22, 0x00, 0x01, 0xB0, 0x00, 0xE2, 0x00, 0x01, 0xC0, 0x22, 0x20, + 0x00, 0x01, 0xB8, 0x23, 0x22, 0x00, 0x01, 0xB0, 0x1F, 0x22, 0x00, 0x01, + 0xA8, 0x20, 0x22, 0x00, 0x01, 0xA0, 0x21, 0x22, 0x00, 0x01, 0xC8, 0x00, + 0xE2, 0x00, 0x01, 0xD8, 0x27, 0x20, 0x00, 0x01, 0xD0, 0x28, 0x22, 0x00, + 0x01, 0xC8, 0x24, 0x22, 0x00, 0x01, 0xC0, 0x25, 0x22, 0x00, 0x01, 0xB8, + 0x26, 0x22, 0x00, 0x01, 0xE0, 0x00, 0xE2, 0x00, 0x01, 0xF0, 0x2C, 0x20, + 0x00, 0x01, 0xE8, 0x2D, 0x22, 0x00, 0x01, 0xE0, 0x29, 0x22, 0x00, 0x01, + 0xD8, 0x2A, 0x22, 0x00, 0x01, 0xD0, 0x2B, 0x22, 0x00, 0x01, 0xF8, 0x00, + 0xE2, 0x00, 0x02, 0x08, 0x31, 0x20, 0x00, 0x02, 0x00, 0x32, 0x22, 0x00, + 0x01, 0xF8, 0x2E, 0x22, 0x00, 0x01, 0xF0, 0x2F, 0x22, 0x00, 0x01, 0xE8, + 0x30, 0x22, 0x00, 0x02, 0x10, 0x00, 0xE2, 0x00, 0x02, 0x20, 0x18, 0x20, + 0x00, 0x02, 0x18, 0x19, 0x22, 0x00, 0x01, 0x80, 0x15, 0x22, 0x00, 0x01, + 0x78, 0x16, 0x22, 0x00, 0x01, 0x70, 0x17, 0x22, 0x00, 0x02, 0x28, 0x00, + 0xE2, 0x00, 0x02, 0x38, 0x1D, 0x20, 0x00, 0x02, 0x30, 0x1E, 0x22, 0x00, + 0x02, 0x28, 0x1A, 0x22, 0x00, 0x02, 0x20, 0x1B, 0x22, 0x00, 0x02, 0x18, + 0x1C, 0x22, 0x00, 0x02, 0x40, 0x00, 0xE2, 0x00, 0x02, 0x50, 0x22, 0x20, + 0x00, 0x02, 0x48, 0x23, 0x22, 0x00, 0x02, 0x40, 0x1F, 0x22, 0x00, 0x02, + 0x38, 0x20, 0x22, 0x00, 0x02, 0x30, 0x21, 0x22, 0x00, 0x02, 0x58, 0x00, + 0xE2, 0x00, 0x02, 0x68, 0x27, 0x20, 0x00, 0x02, 0x60, 0x28, 0x22, 0x00, + 0x02, 0x58, 0x24, 0x22, 0x00, 0x02, 0x50, 0x25, 0x22, 0x00, 0x02, 0x48, + 0x26, 0x22, 0x00, 0x02, 0x70, 0x00, 0xE2, 0x00, 0x02, 0x80, 0x2C, 0x20, + 0x00, 0x02, 0x78, 0x2D, 0x22, 0x00, 0x02, 0x70, 0x29, 0x22, 0x00, 0x02, + 0x68, 0x2A, 0x22, 0x00, 0x02, 0x60, 0x2B, 0x22, 0x00, 0x02, 0x88, 0x00, + 0xE2, 0x00, 0x02, 0x98, 0x31, 0x20, 0x00, 0x02, 0x90, 0x32, 0x22, 0x00, + 0x02, 0x88, 0x2E, 0x22, 0x00, 0x02, 0x80, 0x2F, 0x22, 0x00, 0x02, 0x78, + 0x30, 0x22, 0x00, 0x02, 0xA0, 0x00, 0xE2, 0x00, 0x02, 0xB0, 0x36, 0x20, + 0x00, 0x02, 0xA8, 0x37, 0x22, 0x00, 0x01, 0x38, 0x33, 0x22, 0x00, 0x01, + 0x30, 0x34, 0x22, 0x00, 0x01, 0x28, 0x35, 0x22, 0x00, 0x02, 0xB8, 0x00, + 0xE2, 0x00, 0x02, 0xC8, 0x3B, 0x20, 0x00, 0x02, 0xC0, 0x3C, 0x22, 0x00, + 0x02, 0xB8, 0x38, 0x22, 0x00, 0x02, 0xB0, 0x39, 0x22, 0x00, 0x02, 0xA8, + 0x3A, 0x22, 0x00, 0x02, 0xD0, 0x00, 0xE2, 0x00, 0x02, 0xE0, 0x40, 0x20, + 0x00, 0x02, 0xD8, 0x41, 0x22, 0x00, 0x02, 0xD0, 0x3D, 0x22, 0x00, 0x02, + 0xC8, 0x3E, 0x22, 0x00, 0x02, 0xC0, 0x3F, 0x22, 0x00, 0x02, 0xE8, 0x00, + 0xE2, 0x00, 0x02, 0xF8, 0x45, 0x20, 0x00, 0x02, 0xF0, 0x46, 0x22, 0x00, + 0x02, 0xE8, 0x42, 0x22, 0x00, 0x02, 0xE0, 0x43, 0x22, 0x00, 0x02, 0xD8, + 0x44, 0x22, 0x00, 0x03, 0x00, 0x00, 0xE2, 0x00, 0x03, 0x10, 0x36, 0x20, + 0x00, 0x03, 0x08, 0x37, 0x22, 0x00, 0x01, 0x80, 0x33, 0x22, 0x00, 0x01, + 0x78, 0x34, 0x22, 0x00, 0x01, 0x70, 0x35, 0x22, 0x00, 0x03, 0x18, 0x00, + 0xE2, 0x00, 0x03, 0x28, 0x3B, 0x20, 0x00, 0x03, 0x20, 0x3C, 0x22, 0x00, + 0x03, 0x18, 0x38, 0x22, 0x00, 0x03, 0x10, 0x39, 0x22, 0x00, 0x03, 0x08, + 0x3A, 0x22, 0x00, 0x03, 0x30, 0x00, 0xE2, 0x00, 0x03, 0x40, 0x40, 0x20, + 0x00, 0x03, 0x38, 0x41, 0x22, 0x00, 0x03, 0x30, 0x3D, 0x22, 0x00, 0x03, + 0x28, 0x3E, 0x22, 0x00, 0x03, 0x20, 0x3F, 0x22, 0x00, 0x03, 0x48, 0x00, + 0xE2, 0x00, 0x03, 0x58, 0x45, 0x20, 0x00, 0x03, 0x50, 0x46, 0x22, 0x00, + 0x03, 0x48, 0x42, 0x22, 0x00, 0x03, 0x40, 0x43, 0x22, 0x00, 0x03, 0x38, + 0x44, 0x22, 0x00, 0x03, 0x60, 0x00, 0xE2, 0x00, 0xFF, 0xE8, 0x47, 0x20, + 0x00, 0x03, 0xB0, 0x00, 0xE2, 0x00, 0x01, 0x3D, 0x08, 0x20, 0x00, 0x03, + 0x78, 0x00, 0xE2, 0x00, 0x01, 0x85, 0x08, 0x20, 0x00, 0x03, 0x90, 0x00, + 0xE2, 0x00, 0x02, 0x15, 0x08, 0x20, 0x00, 0x03, 0x80, 0x00, 0xE2, 0x00, + 0x02, 0xA5, 0x08, 0x20, 0x00, 0x03, 0x98, 0x00, 0xE2, 0x00, 0x03, 0x05, + 0x08, 0x20, 0x00, 0x03, 0x88, 0x00, 0xE2, 0x00, 0x03, 0x65, 0x08, 0x20, + 0x00, 0x03, 0xA0, 0x00, 0xE2, 0x00, 0xFF, 0xF5, 0x08, 0x20, 0x00, 0x04, + 0x08, 0x00, 0xE2, 0x00, 0x03, 0xAD, 0x08, 0x20, 0x00, 0x03, 0xB5, 0x08, + 0x22, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xED, 0x08, 0x20, 0x26, + 0x04, 0x08, 0x00, 0xE2, 0x00, 0x03, 0xCD, 0x08, 0x20, 0x00, 0xFF, 0xED, + 0x13, 0x22, 0x48, 0x03, 0xAD, 0x08, 0x20, 0x00, 0x03, 0xED, 0x08, 0x20, + 0x25, 0x03, 0xF0, 0x00, 0xE2, 0x00, 0x03, 0xDD, 0x08, 0x20, 0x00, 0xFF, + 0xED, 0x13, 0x22, 0x48, 0x03, 0xAD, 0x08, 0x20, 0x00, 0x03, 0xFD, 0x08, + 0x20, 0x25, 0x04, 0x00, 0x00, 0xE2, 0x00, 0x04, 0x15, 0x08, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0xF0, 0x00, 0x04, 0x25, + 0x08, 0x20, 0x00, 0xFF, 0xED, 0x13, 0x22, 0x48, 0x04, 0x0D, 0x08, 0x20, + 0x00, 0xFF, 0xF5, 0x08, 0x20, 0x25, 0x04, 0x08, 0x00, 0xE2, 0x00, 0x03, + 0xAD, 0x08, 0x20, 0x00, 0x03, 0xB0, 0x00, 0xE2, 0x25, 0x03, 0xBD, 0x08, + 0x20, 0x00, 0x03, 0xCD, 0x08, 0x22, 0x40, 0x04, 0x18, 0x00, 0xE2, 0x00, + 0x03, 0xCD, 0x08, 0x20, 0x00, 0x04, 0x1D, 0x14, 0x22, 0x00, 0x03, 0xD0, + 0x00, 0xE2, 0x00, 0x03, 0xF0, 0x00, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xA0, + 0x00, 0x03, 0xD0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x7F, 0xFF, 0x20, 0x80, 0x03, 0x68, 0x00, 0xE2, 0x00, 0x03, 0x97, 0xFF, + 0x40, 0x80, 0x03, 0x70, 0x00, 0xE4, 0x00, 0xFF, 0xED, 0x08, 0x20, 0x00, + 0xFF, 0xEF, 0xFF, 0x22, 0x40, 0x03, 0xE0, 0x00, 0xE2, 0x00, 0x04, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xA0, 0x00, 0x03, 0xE0, 0x00, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x7F, 0xFF, 0x20, 0x80, 0x03, + 0x6D, 0x08, 0x22, 0x00, 0x03, 0x68, 0x00, 0xE2, 0x00, 0x03, 0x97, 0xFF, + 0x40, 0x80, 0x03, 0x75, 0x08, 0x44, 0x00, 0x03, 0x70, 0x00, 0xE4, 0x00, + 0x03, 0xBD, 0x08, 0x20, 0x00, 0x04, 0x0D, 0x08, 0x22, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x68, 0x48, 0x20, 0x00, 0x03, 0x70, 0x48, 0x22, 0x00, 0x04, + 0x38, 0x00, 0xE2, 0x00, 0x04, 0x60, 0x4C, 0x20, 0x00, 0x04, 0x58, 0x4D, + 0x22, 0x00, 0x04, 0x48, 0x4C, 0x34, 0x00, 0x04, 0x40, 0x4D, 0x22, 0x00, + 0x04, 0x38, 0x49, 0x22, 0x00, 0x04, 0x30, 0x4A, 0x22, 0x00, 0x04, 0x28, + 0x4B, 0x22, 0x00, 0x04, 0x50, 0x00, 0xE2, 0x00, 0x04, 0x68, 0x00, 0xF2, + 0x00, 0x04, 0x90, 0x51, 0x20, 0x00, 0x04, 0x88, 0x52, 0x22, 0x00, 0x04, + 0x78, 0x51, 0x34, 0x00, 0x04, 0x70, 0x52, 0x22, 0x00, 0x04, 0x50, 0x4E, + 0x22, 0x00, 0x04, 0x48, 0x4F, 0x22, 0x00, 0x04, 0x40, 0x50, 0x22, 0x00, + 0x04, 0x80, 0x00, 0xE2, 0x00, 0x04, 0x98, 0x00, 0xF2, 0x00, 0x04, 0x80, + 0x53, 0x20, 0x00, 0x04, 0xB0, 0x00, 0xE2, 0x00, 0x04, 0xD8, 0x56, 0x20, + 0x00, 0x04, 0xD0, 0x58, 0x22, 0x00, 0x04, 0xC0, 0x56, 0x34, 0x00, 0x04, + 0xB8, 0x58, 0x22, 0x00, 0x04, 0xB0, 0x54, 0x22, 0x00, 0x04, 0xA8, 0x55, + 0x22, 0x00, 0x04, 0xA0, 0x57, 0x22, 0x00, 0x04, 0xC8, 0x00, 0xE2, 0x00, + 0x04, 0xE0, 0x00, 0xF2, 0x00, 0x05, 0x08, 0x5B, 0x20, 0x00, 0x05, 0x00, + 0x5D, 0x22, 0x00, 0x04, 0xF0, 0x5B, 0x34, 0x00, 0x04, 0xE8, 0x5D, 0x22, + 0x00, 0x04, 0xC8, 0x59, 0x22, 0x00, 0x04, 0xC0, 0x5A, 0x22, 0x00, 0x04, + 0xB8, 0x5C, 0x22, 0x00, 0x04, 0xF8, 0x00, 0xE2, 0x00, 0x05, 0xA0, 0x00, + 0xE2, 0x00, 0x05, 0x10, 0x00, 0xF2, 0x00, 0x04, 0x85, 0x08, 0x20, 0x00, + 0x05, 0x28, 0x00, 0xE2, 0x00, 0x05, 0x50, 0x60, 0x20, 0x00, 0x05, 0x48, + 0x62, 0x22, 0x00, 0x05, 0x38, 0x60, 0x34, 0x00, 0x05, 0x30, 0x62, 0x22, + 0x00, 0x05, 0x28, 0x5E, 0x22, 0x00, 0x05, 0x20, 0x5F, 0x22, 0x00, 0x05, + 0x18, 0x61, 0x22, 0x00, 0x05, 0x40, 0x00, 0xE2, 0x00, 0x05, 0x58, 0x00, + 0xF2, 0x00, 0x05, 0x80, 0x65, 0x20, 0x00, 0x05, 0x78, 0x67, 0x22, 0x00, + 0x05, 0x68, 0x65, 0x34, 0x00, 0x05, 0x60, 0x67, 0x22, 0x00, 0x05, 0x40, + 0x63, 0x22, 0x00, 0x05, 0x38, 0x64, 0x22, 0x00, 0x05, 0x30, 0x66, 0x22, + 0x00, 0x05, 0x70, 0x00, 0xE2, 0x00, 0x06, 0x18, 0x00, 0xE2, 0x00, 0x05, + 0x88, 0x00, 0xF2, 0x00, 0x05, 0xC8, 0x6B, 0x20, 0x00, 0x05, 0xC0, 0x6C, + 0x22, 0x00, 0x05, 0xB0, 0x6B, 0x34, 0x00, 0x05, 0xA8, 0x6C, 0x22, 0x00, + 0x05, 0xA0, 0x68, 0x22, 0x00, 0x05, 0x98, 0x69, 0x22, 0x00, 0x05, 0x90, + 0x6A, 0x22, 0x00, 0x05, 0xB8, 0x00, 0xE2, 0x00, 0x05, 0xD0, 0x00, 0xF2, + 0x00, 0x05, 0xF8, 0x70, 0x20, 0x00, 0x05, 0xF0, 0x71, 0x22, 0x00, 0x05, + 0xE0, 0x70, 0x34, 0x00, 0x05, 0xD8, 0x71, 0x22, 0x00, 0x05, 0xB8, 0x6D, + 0x22, 0x00, 0x05, 0xB0, 0x6E, 0x22, 0x00, 0x05, 0xA8, 0x6F, 0x22, 0x00, + 0x05, 0xE8, 0x00, 0xE2, 0x00, 0x06, 0x00, 0x00, 0xF2, 0x00, 0x06, 0x40, + 0x75, 0x20, 0x00, 0x06, 0x38, 0x76, 0x22, 0x00, 0x06, 0x28, 0x75, 0x34, + 0x00, 0x06, 0x20, 0x76, 0x22, 0x00, 0x06, 0x18, 0x72, 0x22, 0x00, 0x06, + 0x10, 0x73, 0x22, 0x00, 0x06, 0x08, 0x74, 0x22, 0x00, 0x06, 0x30, 0x00, + 0xE2, 0x00, 0x06, 0x48, 0x00, 0xF2, 0x00, 0x06, 0x70, 0x7A, 0x20, 0x00, + 0x06, 0x68, 0x7B, 0x22, 0x00, 0x06, 0x58, 0x7A, 0x34, 0x00, 0x06, 0x50, + 0x7B, 0x22, 0x00, 0x06, 0x30, 0x77, 0x22, 0x00, 0x06, 0x28, 0x78, 0x22, + 0x00, 0x06, 0x20, 0x79, 0x22, 0x00, 0x06, 0x60, 0x00, 0xE2, 0x00, 0x06, + 0x78, 0x00, 0xF2, 0x00, 0x06, 0xA0, 0x7F, 0x20, 0x00, 0x06, 0x98, 0x80, + 0x22, 0x00, 0x06, 0x88, 0x7F, 0x34, 0x00, 0x06, 0x80, 0x80, 0x22, 0x00, + 0x06, 0x60, 0x7C, 0x22, 0x00, 0x06, 0x58, 0x7D, 0x22, 0x00, 0x06, 0x50, + 0x7E, 0x22, 0x00, 0x06, 0x90, 0x00, 0xE2, 0x00, 0x06, 0xA8, 0x00, 0xF2, + 0x00, 0x06, 0xD0, 0x84, 0x20, 0x00, 0x06, 0xC8, 0x85, 0x22, 0x00, 0x06, + 0xB8, 0x84, 0x34, 0x00, 0x06, 0xB0, 0x85, 0x22, 0x00, 0x06, 0x90, 0x81, + 0x22, 0x00, 0x06, 0x88, 0x82, 0x22, 0x00, 0x06, 0x80, 0x83, 0x22, 0x00, + 0x06, 0xC0, 0x00, 0xE2, 0x00, 0x06, 0xD8, 0x00, 0xF2, 0x00, 0x07, 0x00, + 0x89, 0x20, 0x00, 0x06, 0xF8, 0x8A, 0x22, 0x00, 0x06, 0xE8, 0x89, 0x34, + 0x00, 0x06, 0xE0, 0x8A, 0x22, 0x00, 0x06, 0xC0, 0x86, 0x22, 0x00, 0x06, + 0xB8, 0x87, 0x22, 0x00, 0x06, 0xB0, 0x88, 0x22, 0x00, 0x06, 0xF0, 0x00, + 0xE2, 0x00, 0x07, 0x08, 0x00, 0xF2, 0x00, 0x07, 0x30, 0x8E, 0x20, 0x00, + 0x07, 0x28, 0x8F, 0x22, 0x00, 0x07, 0x18, 0x8E, 0x34, 0x00, 0x07, 0x10, + 0x8F, 0x22, 0x00, 0x06, 0xF0, 0x8B, 0x22, 0x00, 0x06, 0xE8, 0x8C, 0x22, + 0x00, 0x06, 0xE0, 0x8D, 0x22, 0x00, 0x07, 0x20, 0x00, 0xE2, 0x00, 0x07, + 0x38, 0x00, 0xF2, 0x00, 0x7F, 0xE0, 0x92, 0x20, 0x00, 0x7F, 0xE0, 0x91, + 0x34, 0x00, 0x7F, 0xE8, 0x90, 0x22, 0x00, 0xFF, 0xD8, 0x91, 0x02, 0x00, + 0xFF, 0xD8, 0x92, 0x12, 0x00, 0x05, 0xE8, 0x91, 0x20, 0x00, 0x07, 0x40, + 0x00, 0xE2, 0x00, 0x7F, 0xF0, 0x95, 0x20, 0x00, 0x7F, 0xF0, 0x94, 0x34, + 0x00, 0x7F, 0xF8, 0x93, 0x22, 0x00, 0xFF, 0xD8, 0x94, 0x02, 0x00, 0xFF, + 0xD8, 0x95, 0x12, 0x00, 0x07, 0x20, 0x94, 0x20, 0x00, 0x07, 0x48, 0x00, + 0xE2, 0x00, 0xFF, 0xE8, 0xC1, 0x40, 0x00, 0x07, 0x40, 0x00, 0xC0, 0x00, + 0x07, 0x47, 0xFF, 0x20, 0x00, 0x07, 0xB0, 0x00, 0xE2, 0x00, 0x07, 0xB8, + 0x00, 0xF2, 0x00, 0x07, 0x45, 0x0C, 0x20, 0x00, 0x07, 0xD8, 0x00, 0xE2, + 0x00, 0x07, 0xD8, 0x00, 0xC0, 0x00, 0x07, 0xDF, 0xFF, 0x20, 0x00, 0x07, + 0xD8, 0x00, 0xE2, 0x00, 0x07, 0xE5, 0x08, 0x20, 0x00, 0x07, 0xE0, 0xBE, + 0x22, 0x40, 0x07, 0xD8, 0xBE, 0x22, 0x08, 0x07, 0xE8, 0x00, 0xE2, 0x00, + 0x07, 0x6D, 0x08, 0x20, 0x00, 0x07, 0x68, 0xBE, 0x22, 0x40, 0x07, 0xB8, + 0xBE, 0x22, 0x00, 0x07, 0x5D, 0x08, 0x34, 0x00, 0x07, 0x58, 0xBE, 0x22, + 0x40, 0x07, 0xB0, 0xBE, 0x22, 0x00, 0x07, 0x60, 0x00, 0xE2, 0x00, 0xFF, + 0xF5, 0x08, 0x42, 0x00, 0x07, 0x70, 0x00, 0xF2, 0x00, 0x07, 0xED, 0x08, + 0x20, 0x00, 0xFF, 0xF5, 0x08, 0x82, 0x00, 0xFF, 0xF5, 0x08, 0x84, 0x23, + 0xFF, 0xED, 0x0A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, + 0x00, 0xF6, 0x00, 0x07, 0xF5, 0x08, 0x22, 0x00, 0x07, 0xC0, 0x00, 0xE2, + 0x00, 0x07, 0xC0, 0x00, 0xF6, 0x23, 0x07, 0x8D, 0x08, 0x20, 0x08, 0x07, + 0x90, 0x00, 0xE2, 0x00, 0x07, 0x7D, 0x08, 0x20, 0x00, 0xFF, 0xE8, 0xC0, + 0x22, 0x67, 0x07, 0x80, 0x00, 0xE2, 0x00, 0x07, 0xC5, 0x08, 0x22, 0x48, + 0x07, 0xC5, 0x08, 0x20, 0x00, 0x07, 0x80, 0x00, 0xE2, 0x27, 0xFF, 0xE8, + 0xBF, 0x20, 0x00, 0x07, 0x90, 0x00, 0xE2, 0x27, 0x07, 0x95, 0x08, 0x20, + 0x08, 0xFF, 0xFD, 0x08, 0x22, 0x40, 0x07, 0x90, 0x00, 0xE2, 0x26, 0x07, + 0x85, 0x1A, 0x20, 0x00, 0x07, 0xC8, 0x00, 0xE2, 0x00, 0x07, 0xD0, 0x00, + 0xF2, 0x00, 0x07, 0xC8, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0xA1, 0x00, 0xFF, 0xE5, + 0x08, 0x20, 0x00, 0x00, 0x00, 0x96, 0xA1, 0x00, 0xFF, 0xE5, 0x08, 0x22, + 0x40, 0x07, 0x98, 0x00, 0xE2, 0x00, 0x07, 0xD0, 0x00, 0xC0, 0x00, 0x07, + 0x9F, 0xFF, 0x20, 0x00, 0xFF, 0xE5, 0x08, 0x22, 0x00, 0x07, 0xA8, 0x00, + 0xE2, 0x00, 0x07, 0xA8, 0x00, 0xC0, 0x00, 0x07, 0x47, 0xFF, 0x20, 0x00, + 0x07, 0x50, 0x00, 0xE2, 0x00, 0x07, 0x48, 0xC2, 0x20, 0x00, 0x07, 0xF8, + 0x00, 0xE2, 0x00, 0xFF, 0xE8, 0xEE, 0x40, 0x00, 0x07, 0x50, 0x00, 0xC0, + 0x00, 0x07, 0x57, 0xFF, 0x20, 0x00, 0x08, 0x60, 0x00, 0xE2, 0x00, 0x08, + 0x68, 0x00, 0xF2, 0x00, 0x07, 0x55, 0x0C, 0x20, 0x00, 0x08, 0x88, 0x00, + 0xE2, 0x00, 0x08, 0x88, 0x00, 0xC0, 0x00, 0x08, 0x8F, 0xFF, 0x20, 0x00, + 0x08, 0x88, 0x00, 0xE2, 0x00, 0x08, 0x95, 0x08, 0x20, 0x00, 0x08, 0x90, + 0xEB, 0x22, 0x40, 0x08, 0x88, 0xEB, 0x22, 0x08, 0x08, 0x98, 0x00, 0xE2, + 0x00, 0x08, 0x1D, 0x08, 0x20, 0x00, 0x08, 0x18, 0xEB, 0x22, 0x40, 0x08, + 0x68, 0xEB, 0x22, 0x00, 0x08, 0x0D, 0x08, 0x34, 0x00, 0x08, 0x08, 0xEB, + 0x22, 0x40, 0x08, 0x60, 0xEB, 0x22, 0x00, 0x08, 0x10, 0x00, 0xE2, 0x00, + 0xFF, 0xF5, 0x08, 0x42, 0x00, 0x08, 0x20, 0x00, 0xF2, 0x00, 0x08, 0x9D, + 0x08, 0x20, 0x00, 0xFF, 0xF5, 0x08, 0x82, 0x00, 0xFF, 0xF5, 0x08, 0x84, + 0x23, 0xFF, 0xED, 0x0A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0xA0, 0x00, 0xF6, 0x00, 0x08, 0xA5, 0x08, 0x22, 0x00, 0x08, 0x70, 0x00, + 0xE2, 0x00, 0x08, 0x70, 0x00, 0xF6, 0x23, 0x08, 0x3D, 0x08, 0x20, 0x08, + 0x08, 0x40, 0x00, 0xE2, 0x00, 0x08, 0x2D, 0x08, 0x20, 0x00, 0xFF, 0xE8, + 0xED, 0x22, 0x67, 0x08, 0x30, 0x00, 0xE2, 0x00, 0x08, 0x75, 0x08, 0x22, + 0x48, 0x08, 0x75, 0x08, 0x20, 0x00, 0x08, 0x30, 0x00, 0xE2, 0x27, 0xFF, + 0xE8, 0xEC, 0x20, 0x00, 0x08, 0x40, 0x00, 0xE2, 0x27, 0x08, 0x45, 0x08, + 0x20, 0x08, 0xFF, 0xFD, 0x08, 0x22, 0x40, 0x08, 0x40, 0x00, 0xE2, 0x26, + 0x08, 0x35, 0x1A, 0x20, 0x00, 0x08, 0x78, 0x00, 0xE2, 0x00, 0x08, 0x80, + 0x00, 0xF2, 0x00, 0x08, 0x78, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xA1, 0x00, 0xFF, + 0xE5, 0x08, 0x20, 0x00, 0x00, 0x00, 0xC3, 0xA1, 0x00, 0xFF, 0xE5, 0x08, + 0x22, 0x40, 0x08, 0x48, 0x00, 0xE2, 0x00, 0x08, 0x80, 0x00, 0xC0, 0x00, + 0x08, 0x4F, 0xFF, 0x20, 0x00, 0xFF, 0xE5, 0x08, 0x22, 0x00, 0x08, 0x58, + 0x00, 0xE2, 0x00, 0x08, 0x58, 0x00, 0xC0, 0x00, 0x07, 0x57, 0xFF, 0x20, + 0x00, 0x08, 0x00, 0x00, 0xE2, 0x00, 0xFF, 0xE9, 0x1A, 0x40, 0x00, 0x07, + 0xF8, 0x00, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0x20, 0x00, 0x09, 0x00, 0x00, + 0xE2, 0x00, 0x09, 0x08, 0x00, 0xF2, 0x00, 0x07, 0xFD, 0x0C, 0x20, 0x00, + 0x09, 0x28, 0x00, 0xE2, 0x00, 0x09, 0x28, 0x00, 0xC0, 0x00, 0x09, 0x2F, + 0xFF, 0x20, 0x00, 0x09, 0x28, 0x00, 0xE2, 0x00, 0x09, 0x35, 0x08, 0x20, + 0x00, 0x09, 0x31, 0x17, 0x22, 0x40, 0x09, 0x29, 0x17, 0x22, 0x08, 0x09, + 0x38, 0x00, 0xE2, 0x00, 0x08, 0xBD, 0x08, 0x20, 0x00, 0x08, 0xB9, 0x17, + 0x22, 0x40, 0x09, 0x09, 0x17, 0x22, 0x00, 0x08, 0xAD, 0x08, 0x34, 0x00, + 0x08, 0xA9, 0x17, 0x22, 0x40, 0x09, 0x01, 0x17, 0x22, 0x00, 0x08, 0xB0, + 0x00, 0xE2, 0x00, 0xFF, 0xF5, 0x08, 0x42, 0x00, 0x08, 0xC0, 0x00, 0xF2, + 0x00, 0x09, 0x3D, 0x08, 0x20, 0x00, 0xFF, 0xF5, 0x08, 0x82, 0x00, 0xFF, + 0xF5, 0x08, 0x84, 0x23, 0xFF, 0xED, 0x0A, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x40, 0x00, 0xF6, 0x00, 0x09, 0x45, 0x08, 0x22, 0x00, + 0x09, 0x10, 0x00, 0xE2, 0x00, 0x09, 0x10, 0x00, 0xF6, 0x23, 0x08, 0xDD, + 0x08, 0x20, 0x08, 0x08, 0xE0, 0x00, 0xE2, 0x00, 0x08, 0xCD, 0x08, 0x20, + 0x00, 0xFF, 0xE9, 0x19, 0x22, 0x67, 0x08, 0xD0, 0x00, 0xE2, 0x00, 0x09, + 0x15, 0x08, 0x22, 0x48, 0x09, 0x15, 0x08, 0x20, 0x00, 0x08, 0xD0, 0x00, + 0xE2, 0x27, 0xFF, 0xE9, 0x18, 0x20, 0x00, 0x08, 0xE0, 0x00, 0xE2, 0x27, + 0x08, 0xE5, 0x08, 0x20, 0x08, 0xFF, 0xFD, 0x08, 0x22, 0x40, 0x08, 0xE0, + 0x00, 0xE2, 0x26, 0x08, 0xD5, 0x1A, 0x20, 0x00, 0x09, 0x18, 0x00, 0xE2, + 0x00, 0x09, 0x20, 0x00, 0xF2, 0x00, 0x09, 0x18, 0x00, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0xA1, 0x00, 0xFF, 0xE5, 0x08, 0x20, 0x00, 0x00, 0x00, 0xEF, 0xA1, 0x00, + 0xFF, 0xE5, 0x08, 0x22, 0x40, 0x08, 0xE8, 0x00, 0xE2, 0x00, 0x09, 0x20, + 0x00, 0xC0, 0x00, 0x08, 0xEF, 0xFF, 0x20, 0x00, 0xFF, 0xE5, 0x08, 0x22, + 0x00, 0x08, 0xF8, 0x00, 0xE2, 0x00, 0x08, 0xF8, 0x00, 0xC0, 0x00, 0x07, + 0xFF, 0xFF, 0x20, 0x00, 0x09, 0x60, 0x00, 0xE2, 0x00, 0x08, 0x01, 0x1B, + 0x20, 0x00, 0x09, 0x48, 0x00, 0xE2, 0x00, 0x09, 0x89, 0x1F, 0x20, 0x00, + 0x09, 0x81, 0x20, 0x22, 0x00, 0x09, 0x71, 0x1F, 0x34, 0x00, 0x09, 0x69, + 0x20, 0x22, 0x00, 0x09, 0x61, 0x1C, 0x22, 0x00, 0x09, 0x59, 0x1D, 0x22, + 0x00, 0x09, 0x51, 0x1E, 0x22, 0x00, 0x09, 0x78, 0x00, 0xE2, 0x00, 0x09, + 0x90, 0x00, 0xF2, 0x00, 0x09, 0xB9, 0x24, 0x20, 0x00, 0x09, 0xB1, 0x25, + 0x22, 0x00, 0x09, 0xA1, 0x24, 0x34, 0x00, 0x09, 0x99, 0x25, 0x22, 0x00, + 0x09, 0x79, 0x21, 0x22, 0x00, 0x09, 0x71, 0x22, 0x22, 0x00, 0x09, 0x69, + 0x23, 0x22, 0x00, 0x09, 0xA8, 0x00, 0xE2, 0x00, 0x09, 0xC0, 0x00, 0xF2, + 0x00, 0x09, 0xE9, 0x29, 0x20, 0x00, 0x09, 0xE1, 0x2A, 0x22, 0x00, 0x09, + 0xD1, 0x29, 0x34, 0x00, 0x09, 0xC9, 0x2A, 0x22, 0x00, 0x09, 0xA9, 0x26, + 0x22, 0x00, 0x09, 0xA1, 0x27, 0x22, 0x00, 0x09, 0x99, 0x28, 0x22, 0x00, + 0x09, 0xD8, 0x00, 0xE2, 0x00, 0x09, 0xF0, 0x00, 0xF2, 0x00, 0x09, 0x4D, + 0x08, 0x20, 0x00, 0xFD, 0xB0, 0x00, 0xE2, 0x00, 0x09, 0xD9, 0x2B, 0x20, + 0x00, 0x09, 0xF8, 0x00, 0xE2, 0x00, 0x09, 0xFD, 0x08, 0x20, 0x00, 0xFD, + 0xB8, 0x00, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + +}; + +const unsigned char adau1761_init_arr_34[] = { + 0x00, 0x00, /* (34) Param */ + 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x87, 0x95, 0xA0, 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x0F, 0x02, 0x67, 0x53, 0x00, 0x7D, 0xA0, 0xAF, 0x00, 0xFD, 0x98, 0xAD, + 0x0F, 0x82, 0x5F, 0x51, 0x00, 0x80, 0x00, 0x00, 0x0F, 0x80, 0x9E, 0x3D, + 0x00, 0x34, 0x25, 0x2B, 0x00, 0x7F, 0x61, 0xC3, 0x0F, 0xCB, 0xDA, 0xD5, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE7, 0x44, + 0x0F, 0x13, 0x71, 0x1C, 0x00, 0x70, 0x4A, 0x0B, 0x00, 0xEC, 0x8E, 0xE4, + 0x0F, 0x8E, 0xCE, 0xB1, 0x00, 0x7B, 0xD6, 0x6A, 0x0F, 0x71, 0xA0, 0xD2, + 0x00, 0x63, 0x1A, 0xDB, 0x00, 0x8E, 0x5F, 0x2E, 0x0F, 0xA1, 0x0E, 0xBB, + 0x00, 0x21, 0x51, 0x9D, 0x00, 0x42, 0xA3, 0x3A, 0x00, 0x21, 0x51, 0x9D, + 0x00, 0x26, 0xDF, 0xA6, 0x0F, 0xD3, 0xD9, 0xE5, 0x00, 0x7D, 0x61, 0xFE, + 0x0F, 0x05, 0x3C, 0x04, 0x00, 0x7D, 0x61, 0xFE, 0x00, 0xFA, 0xB2, 0x8B, + 0x0F, 0x85, 0x2A, 0x94, 0x00, 0x80, 0x50, 0xA2, 0x0F, 0x05, 0xB3, 0x1E, + 0x00, 0x7A, 0x85, 0xBD, 0x00, 0xFA, 0x4C, 0xE2, 0x0F, 0x85, 0x29, 0xA1, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x7F, 0x76, 0x6D, 0x0F, 0x01, 0x13, 0x27, + 0x00, 0x7F, 0x76, 0x6D, 0x00, 0xFE, 0xEC, 0x48, 0x0F, 0x81, 0x12, 0x96, + 0x00, 0x7F, 0x76, 0x6D, 0x0F, 0x01, 0x13, 0x27, 0x00, 0x7F, 0x76, 0x6D, + 0x00, 0xFE, 0xEC, 0x48, 0x0F, 0x81, 0x12, 0x96, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x0D, 0x16, 0x00, 0x00, 0x1A, 0x2D, 0x00, 0xF9, 0xD7, 0x21, + 0x00, 0x00, 0x0D, 0x16, 0x0F, 0x86, 0x03, 0xCF, 0x00, 0x00, 0x09, 0x44, + 0x00, 0x00, 0x12, 0x88, 0x00, 0xF9, 0xD7, 0x21, 0x00, 0x00, 0x09, 0x44, + 0x0F, 0x86, 0x03, 0xCF, 0x00, 0x4E, 0xEA, 0x47, 0x0F, 0x62, 0x2B, 0x72, + 0x00, 0xFA, 0x13, 0xC2, 0x00, 0x4E, 0xEA, 0x47, 0x0F, 0x85, 0xC9, 0xF2, + 0x00, 0x7D, 0x12, 0x74, 0x0F, 0x05, 0xDB, 0x18, 0x00, 0xFA, 0x13, 0xC2, + 0x00, 0x7D, 0x12, 0x74, 0x0F, 0x85, 0xC9, 0xF2, 0x00, 0x80, 0x1D, 0x97, + 0x0F, 0x00, 0xEC, 0x9F, 0x00, 0x7E, 0xFD, 0xD9, 0x00, 0xFF, 0x13, 0x61, + 0x0F, 0x80, 0xE4, 0x90, 0x00, 0x80, 0x50, 0x64, 0x0F, 0x00, 0xA5, 0x22, + 0x00, 0x7F, 0x0E, 0x0F, 0x00, 0xFF, 0x5A, 0xDE, 0x0F, 0x80, 0xA1, 0x8D, + 0x00, 0x80, 0x8B, 0x50, 0x0F, 0x06, 0x4F, 0x3C, 0x00, 0x79, 0xAE, 0x9C, + 0x00, 0xF9, 0xB0, 0xC4, 0x0F, 0x85, 0xC6, 0x15, 0x00, 0x80, 0x7E, 0xBB, + 0x0F, 0x03, 0xF8, 0x4B, 0x00, 0x7B, 0xAE, 0x5C, 0x00, 0xFC, 0x07, 0xB5, + 0x0F, 0x83, 0xD2, 0xE9, 0x00, 0x99, 0x7D, 0xD0, 0x0F, 0xA2, 0x18, 0x34, + 0x00, 0x3A, 0xCB, 0x2A, 0x00, 0x37, 0x9D, 0x8E, 0x0F, 0xD2, 0x01, 0x44, + 0x00, 0x7D, 0x06, 0xB4, 0x0F, 0x35, 0xAB, 0x24, 0x00, 0x66, 0x0E, 0x45, + 0x00, 0xCA, 0x54, 0xDC, 0x0F, 0x9C, 0xEB, 0x07, 0x00, 0x84, 0xFA, 0x80, + 0x0F, 0x7B, 0x91, 0x2F, 0x00, 0x54, 0x90, 0xF6, 0x00, 0x84, 0x6E, 0xD1, + 0x0F, 0xA6, 0x74, 0x89, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x94, 0xC5, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x94, 0xC5, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x74, 0xA8, 0xB6, + 0x00, 0x5F, 0x3E, 0x5E, 0x00, 0x47, 0x4B, 0xE9, 0x00, 0x32, 0xF5, 0x1E, + 0x00, 0x24, 0x13, 0x47, 0x00, 0x19, 0x82, 0x54, 0x00, 0x12, 0x09, 0xA3, + 0x00, 0x0C, 0xC1, 0x2A, 0x00, 0x09, 0x04, 0xD2, 0x00, 0x06, 0x60, 0x95, + 0x00, 0x04, 0x82, 0x69, 0x00, 0x00, 0x01, 0x6A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x51, 0xEC, 0x0F, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x7B, 0x31, 0x33, + 0x00, 0x69, 0x82, 0xC9, 0x00, 0x51, 0x87, 0x68, 0x00, 0x3B, 0x86, 0x20, + 0x00, 0x2A, 0xE0, 0x26, 0x00, 0x1E, 0x51, 0x4F, 0x00, 0x15, 0x70, 0x13, + 0x00, 0x0F, 0x28, 0xA7, 0x00, 0x0A, 0xB8, 0x09, 0x00, 0x07, 0x94, 0x54, + 0x00, 0x05, 0x5C, 0x05, 0x00, 0x00, 0x1B, 0x5D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9E, 0x00, 0x00, 0x51, 0xEC, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x72, 0x15, 0x9E, + 0x00, 0x5D, 0x53, 0xC3, 0x00, 0x46, 0x9A, 0xB6, 0x00, 0x32, 0xEA, 0xCB, + 0x00, 0x24, 0x13, 0x47, 0x00, 0x19, 0x8A, 0x13, 0x00, 0x12, 0x14, 0x9A, + 0x00, 0x0C, 0xC8, 0xEB, 0x00, 0x09, 0x0A, 0x4D, 0x00, 0x06, 0x64, 0x75, + 0x00, 0x04, 0x85, 0x27, 0x00, 0x03, 0x32, 0x3B, 0x00, 0x02, 0x42, 0x93, + 0x00, 0x01, 0x12, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8B, + 0x00, 0x00, 0x51, 0xEC, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, +}; + +const unsigned char adau1761_init_arr_35[] = { + 0x1F, 0xFC, /* (35) Non Modulo RAM */ + 0x00, 0x7F, 0xF2, 0x59, 0x00, 0x00, 0x0D, 0xA7, + 0x00, 0x7F, 0xF2, 0x59, 0x00, 0x00, 0x0D, 0xA7, +}; + +const unsigned char adau1761_init_arr_36[] = { + 0x40, + 0xEB, /* (36) IC 1.Sample Rate Setting */ + 0x01, +}; + +const unsigned char adau1761_init_arr_37[] = { + 0x40, + 0xF6, /* (37) IC 1.DSP Run Register */ + 0x01, +}; + +const unsigned char adau1761_init_arr_38[] = { + 0x40, + 0x36, /* (38) IC 1.Dejitter Register Control */ + 0x00, +}; + +const unsigned char adau1761_init_arr_39[] = { + 0x40, + 0x36, /* (39) IC 1.Dejitter Register Control */ + 0x03, +}; + +typedef struct { + const unsigned char *p_arr; + unsigned int byte_len; +} adau1761_init_matrix; + +const adau1761_init_matrix adau1761_init_matrix_arr[] = { + {adau1761_init_arr_00, sizeof(adau1761_init_arr_00)}, + {adau1761_init_arr_01, sizeof(adau1761_init_arr_01)}, + {adau1761_init_arr_02, sizeof(adau1761_init_arr_02)}, + {adau1761_init_arr_03, sizeof(adau1761_init_arr_03)}, + {adau1761_init_arr_04, sizeof(adau1761_init_arr_04)}, + {adau1761_init_arr_05, sizeof(adau1761_init_arr_05)}, + {adau1761_init_arr_06, sizeof(adau1761_init_arr_06)}, + {adau1761_init_arr_07, sizeof(adau1761_init_arr_07)}, + {adau1761_init_arr_08, sizeof(adau1761_init_arr_08)}, + {adau1761_init_arr_09, sizeof(adau1761_init_arr_09)}, + {adau1761_init_arr_10, sizeof(adau1761_init_arr_10)}, + {adau1761_init_arr_11, sizeof(adau1761_init_arr_11)}, + {adau1761_init_arr_12, sizeof(adau1761_init_arr_12)}, + {adau1761_init_arr_13, sizeof(adau1761_init_arr_13)}, + {adau1761_init_arr_14, sizeof(adau1761_init_arr_14)}, + {adau1761_init_arr_15, sizeof(adau1761_init_arr_15)}, + {adau1761_init_arr_16, sizeof(adau1761_init_arr_16)}, + {adau1761_init_arr_17, sizeof(adau1761_init_arr_17)}, + {adau1761_init_arr_18, sizeof(adau1761_init_arr_18)}, + {adau1761_init_arr_19, sizeof(adau1761_init_arr_19)}, + {adau1761_init_arr_20, sizeof(adau1761_init_arr_20)}, + {adau1761_init_arr_21, sizeof(adau1761_init_arr_21)}, + {adau1761_init_arr_22, sizeof(adau1761_init_arr_22)}, + {adau1761_init_arr_23, sizeof(adau1761_init_arr_23)}, + {adau1761_init_arr_24, sizeof(adau1761_init_arr_24)}, + {adau1761_init_arr_25, sizeof(adau1761_init_arr_25)}, + {adau1761_init_arr_26, sizeof(adau1761_init_arr_26)}, + {adau1761_init_arr_27, sizeof(adau1761_init_arr_27)}, + {adau1761_init_arr_28, sizeof(adau1761_init_arr_28)}, + {adau1761_init_arr_29, sizeof(adau1761_init_arr_29)}, + {adau1761_init_arr_30, sizeof(adau1761_init_arr_30)}, + {adau1761_init_arr_31, sizeof(adau1761_init_arr_31)}, + {adau1761_init_arr_32, sizeof(adau1761_init_arr_32)}, + {adau1761_init_arr_33, sizeof(adau1761_init_arr_33)}, + {adau1761_init_arr_34, sizeof(adau1761_init_arr_34)}, + {adau1761_init_arr_35, sizeof(adau1761_init_arr_35)}, + {adau1761_init_arr_36, sizeof(adau1761_init_arr_36)}, + {adau1761_init_arr_37, sizeof(adau1761_init_arr_37)}, + {adau1761_init_arr_38, sizeof(adau1761_init_arr_38)}, + {adau1761_init_arr_39, sizeof(adau1761_init_arr_39)}}; + +#define ADAU1761_INIT_ARR_COUNT \ + (sizeof(adau1761_init_matrix_arr) / sizeof(adau1761_init_matrix)) + +struct vol_table { + int vtable_step; + float volgain_db; + uint8_t ram_word[4]; +}; + +/* 2dB step */ +static const struct vol_table adau1761_vol_table[] = { + {20, 0, {0x00, 0x80, 0x00, 0x00}}, {19, -1, {0x00, 0x72, 0x14, 0x7B}}, + {18, -2, {0x00, 0x65, 0xAC, 0x8C}}, {17, -3, {0x00, 0x5A, 0x9D, 0xF8}}, + {16, -4, {0x00, 0x50, 0xC3, 0x36}}, {15, -6, {0x00, 0x40, 0x26, 0xE7}}, + {14, -8, {0x00, 0x32, 0xF5, 0x2D}}, {13, -10, {0x00, 0x28, 0x7A, 0x27}}, + {12, -12, {0x00, 0x20, 0x26, 0xF3}}, {11, -14, {0x00, 0x19, 0x8A, 0x13}}, + {10, -16, {0x00, 0x14, 0x49, 0x61}}, {9, -20, {0x00, 0x0C, 0xCC, 0xCD}}, + {8, -24, {0x00, 0x08, 0x13, 0x85}}, {7, -28, {0x00, 0x05, 0x5E, 0x7F}}, + {6, -32, {0x00, 0x03, 0x37, 0x18}}, {5, -36, {0x00, 0x02, 0x07, 0x56}}, + {4, -40, {0x00, 0x01, 0x47, 0xAE}}, {3, -44, {0x00, 0x00, 0xCE, 0xC1}}, + {2, -52, {0x00, 0x00, 0x52, 0x4F}}, {1, -60, {0x00, 0x00, 0x20, 0xC5}}, + {0, -80, {0x00, 0x00, 0x03, 0x47}}, +}; + +#define VOL_STEP_NUM (sizeof(adau1761_vol_table) / sizeof(struct vol_table)) +#define MAX_VOL_STEP (VOL_STEP_NUM - 1) + +const u8 src_analog_arr[] = {0x00, 0x00, 0x00, 0x00}; +const u8 src_dig_arr[] = {0x00, 0x00, 0x00, 0x01}; + +const unsigned char adau1761_eq1_normal[] = {0x00, 0x00, 0x00, 0x00}; + +const unsigned char adau1761_eq1_decrease[] = {0x00, 0x00, 0x00, 0x01}; + +const unsigned char adau1761_eq2_improve[] = {0x00, 0x00, 0x00, 0x02}; + +// io commands +#define MAGIC_NUM 'A' +#define ADAU1761_CMD_VOL_SET _IOW(MAGIC_NUM, 0, int) +#define ADAU1761_CMD_VOL_GET _IOR(MAGIC_NUM, 1, int) +#define ADAU1761_CMD_AMP_MUTE_SET _IOW(MAGIC_NUM, 2, int) +#define ADAU1761_CMD_AMP_MUTE_GET _IOR(MAGIC_NUM, 3, int) +#define ADAU1761_CMD_SRC_SET _IOW(MAGIC_NUM, 4, int) +#define ADAU1761_CMD_SRC_GET _IOR(MAGIC_NUM, 5, int) +#define ADAU1761_CMD_FW_LOAD _IOW(MAGIC_NUM, 6, int) +#define ADAU1761_CMD_EQ_SET _IOW(MAGIC_NUM, 7, int) + +#define ADAU1761_CMD_MAX (7) + +struct adau1761_priv_data { + struct i2c_client *i2c_client; + u8 i2c_ch; + u8 vol; + u8 is_mute; + u8 src; // 0-analog, 1-i2s +}; + +static int default_pwm_freq = 24576000; // 24.576 default +static struct pwm_device *pwm_dev[2]; +static int duty_ns; +static int period_ns; +static int polarity = 0; +/*for pa sdz gpio ctrl*/ +static int pa_sdz_item; +/*for pa mute gpio ctrl*/ +static int pa_mute_item; + +static DEFINE_MUTEX(adau1761_mutex); +static struct adau1761_priv_data adau1761_priv; + +static inline u32 sigma_action_len(struct sigma_action *sa) { + return (le32_to_cpu(sa->len)); +} + +static size_t sigma_action_size(struct sigma_action *sa) { + size_t payload = 0; + + switch (le32_to_cpu(sa->ind)) { + case SIGMA_ACTION_WRITEXBYTES: + case SIGMA_ACTION_CONTROL: + payload = sigma_action_len(sa); + break; + + default: + break; + } + + return payload; +} + +/* + * Returns a negative error value in case of an error, 0 if processing of + * the firmware should be stopped after this action, 1 otherwise. + */ +static int process_sigma_action(struct sigma_firmware *ssfw, + struct sigma_action *sa) { + size_t len = sigma_action_len(sa); + u16 addr; + int ret; + + DSP_DEBUG("%s: len:%d ind:%#x\n", __func__, len, le32_to_cpu(sa->ind)); + + switch (le32_to_cpu(sa->ind)) { + case SIGMA_ACTION_WRITEXBYTES: + if (len <= sizeof(struct sigma_action) + 2) { + pr_debug("%s: short length in SIGMA_ACTION_WRITEXBYTES!\n", + __func__); + return -EINVAL; + } + + len = len - sizeof(struct sigma_action); + addr = *(const u16 *)(ssfw->fw->data + ssfw->pos + + sizeof(struct sigma_action)); + DSP_DEBUG("%s: addr:%#x\n", __func__, addr); + + if ((addr == 0) && (len == 4)) { + msleep(100); + } else { + ret = i2c_master_send(adau1761_priv.i2c_client, + (const char *)(ssfw->fw->data + ssfw->pos + + sizeof(struct sigma_action)), + len); + if (ret < 0) + return -EINVAL; + } + break; + + case SIGMA_ACTION_CONTROL: + return 0; + + default: + return -EINVAL; + } + + return 1; +} + +static int process_sigma_actions(struct sigma_firmware *ssfw) { + struct sigma_action *sa; + size_t size; + int ret; + + while (ssfw->pos < ssfw->fw->size) { + sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos); + size = sigma_action_size(sa); + + if (size == 0) + break; + + ret = process_sigma_action(ssfw, sa); + + DSP_DEBUG("%s: action returned %i\n", __func__, ret); + + if (ret <= 0) + return ret; + + size = ALIGN(size, 4); + ssfw->pos += size; + } + + return 0; +} + +static int _process_sigma_firmware(struct device *dev, + struct sigma_firmware *ssfw, + const char *name) { + int ret; + struct sigma_firmware_header *ssfw_head; + const struct firmware *fw; + u32 crc; + + DSP_DEBUG("%s: loading firmware %s\n", __func__, name); + + /* first load the blob */ + ret = request_firmware(&fw, name, dev); + if (ret) { + pr_debug("%s: request_firmware() failed with %i\n", __func__, ret); + return ret; + } + ssfw->fw = fw; + + /* then verify the header */ + ret = -EINVAL; + + /* + * Reject too small or unreasonable large files. The upper limit has been + * chosen a bit arbitrarily, but it should be enough for all practical + * purposes and having the limit makes it easier to avoid integer + * overflows later in the loading process. + */ + if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) { + dev_err(dev, "Failed to load firmware: Invalid size\n"); + goto done; + } + + ssfw_head = (void *)fw->data; + if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) { + dev_err(dev, "Failed to load firmware: Invalid magic\n"); + goto done; + } + + crc = + crc32(0, fw->data + sizeof(*ssfw_head), fw->size - sizeof(*ssfw_head)); + DSP_DEBUG("%s: crc=%x\n", __func__, crc); + + if (crc != le32_to_cpu(ssfw_head->crc)) { + dev_err( + dev, + "Failed to load firmware: Wrong crc checksum: expected %x got %x\n", + le32_to_cpu(ssfw_head->crc), crc); + goto done; + } + + ssfw->pos = sizeof(*ssfw_head) + sizeof(struct sigma_samprate_list); + + /* finally process all of the actions */ + ret = process_sigma_actions(ssfw); + +done: + release_firmware(fw); + + DSP_DEBUG("%s: loaded %s\n", __func__, name); + + return ret; +} + +int process_sigma_firmware(struct i2c_client *client, const char *name) { + struct sigma_firmware ssfw; + + ssfw.control_data = client; + + return _process_sigma_firmware(&client->dev, &ssfw, name); +} + +static void pwm_init(int pwm_ch) { + char pwm_name[10]; + sprintf(pwm_name, "pwm_%d", pwm_ch); + + pwm_dev[pwm_ch] = pwm_request(pwm_ch, pwm_name); + if (NULL == pwm_dev[pwm_ch] || IS_ERR(pwm_dev[pwm_ch])) { + DSP_DEBUG("OSAL_Pwm_request pwm fail!\n"); + } + + pwm_set_polarity(pwm_dev[pwm_ch], polarity); + + period_ns = 1000000000 / default_pwm_freq; + + duty_ns = (128 * period_ns) / 256; + + pwm_config(pwm_dev[pwm_ch], duty_ns, period_ns); +} + +static int adau1761_safe_load(uint8_t *word_arr, unsigned int word_num, + unsigned int target_addr) { + uint8_t temp_arr[SAFE_LOAD_REG_NUM * 4 + 2]; + int cnt, ret = 0; + + if (word_num > SAFE_LOAD_WORD_NUM_MAX) { + DSP_DEBUG("safe_load: > 5 words!\n"); + ret = -1; + + return ret; + } + + if (word_arr == NULL) { + DSP_DEBUG("safe_load: word_arr == NULL!\n"); + ret = -1; + + return ret; + } + + if (target_addr < 1) { + DSP_DEBUG("safe_load: target_addr < 1!\n"); + ret = -1; + + return ret; + } + + /* fill with zero */ + memset(temp_arr, 0, sizeof(temp_arr)); + + /* safeload register */ + temp_arr[0] = (uint8_t)((SAFE_LOAD_DATA_1_REG >> 8) & 0xFF); + temp_arr[1] = (uint8_t)(SAFE_LOAD_DATA_1_REG & 0xFF); + + /* fill with data */ + for (cnt = 0; cnt < word_num * 4; cnt++) { + temp_arr[cnt + 2] = word_arr[cnt]; + } + + /* target addr */ + cnt = (SAFE_LOAD_TARGET_ADDR_REG - SAFE_LOAD_DATA_1_REG) * 4 + 4; + target_addr = target_addr - 1; + temp_arr[cnt] = (unsigned char)((target_addr >> 8) & 0xFF); + cnt++; + temp_arr[cnt] = (unsigned char)(target_addr & 0xFF); + + /* word number */ + cnt = (SAFE_LOAD_WORD_NUM_REG - SAFE_LOAD_DATA_1_REG) * 4 + 5; + temp_arr[cnt] = (unsigned char)(word_num & 0xFF); + + /* burst transfer */ + cnt = SAFE_LOAD_REG_NUM * 4 + 2; + ret = + i2c_master_send(adau1761_priv.i2c_client, (const char *)temp_arr, cnt); + return ret; +} + +/* + * Change EQ when system operating + * input: int arg + * output: int ret + */ +static int adau1761_safe_load_new_eq(unsigned long arg) { + unsigned int i; + int ret = -1; + gpio_set_value(pa_mute_item, 1); + if (arg == 0) { + ret = adau1761_safe_load((uint8_t *)(&adau1761_eq1_normal[0]), 1, + SAFE_LOAD_EQ_SWITCH_REG); + } else if (arg == 1) { + ret = adau1761_safe_load((uint8_t *)(&adau1761_eq1_decrease[0]), 1, + SAFE_LOAD_EQ_SWITCH_REG); + } else if (arg == 2) { + ret = adau1761_safe_load((uint8_t *)(&adau1761_eq2_improve[0]), 1, + SAFE_LOAD_EQ_SWITCH_REG); + } else { + DSP_DEBUG("failed to load adau1761_new_EQ: out range\n"); + } + gpio_set_value(pa_mute_item, 0); + return ret; +} + +static unsigned int adau1761_register_size(unsigned int reg) { + switch (reg) { + case ADAU1761_DIGMIC_JACKDETECT: + case ADAU1761_REC_MIXER_LEFT0: + case ADAU1761_REC_MIXER_LEFT1: + case ADAU1761_REC_MIXER_RIGHT0: + case ADAU1761_REC_MIXER_RIGHT1: + case ADAU1761_LEFT_DIFF_INPUT_VOL: + case ADAU1761_RIGHT_DIFF_INPUT_VOL: + case ADAU1761_PLAY_LR_MIXER_LEFT: + case ADAU1761_PLAY_MIXER_LEFT0: + case ADAU1761_PLAY_MIXER_LEFT1: + case ADAU1761_PLAY_MIXER_RIGHT0: + case ADAU1761_PLAY_MIXER_RIGHT1: + case ADAU1761_PLAY_LR_MIXER_RIGHT: + case ADAU1761_PLAY_MIXER_MONO: + case ADAU1761_PLAY_HP_LEFT_VOL: + case ADAU1761_PLAY_HP_RIGHT_VOL: + case ADAU1761_PLAY_LINE_LEFT_VOL: + case ADAU1761_PLAY_LINE_RIGHT_VOL: + case ADAU1761_PLAY_MONO_OUTPUT_VOL: + case ADAU1761_POP_CLICK_SUPPRESS: + case ADAU1761_JACK_DETECT_PIN: + case ADAU1761_DEJITTER: + case ADAU1761_CLK_ENABLE0: + case ADAU1761_CLK_ENABLE1: + case ADAU17X1_CLOCK_CONTROL: + case ADAU17X1_PLL_CONTROL: + case ADAU17X1_REC_POWER_MGMT: + case ADAU17X1_MICBIAS: + case ADAU17X1_SERIAL_PORT0: + case ADAU17X1_SERIAL_PORT1: + case ADAU17X1_CONVERTER0: + case ADAU17X1_CONVERTER1: + case ADAU17X1_LEFT_INPUT_DIGITAL_VOL: + case ADAU17X1_RIGHT_INPUT_DIGITAL_VOL: + case ADAU17X1_ADC_CONTROL: + case ADAU17X1_PLAY_POWER_MGMT: + case ADAU17X1_DAC_CONTROL0: + case ADAU17X1_DAC_CONTROL1: + case ADAU17X1_DAC_CONTROL2: + case ADAU17X1_SERIAL_PORT_PAD: + case ADAU17X1_CONTROL_PORT_PAD0: + case ADAU17X1_CONTROL_PORT_PAD1: + case ADAU17X1_DSP_SAMPLING_RATE: + case ADAU17X1_SERIAL_INPUT_ROUTE: + case ADAU17X1_SERIAL_OUTPUT_ROUTE: + case ADAU17X1_DSP_ENABLE: + case ADAU17X1_DSP_RUN: + case ADAU17X1_SERIAL_SAMPLING_RATE: + return 1; + + default: + if ((reg > ADAU1761_DATA_PARAM_START_ADDR) && + (reg <= ADAU1761_DATA_PARAM_END_ADDR)) { + return 4; + } else { // do not support program RAM + DSP_DEBUG("register_size: Unsupported register address: %d\n", reg); + + return 0; + } + } +} + +static unsigned int adau1761_read(unsigned int reg) { + unsigned int i; + unsigned int size; + uint8_t buf[4]; + int ret; + + size = adau1761_register_size(reg); + if (size == 0) { + return 0; + } + + buf[0] = (uint8_t)((reg >> 8) && 0xFF); + buf[1] = (uint8_t)(reg && 0xFF); + + ret = i2c_master_send(adau1761_priv.i2c_client, buf, 2); + + if (ret < 0) { + i = (unsigned int)ret; + + return i; + } else if (ret != size + 2) { + i = (unsigned int)(-EIO); + + return i; + } + + ret = i2c_master_recv(adau1761_priv.i2c_client, buf, size); + + if (ret != size) { + i = (unsigned int)(-EIO); + + return i; + } else { + ret = 0; + + for (i = 0; i < size; i++) { + ret += buf[i]; + ret <<= 8; + } + + i = (uint32_t)ret; + + return i; + } +} + +static int adau1761_write(unsigned int reg, unsigned int value) { + unsigned int i; + unsigned int size; + uint8_t buf[4]; + int ret; + + size = adau1761_register_size(reg); + if (size == 0) { + return -EINVAL; + } + + buf[0] = (uint8_t)((reg >> 8) && 0xFF); + buf[1] = (uint8_t)(reg && 0xFF); + + for (i = size + 1; i > 1; --i) { + buf[i] = (uint8_t)(value && 0xFF); + value >>= 8; + } + + ret = i2c_master_send(adau1761_priv.i2c_client, buf, size + 2); + + if (ret == size + 2) { + return 0; + } else if (ret < 0) { + return ret; + } else { + return -EIO; + } +} + +int adau1761_open(struct inode *inode, struct file *filep) { + int ret; + + DSP_DEBUG("open start\n"); + + mutex_lock(&adau1761_mutex); + ret = nonseekable_open(inode, filep); + mutex_unlock(&adau1761_mutex); + + return ret; +} + +int adau1761_release(struct inode *inode, struct file *filep) { + DSP_DEBUG("release start\n"); + + return 0; +} + +// file operations +static long adau1761_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { + u8 i; + int ret = 0; + + DSP_DEBUG("ioctl start cmd: %d arg: %lX\n", cmd, arg); + + if (_IOC_TYPE(cmd) != MAGIC_NUM) + return -EINVAL; + + if (_IOC_NR(cmd) > ADAU1761_CMD_MAX) + return -EINVAL; + + if (_IOC_DIR(cmd) & _IOC_READ) + ret = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); + if (_IOC_DIR(cmd) & _IOC_WRITE) + ret = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); + + if (ret) + return -EFAULT; + + DSP_DEBUG("ioctl start\n"); + + mutex_lock(&adau1761_mutex); + + DSP_DEBUG("ioctl lock\n"); + + switch (cmd) { + case ADAU1761_CMD_VOL_SET: { + if (arg > MAX_VOL_STEP) { + ret = -EINVAL; + goto failure; + } + + for (i = 0; i < VOL_STEP_NUM; i++) { + if (adau1761_vol_table[i].vtable_step == arg) { + adau1761_priv.vol = arg; + adau1761_safe_load((uint8_t *)(adau1761_vol_table[i].ram_word), + 1, VOL_CTL_ADDR); + break; + } + } + } break; + + case ADAU1761_CMD_VOL_GET: { + *(unsigned long *)arg = (unsigned long)adau1761_priv.vol; + } break; + + case ADAU1761_CMD_AMP_MUTE_SET: { + if (arg > 1) { + ret = -EINVAL; + goto failure; + } + + adau1761_priv.is_mute = arg; + gpio_set_value(pa_mute_item, arg); + } break; + + case ADAU1761_CMD_AMP_MUTE_GET: { + *(unsigned long *)arg = (unsigned long)adau1761_priv.is_mute; + } break; + + case ADAU1761_CMD_SRC_SET: { + if (arg > 1) { + ret = -EINVAL; + goto failure; + } + + adau1761_priv.src = arg; + + if (0 == arg) { // ana + adau1761_safe_load((uint8_t *)src_analog_arr, 1, SRC_SW_ADDR); + break; + } else { // dig + adau1761_safe_load((uint8_t *)src_dig_arr, 1, SRC_SW_ADDR); + break; + } + } break; + + case ADAU1761_CMD_SRC_GET: { + *(unsigned long *)arg = (unsigned long)adau1761_priv.src; + } break; + + case ADAU1761_CMD_FW_LOAD: { + process_sigma_firmware(adau1761_priv.i2c_client, ADAU1761_FIRMWARE); + } break; + + case ADAU1761_CMD_EQ_SET: { + ret = adau1761_safe_load_new_eq(arg); + } break; + + default: + break; + } + + mutex_unlock(&adau1761_mutex); + + DSP_DEBUG("ioctl end\n"); + + return ret; + +failure: + DSP_DEBUG("ioctl err: %d\n", ret); + mutex_unlock(&adau1761_mutex); + + return ret; +} + +static const struct file_operations adau1761_fops = { + .owner = THIS_MODULE, + .open = adau1761_open, + .release = adau1761_release, + .unlocked_ioctl = adau1761_ioctl, +}; + +static struct miscdevice adau1761_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "adau1761", + .fops = &adau1761_fops, +}; + +/*****************************************************/ +static int adau1761_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *i2c_id) { + int i, ret = 0; + + DSP_DEBUG("i2c_probe start\n"); + + adau1761_priv.i2c_client = client; + adau1761_priv.vol = ADAU1761_DEF_VOL_STEP; + adau1761_priv.src = 0; // ana + + for (i = 0; i < ADAU1761_INIT_ARR_COUNT; i++) { + if (adau1761_init_matrix_arr[i].byte_len) { + ret = i2c_master_send(adau1761_priv.i2c_client, + adau1761_init_matrix_arr[i].p_arr, + adau1761_init_matrix_arr[i].byte_len); + + if (ret > 0) { + DSP_DEBUG("Succeeded to load adau1761_init_arr_%d, transfer: " + "%d bytes\n", + i, ret); + } else { + DSP_DEBUG("Failed to load adau1761_init_arr_%d, failure: %d\n", + i, ret); + + return -1; + } + + } else { + msleep(100); + } + } + + for (i = 0; ARRAY_SIZE(adau1761_vol_table); i++) { + if (adau1761_vol_table[i].vtable_step == ADAU1761_DEF_VOL_STEP) { + // use safeload + ret = adau1761_safe_load( + (uint8_t *)(adau1761_vol_table[i].ram_word), 1, VOL_CTL_ADDR); + + break; + } + } + + DSP_DEBUG("i2c_probe end\n"); + + if (ret > 0) { + ret = 0; + } else { + ret = -1; + } + + return ret; +} + +static int adau1761_i2c_remove(struct i2c_client *i2c) { return 0; } + +static struct i2c_board_info adau1761_i2c_board_info[] = { + { + I2C_BOARD_INFO("adau1761_0", 0x38), + }, +}; + +static const struct i2c_device_id adau1761_i2c_id[] = { + {"adau1761_0", 0}, +}; +MODULE_DEVICE_TABLE(i2c, adau1761_i2c_id); + +static const unsigned short m_normal_i2c[2] = {0x38, I2C_CLIENT_END}; + +static struct i2c_driver adau1761_i2c_driver = { + .driver = + { + .name = "adau1761_0", + .owner = THIS_MODULE, + }, + .address_list = m_normal_i2c, + .probe = adau1761_i2c_probe, + .remove = adau1761_i2c_remove, + .id_table = adau1761_i2c_id, +}; + +static int __init adau1761_r311_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct gpio_config config; + + pa_sdz_item = of_get_named_gpio_flags(np, "audio_pa_sdz", 0, + (enum of_gpio_flags *)&config); + if (!gpio_is_valid(pa_sdz_item)) { + printk("get audio_pa_sdz failed\n"); + return -EINVAL; + } else { + printk("Get audio_pa_sdz success,gpio:%d\n", pa_sdz_item); + } + + devm_gpio_request(dev, pa_sdz_item, "pa_sdz_item"); + gpio_direction_output(pa_sdz_item, 1); + + pa_mute_item = of_get_named_gpio_flags(np, "audio_pa_mute", 0, + (enum of_gpio_flags *)&config); + if (!gpio_is_valid(pa_mute_item)) { + printk("get pa_mute_item failed\n"); + return -EINVAL; + } else { + printk("Get pa_mute_item success,gpio:%d\n", pa_mute_item); + } + + devm_gpio_request(dev, pa_mute_item, "pa_mute_item"); + if (adau1761_priv.is_mute) { + gpio_direction_output(pa_mute_item, 1); // set mute high + } else { + gpio_direction_output(pa_mute_item, 0); // set mute low + } + + printk("adau1761, set pa_sdz=1, set pa_mute=%d\n", adau1761_priv.is_mute); + + return 0; +} + +static const struct of_device_id adau1761_r311_ids[] = { + {.compatible = "allwinner,adau1761-r311-pv1"}, {/* Sentinel */}}; + +static struct platform_driver adau1761_r311_driver = { + .driver = + { + .owner = THIS_MODULE, + .name = "adau1761-r311-pv1", + .of_match_table = adau1761_r311_ids, + }, +}; + +static int __init adau1761_init(void) { + struct i2c_adapter *adapter; + struct i2c_client *client; + int req_status, ret, i = 0; + + DSP_DEBUG("init start\n"); + + adau1761_priv.is_mute = 1; // mute + + platform_driver_probe(&adau1761_r311_driver, adau1761_r311_probe); + + ret = misc_register(&adau1761_misc); + if (ret < 0) { + DSP_DEBUG("init reg err\n"); + misc_deregister(&adau1761_misc); + + return ret; + } + + adau1761_priv.i2c_ch = 1; + adapter = i2c_get_adapter(adau1761_priv.i2c_ch); + + if (!adapter) + return -ENODEV; + for (i = 0; i < sizeof(adau1761_i2c_board_info) / + sizeof(adau1761_i2c_board_info[0]); + i++) { + client = NULL; + client = i2c_new_device(adapter, &adau1761_i2c_board_info[i]); + if (!client) + return -ENODEV; + } + i2c_put_adapter(adapter); + + return i2c_add_driver(&adau1761_i2c_driver); +} +module_init(adau1761_init); + +static void __exit adau1761_exit(void) { i2c_del_driver(&adau1761_i2c_driver); } +module_exit(adau1761_exit); + +MODULE_DESCRIPTION("ASoC codec adau1761 driver"); +MODULE_AUTHOR("Netease IHW"); +MODULE_LICENSE("GPL"); diff --git a/lichee/linux-4.9/drivers/misc/xunfei/Kconfig b/lichee/linux-4.9/drivers/misc/xunfei/Kconfig new file mode 100755 index 000000000..6248c4727 --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/xunfei/Kconfig @@ -0,0 +1,7 @@ +menu "Xunfei module driver" +config XUNFEI_CPLD + tristate "xunfei cpld driver" + help + Xunfei CPLD Mic sample board control interfaces. Added by wzj. 2018-07-27 + +endmenu diff --git a/lichee/linux-4.9/drivers/misc/xunfei/Makefile b/lichee/linux-4.9/drivers/misc/xunfei/Makefile new file mode 100755 index 000000000..e5a7851af --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/xunfei/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_XUNFEI_CPLD) += cpld/i2c_operator.o cpld/fpga_loader.o cpld/fpga_config.o cpld/cx20810.o cpld/netease_config.o diff --git a/lichee/linux-4.9/drivers/misc/xunfei/cpld/cx20810.c b/lichee/linux-4.9/drivers/misc/xunfei/cpld/cx20810.c new file mode 100755 index 000000000..000e5a298 --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/xunfei/cpld/cx20810.c @@ -0,0 +1,362 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// codec init param +#include "cx20810_config.h" + +#define I2C_CX20810_DRIVER_NAME "i2c_cx20810" +#define MAX_CX20810_NUM (3) +void netease_enable_clk(void); +static int gpio_adc_rst = -1; + +// g_client_cx20810[0] is on adapter 0 and its address is 0x35 +// g_client_cx20810[1] is on adapter 1 and its address is 0x35 +// g_client_cx20810[2] is on adapter 1 and its address is 0x3B +static struct i2c_client *g_client_cx20810[MAX_CX20810_NUM]; +static const unsigned short i2c_cx20810_addr[] = {0x35, 0x3B, I2C_CLIENT_END}; +static const struct i2c_device_id i2c_driver_cx20810_id[] = { + {I2C_CX20810_DRIVER_NAME, 0}, {}}; + +// function declaration +static int cx20810_hw_init(void); +static int i2c_driver_cx20810_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int i2c_driver_cx20810_remove(struct i2c_client *client); +static int i2c_driver_cx20810_detect(struct i2c_client *client, + struct i2c_board_info *info); +static int i2c_master_send_array_to_cx20810(const struct i2c_client *client, + const char *buf, int length); +static void cx20810_init(int index, int mode); +int cx20810_set_mode(int mode, int index); + +// set cx20810 work mode +int cx20810_set_mode(int mode, int index) { + printk("Timothy:cx20810.c->cx20810_set_mode(), mode = %d, index = %d\n", + mode, index); + int i; + int ret; + char *param; + int length; + + switch (mode) { + case CX20810_NORMAL_MODE: + param = codec_config_param_normal_mode; + length = sizeof(codec_config_param_normal_mode); + break; + + case CX20810_NORMAL_MODE_SIMPLE: + param = codec_config_param_normal_mode_simple; + length = sizeof(codec_config_param_normal_mode_simple); + break; + + case CX20810_48K_16BIT_MODE: + param = codec_config_param_48k_16bit_mode; + length = sizeof(codec_config_param_48k_16bit_mode); + break; + + case CX20810_96K_16BIT_MODE: + param = codec_config_param_96k_16bit_mode; + length = sizeof(codec_config_param_96k_16bit_mode); + break; + + case CX20810_NIRMAL_MODE_CODEC3: + param = codec3_config_param_normal_mode; + length = sizeof(codec3_config_param_normal_mode); + break; + + case CX20810_NIRMAL_MODE_CODEC3_SIMPLE: + param = codec3_config_param_normal_mode_simple; + length = sizeof(codec3_config_param_normal_mode_simple); + break; + + default: + return; + break; + } + + // if client is null, return + if (g_client_cx20810[index] == NULL) { + printk("Timothy:cx20810(%d) is not detected yet\n", index); + return -1; + } + + ret = i2c_master_send_array_to_cx20810(g_client_cx20810[index], param, + length); + if (ret != 0) { + printk("Timothy:cx82011[%x] init error!\n", + g_client_cx20810[index]->addr); + return -1; + } else { + printk("Timothy:cx20810[%x] init ok\n", g_client_cx20810[index]->addr); + return 0; + } +} +EXPORT_SYMBOL(cx20810_set_mode); + +int cx20810_write_reg(int index, int addr, int regval) { + char writedata[2] = {0}; + if (index > 1) { + return -1; + } + writedata[0] = (char)addr; + writedata[1] = (char)regval; + + return i2c_master_send(g_client_cx20810[index], writedata, 2); +} +EXPORT_SYMBOL(cx20810_write_reg); + +int cx20810_read_reg(int index, int cmd, int *regval) { + int error = 0; + char data = 0; + if (index > 1) { + return -1; + } + + error = i2c_master_send(g_client_cx20810[index], (const char *)&cmd, 1); + // write reg addr + if (1 != i2c_master_send(g_client_cx20810[index], (const char *)&cmd, 1)) { + printk(KERN_ERR " cx20810_read_reg fail1! \n"); + return -1; + } + // wait + msleep(10); + // read + if (error >= 0) { + error = i2c_master_recv(g_client_cx20810[index], &data, 1); + if (error < 0) { + printk(KERN_ERR " cx20810_read_reg fail2! \n"); + } + } else { + printk(KERN_ERR " cx20810_read_reg fail1! \n"); + } + + *regval = (int)data; + + return 0; +} +EXPORT_SYMBOL(cx20810_read_reg); + +// send parameters to cx20810 as master +static int i2c_master_send_array_to_cx20810(const struct i2c_client *client, + const char *buf, int length) { + printk("Timothy:cx20810.c->i2c_master_send_array_to_cx20810()\n"); + int i; + int nwrite; + for (i = 0; i < (length / 2); i++) { + nwrite = i2c_master_send(client, buf + i * 2, 2); + if (nwrite != 2) { + printk("Timothy:send to cx20810 error\n"); + return -1; + } + } + return 0; +} + +// initial cx20810 +static void cx20810_init(int index, int mode) { + printk("Timothy:cx20810.c->cx20810_init()\n"); + if (cx20810_set_mode(mode, index) == 0) { + printk("Timothy:cx20810 init success\n"); + } else { + printk("Timothy:cx20810 init fail\n"); + } +} + +static int i2c_driver_cx20810_probe(struct i2c_client *client, + const struct i2c_device_id *id) { + if (client->adapter->nr == 0 && client->addr == i2c_cx20810_addr[0]) { + g_client_cx20810[1] = client; + printk("Timothy:cx20810 (0x%x) init ok\n", client->addr); + cx20810_init(1, CX20810_NORMAL_MODE); + } else if (client->adapter->nr == 0 && + client->addr == i2c_cx20810_addr[1]) { + g_client_cx20810[0] = client; + printk("Timothy:cx20810 (0x%x) init ok\n", client->addr); + cx20810_init(0, CX20810_NORMAL_MODE); + } + return 0; +} + +static int i2c_driver_cx20810_remove(struct i2c_client *client) { + printk("Timothy:cx20810.c->i2c_driver_cx20810_remove()\n"); + return 0; +} +MODULE_DEVICE_TABLE(i2c, i2c_driver_cx20810_id); + +static int i2c_driver_cx20810_detect(struct i2c_client *client, + struct i2c_board_info *info) { + printk("Timothy:cx20810.c->i2c_driver_cx20810_detect()...\n"); + struct i2c_adapter *p_adapter; + const char *type_name = I2C_CX20810_DRIVER_NAME; + p_adapter = client->adapter; + printk("Timothy:adapter->nr = %d\n", p_adapter->nr); + if (0 == p_adapter->nr) { + if (info->addr == i2c_cx20810_addr[0]) { + printk("Timothy:detect cx20810 (%x) on i2c adapter (%d)\n", + info->addr, p_adapter->nr); + strlcpy(info->type, type_name, I2C_NAME_SIZE); + return 0; + } else if (info->addr == i2c_cx20810_addr[1]) { + printk("Timothy:detect cx20810 (%x) on i2c adapter (%d)\n", + info->addr, p_adapter->nr); + strlcpy(info->type, type_name, I2C_NAME_SIZE); + return 0; + } + } + return ENODEV; +} + +static struct i2c_driver i2c_driver_cx20810 = { + .class = I2C_CLASS_HWMON, + .probe = i2c_driver_cx20810_probe, + .remove = i2c_driver_cx20810_remove, + .id_table = i2c_driver_cx20810_id, + .driver = + { + .name = I2C_CX20810_DRIVER_NAME, + .owner = THIS_MODULE, + }, + .detect = i2c_driver_cx20810_detect, + .address_list = i2c_cx20810_addr}; + +static int __init i2c_driver_cx20810_init(void) { + printk("Timothy:cx20810.c->i2c_driver_cx20810_init()\n"); + msleep(300); + // cx20810_hw_init(); + return i2c_add_driver(&i2c_driver_cx20810); +} + +static void __exit i2c_driver_cx20810_exit(void) { + printk("Timothy:cx20810.c->i2c_driver_cx20810_exit()\n"); + i2c_del_driver(&i2c_driver_cx20810); +} + +static int __init cpld_r311_probe(struct platform_device *pdev) { + printk("Begin to set luyao asked gpios \n"); + + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct gpio_config cfg; + int gpionum; + + gpionum = of_get_named_gpio_flags(np, "4v5_ldo_en", 0, + (enum of_gpio_flags *)&cfg); + if (gpio_is_valid(gpionum)) { + gpio_request(gpionum, "4v5_ldo_en"); + gpio_direction_output(gpionum, 1); + printk("Set 4v5_ldo_en(%d) success\n", gpionum); + } else { + printk("Set 4v5_ldo_en fail\n"); + } + + gpionum = + of_get_named_gpio_flags(np, "3v_ldo_en", 0, (enum of_gpio_flags *)&cfg); + if (gpio_is_valid(gpionum)) { + gpio_request(gpionum, "3v_ldo_en"); + gpio_direction_output(gpionum, 1); + printk("Set 3v_ldo_en(%d) success\n", gpionum); + } else { + printk("Set 3v_ldo_en fail\n"); + } + + gpionum = of_get_named_gpio_flags(np, "gp_adc_rst", 0, + (enum of_gpio_flags *)&cfg); + gpio_adc_rst = gpionum; + if (!gpio_is_valid(gpionum)) { + printk("get gp_adc_rst failed\n"); + return -EINVAL; + } else { + printk("Get gp_adc_rst success,gpio:%d\n", gpionum); + } + + devm_gpio_request(dev, gpionum, "gp_adc_rst"); + gpio_direction_output(gpionum, 1); + printk("Set gp_adc_rst(%d) to 1\n", gpionum); + + return 0; +} + +void netease_cpld_reset(void) { + printk("Begin to reset cpld!\n"); + if (gpio_is_valid(gpio_adc_rst)) { + gpio_set_value(gpio_adc_rst, 0); + msleep(100); + printk("Begin to start cpld!\n"); + gpio_set_value(gpio_adc_rst, 1); + msleep(800); + printk("Finish reseting cpld!\n"); + } else { + printk("Adc rst gpio is not init!\n"); + } +} + +static const struct of_device_id cpld_r311_ids[] = { + {.compatible = "allwinner,cpld-r311-pv1"}, {/* Sentinel */}}; + +static struct platform_driver cpld_r311_driver = { + .driver = + { + .owner = THIS_MODULE, + .name = "cpld", + .of_match_table = cpld_r311_ids, + }, +}; + +static int __init cpld_r311_init(void) { + int ret = 0; +#if 0 + type = script_get_item("cpld", "gp_ldo_4_5", &item); + if (SCIRPT_ITEM_VALUE_TYPE_PIO == type) { + printk("luyao:set gp_ldo_4_5\n"); + printk("Gpio:%d\n", item.gpio.gpio); + + gpio_request(item.gpio.gpio, NULL); + + gpio_direction_output(item.gpio.gpio, 1); + gpio_set_value(item.gpio.gpio, 1); + + gpio_free(item.gpio.gpio); + } + + type = script_get_item("cpld", "gp_ldo_3", &item); + if (SCIRPT_ITEM_VALUE_TYPE_PIO == type) { + printk("luyao:set gp_ldo_3\n"); + printk("Gpio:%d\n", item.gpio.gpio); + gpio_request(item.gpio.gpio, NULL); + gpio_direction_output(item.gpio.gpio, 1); + gpio_set_value(item.gpio.gpio, 1); + gpio_free(item.gpio.gpio); + } +#endif + printk("Begin to init cpld r311 driver!!\n"); + ret = platform_driver_probe(&cpld_r311_driver, cpld_r311_probe); + printk("platform_driver_probe:%d!\n", ret); + + return ret; +} + +static void __exit cpld_r311_deinit(void) {} + +fs_initcall_sync(cpld_r311_init); +module_exit(cpld_r311_deinit); + +late_initcall_sync(i2c_driver_cx20810_init); +module_exit(i2c_driver_cx20810_exit); + +MODULE_AUTHOR("Timothy"); +MODULE_DESCRIPTION("I2C device cx20810 loader"); +MODULE_LICENSE("GPL"); diff --git a/lichee/linux-4.9/drivers/misc/xunfei/cpld/cx20810_config.h b/lichee/linux-4.9/drivers/misc/xunfei/cpld/cx20810_config.h new file mode 100755 index 000000000..79e4a0012 --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/xunfei/cpld/cx20810_config.h @@ -0,0 +1,340 @@ +#ifndef CX20810_CONFIG_H_ +#define CX20810_CONFIG_H_ + +enum +{ + CX20810_NORMAL_MODE = 0, + CX20810_NORMAL_MODE_SIMPLE, + CX20810_NIRMAL_MODE_CODEC3, + CX20810_NIRMAL_MODE_CODEC3_SIMPLE, + CX20810_96K_16BIT_MODE, + CX20810_48K_16BIT_MODE, +}; + +const char codec_config_param_normal_mode[]= +{ + 0x0F,0x03, //RST + 0x0F,0x03, //repeat write is let chip has more time to RST + 0x0F,0x03, + 0x0F,0x03, + + 0x0F,0x00,//release reset + + 0x78,0x33, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x33, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x33, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x33, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x33, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + + 0x78,0x73, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x73, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x73, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x73, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x73, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + + 0x7A,0x01, + 0x01,0x01, + + 0xA0,0x07,//ADC bias EN + 0xA7,0x07, + 0xAE,0x07, + 0xB5,0x07, + + 0xBC,0x38,// 0x28 20dB 0x34 26dB + 0xBD,0x38, + 0xBE,0x38, + 0xBF,0x38, + + 0x30,0x14,//14 24bit 0a 16bit + 0x31,0x07,//frame (n+1)*8 bit 32+32=64 + 0x32,0x07,// + 0x33,0x1F,//sys width 32 clk + 0x34,0x1F, + 0x35,0xA2,// TX left justified i2s1+i2s2 + 0x36,0x00,// config for right justified ignored. + 0x37,0x00,// RX left justified. + 0x38,0x00,// config for right justified ignored. + 0x39,0x08, // ADC12 0n DATA1.ADC34 On DATA2 + 0x3A,0x00,//Slot1 + 0x3B,0x00,//slot2 + 0x3C,0x00,//slot3 + 0x3D,0x00,//slot4 + 0x3E,0x1F,//slot4 + + 0x16,0x00, // Use DC Filter for ADCs + + 0x80,0x03,// MCLK + 0x81,0x01,// LRCLK BCLK RX Pull down + 0x82,0x3F,// LRCLK BCLK RX + 0x83,0x0F,// LRCLK BCLK +/* +// PLL config + + 0x08,0x00,// disable MCLK + + 0x09,0x40,// I2S TX Bit Clock + + 0x60,0xF8, //reset and Disable PLL1 + + 0x61,0xDF,// + 0x62,0x01, + 0x63,0x01, +//{0x64,0x90}, +//{0x65,0x24}, + 0x66,0x80, + 0x67,0x02, +//{0x68,0x0}, +//{0x69,0x0}, + // enable PLL1 + + 0x60,0xFB,//delay for PLL locked + 0x60,0xFB, + 0x60,0xFB, + 0x60,0xFB, + 0x60,0xFB, + 0x60,0xFB, + +// end PLL config +*/ + + 0x0F,0x01, //RST,clears DSP,audio data interface values + 0x0F,0x01, //repeat write is let chip has more time to RST + 0x0F,0x01, + 0x0F,0x01, + + 0x08,0x00,// disable MCLK to chip + 0x0C,0x0A,// Clocks gated + 0x09,0x02, + + + 0x0F,0x00,//clear RST + //0x08,0x30,// enable MCLK to chip + //0x08,0x38, + 0x08,0x20, + 0x09,0x03, + + 0x10,0x00, // Disable all ADC clocks + 0x11,0x10, // Disable all ADC and Mixer + 0x10,0x1F, // Enable all ADC clocks and ADC digital + 0x11,0x1F, // Enable all ADC and set 16k sample rate + 0x10,0x5F, // Enable all ADC clocks, ADC digital and ADC Mic Clock Gate + +}; + +const char codec_config_param_normal_mode_simple[]= +{ + // mic pga 增益 + // 4通道录音工具 + 0xBC,0x28,// 0x28 20dB 0x34 26dB + 0xBD,0x28, + 0xBE,0x28, + 0xBF,0x28, + + 0x60,0x04, + 0x66,0x00, + 0x67,0x02, + + //PAD配置 + 0x80,0x03,// MCLK 为输入 + 0x83,0x0F,// LRCLK BCLK 为输入脚,TX1 TX2为输出脚 + + //0x08,0x30,// MCLK 作为输入 + //0x08,0x38,// MCLK divisor 生效 + 0x08,0x20,// MCLK 作为输入 12.288MHz + 0x09,0x03,// 选MCLK作为PLL输入源 + 0x0a,0x0b, + 0x0a,0x8b, + 0x0C,0x0A,// RT clock disable, TX clock enable, enable clock to ADC3/4 + + // I2S + //0x30,0x0A,// Tx sample size:16bit, Normal mode + 0x30,0x14,// Tx sample size:24bit, Normal mode + 0x35,0xA2,// left justified, enable I2S-1 and I2S-2 + + 0x10,0x00, + 0x11,0x00, + 0x10,0x1F, + 0x11,0x1F,// ADC 96k, enables all ADCs + 0x16,0x00, + 0x10,0x5F, + +}; + +const char codec3_config_param_normal_mode[]= +{ + // POWER + 0x78,0x39, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x39, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x39, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x39, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x39, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + + 0x78,0x79, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x79, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x79, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x79, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + 0x78,0x79, //*PLLEN = 1 ABIASEN IOBUFEN REFIMP = 11 3KR + + 0x7A,0x01, + 0x01,0x01, + + // Analog ADC Control + // MIcIn PGA A0,A7,AE,B5 [5:4] ctrl_rcm , [1] enable [3] mute [7] bypass + // 模拟部分电源 + 0xA0,0x07,//ADC bias EN + 0xA7,0x07, + 0xAE,0x07, + 0xB5,0x07, + + // mic pga 增益 + // 4通道录音工具 + 0xBC,0x06,// 0x28 20dB 0x34 26dB + 0xBD,0x06, + 0xBE,0x0C, + 0xBF,0x14, + + 0x60,0x04, + 0x66,0x00, + 0x67,0x02, + + //PAD配置 + 0x80,0x03,// MCLK 为输入 + 0x83,0x0F,// LRCLK BCLK 为输入脚,TX1 TX2为输出脚 + + //0x08,0x30,// MCLK 作为输入 + //0x08,0x38,// MCLK divisor 生效 + 0x08,0x20,// MCLK 作为输入 12.288MHz + 0x09,0x03,// 选MCLK作为PLL输入源 + 0x0a,0x0b, + 0x0a,0x8b, + 0x0C,0x0A,// RT clock disable, TX clock enable, enable clock to ADC3/4 + + // I2S + //0x30,0x0A,// Tx sample size:16bit, Normal mode + 0x30,0x14,// Tx sample size:24bit, Normal mode + 0x35,0xA2,// left justified, enable I2S-1 and I2S-2 + + 0x10,0x00, + 0x11,0x00, + 0x10,0x1F, + 0x11,0x1F,// ADC 96k, enables all ADCs + 0x16,0x00, + 0x10,0x5F, + +}; + +const char codec3_config_param_normal_mode_simple[]= +{ + // mic pga 增益 + // 4通道录音工具 + 0xBC,0x28,// 0x28 20dB 0x34 26dB + 0xBD,0x28, + 0xBE,0x28, + 0xBF,0x28, + + 0x60,0x04, + 0x66,0x00, + 0x67,0x02, + + //PAD配置 + 0x80,0x03,// MCLK 为输入 + 0x83,0x0F,// LRCLK BCLK 为输入脚,TX1 TX2为输出脚 + + //0x08,0x30,// MCLK 作为输入 + //0x08,0x38,// MCLK divisor 生效 + 0x08,0x20,// MCLK 作为输入 12.288MHz + 0x09,0x03,// 选MCLK作为PLL输入源 + 0x0a,0x0b, + 0x0a,0x8b, + 0x0C,0x0A,// RT clock disable, TX clock enable, enable clock to ADC3/4 + + // I2S + //0x30,0x0A,// Tx sample size:16bit, Normal mode + 0x30,0x14,// Tx sample size:24bit, Normal mode + 0x35,0xA2,// left justified, enable I2S-1 and I2S-2 + + 0x10,0x00, + 0x11,0x00, + 0x10,0x1F, + 0x11,0x1F,// ADC 96k, enables all ADCs + 0x16,0x00, + 0x10,0x5F, +}; + +const char codec_config_param_48k_16bit_mode[]= +{ + // mic pga 增益 + // 4通道录音工具 + 0xBC,29 << 1,// 0x28 20dB 0x34 26dB + 0xBD,29 << 1, + 0xBE,29 << 1, + 0xBF,29 << 1, + + 0x60,0x04, + 0x66,0x00, + 0x67,0x02, + + //PAD配置 + 0x80,0x03,// MCLK 为输入 + 0x83,0x0F,// LRCLK BCLK 为输入脚,TX1 TX2为输出脚 + + //0x08,0x30,// MCLK 作为输入 + //0x08,0x38,// MCLK divisor 生效 + 0x08,0x20,// MCLK 作为输入 12.288MHz + 0x09,0x03,//选MCLK作为PLL输入源 + 0x0a,0x03, + 0x0a,0x83, + 0x0C,0x0A,// RT clock disable, TX clock enable, enable clock to ADC3/4 + + // I2S + 0x30,0x0A,// Tx sample size:16bit, Normal mode + //0x30,0x14,// Tx sample size:24bit, Normal mode + 0x35,0xA2,// left justified, enable I2S-1 and I2S-2 + + 0x10,0x00, + 0x11,0x00, + 0x10,0x1F, + 0x11,0x4F,// ADC 96k, enables all ADCs + 0x16,0x00, + 0x10,0x5F, +}; + +const char codec_config_param_96k_16bit_mode[]= +{ + // mic pga 增益 + // 4通道录音工具 + 0xBC,29 << 1,// 0x28 20dB 0x34 26dB + 0xBD,29 << 1, + 0xBE,29 << 1, + 0xBF,29 << 1, + + 0x60,0x04, + 0x66,0x00, + 0x67,0x02, + + //PAD配置 + 0x80,0x03,// MCLK 为输入 + 0x83,0x0F,// LRCLK BCLK 为输入脚,TX1 TX2为输出脚 + + //0x08,0x30,// MCLK 作为输入 + //0x08,0x38,// MCLK divisor 生效 + 0x08,0x20,// MCLK 作为输入 12.288MHz + 0x09,0x03,// 选MCLK作为PLL输入源 + 0x0a,0x01, + 0x0a,0x81, + 0x0C,0x0A,// RT clock disable, TX clock enable, enable clock to ADC3/4 + + // I2S + 0x30,0x0A,// Tx sample size:16bit, Normal mode + //0x30,0x14,// Tx sample size:24bit, Normal mode + 0x35,0xA2,// left justified, enable I2S-1 and I2S-2 + + 0x10,0x00, + 0x11,0x00, + 0x10,0x1F, + 0x11,0x5F,// ADC 96k, enables all ADCs + 0x16,0x00, + 0x10,0x5F, +}; + +#endif /* CX20810_CONFIG_H_ */ diff --git a/lichee/linux-4.9/drivers/misc/xunfei/cpld/fpga_config.c b/lichee/linux-4.9/drivers/misc/xunfei/cpld/fpga_config.c new file mode 100755 index 000000000..569dd40d4 --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/xunfei/cpld/fpga_config.c @@ -0,0 +1,428 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +// unsigned char toupad_get_key(void); +// void tipa_set_vol(unsigned char abs_vol); +int at_8740_write(unsigned char *pbuf, unsigned int len); +int at_8740_read(unsigned char *pbuf, unsigned int len); +void at_8740_wakeup(void); + +static unsigned int map_io_base; +#define D_IO_BASE map_io_base +#define D_IO_BASE_PHY (0x01c20800) +#define D_IO_LEN (0x400) +#define D_IO_A (0) +#define D_IO_B (1) +#define D_IO_C (2) +#define D_IO_D (3) +#define D_IO_E (4) +#define D_IO_F (5) +#define D_IO_G (6) +#define D_IO_H (7) +#define D_IO_I (8) +#define D_IO_CFG0(x) (D_IO_BASE + (x * 0x24) + 0x00) +#define D_IO_CFG1(x) (D_IO_BASE + (x * 0x24) + 0x04) +#define D_IO_CFG2(x) (D_IO_BASE + (x * 0x24) + 0x08) +#define D_IO_CFG3(x) (D_IO_BASE + (x * 0x24) + 0x0c) +#define D_IO_DAT(x) (D_IO_BASE + (x * 0x24) + 0x10) +#define D_IO_DRV0(x) (D_IO_BASE + (x * 0x24) + 0x14) +#define D_IO_DRV1(x) (D_IO_BASE + (x * 0x24) + 0x18) +#define D_IO_PUL0(x) (D_IO_BASE + (x * 0x24) + 0x1c) +#define D_IO_PUL1(x) (D_IO_BASE + (x * 0x24) + 0x20) + +int cx20810_set_mode(int mode, int index); + +typedef struct { + unsigned int opcode; + unsigned int param[3]; +} t_data_unit; + +enum { + eDU_RESVER = 0, + eDU_IVW_PRESET_TIME, + eDU_REC_TYPE, + eDU_IVW_POS_INFO, + eDU_MAX +}; + +t_data_unit database[eDU_MAX]; + +static int major_num; +static struct class *p_class; +static struct device *p_fpga; +static struct device *p_reg_debug; +static struct device *p_dsp_settings; +static struct device *p_au; +static struct device *p_tk; +static struct device *p_vol; +static struct device *p_vol2; +static struct device *p_8740; +static struct device *p_8740_wakeup; + +static unsigned int param_config; + +static struct kset *kset_vendor; +static struct kobject kobj_pa; + +static ssize_t gen_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) { + strcpy(buf, "wocao"); + return strlen(buf); +} + +static ssize_t gen_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) { + int i = simple_strtol(buf, (char **)(buf + strlen(buf) - 1), 0); + printk("vol=%ddb", i); + // tipa_set_vol(2 * (24-i)); + return count; +} + +struct attribute gen_vol_set = { + .name = "vol_set", + .mode = S_IRWXUGO, +}; + +struct attribute *gen_attr_group[] = { + &gen_vol_set, + NULL, +}; + +static const struct sysfs_ops gen_ops = { + .show = gen_attr_show, + .store = gen_attr_store, +}; + +static void gen_release(struct kobject *k) { + // nothing to do +} + +static struct kobj_type gen_ktype = { + .sysfs_ops = &gen_ops, + .default_attrs = gen_attr_group, + .release = gen_release, +}; + +static int gp_open(struct inode *pnode, struct file *pfile) { + int major = MAJOR(pnode->i_rdev); + int minor = MINOR(pnode->i_rdev); + + if (minor == 0) { + pfile->private_data = (void *)p_fpga; + } else if (minor == 1) { + pfile->private_data = (void *)p_reg_debug; + } else if (minor == 2) { + pfile->private_data = (void *)p_dsp_settings; + } else if (minor == 3) { + pfile->private_data = (void *)p_au; + } else if (minor == 4) { + pfile->private_data = (void *)p_tk; + } else if (minor == 5) { + pfile->private_data = (void *)p_vol; + } + // else if(minor == 6) + // { + // pfile->private_data = (void*)p_8740; + // } + // else if(minor == 7) + // { + // pfile->private_data = (void*)p_8740_wakeup; + // } + else { + pfile->private_data = NULL; + } + + return 0; +} + +static int gp_close(struct inode *pnode, struct file *pfile) { return 0; } + +static ssize_t gp_read(struct file *pfile, char __user *puser, size_t len, + loff_t *poff) { + if (pfile->private_data == p_fpga) { + return 0; + } else if (pfile->private_data == p_reg_debug) { + unsigned int base_addr = (unsigned int)ioremap(0x1C22400, 0x100); + unsigned int i; + for (i = 0; i <= 0x3C; i += 4) { + printk("[i2s1] addr:0x%x val:0x%x\r\n", base_addr + i, + *((unsigned int *)(base_addr + i))); + } + return len; + } else if (pfile->private_data == p_au) { + t_data_unit tmp_data; + copy_from_user((void *)&tmp_data, puser, len); + if (tmp_data.opcode < eDU_MAX) { + copy_to_user(puser, &database[tmp_data.opcode], + sizeof(t_data_unit)); + return len; + } else { + return 0; + } + } + // else if(pfile->private_data == p_tk) + // { + // unsigned char tmp = toupad_get_key(); + // copy_to_user(puser, &tmp, sizeof(unsigned char)); + // return len; + // } + // else if(pfile->private_data == p_8740) + // { + // unsigned char * pbuf; + // pbuf = kmalloc(len, GFP_KERNEL); + // printk("8740 nread:%d\r\n", at_8740_read(pbuf, len)); + // copy_to_user(puser, pbuf, len); + // kfree(pbuf); + // return len; + // } + // else if(pfile->private_data == p_8740_wakeup) + // { + // return len; + // } + return 0; +} + +enum { + CX20810_NORMAL_MODE = 0, + CX20810_NORMAL_MODE_SIMPLE, + CX20810_NIRMAL_MODE_CODEC3, + CX20810_NIRMAL_MODE_CODEC3_SIMPLE, + CX20810_96K_16BIT_MODE, + CX20810_48K_16BIT_MODE, +}; + +static ssize_t gp_write(struct file *pfile, const char __user *puser, + size_t len, loff_t *poff) { + if (pfile->private_data == p_fpga) { + copy_from_user((void *)¶m_config, puser, len); + switch (param_config) { + case 0: + printk("fpga_config:mode0\r\n"); + // cx20810_set_mode(CX20810_NORMAL_MODE, 0); + // cx20810_set_mode(CX20810_NORMAL_MODE, 1); + // cx20810_set_mode(CX20810_NORMAL_MODE, 2); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x7000000) | + // 0x1000000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) & ~(1 << 6)), + // D_IO_DAT(D_IO_D)); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x7000) | + // 0x1000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) & ~(1 << 3)), + // D_IO_DAT(D_IO_D)); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x70000) | + // 0x10000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) & ~(1 << 4)), + // D_IO_DAT(D_IO_D)); + writel((readl(D_IO_CFG0(D_IO_E)) & ~0x70000) | 0x10000, + D_IO_CFG0(D_IO_E)); + writel((readl(D_IO_DAT(D_IO_E)) & ~(1 << 4)), D_IO_DAT(D_IO_E)); + writel((readl(D_IO_CFG0(D_IO_H)) & ~0x70000000) | 0x10000000, + D_IO_CFG0(D_IO_H)); + writel((readl(D_IO_DAT(D_IO_H)) & ~(1 << 7)), D_IO_DAT(D_IO_H)); + writel((readl(D_IO_CFG0(D_IO_E)) & ~0x7000) | 0x1000, + D_IO_CFG0(D_IO_E)); + writel((readl(D_IO_DAT(D_IO_E)) & ~(1 << 3)), D_IO_DAT(D_IO_E)); + break; + case 1: + printk("fpga_config:mode1\r\n"); + cx20810_set_mode(CX20810_96K_16BIT_MODE, 1); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x7000000) | + // 0x1000000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) & ~(1 << 6)), + // D_IO_DAT(D_IO_D)); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x7000) | + // 0x1000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) | (1 << 3)), + // D_IO_DAT(D_IO_D)); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x70000) | + // 0x10000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) & ~(1 << 4)), + // D_IO_DAT(D_IO_D)); + writel((readl(D_IO_CFG0(D_IO_E)) & ~0x70000) | 0x10000, + D_IO_CFG0(D_IO_E)); + writel((readl(D_IO_DAT(D_IO_E)) & ~(1 << 4)), D_IO_DAT(D_IO_E)); + writel((readl(D_IO_CFG0(D_IO_H)) & ~0x70000000) | 0x10000000, + D_IO_CFG0(D_IO_H)); + writel((readl(D_IO_DAT(D_IO_H)) & ~(1 << 7)), D_IO_DAT(D_IO_H)); + writel((readl(D_IO_CFG0(D_IO_E)) & ~0x7000) | 0x1000, + D_IO_CFG0(D_IO_E)); + writel((readl(D_IO_DAT(D_IO_E)) | (1 << 3)), D_IO_DAT(D_IO_E)); + break; + case 2: + printk("fpga_config:mode2\r\n"); + cx20810_set_mode(CX20810_48K_16BIT_MODE, 0); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x7000000) | + // 0x1000000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) & ~(1 << 6)), + // D_IO_DAT(D_IO_D)); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x7000) | + // 0x1000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) & ~(1 << 3)), + // D_IO_DAT(D_IO_D)); + // writel((readl(D_IO_CFG0(D_IO_D)) & ~0x70000) | + // 0x10000, D_IO_CFG0(D_IO_D)); + // writel((readl(D_IO_DAT(D_IO_D)) | (1 << 4)), + // D_IO_DAT(D_IO_D)); + writel((readl(D_IO_CFG0(D_IO_E)) & ~0x70000) | 0x10000, + D_IO_CFG0(D_IO_E)); + writel((readl(D_IO_DAT(D_IO_E)) & ~(1 << 4)), D_IO_DAT(D_IO_E)); + writel((readl(D_IO_CFG0(D_IO_H)) & ~0x70000000) | 0x10000000, + D_IO_CFG0(D_IO_H)); + writel((readl(D_IO_DAT(D_IO_H)) | (1 << 7)), D_IO_DAT(D_IO_H)); + writel((readl(D_IO_CFG0(D_IO_E)) & ~0x7000) | 0x1000, + D_IO_CFG0(D_IO_E)); + writel((readl(D_IO_DAT(D_IO_E)) & ~(1 << 3)), D_IO_DAT(D_IO_E)); + break; + default: + break; + } + return len; + } else if (pfile->private_data == p_reg_debug) { + return len; + } else if (pfile->private_data == p_dsp_settings) { + return len; + } else if (pfile->private_data == p_au) { + t_data_unit tmp_data; + copy_from_user((void *)&tmp_data, puser, len); + if (tmp_data.opcode < eDU_MAX) { + memcpy(&database[tmp_data.opcode], &tmp_data, sizeof(t_data_unit)); + return len; + } else { + return 0; + } + } else if (pfile->private_data == p_vol) { + unsigned char tmp; + copy_from_user((void *)&tmp, puser, len); + // tipa_set_vol(tmp); + return len; + } + // else if(pfile->private_data == p_8740) + // { + // unsigned char * pbuf; + // pbuf = kmalloc(len, GFP_KERNEL); + // copy_from_user((void*)pbuf, puser, len); + // printk("8740 nwrite:%d\r\n", at_8740_write(pbuf, len)); + // kfree(pbuf); + // return len; + // } + // else if(pfile->private_data == p_8740_wakeup) + // { + // printk("8740 wakeup\r\n"); + // at_8740_wakeup(); + // return len; + // } + else { + } + return 0; +} + +static struct file_operations gp_fops = { + .owner = THIS_MODULE, + .open = gp_open, + .release = gp_close, + .read = gp_read, + .write = gp_write, +}; + +static int __init fpga_config_init(void) { + D_IO_BASE = (unsigned int)ioremap(D_IO_BASE_PHY, D_IO_LEN); + if (!D_IO_BASE) { + printk("[gen_prov] init gpio err\r\n"); + return; + } + + kset_vendor = kset_create_and_add("vendor", NULL, NULL); + kobj_pa.kset = kset_vendor; + kobject_init_and_add(&kobj_pa, &gen_ktype, NULL, "pa"); + + major_num = register_chrdev(0, "fpga_chr", &gp_fops); + if (major_num < 0) { + printk("reg_chr_err\n"); + return 1; + } + + p_class = class_create(THIS_MODULE, "fpga_class"); + if (p_class == NULL) { + printk("class create err\n"); + return 1; + } + + p_fpga = + device_create(p_class, NULL, MKDEV(major_num, 0), NULL, "fpga_config"); + if (p_fpga == NULL) { + printk("device_create err:fpga\n"); + return 1; + } + + p_reg_debug = + device_create(p_class, NULL, MKDEV(major_num, 1), NULL, "reg_debug"); + if (p_reg_debug == NULL) { + printk("device_create err:reg_debug\n"); + return 1; + } + + p_dsp_settings = + device_create(p_class, NULL, MKDEV(major_num, 2), NULL, "dsp_settings"); + if (p_dsp_settings == NULL) { + printk("device_create err:p_dsp_settings\n"); + return 1; + } + + p_au = device_create(p_class, NULL, MKDEV(major_num, 3), NULL, "au_base"); + if (p_au == NULL) { + printk("device_create err:au_base\n"); + return 1; + } + + p_tk = device_create(p_class, NULL, MKDEV(major_num, 4), NULL, "touch_key"); + if (p_tk == NULL) { + printk("device_create err:touch_key\n"); + return 1; + } + + p_vol = device_create(p_class, NULL, MKDEV(major_num, 5), NULL, "vbox_vol"); + if (p_vol == NULL) { + printk("device_create err:vbox_vol\n"); + return 1; + } + + // p_8740 = device_create(p_class, NULL, MKDEV(major_num, 6), NULL, + // "atml_sec"); if(p_8740 == NULL) + // { + // printk("device_create err:p_8740\n"); + // return 1; + // } + + // p_8740_wakeup = device_create(p_class, NULL, MKDEV(major_num, 7), + // NULL, "atml_sec_wake"); if(p_8740_wakeup == NULL) + // { + // printk("device_create err:p_8740\n"); + // return 1; + // } + + return 0; +} +//module_init(fpga_config_init); + +static void __exit fpga_config_exit(void) {} +module_exit(fpga_config_exit); + +/* Module information */ +MODULE_AUTHOR("feitao"); +MODULE_DESCRIPTION("fpga config"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:fpga"); diff --git a/lichee/linux-4.9/drivers/misc/xunfei/cpld/fpga_loader.c b/lichee/linux-4.9/drivers/misc/xunfei/cpld/fpga_loader.c new file mode 100755 index 000000000..e476faf71 --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/xunfei/cpld/fpga_loader.c @@ -0,0 +1,267 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// mem define +static unsigned int map_io_base; +#define D_IO_BASE map_io_base +#define D_IO_BASE_PHY (0x01c20800) +#define D_IO_LEN (0x400) +#define D_IO_A (0) +#define D_IO_B (1) +#define D_IO_C (2) +#define D_IO_D (3) +#define D_IO_E (4) +#define D_IO_F (5) +#define D_IO_G (6) +#define D_IO_H (7) +#define D_IO_I (8) +#define D_IO_CFG0(x) (D_IO_BASE + (x * 0x24) + 0x00) +#define D_IO_CFG1(x) (D_IO_BASE + (x * 0x24) + 0x04) +#define D_IO_CFG2(x) (D_IO_BASE + (x * 0x24) + 0x08) +#define D_IO_CFG3(x) (D_IO_BASE + (x * 0x24) + 0x0c) +#define D_IO_DAT(x) (D_IO_BASE + (x * 0x24) + 0x10) +#define D_IO_DRV0(x) (D_IO_BASE + (x * 0x24) + 0x14) +#define D_IO_DRV1(x) (D_IO_BASE + (x * 0x24) + 0x18) +#define D_IO_PUL0(x) (D_IO_BASE + (x * 0x24) + 0x1c) +#define D_IO_PUL1(x) (D_IO_BASE + (x * 0x24) + 0x20) + +static struct i2c_client *fpga_client = NULL; +static const struct i2c_device_id i2c_driver_fpga_id[] = {{"i2c_fpga", 0}, {}}; +MODULE_DEVICE_TABLE(i2c, i2c_driver_fpga_id); + +static unsigned char fpga_refresh_command[] = {0x79, 0x00, 0x00}; + +static unsigned char fpga_none_command[] = {0xff, 0xff, 0xff, 0xff}; + +static const unsigned short i2c_fpga_addr[] = {0x40, I2C_CLIENT_END}; + +static struct delayed_work fpga_reset_work; + +static struct i2c_msg *i2c_recev_msg; +static int current_msg_pos; + +static void fpga_hw_init(void) { + printk("fpga_loader.c->fpga_hw_init()\n"); + + if (!D_IO_BASE) { + // printk("Timothy:D_IO_BASE is not initial yet, initial it now\n"); + D_IO_BASE = (unsigned int)ioremap(D_IO_BASE_PHY, D_IO_LEN); + if (!D_IO_BASE) { + printk("fpga loader hardware init io error\n"); + return -1; + } + } +} + +// set reset for fpga +// enable = 1:set ph7 high +// enable = 0:set ph7 low +static void set_fpga_reset(int enable) { + // printk("Timothy:fpga_loader.c->set_fpga_reset()\n"); + if (1 == enable) { + writel(readl(D_IO_DAT(D_IO_H)) | (1 << 8), D_IO_DAT(D_IO_H)); + } else { + writel(readl(D_IO_DAT(D_IO_H)) & ~(1 << 8), D_IO_DAT(D_IO_H)); + } +} + +int send_to_device(char *data, int count) { + // //printk("Timothy:fpga_loader.c->send_to_device(), count = %d\n", + //count); + int nwrite; + int i; + + if (data[0] == 0) // STOP causes this, send stop + { + // printk("the data send to device is:"); + // for(i = 1; i < count; i++) + // { + // printk("%x ", data[i]); + // } + // printk("\n"); + nwrite = i2c_master_send(fpga_client, &data[1], count - 1); + if (nwrite != count - 1) { + // printk("Timothy:not write enough, nwrite = %d, count = %d\n", + // nwrite, count); + } else { + // //printk("Timothy:write success, count = %d\n", + //count); + } + return nwrite; + } else if (data[0] == + 1) // RESTART causes this, do not send stop, just put int in buf + { + if (current_msg_pos >= 8) { + // printk("Timothy:buf is overflow, quit"); + return -2; + } + // //printk("Timothy:the data add to buf is:"); + // for(i = 1; i < count; i++) + // { + // printk("%x ", data[i]); + // } + // printk("\n"); + i2c_recev_msg[current_msg_pos].addr = i2c_fpga_addr[0]; + i2c_recev_msg[current_msg_pos].len = count - 1; + i2c_recev_msg[current_msg_pos].buf = (unsigned char *)kzalloc( + i2c_recev_msg[current_msg_pos].len * sizeof(unsigned char), + GFP_KERNEL); + memcpy(i2c_recev_msg[current_msg_pos].buf, &data[1], + i2c_recev_msg[current_msg_pos].len); + current_msg_pos++; + return count - 1; + } else if (data[0] == 2) { + // printk("Timothy:send refresh command now\n"); + nwrite = i2c_master_send(fpga_client, fpga_refresh_command, 3); + return nwrite; + } else if (data[0] == 3) { + // printk("Timothy:send none command now\n"); + nwrite = i2c_master_send(fpga_client, fpga_none_command, 4); + nwrite = i2c_master_send(fpga_client, fpga_none_command, 4); + return nwrite; + } else { + // printk("Timothy:unknow flag for send"); + return -1; + } +} + +EXPORT_SYMBOL(send_to_device); + +int receive_from_device(char *data, int count) { + // //printk("Timothy:fpga_loader.c->receive_from_device()\n"); + int nread; + int i, j; + + if (current_msg_pos >= 8) { + // printk("Timothy:buf is overflow, quit"); + return -2; + } + i2c_recev_msg[current_msg_pos].addr = i2c_fpga_addr[0]; + i2c_recev_msg[current_msg_pos].flags = I2C_M_RD | I2C_M_NO_RD_ACK; + i2c_recev_msg[current_msg_pos].len = count; + i2c_recev_msg[current_msg_pos].buf = data; + current_msg_pos++; + + // //printk("Timothy:the data send before read is:"); + // for(i = 0; i < current_msg_pos-1; i++) + // { + // for(j = 0; j < i2c_recev_msg[i].len; j++) + // { + // printk("%x ", i2c_recev_msg[i].buf[j]); + // } + // } + // printk("\n"); + + nread = i2c_transfer(fpga_client->adapter, i2c_recev_msg, current_msg_pos); + + if (nread != current_msg_pos) { + // printk("Timothy:not read enough, nread = %d, current_msg_pos = %d\n", + // nread, current_msg_pos); + } else { + // //printk("Timothy:read success, current_msg_pos = %d\n", + //current_msg_pos); + } + + // //printk("Timothy:the data read from i2c is:"); + // for(i = 0; i < count; i++) + // { + // printk("%x, ", data[i]); + // } + // printk("\n"); + for (i = 0; i < current_msg_pos - 1; i++) { + if (i2c_recev_msg[i].buf) { + kfree(i2c_recev_msg[i].buf); + i2c_recev_msg[i].buf = NULL; + } + } + current_msg_pos = 0; + + return count; +} + +EXPORT_SYMBOL(receive_from_device); + +static int i2c_driver_fpga_probe(struct i2c_client *client, + const struct i2c_device_id *id) { + // printk("Timothy:fpga_loader.c->i2c_driver_fpga_probe()\n"); + if ((client->addr == i2c_fpga_addr[0])) { + fpga_client = client; + // printk("Timothy:fpga (%x) init ok\n", client->addr); + } + return 0; +} + +static int i2c_driver_fpga_remove(struct i2c_client *client) { + // printk("Timothy:fpga_loader.c->i2c_driver_fpga_remove()\n"); + return 0; +} + +static int i2c_driver_fpga_detect(struct i2c_client *client, + struct i2c_board_info *info) { + // printk("Timothy:fpga_loader.c->i2c_driver_fpga_detect()\n"); + struct i2c_adapter *p_adapter; + const char *type_name = "i2c_fpga"; + p_adapter = client->adapter; + // printk("Timothy:adapter->nr = %d\n", p_adapter->nr); + if (2 == p_adapter->nr) { + if (info->addr == i2c_fpga_addr[0]) { + // printk("Timothy:detect fpga (%x) on i2c adapter (%d)\n", + // info->addr, p_adapter->nr); + strlcpy(info->type, type_name, I2C_NAME_SIZE); + return 0; + } + } + return ENODEV; +} + +static struct i2c_driver i2c_driver_fpga = {.class = I2C_CLASS_HWMON, + .probe = i2c_driver_fpga_probe, + .remove = i2c_driver_fpga_remove, + .id_table = i2c_driver_fpga_id, + .driver = + { + .name = "i2c_fpga", + .owner = THIS_MODULE, + }, + .detect = i2c_driver_fpga_detect, + .address_list = i2c_fpga_addr}; + +static int __init i2c_driver_fpga_init(void) { + // printk("Timothy:fpga_loader.c->i2c_driver_fpga_init()\n"); + fpga_hw_init(); + i2c_recev_msg = + (struct i2c_msg *)kzalloc(8 * sizeof(struct i2c_msg), GFP_KERNEL); + current_msg_pos = 0; + + return i2c_add_driver(&i2c_driver_fpga); +} + +static void __exit i2c_driver_fpga_exit(void) { + // printk("Timothy:fpga_loader.c->i2c_driver_fpga_exit()\n"); + if (i2c_recev_msg) { + kfree(i2c_recev_msg); + i2c_recev_msg = NULL; + } + current_msg_pos = 0; + i2c_del_driver(&i2c_driver_fpga); +} + +module_init(i2c_driver_fpga_init); +module_exit(i2c_driver_fpga_exit); + +MODULE_AUTHOR("Timothy"); +MODULE_DESCRIPTION("I2C device fpga loader"); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/lichee/linux-4.9/drivers/misc/xunfei/cpld/i2c_operator.c b/lichee/linux-4.9/drivers/misc/xunfei/cpld/i2c_operator.c new file mode 100755 index 000000000..5f007eec1 --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/xunfei/cpld/i2c_operator.c @@ -0,0 +1,313 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GP_CLASS_NAME "i2c_operator" +#define GP_CHR_DEV_NAME "i2c_operator" +#define GP_I2C_DEV_NAME "i2c_operator_device" + +struct i2c_ioctl_msg { + int i2c_index; + int reg_addr; + int reg_val; +}; + +#define MAGIC_NUM 'A' +#define CMD_I2C_SET _IOW(MAGIC_NUM, 0, struct i2c_ioctl_msg) +#define CMD_I2C_GET _IOR(MAGIC_NUM, 1, struct i2c_ioctl_msg) + +#define CMD_MAX (1) + +static unsigned int map_io_base; +#define D_IO_BASE map_io_base +#define D_IO_BASE_PHY (0x01c20800) +#define D_IO_LEN (0x400) +#define D_IO_B (1) +#define D_IO_C (2) +#define D_IO_D (3) +#define D_IO_E (4) +#define D_IO_F (5) +#define D_IO_G (6) +#define D_IO_H (7) +#define D_IO_CFG0(x) (D_IO_BASE + (x * 0x24) + 0x00) +#define D_IO_CFG1(x) (D_IO_BASE + (x * 0x24) + 0x04) +#define D_IO_CFG2(x) (D_IO_BASE + (x * 0x24) + 0x08) +#define D_IO_CFG3(x) (D_IO_BASE + (x * 0x24) + 0x0c) +#define D_IO_DAT(x) (D_IO_BASE + (x * 0x24) + 0x10) +#define D_IO_DRV0(x) (D_IO_BASE + (x * 0x24) + 0x14) +#define D_IO_DRV1(x) (D_IO_BASE + (x * 0x24) + 0x18) +#define D_IO_PUL0(x) (D_IO_BASE + (x * 0x24) + 0x1c) +#define D_IO_PUL1(x) (D_IO_BASE + (x * 0x24) + 0x20) + +static struct class *p_gp_class; +static struct device *p_class_i2c; +static int major_num; +static unsigned char *i2c_msg; + +int send_to_device(char *data, int count); + +int receive_from_device(char *data, int count); +int cx20810_set_mode(int mode, int index); +// int led_array_set_mode(unsigned char * param, int length); +int led_array_set_enable(int enable); + +int cx20810_write_reg(int index, int addr, int regval); +int cx20810_read_reg(int index, int cmd, int *regval); + +enum { + I2C_DEVICE_FPGA = 0, + I2C_DEVICE_CX20810, + I2C_DEVICE_CX20810_0, + I2C_DEVICE_CX20810_1, + I2C_DEVICE_CX20810_2, + I2C_DEVICE_LED_ARRAY, +}; + +static void gp_hw_init(void) { + printk("i2c_operator.c->gp_hw_init()\n"); + + if (!D_IO_BASE) { + // printk("Timothy:D_IO_BASE is not initial yet, initial it now\n"); + D_IO_BASE = (unsigned int)ioremap(D_IO_BASE_PHY, D_IO_LEN); + if (!D_IO_BASE) { + printk("led array hardware init io error\n"); + return -1; + } + } + + // set pe6 output and set it high to open mute led + // writel(readl(D_IO_CFG0(D_IO_E)) & (~(0x7<<24)) | (0x1<<24), + // D_IO_CFG0(D_IO_E)); writel(readl(D_IO_DAT(D_IO_E)) | 0x1<<6, + // D_IO_DAT(D_IO_E)); +} + +// add by Timothy +// time:2015-02-09 +// start========== +// i2c设备write处理 +static ssize_t gp_i2c_write_dispatch(int len) { + // //printk("Timothy:i2c_operator.c->gp_i2c_write_dispatch(), len = %d\n", + //len); + int ret = 0; + int i; + int device_index = (int)i2c_msg[0]; + int length = len - sizeof(char); + // //printk("Timothy:device_index = %d\n", device_index); + + // all 3 cx20810 + if (I2C_DEVICE_CX20810 == device_index) { + // //printk("Timothy:operate device:cx20810\n"); + for (i = 0; i < 3; i++) { + cx20810_set_mode((int)i2c_msg[1], i); + } + return 0; + } + + else if (I2C_DEVICE_CX20810_0 == device_index) { + // //printk("Timothy:operate device:cx20810_0\n"); + return cx20810_set_mode((int)i2c_msg[1], 0); + } else if (I2C_DEVICE_CX20810_1 == device_index) { + // //printk("Timothy:operate device:cx20810_1\n"); + return cx20810_set_mode((int)i2c_msg[1], 1); + } else if (I2C_DEVICE_CX20810_2 == device_index) { + // //printk("Timothy:operate device:cx20810_2\n"); + return cx20810_set_mode((int)i2c_msg[1], 2); + } + + // LED + // else if(I2C_DEVICE_LED_ARRAY == device_index) + // { + // //printk("Timothy:operate device:led_array\n"); + // return led_array_set_mode(&i2c_msg[1], length); + // } + + // FPGA + else if (I2C_DEVICE_FPGA == device_index) { + // //printk("Timothy:operate device:FPGA, data lendth is + //%d\n", length); + ret = send_to_device((char *)&i2c_msg[1], length); + return ret; + } + return -1; +} + +static int gp_i2c_read_dispatch(int len) { + // //printk("Timothy:i2c_operator.c->gp_i2c_read_dispatch()\n"); + int ret = 0; + int device_index = (int)i2c_msg[0]; + int length = len - sizeof(char); + // //printk("Timothy:device_index = %d\n", device_index); + if (I2C_DEVICE_FPGA == device_index) // FPGA + { + // //printk("Timothy:operate device:FPGA, data lendth is + //%d\n", length); + ret = receive_from_device((char *)&i2c_msg[1], length); + return ret; + } + return -1; +} +// end========== + +static int gp_open(struct inode *pnode, struct file *pfile) { + // printk("Timothy:i2c_operator.c->gp_open()\n"); + int major = MAJOR(pnode->i_rdev); + int minor = MINOR(pnode->i_rdev); + + if (minor == 0) { + pfile->private_data = (void *)p_class_i2c; + // printk("Timothy:gp_open_i2c\n"); + } else { + pfile->private_data = (void *)NULL; + // printk("Timothy:gp_open:unknow device\n"); + } + return 0; +} + +static int gp_close(struct inode *pnode, struct file *pfile) { + pfile->private_data = (void *)NULL; + printk("gp_close\n"); + return 0; +} + +static ssize_t gp_read(struct file *pfile, char __user *puser, size_t len, + loff_t *poff) { + int nread = 0; + int i; + // //printk("Timothy:i2c_operator.c->gp_read()\n"); + if (pfile->private_data == p_class_i2c) { + // //printk("Timothy:gp_read():i2c device\n"); + i2c_msg = + (unsigned char *)kzalloc(len * sizeof(unsigned char), GFP_KERNEL); + copy_from_user((void *)i2c_msg, puser, len); + nread = gp_i2c_read_dispatch(len); + // //printk("Timothy:the data will send to user is:%d\n", + //i2c_msg[1]); + copy_to_user(puser, (void *)i2c_msg, len); + kfree(i2c_msg); + } + // //printk("Timothy:return value is %d\n", nread); + return nread; +} + +static ssize_t gp_write(struct file *pfile, const char __user *puser, + size_t len, loff_t *poff) { + // //printk("Timothy:i2c_operator.c->gp_write()\n"); + int ret = 0; + int i; + if (pfile->private_data == p_class_i2c) { + // //printk("Timothy:gp_write():i2c device\n"); + i2c_msg = + (unsigned char *)kzalloc(len * sizeof(unsigned char), GFP_KERNEL); + copy_from_user((void *)i2c_msg, puser, len); + + // //printk("Timothy:the data is "); + // for(i = 0; i < len; i++) + // { + // printk("%x ", i2c_msg[i]); + // } + // printk("\n"); + ret = gp_i2c_write_dispatch(len); + kfree(i2c_msg); + } else { + // //printk("Timothy:gp_write_null\n"); + } + // //printk("Timothy:return value is %d\n", ret); + return ret; +} + +// file operations +static long gp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + u8 i; + int ret = 0; + struct i2c_ioctl_msg i2carg = {0}; + + printk("ioctl start cmd: %d arg: %lX\n", cmd, arg); + + if (_IOC_TYPE(cmd) != MAGIC_NUM) + return -EINVAL; + + if (_IOC_NR(cmd) > CMD_MAX) + return -EINVAL; + + printk("ioctl start\n"); + + switch (cmd) { + case CMD_I2C_SET: + ret = copy_from_user(&i2carg, (struct i2c_ioctl_msg *)arg, + sizeof(i2carg)); + if (0 == ret) { + printk("Will set i2c:%d reg:0x%x val:0x%x\n", i2carg.i2c_index, + i2carg.reg_addr, i2carg.reg_val); + } else { + printk("get user arg fail!\n"); + } + cx20810_write_reg(i2carg.i2c_index, i2carg.reg_addr, i2carg.reg_val); + break; + + case CMD_I2C_GET: + i2carg.reg_val = 0; + ret = copy_from_user(&i2carg, (struct i2c_ioctl_msg *)arg, + sizeof(i2carg)); + cx20810_read_reg(i2carg.i2c_index, i2carg.reg_addr, &(i2carg.reg_val)); + printk("Get i2c:%d reg:0x%x val:0x%x\n", i2carg.i2c_index, + i2carg.reg_addr, i2carg.reg_val); + ret = copy_to_user((void *)arg, &i2carg, sizeof(i2carg)); + + break; + + default: + break; + } + printk("ioctl end\n"); + + return ret; +} + +static struct file_operations gp_fops = { + .owner = THIS_MODULE, + .open = gp_open, + .release = gp_close, + .read = gp_read, + .write = gp_write, + .unlocked_ioctl = gp_ioctl, +}; + +static int __init i2c_operator_init(void) { + gp_hw_init(); + + major_num = register_chrdev(0, GP_CHR_DEV_NAME, &gp_fops); + if (major_num < 0) { + // printk("Timothy:gen_prov_reg_chr_err\n"); + return 1; + } + p_gp_class = class_create(THIS_MODULE, GP_CLASS_NAME); + if (p_gp_class == NULL) { + // printk("Timothy:gen_prov:class create err\n"); + } + + p_class_i2c = device_create(p_gp_class, NULL, MKDEV(major_num, 0), NULL, + GP_I2C_DEV_NAME); + if (p_class_i2c == NULL) { + // printk("Timothy:gen_prov:device_create err:i2c\n"); + return 1; + } +} + +static void __exit i2c_operator_exit(void) {} + +module_init(i2c_operator_init); +module_exit(i2c_operator_exit); + +MODULE_AUTHOR("Timothy"); +MODULE_DESCRIPTION("i2c operator driver"); +MODULE_LICENSE("GPL"); diff --git a/lichee/linux-4.9/drivers/misc/xunfei/cpld/netease_config.c b/lichee/linux-4.9/drivers/misc/xunfei/cpld/netease_config.c new file mode 100644 index 000000000..1b5d7ad35 --- /dev/null +++ b/lichee/linux-4.9/drivers/misc/xunfei/cpld/netease_config.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include + +static struct kset *netease_keyset = NULL; +static struct kobject cpld_ko; +extern int cx20810_set_mode(int mode, int index); +extern void netease_cpld_reset(void); + +enum { + CX20810_NORMAL_MODE = 0, + CX20810_NORMAL_MODE_SIMPLE, + CX20810_NIRMAL_MODE_CODEC3, + CX20810_NIRMAL_MODE_CODEC3_SIMPLE, + CX20810_96K_16BIT_MODE, + CX20810_48K_16BIT_MODE, +}; + +static ssize_t gen_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) { + int count = 0; + count += sprintf(buf, "Cpld init help:\n"); + count += sprintf(buf + count, "adc rst and config:echo 1 > cpld_init\n"); + count += sprintf(buf + count, "adc rst:echo 2 > cpld_init\n"); + count += sprintf(buf + count, "adc config:echo 3 > cpld_init\n"); + + return count; +} + +static ssize_t gen_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) { + long ret = -1; + kstrtol(buf, 10, &ret); + + switch (ret) { + case 1: + printk("Adc rst and config\n"); + netease_cpld_reset(); + cx20810_set_mode(CX20810_NORMAL_MODE, 0); + cx20810_set_mode(CX20810_NORMAL_MODE, 1); + break; + case 2: + printk("Adc rst\n"); + netease_cpld_reset(); + break; + case 3: + printk("Adc config\n"); + cx20810_set_mode(CX20810_NORMAL_MODE, 0); + cx20810_set_mode(CX20810_NORMAL_MODE, 1); + break; + default: + printk("Can not read your input cmd, need help? type cat cpld_init."); + } + + printk("Do finish, Get ret:%d, count:%d, input:%s\n", ret, count, buf); + // tipa_set_vol(2 * (24-i)); + return count; +} + +static const struct sysfs_ops cpld_ktype_ops = { + .show = gen_attr_show, + .store = gen_attr_store, +}; +struct attribute cpld_init_set = { + .name = "cpld_init", + .mode = S_IRWXUGO, +}; +struct attribute *cpld_attr_group[] = {&cpld_init_set, NULL}; + +void cpld_release(struct kobject *kobj) { + printk("wzj:release %d\n", kobj->name); +} + +static struct kobj_type cpld_ko_ktype = { + .sysfs_ops = &cpld_ktype_ops, + .default_attrs = cpld_attr_group, + .release = cpld_release, +}; + +static int __init netease_config_init(void) { + printk("Begin to start netease config!\n"); + netease_keyset = kset_create_and_add("netease", NULL, NULL); + + cpld_ko.kset = netease_keyset; + kobject_init_and_add(&cpld_ko, &cpld_ko_ktype, NULL, "cpld_control"); + + return 0; +} + +module_init(netease_config_init); + +static void __exit netease_config_exit(void) {} +module_exit(netease_config_exit); + +/* Module information */ +MODULE_AUTHOR("Wang zijiao"); +MODULE_DESCRIPTION("Netease config!"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:netease_config"); \ No newline at end of file diff --git a/lichee/linux-4.9/sound/soc/sunxi/sunxi-daudio.c b/lichee/linux-4.9/sound/soc/sunxi/sunxi-daudio.c index 51d63d35a..db2d420e4 100644 --- a/lichee/linux-4.9/sound/soc/sunxi/sunxi-daudio.c +++ b/lichee/linux-4.9/sound/soc/sunxi/sunxi-daudio.c @@ -12,25 +12,25 @@ * */ +#include +#include +#include +#include +#include #include #include -#include -#include #include -#include #include -#include -#include +#include #include +#include #include #include -#include #include -#include #include +#include +#include #include -#include -#include #include "sunxi-daudio.h" #include "sunxi-pcm.h" @@ -38,104 +38,104 @@ #include "sunxi-mad.h" #endif -#define DRV_NAME "sunxi-daudio" +#define DRV_NAME "sunxi-daudio" -#define SUNXI_DAUDIO_EXTERNAL_TYPE 1 -#define SUNXI_DAUDIO_TDMHDMI_TYPE 2 +#define SUNXI_DAUDIO_EXTERNAL_TYPE 1 +#define SUNXI_DAUDIO_TDMHDMI_TYPE 2 -#define SUNXI_DAUDIO_DRQDST(sunxi_daudio, x) \ - ((sunxi_daudio)->playback_dma_param.dma_drq_type_num = \ - DRQDST_DAUDIO_##x##_TX) -#define SUNXI_DAUDIO_DRQSRC(sunxi_daudio, x) \ - ((sunxi_daudio)->capture_dma_param.dma_drq_type_num = \ - DRQSRC_DAUDIO_##x##_RX) +#define SUNXI_DAUDIO_DRQDST(sunxi_daudio, x) \ + ((sunxi_daudio)->playback_dma_param.dma_drq_type_num = \ + DRQDST_DAUDIO_##x##_TX) +#define SUNXI_DAUDIO_DRQSRC(sunxi_daudio, x) \ + ((sunxi_daudio)->capture_dma_param.dma_drq_type_num = \ + DRQSRC_DAUDIO_##x##_RX) struct sunxi_daudio_platform_data { - unsigned int daudio_type; - unsigned int external_type; - unsigned int daudio_master; - unsigned int pcm_lrck_period; - unsigned int slot_width_select; - unsigned int audio_format; - unsigned int signal_inversion; - unsigned int frame_type; - unsigned int tdm_config; - unsigned int tdm_num; - unsigned int mclk_div; + unsigned int daudio_type; + unsigned int external_type; + unsigned int daudio_master; + unsigned int pcm_lrck_period; + unsigned int slot_width_select; + unsigned int audio_format; + unsigned int signal_inversion; + unsigned int frame_type; + unsigned int tdm_config; + unsigned int tdm_num; + unsigned int mclk_div; }; struct voltage_supply { - struct regulator *daudio_regulator; - const char *regulator_name; + struct regulator *daudio_regulator; + const char *regulator_name; }; struct sunxi_daudio_info { - struct device *dev; - struct regmap *regmap; - void __iomem *membase; - struct clk *pllclk; - struct clk *moduleclk; - struct voltage_supply vol_supply; - struct mutex mutex; - struct sunxi_dma_params playback_dma_param; - struct sunxi_dma_params capture_dma_param; - struct pinctrl *pinctrl; - struct pinctrl_state *pinstate; - struct pinctrl_state *pinstate_sleep; - struct sunxi_daudio_platform_data *pdata; - unsigned int hub_mode; - unsigned int hdmi_en; - struct delayed_work resume_work; - struct snd_soc_dai *cpu_dai; + struct device *dev; + struct regmap *regmap; + void __iomem *membase; + struct clk *pllclk; + struct clk *moduleclk; + struct voltage_supply vol_supply; + struct mutex mutex; + struct sunxi_dma_params playback_dma_param; + struct sunxi_dma_params capture_dma_param; + struct pinctrl *pinctrl; + struct pinctrl_state *pinstate; + struct pinctrl_state *pinstate_sleep; + struct sunxi_daudio_platform_data *pdata; + unsigned int hub_mode; + unsigned int hdmi_en; + struct delayed_work resume_work; + struct snd_soc_dai *cpu_dai; #ifdef CONFIG_SND_SUNXI_MAD - struct resource res; - unsigned int mad_bind; - unsigned int lpsd_chan_sel; - unsigned int mad_standby_chan_sel; - unsigned int audio_src_chan_num; - unsigned int capture_en; + struct resource res; + unsigned int mad_bind; + unsigned int lpsd_chan_sel; + unsigned int mad_standby_chan_sel; + unsigned int audio_src_chan_num; + unsigned int capture_en; #endif }; static struct reg_label reg_labels[] = { - REG_LABEL(SUNXI_DAUDIO_CTL), - REG_LABEL(SUNXI_DAUDIO_FMT0), - REG_LABEL(SUNXI_DAUDIO_FMT1), - REG_LABEL(SUNXI_DAUDIO_INTSTA), - REG_LABEL(SUNXI_DAUDIO_FIFOCTL), - REG_LABEL(SUNXI_DAUDIO_FIFOSTA), - REG_LABEL(SUNXI_DAUDIO_INTCTL), - REG_LABEL(SUNXI_DAUDIO_CLKDIV), - REG_LABEL(SUNXI_DAUDIO_TXCNT), - REG_LABEL(SUNXI_DAUDIO_RXCNT), - REG_LABEL(SUNXI_DAUDIO_CHCFG), - REG_LABEL(SUNXI_DAUDIO_TX0CHSEL), - REG_LABEL(SUNXI_DAUDIO_TX1CHSEL), - REG_LABEL(SUNXI_DAUDIO_TX2CHSEL), - REG_LABEL(SUNXI_DAUDIO_TX3CHSEL), + REG_LABEL(SUNXI_DAUDIO_CTL), + REG_LABEL(SUNXI_DAUDIO_FMT0), + REG_LABEL(SUNXI_DAUDIO_FMT1), + REG_LABEL(SUNXI_DAUDIO_INTSTA), + REG_LABEL(SUNXI_DAUDIO_FIFOCTL), + REG_LABEL(SUNXI_DAUDIO_FIFOSTA), + REG_LABEL(SUNXI_DAUDIO_INTCTL), + REG_LABEL(SUNXI_DAUDIO_CLKDIV), + REG_LABEL(SUNXI_DAUDIO_TXCNT), + REG_LABEL(SUNXI_DAUDIO_RXCNT), + REG_LABEL(SUNXI_DAUDIO_CHCFG), + REG_LABEL(SUNXI_DAUDIO_TX0CHSEL), + REG_LABEL(SUNXI_DAUDIO_TX1CHSEL), + REG_LABEL(SUNXI_DAUDIO_TX2CHSEL), + REG_LABEL(SUNXI_DAUDIO_TX3CHSEL), #if defined(SUNXI_DAUDIO_MODE_B) - REG_LABEL(SUNXI_DAUDIO_TX0CHMAP0), - REG_LABEL(SUNXI_DAUDIO_TX0CHMAP1), - REG_LABEL(SUNXI_DAUDIO_TX1CHMAP0), - REG_LABEL(SUNXI_DAUDIO_TX1CHMAP1), - REG_LABEL(SUNXI_DAUDIO_TX2CHMAP0), - REG_LABEL(SUNXI_DAUDIO_TX2CHMAP1), - REG_LABEL(SUNXI_DAUDIO_TX3CHMAP0), - REG_LABEL(SUNXI_DAUDIO_TX3CHMAP1), - REG_LABEL(SUNXI_DAUDIO_RXCHSEL), - REG_LABEL(SUNXI_DAUDIO_RXCHMAP0), - REG_LABEL(SUNXI_DAUDIO_RXCHMAP1), - REG_LABEL(SUNXI_DAUDIO_DEBUG), + REG_LABEL(SUNXI_DAUDIO_TX0CHMAP0), + REG_LABEL(SUNXI_DAUDIO_TX0CHMAP1), + REG_LABEL(SUNXI_DAUDIO_TX1CHMAP0), + REG_LABEL(SUNXI_DAUDIO_TX1CHMAP1), + REG_LABEL(SUNXI_DAUDIO_TX2CHMAP0), + REG_LABEL(SUNXI_DAUDIO_TX2CHMAP1), + REG_LABEL(SUNXI_DAUDIO_TX3CHMAP0), + REG_LABEL(SUNXI_DAUDIO_TX3CHMAP1), + REG_LABEL(SUNXI_DAUDIO_RXCHSEL), + REG_LABEL(SUNXI_DAUDIO_RXCHMAP0), + REG_LABEL(SUNXI_DAUDIO_RXCHMAP1), + REG_LABEL(SUNXI_DAUDIO_DEBUG), #else - REG_LABEL(SUNXI_DAUDIO_TX0CHMAP0), - REG_LABEL(SUNXI_DAUDIO_TX1CHMAP0), - REG_LABEL(SUNXI_DAUDIO_TX2CHMAP0), - REG_LABEL(SUNXI_DAUDIO_TX3CHMAP0), - REG_LABEL(SUNXI_DAUDIO_RXCHSEL), - REG_LABEL(SUNXI_DAUDIO_RXCHMAP), - REG_LABEL(SUNXI_DAUDIO_DEBUG), + REG_LABEL(SUNXI_DAUDIO_TX0CHMAP0), + REG_LABEL(SUNXI_DAUDIO_TX1CHMAP0), + REG_LABEL(SUNXI_DAUDIO_TX2CHMAP0), + REG_LABEL(SUNXI_DAUDIO_TX3CHMAP0), + REG_LABEL(SUNXI_DAUDIO_RXCHSEL), + REG_LABEL(SUNXI_DAUDIO_RXCHMAP), + REG_LABEL(SUNXI_DAUDIO_DEBUG), #endif - REG_LABEL_END, + REG_LABEL_END, }; static struct sunxi_daudio_info *sunxi_daudio_global[DAUDIO_NUM_MAX]; @@ -151,880 +151,821 @@ static int device_count; /* * Some codec on electric timing need debugging */ -int daudio_set_clk_onoff(struct snd_soc_dai *dai, u32 mask, u32 onoff) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - - switch (mask) { - case SUNXI_DAUDIO_BCLK: - if (onoff) - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_FIFOCTL, - (1<regmap, - SUNXI_DAUDIO_FIFOCTL, - (1<regmap, - SUNXI_DAUDIO_FIFOCTL, - (1<regmap, - SUNXI_DAUDIO_FIFOCTL, - (1<regmap, - SUNXI_DAUDIO_CLKDIV, - (1<regmap, - SUNXI_DAUDIO_CLKDIV, - (1<regmap, - SUNXI_DAUDIO_CTL, - (1<regmap, - SUNXI_DAUDIO_CTL, - (1<regmap, SUNXI_DAUDIO_FIFOCTL, + (1 << BCLK_OUT), (1 << BCLK_OUT)); + else + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (1 << BCLK_OUT), (0 << BCLK_OUT)); + break; + case SUNXI_DAUDIO_LRCK: + if (onoff) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (1 << LRCK_OUT), (1 << LRCK_OUT)); + else + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (1 << LRCK_OUT), (0 << LRCK_OUT)); + break; + case SUNXI_DAUDIO_MCLK: + if (onoff) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CLKDIV, + (1 << MCLKOUT_EN), (1 << MCLKOUT_EN)); + else + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CLKDIV, + (1 << MCLKOUT_EN), (0 << MCLKOUT_EN)); + break; + case SUNXI_DAUDIO_GEN: + if (onoff) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << GLOBAL_EN), (1 << GLOBAL_EN)); + else + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << GLOBAL_EN), (0 << GLOBAL_EN)); + break; + default: + return -EINVAL; + } + return 0; } EXPORT_SYMBOL_GPL(daudio_set_clk_onoff); - static int sunxi_daudio_get_hub_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct sunxi_daudio_info *sunxi_daudio = - snd_soc_codec_get_drvdata(codec); - unsigned int reg_val; + struct snd_ctl_elem_value *ucontrol) { + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct sunxi_daudio_info *sunxi_daudio = snd_soc_codec_get_drvdata(codec); + unsigned int reg_val; - regmap_read(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, ®_val); + regmap_read(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, ®_val); - ucontrol->value.integer.value[0] = ((reg_val & (1<value.integer.value[0] = ((reg_val & (1 << HUB_EN)) ? 2 : 1); + return 0; } static int sunxi_daudio_set_hub_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct sunxi_daudio_info *sunxi_daudio = - snd_soc_codec_get_drvdata(codec); + struct snd_ctl_elem_value *ucontrol) { + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct sunxi_daudio_info *sunxi_daudio = snd_soc_codec_get_drvdata(codec); - switch (ucontrol->value.integer.value[0]) { - case 0: - case 1: - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, - (1<regmap, SUNXI_DAUDIO_CTL, - (1<regmap, SUNXI_DAUDIO_FIFOCTL, - (1<regmap, SUNXI_DAUDIO_CTL, - (1<value.integer.value[0]) { + case 0: + case 1: + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (1 << HUB_EN), (0 << HUB_EN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (0 << CTL_TXEN)); + break; + case 2: + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (1 << HUB_EN), (1 << HUB_EN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (1 << CTL_TXEN)); + break; + default: + return -EINVAL; + } + return 0; } -static const char *daudio_format_function[] = {"null", - "hub_disable", "hub_enable"}; +static const char *daudio_format_function[] = {"null", "hub_disable", + "hub_enable"}; static const struct soc_enum daudio_format_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(daudio_format_function), - daudio_format_function), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(daudio_format_function), + daudio_format_function), }; #ifdef CONFIG_SND_SUNXI_MAD /*lpsd channel sel*/ static int sunxi_daudio_set_lpsd_chan(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct sunxi_daudio_info *sunxi_daudio = - snd_soc_codec_get_drvdata(codec); + struct snd_ctl_elem_value *ucontrol) { + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct sunxi_daudio_info *sunxi_daudio = snd_soc_codec_get_drvdata(codec); - sunxi_daudio->lpsd_chan_sel = ucontrol->value.integer.value[0]; - return 0; + sunxi_daudio->lpsd_chan_sel = ucontrol->value.integer.value[0]; + return 0; } static int sunxi_daudio_get_lpsd_chan(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct sunxi_daudio_info *sunxi_daudio = - snd_soc_codec_get_drvdata(codec); + struct snd_ctl_elem_value *ucontrol) { + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct sunxi_daudio_info *sunxi_daudio = snd_soc_codec_get_drvdata(codec); - ucontrol->value.integer.value[0] = sunxi_daudio->lpsd_chan_sel; - return 0; + ucontrol->value.integer.value[0] = sunxi_daudio->lpsd_chan_sel; + return 0; } - -static const char *lpsd_chan_sel_function[] = {"NULL", "1st_chan", "2nd_chan", - "3rd_chan", "4th_chan", "5th_chan", "6th_chan", "7th_chan", "8th_chan"}; +static const char *lpsd_chan_sel_function[] = { + "NULL", "1st_chan", "2nd_chan", "3rd_chan", "4th_chan", + "5th_chan", "6th_chan", "7th_chan", "8th_chan"}; static const struct soc_enum lpsd_chan_sel_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lpsd_chan_sel_function), - lpsd_chan_sel_function), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lpsd_chan_sel_function), + lpsd_chan_sel_function), }; /*mad_standby channel sel*/ -static int sunxi_daudio_set_mad_standby_chan(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct sunxi_daudio_info *sunxi_daudio = - snd_soc_codec_get_drvdata(codec); +static int +sunxi_daudio_set_mad_standby_chan(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct sunxi_daudio_info *sunxi_daudio = snd_soc_codec_get_drvdata(codec); - sunxi_daudio->mad_standby_chan_sel = ucontrol->value.integer.value[0]; - return 0; + sunxi_daudio->mad_standby_chan_sel = ucontrol->value.integer.value[0]; + return 0; } -static int sunxi_daudio_get_mad_standby_chan(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - struct sunxi_daudio_info *sunxi_daudio = - snd_soc_codec_get_drvdata(codec); +static int +sunxi_daudio_get_mad_standby_chan(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct sunxi_daudio_info *sunxi_daudio = snd_soc_codec_get_drvdata(codec); - ucontrol->value.integer.value[0] = sunxi_daudio->mad_standby_chan_sel; - return 0; + ucontrol->value.integer.value[0] = sunxi_daudio->mad_standby_chan_sel; + return 0; } -static const char *mad_standby_chan_sel_function[] = { - "Zero chan", "Two chan", "Four chan"}; +static const char *mad_standby_chan_sel_function[] = {"Zero chan", "Two chan", + "Four chan"}; static const struct soc_enum mad_standby_chan_sel_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mad_standby_chan_sel_function), - mad_standby_chan_sel_function), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mad_standby_chan_sel_function), + mad_standby_chan_sel_function), }; #endif /* dts pcm Audio Mode Select */ static const struct snd_kcontrol_new sunxi_daudio_controls[] = { - SOC_ENUM_EXT("sunxi daudio audio hub mode", daudio_format_enum[0], - sunxi_daudio_get_hub_mode, sunxi_daudio_set_hub_mode), - SOC_SINGLE("sunxi daudio loopback debug", SUNXI_DAUDIO_CTL, - LOOP_EN, 1, 0), + SOC_ENUM_EXT("sunxi daudio audio hub mode", daudio_format_enum[0], + sunxi_daudio_get_hub_mode, sunxi_daudio_set_hub_mode), + SOC_SINGLE("sunxi daudio loopback debug", SUNXI_DAUDIO_CTL, LOOP_EN, 1, 0), #ifdef CONFIG_SND_SUNXI_MAD - SOC_ENUM_EXT("lpsd channel sel Function", lpsd_chan_sel_enum[0], - sunxi_daudio_get_lpsd_chan, sunxi_daudio_set_lpsd_chan), - SOC_ENUM_EXT("mad_standby channel sel Function", mad_standby_chan_sel_enum[0], - sunxi_daudio_get_mad_standby_chan, sunxi_daudio_set_mad_standby_chan), + SOC_ENUM_EXT("lpsd channel sel Function", lpsd_chan_sel_enum[0], + sunxi_daudio_get_lpsd_chan, sunxi_daudio_set_lpsd_chan), + SOC_ENUM_EXT( + "mad_standby channel sel Function", mad_standby_chan_sel_enum[0], + sunxi_daudio_get_mad_standby_chan, sunxi_daudio_set_mad_standby_chan), #endif }; static void sunxi_daudio_txctrl_enable(struct sunxi_daudio_info *sunxi_daudio, - int enable) -{ - pr_debug("Enter %s, enable %d\n", __func__, enable); - if (enable) { - /* HDMI audio Transmit Clock just enable at startup */ - if (sunxi_daudio->pdata->daudio_type - != SUNXI_DAUDIO_TDMHDMI_TYPE) - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_CTL, - (1<regmap, SUNXI_DAUDIO_INTCTL, - (1<regmap, SUNXI_DAUDIO_INTCTL, - (1<pdata->daudio_type - != SUNXI_DAUDIO_TDMHDMI_TYPE) - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_CTL, - (1<pdata->daudio_type != SUNXI_DAUDIO_TDMHDMI_TYPE) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (1 << CTL_TXEN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_INTCTL, + (1 << TXDRQEN), (1 << TXDRQEN)); + } else { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_INTCTL, + (1 << TXDRQEN), (0 << TXDRQEN)); + if (sunxi_daudio->pdata->daudio_type != SUNXI_DAUDIO_TDMHDMI_TYPE) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (0 << CTL_TXEN)); + } + pr_debug("End %s, enable %d\n", __func__, enable); } static void sunxi_daudio_rxctrl_enable(struct sunxi_daudio_info *sunxi_daudio, - int enable) -{ - if (enable) { - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<regmap, SUNXI_DAUDIO_INTCTL, - (1<regmap, SUNXI_DAUDIO_INTCTL, - (1<regmap, SUNXI_DAUDIO_CTL, - (1<regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_RXEN), (1 << CTL_RXEN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_INTCTL, + (1 << RXDRQEN), (1 << RXDRQEN)); + } else { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_INTCTL, + (1 << RXDRQEN), (0 << RXDRQEN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_RXEN), (0 << CTL_RXEN)); + } } static int sunxi_daudio_global_enable(struct sunxi_daudio_info *sunxi_daudio, - int enable) -{ - if (enable) { - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<hdmi_en) { - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_CTL, (1<regmap, - SUNXI_DAUDIO_CTL, (1<regmap, - SUNXI_DAUDIO_CTL, (1<regmap, SUNXI_DAUDIO_CTL, - (1<regmap, SUNXI_DAUDIO_CTL, - (1<regmap, SUNXI_DAUDIO_CTL, - (1<hdmi_en) { - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_CTL, (1<regmap, - SUNXI_DAUDIO_CTL, (1<regmap, - SUNXI_DAUDIO_CTL, (1<regmap, SUNXI_DAUDIO_CTL, + (1 << SDO0_EN), (1 << SDO0_EN)); + if (sunxi_daudio->hdmi_en) { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << SDO1_EN), (1 << SDO1_EN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << SDO2_EN), (1 << SDO2_EN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << SDO3_EN), (1 << SDO3_EN)); + } + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << GLOBAL_EN), (1 << GLOBAL_EN)); + } else { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << GLOBAL_EN), (0 << GLOBAL_EN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << SDO0_EN), (0 << SDO0_EN)); + if (sunxi_daudio->hdmi_en) { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << SDO1_EN), (0 << SDO1_EN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << SDO2_EN), (0 << SDO2_EN)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << SDO3_EN), (0 << SDO3_EN)); + } + } + return 0; } -static int sunxi_daudio_mclk_setting(struct sunxi_daudio_info *sunxi_daudio) -{ - unsigned int mclk_div; +static int sunxi_daudio_mclk_setting(struct sunxi_daudio_info *sunxi_daudio) { + unsigned int mclk_div; - if (sunxi_daudio->pdata->mclk_div) { - switch (sunxi_daudio->pdata->mclk_div) { - case 1: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_1; - break; - case 2: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_2; - break; - case 4: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_3; - break; - case 6: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_4; - break; - case 8: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_5; - break; - case 12: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_6; - break; - case 16: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_7; - break; - case 24: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_8; - break; - case 32: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_9; - break; - case 48: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_10; - break; - case 64: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_11; - break; - case 96: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_12; - break; - case 128: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_13; - break; - case 176: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_14; - break; - case 192: - mclk_div = SUNXI_DAUDIO_MCLK_DIV_15; - break; - default: - dev_err(sunxi_daudio->dev, "unsupport mclk_div\n"); - return -EINVAL; - } - /* setting Mclk as external codec input clk */ - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CLKDIV, - (SUNXI_DAUDIO_MCLK_DIV_MASK<regmap, SUNXI_DAUDIO_CLKDIV, - (1<regmap, SUNXI_DAUDIO_CLKDIV, - (1<pdata->mclk_div) { + switch (sunxi_daudio->pdata->mclk_div) { + case 1: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_1; + break; + case 2: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_2; + break; + case 4: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_3; + break; + case 6: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_4; + break; + case 8: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_5; + break; + case 12: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_6; + break; + case 16: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_7; + break; + case 24: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_8; + break; + case 32: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_9; + break; + case 48: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_10; + break; + case 64: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_11; + break; + case 96: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_12; + break; + case 128: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_13; + break; + case 176: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_14; + break; + case 192: + mclk_div = SUNXI_DAUDIO_MCLK_DIV_15; + break; + default: + dev_err(sunxi_daudio->dev, "unsupport mclk_div\n"); + return -EINVAL; + } + /* setting Mclk as external codec input clk */ + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CLKDIV, + (SUNXI_DAUDIO_MCLK_DIV_MASK << MCLK_DIV), + (mclk_div << MCLK_DIV)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CLKDIV, + (1 << MCLKOUT_EN), (1 << MCLKOUT_EN)); + + printk("wzj:mclk enable!mdiv:%d\n", mclk_div); + } else { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CLKDIV, + (1 << MCLKOUT_EN), (0 << MCLKOUT_EN)); + } + return 0; } static int sunxi_daudio_init_fmt(struct sunxi_daudio_info *sunxi_daudio, - unsigned int fmt) -{ - unsigned int offset, mode; - unsigned int lrck_polarity, brck_polarity; + unsigned int fmt) { + unsigned int offset, mode; + unsigned int lrck_polarity, brck_polarity; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (SUNXI_DAUDIO_LRCK_OUT_MASK<regmap, SUNXI_DAUDIO_CTL, - (SUNXI_DAUDIO_LRCK_OUT_MASK<dev, "unknown maser/slave format\n"); - return -EINVAL; - } + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (SUNXI_DAUDIO_LRCK_OUT_MASK << LRCK_OUT), + (SUNXI_DAUDIO_LRCK_OUT_DISABLE << LRCK_OUT)); + break; + case SND_SOC_DAIFMT_CBS_CFS: + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (SUNXI_DAUDIO_LRCK_OUT_MASK << LRCK_OUT), + (SUNXI_DAUDIO_LRCK_OUT_ENABLE << LRCK_OUT)); + break; + default: + dev_err(sunxi_daudio->dev, "unknown maser/slave format\n"); + return -EINVAL; + } - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - offset = SUNXI_DAUDIO_TX_OFFSET_1; - mode = SUNXI_DAUDIO_MODE_CTL_I2S; - break; - case SND_SOC_DAIFMT_RIGHT_J: - offset = SUNXI_DAUDIO_TX_OFFSET_0; - mode = SUNXI_DAUDIO_MODE_CTL_RIGHT; - break; - case SND_SOC_DAIFMT_LEFT_J: - offset = SUNXI_DAUDIO_TX_OFFSET_0; - mode = SUNXI_DAUDIO_MODE_CTL_LEFT; - break; - case SND_SOC_DAIFMT_DSP_A: - offset = SUNXI_DAUDIO_TX_OFFSET_1; - mode = SUNXI_DAUDIO_MODE_CTL_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: - offset = SUNXI_DAUDIO_TX_OFFSET_0; - mode = SUNXI_DAUDIO_MODE_CTL_PCM; - break; - default: - dev_err(sunxi_daudio->dev, "format setting failed\n"); - return -EINVAL; - } - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (SUNXI_DAUDIO_MODE_CTL_MASK<regmap, SUNXI_DAUDIO_TX0CHSEL, - (SUNXI_DAUDIO_TX_OFFSET_MASK<hdmi_en) { - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX1CHSEL, - (SUNXI_DAUDIO_TX_OFFSET_MASK<regmap, SUNXI_DAUDIO_TX2CHSEL, - (SUNXI_DAUDIO_TX_OFFSET_MASK<regmap, SUNXI_DAUDIO_TX3CHSEL, - (SUNXI_DAUDIO_TX_OFFSET_MASK<dev, "format setting failed\n"); + return -EINVAL; + } + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (SUNXI_DAUDIO_MODE_CTL_MASK << MODE_SEL), + (mode << MODE_SEL)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX0CHSEL, + (SUNXI_DAUDIO_TX_OFFSET_MASK << TX_OFFSET), + (offset << TX_OFFSET)); + if (sunxi_daudio->hdmi_en) { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX1CHSEL, + (SUNXI_DAUDIO_TX_OFFSET_MASK << TX_OFFSET), + (offset << TX_OFFSET)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX2CHSEL, + (SUNXI_DAUDIO_TX_OFFSET_MASK << TX_OFFSET), + (offset << TX_OFFSET)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX3CHSEL, + (SUNXI_DAUDIO_TX_OFFSET_MASK << TX_OFFSET), + (offset << TX_OFFSET)); + } - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_RXCHSEL, - (SUNXI_DAUDIO_RX_OFFSET_MASK<regmap, SUNXI_DAUDIO_RXCHSEL, + (SUNXI_DAUDIO_RX_OFFSET_MASK << RX_OFFSET), + (offset << RX_OFFSET)); - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - lrck_polarity = SUNXI_DAUDIO_LRCK_POLARITY_NOR; - brck_polarity = SUNXI_DAUDIO_BCLK_POLARITY_NOR; - break; - case SND_SOC_DAIFMT_NB_IF: - lrck_polarity = SUNXI_DAUDIO_LRCK_POLARITY_INV; - brck_polarity = SUNXI_DAUDIO_BCLK_POLARITY_NOR; - break; - case SND_SOC_DAIFMT_IB_NF: - lrck_polarity = SUNXI_DAUDIO_LRCK_POLARITY_NOR; - brck_polarity = SUNXI_DAUDIO_BCLK_POLARITY_INV; - break; - case SND_SOC_DAIFMT_IB_IF: - lrck_polarity = SUNXI_DAUDIO_LRCK_POLARITY_INV; - brck_polarity = SUNXI_DAUDIO_BCLK_POLARITY_INV; - break; - default: - dev_err(sunxi_daudio->dev, "invert clk setting failed\n"); - return -EINVAL; - } - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, - (1<regmap, SUNXI_DAUDIO_FMT0, - (1<dev, "invert clk setting failed\n"); + return -EINVAL; + } + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, + (1 << LRCK_POLARITY), (lrck_polarity << LRCK_POLARITY)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, + (1 << BRCK_POLARITY), (brck_polarity << BRCK_POLARITY)); + return 0; } -static int sunxi_daudio_init(struct sunxi_daudio_info *sunxi_daudio) -{ - struct sunxi_daudio_platform_data *pdat = sunxi_daudio->pdata; +static int sunxi_daudio_init(struct sunxi_daudio_info *sunxi_daudio) { + struct sunxi_daudio_platform_data *pdat = sunxi_daudio->pdata; - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, - (1<frame_type<regmap, SUNXI_DAUDIO_FMT0, - (SUNXI_DAUDIO_LRCK_PERIOD_MASK)<pcm_lrck_period-1)<regmap, SUNXI_DAUDIO_FMT0, + (1 << LRCK_WIDTH), (pdat->frame_type << LRCK_WIDTH)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, + (SUNXI_DAUDIO_LRCK_PERIOD_MASK) << LRCK_PERIOD, + ((pdat->pcm_lrck_period - 1) << LRCK_PERIOD)); - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, - (SUNXI_DAUDIO_SLOT_WIDTH_MASK<slot_width_select>>2)-1)<regmap, SUNXI_DAUDIO_FMT0, + (SUNXI_DAUDIO_SLOT_WIDTH_MASK << SLOT_WIDTH), + (((pdat->slot_width_select >> 2) - 1) << SLOT_WIDTH)); - /* - * MSB on the transmit format, always be first. - * default using Linear-PCM, without no companding. - * A-law or U-law not working ok. - */ - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_FMT1, SUNXI_DAUDIO_FMT1_DEF); + /* + * MSB on the transmit format, always be first. + * default using Linear-PCM, without no companding. + * A-law or U-law not working ok. + */ + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT1, + SUNXI_DAUDIO_FMT1_DEF); - sunxi_daudio_init_fmt(sunxi_daudio, (pdat->audio_format - | (pdat->signal_inversion<daudio_master<audio_format | + (pdat->signal_inversion << SND_SOC_DAIFMT_SIG_SHIFT) | + (pdat->daudio_master << SND_SOC_DAIFMT_MASTER_SHIFT))); - return sunxi_daudio_mclk_setting(sunxi_daudio); + return sunxi_daudio_mclk_setting(sunxi_daudio); } static int sunxi_daudio_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_card *card = rtd->card; - struct sunxi_hdmi_priv *sunxi_hdmi = snd_soc_card_get_drvdata(card); + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct sunxi_hdmi_priv *sunxi_hdmi = snd_soc_card_get_drvdata(card); #ifdef SUNXI_HDMI_AUDIO_ENABLE - unsigned int reg_val; + unsigned int reg_val; #endif - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - /* - * Special procesing for hdmi, HDMI card name is - * "sndhdmi" or sndhdmiraw. if card not HDMI, - * strstr func just return NULL, jump to right section. - * Not HDMI card, sunxi_hdmi maybe a NULL pointer. - */ - if (sunxi_daudio->pdata->daudio_type == - SUNXI_DAUDIO_TDMHDMI_TYPE - && (sunxi_hdmi->hdmi_format > 1)) { - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_FMT0, - (SUNXI_DAUDIO_SR_MASK<regmap, - SUNXI_DAUDIO_FIFOCTL, - (SUNXI_DAUDIO_TXIM_MASK<regmap, - SUNXI_DAUDIO_FMT0, - (SUNXI_DAUDIO_SR_MASK<stream == SNDRV_PCM_STREAM_PLAYBACK) - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_FIFOCTL, - (SUNXI_DAUDIO_TXIM_MASK<regmap, - SUNXI_DAUDIO_FIFOCTL, - (SUNXI_DAUDIO_RXOM_MASK<regmap, SUNXI_DAUDIO_FMT0, - (SUNXI_DAUDIO_SR_MASK<stream == SNDRV_PCM_STREAM_PLAYBACK) - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_FIFOCTL, - (SUNXI_DAUDIO_TXIM_MASK<regmap, - SUNXI_DAUDIO_FIFOCTL, - (SUNXI_DAUDIO_RXOM_MASK<regmap, SUNXI_DAUDIO_FMT0, - (SUNXI_DAUDIO_SR_MASK<stream == SNDRV_PCM_STREAM_PLAYBACK) - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_FIFOCTL, - (SUNXI_DAUDIO_TXIM_MASK<regmap, - SUNXI_DAUDIO_FIFOCTL, - (SUNXI_DAUDIO_RXOM_MASK<dev, "unrecognized format\n"); - return -EINVAL; - } + printk("wzj:set hw params:%d\n", params_format(params)); + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + /* + * Special procesing for hdmi, HDMI card name is + * "sndhdmi" or sndhdmiraw. if card not HDMI, + * strstr func just return NULL, jump to right section. + * Not HDMI card, sunxi_hdmi maybe a NULL pointer. + */ + if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE && + (sunxi_hdmi->hdmi_format > 1)) { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, + (SUNXI_DAUDIO_SR_MASK << SAMPLE_RESOLUTION), + (SUNXI_DAUDIO_SR_24BIT << SAMPLE_RESOLUTION)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (SUNXI_DAUDIO_TXIM_MASK << TXIM), + (SUNXI_DAUDIO_TXIM_VALID_MSB << TXIM)); + } else { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, + (SUNXI_DAUDIO_SR_MASK << SAMPLE_RESOLUTION), + (SUNXI_DAUDIO_SR_16BIT << SAMPLE_RESOLUTION)); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (SUNXI_DAUDIO_TXIM_MASK << TXIM), + (SUNXI_DAUDIO_TXIM_VALID_LSB << TXIM)); + else + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (SUNXI_DAUDIO_RXOM_MASK << RXOM), + (SUNXI_DAUDIO_RXOM_EXPH << RXOM)); + } + break; + case SNDRV_PCM_FORMAT_S20_3LE: + case SNDRV_PCM_FORMAT_S24_LE: + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, + (SUNXI_DAUDIO_SR_MASK << SAMPLE_RESOLUTION), + (SUNXI_DAUDIO_SR_24BIT << SAMPLE_RESOLUTION)); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (SUNXI_DAUDIO_TXIM_MASK << TXIM), + (SUNXI_DAUDIO_TXIM_VALID_LSB << TXIM)); + else + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (SUNXI_DAUDIO_RXOM_MASK << RXOM), + (SUNXI_DAUDIO_RXOM_EXPH << RXOM)); + break; + case SNDRV_PCM_FORMAT_S32_LE: + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FMT0, + (SUNXI_DAUDIO_SR_MASK << SAMPLE_RESOLUTION), + (SUNXI_DAUDIO_SR_32BIT << SAMPLE_RESOLUTION)); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (SUNXI_DAUDIO_TXIM_MASK << TXIM), + (SUNXI_DAUDIO_TXIM_VALID_LSB << TXIM)); + else + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (SUNXI_DAUDIO_RXOM_MASK << RXOM), + (SUNXI_DAUDIO_RXOM_EXPH << RXOM)); + break; + default: + dev_err(sunxi_daudio->dev, "unrecognized format\n"); + return -EINVAL; + } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CHCFG, - (SUNXI_DAUDIO_TX_SLOT_MASK<hdmi_en == 0) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CHCFG, + (SUNXI_DAUDIO_TX_SLOT_MASK << TX_SLOT_NUM), + ((params_channels(params) - 1) << TX_SLOT_NUM)); + if (sunxi_daudio->hdmi_en == 0) { #ifdef SUNXI_DAUDIO_MODE_B - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX0CHMAP0, SUNXI_DEFAULT_CHMAP0); - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX0CHMAP1, SUNXI_DEFAULT_CHMAP1); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX0CHMAP0, + SUNXI_DEFAULT_CHMAP0); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX0CHMAP1, + SUNXI_DEFAULT_CHMAP1); #else - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX0CHMAP0, SUNXI_DEFAULT_CHMAP); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX0CHMAP0, + SUNXI_DEFAULT_CHMAP); #endif - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX0CHSEL, - (SUNXI_DAUDIO_TX_CHSEL_MASK<regmap, - SUNXI_DAUDIO_TX0CHSEL, - (SUNXI_DAUDIO_TX_CHEN_MASK<regmap, SUNXI_DAUDIO_TX0CHSEL, + (SUNXI_DAUDIO_TX_CHSEL_MASK << TX_CHSEL), + ((params_channels(params) - 1) << TX_CHSEL)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX0CHSEL, + (SUNXI_DAUDIO_TX_CHEN_MASK << TX_CHEN), + ((1 << params_channels(params)) - 1) << TX_CHEN); + } else { + /* HDMI multi-channel processing */ #ifdef SUNXI_HDMI_AUDIO_ENABLE #ifdef SUNXI_DAUDIO_MODE_B - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX0CHMAP1, 0x10); - if (sunxi_hdmi->hdmi_format > 1) { - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX1CHMAP1, 0x32); - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX2CHMAP1, 0x54); - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX3CHMAP1, 0x76); - } else { - if (params_channels(params) > 2) - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX1CHMAP1, 0x23); - if (params_channels(params) > 4) { - if (params_channels(params) == 6) - regmap_write( - sunxi_daudio->regmap, - SUNXI_DAUDIO_TX2CHMAP1, - 0x54); - else - regmap_write( - sunxi_daudio->regmap, - SUNXI_DAUDIO_TX2CHMAP1, - 0x76); - } - if (params_channels(params) > 6) - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX3CHMAP1, - 0x54); - } + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX0CHMAP1, 0x10); + if (sunxi_hdmi->hdmi_format > 1) { + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX1CHMAP1, + 0x32); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX2CHMAP1, + 0x54); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX3CHMAP1, + 0x76); + } else { + if (params_channels(params) > 2) + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX1CHMAP1, + 0x23); + if (params_channels(params) > 4) { + if (params_channels(params) == 6) + regmap_write(sunxi_daudio->regmap, + SUNXI_DAUDIO_TX2CHMAP1, 0x54); + else + regmap_write(sunxi_daudio->regmap, + SUNXI_DAUDIO_TX2CHMAP1, 0x76); + } + if (params_channels(params) > 6) + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX3CHMAP1, + 0x54); + } #else - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX0CHMAP0, 0x10); - if (sunxi_hdmi->hdmi_format > 1) { - /* support for HBR */ - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX1CHMAP0, 0x32); - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX2CHMAP0, 0x54); - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX3CHMAP0, 0x76); - } else { - /* LPCM 5.1 & 7.1 support */ - if (params_channels(params) > 2) - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX1CHMAP0, 0x23); - if (params_channels(params) > 4) { - if (params_channels(params) == 6) - regmap_write( - sunxi_daudio->regmap, - SUNXI_DAUDIO_TX2CHMAP0, - 0x54); - else - regmap_write( - sunxi_daudio->regmap, - SUNXI_DAUDIO_TX2CHMAP0, - 0x76); - } - if (params_channels(params) > 6) - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX3CHMAP0, - 0x54); - } + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX0CHMAP0, 0x10); + if (sunxi_hdmi->hdmi_format > 1) { + /* support for HBR */ + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX1CHMAP0, + 0x32); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX2CHMAP0, + 0x54); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX3CHMAP0, + 0x76); + } else { + /* LPCM 5.1 & 7.1 support */ + if (params_channels(params) > 2) + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX1CHMAP0, + 0x23); + if (params_channels(params) > 4) { + if (params_channels(params) == 6) + regmap_write(sunxi_daudio->regmap, + SUNXI_DAUDIO_TX2CHMAP0, 0x54); + else + regmap_write(sunxi_daudio->regmap, + SUNXI_DAUDIO_TX2CHMAP0, 0x76); + } + if (params_channels(params) > 6) + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TX3CHMAP0, + 0x54); + } #endif - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX0CHSEL, - 0x01 << TX_CHSEL, 0x01 << TX_CHSEL); - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX0CHSEL, - 0x03 << TX_CHEN, 0x03 << TX_CHEN); - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX1CHSEL, - 0x01 << TX_CHSEL, 0x01 << TX_CHSEL); - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX1CHSEL, - (0x03)<regmap, - SUNXI_DAUDIO_TX2CHSEL, - 0x01 << TX_CHSEL, 0x01 << TX_CHSEL); - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX2CHSEL, - (0x03)<regmap, - SUNXI_DAUDIO_TX3CHSEL, - 0x01 << TX_CHSEL, 0x01 << TX_CHSEL); - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_TX3CHSEL, - (0x03)<regmap, SUNXI_DAUDIO_TX0CHSEL, + 0x01 << TX_CHSEL, 0x01 << TX_CHSEL); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX0CHSEL, + 0x03 << TX_CHEN, 0x03 << TX_CHEN); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX1CHSEL, + 0x01 << TX_CHSEL, 0x01 << TX_CHSEL); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX1CHSEL, + (0x03) << TX_CHEN, 0x03 << TX_CHEN); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX2CHSEL, + 0x01 << TX_CHSEL, 0x01 << TX_CHSEL); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX2CHSEL, + (0x03) << TX_CHEN, 0x03 << TX_CHEN); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX3CHSEL, + 0x01 << TX_CHSEL, 0x01 << TX_CHSEL); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_TX3CHSEL, + (0x03) << TX_CHEN, 0x03 << TX_CHEN); +#endif /* HDMI */ + } + } else { #ifdef SUNXI_DAUDIO_MODE_B - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_RXCHMAP0, SUNXI_DEFAULT_CHMAP0); - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_RXCHMAP1, SUNXI_DEFAULT_CHMAP1); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_RXCHMAP0, + SUNXI_DEFAULT_CHMAP0); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_RXCHMAP1, + SUNXI_DEFAULT_CHMAP1); #else - regmap_write(sunxi_daudio->regmap, - SUNXI_DAUDIO_RXCHMAP, SUNXI_DEFAULT_CHMAP); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_RXCHMAP, + SUNXI_DEFAULT_CHMAP); #endif - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CHCFG, - (SUNXI_DAUDIO_RX_SLOT_MASK<regmap, SUNXI_DAUDIO_RXCHSEL, - (SUNXI_DAUDIO_RX_CHSEL_MASK<regmap, SUNXI_DAUDIO_CHCFG, + (SUNXI_DAUDIO_RX_SLOT_MASK << RX_SLOT_NUM), + ((params_channels(params) - 1) << RX_SLOT_NUM)); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_RXCHSEL, + (SUNXI_DAUDIO_RX_CHSEL_MASK << RX_CHSEL), + ((params_channels(params) - 1) << RX_CHSEL)); + } #ifdef SUNXI_HDMI_AUDIO_ENABLE - /* Special processing for HDMI hub playback to enable hdmi module */ - if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) { - mutex_lock(&sunxi_daudio->mutex); - regmap_read(sunxi_daudio->regmap, - SUNXI_DAUDIO_FIFOCTL, ®_val); - sunxi_daudio->hub_mode = (reg_val & (1<hub_mode) { - sunxi_hdmi_codec_hw_params(substream, params, NULL); - sunxi_hdmi_codec_prepare(substream, NULL); - } - mutex_unlock(&sunxi_daudio->mutex); - } + /* Special processing for HDMI hub playback to enable hdmi module */ + if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) { + mutex_lock(&sunxi_daudio->mutex); + regmap_read(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, ®_val); + sunxi_daudio->hub_mode = (reg_val & (1 << HUB_EN)); + if (sunxi_daudio->hub_mode) { + sunxi_hdmi_codec_hw_params(substream, params, NULL); + sunxi_hdmi_codec_prepare(substream, NULL); + } + mutex_unlock(&sunxi_daudio->mutex); + } #endif #ifdef CONFIG_SND_SUNXI_MAD - /*mad only supported 16k/48KHz samplerate when capturing*/ - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - if (sunxi_daudio->mad_bind == 1) { - if (params_format(params) != SNDRV_PCM_FORMAT_S16_LE) { - dev_err(sunxi_daudio->dev, "unsupported mad sample bits\n"); - return -EINVAL; - } - if ((params_rate(params) == 16000) || (params_rate(params) == 48000)) { - sunxi_mad_hw_params(params_channels(params), params_rate(params)); - sunxi_daudio->audio_src_chan_num = params_channels(params); - } else { - dev_err(sunxi_daudio->dev, "unsupported mad rate\n"); - return -EINVAL; - } - } - } + /*mad only supported 16k/48KHz samplerate when capturing*/ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (sunxi_daudio->mad_bind == 1) { + if (params_format(params) != SNDRV_PCM_FORMAT_S16_LE) { + dev_err(sunxi_daudio->dev, "unsupported mad sample bits\n"); + return -EINVAL; + } + if ((params_rate(params) == 16000) || + (params_rate(params) == 48000)) { + sunxi_mad_hw_params(params_channels(params), + params_rate(params)); + sunxi_daudio->audio_src_chan_num = params_channels(params); + } else { + dev_err(sunxi_daudio->dev, "unsupported mad rate\n"); + return -EINVAL; + } + } + } #endif - return 0; + return 0; } -static int sunxi_daudio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); +static int sunxi_daudio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - sunxi_daudio_init_fmt(sunxi_daudio, fmt); - return 0; + sunxi_daudio_init_fmt(sunxi_daudio, fmt); + return 0; } -static int sunxi_daudio_set_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int freq, int dir) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); +static int sunxi_daudio_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - if (clk_set_rate(sunxi_daudio->pllclk, freq)) { - dev_err(sunxi_daudio->dev, "set pllclk rate failed\n"); - pr_err("set sysclk error"); - return -EBUSY; - } - return 0; + printk("wzj:set sysclk:%d, id:%d, name:%s\n", freq, dai->id, dai->name); + if (clk_set_rate(sunxi_daudio->pllclk, freq)) { + dev_err(sunxi_daudio->dev, "set pllclk rate failed\n"); + pr_err("set sysclk error"); + return -EBUSY; + } + return 0; } -static int sunxi_daudio_set_clkdiv(struct snd_soc_dai *dai, - int clk_id, int clk_div) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - unsigned int bclk_div, div_ratio; +static int sunxi_daudio_set_clkdiv(struct snd_soc_dai *dai, int clk_id, + int clk_div) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + unsigned int bclk_div, div_ratio; - if (sunxi_daudio->pdata->tdm_config) - /* I2S/TDM two channel mode */ - div_ratio = clk_div/(2 * sunxi_daudio->pdata->pcm_lrck_period); - else - /* PCM mode */ - div_ratio = clk_div / sunxi_daudio->pdata->pcm_lrck_period; + if (sunxi_daudio->pdata->tdm_config) + /* I2S/TDM two channel mode */ + div_ratio = clk_div / (2 * sunxi_daudio->pdata->pcm_lrck_period); + else + /* PCM mode */ + div_ratio = clk_div / sunxi_daudio->pdata->pcm_lrck_period; - switch (div_ratio) { - case 1: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_1; - break; - case 2: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_2; - break; - case 4: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_3; - break; - case 6: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_4; - break; - case 8: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_5; - break; - case 12: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_6; - break; - case 16: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_7; - break; - case 24: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_8; - break; - case 32: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_9; - break; - case 48: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_10; - break; - case 64: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_11; - break; - case 96: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_12; - break; - case 128: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_13; - break; - case 176: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_14; - break; - case 192: - bclk_div = SUNXI_DAUDIO_BCLK_DIV_15; - break; - default: - dev_err(sunxi_daudio->dev, "unsupport clk_div\n"); - return -EINVAL; - } + switch (div_ratio) { + case 1: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_1; + break; + case 2: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_2; + break; + case 4: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_3; + break; + case 6: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_4; + break; + case 8: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_5; + break; + case 12: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_6; + break; + case 16: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_7; + break; + case 24: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_8; + break; + case 32: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_9; + break; + case 48: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_10; + break; + case 64: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_11; + break; + case 96: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_12; + break; + case 128: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_13; + break; + case 176: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_14; + break; + case 192: + bclk_div = SUNXI_DAUDIO_BCLK_DIV_15; + break; + default: + dev_err(sunxi_daudio->dev, "unsupport clk_div\n"); + return -EINVAL; + } - /* setting bclk to driver external codec bit clk */ - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CLKDIV, - (SUNXI_DAUDIO_BCLK_DIV_MASK<regmap, SUNXI_DAUDIO_CLKDIV, + (SUNXI_DAUDIO_BCLK_DIV_MASK << BCLK_DIV), + (bclk_div << BCLK_DIV)); + printk("wzj:set bclk:%d, inputdiv:%d, period:%d, clkid:%d\n", bclk_div, clk_div, sunxi_daudio->pdata->pcm_lrck_period, clk_id); + return 0; } static int sunxi_daudio_dai_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + struct snd_soc_dai *dai) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + printk("Wzj:sunxi_daudio_dai_startup\n"); #ifdef CONFIG_SND_SUNXI_MAD - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_card *card = rtd->card; - struct sunxi_mad_priv *sunxi_daudio_priv = snd_soc_card_get_drvdata(card); - unsigned int path_sel; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct sunxi_mad_priv *sunxi_daudio_priv = snd_soc_card_get_drvdata(card); + unsigned int path_sel; #endif - /* FIXME: As HDMI module to play audio, it need at least 1100ms to sync. - * if we not wait we lost audio data to playback, or we wait for 1100ms - * to playback, user experience worst than you can imagine. So we need - * to cutdown that sync time by keeping clock signal on. we just enable - * it at startup and resume, cutdown it at remove and suspend time. - */ - if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (1 << CTL_TXEN)); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - snd_soc_dai_set_dma_data(dai, substream, - &sunxi_daudio->playback_dma_param); - } else { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + snd_soc_dai_set_dma_data(dai, substream, + &sunxi_daudio->playback_dma_param); + } else { #ifdef CONFIG_SND_SUNXI_MAD - sunxi_daudio->mad_bind = sunxi_daudio_priv->mad_bind; - sunxi_daudio->capture_en = 1; + sunxi_daudio->mad_bind = sunxi_daudio_priv->mad_bind; + sunxi_daudio->capture_en = 1; - if (sunxi_daudio->mad_bind == 1) { - sunxi_mad_init(); - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<capture_dma_param); + if (sunxi_daudio->mad_bind == 1) { + sunxi_mad_init(); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << MAD_DATA_EN), (1 << MAD_DATA_EN)); + sunxi_sram_dma_config(&sunxi_daudio->capture_dma_param); - switch (sunxi_daudio->pdata->tdm_num) { - case 0: - path_sel = 1; /*I2S0*/ - break; - case 1: - path_sel = 4; /*i2s1*/ - break; - case 2: - path_sel = 5; /*I2S2*/ - break; - default: - dev_err(sunxi_daudio->dev, "unsupported I2S number!\n"); - return -EINVAL; - } - /*open daudio src*/ - sunxi_mad_audio_source_sel(path_sel, 1); - } + switch (sunxi_daudio->pdata->tdm_num) { + case 0: + path_sel = 1; /*I2S0*/ + break; + case 1: + path_sel = 4; /*i2s1*/ + break; + case 2: + path_sel = 5; /*I2S2*/ + break; + default: + dev_err(sunxi_daudio->dev, "unsupported I2S number!\n"); + return -EINVAL; + } + /*open daudio src*/ + sunxi_mad_audio_source_sel(path_sel, 1); + } #endif - snd_soc_dai_set_dma_data(dai, substream, - &sunxi_daudio->capture_dma_param); - } + snd_soc_dai_set_dma_data(dai, substream, + &sunxi_daudio->capture_dma_param); + } - return 0; + return 0; } -static int sunxi_daudio_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - sunxi_daudio_txctrl_enable(sunxi_daudio, 1); - } else { - #if 0 +static int sunxi_daudio_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + printk("wzj:sunxi_daudio_trigger,cmd:%d\n", cmd); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + sunxi_daudio_txctrl_enable(sunxi_daudio, 1); + } else { +#if 0 if (daudio_loop_en) regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, @@ -1033,109 +974,128 @@ static int sunxi_daudio_trigger(struct snd_pcm_substream *substream, regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, (1<stream == SNDRV_PCM_STREAM_PLAYBACK) - sunxi_daudio_txctrl_enable(sunxi_daudio, 0); - else - sunxi_daudio_rxctrl_enable(sunxi_daudio, 0); - break; - default: - return -EINVAL; - } - return 0; +#endif + sunxi_daudio_rxctrl_enable(sunxi_daudio, 1); + } + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + sunxi_daudio_txctrl_enable(sunxi_daudio, 0); + else + sunxi_daudio_rxctrl_enable(sunxi_daudio, 0); + break; + default: + return -EINVAL; + } + return 0; } static int sunxi_daudio_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - unsigned int i; - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - for (i = 0 ; i < SUNXI_DAUDIO_FTX_TIMES ; i++) { - regmap_update_bits(sunxi_daudio->regmap, - SUNXI_DAUDIO_FIFOCTL, - (1<regmap, SUNXI_DAUDIO_TXCNT, 0); - } else { - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, - (1<regmap, SUNXI_DAUDIO_RXCNT, 0); - } - return 0; + struct snd_soc_dai *dai) { + unsigned int i; + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + printk("wzj:sunxi_daudio_prepare\n"); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + for (i = 0; i < SUNXI_DAUDIO_FTX_TIMES; i++) { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (1 << FIFO_CTL_FTX), (1 << FIFO_CTL_FTX)); + mdelay(1); + } + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_TXCNT, 0); + } else { + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_FIFOCTL, + (1 << FIFO_CTL_FRX), (1 << FIFO_CTL_FRX)); + regmap_write(sunxi_daudio->regmap, SUNXI_DAUDIO_RXCNT, 0); + } + return 0; } -static int sunxi_daudio_probe(struct snd_soc_dai *dai) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); +static struct snd_soc_dai *mic_i2s_dai = NULL; - mutex_init(&sunxi_daudio->mutex); +void netease_enable_clk(void) { + struct snd_soc_dai *dai = mic_i2s_dai; + if (dai != NULL && dai->id == 0) { + printk("Wzj:Begin to init i2s0 clk! dainame:%s\n", dai->name); + sunxi_daudio_set_sysclk(dai, 0, 24576000, 0); + sunxi_daudio_set_clkdiv(dai, 0, 256); + //sunxi_daudio_rxctrl_enable(sunxi_daudio, 1); + printk("end!\n"); + } +} +EXPORT_SYMBOL(netease_enable_clk); - sunxi_daudio_init(sunxi_daudio); - return 0; +static int sunxi_daudio_probe(struct snd_soc_dai *dai) { + printk("wzj:sunxi_daudio_probe\n"); + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + + mutex_init(&sunxi_daudio->mutex); + + sunxi_daudio_init(sunxi_daudio); + + if (dai != NULL && dai->id == 0) { + mic_i2s_dai = dai; + } + return 0; } static void sunxi_daudio_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + struct snd_soc_dai *dai) { + printk("wzj:sunxi_daudio_shutdown\n"); + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); #ifdef CONFIG_SND_SUNXI_MAD - unsigned int path_sel; + unsigned int path_sel; #endif - /* Special processing for HDMI hub playback to shutdown hdmi module */ - if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) { - mutex_lock(&sunxi_daudio->mutex); - if (sunxi_daudio->hub_mode) - sunxi_hdmi_codec_shutdown(substream, NULL); - mutex_unlock(&sunxi_daudio->mutex); - } + /* Special processing for HDMI hub playback to shutdown hdmi module */ + if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) { + mutex_lock(&sunxi_daudio->mutex); + if (sunxi_daudio->hub_mode) + sunxi_hdmi_codec_shutdown(substream, NULL); + mutex_unlock(&sunxi_daudio->mutex); + } #ifdef CONFIG_SND_SUNXI_MAD - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - if (sunxi_daudio->mad_bind == 1) { - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<pdata->tdm_num) { - case 0: - SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 0); - path_sel = 1; /*I2S0*/ - break; - case 1: - SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 1); - path_sel = 4; /*i2s1*/ - break; - case 2: - SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 2); - path_sel = 5; /*I2S2*/ - break; - } - sunxi_mad_audio_source_sel(path_sel, 0); /*diable daudio src*/ - /*if not use mad again*/ - sunxi_daudio->capture_dma_param.dma_addr = - sunxi_daudio->res.start + SUNXI_DAUDIO_RXFIFO; - sunxi_daudio->capture_en = 0; - } - } + printk("wzj:sunxi_daudio_shutdown0\n"); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + printk("wzj:sunxi_daudio_shutdown1\n"); + if (sunxi_daudio->mad_bind == 1) { + printk("wzj:sunxi_daudio_shutdown2\n"); + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << MAD_DATA_EN), (0 << MAD_DATA_EN)); + printk("wzj:sunxi_daudio_shutdown3, tdm:%d\n", + sunxi_daudio->pdata->tdm_num); + switch (sunxi_daudio->pdata->tdm_num) { + case 0: + SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 0); + path_sel = 1; /*I2S0*/ + break; + case 1: + SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 1); + path_sel = 4; /*i2s1*/ + break; + case 2: + SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 2); + path_sel = 5; /*I2S2*/ + break; + } + sunxi_mad_audio_source_sel(path_sel, 0); /*diable daudio src*/ + /*if not use mad again*/ + sunxi_daudio->capture_dma_param.dma_addr = + sunxi_daudio->res.start + SUNXI_DAUDIO_RXFIFO; + sunxi_daudio->capture_en = 0; + } + } #endif } -static int sunxi_daudio_remove(struct snd_soc_dai *dai) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); +static int sunxi_daudio_remove(struct snd_soc_dai *dai) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (0 << CTL_TXEN)); + return 0; } #define DAUDIO_STANDBY_DEBUG 0 @@ -1143,270 +1103,257 @@ static int sunxi_daudio_remove(struct snd_soc_dai *dai) #if DAUDIO_STANDBY_DEBUG static int daudio_standby_debug; -static int sunxi_daudio_debug_suspend(struct sunxi_daudio_info *sunxi_daudio) -{ - int ret = 0; +static int sunxi_daudio_debug_suspend(struct sunxi_daudio_info *sunxi_daudio) { + int ret = 0; - pr_debug("[daudio] suspend .%s start\n", dev_name(sunxi_daudio->dev)); - /* Global disable I2S/TDM module */ - sunxi_daudio_global_enable(sunxi_daudio, 0); + pr_debug("[daudio] suspend .%s start\n", dev_name(sunxi_daudio->dev)); + /* Global disable I2S/TDM module */ + sunxi_daudio_global_enable(sunxi_daudio, 0); - if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (0 << CTL_TXEN)); - clk_disable_unprepare(sunxi_daudio->moduleclk); - clk_disable_unprepare(sunxi_daudio->pllclk); + clk_disable_unprepare(sunxi_daudio->moduleclk); + clk_disable_unprepare(sunxi_daudio->pllclk); - if (sunxi_daudio->pdata->external_type) { - ret = pinctrl_select_state(sunxi_daudio->pinctrl, - sunxi_daudio->pinstate_sleep); - if (ret) { - pr_warn("[daudio]select pin sleep state failed\n"); - return ret; - } - devm_pinctrl_put(sunxi_daudio->pinctrl); - } + if (sunxi_daudio->pdata->external_type) { + ret = pinctrl_select_state(sunxi_daudio->pinctrl, + sunxi_daudio->pinstate_sleep); + if (ret) { + pr_warn("[daudio]select pin sleep state failed\n"); + return ret; + } + devm_pinctrl_put(sunxi_daudio->pinctrl); + } - pr_debug("[daudio] suspend-->line%d\n", __LINE__); - if (sunxi_daudio->vol_supply.daudio_regulator) { - pr_debug("[daudio] suspend-->line%d\n", __LINE__); - regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); - pr_debug("[daudio] suspend-->line%d\n", __LINE__); - } + pr_debug("[daudio] suspend-->line%d\n", __LINE__); + if (sunxi_daudio->vol_supply.daudio_regulator) { + pr_debug("[daudio] suspend-->line%d\n", __LINE__); + regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); + pr_debug("[daudio] suspend-->line%d\n", __LINE__); + } - pr_debug("[daudio] suspend .%s end\n", dev_name(sunxi_daudio->dev)); + pr_debug("[daudio] suspend .%s end\n", dev_name(sunxi_daudio->dev)); - return 0; + return 0; } -static int sunxi_daudio_debug_resume(struct sunxi_daudio_info *sunxi_daudio) -{ - int ret = 0; +static int sunxi_daudio_debug_resume(struct sunxi_daudio_info *sunxi_daudio) { + int ret = 0; - pr_debug("[%s] resume .%s start\n", __func__, - dev_name(sunxi_daudio->dev)); + pr_debug("[%s] resume .%s start\n", __func__, dev_name(sunxi_daudio->dev)); - if (sunxi_daudio->vol_supply.daudio_regulator) { - ret = regulator_enable(sunxi_daudio->vol_supply.daudio_regulator); - if (ret) { - dev_err(sunxi_daudio->dev, - "resume enable duaido[%d] vcc-pin failed\n", - sunxi_daudio->pdata->tdm_num); - goto err_resume_out; - } - } + if (sunxi_daudio->vol_supply.daudio_regulator) { + ret = regulator_enable(sunxi_daudio->vol_supply.daudio_regulator); + if (ret) { + dev_err(sunxi_daudio->dev, + "resume enable duaido[%d] vcc-pin failed\n", + sunxi_daudio->pdata->tdm_num); + goto err_resume_out; + } + } - if (clk_prepare_enable(sunxi_daudio->pllclk)) { - dev_err(sunxi_daudio->dev, "pllclk resume failed\n"); - ret = -EBUSY; - goto err_resume_out; - } + if (clk_prepare_enable(sunxi_daudio->pllclk)) { + dev_err(sunxi_daudio->dev, "pllclk resume failed\n"); + ret = -EBUSY; + goto err_resume_out; + } - if (clk_prepare_enable(sunxi_daudio->moduleclk)) { - dev_err(sunxi_daudio->dev, "moduleclk resume failed\n"); - ret = -EBUSY; - goto err_pllclk_disable; - } + if (clk_prepare_enable(sunxi_daudio->moduleclk)) { + dev_err(sunxi_daudio->dev, "moduleclk resume failed\n"); + ret = -EBUSY; + goto err_pllclk_disable; + } - if (sunxi_daudio->pdata->external_type) { - sunxi_daudio->pinctrl = devm_pinctrl_get(sunxi_daudio->dev); - if (IS_ERR_OR_NULL(sunxi_daudio)) { - dev_err(sunxi_daudio->dev, "pinctrl resume get fail\n"); - ret = -ENOMEM; - goto err_moduleclk_disable; - } + if (sunxi_daudio->pdata->external_type) { + sunxi_daudio->pinctrl = devm_pinctrl_get(sunxi_daudio->dev); + if (IS_ERR_OR_NULL(sunxi_daudio)) { + dev_err(sunxi_daudio->dev, "pinctrl resume get fail\n"); + ret = -ENOMEM; + goto err_moduleclk_disable; + } - sunxi_daudio->pinstate = pinctrl_lookup_state( - sunxi_daudio->pinctrl, PINCTRL_STATE_DEFAULT); - if (IS_ERR_OR_NULL(sunxi_daudio->pinstate)) { - dev_err(sunxi_daudio->dev, - "pinctrl default state get failed\n"); - ret = -EINVAL; - goto err_pinctrl_put; - } + sunxi_daudio->pinstate = + pinctrl_lookup_state(sunxi_daudio->pinctrl, PINCTRL_STATE_DEFAULT); + if (IS_ERR_OR_NULL(sunxi_daudio->pinstate)) { + dev_err(sunxi_daudio->dev, "pinctrl default state get failed\n"); + ret = -EINVAL; + goto err_pinctrl_put; + } - sunxi_daudio->pinstate_sleep = pinctrl_lookup_state( - sunxi_daudio->pinctrl, PINCTRL_STATE_SLEEP); - if (IS_ERR_OR_NULL(sunxi_daudio->pinstate_sleep)) { - dev_err(sunxi_daudio->dev, - "pinctrl sleep state get failed\n"); - ret = -EINVAL; - goto err_pinctrl_put; - } + sunxi_daudio->pinstate_sleep = + pinctrl_lookup_state(sunxi_daudio->pinctrl, PINCTRL_STATE_SLEEP); + if (IS_ERR_OR_NULL(sunxi_daudio->pinstate_sleep)) { + dev_err(sunxi_daudio->dev, "pinctrl sleep state get failed\n"); + ret = -EINVAL; + goto err_pinctrl_put; + } - ret = pinctrl_select_state(sunxi_daudio->pinctrl, - sunxi_daudio->pinstate); - if (ret) - dev_warn(sunxi_daudio->dev, - "daudio set pinctrl default state fail\n"); - } + ret = + pinctrl_select_state(sunxi_daudio->pinctrl, sunxi_daudio->pinstate); + if (ret) + dev_warn(sunxi_daudio->dev, + "daudio set pinctrl default state fail\n"); + } - sunxi_daudio_init(sunxi_daudio); + sunxi_daudio_init(sunxi_daudio); - /* Global enable I2S/TDM module */ - sunxi_daudio_global_enable(sunxi_daudio, 1); + /* Global enable I2S/TDM module */ + sunxi_daudio_global_enable(sunxi_daudio, 1); - if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (1 << CTL_TXEN)); - pr_debug("[%s] resume .%s end\n", __func__, - dev_name(sunxi_daudio->dev)); + pr_debug("[%s] resume .%s end\n", __func__, dev_name(sunxi_daudio->dev)); - return 0; + return 0; err_pinctrl_put: - devm_pinctrl_put(sunxi_daudio->pinctrl); + devm_pinctrl_put(sunxi_daudio->pinctrl); err_moduleclk_disable: - clk_disable_unprepare(sunxi_daudio->moduleclk); + clk_disable_unprepare(sunxi_daudio->moduleclk); err_pllclk_disable: - clk_disable_unprepare(sunxi_daudio->pllclk); + clk_disable_unprepare(sunxi_daudio->pllclk); err_resume_out: - return ret; + return ret; } #endif -static int sunxi_daudio_suspend(struct snd_soc_dai *dai) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - int ret = 0; +static int sunxi_daudio_suspend(struct snd_soc_dai *dai) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + int ret = 0; - pr_debug("[daudio] suspend .%s start\n", dev_name(sunxi_daudio->dev)); + printk("[daudio] suspend .%s start\n", dev_name(sunxi_daudio->dev)); #ifdef CONFIG_SND_SUNXI_MAD - if ((sunxi_daudio->mad_bind == 1) && (sunxi_daudio->capture_en == 1)) { - sunxi_mad_suspend_external(sunxi_daudio->lpsd_chan_sel, - sunxi_daudio->mad_standby_chan_sel); - pr_debug("mad suspend succeed %s\n", __func__); - return 0; - } + if ((sunxi_daudio->mad_bind == 1) && (sunxi_daudio->capture_en == 1)) { + sunxi_mad_suspend_external(sunxi_daudio->lpsd_chan_sel, + sunxi_daudio->mad_standby_chan_sel); + pr_debug("mad suspend succeed %s\n", __func__); + return 0; + } #endif - /* Global disable I2S/TDM module */ - sunxi_daudio_global_enable(sunxi_daudio, 0); + /* Global disable I2S/TDM module */ + sunxi_daudio_global_enable(sunxi_daudio, 0); - if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (0 << CTL_TXEN)); - clk_disable_unprepare(sunxi_daudio->moduleclk); - clk_disable_unprepare(sunxi_daudio->pllclk); + clk_disable_unprepare(sunxi_daudio->moduleclk); + clk_disable_unprepare(sunxi_daudio->pllclk); - if (sunxi_daudio->pdata->external_type) { - ret = pinctrl_select_state(sunxi_daudio->pinctrl, - sunxi_daudio->pinstate_sleep); - if (ret) { - pr_warn("[daudio]select pin sleep state failed\n"); - return ret; - } - devm_pinctrl_put(sunxi_daudio->pinctrl); - } + if (sunxi_daudio->pdata->external_type) { + ret = pinctrl_select_state(sunxi_daudio->pinctrl, + sunxi_daudio->pinstate_sleep); + if (ret) { + pr_warn("[daudio]select pin sleep state failed\n"); + return ret; + } + devm_pinctrl_put(sunxi_daudio->pinctrl); + } - if (sunxi_daudio->vol_supply.daudio_regulator) - regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); + if (sunxi_daudio->vol_supply.daudio_regulator) + regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); - pr_debug("[daudio] suspend .%s end \n", dev_name(sunxi_daudio->dev)); + pr_debug("[daudio] suspend .%s end \n", dev_name(sunxi_daudio->dev)); - return 0; + return 0; } -static int sunxi_daudio_resume(struct snd_soc_dai *dai) -{ - struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); - int ret; +static int sunxi_daudio_resume(struct snd_soc_dai *dai) { + struct sunxi_daudio_info *sunxi_daudio = snd_soc_dai_get_drvdata(dai); + int ret; - pr_debug("[%s] resume .%s start\n", __func__, - dev_name(sunxi_daudio->dev)); + printk("[%s] resume .%s start\n", __func__, dev_name(sunxi_daudio->dev)); - if (sunxi_daudio->vol_supply.daudio_regulator) { - ret = regulator_enable(sunxi_daudio->vol_supply.daudio_regulator); - if (ret) { - dev_err(sunxi_daudio->dev, - "resume enable duaido vcc-pin failed\n"); - goto err_resume_out; - } - } + if (sunxi_daudio->vol_supply.daudio_regulator) { + ret = regulator_enable(sunxi_daudio->vol_supply.daudio_regulator); + if (ret) { + dev_err(sunxi_daudio->dev, "resume enable duaido vcc-pin failed\n"); + goto err_resume_out; + } + } #ifdef CONFIG_SND_SUNXI_MAD - if ((sunxi_daudio->mad_bind == 1) && (sunxi_daudio->capture_en == 1)) { - sunxi_mad_resume_external(sunxi_daudio->mad_standby_chan_sel, - sunxi_daudio->audio_src_chan_num); - pr_debug("mad resume succeed %s\n", __func__); - return 0; - } + if ((sunxi_daudio->mad_bind == 1) && (sunxi_daudio->capture_en == 1)) { + sunxi_mad_resume_external(sunxi_daudio->mad_standby_chan_sel, + sunxi_daudio->audio_src_chan_num); + pr_debug("mad resume succeed %s\n", __func__); + return 0; + } #endif - if (clk_prepare_enable(sunxi_daudio->pllclk)) { - dev_err(sunxi_daudio->dev, "pllclk resume failed\n"); - ret = -EBUSY; - goto err_resume_out; - } + if (clk_prepare_enable(sunxi_daudio->pllclk)) { + dev_err(sunxi_daudio->dev, "pllclk resume failed\n"); + ret = -EBUSY; + goto err_resume_out; + } - if (clk_prepare_enable(sunxi_daudio->moduleclk)) { - dev_err(sunxi_daudio->dev, "moduleclk resume failed\n"); - ret = -EBUSY; - goto err_pllclk_disable; - } + if (clk_prepare_enable(sunxi_daudio->moduleclk)) { + dev_err(sunxi_daudio->dev, "moduleclk resume failed\n"); + ret = -EBUSY; + goto err_pllclk_disable; + } - if (sunxi_daudio->pdata->external_type) { - sunxi_daudio->pinctrl = devm_pinctrl_get(sunxi_daudio->dev); - if (IS_ERR_OR_NULL(sunxi_daudio)) { - dev_err(sunxi_daudio->dev, "pinctrl resume get fail\n"); - ret = -ENOMEM; - goto err_moduleclk_disable; - } + if (sunxi_daudio->pdata->external_type) { + sunxi_daudio->pinctrl = devm_pinctrl_get(sunxi_daudio->dev); + if (IS_ERR_OR_NULL(sunxi_daudio)) { + dev_err(sunxi_daudio->dev, "pinctrl resume get fail\n"); + ret = -ENOMEM; + goto err_moduleclk_disable; + } - sunxi_daudio->pinstate = pinctrl_lookup_state( - sunxi_daudio->pinctrl, PINCTRL_STATE_DEFAULT); - if (IS_ERR_OR_NULL(sunxi_daudio->pinstate)) { - dev_err(sunxi_daudio->dev, - "pinctrl default state get failed\n"); - ret = -EINVAL; - goto err_pinctrl_put; - } + sunxi_daudio->pinstate = + pinctrl_lookup_state(sunxi_daudio->pinctrl, PINCTRL_STATE_DEFAULT); + if (IS_ERR_OR_NULL(sunxi_daudio->pinstate)) { + dev_err(sunxi_daudio->dev, "pinctrl default state get failed\n"); + ret = -EINVAL; + goto err_pinctrl_put; + } - sunxi_daudio->pinstate_sleep = pinctrl_lookup_state( - sunxi_daudio->pinctrl, PINCTRL_STATE_SLEEP); - if (IS_ERR_OR_NULL(sunxi_daudio->pinstate_sleep)) { - dev_err(sunxi_daudio->dev, - "pinctrl sleep state get failed\n"); - ret = -EINVAL; - goto err_pinctrl_put; - } + sunxi_daudio->pinstate_sleep = + pinctrl_lookup_state(sunxi_daudio->pinctrl, PINCTRL_STATE_SLEEP); + if (IS_ERR_OR_NULL(sunxi_daudio->pinstate_sleep)) { + dev_err(sunxi_daudio->dev, "pinctrl sleep state get failed\n"); + ret = -EINVAL; + goto err_pinctrl_put; + } - ret = pinctrl_select_state(sunxi_daudio->pinctrl, - sunxi_daudio->pinstate); - if (ret) - dev_warn(sunxi_daudio->dev, - "daudio set pinctrl default state fail\n"); - } + ret = + pinctrl_select_state(sunxi_daudio->pinctrl, sunxi_daudio->pinstate); + if (ret) + dev_warn(sunxi_daudio->dev, + "daudio set pinctrl default state fail\n"); + } - sunxi_daudio_init(sunxi_daudio); + sunxi_daudio_init(sunxi_daudio); - /* Global enable I2S/TDM module */ - sunxi_daudio_global_enable(sunxi_daudio, 1); + /* Global enable I2S/TDM module */ + sunxi_daudio_global_enable(sunxi_daudio, 1); - if (sunxi_daudio->pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) - regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, - (1<pdata->daudio_type == SUNXI_DAUDIO_TDMHDMI_TYPE) + regmap_update_bits(sunxi_daudio->regmap, SUNXI_DAUDIO_CTL, + (1 << CTL_TXEN), (1 << CTL_TXEN)); - pr_debug("[%s] resume .%s end\n", __func__, - dev_name(sunxi_daudio->dev)); - return 0; + pr_debug("[%s] resume .%s end\n", __func__, dev_name(sunxi_daudio->dev)); + return 0; err_pinctrl_put: - devm_pinctrl_put(sunxi_daudio->pinctrl); + devm_pinctrl_put(sunxi_daudio->pinctrl); err_moduleclk_disable: - clk_disable_unprepare(sunxi_daudio->moduleclk); + clk_disable_unprepare(sunxi_daudio->moduleclk); err_pllclk_disable: - clk_disable_unprepare(sunxi_daudio->pllclk); + clk_disable_unprepare(sunxi_daudio->pllclk); err_resume_out: - if (sunxi_daudio->vol_supply.daudio_regulator) - regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); - return ret; + if (sunxi_daudio->vol_supply.daudio_regulator) + regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); + return ret; } #if DAUDIO_STANDBY_DEBUG @@ -1421,77 +1368,74 @@ err_resume_out: * echo 1,0x1,0x1 > daudio_standby */ static ssize_t daudio_class_standby_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - int i; - ssize_t count = 0; - int daudio_num = daudio_standby_debug >> 4; - int standby_mode = (daudio_standby_debug >> 1) & 0x1; - int enable = daudio_standby_debug & 0x1; + struct class_attribute *attr, + char *buf) { + int i; + ssize_t count = 0; + int daudio_num = daudio_standby_debug >> 4; + int standby_mode = (daudio_standby_debug >> 1) & 0x1; + int enable = daudio_standby_debug & 0x1; - if (daudio_standby_debug == 0) { - count += sprintf(buf, "Example(:daudio_num->%d):\n", DAUDIO_NUM_MAX); - count += sprintf(buf + count, "echo 0,0x1,0x1 > daudio_standby\n\n"); - count += sprintf(buf + count, "param 1: 0 Daudio0; 1 Daudio1;...\n"); - count += sprintf(buf + count, "param 2: 0 Suspend; 1 Resume;\n"); - count += sprintf(buf + count, "param 3: 0 disabled; 1 enabled;\n"); - count += sprintf(buf + count, "Daudio[1], Standby->[resume], Enable\n\n"); - return count; - } + if (daudio_standby_debug == 0) { + count += sprintf(buf, "Example(:daudio_num->%d):\n", DAUDIO_NUM_MAX); + count += sprintf(buf + count, "echo 0,0x1,0x1 > daudio_standby\n\n"); + count += sprintf(buf + count, "param 1: 0 Daudio0; 1 Daudio1;...\n"); + count += sprintf(buf + count, "param 2: 0 Suspend; 1 Resume;\n"); + count += sprintf(buf + count, "param 3: 0 disabled; 1 enabled;\n"); + count += + sprintf(buf + count, "Daudio[1], Standby->[resume], Enable\n\n"); + return count; + } - pr_err("[%s], Daudio[%d], Standby->[%s], %s\n", __func__, - daudio_num, - standby_mode ? "resume":"suspend", - enable ? "Enable":"Disable"); - for (i = 0; i < DAUDIO_NUM_MAX; i++) { - if (sunxi_daudio_global[i] && sunxi_daudio_global[i]->pdata) { - if ((sunxi_daudio_global[i]->pdata->tdm_num == - (daudio_standby_debug >> 4)) && - (daudio_standby_debug & 0x1)) { - if ((daudio_standby_debug >> 1) & 0x1) { - sunxi_daudio_debug_resume( - sunxi_daudio_global[i]); - } else { - sunxi_daudio_debug_suspend( - sunxi_daudio_global[i]); - } - } - } - } + pr_err("[%s], Daudio[%d], Standby->[%s], %s\n", __func__, daudio_num, + standby_mode ? "resume" : "suspend", enable ? "Enable" : "Disable"); + for (i = 0; i < DAUDIO_NUM_MAX; i++) { + if (sunxi_daudio_global[i] && sunxi_daudio_global[i]->pdata) { + if ((sunxi_daudio_global[i]->pdata->tdm_num == + (daudio_standby_debug >> 4)) && + (daudio_standby_debug & 0x1)) { + if ((daudio_standby_debug >> 1) & 0x1) { + sunxi_daudio_debug_resume(sunxi_daudio_global[i]); + } else { + sunxi_daudio_debug_suspend(sunxi_daudio_global[i]); + } + } + } + } - daudio_standby_debug = 0; - return 0; + daudio_standby_debug = 0; + return 0; } static ssize_t daudio_class_standby_store(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) -{ - int ret; - int input_reg_group = 0; - int standby_mode = 0; - int input_bool_val = 0; + struct class_attribute *attr, + const char *buf, size_t count) { + int ret; + int input_reg_group = 0; + int standby_mode = 0; + int input_bool_val = 0; - ret = sscanf(buf, "%d,0x%x,0x%x", &input_reg_group, - &standby_mode, &input_bool_val); - if ((input_reg_group >= DAUDIO_NUM_MAX) || (input_reg_group < 0)) { - pr_err("not exist daudio%d\n", input_reg_group); - return count; - } - if ((standby_mode > 1) || (standby_mode < 0) || - (input_bool_val > 1) || (input_bool_val < 0)) { - pr_err("is bool vaule!!\n"); - return count; - } + ret = sscanf(buf, "%d,0x%x,0x%x", &input_reg_group, &standby_mode, + &input_bool_val); + if ((input_reg_group >= DAUDIO_NUM_MAX) || (input_reg_group < 0)) { + pr_err("not exist daudio%d\n", input_reg_group); + return count; + } + if ((standby_mode > 1) || (standby_mode < 0) || (input_bool_val > 1) || + (input_bool_val < 0)) { + pr_err("is bool vaule!!\n"); + return count; + } - daudio_standby_debug = (input_reg_group << 4) & 0xf0; - daudio_standby_debug |= (standby_mode << 1) & 0x2; - daudio_standby_debug |= input_bool_val & 0x1; + daudio_standby_debug = (input_reg_group << 4) & 0xf0; + daudio_standby_debug |= (standby_mode << 1) & 0x2; + daudio_standby_debug |= input_bool_val & 0x1; - pr_err("ret:%d, Daudio[%d], Standby->[%s], %s\n", - ret, input_reg_group, standby_mode ? "resume":"suspend", - input_bool_val ? "Enable":"Disable"); + pr_err("ret:%d, Daudio[%d], Standby->[%s], %s\n", ret, input_reg_group, + standby_mode ? "resume" : "suspend", + input_bool_val ? "Enable" : "Disable"); - return count; + return count; } #endif @@ -1511,609 +1455,602 @@ static ssize_t daudio_class_standby_store(struct class *class, * echo 1,0,0x00,0xff > daudio_reg_debug */ static ssize_t daudio_class_debug_store(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) -{ - int ret; - int rw_flag; - int reg_val_read; - int input_reg_val = 0; - int input_reg_group = 0; - int input_reg_offset = 0; - int i = 0; + struct class_attribute *attr, + const char *buf, size_t count) { + int ret; + int rw_flag; + int reg_val_read; + int input_reg_val = 0; + int input_reg_group = 0; + int input_reg_offset = 0; + int i = 0; - ret = sscanf(buf, "%d,%d,0x%x,0x%x", &rw_flag, &input_reg_group, - &input_reg_offset, &input_reg_val); + ret = sscanf(buf, "%d,%d,0x%x,0x%x", &rw_flag, &input_reg_group, + &input_reg_offset, &input_reg_val); - if (!(rw_flag == 1 || rw_flag == 0)) { - pr_err("not rw_flag\n"); - return count; - } + if (!(rw_flag == 1 || rw_flag == 0)) { + pr_err("not rw_flag\n"); + return count; + } - if ((input_reg_group >= DAUDIO_NUM_MAX) || - !sunxi_daudio_global[input_reg_group]) { - pr_err("not exist daudio[%d] driver or device\n", - input_reg_group); - pr_err("Daudio device list:\n\n"); - for (i = 0; i < DAUDIO_NUM_MAX; i++) { - if (sunxi_daudio_global[i] != NULL) - pr_err(" Daudio[%d]\n", i); - } - return count; - } + if ((input_reg_group >= DAUDIO_NUM_MAX) || + !sunxi_daudio_global[input_reg_group]) { + pr_err("not exist daudio[%d] driver or device\n", input_reg_group); + pr_err("Daudio device list:\n\n"); + for (i = 0; i < DAUDIO_NUM_MAX; i++) { + if (sunxi_daudio_global[i] != NULL) + pr_err(" Daudio[%d]\n", i); + } + return count; + } - pr_err("Dump daudio reg:\n"); + pr_err("Dump daudio reg:\n"); - if (rw_flag) { - if (ret == 4) { - writel(input_reg_val, - sunxi_daudio_global[input_reg_group]->membase + - input_reg_offset); - reg_val_read = readl( - sunxi_daudio_global[input_reg_group]->membase + - input_reg_offset); - pr_err("\n\n Daudio[%d] Reg[0x%x] : 0x%x\n\n", - input_reg_group, input_reg_offset, - reg_val_read); - } else { - pr_err("\nnum of params invalid\n"); - } - } else { - switch (ret) { - case 2: - while (reg_labels[i].name != NULL) { - pr_err("%s 0x%p: 0x%x\n", reg_labels[i].name, - (sunxi_daudio_global[input_reg_group]->membase + - reg_labels[i].address), - readl(sunxi_daudio_global[input_reg_group]->membase + - reg_labels[i].address)); - i++; - } - break; - case 3: - reg_val_read = readl( - sunxi_daudio_global[input_reg_group]->membase + - input_reg_offset); - pr_err("\n\n Daudio[%d] Reg[0x%x] : 0x%x\n\n", - input_reg_group, input_reg_offset, - reg_val_read); - break; - default: - pr_err("\nnum of params invalid\n"); - break; - } - } + if (rw_flag) { + if (ret == 4) { + writel(input_reg_val, + sunxi_daudio_global[input_reg_group]->membase + + input_reg_offset); + reg_val_read = readl(sunxi_daudio_global[input_reg_group]->membase + + input_reg_offset); + pr_err("\n\n Daudio[%d] Reg[0x%x] : 0x%x\n\n", input_reg_group, + input_reg_offset, reg_val_read); + } else { + pr_err("\nnum of params invalid\n"); + } + } else { + switch (ret) { + case 2: + while (reg_labels[i].name != NULL) { + pr_err("%s 0x%p: 0x%x\n", reg_labels[i].name, + (sunxi_daudio_global[input_reg_group]->membase + + reg_labels[i].address), + readl(sunxi_daudio_global[input_reg_group]->membase + + reg_labels[i].address)); + i++; + } + break; + case 3: + reg_val_read = readl(sunxi_daudio_global[input_reg_group]->membase + + input_reg_offset); + pr_err("\n\n Daudio[%d] Reg[0x%x] : 0x%x\n\n", input_reg_group, + input_reg_offset, reg_val_read); + break; + default: + pr_err("\nnum of params invalid\n"); + break; + } + } - return count; + return count; } static ssize_t daudio_class_debug_show(struct class *class, - struct class_attribute *attr, char *buf) -{ - int count = 0; - int i = 0; + struct class_attribute *attr, + char *buf) { + int count = 0; + int i = 0; - count += sprintf(buf, "Example(:daudio_num->%d):\n", DAUDIO_NUM_MAX); - count += sprintf(buf + count, "param 1: 0 read; 1 write;\n"); - count += sprintf(buf + count, "param 2: 0 daudio0; 1 dauido1...;\n"); - count += sprintf(buf + count, "param 3: address\n"); - count += sprintf(buf + count, "param 4: reg value\n\n"); - count += sprintf(buf + count, "echo 0,0 > daudio_reg_debug\n"); - count += sprintf(buf + count, "echo 0,1,0x4 > daudio_reg_debug\n"); - count += sprintf(buf + count, "echo 1,0,0x4,0x1 > daudio_reg_debug\n"); - count += sprintf(buf + count, "echo 1,1,0x14,0xa > daudio_reg_debug\n\n"); + count += sprintf(buf, "Example(:daudio_num->%d):\n", DAUDIO_NUM_MAX); + count += sprintf(buf + count, "param 1: 0 read; 1 write;\n"); + count += sprintf(buf + count, "param 2: 0 daudio0; 1 dauido1...;\n"); + count += sprintf(buf + count, "param 3: address\n"); + count += sprintf(buf + count, "param 4: reg value\n\n"); + count += sprintf(buf + count, "echo 0,0 > daudio_reg_debug\n"); + count += sprintf(buf + count, "echo 0,1,0x4 > daudio_reg_debug\n"); + count += sprintf(buf + count, "echo 1,0,0x4,0x1 > daudio_reg_debug\n"); + count += sprintf(buf + count, "echo 1,1,0x14,0xa > daudio_reg_debug\n\n"); - count += sprintf(buf + count, "daudio device list:\n\n"); - for (i = 0; i < DAUDIO_NUM_MAX; i++) { - if (sunxi_daudio_global[i] != NULL) - count += sprintf(buf + count, " Daudio[%d]\n", i); - } + count += sprintf(buf + count, "daudio device list:\n\n"); + for (i = 0; i < DAUDIO_NUM_MAX; i++) { + if (sunxi_daudio_global[i] != NULL) + count += sprintf(buf + count, " Daudio[%d]\n", i); + } - return count; + return count; } static struct class_attribute daudio_class_attrs[] = { #if DAUDIO_STANDBY_DEBUG - __ATTR(daudio_standby, S_IRUGO|S_IWUSR, daudio_class_standby_show, daudio_class_standby_store), + __ATTR(daudio_standby, S_IRUGO | S_IWUSR, daudio_class_standby_show, + daudio_class_standby_store), #endif - __ATTR(daudio_reg_debug, S_IRUGO|S_IWUSR, daudio_class_debug_show, daudio_class_debug_store), - __ATTR_NULL -}; + __ATTR(daudio_reg_debug, S_IRUGO | S_IWUSR, daudio_class_debug_show, + daudio_class_debug_store), + __ATTR_NULL}; static struct class daudio_class = { - .name = "daudio", - .class_attrs = daudio_class_attrs, + .name = "daudio", + .class_attrs = daudio_class_attrs, }; - -#define SUNXI_DAUDIO_RATES (SNDRV_PCM_RATE_8000_192000 \ - | SNDRV_PCM_RATE_KNOT) +#define SUNXI_DAUDIO_RATES (SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT) static struct snd_soc_dai_ops sunxi_daudio_dai_ops = { - .hw_params = sunxi_daudio_hw_params, - .set_sysclk = sunxi_daudio_set_sysclk, - .set_clkdiv = sunxi_daudio_set_clkdiv, - .set_fmt = sunxi_daudio_set_fmt, - .startup = sunxi_daudio_dai_startup, - .trigger = sunxi_daudio_trigger, - .prepare = sunxi_daudio_prepare, - .shutdown = sunxi_daudio_shutdown, + .hw_params = sunxi_daudio_hw_params, + .set_sysclk = sunxi_daudio_set_sysclk, + .set_clkdiv = sunxi_daudio_set_clkdiv, + .set_fmt = sunxi_daudio_set_fmt, + .startup = sunxi_daudio_dai_startup, + .trigger = sunxi_daudio_trigger, + .prepare = sunxi_daudio_prepare, + .shutdown = sunxi_daudio_shutdown, }; static struct snd_soc_dai_driver sunxi_daudio_dai = { - .probe = sunxi_daudio_probe, - .suspend = sunxi_daudio_suspend, - .resume = sunxi_daudio_resume, - .remove = sunxi_daudio_remove, - .playback = { - .channels_min = 1, - .channels_max = 8, - .rates = SUNXI_DAUDIO_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE - | SNDRV_PCM_FMTBIT_S20_3LE - | SNDRV_PCM_FMTBIT_S24_LE - | SNDRV_PCM_FMTBIT_S32_LE, - }, - .capture = { - .channels_min = 1, - .channels_max = 8, - .rates = SUNXI_DAUDIO_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE - | SNDRV_PCM_FMTBIT_S20_3LE - | SNDRV_PCM_FMTBIT_S24_LE - | SNDRV_PCM_FMTBIT_S32_LE, - }, - .ops = &sunxi_daudio_dai_ops, + .probe = sunxi_daudio_probe, + .suspend = sunxi_daudio_suspend, + .resume = sunxi_daudio_resume, + .remove = sunxi_daudio_remove, + .playback = + { + .channels_min = 1, + .channels_max = 8, + .rates = SUNXI_DAUDIO_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = + { + .channels_min = 1, + .channels_max = 8, + .rates = SUNXI_DAUDIO_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &sunxi_daudio_dai_ops, }; static const struct snd_soc_component_driver sunxi_daudio_component = { - .name = DRV_NAME, - .controls = sunxi_daudio_controls, - .num_controls = ARRAY_SIZE(sunxi_daudio_controls), + .name = DRV_NAME, + .controls = sunxi_daudio_controls, + .num_controls = ARRAY_SIZE(sunxi_daudio_controls), }; static struct sunxi_daudio_platform_data sunxi_daudio = { - .daudio_type = SUNXI_DAUDIO_EXTERNAL_TYPE, - .external_type = 1, + .daudio_type = SUNXI_DAUDIO_EXTERNAL_TYPE, + .external_type = 1, }; static struct sunxi_daudio_platform_data sunxi_tdmhdmi = { - .daudio_type = SUNXI_DAUDIO_TDMHDMI_TYPE, - .external_type = 0, - .audio_format = 1, - .signal_inversion = 1, - .daudio_master = 4, - .pcm_lrck_period = 32, - .slot_width_select = 32, - .tdm_config = 1, - .mclk_div = 0, + .daudio_type = SUNXI_DAUDIO_TDMHDMI_TYPE, + .external_type = 0, + .audio_format = 1, + .signal_inversion = 1, + .daudio_master = 4, + .pcm_lrck_period = 32, + .slot_width_select = 32, + .tdm_config = 1, + .mclk_div = 0, }; static const struct of_device_id sunxi_daudio_of_match[] = { - { - .compatible = "allwinner,sunxi-daudio", - .data = &sunxi_daudio, - }, - { - .compatible = "allwinner,sunxi-tdmhdmi", - .data = &sunxi_tdmhdmi, - }, - {}, + { + .compatible = "allwinner,sunxi-daudio", + .data = &sunxi_daudio, + }, + { + .compatible = "allwinner,sunxi-tdmhdmi", + .data = &sunxi_tdmhdmi, + }, + {}, }; MODULE_DEVICE_TABLE(of, sunxi_daudio_of_match); static const struct regmap_config sunxi_daudio_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = SUNXI_DAUDIO_DEBUG, - .cache_type = REGCACHE_NONE, + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = SUNXI_DAUDIO_DEBUG, + .cache_type = REGCACHE_NONE, }; -static int sunxi_daudio_dev_probe(struct platform_device *pdev) -{ - struct resource res, *memregion; - const struct of_device_id *match; - void __iomem *sunxi_daudio_membase; - struct sunxi_daudio_info *sunxi_daudio; - struct device_node *np = pdev->dev.of_node; - unsigned int temp_val; - int ret; +static int sunxi_daudio_dev_probe(struct platform_device *pdev) { + struct resource res, *memregion; + const struct of_device_id *match; + void __iomem *sunxi_daudio_membase; + struct sunxi_daudio_info *sunxi_daudio; + struct device_node *np = pdev->dev.of_node; + unsigned int temp_val; + int ret; + printk("wzj:sunxi_daudio_dev_probe\n"); + match = of_match_device(sunxi_daudio_of_match, &pdev->dev); + if (match) { + sunxi_daudio = devm_kzalloc( + &pdev->dev, sizeof(struct sunxi_daudio_info), GFP_KERNEL); + if (!sunxi_daudio) { + dev_err(&pdev->dev, "alloc sunxi_daudio failed\n"); + ret = -ENOMEM; + goto err_node_put; + } + dev_set_drvdata(&pdev->dev, sunxi_daudio); + sunxi_daudio->dev = &pdev->dev; - match = of_match_device(sunxi_daudio_of_match, &pdev->dev); - if (match) { - sunxi_daudio = devm_kzalloc(&pdev->dev, - sizeof(struct sunxi_daudio_info), - GFP_KERNEL); - if (!sunxi_daudio) { - dev_err(&pdev->dev, "alloc sunxi_daudio failed\n"); - ret = -ENOMEM; - goto err_node_put; - } - dev_set_drvdata(&pdev->dev, sunxi_daudio); - sunxi_daudio->dev = &pdev->dev; + sunxi_daudio->pdata = devm_kzalloc( + &pdev->dev, sizeof(struct sunxi_daudio_platform_data), GFP_KERNEL); + if (!sunxi_daudio->pdata) { + dev_err(&pdev->dev, "alloc sunxi daudio platform data failed\n"); + ret = -ENOMEM; + goto err_devm_kfree; + } - sunxi_daudio->pdata = devm_kzalloc(&pdev->dev, - sizeof(struct sunxi_daudio_platform_data), - GFP_KERNEL); - if (!sunxi_daudio->pdata) { - dev_err(&pdev->dev, - "alloc sunxi daudio platform data failed\n"); - ret = -ENOMEM; - goto err_devm_kfree; - } + memcpy(sunxi_daudio->pdata, match->data, + sizeof(struct sunxi_daudio_platform_data)); + } else { + dev_err(&pdev->dev, "node match failed\n"); + return -EINVAL; + } - memcpy(sunxi_daudio->pdata, match->data, - sizeof(struct sunxi_daudio_platform_data)); - } else { - dev_err(&pdev->dev, "node match failed\n"); - return -EINVAL; - } - - ret = of_address_to_resource(np, 0, &res); - if (ret) { - dev_err(&pdev->dev, "parse device node resource failed\n"); - ret = -EINVAL; - goto err_devm_kfree; - } + ret = of_address_to_resource(np, 0, &res); + if (ret) { + dev_err(&pdev->dev, "parse device node resource failed\n"); + ret = -EINVAL; + goto err_devm_kfree; + } #ifdef CONFIG_SND_SUNXI_MAD - sunxi_daudio->mad_bind = 0; - sunxi_daudio->lpsd_chan_sel = 0; - sunxi_daudio->mad_standby_chan_sel = 0; - sunxi_daudio->res.start = res.start; - sunxi_daudio->capture_en = 0; + sunxi_daudio->mad_bind = 0; + sunxi_daudio->lpsd_chan_sel = 0; + sunxi_daudio->mad_standby_chan_sel = 0; + sunxi_daudio->res.start = res.start; + sunxi_daudio->capture_en = 0; #endif - memregion = devm_request_mem_region(&pdev->dev, res.start, - resource_size(&res), DRV_NAME); - if (!memregion) { - dev_err(&pdev->dev, "Memory region already claimed\n"); - ret = -EBUSY; - goto err_devm_kfree; - } + memregion = devm_request_mem_region(&pdev->dev, res.start, + resource_size(&res), DRV_NAME); + if (!memregion) { + dev_err(&pdev->dev, "Memory region already claimed\n"); + ret = -EBUSY; + goto err_devm_kfree; + } - sunxi_daudio_membase = ioremap(res.start, resource_size(&res)); - if (!sunxi_daudio_membase) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -EBUSY; - goto err_devm_kfree; - } - sunxi_daudio->membase = sunxi_daudio_membase; + sunxi_daudio_membase = ioremap(res.start, resource_size(&res)); + if (!sunxi_daudio_membase) { + dev_err(&pdev->dev, "ioremap failed\n"); + ret = -EBUSY; + goto err_devm_kfree; + } + sunxi_daudio->membase = sunxi_daudio_membase; - sunxi_daudio->regmap = devm_regmap_init_mmio(&pdev->dev, - sunxi_daudio_membase, - &sunxi_daudio_regmap_config); - if (IS_ERR(sunxi_daudio->regmap)) { - dev_err(&pdev->dev, "regmap init failed\n"); - ret = PTR_ERR(sunxi_daudio->regmap); - goto err_iounmap; - } + sunxi_daudio->regmap = devm_regmap_init_mmio( + &pdev->dev, sunxi_daudio_membase, &sunxi_daudio_regmap_config); + if (IS_ERR(sunxi_daudio->regmap)) { + dev_err(&pdev->dev, "regmap init failed\n"); + ret = PTR_ERR(sunxi_daudio->regmap); + goto err_iounmap; + } - sunxi_daudio->pllclk = of_clk_get(np, 0); - if (IS_ERR_OR_NULL(sunxi_daudio->pllclk)) { - dev_err(&pdev->dev, "pllclk get failed\n"); - ret = PTR_ERR(sunxi_daudio->pllclk); - goto err_iounmap; - } + sunxi_daudio->pllclk = of_clk_get(np, 0); + if (IS_ERR_OR_NULL(sunxi_daudio->pllclk)) { + dev_err(&pdev->dev, "pllclk get failed\n"); + ret = PTR_ERR(sunxi_daudio->pllclk); + goto err_iounmap; + } - sunxi_daudio->moduleclk = of_clk_get(np, 1); - if (IS_ERR_OR_NULL(sunxi_daudio->moduleclk)) { - dev_err(&pdev->dev, "moduleclk get failed\n"); - ret = PTR_ERR(sunxi_daudio->moduleclk); - goto err_pllclk_put; - } + sunxi_daudio->moduleclk = of_clk_get(np, 1); + if (IS_ERR_OR_NULL(sunxi_daudio->moduleclk)) { + dev_err(&pdev->dev, "moduleclk get failed\n"); + ret = PTR_ERR(sunxi_daudio->moduleclk); + goto err_pllclk_put; + } - if (clk_set_parent(sunxi_daudio->moduleclk, sunxi_daudio->pllclk)) { - dev_err(&pdev->dev, "set parent of moduleclk to pllclk fail\n"); - ret = -EBUSY; - goto err_moduleclk_put; - } - clk_prepare_enable(sunxi_daudio->pllclk); - clk_prepare_enable(sunxi_daudio->moduleclk); + if (clk_set_parent(sunxi_daudio->moduleclk, sunxi_daudio->pllclk)) { + dev_err(&pdev->dev, "set parent of moduleclk to pllclk fail\n"); + ret = -EBUSY; + goto err_moduleclk_put; + } + clk_prepare_enable(sunxi_daudio->pllclk); + clk_prepare_enable(sunxi_daudio->moduleclk); - if (sunxi_daudio->pdata->external_type) { - sunxi_daudio->pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR_OR_NULL(sunxi_daudio->pinctrl)) { - dev_err(&pdev->dev, "pinctrl get failed\n"); - ret = -EINVAL; - goto err_moduleclk_put; - } + if (sunxi_daudio->pdata->external_type) { + sunxi_daudio->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR_OR_NULL(sunxi_daudio->pinctrl)) { + dev_err(&pdev->dev, "pinctrl get failed\n"); + ret = -EINVAL; + goto err_moduleclk_put; + } - sunxi_daudio->pinstate = pinctrl_lookup_state( - sunxi_daudio->pinctrl, PINCTRL_STATE_DEFAULT); - if (IS_ERR_OR_NULL(sunxi_daudio->pinstate)) { - dev_err(&pdev->dev, "pinctrl default state get fail\n"); - ret = -EINVAL; - goto err_pinctrl_put; - } + sunxi_daudio->pinstate = + pinctrl_lookup_state(sunxi_daudio->pinctrl, PINCTRL_STATE_DEFAULT); + if (IS_ERR_OR_NULL(sunxi_daudio->pinstate)) { + dev_err(&pdev->dev, "pinctrl default state get fail\n"); + ret = -EINVAL; + goto err_pinctrl_put; + } - sunxi_daudio->pinstate_sleep = pinctrl_lookup_state( - sunxi_daudio->pinctrl, PINCTRL_STATE_SLEEP); - if (IS_ERR_OR_NULL(sunxi_daudio->pinstate_sleep)) { - dev_err(&pdev->dev, "pinctrl sleep state get failed\n"); - ret = -EINVAL; - goto err_pinctrl_put; - } + sunxi_daudio->pinstate_sleep = + pinctrl_lookup_state(sunxi_daudio->pinctrl, PINCTRL_STATE_SLEEP); + if (IS_ERR_OR_NULL(sunxi_daudio->pinstate_sleep)) { + dev_err(&pdev->dev, "pinctrl sleep state get failed\n"); + ret = -EINVAL; + goto err_pinctrl_put; + } - ret = pinctrl_select_state(sunxi_daudio->pinctrl, - sunxi_daudio->pinstate); - if (ret) - dev_warn(sunxi_daudio->dev, - "daudio set pinctrl default state fail\n"); - } + ret = + pinctrl_select_state(sunxi_daudio->pinctrl, sunxi_daudio->pinstate); + if (ret) + dev_warn(sunxi_daudio->dev, + "daudio set pinctrl default state fail\n"); + } - switch (sunxi_daudio->pdata->daudio_type) { - case SUNXI_DAUDIO_EXTERNAL_TYPE: - ret = of_property_read_u32(np, "tdm_num", &temp_val); - if (ret < 0) { - dev_warn(&pdev->dev, "tdm configuration missing\n"); - /* - * warnning just continue, - * making tdm_num as default setting - */ - sunxi_daudio->pdata->tdm_num = 0; - } else { - /* - * FIXME, for channel number mess, - * so just not check channel overflow - */ - sunxi_daudio->pdata->tdm_num = temp_val; - } + switch (sunxi_daudio->pdata->daudio_type) { + case SUNXI_DAUDIO_EXTERNAL_TYPE: + ret = of_property_read_u32(np, "tdm_num", &temp_val); + if (ret < 0) { + dev_warn(&pdev->dev, "tdm configuration missing\n"); + /* + * warnning just continue, + * making tdm_num as default setting + */ + sunxi_daudio->pdata->tdm_num = 0; + } else { + /* + * FIXME, for channel number mess, + * so just not check channel overflow + */ + sunxi_daudio->pdata->tdm_num = temp_val; + } - sunxi_daudio->playback_dma_param.src_maxburst = 4; - sunxi_daudio->playback_dma_param.dst_maxburst = 4; + sunxi_daudio->playback_dma_param.src_maxburst = 4; + sunxi_daudio->playback_dma_param.dst_maxburst = 4; - sunxi_daudio->capture_dma_param.dma_addr = - res.start + SUNXI_DAUDIO_RXFIFO; - sunxi_daudio->capture_dma_param.src_maxburst = 4; - sunxi_daudio->capture_dma_param.dst_maxburst = 4; + sunxi_daudio->capture_dma_param.dma_addr = + res.start + SUNXI_DAUDIO_RXFIFO; + sunxi_daudio->capture_dma_param.src_maxburst = 4; + sunxi_daudio->capture_dma_param.dst_maxburst = 4; - sunxi_daudio->playback_dma_param.dma_addr = - res.start + SUNXI_DAUDIO_TXFIFO; - switch (sunxi_daudio->pdata->tdm_num) { - case 0: - SUNXI_DAUDIO_DRQDST(sunxi_daudio, 0); - SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 0); - break; - case 1: - SUNXI_DAUDIO_DRQDST(sunxi_daudio, 1); - SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 1); - break; - case 2: - SUNXI_DAUDIO_DRQDST(sunxi_daudio, 2); - SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 2); - break; - case 3: - SUNXI_DAUDIO_DRQDST(sunxi_daudio, 3); - SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 3); - break; - default: - dev_warn(&pdev->dev, "tdm_num setting overflow\n"); - ret = -EFAULT; - goto err_pinctrl_put; - break; - } + sunxi_daudio->playback_dma_param.dma_addr = + res.start + SUNXI_DAUDIO_TXFIFO; + switch (sunxi_daudio->pdata->tdm_num) { + case 0: + SUNXI_DAUDIO_DRQDST(sunxi_daudio, 0); + SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 0); + break; + case 1: + SUNXI_DAUDIO_DRQDST(sunxi_daudio, 1); + SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 1); + break; + case 2: + SUNXI_DAUDIO_DRQDST(sunxi_daudio, 2); + SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 2); + break; + case 3: + SUNXI_DAUDIO_DRQDST(sunxi_daudio, 3); + SUNXI_DAUDIO_DRQSRC(sunxi_daudio, 3); + break; + default: + dev_warn(&pdev->dev, "tdm_num setting overflow\n"); + ret = -EFAULT; + goto err_pinctrl_put; + break; + } - sunxi_daudio->vol_supply.regulator_name = NULL; - ret = of_property_read_string(np, "daudio_regulator", - &sunxi_daudio->vol_supply.regulator_name); - if (ret < 0) { - dev_warn(&pdev->dev, "regulator missing or invalid\n"); - sunxi_daudio->vol_supply.daudio_regulator = NULL; - } else { - sunxi_daudio->vol_supply.daudio_regulator = - regulator_get(NULL, sunxi_daudio->vol_supply.regulator_name); - if (IS_ERR(sunxi_daudio->vol_supply.daudio_regulator)) { - pr_err("get duaido[%d] vcc-pin failed\n", - sunxi_daudio->pdata->tdm_num); - ret = -EFAULT; - goto err_pinctrl_put; - } else { - ret = regulator_set_voltage( - sunxi_daudio->vol_supply.daudio_regulator, - 3300000, 3300000); - if (ret) { - pr_err("set duaido[%d] voltage failed\n", - sunxi_daudio->pdata->tdm_num); - ret = -EFAULT; - goto err_regulator_get; - } - ret = regulator_enable( - sunxi_daudio->vol_supply.daudio_regulator); - if (ret) { - pr_err("enable duaido[%d] vcc-pin failed\n", - sunxi_daudio->pdata->tdm_num); - ret = -EFAULT; - goto err_regulator_get; - } - } - } + sunxi_daudio->vol_supply.regulator_name = NULL; + ret = of_property_read_string(np, "daudio_regulator", + &sunxi_daudio->vol_supply.regulator_name); + if (ret < 0) { + dev_warn(&pdev->dev, "regulator missing or invalid\n"); + sunxi_daudio->vol_supply.daudio_regulator = NULL; + } else { + sunxi_daudio->vol_supply.daudio_regulator = + regulator_get(NULL, sunxi_daudio->vol_supply.regulator_name); + if (IS_ERR(sunxi_daudio->vol_supply.daudio_regulator)) { + pr_err("get duaido[%d] vcc-pin failed\n", + sunxi_daudio->pdata->tdm_num); + ret = -EFAULT; + goto err_pinctrl_put; + } else { + ret = regulator_set_voltage( + sunxi_daudio->vol_supply.daudio_regulator, 3300000, + 3300000); + if (ret) { + pr_err("set duaido[%d] voltage failed\n", + sunxi_daudio->pdata->tdm_num); + ret = -EFAULT; + goto err_regulator_get; + } + ret = + regulator_enable(sunxi_daudio->vol_supply.daudio_regulator); + if (ret) { + pr_err("enable duaido[%d] vcc-pin failed\n", + sunxi_daudio->pdata->tdm_num); + ret = -EFAULT; + goto err_regulator_get; + } + } + } - ret = of_property_read_u32(np, "daudio_master", &temp_val); - if (ret < 0) { - dev_warn(&pdev->dev, "daudio_master configuration missing or invalid\n"); - /* - * default setting SND_SOC_DAIFMT_CBS_CFS mode - * codec clk & FRM slave - */ - sunxi_daudio->pdata->daudio_master = 4; - } else { - sunxi_daudio->pdata->daudio_master = temp_val; - } + ret = of_property_read_u32(np, "daudio_master", &temp_val); + if (ret < 0) { + dev_warn(&pdev->dev, + "daudio_master configuration missing or invalid\n"); + /* + * default setting SND_SOC_DAIFMT_CBS_CFS mode + * codec clk & FRM slave + */ + sunxi_daudio->pdata->daudio_master = 4; + } else { + sunxi_daudio->pdata->daudio_master = temp_val; + } - ret = of_property_read_u32(np, "pcm_lrck_period", &temp_val); - if (ret < 0) { - dev_warn(&pdev->dev, "pcm_lrck_period configuration missing or invalid\n"); - sunxi_daudio->pdata->pcm_lrck_period = 0; - } else { - sunxi_daudio->pdata->pcm_lrck_period = temp_val; - } + ret = of_property_read_u32(np, "pcm_lrck_period", &temp_val); + if (ret < 0) { + dev_warn(&pdev->dev, + "pcm_lrck_period configuration missing or invalid\n"); + sunxi_daudio->pdata->pcm_lrck_period = 0; + } else { + sunxi_daudio->pdata->pcm_lrck_period = temp_val; + } - ret = of_property_read_u32(np, "slot_width_select", &temp_val); - if (ret < 0) { - dev_warn(&pdev->dev, "slot_width_select configuration missing or invalid\n"); - sunxi_daudio->pdata->slot_width_select = 0; - } else { - sunxi_daudio->pdata->slot_width_select = temp_val; - } + ret = of_property_read_u32(np, "slot_width_select", &temp_val); + if (ret < 0) { + dev_warn(&pdev->dev, + "slot_width_select configuration missing or invalid\n"); + sunxi_daudio->pdata->slot_width_select = 0; + } else { + sunxi_daudio->pdata->slot_width_select = temp_val; + } - ret = of_property_read_u32(np, "audio_format", &temp_val); - if (ret < 0) { - dev_warn(&pdev->dev, "audio_format configuration missing or invalid\n"); - sunxi_daudio->pdata->audio_format = 1; - } else { - sunxi_daudio->pdata->audio_format = temp_val; - } + ret = of_property_read_u32(np, "audio_format", &temp_val); + if (ret < 0) { + dev_warn(&pdev->dev, + "audio_format configuration missing or invalid\n"); + sunxi_daudio->pdata->audio_format = 1; + } else { + sunxi_daudio->pdata->audio_format = temp_val; + } - ret = of_property_read_u32(np, "signal_inversion", &temp_val); - if (ret < 0) { - dev_warn(&pdev->dev, "signal_inversion configuration missing or invalid\n"); - sunxi_daudio->pdata->signal_inversion = 1; - } else { - sunxi_daudio->pdata->signal_inversion = temp_val; - } + ret = of_property_read_u32(np, "signal_inversion", &temp_val); + if (ret < 0) { + dev_warn(&pdev->dev, + "signal_inversion configuration missing or invalid\n"); + sunxi_daudio->pdata->signal_inversion = 1; + } else { + sunxi_daudio->pdata->signal_inversion = temp_val; + } - ret = of_property_read_u32(np, "frametype", &temp_val); - if (ret < 0) { - dev_warn(&pdev->dev, "frametype configuration missing or invalid\n"); - sunxi_daudio->pdata->frame_type = 0; - } else { - sunxi_daudio->pdata->frame_type = temp_val; - } + ret = of_property_read_u32(np, "frametype", &temp_val); + if (ret < 0) { + dev_warn(&pdev->dev, + "frametype configuration missing or invalid\n"); + sunxi_daudio->pdata->frame_type = 0; + } else { + sunxi_daudio->pdata->frame_type = temp_val; + } - ret = of_property_read_u32(np, "tdm_config", &temp_val); - if (ret < 0) { - dev_warn(&pdev->dev, "tdm_config configuration missing or invalid\n"); - sunxi_daudio->pdata->tdm_config = 1; - } else { - sunxi_daudio->pdata->tdm_config = temp_val; - } + ret = of_property_read_u32(np, "tdm_config", &temp_val); + if (ret < 0) { + dev_warn(&pdev->dev, + "tdm_config configuration missing or invalid\n"); + sunxi_daudio->pdata->tdm_config = 1; + } else { + sunxi_daudio->pdata->tdm_config = temp_val; + } - ret = of_property_read_u32(np, "mclk_div", &temp_val); - if (ret < 0) - sunxi_daudio->pdata->mclk_div = 0; - else - sunxi_daudio->pdata->mclk_div = temp_val; + ret = of_property_read_u32(np, "mclk_div", &temp_val); + if (ret < 0) + sunxi_daudio->pdata->mclk_div = 0; + else + sunxi_daudio->pdata->mclk_div = temp_val; - of_node_put(np); - break; - case SUNXI_DAUDIO_TDMHDMI_TYPE: + of_node_put(np); + break; + case SUNXI_DAUDIO_TDMHDMI_TYPE: #ifdef SUNXI_HDMI_AUDIO_ENABLE - sunxi_daudio->playback_dma_param.dma_addr = - res.start + SUNXI_DAUDIO_TXFIFO; - sunxi_daudio->playback_dma_param.dma_drq_type_num = - DRQDST_HDMI_TX; - sunxi_daudio->playback_dma_param.src_maxburst = 8; - sunxi_daudio->playback_dma_param.dst_maxburst = 8; - sunxi_daudio->hdmi_en = 1; + sunxi_daudio->playback_dma_param.dma_addr = + res.start + SUNXI_DAUDIO_TXFIFO; + sunxi_daudio->playback_dma_param.dma_drq_type_num = DRQDST_HDMI_TX; + sunxi_daudio->playback_dma_param.src_maxburst = 8; + sunxi_daudio->playback_dma_param.dst_maxburst = 8; + sunxi_daudio->hdmi_en = 1; #endif - break; - default: - dev_err(&pdev->dev, "missing digital audio type\n"); - ret = -EINVAL; - goto err_moduleclk_put; - } + break; + default: + dev_err(&pdev->dev, "missing digital audio type\n"); + ret = -EINVAL; + goto err_moduleclk_put; + } - ret = snd_soc_register_component(&pdev->dev, &sunxi_daudio_component, - &sunxi_daudio_dai, 1); - if (ret) { - dev_err(&pdev->dev, "component register failed\n"); - ret = -ENOMEM; - goto err_regulator_disable; - } + ret = snd_soc_register_component(&pdev->dev, &sunxi_daudio_component, + &sunxi_daudio_dai, 1); + if (ret) { + dev_err(&pdev->dev, "component register failed\n"); + ret = -ENOMEM; + goto err_regulator_disable; + } - switch (sunxi_daudio->pdata->daudio_type) { - case SUNXI_DAUDIO_EXTERNAL_TYPE: - ret = asoc_dma_platform_register(&pdev->dev, 0); - if (ret) { - dev_err(&pdev->dev, "register ASoC platform failed\n"); - ret = -ENOMEM; - goto err_unregister_component; - } - break; - case SUNXI_DAUDIO_TDMHDMI_TYPE: - ret = asoc_dma_platform_register(&pdev->dev, - SND_DMAENGINE_PCM_FLAG_NO_DT); - if (ret) { - dev_err(&pdev->dev, "register ASoC platform failed\n"); - ret = -ENOMEM; - goto err_unregister_component; - } - break; - default: - dev_err(&pdev->dev, "missing digital audio type\n"); - ret = -EINVAL; - goto err_unregister_component; - } + switch (sunxi_daudio->pdata->daudio_type) { + case SUNXI_DAUDIO_EXTERNAL_TYPE: + ret = asoc_dma_platform_register(&pdev->dev, 0); + if (ret) { + dev_err(&pdev->dev, "register ASoC platform failed\n"); + ret = -ENOMEM; + goto err_unregister_component; + } + break; + case SUNXI_DAUDIO_TDMHDMI_TYPE: + ret = asoc_dma_platform_register(&pdev->dev, + SND_DMAENGINE_PCM_FLAG_NO_DT); + if (ret) { + dev_err(&pdev->dev, "register ASoC platform failed\n"); + ret = -ENOMEM; + goto err_unregister_component; + } + break; + default: + dev_err(&pdev->dev, "missing digital audio type\n"); + ret = -EINVAL; + goto err_unregister_component; + } - if (device_count++ == 0) { - ret = class_register(&daudio_class); - if (ret) - pr_warn("daudio: Failed to create debugfs directory\n"); - } - sunxi_daudio_global[sunxi_daudio->pdata->tdm_num] = sunxi_daudio; + if (device_count++ == 0) { + ret = class_register(&daudio_class); + if (ret) + pr_warn("daudio: Failed to create debugfs directory\n"); + } + sunxi_daudio_global[sunxi_daudio->pdata->tdm_num] = sunxi_daudio; - sunxi_daudio_global_enable(sunxi_daudio, 1); - - return 0; + sunxi_daudio_global_enable(sunxi_daudio, 1); + printk("wzj: prbe end!\n"); + return 0; err_unregister_component: - snd_soc_unregister_component(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); err_regulator_disable: - if (sunxi_daudio->pdata->external_type && - sunxi_daudio->vol_supply.daudio_regulator) - regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); + if (sunxi_daudio->pdata->external_type && + sunxi_daudio->vol_supply.daudio_regulator) + regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); err_regulator_get: - if (sunxi_daudio->pdata->external_type && - sunxi_daudio->vol_supply.daudio_regulator) - regulator_put(sunxi_daudio->vol_supply.daudio_regulator); + if (sunxi_daudio->pdata->external_type && + sunxi_daudio->vol_supply.daudio_regulator) + regulator_put(sunxi_daudio->vol_supply.daudio_regulator); err_pinctrl_put: - if (sunxi_daudio->pdata->external_type) - devm_pinctrl_put(sunxi_daudio->pinctrl); + if (sunxi_daudio->pdata->external_type) + devm_pinctrl_put(sunxi_daudio->pinctrl); err_moduleclk_put: - clk_put(sunxi_daudio->moduleclk); + clk_put(sunxi_daudio->moduleclk); err_pllclk_put: - clk_put(sunxi_daudio->pllclk); + clk_put(sunxi_daudio->pllclk); err_iounmap: - iounmap(sunxi_daudio_membase); + iounmap(sunxi_daudio_membase); err_devm_kfree: - devm_kfree(&pdev->dev, sunxi_daudio); + devm_kfree(&pdev->dev, sunxi_daudio); err_node_put: - of_node_put(np); - return ret; + of_node_put(np); + return ret; } -static int __exit sunxi_daudio_dev_remove(struct platform_device *pdev) -{ - struct sunxi_daudio_info *sunxi_daudio = dev_get_drvdata(&pdev->dev); +static int __exit sunxi_daudio_dev_remove(struct platform_device *pdev) { + struct sunxi_daudio_info *sunxi_daudio = dev_get_drvdata(&pdev->dev); - if (--device_count == 0) - class_unregister(&daudio_class); + if (--device_count == 0) + class_unregister(&daudio_class); - cancel_delayed_work_sync(&sunxi_daudio->resume_work); + cancel_delayed_work_sync(&sunxi_daudio->resume_work); - if (sunxi_daudio->pdata->external_type) - devm_pinctrl_put(sunxi_daudio->pinctrl); + if (sunxi_daudio->pdata->external_type) + devm_pinctrl_put(sunxi_daudio->pinctrl); - if (sunxi_daudio->vol_supply.daudio_regulator) { - regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); - regulator_put(sunxi_daudio->vol_supply.daudio_regulator); - } + if (sunxi_daudio->vol_supply.daudio_regulator) { + regulator_disable(sunxi_daudio->vol_supply.daudio_regulator); + regulator_put(sunxi_daudio->vol_supply.daudio_regulator); + } - snd_soc_unregister_component(&pdev->dev); - clk_put(sunxi_daudio->moduleclk); - clk_put(sunxi_daudio->pllclk); - devm_kfree(&pdev->dev, sunxi_daudio); - return 0; + snd_soc_unregister_component(&pdev->dev); + clk_put(sunxi_daudio->moduleclk); + clk_put(sunxi_daudio->pllclk); + devm_kfree(&pdev->dev, sunxi_daudio); + return 0; } static struct platform_driver sunxi_daudio_driver = { - .probe = sunxi_daudio_dev_probe, - .remove = __exit_p(sunxi_daudio_dev_remove), - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = sunxi_daudio_of_match, - }, + .probe = sunxi_daudio_dev_probe, + .remove = __exit_p(sunxi_daudio_dev_remove), + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = sunxi_daudio_of_match, + }, }; module_platform_driver(sunxi_daudio_driver); diff --git a/lichee/linux-4.9/sound/soc/sunxi/sunxi-snddaudio.c b/lichee/linux-4.9/sound/soc/sunxi/sunxi-snddaudio.c index 7c0f29a87..673913438 100644 --- a/lichee/linux-4.9/sound/soc/sunxi/sunxi-snddaudio.c +++ b/lichee/linux-4.9/sound/soc/sunxi/sunxi-snddaudio.c @@ -102,6 +102,7 @@ static int sunxi_snddaudio_hw_params(struct snd_pcm_substream *substream, /* sunxi card initialization */ static int sunxi_snddaudio_init(struct snd_soc_pcm_runtime *rtd) { + printk("wzj:sunxi_snddaudio_init!\n"); return 0; } @@ -356,6 +357,9 @@ cpu_node_find: dai_link->codec_name, dai_link->codec_dai_name); + printk("wzj: codec: %s, codec_dai: %s.\n", + dai_link->codec_name, + dai_link->codec_dai_name); #ifdef CONFIG_SND_SUNXI_MAD sunxi_daudio_priv.mad_bind = 0; snd_soc_card_set_drvdata(card, &sunxi_daudio_priv); diff --git a/package/allwinner/adau1761/Makefile b/package/allwinner/adau1761/Makefile new file mode 100644 index 000000000..85dc10604 --- /dev/null +++ b/package/allwinner/adau1761/Makefile @@ -0,0 +1,98 @@ +############################################## +# OpenWrt Makefile for helloworld program +# +# +# Most of the variables used here are defined in +# the include directives below. We just need to +# specify a basic description of the package, +# where to build our program, where to find +# the source files, and where to install the +# compiled program on the router. +# +# Be very careful of spacing in this file. +# Indents should be tabs, not spaces, and +# there should be no trailing whitespace in +# lines that are not commented. +# +############################################## +include $(TOPDIR)/rules.mk + +# Name and release number of this package +PKG_NAME:=adau1761 +PKG_VERSION:=0.0.1 +PKG_RELEASE:=1 + + +# This specifies the directory where we're going to build the program. +# The root build directory, $(BUILD_DIR), is by default the build_mipsel +# directory in your OpenWrt SDK directory +PKG_BUILD_DIR := $(COMPILE_DIR)/$(PKG_NAME) + + +include $(BUILD_DIR)/package.mk + +# Specify package information for this program. +# The variables defined here should be self explanatory. +# If you are running Kamikaze, delete the DESCRIPTION +# variable below and uncomment the Kamikaze define +# directive for the description below +define Package/adau1761 + SECTION:=utils + CATEGORY:=Allwinner + TITLE:=just test adau1761 + DEPENDS:=+libpthread +endef + + +# Uncomment portion below for Kamikaze and delete DESCRIPTION variable above +define Package/adau1761/description + If you can't figure out what this program does, you're probably + brain-dead and need immediate medical attention. +endef + +# Specify what needs to be done to prepare for building the package. +# In our case, we need to copy the source files to the build directory. +# This is NOT the default. The default uses the PKG_SOURCE_URL and the +# PKG_SOURCE which is not defined here to download the source from the web. +# In order to just build a simple program that we have just written, it is +# much easier to do it this way. +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Configure +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS)" -Wall \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + LIBS="-lpthread" \ + all +endef + +# We do not need to define Build/Configure or Build/Compile directives +# The defaults are appropriate for compiling a simple program such as this one + + +# Specify where and how to install the program. Since we only have one file, +# the helloworld executable, install it by copying it to the /bin directory on +# the router. The $(1) variable represents the root directory on the router running +# OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install +# directory if it does not already exist. Likewise $(INSTALL_BIN) contains the +# command to copy the binary file from its current location (in our case the build +# directory) to the install directory. +define Package/adau1761/install + $(INSTALL_DIR) $(1)/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/adau1761 $(1)/bin/ +endef + + +# This line executes the necessary commands to compile our program. +# The above define directives specify all the information needed, but this +# line calls BuildPackage which in turn actually uses this information to +# build a package. + +$(eval $(call BuildPackage,adau1761)) diff --git a/package/allwinner/adau1761/src/Makefile b/package/allwinner/adau1761/src/Makefile new file mode 100644 index 000000000..38fe68f1b --- /dev/null +++ b/package/allwinner/adau1761/src/Makefile @@ -0,0 +1,16 @@ +TARGET = adau1761 +LIBS += -lpthread -lm -lrt + +SRCS = main.c +OBJS = $(SRCS:.c=.o) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +$(TARGET): $(OBJS) + $(CC) -o $@ $(OBJS) $(LIBS) $(LDFLAGS) + +all:$(TARGET) + +clean: + rm -rf $(TARGET) *.o *.a *~ diff --git a/package/allwinner/adau1761/src/main.c b/package/allwinner/adau1761/src/main.c new file mode 100755 index 000000000..c10721d23 --- /dev/null +++ b/package/allwinner/adau1761/src/main.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// io commands +#define MAGIC_NUM 'A' +#define ADAU1761_CMD_VOL_SET _IOW(MAGIC_NUM, 0, int) +#define ADAU1761_CMD_VOL_GET _IOR(MAGIC_NUM, 1, int) +#define ADAU1761_CMD_AMP_MUTE_SET _IOW(MAGIC_NUM, 2, int) +#define ADAU1761_CMD_AMP_MUTE_GET _IOR(MAGIC_NUM, 3, int) +#define ADAU1761_CMD_SRC_SET _IOW(MAGIC_NUM, 4, int) +#define ADAU1761_CMD_SRC_GET _IOR(MAGIC_NUM, 5, int) +#define ADAU1761_CMD_FW_LOAD _IOW(MAGIC_NUM, 6, int) +#define ADAU1761_CMD_EQ_SET _IOW(MAGIC_NUM, 7, int) + +#define ADAU1761_CMD_MAX (7) + + +#define MAX_VOL_STEP (20) + +int main(int argc, char *argv[]) +{ + int fd, ret = 0; + unsigned int cmd; + unsigned long para; + char *path = "/dev/adau1761"; + + printf("argv1 is cmd, argv2 is para.\n"); + + if((atoi(argv[1]) < 0) || (atoi(argv[1]) > ADAU1761_CMD_MAX)) { + printf("argv1 is out of scope\n"); + exit(1); + } + + cmd = (unsigned int)atoi(argv[1]); + para = (unsigned long)atoi(argv[2]); + printf("cmd %ud, para %lu.\n", cmd, para); + + fd = open(path, O_RDWR); + + if(fd < 0) { + printf("open %s failed.\n", path); + } else { + printf("fd %d, cmd %ud, para %lu.\n", fd, cmd, para); + + switch(cmd) { + case 0: + if((para < 0) || (para > MAX_VOL_STEP)) { + printf("argv2 is out of scope\n"); + exit(2); + } + + cmd = _IOW(MAGIC_NUM, cmd, int); + + ret = ioctl(fd, cmd, para); + printf("return: %d\n", ret); + break; + + case 1: + cmd = _IOR(MAGIC_NUM, cmd, int); + ret = ioctl(fd, cmd, (unsigned long)¶); + printf("return: %lu\n", para); + + if((para < 0) || (para > MAX_VOL_STEP)) { + printf("vol is out of scope\n"); + exit(3); + } + + break; + + case 2: + if((para < 0) || (para > 1)) { + printf("argv2 is out of scope\n"); + exit(4); + } + + cmd = _IOW(MAGIC_NUM, cmd, int); + + ret = ioctl(fd, cmd, para); + printf("return: %d\n", ret); + break; + + case 3: + cmd = _IOR(MAGIC_NUM, cmd, int); + ret = ioctl(fd, cmd, (unsigned long)¶); + printf("return: %lu\n", para); + + if((para < 0) || (para > 1)) { + printf("mute is out of scope\n"); + exit(5); + } + break; + + case 4: + if((para < 0) || (para > 1)) { + printf("argv2 is out of scope\n"); + exit(6); + } + + cmd = _IOW(MAGIC_NUM, cmd, int); + + ret = ioctl(fd, cmd, para); + printf("return: %d\n", ret); + break; + + case 5: + cmd = _IOR(MAGIC_NUM, cmd, int); + ret = ioctl(fd, cmd, (unsigned long)¶); + printf("return: %lu\n", para); + + if((para < 0) || (para > 1)) { + printf("src is out of scope\n"); + exit(7); + } + break; + + case 6: + cmd = _IOW(MAGIC_NUM, cmd, int); + + ret = ioctl(fd, cmd, para); + printf("return: %d\n", ret); + break; + + case 7: + if((para < 0) || (para > 2)) { + printf("argv2 is out of scope\n"); + } + + cmd = _IOW(MAGIC_NUM, cmd, int); + + ret = ioctl(fd, cmd, para); + printf("return: %d\n", ret); + break; + + default: + break; + } + } + + close(fd); + + return ret; +} diff --git a/package/base-files/files/etc/config/system b/package/base-files/files/etc/config/system index 021169978..3c6cfdeba 100644 --- a/package/base-files/files/etc/config/system +++ b/package/base-files/files/etc/config/system @@ -1,6 +1,6 @@ config system option hostname TinaLinux - option timezone Asia/Shanghai + option zonename Asia/Shanghai option timezone CST-8 option log_file /root/.lastlog option log_size 512 diff --git a/package/base-files/files/usr/share/golang/lib/time/zoneinfo.zip b/package/base-files/files/usr/share/golang/lib/time/zoneinfo.zip new file mode 100644 index 000000000..d33dc1d27 Binary files /dev/null and b/package/base-files/files/usr/share/golang/lib/time/zoneinfo.zip differ diff --git a/package/base-files/files/usr/share/zoneinfo/Asia/Shanghai b/package/base-files/files/usr/share/zoneinfo/Asia/Shanghai new file mode 100644 index 000000000..5a290a3ce Binary files /dev/null and b/package/base-files/files/usr/share/zoneinfo/Asia/Shanghai differ diff --git a/package/libs/libmsc/lib/libmsc.so b/package/libs/libmsc/lib/libmsc.so new file mode 100644 index 000000000..f4caed4b5 Binary files /dev/null and b/package/libs/libmsc/lib/libmsc.so differ diff --git a/package/netease/netease_control_center/Makefile b/package/netease/netease_control_center/Makefile index aeca3647b..5a62b3988 100644 --- a/package/netease/netease_control_center/Makefile +++ b/package/netease/netease_control_center/Makefile @@ -92,12 +92,12 @@ define Package/$(PKG_NAME)/install $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/$(PKG_NAME)/nembd/evdev/bin/netease_keytest $(1)/usr/sbin/ $(INSTALL_BIN) ./netease.init $(1)/etc/init.d/netease_services $(INSTALL_BIN) ./neteasewifi.init $(1)/etc/init.d/netease_wifi_service - $(INSTALL_BIN) ./neteasevoice.init $(1)/etc/init.d/netease_voice_service - $(INSTALL_BIN) ./neteaseplayer.init $(1)/etc/init.d/netease_player_service +# $(INSTALL_BIN) ./neteasevoice.init $(1)/etc/init.d/netease_voice_service +# $(INSTALL_BIN) ./neteaseplayer.init $(1)/etc/init.d/netease_player_service $(INSTALL_BIN) ./neteasemanufacture_cc.init $(1)/etc/init.d/netease_cc_manufacture_service $(INSTALL_BIN) ./neteasemanufacture_mcu.init $(1)/etc/init.d/netease_mcu_manufacture_service $(INSTALL_BIN) ./neteasemanufacture_rf.init $(1)/etc/init.d/netease_rf_manufacture_service - $(INSTALL_BIN) ./neteasecc.init $(1)/etc/init.d/netease_cc_service +# $(INSTALL_BIN) ./neteasecc.init $(1)/etc/init.d/netease_cc_service $(INSTALL_BIN) ./neteasebt.init $(1)/etc/init.d/netease_bt_service $(INSTALL_DATA) mcu/* $(1)/usr/share/golang/mcu/ $(INSTALL_DATA) vol_adc.config $(1)/usr/share/golang/ diff --git a/package/netease/netease_voice/src/base.c b/package/netease/netease_voice/src/base.c index 925fa05f8..f8fcc048a 100644 --- a/package/netease/netease_voice/src/base.c +++ b/package/netease/netease_voice/src/base.c @@ -160,4 +160,12 @@ void setBindUser(char *user, size_t len) { baseCopy(user, len, g_binduser, sizeof(g_binduser)); } -char *getBindUser() { return (char *)g_binduser; } \ No newline at end of file +char *getBindUser() { return (char *)g_binduser; } + +void resetAdc() { + n_debug("Begin to reset adc!\n"); + char * cmd = "1"; + int fd = open("/sys/netease/cpld_control/cpld_init", O_RDWR); + write(fd, cmd, strlen(cmd)); + close(fd); +} \ No newline at end of file diff --git a/package/netease/netease_voice/src/include/base.h b/package/netease/netease_voice/src/include/base.h index 025edde28..4b656a925 100644 --- a/package/netease/netease_voice/src/include/base.h +++ b/package/netease/netease_voice/src/include/base.h @@ -85,6 +85,7 @@ int getVoiceStatus(); void setVoiceConfidence(double voiceConfidence); double getVoiceConfidence(); +void resetAdc(); #ifdef __cplusplus } /* extern "C" */ #endif /* C++ */ diff --git a/package/netease/netease_voice/src/include/error.h b/package/netease/netease_voice/src/include/error.h index a2efbd340..8c27e0ebe 100644 --- a/package/netease/netease_voice/src/include/error.h +++ b/package/netease/netease_voice/src/include/error.h @@ -38,7 +38,7 @@ enum { // fprintf(stderr, format, ##arg) #ifdef NETEASE_TOAST -#define n_toast(fmt, arg...) n_printf(fmt, ##arg) +#define n_toast(fmt, arg...) printf(fmt, ##arg) #else #define n_toast(fmt, arg...) \ do { \ @@ -46,7 +46,7 @@ enum { #endif #ifdef NETEASE_DEBUG -#define n_debug(fmt, arg...) n_printf(fmt, ##arg) +#define n_debug(fmt, arg...) printf(fmt, ##arg) #else #define n_debug(fmt, arg...) \ do { \ @@ -54,7 +54,7 @@ enum { #endif #ifdef NETEASE_ERROR -#define n_error(fmt, arg...) n_printf(fmt, ##arg) +#define n_error(fmt, arg...) printf(fmt, ##arg) #else #define n_error(fmt, arg...) \ do { \ diff --git a/package/netease/netease_voice/src/main.c b/package/netease/netease_voice/src/main.c index 1a9ca737e..116a23b39 100644 --- a/package/netease/netease_voice/src/main.c +++ b/package/netease/netease_voice/src/main.c @@ -46,7 +46,7 @@ when who why /* ------------------------------------------------------------------------ ** Macros ** ------------------------------------------------------------------------ */ -//#define BACKUP_ORIG_AUDIO +#define BACKUP_ORIG_AUDIO //#define BACKUP_FINAL_AUDIO /* ------------------------------------------------------------------------ @@ -515,13 +515,13 @@ void main(int argc, char **argv) { #ifdef ENABLE_OEM_DBUS ret = Netease_dbus_oem_init(DBusMessageCb); #else - ret = Netease_Dbus_Init(DBusMessageCb); + // ret = Netease_Dbus_Init(DBusMessageCb); #endif if (NETEASE_SUCCESS == ret) { n_debug("Dbus init success\n"); } else { n_error("Dbus init fail: %d\n", ret); - return; + // return; } #if USED_NETEASE_FMAE @@ -563,6 +563,10 @@ void main(int argc, char **argv) { printf("period_size name is %d\n", recordconfig.period_size); printf("++++++++++++++++++++++++++\n"); n_debug("Begin to init netease_voice modules!\n"); + + extern void listAlsaDev(); + resetAdc(); + listAlsaDev(); #ifdef BACKUP_ORIG_AUDIO fd_audio_orig = open(argv[1], O_CREAT | O_APPEND | O_RDWR); n_debug("Open file: %s, fd:%d\n", argv[1], fd_audio_orig); @@ -654,7 +658,7 @@ void main(int argc, char **argv) { } #ifdef ENABLE_YUNXIN - Netease_yunxin_init(&audiobypassconfig); + // Netease_yunxin_init(&audiobypassconfig); #endif // Netease_Dbus_Start_Sync(); @@ -662,14 +666,14 @@ void main(int argc, char **argv) { #ifdef ENABLE_OEM_DBUS pthread_create(&tid, NULL, Netease_dbus_oem_start, NULL); #else - pthread_create(&tid, NULL, Netease_Dbus_Start_Sync, NULL); + // pthread_create(&tid, NULL, Netease_Dbus_Start_Sync, NULL); #endif // Netease_yunxin_test(); while (1) { if (strlen(getUuid()) == 0 || strlen(getYxToken()) == 0) { - n_toast("Get args frome cc\n"); - Netease_dbus_initargs(); + // n_toast("Get args frome cc\n"); + // Netease_dbus_initargs(); usleep(1000000); } else { break; diff --git a/package/netease/netease_voice/src/yunxin.c b/package/netease/netease_voice/src/yunxin.c index 23d94a765..cdbf0cdcc 100644 --- a/package/netease/netease_voice/src/yunxin.c +++ b/package/netease/netease_voice/src/yunxin.c @@ -506,6 +506,11 @@ void Netease_yunxin_cb_disconnect(const char *json_params, NULL); } +void listAlsaDev() { + char *dev = nrtc_alsa_available_devices(false); + n_toast("Avalible dev: %s\n", dev); +} + int Netease_yunxin_init(struct audio_bypass **bypass) { // alsa_hd = nrtc_audio_alsa_core_create(false, 1, 16000, 16); // if (!alsa_hd) { diff --git a/package/netease/ntes_record/Makefile b/package/netease/ntes_record/Makefile index cd38cf8a5..8ae9dc7db 100644 --- a/package/netease/ntes_record/Makefile +++ b/package/netease/ntes_record/Makefile @@ -38,7 +38,7 @@ define Package/$(PKG_NAME)/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin/ - $(INSTALL_BIN) ./voice.init $(1)/etc/init.d/voice_service +# $(INSTALL_BIN) ./voice.init $(1)/etc/init.d/voice_service $(INSTALL_BIN) ./netease_record.sh $(1)/usr/sbin/netease_record endef diff --git a/package/netease/ntes_record/src/record.c b/package/netease/ntes_record/src/record.c index b553f4e3e..d677ec716 100644 --- a/package/netease/ntes_record/src/record.c +++ b/package/netease/ntes_record/src/record.c @@ -140,7 +140,6 @@ static void* RecordThread(void* param) static void record_audio_cb(const void *audio, unsigned int audio_len, int err_code) { - if (SUCCESS == err_code){ FILE *fp = fopen(out_pcm_name, "ab+"); if (NULL == fp){ @@ -150,7 +149,6 @@ static void record_audio_cb(const void *audio, unsigned int audio_len, int err_c fwrite(audio, audio_len, 1, fp); fclose(fp); } - } int start_record(struct pcm_config pcm_cfg) diff --git a/target/allwinner/mandolin-pv1/config-4.9 b/target/allwinner/mandolin-pv1/config-4.9 index af727c523..317468594 100644 --- a/target/allwinner/mandolin-pv1/config-4.9 +++ b/target/allwinner/mandolin-pv1/config-4.9 @@ -1,3 +1,7 @@ +# CONFIG_ADAU1761 is not set +# CONFIG_ADAU1761_ES1 is not set +# CONFIG_ADAU1761_ES2 is not set +CONFIG_ADAU1761_R311_PV1=y CONFIG_ADVISE_SYSCALLS=y # CONFIG_AF_KCM is not set CONFIG_ALIGNMENT_TRAP=y @@ -325,6 +329,7 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_FW_CFG_SYSFS is not set # CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set # CONFIG_GCC_PLUGINS is not set +CONFIG_GDB_SCRIPTS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -348,6 +353,7 @@ CONFIG_GPIOLIB=y # CONFIG_GPIO_MPC8XXX is not set # CONFIG_GPIO_PISOSR is not set # CONFIG_GPIO_SUNXI is not set +CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_TPIC2810 is not set # CONFIG_GPIO_TS4900 is not set # CONFIG_GREYBUS is not set @@ -512,6 +518,7 @@ CONFIG_MEDIA_SUBDRV_AUTOSELECT=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEMORY_ISOLATION=y # CONFIG_MEMORY_STATE_TIME is not set +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 # CONFIG_MFD_ACT8945A is not set # CONFIG_MFD_ACX00 is not set # CONFIG_MFD_AXP20X_I2C is not set @@ -743,10 +750,11 @@ CONFIG_SND_SOC_I2C_AND_SPI=y CONFIG_SND_SPI=y CONFIG_SND_SUN8IW15_CODEC=y CONFIG_SND_SUNXI_SOC=y +CONFIG_SND_SUNXI_SOC_DAUDIO=y CONFIG_SND_SUNXI_SOC_INTER_I2S=y CONFIG_SND_SUNXI_SOC_RWFUNC=y CONFIG_SND_SUNXI_SOC_SUN8IW15_CODEC=y -# CONFIG_SND_SUNXI_SOC_SUNXI_DAUDIO is not set +CONFIG_SND_SUNXI_SOC_SUNXI_DAUDIO=y # CONFIG_SND_SUNXI_SOC_SUNXI_DMIC is not set CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_TIMER=y @@ -953,6 +961,7 @@ CONFIG_XFRM_SUB_POLICY=y CONFIG_XFRM_USER=y CONFIG_XPS=y # CONFIG_XR_WLAN is not set +CONFIG_XUNFEI_CPLD=y CONFIG_ZBOOT_ROM_BSS=0 CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZLIB_INFLATE=y diff --git a/target/allwinner/mandolin-pv1/configs/sys_config.fex b/target/allwinner/mandolin-pv1/configs/sys_config.fex index 1c3a6f3c9..d4d92cfa4 100755 --- a/target/allwinner/mandolin-pv1/configs/sys_config.fex +++ b/target/allwinner/mandolin-pv1/configs/sys_config.fex @@ -550,7 +550,7 @@ lcd1_hue = 50 ;smart_color 90:normal lcd screen 65:retina lcd screen(9.7inch) ;---------------------------------------------------------------------------------- [lcd0] -lcd_used = 1 +lcd_used = 0 lcd_driver_name = "default_lcd" lcd_backlight = 50 @@ -702,13 +702,13 @@ lcdvsync = port:PD21<7><0> ;hdmi configuration ;---------------------------------------------------------------------------------- [hdmi_para] -hdmi_used = 1 +hdmi_used = 0 ;---------------------------------------------------------------------------------- ;pwm config ;---------------------------------------------------------------------------------- [pwm0] -pwm_used = 1 +pwm_used = 0 pwm_positive = port:PD23<2><0> [pwm0_suspend] @@ -1251,12 +1251,12 @@ snddaudio0_used = 1 daudio0_used = 1 daudio_master = 4 tdm_config = 1 -mclk_div = 1 -clk_active = 0 +mclk_div = 2 +clk_active = 1 audio_format = 1 signal_inversion = 1 pcm_lrck_period = 32 -;msb_lsb_first = 0 +msb_lsb_first = 0 slot_width_select = 32 frametype = 1 ;tx_data_mode = 1 @@ -1690,6 +1690,14 @@ hold-time-ms = 0 fall-time-ms = 6 off-time-ms = 4 +;-------------------------------------------------------------------------------- +;digital amplifier control +;-------------------------------------------------------------------------------- +[dig_amp] +compatible = "allwinner,adau1761-r311-pv1" +audio_pa_mute = port:PH07<1><0> +audio_pa_sdz = port:PH06<1><0> + [led_g] led_name = "green" id = 1 @@ -1711,3 +1719,10 @@ rise-time-ms = 6 hold-time-ms = 0 fall-time-ms = 6 off-time-ms = 4 + +[cpld] +compatible = "allwinner,cpld-r311-pv1" +gp_adc_rst = port:PD21<1><1><1> +gp_cpld_rst = port:PL10<1><1><1> +4v5_ldo_en = port:PH04<1><0> +3v_ldo_en = port:PH05<1><0> diff --git a/target/allwinner/mandolin-pv1/defconfig b/target/allwinner/mandolin-pv1/defconfig index f1e8c1cd4..f01e5d7cc 100644 --- a/target/allwinner/mandolin-pv1/defconfig +++ b/target/allwinner/mandolin-pv1/defconfig @@ -1365,6 +1365,7 @@ CONFIG_PACKAGE_wireless-tools=y # CONFIG_PACKAGE_tplayerdemo is not set # CONFIG_PACKAGE_trecorderdemo is not set # CONFIG_PACKAGE_MtpDaemon is not set +CONFIG_PACKAGE_adau1761=y CONFIG_PACKAGE_adb=y # CONFIG_PACKAGE_aec-xt-demo is not set # CONFIG_PACKAGE_benchmarks is not set @@ -1465,7 +1466,7 @@ CONFIG_PACKAGE_softap=y # CONFIG_PACKAGE_stress-ng is not set # CONFIG_PACKAGE_tina-upgrade is not set # CONFIG_PACKAGE_tinacvr is not set -# CONFIG_PACKAGE_tinymp3 is not set +CONFIG_PACKAGE_tinymp3=y # CONFIG_PACKAGE_tsc_demo is not set # CONFIG_PACKAGE_usb-gadget is not set CONFIG_PACKAGE_wifimanager=y @@ -2438,7 +2439,7 @@ CONFIG_PACKAGE_libjson-c=y # CONFIG_PACKAGE_liblua is not set # CONFIG_PACKAGE_liblz4 is not set # CONFIG_PACKAGE_liblzo is not set -# CONFIG_PACKAGE_libmad is not set +CONFIG_PACKAGE_libmad=y # CONFIG_PACKAGE_libmcrypt is not set # CONFIG_PACKAGE_libmicrohttpd is not set # CONFIG_PACKAGE_libmijia is not set @@ -2449,7 +2450,7 @@ CONFIG_PACKAGE_libjson-c=y # CONFIG_PACKAGE_libmosquittopp is not set # CONFIG_PACKAGE_libmount is not set # CONFIG_PACKAGE_libmraa is not set -# CONFIG_PACKAGE_libmsc is not set +CONFIG_PACKAGE_libmsc=y # CONFIG_PACKAGE_libmysqlclient is not set # CONFIG_PACKAGE_libmysqlclient-r is not set CONFIG_PACKAGE_libncurses=y @@ -2771,7 +2772,7 @@ CONFIG_TTF2_SUPPORT=y # CONFIG_PACKAGE_KPlayerTest is not set # CONFIG_PACKAGE_SPlayer is not set # CONFIG_PACKAGE_SPlayer-demo is not set -CONFIG_PACKAGE_alarmer=y +# CONFIG_PACKAGE_alarmer is not set # CONFIG_PACKAGE_blueKC is not set # CONFIG_PACKAGE_blueKC-demo is not set # CONFIG_PACKAGE_config_server is not set @@ -2787,7 +2788,7 @@ CONFIG_PACKAGE_libuvdbus=y CONFIG_RES_NORMAL_MODE=y # CONFIG_PACKAGE_log_ctrl is not set # CONFIG_PACKAGE_mcu_ota is not set -CONFIG_PACKAGE_netease_control_center=y +# CONFIG_PACKAGE_netease_control_center is not set # CONFIG_PACKAGE_netease_test is not set CONFIG_PACKAGE_netease_voice=y @@ -2799,13 +2800,13 @@ CONFIG_NETEASE_MSC_SDK=y # CONFIG_NETEASE_CAE_SDK is not set CONFIG_XUNFEI_CAE_SDK=y CONFIG_NETEASE_DUILITE_SDK=y -CONFIG_NETEASE_TTS_SDK=y -# CONFIG_XUNFEI_TTS_SDK is not set +# CONFIG_NETEASE_TTS_SDK is not set +CONFIG_XUNFEI_TTS_SDK=y # CONFIG_USED_NONE is not set CONFIG_USED_DC_SDK=y -# CONFIG_PACKAGE_ntes_record is not set -CONFIG_PACKAGE_ota=y -CONFIG_PACKAGE_pv1res=y +CONFIG_PACKAGE_ntes_record=y +# CONFIG_PACKAGE_ota is not set +# CONFIG_PACKAGE_pv1res is not set # CONFIG_PACKAGE_rokid_test is not set # CONFIG_PACKAGE_sraop is not set # CONFIG_PACKAGE_wifiDemo is not set