Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From a576378efc21973bd91fbbd01cd461a0f7e7659a Mon Sep 17 00:00:00 2001
- From: Insei <goodmobiledevices@gmail.com>
- Date: Sat, 27 May 2017 19:40:22 +0300
- Subject: [PATCH] sound
- ---
- arch/arm/configs/tegra12_defconfig | 1 +
- arch/arm/mach-tegra/Makefile | 2 +-
- arch/arm/mach-tegra/board-ardbeg.c | 73 +-
- arch/arm/mach-tegra/board-ardbeg.h | 8 +-
- arch/arm/mach-tegra/common.c | 2 +-
- arch/arm/mach-tegra/devices.c | 6 +
- arch/arm/mach-tegra/devices.h | 1 +
- arch/arm/mach-tegra/include/mach/tegra_emc.h | 1 +
- arch/arm/mach-tegra/tegra12_emc.c | 4 +
- include/sound/core.h | 15 +-
- include/sound/rt5670.h | 30 +
- include/sound/soc-dapm.h | 8 +-
- include/sound/soc.h | 2 +-
- sound/core/pcm.c | 4 +-
- sound/core/pcm_lib.c | 7 +-
- sound/core/pcm_native.c | 3 -
- sound/soc/codecs/Kconfig | 8 +
- sound/soc/codecs/Makefile | 4 +
- sound/soc/codecs/rt5639.c | 2 +-
- sound/soc/codecs/rt5639_ioctl.c | 2 +-
- sound/soc/codecs/rt5640.c | 6 +-
- sound/soc/codecs/rt5645_ioctl.c | 2 +-
- sound/soc/codecs/rt5671-dsp.c | 1966 +++++++++++
- sound/soc/codecs/rt5671-dsp.h | 82 +
- sound/soc/codecs/rt5671.c | 4513 ++++++++++++++++++++++++++
- sound/soc/codecs/rt5671.h | 2091 ++++++++++++
- sound/soc/codecs/rt5671_ioctl.c | 138 +
- sound/soc/codecs/rt5671_ioctl.h | 45 +
- sound/soc/codecs/rt56xx_ioctl.c | 4 +-
- sound/soc/codecs/rt56xx_ioctl.h | 1 +
- sound/soc/codecs/rt_codec_ioctl.c | 4 +-
- sound/soc/codecs/spdif_transciever.c | 8 -
- sound/soc/codecs/tfa98xx.c | 1513 +++++++++
- sound/soc/codecs/tfa98xx.h | 2590 +++++++++++++++
- sound/soc/soc-cache.c | 4 +-
- sound/soc/soc-core.c | 40 +-
- sound/soc/soc-dapm.c | 226 +-
- sound/soc/soc-jack.c | 5 +-
- sound/soc/soc-pcm.c | 125 +-
- sound/soc/tegra/Kconfig | 13 +
- sound/soc/tegra/Makefile | 2 +
- sound/soc/tegra/tegra_asoc_utils.c | 40 +-
- sound/soc/tegra/tegra_asoc_utils.h | 1 +
- sound/soc/tegra/tegra_rt5671.c | 951 ++++++
- 44 files changed, 14303 insertions(+), 250 deletions(-)
- create mode 100644 include/sound/rt5670.h
- create mode 100644 sound/soc/codecs/rt5671-dsp.c
- create mode 100644 sound/soc/codecs/rt5671-dsp.h
- create mode 100755 sound/soc/codecs/rt5671.c
- create mode 100644 sound/soc/codecs/rt5671.h
- create mode 100644 sound/soc/codecs/rt5671_ioctl.c
- create mode 100644 sound/soc/codecs/rt5671_ioctl.h
- create mode 100644 sound/soc/codecs/tfa98xx.c
- create mode 100644 sound/soc/codecs/tfa98xx.h
- create mode 100644 sound/soc/tegra/tegra_rt5671.c
- diff --git a/arch/arm/configs/tegra12_defconfig b/arch/arm/configs/tegra12_defconfig
- index 1ef65e6..dc0eebd 100644
- --- a/arch/arm/configs/tegra12_defconfig
- +++ b/arch/arm/configs/tegra12_defconfig
- @@ -580,3 +580,4 @@ CONFIG_BCMDHD_INSMOD_NO_FW_LOAD=y
- # Touchscreen
- CONFIG_INPUT_TOUCHSCREEN=y
- CONFIG_TOUCHSCREEN_ATMEL_MXT=y
- +CONFIG_SND_SOC_TEGRA_RT5671=y
- diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
- index 6d6b4a9..fe7b087 100644
- --- a/arch/arm/mach-tegra/Makefile
- +++ b/arch/arm/mach-tegra/Makefile
- @@ -1,7 +1,7 @@
- GCOV_PROFILE := y
- asflags-y += -march=armv7-a
- -subdir-ccflags-y := -Werror
- +//subdir-ccflags-y := -Werror
- obj-y += ahb.o
- obj-y += common.o
- diff --git a/arch/arm/mach-tegra/board-ardbeg.c b/arch/arm/mach-tegra/board-ardbeg.c
- index c38b262..cc07972 100644
- --- a/arch/arm/mach-tegra/board-ardbeg.c
- +++ b/arch/arm/mach-tegra/board-ardbeg.c
- @@ -57,6 +57,7 @@
- #include <media/tegra_dtv.h>
- #include <linux/clocksource.h>
- #include <linux/irqchip.h>
- +#include <sound/rt5670.h>
- #include <linux/irqchip/tegra.h>
- #include <linux/tegra-soc.h>
- #include <linux/tegra_fiq_debugger.h>
- @@ -99,6 +100,28 @@
- static struct board_info board_info, display_board_info;
- +static struct rt5670_platform_data rt5671_pdata = {
- + .jd_mode = 2,
- + .codec_gpio = TEGRA_GPIO_CDC_IRQ,
- + .in2_diff = true,
- + .in3_diff = false,
- + .in4_diff = true,
- + .bclk_32fs = {false, true, true, true},
- +};
- +
- +static struct i2c_board_info __initdata audio_board_info[] = {
- + {
- + I2C_BOARD_INFO("rt5671", 0x1c),
- + .platform_data = &rt5671_pdata,
- + },
- + {
- + I2C_BOARD_INFO("tfa98xx", 0x34),
- + },
- + {
- + I2C_BOARD_INFO("tfa98xx", 0x37),
- + },
- +};
- +
- static struct resource ardbeg_bluedroid_pm_resources[] = {
- [0] = {
- .name = "shutdown_gpio",
- @@ -205,6 +228,7 @@ static __initdata struct tegra_clk_init_table ardbeg_clk_init_table[] = {
- { "uartb", "pll_p", 408000000, false},
- { "uartc", "pll_p", 408000000, false},
- { "uartd", "pll_p", 408000000, false},
- + { "audio.emc", "emc", 50000000, false},
- { NULL, NULL, 0, 0},
- };
- @@ -231,10 +255,7 @@ static void ardbeg_i2c_init(void)
- struct board_info board_info;
- tegra_get_board_info(&board_info);
- - if (board_info.board_id == BOARD_PM374) {
- - i2c_register_board_info(0, &max98090_board_info, 1);
- - } else if (board_info.board_id != BOARD_PM359)
- - i2c_register_board_info(0, &rt5639_board_info, 1);
- + i2c_register_board_info(0, audio_board_info, ARRAY_SIZE(audio_board_info));
- if (board_info.board_id == BOARD_PM359 ||
- board_info.board_id == BOARD_PM358 ||
- @@ -276,13 +297,13 @@ static struct tegra_serial_platform_data ardbeg_uartd_pdata = {
- .modem_interrupt = false,
- };
- -static struct tegra_asoc_platform_data ardbeg_audio_pdata_rt5639 = {
- - .gpio_hp_det = TEGRA_GPIO_HP_DET,
- - .gpio_ldo1_en = TEGRA_GPIO_LDO_EN,
- +static struct tegra_asoc_platform_data ardbeg_audio_pdata_rt5671 = {
- + .gpio_hp_det = -1,
- + .gpio_ldo1_en = -1,
- .gpio_spkr_en = -1,
- .gpio_int_mic_en = -1,
- .gpio_ext_mic_en = -1,
- - .gpio_hp_mute = -1,
- + .gpio_hp_mute = TEGRA_GPIO_HP_MUTE,
- .gpio_codec1 = -1,
- .gpio_codec2 = -1,
- .gpio_codec3 = -1,
- @@ -292,26 +313,12 @@ static struct tegra_asoc_platform_data ardbeg_audio_pdata_rt5639 = {
- .i2s_mode = TEGRA_DAIFMT_I2S,
- .sample_size = 16,
- .channels = 2,
- - .bit_clk = 1536000,
- - },
- - .i2s_param[BT_SCO] = {
- - .audio_port_id = 3,
- - .is_i2s_master = 1,
- - .i2s_mode = TEGRA_DAIFMT_DSP_A,
- - },
- - .i2s_param[BASEBAND] = {
- - .audio_port_id = 0,
- - .is_i2s_master = 1,
- - .i2s_mode = TEGRA_DAIFMT_I2S,
- - .sample_size = 16,
- - .rate = 16000,
- - .channels = 2,
- - .bit_clk = 1024000,
- + .rate = 48000,
- },
- };
- static struct tegra_asoc_platform_data norrin_audio_pdata_max98090 = {
- - .gpio_hp_det = NORRIN_GPIO_HP_DET,
- + .gpio_hp_det = -1,
- .gpio_ext_mic_en = TEGRA_GPIO_HP_DET,
- .gpio_hp_mute = -1,
- .edp_support = true,
- @@ -384,11 +391,11 @@ static void ardbeg_audio_init(void)
- #endif /* FIX ME! Problem in gpio pin's rt5639 */
- }
- -static struct platform_device ardbeg_audio_device_rt5639 = {
- - .name = "tegra-snd-rt5639",
- +static struct platform_device ardbeg_audio_device_rt5671 = {
- + .name = "tegra-snd-rt5671",
- .id = 0,
- .dev = {
- - .platform_data = &ardbeg_audio_pdata_rt5639,
- + .platform_data = &ardbeg_audio_pdata_rt5671,
- },
- };
- @@ -477,6 +484,7 @@ static struct platform_device *ardbeg_devices[] __initdata = {
- &tegra_i2s_device1,
- &tegra_i2s_device3,
- &tegra_i2s_device4,
- + &ardbeg_audio_device_rt5671,
- &tegra_spdif_device,
- &spdif_dit_device,
- &bluetooth_dit_device,
- @@ -1319,17 +1327,15 @@ static void __init tegra_ardbeg_late_init(void)
- #endif
- ardbeg_uart_init();
- ardbeg_usb_init();
- - ardbeg_modem_init();
- #ifdef CONFIG_TEGRA_XUSB_PLATFORM
- ardbeg_xusb_init();
- #endif
- ardbeg_i2c_init();
- - ardbeg_audio_init();
- platform_add_devices(ardbeg_devices, ARRAY_SIZE(ardbeg_devices));
- - if (board_info.board_id == BOARD_PM374) /* Norrin ERS */
- - platform_device_register(&norrin_audio_device_max98090);
- - else if (board_info.board_id != BOARD_PM359)
- - platform_device_register(&ardbeg_audio_device_rt5639);
- +// if (board_info.board_id == BOARD_PM374) /* Norrin ERS */
- +// platform_device_register(&norrin_audio_device_max98090);
- +// else if (board_info.board_id != BOARD_PM359)
- +// platform_device_register(&ardbeg_audio_device_rt5639);
- tegra_io_dpd_init();
- if (board_info.board_id == BOARD_E2548 ||
- board_info.board_id == BOARD_P2530)
- @@ -1351,7 +1357,6 @@ static void __init tegra_ardbeg_late_init(void)
- loki_regulator_init();
- else
- ardbeg_regulator_init();
- - ardbeg_dtv_init();
- ardbeg_suspend_init();
- if ((board_info.board_id == BOARD_PM374) ||
- diff --git a/arch/arm/mach-tegra/board-ardbeg.h b/arch/arm/mach-tegra/board-ardbeg.h
- index e72e9e7..48ee32e 100644
- --- a/arch/arm/mach-tegra/board-ardbeg.h
- +++ b/arch/arm/mach-tegra/board-ardbeg.h
- @@ -97,11 +97,9 @@ enum tegra_bb_type {
- #define TOUCH_GPIO_RST_MAXIM_STI_SPI TEGRA_GPIO_PK4
- /* Audio-related GPIOs */
- -/*Same GPIO's used for T114(Interposer) and T124*/
- -/*Below GPIO's are same for Laguna and Ardbeg*/
- -#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PH4
- -#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PR7
- -#define NORRIN_GPIO_HP_DET TEGRA_GPIO_PI7
- +#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PW2
- +#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PK2
- +#define TEGRA_GPIO_HP_MUTE TEGRA_GPIO_PX1
- /*LDO_EN signal is required only for RT5639 and not for RT5645,
- on Laguna the LDO_EN signal comes from a GPIO expander and
- this is exposed as a fixed regulator directly handeled from
- diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
- index 23ae029..2965873 100644
- --- a/arch/arm/mach-tegra/common.c
- +++ b/arch/arm/mach-tegra/common.c
- @@ -2374,7 +2374,7 @@ int __init tegra_soc_device_init(const char *machine)
- soc_dev = soc_device_register(soc_dev_attr);
- if (IS_ERR_OR_NULL(soc_dev)) {
- kfree(soc_dev_attr);
- - return -1;
- + return -EPERM;
- }
- return 0;
- diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
- index 3b2665d..b1498ce 100644
- --- a/arch/arm/mach-tegra/devices.c
- +++ b/arch/arm/mach-tegra/devices.c
- @@ -1536,6 +1536,12 @@ struct platform_device baseband_dit_device = {
- .id = 2,
- };
- +struct platform_device fm_dit_device = {
- + .name = "spdif-dit",
- + .id = 3,
- +};
- +
- +
- struct platform_device tegra_pcm_device = {
- .name = "tegra-pcm-audio",
- .id = -1,
- diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
- index eaba9cf..2c02b02 100644
- --- a/arch/arm/mach-tegra/devices.h
- +++ b/arch/arm/mach-tegra/devices.h
- @@ -80,6 +80,7 @@ extern struct platform_device tegra_das_device;
- extern struct platform_device spdif_dit_device;
- extern struct platform_device bluetooth_dit_device;
- extern struct platform_device baseband_dit_device;
- +extern struct platform_device fm_dit_device;
- extern struct platform_device tegra_pcm_device;
- extern struct platform_device tegra_tdm_pcm_device;
- extern struct platform_device tegra_offload_device;
- diff --git a/arch/arm/mach-tegra/include/mach/tegra_emc.h b/arch/arm/mach-tegra/include/mach/tegra_emc.h
- index 16c2208..c149c26 100644
- --- a/arch/arm/mach-tegra/include/mach/tegra_emc.h
- +++ b/arch/arm/mach-tegra/include/mach/tegra_emc.h
- @@ -45,6 +45,7 @@ enum emc_user_id {
- EMC_USER_VI2,
- EMC_USER_ISP1,
- EMC_USER_ISP2,
- + EMC_USER_AUDIO,
- EMC_USER_NUM,
- };
- diff --git a/arch/arm/mach-tegra/tegra12_emc.c b/arch/arm/mach-tegra/tegra12_emc.c
- index 8e9dbe8..647d2b2 100644
- --- a/arch/arm/mach-tegra/tegra12_emc.c
- +++ b/arch/arm/mach-tegra/tegra12_emc.c
- @@ -102,6 +102,10 @@ static struct emc_iso_usage tegra12_emc_iso_usage[] = {
- 50, iso_share_calc_t124_general
- },
- {
- + BIT(EMC_USER_AUDIO),
- + 50, iso_share_calc_t124_general
- + },
- + {
- BIT(EMC_USER_DC1) | BIT(EMC_USER_VI),
- 50, iso_share_calc_t124_general
- },
- diff --git a/include/sound/core.h b/include/sound/core.h
- index 5bfe513..aab7626 100644
- --- a/include/sound/core.h
- +++ b/include/sound/core.h
- @@ -71,7 +71,7 @@ typedef int __bitwise snd_device_state_t;
- typedef int __bitwise snd_device_cmd_t;
- #define SNDRV_DEV_CMD_PRE ((__force snd_device_cmd_t) 0)
- -#define SNDRV_DEV_CMD_NORMAL ((__force snd_device_cmd_t) 1)
- +#define SNDRV_DEV_CMD_NORMAL ((__force snd_device_cmd_t) 1)
- #define SNDRV_DEV_CMD_POST ((__force snd_device_cmd_t) 2)
- struct snd_device;
- @@ -140,6 +140,8 @@ struct snd_card {
- unsigned int power_state; /* power state */
- struct mutex power_lock; /* power lock */
- wait_queue_head_t power_sleep;
- + struct task_struct *power_owner;
- + unsigned int power_count;
- #endif
- #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
- @@ -151,12 +153,19 @@ struct snd_card {
- #ifdef CONFIG_PM
- static inline void snd_power_lock(struct snd_card *card)
- {
- - mutex_lock(&card->power_lock);
- + if (card->power_owner != current) {
- + mutex_lock(&card->power_lock);
- + card->power_owner = current;
- + }
- + card->power_count++;
- }
- static inline void snd_power_unlock(struct snd_card *card)
- {
- - mutex_unlock(&card->power_lock);
- + if (--card->power_count == 0) {
- + card->power_owner = NULL;
- + mutex_unlock(&card->power_lock);
- + }
- }
- static inline unsigned int snd_power_get_state(struct snd_card *card)
- diff --git a/include/sound/rt5670.h b/include/sound/rt5670.h
- new file mode 100644
- index 0000000..aa65b8d
- --- /dev/null
- +++ b/include/sound/rt5670.h
- @@ -0,0 +1,30 @@
- +/*
- + * linux/sound/rt5670.h -- Platform data for RT5670
- + *
- + * Copyright 2011 Realtek Microelectronics
- + * Copyright (C) 2016 XiaoMi, Inc.
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#ifndef __LINUX_SND_RT5670_H
- +#define __LINUX_SND_RT5670_H
- +
- +struct rt5670_platform_data {
- + int jd_mode;
- + int codec_gpio;
- + /*
- + 0: disable,
- + 1: 3.3v, 2 port,
- + 2: 1.8v, 1 port,
- + 3: 3.3v, 1 port,
- + */
- + bool in2_diff;
- + bool in3_diff;
- + bool in4_diff;
- + bool bclk_32fs[4];
- +};
- +
- +#endif
- diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
- index 385c632..a1ed4e5 100644
- --- a/include/sound/soc-dapm.h
- +++ b/include/sound/soc-dapm.h
- @@ -368,10 +368,8 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
- int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
- struct snd_soc_dai *dai);
- int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
- -int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
- - const struct snd_soc_pcm_stream *params,
- - struct snd_soc_dapm_widget *source,
- - struct snd_soc_dapm_widget *sink);
- +int snd_soc_dapm_new_dai_link_widgets(struct snd_soc_dapm_context *dapm,
- + struct snd_soc_pcm_runtime *rtd);
- /* dapm path setup */
- int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
- @@ -512,7 +510,7 @@ struct snd_soc_dapm_widget {
- void *priv; /* widget specific data */
- struct regulator *regulator; /* attached regulator */
- - const struct snd_soc_pcm_stream *params; /* params for dai links */
- + struct snd_soc_pcm_runtime *rtd; /* rtd for dai links */
- /* dapm control */
- int reg; /* negative reg = no direct dapm */
- diff --git a/include/sound/soc.h b/include/sound/soc.h
- index 5bbdc65..7a9c07e 100644
- --- a/include/sound/soc.h
- +++ b/include/sound/soc.h
- @@ -612,7 +612,7 @@ struct snd_soc_jack_gpio {
- struct snd_soc_jack *jack;
- struct delayed_work work;
- - int (*jack_status_check)(void);
- + int (*jack_status_check)(struct snd_soc_jack_gpio *gpio);
- };
- #endif
- diff --git a/sound/core/pcm.c b/sound/core/pcm.c
- index e1e9e0c..314530d 100644
- --- a/sound/core/pcm.c
- +++ b/sound/core/pcm.c
- @@ -903,7 +903,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
- return -EINVAL;
- }
- - if (file->f_flags & O_APPEND) {
- + if (file && (file->f_flags & O_APPEND)) {
- if (prefer_subdevice < 0) {
- if (pstr->substream_count > 1)
- return -EINVAL; /* must be unique */
- @@ -965,7 +965,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
- substream->runtime = runtime;
- substream->private_data = pcm->private_data;
- substream->ref_count = 1;
- - substream->f_flags = file->f_flags;
- + substream->f_flags = file ? file->f_flags : 0;
- substream->pid = get_pid(task_pid(current));
- pstr->substream_opened++;
- *rsubstream = substream;
- diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
- index 3284940..6eaeb00 100644
- --- a/sound/core/pcm_lib.c
- +++ b/sound/core/pcm_lib.c
- @@ -1885,12 +1885,11 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
- if (runtime->no_period_wakeup)
- wait_time = MAX_SCHEDULE_TIMEOUT;
- else {
- - wait_time = 10;
- + wait_time = 10000;
- if (runtime->rate) {
- - long t = runtime->period_size * 2 / runtime->rate;
- - wait_time = max(t, wait_time);
- + wait_time = DIV_ROUND_UP(runtime->buffer_size * 1000, runtime->rate);
- }
- - wait_time = msecs_to_jiffies(wait_time * 1000);
- + wait_time = msecs_to_jiffies(wait_time);
- }
- for (;;) {
- diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
- index f928181..df14820 100644
- --- a/sound/core/pcm_native.c
- +++ b/sound/core/pcm_native.c
- @@ -852,9 +852,6 @@ static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
- struct snd_pcm_runtime *runtime = substream->runtime;
- if (runtime->status->state != SNDRV_PCM_STATE_PREPARED)
- return -EBADFD;
- - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- - !snd_pcm_playback_data(substream))
- - return -EPIPE;
- runtime->trigger_master = substream;
- return 0;
- }
- diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
- index 3684f0c..55c1ff2 100644
- --- a/sound/soc/codecs/Kconfig
- +++ b/sound/soc/codecs/Kconfig
- @@ -62,6 +62,7 @@ config SND_SOC_ALL_CODECS
- select SND_SOC_RT5639 if I2C
- select SND_SOC_RT5640 if I2C
- select SND_SOC_RT5645 if I2C
- + select SND_SOC_RT5671 if I2C
- select SND_SOC_SGTL5000 if I2C
- select SND_SOC_SI476X if MFD_SI476X_CORE
- select SND_SOC_SN95031 if INTEL_SCU_IPC
- @@ -71,6 +72,7 @@ config SND_SOC_ALL_CODECS
- select SND_SOC_STA529 if I2C
- select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
- select SND_SOC_TAS5086 if I2C
- + select SND_SOC_TFA98XX if I2C
- select SND_SOC_TLV320AIC23 if I2C
- select SND_SOC_TLV320AIC26 if SPI_MASTER
- select SND_SOC_TLV320AIC32X4 if I2C
- @@ -316,6 +318,9 @@ config SND_SOC_RT5640
- config SND_SOC_RT5645
- tristate
- +config SND_SOC_RT5671
- + tristate
- +
- #Freescale sgtl5000 codec
- config SND_SOC_SGTL5000
- tristate
- @@ -348,6 +353,9 @@ config SND_SOC_STAC9766
- config SND_SOC_TAS5086
- tristate
- +config SND_SOC_TFA98XX
- + tristate
- +
- config SND_SOC_TLV320AIC23
- tristate
- diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
- index 5d3fed8..c1519c9 100644
- --- a/sound/soc/codecs/Makefile
- +++ b/sound/soc/codecs/Makefile
- @@ -58,6 +58,7 @@ snd-soc-sta32x-objs := sta32x.o
- snd-soc-sta529-objs := sta529.o
- snd-soc-stac9766-objs := stac9766.o
- snd-soc-tas5086-objs := tas5086.o
- +snd-soc-tfa98xx-objs := tfa98xx.o
- snd-soc-tlv320aic23-objs := tlv320aic23.o
- snd-soc-tlv320aic26-objs := tlv320aic26.o
- snd-soc-tlv320aic3x-objs := tlv320aic3x.o
- @@ -125,6 +126,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
- snd-soc-rt5639-objs := rt5639.o rt56xx_ioctl.o rt5639_ioctl.o
- snd-soc-rt5640-objs := rt5640.o
- snd-soc-rt5645-objs := rt5645.o rt5645_ioctl.o rt_codec_ioctl.o
- +snd-soc-rt5671-objs := rt5671.o rt5671_ioctl.o rt_codec_ioctl.o rt5671-dsp.o
- # Amp
- snd-soc-max9877-objs := max9877.o
- @@ -190,6 +192,7 @@ obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
- obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
- obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
- obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
- +obj-$(CONFIG_SND_SOC_TFA98XX) += snd-soc-tfa98xx.o
- obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
- obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
- obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
- @@ -257,6 +260,7 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
- obj-$(CONFIG_SND_SOC_RT5639) += snd-soc-rt5639.o
- obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
- obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
- +obj-$(CONFIG_SND_SOC_RT5671) += snd-soc-rt5671.o
- # Amp
- obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
- diff --git a/sound/soc/codecs/rt5639.c b/sound/soc/codecs/rt5639.c
- index c11dcc2..8ac8c37 100644
- --- a/sound/soc/codecs/rt5639.c
- +++ b/sound/soc/codecs/rt5639.c
- @@ -3131,7 +3131,7 @@ static int rt5639_probe(struct snd_soc_codec *codec)
- ioctl_ops->index_read = rt5639_index_read;
- ioctl_ops->index_update_bits = rt5639_index_update_bits;
- ioctl_ops->ioctl_common = rt5639_ioctl_common;
- - realtek_ce_init_hwdep(codec);
- + rt56xx_init_hwdep(codec);
- #endif
- #endif
- diff --git a/sound/soc/codecs/rt5639_ioctl.c b/sound/soc/codecs/rt5639_ioctl.c
- index b168756..04b9a9f 100644
- --- a/sound/soc/codecs/rt5639_ioctl.c
- +++ b/sound/soc/codecs/rt5639_ioctl.c
- @@ -18,7 +18,7 @@
- #include "rt5639-dsp.h"
- #endif
- -hweq_t hweq_param[] = {
- +static hweq_t hweq_param[] = {
- {/* NORMAL */
- {0},
- {0},
- diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
- index 65d213b..bfaed59 100644
- --- a/sound/soc/codecs/rt5640.c
- +++ b/sound/soc/codecs/rt5640.c
- @@ -1312,7 +1312,7 @@ static int spk_event(struct snd_soc_dapm_widget *w,
- }
- #if USE_ONEBIT_DEPOP
- -void hp_amp_power(struct snd_soc_codec *codec, int on)
- +static void hp_amp_power(struct snd_soc_codec *codec, int on)
- {
- static int hp_amp_power_count;
- // printk("one bit hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count);
- @@ -1397,8 +1397,8 @@ static void rt5640_pmd_depop(struct snd_soc_codec *codec)
- hp_amp_power(codec, 0);
- }
- -#else //seq
- -void hp_amp_power(struct snd_soc_codec *codec, int on)
- +#else
- +static void hp_amp_power(struct snd_soc_codec *codec, int on)
- {
- static int hp_amp_power_count;
- // printk("hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count);
- diff --git a/sound/soc/codecs/rt5645_ioctl.c b/sound/soc/codecs/rt5645_ioctl.c
- index 37f0b8f..c67c3de 100644
- --- a/sound/soc/codecs/rt5645_ioctl.c
- +++ b/sound/soc/codecs/rt5645_ioctl.c
- @@ -15,7 +15,7 @@
- #include "rt5645_ioctl.h"
- #include "rt5645.h"
- -hweq_t hweq_param[] = {
- +static hweq_t hweq_param[] = {
- {/* NORMAL */
- {0},
- {0},
- diff --git a/sound/soc/codecs/rt5671-dsp.c b/sound/soc/codecs/rt5671-dsp.c
- new file mode 100644
- index 0000000..60bcd99
- --- /dev/null
- +++ b/sound/soc/codecs/rt5671-dsp.c
- @@ -0,0 +1,1966 @@
- +/*
- + * rt5671.c -- RT5671 ALSA SoC DSP driver
- + *
- + * Copyright 2011 Realtek Semiconductor Corp.
- + * Copyright (C) 2016 XiaoMi, Inc.
- + * Author: Johnny Hsu <johnnyhsu@realtek.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/delay.h>
- +#include <linux/i2c.h>
- +#include <linux/platform_device.h>
- +#include <sound/soc.h>
- +#include <sound/soc-dapm.h>
- +
- +#define RTK_IOCTL
- +#ifdef RTK_IOCTL
- +#include <linux/spi/spi.h>
- +#include "rt_codec_ioctl.h"
- +#endif
- +
- +#include "rt5671.h"
- +#include "rt5671-dsp.h"
- +
- +#define DSP_CLK_RATE RT5671_DSP_CLK_96K
- +
- +static unsigned short rt5671_dsp_init_patch_code[][2] = {
- + {0xe1, 0x0010}, {0xe2, 0x0000}, {0xe0, 0x6ac9},
- + {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
- + {0xe1, 0x3f00}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f01}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f02}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f03}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f04}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f05}, {0xe2, 0x4009}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f06}, {0xe2, 0x267c}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f07}, {0xe2, 0x23a2}, {0xe3, 0x00d0}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f08}, {0xe2, 0x9212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f09}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0a}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0b}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0c}, {0xe2, 0x1bf0}, {0xe3, 0x00a1}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0d}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0e}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0f}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f10}, {0xe2, 0x1918}, {0xe3, 0x004f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f11}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f12}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f13}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f14}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f15}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f16}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f17}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f18}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f19}, {0xe2, 0x1bf1}, {0xe3, 0x0071}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1a}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1b}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1c}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1d}, {0xe2, 0x191b}, {0xe3, 0x004f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1e}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1f}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f20}, {0xe2, 0x830f}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f21}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f22}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f23}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f24}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f25}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f26}, {0xe2, 0x1bf2}, {0xe3, 0x0041}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f27}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f28}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f29}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2a}, {0xe2, 0x1921}, {0xe3, 0x007f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2b}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2c}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2d}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2e}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2f}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f30}, {0xe2, 0x4009}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f31}, {0xe2, 0x267c}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f32}, {0xe2, 0x23a2}, {0xe3, 0x00d0}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f33}, {0xe2, 0x9212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f34}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f35}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f36}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f37}, {0xe2, 0x1bf3}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f38}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f39}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3a}, {0xe2, 0x81cc}, {0xe3, 0x008c}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3b}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3c}, {0xe2, 0x1a09}, {0xe3, 0x00ef}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3d}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3e}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3f}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f40}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f41}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f42}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f43}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f44}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f45}, {0xe2, 0x1bf4}, {0xe3, 0x0031}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f46}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f47}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f48}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f49}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4a}, {0xe2, 0x1a0c}, {0xe3, 0x00ef}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4b}, {0xe2, 0x8301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4c}, {0xe2, 0x9212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4d}, {0xe2, 0x8307}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4e}, {0xe2, 0x9301}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4f}, {0xe2, 0x8212}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f50}, {0xe2, 0x93ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f51}, {0xe2, 0x83ff}, {0xe3, 0x00ea}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f52}, {0xe2, 0x278a}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f53}, {0xe2, 0x1bf5}, {0xe3, 0x0011}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f54}, {0xe2, 0x8212}, {0xe3, 0x0098}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f55}, {0xe2, 0x9301}, {0xe3, 0x00f8}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f56}, {0xe2, 0x8117}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f57}, {0xe2, 0x3400}, {0xe3, 0x004e}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f58}, {0xe2, 0x1a13}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f59}, {0xe2, 0x8e77}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5a}, {0xe2, 0x34b8}, {0xe3, 0x0001}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5b}, {0xe2, 0x3960}, {0xe3, 0x0002}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5c}, {0xe2, 0x17f6}, {0xe3, 0x000e}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5d}, {0xe2, 0x6000}, {0xe3, 0x0016}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5e}, {0xe2, 0x7000}, {0xe3, 0x005a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5f}, {0xe2, 0x6800}, {0xe3, 0x0055}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f60}, {0xe2, 0x7800}, {0xe3, 0x0019}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f61}, {0xe2, 0x1859}, {0xe3, 0x00bf}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f62}, {0xe2, 0x8230}, {0xe3, 0x0010}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f63}, {0xe2, 0x26e0}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f64}, {0xe2, 0x1bf6}, {0xe3, 0x0072}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f65}, {0xe2, 0x3c00}, {0xe3, 0x0015}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f66}, {0xe2, 0x194f}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f67}, {0xe2, 0x0c20}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f68}, {0xe2, 0x8240}, {0xe3, 0x0003}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f69}, {0xe2, 0x8324}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6a}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6b}, {0xe2, 0x9240}, {0xe3, 0x000c}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6c}, {0xe2, 0x824c}, {0xe3, 0x0003}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6d}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6e}, {0xe2, 0x924c}, {0xe3, 0x000c}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6f}, {0xe2, 0x0c30}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f70}, {0xe2, 0x1950}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f71}, {0xe2, 0x962c}, {0xe3, 0x0076}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f72}, {0xe2, 0x962c}, {0xe3, 0x0086}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f73}, {0xe2, 0x4001}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f74}, {0xe2, 0x922c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f75}, {0xe2, 0x3521}, {0xe3, 0x0091}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f76}, {0xe2, 0x3521}, {0xe3, 0x0062}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f77}, {0xe2, 0x3521}, {0xe3, 0x00c0}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f78}, {0xe2, 0x3c00}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f79}, {0xe2, 0x0c0c}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7a}, {0xe2, 0x17f8}, {0xe3, 0x00ee}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7b}, {0xe2, 0x6000}, {0xe3, 0x00a5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7c}, {0xe2, 0x22fa}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7d}, {0xe2, 0x6000}, {0xe3, 0x0049}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7e}, {0xe2, 0x66e2}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7f}, {0xe2, 0x1bf8}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f80}, {0xe2, 0x26ea}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f81}, {0xe2, 0x1bf8}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f82}, {0xe2, 0x822c}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f83}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f84}, {0xe2, 0x822c}, {0xe3, 0x0094}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f85}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f86}, {0xe2, 0x1bf8}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f87}, {0xe2, 0x822c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f88}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f89}, {0xe2, 0x922c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f8a}, {0xe2, 0x822c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f8b}, {0xe2, 0x922c}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f8c}, {0xe2, 0x822c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f8d}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f8e}, {0xe2, 0x922c}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f8f}, {0xe2, 0x0c08}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f90}, {0xe2, 0x8230}, {0xe3, 0x0030}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f91}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f92}, {0xe2, 0x1bfa}, {0xe3, 0x0020}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f93}, {0xe2, 0x822c}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f94}, {0xe2, 0x822c}, {0xe3, 0x00c4}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f95}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f96}, {0xe2, 0x1bf9}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f97}, {0xe2, 0x822c}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f98}, {0xe2, 0x22e2}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f99}, {0xe2, 0x922c}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f9a}, {0xe2, 0x1bfa}, {0xe3, 0x0022}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f9b}, {0xe2, 0x962c}, {0xe3, 0x00a6}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f9c}, {0xe2, 0x962c}, {0xe3, 0x00b6}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f9d}, {0xe2, 0x1bfa}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f9e}, {0xe2, 0x4100}, {0xe3, 0x0014}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f9f}, {0xe2, 0x922c}, {0xe3, 0x00b4}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa0}, {0xe2, 0x4001}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa1}, {0xe2, 0x922c}, {0xe3, 0x00a4}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa2}, {0xe2, 0x3c00}, {0xe3, 0x0075}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa3}, {0xe2, 0x193c}, {0xe3, 0x00af}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa4}, {0xe2, 0x8230}, {0xe3, 0x0030}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa5}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa6}, {0xe2, 0x1bfb}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa7}, {0xe2, 0x822c}, {0xe3, 0x00ba}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa8}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fa9}, {0xe2, 0x1bfb}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
- + {0xe1, 0x3faa}, {0xe2, 0x8230}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fab}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fac}, {0xe2, 0x4001}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fad}, {0xe2, 0x4001}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fae}, {0xe2, 0x2279}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3faf}, {0xe2, 0x0d04}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb0}, {0xe2, 0x3724}, {0xe3, 0x0001}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb1}, {0xe2, 0x0900}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb2}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb3}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb4}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb5}, {0xe2, 0x3b24}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb6}, {0xe2, 0x194f}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb7}, {0xe2, 0x3c00}, {0xe3, 0x0025}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb8}, {0xe2, 0x3916}, {0xe3, 0x0072}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fb9}, {0xe2, 0x3501}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fba}, {0xe2, 0x1dbe}, {0xe3, 0x008f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fbb}, {0xe2, 0x8e2e}, {0xe3, 0x00b5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fbc}, {0xe2, 0x3916}, {0xe3, 0x0012}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fbd}, {0xe2, 0x3500}, {0xe3, 0x0091}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fbe}, {0xe2, 0x1dbe}, {0xe3, 0x008f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fbf}, {0xe2, 0x822e}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fc0}, {0xe2, 0x2780}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fc1}, {0xe2, 0x1bfc}, {0xe3, 0x0060}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fc2}, {0xe2, 0x3c00}, {0xe3, 0x0025}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fc3}, {0xe2, 0x3916}, {0xe3, 0x0012}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fc4}, {0xe2, 0x3501}, {0xe3, 0x00a1}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fc5}, {0xe2, 0x1dbe}, {0xe3, 0x008f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fc6}, {0xe2, 0x810b}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
- + {0xe1, 0x3fc7}, {0xe2, 0x1831}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
- + {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
- + {0xe1, 0x3fa0}, {0xe2, 0x9183}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb0}, {0xe2, 0x3f00}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa1}, {0xe2, 0x91b3}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb1}, {0xe2, 0x3f11}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa2}, {0xe2, 0x9216}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb2}, {0xe2, 0x3f1e}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa3}, {0xe2, 0xe09d}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb3}, {0xe2, 0x3f2b}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa4}, {0xe2, 0xe0cd}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb4}, {0xe2, 0x3f3d}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa5}, {0xe2, 0xe130}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb5}, {0xe2, 0x3f4b}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa6}, {0xe2, 0x859a}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb6}, {0xe2, 0x3f59}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa7}, {0xe2, 0x94fc}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb7}, {0xe2, 0x3f62}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa8}, {0xe2, 0x93c9}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb8}, {0xe2, 0x3f71}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa9}, {0xe2, 0x94f2}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb9}, {0xe2, 0x3fa4}, {0xe0, 0x3bcb},
- + {0xe1, 0x22cc}, {0xe2, 0x0001}, {0xe0, 0x3bcb},
- + {0xe1, 0x3faa}, {0xe2, 0x823a}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fba}, {0xe2, 0x023e}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fab}, {0xe2, 0x8351}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbb}, {0xe2, 0x0355}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fac}, {0xe2, 0x838d}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbc}, {0xe2, 0x0391}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fad}, {0xe2, 0x8342}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbd}, {0xe2, 0x0346}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fae}, {0xe2, 0x8382}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbe}, {0xe2, 0x0386}, {0xe0, 0x3bcb},
- + {0xe1, 0x3faf}, {0xe2, 0x831c}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbf}, {0xe2, 0x3fb7}, {0xe0, 0x3bcb},
- + {0xe1, 0x0010}, {0xe2, 0x0001}, {0xe0, 0x6ac9},
- + {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
- + {0xe1, 0x3f00}, {0xe2, 0x26e1}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f01}, {0xe2, 0x1924}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f02}, {0xe2, 0x82f5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f03}, {0xe2, 0x26e0}, {0xe3, 0x00df}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f04}, {0xe2, 0x1bf0}, {0xe3, 0x0072}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f05}, {0xe2, 0x3400}, {0xe3, 0x0008}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f06}, {0xe2, 0x198e}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f07}, {0xe2, 0x0c20}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f08}, {0xe2, 0x80f5}, {0xe3, 0x00b3}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f09}, {0xe2, 0x8149}, {0xe3, 0x00b7}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0a}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0b}, {0xe2, 0x90f5}, {0xe3, 0x00bc}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0c}, {0xe2, 0x8101}, {0xe3, 0x00b3}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0d}, {0xe2, 0x2029}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0e}, {0xe2, 0x9101}, {0xe3, 0x00bc}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f0f}, {0xe2, 0x0c30}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f10}, {0xe2, 0x198e}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f11}, {0xe2, 0x9433}, {0xe3, 0x0006}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f12}, {0xe2, 0x9433}, {0xe3, 0x0016}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f13}, {0xe2, 0x4001}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f14}, {0xe2, 0x9033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f15}, {0xe2, 0x3527}, {0xe3, 0x0041}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f16}, {0xe2, 0x3527}, {0xe3, 0x0012}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f17}, {0xe2, 0x3527}, {0xe3, 0x0070}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f18}, {0xe2, 0x3c00}, {0xe3, 0x00c5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f19}, {0xe2, 0x0c0c}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1a}, {0xe2, 0x17f2}, {0xe3, 0x00ee}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1b}, {0xe2, 0x6000}, {0xe3, 0x00a5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1c}, {0xe2, 0x22fa}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1d}, {0xe2, 0x6000}, {0xe3, 0x0049}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1e}, {0xe2, 0x66e2}, {0xe3, 0x0051}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f1f}, {0xe2, 0x1bf2}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f20}, {0xe2, 0x26ea}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f21}, {0xe2, 0x1bf2}, {0xe3, 0x00c3}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f22}, {0xe2, 0x8033}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f23}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f24}, {0xe2, 0x8033}, {0xe3, 0x0024}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f25}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f26}, {0xe2, 0x1bf2}, {0xe3, 0x00a0}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f27}, {0xe2, 0x8033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f28}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f29}, {0xe2, 0x9033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2a}, {0xe2, 0x8033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2b}, {0xe2, 0x9033}, {0xe3, 0x001a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2c}, {0xe2, 0x8033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2d}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2e}, {0xe2, 0x9033}, {0xe3, 0x002a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f2f}, {0xe2, 0x0c08}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f30}, {0xe2, 0x82f5}, {0xe3, 0x0060}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f31}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f32}, {0xe2, 0x1bf4}, {0xe3, 0x0020}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f33}, {0xe2, 0x8033}, {0xe3, 0x000a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f34}, {0xe2, 0x8033}, {0xe3, 0x0054}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f35}, {0xe2, 0x26e2}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f36}, {0xe2, 0x1bf3}, {0xe3, 0x00e5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f37}, {0xe2, 0x8033}, {0xe3, 0x003a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f38}, {0xe2, 0x22e2}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f39}, {0xe2, 0x9033}, {0xe3, 0x003a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3a}, {0xe2, 0x1bf4}, {0xe3, 0x0022}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3b}, {0xe2, 0x9433}, {0xe3, 0x0036}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3c}, {0xe2, 0x9433}, {0xe3, 0x0046}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3d}, {0xe2, 0x1bf4}, {0xe3, 0x002f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3e}, {0xe2, 0x4100}, {0xe3, 0x0014}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f3f}, {0xe2, 0x9033}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f40}, {0xe2, 0x4001}, {0xe3, 0x0044}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f41}, {0xe2, 0x9033}, {0xe3, 0x0034}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f42}, {0xe2, 0x3c00}, {0xe3, 0x0075}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f43}, {0xe2, 0x192f}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f44}, {0xe2, 0x82f5}, {0xe3, 0x0060}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f45}, {0xe2, 0x2398}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f46}, {0xe2, 0x1bf5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f47}, {0xe2, 0x8033}, {0xe3, 0x004a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f48}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f49}, {0xe2, 0x1bf5}, {0xe3, 0x0050}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4a}, {0xe2, 0x82f5}, {0xe3, 0x005a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4b}, {0xe2, 0x267a}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4c}, {0xe2, 0x4001}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4d}, {0xe2, 0x4001}, {0xe3, 0x00f1}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4e}, {0xe2, 0x2279}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f4f}, {0xe2, 0x0d04}, {0xe3, 0x007a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f50}, {0xe2, 0x3549}, {0xe3, 0x00b1}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f51}, {0xe2, 0x0900}, {0xe3, 0x0007}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f52}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f53}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f54}, {0xe2, 0xa7ff}, {0xe3, 0x00f5}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f55}, {0xe2, 0x3949}, {0xe3, 0x00b0}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f56}, {0xe2, 0x1984}, {0xe3, 0x003f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f57}, {0xe2, 0x82b6}, {0xe3, 0x0061}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f58}, {0xe2, 0x17f8}, {0xe3, 0x006e}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f59}, {0xe2, 0x8291}, {0xe3, 0x006a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5a}, {0xe2, 0x602a}, {0xe3, 0x0065}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5b}, {0xe2, 0x2084}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5c}, {0xe2, 0x0d00}, {0xe3, 0x00fc}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5d}, {0xe2, 0x0d00}, {0xe3, 0x00eb}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5e}, {0xe2, 0x2058}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f5f}, {0xe2, 0x1067}, {0xe3, 0x00be}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f60}, {0xe2, 0x1073}, {0xe3, 0x0087}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f61}, {0xe2, 0x1047}, {0xe3, 0x00a9}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f62}, {0xe2, 0x0e5b}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f63}, {0xe2, 0x2262}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f64}, {0xe2, 0x902f}, {0xe3, 0x009f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f65}, {0xe2, 0x902f}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f66}, {0xe2, 0x1c95}, {0xe3, 0x00cf}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f67}, {0xe2, 0x1c50}, {0xe3, 0x00cf}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f68}, {0xe2, 0x0f22}, {0xe3, 0x00ff}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f69}, {0xe2, 0x802f}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6a}, {0xe2, 0x0d00}, {0xe3, 0x005f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6b}, {0xe2, 0x4000}, {0xe3, 0x0004}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6c}, {0xe2, 0x060a}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6d}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6e}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f6f}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f70}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f71}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f72}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f73}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f74}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f75}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f76}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f77}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f78}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f79}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7a}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7b}, {0xe2, 0x0712}, {0xe3, 0x0000}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7c}, {0xe2, 0x802f}, {0xe3, 0x00aa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7d}, {0xe2, 0x2b3a}, {0xe3, 0x00b4}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7e}, {0xe2, 0x2262}, {0xe3, 0x001f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f7f}, {0xe2, 0x0d00}, {0xe3, 0x009a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f80}, {0xe2, 0x1023}, {0xe3, 0x0061}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f81}, {0xe2, 0x2027}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f82}, {0xe2, 0x428b}, {0xe3, 0x00e6}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f83}, {0xe2, 0x2024}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f84}, {0xe2, 0x82b7}, {0xe3, 0x0084}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f85}, {0xe2, 0x2b24}, {0xe3, 0x0078}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f86}, {0xe2, 0x92b7}, {0xe3, 0x008a}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f87}, {0xe2, 0x1a20}, {0xe3, 0x007f}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f88}, {0xe2, 0x47ff}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f89}, {0xe2, 0x92b5}, {0xe3, 0x00fa}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f8a}, {0xe2, 0x356d}, {0xe3, 0x00b1}, {0xe0, 0x0dcf},
- + {0xe1, 0x3f8b}, {0xe2, 0x19e4}, {0xe3, 0x000f}, {0xe0, 0x0dcf},
- + {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
- + {0xe1, 0x3fa0}, {0xe2, 0x9248}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb0}, {0xe2, 0x3f00}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa1}, {0xe2, 0x98e2}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb1}, {0xe2, 0x3f02}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa2}, {0xe2, 0x92f0}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb2}, {0xe2, 0x3f11}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa3}, {0xe2, 0x9842}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb3}, {0xe2, 0x3f44}, {0xe0, 0x3bcb},
- + {0xe1, 0x0335}, {0xe2, 0x0001}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa4}, {0xe2, 0xa1d6}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb4}, {0xe2, 0x3f57}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa5}, {0xe2, 0x9e3f}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb5}, {0xe2, 0x3f88}, {0xe0, 0x3bcb},
- + {0xe1, 0x0010}, {0xe2, 0x0000}, {0xe0, 0x6ac9},
- +};
- +#define RT5671_DSP_INIT_PATCH_NUM \
- + (sizeof(rt5671_dsp_init_patch_code) / sizeof(rt5671_dsp_init_patch_code[0]))
- +
- +static unsigned short rt5671_dsp_reset_patch_code[][2] = {
- + {0xe1, 0x0010}, {0xe2, 0x0000}, {0xe0, 0x6ac9},
- + {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
- + {0xe1, 0x3fa0}, {0xe2, 0x9183}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb0}, {0xe2, 0x3f00}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa1}, {0xe2, 0x91b3}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb1}, {0xe2, 0x3f11}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa2}, {0xe2, 0x9216}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb2}, {0xe2, 0x3f1e}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa3}, {0xe2, 0xe09d}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb3}, {0xe2, 0x3f2b}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa4}, {0xe2, 0xe0cd}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb4}, {0xe2, 0x3f3d}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa5}, {0xe2, 0xe130}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb5}, {0xe2, 0x3f4b}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa6}, {0xe2, 0x859a}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb6}, {0xe2, 0x3f59}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa7}, {0xe2, 0x94fc}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb7}, {0xe2, 0x3f62}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa8}, {0xe2, 0x93c9}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb8}, {0xe2, 0x3f71}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa9}, {0xe2, 0x94f2}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb9}, {0xe2, 0x3fa4}, {0xe0, 0x3bcb},
- + {0xe1, 0x22cc}, {0xe2, 0x0001}, {0xe0, 0x3bcb},
- + {0xe1, 0x3faa}, {0xe2, 0x823a}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fba}, {0xe2, 0x023e}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fab}, {0xe2, 0x8351}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbb}, {0xe2, 0x0355}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fac}, {0xe2, 0x838d}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbc}, {0xe2, 0x0391}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fad}, {0xe2, 0x8342}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbd}, {0xe2, 0x0346}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fae}, {0xe2, 0x8382}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbe}, {0xe2, 0x0386}, {0xe0, 0x3bcb},
- + {0xe1, 0x3faf}, {0xe2, 0x831c}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fbf}, {0xe2, 0x3fb7}, {0xe0, 0x3bcb},
- +
- + {0xe1, 0x0010}, {0xe2, 0x0001}, {0xe0, 0x6ac9},
- + {0xe1, 0x0064}, {0xe2, 0x0000}, {0xe0, 0x68c5},
- + {0xe1, 0x3fa0}, {0xe2, 0x9248}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb0}, {0xe2, 0x3f00}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa1}, {0xe2, 0x98e2}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb1}, {0xe2, 0x3f02}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa2}, {0xe2, 0x92f0}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb2}, {0xe2, 0x3f11}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa3}, {0xe2, 0x9842}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb3}, {0xe2, 0x3f44}, {0xe0, 0x3bcb},
- + {0xe1, 0x0335}, {0xe2, 0x0001}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa4}, {0xe2, 0xa1d6}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb4}, {0xe2, 0x3f57}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fa5}, {0xe2, 0x9e3f}, {0xe0, 0x3bcb},
- + {0xe1, 0x3fb5}, {0xe2, 0x3f88}, {0xe0, 0x3bcb},
- + {0xe1, 0x0010}, {0xe2, 0x0000}, {0xe0, 0x6ac9},
- +};
- +#define RT5671_DSP_RESET_PATCH_NUM \
- + (sizeof(rt5671_dsp_reset_patch_code) / sizeof(rt5671_dsp_reset_patch_code[0]))
- +
- +/* DSP init */
- +static unsigned short rt5671_dsp_init[][2] = {
- + {0x2260, 0x30d9}, {0x2260, 0x30d9}, /*{0x2261, 0x30d9},*/ {0x2289, 0x7fff}, {0x2290, 0x7fff},
- + {0x2288, 0x0002}, {0x22b2, 0x0002}, {0x2295, 0x0001}, {0x22b3, 0x0001},
- + /*{0x22d7, 0x0008}, {0x22d8, 0x0009},*/ {0x22d9, 0x0000}, {0x22da, 0x0001},
- + {0x22fd, 0x001e}, {0x22c1, 0x1006}, {0x22c2, 0x1006}, {0x22c3, 0x1007},
- + {0x22c4, 0x1007}
- +};
- +#define RT5671_DSP_INIT_NUM \
- + (sizeof(rt5671_dsp_init) / sizeof(rt5671_dsp_init[0]))
- +
- +/* Data Source */
- +#define RT5671_DSP_TDM_SRC_PAR_NUM 5
- +
- +static unsigned short rt5671_dsp_data_src[][2] = {
- + /*For Stereo ADC mixer*/
- + {0x2261, 0x30d9}, {0x2282, 0x0008}, {0x2283, 0x0009},
- + {0x22d7, 0x0008}, {0x22d8, 0x0009},
- + /*For Mono ADC mixer*/
- + {0x2261, 0x30df}, {0x2282, 0x000a}, {0x2283, 0x000b},
- + {0x22d7, 0x000a}, {0x22d8, 0x000b},
- +};
- +
- +static unsigned short rt5671_dsp_rate_par[] = {
- + 0x226c, 0x226d, 0x226e, 0x22f2, 0x2301, 0x2306,
- +};
- +#define RT5671_DSP_RATE_NUM \
- + (sizeof(rt5671_dsp_rate_par) / sizeof(rt5671_dsp_rate_par[0]))
- +
- +/* MCLK rate */
- +static unsigned short rt5671_dsp_4096000[][2] = {
- + {0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x0022},
- +};
- +#define RT5671_DSP_4096000_NUM \
- + (sizeof(rt5671_dsp_4096000) / sizeof(rt5671_dsp_4096000[0]))
- +
- +static unsigned short rt5671_dsp_12288000[][2] = {
- + {0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x0026},
- +};
- +#define RT5671_DSP_12288000_NUM \
- + (sizeof(rt5671_dsp_12288000) / sizeof(rt5671_dsp_12288000[0]))
- +
- +static unsigned short rt5671_dsp_11289600[][2] = {
- + {0x226c, 0x0031}, {0x226d, 0x0050}, {0x226e, 0x0009},
- +};
- +#define RT5671_DSP_11289600_NUM \
- + (sizeof(rt5671_dsp_11289600) / sizeof(rt5671_dsp_11289600[0]))
- +
- +static unsigned short rt5671_dsp_24576000[][2] = {
- + {0x226c, 0x000c}, {0x226d, 0x000c}, {0x226e, 0x002c},
- +};
- +#define RT5671_DSP_24576000_NUM \
- + (sizeof(rt5671_dsp_24576000) / sizeof(rt5671_dsp_24576000[0]))
- +
- +/* sample rate */
- +static unsigned short rt5671_dsp_48_441[][2] = {
- + {0x22f2, 0x005c}, {0x2301, 0x0016}
- +};
- +#define RT5671_DSP_48_441_NUM \
- + (sizeof(rt5671_dsp_48_441) / sizeof(rt5671_dsp_48_441[0]))
- +
- +static unsigned short rt5671_dsp_24[][2] = {
- + {0x22f2, 0x005c}, {0x2301, 0x0004}
- +};
- +#define RT5671_DSP_24_NUM (sizeof(rt5671_dsp_24) / sizeof(rt5671_dsp_24[0]))
- +
- +static unsigned short rt5671_dsp_16[][2] = {
- + {0x22f2, 0x0058}, {0x2301, 0x0002}
- +};
- +#define RT5671_DSP_16_NUM (sizeof(rt5671_dsp_16) / sizeof(rt5671_dsp_16[0]))
- +
- +static unsigned short rt5671_dsp_8[][2] = {
- + {0x22f2, 0x004c}, {0x2301, 0x0000}
- +};
- +#define RT5671_DSP_8_NUM (sizeof(rt5671_dsp_8) / sizeof(rt5671_dsp_8[0]))
- +
- +/* DSP mode */
- +static unsigned short rt5671_dsp_hs_aec[][2] = {
- + /* AEC_WB_HP_VOIP */
- + {0x22f8, 0x8005},
- + {0x229d, 0x0000},
- + {0x232f, 0x0010},
- + {0x2355, 0x0800},
- + {0x2356, 0x0800},
- + {0x2357, 0x1000},
- + {0x2358, 0x2000},
- + {0x2359, 0x4000},
- + {0x235a, 0x6000},
- + {0x235b, 0x7fff},
- + {0x235c, 0x7fff},
- + {0x235d, 0x7fff},
- + {0x235e, 0x7fff},
- + {0x235f, 0x7fff},
- + {0x2360, 0x7fff},
- + {0x2361, 0x7fff},
- + {0x2362, 0x1000},
- + {0x2367, 0x0008},
- + {0x2368, 0x2000},
- + {0x2369, 0x0010},
- + {0x236a, 0x0200},
- + {0x236b, 0x0000},
- + {0x236d, 0x0000},
- + {0x236f, 0x0200},
- + {0x2375, 0x7ff0},
- + {0x2376, 0x7990},
- + {0x2377, 0x7330},
- + {0x238a, 0x0400},
- + {0x238b, 0x1800},
- + {0x238c, 0x1800},
- + {0x23a3, 0x2000},
- + {0x23ad, 0x2000},
- + {0x23ae, 0x2000},
- + {0x23af, 0x2000},
- + {0x23b0, 0x2000},
- + {0x23b1, 0x2000},
- + {0x23b4, 0x0800},
- + {0x23b5, 0x0800},
- + {0x23b6, 0x0800},
- + {0x23b7, 0x0800},
- + {0x23b8, 0x0800},
- + {0x23bb, 0x2000},
- + {0x23e7, 0x0400},
- + {0x23e8, 0x0c00},
- + {0x23e9, 0x5000},
- + {0x23ea, 0x7800},
- + {0x23c4, 0x1000},
- + {0x2304, 0x0332},
- + {0x230c, 0x05a0},
- + {0x230d, 0x0020},
- + {0x2310, 0x0001},
- +
- + {0x22fb, 0x0000},
- +};
- +#define RT5671_DSP_HS_AEC_NUM \
- + (sizeof(rt5671_dsp_hs_aec) / sizeof(rt5671_dsp_hs_aec[0]))
- +
- +static unsigned short rt5671_dsp_bt_ezaec[][2] = {
- + /* ezAEC_WB_1mic_BT */
- + {0x22f8, 0x8005},
- + {0x229d, 0x0000},
- + {0x232f, 0x0008},
- + {0x2355, 0x0800},
- + {0x2356, 0x0800},
- + {0x2357, 0x0800},
- + {0x2358, 0x0800},
- + {0x2359, 0x0800},
- + {0x235a, 0x0800},
- + {0x235b, 0x1000},
- + {0x235c, 0x2000},
- + {0x235d, 0x2000},
- + {0x235e, 0x2000},
- + {0x235f, 0x2000},
- + {0x2360, 0x7fff},
- + {0x2361, 0x7fff},
- + {0x2362, 0x0200},
- + {0x2367, 0x000c},
- + {0x2368, 0x0400},
- + {0x2369, 0x0010},
- + {0x2375, 0x7ff0},
- + {0x2376, 0x7990},
- + {0x2377, 0x7330},
- + {0x238a, 0x0400},
- + {0x238b, 0x2000},
- + {0x238c, 0x2000},
- + {0x23a3, 0x2000},
- + {0x23ad, 0x1000},
- + {0x23ae, 0x1000},
- + {0x23af, 0x1000},
- + {0x23b0, 0x1000},
- + {0x23b1, 0x1000},
- + {0x23b4, 0x0200},
- + {0x23b5, 0x0200},
- + {0x23b6, 0x0200},
- + {0x23b7, 0x0200},
- + {0x23b8, 0x0200},
- + {0x23bb, 0x0800},
- + {0x23c4, 0x2000},
- + {0x23e7, 0x1000},
- + {0x23e8, 0x1800},
- + {0x23e9, 0x5000},
- + {0x23ea, 0x7800},
- + {0x230c, 0x0100},
- + {0x230d, 0x0080},
- + {0x2304, 0x0332},
- + {0x2310, 0x0001},
- +
- + {0x22fb, 0x0000},
- +};
- +#define RT5671_DSP_BT_EZAEC_NUM \
- + (sizeof(rt5671_dsp_bt_ezaec) / sizeof(rt5671_dsp_bt_ezaec[0]))
- +
- +static unsigned short rt5671_dsp_bt_aec[][2] = {
- + /* (AEC mode)~[1mic][WB][for BT & headphone]*/
- + {0x22f8, 0x8005},
- + {0x229d, 0x0000},
- + {0x232f, 0x0020},
- + {0x2355, 0x0800},
- + {0x2356, 0x0800},
- + {0x2357, 0x0800},
- + {0x2358, 0x1000},
- + {0x2359, 0x1000},
- + {0x235a, 0x1000},
- + {0x235b, 0x1000},
- + {0x235c, 0x2000},
- + {0x235d, 0x2000},
- + {0x235e, 0x4000},
- + {0x235f, 0x4000},
- + {0x2360, 0x7fff},
- + {0x2361, 0x7fff},
- + {0x2362, 0x0400},
- + {0x2367, 0x0008},
- + {0x2368, 0x1000},
- + {0x2369, 0x0010},
- + {0x2375, 0x7ff0},
- + {0x2376, 0x7990},
- + {0x2377, 0x7330},
- + {0x238a, 0x0400},
- + {0x238b, 0x1000},
- + {0x238c, 0x1000},
- + {0x23a3, 0x2000},
- + {0x23ad, 0x2000},
- + {0x23ae, 0x2000},
- + {0x23af, 0x2000},
- + {0x23b0, 0x2000},
- + {0x23b1, 0x2000},
- + {0x23b4, 0x0800},
- + {0x23b5, 0x0800},
- + {0x23b6, 0x0800},
- + {0x23b7, 0x0800},
- + {0x23b8, 0x0800},
- + {0x23bb, 0x1000},
- + {0x23c4, 0x1800},
- + {0x23e7, 0x1000},
- + {0x23e8, 0x1800},
- + {0x23e9, 0x5000},
- + {0x23ea, 0x7800},
- + {0x230c, 0x0100},
- + {0x230d, 0x0080},
- + {0x2304, 0x0332},
- + {0x2310, 0x0001},
- +
- + {0x22fb, 0x0000},
- +};
- +#define RT5671_DSP_BT_AEC_NUM \
- + (sizeof(rt5671_dsp_bt_aec) / sizeof(rt5671_dsp_bt_aec[0]))
- +
- +static unsigned short rt5671_dsp_1mic_aec[][2] = {
- + /* (AEC mode)~[1mic][WB][VOIP] */
- + {0x22f8, 0x8005},
- + {0x229d, 0x0000},
- + {0x232b, 0x0006},
- + {0x232f, 0x0180},
- + {0x2355, 0x2666},
- + {0x2356, 0x2666},
- + {0x2357, 0x6666},
- + {0x2358, 0x6666},
- + {0x2359, 0x7fff},
- + {0x235a, 0x7fff},
- + {0x235b, 0x7fff},
- + {0x235c, 0x7fff},
- + {0x235d, 0x7fff},
- + {0x235e, 0x7fff},
- + {0x235f, 0x7fff},
- + {0x2360, 0x7fff},
- + {0x2361, 0x7fff},
- + {0x2362, 0x4000},
- + {0x2368, 0x6000},
- + {0x2369, 0x0006},
- + {0x236a, 0x2000},
- + {0x236b, 0x000a},
- + {0x236c, 0x0040},
- + {0x236d, 0x0000},
- + {0x236f, 0x2000},
- + {0x2375, 0x7ff0},
- + {0x2376, 0x7332},
- + {0x2377, 0x6666},
- + {0x237e, 0x0001},
- + {0x2388, 0x4000},
- + {0x238a, 0x2000},
- + {0x238b, 0x1000},
- + {0x238c, 0x1000},
- + {0x23a3, 0x2000},
- + {0x23ad, 0x2000},
- + {0x23ae, 0x7000},
- + {0x23af, 0x7000},
- + {0x23b0, 0x7000},
- + {0x23b1, 0x7fff},
- + {0x23b4, 0x0800},
- + {0x23b5, 0x1000},
- + {0x23b6, 0x4000},
- + {0x23b7, 0x4000},
- + {0x23b8, 0x7fff},
- + {0x23bb, 0x2000},
- + {0x23c4, 0x2800},
- + {0x23df, 0x4210},
- + {0x23e0, 0x1374},
- + {0x23e4, 0x5677},
- + {0x2304, 0x0332},
- + {0x230c, 0x05a0},
- + {0x230d, 0x0200},
- + {0x23e7, 0x0e00},
- + {0x23e8, 0x1200},
- + {0x23e9, 0x6000},
- + {0x23ea, 0x7800},
- + {0x2310, 0x0008},
- +
- + {0x22fb, 0x0000},
- +};
- +#define RT5671_DSP_1MIC_AEC_NUM \
- + (sizeof(rt5671_dsp_1mic_aec) / sizeof(rt5671_dsp_1mic_aec[0]))
- +
- +static unsigned short rt5671_dsp_1mic_ezaec[][2] = {
- + /* (AEC mode)~[1mic][WB][VOIP] with SW-AEC */
- + {0x22f8, 0x8005},
- + {0x229d, 0x0000},
- + {0x232b, 0x0006},
- + {0x232f, 0x0180},
- + {0x2355, 0x2666},
- + {0x2356, 0x2666},
- + {0x2357, 0x6666},
- + {0x2358, 0x6666},
- + {0x2359, 0x7fff},
- + {0x235a, 0x7fff},
- + {0x235b, 0x7fff},
- + {0x235c, 0x7fff},
- + {0x235d, 0x7fff},
- + {0x235e, 0x7fff},
- + {0x235f, 0x7fff},
- + {0x2360, 0x7fff},
- + {0x2361, 0x7fff},
- + {0x2362, 0x4000},
- + {0x2368, 0x6000},
- + {0x2369, 0x000c},
- + {0x236a, 0x1000},
- + {0x236b, 0x000a},
- + {0x236c, 0x0040},
- + {0x236d, 0x0000},
- + {0x236f, 0x1000},
- + {0x2375, 0x7ff0},
- + {0x2376, 0x7332},
- + {0x2377, 0x6666},
- + {0x237e, 0x0001},
- + {0x2388, 0x4000},
- + {0x238a, 0x1000},
- + {0x238b, 0x1000},
- + {0x238c, 0x1000},
- + {0x23a3, 0x2000},
- + {0x23ad, 0x2000},
- + {0x23ae, 0x2000},
- + {0x23af, 0x4000},
- + {0x23b0, 0x6000},
- + {0x23b1, 0x7fff},
- + {0x23b4, 0x0800},
- + {0x23b5, 0x1000},
- + {0x23b6, 0x2000},
- + {0x23b7, 0x4000},
- + {0x23b8, 0x6000},
- + {0x23bb, 0x2000},
- + {0x23c4, 0x2800},
- + {0x23df, 0x4210},
- + {0x23e0, 0x1374},
- + {0x23e4, 0x5677},
- + {0x2304, 0x0332},
- + {0x230c, 0x05a0},
- + {0x230d, 0x0200},
- + {0x23e7, 0x0e00},
- + {0x23e8, 0x1200},
- + {0x23e9, 0x6000},
- + {0x23ea, 0x7800},
- + {0x2310, 0x0008},
- +
- + {0x22fb, 0x0000},
- +
- +
- +};
- +#define RT5671_DSP_1MIC_EZAEC_NUM \
- + (sizeof(rt5671_dsp_1mic_ezaec) / sizeof(rt5671_dsp_1mic_ezaec[0]))
- +
- +static unsigned short rt5671_dsp_aec[][2] = {
- + /* (AEC mode)~[2mic][WB][VT] for VOIP without SW-AEC */
- + {0x22f8, 0x8003},
- + {0x229d, 0x0000},
- + {0x232b, 0x0006},
- + {0x232f, 0x0180},
- + {0x2355, 0x2666},
- + {0x2356, 0x2666},
- + {0x2357, 0x6666},
- + {0x2358, 0x6666},
- + {0x2359, 0x7fff},
- + {0x235a, 0x7fff},
- + {0x235b, 0x7fff},
- + {0x235c, 0x7fff},
- + {0x235d, 0x7fff},
- + {0x235e, 0x7fff},
- + {0x235f, 0x7fff},
- + {0x2360, 0x7fff},
- + {0x2361, 0x7fff},
- + {0x2362, 0x4000},
- + {0x2368, 0x6000},
- + {0x2369, 0x0006},
- + {0x236a, 0x2000},
- + {0x236b, 0x000a},
- + {0x236c, 0x0040},
- + {0x236d, 0x0000},
- + {0x236f, 0x2000},
- + {0x2371, 0x0005},
- + {0x2375, 0x7999},
- + {0x2376, 0x6ccc},
- + {0x2377, 0x5fff},
- + {0x2379, 0x1800},
- + {0x237a, 0x1800},
- + {0x237e, 0x0001},
- + {0x2388, 0x6800},
- + {0x2389, 0x7000},
- + {0x238a, 0x2000},
- + {0x238b, 0x0800},
- + {0x238c, 0x0800},
- + {0x2393, 0x8222},
- + {0x2394, 0x2104},
- + {0x2395, 0x4444},
- + {0x2396, 0x2222},
- + {0x2397, 0x3344},
- + {0x2398, 0x88aa},
- + {0x23a1, 0x1000},
- + {0x23a3, 0x1000},
- + {0x23ad, 0x2000},
- + {0x23ae, 0x7000},
- + {0x23af, 0x7000},
- + {0x23b0, 0x7000},
- + {0x23b1, 0x7fff},
- + {0x23b4, 0x0800},
- + {0x23b5, 0x1000},
- + {0x23b6, 0x4000},
- + {0x23b7, 0x4000},
- + {0x23b8, 0x7fff},
- + {0x23bb, 0x2000},
- + {0x23c4, 0x2800},
- + {0x23df, 0x4210},
- + {0x23e0, 0x1374},
- + {0x23e4, 0x5677},
- + {0x2304, 0x0332},
- + {0x230c, 0x0600},
- + {0x230d, 0x0200},
- + {0x23e7, 0x0e00},
- + {0x23e8, 0x1200},
- + {0x23e9, 0x6000},
- + {0x23ea, 0x7800},
- + {0x2310, 0x0008},
- +
- + {0x22fb, 0x0000},
- +};
- +#define RT5671_DSP_AEC_NUM \
- + (sizeof(rt5671_dsp_aec) / sizeof(rt5671_dsp_aec[0]))
- +
- +static unsigned short rt5671_dsp_ezaec[][2] = {
- + /* (AEC mode)~[2mic][WB][VT] for VOIP with SW-AEC */
- + {0x22f8, 0x8003},
- + {0x229d, 0x0000},
- + {0x232b, 0x0006},
- + {0x232f, 0x0180},
- + {0x2355, 0x2666},
- + {0x2356, 0x2666},
- + {0x2357, 0x6666},
- + {0x2358, 0x6666},
- + {0x2359, 0x7fff},
- + {0x235a, 0x7fff},
- + {0x235b, 0x7fff},
- + {0x235c, 0x7fff},
- + {0x235d, 0x7fff},
- + {0x235e, 0x7fff},
- + {0x235f, 0x7fff},
- + {0x2360, 0x7fff},
- + {0x2361, 0x7fff},
- + {0x2362, 0x4000},
- + {0x2368, 0x6000},
- + {0x2369, 0x000c},
- + {0x236a, 0x1000},
- + {0x236b, 0x000a},
- + {0x236c, 0x0040},
- + {0x236d, 0x0000},
- + {0x236f, 0x1000},
- + {0x2371, 0x0005},
- + {0x2375, 0x7999},
- + {0x2376, 0x6ccc},
- + {0x2377, 0x5fff},
- + {0x2379, 0x1800},
- + {0x237a, 0x1800},
- + {0x237e, 0x0001},
- + {0x2388, 0x6800},
- + {0x2389, 0x7000},
- + {0x238a, 0x1000},
- + {0x238b, 0x0800},
- + {0x238c, 0x0800},
- + {0x2393, 0x8222},
- + {0x2394, 0x2104},
- + {0x2395, 0x4444},
- + {0x2396, 0x2222},
- + {0x2397, 0x3344},
- + {0x2398, 0x88aa},
- + {0x23a1, 0x1000},
- + {0x23a3, 0x1000},
- + {0x23ad, 0x2000},
- + {0x23ae, 0x2000},
- + {0x23af, 0x4000},
- + {0x23b0, 0x6000},
- + {0x23b1, 0x7fff},
- + {0x23b4, 0x0800},
- + {0x23b5, 0x1000},
- + {0x23b6, 0x2000},
- + {0x23b7, 0x4000},
- + {0x23b8, 0x6000},
- + {0x23bb, 0x2000},
- + {0x23c4, 0x2800},
- + {0x23df, 0x4210},
- + {0x23e0, 0x1374},
- + {0x23e4, 0x5677},
- + {0x2304, 0x0332},
- + {0x230c, 0x0680},
- + {0x230d, 0x0200},
- + {0x23e7, 0x0e00},
- + {0x23e8, 0x1200},
- + {0x23e9, 0x6000},
- + {0x23ea, 0x7800},
- + {0x2310, 0x0008},
- +
- + {0x22fb, 0x0000},
- +};
- +#define RT5671_DSP_EZAEC_NUM \
- + (sizeof(rt5671_dsp_ezaec) / sizeof(rt5671_dsp_ezaec[0]))
- +
- +static unsigned short rt5671_dsp_48k_sto[][2] = {
- + /* (48Khz-stereo-recording) [with NS] */
- + {0x22c1, 0x1025},
- + {0x22c2, 0x1026},
- + {0x2278, 0xe4e4},
- + {0x22f8, 0x8004},
- + {0x22ea, 0x0001},
- + {0x230c, 0x0100},
- + {0x230d, 0x0100},
- + {0x2301, 0x0010},
- + {0x2303, 0x0200},
- + {0x2304, 0x0000},
- + {0x2305, 0x0000},
- + {0x2388, 0x6800},
- + {0x238b, 0x3000},
- + {0x238c, 0x3000},
- + {0x23c4, 0x3000},
- +
- + {0x22fb, 0x0000},
- +};
- +#define RT5671_DSP_48K_STO_REC_NUM \
- + (sizeof(rt5671_dsp_48k_sto) / sizeof(rt5671_dsp_48k_sto[0]))
- +
- +/**
- + * rt5671_dsp_done - Wait until DSP is ready.
- + * @codec: SoC Audio Codec device.
- + *
- + * To check voice DSP status and confirm it's ready for next work.
- + *
- + * Returns 0 for success or negative error code.
- + */
- +static int rt5671_dsp_done(struct snd_soc_codec *codec)
- +{
- + unsigned int count = 0, dsp_val;
- +
- + dsp_val = snd_soc_read(codec, RT5671_DSP_CTRL1);
- + while (dsp_val & RT5671_DSP_BUSY_MASK) {
- + if (count > 10)
- + return -EBUSY;
- + dsp_val = snd_soc_read(codec, RT5671_DSP_CTRL1);
- + count++;
- + }
- +
- + return 0;
- +}
- +
- +/**
- + * rt5671_dsp_write - Write DSP register.
- + * @codec: SoC audio codec device.
- + * @param: DSP parameters.
- + *
- + * Modify voice DSP register for sound effect. The DSP can be controlled
- + * through DSP command format (0xfc), addr (0xc4), data (0xc5) and cmd (0xc6)
- + * register. It has to wait until the DSP is ready.
- + *
- + * Returns 0 for success or negative error code.
- + */
- +int rt5671_dsp_write(struct snd_soc_codec *codec,
- + unsigned int addr, unsigned int data)
- +{
- + unsigned int dsp_val;
- + int ret;
- +
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL2, addr);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
- + goto err;
- + }
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL3, data);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP data reg: %d\n", ret);
- + goto err;
- + }
- + dsp_val = RT5671_DSP_I2C_AL_16 | RT5671_DSP_DL_2 |
- + RT5671_DSP_CMD_MW | DSP_CLK_RATE | RT5671_DSP_CMD_EN;
- +
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL1, dsp_val);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
- + goto err;
- + }
- + ret = rt5671_dsp_done(codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "DSP is busy: %d\n", ret);
- + goto err;
- + }
- +
- + return 0;
- +
- +err:
- + return ret;
- +}
- +
- +/**
- + * rt5671_dsp_read - Read DSP register.
- + * @codec: SoC audio codec device.
- + * @reg: DSP register index.
- + *
- + * Read DSP setting value from voice DSP. The DSP can be controlled
- + * through DSP addr (0xc4), data (0xc5) and cmd (0xc6) register. Each
- + * command has to wait until the DSP is ready.
- + *
- + * Returns DSP register value or negative error code.
- + */
- +unsigned int rt5671_dsp_read(
- + struct snd_soc_codec *codec, unsigned int reg)
- +{
- + unsigned int value;
- + unsigned int dsp_val;
- + int ret = 0;
- +
- + ret = rt5671_dsp_done(codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "DSP is busy: %d\n", ret);
- + goto err;
- + }
- +
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL2, reg);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
- + goto err;
- + }
- + dsp_val = RT5671_DSP_I2C_AL_16 | RT5671_DSP_DL_0 | RT5671_DSP_RW_MASK |
- + RT5671_DSP_CMD_MR | DSP_CLK_RATE | RT5671_DSP_CMD_EN;
- +
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL1, dsp_val);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
- + goto err;
- + }
- +
- + ret = rt5671_dsp_done(codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "DSP is busy: %d\n", ret);
- + goto err;
- + }
- +
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL2, 0x26);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
- + goto err;
- + }
- + dsp_val = RT5671_DSP_DL_1 | RT5671_DSP_CMD_RR | RT5671_DSP_RW_MASK |
- + DSP_CLK_RATE | RT5671_DSP_CMD_EN;
- +
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL1, dsp_val);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
- + goto err;
- + }
- +
- + ret = rt5671_dsp_done(codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "DSP is busy: %d\n", ret);
- + goto err;
- + }
- +
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL2, 0x25);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
- + goto err;
- + }
- +
- + dsp_val = RT5671_DSP_DL_1 | RT5671_DSP_CMD_RR | RT5671_DSP_RW_MASK |
- + DSP_CLK_RATE | RT5671_DSP_CMD_EN;
- +
- + ret = snd_soc_write(codec, RT5671_DSP_CTRL1, dsp_val);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
- + goto err;
- + }
- +
- + ret = rt5671_dsp_done(codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "DSP is busy: %d\n", ret);
- + goto err;
- + }
- +
- + ret = snd_soc_read(codec, RT5671_DSP_CTRL5);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret);
- + goto err;
- + }
- +
- + value = ret;
- + return value;
- +
- +err:
- + return ret;
- +}
- +
- +static int rt5671_dsp_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + ucontrol->value.integer.value[0] = rt5671->dsp_sw;
- +
- + return 0;
- +}
- +
- +static int rt5671_dsp_snd_effect(struct snd_soc_codec *codec);
- +
- +static int rt5671_dsp_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + if (rt5671->dsp_sw != ucontrol->value.integer.value[0]) {
- + rt5671->dsp_sw = ucontrol->value.integer.value[0];
- + if (snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_I2S_DSP)
- + rt5671_dsp_snd_effect(codec);
- + }
- +
- + return 0;
- +}
- +
- +/* DSP Path Control 1 */
- +static const char * const rt5671_src_rxdp_mode[] = {
- + "Normal", "Divided by 2", "Divided by 3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_src_rxdp_enum, RT5671_DSP_PATH1,
- + RT5671_RXDP_SRC_SFT, rt5671_src_rxdp_mode);
- +
- +static const char * const rt5671_src_txdp_mode[] = {
- + "Normal", "Multiplied by 2", "Multiplied by 3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_src_txdp_enum, RT5671_DSP_PATH1,
- + RT5671_TXDP_SRC_SFT, rt5671_src_txdp_mode);
- +
- +/* Sound Effect */
- +static const char *rt5671_dsp_mode[] = {
- + "Disable",
- + "BuiltinMic AEC-2mic",
- + "BuiltinMic ezAEC-2mic",
- + "BuiltinMic AEC-1mic",
- + "BuiltinMic ezAEC-1mic",
- + "BuiltinMic 48K-stereo+FFP+NS",
- + "HeadsetMic AEC",
- + "HeadsetMic 48K-stereo+FFP+NS",
- + "BtMic AEC",
- + "BtMic ezAEC",
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_dsp_enum, 0, 0,
- + rt5671_dsp_mode);
- +
- +static const struct snd_kcontrol_new rt5671_dsp_snd_controls[] = {
- + SOC_ENUM("RxDP SRC Switch", rt5671_src_rxdp_enum),
- + SOC_ENUM("TxDP SRC Switch", rt5671_src_txdp_enum),
- + /* AEC */
- + SOC_ENUM_EXT("DSP Function Switch", rt5671_dsp_enum,
- + rt5671_dsp_get, rt5671_dsp_put),
- +};
- +
- +/**
- + * rt5671_dsp_conf - Set DSP basic setting.
- + *
- + * @codec: SoC audio codec device.
- + *
- + * Set parameters of basic setting to DSP.
- + *
- + * Returns 0 for success or negative error code.
- + */
- +static int rt5671_dsp_conf(struct snd_soc_codec *codec)
- +{
- + int ret, i;
- +
- + for (i = 0; i < RT5671_DSP_INIT_NUM; i++) {
- + ret = rt5671_dsp_write(codec, rt5671_dsp_init[i][0],
- + rt5671_dsp_init[i][1]);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to config Dsp: %d\n", ret);
- + goto conf_err;
- + }
- + }
- +
- + return 0;
- +
- +conf_err:
- +
- + return ret;
- +}
- +
- +/**
- + * rt5671_dsp_rate - Set DSP rate setting.
- + *
- + * @codec: SoC audio codec device.
- + * @sys_clk: System clock.
- + * @srate: Sampling rate.
- + *
- + * Set parameters of system clock and sampling rate to DSP.
- + *
- + * Returns 0 for success or negative error code.
- + */
- +static int rt5671_dsp_rate(struct snd_soc_codec *codec, int sys_clk,
- + int srate)
- +{
- + int ret, i, tab_num;
- + unsigned short (*rate_tab)[2];
- +
- + dev_dbg(codec->dev, "rt5671_dsp_rate sys:%d srate:%d\n", sys_clk, srate);
- +
- + switch (sys_clk) {
- + case 4096000:
- + rate_tab = rt5671_dsp_4096000;
- + tab_num = RT5671_DSP_4096000_NUM;
- + break;
- + case 11289600:
- + rate_tab = rt5671_dsp_11289600;
- + tab_num = RT5671_DSP_11289600_NUM;
- + break;
- + case 12288000:
- + rate_tab = rt5671_dsp_12288000;
- + tab_num = RT5671_DSP_12288000_NUM;
- + break;
- + case 24576000:
- + rate_tab = rt5671_dsp_24576000;
- + tab_num = RT5671_DSP_24576000_NUM;
- + break;
- + default:
- + return -EINVAL;
- + break;
- + }
- +
- + for (i = 0; i < tab_num; i++) {
- + ret = rt5671_dsp_write(codec, rate_tab[i][0], rate_tab[i][1]);
- + if (ret < 0)
- + goto rate_err;
- + }
- +
- + switch (srate) {
- + case 8000:
- + rate_tab = rt5671_dsp_8;
- + tab_num = RT5671_DSP_8_NUM;
- + break;
- + case 16000:
- + rate_tab = rt5671_dsp_16;
- + tab_num = RT5671_DSP_16_NUM;
- + break;
- + case 24000:
- + rate_tab = rt5671_dsp_24;
- + tab_num = RT5671_DSP_24_NUM;
- + break;
- + case 44100:
- + case 48000:
- + rate_tab = rt5671_dsp_48_441;
- + tab_num = RT5671_DSP_48_441_NUM;
- + break;
- + default:
- + return -EINVAL;
- + break;
- + }
- +
- + for (i = 0; i < tab_num; i++) {
- + ret = rt5671_dsp_write(codec, rate_tab[i][0], rate_tab[i][1]);
- + if (ret < 0)
- + goto rate_err;
- + }
- +
- + return 0;
- +
- +rate_err:
- +
- + dev_err(codec->dev, "Fail to set rate parameters: %d\n", ret);
- + return ret;
- +}
- +
- +/**
- + * rt5671_dsp_do_patch - Write DSP patch code.
- + *
- + * @codec: SoC audio codec device.
- + *
- + * Write patch codes to DSP.
- + *
- + * mode:
- + * 0: Init
- + * 1: Reaset
- + *
- + * Returns 0 for success or negative error code.
- + */
- +static int rt5671_dsp_do_patch(struct snd_soc_codec *codec, int mode)
- +{
- + int ret, i;
- +
- + switch (mode) {
- + case 0: /*Init*/
- + for (i = 0; i < RT5671_DSP_INIT_PATCH_NUM; i++) {
- + ret = snd_soc_write(codec, rt5671_dsp_init_patch_code[i][0],
- + rt5671_dsp_init_patch_code[i][1]);
- + if (ret < 0)
- + goto patch_err;
- +
- +
- + if (rt5671_dsp_init_patch_code[i][0] == 0xe0) {
- + ret = rt5671_dsp_done(codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "DSP is busy: %d\n", ret);
- + goto patch_err;
- + }
- + }
- + }
- + break;
- + case 1: /*Reset*/
- + for (i = 0; i < RT5671_DSP_RESET_PATCH_NUM; i++) {
- + ret = snd_soc_write(codec, rt5671_dsp_reset_patch_code[i][0],
- + rt5671_dsp_reset_patch_code[i][1]);
- + if (ret < 0)
- + goto patch_err;
- +
- +
- + if (rt5671_dsp_reset_patch_code[i][0] == 0xe0) {
- + ret = rt5671_dsp_done(codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "DSP is busy: %d\n", ret);
- + goto patch_err;
- + }
- + }
- + }
- + break;
- + default:
- + pr_err("Invalid patch mode %d\n", mode);
- + ret = -EINVAL;
- + break;
- + }
- +
- + return 0;
- +
- +patch_err:
- + dev_err(codec->dev, "DSP patch error: %d\n", ret);
- + return ret;
- +}
- +
- +static int rt5671_dsp_set_data_source(struct snd_soc_codec *codec, int src)
- +{
- + int ret, i;
- +
- + pr_debug("%s: src=%d\n", __func__, src);
- + for (i = src * RT5671_DSP_TDM_SRC_PAR_NUM;
- + i < (src + 1) * RT5671_DSP_TDM_SRC_PAR_NUM; i++) {
- + ret = rt5671_dsp_write(codec,
- + rt5671_dsp_data_src[i][0], rt5671_dsp_data_src[i][1]);
- + if (ret < 0)
- + goto src_err;
- + }
- +
- + return 0;
- +
- +src_err:
- +
- + dev_err(codec->dev, "Fail to set tdm source %d parameters: %d\n",
- + src, ret);
- + return ret;
- +}
- +
- +/**
- + * rt5671_dsp_set_mode - Set DSP mode parameters.
- + *
- + * @codec: SoC audio codec device.
- + * @mode: DSP mode.
- + *
- + * Set parameters of mode to DSP.
- + * There are three modes which includes " mic AEC + NS + FENS",
- + * "HFBF" and "Far-field pickup".
- + *
- + * Returns 0 for success or negative error code.
- + */
- +static int rt5671_dsp_set_mode(struct snd_soc_codec *codec, int mode)
- +{
- + int ret, i, tab_num;
- + unsigned short (*mode_tab)[2];
- +
- + switch (mode) {
- + case RT5671_DSP_ONE_MIC_AEC:
- + dev_info(codec->dev, "One Mic AEC\n");
- + mode_tab = rt5671_dsp_1mic_aec;
- + tab_num = RT5671_DSP_1MIC_AEC_NUM;
- + break;
- + case RT5671_DSP_ONE_MIC_EZAEC:
- + dev_info(codec->dev, "One Mic ezAEC\n");
- + mode_tab = rt5671_dsp_1mic_ezaec;
- + tab_num = RT5671_DSP_1MIC_EZAEC_NUM;
- + break;
- + case RT5671_DSP_TWO_MIC_AEC:
- + dev_info(codec->dev, "Two Mic AEC\n");
- + mode_tab = rt5671_dsp_aec;
- + tab_num = RT5671_DSP_AEC_NUM;
- + break;
- + case RT5671_DSP_TWO_MIC_EZAEC:
- + dev_info(codec->dev, "Two Mic ezAEC\n");
- + mode_tab = rt5671_dsp_ezaec;
- + tab_num = RT5671_DSP_EZAEC_NUM;
- + break;
- + case RT5671_DSP_BT_AEC:
- + dev_info(codec->dev, "BT AEC\n");
- + mode_tab = rt5671_dsp_bt_aec;
- + tab_num = RT5671_DSP_BT_AEC_NUM;
- + break;
- + case RT5671_DSP_BT_EZAEC:
- + dev_info(codec->dev, "BT ezAEC\n");
- + mode_tab = rt5671_dsp_bt_ezaec;
- + tab_num = RT5671_DSP_BT_EZAEC_NUM;
- + break;
- + case RT5671_DSP_HS_AEC:
- + dev_info(codec->dev, "HS AEC\n");
- + mode_tab = rt5671_dsp_hs_aec;
- + tab_num = RT5671_DSP_HS_AEC_NUM;
- + break;
- +
- + case RT5671_DSP_BM_48K_STO_FFP_NS:
- + case RT5671_DSP_HS_48K_STO_FFP_NS:
- + dev_info(codec->dev, "48K_STO_REC\n");
- + mode_tab = rt5671_dsp_48k_sto;
- + tab_num = RT5671_DSP_48K_STO_REC_NUM;
- + break;
- +
- + case RT5671_DSP_DIS:
- + default:
- + dev_info(codec->dev, "Disable\n");
- + return 0;
- + }
- +
- + for (i = 0; i < tab_num; i++) {
- + ret = rt5671_dsp_write(codec, mode_tab[i][0], mode_tab[i][1]);
- + if (ret < 0)
- + goto mode_err;
- + }
- +
- + return 0;
- +
- +mode_err:
- +
- + dev_err(codec->dev, "Fail to set mode %d parameters: %d\n", mode, ret);
- + return ret;
- +}
- +
- +/**
- + * rt5671_dsp_snd_effect - Set DSP sound effect.
- + *
- + * Set parameters of sound effect to DSP.
- + *
- + * Returns 0 for success or negative error code.
- + */
- +static int rt5671_dsp_snd_effect(struct snd_soc_codec *codec)
- +{
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- + int ret, val, rate, src = 0;
- +
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL1, RT5671_RST_DSP,
- + RT5671_RST_DSP);
- + mdelay(5);
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL1, RT5671_RST_DSP, 0);
- +
- + mdelay(10);
- +
- + if (!rt5671->dsp_inited) {
- + ret = rt5671_dsp_do_patch(codec, 0);
- + if (ret < 0)
- + goto effect_err;
- + rt5671->dsp_inited = true;
- + }
- +
- + ret = rt5671_dsp_do_patch(codec, 1);
- + if (ret < 0)
- + goto effect_err;
- +
- + switch (rt5671->dsp_sw) {
- + case RT5671_DSP_BM_48K_STO_FFP_NS:
- + case RT5671_DSP_HS_48K_STO_FFP_NS:
- + rate = 48000;
- + break;
- + default:
- + rate = 16000;
- + break;
- + }
- +
- + ret = rt5671_dsp_rate(codec, 12288000, rate);
- + if (ret < 0)
- + goto effect_err;
- +
- + /*read MX-2d [3:2] to decide TDM source*/
- + /*currently, support slot 0/1 and 2/3 only*/
- + val = snd_soc_read(codec, RT5671_DSP_PATH1) & 0xc;
- + if (val == 0x4) /*slot 2/3*/
- + src = 1;
- +
- + ret = rt5671_dsp_set_data_source(codec, src);
- + if (ret < 0)
- + goto effect_err;
- +
- + ret = rt5671_dsp_conf(codec);
- + if (ret < 0)
- + goto effect_err;
- +
- + ret = rt5671_dsp_set_mode(codec, rt5671->dsp_sw);
- + if (ret < 0)
- + goto effect_err;
- +
- + return 0;
- +
- +effect_err:
- +
- + return ret;
- +}
- +
- +static int rt5671_dsp_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *k, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMD:
- + dev_dbg(codec->dev, "%s(): PMD\n", __func__);
- + rt5671_dsp_write(codec, 0x22f9, 1);
- + break;
- +
- + case SND_SOC_DAPM_POST_PMU:
- + dev_dbg(codec->dev, "%s(): PMU\n", __func__);
- + rt5671_dsp_snd_effect(codec);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static const struct snd_soc_dapm_widget rt5671_dsp_dapm_widgets[] = {
- + SND_SOC_DAPM_SUPPLY_S("Voice DSP", 1, SND_SOC_NOPM,
- + 0, 0, rt5671_dsp_event,
- + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_PGA("DSP Downstream", SND_SOC_NOPM,
- + 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("DSP Upstream", SND_SOC_NOPM,
- + 0, 0, NULL, 0),
- +};
- +
- +static const struct snd_soc_dapm_route rt5671_dsp_dapm_routes[] = {
- + {"DSP Downstream", NULL, "Voice DSP"},
- + {"DSP Downstream", NULL, "RxDP Mux"},
- + {"DSP Upstream", NULL, "Voice DSP"},
- + {"DSP Upstream", NULL, "TDM Data Mux"},
- + {"DSP DL Mux", "DSP", "DSP Downstream"},
- + {"DSP UL Mux", "DSP", "DSP Upstream"},
- +};
- +
- +/**
- + * rt5671_dsp_show - Dump DSP registers.
- + * @dev: codec device.
- + * @attr: device attribute.
- + * @buf: buffer for display.
- + *
- + * To show non-zero values of all DSP registers.
- + *
- + * Returns buffer length.
- + */
- +static ssize_t rt5671_dsp_show(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- + unsigned short (*rt5671_dsp_tab)[2];
- + unsigned int val;
- + int cnt = 0, i, tab_num;
- +
- + /*Check if DSP bypass*/
- + if (!(snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_I2S_DSP) ||
- + snd_soc_read(codec, RT5671_DSP_PATH1) & RT5671_DSP_UL_SEL) {
- + cnt += sprintf(buf, "[ DSP Bypass ]\n");
- + goto dsp_done;
- + }
- +
- + switch (rt5671->dsp_sw) {
- + case RT5671_DSP_ONE_MIC_AEC:
- + cnt += sprintf(buf, "[ DSP 'One Mic AEC' ]\n");
- + rt5671_dsp_tab = rt5671_dsp_1mic_aec;
- + tab_num = RT5671_DSP_1MIC_AEC_NUM;
- + break;
- + case RT5671_DSP_ONE_MIC_EZAEC:
- + cnt += sprintf(buf, "[ DSP 'One Mic ezAEC' ]\n");
- + rt5671_dsp_tab = rt5671_dsp_1mic_ezaec;
- + tab_num = RT5671_DSP_1MIC_EZAEC_NUM;
- + break;
- + case RT5671_DSP_TWO_MIC_AEC:
- + cnt += sprintf(buf, "[ DSP 'Two Mic AEC' ]\n");
- + rt5671_dsp_tab = rt5671_dsp_aec;
- + tab_num = RT5671_DSP_AEC_NUM;
- + break;
- + case RT5671_DSP_TWO_MIC_EZAEC:
- + cnt += sprintf(buf, "[ DSP 'Two Mic ezAEC' ]\n");
- + rt5671_dsp_tab = rt5671_dsp_ezaec;
- + tab_num = RT5671_DSP_EZAEC_NUM;
- + break;
- + case RT5671_DSP_BT_EZAEC:
- + cnt += sprintf(buf, "[ DSP 'BT ezAEC' ]\n");
- + rt5671_dsp_tab = rt5671_dsp_bt_ezaec;
- + tab_num = RT5671_DSP_BT_EZAEC_NUM;
- + break;
- + case RT5671_DSP_BT_AEC:
- + cnt += sprintf(buf, "[ DSP 'BT AEC' ]\n");
- + rt5671_dsp_tab = rt5671_dsp_bt_aec;
- + tab_num = RT5671_DSP_BT_AEC_NUM;
- + break;
- + case RT5671_DSP_HS_AEC:
- + cnt += sprintf(buf, "[ DSP 'HS AEC' ]\n");
- + rt5671_dsp_tab = rt5671_dsp_hs_aec;
- + tab_num = RT5671_DSP_HS_AEC_NUM;
- + break;
- +
- + case RT5671_DSP_BM_48K_STO_FFP_NS:
- + case RT5671_DSP_HS_48K_STO_FFP_NS:
- + cnt += sprintf(buf, "[ DSP '48K_STO_REC' ]\n");
- + rt5671_dsp_tab = rt5671_dsp_48k_sto;
- + tab_num = RT5671_DSP_48K_STO_REC_NUM;
- + break;
- +
- + case RT5671_DSP_DIS:
- + default:
- + cnt += sprintf(buf, " DSP Disabled\n");
- + goto dsp_done;
- + }
- +
- + for (i = 0; i < tab_num; i++) {
- + if (cnt + RT5671_DSP_REG_DISP_LEN >= PAGE_SIZE)
- + break;
- + val = rt5671_dsp_read(codec, rt5671_dsp_tab[i][0]);
- + if (!val)
- + continue;
- + cnt += snprintf(buf + cnt, RT5671_DSP_REG_DISP_LEN,
- + "%04x: %04x\n", rt5671_dsp_tab[i][0], val);
- + }
- +
- + rt5671_dsp_tab = rt5671_dsp_init;
- + tab_num = RT5671_DSP_INIT_NUM;
- + for (i = 0; i < tab_num; i++) {
- + if (cnt + RT5671_DSP_REG_DISP_LEN >= PAGE_SIZE)
- + break;
- + val = rt5671_dsp_read(codec, rt5671_dsp_tab[i][0]);
- + if (!val)
- + continue;
- + cnt += snprintf(buf + cnt, RT5671_DSP_REG_DISP_LEN,
- + "%04x: %04x\n",
- + rt5671_dsp_tab[i][0], val);
- + }
- +
- + rt5671_dsp_tab = rt5671_dsp_data_src;
- + tab_num = RT5671_DSP_TDM_SRC_PAR_NUM;
- + for (i = 0; i < tab_num; i++) {
- + if (cnt + RT5671_DSP_REG_DISP_LEN >= PAGE_SIZE)
- + break;
- + val = rt5671_dsp_read(codec, rt5671_dsp_tab[i][0]);
- + if (!val)
- + continue;
- + cnt += snprintf(buf + cnt, RT5671_DSP_REG_DISP_LEN,
- + "%04x: %04x\n",
- + rt5671_dsp_tab[i][0], val);
- + }
- +
- + tab_num = RT5671_DSP_RATE_NUM;
- + for (i = 0; i < tab_num; i++) {
- + if (cnt + RT5671_DSP_REG_DISP_LEN >= PAGE_SIZE)
- + break;
- + val = rt5671_dsp_read(codec, rt5671_dsp_rate_par[i]);
- + cnt += snprintf(buf + cnt, RT5671_DSP_REG_DISP_LEN,
- + "%04x: %04x\n",
- + rt5671_dsp_rate_par[i], val);
- + }
- + if (cnt + RT5671_DSP_REG_DISP_LEN < PAGE_SIZE) {
- + val = rt5671_dsp_read(codec, 0x3fb5);
- + cnt += snprintf(buf + cnt, RT5671_DSP_REG_DISP_LEN,
- + "%04x: %04x\n",
- + 0x3fb5, val);
- + }
- +dsp_done:
- +
- + if (cnt >= PAGE_SIZE)
- + cnt = PAGE_SIZE - 1;
- +
- + return cnt;
- +}
- +
- +static ssize_t dsp_reg_store(struct device *dev,
- + struct device_attribute *attr, const char *buf, size_t count)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- + unsigned int val = 0, addr = 0;
- + int i;
- +
- + pr_debug("register \"%s\" count = %d\n", buf, count);
- +
- + /* address */
- + for (i = 0; i < count; i++)
- + if (*(buf + i) <= '9' && *(buf + i) >= '0')
- + addr = (addr << 4) | (*(buf + i) - '0');
- + else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
- + addr = (addr << 4) | ((*(buf + i) - 'a') + 0xa);
- + else if (*(buf + i) <= 'A' && *(buf + i) >= 'A')
- + addr = (addr << 4) | ((*(buf + i) - 'A') + 0xa);
- + else
- + break;
- +
- + /* Value*/
- + for (i = i + 1; i < count; i++)
- + if (*(buf + i) <= '9' && *(buf + i) >= '0')
- + val = (val << 4) | (*(buf + i) - '0');
- + else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
- + val = (val << 4) | ((*(buf + i) - 'a') + 0xa);
- + else if (*(buf + i) <= 'F' && *(buf + i) >= 'A')
- + val = (val << 4) | ((*(buf + i) - 'A') + 0xa);
- + else
- + break;
- +
- + pr_debug("addr=0x%x val=0x%x\n", addr, val);
- + if (i == count)
- + pr_debug("0x%04x = 0x%04x\n",
- + addr, rt5671_dsp_read(codec, addr));
- + else
- + rt5671_dsp_write(codec, addr, val);
- +
- + return count;
- +}
- +static DEVICE_ATTR(dsp_reg, 0664, rt5671_dsp_show, dsp_reg_store);
- +
- +/**
- + * rt5671_dsp_probe - register DSP for rt5671
- + * @codec: audio codec
- + *
- + * To register DSP function for rt5671.
- + *
- + * Returns 0 for success or negative error code.
- + */
- +int rt5671_dsp_probe(struct snd_soc_codec *codec)
- +{
- + int ret;
- +
- + if (codec == NULL)
- + return -EINVAL;
- +
- + snd_soc_add_codec_controls(codec, rt5671_dsp_snd_controls,
- + ARRAY_SIZE(rt5671_dsp_snd_controls));
- + snd_soc_dapm_new_controls(&codec->dapm, rt5671_dsp_dapm_widgets,
- + ARRAY_SIZE(rt5671_dsp_dapm_widgets));
- + snd_soc_dapm_add_routes(&codec->dapm, rt5671_dsp_dapm_routes,
- + ARRAY_SIZE(rt5671_dsp_dapm_routes));
- +
- + ret = device_create_file(codec->dev, &dev_attr_dsp_reg);
- + if (ret != 0) {
- + dev_err(codec->dev,
- + "Failed to create dsp_reg sysfs files: %d\n", ret);
- + return ret;
- + }
- +
- + return 0;
- +}
- +EXPORT_SYMBOL_GPL(rt5671_dsp_probe);
- +
- +#ifdef RTK_IOCTL
- +int rt5671_dsp_ioctl_common(struct snd_hwdep *hw,
- + struct file *file, unsigned int cmd, unsigned long arg)
- +{
- + struct rt_codec_cmd rt_codec;
- + int *buf;
- + int *p;
- + int ret;
- +
- + struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
- + struct snd_soc_codec *codec = hw->private_data;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
- + dev_err(codec->dev, "copy_from_user faild\n");
- + return -EFAULT;
- + }
- + dev_dbg(codec->dev, "rt_codec.number=%d\n", rt_codec.number);
- + buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
- + if (buf == NULL)
- + return -ENOMEM;
- + if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number))
- + goto err;
- +
- + ret = snd_soc_update_bits(codec, RT5671_PWR_DIG2,
- + RT5671_PWR_I2S_DSP, RT5671_PWR_I2S_DSP);
- + if (ret < 0) {
- + dev_err(codec->dev,
- + "Failed to power up DSP IIS interface: %d\n", ret);
- + goto err;
- + }
- +
- + switch (cmd) {
- + case RT_READ_CODEC_DSP_IOCTL:
- + for (p = buf; p < buf + rt_codec.number / 2; p++)
- + *(p + rt_codec.number / 2) = rt5671_dsp_read(codec, *p);
- + if (copy_to_user(rt_codec.buf, buf,
- + sizeof(*buf) * rt_codec.number))
- + goto err;
- + break;
- +
- + case RT_WRITE_CODEC_DSP_IOCTL:
- + if (codec == NULL) {
- + dev_dbg(codec->dev, "codec is null\n");
- + break;
- + }
- + for (p = buf; p < buf + rt_codec.number / 2; p++)
- + rt5671_dsp_write(codec, *p, *(p + rt_codec.number / 2));
- + break;
- +
- + case RT_GET_CODEC_DSP_MODE_IOCTL:
- + *buf = rt5671->dsp_sw;
- + if (copy_to_user(rt_codec.buf, buf,
- + sizeof(*buf) * rt_codec.number))
- + goto err;
- + break;
- +
- + default:
- + dev_info(codec->dev, "unsported dsp command\n");
- + break;
- + }
- +
- + kfree(buf);
- + return 0;
- +
- +err:
- + kfree(buf);
- + return -EFAULT;
- +}
- +EXPORT_SYMBOL_GPL(rt5671_dsp_ioctl_common);
- +#endif
- +
- +#ifdef CONFIG_PM
- +int rt5671_dsp_suspend(struct snd_soc_codec *codec)
- +{
- + return 0;
- +}
- +EXPORT_SYMBOL_GPL(rt5671_dsp_suspend);
- +
- +int rt5671_dsp_resume(struct snd_soc_codec *codec)
- +{
- + return 0;
- +}
- +EXPORT_SYMBOL_GPL(rt5671_dsp_resume);
- +#endif
- +
- diff --git a/sound/soc/codecs/rt5671-dsp.h b/sound/soc/codecs/rt5671-dsp.h
- new file mode 100644
- index 0000000..d4651b2
- --- /dev/null
- +++ b/sound/soc/codecs/rt5671-dsp.h
- @@ -0,0 +1,82 @@
- +/*
- + * rt5671-dsp.h -- RT5671 ALSA SoC DSP driver
- + *
- + * Copyright 2011 Realtek Microelectronics
- + * Copyright (C) 2016 XiaoMi, Inc.
- + * Author: Johnny Hsu <johnnyhsu@realtek.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#ifndef __RT5671_DSP_H__
- +#define __RT5671_DSP_H__
- +
- +#define RT5671_DSP_CTRL1 0xe0
- +#define RT5671_DSP_CTRL2 0xe1
- +#define RT5671_DSP_CTRL3 0xe2
- +#define RT5671_DSP_CTRL4 0xe3
- +#define RT5671_DSP_CTRL5 0xe4
- +
- +/* DSP Control 1 (0xe0) */
- +#define RT5671_DSP_CMD_MASK (0xff << 8)
- +#define RT5671_DSP_CMD_PE (0x0d << 8) /* Patch Entry */
- +#define RT5671_DSP_CMD_MW (0x3b << 8) /* Memory Write */
- +#define RT5671_DSP_CMD_MR (0x37 << 8) /* Memory Read */
- +#define RT5671_DSP_CMD_RR (0x60 << 8) /* Register Read */
- +#define RT5671_DSP_CMD_RW (0x68 << 8) /* Register Write */
- +#define RT5671_DSP_REG_DATHI (0x26 << 8) /* High Data Addr */
- +#define RT5671_DSP_REG_DATLO (0x25 << 8) /* Low Data Addr */
- +#define RT5671_DSP_CLK_MASK (0x3 << 6)
- +#define RT5671_DSP_CLK_SFT 6
- +#define RT5671_DSP_CLK_768K (0x0 << 6)
- +#define RT5671_DSP_CLK_384K (0x1 << 6)
- +#define RT5671_DSP_CLK_192K (0x2 << 6)
- +#define RT5671_DSP_CLK_96K (0x3 << 6)
- +#define RT5671_DSP_BUSY_MASK (0x1 << 5)
- +#define RT5671_DSP_RW_MASK (0x1 << 4)
- +#define RT5671_DSP_DL_MASK (0x3 << 2)
- +#define RT5671_DSP_DL_0 (0x0 << 2)
- +#define RT5671_DSP_DL_1 (0x1 << 2)
- +#define RT5671_DSP_DL_2 (0x2 << 2)
- +#define RT5671_DSP_DL_3 (0x3 << 2)
- +#define RT5671_DSP_I2C_AL_16 (0x1 << 1)
- +#define RT5671_DSP_CMD_EN (0x1)
- +
- +/* Debug String Length */
- +#define RT5671_DSP_REG_DISP_LEN 25
- +
- +
- +enum {
- + RT5671_DSP_DIS,
- + RT5671_DSP_TWO_MIC_AEC,
- + RT5671_DSP_TWO_MIC_EZAEC,
- + RT5671_DSP_ONE_MIC_AEC,
- + RT5671_DSP_ONE_MIC_EZAEC,
- + RT5671_DSP_BM_48K_STO_FFP_NS,
- + RT5671_DSP_HS_AEC,
- + RT5671_DSP_HS_48K_STO_FFP_NS,
- + RT5671_DSP_BT_AEC,
- + RT5671_DSP_BT_EZAEC,
- +};
- +
- +struct rt5671_dsp_param {
- + u16 cmd_fmt;
- + u16 addr;
- + u16 data;
- + u8 cmd;
- +};
- +
- +int rt5671_dsp_probe(struct snd_soc_codec *codec);
- +int rt5671_dsp_ioctl_common(struct snd_hwdep *hw,
- + struct file *file, unsigned int cmd, unsigned long arg);
- +#ifdef CONFIG_PM
- +int rt5671_dsp_suspend(struct snd_soc_codec *codec);
- +int rt5671_dsp_resume(struct snd_soc_codec *codec);
- +#endif
- +unsigned int rt5671_dsp_read(struct snd_soc_codec *codec, unsigned int reg);
- +int rt5671_dsp_write(struct snd_soc_codec *codec, unsigned int addr, unsigned int data);
- +
- +#endif /* __RT5671_DSP_H__ */
- +
- diff --git a/sound/soc/codecs/rt5671.c b/sound/soc/codecs/rt5671.c
- new file mode 100755
- index 0000000..70655507
- --- /dev/null
- +++ b/sound/soc/codecs/rt5671.c
- @@ -0,0 +1,4513 @@
- +/*
- + * rt5671.c -- RT5671 ALSA SoC audio codec driver
- + *
- + * Copyright 2012 Realtek Semiconductor Corp.
- + * Copyright (C) 2016 XiaoMi, Inc.
- + * Author: Bard Liao <bardliao@realtek.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/module.h>
- +#include <linux/moduleparam.h>
- +#include <linux/init.h>
- +#include <linux/delay.h>
- +#include <linux/pm.h>
- +#include <linux/i2c.h>
- +#include <linux/platform_device.h>
- +#include <linux/spi/spi.h>
- +#include <sound/core.h>
- +#include <sound/pcm.h>
- +#include <sound/pcm_params.h>
- +#include <sound/jack.h>
- +#include <sound/soc.h>
- +#include <sound/soc-dapm.h>
- +#include <sound/initval.h>
- +#include <sound/rt5670.h>
- +#include <sound/tlv.h>
- +
- +#define RTK_IOCTL
- +#ifdef RTK_IOCTL
- +#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
- +#include "rt_codec_ioctl.h"
- +#include "rt5671_ioctl.h"
- +#endif
- +#endif
- +
- +#include "rt5671.h"
- +#include "rt5671-dsp.h"
- +
- +static int pmu_depop_time = 80;
- +module_param(pmu_depop_time, int, 0644);
- +
- +static int hp_amp_time = 20;
- +module_param(hp_amp_time, int, 0644);
- +
- +#define RT5671_DET_EXT_MIC 0
- +/*#define USE_INT_CLK*/
- +/*#define ALC_DRC_FUNC*/
- +/*#define USE_TDM*/
- +/*#define NVIDIA_DALMORE*/
- +
- +#define VERSION "0.0.5 alsa 1.0.25"
- +
- +struct rt5671_init_reg {
- + u8 reg;
- + u16 val;
- +};
- +
- +static struct rt5671_init_reg init_list[] = {
- + { RT5671_GEN_CTRL3 , 0x0084 },
- + { RT5671_IL_CMD1 , 0x0000 },
- + { RT5671_IL_CMD2 , 0x0010 }, /* set Inline Command Window */
- + { RT5671_IL_CMD3 , 0x0014 },
- + { RT5671_PRIV_INDEX , 0x0014 },
- + { RT5671_PRIV_DATA , 0x9a8a },
- + { RT5671_PRIV_INDEX , 0x003d },
- + { RT5671_PRIV_DATA , 0x3e40 },
- + { RT5671_PRIV_INDEX , 0x0038 },
- + { RT5671_PRIV_DATA , 0x1fe1 },
- + { RT5671_TDM_CTRL_3 , 0x0101 }, /* enable IF1_DAC2 */
- + { RT5671_CHARGE_PUMP , 0x0c00 },
- + /* for stereo SPK */
- + { RT5671_GPIO_CTRL2 , 0x8000 },
- + { RT5671_GPIO_CTRL3 , 0x0d00 },
- + /* Mute STO1 ADC for depop */
- + { RT5671_STO1_ADC_DIG_VOL, 0xafaf },
- + { RT5671_ASRC_4 , 0x8020 },
- +};
- +#define RT5671_INIT_REG_LEN ARRAY_SIZE(init_list)
- +
- +#ifdef ALC_DRC_FUNC
- +static struct rt5671_init_reg alc_drc_list[] = {
- + { RT5671_ALC_DRC_CTRL1 , 0x0000 },
- + { RT5671_ALC_DRC_CTRL2 , 0x0000 },
- + { RT5671_ALC_CTRL_2 , 0x0000 },
- + { RT5671_ALC_CTRL_3 , 0x0000 },
- + { RT5671_ALC_CTRL_4 , 0x0000 },
- + { RT5671_ALC_CTRL_1 , 0x0000 },
- +};
- +#define RT5671_ALC_DRC_REG_LEN ARRAY_SIZE(alc_drc_list)
- +#endif
- +
- +static int rt5671_reg_init(struct snd_soc_codec *codec)
- +{
- + int i;
- +
- + for (i = 0; i < RT5671_INIT_REG_LEN; i++)
- + snd_soc_write(codec, init_list[i].reg, init_list[i].val);
- +#ifdef ALC_DRC_FUNC
- + for (i = 0; i < RT5671_ALC_DRC_REG_LEN; i++)
- + snd_soc_write(codec, alc_drc_list[i].reg, alc_drc_list[i].val);
- +#endif
- +
- + return 0;
- +}
- +
- +static int rt5671_index_sync(struct snd_soc_codec *codec)
- +{
- + int i;
- +
- + for (i = 0; i < RT5671_INIT_REG_LEN; i++)
- + if (RT5671_PRIV_INDEX == init_list[i].reg ||
- + RT5671_PRIV_DATA == init_list[i].reg)
- + snd_soc_write(codec, init_list[i].reg,
- + init_list[i].val);
- + return 0;
- +}
- +
- +static const u16 rt5671_reg[RT5671_VENDOR_ID2 + 1] = {
- + [RT5671_HP_VOL] = 0x8888,
- + [RT5671_LOUT1] = 0x8888,
- + [RT5671_MONO_OUT] = 0x8800,
- + [RT5671_CJ_CTRL1] = 0x0001,
- + [RT5671_CJ_CTRL2] = 0x0827,
- + [RT5671_IN2] = 0x0008,
- + [RT5671_INL1_INR1_VOL] = 0x0808,
- + [RT5671_SIDETONE_CTRL] = 0x018b,
- + [RT5671_DAC1_DIG_VOL] = 0xafaf,
- + [RT5671_DAC2_DIG_VOL] = 0xafaf,
- + [RT5671_DAC_CTRL] = 0x0011,
- + [RT5671_STO1_ADC_DIG_VOL] = 0x2f2f,
- + [RT5671_MONO_ADC_DIG_VOL] = 0x2f2f,
- + [RT5671_STO2_ADC_DIG_VOL] = 0x2f2f,
- + [RT5671_STO2_ADC_MIXER] = 0x7860,
- + [RT5671_STO1_ADC_MIXER] = 0x7860,
- + [RT5671_MONO_ADC_MIXER] = 0x7871,
- + [RT5671_AD_DA_MIXER] = 0x8080,
- + [RT5671_STO_DAC_MIXER] = 0x5656,
- + [RT5671_MONO_DAC_MIXER] = 0x5454,
- + [RT5671_DIG_MIXER] = 0xaaa0,
- + [RT5671_DSP_PATH2] = 0x2f2f,
- + [RT5671_DIG_INF1_DATA] = 0x1002,
- + [RT5671_PDM_OUT_CTRL] = 0x5f00,
- + [RT5671_REC_L2_MIXER] = 0x007f,
- + [RT5671_REC_R2_MIXER] = 0x007f,
- + [RT5671_REC_MONO2_MIXER] = 0x001f,
- + [RT5671_HPO_MIXER] = 0xe00f,
- + [RT5671_MONO_MIXER] = 0x5380,
- + [RT5671_OUT_L1_MIXER] = 0x0073,
- + [RT5671_OUT_R1_MIXER] = 0x00d3,
- + [RT5671_LOUT_MIXER] = 0xf0f0,
- + [RT5671_PWR_DIG2] = 0x0001,
- + [RT5671_PWR_ANLG1] = 0x00c3,
- + [RT5671_I2S4_SDP] = 0x8000,
- + [RT5671_I2S1_SDP] = 0x8000,
- + [RT5671_I2S2_SDP] = 0x8000,
- + [RT5671_I2S3_SDP] = 0x8000,
- + [RT5671_ADDA_CLK1] = 0x7770,
- + [RT5671_ADDA_HPF] = 0x0e00,
- + [RT5671_DMIC_CTRL1] = 0x1505,
- + [RT5671_DMIC_CTRL2] = 0x0015,
- + [RT5671_TDM_CTRL_1] = 0x0c00,
- + [RT5671_TDM_CTRL_2] = 0x4000,
- + [RT5671_TDM_CTRL_3] = 0x0123,
- + [RT5671_DSP_CLK] = 0x1100,
- + [RT5671_ASRC_5] = 0x0003,
- + [RT5671_DEPOP_M1] = 0x0004,
- + [RT5671_DEPOP_M2] = 0x1100,
- + [RT5671_DEPOP_M3] = 0x0646,
- + [RT5671_CHARGE_PUMP] = 0x0c06,
- + [RT5671_VAD_CTRL1] = 0x2184,
- + [RT5671_VAD_CTRL2] = 0x010a,
- + [RT5671_VAD_CTRL3] = 0x0aea,
- + [RT5671_VAD_CTRL4] = 0x000c,
- + [RT5671_VAD_CTRL5] = 0x0400,
- + [RT5671_ADC_EQ_CTRL1] = 0x7000,
- + [RT5671_EQ_CTRL1] = 0x7000,
- + [RT5671_ALC_DRC_CTRL2] = 0x001f,
- + [RT5671_ALC_CTRL_1] = 0x220c,
- + [RT5671_ALC_CTRL_2] = 0x1f00,
- + [RT5671_BASE_BACK] = 0x1813,
- + [RT5671_MP3_PLUS1] = 0x0690,
- + [RT5671_MP3_PLUS2] = 0x1c17,
- + [RT5671_ADJ_HPF1] = 0xa220,
- + [RT5671_HP_CALIB_AMP_DET] = 0x0400,
- + [RT5671_SV_ZCD1] = 0x0809,
- + [RT5671_IL_CMD1] = 0x0001,
- + [RT5671_IL_CMD2] = 0x0049,
- + [RT5671_IL_CMD3] = 0x0024,
- + [RT5671_DRC_HL_CTRL1] = 0x8000,
- + [RT5671_ADC_MONO_HP_CTRL1] = 0xa200,
- + [RT5671_ADC_STO2_HP_CTRL1] = 0xa200,
- + [RT5671_GEN_CTRL1] = 0x8010,
- + [RT5671_GEN_CTRL2] = 0x0033,
- + [RT5671_GEN_CTRL3] = 0x0080,
- +};
- +
- +static int rt5671_reset(struct snd_soc_codec *codec)
- +{
- + return snd_soc_write(codec, RT5671_RESET, 0);
- +}
- +
- +/**
- + * rt5671_index_write - Write private register.
- + * @codec: SoC audio codec device.
- + * @reg: Private register index.
- + * @value: Private register Data.
- + *
- + * Modify private register for advanced setting. It can be written through
- + * private index (0x6a) and data (0x6c) register.
- + *
- + * Returns 0 for success or negative error code.
- + */
- +static int rt5671_index_write(struct snd_soc_codec *codec,
- + unsigned int reg, unsigned int value)
- +{
- + int ret;
- +
- + ret = snd_soc_write(codec, RT5671_PRIV_INDEX, reg);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
- + goto err;
- + }
- + ret = snd_soc_write(codec, RT5671_PRIV_DATA, value);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to set private value: %d\n", ret);
- + goto err;
- + }
- + return 0;
- +
- +err:
- + return ret;
- +}
- +
- +/**
- + * rt5671_index_read - Read private register.
- + * @codec: SoC audio codec device.
- + * @reg: Private register index.
- + *
- + * Read advanced setting from private register. It can be read through
- + * private index (0x6a) and data (0x6c) register.
- + *
- + * Returns private register value or negative error code.
- + */
- +static unsigned int rt5671_index_read(
- + struct snd_soc_codec *codec, unsigned int reg)
- +{
- + int ret;
- +
- + ret = snd_soc_write(codec, RT5671_PRIV_INDEX, reg);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
- + return ret;
- + }
- + return snd_soc_read(codec, RT5671_PRIV_DATA);
- +}
- +
- +/**
- + * rt5671_index_update_bits - update private register bits
- + * @codec: audio codec
- + * @reg: Private register index.
- + * @mask: register mask
- + * @value: new value
- + *
- + * Writes new register value.
- + *
- + * Returns 1 for change, 0 for no change, or negative error code.
- + */
- +static int rt5671_index_update_bits(struct snd_soc_codec *codec,
- + unsigned int reg, unsigned int mask, unsigned int value)
- +{
- + unsigned int old, new;
- + int change, ret;
- +
- + ret = rt5671_index_read(codec, reg);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to read private reg: %d\n", ret);
- + goto err;
- + }
- +
- + old = ret;
- + new = (old & ~mask) | (value & mask);
- + change = old != new;
- + if (change) {
- + ret = rt5671_index_write(codec, reg, new);
- + if (ret < 0) {
- + dev_err(codec->dev,
- + "Failed to write private reg: %d\n", ret);
- + goto err;
- + }
- + }
- + return change;
- +
- +err:
- + return ret;
- +}
- +
- +static int rt5671_volatile_register(
- + struct snd_soc_codec *codec, unsigned int reg)
- +{
- + switch (reg) {
- + case RT5671_RESET:
- + case RT5671_PDM_DATA_CTRL1:
- + case RT5671_PDM1_DATA_CTRL4:
- + case RT5671_PDM2_DATA_CTRL4:
- + case RT5671_PRIV_DATA:
- + case RT5671_CJ_CTRL1:
- + case RT5671_CJ_CTRL2:
- + case RT5671_CJ_CTRL3:
- + case RT5671_A_JD_CTRL1:
- + case RT5671_A_JD_CTRL2:
- + case RT5671_VAD_CTRL5:
- + case RT5671_ADC_EQ_CTRL1:
- + case RT5671_EQ_CTRL1:
- + case RT5671_ALC_CTRL_1:
- + case RT5671_IRQ_CTRL1:
- + case RT5671_IRQ_CTRL2:
- + case RT5671_IRQ_CTRL3:
- + case RT5671_IL_CMD1:
- + case RT5671_DSP_CTRL1:
- + case RT5671_DSP_CTRL2:
- + case RT5671_DSP_CTRL3:
- + case RT5671_DSP_CTRL4:
- + case RT5671_DSP_CTRL5:
- + case RT5671_JD_CTRL3:
- + case RT5671_VENDOR_ID:
- + case RT5671_VENDOR_ID1:
- + case RT5671_VENDOR_ID2:
- + return 1;
- + default:
- + return 0;
- + }
- +}
- +
- +static int rt5671_readable_register(
- + struct snd_soc_codec *codec, unsigned int reg)
- +{
- + switch (reg) {
- + case RT5671_RESET:
- + case RT5671_HP_VOL:
- + case RT5671_LOUT1:
- + case RT5671_MONO_OUT:
- + case RT5671_CJ_CTRL1:
- + case RT5671_CJ_CTRL2:
- + case RT5671_CJ_CTRL3:
- + case RT5671_IN2:
- + case RT5671_IN3_IN4:
- + case RT5671_INL1_INR1_VOL:
- + case RT5671_SIDETONE_CTRL:
- + case RT5671_DAC1_DIG_VOL:
- + case RT5671_DAC2_DIG_VOL:
- + case RT5671_DAC_CTRL:
- + case RT5671_STO1_ADC_DIG_VOL:
- + case RT5671_MONO_ADC_DIG_VOL:
- + case RT5671_STO2_ADC_DIG_VOL:
- + case RT5671_ADC_BST_VOL1:
- + case RT5671_ADC_BST_VOL2:
- + case RT5671_STO2_ADC_MIXER:
- + case RT5671_STO1_ADC_MIXER:
- + case RT5671_MONO_ADC_MIXER:
- + case RT5671_AD_DA_MIXER:
- + case RT5671_STO_DAC_MIXER:
- + case RT5671_MONO_DAC_MIXER:
- + case RT5671_DIG_MIXER:
- + case RT5671_DSP_PATH1:
- + case RT5671_DSP_PATH2:
- + case RT5671_DIG_INF1_DATA:
- + case RT5671_DIG_INF2_DATA:
- + case RT5671_PDM_OUT_CTRL:
- + case RT5671_PDM_DATA_CTRL1:
- + case RT5671_PDM1_DATA_CTRL2:
- + case RT5671_PDM1_DATA_CTRL3:
- + case RT5671_PDM1_DATA_CTRL4:
- + case RT5671_PDM2_DATA_CTRL2:
- + case RT5671_PDM2_DATA_CTRL3:
- + case RT5671_PDM2_DATA_CTRL4:
- + case RT5671_REC_L1_MIXER:
- + case RT5671_REC_L2_MIXER:
- + case RT5671_REC_R1_MIXER:
- + case RT5671_REC_R2_MIXER:
- + case RT5671_REC_MONO1_MIXER:
- + case RT5671_REC_MONO2_MIXER:
- + case RT5671_HPO_MIXER:
- + case RT5671_MONO_MIXER:
- + case RT5671_OUT_L1_MIXER:
- + case RT5671_OUT_R1_MIXER:
- + case RT5671_LOUT_MIXER:
- + case RT5671_PWR_DIG1:
- + case RT5671_PWR_DIG2:
- + case RT5671_PWR_ANLG1:
- + case RT5671_PWR_ANLG2:
- + case RT5671_PWR_MIXER:
- + case RT5671_PWR_VOL:
- + case RT5671_PRIV_INDEX:
- + case RT5671_PRIV_DATA:
- + case RT5671_I2S4_SDP:
- + case RT5671_I2S1_SDP:
- + case RT5671_I2S2_SDP:
- + case RT5671_I2S3_SDP:
- + case RT5671_ADDA_CLK1:
- + case RT5671_ADDA_HPF:
- + case RT5671_DMIC_CTRL1:
- + case RT5671_DMIC_CTRL2:
- + case RT5671_TDM_CTRL_1:
- + case RT5671_TDM_CTRL_2:
- + case RT5671_TDM_CTRL_3:
- + case RT5671_DSP_CLK:
- + case RT5671_GLB_CLK:
- + case RT5671_PLL_CTRL1:
- + case RT5671_PLL_CTRL2:
- + case RT5671_ASRC_1:
- + case RT5671_ASRC_2:
- + case RT5671_ASRC_3:
- + case RT5671_ASRC_4:
- + case RT5671_ASRC_5:
- + case RT5671_ASRC_I2S1:
- + case RT5671_ASRC_I2S2:
- + case RT5671_ASRC_I2S3:
- + case RT5671_DEPOP_M1:
- + case RT5671_DEPOP_M2:
- + case RT5671_DEPOP_M3:
- + case RT5671_CHARGE_PUMP:
- + case RT5671_MICBIAS:
- + case RT5671_A_JD_CTRL1:
- + case RT5671_A_JD_CTRL2:
- + case RT5671_VAD_CTRL1:
- + case RT5671_VAD_CTRL2:
- + case RT5671_VAD_CTRL3:
- + case RT5671_VAD_CTRL4:
- + case RT5671_VAD_CTRL5:
- + case RT5671_ADC_EQ_CTRL1:
- + case RT5671_ADC_EQ_CTRL2:
- + case RT5671_EQ_CTRL1:
- + case RT5671_EQ_CTRL2:
- + case RT5671_ALC_DRC_CTRL1:
- + case RT5671_ALC_DRC_CTRL2:
- + case RT5671_ALC_CTRL_1:
- + case RT5671_ALC_CTRL_2:
- + case RT5671_ALC_CTRL_3:
- + case RT5671_ALC_CTRL_4:
- + case RT5671_JD_CTRL1:
- + case RT5671_JD_CTRL2:
- + case RT5671_IRQ_CTRL1:
- + case RT5671_IRQ_CTRL2:
- + case RT5671_IRQ_CTRL3:
- + case RT5671_GPIO_CTRL1:
- + case RT5671_GPIO_CTRL2:
- + case RT5671_GPIO_CTRL3:
- + case RT5671_SCRABBLE_FUN:
- + case RT5671_SCRABBLE_CTRL:
- + case RT5671_BASE_BACK:
- + case RT5671_MP3_PLUS1:
- + case RT5671_MP3_PLUS2:
- + case RT5671_ADJ_HPF1:
- + case RT5671_ADJ_HPF2:
- + case RT5671_HP_CALIB_AMP_DET:
- + case RT5671_SV_ZCD1:
- + case RT5671_SV_ZCD2:
- + case RT5671_IL_CMD1:
- + case RT5671_IL_CMD2:
- + case RT5671_IL_CMD3:
- + case RT5671_DRC_HL_CTRL1:
- + case RT5671_DRC_HL_CTRL2:
- + case RT5671_ADC_MONO_HP_CTRL1:
- + case RT5671_ADC_MONO_HP_CTRL2:
- + case RT5671_ADC_STO2_HP_CTRL1:
- + case RT5671_ADC_STO2_HP_CTRL2:
- + case RT5671_JD_CTRL3:
- + case RT5671_JD_CTRL4:
- + case RT5671_GEN_CTRL1:
- + case RT5671_DSP_CTRL1:
- + case RT5671_DSP_CTRL2:
- + case RT5671_DSP_CTRL3:
- + case RT5671_DSP_CTRL4:
- + case RT5671_DSP_CTRL5:
- + case RT5671_GEN_CTRL2:
- + case RT5671_GEN_CTRL3:
- + case RT5671_VENDOR_ID:
- + case RT5671_VENDOR_ID1:
- + case RT5671_VENDOR_ID2:
- + return 1;
- + default:
- + return 0;
- + }
- +}
- +
- +/**
- + * rt5671_headset_detect - Detect headset.
- + * @codec: SoC audio codec device.
- + * @jack_insert: Jack insert or not.
- + *
- + * Detect whether is headset or not when jack inserted.
- + *
- + * Returns detect status.
- + */
- +
- +int rt5671_headset_detect(struct snd_soc_codec *codec, int jack_insert)
- +{
- + int val;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + if (jack_insert) {
- + snd_soc_dapm_force_enable_pin(&codec->dapm, "micbias1");
- + snd_soc_dapm_force_enable_pin(&codec->dapm, "Mic Det Power");
- + snd_soc_dapm_sync(&codec->dapm);
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL2,
- + 0x0400, 0x0400);
- + snd_soc_update_bits(codec, RT5671_CJ_CTRL2,
- + RT5671_CBJ_DET_MODE, RT5671_CBJ_DET_MODE);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_JD1, RT5671_PWR_JD1);
- + snd_soc_update_bits(codec, RT5671_CJ_CTRL1, 0x20, 0x20);
- + msleep(300);
- + val = snd_soc_read(codec, RT5671_JD_CTRL3) & 0x7000;
- + if (val == 0x7000) {
- + rt5671->jack_type = SND_JACK_HEADSET;
- +
- + snd_soc_update_bits(codec, RT5671_CJ_CTRL1, 0x0180, 0x0180);
- + snd_soc_update_bits(codec, RT5671_JD_CTRL3, 0x00c0, 0x00c0);
- +
- + snd_soc_update_bits(codec, RT5671_IRQ_CTRL3, 0x8, 0x8);
- + snd_soc_update_bits(codec, RT5671_IL_CMD1, 0x40, 0x40);
- + snd_soc_read(codec, RT5671_IL_CMD1);
- + } else {
- + rt5671->jack_type = SND_JACK_HEADPHONE;
- + snd_soc_dapm_disable_pin(&codec->dapm, "micbias1");
- + snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
- + snd_soc_dapm_sync(&codec->dapm);
- + }
- + } else {
- + snd_soc_update_bits(codec, RT5671_IL_CMD1, 0x40, 0x0);
- + snd_soc_update_bits(codec, RT5671_IRQ_CTRL3, 0x8, 0x0);
- + snd_soc_update_bits(codec, RT5671_CJ_CTRL1, 0x0180, 0x0);
- + snd_soc_update_bits(codec, RT5671_JD_CTRL3, 0x00c0, 0x0);
- + rt5671->jack_type = 0;
- + snd_soc_dapm_disable_pin(&codec->dapm, "micbias1");
- + snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
- + snd_soc_dapm_sync(&codec->dapm);
- + }
- +
- + pr_debug("jack_type = %d\n", rt5671->jack_type);
- + return rt5671->jack_type;
- +}
- +EXPORT_SYMBOL(rt5671_headset_detect);
- +
- +int rt5671_button_detect(struct snd_soc_codec *codec)
- +{
- + int btn_type, val;
- +
- + val = snd_soc_read(codec, RT5671_IL_CMD1);
- + btn_type = val & 0xff80;
- + snd_soc_write(codec, RT5671_IL_CMD1, val);
- + if (btn_type != 0) {
- + msleep(20);
- + val = snd_soc_read(codec, RT5671_IL_CMD1);
- + snd_soc_write(codec, RT5671_IL_CMD1, val);
- + }
- + return btn_type;
- +}
- +EXPORT_SYMBOL(rt5671_button_detect);
- +
- +int rt5671_check_interrupt_event(struct snd_soc_codec *codec, int *data)
- +{
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- + int val, event_type;
- +
- + if (snd_soc_read(codec, 0xbe) & 0x0080)
- + return RT5671_VAD_EVENT;
- +
- + if (1 == rt5671->pdata.jd_mode) /* 2 port */
- + val = snd_soc_read(codec, RT5671_A_JD_CTRL1) & 0x0070;
- + else
- + val = snd_soc_read(codec, RT5671_A_JD_CTRL1) & 0x0020;
- +
- + *data = 0;
- + switch (val) {
- + case 0x30: /* 2 port */
- + case 0x0: /* 1 port or 2 port */
- + /* jack insert */
- + if (rt5671->jack_type == 0) {
- + rt5671_headset_detect(codec, 1);
- + *data = rt5671->jack_type;
- + return RT5671_J_IN_EVENT;
- + }
- + event_type = 0;
- + if (snd_soc_read(codec, RT5671_IRQ_CTRL3) & 0x4) {
- + /* button event */
- + event_type = RT5671_BTN_EVENT;
- + *data = rt5671_button_detect(codec);
- + }
- + if (*data == 0) {
- + event_type = RT5671_BR_EVENT;
- + }
- + return (event_type == 0 ? RT5671_UN_EVENT : event_type);
- + case 0x70: /* 2 port */
- + case 0x10: /* 2 port */
- + case 0x20: /* 1 port */
- + snd_soc_update_bits(codec, RT5671_IRQ_CTRL3, 0x1, 0x0);
- + rt5671_headset_detect(codec, 0);
- + return RT5671_J_OUT_EVENT;
- + default:
- + return RT5671_UN_EVENT;
- + }
- +
- + return RT5671_UN_EVENT;
- +
- +}
- +EXPORT_SYMBOL(rt5671_check_interrupt_event);
- +
- +static int rt5671_irq_detection(struct snd_soc_jack_gpio *gpio)
- +{
- + struct snd_soc_jack *jack = gpio->jack;
- + struct snd_soc_codec *codec = jack->codec;
- + int status, jack_type = jack->status;
- + int data;
- +
- + pr_debug("Enter:%s", __func__);
- + status = rt5671_check_interrupt_event(codec, &data);
- + switch (status) {
- + case RT5671_J_IN_EVENT:
- + pr_debug("Jack insert intr");
- + jack_type = data;
- + pr_debug("Jack type detected:%d", jack_type);
- + gpio->debounce_time = 25; /* for push button and jack out */
- + break;
- + case RT5671_J_OUT_EVENT:
- + pr_debug("Jack remove intr");
- + gpio->debounce_time = 150; /* for jack in */
- + jack_type = 0;
- + break;
- + case RT5671_BR_EVENT:
- + pr_debug("BR event received");
- + jack_type = SND_JACK_HEADSET;
- + break;
- + case RT5671_BTN_EVENT:
- + pr_debug("BP event received");
- + jack_type = SND_JACK_HEADSET;
- + pr_debug("button code 0x%04x\n", data);
- + switch (data) {
- + case 0x2000: /* up */
- + jack_type |= SND_JACK_BTN_1;
- + break;
- + case 0x0400: /* center */
- + jack_type |= SND_JACK_BTN_0;
- + break;
- + case 0x0080: /* down */
- + jack_type |= SND_JACK_BTN_2;
- + break;
- + default:
- + dev_err(codec->dev, "Unexpected button code 0x%04x\n", data);
- + break;
- + }
- + break;
- + case RT5671_UN_EVENT:
- + pr_debug("Reported invalid/RT5671_UN_EVENT");
- + break;
- + default:
- + dev_err(codec->dev, "Error: Invalid event");
- + }
- + return jack_type;
- +}
- +
- +static const DECLARE_TLV_DB_SCALE(drc_limiter_tlv, 0, 375, 0);
- +static const DECLARE_TLV_DB_SCALE(drc_pre_tlv, 0, 750, 0);
- +static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
- +static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
- +static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
- +static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
- +static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
- +
- +/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
- +static unsigned int bst_tlv[] = {
- + TLV_DB_RANGE_HEAD(7),
- + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
- + 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
- + 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
- + 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
- + 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
- + 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
- + 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
- +};
- +
- +/* Interface data select */
- +static const char * const rt5671_data_select[] = {
- + "Normal", "Swap", "left copy to right", "right copy to left"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_if2_dac_enum, RT5671_DIG_INF1_DATA,
- + RT5671_IF2_DAC_SEL_SFT, rt5671_data_select);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_if2_adc_enum, RT5671_DIG_INF1_DATA,
- + RT5671_IF2_ADC_SEL_SFT, rt5671_data_select);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_if3_dac_enum, RT5671_DIG_INF1_DATA,
- + RT5671_IF3_DAC_SEL_SFT, rt5671_data_select);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_if3_adc_enum, RT5671_DIG_INF1_DATA,
- + RT5671_IF3_ADC_SEL_SFT, rt5671_data_select);
- +
- +static const char * const rt5671_asrc_clk_source[] = {
- + "clk_sysy_div_out", "clk_i2s1_track", "clk_i2s2_track",
- + "clk_i2s3_track", "clk_i2s4_track", "clk_sys2", "clk_sys3",
- + "clk_sys4", "clk_sys5"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_da_sto_asrc_enum, RT5671_ASRC_2,
- + 12, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_da_monol_asrc_enum, RT5671_ASRC_2,
- + 8, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_da_monor_asrc_enum, RT5671_ASRC_2,
- + 4, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_ad_sto1_asrc_enum, RT5671_ASRC_2,
- + 0, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_up_filter_asrc_enum, RT5671_ASRC_3,
- + 12, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_down_filter_asrc_enum, RT5671_ASRC_3,
- + 8, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_ad_monol_asrc_enum, RT5671_ASRC_3,
- + 4, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_ad_monor_asrc_enum, RT5671_ASRC_3,
- + 0, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_ad_sto2_asrc_enum, RT5671_ASRC_5,
- + 12, rt5671_asrc_clk_source);
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_dsp_asrc_enum, RT5671_DSP_CLK,
- + 0, rt5671_asrc_clk_source);
- +
- +static int rt5671_ad_sto1_asrc_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- +
- + switch (ucontrol->value.integer.value[0]) {
- + case 1 ... 4: /*enable*/
- + if (snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_ADC_S1F)
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x8, 0x8);
- + break;
- + default: /*disable*/
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x8, 0);
- + break;
- + }
- +
- + return snd_soc_put_enum_double(kcontrol, ucontrol);
- +}
- +
- +static int rt5671_ad_sto2_asrc_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- +
- + switch (ucontrol->value.integer.value[0]) {
- + case 1 ... 4: /*enable*/
- + if (snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_ADC_S2F)
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x4, 0x4);
- + break;
- + default: /*disable*/
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x4, 0);
- + break;
- + }
- +
- + return snd_soc_put_enum_double(kcontrol, ucontrol);
- +}
- +
- +static int rt5671_ad_monol_asrc_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- +
- + switch (ucontrol->value.integer.value[0]) {
- + case 1 ... 4: /*enable*/
- + if (snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_ADC_MF_L)
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x2, 0x2);
- + break;
- + default: /*disable*/
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x2, 0);
- + break;
- + }
- +
- + return snd_soc_put_enum_double(kcontrol, ucontrol);
- +}
- +
- +static int rt5671_ad_monor_asrc_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- +
- + switch (ucontrol->value.integer.value[0]) {
- + case 1 ... 4: /*enable*/
- + if (snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_ADC_MF_R)
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x1, 0x1);
- + break;
- + default: /*disable*/
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x1, 0);
- + break;
- + }
- +
- + return snd_soc_put_enum_double(kcontrol, ucontrol);
- +}
- +
- +static int rt5671_da_monol_asrc_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- +
- + switch (ucontrol->value.integer.value[0]) {
- + case 1 ... 4: /*enable*/
- + if (snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_DAC_MF_L)
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x200, 0x200);
- + break;
- + default: /*disable*/
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x200, 0);
- + break;
- + }
- +
- + return snd_soc_put_enum_double(kcontrol, ucontrol);
- +}
- +
- +static int rt5671_da_monor_asrc_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- +
- + switch (ucontrol->value.integer.value[0]) {
- + case 1 ... 4: /*enable*/
- + if (snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_DAC_MF_R)
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x100, 0x100);
- + break;
- + default: /*disable*/
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x100, 0);
- + break;
- + }
- +
- + return snd_soc_put_enum_double(kcontrol, ucontrol);
- +}
- +
- +static int rt5671_da_sto_asrc_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- +
- + switch (ucontrol->value.integer.value[0]) {
- + case 1 ... 4: /*enable*/
- + if (snd_soc_read(codec, RT5671_PWR_DIG2) & RT5671_PWR_DAC_S1F)
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x400, 0x400);
- + break;
- + default: /*disable*/
- + snd_soc_update_bits(codec, RT5671_ASRC_1, 0x400, 0);
- + break;
- + }
- +
- + return snd_soc_put_enum_double(kcontrol, ucontrol);
- +}
- +
- +static const char *rt5671_push_btn_mode[] = {
- + "Disable", "read"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_push_btn_enum, 0, 0, rt5671_push_btn_mode);
- +
- +static int rt5671_push_btn_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + ucontrol->value.integer.value[0] = 0;
- +
- + return 0;
- +}
- +
- +static int rt5671_push_btn_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- +
- + printk(KERN_INFO "ret=0x%x\n", rt5671_button_detect(codec));
- +
- + return 0;
- +}
- +
- +static const char *rt5671_jack_type_mode[] = {
- + "Disable", "read"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_jack_type_enum, 0, 0, rt5671_jack_type_mode);
- +
- +static int rt5671_jack_type_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + ucontrol->value.integer.value[0] = 0;
- +
- + return 0;
- +}
- +
- +static int rt5671_jack_type_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + int jack_insert = ucontrol->value.integer.value[0];
- +
- + printk(KERN_INFO "ret=0x%x\n", rt5671_headset_detect(codec, jack_insert));
- +
- + return 0;
- +}
- +
- +static const char *rt5671_drc_mode[] = {
- + "Disable", "Enable"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(rt5671_drc_enum, 0, 0, rt5671_drc_mode);
- +
- +static int rt5671_drc_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + ucontrol->value.integer.value[0] = rt5671->drc_mode;
- +
- + return 0;
- +}
- +
- +static int rt5671_drc_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + rt5671->drc_mode = ucontrol->value.integer.value[0];
- +
- + return 0;
- +}
- +
- +static const struct snd_kcontrol_new rt5671_snd_controls[] = {
- + /* Headphone Output Volume */
- + SOC_DOUBLE_TLV("HP Playback Volume", RT5671_HP_VOL,
- + RT5671_L_VOL_SFT, RT5671_R_VOL_SFT, 39, 1, out_vol_tlv),
- + /* OUTPUT Control */
- + SOC_SINGLE("OUT Channel Switch", RT5671_LOUT1,
- + RT5671_VOL_L_SFT, 1, 0),
- + SOC_DOUBLE_TLV("OUT Playback Volume", RT5671_LOUT1,
- + RT5671_L_VOL_SFT, RT5671_R_VOL_SFT, 39, 1, out_vol_tlv),
- + /* DAC Digital Volume */
- + SOC_DOUBLE("DAC2 Playback Switch", RT5671_DAC_CTRL,
- + RT5671_M_DAC_L2_VOL_SFT, RT5671_M_DAC_R2_VOL_SFT, 1, 1),
- + SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5671_DAC1_DIG_VOL,
- + RT5671_L_VOL_SFT, RT5671_R_VOL_SFT,
- + 175, 0, dac_vol_tlv),
- + SOC_DOUBLE_TLV("DAC2 Playback Volume", RT5671_DAC2_DIG_VOL,
- + RT5671_L_VOL_SFT, RT5671_R_VOL_SFT,
- + 175, 0, dac_vol_tlv),
- + /* DRC Gain */
- + SOC_SINGLE_TLV("DRC Pre Boost", RT5671_ALC_DRC_CTRL2,
- + 6, 0x27, 0, drc_pre_tlv),
- + SOC_SINGLE_TLV("DRC Limiter Th", RT5671_ALC_CTRL_4,
- + 0, 0x3f, 0, drc_limiter_tlv),
- + /* IN1/IN2 Control */
- + SOC_SINGLE_TLV("IN1 Boost", RT5671_CJ_CTRL1,
- + RT5671_CBJ_BST1_SFT, 8, 0, bst_tlv),
- + SOC_SINGLE_TLV("IN2 Boost", RT5671_IN2,
- + RT5671_BST_SFT2, 8, 0, bst_tlv),
- + SOC_SINGLE_TLV("IN3 Boost", RT5671_IN3_IN4,
- + RT5671_BST_SFT1, 8, 0, bst_tlv),
- + SOC_SINGLE_TLV("IN4 Boost", RT5671_IN3_IN4,
- + RT5671_BST_SFT2, 8, 0, bst_tlv),
- + /* INL/INR Volume Control */
- + SOC_DOUBLE_TLV("IN Capture Volume", RT5671_INL1_INR1_VOL,
- + RT5671_INL_VOL_SFT, RT5671_INR_VOL_SFT,
- + 31, 1, in_vol_tlv),
- + /* ADC Digital Volume Control */
- + SOC_DOUBLE_TLV("ADC Capture Volume", RT5671_STO1_ADC_DIG_VOL,
- + RT5671_L_VOL_SFT, RT5671_R_VOL_SFT,
- + 127, 0, adc_vol_tlv),
- +
- + SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5671_MONO_ADC_DIG_VOL,
- + RT5671_L_VOL_SFT, RT5671_R_VOL_SFT,
- + 127, 0, adc_vol_tlv),
- +
- + SOC_DOUBLE_TLV("TxDP Capture Volume", RT5671_DSP_PATH2,
- + RT5671_L_VOL_SFT, RT5671_R_VOL_SFT,
- + 127, 0, adc_vol_tlv),
- +
- + /* ADC Boost Volume Control */
- + SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5671_ADC_BST_VOL1,
- + RT5671_STO1_ADC_L_BST_SFT, RT5671_STO1_ADC_R_BST_SFT,
- + 3, 0, adc_bst_tlv),
- +
- + SOC_DOUBLE_TLV("STO2 ADC Boost Gain", RT5671_ADC_BST_VOL1,
- + RT5671_STO2_ADC_L_BST_SFT, RT5671_STO2_ADC_R_BST_SFT,
- + 3, 0, adc_bst_tlv),
- +
- + SOC_ENUM("ADC IF2 Data Switch", rt5671_if2_adc_enum),
- + SOC_ENUM("DAC IF2 Data Switch", rt5671_if2_dac_enum),
- + SOC_ENUM("ADC IF3 Data Switch", rt5671_if3_adc_enum),
- + SOC_ENUM("DAC IF3 Data Switch", rt5671_if3_dac_enum),
- +
- + SOC_ENUM_EXT("DA STO ASRC Switch", rt5671_da_sto_asrc_enum,
- + snd_soc_get_enum_double, rt5671_da_sto_asrc_put),
- + SOC_ENUM_EXT("DA MONOL ASRC Switch", rt5671_da_monol_asrc_enum,
- + snd_soc_get_enum_double, rt5671_da_monol_asrc_put),
- + SOC_ENUM_EXT("DA MONOR ASRC Switch", rt5671_da_monor_asrc_enum,
- + snd_soc_get_enum_double, rt5671_da_monor_asrc_put),
- + SOC_ENUM_EXT("AD STO1 ASRC Switch", rt5671_ad_sto1_asrc_enum,
- + snd_soc_get_enum_double, rt5671_ad_sto1_asrc_put),
- + SOC_ENUM_EXT("AD MONOL ASRC Switch", rt5671_ad_monol_asrc_enum,
- + snd_soc_get_enum_double, rt5671_ad_monol_asrc_put),
- + SOC_ENUM_EXT("AD MONOR ASRC Switch", rt5671_ad_monor_asrc_enum,
- + snd_soc_get_enum_double, rt5671_ad_monor_asrc_put),
- + SOC_ENUM("UP ASRC Switch", rt5671_up_filter_asrc_enum),
- + SOC_ENUM("DOWN ASRC Switch", rt5671_down_filter_asrc_enum),
- + SOC_ENUM_EXT("AD STO2 ASRC Switch", rt5671_ad_sto2_asrc_enum,
- + snd_soc_get_enum_double, rt5671_ad_sto2_asrc_put),
- + SOC_ENUM("DSP ASRC Switch", rt5671_dsp_asrc_enum),
- +
- + SOC_ENUM_EXT("DRC Switch", rt5671_drc_enum,
- + rt5671_drc_get, rt5671_drc_put),
- +
- + SOC_ENUM_EXT("push button", rt5671_push_btn_enum,
- + rt5671_push_btn_get, rt5671_push_btn_put),
- + SOC_ENUM_EXT("jack type", rt5671_jack_type_enum,
- + rt5671_jack_type_get, rt5671_jack_type_put),
- +};
- +
- +/**
- + * set_dmic_clk - Set parameter of dmic.
- + *
- + * @w: DAPM widget.
- + * @kcontrol: The kcontrol of this widget.
- + * @event: Event id.
- + *
- + * Choose dmic clock between 1MHz and 3MHz.
- + * It is better for clock to approximate 3MHz.
- + */
- +static int set_dmic_clk(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- + int div[] = {2, 3, 4, 6, 8, 12}, idx = -EINVAL, i;
- + int rate, red, bound, temp;
- +
- + rate = rt5671->lrck[rt5671->aif_pu] << 8;
- + red = 2000000 * 12;
- + for (i = 0; i < ARRAY_SIZE(div); i++) {
- + bound = div[i] * 2000000;
- + if (rate > bound)
- + continue;
- + temp = bound - rate;
- + if (temp < red) {
- + red = temp;
- + idx = i;
- + }
- + }
- +
- + if (idx < 0)
- + dev_err(codec->dev, "Failed to set DMIC clock\n");
- + else
- + snd_soc_update_bits(codec, RT5671_DMIC_CTRL1,
- + RT5671_DMIC_CLK_MASK, idx << RT5671_DMIC_CLK_SFT);
- + return idx;
- +}
- +
- +static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
- + struct snd_soc_dapm_widget *sink)
- +{
- + struct snd_soc_codec *codec = source->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + return rt5671->sysclk_src == RT5671_SCLK_S_PLL1;
- +}
- +
- +static int is_using_asrc(struct snd_soc_codec *codec,
- + unsigned int reg, unsigned int shift)
- +{
- + unsigned int val;
- +
- + val = (snd_soc_read(codec, reg) >> shift) & 0xf;
- + pr_debug("%s: val = 0x%x\n", __func__, val);
- + switch (val) {
- + case 1:
- + case 2:
- + case 3:
- + case 4:
- + return 1;
- + default:
- + return 0;
- + }
- +}
- +
- +static int check_adc_sto1_asrc_source(struct snd_soc_dapm_widget *source,
- + struct snd_soc_dapm_widget *sink)
- +{
- + struct snd_soc_codec *codec = source->codec;
- +
- + return is_using_asrc(codec, RT5671_ASRC_2, 0);
- +}
- +
- +static int check_adc_sto2_asrc_source(struct snd_soc_dapm_widget *source,
- + struct snd_soc_dapm_widget *sink)
- +{
- + struct snd_soc_codec *codec = source->codec;
- +
- + return is_using_asrc(codec, RT5671_ASRC_5, 12);
- +}
- +
- +static int check_adc_monol_asrc_source(struct snd_soc_dapm_widget *source,
- + struct snd_soc_dapm_widget *sink)
- +{
- + struct snd_soc_codec *codec = source->codec;
- +
- + return is_using_asrc(codec, RT5671_ASRC_3, 4);
- +}
- +
- +static int check_adc_monor_asrc_source(struct snd_soc_dapm_widget *source,
- + struct snd_soc_dapm_widget *sink)
- +{
- + struct snd_soc_codec *codec = source->codec;
- +
- + return is_using_asrc(codec, RT5671_ASRC_3, 0);
- +}
- +
- +static int check_dac_sto_asrc_source(struct snd_soc_dapm_widget *source,
- + struct snd_soc_dapm_widget *sink)
- +{
- + struct snd_soc_codec *codec = source->codec;
- +
- + return is_using_asrc(codec, RT5671_ASRC_2, 12);
- +}
- +
- +static int check_dac_monol_asrc_source(struct snd_soc_dapm_widget *source,
- + struct snd_soc_dapm_widget *sink)
- +{
- + struct snd_soc_codec *codec = source->codec;
- +
- + return is_using_asrc(codec, RT5671_ASRC_2, 8);
- +}
- +
- +static int check_dac_monor_asrc_source(struct snd_soc_dapm_widget *source,
- + struct snd_soc_dapm_widget *sink)
- +{
- + struct snd_soc_codec *codec = source->codec;
- +
- + return is_using_asrc(codec, RT5671_ASRC_2, 4);
- +}
- +
- +/* Digital Mixer */
- +static const struct snd_kcontrol_new rt5671_sto1_adc_l_mix[] = {
- + SOC_DAPM_SINGLE("ADC1 Switch", RT5671_STO1_ADC_MIXER,
- + RT5671_M_ADC_L1_SFT, 1, 1),
- + SOC_DAPM_SINGLE("ADC2 Switch", RT5671_STO1_ADC_MIXER,
- + RT5671_M_ADC_L2_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_sto1_adc_r_mix[] = {
- + SOC_DAPM_SINGLE("ADC1 Switch", RT5671_STO1_ADC_MIXER,
- + RT5671_M_ADC_R1_SFT, 1, 1),
- + SOC_DAPM_SINGLE("ADC2 Switch", RT5671_STO1_ADC_MIXER,
- + RT5671_M_ADC_R2_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_sto2_adc_l_mix[] = {
- + SOC_DAPM_SINGLE("ADC1 Switch", RT5671_STO2_ADC_MIXER,
- + RT5671_M_ADC_L1_SFT, 1, 1),
- + SOC_DAPM_SINGLE("ADC2 Switch", RT5671_STO2_ADC_MIXER,
- + RT5671_M_ADC_L2_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_sto2_adc_r_mix[] = {
- + SOC_DAPM_SINGLE("ADC1 Switch", RT5671_STO2_ADC_MIXER,
- + RT5671_M_ADC_R1_SFT, 1, 1),
- + SOC_DAPM_SINGLE("ADC2 Switch", RT5671_STO2_ADC_MIXER,
- + RT5671_M_ADC_R2_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_mono_adc_l_mix[] = {
- + SOC_DAPM_SINGLE("ADC1 Switch", RT5671_MONO_ADC_MIXER,
- + RT5671_M_MONO_ADC_L1_SFT, 1, 1),
- + SOC_DAPM_SINGLE("ADC2 Switch", RT5671_MONO_ADC_MIXER,
- + RT5671_M_MONO_ADC_L2_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_mono_adc_r_mix[] = {
- + SOC_DAPM_SINGLE("ADC1 Switch", RT5671_MONO_ADC_MIXER,
- + RT5671_M_MONO_ADC_R1_SFT, 1, 1),
- + SOC_DAPM_SINGLE("ADC2 Switch", RT5671_MONO_ADC_MIXER,
- + RT5671_M_MONO_ADC_R2_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_dac_l_mix[] = {
- + SOC_DAPM_SINGLE("Stereo ADC Switch", RT5671_AD_DA_MIXER,
- + RT5671_M_ADCMIX_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC1 Switch", RT5671_AD_DA_MIXER,
- + RT5671_M_DAC1_L_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_dac_r_mix[] = {
- + SOC_DAPM_SINGLE("Stereo ADC Switch", RT5671_AD_DA_MIXER,
- + RT5671_M_ADCMIX_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC1 Switch", RT5671_AD_DA_MIXER,
- + RT5671_M_DAC1_R_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_sto_dac_l_mix[] = {
- + SOC_DAPM_SINGLE("DAC L1 Switch", RT5671_STO_DAC_MIXER,
- + RT5671_M_DAC_L1_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L2 Switch", RT5671_STO_DAC_MIXER,
- + RT5671_M_DAC_L2_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R1 Switch", RT5671_STO_DAC_MIXER,
- + RT5671_M_DAC_R1_STO_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("ANC Switch", RT5671_STO_DAC_MIXER,
- + RT5671_M_ANC_DAC_L_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_sto_dac_r_mix[] = {
- + SOC_DAPM_SINGLE("DAC R1 Switch", RT5671_STO_DAC_MIXER,
- + RT5671_M_DAC_R1_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R2 Switch", RT5671_STO_DAC_MIXER,
- + RT5671_M_DAC_R2_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L1 Switch", RT5671_STO_DAC_MIXER,
- + RT5671_M_DAC_L1_STO_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("ANC Switch", RT5671_STO_DAC_MIXER,
- + RT5671_M_ANC_DAC_R_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_mono_dac_l_mix[] = {
- + SOC_DAPM_SINGLE("DAC L1 Switch", RT5671_MONO_DAC_MIXER,
- + RT5671_M_DAC_L1_MONO_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L2 Switch", RT5671_MONO_DAC_MIXER,
- + RT5671_M_DAC_L2_MONO_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R2 Switch", RT5671_MONO_DAC_MIXER,
- + RT5671_M_DAC_R2_MONO_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("Sidetone Switch", RT5671_SIDETONE_CTRL,
- + RT5671_M_ST_DACL2_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_mono_dac_r_mix[] = {
- + SOC_DAPM_SINGLE("DAC R1 Switch", RT5671_MONO_DAC_MIXER,
- + RT5671_M_DAC_R1_MONO_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R2 Switch", RT5671_MONO_DAC_MIXER,
- + RT5671_M_DAC_R2_MONO_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L2 Switch", RT5671_MONO_DAC_MIXER,
- + RT5671_M_DAC_L2_MONO_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("Sidetone Switch", RT5671_SIDETONE_CTRL,
- + RT5671_M_ST_DACR2_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_dig_l_mix[] = {
- + SOC_DAPM_SINGLE("Sto DAC Mix L Switch", RT5671_DIG_MIXER,
- + RT5671_M_STO_L_DAC_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L2 Switch", RT5671_DIG_MIXER,
- + RT5671_M_DAC_L2_DAC_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R2 Switch", RT5671_DIG_MIXER,
- + RT5671_M_DAC_R2_DAC_L_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_dig_r_mix[] = {
- + SOC_DAPM_SINGLE("Sto DAC Mix R Switch", RT5671_DIG_MIXER,
- + RT5671_M_STO_R_DAC_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R2 Switch", RT5671_DIG_MIXER,
- + RT5671_M_DAC_R2_DAC_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L2 Switch", RT5671_DIG_MIXER,
- + RT5671_M_DAC_L2_DAC_R_SFT, 1, 1),
- +};
- +
- +/* Analog Input Mixer */
- +static const struct snd_kcontrol_new rt5671_rec_l_mix[] = {
- + SOC_DAPM_SINGLE("INL Switch", RT5671_REC_L2_MIXER,
- + RT5671_M_IN_L_RM_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST4 Switch", RT5671_REC_L2_MIXER,
- + RT5671_M_BST4_RM_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST3 Switch", RT5671_REC_L2_MIXER,
- + RT5671_M_BST3_RM_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST2 Switch", RT5671_REC_L2_MIXER,
- + RT5671_M_BST2_RM_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST1 Switch", RT5671_REC_L2_MIXER,
- + RT5671_M_BST1_RM_L_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_rec_r_mix[] = {
- + SOC_DAPM_SINGLE("INR Switch", RT5671_REC_R2_MIXER,
- + RT5671_M_IN_R_RM_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST4 Switch", RT5671_REC_R2_MIXER,
- + RT5671_M_BST4_RM_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST3 Switch", RT5671_REC_R2_MIXER,
- + RT5671_M_BST3_RM_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST2 Switch", RT5671_REC_R2_MIXER,
- + RT5671_M_BST2_RM_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST1 Switch", RT5671_REC_R2_MIXER,
- + RT5671_M_BST1_RM_R_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_rec_m_mix[] = {
- + SOC_DAPM_SINGLE("BST4 Switch", RT5671_REC_MONO2_MIXER,
- + RT5671_M_BST4_RM_M_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST3 Switch", RT5671_REC_MONO2_MIXER,
- + RT5671_M_BST3_RM_M_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST2 Switch", RT5671_REC_MONO2_MIXER,
- + RT5671_M_BST2_RM_M_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST1 Switch", RT5671_REC_MONO2_MIXER,
- + RT5671_M_BST1_RM_M_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_out_l_mix[] = {
- + SOC_DAPM_SINGLE("BST2 Switch", RT5671_OUT_L1_MIXER,
- + RT5671_M_BST2_OM_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST1 Switch", RT5671_OUT_L1_MIXER,
- + RT5671_M_BST1_OM_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("INL Switch", RT5671_OUT_L1_MIXER,
- + RT5671_M_IN_L_OM_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L2 Switch", RT5671_OUT_L1_MIXER,
- + RT5671_M_DAC_L2_OM_L_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L1 Switch", RT5671_OUT_L1_MIXER,
- + RT5671_M_DAC_L1_OM_L_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_out_r_mix[] = {
- + SOC_DAPM_SINGLE("BST3 Switch", RT5671_OUT_R1_MIXER,
- + RT5671_M_BST3_OM_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST4 Switch", RT5671_OUT_R1_MIXER,
- + RT5671_M_BST4_OM_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("INR Switch", RT5671_OUT_R1_MIXER,
- + RT5671_M_IN_R_OM_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R2 Switch", RT5671_OUT_R1_MIXER,
- + RT5671_M_DAC_R2_OM_R_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R1 Switch", RT5671_OUT_R1_MIXER,
- + RT5671_M_DAC_R1_OM_R_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_mono_mix[] = {
- + SOC_DAPM_SINGLE("DAC R2 Switch", RT5671_MONO_MIXER,
- + RT5671_M_DAC_R2_MM_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC L2 Switch", RT5671_MONO_MIXER,
- + RT5671_M_DAC_L2_MM_SFT, 1, 1),
- + SOC_DAPM_SINGLE("BST4 Switch", RT5671_MONO_MIXER,
- + RT5671_M_BST4_MM_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_hpo_mix[] = {
- + SOC_DAPM_SINGLE("DAC1 Switch", RT5671_HPO_MIXER,
- + RT5671_M_DAC1_HM_SFT, 1, 1),
- + SOC_DAPM_SINGLE("HPVOL Switch", RT5671_HPO_MIXER,
- + RT5671_M_HPVOL_HM_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_hpvoll_mix[] = {
- + SOC_DAPM_SINGLE("DAC1 Switch", RT5671_HPO_MIXER,
- + RT5671_M_DACL1_HML_SFT, 1, 1),
- + SOC_DAPM_SINGLE("INL Switch", RT5671_HPO_MIXER,
- + RT5671_M_INL1_HML_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_hpvolr_mix[] = {
- + SOC_DAPM_SINGLE("DAC1 Switch", RT5671_HPO_MIXER,
- + RT5671_M_DACR1_HMR_SFT, 1, 1),
- + SOC_DAPM_SINGLE("INR Switch", RT5671_HPO_MIXER,
- + RT5671_M_INR1_HMR_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_lout_mix[] = {
- + SOC_DAPM_SINGLE("DAC L1 Switch", RT5671_LOUT_MIXER,
- + RT5671_M_DAC_L1_LM_SFT, 1, 1),
- + SOC_DAPM_SINGLE("DAC R1 Switch", RT5671_LOUT_MIXER,
- + RT5671_M_DAC_R1_LM_SFT, 1, 1),
- + SOC_DAPM_SINGLE("OUTMIX L Switch", RT5671_LOUT_MIXER,
- + RT5671_M_OV_L_LM_SFT, 1, 1),
- + SOC_DAPM_SINGLE("OUTMIX R Switch", RT5671_LOUT_MIXER,
- + RT5671_M_OV_R_LM_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_monoamp_mix[] = {
- + SOC_DAPM_SINGLE("DAC L1 Switch", RT5671_MONO_MIXER,
- + RT5671_M_DAC_L1_MA_SFT, 1, 1),
- + SOC_DAPM_SINGLE("MONOVOL Switch", RT5671_MONO_MIXER,
- + RT5671_M_OV_L_MM_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_hpl_mix[] = {
- + SOC_DAPM_SINGLE("DAC L1 Switch", RT5671_HPO_MIXER,
- + RT5671_M_DACL1_HML_SFT, 1, 1),
- + SOC_DAPM_SINGLE("INL1 Switch", RT5671_HPO_MIXER,
- + RT5671_M_INL1_HML_SFT, 1, 1),
- +};
- +
- +static const struct snd_kcontrol_new rt5671_hpr_mix[] = {
- + SOC_DAPM_SINGLE("DAC R1 Switch", RT5671_HPO_MIXER,
- + RT5671_M_DACR1_HMR_SFT, 1, 1),
- + SOC_DAPM_SINGLE("INR1 Switch", RT5671_HPO_MIXER,
- + RT5671_M_INR1_HMR_SFT, 1, 1),
- +};
- +
- +/* DAC1 L/R source */ /* MX-29 [9:8] [11:10] */
- +static const char * const const rt5671_dac1_src[] = {
- + "IF1 DAC", "IF2 DAC", "IF3 DAC", "IF4 DAC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_dac1l_enum, RT5671_AD_DA_MIXER,
- + RT5671_DAC1_L_SEL_SFT, rt5671_dac1_src);
- +
- +static const struct snd_kcontrol_new rt5671_dac1l_mux =
- + SOC_DAPM_ENUM("DAC1 L source", rt5671_dac1l_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_dac1r_enum, RT5671_AD_DA_MIXER,
- + RT5671_DAC1_R_SEL_SFT, rt5671_dac1_src);
- +
- +static const struct snd_kcontrol_new rt5671_dac1r_mux =
- + SOC_DAPM_ENUM("DAC1 R source", rt5671_dac1r_enum);
- +
- +/* DAC2 L/R source */ /* MX-1B [6:4] [2:0] */
- +static int rt5671_dac12_map_values[] = {
- + 0, 1, 2, 3, 5, 6,
- +};
- +static const char * const const rt5671_dac12_src[] = {
- + "IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", "VAD_ADC", "IF4 DAC"
- +};
- +
- +static const SOC_VALUE_ENUM_SINGLE_DECL(
- + rt5671_dac2l_enum, RT5671_DAC_CTRL,
- + RT5671_DAC2_L_SEL_SFT, 0x7, rt5671_dac12_src, rt5671_dac12_map_values);
- +
- +static const struct snd_kcontrol_new rt5671_dac_l2_mux =
- + SOC_DAPM_VALUE_ENUM("DAC2 L source", rt5671_dac2l_enum);
- +
- +static const char * const rt5671_dacr2_src[] = {
- + "IF1 DAC", "IF2 DAC", "IF3 DAC", "TxDC DAC", "TxDP ADC", "IF4 DAC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_dac2r_enum, RT5671_DAC_CTRL,
- + RT5671_DAC2_R_SEL_SFT, rt5671_dacr2_src);
- +
- +static const struct snd_kcontrol_new rt5671_dac_r2_mux =
- + SOC_DAPM_ENUM("DAC2 R source", rt5671_dac2r_enum);
- +
- +/* RxDP source */ /* MX-2D [15:13] */
- +static const char * const rt5671_rxdp_src[] = {
- + "IF2 DAC", "IF1 DAC", "STO1 ADC Mixer", "STO2 ADC Mixer",
- + "Mono ADC Mixer L", "Mono ADC Mixer R", "DAC1"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_rxdp_enum, RT5671_DSP_PATH1,
- + RT5671_RXDP_SEL_SFT, rt5671_rxdp_src);
- +
- +static const struct snd_kcontrol_new rt5671_rxdp_mux =
- + SOC_DAPM_ENUM("RxDP source", rt5671_rxdp_enum);
- +
- +/* MX-2D [1] [0] */
- +static const char * const rt5671_dsp_bypass_src[] = {
- + "DSP", "Bypass"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_dsp_ul_enum, RT5671_DSP_PATH1,
- + RT5671_DSP_UL_SFT, rt5671_dsp_bypass_src);
- +
- +static const struct snd_kcontrol_new rt5671_dsp_ul_mux =
- + SOC_DAPM_ENUM("DSP UL source", rt5671_dsp_ul_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_dsp_dl_enum, RT5671_DSP_PATH1,
- + RT5671_DSP_DL_SFT, rt5671_dsp_bypass_src);
- +
- +static const struct snd_kcontrol_new rt5671_dsp_dl_mux =
- + SOC_DAPM_ENUM("DSP DL source", rt5671_dsp_dl_enum);
- +
- +
- +/* INL/R source */
- +static const char * const rt5671_inl_src[] = {
- + "IN2P", "MonoP"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_inl_enum, RT5671_INL1_INR1_VOL,
- + RT5671_INL_SEL_SFT, rt5671_inl_src);
- +
- +static const struct snd_kcontrol_new rt5671_inl_mux =
- + SOC_DAPM_ENUM("INL source", rt5671_inl_enum);
- +
- +static const char * const rt5671_inr_src[] = {
- + "IN2N", "MonoN"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_inr_enum, RT5671_INL1_INR1_VOL,
- + RT5671_INR_SEL_SFT, rt5671_inr_src);
- +
- +static const struct snd_kcontrol_new rt5671_inr_mux =
- + SOC_DAPM_ENUM("INR source", rt5671_inr_enum);
- +
- +/* Stereo2 ADC source */
- +/* MX-26 [15] */
- +static const char * const rt5671_stereo2_adc_lr_src[] = {
- + "L", "LR"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo2_adc_lr_enum, RT5671_STO2_ADC_MIXER,
- + RT5671_STO2_ADC_SRC_SFT, rt5671_stereo2_adc_lr_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto2_adc_lr_mux =
- + SOC_DAPM_ENUM("Stereo2 ADC LR source", rt5671_stereo2_adc_lr_enum);
- +
- +/* Stereo1 ADC source */
- +/* MX-27 MX-26 [12] */
- +static const char * const rt5671_stereo_adc1_src[] = {
- + "DAC MIX", "ADC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo1_adc1_enum, RT5671_STO1_ADC_MIXER,
- + RT5671_ADC_1_SRC_SFT, rt5671_stereo_adc1_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto_adc1_mux =
- + SOC_DAPM_ENUM("Stereo1 ADC1 source", rt5671_stereo1_adc1_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo2_adc1_enum, RT5671_STO2_ADC_MIXER,
- + RT5671_ADC_1_SRC_SFT, rt5671_stereo_adc1_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto2_adc1_mux =
- + SOC_DAPM_ENUM("Stereo2 ADC1 source", rt5671_stereo2_adc1_enum);
- +
- +/* MX-27 MX-26 [11] */
- +static const char * const rt5671_stereo_adc2_src[] = {
- + "DAC MIX", "DMIC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo1_adc2_enum, RT5671_STO1_ADC_MIXER,
- + RT5671_ADC_2_SRC_SFT, rt5671_stereo_adc2_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto_adc2_mux =
- + SOC_DAPM_ENUM("Stereo1 ADC2 source", rt5671_stereo1_adc2_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo2_adc2_enum, RT5671_STO2_ADC_MIXER,
- + RT5671_ADC_2_SRC_SFT, rt5671_stereo_adc2_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto2_adc2_mux =
- + SOC_DAPM_ENUM("Stereo2 ADC2 source", rt5671_stereo2_adc2_enum);
- +
- +/* MX-27 MX26 [10] */
- +static const char * const rt5671_stereo_adc_src[] = {
- + "ADC1L ADC2R", "ADC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo1_adc_enum, RT5671_STO1_ADC_MIXER,
- + RT5671_ADC_SRC_SFT, rt5671_stereo_adc_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto_adc_mux =
- + SOC_DAPM_ENUM("Stereo1 ADC source", rt5671_stereo1_adc_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo2_adc_enum, RT5671_STO2_ADC_MIXER,
- + RT5671_ADC_SRC_SFT, rt5671_stereo_adc_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto2_adc_mux =
- + SOC_DAPM_ENUM("Stereo2 ADC source", rt5671_stereo2_adc_enum);
- +
- +static const char * const rt5671_stereo_adc12_src[] = {
- + "ADC", "Stereo DAC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo_adc12_enum, RT5671_DUMMY_CTRL,
- + 10, rt5671_stereo_adc12_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto_adc12_mux =
- + SOC_DAPM_ENUM("ADC 1_2 source", rt5671_stereo_adc12_enum);
- +
- +/* MX-27 MX-26 [9:8] */
- +static const char * const rt5671_stereo_dmic_src[] = {
- + "DMIC1", "DMIC2", "DMIC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo1_dmic_enum, RT5671_STO1_ADC_MIXER,
- + RT5671_DMIC_SRC_SFT, rt5671_stereo_dmic_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto1_dmic_mux =
- + SOC_DAPM_ENUM("Stereo1 DMIC source", rt5671_stereo1_dmic_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo2_dmic_enum, RT5671_STO2_ADC_MIXER,
- + RT5671_DMIC_SRC_SFT, rt5671_stereo_dmic_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto2_dmic_mux =
- + SOC_DAPM_ENUM("Stereo2 DMIC source", rt5671_stereo2_dmic_enum);
- +
- +/* MX-27 [0] */
- +static const char * const rt5671_stereo_dmic3_src[] = {
- + "DMIC3", "PDM ADC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_stereo_dmic3_enum, RT5671_STO1_ADC_MIXER,
- + RT5671_DMIC3_SRC_SFT, rt5671_stereo_dmic3_src);
- +
- +static const struct snd_kcontrol_new rt5671_sto_dmic3_mux =
- + SOC_DAPM_ENUM("Stereo DMIC3 source", rt5671_stereo_dmic3_enum);
- +
- +/* Mono ADC source */
- +/* MX-28 [12] */
- +static const char * const rt5671_mono_adc_l1_src[] = {
- + "Mono DAC MIXL", "ADC1 ADC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_mono_adc_l1_enum, RT5671_MONO_ADC_MIXER,
- + RT5671_MONO_ADC_L1_SRC_SFT, rt5671_mono_adc_l1_src);
- +
- +static const struct snd_kcontrol_new rt5671_mono_adc_l1_mux =
- + SOC_DAPM_ENUM("Mono ADC1 left source", rt5671_mono_adc_l1_enum);
- +/* MX-28 [11] */
- +static const char * const rt5671_mono_adc_l2_src[] = {
- + "Mono DAC MIXL", "DMIC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_mono_adc_l2_enum, RT5671_MONO_ADC_MIXER,
- + RT5671_MONO_ADC_L2_SRC_SFT, rt5671_mono_adc_l2_src);
- +
- +static const struct snd_kcontrol_new rt5671_mono_adc_l2_mux =
- + SOC_DAPM_ENUM("Mono ADC2 left source", rt5671_mono_adc_l2_enum);
- +
- +/* MX-28 [10] */
- +static const char * const rt5671_mono_adc_l_src[] = {
- + "ADC1", "ADC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_mono_adc_l_enum, RT5671_MONO_ADC_MIXER,
- + RT5671_MONO_ADC_L_SRC_SFT, rt5671_mono_adc_l_src);
- +
- +static const struct snd_kcontrol_new rt5671_mono_adc_l_mux =
- + SOC_DAPM_ENUM("Mono ADC left source", rt5671_mono_adc_l_enum);
- +
- +/* MX-28 [9:8] */
- +static const char * const rt5671_mono_dmic_src[] = {
- + "DMIC1", "DMIC2", "DMIC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_mono_dmic_l_enum, RT5671_MONO_ADC_MIXER,
- + RT5671_MONO_DMIC_L_SRC_SFT, rt5671_mono_dmic_src);
- +
- +static const struct snd_kcontrol_new rt5671_mono_dmic_l_mux =
- + SOC_DAPM_ENUM("Mono DMIC left source", rt5671_mono_dmic_l_enum);
- +/* MX-28 [1:0] */
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_mono_dmic_r_enum, RT5671_MONO_ADC_MIXER,
- + RT5671_MONO_DMIC_R_SRC_SFT, rt5671_mono_dmic_src);
- +
- +static const struct snd_kcontrol_new rt5671_mono_dmic_r_mux =
- + SOC_DAPM_ENUM("Mono DMIC Right source", rt5671_mono_dmic_r_enum);
- +/* MX-28 [4] */
- +static const char * const rt5671_mono_adc_r1_src[] = {
- + "Mono DAC MIXR", "ADC2 ADC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_mono_adc_r1_enum, RT5671_MONO_ADC_MIXER,
- + RT5671_MONO_ADC_R1_SRC_SFT, rt5671_mono_adc_r1_src);
- +
- +static const struct snd_kcontrol_new rt5671_mono_adc_r1_mux =
- + SOC_DAPM_ENUM("Mono ADC1 right source", rt5671_mono_adc_r1_enum);
- +/* MX-28 [3] */
- +static const char * const rt5671_mono_adc_r2_src[] = {
- + "Mono DAC MIXR", "DMIC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_mono_adc_r2_enum, RT5671_MONO_ADC_MIXER,
- + RT5671_MONO_ADC_R2_SRC_SFT, rt5671_mono_adc_r2_src);
- +
- +static const struct snd_kcontrol_new rt5671_mono_adc_r2_mux =
- + SOC_DAPM_ENUM("Mono ADC2 right source", rt5671_mono_adc_r2_enum);
- +
- +/* MX-28 [2] */
- +static const char * const rt5671_mono_adc_r_src[] = {
- + "ADC2", "ADC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_mono_adc_r_enum, RT5671_MONO_ADC_MIXER,
- + RT5671_MONO_ADC_R_SRC_SFT, rt5671_mono_adc_r_src);
- +
- +static const struct snd_kcontrol_new rt5671_mono_adc_r_mux =
- + SOC_DAPM_ENUM("Mono ADC Right source", rt5671_mono_adc_r_enum);
- +
- +/* MX-2D [3:2] */
- +static const char * const rt5671_txdp_slot_src[] = {
- + "Slot 0-1", "Slot 2-3", "Slot 4-5", "Slot 6-7"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_txdp_slot_enum, RT5671_DSP_PATH1,
- + RT5671_TXDP_SLOT_SEL_SFT, rt5671_txdp_slot_src);
- +
- +static const struct snd_kcontrol_new rt5671_txdp_slot_mux =
- + SOC_DAPM_ENUM("TxDP Slot source", rt5671_txdp_slot_enum);
- +
- +/* MX-2F [15] */
- +static const char * const rt5671_if1_adc2_in_src[] = {
- + "IF_ADC2", "VAD_ADC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_if1_adc2_in_enum, RT5671_DIG_INF1_DATA,
- + RT5671_IF1_ADC2_IN_SFT, rt5671_if1_adc2_in_src);
- +
- +static const struct snd_kcontrol_new rt5671_if1_adc2_in_mux =
- + SOC_DAPM_ENUM("IF1 ADC2 IN source", rt5671_if1_adc2_in_enum);
- +
- +/* MX-77 [9:8] */
- +static const char * const rt5671_if1_adc_in_src[] = {
- + "IF1_ADC1", "IF_ADC3", "IF1_ADC2", "TxDC_DAC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_if1_adc_in_enum, RT5671_TDM_CTRL_1, 8, rt5671_if1_adc_in_src);
- +
- +static const struct snd_kcontrol_new rt5671_if1_adc_in_mux =
- + SOC_DAPM_ENUM("IF1 ADC IN source", rt5671_if1_adc_in_enum);
- +
- +/* MX-2F [14:12] */
- +static const char * const rt5671_if2_adc_in_src[] = {
- + "IF_ADC1", "IF_ADC2", "IF_ADC3", "TxDC_DAC", "TxDP_ADC", "VAD_ADC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_if2_adc_in_enum, RT5671_DIG_INF1_DATA,
- + RT5671_IF2_ADC_IN_SFT, rt5671_if2_adc_in_src);
- +
- +static const struct snd_kcontrol_new rt5671_if2_adc_in_mux =
- + SOC_DAPM_ENUM("IF2 ADC IN source", rt5671_if2_adc_in_enum);
- +
- +/* MX-2F [2:0] */
- +static const char * const rt5671_if3_adc_in_src[] = {
- + "IF_ADC1", "IF_ADC2", "IF_ADC3", "TxDC_DAC", "TxDP_ADC", "VAD_ADC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_if3_adc_in_enum, RT5671_DIG_INF1_DATA,
- + RT5671_IF3_ADC_IN_SFT, rt5671_if3_adc_in_src);
- +
- +static const struct snd_kcontrol_new rt5671_if3_adc_in_mux =
- + SOC_DAPM_ENUM("IF3 ADC IN source", rt5671_if3_adc_in_enum);
- +
- +/* MX-30 [5:4] */
- +static const char * const rt5671_if4_adc_in_src[] = {
- + "IF_ADC1", "IF_ADC2", "IF_ADC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_if4_adc_in_enum, RT5671_DIG_INF2_DATA,
- + RT5671_IF4_ADC_IN_SFT, rt5671_if4_adc_in_src);
- +
- +static const struct snd_kcontrol_new rt5671_if4_adc_in_mux =
- + SOC_DAPM_ENUM("IF4 ADC IN source", rt5671_if4_adc_in_enum);
- +
- +/* MX-31 [15] [13] [11] [9] */
- +static const char * const rt5671_pdm_src[] = {
- + "Mono DAC", "Stereo DAC"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_pdm1_l_enum, RT5671_PDM_OUT_CTRL,
- + RT5671_PDM1_L_SFT, rt5671_pdm_src);
- +
- +static const struct snd_kcontrol_new rt5671_pdm1_l_mux =
- + SOC_DAPM_ENUM("PDM1 L source", rt5671_pdm1_l_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_pdm1_r_enum, RT5671_PDM_OUT_CTRL,
- + RT5671_PDM1_R_SFT, rt5671_pdm_src);
- +
- +static const struct snd_kcontrol_new rt5671_pdm1_r_mux =
- + SOC_DAPM_ENUM("PDM1 R source", rt5671_pdm1_r_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_pdm2_l_enum, RT5671_PDM_OUT_CTRL,
- + RT5671_PDM2_L_SFT, rt5671_pdm_src);
- +
- +static const struct snd_kcontrol_new rt5671_pdm2_l_mux =
- + SOC_DAPM_ENUM("PDM2 L source", rt5671_pdm2_l_enum);
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_pdm2_r_enum, RT5671_PDM_OUT_CTRL,
- + RT5671_PDM2_R_SFT, rt5671_pdm_src);
- +
- +static const struct snd_kcontrol_new rt5671_pdm2_r_mux =
- + SOC_DAPM_ENUM("PDM2 R source", rt5671_pdm2_r_enum);
- +
- +/* MX-FA [12] */
- +static const char * const rt5671_if1_adc1_in1_src[] = {
- + "IF_ADC1", "IF1_ADC3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_if1_adc1_in1_enum, RT5671_GEN_CTRL1,
- + RT5671_IF1_ADC1_IN1_SFT, rt5671_if1_adc1_in1_src);
- +
- +static const struct snd_kcontrol_new rt5671_if1_adc1_in1_mux =
- + SOC_DAPM_ENUM("IF1 ADC1 IN1 source", rt5671_if1_adc1_in1_enum);
- +
- +/* MX-FA [11] */
- +static const char * const rt5671_if1_adc1_in2_src[] = {
- + "IF1_ADC1_IN1", "IF1_ADC4"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_if1_adc1_in2_enum, RT5671_GEN_CTRL1,
- + RT5671_IF1_ADC1_IN2_SFT, rt5671_if1_adc1_in2_src);
- +
- +static const struct snd_kcontrol_new rt5671_if1_adc1_in2_mux =
- + SOC_DAPM_ENUM("IF1 ADC1 IN2 source", rt5671_if1_adc1_in2_enum);
- +
- +/* MX-FA [10] */
- +static const char * const rt5671_if1_adc2_in1_src[] = {
- + "IF1_ADC2_IN", "IF1_ADC4"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_if1_adc2_in1_enum, RT5671_GEN_CTRL1,
- + RT5671_IF1_ADC2_IN1_SFT, rt5671_if1_adc2_in1_src);
- +
- +static const struct snd_kcontrol_new rt5671_if1_adc2_in1_mux =
- + SOC_DAPM_ENUM("IF1 ADC2 IN1 source", rt5671_if1_adc2_in1_enum);
- +
- +/* MX-18 [11:9] */
- +static const char * const rt5671_sidetone_src[] = {
- + "DMIC L1", "DMIC L2", "DMIC L3", "ADC 1", "ADC 2", "ADC 3"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_sidetone_enum, RT5671_SIDETONE_CTRL,
- + RT5671_ST_SEL_SFT, rt5671_sidetone_src);
- +
- +static const struct snd_kcontrol_new rt5671_sidetone_mux =
- + SOC_DAPM_ENUM("Sidetone source", rt5671_sidetone_enum);
- +
- +/* MX-18 [6] */
- +static const char * const rt5671_anc_src[] = {
- + "SNC", "Sidetone"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_anc_enum, RT5671_SIDETONE_CTRL,
- + RT5671_ST_EN_SFT, rt5671_anc_src);
- +
- +static const struct snd_kcontrol_new rt5671_anc_mux =
- + SOC_DAPM_ENUM("ANC source", rt5671_anc_enum);
- +
- +/* MX-9D [9:8] */
- +static const char * const rt5671_vad_adc_src[] = {
- + "Sto1 ADC L", "Mono ADC L", "Mono ADC R", "Sto2 ADC L"
- +};
- +
- +static const SOC_ENUM_SINGLE_DECL(
- + rt5671_vad_adc_enum, RT5671_VAD_CTRL4,
- + RT5671_VAD_SEL_SFT, rt5671_vad_adc_src);
- +
- +static const struct snd_kcontrol_new rt5671_vad_adc_mux =
- + SOC_DAPM_ENUM("VAD ADC source", rt5671_vad_adc_enum);
- +
- +static int rt5671_adc_clk_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + rt5671_index_update_bits(codec,
- + RT5671_CHOP_DAC_ADC, 0x1000, 0x1000);
- + break;
- +
- + case SND_SOC_DAPM_POST_PMD:
- + rt5671_index_update_bits(codec,
- + RT5671_CHOP_DAC_ADC, 0x1000, 0x0000);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_sto1_adcl_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + msleep(50);
- + snd_soc_update_bits(codec, RT5671_STO1_ADC_DIG_VOL,
- + RT5671_L_MUTE, 0);
- + break;
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_STO1_ADC_DIG_VOL,
- + RT5671_L_MUTE,
- + RT5671_L_MUTE);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_sto1_adcr_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + msleep(50);
- + snd_soc_update_bits(codec, RT5671_STO1_ADC_DIG_VOL,
- + RT5671_R_MUTE, 0);
- + break;
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_STO1_ADC_DIG_VOL,
- + RT5671_R_MUTE,
- + RT5671_R_MUTE);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_mono_adcl_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_MONO_ADC_DIG_VOL,
- + RT5671_L_MUTE, 0);
- + break;
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_MONO_ADC_DIG_VOL,
- + RT5671_L_MUTE,
- + RT5671_L_MUTE);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_mono_adcr_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_MONO_ADC_DIG_VOL,
- + RT5671_R_MUTE, 0);
- + break;
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_MONO_ADC_DIG_VOL,
- + RT5671_R_MUTE,
- + RT5671_R_MUTE);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static void hp_amp_power(struct snd_soc_codec *codec, int on)
- +{
- + if (on) {
- + snd_soc_update_bits(codec, RT5671_CHARGE_PUMP,
- + RT5671_PM_HP_MASK, RT5671_PM_HP_HV);
- + /* headphone amp power on */
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1,
- + RT5671_PWR_HA | RT5671_PWR_FV1 |
- + RT5671_PWR_FV2, RT5671_PWR_HA |
- + RT5671_PWR_FV1 | RT5671_PWR_FV2);
- + /* depop parameters */
- + snd_soc_write(codec, RT5671_DEPOP_M2, 0x3140); /*bit 6 = 1 for Auto Power Down*/
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x8009);
- + rt5671_index_write(codec, RT5671_HP_DCC_INT1, 0x9f00);
- + pr_debug("hp_amp_time=%d\n", hp_amp_time);
- + mdelay(hp_amp_time);
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x8019);
- + } else {
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x0004);
- + msleep(30);
- + }
- +}
- +
- +static void rt5671_pmu_depop(struct snd_soc_codec *codec)
- +{
- + /* headphone unmute sequence */
- + rt5671_index_write(codec, RT5671_MAMP_INT_REG2, 0xb400);
- + snd_soc_write(codec, RT5671_DEPOP_M3, 0x0772);
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x805d);
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x831d);
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL2,
- + 0x0300, 0x0300);
- + snd_soc_update_bits(codec, RT5671_HP_VOL,
- + RT5671_L_MUTE | RT5671_R_MUTE, 0);
- + pr_debug("pmu_depop_time=%d\n", pmu_depop_time);
- + msleep(pmu_depop_time);
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x8019);
- +}
- +
- +static void rt5671_pmd_depop(struct snd_soc_codec *codec)
- +{
- + /* headphone mute sequence */
- + rt5671_index_write(codec, RT5671_MAMP_INT_REG2, 0xb400);
- + snd_soc_write(codec, RT5671_DEPOP_M3, 0x0772);
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x803d);
- + mdelay(10);
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x831d);
- + mdelay(10);
- + snd_soc_update_bits(codec, RT5671_HP_VOL,
- + RT5671_L_MUTE | RT5671_R_MUTE, RT5671_L_MUTE | RT5671_R_MUTE);
- + msleep(20);
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL2, 0x0300, 0x0);
- + snd_soc_write(codec, RT5671_DEPOP_M1, 0x8019);
- + snd_soc_write(codec, RT5671_DEPOP_M3, 0x0707);
- + rt5671_index_write(codec, RT5671_MAMP_INT_REG2, 0xfc00);
- +}
- +
- +static int rt5671_hp_power_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + hp_amp_power(codec, 1);
- + break;
- + case SND_SOC_DAPM_PRE_PMD:
- + hp_amp_power(codec, 0);
- + break;
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_hp_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + rt5671_pmu_depop(codec);
- + snd_soc_update_bits(codec, RT5671_ALC_CTRL_1,
- + RT5671_DRC_AGC_MASK, RT5671_DRC_AGC_EN);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_ALC_CTRL_1,
- + RT5671_DRC_AGC_MASK, RT5671_DRC_AGC_DIS);
- + rt5671_pmd_depop(codec);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_mono_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_MONO_OUT,
- + RT5671_L_MUTE, 0);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_MONO_OUT,
- + RT5671_L_MUTE, RT5671_L_MUTE);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_lout_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_CHARGE_PUMP,
- + RT5671_PM_HP_MASK, RT5671_PM_HP_HV);
- + snd_soc_update_bits(codec, RT5671_LOUT1,
- + RT5671_L_MUTE | RT5671_R_MUTE, 0);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_LOUT1,
- + RT5671_L_MUTE | RT5671_R_MUTE,
- + RT5671_L_MUTE | RT5671_R_MUTE);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_set_dmic1_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_PRE_PMU:
- +#ifdef NVIDIA_DALMORE
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST1 | RT5671_PWR_BST1_P,
- + RT5671_PWR_BST1 | RT5671_PWR_BST1_P);
- + snd_soc_update_bits(codec, RT5671_CJ_CTRL2,
- + RT5671_CBJ_DET_MODE, RT5671_CBJ_DET_MODE);
- +#endif
- + snd_soc_update_bits(codec, RT5671_GPIO_CTRL1,
- + RT5671_GP2_PIN_MASK | RT5671_GP6_PIN_MASK |
- + RT5671_I2S2_PIN_MASK,
- + RT5671_GP2_PIN_DMIC1_SCL | RT5671_GP6_PIN_DMIC1_SDA |
- + RT5671_I2S2_PIN_GPIO);
- + snd_soc_update_bits(codec, RT5671_DMIC_CTRL1,
- + RT5671_DMIC_1L_LH_MASK | RT5671_DMIC_1R_LH_MASK |
- + RT5671_DMIC_1_DP_MASK,
- + RT5671_DMIC_1L_LH_FALLING | RT5671_DMIC_1R_LH_RISING |
- + RT5671_DMIC_1_DP_GPIO6);
- + break;
- + case SND_SOC_DAPM_POST_PMD:
- +#ifdef NVIDIA_DALMORE
- + snd_soc_update_bits(codec, RT5671_CJ_CTRL2, RT5671_CBJ_DET_MODE,
- + 0);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST1 | RT5671_PWR_BST1_P, 0);
- +#endif
- + break;
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_set_dmic2_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_PRE_PMU:
- + snd_soc_update_bits(codec, RT5671_GPIO_CTRL1,
- + RT5671_GP2_PIN_MASK | RT5671_GP4_PIN_MASK,
- + RT5671_GP2_PIN_DMIC1_SCL | RT5671_GP4_PIN_DMIC2_SDA);
- + snd_soc_update_bits(codec, RT5671_DMIC_CTRL1,
- + RT5671_DMIC_2L_LH_MASK | RT5671_DMIC_2R_LH_MASK |
- + RT5671_DMIC_2_DP_MASK,
- + RT5671_DMIC_2L_LH_FALLING | RT5671_DMIC_2R_LH_RISING |
- + RT5671_DMIC_2_DP_IN1N);
- + break;
- +
- + case SND_SOC_DAPM_POST_PMD:
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_set_dmic3_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_PRE_PMU:
- + snd_soc_update_bits(codec, RT5671_GPIO_CTRL1,
- + RT5671_GP2_PIN_MASK | RT5671_GP4_PIN_MASK,
- + RT5671_GP2_PIN_DMIC1_SCL | RT5671_GP4_PIN_DMIC2_SDA);
- + snd_soc_update_bits(codec, RT5671_DMIC_CTRL1,
- + RT5671_DMIC_2L_LH_MASK | RT5671_DMIC_2R_LH_MASK |
- + RT5671_DMIC_2_DP_MASK,
- + RT5671_DMIC_2L_LH_FALLING | RT5671_DMIC_2R_LH_RISING |
- + RT5671_DMIC_2_DP_IN1N);
- + break;
- +
- + case SND_SOC_DAPM_POST_PMD:
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_bst1_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_CHARGE_PUMP,
- + RT5671_OSW_L_MASK | RT5671_OSW_R_MASK,
- + RT5671_OSW_L_DIS | RT5671_OSW_R_DIS);
- +
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST1_P, RT5671_PWR_BST1_P);
- + if (rt5671->combo_jack_en) {
- + snd_soc_update_bits(codec, RT5671_PWR_VOL,
- + RT5671_PWR_MIC_DET, RT5671_PWR_MIC_DET);
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL2, 0x2, 0x0);
- + }
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL2, 0x2, 0x2);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST1_P, 0);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_bst2_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST2_P, RT5671_PWR_BST2_P);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST2_P, 0);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_bst3_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST3_P, RT5671_PWR_BST3_P);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST3_P, 0);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_bst4_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST4_P, RT5671_PWR_BST4_P);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_BST4_P, 0);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_pdm1_l_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_PDM_OUT_CTRL,
- + RT5671_M_PDM1_L, 0);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_PDM_OUT_CTRL,
- + RT5671_M_PDM1_L, RT5671_M_PDM1_L);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_pdm1_r_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_PDM_OUT_CTRL,
- + RT5671_M_PDM1_R, 0);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_PDM_OUT_CTRL,
- + RT5671_M_PDM1_R, RT5671_M_PDM1_R);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_pdm2_l_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_PDM_OUT_CTRL,
- + RT5671_M_PDM2_L, 0);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_PDM_OUT_CTRL,
- + RT5671_M_PDM2_L, RT5671_M_PDM2_L);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_pdm2_r_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_update_bits(codec, RT5671_PDM_OUT_CTRL,
- + RT5671_M_PDM2_R, 0);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_update_bits(codec, RT5671_PDM_OUT_CTRL,
- + RT5671_M_PDM2_R, RT5671_M_PDM2_R);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_sto_adc12_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- + unsigned int val;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_REG:
- + val = snd_soc_read(codec, RT5671_DUMMY_CTRL) & 0x0400;
- + rt5671_index_update_bits(codec, 0x3a, 0x0400, val);
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_drc_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + if (rt5671->drc_mode)
- + snd_soc_write(codec, RT5671_ALC_CTRL_1, 0xe206);
- + break;
- +
- + case SND_SOC_DAPM_PRE_PMD:
- + snd_soc_write(codec, RT5671_ALC_CTRL_1, 0x2206); /*MX-B4*/
- + break;
- +
- + default:
- + return 0;
- + }
- +
- + return 0;
- +}
- +
- +static const struct snd_soc_dapm_widget rt5671_dapm_widgets[] = {
- + SND_SOC_DAPM_SUPPLY("PLL1", RT5671_PWR_ANLG2,
- + RT5671_PWR_PLL_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("I2S DSP", RT5671_PWR_DIG2,
- + RT5671_PWR_I2S_DSP_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5671_PWR_VOL,
- + RT5671_PWR_MIC_DET_BIT, 0, NULL, 0),
- +
- + /* ASRC */
- + SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5671_ASRC_1,
- + 11, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5671_ASRC_1,
- + 12, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5671_ASRC_1,
- + 13, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("I2S4 ASRC", 1, RT5671_ASRC_1,
- + 14, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5671_ASRC_1,
- + 10, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("DAC MONO L ASRC", 1, RT5671_ASRC_1,
- + 9, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("DAC MONO R ASRC", 1, RT5671_ASRC_1,
- + 8, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5671_ASRC_1,
- + 3, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("ADC STO2 ASRC", 1, RT5671_ASRC_1,
- + 2, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5671_ASRC_1,
- + 1, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5671_ASRC_1,
- + 0, 0, NULL, 0),
- +
- + /* Input Side */
- + /* micbias */
- + SND_SOC_DAPM_MICBIAS("micbias1", RT5671_PWR_ANLG2,
- + RT5671_PWR_MB1_BIT, 0),
- + SND_SOC_DAPM_MICBIAS("micbias2", RT5671_PWR_ANLG2,
- + RT5671_PWR_MB2_BIT, 0),
- + /* Input Lines */
- + SND_SOC_DAPM_INPUT("DMIC L1"),
- + SND_SOC_DAPM_INPUT("DMIC R1"),
- + SND_SOC_DAPM_INPUT("DMIC L2"),
- + SND_SOC_DAPM_INPUT("DMIC R2"),
- + SND_SOC_DAPM_INPUT("DMIC L3"),
- + SND_SOC_DAPM_INPUT("DMIC R3"),
- +
- + SND_SOC_DAPM_INPUT("IN1P"),
- + SND_SOC_DAPM_INPUT("IN1N"),
- + SND_SOC_DAPM_INPUT("IN2P"),
- + SND_SOC_DAPM_INPUT("IN2N"),
- + SND_SOC_DAPM_INPUT("IN3P"),
- + SND_SOC_DAPM_INPUT("IN3N"),
- + SND_SOC_DAPM_INPUT("IN4P"),
- + SND_SOC_DAPM_INPUT("IN4N"),
- +
- + SND_SOC_DAPM_PGA_E("DMIC1", SND_SOC_NOPM,
- + 0, 0, NULL, 0, NULL,
- + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- + SND_SOC_DAPM_PGA_E("DMIC2", SND_SOC_NOPM,
- + 0, 0, NULL, 0, NULL,
- + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- + SND_SOC_DAPM_PGA_E("DMIC3", SND_SOC_NOPM,
- + 0, 0, NULL, 0, NULL,
- + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- + SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
- + set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
- + SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5671_DMIC_CTRL1,
- + RT5671_DMIC_1_EN_SFT, 0, rt5671_set_dmic1_event,
- + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- + SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5671_DMIC_CTRL1,
- + RT5671_DMIC_2_EN_SFT, 0, rt5671_set_dmic2_event,
- + SND_SOC_DAPM_PRE_PMU),
- + SND_SOC_DAPM_SUPPLY("DMIC3 Power", RT5671_DMIC_CTRL1,
- + RT5671_DMIC_3_EN_SFT, 0, rt5671_set_dmic3_event,
- + SND_SOC_DAPM_PRE_PMU),
- +
- + /* Boost */
- + SND_SOC_DAPM_PGA_E("BST1", RT5671_PWR_ANLG2,
- + RT5671_PWR_BST1_BIT, 0, NULL, 0, rt5671_bst1_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_PGA_E("BST2", RT5671_PWR_ANLG2,
- + RT5671_PWR_BST2_BIT, 0, NULL, 0, rt5671_bst2_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_PGA_E("BST3", RT5671_PWR_ANLG2,
- + RT5671_PWR_BST3_BIT, 0, NULL, 0, rt5671_bst3_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_PGA_E("BST4", RT5671_PWR_ANLG2,
- + RT5671_PWR_BST4_BIT, 0, NULL, 0, rt5671_bst4_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- + /* Input Volume */
- + SND_SOC_DAPM_PGA("INL VOL", RT5671_PWR_VOL,
- + RT5671_PWR_IN_L_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("INR VOL", RT5671_PWR_VOL,
- + RT5671_PWR_IN_R_BIT, 0, NULL, 0),
- +
- + /* REC Mixer */
- + SND_SOC_DAPM_MIXER("RECMIXL", RT5671_PWR_MIXER, RT5671_PWR_RM_L_BIT, 0,
- + rt5671_rec_l_mix, ARRAY_SIZE(rt5671_rec_l_mix)),
- + SND_SOC_DAPM_MIXER("RECMIXR", RT5671_PWR_MIXER, RT5671_PWR_RM_R_BIT, 0,
- + rt5671_rec_r_mix, ARRAY_SIZE(rt5671_rec_r_mix)),
- + SND_SOC_DAPM_MIXER("RECMIXM", RT5671_PWR_MIXER, RT5671_PWR_RM_M_BIT, 0,
- + rt5671_rec_m_mix, ARRAY_SIZE(rt5671_rec_m_mix)),
- + /* ADCs */
- + SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_ADC("ADC 2", NULL, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_ADC("ADC 3", NULL, SND_SOC_NOPM, 0, 0),
- +
- + SND_SOC_DAPM_MUX_E("ADC 1_2", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto_adc12_mux, rt5671_sto_adc12_event,
- + SND_SOC_DAPM_POST_REG),
- +
- + SND_SOC_DAPM_SUPPLY("ADC 1 power", RT5671_PWR_DIG1,
- + RT5671_PWR_ADC_L_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("ADC 2 power", RT5671_PWR_DIG1,
- + RT5671_PWR_ADC_R_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("ADC 3 power", RT5671_PWR_DIG1,
- + RT5671_PWR_ADC_3_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("ADC clock", SND_SOC_NOPM, 0, 0,
- + rt5671_adc_clk_event, SND_SOC_DAPM_POST_PMD |
- + SND_SOC_DAPM_POST_PMU),
- + /* ADC Mux */
- + SND_SOC_DAPM_MUX("Stereo1 ADC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto_adc_mux),
- + SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto1_dmic_mux),
- + SND_SOC_DAPM_MUX("Stereo1 ADC2 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto_adc2_mux),
- + SND_SOC_DAPM_MUX("Stereo1 ADC1 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto_adc1_mux),
- + SND_SOC_DAPM_MUX("Stereo2 ADC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto2_adc_mux),
- + SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto2_dmic_mux),
- + SND_SOC_DAPM_MUX("Stereo2 ADC2 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto2_adc2_mux),
- + SND_SOC_DAPM_MUX("Stereo2 ADC1 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto2_adc1_mux),
- + SND_SOC_DAPM_MUX("Stereo2 ADC LR Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sto2_adc_lr_mux),
- + SND_SOC_DAPM_MUX("Mono ADC L Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_mono_adc_l_mux),
- + SND_SOC_DAPM_MUX("Mono ADC R Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_mono_adc_r_mux),
- + SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_mono_dmic_l_mux),
- + SND_SOC_DAPM_MUX("Mono DMIC R Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_mono_dmic_r_mux),
- + SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_mono_adc_l2_mux),
- + SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_mono_adc_l1_mux),
- + SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_mono_adc_r1_mux),
- + SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_mono_adc_r2_mux),
- + /* ADC Mixer */
- + SND_SOC_DAPM_SUPPLY("adc stereo1 filter", RT5671_PWR_DIG2,
- + RT5671_PWR_ADC_S1F_BIT, 0, rt5671_drc_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_SUPPLY("adc stereo2 filter", RT5671_PWR_DIG2,
- + RT5671_PWR_ADC_S2F_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
- + rt5671_sto1_adc_l_mix, ARRAY_SIZE(rt5671_sto1_adc_l_mix)),
- + SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0,
- + rt5671_sto1_adc_r_mix, ARRAY_SIZE(rt5671_sto1_adc_r_mix)),
- + SND_SOC_DAPM_MIXER("Sto2 ADC MIXL", SND_SOC_NOPM, 0, 0,
- + rt5671_sto2_adc_l_mix, ARRAY_SIZE(rt5671_sto2_adc_l_mix)),
- + SND_SOC_DAPM_MIXER("Sto2 ADC MIXR", SND_SOC_NOPM, 0, 0,
- + rt5671_sto2_adc_r_mix, ARRAY_SIZE(rt5671_sto2_adc_r_mix)),
- + SND_SOC_DAPM_SUPPLY("adc mono left filter", RT5671_PWR_DIG2,
- + RT5671_PWR_ADC_MF_L_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_MIXER_E("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
- + rt5671_mono_adc_l_mix, ARRAY_SIZE(rt5671_mono_adc_l_mix),
- + rt5671_mono_adcl_event, SND_SOC_DAPM_PRE_PMD |
- + SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_SUPPLY("adc mono right filter", RT5671_PWR_DIG2,
- + RT5671_PWR_ADC_MF_R_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_MIXER_E("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
- + rt5671_mono_adc_r_mix, ARRAY_SIZE(rt5671_mono_adc_r_mix),
- + rt5671_mono_adcr_event, SND_SOC_DAPM_PRE_PMD |
- + SND_SOC_DAPM_POST_PMU),
- +
- + /* ADC PGA */
- + SND_SOC_DAPM_PGA_S("Stereo1 ADC MIXL", 1, SND_SOC_NOPM, 0, 0,
- + rt5671_sto1_adcl_event, SND_SOC_DAPM_PRE_PMD |
- + SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_PGA_S("Stereo1 ADC MIXR", 1, SND_SOC_NOPM, 0, 0,
- + rt5671_sto1_adcr_event, SND_SOC_DAPM_PRE_PMD |
- + SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_PGA("Stereo2 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("Stereo2 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("Sto2 ADC LR MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("Stereo2 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("Mono ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("VAD_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
- +
- + /* DSP */
- + SND_SOC_DAPM_PGA("TxDP_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("TxDP_ADC_L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("TxDP_ADC_R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("TxDC_DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
- +
- + SND_SOC_DAPM_MUX("TDM Data Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_txdp_slot_mux),
- +
- + SND_SOC_DAPM_MUX("DSP UL Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_dsp_ul_mux),
- + SND_SOC_DAPM_MUX("DSP DL Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_dsp_dl_mux),
- +
- + SND_SOC_DAPM_MUX("RxDP Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_rxdp_mux),
- +
- + /* IF1 2 3 4 Mux */
- + SND_SOC_DAPM_MUX("IF1 ADC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_if1_adc_in_mux),
- + SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_if2_adc_in_mux),
- + SND_SOC_DAPM_MUX("IF3 ADC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_if3_adc_in_mux),
- + SND_SOC_DAPM_MUX("IF4 ADC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_if4_adc_in_mux),
- +
- + /* Digital Interface */
- + SND_SOC_DAPM_SUPPLY("I2S1", RT5671_PWR_DIG1,
- + RT5671_PWR_I2S1_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("I2S2", RT5671_PWR_DIG1,
- + RT5671_PWR_I2S2_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF2 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF2 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("I2S3", RT5671_PWR_DIG1,
- + RT5671_PWR_I2S3_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF3 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF3 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF3 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF3 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF3 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF3 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF4 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF4 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF4 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF4 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF4 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("IF4 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("I2S4", RT5671_PWR_DIG1,
- + RT5671_PWR_I2S4_BIT, 0, NULL, 0),
- +
- + /* Digital Interface Select */
- + SND_SOC_DAPM_MUX("IF1 ADC1 IN1 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_if1_adc1_in1_mux),
- + SND_SOC_DAPM_MUX("IF1 ADC1 IN2 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_if1_adc1_in2_mux),
- + SND_SOC_DAPM_MUX("IF1 ADC2 IN Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_if1_adc2_in_mux),
- + SND_SOC_DAPM_MUX("IF1 ADC2 IN1 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_if1_adc2_in1_mux),
- + SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_vad_adc_mux),
- +
- + /* Audio Interface */
- + SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_AIF_IN("AIF3RX", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_AIF_OUT("AIF3TX", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_AIF_IN("AIF4RX", "AIF4 Playback", 0, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_AIF_OUT("AIF4TX", "AIF4 Capture", 0, SND_SOC_NOPM, 0, 0),
- +
- + /* Audio DSP */
- + SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
- +
- + /* Output Side */
- + /* DAC mixer before sound effect */
- + SND_SOC_DAPM_MIXER("DAC1 MIXL", RT5671_GEN_CTRL2, 12, 0,
- + rt5671_dac_l_mix, ARRAY_SIZE(rt5671_dac_l_mix)),
- + SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
- + rt5671_dac_r_mix, ARRAY_SIZE(rt5671_dac_r_mix)),
- + SND_SOC_DAPM_PGA("DAC1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
- +
- + /* DAC2 channel Mux */
- + SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_dac_l2_mux),
- + SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_dac_r2_mux),
- + SND_SOC_DAPM_PGA("DAC L2 Volume", RT5671_PWR_DIG1,
- + RT5671_PWR_DAC_L2_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("DAC R2 Volume", RT5671_PWR_DIG1,
- + RT5671_PWR_DAC_R2_BIT, 0, NULL, 0),
- +
- + SND_SOC_DAPM_MUX("DAC1 L Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_dac1l_mux),
- + SND_SOC_DAPM_MUX("DAC1 R Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_dac1r_mux),
- +
- + /* Sidetone */
- + SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_sidetone_mux),
- + SND_SOC_DAPM_MUX("ANC Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_anc_mux),
- + SND_SOC_DAPM_PGA("SNC", SND_SOC_NOPM,
- + 0, 0, NULL, 0),
- + /* DAC Mixer */
- + SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5671_PWR_DIG2,
- + RT5671_PWR_DAC_S1F_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("dac mono left filter", RT5671_PWR_DIG2,
- + RT5671_PWR_DAC_MF_L_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("dac mono right filter", RT5671_PWR_DIG2,
- + RT5671_PWR_DAC_MF_R_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
- + rt5671_sto_dac_l_mix, ARRAY_SIZE(rt5671_sto_dac_l_mix)),
- + SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
- + rt5671_sto_dac_r_mix, ARRAY_SIZE(rt5671_sto_dac_r_mix)),
- + SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
- + rt5671_mono_dac_l_mix, ARRAY_SIZE(rt5671_mono_dac_l_mix)),
- + SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
- + rt5671_mono_dac_r_mix, ARRAY_SIZE(rt5671_mono_dac_r_mix)),
- + SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
- + rt5671_dig_l_mix, ARRAY_SIZE(rt5671_dig_l_mix)),
- + SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
- + rt5671_dig_r_mix, ARRAY_SIZE(rt5671_dig_r_mix)),
- + SND_SOC_DAPM_PGA("DAC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
- +
- + /* DACs */
- + SND_SOC_DAPM_SUPPLY("DAC L1 Power", RT5671_PWR_DIG1,
- + RT5671_PWR_DAC_L1_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5671_PWR_DIG1,
- + RT5671_PWR_DAC_R1_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0),
- + SND_SOC_DAPM_DAC("DAC L2", NULL, RT5671_PWR_DIG1,
- + RT5671_PWR_DAC_L2_BIT, 0),
- +
- + SND_SOC_DAPM_DAC("DAC R2", NULL, RT5671_PWR_DIG1,
- + RT5671_PWR_DAC_R2_BIT, 0),
- + /* OUT Mixer */
- +
- + SND_SOC_DAPM_MIXER("OUT MIXL", RT5671_PWR_MIXER, RT5671_PWR_OM_L_BIT,
- + 0, rt5671_out_l_mix, ARRAY_SIZE(rt5671_out_l_mix)),
- + SND_SOC_DAPM_MIXER("OUT MIXR", RT5671_PWR_MIXER, RT5671_PWR_OM_R_BIT,
- + 0, rt5671_out_r_mix, ARRAY_SIZE(rt5671_out_r_mix)),
- + /* Ouput Volume */
- + SND_SOC_DAPM_MIXER("HPOVOL MIXL", RT5671_PWR_VOL, RT5671_PWR_HV_L_BIT,
- + 0, rt5671_hpvoll_mix, ARRAY_SIZE(rt5671_hpvoll_mix)),
- + SND_SOC_DAPM_MIXER("HPOVOL MIXR", RT5671_PWR_VOL, RT5671_PWR_HV_R_BIT,
- + 0, rt5671_hpvolr_mix, ARRAY_SIZE(rt5671_hpvolr_mix)),
- + SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM,
- + 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM,
- + 0, 0, NULL, 0),
- + SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM,
- + 0, 0, NULL, 0),
- +
- + /* HPO/LOUT/Mono Mixer */
- + SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0,
- + rt5671_hpo_mix, ARRAY_SIZE(rt5671_hpo_mix)),
- + SND_SOC_DAPM_MIXER("LOUT MIX", RT5671_PWR_ANLG1, RT5671_PWR_LM_BIT,
- + 0, rt5671_lout_mix, ARRAY_SIZE(rt5671_lout_mix)),
- + SND_SOC_DAPM_MIXER("MONOVOL MIX", RT5671_PWR_ANLG1, RT5671_PWR_MM_BIT,
- + 0, rt5671_mono_mix, ARRAY_SIZE(rt5671_mono_mix)),
- + SND_SOC_DAPM_MIXER("MONOAmp MIX", SND_SOC_NOPM, 0,
- + 0, rt5671_monoamp_mix, ARRAY_SIZE(rt5671_monoamp_mix)),
- +
- + SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM,
- + 0, 0, rt5671_hp_power_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
- + SND_SOC_DAPM_SUPPLY("HP L Amp", RT5671_PWR_ANLG1,
- + RT5671_PWR_HP_L_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("HP R Amp", RT5671_PWR_ANLG1,
- + RT5671_PWR_HP_R_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0,
- + rt5671_hp_event, SND_SOC_DAPM_PRE_PMD |
- + SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_PGA_S("LOUT Amp", 1, SND_SOC_NOPM, 0, 0,
- + rt5671_lout_event, SND_SOC_DAPM_PRE_PMD |
- + SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_PGA_S("Mono Amp", 1, RT5671_PWR_ANLG1,
- + RT5671_PWR_MA_BIT, 0, rt5671_mono_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- +
- + /* PDM */
- + SND_SOC_DAPM_SUPPLY("PDM1 Power", RT5671_PWR_DIG2,
- + RT5671_PWR_PDM1_BIT, 0, NULL, 0),
- + SND_SOC_DAPM_SUPPLY("PDM2 Power", RT5671_PWR_DIG2,
- + RT5671_PWR_PDM2_BIT, 0, NULL, 0),
- +
- + SND_SOC_DAPM_MUX_E("PDM1 L Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_pdm1_l_mux, rt5671_pdm1_l_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_MUX_E("PDM1 R Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_pdm1_r_mux, rt5671_pdm1_r_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_MUX_E("PDM2 L Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_pdm2_l_mux, rt5671_pdm2_l_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_MUX_E("PDM2 R Mux", SND_SOC_NOPM, 0, 0,
- + &rt5671_pdm2_r_mux, rt5671_pdm2_r_event,
- + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- +
- + /* Output Lines */
- + SND_SOC_DAPM_OUTPUT("HPOL"),
- + SND_SOC_DAPM_OUTPUT("HPOR"),
- + SND_SOC_DAPM_OUTPUT("LOUTL"),
- + SND_SOC_DAPM_OUTPUT("LOUTR"),
- + SND_SOC_DAPM_OUTPUT("MonoP"),
- + SND_SOC_DAPM_OUTPUT("MonoN"),
- + SND_SOC_DAPM_OUTPUT("PDM1L"),
- + SND_SOC_DAPM_OUTPUT("PDM1R"),
- + SND_SOC_DAPM_OUTPUT("PDM2L"),
- + SND_SOC_DAPM_OUTPUT("PDM2R"),
- +};
- +
- +static const struct snd_soc_dapm_route rt5671_dapm_routes[] = {
- + { "adc stereo1 filter", NULL, "ADC STO1 ASRC", check_adc_sto1_asrc_source },
- + { "adc stereo2 filter", NULL, "ADC STO2 ASRC", check_adc_sto2_asrc_source },
- + { "adc mono left filter", NULL, "ADC MONO L ASRC", check_adc_monol_asrc_source },
- + { "adc mono right filter", NULL, "ADC MONO R ASRC", check_adc_monor_asrc_source },
- + { "dac mono left filter", NULL, "DAC MONO L ASRC", check_dac_monol_asrc_source },
- + { "dac mono right filter", NULL, "DAC MONO R ASRC", check_dac_monor_asrc_source },
- + { "dac stereo1 filter", NULL, "DAC STO ASRC", check_dac_sto_asrc_source },
- +
- + {"I2S1", NULL, "I2S1 ASRC"},
- + {"I2S2", NULL, "I2S2 ASRC"},
- + {"I2S3", NULL, "I2S3 ASRC"},
- + {"I2S4", NULL, "I2S4 ASRC"},
- +
- + { "micbias1", NULL, "DAC L1 Power" },
- + { "micbias1", NULL, "DAC R1 Power" },
- + { "micbias2", NULL, "DAC L1 Power" },
- + { "micbias2", NULL, "DAC R1 Power" },
- +
- + { "DMIC1", NULL, "DMIC L1" },
- + { "DMIC1", NULL, "DMIC R1" },
- + { "DMIC2", NULL, "DMIC L2" },
- + { "DMIC2", NULL, "DMIC R2" },
- + { "DMIC3", NULL, "DMIC L3" },
- + { "DMIC3", NULL, "DMIC R3" },
- +
- + { "BST1", NULL, "IN1P" },
- + { "BST1", NULL, "IN1N" },
- + { "BST1", NULL, "Mic Det Power" },
- + { "BST2", NULL, "IN2P" },
- + { "BST2", NULL, "IN2N" },
- + { "BST3", NULL, "IN3P" },
- + { "BST3", NULL, "IN3N" },
- + { "BST4", NULL, "IN4P" },
- + { "BST4", NULL, "IN4N" },
- +
- + { "INL VOL", NULL, "IN3P" },
- + { "INR VOL", NULL, "IN3N" },
- +
- + { "RECMIXL", "INL Switch", "INL VOL" },
- + { "RECMIXL", "BST4 Switch", "BST4" },
- + { "RECMIXL", "BST3 Switch", "BST3" },
- + { "RECMIXL", "BST2 Switch", "BST2" },
- + { "RECMIXL", "BST1 Switch", "BST1" },
- +
- + { "RECMIXR", "INR Switch", "INR VOL" },
- + { "RECMIXR", "BST4 Switch", "BST4" },
- + { "RECMIXR", "BST3 Switch", "BST3" },
- + { "RECMIXR", "BST2 Switch", "BST2" },
- + { "RECMIXR", "BST1 Switch", "BST1" },
- +
- + { "RECMIXM", "BST4 Switch", "BST4" },
- + { "RECMIXM", "BST3 Switch", "BST3" },
- + { "RECMIXM", "BST2 Switch", "BST2" },
- + { "RECMIXM", "BST1 Switch", "BST1" },
- +
- + { "ADC 1", NULL, "RECMIXL" },
- + { "ADC 1", NULL, "ADC 1 power" },
- + { "ADC 1", NULL, "ADC clock" },
- + { "ADC 2", NULL, "RECMIXR" },
- + { "ADC 2", NULL, "ADC 2 power" },
- + { "ADC 2", NULL, "ADC clock" },
- + { "ADC 3", NULL, "RECMIXM" },
- + { "ADC 3", NULL, "ADC 3 power" },
- + { "ADC 3", NULL, "ADC clock" },
- +
- + { "DMIC L1", NULL, "DMIC CLK" },
- + { "DMIC R1", NULL, "DMIC CLK" },
- + { "DMIC L2", NULL, "DMIC CLK" },
- + { "DMIC R2", NULL, "DMIC CLK" },
- + { "DMIC L3", NULL, "DMIC CLK" },
- + { "DMIC R3", NULL, "DMIC CLK" },
- +
- + { "DMIC L1", NULL, "DMIC1 Power" },
- + { "DMIC R1", NULL, "DMIC1 Power" },
- + { "DMIC L2", NULL, "DMIC2 Power" },
- + { "DMIC R2", NULL, "DMIC2 Power" },
- + { "DMIC L3", NULL, "DMIC3 Power" },
- + { "DMIC R3", NULL, "DMIC3 Power" },
- +
- + { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" },
- + { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" },
- + { "Stereo1 DMIC Mux", "DMIC3", "DMIC3" },
- +
- + { "Stereo2 DMIC Mux", "DMIC1", "DMIC1" },
- + { "Stereo2 DMIC Mux", "DMIC2", "DMIC2" },
- + { "Stereo2 DMIC Mux", "DMIC3", "DMIC3" },
- +
- + { "Mono DMIC L Mux", "DMIC1", "DMIC L1" },
- + { "Mono DMIC L Mux", "DMIC2", "DMIC L2" },
- + { "Mono DMIC L Mux", "DMIC3", "DMIC L3" },
- +
- + { "Mono DMIC R Mux", "DMIC1", "DMIC R1" },
- + { "Mono DMIC R Mux", "DMIC2", "DMIC R2" },
- + { "Mono DMIC R Mux", "DMIC3", "DMIC R3" },
- +
- + { "ADC 1_2", "ADC", "ADC 1" },
- + { "ADC 1_2", "ADC", "ADC 2" },
- +
- + { "ADC 1_2", "Stereo DAC", "Stereo DAC MIXL" },
- + { "ADC 1_2", "Stereo DAC", "Stereo DAC MIXR" },
- +
- + { "Stereo1 ADC Mux", "ADC1L ADC2R", "ADC 1_2" },
- + { "Stereo1 ADC Mux", "ADC3", "ADC 3" },
- +
- + { "DAC MIX", NULL, "DAC MIXL" },
- + { "DAC MIX", NULL, "DAC MIXR" },
- +
- + { "Stereo1 ADC2 Mux", "DMIC", "Stereo1 DMIC Mux" },
- + { "Stereo1 ADC2 Mux", "DAC MIX", "DAC MIX" },
- + { "Stereo1 ADC1 Mux", "ADC", "Stereo1 ADC Mux" },
- + { "Stereo1 ADC1 Mux", "DAC MIX", "DAC MIX" },
- +
- + { "Mono ADC L Mux", "ADC1", "ADC 1" },
- + { "Mono ADC L Mux", "ADC3", "ADC 3" },
- +
- + { "Mono ADC R Mux", "ADC2", "ADC 2" },
- + { "Mono ADC R Mux", "ADC3", "ADC 3" },
- +
- + { "Mono ADC L2 Mux", "DMIC", "Mono DMIC L Mux" },
- + { "Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
- + { "Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
- + { "Mono ADC L1 Mux", "ADC1 ADC3", "Mono ADC L Mux" },
- +
- + { "Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
- + { "Mono ADC R1 Mux", "ADC2 ADC3", "Mono ADC R Mux" },
- + { "Mono ADC R2 Mux", "DMIC", "Mono DMIC R Mux" },
- + { "Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
- +
- + { "Sto1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC1 Mux" },
- + { "Sto1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC2 Mux" },
- + { "Sto1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC1 Mux" },
- + { "Sto1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC2 Mux" },
- +
- + { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
- + { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" },
- +
- + { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
- + { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" },
- + { "adc stereo1 filter", NULL, "PLL1", check_sysclk1_source },
- +
- + { "Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux" },
- + { "Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux" },
- + { "Mono ADC MIXL", NULL, "adc mono left filter" },
- + { "adc mono left filter", NULL, "PLL1", check_sysclk1_source },
- +
- + { "Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux" },
- + { "Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux" },
- + { "Mono ADC MIXR", NULL, "adc mono right filter" },
- + { "adc mono right filter", NULL, "PLL1", check_sysclk1_source },
- +
- + { "Stereo2 ADC Mux", "ADC1L ADC2R", "ADC 1_2" },
- + { "Stereo2 ADC Mux", "ADC3", "ADC 3" },
- +
- + { "Stereo2 ADC2 Mux", "DMIC", "Stereo2 DMIC Mux" },
- + { "Stereo2 ADC2 Mux", "DAC MIX", "DAC MIX" },
- + { "Stereo2 ADC1 Mux", "ADC", "Stereo2 ADC Mux" },
- + { "Stereo2 ADC1 Mux", "DAC MIX", "DAC MIX" },
- +
- + { "Sto2 ADC MIXL", "ADC1 Switch", "Stereo2 ADC1 Mux" },
- + { "Sto2 ADC MIXL", "ADC2 Switch", "Stereo2 ADC2 Mux" },
- + { "Sto2 ADC MIXR", "ADC1 Switch", "Stereo2 ADC1 Mux" },
- + { "Sto2 ADC MIXR", "ADC2 Switch", "Stereo2 ADC2 Mux" },
- +
- + { "Sto2 ADC LR MIX", NULL, "Sto2 ADC MIXL" },
- + { "Sto2 ADC LR MIX", NULL, "Sto2 ADC MIXR" },
- +
- + { "Stereo2 ADC LR Mux", "L", "Sto2 ADC MIXL" },
- + { "Stereo2 ADC LR Mux", "LR", "Sto2 ADC LR MIX" },
- +
- + { "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" },
- + { "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" },
- +
- + { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" },
- + { "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" },
- + { "adc stereo2 filter", NULL, "PLL1", check_sysclk1_source },
- +
- + { "VAD ADC Mux", "Sto1 ADC L", "Stereo1 ADC MIXL" },
- + { "VAD ADC Mux", "Mono ADC L", "Mono ADC MIXL" },
- + { "VAD ADC Mux", "Mono ADC R", "Mono ADC MIXR" },
- + { "VAD ADC Mux", "Sto2 ADC L", "Stereo2 ADC MIXL" },
- +
- + { "VAD_ADC", NULL, "VAD ADC Mux" },
- +
- + { "IF_ADC1", NULL, "Stereo1 ADC MIXL" },
- + { "IF_ADC1", NULL, "Stereo1 ADC MIXR" },
- + { "IF_ADC2", NULL, "Mono ADC MIXL" },
- + { "IF_ADC2", NULL, "Mono ADC MIXR" },
- + { "IF_ADC3", NULL, "Stereo2 ADC MIXL" },
- + { "IF_ADC3", NULL, "Stereo2 ADC MIXR" },
- +
- + { "IF1 ADC1 IN1 Mux", "IF_ADC1", "IF_ADC1" },
- + { "IF1 ADC1 IN1 Mux", "IF1_ADC3", "IF_ADC3" },
- +
- + { "IF1 ADC1 IN2 Mux", "IF1_ADC1_IN1", "IF1 ADC1 IN1 Mux" },
- + { "IF1 ADC1 IN2 Mux", "IF1_ADC4", "TxDP_ADC" },
- +
- + { "IF1 ADC2 IN Mux", "IF_ADC2", "IF_ADC2" },
- + { "IF1 ADC2 IN Mux", "VAD_ADC", "VAD_ADC" },
- +
- + { "IF1 ADC2 IN1 Mux", "IF1_ADC2_IN", "IF1 ADC2 IN Mux" },
- + { "IF1 ADC2 IN1 Mux", "IF1_ADC4", "TxDP_ADC" },
- +
- + { "IF1_ADC1" , NULL, "IF1 ADC1 IN2 Mux" },
- + { "IF1_ADC2" , NULL, "IF1 ADC2 IN1 Mux" },
- +
- + { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXL" },
- + { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR" },
- + { "Stereo2 ADC MIX", NULL, "Stereo2 ADC MIXL" },
- + { "Stereo2 ADC MIX", NULL, "Stereo2 ADC MIXR" },
- + { "Mono ADC MIX", NULL, "Mono ADC MIXL" },
- + { "Mono ADC MIX", NULL, "Mono ADC MIXR" },
- +
- + { "RxDP Mux", "IF2 DAC", "IF2 DAC" },
- + { "RxDP Mux", "IF1 DAC", "IF1 DAC2" },
- + { "RxDP Mux", "STO1 ADC Mixer", "Stereo1 ADC MIX" },
- + { "RxDP Mux", "STO2 ADC Mixer", "Stereo2 ADC MIX" },
- + { "RxDP Mux", "Mono ADC Mixer L", "Mono ADC MIXL" },
- + { "RxDP Mux", "Mono ADC Mixer R", "Mono ADC MIXR" },
- + { "RxDP Mux", "DAC1", "DAC1 MIX" },
- +
- + { "TDM Data Mux", "Slot 0-1", "Stereo1 ADC MIX" },
- + { "TDM Data Mux", "Slot 2-3", "Mono ADC MIX" },
- + { "TDM Data Mux", "Slot 4-5", "Stereo2 ADC MIX" },
- + { "TDM Data Mux", "Slot 6-7", "IF2 DAC" },
- +
- + { "DSP UL Mux", "Bypass", "TDM Data Mux" },
- + { "DSP UL Mux", NULL, "I2S DSP" },
- + { "DSP DL Mux", "Bypass", "RxDP Mux" },
- + { "DSP DL Mux", NULL, "I2S DSP" },
- +
- + { "TxDP_ADC_L", NULL, "DSP UL Mux" },
- + { "TxDP_ADC_R", NULL, "DSP UL Mux" },
- + { "TxDC_DAC", NULL, "DSP DL Mux" },
- +
- + { "TxDP_ADC", NULL, "TxDP_ADC_L" },
- + { "TxDP_ADC", NULL, "TxDP_ADC_R" },
- +
- + { "IF1 ADC", NULL, "I2S1" },
- +#ifdef USE_TDM
- + { "IF1 ADC", NULL, "IF1_ADC1" },
- + { "IF1 ADC", NULL, "IF1_ADC2" },
- + { "IF1 ADC", NULL, "IF_ADC3" },
- + { "IF1 ADC", NULL, "TxDP_ADC" },
- +#else
- + { "IF1 ADC Mux", "IF1_ADC1", "IF1_ADC1" },
- + { "IF1 ADC Mux", "IF1_ADC2", "IF1_ADC2" },
- + { "IF1 ADC Mux", "IF_ADC3", "IF_ADC3" },
- + { "IF1 ADC Mux", "TxDC_DAC", "TxDC_DAC" },
- + { "IF1 ADC", NULL, "IF1 ADC Mux" },
- +#endif
- + { "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" },
- + { "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" },
- + { "IF2 ADC Mux", "IF_ADC3", "IF_ADC3" },
- + { "IF2 ADC Mux", "TxDC_DAC", "TxDC_DAC" },
- + { "IF2 ADC Mux", "TxDP_ADC", "TxDP_ADC" },
- + { "IF2 ADC Mux", "VAD_ADC", "VAD_ADC" },
- +
- + { "IF3 ADC Mux", "IF_ADC1", "IF_ADC1" },
- + { "IF3 ADC Mux", "IF_ADC2", "IF_ADC2" },
- + { "IF3 ADC Mux", "IF_ADC3", "IF_ADC3" },
- + { "IF3 ADC Mux", "TxDC_DAC", "TxDC_DAC" },
- + { "IF3 ADC Mux", "TxDP_ADC", "TxDP_ADC" },
- + { "IF3 ADC Mux", "VAD_ADC", "VAD_ADC" },
- +
- + { "IF4 ADC Mux", "IF_ADC1", "IF_ADC1" },
- + { "IF4 ADC Mux", "IF_ADC2", "IF_ADC2" },
- + { "IF4 ADC Mux", "IF_ADC3", "IF_ADC3" },
- +
- + { "IF2 ADC L", NULL, "IF2 ADC Mux" },
- + { "IF2 ADC R", NULL, "IF2 ADC Mux" },
- + { "IF3 ADC L", NULL, "IF3 ADC Mux" },
- + { "IF3 ADC R", NULL, "IF3 ADC Mux" },
- + { "IF4 ADC L", NULL, "IF4 ADC Mux" },
- + { "IF4 ADC R", NULL, "IF4 ADC Mux" },
- +
- + { "IF2 ADC", NULL, "I2S2" },
- + { "IF2 ADC", NULL, "IF2 ADC L" },
- + { "IF2 ADC", NULL, "IF2 ADC R" },
- + { "IF3 ADC", NULL, "I2S3" },
- + { "IF3 ADC", NULL, "IF3 ADC L" },
- + { "IF3 ADC", NULL, "IF3 ADC R" },
- + { "IF4 ADC", NULL, "I2S4" },
- + { "IF4 ADC", NULL, "IF4 ADC L" },
- + { "IF4 ADC", NULL, "IF4 ADC R" },
- +
- + { "AIF1TX", NULL, "IF1 ADC" },
- + { "AIF2TX", NULL, "IF2 ADC" },
- + { "AIF3TX", NULL, "IF3 ADC" },
- + { "AIF4TX", NULL, "IF4 ADC" },
- +
- + { "IF1 DAC1", NULL, "AIF1RX" },
- + { "IF1 DAC2", NULL, "AIF1RX" },
- + { "IF2 DAC", NULL, "AIF2RX" },
- + { "IF3 DAC", NULL, "AIF3RX" },
- + { "IF4 DAC", NULL, "AIF4RX" },
- +
- + { "IF1 DAC1", NULL, "I2S1" },
- + { "IF1 DAC2", NULL, "I2S1" },
- + { "IF2 DAC", NULL, "I2S2" },
- + { "IF3 DAC", NULL, "I2S3" },
- + { "IF4 DAC", NULL, "I2S4" },
- +
- + { "IF1 DAC2 L", NULL, "IF1 DAC2" },
- + { "IF1 DAC2 R", NULL, "IF1 DAC2" },
- + { "IF1 DAC1 L", NULL, "IF1 DAC1" },
- + { "IF1 DAC1 R", NULL, "IF1 DAC1" },
- + { "IF2 DAC L", NULL, "IF2 DAC" },
- + { "IF2 DAC R", NULL, "IF2 DAC" },
- + { "IF3 DAC L", NULL, "IF3 DAC" },
- + { "IF3 DAC R", NULL, "IF3 DAC" },
- + { "IF4 DAC L", NULL, "IF4 DAC" },
- + { "IF4 DAC R", NULL, "IF4 DAC" },
- +
- + { "Sidetone Mux", "DMIC L1", "DMIC L1" },
- + { "Sidetone Mux", "DMIC L2", "DMIC L2" },
- + { "Sidetone Mux", "DMIC L3", "DMIC L3" },
- + { "Sidetone Mux", "ADC 1", "ADC 1" },
- + { "Sidetone Mux", "ADC 2", "ADC 2" },
- + { "Sidetone Mux", "ADC 3", "ADC 3" },
- +
- + { "DAC1 L Mux", "IF1 DAC", "IF1 DAC1 L" },
- + { "DAC1 L Mux", "IF2 DAC", "IF2 DAC L" },
- + { "DAC1 L Mux", "IF3 DAC", "IF3 DAC L" },
- + { "DAC1 L Mux", "IF4 DAC", "IF4 DAC L" },
- +
- + { "DAC1 R Mux", "IF1 DAC", "IF1 DAC1 R" },
- + { "DAC1 R Mux", "IF2 DAC", "IF2 DAC R" },
- + { "DAC1 R Mux", "IF3 DAC", "IF3 DAC R" },
- + { "DAC1 R Mux", "IF4 DAC", "IF4 DAC R" },
- +
- + { "DAC1 MIXL", NULL, "DAC L1 Power" },
- + { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" },
- + { "DAC1 MIXL", "DAC1 Switch", "DAC1 L Mux" },
- + { "DAC1 MIXL", NULL, "dac stereo1 filter" },
- + { "DAC1 MIXR", NULL, "DAC R1 Power" },
- + { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" },
- + { "DAC1 MIXR", "DAC1 Switch", "DAC1 R Mux" },
- + { "DAC1 MIXR", NULL, "dac stereo1 filter" },
- +
- + { "DAC1 MIX", NULL, "DAC1 MIXL" },
- + { "DAC1 MIX", NULL, "DAC1 MIXR" },
- +
- + { "Audio DSP", NULL, "DAC1 MIXL" },
- + { "Audio DSP", NULL, "DAC1 MIXR" },
- +
- + { "DAC L2 Mux", "IF1 DAC", "IF1 DAC2 L" },
- + { "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" },
- + { "DAC L2 Mux", "IF3 DAC", "IF3 DAC L" },
- + { "DAC L2 Mux", "IF4 DAC", "IF4 DAC L" },
- + { "DAC L2 Mux", "TxDC DAC", "TxDC_DAC" },
- + { "DAC L2 Mux", "VAD_ADC", "VAD_ADC" },
- + { "DAC L2 Volume", NULL, "DAC L2 Mux" },
- + { "DAC L2 Volume", NULL, "dac mono left filter" },
- +
- + { "DAC R2 Mux", "IF1 DAC", "IF1 DAC2 R" },
- + { "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" },
- + { "DAC R2 Mux", "IF3 DAC", "IF3 DAC R" },
- + { "DAC R2 Mux", "IF4 DAC", "IF4 DAC R" },
- + { "DAC R2 Mux", "TxDC DAC", "TxDC_DAC" },
- + { "DAC R2 Mux", "TxDP ADC", "TxDP_ADC" },
- + { "DAC R2 Volume", NULL, "DAC R2 Mux" },
- + { "DAC R2 Volume", NULL, "dac mono right filter" },
- +
- + { "SNC", NULL, "ADC 1" },
- + { "SNC", NULL, "ADC 2" },
- +
- + { "ANC Mux", "SNC", "SNC" },
- + { "ANC Mux", "Sidetone", "Sidetone Mux" },
- +
- + { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
- + { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
- + { "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
- + { "Stereo DAC MIXL", "ANC Switch", "ANC Mux" },
- + { "Stereo DAC MIXL", NULL, "dac stereo1 filter" },
- + { "Stereo DAC MIXL", NULL, "DAC L1 Power" },
- + { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
- + { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
- + { "Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
- + { "Stereo DAC MIXR", "ANC Switch", "ANC Mux" },
- + { "Stereo DAC MIXR", NULL, "dac stereo1 filter" },
- + { "Stereo DAC MIXR", NULL, "DAC R1 Power" },
- +
- + { "Mono DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
- + { "Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
- + { "Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
- + { "Mono DAC MIXL", "Sidetone Switch", "Sidetone Mux" },
- + { "Mono DAC MIXL", NULL, "dac mono left filter" },
- + { "Mono DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
- + { "Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
- + { "Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
- + { "Mono DAC MIXR", "Sidetone Switch", "Sidetone Mux" },
- + { "Mono DAC MIXR", NULL, "dac mono right filter" },
- +
- + { "DAC MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
- + { "DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
- + { "DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
- + { "DAC MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
- + { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
- + { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
- +
- + { "DAC L1", NULL, "Stereo DAC MIXL" },
- + { "DAC L1", NULL, "PLL1", check_sysclk1_source },
- + { "DAC R1", NULL, "Stereo DAC MIXR" },
- + { "DAC R1", NULL, "PLL1", check_sysclk1_source },
- + { "DAC L2", NULL, "Mono DAC MIXL" },
- + { "DAC L2", NULL, "PLL1", check_sysclk1_source },
- + { "DAC R2", NULL, "Mono DAC MIXR" },
- + { "DAC R2", NULL, "PLL1", check_sysclk1_source },
- +
- + { "OUT MIXL", "BST2 Switch", "BST2" },
- + { "OUT MIXL", "BST1 Switch", "BST1" },
- + { "OUT MIXL", "INL Switch", "INL VOL" },
- + { "OUT MIXL", "DAC L2 Switch", "DAC L2" },
- + { "OUT MIXL", "DAC L1 Switch", "DAC L1" },
- +
- + { "OUT MIXR", "BST4 Switch", "BST4" },
- + { "OUT MIXR", "BST3 Switch", "BST3" },
- + { "OUT MIXR", "INR Switch", "INR VOL" },
- + { "OUT MIXR", "DAC R2 Switch", "DAC R2" },
- + { "OUT MIXR", "DAC R1 Switch", "DAC R1" },
- +
- + { "HPOVOL MIXL", "DAC1 Switch", "DAC L1" },
- + { "HPOVOL MIXL", "INL Switch", "INL VOL" },
- + { "HPOVOL MIXR", "DAC1 Switch", "DAC R1" },
- + { "HPOVOL MIXR", "INR Switch", "INR VOL" },
- +
- + { "DAC 2", NULL, "DAC L2" },
- + { "DAC 2", NULL, "DAC R2" },
- + { "DAC 1", NULL, "DAC L1" },
- + { "DAC 1", NULL, "DAC R1" },
- + { "HPOVOL", NULL, "HPOVOL MIXL" },
- + { "HPOVOL", NULL, "HPOVOL MIXR" },
- + { "HPO MIX", "DAC1 Switch", "DAC 1" },
- + { "HPO MIX", "HPVOL Switch", "HPOVOL" },
- +
- + { "LOUT MIX", "DAC L1 Switch", "DAC L1" },
- + { "LOUT MIX", "DAC R1 Switch", "DAC R1" },
- + { "LOUT MIX", "OUTMIX L Switch", "OUT MIXL" },
- + { "LOUT MIX", "OUTMIX R Switch", "OUT MIXR" },
- +
- + { "MONOVOL MIX", "DAC R2 Switch", "DAC R2" },
- + { "MONOVOL MIX", "DAC L2 Switch", "DAC L2" },
- + { "MONOVOL MIX", "BST4 Switch", "BST4" },
- +
- + { "MONOAmp MIX", "DAC L1 Switch", "DAC L1" },
- + { "MONOAmp MIX", "MONOVOL Switch", "MONOVOL MIX" },
- +
- + { "PDM1 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
- + { "PDM1 L Mux", "Mono DAC", "Mono DAC MIXL" },
- + { "PDM1 L Mux", NULL, "PDM1 Power" },
- + { "PDM1 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
- + { "PDM1 R Mux", "Mono DAC", "Mono DAC MIXR" },
- + { "PDM1 R Mux", NULL, "PDM1 Power" },
- + { "PDM2 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
- + { "PDM2 L Mux", "Mono DAC", "Mono DAC MIXL" },
- + { "PDM2 L Mux", NULL, "PDM2 Power" },
- + { "PDM2 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
- + { "PDM2 R Mux", "Mono DAC", "Mono DAC MIXR" },
- + { "PDM2 R Mux", NULL, "PDM2 Power" },
- +
- + { "HP Amp", NULL, "HPO MIX" },
- + { "HP Amp", NULL, "Mic Det Power" },
- + { "HPOL", NULL, "HP Amp" },
- + { "HPOL", NULL, "HP L Amp" },
- + { "HPOL", NULL, "Improve HP Amp Drv" },
- + { "HPOR", NULL, "HP Amp" },
- + { "HPOR", NULL, "HP R Amp" },
- + { "HPOR", NULL, "Improve HP Amp Drv" },
- +
- + { "LOUT Amp", NULL, "LOUT MIX" },
- + { "LOUTL", NULL, "LOUT Amp" },
- + { "LOUTR", NULL, "LOUT Amp" },
- + { "LOUTL", NULL, "Improve HP Amp Drv" },
- + { "LOUTR", NULL, "Improve HP Amp Drv" },
- +
- + { "Mono Amp", NULL, "MONOAmp MIX" },
- + { "MonoP", NULL, "Mono Amp" },
- + { "MonoN", NULL, "Mono Amp" },
- +
- + { "PDM1L", NULL, "PDM1 L Mux" },
- + { "PDM1R", NULL, "PDM1 R Mux" },
- + { "PDM2L", NULL, "PDM2 L Mux" },
- + { "PDM2R", NULL, "PDM2 R Mux" },
- +};
- +
- +static int get_clk_info(int sclk, int rate)
- +{
- + int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
- +
- + if (sclk <= 0 || rate <= 0)
- + return -EINVAL;
- +
- + rate = rate << 8;
- + for (i = 0; i < ARRAY_SIZE(pd); i++)
- + if (sclk == rate * pd[i])
- + return i;
- +
- + return -EINVAL;
- +}
- +
- +static int rt5671_hw_params(struct snd_pcm_substream *substream,
- + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
- +{
- + struct snd_soc_codec *codec = dai->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- + unsigned int val = 0, val_clk, mask_clk;
- + int pre_div, bclk_ms;
- +
- + rt5671->lrck[dai->id] = params_rate(params);
- + pre_div = get_clk_info(rt5671->sysclk, rt5671->lrck[dai->id]);
- + if (pre_div < 0) {
- + dev_err(codec->dev, "Unsupported clock setting\n");
- + return -EINVAL;
- + }
- +
- + if (rt5671->pdata.bclk_32fs[dai->id])
- + bclk_ms = 0;
- + else
- + bclk_ms = 1;
- + rt5671->bclk[dai->id] = rt5671->lrck[dai->id] * (32 << bclk_ms);
- +
- + dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
- + rt5671->bclk[dai->id], rt5671->lrck[dai->id]);
- + dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
- + bclk_ms, pre_div, dai->id);
- +
- + switch (params_format(params)) {
- + case SNDRV_PCM_FORMAT_S16_LE:
- + break;
- + case SNDRV_PCM_FORMAT_S20_3LE:
- + val |= RT5671_I2S_DL_20;
- + break;
- + case SNDRV_PCM_FORMAT_S24_LE:
- + val |= RT5671_I2S_DL_24;
- + break;
- + case SNDRV_PCM_FORMAT_S8:
- + val |= RT5671_I2S_DL_8;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + if (rt5671->master[dai->id] == 0)
- + val |= RT5671_I2S_MS_S;
- +
- + switch (dai->id) {
- + case RT5671_AIF1:
- + mask_clk = RT5671_I2S_PD1_MASK;
- + val_clk = pre_div << RT5671_I2S_PD1_SFT;
- + snd_soc_update_bits(codec, RT5671_ADDA_CLK1, mask_clk, val_clk);
- + snd_soc_update_bits(codec, RT5671_I2S1_SDP,
- + RT5671_I2S_DL_MASK | RT5671_I2S_MS_MASK, val);
- + break;
- + case RT5671_AIF2:
- + mask_clk = RT5671_I2S_BCLK_MS2_MASK | RT5671_I2S_PD2_MASK;
- + val_clk = bclk_ms << RT5671_I2S_BCLK_MS2_SFT |
- + pre_div << RT5671_I2S_PD2_SFT;
- + snd_soc_update_bits(codec, RT5671_ADDA_CLK1, mask_clk, val_clk);
- + snd_soc_update_bits(codec, RT5671_I2S2_SDP,
- + RT5671_I2S_DL_MASK | RT5671_I2S_MS_MASK, val);
- + break;
- + case RT5671_AIF3:
- + mask_clk = RT5671_I2S_BCLK_MS3_MASK | RT5671_I2S_PD3_MASK;
- + val_clk = bclk_ms << RT5671_I2S_BCLK_MS3_SFT |
- + pre_div << RT5671_I2S_PD3_SFT;
- + snd_soc_update_bits(codec, RT5671_ADDA_CLK1, mask_clk, val_clk);
- + snd_soc_update_bits(codec, RT5671_I2S3_SDP,
- + RT5671_I2S_DL_MASK | RT5671_I2S_MS_MASK, val);
- + break;
- + case RT5671_AIF4:
- + mask_clk = RT5671_I2S_BCLK_MS4_MASK | RT5671_I2S_PD4_MASK;
- + val_clk = bclk_ms << RT5671_I2S_BCLK_MS4_SFT |
- + pre_div << RT5671_I2S_PD4_SFT;
- + snd_soc_update_bits(codec, RT5671_DSP_CLK, mask_clk, val_clk);
- + snd_soc_update_bits(codec, RT5671_I2S4_SDP,
- + RT5671_I2S_DL_MASK | RT5671_I2S_MS_MASK, val);
- + break;
- + }
- +
- + return 0;
- +}
- +
- +static void rt5671_shutdown(struct snd_pcm_substream *substream,
- + struct snd_soc_dai *dai)
- +{
- + struct snd_soc_codec *codec = dai->codec;
- +
- + if (!dai->active) {
- + switch (dai->id) {
- + case RT5671_AIF1:
- + snd_soc_update_bits(codec, RT5671_I2S1_SDP,
- + RT5671_I2S_MS_MASK, RT5671_I2S_MS_S);
- + break;
- + case RT5671_AIF2:
- + snd_soc_update_bits(codec, RT5671_I2S2_SDP,
- + RT5671_I2S_MS_MASK, RT5671_I2S_MS_S);
- + break;
- + case RT5671_AIF3:
- + snd_soc_update_bits(codec, RT5671_I2S3_SDP,
- + RT5671_I2S_MS_MASK, RT5671_I2S_MS_S);
- + break;
- + case RT5671_AIF4:
- + snd_soc_update_bits(codec, RT5671_I2S4_SDP,
- + RT5671_I2S_MS_MASK, RT5671_I2S_MS_S);
- + break;
- + }
- + }
- +}
- +
- +static int rt5671_prepare(struct snd_pcm_substream *substream,
- + struct snd_soc_dai *dai)
- +{
- + struct snd_soc_codec *codec = dai->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + rt5671->aif_pu = dai->id;
- + return 0;
- +}
- +
- +static int rt5671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
- +{
- + struct snd_soc_codec *codec = dai->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- + unsigned int reg_val = 0;
- +
- + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- + case SND_SOC_DAIFMT_CBM_CFM:
- + rt5671->master[dai->id] = 1;
- + break;
- + case SND_SOC_DAIFMT_CBS_CFS:
- + rt5671->master[dai->id] = 0;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- + case SND_SOC_DAIFMT_NB_NF:
- + break;
- + case SND_SOC_DAIFMT_IB_NF:
- + reg_val |= RT5671_I2S_BP_INV;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- + case SND_SOC_DAIFMT_I2S:
- + break;
- + case SND_SOC_DAIFMT_LEFT_J:
- + reg_val |= RT5671_I2S_DF_LEFT;
- + break;
- + case SND_SOC_DAIFMT_DSP_A:
- + reg_val |= RT5671_I2S_DF_PCM_A;
- + break;
- + case SND_SOC_DAIFMT_DSP_B:
- + reg_val |= RT5671_I2S_DF_PCM_B;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + switch (dai->id) {
- + case RT5671_AIF1:
- + snd_soc_update_bits(codec, RT5671_I2S1_SDP,
- + RT5671_I2S_BP_MASK |
- + RT5671_I2S_DF_MASK, reg_val);
- + break;
- + case RT5671_AIF2:
- + snd_soc_update_bits(codec, RT5671_I2S2_SDP,
- + RT5671_I2S_BP_MASK |
- + RT5671_I2S_DF_MASK, reg_val);
- + break;
- + case RT5671_AIF3:
- + snd_soc_update_bits(codec, RT5671_I2S3_SDP,
- + RT5671_I2S_BP_MASK |
- + RT5671_I2S_DF_MASK, reg_val);
- + break;
- + case RT5671_AIF4:
- + snd_soc_update_bits(codec, RT5671_I2S4_SDP,
- + RT5671_I2S_BP_MASK |
- + RT5671_I2S_DF_MASK, reg_val);
- + break;
- + }
- +
- + return 0;
- +}
- +
- +static int rt5671_set_dai_sysclk(struct snd_soc_dai *dai,
- + int clk_id, unsigned int freq, int dir)
- +{
- + struct snd_soc_codec *codec = dai->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- + unsigned int reg_val = 0;
- +
- + if (freq == rt5671->sysclk && clk_id == rt5671->sysclk_src)
- + return 0;
- +
- + if (SND_SOC_BIAS_OFF != codec->dapm.bias_level) {
- + switch (clk_id) {
- + case RT5671_SCLK_S_MCLK:
- + reg_val |= RT5671_SCLK_SRC_MCLK;
- + break;
- + case RT5671_SCLK_S_PLL1:
- + reg_val |= RT5671_SCLK_SRC_PLL1;
- + break;
- + case RT5671_SCLK_S_RCCLK:
- + reg_val |= RT5671_SCLK_SRC_RCCLK;
- + break;
- + default:
- + dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
- + return -EINVAL;
- + }
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_SCLK_SRC_MASK, reg_val);
- + }
- +
- + rt5671->sysclk = freq;
- + rt5671->sysclk_src = clk_id;
- +
- + dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
- +
- + return 0;
- +}
- +
- +/**
- + * rt5671_pll_calc - Calcualte PLL M/N/K code.
- + * @freq_in: external clock provided to codec.
- + * @freq_out: target clock which codec works on.
- + * @pll_code: Pointer to structure with M, N, K and bypass flag.
- + *
- + * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2
- + * which make calculation more efficiently.
- + *
- + * Returns 0 for success or negative error code.
- + */
- +static int rt5671_pll_calc(const unsigned int freq_in,
- + const unsigned int freq_out, struct rt5671_pll_code *pll_code)
- +{
- + int max_n = RT5671_PLL_N_MAX, max_m = RT5671_PLL_M_MAX;
- + int k, n = 0, m = 0, red, n_t, m_t, pll_out, in_t;
- + int out_t, red_t = abs(freq_out - freq_in);
- + bool bypass = false;
- +
- + if (RT5671_PLL_INP_MAX < freq_in || RT5671_PLL_INP_MIN > freq_in)
- + return -EINVAL;
- +
- + k = 100000000 / freq_out - 2;
- + if (k > RT5671_PLL_K_MAX)
- + k = RT5671_PLL_K_MAX;
- + for (n_t = 0; n_t <= max_n; n_t++) {
- + in_t = freq_in / (k + 2);
- + pll_out = freq_out / (n_t + 2);
- + if (in_t < 0)
- + continue;
- + if (in_t == pll_out) {
- + bypass = true;
- + n = n_t;
- + goto code_find;
- + }
- + red = abs(in_t - pll_out);
- + if (red < red_t) {
- + bypass = true;
- + n = n_t;
- + m = m_t;
- + if (red == 0)
- + goto code_find;
- + red_t = red;
- + }
- + for (m_t = 0; m_t <= max_m; m_t++) {
- + out_t = in_t / (m_t + 2);
- + red = abs(out_t - pll_out);
- + if (red < red_t) {
- + bypass = false;
- + n = n_t;
- + m = m_t;
- + if (red == 0)
- + goto code_find;
- + red_t = red;
- + }
- + }
- + }
- + pr_info("Only get approximation about PLL\n");
- +
- +code_find:
- +
- + pll_code->m_bp = bypass;
- + pll_code->m_code = m;
- + pll_code->n_code = n;
- + pll_code->k_code = k;
- + return 0;
- +}
- +
- +static int rt5671_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
- + unsigned int freq_in, unsigned int freq_out)
- +{
- + struct snd_soc_codec *codec = dai->codec;
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- + struct rt5671_pll_code pll_code;
- + int ret;
- +
- + if (source == rt5671->pll_src && freq_in == rt5671->pll_in &&
- + freq_out == rt5671->pll_out)
- + return 0;
- +
- + if (!freq_in || !freq_out) {
- + dev_dbg(codec->dev, "PLL disabled\n");
- +
- + rt5671->pll_in = 0;
- + rt5671->pll_out = 0;
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_SCLK_SRC_MASK, RT5671_SCLK_SRC_MCLK);
- + return 0;
- + }
- +
- + switch (source) {
- + case RT5671_PLL1_S_MCLK:
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_PLL1_SRC_MASK, RT5671_PLL1_SRC_MCLK);
- + break;
- + case RT5671_PLL1_S_BCLK1:
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_PLL1_SRC_MASK, RT5671_PLL1_SRC_BCLK1);
- + break;
- + case RT5671_PLL1_S_BCLK2:
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_PLL1_SRC_MASK, RT5671_PLL1_SRC_BCLK2);
- + break;
- + case RT5671_PLL1_S_BCLK3:
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_PLL1_SRC_MASK, RT5671_PLL1_SRC_BCLK3);
- + break;
- + case RT5671_PLL1_S_BCLK4:
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_PLL1_SRC_MASK, RT5671_PLL1_SRC_BCLK4);
- + break;
- + default:
- + dev_err(codec->dev, "Unknown PLL source %d\n", source);
- + return -EINVAL;
- + }
- +
- + ret = rt5671_pll_calc(freq_in, freq_out, &pll_code);
- + if (ret < 0) {
- + dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
- + return ret;
- + }
- +
- + dev_info(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
- + pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
- + pll_code.n_code, pll_code.k_code);
- +
- + snd_soc_write(codec, RT5671_PLL_CTRL1,
- + pll_code.n_code << RT5671_PLL_N_SFT | pll_code.k_code);
- + snd_soc_write(codec, RT5671_PLL_CTRL2,
- + (pll_code.m_bp ? 0 : pll_code.m_code) << RT5671_PLL_M_SFT |
- + pll_code.m_bp << RT5671_PLL_M_BP_SFT);
- +
- + rt5671->pll_in = freq_in;
- + rt5671->pll_out = freq_out;
- + rt5671->pll_src = source;
- +
- + dev_info(codec->dev, "pll_in=%d pll_out=%d pll_src=%d\n",
- + rt5671->pll_in, rt5671->pll_out, rt5671->pll_src);
- +
- + return 0;
- +}
- +
- +/**
- + * rt5671_index_show - Dump private registers.
- + * @dev: codec device.
- + * @attr: device attribute.
- + * @buf: buffer for display.
- + *
- + * To show non-zero values of all private registers.
- + *
- + * Returns buffer length.
- + */
- +static ssize_t rt5671_index_show(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- + unsigned int val;
- + int cnt = 0, i;
- +
- + cnt += sprintf(buf, "RT5671 index register\n");
- + for (i = 0; i < 0xff; i++) {
- + if (cnt + RT5671_REG_DISP_LEN >= PAGE_SIZE)
- + break;
- + val = rt5671_index_read(codec, i);
- + if (!val)
- + continue;
- + cnt += snprintf(buf + cnt, RT5671_REG_DISP_LEN,
- + "%02x: %04x\n", i, val);
- + }
- +
- + if (cnt >= PAGE_SIZE)
- + cnt = PAGE_SIZE - 1;
- +
- + return cnt;
- +}
- +
- +static ssize_t rt5671_index_store(struct device *dev,
- + struct device_attribute *attr, const char *buf, size_t count)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- + unsigned int val = 0, addr = 0;
- + int i;
- +
- + for (i = 0; i < count; i++) {
- + if (*(buf+i) <= '9' && *(buf + i) >= '0')
- + addr = (addr << 4) | (*(buf + i) - '0');
- + else if (*(buf+i) <= 'f' && *(buf + i) >= 'a')
- + addr = (addr << 4) | ((*(buf + i) - 'a')+0xa);
- + else if (*(buf+i) <= 'F' && *(buf+i) >= 'A')
- + addr = (addr << 4) | ((*(buf + i) - 'A')+0xa);
- + else
- + break;
- + }
- +
- + for (i = i + 1; i < count; i++) {
- + if (*(buf+i) <= '9' && *(buf+i) >= '0')
- + val = (val << 4) | (*(buf + i) - '0');
- + else if (*(buf+i) <= 'f' && *(buf + i) >= 'a')
- + val = (val << 4) | ((*(buf + i)-'a')+0xa);
- + else if (*(buf+i) <= 'F' && *(buf + i) >= 'A')
- + val = (val << 4) | ((*(buf + i) - 'A')+0xa);
- + else
- + break;
- + }
- + pr_debug("addr=0x%x val=0x%x\n", addr, val);
- + if (addr > RT5671_VENDOR_ID2 || val > 0xffff || val < 0)
- + return count;
- +
- + if (i == count)
- + pr_debug("0x%02x = 0x%04x\n", addr,
- + rt5671_index_read(codec, addr));
- + else
- + rt5671_index_write(codec, addr, val);
- +
- +
- + return count;
- +}
- +static DEVICE_ATTR(index_reg, 0664, rt5671_index_show, rt5671_index_store);
- +
- +static ssize_t rt5671_codec_show(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- + unsigned int val;
- + int cnt = 0, i;
- +
- + for (i = 0; i <= RT5671_VENDOR_ID2; i++) {
- + if (cnt + RT5671_REG_DISP_LEN >= PAGE_SIZE)
- + break;
- +
- + if (rt5671_readable_register(codec, i)) {
- + val = snd_soc_read(codec, i);
- +
- + cnt += snprintf(buf + cnt, RT5671_REG_DISP_LEN,
- + "%04x: %04x\n", i, val);
- + }
- + }
- +
- + if (cnt >= PAGE_SIZE)
- + cnt = PAGE_SIZE - 1;
- +
- + return cnt;
- +}
- +
- +static ssize_t rt5671_codec_store(struct device *dev,
- + struct device_attribute *attr, const char *buf, size_t count)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- + unsigned int val = 0, addr = 0;
- + int i;
- +
- + pr_debug("register \"%s\" count=%d\n", buf, count);
- + for (i = 0; i < count; i++) {
- + if (*(buf+i) <= '9' && *(buf + i) >= '0')
- + addr = (addr << 4) | (*(buf + i) - '0');
- + else if (*(buf+i) <= 'f' && *(buf + i) >= 'a')
- + addr = (addr << 4) | ((*(buf + i) - 'a')+0xa);
- + else if (*(buf+i) <= 'F' && *(buf + i) >= 'A')
- + addr = (addr << 4) | ((*(buf + i) - 'A')+0xa);
- + else
- + break;
- + }
- +
- + for (i = i+1; i < count; i++) {
- + if (*(buf+i) <= '9' && *(buf + i) >= '0')
- + val = (val << 4) | (*(buf + i) - '0');
- + else if (*(buf+i) <= 'f' && *(buf + i) >= 'a')
- + val = (val << 4) | ((*(buf + i) - 'a')+0xa);
- + else if (*(buf+i) <= 'F' && *(buf + i) >= 'A')
- + val = (val << 4) | ((*(buf + i) - 'A')+0xa);
- + else
- + break;
- + }
- + pr_debug("addr=0x%x val=0x%x\n", addr, val);
- + if (addr > RT5671_VENDOR_ID2 || val > 0xffff || val < 0)
- + return count;
- +
- + if (i == count)
- + pr_debug("0x%02x = 0x%04x\n", addr,
- + snd_soc_read(codec, addr));
- + else
- + snd_soc_write(codec, addr, val);
- +
- + return count;
- +}
- +
- +static DEVICE_ATTR(codec_reg, 0664, rt5671_codec_show, rt5671_codec_store);
- +
- +static ssize_t rt5671_codec_adb_show(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- + unsigned int val;
- + int cnt = 0, i;
- +
- + for (i = 0; i < rt5671->adb_reg_num; i++) {
- + if (cnt + RT5671_REG_DISP_LEN >= PAGE_SIZE)
- + break;
- +
- + switch (rt5671->adb_reg_addr[i] & 0x30000) {
- + case 0x10000:
- + val = rt5671_index_read(codec, rt5671->adb_reg_addr[i] & 0xffff);
- + break;
- + case 0x20000:
- + val = rt5671_dsp_read(codec, rt5671->adb_reg_addr[i] & 0xffff);
- + break;
- + default:
- + val = snd_soc_read(codec, rt5671->adb_reg_addr[i] & 0xffff);
- + }
- +
- + cnt += snprintf(buf + cnt, RT5671_REG_DISP_LEN, "%05x: %04x\n",
- + rt5671->adb_reg_addr[i], val);
- + }
- +
- + return cnt;
- +}
- +
- +static ssize_t rt5671_codec_adb_store(struct device *dev,
- + struct device_attribute *attr, const char *buf, size_t count)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- + unsigned int value = 0;
- + int i = 2, j = 0;
- +
- + if (buf[0] == 'R' || buf[0] == 'r') {
- + while (j < 0x100 && i < count) {
- + rt5671->adb_reg_addr[j] = 0;
- + value = 0;
- + for (; i < count; i++) {
- + if (*(buf + i) <= '9' && *(buf + i) >= '0')
- + value = (value << 4) | (*(buf + i) - '0');
- + else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
- + value = (value << 4) | ((*(buf + i) - 'a')+0xa);
- + else if (*(buf + i) <= 'F' && *(buf + i) >= 'A')
- + value = (value << 4) | ((*(buf + i) - 'A')+0xa);
- + else
- + break;
- + }
- + i++;
- +
- + rt5671->adb_reg_addr[j] = value;
- + j++;
- + }
- + rt5671->adb_reg_num = j;
- + } else if (buf[0] == 'W' || buf[0] == 'w') {
- + while (j < 0x100 && i < count) {
- + /* Get address */
- + rt5671->adb_reg_addr[j] = 0;
- + value = 0;
- + for (; i < count; i++) {
- + if (*(buf + i) <= '9' && *(buf + i) >= '0')
- + value = (value << 4) | (*(buf + i) - '0');
- + else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
- + value = (value << 4) | ((*(buf + i) - 'a')+0xa);
- + else if (*(buf + i) <= 'F' && *(buf + i) >= 'A')
- + value = (value << 4) | ((*(buf + i) - 'A')+0xa);
- + else
- + break;
- + }
- + i++;
- + rt5671->adb_reg_addr[j] = value;
- +
- + /* Get value */
- + rt5671->adb_reg_value[j] = 0;
- + value = 0;
- + for (; i < count; i++) {
- + if (*(buf + i) <= '9' && *(buf + i) >= '0')
- + value = (value << 4) | (*(buf + i) - '0');
- + else if (*(buf + i) <= 'f' && *(buf + i) >= 'a')
- + value = (value << 4) | ((*(buf + i) - 'a')+0xa);
- + else if (*(buf + i) <= 'F' && *(buf + i) >= 'A')
- + value = (value << 4) | ((*(buf + i) - 'A')+0xa);
- + else
- + break;
- + }
- + i++;
- + rt5671->adb_reg_value[j] = value;
- +
- + j++;
- + }
- +
- + rt5671->adb_reg_num = j;
- +
- + for (i = 0; i < rt5671->adb_reg_num; i++) {
- + switch (rt5671->adb_reg_addr[i] & 0x30000) {
- + case 0x10000:
- + rt5671_index_write(codec,
- + rt5671->adb_reg_addr[i] & 0xffff,
- + rt5671->adb_reg_value[i]);
- + break;
- + case 0x20000:
- + rt5671_dsp_write(codec,
- + rt5671->adb_reg_addr[i] & 0xffff,
- + rt5671->adb_reg_value[i]);
- + break;
- + default:
- + snd_soc_write(codec,
- + rt5671->adb_reg_addr[i] & 0xffff,
- + rt5671->adb_reg_value[i]);
- + }
- + }
- +
- + }
- +
- + return count;
- +}
- +static DEVICE_ATTR(codec_reg_adb, 0664, rt5671_codec_adb_show, rt5671_codec_adb_store);
- +
- +static int rt5671_set_bias_level(struct snd_soc_codec *codec,
- + enum snd_soc_bias_level level)
- +{
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- + switch (level) {
- + case SND_SOC_BIAS_ON:
- + break;
- +
- + case SND_SOC_BIAS_PREPARE:
- + snd_soc_update_bits(codec, RT5671_ADDA_CLK1,
- + RT5671_I2S_PD1_MASK, RT5671_I2S_PD1_2);
- + snd_soc_update_bits(codec, RT5671_CHARGE_PUMP,
- + RT5671_OSW_L_MASK | RT5671_OSW_R_MASK,
- + RT5671_OSW_L_DIS | RT5671_OSW_R_DIS);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1,
- + RT5671_LDO_SEL_MASK, 0x5);
- + if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) {
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1,
- + RT5671_PWR_VREF1 | RT5671_PWR_MB |
- + RT5671_PWR_BG | RT5671_PWR_VREF2,
- + RT5671_PWR_VREF1 | RT5671_PWR_MB |
- + RT5671_PWR_BG | RT5671_PWR_VREF2);
- + mdelay(10);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1,
- + RT5671_PWR_FV1 | RT5671_PWR_FV2,
- + RT5671_PWR_FV1 | RT5671_PWR_FV2);
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL1, 0x1, 0x1);
- + switch (rt5671->sysclk_src) {
- + case RT5671_SCLK_S_MCLK:
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_SCLK_SRC_MASK,
- + RT5671_SCLK_SRC_MCLK);
- + break;
- + case RT5671_SCLK_S_PLL1:
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_SCLK_SRC_MASK,
- + RT5671_SCLK_SRC_PLL1);
- + break;
- + default:
- + pr_err("Invalid sysclk_src %d, use MCLK\n",
- + rt5671->sysclk_src);
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_SCLK_SRC_MASK,
- + RT5671_SCLK_SRC_MCLK);
- + break;
- + }
- +
- + snd_soc_update_bits(codec, RT5671_MICBIAS,
- + RT5671_PWR_CLK25M_MASK |
- + RT5671_PWR_MB_MASK, 0);
- + }
- + break;
- +
- + case SND_SOC_BIAS_STANDBY:
- +
- + break;
- +
- + case SND_SOC_BIAS_OFF:
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_SCLK_SRC_MASK, RT5671_SCLK_SRC_RCCLK);
- + snd_soc_write(codec, RT5671_ADDA_CLK1, 0x7770);
- + snd_soc_update_bits(codec, RT5671_MICBIAS,
- + RT5671_PWR_CLK25M_MASK | RT5671_PWR_MB_MASK,
- + RT5671_PWR_CLK25M_PU | RT5671_PWR_MB_PU);
- + snd_soc_update_bits(codec, RT5671_GEN_CTRL1, 0x1, 0);
- + snd_soc_write(codec, RT5671_PWR_DIG1, 0x0000);
- + snd_soc_write(codec, RT5671_PWR_DIG2, 0x0001);
- + snd_soc_write(codec, RT5671_PWR_VOL, 0x0000);
- + snd_soc_write(codec, RT5671_PWR_MIXER, 0x0001);
- + snd_soc_write(codec, RT5671_PWR_ANLG1, 0x2001);
- + snd_soc_write(codec, RT5671_PWR_ANLG2, 0x0004);
- + break;
- +
- + default:
- + break;
- + }
- + codec->dapm.bias_level = level;
- +
- + return 0;
- +}
- +
- +static int rt5671_probe(struct snd_soc_codec *codec)
- +{
- + struct rt5670_platform_data *pdata = dev_get_platdata(codec->dev);
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +#ifdef RTK_IOCTL
- +#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
- + struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
- +#endif
- +#endif
- + int ret;
- +
- + pr_info("Codec driver version %s\n", VERSION);
- +
- + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
- + if (ret != 0) {
- + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- + return ret;
- + }
- + rt5671_reset(codec);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1,
- + RT5671_PWR_HP_L | RT5671_PWR_HP_R |
- + RT5671_PWR_VREF2, RT5671_PWR_VREF2);
- + msleep(100);
- +
- + rt5671_reset(codec);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1,
- + RT5671_PWR_VREF1 | RT5671_PWR_MB |
- + RT5671_PWR_BG | RT5671_PWR_VREF2,
- + RT5671_PWR_VREF1 | RT5671_PWR_MB |
- + RT5671_PWR_BG | RT5671_PWR_VREF2);
- + mdelay(10);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1,
- + RT5671_PWR_FV1 | RT5671_PWR_FV2,
- + RT5671_PWR_FV1 | RT5671_PWR_FV2);
- + /* DMIC */
- + if (rt5671->dmic_en == RT5671_DMIC1) {
- + snd_soc_update_bits(codec, RT5671_GPIO_CTRL1,
- + RT5671_GP2_PIN_MASK, RT5671_GP2_PIN_DMIC1_SCL);
- + snd_soc_update_bits(codec, RT5671_DMIC_CTRL1,
- + RT5671_DMIC_1L_LH_MASK | RT5671_DMIC_1R_LH_MASK,
- + RT5671_DMIC_1L_LH_FALLING | RT5671_DMIC_1R_LH_RISING);
- + } else if (rt5671->dmic_en == RT5671_DMIC2) {
- + snd_soc_update_bits(codec, RT5671_GPIO_CTRL1,
- + RT5671_GP2_PIN_MASK, RT5671_GP2_PIN_DMIC1_SCL);
- + snd_soc_update_bits(codec, RT5671_DMIC_CTRL1,
- + RT5671_DMIC_2L_LH_MASK | RT5671_DMIC_2R_LH_MASK,
- + RT5671_DMIC_2L_LH_FALLING | RT5671_DMIC_2R_LH_RISING);
- + }
- +
- + rt5671_reg_init(codec);
- + /*for IRQ*/
- + snd_soc_update_bits(codec, RT5671_GPIO_CTRL1, 0x8000, 0x8000);
- + snd_soc_update_bits(codec, RT5671_GPIO_CTRL2, 0x0004, 0x0004);
- +
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1, RT5671_LDO_SEL_MASK, 0x1);
- +
- + rt5671->codec = codec;
- + rt5671->combo_jack_en = true; /* enable combo jack */
- +
- + if (pdata)
- + rt5671->pdata = *pdata;
- + else
- + pr_info("pdata = NULL\n");
- +
- + if (rt5671->pdata.in2_diff)
- + snd_soc_update_bits(codec, RT5671_IN2,
- + RT5671_IN_DF2, RT5671_IN_DF2);
- + if (rt5671->pdata.in3_diff)
- + snd_soc_update_bits(codec, RT5671_IN3_IN4,
- + RT5671_IN_DF1, RT5671_IN_DF1);
- +
- + if (rt5671->pdata.in4_diff)
- + snd_soc_update_bits(codec, RT5671_IN3_IN4,
- + RT5671_IN_DF2, RT5671_IN_DF2);
- +
- + if (rt5671->pdata.jd_mode) {
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG1,
- + RT5671_PWR_MB,
- + RT5671_PWR_MB);
- + snd_soc_update_bits(codec, RT5671_PWR_ANLG2,
- + RT5671_PWR_JD1,
- + RT5671_PWR_JD1);
- + snd_soc_update_bits(codec, RT5671_IRQ_CTRL1,
- + 0x0200, 0x0200);
- + switch (rt5671->pdata.jd_mode) {
- + case 1:
- + snd_soc_update_bits(codec, RT5671_A_JD_CTRL1,
- + 0x3, 0x0);
- + break;
- + case 2:
- + snd_soc_update_bits(codec, RT5671_A_JD_CTRL1,
- + 0x3, 0x1);
- + break;
- + case 3:
- + snd_soc_update_bits(codec, RT5671_A_JD_CTRL1,
- + 0x3, 0x2);
- + break;
- + default:
- + break;
- + }
- + }
- +
- + snd_soc_add_codec_controls(codec, rt5671_snd_controls,
- + ARRAY_SIZE(rt5671_snd_controls));
- + snd_soc_dapm_new_controls(&codec->dapm, rt5671_dapm_widgets,
- + ARRAY_SIZE(rt5671_dapm_widgets));
- + snd_soc_dapm_add_routes(&codec->dapm, rt5671_dapm_routes,
- + ARRAY_SIZE(rt5671_dapm_routes));
- + rt5671_dsp_probe(codec);
- +
- +#ifdef RTK_IOCTL
- +#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
- + ioctl_ops->index_write = rt5671_index_write;
- + ioctl_ops->index_read = rt5671_index_read;
- + ioctl_ops->index_update_bits = rt5671_index_update_bits;
- + ioctl_ops->ioctl_common = rt5671_ioctl_common;
- + realtek_ce_init_hwdep(codec);
- +#endif
- +#endif
- +
- + ret = device_create_file(codec->dev, &dev_attr_index_reg);
- + if (ret != 0) {
- + dev_err(codec->dev,
- + "Failed to create index_reg sysfs files: %d\n", ret);
- + return ret;
- + }
- +
- + ret = device_create_file(codec->dev, &dev_attr_codec_reg);
- + if (ret != 0) {
- + dev_err(codec->dev,
- + "Failed to create codex_reg sysfs files: %d\n", ret);
- + return ret;
- + }
- +
- + ret = device_create_file(codec->dev, &dev_attr_codec_reg_adb);
- + if (ret != 0) {
- + dev_err(codec->dev,
- + "Failed to create codec_reg_adb sysfs files: %d\n", ret);
- + return ret;
- + }
- +
- + rt5671->jack_type = 0;
- + if (rt5671->pdata.codec_gpio != -1) {
- + rt5671->hp_gpio.gpio = rt5671->pdata.codec_gpio;
- + rt5671->hp_gpio.name = "headphone detect";
- + rt5671->hp_gpio.report = SND_JACK_HEADSET |
- + SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2;
- + rt5671->hp_gpio.debounce_time = 150,
- + rt5671->hp_gpio.wake = true,
- + rt5671->hp_gpio.jack_status_check = rt5671_irq_detection,
- + snd_soc_jack_new(codec, rt5671->hp_gpio.name,
- + rt5671->hp_gpio.report,
- + &rt5671->hp_jack);
- + snd_soc_jack_add_gpios(&rt5671->hp_jack, 1,
- + &rt5671->hp_gpio);
- + }
- +
- + rt5671_set_bias_level(codec, SND_SOC_BIAS_OFF);
- +
- + return 0;
- +}
- +
- +static int rt5671_remove(struct snd_soc_codec *codec)
- +{
- + struct rt5671_priv *rt5671 = snd_soc_codec_get_drvdata(codec);
- +
- + rt5671_set_bias_level(codec, SND_SOC_BIAS_OFF);
- + snd_soc_jack_free_gpios(&rt5671->hp_jack, 1, &rt5671->hp_gpio);
- + return 0;
- +}
- +
- +#ifdef CONFIG_PM
- +static int rt5671_suspend(struct snd_soc_codec *codec)
- +{
- + rt5671_dsp_suspend(codec);
- + snd_soc_update_bits(codec, RT5671_GLB_CLK,
- + RT5671_SCLK_SRC_MASK, RT5671_SCLK_SRC_MCLK);
- + snd_soc_write(codec, RT5671_MICBIAS, 0x0000);
- + snd_soc_write(codec, RT5671_PWR_DIG1, 0x0000);
- + snd_soc_write(codec, RT5671_PWR_DIG2, 0x0000);
- + snd_soc_write(codec, RT5671_PWR_VOL, 0x0000);
- + snd_soc_write(codec, RT5671_PWR_MIXER, 0x0000);
- + snd_soc_write(codec, RT5671_PWR_ANLG1, 0x0001);
- + snd_soc_write(codec, RT5671_PWR_ANLG2, 0x0000);
- + return 0;
- +}
- +
- +static int rt5671_resume(struct snd_soc_codec *codec)
- +{
- + codec->cache_only = false;
- + codec->cache_sync = 1;
- + snd_soc_cache_sync(codec);
- + rt5671_index_sync(codec);
- + rt5671_dsp_resume(codec);
- + rt5671_set_bias_level(codec, SND_SOC_BIAS_OFF);
- + return 0;
- +}
- +#else
- +#define rt5671_suspend NULL
- +#define rt5671_resume NULL
- +#endif
- +
- +#define RT5671_STEREO_RATES SNDRV_PCM_RATE_8000_96000
- +#define RT5671_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
- +
- +struct snd_soc_dai_ops rt5671_aif_dai_ops = {
- + .hw_params = rt5671_hw_params,
- + .prepare = rt5671_prepare,
- + .set_fmt = rt5671_set_dai_fmt,
- + .set_sysclk = rt5671_set_dai_sysclk,
- + .set_pll = rt5671_set_dai_pll,
- + .shutdown = rt5671_shutdown,
- +};
- +
- +struct snd_soc_dai_driver rt5671_dai[] = {
- + {
- + .name = "rt5671-aif1",
- + .id = RT5671_AIF1,
- + .playback = {
- + .stream_name = "AIF1 Playback",
- + .channels_min = 1,
- + .channels_max = 2,
- + .rates = RT5671_STEREO_RATES,
- + .formats = RT5671_FORMATS,
- + },
- + .capture = {
- + .stream_name = "AIF1 Capture",
- + .channels_min = 1,
- + .channels_max = 2,
- + .rates = RT5671_STEREO_RATES,
- + .formats = RT5671_FORMATS,
- + },
- + .ops = &rt5671_aif_dai_ops,
- + .symmetric_rates = 1,
- + },
- + {
- + .name = "rt5671-aif2",
- + .id = RT5671_AIF2,
- + .playback = {
- + .stream_name = "AIF2 Playback",
- + .channels_min = 1,
- + .channels_max = 2,
- + .rates = RT5671_STEREO_RATES,
- + .formats = RT5671_FORMATS,
- + },
- + .capture = {
- + .stream_name = "AIF2 Capture",
- + .channels_min = 1,
- + .channels_max = 2,
- + .rates = RT5671_STEREO_RATES,
- + .formats = RT5671_FORMATS,
- + },
- + .ops = &rt5671_aif_dai_ops,
- + .symmetric_rates = 1,
- + },
- + {
- + .name = "rt5671-aif3",
- + .id = RT5671_AIF3,
- + .playback = {
- + .stream_name = "AIF3 Playback",
- + .channels_min = 1,
- + .channels_max = 2,
- + .rates = RT5671_STEREO_RATES,
- + .formats = RT5671_FORMATS,
- + },
- + .capture = {
- + .stream_name = "AIF3 Capture",
- + .channels_min = 1,
- + .channels_max = 2,
- + .rates = RT5671_STEREO_RATES,
- + .formats = RT5671_FORMATS,
- + },
- + .ops = &rt5671_aif_dai_ops,
- + .symmetric_rates = 1,
- + },
- + {
- + .name = "rt5671-aif4",
- + .id = RT5671_AIF4,
- + .playback = {
- + .stream_name = "AIF4 Playback",
- + .channels_min = 1,
- + .channels_max = 2,
- + .rates = RT5671_STEREO_RATES,
- + .formats = RT5671_FORMATS,
- + },
- + .capture = {
- + .stream_name = "AIF4 Capture",
- + .channels_min = 1,
- + .channels_max = 2,
- + .rates = RT5671_STEREO_RATES,
- + .formats = RT5671_FORMATS,
- + },
- + .ops = &rt5671_aif_dai_ops,
- + .symmetric_rates = 1,
- + },
- +
- +};
- +
- +static struct snd_soc_codec_driver soc_codec_dev_rt5671 = {
- + .probe = rt5671_probe,
- + .remove = rt5671_remove,
- + .suspend = rt5671_suspend,
- + .resume = rt5671_resume,
- + .set_bias_level = rt5671_set_bias_level,
- + .idle_bias_off = true,
- + .reg_cache_size = RT5671_VENDOR_ID2 + 1,
- + .reg_word_size = sizeof(u16),
- + .reg_cache_default = rt5671_reg,
- + .volatile_register = rt5671_volatile_register,
- + .readable_register = rt5671_readable_register,
- + .reg_cache_step = 1,
- +};
- +
- +static const struct i2c_device_id rt5671_i2c_id[] = {
- + { "rt5671", 0 },
- + { }
- +};
- +MODULE_DEVICE_TABLE(i2c, rt5671_i2c_id);
- +
- +static int rt5671_i2c_probe(struct i2c_client *i2c,
- + const struct i2c_device_id *id)
- +{
- + struct rt5671_priv *rt5671;
- + int ret;
- +
- + pr_debug("enter %s\n", __func__);
- + rt5671 = kzalloc(sizeof(struct rt5671_priv), GFP_KERNEL);
- + if (NULL == rt5671)
- + return -ENOMEM;
- +
- + i2c_set_clientdata(i2c, rt5671);
- +
- + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5671,
- + rt5671_dai, ARRAY_SIZE(rt5671_dai));
- + if (ret < 0)
- + kfree(rt5671);
- +
- + return ret;
- +}
- +
- +static int rt5671_i2c_remove(struct i2c_client *i2c)
- +{
- + snd_soc_unregister_codec(&i2c->dev);
- + kfree(i2c_get_clientdata(i2c));
- + return 0;
- +}
- +
- +void rt5671_i2c_shutdown(struct i2c_client *client)
- +{
- + struct rt5671_priv *rt5671 = i2c_get_clientdata(client);
- + struct snd_soc_codec *codec = rt5671->codec;
- +
- + pr_debug("enter %s\n", __func__);
- + if (codec != NULL)
- + rt5671_set_bias_level(codec, SND_SOC_BIAS_OFF);
- +}
- +
- +struct i2c_driver rt5671_i2c_driver = {
- + .driver = {
- + .name = "rt5671",
- + .owner = THIS_MODULE,
- + },
- + .probe = rt5671_i2c_probe,
- + .remove = rt5671_i2c_remove,
- + .shutdown = rt5671_i2c_shutdown,
- + .id_table = rt5671_i2c_id,
- +};
- +
- +static int __init rt5671_modinit(void)
- +{
- + return i2c_add_driver(&rt5671_i2c_driver);
- +}
- +module_init(rt5671_modinit);
- +
- +static void __exit rt5671_modexit(void)
- +{
- + i2c_del_driver(&rt5671_i2c_driver);
- +}
- +module_exit(rt5671_modexit);
- +
- +MODULE_DESCRIPTION("ASoC RT5671 driver");
- +MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
- +MODULE_LICENSE("GPL");
- diff --git a/sound/soc/codecs/rt5671.h b/sound/soc/codecs/rt5671.h
- new file mode 100644
- index 0000000..36e76cd
- --- /dev/null
- +++ b/sound/soc/codecs/rt5671.h
- @@ -0,0 +1,2091 @@
- +/*
- + * rt5671.h -- RT5671 ALSA SoC audio driver
- + *
- + * Copyright 2011 Realtek Microelectronics
- + * Copyright (C) 2016 XiaoMi, Inc.
- + * Author: Johnny Hsu <johnnyhsu@realtek.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#ifndef __RT5671_H__
- +#define __RT5671_H__
- +
- +#include <sound/rt5670.h>
- +
- +/* Info */
- +#define RT5671_RESET 0x00
- +#define RT5671_VENDOR_ID 0xfd
- +#define RT5671_VENDOR_ID1 0xfe
- +#define RT5671_VENDOR_ID2 0xff
- +/* dummy register */
- +#define RT5671_DUMMY_CTRL 0x01
- +/* I/O - Output */
- +#define RT5671_HP_VOL 0x02
- +#define RT5671_LOUT1 0x03
- +#define RT5671_MONO_OUT 0x04
- +/* I/O - Input */
- +#define RT5671_CJ_CTRL1 0x0a
- +#define RT5671_CJ_CTRL2 0x0b
- +#define RT5671_CJ_CTRL3 0x0c
- +#define RT5671_IN2 0x0d
- +#define RT5671_IN3_IN4 0x0e
- +#define RT5671_INL1_INR1_VOL 0x0f
- +/* I/O - ADC/DAC/DMIC */
- +#define RT5671_SIDETONE_CTRL 0x18
- +#define RT5671_DAC1_DIG_VOL 0x19
- +#define RT5671_DAC2_DIG_VOL 0x1a
- +#define RT5671_DAC_CTRL 0x1b
- +#define RT5671_STO1_ADC_DIG_VOL 0x1c
- +#define RT5671_MONO_ADC_DIG_VOL 0x1d
- +#define RT5671_ADC_BST_VOL1 0x1e
- +#define RT5671_STO2_ADC_DIG_VOL 0x1f
- +/* Mixer - D-D */
- +#define RT5671_ADC_BST_VOL2 0x20
- +#define RT5671_STO2_ADC_MIXER 0x26
- +#define RT5671_STO1_ADC_MIXER 0x27
- +#define RT5671_MONO_ADC_MIXER 0x28
- +#define RT5671_AD_DA_MIXER 0x29
- +#define RT5671_STO_DAC_MIXER 0x2a
- +#define RT5671_MONO_DAC_MIXER 0x2b
- +#define RT5671_DIG_MIXER 0x2c
- +#define RT5671_DSP_PATH1 0x2d
- +#define RT5671_DSP_PATH2 0x2e
- +#define RT5671_DIG_INF1_DATA 0x2f
- +#define RT5671_DIG_INF2_DATA 0x30
- +/* Mixer - PDM */
- +#define RT5671_PDM_OUT_CTRL 0x31
- +#define RT5671_PDM_DATA_CTRL1 0x32
- +#define RT5671_PDM1_DATA_CTRL2 0x33
- +#define RT5671_PDM1_DATA_CTRL3 0x34
- +#define RT5671_PDM1_DATA_CTRL4 0x35
- +#define RT5671_PDM2_DATA_CTRL2 0x36
- +#define RT5671_PDM2_DATA_CTRL3 0x37
- +#define RT5671_PDM2_DATA_CTRL4 0x38
- +/* Mixer - ADC */
- +#define RT5671_REC_L1_MIXER 0x3b
- +#define RT5671_REC_L2_MIXER 0x3c
- +#define RT5671_REC_R1_MIXER 0x3d
- +#define RT5671_REC_R2_MIXER 0x3e
- +#define RT5671_REC_MONO1_MIXER 0x3f
- +#define RT5671_REC_MONO2_MIXER 0x40
- +/* Mixer - DAC */
- +#define RT5671_HPO_MIXER 0x45
- +#define RT5671_MONO_MIXER 0x4c
- +#define RT5671_OUT_L1_MIXER 0x4f
- +#define RT5671_OUT_R1_MIXER 0x52
- +#define RT5671_LOUT_MIXER 0x53
- +/* Power */
- +#define RT5671_PWR_DIG1 0x61
- +#define RT5671_PWR_DIG2 0x62
- +#define RT5671_PWR_ANLG1 0x63
- +#define RT5671_PWR_ANLG2 0x64
- +#define RT5671_PWR_MIXER 0x65
- +#define RT5671_PWR_VOL 0x66
- +/* Private Register Control */
- +#define RT5671_PRIV_INDEX 0x6a
- +#define RT5671_PRIV_DATA 0x6c
- +/* Format - ADC/DAC */
- +#define RT5671_I2S4_SDP 0x6f
- +#define RT5671_I2S1_SDP 0x70
- +#define RT5671_I2S2_SDP 0x71
- +#define RT5671_I2S3_SDP 0x72
- +#define RT5671_ADDA_CLK1 0x73
- +#define RT5671_ADDA_HPF 0x74
- +#define RT5671_DMIC_CTRL1 0x75
- +#define RT5671_DMIC_CTRL2 0x76
- +/* Format - TDM Control */
- +#define RT5671_TDM_CTRL_1 0x77
- +#define RT5671_TDM_CTRL_2 0x78
- +#define RT5671_TDM_CTRL_3 0x79
- +
- +/* Function - Analog */
- +#define RT5671_DSP_CLK 0x7f
- +#define RT5671_GLB_CLK 0x80
- +#define RT5671_PLL_CTRL1 0x81
- +#define RT5671_PLL_CTRL2 0x82
- +#define RT5671_ASRC_1 0x83
- +#define RT5671_ASRC_2 0x84
- +#define RT5671_ASRC_3 0x85
- +#define RT5671_ASRC_I2S1 0x87
- +#define RT5671_ASRC_I2S2 0x88
- +#define RT5671_ASRC_I2S3 0x89
- +#define RT5671_ASRC_4 0x8a
- +#define RT5671_ASRC_5 0x8c
- +#define RT5671_DEPOP_M1 0x8e
- +#define RT5671_DEPOP_M2 0x8f
- +#define RT5671_DEPOP_M3 0x90
- +#define RT5671_CHARGE_PUMP 0x91
- +#define RT5671_MICBIAS 0x93
- +#define RT5671_A_JD_CTRL1 0x94
- +#define RT5671_A_JD_CTRL2 0x95
- +#define RT5671_VAD_CTRL1 0x9a
- +#define RT5671_VAD_CTRL2 0x9b
- +#define RT5671_VAD_CTRL3 0x9c
- +#define RT5671_VAD_CTRL4 0x9d
- +#define RT5671_VAD_CTRL5 0x9e
- +/* Function - Digital */
- +#define RT5671_ADC_EQ_CTRL1 0xae
- +#define RT5671_ADC_EQ_CTRL2 0xaf
- +#define RT5671_EQ_CTRL1 0xb0
- +#define RT5671_EQ_CTRL2 0xb1
- +#define RT5671_ALC_DRC_CTRL1 0xb2
- +#define RT5671_ALC_DRC_CTRL2 0xb3
- +#define RT5671_ALC_CTRL_1 0xb4
- +#define RT5671_ALC_CTRL_2 0xb5
- +#define RT5671_ALC_CTRL_3 0xb6
- +#define RT5671_ALC_CTRL_4 0xb7
- +#define RT5671_JD_CTRL1 0xbb
- +#define RT5671_JD_CTRL2 0xbc
- +#define RT5671_IRQ_CTRL1 0xbd
- +#define RT5671_IRQ_CTRL2 0xbe
- +#define RT5671_IRQ_CTRL3 0xbf
- +#define RT5671_GPIO_CTRL1 0xc0
- +#define RT5671_GPIO_CTRL2 0xc1
- +#define RT5671_GPIO_CTRL3 0xc2
- +#define RT5671_SCRABBLE_FUN 0xcd
- +#define RT5671_SCRABBLE_CTRL 0xce
- +#define RT5671_BASE_BACK 0xcf
- +#define RT5671_MP3_PLUS1 0xd0
- +#define RT5671_MP3_PLUS2 0xd1
- +#define RT5671_ADJ_HPF1 0xd3
- +#define RT5671_ADJ_HPF2 0xd4
- +#define RT5671_HP_CALIB_AMP_DET 0xd6
- +#define RT5671_SV_ZCD1 0xd9
- +#define RT5671_SV_ZCD2 0xda
- +#define RT5671_IL_CMD1 0xdb
- +#define RT5671_IL_CMD2 0xdc
- +#define RT5671_IL_CMD3 0xdd
- +#define RT5671_DRC_HL_CTRL1 0xe6
- +#define RT5671_DRC_HL_CTRL2 0xe7
- +#define RT5671_ADC_MONO_HP_CTRL1 0xec
- +#define RT5671_ADC_MONO_HP_CTRL2 0xed
- +#define RT5671_ADC_STO2_HP_CTRL1 0xee
- +#define RT5671_ADC_STO2_HP_CTRL2 0xef
- +#define RT5671_JD_CTRL3 0xf8
- +#define RT5671_JD_CTRL4 0xf9
- +/* General Control */
- +#define RT5671_GEN_CTRL1 0xfa
- +#define RT5671_GEN_CTRL2 0xfb
- +#define RT5671_GEN_CTRL3 0xfc
- +
- +
- +/* Index of Codec Private Register definition */
- +#define RT5671_DIG_VOL 0x00
- +#define RT5671_PR_ALC_CTRL_1 0x01
- +#define RT5671_PR_ALC_CTRL_2 0x02
- +#define RT5671_PR_ALC_CTRL_3 0x03
- +#define RT5671_PR_ALC_CTRL_4 0x04
- +#define RT5671_PR_ALC_CTRL_5 0x05
- +#define RT5671_PR_ALC_CTRL_6 0x06
- +#define RT5671_BIAS_CUR1 0x12
- +#define RT5671_BIAS_CUR3 0x14
- +#define RT5671_CLSD_INT_REG1 0x1c
- +#define RT5671_MAMP_INT_REG2 0x37
- +#define RT5671_CHOP_DAC_ADC 0x3d
- +#define RT5671_MIXER_INT_REG 0x3f
- +#define RT5671_3D_SPK 0x63
- +#define RT5671_WND_1 0x6c
- +#define RT5671_WND_2 0x6d
- +#define RT5671_WND_3 0x6e
- +#define RT5671_WND_4 0x6f
- +#define RT5671_WND_5 0x70
- +#define RT5671_WND_8 0x73
- +#define RT5671_DIP_SPK_INF 0x75
- +#define RT5671_HP_DCC_INT1 0x77
- +#define RT5671_EQ_BW_LOP 0xa0
- +#define RT5671_EQ_GN_LOP 0xa1
- +#define RT5671_EQ_FC_BP1 0xa2
- +#define RT5671_EQ_BW_BP1 0xa3
- +#define RT5671_EQ_GN_BP1 0xa4
- +#define RT5671_EQ_FC_BP2 0xa5
- +#define RT5671_EQ_BW_BP2 0xa6
- +#define RT5671_EQ_GN_BP2 0xa7
- +#define RT5671_EQ_FC_BP3 0xa8
- +#define RT5671_EQ_BW_BP3 0xa9
- +#define RT5671_EQ_GN_BP3 0xaa
- +#define RT5671_EQ_FC_BP4 0xab
- +#define RT5671_EQ_BW_BP4 0xac
- +#define RT5671_EQ_GN_BP4 0xad
- +#define RT5671_EQ_FC_HIP1 0xae
- +#define RT5671_EQ_GN_HIP1 0xaf
- +#define RT5671_EQ_FC_HIP2 0xb0
- +#define RT5671_EQ_BW_HIP2 0xb1
- +#define RT5671_EQ_GN_HIP2 0xb2
- +#define RT5671_EQ_PRE_VOL 0xb3
- +#define RT5671_EQ_PST_VOL 0xb4
- +
- +
- +/* global definition */
- +#define RT5671_L_MUTE (0x1 << 15)
- +#define RT5671_L_MUTE_SFT 15
- +#define RT5671_VOL_L_MUTE (0x1 << 14)
- +#define RT5671_VOL_L_SFT 14
- +#define RT5671_R_MUTE (0x1 << 7)
- +#define RT5671_R_MUTE_SFT 7
- +#define RT5671_VOL_R_MUTE (0x1 << 6)
- +#define RT5671_VOL_R_SFT 6
- +#define RT5671_L_VOL_MASK (0x3f << 8)
- +#define RT5671_L_VOL_SFT 8
- +#define RT5671_R_VOL_MASK (0x3f)
- +#define RT5671_R_VOL_SFT 0
- +
- +/* Combo Jack Control 1 (0x0a) */
- +#define RT5671_CBJ_BST1_MASK (0xf << 12)
- +#define RT5671_CBJ_BST1_SFT (12)
- +#define RT5671_CBJ_JD_HP_EN (0x1 << 9)
- +#define RT5671_CBJ_JD_MIC_EN (0x1 << 8)
- +#define RT5671_CBJ_BST1_EN (0x1 << 2)
- +
- +/* Combo Jack Control 1 (0x0b) */
- +#define RT5671_CBJ_MN_JD (0x1 << 12)
- +#define RT5671_CAPLESS_EN (0x1 << 11)
- +#define RT5671_CBJ_DET_MODE (0x1 << 7)
- +
- +/* IN1 and IN2 Control (0x0d) */
- +/* IN3 and IN4 Control (0x0e) */
- +#define RT5671_BST_MASK1 (0xf<<12)
- +#define RT5671_BST_SFT1 12
- +#define RT5671_BST_MASK2 (0xf<<8)
- +#define RT5671_BST_SFT2 8
- +#define RT5671_IN_DF1 (0x1 << 7)
- +#define RT5671_IN_SFT1 7
- +#define RT5671_IN_DF2 (0x1 << 6)
- +#define RT5671_IN_SFT2 6
- +
- +/* INL and INR Volume Control (0x0f) */
- +#define RT5671_INL_SEL_MASK (0x1 << 15)
- +#define RT5671_INL_SEL_SFT 15
- +#define RT5671_INL_SEL_IN4P (0x0 << 15)
- +#define RT5671_INL_SEL_MONOP (0x1 << 15)
- +#define RT5671_INL_VOL_MASK (0x1f << 8)
- +#define RT5671_INL_VOL_SFT 8
- +#define RT5671_INR_SEL_MASK (0x1 << 7)
- +#define RT5671_INR_SEL_SFT 7
- +#define RT5671_INR_SEL_IN4N (0x0 << 7)
- +#define RT5671_INR_SEL_MONON (0x1 << 7)
- +#define RT5671_INR_VOL_MASK (0x1f)
- +#define RT5671_INR_VOL_SFT 0
- +
- +/* Sidetone Control (0x18) */
- +#define RT5671_ST_SEL_MASK (0x7 << 9)
- +#define RT5671_ST_SEL_SFT 9
- +#define RT5671_M_ST_DACR2 (0x1 << 8)
- +#define RT5671_M_ST_DACR2_SFT 8
- +#define RT5671_M_ST_DACL2 (0x1 << 7)
- +#define RT5671_M_ST_DACL2_SFT 7
- +#define RT5671_ST_EN (0x1 << 6)
- +#define RT5671_ST_EN_SFT 6
- +
- +/* DAC1 Digital Volume (0x19) */
- +#define RT5671_DAC_L1_VOL_MASK (0xff << 8)
- +#define RT5671_DAC_L1_VOL_SFT 8
- +#define RT5671_DAC_R1_VOL_MASK (0xff)
- +#define RT5671_DAC_R1_VOL_SFT 0
- +
- +/* DAC2 Digital Volume (0x1a) */
- +#define RT5671_DAC_L2_VOL_MASK (0xff << 8)
- +#define RT5671_DAC_L2_VOL_SFT 8
- +#define RT5671_DAC_R2_VOL_MASK (0xff)
- +#define RT5671_DAC_R2_VOL_SFT 0
- +
- +/* DAC2 Control (0x1b) */
- +#define RT5671_M_DAC_L2_VOL (0x1 << 13)
- +#define RT5671_M_DAC_L2_VOL_SFT 13
- +#define RT5671_M_DAC_R2_VOL (0x1 << 12)
- +#define RT5671_M_DAC_R2_VOL_SFT 12
- +#define RT5671_DAC2_L_SEL_MASK (0x7 << 4)
- +#define RT5671_DAC2_L_SEL_SFT 4
- +#define RT5671_DAC2_R_SEL_MASK (0x7 << 0)
- +#define RT5671_DAC2_R_SEL_SFT 0
- +
- +/* ADC Digital Volume Control (0x1c) */
- +#define RT5671_ADC_L_VOL_MASK (0x7f << 8)
- +#define RT5671_ADC_L_VOL_SFT 8
- +#define RT5671_ADC_R_VOL_MASK (0x7f)
- +#define RT5671_ADC_R_VOL_SFT 0
- +
- +/* Mono ADC Digital Volume Control (0x1d) */
- +#define RT5671_MONO_ADC_L_VOL_MASK (0x7f << 8)
- +#define RT5671_MONO_ADC_L_VOL_SFT 8
- +#define RT5671_MONO_ADC_R_VOL_MASK (0x7f)
- +#define RT5671_MONO_ADC_R_VOL_SFT 0
- +
- +/* ADC Boost Volume Control (0x1e) */
- +#define RT5671_STO1_ADC_L_BST_MASK (0x3 << 14)
- +#define RT5671_STO1_ADC_L_BST_SFT 14
- +#define RT5671_STO1_ADC_R_BST_MASK (0x3 << 12)
- +#define RT5671_STO1_ADC_R_BST_SFT 12
- +#define RT5671_STO1_ADC_COMP_MASK (0x3 << 10)
- +#define RT5671_STO1_ADC_COMP_SFT 10
- +#define RT5671_STO2_ADC_L_BST_MASK (0x3 << 8)
- +#define RT5671_STO2_ADC_L_BST_SFT 8
- +#define RT5671_STO2_ADC_R_BST_MASK (0x3 << 6)
- +#define RT5671_STO2_ADC_R_BST_SFT 6
- +#define RT5671_STO2_ADC_COMP_MASK (0x3 << 4)
- +#define RT5671_STO2_ADC_COMP_SFT 4
- +
- +/* Stereo2 ADC Mixer Control (0x26) */
- +#define RT5671_STO2_ADC_SRC_MASK (0x1 << 15)
- +#define RT5671_STO2_ADC_SRC_SFT 15
- +
- +/* Stereo ADC Mixer Control (0x26 0x27) */
- +#define RT5671_M_ADC_L1 (0x1 << 14)
- +#define RT5671_M_ADC_L1_SFT 14
- +#define RT5671_M_ADC_L2 (0x1 << 13)
- +#define RT5671_M_ADC_L2_SFT 13
- +#define RT5671_ADC_1_SRC_MASK (0x1 << 12)
- +#define RT5671_ADC_1_SRC_SFT 12
- +#define RT5671_ADC_1_SRC_ADC (0x1 << 12)
- +#define RT5671_ADC_1_SRC_DACMIX (0x0 << 12)
- +#define RT5671_ADC_2_SRC_MASK (0x1 << 11)
- +#define RT5671_ADC_2_SRC_SFT 11
- +#define RT5671_ADC_SRC_MASK (0x1 << 10)
- +#define RT5671_ADC_SRC_SFT 10
- +#define RT5671_DMIC_SRC_MASK (0x3 << 8)
- +#define RT5671_DMIC_SRC_SFT 8
- +#define RT5671_M_ADC_R1 (0x1 << 6)
- +#define RT5671_M_ADC_R1_SFT 6
- +#define RT5671_M_ADC_R2 (0x1 << 5)
- +#define RT5671_M_ADC_R2_SFT 5
- +#define RT5671_DMIC3_SRC_MASK (0x1 << 1)
- +#define RT5671_DMIC3_SRC_SFT 0
- +
- +/* Mono ADC Mixer Control (0x28) */
- +#define RT5671_M_MONO_ADC_L1 (0x1 << 14)
- +#define RT5671_M_MONO_ADC_L1_SFT 14
- +#define RT5671_M_MONO_ADC_L2 (0x1 << 13)
- +#define RT5671_M_MONO_ADC_L2_SFT 13
- +#define RT5671_MONO_ADC_L1_SRC_MASK (0x1 << 12)
- +#define RT5671_MONO_ADC_L1_SRC_SFT 12
- +#define RT5671_MONO_ADC_L1_SRC_DACMIXL (0x0 << 12)
- +#define RT5671_MONO_ADC_L1_SRC_ADCL (0x1 << 12)
- +#define RT5671_MONO_ADC_L2_SRC_MASK (0x1 << 11)
- +#define RT5671_MONO_ADC_L2_SRC_SFT 11
- +#define RT5671_MONO_ADC_L_SRC_MASK (0x1 << 10)
- +#define RT5671_MONO_ADC_L_SRC_SFT 10
- +#define RT5671_MONO_DMIC_L_SRC_MASK (0x3 << 8)
- +#define RT5671_MONO_DMIC_L_SRC_SFT 8
- +#define RT5671_M_MONO_ADC_R1 (0x1 << 6)
- +#define RT5671_M_MONO_ADC_R1_SFT 6
- +#define RT5671_M_MONO_ADC_R2 (0x1 << 5)
- +#define RT5671_M_MONO_ADC_R2_SFT 5
- +#define RT5671_MONO_ADC_R1_SRC_MASK (0x1 << 4)
- +#define RT5671_MONO_ADC_R1_SRC_SFT 4
- +#define RT5671_MONO_ADC_R1_SRC_ADCR (0x1 << 4)
- +#define RT5671_MONO_ADC_R1_SRC_DACMIXR (0x0 << 4)
- +#define RT5671_MONO_ADC_R2_SRC_MASK (0x1 << 3)
- +#define RT5671_MONO_ADC_R2_SRC_SFT 3
- +#define RT5671_MONO_ADC_R_SRC_MASK (0x1 << 2)
- +#define RT5671_MONO_ADC_R_SRC_SFT 2
- +#define RT5671_MONO_DMIC_R_SRC_MASK (0x3)
- +#define RT5671_MONO_DMIC_R_SRC_SFT 0
- +
- +/* ADC Mixer to DAC Mixer Control (0x29) */
- +#define RT5671_M_ADCMIX_L (0x1 << 15)
- +#define RT5671_M_ADCMIX_L_SFT 15
- +#define RT5671_M_DAC1_L (0x1 << 14)
- +#define RT5671_M_DAC1_L_SFT 14
- +#define RT5671_DAC1_R_SEL_MASK (0x3 << 10)
- +#define RT5671_DAC1_R_SEL_SFT 10
- +#define RT5671_DAC1_R_SEL_IF1 (0x0 << 10)
- +#define RT5671_DAC1_R_SEL_IF2 (0x1 << 10)
- +#define RT5671_DAC1_R_SEL_IF3 (0x2 << 10)
- +#define RT5671_DAC1_R_SEL_IF4 (0x3 << 10)
- +#define RT5671_DAC1_L_SEL_MASK (0x3 << 8)
- +#define RT5671_DAC1_L_SEL_SFT 8
- +#define RT5671_DAC1_L_SEL_IF1 (0x0 << 8)
- +#define RT5671_DAC1_L_SEL_IF2 (0x1 << 8)
- +#define RT5671_DAC1_L_SEL_IF3 (0x2 << 8)
- +#define RT5671_DAC1_L_SEL_IF4 (0x3 << 8)
- +#define RT5671_M_ADCMIX_R (0x1 << 7)
- +#define RT5671_M_ADCMIX_R_SFT 7
- +#define RT5671_M_DAC1_R (0x1 << 6)
- +#define RT5671_M_DAC1_R_SFT 6
- +
- +/* Stereo DAC Mixer Control (0x2a) */
- +#define RT5671_M_DAC_L1 (0x1 << 14)
- +#define RT5671_M_DAC_L1_SFT 14
- +#define RT5671_DAC_L1_STO_L_VOL_MASK (0x1 << 13)
- +#define RT5671_DAC_L1_STO_L_VOL_SFT 13
- +#define RT5671_M_DAC_L2 (0x1 << 12)
- +#define RT5671_M_DAC_L2_SFT 12
- +#define RT5671_DAC_L2_STO_L_VOL_MASK (0x1 << 11)
- +#define RT5671_DAC_L2_STO_L_VOL_SFT 11
- +#define RT5671_M_ANC_DAC_L (0x1 << 10)
- +#define RT5671_M_ANC_DAC_L_SFT 10
- +#define RT5671_M_DAC_R1_STO_L (0x1 << 9)
- +#define RT5671_M_DAC_R1_STO_L_SFT 9
- +#define RT5671_DAC_R1_STO_L_VOL_MASK (0x1 << 8)
- +#define RT5671_DAC_R1_STO_L_VOL_SFT 8
- +#define RT5671_M_DAC_R1 (0x1 << 6)
- +#define RT5671_M_DAC_R1_SFT 6
- +#define RT5671_DAC_R1_STO_R_VOL_MASK (0x1 << 5)
- +#define RT5671_DAC_R1_STO_R_VOL_SFT 5
- +#define RT5671_M_DAC_R2 (0x1 << 4)
- +#define RT5671_M_DAC_R2_SFT 4
- +#define RT5671_DAC_R2_STO_R_VOL_MASK (0x1 << 3)
- +#define RT5671_DAC_R2_STO_R_VOL_SFT 3
- +#define RT5671_M_ANC_DAC_R (0x1 << 2)
- +#define RT5671_M_ANC_DAC_R_SFT 2
- +#define RT5671_M_DAC_L1_STO_R (0x1 << 1)
- +#define RT5671_M_DAC_L1_STO_R_SFT 1
- +#define RT5671_DAC_L1_STO_R_VOL_MASK (0x1)
- +#define RT5671_DAC_L1_STO_R_VOL_SFT 0
- +
- +/* Mono DAC Mixer Control (0x2b) */
- +#define RT5671_M_DAC_L1_MONO_L (0x1 << 14)
- +#define RT5671_M_DAC_L1_MONO_L_SFT 14
- +#define RT5671_DAC_L1_MONO_L_VOL_MASK (0x1 << 13)
- +#define RT5671_DAC_L1_MONO_L_VOL_SFT 13
- +#define RT5671_M_DAC_L2_MONO_L (0x1 << 12)
- +#define RT5671_M_DAC_L2_MONO_L_SFT 12
- +#define RT5671_DAC_L2_MONO_L_VOL_MASK (0x1 << 11)
- +#define RT5671_DAC_L2_MONO_L_VOL_SFT 11
- +#define RT5671_M_DAC_R2_MONO_L (0x1 << 10)
- +#define RT5671_M_DAC_R2_MONO_L_SFT 10
- +#define RT5671_DAC_R2_MONO_L_VOL_MASK (0x1 << 9)
- +#define RT5671_DAC_R2_MONO_L_VOL_SFT 9
- +#define RT5671_M_DAC_R1_MONO_R (0x1 << 6)
- +#define RT5671_M_DAC_R1_MONO_R_SFT 6
- +#define RT5671_DAC_R1_MONO_R_VOL_MASK (0x1 << 5)
- +#define RT5671_DAC_R1_MONO_R_VOL_SFT 5
- +#define RT5671_M_DAC_R2_MONO_R (0x1 << 4)
- +#define RT5671_M_DAC_R2_MONO_R_SFT 4
- +#define RT5671_DAC_R2_MONO_R_VOL_MASK (0x1 << 3)
- +#define RT5671_DAC_R2_MONO_R_VOL_SFT 3
- +#define RT5671_M_DAC_L2_MONO_R (0x1 << 2)
- +#define RT5671_M_DAC_L2_MONO_R_SFT 2
- +#define RT5671_DAC_L2_MONO_R_VOL_MASK (0x1 << 1)
- +#define RT5671_DAC_L2_MONO_R_VOL_SFT 1
- +
- +/* Digital Mixer Control (0x2c) */
- +#define RT5671_M_STO_L_DAC_L (0x1 << 15)
- +#define RT5671_M_STO_L_DAC_L_SFT 15
- +#define RT5671_STO_L_DAC_L_VOL_MASK (0x1 << 14)
- +#define RT5671_STO_L_DAC_L_VOL_SFT 14
- +#define RT5671_M_DAC_L2_DAC_L (0x1 << 13)
- +#define RT5671_M_DAC_L2_DAC_L_SFT 13
- +#define RT5671_DAC_L2_DAC_L_VOL_MASK (0x1 << 12)
- +#define RT5671_DAC_L2_DAC_L_VOL_SFT 12
- +#define RT5671_M_STO_R_DAC_R (0x1 << 11)
- +#define RT5671_M_STO_R_DAC_R_SFT 11
- +#define RT5671_STO_R_DAC_R_VOL_MASK (0x1 << 10)
- +#define RT5671_STO_R_DAC_R_VOL_SFT 10
- +#define RT5671_M_DAC_R2_DAC_R (0x1 << 9)
- +#define RT5671_M_DAC_R2_DAC_R_SFT 9
- +#define RT5671_DAC_R2_DAC_R_VOL_MASK (0x1 << 8)
- +#define RT5671_DAC_R2_DAC_R_VOL_SFT 8
- +#define RT5671_M_DAC_R2_DAC_L (0x1 << 7)
- +#define RT5671_M_DAC_R2_DAC_L_SFT 7
- +#define RT5671_DAC_R2_DAC_L_VOL_MASK (0x1 << 6)
- +#define RT5671_DAC_R2_DAC_L_VOL_SFT 6
- +#define RT5671_M_DAC_L2_DAC_R (0x1 << 5)
- +#define RT5671_M_DAC_L2_DAC_R_SFT 5
- +#define RT5671_DAC_L2_DAC_R_VOL_MASK (0x1 << 4)
- +#define RT5671_DAC_L2_DAC_R_VOL_SFT 4
- +
- +/* DSP Path Control 1 (0x2d) */
- +#define RT5671_RXDP_SEL_MASK (0x7 << 13)
- +#define RT5671_RXDP_SEL_SFT 13
- +#define RT5671_RXDP_SRC_MASK (0x3 << 11)
- +#define RT5671_RXDP_SRC_SFT 11
- +#define RT5671_RXDP_SRC_NOR (0x0 << 11)
- +#define RT5671_RXDP_SRC_DIV2 (0x1 << 11)
- +#define RT5671_RXDP_SRC_DIV3 (0x2 << 11)
- +#define RT5671_TXDP_SRC_MASK (0x3 << 4)
- +#define RT5671_TXDP_SRC_SFT 4
- +#define RT5671_TXDP_SRC_NOR (0x0 << 4)
- +#define RT5671_TXDP_SRC_DIV2 (0x1 << 4)
- +#define RT5671_TXDP_SRC_DIV3 (0x2 << 4)
- +#define RT5671_TXDP_SLOT_SEL_MASK (0x3 << 2)
- +#define RT5671_TXDP_SLOT_SEL_SFT 2
- +#define RT5671_DSP_UL_SEL (0x1 << 1)
- +#define RT5671_DSP_UL_SFT 1
- +#define RT5671_DSP_DL_SEL 0x1
- +#define RT5671_DSP_DL_SFT 0
- +
- +/* DSP Path Control 2 (0x2e) */
- +#define RT5671_TXDP_L_VOL_MASK (0x7f << 8)
- +#define RT5671_TXDP_L_VOL_SFT 8
- +#define RT5671_TXDP_R_VOL_MASK (0x7f)
- +#define RT5671_TXDP_R_VOL_SFT 0
- +
- +/* Digital Interface Data Control (0x2f) */
- +#define RT5671_IF1_ADC2_IN_SEL (0x1 << 15)
- +#define RT5671_IF1_ADC2_IN_SFT 15
- +#define RT5671_IF2_ADC_IN_MASK (0x7 << 12)
- +#define RT5671_IF2_ADC_IN_SFT 12
- +#define RT5671_IF2_DAC_SEL_MASK (0x3 << 10)
- +#define RT5671_IF2_DAC_SEL_SFT 10
- +#define RT5671_IF2_ADC_SEL_MASK (0x3 << 8)
- +#define RT5671_IF2_ADC_SEL_SFT 8
- +#define RT5671_IF3_DAC_SEL_MASK (0x3 << 6)
- +#define RT5671_IF3_DAC_SEL_SFT 6
- +#define RT5671_IF3_ADC_SEL_MASK (0x3 << 4)
- +#define RT5671_IF3_ADC_SEL_SFT 4
- +#define RT5671_IF3_ADC_IN_MASK (0x7)
- +#define RT5671_IF3_ADC_IN_SFT 0
- +
- +/* Digital Interface Data Control (0x30) */
- +#define RT5671_IF4_ADC_IN_MASK (0x3 << 4)
- +#define RT5671_IF4_ADC_IN_SFT 4
- +
- +/* PDM Output Control (0x31) */
- +#define RT5671_PDM1_L_MASK (0x1 << 15)
- +#define RT5671_PDM1_L_SFT 15
- +#define RT5671_M_PDM1_L (0x1 << 14)
- +#define RT5671_M_PDM1_L_SFT 14
- +#define RT5671_PDM1_R_MASK (0x1 << 13)
- +#define RT5671_PDM1_R_SFT 13
- +#define RT5671_M_PDM1_R (0x1 << 12)
- +#define RT5671_M_PDM1_R_SFT 12
- +#define RT5671_PDM2_L_MASK (0x1 << 11)
- +#define RT5671_PDM2_L_SFT 11
- +#define RT5671_M_PDM2_L (0x1 << 10)
- +#define RT5671_M_PDM2_L_SFT 10
- +#define RT5671_PDM2_R_MASK (0x1 << 9)
- +#define RT5671_PDM2_R_SFT 9
- +#define RT5671_M_PDM2_R (0x1 << 8)
- +#define RT5671_M_PDM2_R_SFT 8
- +#define RT5671_PDM2_BUSY (0x1 << 7)
- +#define RT5671_PDM1_BUSY (0x1 << 6)
- +#define RT5671_PDM_PATTERN (0x1 << 5)
- +#define RT5671_PDM_GAIN (0x1 << 4)
- +#define RT5671_PDM_DIV_MASK (0x3)
- +
- +/* REC Left Mixer Control 1 (0x3b) */
- +#define RT5671_G_HP_L_RM_L_MASK (0x7 << 13)
- +#define RT5671_G_HP_L_RM_L_SFT 13
- +#define RT5671_G_IN_L_RM_L_MASK (0x7 << 10)
- +#define RT5671_G_IN_L_RM_L_SFT 10
- +#define RT5671_G_BST4_RM_L_MASK (0x7 << 7)
- +#define RT5671_G_BST4_RM_L_SFT 7
- +#define RT5671_G_BST3_RM_L_MASK (0x7 << 4)
- +#define RT5671_G_BST3_RM_L_SFT 4
- +#define RT5671_G_BST2_RM_L_MASK (0x7 << 1)
- +#define RT5671_G_BST2_RM_L_SFT 1
- +
- +/* REC Left Mixer Control 2 (0x3c) */
- +#define RT5671_G_BST1_RM_L_MASK (0x7 << 13)
- +#define RT5671_G_BST1_RM_L_SFT 13
- +#define RT5671_M_IN_L_RM_L (0x1 << 5)
- +#define RT5671_M_IN_L_RM_L_SFT 5
- +#define RT5671_M_BST4_RM_L (0x1 << 4)
- +#define RT5671_M_BST4_RM_L_SFT 4
- +#define RT5671_M_BST3_RM_L (0x1 << 3)
- +#define RT5671_M_BST3_RM_L_SFT 3
- +#define RT5671_M_BST2_RM_L (0x1 << 2)
- +#define RT5671_M_BST2_RM_L_SFT 2
- +#define RT5671_M_BST1_RM_L (0x1 << 1)
- +#define RT5671_M_BST1_RM_L_SFT 1
- +
- +/* REC Right Mixer Control 1 (0x3d) */
- +#define RT5671_G_HP_R_RM_R_MASK (0x7 << 13)
- +#define RT5671_G_HP_R_RM_R_SFT 13
- +#define RT5671_G_IN_R_RM_R_MASK (0x7 << 10)
- +#define RT5671_G_IN_R_RM_R_SFT 10
- +#define RT5671_G_BST4_RM_R_MASK (0x7 << 7)
- +#define RT5671_G_BST4_RM_R_SFT 7
- +#define RT5671_G_BST3_RM_R_MASK (0x7 << 4)
- +#define RT5671_G_BST3_RM_R_SFT 4
- +#define RT5671_G_BST2_RM_R_MASK (0x7 << 1)
- +#define RT5671_G_BST2_RM_R_SFT 1
- +
- +/* REC Right Mixer Control 2 (0x3e) */
- +#define RT5671_G_BST1_RM_R_MASK (0x7 << 13)
- +#define RT5671_G_BST1_RM_R_SFT 13
- +#define RT5671_M_IN_R_RM_R (0x1 << 5)
- +#define RT5671_M_IN_R_RM_R_SFT 5
- +#define RT5671_M_BST4_RM_R (0x1 << 4)
- +#define RT5671_M_BST4_RM_R_SFT 4
- +#define RT5671_M_BST3_RM_R (0x1 << 3)
- +#define RT5671_M_BST3_RM_R_SFT 3
- +#define RT5671_M_BST2_RM_R (0x1 << 2)
- +#define RT5671_M_BST2_RM_R_SFT 2
- +#define RT5671_M_BST1_RM_R (0x1 << 1)
- +#define RT5671_M_BST1_RM_R_SFT 1
- +
- +/* REC Mono Mixer Control 2 (0x40) */
- +#define RT5671_G_BST1_RM_M_MASK (0x7 << 13)
- +#define RT5671_G_BST1_RM_M_SFT 13
- +#define RT5671_M_BST4_RM_M (0x1 << 4)
- +#define RT5671_M_BST4_RM_M_SFT 4
- +#define RT5671_M_BST3_RM_M (0x1 << 3)
- +#define RT5671_M_BST3_RM_M_SFT 3
- +#define RT5671_M_BST2_RM_M (0x1 << 2)
- +#define RT5671_M_BST2_RM_M_SFT 2
- +#define RT5671_M_BST1_RM_M (0x1 << 1)
- +#define RT5671_M_BST1_RM_M_SFT 1
- +
- +
- +/* HPMIX Control (0x45) */
- +#define RT5671_M_DAC2_HM (0x1 << 15)
- +#define RT5671_M_DAC2_HM_SFT 15
- +#define RT5671_M_HPVOL_HM (0x1 << 14)
- +#define RT5671_M_HPVOL_HM_SFT 14
- +#define RT5671_M_DAC1_HM (0x1 << 13)
- +#define RT5671_M_DAC1_HM_SFT 13
- +#define RT5671_G_HPOMIX_MASK (0x1 << 12)
- +#define RT5671_G_HPOMIX_SFT 12
- +#define RT5671_M_INR1_HMR (0x1 << 3)
- +#define RT5671_M_INR1_HMR_SFT 3
- +#define RT5671_M_DACR1_HMR (0x1 << 2)
- +#define RT5671_M_DACR1_HMR_SFT 2
- +#define RT5671_M_INL1_HML (0x1 << 1)
- +#define RT5671_M_INL1_HML_SFT 1
- +#define RT5671_M_DACL1_HML (0x1)
- +#define RT5671_M_DACL1_HML_SFT 0
- +
- +/* Mono Output Mixer Control (0x4c) */
- +#define RT5671_M_DAC_L1_MA (0x1 << 14)
- +#define RT5671_M_DAC_L1_MA_SFT 14
- +#define RT5671_M_OV_R_MM (0x1 << 13)
- +#define RT5671_M_OV_R_MM_SFT 13
- +#define RT5671_M_OV_L_MM (0x1 << 12)
- +#define RT5671_M_OV_L_MM_SFT 12
- +#define RT5671_G_MONOMIX_MASK (0x1 << 10)
- +#define RT5671_G_MONOMIX_SFT 10
- +#define RT5671_M_DAC_R2_MM (0x1 << 9)
- +#define RT5671_M_DAC_R2_MM_SFT 9
- +#define RT5671_M_DAC_L2_MM (0x1 << 8)
- +#define RT5671_M_DAC_L2_MM_SFT 8
- +#define RT5671_M_BST4_MM (0x1 << 7)
- +#define RT5671_M_BST4_MM_SFT 7
- +
- +/* Output Left Mixer Control 1 (0x4d) */
- +#define RT5671_G_BST3_OM_L_MASK (0x7 << 13)
- +#define RT5671_G_BST3_OM_L_SFT 13
- +#define RT5671_G_BST2_OM_L_MASK (0x7 << 10)
- +#define RT5671_G_BST2_OM_L_SFT 10
- +#define RT5671_G_BST1_OM_L_MASK (0x7 << 7)
- +#define RT5671_G_BST1_OM_L_SFT 7
- +#define RT5671_G_IN_L_OM_L_MASK (0x7 << 4)
- +#define RT5671_G_IN_L_OM_L_SFT 4
- +#define RT5671_G_RM_L_OM_L_MASK (0x7 << 1)
- +#define RT5671_G_RM_L_OM_L_SFT 1
- +
- +/* Output Left Mixer Control 2 (0x4e) */
- +#define RT5671_G_DAC_R2_OM_L_MASK (0x7 << 13)
- +#define RT5671_G_DAC_R2_OM_L_SFT 13
- +#define RT5671_G_DAC_L2_OM_L_MASK (0x7 << 10)
- +#define RT5671_G_DAC_L2_OM_L_SFT 10
- +#define RT5671_G_DAC_L1_OM_L_MASK (0x7 << 7)
- +#define RT5671_G_DAC_L1_OM_L_SFT 7
- +
- +/* Output Left Mixer Control 3 (0x4f) */
- +#define RT5671_M_BST2_OM_L (0x1 << 6)
- +#define RT5671_M_BST2_OM_L_SFT 6
- +#define RT5671_M_BST1_OM_L (0x1 << 5)
- +#define RT5671_M_BST1_OM_L_SFT 5
- +#define RT5671_M_IN_L_OM_L (0x1 << 4)
- +#define RT5671_M_IN_L_OM_L_SFT 4
- +#define RT5671_M_DAC_L2_OM_L (0x1 << 1)
- +#define RT5671_M_DAC_L2_OM_L_SFT 1
- +#define RT5671_M_DAC_L1_OM_L (0x1)
- +#define RT5671_M_DAC_L1_OM_L_SFT 0
- +
- +/* Output Right Mixer Control 1 (0x50) */
- +#define RT5671_G_BST4_OM_R_MASK (0x7 << 13)
- +#define RT5671_G_BST4_OM_R_SFT 13
- +#define RT5671_G_BST2_OM_R_MASK (0x7 << 10)
- +#define RT5671_G_BST2_OM_R_SFT 10
- +#define RT5671_G_BST1_OM_R_MASK (0x7 << 7)
- +#define RT5671_G_BST1_OM_R_SFT 7
- +#define RT5671_G_IN_R_OM_R_MASK (0x7 << 4)
- +#define RT5671_G_IN_R_OM_R_SFT 4
- +#define RT5671_G_RM_R_OM_R_MASK (0x7 << 1)
- +#define RT5671_G_RM_R_OM_R_SFT 1
- +
- +/* Output Right Mixer Control 2 (0x51) */
- +#define RT5671_G_DAC_L2_OM_R_MASK (0x7 << 13)
- +#define RT5671_G_DAC_L2_OM_R_SFT 13
- +#define RT5671_G_DAC_R2_OM_R_MASK (0x7 << 10)
- +#define RT5671_G_DAC_R2_OM_R_SFT 10
- +#define RT5671_G_DAC_R1_OM_R_MASK (0x7 << 7)
- +#define RT5671_G_DAC_R1_OM_R_SFT 7
- +
- +/* Output Right Mixer Control 3 (0x52) */
- +#define RT5671_M_BST4_OM_R (0x1 << 7)
- +#define RT5671_M_BST4_OM_R_SFT 7
- +#define RT5671_M_BST3_OM_R (0x1 << 6)
- +#define RT5671_M_BST3_OM_R_SFT 6
- +#define RT5671_M_IN_R_OM_R (0x1 << 4)
- +#define RT5671_M_IN_R_OM_R_SFT 4
- +#define RT5671_M_DAC_R2_OM_R (0x1 << 1)
- +#define RT5671_M_DAC_R2_OM_R_SFT 1
- +#define RT5671_M_DAC_R1_OM_R (0x1)
- +#define RT5671_M_DAC_R1_OM_R_SFT 0
- +
- +/* LOUT Mixer Control (0x53) */
- +#define RT5671_M_DAC_L1_LM (0x1 << 15)
- +#define RT5671_M_DAC_L1_LM_SFT 15
- +#define RT5671_M_DAC_R1_LM (0x1 << 14)
- +#define RT5671_M_DAC_R1_LM_SFT 14
- +#define RT5671_M_OV_L_LM (0x1 << 13)
- +#define RT5671_M_OV_L_LM_SFT 13
- +#define RT5671_M_OV_R_LM (0x1 << 12)
- +#define RT5671_M_OV_R_LM_SFT 12
- +#define RT5671_G_LOUTMIX_MASK (0x1 << 11)
- +#define RT5671_G_LOUTMIX_SFT 11
- +
- +/* Power Management for Digital 1 (0x61) */
- +#define RT5671_PWR_I2S1 (0x1 << 15)
- +#define RT5671_PWR_I2S1_BIT 15
- +#define RT5671_PWR_I2S2 (0x1 << 14)
- +#define RT5671_PWR_I2S2_BIT 14
- +#define RT5671_PWR_I2S3 (0x1 << 13)
- +#define RT5671_PWR_I2S3_BIT 13
- +#define RT5671_PWR_DAC_L1 (0x1 << 12)
- +#define RT5671_PWR_DAC_L1_BIT 12
- +#define RT5671_PWR_DAC_R1 (0x1 << 11)
- +#define RT5671_PWR_DAC_R1_BIT 11
- +#define RT5671_PWR_I2S4 (0x1 << 10)
- +#define RT5671_PWR_I2S4_BIT 10
- +#define RT5671_PWR_DAC_L2 (0x1 << 7)
- +#define RT5671_PWR_DAC_L2_BIT 7
- +#define RT5671_PWR_DAC_R2 (0x1 << 6)
- +#define RT5671_PWR_DAC_R2_BIT 6
- +#define RT5671_PWR_ADC_3 (0x1 << 3)
- +#define RT5671_PWR_ADC_3_BIT 3
- +#define RT5671_PWR_ADC_L (0x1 << 2)
- +#define RT5671_PWR_ADC_L_BIT 2
- +#define RT5671_PWR_ADC_R (0x1 << 1)
- +#define RT5671_PWR_ADC_R_BIT 1
- +#define RT5671_PWR_CLS_D (0x1)
- +#define RT5671_PWR_CLS_D_BIT 0
- +
- +/* Power Management for Digital 2 (0x62) */
- +#define RT5671_PWR_ADC_S1F (0x1 << 15)
- +#define RT5671_PWR_ADC_S1F_BIT 15
- +#define RT5671_PWR_ADC_MF_L (0x1 << 14)
- +#define RT5671_PWR_ADC_MF_L_BIT 14
- +#define RT5671_PWR_ADC_MF_R (0x1 << 13)
- +#define RT5671_PWR_ADC_MF_R_BIT 13
- +#define RT5671_PWR_I2S_DSP (0x1 << 12)
- +#define RT5671_PWR_I2S_DSP_BIT 12
- +#define RT5671_PWR_DAC_S1F (0x1 << 11)
- +#define RT5671_PWR_DAC_S1F_BIT 11
- +#define RT5671_PWR_DAC_MF_L (0x1 << 10)
- +#define RT5671_PWR_DAC_MF_L_BIT 10
- +#define RT5671_PWR_DAC_MF_R (0x1 << 9)
- +#define RT5671_PWR_DAC_MF_R_BIT 9
- +#define RT5671_PWR_ADC_S2F (0x1 << 8)
- +#define RT5671_PWR_ADC_S2F_BIT 8
- +#define RT5671_PWR_PDM1 (0x1 << 7)
- +#define RT5671_PWR_PDM1_BIT 7
- +#define RT5671_PWR_PDM2 (0x1 << 6)
- +#define RT5671_PWR_PDM2_BIT 6
- +
- +/* Power Management for Analog 1 (0x63) */
- +#define RT5671_PWR_VREF1 (0x1 << 15)
- +#define RT5671_PWR_VREF1_BIT 15
- +#define RT5671_PWR_FV1 (0x1 << 14)
- +#define RT5671_PWR_FV1_BIT 14
- +#define RT5671_PWR_MB (0x1 << 13)
- +#define RT5671_PWR_MB_BIT 13
- +#define RT5671_PWR_LM (0x1 << 12)
- +#define RT5671_PWR_LM_BIT 12
- +#define RT5671_PWR_BG (0x1 << 11)
- +#define RT5671_PWR_BG_BIT 11
- +#define RT5671_PWR_MA (0x1 << 10)
- +#define RT5671_PWR_MA_BIT 10
- +#define RT5671_PWR_MM (0x1 << 9)
- +#define RT5671_PWR_MM_BIT 9
- +#define RT5671_PWR_HP_L (0x1 << 7)
- +#define RT5671_PWR_HP_L_BIT 7
- +#define RT5671_PWR_HP_R (0x1 << 6)
- +#define RT5671_PWR_HP_R_BIT 6
- +#define RT5671_PWR_HA (0x1 << 5)
- +#define RT5671_PWR_HA_BIT 5
- +#define RT5671_PWR_VREF2 (0x1 << 4)
- +#define RT5671_PWR_VREF2_BIT 4
- +#define RT5671_PWR_FV2 (0x1 << 3)
- +#define RT5671_PWR_FV2_BIT 3
- +#define RT5671_LDO_SEL_MASK (0x7)
- +#define RT5671_LDO_SEL_SFT 0
- +
- +/* Power Management for Analog 2 (0x64) */
- +#define RT5671_PWR_BST1 (0x1 << 15)
- +#define RT5671_PWR_BST1_BIT 15
- +#define RT5671_PWR_BST2 (0x1 << 14)
- +#define RT5671_PWR_BST2_BIT 14
- +#define RT5671_PWR_BST3 (0x1 << 13)
- +#define RT5671_PWR_BST3_BIT 13
- +#define RT5671_PWR_BST4 (0x1 << 12)
- +#define RT5671_PWR_BST4_BIT 12
- +#define RT5671_PWR_MB1 (0x1 << 11)
- +#define RT5671_PWR_MB1_BIT 11
- +#define RT5671_PWR_MB2 (0x1 << 10)
- +#define RT5671_PWR_MB2_BIT 10
- +#define RT5671_PWR_PLL (0x1 << 9)
- +#define RT5671_PWR_PLL_BIT 9
- +#define RT5671_PWR_BST1_P (0x1 << 6)
- +#define RT5671_PWR_BST1_P_BIT 6
- +#define RT5671_PWR_BST2_P (0x1 << 5)
- +#define RT5671_PWR_BST2_P_BIT 5
- +#define RT5671_PWR_BST3_P (0x1 << 4)
- +#define RT5671_PWR_BST3_P_BIT 4
- +#define RT5671_PWR_BST4_P (0x1 << 3)
- +#define RT5671_PWR_BST4_P_BIT 3
- +#define RT5671_PWR_JD1 (0x1 << 2)
- +#define RT5671_PWR_JD1_BIT 2
- +#define RT5671_PWR_JD (0x1 << 1)
- +#define RT5671_PWR_JD_BIT 1
- +
- +/* Power Management for Mixer (0x65) */
- +#define RT5671_PWR_OM_L (0x1 << 15)
- +#define RT5671_PWR_OM_L_BIT 15
- +#define RT5671_PWR_OM_R (0x1 << 14)
- +#define RT5671_PWR_OM_R_BIT 14
- +#define RT5671_PWR_RM_L (0x1 << 11)
- +#define RT5671_PWR_RM_L_BIT 11
- +#define RT5671_PWR_RM_R (0x1 << 10)
- +#define RT5671_PWR_RM_R_BIT 10
- +#define RT5671_PWR_RM_M (0x1 << 9)
- +#define RT5671_PWR_RM_M_BIT 9
- +
- +/* Power Management for Volume (0x66) */
- +#define RT5671_PWR_HV_L (0x1 << 11)
- +#define RT5671_PWR_HV_L_BIT 11
- +#define RT5671_PWR_HV_R (0x1 << 10)
- +#define RT5671_PWR_HV_R_BIT 10
- +#define RT5671_PWR_IN_L (0x1 << 9)
- +#define RT5671_PWR_IN_L_BIT 9
- +#define RT5671_PWR_IN_R (0x1 << 8)
- +#define RT5671_PWR_IN_R_BIT 8
- +#define RT5671_PWR_MIC_DET (0x1 << 5)
- +#define RT5671_PWR_MIC_DET_BIT 5
- +
- +/* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71 0x72) */
- +#define RT5671_I2S_MS_MASK (0x1 << 15)
- +#define RT5671_I2S_MS_SFT 15
- +#define RT5671_I2S_MS_M (0x0 << 15)
- +#define RT5671_I2S_MS_S (0x1 << 15)
- +#define RT5671_I2S_IF_MASK (0x7 << 12)
- +#define RT5671_I2S_IF_SFT 12
- +#define RT5671_I2S_O_CP_MASK (0x3 << 10)
- +#define RT5671_I2S_O_CP_SFT 10
- +#define RT5671_I2S_O_CP_OFF (0x0 << 10)
- +#define RT5671_I2S_O_CP_U_LAW (0x1 << 10)
- +#define RT5671_I2S_O_CP_A_LAW (0x2 << 10)
- +#define RT5671_I2S_I_CP_MASK (0x3 << 8)
- +#define RT5671_I2S_I_CP_SFT 8
- +#define RT5671_I2S_I_CP_OFF (0x0 << 8)
- +#define RT5671_I2S_I_CP_U_LAW (0x1 << 8)
- +#define RT5671_I2S_I_CP_A_LAW (0x2 << 8)
- +#define RT5671_I2S_BP_MASK (0x1 << 7)
- +#define RT5671_I2S_BP_SFT 7
- +#define RT5671_I2S_BP_NOR (0x0 << 7)
- +#define RT5671_I2S_BP_INV (0x1 << 7)
- +#define RT5671_I2S_DL_MASK (0x3 << 2)
- +#define RT5671_I2S_DL_SFT 2
- +#define RT5671_I2S_DL_16 (0x0 << 2)
- +#define RT5671_I2S_DL_20 (0x1 << 2)
- +#define RT5671_I2S_DL_24 (0x2 << 2)
- +#define RT5671_I2S_DL_8 (0x3 << 2)
- +#define RT5671_I2S_DF_MASK (0x3)
- +#define RT5671_I2S_DF_SFT 0
- +#define RT5671_I2S_DF_I2S (0x0)
- +#define RT5671_I2S_DF_LEFT (0x1)
- +#define RT5671_I2S_DF_PCM_A (0x2)
- +#define RT5671_I2S_DF_PCM_B (0x3)
- +
- +/* I2S2 Audio Serial Data Port Control (0x71) */
- +#define RT5671_I2S2_SDI_MASK (0x1 << 6)
- +#define RT5671_I2S2_SDI_SFT 6
- +#define RT5671_I2S2_SDI_I2S1 (0x0 << 6)
- +#define RT5671_I2S2_SDI_I2S2 (0x1 << 6)
- +
- +/* ADC/DAC Clock Control 1 (0x73) */
- +#define RT5671_I2S_PD1_MASK (0x7 << 12)
- +#define RT5671_I2S_PD1_SFT 12
- +#define RT5671_I2S_PD1_1 (0x0 << 12)
- +#define RT5671_I2S_PD1_2 (0x1 << 12)
- +#define RT5671_I2S_PD1_3 (0x2 << 12)
- +#define RT5671_I2S_PD1_4 (0x3 << 12)
- +#define RT5671_I2S_PD1_6 (0x4 << 12)
- +#define RT5671_I2S_PD1_8 (0x5 << 12)
- +#define RT5671_I2S_PD1_12 (0x6 << 12)
- +#define RT5671_I2S_PD1_16 (0x7 << 12)
- +#define RT5671_I2S_BCLK_MS2_MASK (0x1 << 11)
- +#define RT5671_I2S_BCLK_MS2_SFT 11
- +#define RT5671_I2S_BCLK_MS2_32 (0x0 << 11)
- +#define RT5671_I2S_BCLK_MS2_64 (0x1 << 11)
- +#define RT5671_I2S_PD2_MASK (0x7 << 8)
- +#define RT5671_I2S_PD2_SFT 8
- +#define RT5671_I2S_PD2_1 (0x0 << 8)
- +#define RT5671_I2S_PD2_2 (0x1 << 8)
- +#define RT5671_I2S_PD2_3 (0x2 << 8)
- +#define RT5671_I2S_PD2_4 (0x3 << 8)
- +#define RT5671_I2S_PD2_6 (0x4 << 8)
- +#define RT5671_I2S_PD2_8 (0x5 << 8)
- +#define RT5671_I2S_PD2_12 (0x6 << 8)
- +#define RT5671_I2S_PD2_16 (0x7 << 8)
- +#define RT5671_I2S_BCLK_MS3_MASK (0x1 << 7)
- +#define RT5671_I2S_BCLK_MS3_SFT 7
- +#define RT5671_I2S_BCLK_MS3_32 (0x0 << 7)
- +#define RT5671_I2S_BCLK_MS3_64 (0x1 << 7)
- +#define RT5671_I2S_PD3_MASK (0x7 << 4)
- +#define RT5671_I2S_PD3_SFT 4
- +#define RT5671_I2S_PD3_1 (0x0 << 4)
- +#define RT5671_I2S_PD3_2 (0x1 << 4)
- +#define RT5671_I2S_PD3_3 (0x2 << 4)
- +#define RT5671_I2S_PD3_4 (0x3 << 4)
- +#define RT5671_I2S_PD3_6 (0x4 << 4)
- +#define RT5671_I2S_PD3_8 (0x5 << 4)
- +#define RT5671_I2S_PD3_12 (0x6 << 4)
- +#define RT5671_I2S_PD3_16 (0x7 << 4)
- +#define RT5671_DAC_OSR_MASK (0x3 << 2)
- +#define RT5671_DAC_OSR_SFT 2
- +#define RT5671_DAC_OSR_128 (0x0 << 2)
- +#define RT5671_DAC_OSR_64 (0x1 << 2)
- +#define RT5671_DAC_OSR_32 (0x2 << 2)
- +#define RT5671_DAC_OSR_16 (0x3 << 2)
- +#define RT5671_ADC_OSR_MASK (0x3)
- +#define RT5671_ADC_OSR_SFT 0
- +#define RT5671_ADC_OSR_128 (0x0)
- +#define RT5671_ADC_OSR_64 (0x1)
- +#define RT5671_ADC_OSR_32 (0x2)
- +#define RT5671_ADC_OSR_16 (0x3)
- +
- +/* ADC/DAC Clock Control 2 (0x74) */
- +#define RT5671_DAC_L_OSR_MASK (0x3 << 14)
- +#define RT5671_DAC_L_OSR_SFT 14
- +#define RT5671_DAC_L_OSR_128 (0x0 << 14)
- +#define RT5671_DAC_L_OSR_64 (0x1 << 14)
- +#define RT5671_DAC_L_OSR_32 (0x2 << 14)
- +#define RT5671_DAC_L_OSR_16 (0x3 << 14)
- +#define RT5671_ADC_R_OSR_MASK (0x3 << 12)
- +#define RT5671_ADC_R_OSR_SFT 12
- +#define RT5671_ADC_R_OSR_128 (0x0 << 12)
- +#define RT5671_ADC_R_OSR_64 (0x1 << 12)
- +#define RT5671_ADC_R_OSR_32 (0x2 << 12)
- +#define RT5671_ADC_R_OSR_16 (0x3 << 12)
- +#define RT5671_DAHPF_EN (0x1 << 11)
- +#define RT5671_DAHPF_EN_SFT 11
- +#define RT5671_ADHPF_EN (0x1 << 10)
- +#define RT5671_ADHPF_EN_SFT 10
- +
- +/* Digital Microphone Control (0x75) */
- +#define RT5671_DMIC_1_EN_MASK (0x1 << 15)
- +#define RT5671_DMIC_1_EN_SFT 15
- +#define RT5671_DMIC_1_DIS (0x0 << 15)
- +#define RT5671_DMIC_1_EN (0x1 << 15)
- +#define RT5671_DMIC_2_EN_MASK (0x1 << 14)
- +#define RT5671_DMIC_2_EN_SFT 14
- +#define RT5671_DMIC_2_DIS (0x0 << 14)
- +#define RT5671_DMIC_2_EN (0x1 << 14)
- +#define RT5671_DMIC_1L_LH_MASK (0x1 << 13)
- +#define RT5671_DMIC_1L_LH_SFT 13
- +#define RT5671_DMIC_1L_LH_FALLING (0x0 << 13)
- +#define RT5671_DMIC_1L_LH_RISING (0x1 << 13)
- +#define RT5671_DMIC_1R_LH_MASK (0x1 << 12)
- +#define RT5671_DMIC_1R_LH_SFT 12
- +#define RT5671_DMIC_1R_LH_FALLING (0x0 << 12)
- +#define RT5671_DMIC_1R_LH_RISING (0x1 << 12)
- +#define RT5671_DMIC_2_DP_MASK (0x1 << 10)
- +#define RT5671_DMIC_2_DP_SFT 10
- +#define RT5671_DMIC_2_DP_GPIO4 (0x0 << 10)
- +#define RT5671_DMIC_2_DP_IN1N (0x1 << 10)
- +#define RT5671_DMIC_2L_LH_MASK (0x1 << 9)
- +#define RT5671_DMIC_2L_LH_SFT 9
- +#define RT5671_DMIC_2L_LH_FALLING (0x0 << 9)
- +#define RT5671_DMIC_2L_LH_RISING (0x1 << 9)
- +#define RT5671_DMIC_2R_LH_MASK (0x1 << 8)
- +#define RT5671_DMIC_2R_LH_SFT 8
- +#define RT5671_DMIC_2R_LH_FALLING (0x0 << 8)
- +#define RT5671_DMIC_2R_LH_RISING (0x1 << 8)
- +#define RT5671_DMIC_CLK_MASK (0x7 << 5)
- +#define RT5671_DMIC_CLK_SFT 5
- +#define RT5671_DMIC_3_EN_MASK (0x1 << 4)
- +#define RT5671_DMIC_3_EN_SFT 4
- +#define RT5671_DMIC_3_DIS (0x0 << 4)
- +#define RT5671_DMIC_3_EN (0x1 << 4)
- +#define RT5671_DMIC_1_DP_MASK (0x3 << 0)
- +#define RT5671_DMIC_1_DP_SFT 0
- +#define RT5671_DMIC_1_DP_GPIO6 (0x0 << 0)
- +#define RT5671_DMIC_1_DP_IN2P (0x1 << 0)
- +#define RT5671_DMIC_1_DP_GPIO7 (0x2 << 0)
- +
- +/* Clock Control 1 (0x7f) */
- +#define RT5671_I2S_BCLK_MS4_MASK (0x1 << 15)
- +#define RT5671_I2S_BCLK_MS4_SFT 15
- +#define RT5671_I2S_BCLK_MS4_32 (0x0 << 15)
- +#define RT5671_I2S_BCLK_MS4_64 (0x1 << 15)
- +#define RT5671_I2S_PD4_MASK (0x7 << 12)
- +#define RT5671_I2S_PD4_SFT 12
- +#define RT5671_I2S_PD4_1 (0x0 << 12)
- +#define RT5671_I2S_PD4_2 (0x1 << 12)
- +#define RT5671_I2S_PD4_3 (0x2 << 12)
- +#define RT5671_I2S_PD4_4 (0x3 << 12)
- +#define RT5671_I2S_PD4_6 (0x4 << 12)
- +#define RT5671_I2S_PD4_8 (0x5 << 12)
- +#define RT5671_I2S_PD4_12 (0x6 << 12)
- +#define RT5671_I2S_PD4_16 (0x7 << 12)
- +
- +/* Global Clock Control (0x80) */
- +#define RT5671_SCLK_SRC_MASK (0x3 << 14)
- +#define RT5671_SCLK_SRC_SFT 14
- +#define RT5671_SCLK_SRC_MCLK (0x0 << 14)
- +#define RT5671_SCLK_SRC_PLL1 (0x1 << 14)
- +#define RT5671_SCLK_SRC_RCCLK (0x2 << 14) /* 15MHz */
- +#define RT5671_PLL1_SRC_MASK (0x7 << 11)
- +#define RT5671_PLL1_SRC_SFT 11
- +#define RT5671_PLL1_SRC_MCLK (0x0 << 11)
- +#define RT5671_PLL1_SRC_BCLK1 (0x1 << 11)
- +#define RT5671_PLL1_SRC_BCLK2 (0x2 << 11)
- +#define RT5671_PLL1_SRC_BCLK3 (0x3 << 11)
- +#define RT5671_PLL1_SRC_BCLK4 (0x4 << 11)
- +#define RT5671_PLL1_SRC_Int (0x5 << 11)
- +#define RT5671_PLL1_PD_MASK (0x1 << 3)
- +#define RT5671_PLL1_PD_SFT 3
- +#define RT5671_PLL1_PD_1 (0x0 << 3)
- +#define RT5671_PLL1_PD_2 (0x1 << 3)
- +
- +#define RT5671_PLL_INP_MAX 40000000
- +#define RT5671_PLL_INP_MIN 256000
- +/* PLL M/N/K Code Control 1 (0x81) */
- +#define RT5671_PLL_N_MAX 0x1ff
- +#define RT5671_PLL_N_MASK (RT5671_PLL_N_MAX << 7)
- +#define RT5671_PLL_N_SFT 7
- +#define RT5671_PLL_K_MAX 0x1f
- +#define RT5671_PLL_K_MASK (RT5671_PLL_K_MAX)
- +#define RT5671_PLL_K_SFT 0
- +
- +/* PLL M/N/K Code Control 2 (0x82) */
- +#define RT5671_PLL_M_MAX 0xf
- +#define RT5671_PLL_M_MASK (RT5671_PLL_M_MAX << 12)
- +#define RT5671_PLL_M_SFT 12
- +#define RT5671_PLL_M_BP (0x1 << 11)
- +#define RT5671_PLL_M_BP_SFT 11
- +
- +/* ASRC Control 1 (0x83) */
- +#define RT5671_STO_T_MASK (0x1 << 15)
- +#define RT5671_STO_T_SFT 15
- +#define RT5671_STO_T_SCLK (0x0 << 15)
- +#define RT5671_STO_T_LRCK1 (0x1 << 15)
- +#define RT5671_M1_T_MASK (0x1 << 14)
- +#define RT5671_M1_T_SFT 14
- +#define RT5671_M1_T_I2S2 (0x0 << 14)
- +#define RT5671_M1_T_I2S2_D3 (0x1 << 14)
- +#define RT5671_I2S2_F_MASK (0x1 << 12)
- +#define RT5671_I2S2_F_SFT 12
- +#define RT5671_I2S2_F_I2S2_D2 (0x0 << 12)
- +#define RT5671_I2S2_F_I2S1_TCLK (0x1 << 12)
- +#define RT5671_DMIC_1_M_MASK (0x1 << 9)
- +#define RT5671_DMIC_1_M_SFT 9
- +#define RT5671_DMIC_1_M_NOR (0x0 << 9)
- +#define RT5671_DMIC_1_M_ASYN (0x1 << 9)
- +#define RT5671_DMIC_2_M_MASK (0x1 << 8)
- +#define RT5671_DMIC_2_M_SFT 8
- +#define RT5671_DMIC_2_M_NOR (0x0 << 8)
- +#define RT5671_DMIC_2_M_ASYN (0x1 << 8)
- +
- +/* ASRC Control 2 (0x84) */
- +#define RT5671_MDA_L_M_MASK (0x1 << 15)
- +#define RT5671_MDA_L_M_SFT 15
- +#define RT5671_MDA_L_M_NOR (0x0 << 15)
- +#define RT5671_MDA_L_M_ASYN (0x1 << 15)
- +#define RT5671_MDA_R_M_MASK (0x1 << 14)
- +#define RT5671_MDA_R_M_SFT 14
- +#define RT5671_MDA_R_M_NOR (0x0 << 14)
- +#define RT5671_MDA_R_M_ASYN (0x1 << 14)
- +#define RT5671_MAD_L_M_MASK (0x1 << 13)
- +#define RT5671_MAD_L_M_SFT 13
- +#define RT5671_MAD_L_M_NOR (0x0 << 13)
- +#define RT5671_MAD_L_M_ASYN (0x1 << 13)
- +#define RT5671_MAD_R_M_MASK (0x1 << 12)
- +#define RT5671_MAD_R_M_SFT 12
- +#define RT5671_MAD_R_M_NOR (0x0 << 12)
- +#define RT5671_MAD_R_M_ASYN (0x1 << 12)
- +#define RT5671_ADC_M_MASK (0x1 << 11)
- +#define RT5671_ADC_M_SFT 11
- +#define RT5671_ADC_M_NOR (0x0 << 11)
- +#define RT5671_ADC_M_ASYN (0x1 << 11)
- +#define RT5671_STO_DAC_M_MASK (0x1 << 5)
- +#define RT5671_STO_DAC_M_SFT 5
- +#define RT5671_STO_DAC_M_NOR (0x0 << 5)
- +#define RT5671_STO_DAC_M_ASYN (0x1 << 5)
- +#define RT5671_I2S1_R_D_MASK (0x1 << 4)
- +#define RT5671_I2S1_R_D_SFT 4
- +#define RT5671_I2S1_R_D_DIS (0x0 << 4)
- +#define RT5671_I2S1_R_D_EN (0x1 << 4)
- +#define RT5671_I2S2_R_D_MASK (0x1 << 3)
- +#define RT5671_I2S2_R_D_SFT 3
- +#define RT5671_I2S2_R_D_DIS (0x0 << 3)
- +#define RT5671_I2S2_R_D_EN (0x1 << 3)
- +#define RT5671_PRE_SCLK_MASK (0x3)
- +#define RT5671_PRE_SCLK_SFT 0
- +#define RT5671_PRE_SCLK_512 (0x0)
- +#define RT5671_PRE_SCLK_1024 (0x1)
- +#define RT5671_PRE_SCLK_2048 (0x2)
- +
- +/* ASRC Control 3 (0x85) */
- +#define RT5671_I2S1_RATE_MASK (0xf << 12)
- +#define RT5671_I2S1_RATE_SFT 12
- +#define RT5671_I2S2_RATE_MASK (0xf << 8)
- +#define RT5671_I2S2_RATE_SFT 8
- +
- +/* ASRC Control 4 (0x89) */
- +#define RT5671_I2S1_PD_MASK (0x7 << 12)
- +#define RT5671_I2S1_PD_SFT 12
- +#define RT5671_I2S2_PD_MASK (0x7 << 8)
- +#define RT5671_I2S2_PD_SFT 8
- +
- +/* HPOUT Over Current Detection (0x8b) */
- +#define RT5671_HP_OVCD_MASK (0x1 << 10)
- +#define RT5671_HP_OVCD_SFT 10
- +#define RT5671_HP_OVCD_DIS (0x0 << 10)
- +#define RT5671_HP_OVCD_EN (0x1 << 10)
- +#define RT5671_HP_OC_TH_MASK (0x3 << 8)
- +#define RT5671_HP_OC_TH_SFT 8
- +#define RT5671_HP_OC_TH_90 (0x0 << 8)
- +#define RT5671_HP_OC_TH_105 (0x1 << 8)
- +#define RT5671_HP_OC_TH_120 (0x2 << 8)
- +#define RT5671_HP_OC_TH_135 (0x3 << 8)
- +
- +/* Class D Over Current Control (0x8c) */
- +#define RT5671_CLSD_OC_MASK (0x1 << 9)
- +#define RT5671_CLSD_OC_SFT 9
- +#define RT5671_CLSD_OC_PU (0x0 << 9)
- +#define RT5671_CLSD_OC_PD (0x1 << 9)
- +#define RT5671_AUTO_PD_MASK (0x1 << 8)
- +#define RT5671_AUTO_PD_SFT 8
- +#define RT5671_AUTO_PD_DIS (0x0 << 8)
- +#define RT5671_AUTO_PD_EN (0x1 << 8)
- +#define RT5671_CLSD_OC_TH_MASK (0x3f)
- +#define RT5671_CLSD_OC_TH_SFT 0
- +
- +/* Class D Output Control (0x8d) */
- +#define RT5671_CLSD_RATIO_MASK (0xf << 12)
- +#define RT5671_CLSD_RATIO_SFT 12
- +#define RT5671_CLSD_OM_MASK (0x1 << 11)
- +#define RT5671_CLSD_OM_SFT 11
- +#define RT5671_CLSD_OM_MONO (0x0 << 11)
- +#define RT5671_CLSD_OM_STO (0x1 << 11)
- +#define RT5671_CLSD_SCH_MASK (0x1 << 10)
- +#define RT5671_CLSD_SCH_SFT 10
- +#define RT5671_CLSD_SCH_L (0x0 << 10)
- +#define RT5671_CLSD_SCH_S (0x1 << 10)
- +
- +/* Depop Mode Control 1 (0x8e) */
- +#define RT5671_SMT_TRIG_MASK (0x1 << 15)
- +#define RT5671_SMT_TRIG_SFT 15
- +#define RT5671_SMT_TRIG_DIS (0x0 << 15)
- +#define RT5671_SMT_TRIG_EN (0x1 << 15)
- +#define RT5671_HP_L_SMT_MASK (0x1 << 9)
- +#define RT5671_HP_L_SMT_SFT 9
- +#define RT5671_HP_L_SMT_DIS (0x0 << 9)
- +#define RT5671_HP_L_SMT_EN (0x1 << 9)
- +#define RT5671_HP_R_SMT_MASK (0x1 << 8)
- +#define RT5671_HP_R_SMT_SFT 8
- +#define RT5671_HP_R_SMT_DIS (0x0 << 8)
- +#define RT5671_HP_R_SMT_EN (0x1 << 8)
- +#define RT5671_HP_CD_PD_MASK (0x1 << 7)
- +#define RT5671_HP_CD_PD_SFT 7
- +#define RT5671_HP_CD_PD_DIS (0x0 << 7)
- +#define RT5671_HP_CD_PD_EN (0x1 << 7)
- +#define RT5671_RSTN_MASK (0x1 << 6)
- +#define RT5671_RSTN_SFT 6
- +#define RT5671_RSTN_DIS (0x0 << 6)
- +#define RT5671_RSTN_EN (0x1 << 6)
- +#define RT5671_RSTP_MASK (0x1 << 5)
- +#define RT5671_RSTP_SFT 5
- +#define RT5671_RSTP_DIS (0x0 << 5)
- +#define RT5671_RSTP_EN (0x1 << 5)
- +#define RT5671_HP_CO_MASK (0x1 << 4)
- +#define RT5671_HP_CO_SFT 4
- +#define RT5671_HP_CO_DIS (0x0 << 4)
- +#define RT5671_HP_CO_EN (0x1 << 4)
- +#define RT5671_HP_CP_MASK (0x1 << 3)
- +#define RT5671_HP_CP_SFT 3
- +#define RT5671_HP_CP_PD (0x0 << 3)
- +#define RT5671_HP_CP_PU (0x1 << 3)
- +#define RT5671_HP_SG_MASK (0x1 << 2)
- +#define RT5671_HP_SG_SFT 2
- +#define RT5671_HP_SG_DIS (0x0 << 2)
- +#define RT5671_HP_SG_EN (0x1 << 2)
- +#define RT5671_HP_DP_MASK (0x1 << 1)
- +#define RT5671_HP_DP_SFT 1
- +#define RT5671_HP_DP_PD (0x0 << 1)
- +#define RT5671_HP_DP_PU (0x1 << 1)
- +#define RT5671_HP_CB_MASK (0x1)
- +#define RT5671_HP_CB_SFT 0
- +#define RT5671_HP_CB_PD (0x0)
- +#define RT5671_HP_CB_PU (0x1)
- +
- +/* Depop Mode Control 2 (0x8f) */
- +#define RT5671_DEPOP_MASK (0x1 << 13)
- +#define RT5671_DEPOP_SFT 13
- +#define RT5671_DEPOP_AUTO (0x0 << 13)
- +#define RT5671_DEPOP_MAN (0x1 << 13)
- +#define RT5671_RAMP_MASK (0x1 << 12)
- +#define RT5671_RAMP_SFT 12
- +#define RT5671_RAMP_DIS (0x0 << 12)
- +#define RT5671_RAMP_EN (0x1 << 12)
- +#define RT5671_BPS_MASK (0x1 << 11)
- +#define RT5671_BPS_SFT 11
- +#define RT5671_BPS_DIS (0x0 << 11)
- +#define RT5671_BPS_EN (0x1 << 11)
- +#define RT5671_FAST_UPDN_MASK (0x1 << 10)
- +#define RT5671_FAST_UPDN_SFT 10
- +#define RT5671_FAST_UPDN_DIS (0x0 << 10)
- +#define RT5671_FAST_UPDN_EN (0x1 << 10)
- +#define RT5671_MRES_MASK (0x3 << 8)
- +#define RT5671_MRES_SFT 8
- +#define RT5671_MRES_15MO (0x0 << 8)
- +#define RT5671_MRES_25MO (0x1 << 8)
- +#define RT5671_MRES_35MO (0x2 << 8)
- +#define RT5671_MRES_45MO (0x3 << 8)
- +#define RT5671_VLO_MASK (0x1 << 7)
- +#define RT5671_VLO_SFT 7
- +#define RT5671_VLO_3V (0x0 << 7)
- +#define RT5671_VLO_32V (0x1 << 7)
- +#define RT5671_DIG_DP_MASK (0x1 << 6)
- +#define RT5671_DIG_DP_SFT 6
- +#define RT5671_DIG_DP_DIS (0x0 << 6)
- +#define RT5671_DIG_DP_EN (0x1 << 6)
- +#define RT5671_DP_TH_MASK (0x3 << 4)
- +#define RT5671_DP_TH_SFT 4
- +
- +/* Depop Mode Control 3 (0x90) */
- +#define RT5671_CP_SYS_MASK (0x7 << 12)
- +#define RT5671_CP_SYS_SFT 12
- +#define RT5671_CP_FQ1_MASK (0x7 << 8)
- +#define RT5671_CP_FQ1_SFT 8
- +#define RT5671_CP_FQ2_MASK (0x7 << 4)
- +#define RT5671_CP_FQ2_SFT 4
- +#define RT5671_CP_FQ3_MASK (0x7)
- +#define RT5671_CP_FQ3_SFT 0
- +#define RT5671_CP_FQ_1_5_KHZ 0
- +#define RT5671_CP_FQ_3_KHZ 1
- +#define RT5671_CP_FQ_6_KHZ 2
- +#define RT5671_CP_FQ_12_KHZ 3
- +#define RT5671_CP_FQ_24_KHZ 4
- +#define RT5671_CP_FQ_48_KHZ 5
- +#define RT5671_CP_FQ_96_KHZ 6
- +#define RT5671_CP_FQ_192_KHZ 7
- +
- +/* HPOUT charge pump (0x91) */
- +#define RT5671_OSW_L_MASK (0x1 << 11)
- +#define RT5671_OSW_L_SFT 11
- +#define RT5671_OSW_L_DIS (0x0 << 11)
- +#define RT5671_OSW_L_EN (0x1 << 11)
- +#define RT5671_OSW_R_MASK (0x1 << 10)
- +#define RT5671_OSW_R_SFT 10
- +#define RT5671_OSW_R_DIS (0x0 << 10)
- +#define RT5671_OSW_R_EN (0x1 << 10)
- +#define RT5671_PM_HP_MASK (0x3 << 8)
- +#define RT5671_PM_HP_SFT 8
- +#define RT5671_PM_HP_LV (0x0 << 8)
- +#define RT5671_PM_HP_MV (0x1 << 8)
- +#define RT5671_PM_HP_HV (0x2 << 8)
- +#define RT5671_IB_HP_MASK (0x3 << 6)
- +#define RT5671_IB_HP_SFT 6
- +#define RT5671_IB_HP_125IL (0x0 << 6)
- +#define RT5671_IB_HP_25IL (0x1 << 6)
- +#define RT5671_IB_HP_5IL (0x2 << 6)
- +#define RT5671_IB_HP_1IL (0x3 << 6)
- +
- +/* PV detection and SPK gain control (0x92) */
- +#define RT5671_PVDD_DET_MASK (0x1 << 15)
- +#define RT5671_PVDD_DET_SFT 15
- +#define RT5671_PVDD_DET_DIS (0x0 << 15)
- +#define RT5671_PVDD_DET_EN (0x1 << 15)
- +#define RT5671_SPK_AG_MASK (0x1 << 14)
- +#define RT5671_SPK_AG_SFT 14
- +#define RT5671_SPK_AG_DIS (0x0 << 14)
- +#define RT5671_SPK_AG_EN (0x1 << 14)
- +
- +/* Micbias Control (0x93) */
- +#define RT5671_MIC1_BS_MASK (0x1 << 15)
- +#define RT5671_MIC1_BS_SFT 15
- +#define RT5671_MIC1_BS_9AV (0x0 << 15)
- +#define RT5671_MIC1_BS_75AV (0x1 << 15)
- +#define RT5671_MIC2_BS_MASK (0x1 << 14)
- +#define RT5671_MIC2_BS_SFT 14
- +#define RT5671_MIC2_BS_9AV (0x0 << 14)
- +#define RT5671_MIC2_BS_75AV (0x1 << 14)
- +#define RT5671_MIC1_CLK_MASK (0x1 << 13)
- +#define RT5671_MIC1_CLK_SFT 13
- +#define RT5671_MIC1_CLK_DIS (0x0 << 13)
- +#define RT5671_MIC1_CLK_EN (0x1 << 13)
- +#define RT5671_MIC2_CLK_MASK (0x1 << 12)
- +#define RT5671_MIC2_CLK_SFT 12
- +#define RT5671_MIC2_CLK_DIS (0x0 << 12)
- +#define RT5671_MIC2_CLK_EN (0x1 << 12)
- +#define RT5671_MIC1_OVCD_MASK (0x1 << 11)
- +#define RT5671_MIC1_OVCD_SFT 11
- +#define RT5671_MIC1_OVCD_DIS (0x0 << 11)
- +#define RT5671_MIC1_OVCD_EN (0x1 << 11)
- +#define RT5671_MIC1_OVTH_MASK (0x3 << 9)
- +#define RT5671_MIC1_OVTH_SFT 9
- +#define RT5671_MIC1_OVTH_600UA (0x0 << 9)
- +#define RT5671_MIC1_OVTH_1500UA (0x1 << 9)
- +#define RT5671_MIC1_OVTH_2000UA (0x2 << 9)
- +#define RT5671_MIC2_OVCD_MASK (0x1 << 8)
- +#define RT5671_MIC2_OVCD_SFT 8
- +#define RT5671_MIC2_OVCD_DIS (0x0 << 8)
- +#define RT5671_MIC2_OVCD_EN (0x1 << 8)
- +#define RT5671_MIC2_OVTH_MASK (0x3 << 6)
- +#define RT5671_MIC2_OVTH_SFT 6
- +#define RT5671_MIC2_OVTH_600UA (0x0 << 6)
- +#define RT5671_MIC2_OVTH_1500UA (0x1 << 6)
- +#define RT5671_MIC2_OVTH_2000UA (0x2 << 6)
- +#define RT5671_PWR_MB_MASK (0x1 << 5)
- +#define RT5671_PWR_MB_SFT 5
- +#define RT5671_PWR_MB_PD (0x0 << 5)
- +#define RT5671_PWR_MB_PU (0x1 << 5)
- +#define RT5671_PWR_CLK25M_MASK (0x1 << 4)
- +#define RT5671_PWR_CLK25M_SFT 4
- +#define RT5671_PWR_CLK25M_PD (0x0 << 4)
- +#define RT5671_PWR_CLK25M_PU (0x1 << 4)
- +
- +/* VAD Control 4 (0x9d) */
- +#define RT5671_VAD_SEL_MASK (0x3 << 8)
- +#define RT5671_VAD_SEL_SFT 8
- +
- +/* EQ Control 1 (0xb0) */
- +#define RT5671_EQ_SRC_MASK (0x1 << 15)
- +#define RT5671_EQ_SRC_SFT 15
- +#define RT5671_EQ_SRC_DAC (0x0 << 15)
- +#define RT5671_EQ_SRC_ADC (0x1 << 15)
- +#define RT5671_EQ_UPD (0x1 << 14)
- +#define RT5671_EQ_UPD_BIT 14
- +#define RT5671_EQ_CD_MASK (0x1 << 13)
- +#define RT5671_EQ_CD_SFT 13
- +#define RT5671_EQ_CD_DIS (0x0 << 13)
- +#define RT5671_EQ_CD_EN (0x1 << 13)
- +#define RT5671_EQ_DITH_MASK (0x3 << 8)
- +#define RT5671_EQ_DITH_SFT 8
- +#define RT5671_EQ_DITH_NOR (0x0 << 8)
- +#define RT5671_EQ_DITH_LSB (0x1 << 8)
- +#define RT5671_EQ_DITH_LSB_1 (0x2 << 8)
- +#define RT5671_EQ_DITH_LSB_2 (0x3 << 8)
- +
- +/* EQ Control 2 (0xb1) */
- +#define RT5671_EQ_HPF1_M_MASK (0x1 << 8)
- +#define RT5671_EQ_HPF1_M_SFT 8
- +#define RT5671_EQ_HPF1_M_HI (0x0 << 8)
- +#define RT5671_EQ_HPF1_M_1ST (0x1 << 8)
- +#define RT5671_EQ_LPF1_M_MASK (0x1 << 7)
- +#define RT5671_EQ_LPF1_M_SFT 7
- +#define RT5671_EQ_LPF1_M_LO (0x0 << 7)
- +#define RT5671_EQ_LPF1_M_1ST (0x1 << 7)
- +#define RT5671_EQ_HPF2_MASK (0x1 << 6)
- +#define RT5671_EQ_HPF2_SFT 6
- +#define RT5671_EQ_HPF2_DIS (0x0 << 6)
- +#define RT5671_EQ_HPF2_EN (0x1 << 6)
- +#define RT5671_EQ_HPF1_MASK (0x1 << 5)
- +#define RT5671_EQ_HPF1_SFT 5
- +#define RT5671_EQ_HPF1_DIS (0x0 << 5)
- +#define RT5671_EQ_HPF1_EN (0x1 << 5)
- +#define RT5671_EQ_BPF4_MASK (0x1 << 4)
- +#define RT5671_EQ_BPF4_SFT 4
- +#define RT5671_EQ_BPF4_DIS (0x0 << 4)
- +#define RT5671_EQ_BPF4_EN (0x1 << 4)
- +#define RT5671_EQ_BPF3_MASK (0x1 << 3)
- +#define RT5671_EQ_BPF3_SFT 3
- +#define RT5671_EQ_BPF3_DIS (0x0 << 3)
- +#define RT5671_EQ_BPF3_EN (0x1 << 3)
- +#define RT5671_EQ_BPF2_MASK (0x1 << 2)
- +#define RT5671_EQ_BPF2_SFT 2
- +#define RT5671_EQ_BPF2_DIS (0x0 << 2)
- +#define RT5671_EQ_BPF2_EN (0x1 << 2)
- +#define RT5671_EQ_BPF1_MASK (0x1 << 1)
- +#define RT5671_EQ_BPF1_SFT 1
- +#define RT5671_EQ_BPF1_DIS (0x0 << 1)
- +#define RT5671_EQ_BPF1_EN (0x1 << 1)
- +#define RT5671_EQ_LPF_MASK (0x1)
- +#define RT5671_EQ_LPF_SFT 0
- +#define RT5671_EQ_LPF_DIS (0x0)
- +#define RT5671_EQ_LPF_EN (0x1)
- +#define RT5671_EQ_CTRL_MASK (0x7f)
- +
- +/* Memory Test (0xb2) */
- +#define RT5671_MT_MASK (0x1 << 15)
- +#define RT5671_MT_SFT 15
- +#define RT5671_MT_DIS (0x0 << 15)
- +#define RT5671_MT_EN (0x1 << 15)
- +
- +/* DRC/AGC Control 1 (0xb4) */
- +#define RT5671_DRC_AGC_P_MASK (0x1 << 15)
- +#define RT5671_DRC_AGC_P_SFT 15
- +#define RT5671_DRC_AGC_P_DAC (0x0 << 15)
- +#define RT5671_DRC_AGC_P_ADC (0x1 << 15)
- +#define RT5671_DRC_AGC_MASK (0x1 << 14)
- +#define RT5671_DRC_AGC_SFT 14
- +#define RT5671_DRC_AGC_DIS (0x0 << 14)
- +#define RT5671_DRC_AGC_EN (0x1 << 14)
- +#define RT5671_DRC_AGC_UPD (0x1 << 13)
- +#define RT5671_DRC_AGC_UPD_BIT 13
- +#define RT5671_DRC_AGC_AR_MASK (0x1f << 8)
- +#define RT5671_DRC_AGC_AR_SFT 8
- +#define RT5671_DRC_AGC_R_MASK (0x7 << 5)
- +#define RT5671_DRC_AGC_R_SFT 5
- +#define RT5671_DRC_AGC_R_48K (0x1 << 5)
- +#define RT5671_DRC_AGC_R_96K (0x2 << 5)
- +#define RT5671_DRC_AGC_R_192K (0x3 << 5)
- +#define RT5671_DRC_AGC_R_441K (0x5 << 5)
- +#define RT5671_DRC_AGC_R_882K (0x6 << 5)
- +#define RT5671_DRC_AGC_R_1764K (0x7 << 5)
- +#define RT5671_DRC_AGC_RC_MASK (0x1f)
- +#define RT5671_DRC_AGC_RC_SFT 0
- +
- +/* DRC/AGC Control 2 (0xb5) */
- +#define RT5671_DRC_AGC_POB_MASK (0x3f << 8)
- +#define RT5671_DRC_AGC_POB_SFT 8
- +#define RT5671_DRC_AGC_CP_MASK (0x1 << 7)
- +#define RT5671_DRC_AGC_CP_SFT 7
- +#define RT5671_DRC_AGC_CP_DIS (0x0 << 7)
- +#define RT5671_DRC_AGC_CP_EN (0x1 << 7)
- +#define RT5671_DRC_AGC_CPR_MASK (0x3 << 5)
- +#define RT5671_DRC_AGC_CPR_SFT 5
- +#define RT5671_DRC_AGC_CPR_1_1 (0x0 << 5)
- +#define RT5671_DRC_AGC_CPR_1_2 (0x1 << 5)
- +#define RT5671_DRC_AGC_CPR_1_3 (0x2 << 5)
- +#define RT5671_DRC_AGC_CPR_1_4 (0x3 << 5)
- +#define RT5671_DRC_AGC_PRB_MASK (0x1f)
- +#define RT5671_DRC_AGC_PRB_SFT 0
- +
- +/* DRC/AGC Control 3 (0xb6) */
- +#define RT5671_DRC_AGC_NGB_MASK (0xf << 12)
- +#define RT5671_DRC_AGC_NGB_SFT 12
- +#define RT5671_DRC_AGC_TAR_MASK (0x1f << 7)
- +#define RT5671_DRC_AGC_TAR_SFT 7
- +#define RT5671_DRC_AGC_NG_MASK (0x1 << 6)
- +#define RT5671_DRC_AGC_NG_SFT 6
- +#define RT5671_DRC_AGC_NG_DIS (0x0 << 6)
- +#define RT5671_DRC_AGC_NG_EN (0x1 << 6)
- +#define RT5671_DRC_AGC_NGH_MASK (0x1 << 5)
- +#define RT5671_DRC_AGC_NGH_SFT 5
- +#define RT5671_DRC_AGC_NGH_DIS (0x0 << 5)
- +#define RT5671_DRC_AGC_NGH_EN (0x1 << 5)
- +#define RT5671_DRC_AGC_NGT_MASK (0x1f)
- +#define RT5671_DRC_AGC_NGT_SFT 0
- +
- +/* Jack Detect Control (0xbb) */
- +#define RT5671_JD_MASK (0x7 << 13)
- +#define RT5671_JD_SFT 13
- +#define RT5671_JD_DIS (0x0 << 13)
- +#define RT5671_JD_GPIO1 (0x1 << 13)
- +#define RT5671_JD_JD1_IN4P (0x2 << 13)
- +#define RT5671_JD_JD2_IN4N (0x3 << 13)
- +#define RT5671_JD_GPIO2 (0x4 << 13)
- +#define RT5671_JD_GPIO3 (0x5 << 13)
- +#define RT5671_JD_GPIO4 (0x6 << 13)
- +#define RT5671_JD_HP_MASK (0x1 << 11)
- +#define RT5671_JD_HP_SFT 11
- +#define RT5671_JD_HP_DIS (0x0 << 11)
- +#define RT5671_JD_HP_EN (0x1 << 11)
- +#define RT5671_JD_HP_TRG_MASK (0x1 << 10)
- +#define RT5671_JD_HP_TRG_SFT 10
- +#define RT5671_JD_HP_TRG_LO (0x0 << 10)
- +#define RT5671_JD_HP_TRG_HI (0x1 << 10)
- +#define RT5671_JD_SPL_MASK (0x1 << 9)
- +#define RT5671_JD_SPL_SFT 9
- +#define RT5671_JD_SPL_DIS (0x0 << 9)
- +#define RT5671_JD_SPL_EN (0x1 << 9)
- +#define RT5671_JD_SPL_TRG_MASK (0x1 << 8)
- +#define RT5671_JD_SPL_TRG_SFT 8
- +#define RT5671_JD_SPL_TRG_LO (0x0 << 8)
- +#define RT5671_JD_SPL_TRG_HI (0x1 << 8)
- +#define RT5671_JD_SPR_MASK (0x1 << 7)
- +#define RT5671_JD_SPR_SFT 7
- +#define RT5671_JD_SPR_DIS (0x0 << 7)
- +#define RT5671_JD_SPR_EN (0x1 << 7)
- +#define RT5671_JD_SPR_TRG_MASK (0x1 << 6)
- +#define RT5671_JD_SPR_TRG_SFT 6
- +#define RT5671_JD_SPR_TRG_LO (0x0 << 6)
- +#define RT5671_JD_SPR_TRG_HI (0x1 << 6)
- +#define RT5671_JD_MO_MASK (0x1 << 5)
- +#define RT5671_JD_MO_SFT 5
- +#define RT5671_JD_MO_DIS (0x0 << 5)
- +#define RT5671_JD_MO_EN (0x1 << 5)
- +#define RT5671_JD_MO_TRG_MASK (0x1 << 4)
- +#define RT5671_JD_MO_TRG_SFT 4
- +#define RT5671_JD_MO_TRG_LO (0x0 << 4)
- +#define RT5671_JD_MO_TRG_HI (0x1 << 4)
- +#define RT5671_JD_LO_MASK (0x1 << 3)
- +#define RT5671_JD_LO_SFT 3
- +#define RT5671_JD_LO_DIS (0x0 << 3)
- +#define RT5671_JD_LO_EN (0x1 << 3)
- +#define RT5671_JD_LO_TRG_MASK (0x1 << 2)
- +#define RT5671_JD_LO_TRG_SFT 2
- +#define RT5671_JD_LO_TRG_LO (0x0 << 2)
- +#define RT5671_JD_LO_TRG_HI (0x1 << 2)
- +#define RT5671_JD1_IN4P_MASK (0x1 << 1)
- +#define RT5671_JD1_IN4P_SFT 1
- +#define RT5671_JD1_IN4P_DIS (0x0 << 1)
- +#define RT5671_JD1_IN4P_EN (0x1 << 1)
- +#define RT5671_JD2_IN4N_MASK (0x1)
- +#define RT5671_JD2_IN4N_SFT 0
- +#define RT5671_JD2_IN4N_DIS (0x0)
- +#define RT5671_JD2_IN4N_EN (0x1)
- +
- +/* IRQ Control 1 (0xbd) */
- +#define RT5671_IRQ_JD_MASK (0x1 << 15)
- +#define RT5671_IRQ_JD_SFT 15
- +#define RT5671_IRQ_JD_BP (0x0 << 15)
- +#define RT5671_IRQ_JD_NOR (0x1 << 15)
- +#define RT5671_IRQ_OT_MASK (0x1 << 14)
- +#define RT5671_IRQ_OT_SFT 14
- +#define RT5671_IRQ_OT_BP (0x0 << 14)
- +#define RT5671_IRQ_OT_NOR (0x1 << 14)
- +#define RT5671_JD_STKY_MASK (0x1 << 13)
- +#define RT5671_JD_STKY_SFT 13
- +#define RT5671_JD_STKY_DIS (0x0 << 13)
- +#define RT5671_JD_STKY_EN (0x1 << 13)
- +#define RT5671_OT_STKY_MASK (0x1 << 12)
- +#define RT5671_OT_STKY_SFT 12
- +#define RT5671_OT_STKY_DIS (0x0 << 12)
- +#define RT5671_OT_STKY_EN (0x1 << 12)
- +#define RT5671_JD_P_MASK (0x1 << 11)
- +#define RT5671_JD_P_SFT 11
- +#define RT5671_JD_P_NOR (0x0 << 11)
- +#define RT5671_JD_P_INV (0x1 << 11)
- +#define RT5671_OT_P_MASK (0x1 << 10)
- +#define RT5671_OT_P_SFT 10
- +#define RT5671_OT_P_NOR (0x0 << 10)
- +#define RT5671_OT_P_INV (0x1 << 10)
- +
- +/* IRQ Control 2 (0xbe) */
- +#define RT5671_IRQ_MB1_OC_MASK (0x1 << 15)
- +#define RT5671_IRQ_MB1_OC_SFT 15
- +#define RT5671_IRQ_MB1_OC_BP (0x0 << 15)
- +#define RT5671_IRQ_MB1_OC_NOR (0x1 << 15)
- +#define RT5671_IRQ_MB2_OC_MASK (0x1 << 14)
- +#define RT5671_IRQ_MB2_OC_SFT 14
- +#define RT5671_IRQ_MB2_OC_BP (0x0 << 14)
- +#define RT5671_IRQ_MB2_OC_NOR (0x1 << 14)
- +#define RT5671_MB1_OC_STKY_MASK (0x1 << 11)
- +#define RT5671_MB1_OC_STKY_SFT 11
- +#define RT5671_MB1_OC_STKY_DIS (0x0 << 11)
- +#define RT5671_MB1_OC_STKY_EN (0x1 << 11)
- +#define RT5671_MB2_OC_STKY_MASK (0x1 << 10)
- +#define RT5671_MB2_OC_STKY_SFT 10
- +#define RT5671_MB2_OC_STKY_DIS (0x0 << 10)
- +#define RT5671_MB2_OC_STKY_EN (0x1 << 10)
- +#define RT5671_MB1_OC_P_MASK (0x1 << 7)
- +#define RT5671_MB1_OC_P_SFT 7
- +#define RT5671_MB1_OC_P_NOR (0x0 << 7)
- +#define RT5671_MB1_OC_P_INV (0x1 << 7)
- +#define RT5671_MB2_OC_P_MASK (0x1 << 6)
- +#define RT5671_MB2_OC_P_SFT 6
- +#define RT5671_MB2_OC_P_NOR (0x0 << 6)
- +#define RT5671_MB2_OC_P_INV (0x1 << 6)
- +#define RT5671_MB1_OC_CLR (0x1 << 3)
- +#define RT5671_MB1_OC_CLR_SFT 3
- +#define RT5671_MB2_OC_CLR (0x1 << 2)
- +#define RT5671_MB2_OC_CLR_SFT 2
- +
- +/* GPIO Control 1 (0xc0) */
- +#define RT5671_GP1_PIN_MASK (0x1 << 15)
- +#define RT5671_GP1_PIN_SFT 15
- +#define RT5671_GP1_PIN_GPIO1 (0x0 << 15)
- +#define RT5671_GP1_PIN_IRQ (0x1 << 15)
- +#define RT5671_GP2_PIN_MASK (0x1 << 14)
- +#define RT5671_GP2_PIN_SFT 14
- +#define RT5671_GP2_PIN_GPIO2 (0x0 << 14)
- +#define RT5671_GP2_PIN_DMIC1_SCL (0x1 << 14)
- +#define RT5671_GP3_PIN_MASK (0x3 << 12)
- +#define RT5671_GP3_PIN_SFT 12
- +#define RT5671_GP3_PIN_GPIO3 (0x0 << 12)
- +#define RT5671_GP3_PIN_DMIC1_SDA (0x1 << 12)
- +#define RT5671_GP3_PIN_IRQ (0x2 << 12)
- +#define RT5671_GP4_PIN_MASK (0x1 << 11)
- +#define RT5671_GP4_PIN_SFT 11
- +#define RT5671_GP4_PIN_GPIO4 (0x0 << 11)
- +#define RT5671_GP4_PIN_DMIC2_SDA (0x1 << 11)
- +#define RT5671_DP_SIG_MASK (0x1 << 10)
- +#define RT5671_DP_SIG_SFT 10
- +#define RT5671_DP_SIG_TEST (0x0 << 10)
- +#define RT5671_DP_SIG_AP (0x1 << 10)
- +#define RT5671_GPIO_M_MASK (0x1 << 9)
- +#define RT5671_GPIO_M_SFT 9
- +#define RT5671_GPIO_M_FLT (0x0 << 9)
- +#define RT5671_GPIO_M_PH (0x1 << 9)
- +#define RT5671_I2S2_PIN_MASK (0x1 << 8)
- +#define RT5671_I2S2_PIN_SFT 8
- +#define RT5671_I2S2_PIN_I2S (0x0 << 8)
- +#define RT5671_I2S2_PIN_GPIO (0x1 << 8)
- +#define RT5671_GP5_PIN_MASK (0x1 << 7)
- +#define RT5671_GP5_PIN_SFT 7
- +#define RT5671_GP5_PIN_GPIO5 (0x0 << 7)
- +#define RT5671_GP5_PIN_DMIC3_SCL (0x1 << 7)
- +#define RT5671_GP6_PIN_MASK (0x1 << 6)
- +#define RT5671_GP6_PIN_SFT 6
- +#define RT5671_GP6_PIN_GPIO6 (0x0 << 6)
- +#define RT5671_GP6_PIN_DMIC1_SDA (0x1 << 6)
- +#define RT5671_GP7_PIN_MASK (0x3 << 4)
- +#define RT5671_GP7_PIN_SFT 4
- +#define RT5671_GP7_PIN_GPIO7 (0x0 << 4)
- +#define RT5671_GP7_PIN_DMIC1_SDA (0x1 << 4)
- +#define RT5671_GP7_PIN_PDM_SCL2 (0x2 << 4)
- +#define RT5671_GP8_PIN_MASK (0x1 << 3)
- +#define RT5671_GP8_PIN_SFT 3
- +#define RT5671_GP8_PIN_GPIO8 (0x0 << 3)
- +#define RT5671_GP8_PIN_DMIC2_SDA (0x1 << 3)
- +#define RT5671_GP9_PIN_MASK (0x1 << 2)
- +#define RT5671_GP9_PIN_SFT 2
- +#define RT5671_GP9_PIN_GPIO9 (0x0 << 2)
- +#define RT5671_GP9_PIN_DMIC3_SDA (0x1 << 2)
- +#define RT5671_GP10_PIN_MASK (0x3)
- +#define RT5671_GP10_PIN_SFT 0
- +#define RT5671_GP10_PIN_GPIO9 (0x0)
- +#define RT5671_GP10_PIN_DMIC3_SDA (0x1)
- +#define RT5671_GP10_PIN_PDM_ADT2 (0x2)
- +
- +/* GPIO Control 3 (0xc2) */
- +#define RT5671_GP4_PF_MASK (0x1 << 11)
- +#define RT5671_GP4_PF_SFT 11
- +#define RT5671_GP4_PF_IN (0x0 << 11)
- +#define RT5671_GP4_PF_OUT (0x1 << 11)
- +#define RT5671_GP4_OUT_MASK (0x1 << 10)
- +#define RT5671_GP4_OUT_SFT 10
- +#define RT5671_GP4_OUT_LO (0x0 << 10)
- +#define RT5671_GP4_OUT_HI (0x1 << 10)
- +#define RT5671_GP4_P_MASK (0x1 << 9)
- +#define RT5671_GP4_P_SFT 9
- +#define RT5671_GP4_P_NOR (0x0 << 9)
- +#define RT5671_GP4_P_INV (0x1 << 9)
- +#define RT5671_GP3_PF_MASK (0x1 << 8)
- +#define RT5671_GP3_PF_SFT 8
- +#define RT5671_GP3_PF_IN (0x0 << 8)
- +#define RT5671_GP3_PF_OUT (0x1 << 8)
- +#define RT5671_GP3_OUT_MASK (0x1 << 7)
- +#define RT5671_GP3_OUT_SFT 7
- +#define RT5671_GP3_OUT_LO (0x0 << 7)
- +#define RT5671_GP3_OUT_HI (0x1 << 7)
- +#define RT5671_GP3_P_MASK (0x1 << 6)
- +#define RT5671_GP3_P_SFT 6
- +#define RT5671_GP3_P_NOR (0x0 << 6)
- +#define RT5671_GP3_P_INV (0x1 << 6)
- +#define RT5671_GP2_PF_MASK (0x1 << 5)
- +#define RT5671_GP2_PF_SFT 5
- +#define RT5671_GP2_PF_IN (0x0 << 5)
- +#define RT5671_GP2_PF_OUT (0x1 << 5)
- +#define RT5671_GP2_OUT_MASK (0x1 << 4)
- +#define RT5671_GP2_OUT_SFT 4
- +#define RT5671_GP2_OUT_LO (0x0 << 4)
- +#define RT5671_GP2_OUT_HI (0x1 << 4)
- +#define RT5671_GP2_P_MASK (0x1 << 3)
- +#define RT5671_GP2_P_SFT 3
- +#define RT5671_GP2_P_NOR (0x0 << 3)
- +#define RT5671_GP2_P_INV (0x1 << 3)
- +#define RT5671_GP1_PF_MASK (0x1 << 2)
- +#define RT5671_GP1_PF_SFT 2
- +#define RT5671_GP1_PF_IN (0x0 << 2)
- +#define RT5671_GP1_PF_OUT (0x1 << 2)
- +#define RT5671_GP1_OUT_MASK (0x1 << 1)
- +#define RT5671_GP1_OUT_SFT 1
- +#define RT5671_GP1_OUT_LO (0x0 << 1)
- +#define RT5671_GP1_OUT_HI (0x1 << 1)
- +#define RT5671_GP1_P_MASK (0x1)
- +#define RT5671_GP1_P_SFT 0
- +#define RT5671_GP1_P_NOR (0x0)
- +#define RT5671_GP1_P_INV (0x1)
- +
- +/* Scramble Function (0xcd) */
- +#define RT5671_SCB_KEY_MASK (0xff)
- +#define RT5671_SCB_KEY_SFT 0
- +
- +/* Scramble Control (0xce) */
- +#define RT5671_SCB_SWAP_MASK (0x1 << 15)
- +#define RT5671_SCB_SWAP_SFT 15
- +#define RT5671_SCB_SWAP_DIS (0x0 << 15)
- +#define RT5671_SCB_SWAP_EN (0x1 << 15)
- +#define RT5671_SCB_MASK (0x1 << 14)
- +#define RT5671_SCB_SFT 14
- +#define RT5671_SCB_DIS (0x0 << 14)
- +#define RT5671_SCB_EN (0x1 << 14)
- +
- +/* Baseback Control (0xcf) */
- +#define RT5671_BB_MASK (0x1 << 15)
- +#define RT5671_BB_SFT 15
- +#define RT5671_BB_DIS (0x0 << 15)
- +#define RT5671_BB_EN (0x1 << 15)
- +#define RT5671_BB_CT_MASK (0x7 << 12)
- +#define RT5671_BB_CT_SFT 12
- +#define RT5671_BB_CT_A (0x0 << 12)
- +#define RT5671_BB_CT_B (0x1 << 12)
- +#define RT5671_BB_CT_C (0x2 << 12)
- +#define RT5671_BB_CT_D (0x3 << 12)
- +#define RT5671_M_BB_L_MASK (0x1 << 9)
- +#define RT5671_M_BB_L_SFT 9
- +#define RT5671_M_BB_R_MASK (0x1 << 8)
- +#define RT5671_M_BB_R_SFT 8
- +#define RT5671_M_BB_HPF_L_MASK (0x1 << 7)
- +#define RT5671_M_BB_HPF_L_SFT 7
- +#define RT5671_M_BB_HPF_R_MASK (0x1 << 6)
- +#define RT5671_M_BB_HPF_R_SFT 6
- +#define RT5671_G_BB_BST_MASK (0x3f)
- +#define RT5671_G_BB_BST_SFT 0
- +
- +/* MP3 Plus Control 1 (0xd0) */
- +#define RT5671_M_MP3_L_MASK (0x1 << 15)
- +#define RT5671_M_MP3_L_SFT 15
- +#define RT5671_M_MP3_R_MASK (0x1 << 14)
- +#define RT5671_M_MP3_R_SFT 14
- +#define RT5671_M_MP3_MASK (0x1 << 13)
- +#define RT5671_M_MP3_SFT 13
- +#define RT5671_M_MP3_DIS (0x0 << 13)
- +#define RT5671_M_MP3_EN (0x1 << 13)
- +#define RT5671_EG_MP3_MASK (0x1f << 8)
- +#define RT5671_EG_MP3_SFT 8
- +#define RT5671_MP3_HLP_MASK (0x1 << 7)
- +#define RT5671_MP3_HLP_SFT 7
- +#define RT5671_MP3_HLP_DIS (0x0 << 7)
- +#define RT5671_MP3_HLP_EN (0x1 << 7)
- +#define RT5671_M_MP3_ORG_L_MASK (0x1 << 6)
- +#define RT5671_M_MP3_ORG_L_SFT 6
- +#define RT5671_M_MP3_ORG_R_MASK (0x1 << 5)
- +#define RT5671_M_MP3_ORG_R_SFT 5
- +
- +/* MP3 Plus Control 2 (0xd1) */
- +#define RT5671_MP3_WT_MASK (0x1 << 13)
- +#define RT5671_MP3_WT_SFT 13
- +#define RT5671_MP3_WT_1_4 (0x0 << 13)
- +#define RT5671_MP3_WT_1_2 (0x1 << 13)
- +#define RT5671_OG_MP3_MASK (0x1f << 8)
- +#define RT5671_OG_MP3_SFT 8
- +#define RT5671_HG_MP3_MASK (0x3f)
- +#define RT5671_HG_MP3_SFT 0
- +
- +/* 3D HP Control 1 (0xd2) */
- +#define RT5671_3D_CF_MASK (0x1 << 15)
- +#define RT5671_3D_CF_SFT 15
- +#define RT5671_3D_CF_DIS (0x0 << 15)
- +#define RT5671_3D_CF_EN (0x1 << 15)
- +#define RT5671_3D_HP_MASK (0x1 << 14)
- +#define RT5671_3D_HP_SFT 14
- +#define RT5671_3D_HP_DIS (0x0 << 14)
- +#define RT5671_3D_HP_EN (0x1 << 14)
- +#define RT5671_3D_BT_MASK (0x1 << 13)
- +#define RT5671_3D_BT_SFT 13
- +#define RT5671_3D_BT_DIS (0x0 << 13)
- +#define RT5671_3D_BT_EN (0x1 << 13)
- +#define RT5671_3D_1F_MIX_MASK (0x3 << 11)
- +#define RT5671_3D_1F_MIX_SFT 11
- +#define RT5671_3D_HP_M_MASK (0x1 << 10)
- +#define RT5671_3D_HP_M_SFT 10
- +#define RT5671_3D_HP_M_SUR (0x0 << 10)
- +#define RT5671_3D_HP_M_FRO (0x1 << 10)
- +#define RT5671_M_3D_HRTF_MASK (0x1 << 9)
- +#define RT5671_M_3D_HRTF_SFT 9
- +#define RT5671_M_3D_D2H_MASK (0x1 << 8)
- +#define RT5671_M_3D_D2H_SFT 8
- +#define RT5671_M_3D_D2R_MASK (0x1 << 7)
- +#define RT5671_M_3D_D2R_SFT 7
- +#define RT5671_M_3D_REVB_MASK (0x1 << 6)
- +#define RT5671_M_3D_REVB_SFT 6
- +
- +/* Adjustable high pass filter control 1 (0xd3) */
- +#define RT5671_2ND_HPF_MASK (0x1 << 15)
- +#define RT5671_2ND_HPF_SFT 15
- +#define RT5671_2ND_HPF_DIS (0x0 << 15)
- +#define RT5671_2ND_HPF_EN (0x1 << 15)
- +#define RT5671_HPF_CF_L_MASK (0x7 << 12)
- +#define RT5671_HPF_CF_L_SFT 12
- +#define RT5671_1ST_HPF_MASK (0x1 << 11)
- +#define RT5671_1ST_HPF_SFT 11
- +#define RT5671_1ST_HPF_DIS (0x0 << 11)
- +#define RT5671_1ST_HPF_EN (0x1 << 11)
- +#define RT5671_HPF_CF_R_MASK (0x7 << 8)
- +#define RT5671_HPF_CF_R_SFT 8
- +#define RT5671_ZD_T_MASK (0x3 << 6)
- +#define RT5671_ZD_T_SFT 6
- +#define RT5671_ZD_F_MASK (0x3 << 4)
- +#define RT5671_ZD_F_SFT 4
- +#define RT5671_ZD_F_IM (0x0 << 4)
- +#define RT5671_ZD_F_ZC_IM (0x1 << 4)
- +#define RT5671_ZD_F_ZC_IOD (0x2 << 4)
- +#define RT5671_ZD_F_UN (0x3 << 4)
- +
- +/* HP calibration control and Amp detection (0xd6) */
- +#define RT5671_SI_DAC_MASK (0x1 << 11)
- +#define RT5671_SI_DAC_SFT 11
- +#define RT5671_SI_DAC_AUTO (0x0 << 11)
- +#define RT5671_SI_DAC_TEST (0x1 << 11)
- +#define RT5671_DC_CAL_M_MASK (0x1 << 10)
- +#define RT5671_DC_CAL_M_SFT 10
- +#define RT5671_DC_CAL_M_CAL (0x0 << 10)
- +#define RT5671_DC_CAL_M_NOR (0x1 << 10)
- +#define RT5671_DC_CAL_MASK (0x1 << 9)
- +#define RT5671_DC_CAL_SFT 9
- +#define RT5671_DC_CAL_DIS (0x0 << 9)
- +#define RT5671_DC_CAL_EN (0x1 << 9)
- +#define RT5671_HPD_RCV_MASK (0x7 << 6)
- +#define RT5671_HPD_RCV_SFT 6
- +#define RT5671_HPD_PS_MASK (0x1 << 5)
- +#define RT5671_HPD_PS_SFT 5
- +#define RT5671_HPD_PS_DIS (0x0 << 5)
- +#define RT5671_HPD_PS_EN (0x1 << 5)
- +#define RT5671_CAL_M_MASK (0x1 << 4)
- +#define RT5671_CAL_M_SFT 4
- +#define RT5671_CAL_M_DEP (0x0 << 4)
- +#define RT5671_CAL_M_CAL (0x1 << 4)
- +#define RT5671_CAL_MASK (0x1 << 3)
- +#define RT5671_CAL_SFT 3
- +#define RT5671_CAL_DIS (0x0 << 3)
- +#define RT5671_CAL_EN (0x1 << 3)
- +#define RT5671_CAL_TEST_MASK (0x1 << 2)
- +#define RT5671_CAL_TEST_SFT 2
- +#define RT5671_CAL_TEST_DIS (0x0 << 2)
- +#define RT5671_CAL_TEST_EN (0x1 << 2)
- +#define RT5671_CAL_P_MASK (0x3)
- +#define RT5671_CAL_P_SFT 0
- +#define RT5671_CAL_P_NONE (0x0)
- +#define RT5671_CAL_P_CAL (0x1)
- +#define RT5671_CAL_P_DAC_CAL (0x2)
- +
- +/* Soft volume and zero cross control 1 (0xd9) */
- +#define RT5671_SV_MASK (0x1 << 15)
- +#define RT5671_SV_SFT 15
- +#define RT5671_SV_DIS (0x0 << 15)
- +#define RT5671_SV_EN (0x1 << 15)
- +#define RT5671_SPO_SV_MASK (0x1 << 14)
- +#define RT5671_SPO_SV_SFT 14
- +#define RT5671_SPO_SV_DIS (0x0 << 14)
- +#define RT5671_SPO_SV_EN (0x1 << 14)
- +#define RT5671_OUT_SV_MASK (0x1 << 13)
- +#define RT5671_OUT_SV_SFT 13
- +#define RT5671_OUT_SV_DIS (0x0 << 13)
- +#define RT5671_OUT_SV_EN (0x1 << 13)
- +#define RT5671_HP_SV_MASK (0x1 << 12)
- +#define RT5671_HP_SV_SFT 12
- +#define RT5671_HP_SV_DIS (0x0 << 12)
- +#define RT5671_HP_SV_EN (0x1 << 12)
- +#define RT5671_ZCD_DIG_MASK (0x1 << 11)
- +#define RT5671_ZCD_DIG_SFT 11
- +#define RT5671_ZCD_DIG_DIS (0x0 << 11)
- +#define RT5671_ZCD_DIG_EN (0x1 << 11)
- +#define RT5671_ZCD_MASK (0x1 << 10)
- +#define RT5671_ZCD_SFT 10
- +#define RT5671_ZCD_PD (0x0 << 10)
- +#define RT5671_ZCD_PU (0x1 << 10)
- +#define RT5671_M_ZCD_MASK (0x3f << 4)
- +#define RT5671_M_ZCD_SFT 4
- +#define RT5671_M_ZCD_RM_L (0x1 << 9)
- +#define RT5671_M_ZCD_RM_R (0x1 << 8)
- +#define RT5671_M_ZCD_SM_L (0x1 << 7)
- +#define RT5671_M_ZCD_SM_R (0x1 << 6)
- +#define RT5671_M_ZCD_OM_L (0x1 << 5)
- +#define RT5671_M_ZCD_OM_R (0x1 << 4)
- +#define RT5671_SV_DLY_MASK (0xf)
- +#define RT5671_SV_DLY_SFT 0
- +
- +/* Soft volume and zero cross control 2 (0xda) */
- +#define RT5671_ZCD_HP_MASK (0x1 << 15)
- +#define RT5671_ZCD_HP_SFT 15
- +#define RT5671_ZCD_HP_DIS (0x0 << 15)
- +#define RT5671_ZCD_HP_EN (0x1 << 15)
- +
- +
- +/* Codec Private Register definition */
- +/* 3D Speaker Control (0x63) */
- +#define RT5671_3D_SPK_MASK (0x1 << 15)
- +#define RT5671_3D_SPK_SFT 15
- +#define RT5671_3D_SPK_DIS (0x0 << 15)
- +#define RT5671_3D_SPK_EN (0x1 << 15)
- +#define RT5671_3D_SPK_M_MASK (0x3 << 13)
- +#define RT5671_3D_SPK_M_SFT 13
- +#define RT5671_3D_SPK_CG_MASK (0x1f << 8)
- +#define RT5671_3D_SPK_CG_SFT 8
- +#define RT5671_3D_SPK_SG_MASK (0x1f)
- +#define RT5671_3D_SPK_SG_SFT 0
- +
- +/* Wind Noise Detection Control 1 (0x6c) */
- +#define RT5671_WND_MASK (0x1 << 15)
- +#define RT5671_WND_SFT 15
- +#define RT5671_WND_DIS (0x0 << 15)
- +#define RT5671_WND_EN (0x1 << 15)
- +
- +/* Wind Noise Detection Control 2 (0x6d) */
- +#define RT5671_WND_FC_NW_MASK (0x3f << 10)
- +#define RT5671_WND_FC_NW_SFT 10
- +#define RT5671_WND_FC_WK_MASK (0x3f << 4)
- +#define RT5671_WND_FC_WK_SFT 4
- +
- +/* Wind Noise Detection Control 3 (0x6e) */
- +#define RT5671_HPF_FC_MASK (0x3f << 6)
- +#define RT5671_HPF_FC_SFT 6
- +#define RT5671_WND_FC_ST_MASK (0x3f)
- +#define RT5671_WND_FC_ST_SFT 0
- +
- +/* Wind Noise Detection Control 4 (0x6f) */
- +#define RT5671_WND_TH_LO_MASK (0x3ff)
- +#define RT5671_WND_TH_LO_SFT 0
- +
- +/* Wind Noise Detection Control 5 (0x70) */
- +#define RT5671_WND_TH_HI_MASK (0x3ff)
- +#define RT5671_WND_TH_HI_SFT 0
- +
- +/* Wind Noise Detection Control 8 (0x73) */
- +#define RT5671_WND_WIND_MASK (0x1 << 13) /* Read-Only */
- +#define RT5671_WND_WIND_SFT 13
- +#define RT5671_WND_STRONG_MASK (0x1 << 12) /* Read-Only */
- +#define RT5671_WND_STRONG_SFT 12
- +enum {
- + RT5671_NO_WIND,
- + RT5671_BREEZE,
- + RT5671_STORM,
- +};
- +
- +/* Dipole Speaker Interface (0x75) */
- +#define RT5671_DP_ATT_MASK (0x3 << 14)
- +#define RT5671_DP_ATT_SFT 14
- +#define RT5671_DP_SPK_MASK (0x1 << 10)
- +#define RT5671_DP_SPK_SFT 10
- +#define RT5671_DP_SPK_DIS (0x0 << 10)
- +#define RT5671_DP_SPK_EN (0x1 << 10)
- +
- +/* EQ Pre Volume Control (0xb3) */
- +#define RT5671_EQ_PRE_VOL_MASK (0xffff)
- +#define RT5671_EQ_PRE_VOL_SFT 0
- +
- +/* EQ Post Volume Control (0xb4) */
- +#define RT5671_EQ_PST_VOL_MASK (0xffff)
- +#define RT5671_EQ_PST_VOL_SFT 0
- +
- +/* Jack Detect Control 3 (0xf8) */
- +#define RT5671_CMP_MIC_IN_DET_MASK (0x7 << 12)
- +#define RT5671_JD_CBJ_EN (0x1 << 7)
- +#define RT5671_JD_CBJ_POL (0x1 << 6)
- +#define RT5671_JD_TRI_CBJ_SEL_MASK (0x7 << 3)
- +#define RT5671_JD_TRI_CBJ_SEL_SFT (3)
- +#define RT5671_JD_TRI_HPO_SEL_MASK (0x7)
- +#define RT5671_JD_TRI_HPO_SEL_SFT (0)
- +#define RT5671_JD_F_GPIO_JD1 (0x0)
- +#define RT5671_JD_F_JD1_1 (0x1)
- +#define RT5671_JD_F_JD1_2 (0x2)
- +#define RT5671_JD_F_JD2 (0x3)
- +#define RT5671_JD_F_JD3 (0x4)
- +#define RT5671_JD_F_GPIO_JD2 (0x5)
- +#define RT5671_JD_F_MX0B_12 (0x6)
- +
- +/* Digital Misc Control (0xfa) */
- +#define RT5671_RST_DSP (0x1 << 13)
- +#define RT5671_IF1_ADC1_IN1_SEL (0x1 << 12)
- +#define RT5671_IF1_ADC1_IN1_SFT 12
- +#define RT5671_IF1_ADC1_IN2_SEL (0x1 << 11)
- +#define RT5671_IF1_ADC1_IN2_SFT 11
- +#define RT5671_IF1_ADC2_IN1_SEL (0x1 << 10)
- +#define RT5671_IF1_ADC2_IN1_SFT 10
- +
- +/* General Control2 (0xfb) */
- +#define RT5671_RXDC_SRC_MASK (0x1 << 7)
- +#define RT5671_RXDC_SRC_STO (0x0 << 7)
- +#define RT5671_RXDC_SRC_MONO (0x1 << 7)
- +#define RT5671_RXDC_SRC_SFT (7)
- +#define RT5671_RXDP2_SEL_MASK (0x1 << 3)
- +#define RT5671_RXDP2_SEL_IF2 (0x0 << 3)
- +#define RT5671_RXDP2_SEL_ADC (0x1 << 3)
- +#define RT5671_RXDP2_SEL_SFT (3)
- +
- +
- +/* Vendor ID (0xfd) */
- +#define RT5671_VER_C 0x2
- +#define RT5671_VER_D 0x3
- +
- +
- +/* Volume Rescale */
- +#define RT5671_VOL_RSCL_MAX 0x27
- +#define RT5671_VOL_RSCL_RANGE 0x1F
- +/* Debug String Length */
- +#define RT5671_REG_DISP_LEN 13
- +
- +#define RT5671_NO_JACK BIT(0)
- +#define RT5671_HEADSET_DET BIT(1)
- +#define RT5671_HEADPHO_DET BIT(2)
- +
- +int rt5671_headset_detect(struct snd_soc_codec *codec, int jack_insert);
- +
- +/* System Clock Source */
- +enum {
- + RT5671_SCLK_S_MCLK,
- + RT5671_SCLK_S_PLL1,
- + RT5671_SCLK_S_RCCLK,
- +};
- +
- +/* PLL1 Source */
- +enum {
- + RT5671_PLL1_S_MCLK,
- + RT5671_PLL1_S_BCLK1,
- + RT5671_PLL1_S_BCLK2,
- + RT5671_PLL1_S_BCLK3,
- + RT5671_PLL1_S_BCLK4,
- +};
- +
- +enum {
- + RT5671_AIF1,
- + RT5671_AIF2,
- + RT5671_AIF3,
- + RT5671_AIF4,
- + RT5671_AIFS,
- +};
- +
- +enum {
- + RT5671_BTN_EVENT = BIT(0), /* Button Push */
- + RT5671_BR_EVENT = BIT(1), /* Button Release */
- + RT5671_J_IN_EVENT = BIT(2), /* Jack insert */
- + RT5671_J_OUT_EVENT = BIT(3), /* Jack evulse */
- + RT5671_VAD_EVENT = BIT(4), /* VAD Triggered */
- + RT5671_UN_EVENT = BIT(5), /* Unknown */
- +};
- +
- +#define RT5671_U_IF1 (0x1)
- +#define RT5671_U_IF2 (0x1 << 1)
- +#define RT5671_U_IF3 (0x1 << 2)
- +#define RT5671_U_IF4 (0x1 << 3)
- +
- +enum {
- + RT5671_DMIC_DIS,
- + RT5671_DMIC1,
- + RT5671_DMIC2,
- + RT5671_DMIC3,
- +};
- +
- +struct rt5671_pll_code {
- + bool m_bp; /* Indicates bypass m code or not. */
- + int m_code;
- + int n_code;
- + int k_code;
- +};
- +
- +struct rt5671_priv {
- + struct snd_soc_codec *codec;
- + struct rt5670_platform_data pdata;
- + struct snd_soc_jack hp_jack;
- + struct snd_soc_jack_gpio hp_gpio;
- +
- + int aif_pu;
- + int sysclk;
- + int sysclk_src;
- + int lrck[RT5671_AIFS];
- + int bclk[RT5671_AIFS];
- + int master[RT5671_AIFS];
- +
- + int pll_src;
- + int pll_in;
- + int pll_out;
- +
- + int dmic_en;
- + bool combo_jack_en;
- + int dsp_sw; /* expected parameter setting */
- + int drc_mode;
- + bool dsp_inited;
- + int jack_type;
- + unsigned int adb_register;
- + unsigned int adb_reg_addr[0x100];
- + unsigned int adb_reg_value[0x100];
- + unsigned char adb_reg_num;
- +};
- +
- +int rt5671_conn_mux_path(struct snd_soc_codec *codec,
- + char *widget_name, char *path_name);
- +
- +#endif /* __RT5671_H__ */
- diff --git a/sound/soc/codecs/rt5671_ioctl.c b/sound/soc/codecs/rt5671_ioctl.c
- new file mode 100644
- index 0000000..9fa040e
- --- /dev/null
- +++ b/sound/soc/codecs/rt5671_ioctl.c
- @@ -0,0 +1,138 @@
- +/*
- + * rt5671_ioctl.h -- RT5671 ALSA SoC audio driver IO control
- + *
- + * Copyright 2012 Realtek Microelectronics
- + * Copyright (C) 2016 XiaoMi, Inc.
- + * Author: Bard <bardliao@realtek.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/spi/spi.h>
- +#include <sound/soc.h>
- +#include "rt_codec_ioctl.h"
- +#include "rt5671_ioctl.h"
- +#include "rt5671.h"
- +#include "rt5671-dsp.h"
- +
- +static struct hweq_t hweq_param[] = {
- + {/* NORMAL */
- + {0},
- + {0},
- + 0x0000,
- + },
- + {/* SPK */
- + {0},
- + {0x1c10, 0x01f4, 0xc5e9, 0x1a98, 0x1d2c, 0xc882, 0x1c10,
- + 0x01f4, 0xe904, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4,
- + 0x1c10, 0x01f4, 0x2000, 0x0000, 0x2000},
- + 0x0000,
- + },
- + {/* HP */
- + {0},
- + {0x1c10, 0x01f4, 0xc5e9, 0x1a98, 0x1d2c, 0xc882, 0x1c10,
- + 0x01f4, 0xe904, 0x1c10, 0x01f4, 0xe904, 0x1c10, 0x01f4,
- + 0x1c10, 0x01f4, 0x2000, 0x0000, 0x2000},
- + 0x0000,
- + },
- +};
- +#define RT5671_HWEQ_LEN ARRAY_SIZE(hweq_param)
- +
- +int eqreg[EQ_CH_NUM][EQ_REG_NUM] = {
- + {0xa4, 0xa5, 0xeb, 0xec, 0xed, 0xee, 0xe7, 0xe8, 0xe9, 0xea, 0xe5,
- + 0xe6, 0xae, 0xaf, 0xb0, 0xb4, 0xb5, 0xb6, 0xba, 0xbb, 0xbc, 0xc0,
- + 0xc1, 0xc4, 0xc5, 0xc6, 0xca, 0xcc},
- + {0xa6, 0xa7, 0xf5, 0xf6, 0xf7, 0xf8, 0xf1, 0xf2, 0xf3, 0xf4, 0xef,
- + 0xf0, 0xb1, 0xb2, 0xb3, 0xb7, 0xb8, 0xb9, 0xbd, 0xbe, 0xbf, 0xc2,
- + 0xc3, 0xc7, 0xc8, 0xc9, 0xcb, 0xcd},
- + {0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
- + 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xe1, 0xe2},
- +};
- +
- +int rt5671_update_eqmode(
- + struct snd_soc_codec *codec, int channel, int mode)
- +{
- + struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
- + int i;
- +
- + if (codec == NULL || mode >= RT5671_HWEQ_LEN)
- + return -EINVAL;
- +
- + dev_dbg(codec->dev, "%s(): mode=%d\n", __func__, mode);
- +
- + for (i = 0; i <= EQ_REG_NUM; i++)
- + hweq_param[mode].reg[i] = eqreg[channel][i];
- +
- + for (i = 0; i <= EQ_REG_NUM; i++) {
- + if (hweq_param[mode].reg[i])
- + ioctl_ops->index_write(codec, hweq_param[mode].reg[i],
- + hweq_param[mode].value[i]);
- + else
- + break;
- + }
- + snd_soc_update_bits(codec, RT5671_EQ_CTRL2, RT5671_EQ_CTRL_MASK,
- + hweq_param[mode].ctrl);
- + snd_soc_update_bits(codec, RT5671_EQ_CTRL1,
- + RT5671_EQ_UPD, RT5671_EQ_UPD);
- + snd_soc_update_bits(codec, RT5671_EQ_CTRL1, RT5671_EQ_UPD, 0);
- +
- + return 0;
- +}
- +
- +int rt5671_ioctl_common(struct snd_hwdep *hw, struct file *file,
- + unsigned int cmd, unsigned long arg)
- +{
- + struct snd_soc_codec *codec = hw->private_data;
- + struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
- + struct rt_codec_cmd rt_codec;
- + int *buf;
- + static int eq_mode[EQ_CH_NUM];
- +
- + if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
- + dev_err(codec->dev, "copy_from_user faild\n");
- + return -EFAULT;
- + }
- + dev_dbg(codec->dev, "%s(): rt_codec.number=%d, cmd=%d\n",
- + __func__, rt_codec.number, cmd);
- + buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
- + if (buf == NULL)
- + return -ENOMEM;
- + if (copy_from_user(buf, rt_codec.buf,
- + sizeof(*buf) * rt_codec.number))
- + goto err;
- +
- + switch (cmd) {
- + case RT_SET_CODEC_HWEQ_IOCTL:
- + if (*buf >= EQ_CH_NUM)
- + break;
- + if (eq_mode[*buf] == *(buf + 1))
- + break;
- + eq_mode[*buf] = *(buf + 1);
- + rt5671_update_eqmode(codec, eq_mode[*buf], *buf);
- + break;
- +
- + case RT_GET_CODEC_ID:
- + *buf = snd_soc_read(codec, RT5671_VENDOR_ID2);
- + if (copy_to_user(rt_codec.buf, buf,
- + sizeof(*buf) * rt_codec.number))
- + goto err;
- + break;
- + case RT_READ_CODEC_DSP_IOCTL:
- + case RT_WRITE_CODEC_DSP_IOCTL:
- + case RT_GET_CODEC_DSP_MODE_IOCTL:
- + return rt5671_dsp_ioctl_common(hw, file, cmd, arg);
- + break;
- + default:
- + break;
- + }
- +
- + kfree(buf);
- + return 0;
- +
- +err:
- + kfree(buf);
- + return -EFAULT;
- +}
- +EXPORT_SYMBOL_GPL(rt5671_ioctl_common);
- diff --git a/sound/soc/codecs/rt5671_ioctl.h b/sound/soc/codecs/rt5671_ioctl.h
- new file mode 100644
- index 0000000..558c9ad
- --- /dev/null
- +++ b/sound/soc/codecs/rt5671_ioctl.h
- @@ -0,0 +1,45 @@
- +/*
- + * rt5671_ioctl.h -- RT5671 ALSA SoC audio driver IO control
- + *
- + * Copyright 2012 Realtek Microelectronics
- + * Copyright (C) 2016 XiaoMi, Inc.
- + * Author: Bard <bardliao@realtek.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#ifndef __RT5671_IOCTL_H__
- +#define __RT5671_IOCTL_H__
- +
- +#include <sound/hwdep.h>
- +#include <linux/ioctl.h>
- +
- +enum {
- + NORMAL = 0,
- + SPK,
- + HP,
- + MODE_NUM,
- +};
- +
- +enum {
- + EQ_CH_DACL = 0,
- + EQ_CH_DACR,
- + EQ_CH_ADC,
- + EQ_CH_NUM,
- +};
- +
- +#define EQ_REG_NUM 28
- +struct hweq_t {
- + unsigned int reg[EQ_REG_NUM];
- + unsigned int value[EQ_REG_NUM];
- + unsigned int ctrl;
- +};
- +
- +int rt5671_ioctl_common(struct snd_hwdep *hw, struct file *file,
- + unsigned int cmd, unsigned long arg);
- +int rt5671_update_eqmode(
- + struct snd_soc_codec *codec, int channel, int mode);
- +
- +#endif /* __RT5671_IOCTL_H__ */
- diff --git a/sound/soc/codecs/rt56xx_ioctl.c b/sound/soc/codecs/rt56xx_ioctl.c
- index 23ebf2a..96d0279 100644
- --- a/sound/soc/codecs/rt56xx_ioctl.c
- +++ b/sound/soc/codecs/rt56xx_ioctl.c
- @@ -145,7 +145,7 @@ static int rt56xx_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
- return 0;
- }
- -int realtek_ce_init_hwdep(struct snd_soc_codec *codec)
- +int rt56xx_init_hwdep(struct snd_soc_codec *codec)
- {
- struct snd_hwdep *hw;
- struct snd_card *card = codec->card->snd_card;
- @@ -165,7 +165,7 @@ int realtek_ce_init_hwdep(struct snd_soc_codec *codec)
- return 0;
- }
- -EXPORT_SYMBOL_GPL(realtek_ce_init_hwdep);
- +EXPORT_SYMBOL_GPL(rt56xx_init_hwdep);
- #endif
- struct rt56xx_ops *rt56xx_get_ioctl_ops(void)
- diff --git a/sound/soc/codecs/rt56xx_ioctl.h b/sound/soc/codecs/rt56xx_ioctl.h
- index caadd91..a60fc18 100644
- --- a/sound/soc/codecs/rt56xx_ioctl.h
- +++ b/sound/soc/codecs/rt56xx_ioctl.h
- @@ -73,6 +73,7 @@ enum {
- };
- int realtek_ce_init_hwdep(struct snd_soc_codec *codec);
- +int rt56xx_init_hwdep(struct snd_soc_codec *codec);
- struct rt56xx_ops *rt56xx_get_ioctl_ops(void);
- #endif /* __RT56XX_IOCTL_H__ */
- diff --git a/sound/soc/codecs/rt_codec_ioctl.c b/sound/soc/codecs/rt_codec_ioctl.c
- index a41c683..7675af1 100644
- --- a/sound/soc/codecs/rt_codec_ioctl.c
- +++ b/sound/soc/codecs/rt_codec_ioctl.c
- @@ -8,7 +8,6 @@
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
- -#define DEBUG 1
- #include <linux/spi/spi.h>
- #include <sound/soc.h>
- #include "rt_codec_ioctl.h"
- @@ -162,7 +161,8 @@ int realtek_ce_init_hwdep(struct snd_soc_codec *codec)
- dev_dbg(codec->dev, "enter %s\n", __func__);
- - if ((err = snd_hwdep_new(card, RT_CE_CODEC_HWDEP_NAME, 0, &hw)) < 0)
- + err = snd_hwdep_new(card, RT_CE_CODEC_HWDEP_NAME, 0, &hw);
- + if (err < 0)
- return err;
- strcpy(hw->name, RT_CE_CODEC_HWDEP_NAME);
- diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
- index 8efbda4..d20801d 100644
- --- a/sound/soc/codecs/spdif_transciever.c
- +++ b/sound/soc/codecs/spdif_transciever.c
- @@ -34,12 +34,6 @@ static int spdif_probe(struct snd_soc_codec *codec) {
- return 0;
- }
- -static const struct snd_soc_dapm_widget spdif_dapm_widgets[] = {
- - SND_SOC_DAPM_VMID("spdif dummy Vmid"),
- - SND_SOC_DAPM_OUTPUT("OUT"),
- - SND_SOC_DAPM_INPUT("IN"),
- -};
- -
- static const struct snd_soc_dapm_route spdif_intercon[] = {
- { "OUT", NULL, "Playback" },
- { "Capture", NULL, "IN" },
- @@ -57,8 +51,6 @@ static unsigned int spdif_read(struct snd_soc_codec *codec, unsigned int reg) {
- static struct snd_soc_codec_driver soc_codec_spdif_dit = {
- .probe = spdif_probe,
- - .dapm_widgets = spdif_dapm_widgets,
- - .num_dapm_widgets = ARRAY_SIZE(spdif_dapm_widgets),
- .dapm_routes = spdif_intercon,
- .num_dapm_routes = ARRAY_SIZE(spdif_intercon),
- .read = spdif_read,
- diff --git a/sound/soc/codecs/tfa98xx.c b/sound/soc/codecs/tfa98xx.c
- new file mode 100644
- index 0000000..21b5339
- --- /dev/null
- +++ b/sound/soc/codecs/tfa98xx.c
- @@ -0,0 +1,1513 @@
- +/*
- + * tfa98xx.c -- codec driver for TFA98XX
- + *
- + * Copyright (C) 2014 Xiaomi Corporation
- + * Copyright (C) 2016 XiaoMi, Inc.
- + *
- + * Author: Xiang Xiao <xiaoxiang@xiaomi.com>
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + *
- + */
- +
- +#include <linux/delay.h>
- +#include <linux/firmware.h>
- +#include <linux/i2c.h>
- +#include <linux/module.h>
- +#include <linux/slab.h>
- +#include <linux/workqueue.h>
- +#include <sound/pcm_params.h>
- +#include <sound/soc.h>
- +#include <sound/tlv.h>
- +
- +#include "tfa98xx.h"
- +
- +#define TFA98XX_STATUSREG_UP (TFA98XX_STATUSREG_PLLS | \
- + TFA98XX_STATUSREG_CLKS | \
- + TFA98XX_STATUSREG_AREFS)
- +#define TFA98XX_STATUSREG_UP_MSK (TFA98XX_STATUSREG_PLLS_MSK | \
- + TFA98XX_STATUSREG_MTPB_MSK | \
- + TFA98XX_STATUSREG_CLKS_MSK | \
- + TFA98XX_STATUSREG_AREFS_MSK)
- +
- +#define TFA98XX_STATUSREG_ERR1 (TFA98XX_STATUSREG_OCDS)
- +#define TFA98XX_STATUSREG_ERR1_MSK (TFA98XX_STATUSREG_OCDS_MSK)
- +
- +#define TFA98XX_STATUSREG_ERR2 (TFA98XX_STATUSREG_ACS | \
- + TFA98XX_STATUSREG_WDS)
- +#define TFA98XX_STATUSREG_ERR2_MSK (TFA98XX_STATUSREG_ACS_MSK | \
- + TFA98XX_STATUSREG_WDS_MSK)
- +
- +#define TFA98XX_I2SCTRL_MSB_J (2 << TFA98XX_I2SREG_I2SF_POS)
- +#define TFA98XX_I2SCTRL_PHILIPS (3 << TFA98XX_I2SREG_I2SF_POS)
- +#define TFA98XX_I2SCTRL_LSB_J_16 (4 << TFA98XX_I2SREG_I2SF_POS)
- +#define TFA98XX_I2SCTRL_LSB_J_18 (5 << TFA98XX_I2SREG_I2SF_POS)
- +#define TFA98XX_I2SCTRL_LSB_J_20 (6 << TFA98XX_I2SREG_I2SF_POS)
- +#define TFA98XX_I2SCTRL_LSB_J_24 (7 << TFA98XX_I2SREG_I2SF_POS)
- +
- +#define TFA98XX_I2SCTRL_RATE_08000 (0 << TFA98XX_I2SREG_I2SSR_POS)
- +#define TFA98XX_I2SCTRL_RATE_11025 (1 << TFA98XX_I2SREG_I2SSR_POS)
- +#define TFA98XX_I2SCTRL_RATE_12000 (2 << TFA98XX_I2SREG_I2SSR_POS)
- +#define TFA98XX_I2SCTRL_RATE_16000 (3 << TFA98XX_I2SREG_I2SSR_POS)
- +#define TFA98XX_I2SCTRL_RATE_22050 (4 << TFA98XX_I2SREG_I2SSR_POS)
- +#define TFA98XX_I2SCTRL_RATE_24000 (5 << TFA98XX_I2SREG_I2SSR_POS)
- +#define TFA98XX_I2SCTRL_RATE_32000 (6 << TFA98XX_I2SREG_I2SSR_POS)
- +#define TFA98XX_I2SCTRL_RATE_44100 (7 << TFA98XX_I2SREG_I2SSR_POS)
- +#define TFA98XX_I2SCTRL_RATE_48000 (8 << TFA98XX_I2SREG_I2SSR_POS)
- +
- +#define TFA98XX_MUTE_OFF 0
- +#define TFA98XX_MUTE_DIGITAL 1
- +#define TFA98XX_MUTE_AMPLIFIER 2
- +
- +#define TFA98XX_MODULE_SPEAKERBOOST (128 + 1)
- +#define TFA98XX_MODULE_BIQUADFILTERBANK (128 + 2)
- +
- +#define TFA98XX_PARAM_SET_LSMODEL 0x06
- +#define TFA98XX_PARAM_SET_PRESET 0x0D
- +#define TFA98XX_PARAM_SET_CONFIG 0x0E
- +
- +#define TFA98XX_FW_BOOT 0
- +#define TFA98XX_FW_ROM 1
- +#define TFA98XX_FW_SPEAKER 2
- +#define TFA98XX_FW_CONFIG 3
- +#define TFA98XX_FW_PRESET 4
- +#define TFA98XX_FW_EQUALIZER 5
- +#define TFA98XX_FW_NUMBER 6
- +
- +struct tfa98xx_priv {
- + struct mutex fw_lock;
- + bool fw_chg[TFA98XX_FW_NUMBER];
- + char fw_name[TFA98XX_FW_NUMBER][512];
- + const struct firmware *fw[TFA98XX_FW_NUMBER];
- + struct workqueue_struct *workqueue;
- + struct delayed_work monitor_work;
- + struct delayed_work download_work;
- + struct snd_soc_codec *codec;
- + unsigned int pilot_tone;
- + unsigned int reg_addr;
- + unsigned int fmt;
- + bool dsp_crash;
- + bool recalib;
- +};
- +
- +static int tfa98xx_bulk_read(struct snd_soc_codec *codec,
- + unsigned int reg_,
- + void *data, size_t len)
- +{
- + struct i2c_client *client = to_i2c_client(codec->dev);
- + struct i2c_msg msgs[2];
- + u8 reg = reg_;
- + int ret;
- +
- + msgs[0].addr = client->addr;
- + msgs[0].flags = client->flags;
- + msgs[0].len = 1;
- + msgs[0].buf = ®
- + msgs[1].addr = client->addr;
- + msgs[1].flags = client->flags | I2C_M_RD;
- + msgs[1].len = len;
- + msgs[1].buf = data;
- +
- + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- + if (ret > 0)
- + ret = 0;
- +
- + return ret;
- +}
- +
- +static int tfa98xx_bulk_write(struct snd_soc_codec *codec,
- + unsigned int reg,
- + const void *data, size_t len)
- +{
- + struct i2c_client *client = to_i2c_client(codec->dev);
- + struct i2c_msg msg;
- + u8 buf[len + 1];
- + int ret;
- +
- + buf[0] = reg;
- + memcpy(buf + 1, data, len);
- +
- + msg.addr = client->addr;
- + msg.flags = client->flags;
- + msg.len = len + 1;
- + msg.buf = buf;
- +
- + ret = i2c_transfer(client->adapter, &msg, 1);
- + if (ret > 0)
- + ret = 0;
- +
- + return ret;
- +}
- +
- +static unsigned int tfa98xx_read(struct snd_soc_codec *codec, unsigned int reg)
- +{
- + unsigned int val;
- + u8 buf[3];
- + int ret;
- +
- + if (reg >= codec->driver->reg_cache_size ||
- + snd_soc_codec_volatile_register(codec, reg) ||
- + codec->cache_bypass) {
- + if (codec->cache_only)
- + return -EINVAL;
- +
- + ret = tfa98xx_bulk_read(codec, reg, buf, reg == TFA98XX_CF_MEM ? 3 : 2);
- + if (ret < 0)
- + return ret;
- + else if (reg == TFA98XX_CF_MEM)
- + return (buf[0] << 16) | (buf[1] << 8) | buf[2];
- + else
- + return (buf[0] << 8) | buf[1];
- + }
- +
- + ret = snd_soc_cache_read(codec, reg, &val);
- + if (ret < 0)
- + return ret;
- + return val;
- +}
- +
- +static int tfa98xx_write(struct snd_soc_codec *codec, unsigned int reg,
- + unsigned int value)
- +{
- + u8 buf[3];
- + size_t sz;
- + int ret;
- +
- + if (!snd_soc_codec_volatile_register(codec, reg) &&
- + reg < codec->driver->reg_cache_size &&
- + !codec->cache_bypass) {
- + ret = snd_soc_cache_write(codec, reg, value);
- + if (ret < 0)
- + return ret;
- + }
- +
- + if (codec->cache_only) {
- + codec->cache_sync = 1;
- + return 0;
- + }
- +
- + if (reg == TFA98XX_CF_MEM) {
- + buf[0] = value >> 16;
- + buf[1] = value >> 8;
- + buf[2] = value >> 0;
- + sz = 3;
- + } else {
- + buf[0] = value >> 8;
- + buf[1] = value >> 0;
- + sz = 2;
- + }
- +
- + return tfa98xx_bulk_write(codec, reg, buf, sz);
- +}
- +
- +static unsigned int tfa98xx_read_dsp(struct snd_soc_codec *codec, unsigned int reg)
- +{
- + int ret;
- +
- + ret = snd_soc_write(codec, TFA98XX_CF_CONTROLS, (reg >> 15) & 0x0E);
- + if (ret < 0)
- + return ret;
- +
- + ret = snd_soc_write(codec, TFA98XX_CF_MAD, reg & 0xFFFF);
- + if (ret < 0)
- + return ret;
- +
- + return snd_soc_read(codec, TFA98XX_CF_MEM);
- +}
- +
- +static int tfa98xx_reset(struct snd_soc_codec *codec)
- +{
- + struct i2c_client *client = to_i2c_client(codec->dev);
- + int ret;
- +
- + /* use the low level function to bypass the codec cache */
- + ret = i2c_smbus_write_word_swapped(client, TFA98XX_SYS_CTRL, TFA98XX_SYS_CTRL_I2CR);
- + if (ret < 0)
- + return ret;
- +
- + /* apply the current setting after reset */
- + codec->cache_sync = 1;
- + ret = snd_soc_cache_sync(codec);
- + if (ret < 0)
- + return ret;
- +
- + return ret;
- +}
- +
- +static int tfa98xx_reset_dsp(struct snd_soc_codec *codec)
- +{
- + unsigned int sense4;
- + int ret;
- +
- + /* temporarily disable clock gating when dsp reset */
- + sense4 = snd_soc_read(codec, TFA98XX_CURRENTSENSE4);
- + ret = snd_soc_write(codec, TFA98XX_CURRENTSENSE4,
- + sense4 | TFA9897_CURRENTSENSE4_2);
- + if (ret < 0)
- + return ret;
- +
- + ret = snd_soc_update_bits(codec, TFA98XX_CF_CONTROLS,
- + TFA98XX_CF_CONTROLS_RST_MSK, TFA98XX_CF_CONTROLS_RST);
- + /* clock gating restore */
- + snd_soc_write(codec, TFA98XX_CURRENTSENSE4, sense4);
- +
- + return ret;
- +}
- +
- +static int tfa98xx_wait_clock(struct snd_soc_codec *codec)
- +{
- + unsigned int status;
- + int tries;
- +
- + for (tries = 10; tries > 0; tries--) {
- + status = snd_soc_read(codec, TFA98XX_STATUSREG);
- + if ((status & TFA98XX_STATUSREG_UP_MSK) == TFA98XX_STATUSREG_UP)
- + break;
- + mdelay(1);
- + }
- + if (tries == 0) {
- + dev_err(codec->dev, "Fail to sync i2s clock on time(%x)\n", status);
- + return -EBUSY;
- + }
- +
- + return 0;
- +}
- +
- +static int tfa98xx_power(struct snd_soc_codec *codec, bool on)
- +{
- + int ret;
- +
- + ret = snd_soc_update_bits_locked(codec, TFA98XX_SYS_CTRL,
- + TFA98XX_SYS_CTRL_PWDN_MSK, on ? 0 : TFA98XX_SYS_CTRL_PWDN);
- + if (ret < 0)
- + return ret;
- + if (on)
- + ret = tfa98xx_wait_clock(codec);
- + return ret;
- +}
- +
- +static int tfa98xx_mute(struct snd_soc_codec *codec, int mute)
- +{
- + unsigned int status;
- + int ret = 0, tries;
- +
- + switch (mute) {
- + case TFA98XX_MUTE_OFF:
- + ret = snd_soc_update_bits_locked(codec,
- + TFA98XX_AUDIO_CTR, TFA98XX_AUDIO_CTR_CFSM_MSK, 0);
- + if (ret < 0)
- + return ret;
- + ret = snd_soc_update_bits_locked(codec, TFA98XX_SYS_CTRL,
- + TFA98XX_SYS_CTRL_DCA_MSK | TFA98XX_SYS_CTRL_AMPE_MSK,
- + TFA98XX_SYS_CTRL_DCA | TFA98XX_SYS_CTRL_AMPE);
- + if (ret < 0)
- + return ret;
- + break;
- + case TFA98XX_MUTE_DIGITAL:
- + ret = snd_soc_update_bits_locked(codec, TFA98XX_AUDIO_CTR,
- + TFA98XX_AUDIO_CTR_CFSM_MSK, TFA98XX_AUDIO_CTR_CFSM);
- + if (ret < 0)
- + return ret;
- + ret = snd_soc_update_bits_locked(codec, TFA98XX_SYS_CTRL,
- + TFA98XX_SYS_CTRL_DCA_MSK | TFA98XX_SYS_CTRL_AMPE_MSK,
- + TFA98XX_SYS_CTRL_AMPE);
- + if (ret < 0)
- + return ret;
- + break;
- + case TFA98XX_MUTE_AMPLIFIER:
- + ret = snd_soc_update_bits_locked(codec,
- + TFA98XX_AUDIO_CTR, TFA98XX_AUDIO_CTR_CFSM_MSK, 0);
- + if (ret < 0)
- + return ret;
- + ret = snd_soc_update_bits_locked(codec, TFA98XX_SYS_CTRL,
- + TFA98XX_SYS_CTRL_DCA_MSK | TFA98XX_SYS_CTRL_AMPE_MSK,
- + 0);
- + if (ret < 0)
- + return ret;
- +
- + /* wait for amplifier to stop switching */
- + for (tries = 10; tries > 0; tries--) {
- + status = snd_soc_read(codec, TFA98XX_STATUSREG);
- + if (!(status & TFA98XX_STATUSREG_SWS_MSK))
- + break;
- + msleep(10);
- + }
- + if (tries == 0)
- + dev_warn(codec->dev, "Fail to stop amplifier on time\n");
- + break;
- + }
- +
- + return ret;
- +}
- +
- +static int tfa98xx_enable_otc(struct snd_soc_codec *codec, bool recalib)
- +{
- + unsigned int mtp, status;
- + int ret = 0, tries;
- +
- + mtp = snd_soc_read(codec, TFA98XX_MTP_SPKR_CAL);
- + if (recalib || !(mtp & TFA98XX_MTP_SPKR_CAL_MTPOTC_MSK)) {
- + ret = snd_soc_write(codec, TFA98XX_MTPKEY2_REG, 0x5A);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to unlock key(%d)\n", ret);
- + return ret;
- + }
- +
- + mtp &= ~TFA98XX_MTP_SPKR_CAL_MTPEX_MSK;
- + mtp |= TFA98XX_MTP_SPKR_CAL_MTPOTC_MSK;
- + ret = snd_soc_write(codec, TFA98XX_MTP_SPKR_CAL, mtp);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to update mtp(%d)\n", ret);
- + return ret;
- + }
- +
- + ret = snd_soc_update_bits(codec, TFA98XX_MTP_CTRL_REG3,
- + TFA98XX_MTP_CTRL_REG3_CIMTP_MSK, TFA98XX_MTP_CTRL_REG3_CIMTP);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to enable mtp copy(%d)\n", ret);
- + return ret;
- + }
- +
- + for (tries = 10; tries > 0; tries--) {
- + status = snd_soc_read(codec, TFA98XX_STATUSREG);
- + if (!(status & TFA98XX_STATUSREG_MTPB_MSK))
- + break;
- + msleep(100);
- + }
- + if (tries == 0) {
- + dev_err(codec->dev, "Fail to copy mtp on time\n");
- + return -EBUSY;
- + }
- + }
- +
- + return ret;
- +}
- +
- +static int tfa98xx_download_patch(struct snd_soc_codec *codec,
- + const struct firmware *fw)
- +{
- + int ret = -EINVAL;
- + size_t i, sz;
- +
- + /* start from 6 to skip the patch header */
- + for (i = 6; i < fw->size; i += sz) {
- + sz = fw->data[i++];
- + sz += fw->data[i++] << 8;
- +
- + if (i + sz > fw->size) {
- + dev_err(codec->dev,
- + "Invalid patch format(%x, %x)\n", i, sz);
- + return -EINVAL;
- + }
- +
- + dev_dbg(codec->dev,
- + "Download patch offset = %x, size = %x\n", i, sz);
- +
- + ret = snd_soc_bulk_write_raw(codec,
- + fw->data[i], &fw->data[i + 1], sz - 1);
- + if (ret < 0) {
- + dev_err(codec->dev,
- + "Fail to download patch(%x, %x, %d)\n", i, sz, ret);
- + return ret;
- + }
- + }
- +
- + return ret;
- +}
- +
- +static int tfa98xx_upload_file(struct snd_soc_codec *codec,
- + int module_id, int param_id,
- + void *data, size_t size)
- +{
- + unsigned int status;
- + int ret, tries;
- + u8 buf[7];
- +
- + /* step 1: write the header */
- + buf[0] = 0x00; /* CF_CONTROLS: req=0, int=0, aif=0, dmem=1(XMEM), rst_dsp=0 */
- + buf[1] = 0x02;
- + buf[2] = 0x00; /* CF_MAD: addr=1(ID) */
- + buf[3] = 0x01;
- + buf[4] = 0x00; /* CF_MEM */
- + buf[5] = module_id;
- + buf[6] = param_id;
- +
- + ret = snd_soc_bulk_write_raw(codec, TFA98XX_CF_CONTROLS, buf, 7);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to write data header(%d)\n", ret);
- + return ret;
- + }
- +
- + /* step 2: wake up dsp and wait done */
- + /* CF_CONTROLS: req=1, int=1, aif=0, dmem=1(XMEM), rst_dsp=0 */
- + ret = snd_soc_write(codec, TFA98XX_CF_CONTROLS, 0x0112);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to wake up dsp(%d)\n", ret);
- + return ret;
- + }
- +
- + for (tries = 10; tries > 0; tries--) {
- + status = snd_soc_read(codec, TFA98XX_CF_STATUS);
- + if ((status & TFA98XX_CF_STATUS_ACK_MSK) == 0x0100)
- + break;
- + mdelay(1);
- + }
- + if (tries == 0) {
- + dev_err(codec->dev, "Fail to response on time\n");
- + return -EBUSY;
- + }
- +
- + /* step 3: check dsp result */
- + buf[0] = 0x00; /* CF_CONTROLS: req=0, int=0, aif=0, dmem=1(XMEM), rst_dsp=0 */
- + buf[1] = 0x02;
- + buf[2] = 0x00; /* CF_MAD: addr=0(STATUS) */
- + buf[3] = 0x00;
- +
- + ret = snd_soc_bulk_write_raw(codec, TFA98XX_CF_CONTROLS, buf, 4);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to write status header(%d)\n", ret);
- + return ret;
- + }
- +
- + status = snd_soc_read(codec, TFA98XX_CF_MEM);
- + if (status != 0) {
- + dev_err(codec->dev, "Fail to upload file(%d)\n", status);
- + return -EINVAL;
- + }
- +
- + /* step 4: read the data */
- + ret = snd_soc_write(codec, TFA98XX_CF_MAD, 0x0002);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to write memory address(%d)\n", ret);
- + return ret;
- + }
- +
- + ret = tfa98xx_bulk_read(codec, TFA98XX_CF_MEM, data, size);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to read data(%d)\n", ret);
- + return ret;
- + }
- +
- + return ret;
- +}
- +
- +static int tfa98xx_download_file(struct snd_soc_codec *codec,
- + int module_id, int param_id,
- + const void *data, size_t size)
- +{
- + unsigned int status;
- + int ret, tries;
- + u8 buf[7];
- +
- + /* step 1: write the header */
- + buf[0] = 0x00; /* CF_CONTROLS: req=0, int=0, aif=0, dmem=1(XMEM), rst_dsp=0 */
- + buf[1] = 0x02;
- + buf[2] = 0x00; /* CF_MAD: addr=1(ID) */
- + buf[3] = 0x01;
- + buf[4] = 0x00; /* CF_MEM */
- + buf[5] = module_id;
- + buf[6] = param_id;
- +
- + ret = snd_soc_bulk_write_raw(codec, TFA98XX_CF_CONTROLS, buf, 7);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to write data header(%d)\n", ret);
- + return ret;
- + }
- +
- + /* step 2: write the data */
- + ret = snd_soc_bulk_write_raw(codec, TFA98XX_CF_MEM, data, size);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to write data(%d)\n", ret);
- + return ret;
- + }
- +
- + /* step 3: wake up dsp and wait done */
- + /* CF_CONTROLS: req=1, int=1, aif=0, dmem=1(XMEM), rst_dsp=0 */
- + ret = snd_soc_write(codec, TFA98XX_CF_CONTROLS, 0x0112);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to wake up dsp(%d)\n", ret);
- + return ret;
- + }
- +
- + for (tries = 10; tries > 0; tries--) {
- + status = snd_soc_read(codec, TFA98XX_CF_STATUS);
- + if ((status & TFA98XX_CF_STATUS_ACK_MSK) == 0x0100)
- + break;
- + mdelay(1);
- + }
- + if (tries == 0) {
- + dev_err(codec->dev, "Fail to response on time\n");
- + return -EBUSY;
- + }
- +
- + /* step 4: check dsp result */
- + buf[0] = 0x00; /* CF_CONTROLS: req=0, int=0, aif=0, dmem=1(XMEM), rst_dsp=0 */
- + buf[1] = 0x02;
- + buf[2] = 0x00; /* CF_MAD: addr=0(STATUS) */
- + buf[3] = 0x00;
- +
- + ret = snd_soc_bulk_write_raw(codec, TFA98XX_CF_CONTROLS, buf, 4);
- + if (ret < 0) {
- + dev_err(codec->dev, "Fail to write status header(%d)\n", ret);
- + return ret;
- + }
- +
- + status = snd_soc_read(codec, TFA98XX_CF_MEM);
- + if (status != 0) {
- + dev_err(codec->dev, "Fail to download file(%d)\n", status);
- + return -EINVAL;
- + }
- +
- + return ret;
- +}
- +
- +static int tfa98xx_download_and_verify_file(struct snd_soc_codec *codec,
- + int module_id, int param_id,
- + const void *data, size_t size)
- +{
- + u8 buf[size];
- + int ret;
- +
- + ret = tfa98xx_download_file(codec, module_id, param_id, data, size);
- + if (ret < 0)
- + return ret;
- + ret = tfa98xx_upload_file(codec, module_id, param_id, buf, size);
- + if (ret < 0)
- + return ret;
- + if (memcmp(data, buf, size) != 0) {
- + dev_err(codec->dev, "Write then read mismatch:\n");
- + print_hex_dump(KERN_ERR, "WR ",
- + DUMP_PREFIX_ADDRESS, 16, 1, data, size, true);
- + print_hex_dump(KERN_ERR, "RD ",
- + DUMP_PREFIX_ADDRESS, 16, 1, buf, size, true);
- + return -EINVAL;
- + }
- +
- + return ret;
- +}
- +
- +static void tfa98xx_download(struct work_struct *work)
- +{
- + struct tfa98xx_priv *tfa98xx;
- + struct snd_soc_codec *codec;
- + struct delayed_work *dwork;
- + unsigned int mtp;
- + int ret = 0, id, tries;
- +
- + dwork = to_delayed_work(work);
- + tfa98xx = container_of(dwork, struct tfa98xx_priv, download_work);
- + codec = tfa98xx->codec;
- +
- + mutex_lock(&tfa98xx->fw_lock);
- +
- + /* wait the clock stable */
- + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- + goto unlock; /* impossible to get the clock */
- +
- + ret = tfa98xx_wait_clock(codec);
- + if (ret < 0)
- + goto unlock;
- +
- + ret = tfa98xx_enable_otc(codec, tfa98xx->recalib);
- + if (ret < 0)
- + goto unlock;
- + tfa98xx->recalib = false;
- +
- + ret = tfa98xx_mute(codec, TFA98XX_MUTE_DIGITAL);
- + if (ret < 0)
- + goto unlock;
- +
- + for (id = 0; id < TFA98XX_FW_NUMBER; id++) {
- + if (tfa98xx->fw[id] == NULL)
- + goto unmute;
- + if (!tfa98xx->fw_chg[id])
- + continue;
- +
- + dev_info(codec->dev,
- + "Download firmware %s\n", tfa98xx->fw_name[id]);
- +
- + switch (id) {
- + case TFA98XX_FW_BOOT:
- + ret = tfa98xx_reset_dsp(codec);
- + if (ret < 0)
- + goto unmute;
- + ret = tfa98xx_wait_clock(codec);
- + if (ret < 0)
- + goto unmute;
- + ret = tfa98xx_download_patch(codec, tfa98xx->fw[id]);
- + if (ret < 0)
- + goto unmute;
- + /* reload rom patch */
- + tfa98xx->fw_chg[TFA98XX_FW_ROM] = true;
- + break;
- + case TFA98XX_FW_ROM:
- + ret = tfa98xx_download_patch(codec, tfa98xx->fw[id]);
- + if (ret < 0)
- + goto unmute;
- + /* reload all setting */
- + tfa98xx->fw_chg[TFA98XX_FW_SPEAKER] = true;
- + tfa98xx->fw_chg[TFA98XX_FW_CONFIG] = true;
- + tfa98xx->fw_chg[TFA98XX_FW_PRESET] = true;
- + tfa98xx->fw_chg[TFA98XX_FW_EQUALIZER] = true;
- + break;
- + case TFA98XX_FW_SPEAKER:
- + ret = tfa98xx_download_and_verify_file(codec,
- + TFA98XX_MODULE_SPEAKERBOOST,
- + TFA98XX_PARAM_SET_LSMODEL,
- + tfa98xx->fw[id]->data,
- + tfa98xx->fw[id]->size);
- + if (ret < 0)
- + goto unmute;
- + break;
- + case TFA98XX_FW_CONFIG:
- + ret = tfa98xx_download_and_verify_file(codec,
- + TFA98XX_MODULE_SPEAKERBOOST,
- + TFA98XX_PARAM_SET_CONFIG,
- + tfa98xx->fw[id]->data,
- + tfa98xx->fw[id]->size);
- + if (ret < 0)
- + goto unmute;
- + break;
- + case TFA98XX_FW_PRESET:
- + ret = tfa98xx_download_and_verify_file(codec,
- + TFA98XX_MODULE_SPEAKERBOOST,
- + TFA98XX_PARAM_SET_PRESET,
- + tfa98xx->fw[id]->data,
- + tfa98xx->fw[id]->size);
- + if (ret < 0)
- + goto unmute;
- + break;
- + case TFA98XX_FW_EQUALIZER:
- + ret = tfa98xx_download_and_verify_file(codec,
- + TFA98XX_MODULE_BIQUADFILTERBANK,
- + 0,
- + tfa98xx->fw[id]->data,
- + tfa98xx->fw[id]->size);
- + if (ret < 0)
- + goto unmute;
- + break;
- + }
- +
- + /* done, clear dirty flag */
- + tfa98xx->fw_chg[id] = false;
- + }
- +
- + /* signal dsp to load the setting */
- + mtp = snd_soc_read(codec, TFA98XX_MTP_SPKR_CAL);
- + if (!(mtp & TFA98XX_MTP_SPKR_CAL_MTPEX_MSK))
- + dev_info(codec->dev, "Start one time calibration\n");
- + else
- + dev_info(codec->dev, "Load the calibration value from mtp\n");
- +
- + snd_soc_update_bits_locked(codec, TFA98XX_SYS_CTRL,
- + TFA98XX_SYS_CTRL_SBSL_MSK, TFA98XX_SYS_CTRL_SBSL);
- +
- + for (tries = 10; tries > 0; tries--) {
- + mtp = snd_soc_read(codec, TFA98XX_MTP_SPKR_CAL);
- + if (mtp & TFA98XX_MTP_SPKR_CAL_MTPEX_MSK)
- + break;
- + msleep(100);
- + }
- +
- + if (tries == 0)
- + dev_warn(codec->dev, "Fail to calibrate on time\n");
- + else
- + dev_info(codec->dev, "Finish one time calibration\n");
- +
- +unmute:
- + tfa98xx_mute(codec, TFA98XX_MUTE_OFF);
- +unlock:
- + mutex_unlock(&tfa98xx->fw_lock);
- +
- + /* retry in a late time if fail */
- + if (ret < 0) {
- + queue_delayed_work(tfa98xx->workqueue,
- + &tfa98xx->download_work, msecs_to_jiffies(10));
- + }
- +}
- +
- +static bool tfa98xx_start_download(struct tfa98xx_priv *tfa98xx, bool force)
- +{
- + bool sched = force;
- + int id;
- +
- + mutex_lock(&tfa98xx->fw_lock);
- + if (force) { /* re-download all firmware */
- + for (id = 0; id < TFA98XX_FW_NUMBER; id++)
- + tfa98xx->fw_chg[id] = true;
- + } else { /* check the pending change exist */
- + for (id = 0; id < TFA98XX_FW_NUMBER; id++) {
- + if (tfa98xx->fw_chg[id]) {
- + sched = true;
- + break;
- + }
- + }
- + }
- + mutex_unlock(&tfa98xx->fw_lock);
- +
- + if (sched)
- + queue_delayed_work(tfa98xx->workqueue, &tfa98xx->download_work, 0);
- + return sched;
- +}
- +
- +static void tfa98xx_stop_download(struct tfa98xx_priv *tfa98xx)
- +{
- + cancel_delayed_work_sync(&tfa98xx->download_work);
- +}
- +
- +static void tfa98xx_start_monitor(struct tfa98xx_priv *tfa98xx)
- +{
- + queue_delayed_work(tfa98xx->workqueue,
- + &tfa98xx->monitor_work, msecs_to_jiffies(5000));
- +}
- +
- +static void tfa98xx_stop_monitor(struct tfa98xx_priv *tfa98xx)
- +{
- + cancel_delayed_work_sync(&tfa98xx->monitor_work);
- +}
- +
- +static int tfa98xx_check_error(struct snd_soc_codec *codec)
- +{
- + unsigned int status;
- +
- + status = snd_soc_read(codec, TFA98XX_STATUSREG);
- + if (status & TFA98XX_STATUSREG_ERR2_MSK)
- + return 2;
- + else if (status & TFA98XX_STATUSREG_ERR1_MSK)
- + return 1;
- +
- + status = tfa98xx_read_dsp(codec, 0x666);
- + if (status == 0x7FFFFF)
- + return 2;
- +
- + return 0;
- +}
- +
- +static void tfa98xx_monitor(struct work_struct *work)
- +{
- + struct tfa98xx_priv *tfa98xx;
- + struct snd_soc_codec *codec;
- + struct delayed_work *dwork;
- +
- + dwork = to_delayed_work(work);
- + tfa98xx = container_of(dwork, struct tfa98xx_priv, monitor_work);
- + codec = tfa98xx->codec;
- +
- + switch (tfa98xx_check_error(codec)) {
- + case 2:
- + dev_err(codec->dev, "Restart due to dsp crash\n");
- + tfa98xx->dsp_crash = true; /* save crash info */
- + tfa98xx->pilot_tone = tfa98xx_read_dsp(codec, 0x1029A);
- + tfa98xx_reset(codec);
- + tfa98xx_start_download(tfa98xx, true);
- + break;
- + case 1:
- + dev_err(codec->dev, "Repower due to over condition\n");
- + tfa98xx_power(codec, false);
- + usleep_range(5000, 5000);
- + tfa98xx_power(codec, true);
- + break;
- + }
- +
- + tfa98xx_start_monitor(tfa98xx);
- +}
- +
- +static ssize_t tfa98xx_dsp_crash_show(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct tfa98xx_priv *tfa98xx = i2c_get_clientdata(client);
- +
- + return sprintf(buf, "%d\n", tfa98xx->dsp_crash);
- +}
- +
- +static ssize_t tfa98xx_crash_store(struct device *dev,
- + struct device_attribute *attr, const char *buf, size_t count)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct tfa98xx_priv *tfa98xx = i2c_get_clientdata(client);
- + unsigned long val;
- + int ret;
- +
- + ret = strict_strtoul(buf, 0, &val);
- + if (ret < 0)
- + return ret;
- + tfa98xx->dsp_crash = (val != 0);
- +
- + return count;
- +}
- +static DEVICE_ATTR(dsp_crash, 0664, tfa98xx_dsp_crash_show, tfa98xx_crash_store);
- +
- +
- +static ssize_t tfa98xx_pilot_tone_show(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + struct i2c_client *client = to_i2c_client(dev);
- + struct tfa98xx_priv *tfa98xx = i2c_get_clientdata(client);
- +
- + return sprintf(buf, "0x%06X\n", tfa98xx->pilot_tone);
- +}
- +static DEVICE_ATTR(pilot_tone, 0444, tfa98xx_pilot_tone_show, NULL);
- +
- +static int tfa98xx_probe(struct snd_soc_codec *codec)
- +{
- + struct tfa98xx_priv *tfa98xx;
- + int ret;
- +
- + tfa98xx = kzalloc(sizeof(struct tfa98xx_priv), GFP_KERNEL);
- + if (tfa98xx == NULL) {
- + dev_err(codec->dev, "Failed to alloc tfa98xx_priv\n");
- + return -ENOMEM;
- + }
- +
- + tfa98xx->codec = codec;
- + mutex_init(&tfa98xx->fw_lock);
- +
- + INIT_DELAYED_WORK(&tfa98xx->monitor_work, tfa98xx_monitor);
- + INIT_DELAYED_WORK(&tfa98xx->download_work, tfa98xx_download);
- +
- + codec->bulk_write_raw = tfa98xx_bulk_write;
- + snd_soc_codec_set_drvdata(codec, tfa98xx);
- +
- + tfa98xx->workqueue = create_singlethread_workqueue(dev_name(codec->dev));
- + if (tfa98xx->workqueue == NULL) {
- + dev_err(codec->dev, "Failed to create workqueue\n");
- + ret = -ENOMEM;
- + goto wq_fail;
- + }
- +
- + ret = tfa98xx_reset(codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to reset tf98xx(%d)\n", ret);
- + goto reset_fail;
- + }
- +
- + device_create_file(codec->dev, &dev_attr_dsp_crash);
- + device_create_file(codec->dev, &dev_attr_pilot_tone);
- +
- + return ret;
- +
- +reset_fail:
- + destroy_workqueue(tfa98xx->workqueue);
- +wq_fail:
- + kfree(tfa98xx);
- + return ret;
- +}
- +
- +static int tfa98xx_remove(struct snd_soc_codec *codec)
- +{
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- + int id;
- +
- + tfa98xx_stop_monitor(tfa98xx);
- + tfa98xx_stop_download(tfa98xx);
- + destroy_workqueue(tfa98xx->workqueue);
- +
- + for (id = 0; id < TFA98XX_FW_NUMBER; id++)
- + release_firmware(tfa98xx->fw[id]);
- + kfree(tfa98xx);
- +
- + return 0;
- +}
- +
- +static int tfa98xx_reg_addr_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- +
- + ucontrol->value.integer.value[0] = tfa98xx->reg_addr;
- + return 0;
- +}
- +
- +static int tfa98xx_reg_addr_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- +
- + tfa98xx->reg_addr = ucontrol->value.integer.value[0];
- + return 0;
- +}
- +
- +static int tfa98xx_reg_value_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- +
- + ucontrol->value.integer.value[0] = snd_soc_read(codec, tfa98xx->reg_addr);
- + return 0;
- +}
- +
- +static int tfa98xx_reg_value_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- +
- + return snd_soc_write(codec, tfa98xx->reg_addr, ucontrol->value.integer.value[0]);
- +}
- +
- +static int tfa98xx_chsa_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + bool bypass = ucontrol->value.enumerated.item[0] < 2;
- + int ret;
- +
- + ret = snd_soc_update_bits_locked(codec, TFA98XX_SYS_CTRL,
- + TFA98XX_SYS_CTRL_CFE_MSK, bypass ? 0 : TFA98XX_SYS_CTRL_CFE);
- + if (ret < 0)
- + return ret;
- +
- + return snd_soc_put_enum_double(kcontrol, ucontrol);
- +}
- +
- +static int tfa98xx_bsst_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + unsigned int bsss, bsst;
- +
- + bsss = snd_soc_read(codec, TFA98XX_AUDIO_CTR);
- + bsss &= TFA989X_AUDIO_CTR_BSSS_MSK;
- + bsss >>= TFA989X_AUDIO_CTR_BSSS_POS;
- +
- + bsst = snd_soc_read(codec, TFA98XX_BAT_PROT);
- + bsst &= TFA989X_BAT_PROT_BSST_MSK;
- + bsst >>= TFA989X_BAT_PROT_BSST_POS;
- +
- + ucontrol->value.enumerated.item[0] = (bsst << 1) | bsss;
- + return 0;
- +}
- +
- +static int tfa98xx_bsst_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + unsigned int bsss = ucontrol->value.enumerated.item[0] & 1;
- + unsigned int bsst = ucontrol->value.enumerated.item[0] >> 1;
- + int ret;
- +
- + ret = snd_soc_update_bits_locked(codec, TFA98XX_AUDIO_CTR,
- + TFA989X_AUDIO_CTR_BSSS_MSK,
- + bsss << TFA989X_AUDIO_CTR_BSSS_POS);
- + if (ret < 0)
- + return ret;
- +
- + ret = snd_soc_update_bits(codec, TFA98XX_BAT_PROT,
- + TFA989X_BAT_PROT_BSST_MSK,
- + bsst << TFA989X_BAT_PROT_BSST_POS);
- + if (ret < 0)
- + return ret;
- +
- + return ret;
- +}
- +
- +static int tfa98xx_recalib_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- +
- + ucontrol->value.integer.value[0] = tfa98xx->recalib;
- + return 0;
- +}
- +
- +static int tfa98xx_recalib_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- +
- + tfa98xx->recalib = !!ucontrol->value.integer.value[0];
- + if (tfa98xx->recalib)
- + tfa98xx_start_download(tfa98xx, true);
- +
- + return 0;
- +}
- +
- +static int tfa98xx_firmware_info(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_info *uinfo)
- +{
- + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- + uinfo->count = 512;
- + return 0;
- +}
- +
- +static int tfa98xx_firmware_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- + unsigned long id = kcontrol->private_value;
- +
- + strcpy(ucontrol->value.bytes.data, tfa98xx->fw_name[id]);
- + return 0;
- +}
- +
- +static int tfa98xx_firmware_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- + unsigned long id = kcontrol->private_value;
- + const char *name = ucontrol->value.bytes.data;
- + const struct firmware *fw;
- + int ret;
- +
- + ret = request_firmware(&fw, name, codec->dev);
- + if (ret < 0) {
- + dev_err(codec->dev, "Failed to request %s(%d)\n", name, ret);
- + return ret;
- + }
- +
- + mutex_lock(&tfa98xx->fw_lock);
- + strcpy(tfa98xx->fw_name[id], name);
- + if (tfa98xx->fw[id] == NULL || /* no firmware yet */
- + tfa98xx->fw[id]->size != fw->size || /* or change */
- + memcmp(tfa98xx->fw[id]->data, fw->data, fw->size)) {
- + tfa98xx->fw_chg[id] = true;
- + swap(tfa98xx->fw[id], fw);
- + }
- + mutex_unlock(&tfa98xx->fw_lock);
- +
- + /* download in the background to unblock
- + the caller to turn on the clock */
- + tfa98xx_start_download(tfa98xx, false);
- +
- + release_firmware(fw);
- + return ret;
- +}
- +
- +#define TFA98XX_FIRMWARE(xname, id) \
- + { \
- + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
- + .name = xname, \
- + .info = tfa98xx_firmware_info, \
- + .get = tfa98xx_firmware_get, \
- + .put = tfa98xx_firmware_put, \
- + .private_value = id, \
- + }
- +
- +static const char * const tfa98xx_chs12_text[] = {
- + "Left", "Right", "Mono",
- +};
- +static const unsigned int tfa98xx_chs12_value[] = {
- + 1, 2, 3,
- +};
- +static const SOC_VALUE_ENUM_SINGLE_DECL(
- + tfa98xx_chs12_enum, TFA98XX_I2SREG,
- + TFA98XX_I2SREG_CHS12_POS, TFA98XX_I2SREG_CHS12_MAX,
- + tfa98xx_chs12_text, tfa98xx_chs12_value);
- +
- +static const char * const tfa98xx_chs3_text[] = {
- + "Left", "Right",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_chs3_enum, TFA98XX_I2SREG,
- + TFA98XX_I2SREG_CHS3_POS, tfa98xx_chs3_text);
- +
- +static const char * const tfa98xx_chsa_text[] = {
- + "Left", "Right", "DSP",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_chsa_enum, TFA98XX_I2SREG,
- + TFA98XX_I2SREG_CHSA_POS, tfa98xx_chsa_text);
- +
- +static const char * const tfa98xx_i2sdoc_text[] = {
- + "DSP", "DATAI1", "DATAI2", "DATAI3",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_i2sdoc_enum, TFA98XX_I2SREG,
- + TFA9890_I2SREG_I2SDOC_POS, tfa98xx_i2sdoc_text);
- +
- +static const char * const tfa98xx_bsst_text[] = {
- + "2.73V", "2.99V", "2.83V", "3.09V", "2.93V", "3.19V", "3.03V", "3.29V",
- + "3.13V", "3.39V", "3.23V", "3.49V", "3.33V", "3.59V", "3.43V", "3.69V",
- + "3.53V", "3.79V", "3.63V", "3.89V", "3.73V", "3.99V", "3.83V", "4.09V",
- + "3.93V", "4.19V", "4.03V", "4.29V", "4.13V", "4.39V", "4.23V", "4.49V",
- +};
- +static const SOC_ENUM_SINGLE_EXT_DECL(
- + tfa98xx_bsst_enum, tfa98xx_bsst_text);
- +
- +static const DECLARE_TLV_DB_SCALE(
- + tfa98xx_vol_tlv, -12750, 50, 0);
- +
- +static const char * const tfa98xx_dcvo_text[] = {
- + "6.0V", "6.5V", "7.0V", "7.5V", "8.0V", "8.5V", "9.0V", "9.5V",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_dcvo_enum, TFA98XX_DCDCBOOST,
- + TFA98XX_DCDCBOOST_DCVO_POS, tfa98xx_dcvo_text);
- +
- +static const char * const tfa98xx_dcmcc_text[] = {
- + "0.5A", "1.0A", "1.4A", "1.9A", "2.4A", "2.9A", "3.3A", "3.8A",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_dcmcc_enum, TFA98XX_DCDCBOOST,
- + TFA98XX_DCDCBOOST_DCMCC_POS, tfa98xx_dcmcc_text);
- +
- +static const char * const tfa98xx_isel_text[] = {
- + "Input1", "Input2",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_isel_enum, TFA98XX_SYS_CTRL,
- + TFA98XX_SYS_CTRL_ISEL_POS, tfa98xx_isel_text);
- +
- +static const char * const tfa98xx_dccv_text[] = {
- + "0.7uH", "1uH", "1.5uH", "2.2uH",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_dccv_enum, TFA98XX_SYS_CTRL,
- + TFA98XX_SYS_CTRL_DCCV_POS, tfa98xx_dccv_text);
- +
- +static const char * const tfa98xx_spkr_text[] = {
- + "Auto", "4Omh", "6Omh", "8Omh",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_spkr_enum, TFA98XX_I2S_SEL_REG,
- + TFA98XX_I2S_SEL_REG_SPKR_POS, tfa98xx_spkr_text);
- +
- +static const char * const tfa98xx_spkl_text[] = {
- + "22uH", "27uH", "33uH", "39uH", "47uH", "56uH", "68uH", "82uH",
- +};
- +static const SOC_ENUM_SINGLE_DECL(
- + tfa98xx_spkl_enum, TFA98XX_I2S_SEL_REG,
- + TFA98XX_I2S_SEL_REG_SPKL_POS, tfa98xx_spkl_text);
- +
- +static const char * const tfa98xx_dos_text[] = {
- + "Current", "Gain", "AEC", "Voltage", "DATAI3 Right", "DATAI3 Left",
- +};
- +static const SOC_ENUM_DOUBLE_DECL(
- + tfa98xx_dos_enum, TFA98XX_I2S_SEL_REG,
- + TFA98XX_I2S_SEL_REG_DOLS_POS, TFA98XX_I2S_SEL_REG_DORS_POS,
- + tfa98xx_dos_text);
- +
- +static const struct snd_kcontrol_new tfa98xx_controls[] = {
- + SOC_SINGLE_EXT("Reg Addr", SND_SOC_NOPM, 0, 0x8F, 0,
- + tfa98xx_reg_addr_get, tfa98xx_reg_addr_put),
- + SOC_SINGLE_EXT("Reg Value", SND_SOC_NOPM, 0, 0xFFFFFF, 0,
- + tfa98xx_reg_value_get, tfa98xx_reg_value_put),
- + SOC_SINGLE("Battery Voltage", TFA98XX_BATTERYVOLTAGE,
- + TFA98XX_BATTERYVOLTAGE_BATS_POS, TFA98XX_BATTERYVOLTAGE_BATS_MAX, 0),
- + SOC_SINGLE("Temperature", TFA98XX_TEMPERATURE,
- + TFA98XX_TEMPERATURE_TEMPS_POS, TFA98XX_TEMPERATURE_TEMPS_MAX, 0),
- + SOC_VALUE_ENUM("Input Channel Mux", tfa98xx_chs12_enum),
- + SOC_ENUM("Gain Channel Mux", tfa98xx_chs3_enum),
- + SOC_ENUM_EXT("Amplifier Channel Mux", tfa98xx_chsa_enum,
- + snd_soc_get_enum_double, tfa98xx_chsa_put),
- + SOC_ENUM("Output Interface Mux", tfa98xx_i2sdoc_enum),
- + SOC_ENUM_EXT("Safeguard Threshold", tfa98xx_bsst_enum,
- + tfa98xx_bsst_get, tfa98xx_bsst_put),
- + SOC_SINGLE("Safeguard Bypass", TFA98XX_BAT_PROT,
- + TFA989X_BAT_PROT_BSSBY_POS, TFA989X_BAT_PROT_BSSBY_MAX, 0),
- + SOC_SINGLE_TLV("Digital Volume", TFA98XX_AUDIO_CTR,
- + TFA98XX_AUDIO_CTR_VOL_POS, TFA98XX_AUDIO_CTR_VOL_MAX,
- + 1, tfa98xx_vol_tlv),
- + SOC_ENUM("Output Voltage", tfa98xx_dcvo_enum),
- + SOC_ENUM("Max Coil Current", tfa98xx_dcmcc_enum),
- + SOC_SINGLE("Use External Temperature", TFA98XX_SPKR_CALIBRATION,
- + TFA98XX_SPKR_CALIBRATION_TROS_POS, TFA98XX_SPKR_CALIBRATION_TROS_MAX, 0),
- + SOC_SINGLE("External Temperature", TFA98XX_SPKR_CALIBRATION,
- + TFA98XX_SPKR_CALIBRATION_EXTTS_POS, TFA98XX_SPKR_CALIBRATION_EXTTS_MAX, 0),
- + SOC_ENUM("Input Interface Mux", tfa98xx_isel_enum),
- + SOC_ENUM("Coil Value", tfa98xx_dccv_enum),
- + SOC_ENUM("Resistance", tfa98xx_spkr_enum),
- + SOC_ENUM("Inductance", tfa98xx_spkl_enum),
- + SOC_ENUM("Output Channel Mux", tfa98xx_dos_enum),
- + SOC_SINGLE_BOOL_EXT("Recalibrate", 0,
- + tfa98xx_recalib_get, tfa98xx_recalib_put),
- + TFA98XX_FIRMWARE("Boot Patch", TFA98XX_FW_BOOT),
- + TFA98XX_FIRMWARE("ROM Patch", TFA98XX_FW_ROM),
- + TFA98XX_FIRMWARE("Speaker File", TFA98XX_FW_SPEAKER),
- + TFA98XX_FIRMWARE("Config File", TFA98XX_FW_CONFIG),
- + TFA98XX_FIRMWARE("Preset File", TFA98XX_FW_PRESET),
- + TFA98XX_FIRMWARE("Equalizer File", TFA98XX_FW_EQUALIZER),
- +};
- +
- +static const struct snd_soc_dapm_route tfa98xx_routes[] = {
- + { "Capture", NULL, "Playback" },
- +};
- +
- +static const u16 tfa98xx_reg[0x90] = {
- + [TFA98XX_I2SREG] = 0x888B,
- + [TFA98XX_BAT_PROT] = 0x9392,
- + [TFA98XX_AUDIO_CTR] = 0x000F,
- + [TFA98XX_DCDCBOOST] = 0x8FFF,
- + [TFA98XX_SPKR_CALIBRATION] = 0x3800,
- + [TFA98XX_SYS_CTRL] = 0x824D,
- + [TFA98XX_I2S_SEL_REG] = 0x3EC3,
- +
- +
- + [TFA98XX_INTERRUPT_REG] = 0x0040,
- +
- +
- + [TFA98XX_CURRENTSENSE4] = 0xAD93,
- +};
- +
- +static int tfa98xx_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
- +{
- + switch (reg) {
- + case TFA98XX_I2SREG:
- + case TFA98XX_BAT_PROT:
- + case TFA98XX_AUDIO_CTR:
- + case TFA98XX_DCDCBOOST:
- + case TFA98XX_SPKR_CALIBRATION:
- + case TFA98XX_SYS_CTRL:
- + case TFA98XX_I2S_SEL_REG:
- + case TFA98XX_INTERRUPT_REG:
- + case TFA98XX_CURRENTSENSE4:
- + return 0;
- + default:
- + return 1;
- + }
- +}
- +
- +static int tfa98xx_writable_register(struct snd_soc_codec *codec, unsigned int reg)
- +{
- + switch (reg) {
- + case TFA98XX_STATUSREG:
- + case TFA98XX_BATTERYVOLTAGE:
- + case TFA98XX_TEMPERATURE:
- + case TFA98XX_REVISIONNUMBER:
- + case TFA9890_MTPF:
- + return 0;
- + default:
- + return 1;
- + }
- +}
- +
- +static const struct snd_soc_codec_driver tfa98xx_drv = {
- + .probe = tfa98xx_probe,
- + .remove = tfa98xx_remove,
- + .controls = tfa98xx_controls,
- + .num_controls = ARRAY_SIZE(tfa98xx_controls),
- + .dapm_routes = tfa98xx_routes,
- + .num_dapm_routes = ARRAY_SIZE(tfa98xx_routes),
- + .read = tfa98xx_read,
- + .write = tfa98xx_write,
- + .volatile_register = tfa98xx_volatile_register,
- + .writable_register = tfa98xx_writable_register,
- + .reg_cache_size = ARRAY_SIZE(tfa98xx_reg),
- + .reg_word_size = sizeof(tfa98xx_reg[0]),
- + .reg_cache_default = tfa98xx_reg,
- + .idle_bias_off = 1,
- +};
- +
- +#define TFA98XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
- + SNDRV_PCM_FMTBIT_S18_3LE | \
- + SNDRV_PCM_FMTBIT_S20_3LE | \
- + SNDRV_PCM_FMTBIT_S24_LE)
- +
- +#define TFA98XX_RATES SNDRV_PCM_RATE_8000_48000
- +
- +static int tfa98xx_set_format(struct snd_soc_dai *codec_dai, unsigned int fmt)
- +{
- + struct snd_soc_codec *codec = codec_dai->codec;
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- +
- + /* interface format */
- + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- + case SND_SOC_DAIFMT_I2S:
- + case SND_SOC_DAIFMT_RIGHT_J:
- + case SND_SOC_DAIFMT_LEFT_J:
- + break;
- + default:
- + dev_err(codec->dev, "Invalid interface format\n");
- + return -EINVAL;
- + }
- +
- + /* clock inversion */
- + switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- + case SND_SOC_DAIFMT_NB_NF:
- + break;
- + default:
- + dev_err(codec->dev, "Invalid clock inversion\n");
- + return -EINVAL;
- + }
- +
- + /* set master/slave audio interface */
- + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- + case SND_SOC_DAIFMT_CBS_CFS:
- + break;
- + default:
- + dev_err(codec->dev, "Invalid master/slave setting\n");
- + return -EINVAL;
- + }
- +
- + /* save for later use */
- + tfa98xx->fmt = fmt;
- + return 0;
- +}
- +
- +static int tfa98xx_digital_mute(struct snd_soc_dai *codec_dai, int mute)
- +{
- + struct snd_soc_codec *codec = codec_dai->codec;
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- +
- + if (mute) {
- + tfa98xx_stop_monitor(tfa98xx);
- + tfa98xx_stop_download(tfa98xx);
- + tfa98xx_mute(codec, TFA98XX_MUTE_AMPLIFIER);
- + tfa98xx_power(codec, false);
- + usleep_range(5000, 5000);
- + } else {
- + usleep_range(5000, 5000);
- + tfa98xx_power(codec, true);
- + if (tfa98xx_start_download(tfa98xx, false))
- + ; /* will turn off the mute after download */
- + else
- + tfa98xx_mute(codec, TFA98XX_MUTE_OFF);
- + tfa98xx_start_monitor(tfa98xx);
- + }
- +
- + return 0;
- +}
- +
- +static int tfa98xx_hw_params(struct snd_pcm_substream *substream,
- + struct snd_pcm_hw_params *params,
- + struct snd_soc_dai *dai)
- +{
- + struct snd_soc_codec *codec = dai->codec;
- + struct tfa98xx_priv *tfa98xx = snd_soc_codec_get_drvdata(codec);
- + unsigned int value = 0;
- +
- + switch (tfa98xx->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- + case SND_SOC_DAIFMT_I2S:
- + value |= TFA98XX_I2SCTRL_PHILIPS;
- + break;
- + case SND_SOC_DAIFMT_RIGHT_J:
- + switch (params_format(params)) {
- + case SNDRV_PCM_FORMAT_S16_LE:
- + value |= TFA98XX_I2SCTRL_LSB_J_16;
- + break;
- + case SNDRV_PCM_FORMAT_S18_3LE:
- + value |= TFA98XX_I2SCTRL_LSB_J_18;
- + break;
- + case SNDRV_PCM_FORMAT_S20_3LE:
- + value |= TFA98XX_I2SCTRL_LSB_J_20;
- + break;
- + case SNDRV_PCM_FORMAT_S24_LE:
- + value |= TFA98XX_I2SCTRL_LSB_J_24;
- + break;
- + default:
- + return -EINVAL;
- + }
- + break;
- + case SND_SOC_DAIFMT_LEFT_J:
- + value |= TFA98XX_I2SCTRL_MSB_J;
- + break;
- + default:
- + dev_err(codec->dev, "Invalid dai format = %d\n", tfa98xx->fmt);
- + return -EINVAL;
- + }
- +
- + switch (params_rate(params)) {
- + case 48000:
- + value |= TFA98XX_I2SCTRL_RATE_48000;
- + break;
- + case 44100:
- + value |= TFA98XX_I2SCTRL_RATE_44100;
- + break;
- + case 32000:
- + value |= TFA98XX_I2SCTRL_RATE_32000;
- + break;
- + case 24000:
- + value |= TFA98XX_I2SCTRL_RATE_24000;
- + break;
- + case 22050:
- + value |= TFA98XX_I2SCTRL_RATE_22050;
- + break;
- + case 16000:
- + value |= TFA98XX_I2SCTRL_RATE_16000;
- + break;
- + case 12000:
- + value |= TFA98XX_I2SCTRL_RATE_12000;
- + break;
- + case 11025:
- + value |= TFA98XX_I2SCTRL_RATE_11025;
- + break;
- + case 8000:
- + value |= TFA98XX_I2SCTRL_RATE_08000;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + return snd_soc_update_bits_locked(codec, TFA98XX_I2SREG,
- + TFA98XX_I2SREG_I2SSR_MSK | TFA98XX_I2SREG_I2SF_MSK, value);
- +}
- +
- +static const struct snd_soc_dai_ops tfa98xx_dai_ops = {
- + .set_fmt = tfa98xx_set_format,
- + .digital_mute = tfa98xx_digital_mute,
- + .hw_params = tfa98xx_hw_params,
- +};
- +
- +static struct snd_soc_dai_driver tfa98xx_dai = {
- + .name = "tfa98xx-dai",
- + .ops = &tfa98xx_dai_ops,
- + .capture = {
- + .stream_name = "Capture",
- + .formats = TFA98XX_FORMATS,
- + .rates = TFA98XX_RATES,
- + .channels_min = 2,
- + .channels_max = 2,
- + },
- + .playback = {
- + .stream_name = "Playback",
- + .formats = TFA98XX_FORMATS,
- + .rates = TFA98XX_RATES,
- + .channels_min = 2,
- + .channels_max = 2,
- + },
- + .symmetric_rates = 1,
- +};
- +
- +static int tfa98xx_i2c_probe(struct i2c_client *client,
- + const struct i2c_device_id *id)
- +{
- + return snd_soc_register_codec(&client->dev,
- + &tfa98xx_drv, &tfa98xx_dai, 1);
- +}
- +
- +static int tfa98xx_i2c_remove(struct i2c_client *client)
- +{
- + snd_soc_unregister_codec(&client->dev);
- + return 0;
- +}
- +
- +static void tfa98xx_i2c_shutdown(struct i2c_client *client)
- +{
- + struct tfa98xx_priv *tfa98xx = i2c_get_clientdata(client);
- +
- + if (tfa98xx)
- + tfa98xx_power(tfa98xx->codec, false);
- +}
- +
- +static const struct i2c_device_id tfa98xx_i2c_id[] = {
- + { "tfa98xx", 0 },
- + { }
- +};
- +MODULE_DEVICE_TABLE(i2c, tfa98xx_i2c_id);
- +
- +static struct i2c_driver tfa98xx_i2c_driver = {
- + .driver = {
- + .name = "tfa98xx",
- + .owner = THIS_MODULE,
- + },
- + .probe = tfa98xx_i2c_probe,
- + .remove = tfa98xx_i2c_remove,
- + .shutdown = tfa98xx_i2c_shutdown,
- + .id_table = tfa98xx_i2c_id,
- +};
- +module_i2c_driver(tfa98xx_i2c_driver);
- +
- +MODULE_AUTHOR("Xiang Xiao <xiaoxiang@xiaomi.com>");
- +MODULE_DESCRIPTION("ASoC TFA98XX codec driver");
- +MODULE_LICENSE("GPL");
- diff --git a/sound/soc/codecs/tfa98xx.h b/sound/soc/codecs/tfa98xx.h
- new file mode 100644
- index 0000000..2d63f34
- --- /dev/null
- +++ b/sound/soc/codecs/tfa98xx.h
- @@ -0,0 +1,2590 @@
- +/** \file Tfa98xx_genregs.h
- + * This file was automatically generated.
- + */
- +#ifndef TFA98XX_GENREGS_H_
- +#define TFA98XX_GENREGS_H_
- +
- +
- +/** StatusReg Register ($00) ********************************************/
- +
- +/** \addtogroup _0x00_StatusReg
- + * @{
- + */
- +#define TFA98XX_STATUSREG 0x00
- +/** \addtogroup VDDS
- + * @{
- + */
- +/*!
- + Power-on-reset flag
- + * - 1 = Power-on-reset detected
- + * - 0 = Power-on-reset detected and cleared by reading status register
- +*/
- +#define TFA98XX_STATUSREG_VDDS (0x1<<0)
- +#define TFA98XX_STATUSREG_VDDS_POS 0
- +#define TFA98XX_STATUSREG_VDDS_LEN 1
- +#define TFA98XX_STATUSREG_VDDS_MAX 1
- +#define TFA98XX_STATUSREG_VDDS_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup PLLS
- + * @{
- + */
- +/*!
- + PLL lock
- + * - 0 = PLL not in lock
- + * - 1 = PLL in lock
- +*/
- +#define TFA98XX_STATUSREG_PLLS (0x1<<1)
- +#define TFA98XX_STATUSREG_PLLS_POS 1
- +#define TFA98XX_STATUSREG_PLLS_LEN 1
- +#define TFA98XX_STATUSREG_PLLS_MAX 1
- +#define TFA98XX_STATUSREG_PLLS_MSK 0x2
- +/** @} */
- +
- +/** \addtogroup OTDS
- + * @{
- + */
- +/*!
- + Over Temperature Protection alarm
- + * - 0 = Temperature To High
- + * - 1 = Temperature OK
- +*/
- +#define TFA98XX_STATUSREG_OTDS (0x1<<2)
- +#define TFA98XX_STATUSREG_OTDS_POS 2
- +#define TFA98XX_STATUSREG_OTDS_LEN 1
- +#define TFA98XX_STATUSREG_OTDS_MAX 1
- +#define TFA98XX_STATUSREG_OTDS_MSK 0x4
- +/** @} */
- +
- +/** \addtogroup OVDS
- + * @{
- + */
- +/*!
- + Over Voltage Protection alarm
- + * - 0 = VddP is To High
- + * - 1 = VddP is OK
- +*/
- +#define TFA98XX_STATUSREG_OVDS (0x1<<3)
- +#define TFA98XX_STATUSREG_OVDS_POS 3
- +#define TFA98XX_STATUSREG_OVDS_LEN 1
- +#define TFA98XX_STATUSREG_OVDS_MAX 1
- +#define TFA98XX_STATUSREG_OVDS_MSK 0x8
- +/** @} */
- +
- +/** \addtogroup UVDS
- + * @{
- + */
- +/*!
- + Under Voltage Proection alarm
- + * - 0 = VddP is too low
- + * - 1 = VddP is OK
- +*/
- +#define TFA98XX_STATUSREG_UVDS (0x1<<4)
- +#define TFA98XX_STATUSREG_UVDS_POS 4
- +#define TFA98XX_STATUSREG_UVDS_LEN 1
- +#define TFA98XX_STATUSREG_UVDS_MAX 1
- +#define TFA98XX_STATUSREG_UVDS_MSK 0x10
- +/** @} */
- +
- +/** \addtogroup OCDS
- + * @{
- + */
- +/*!
- + Over Current Protection alarm
- + * - 0 = Current is OK
- + * - 1 = Current is to High
- +*/
- +#define TFA98XX_STATUSREG_OCDS (0x1<<5)
- +#define TFA98XX_STATUSREG_OCDS_POS 5
- +#define TFA98XX_STATUSREG_OCDS_LEN 1
- +#define TFA98XX_STATUSREG_OCDS_MAX 1
- +#define TFA98XX_STATUSREG_OCDS_MSK 0x20
- +/** @} */
- +
- +/** \addtogroup CLKS
- + * @{
- + */
- +/*!
- + Clocks stable flag
- + * - 0 = Clock is unstable
- + * - 1 = Clock is Stable
- +*/
- +#define TFA98XX_STATUSREG_CLKS (0x1<<6)
- +#define TFA98XX_STATUSREG_CLKS_POS 6
- +#define TFA98XX_STATUSREG_CLKS_LEN 1
- +#define TFA98XX_STATUSREG_CLKS_MAX 1
- +#define TFA98XX_STATUSREG_CLKS_MSK 0x40
- +/** @} */
- +
- +/** \addtogroup CLIPS
- + * @{
- + */
- +/*!
- + Amplifier clipping
- + * - 0 = Not clipping
- + * - 1 = Clipping
- +*/
- +#define TFA98XX_STATUSREG_CLIPS (0x1<<7)
- +#define TFA98XX_STATUSREG_CLIPS_POS 7
- +#define TFA98XX_STATUSREG_CLIPS_LEN 1
- +#define TFA98XX_STATUSREG_CLIPS_MAX 1
- +#define TFA98XX_STATUSREG_CLIPS_MSK 0x80
- +/** @} */
- +
- +/** \addtogroup MTPB
- + * @{
- + */
- +/*!
- + MTP busy
- + * - 0 = MTP is idle
- + * - 1 = MTP is busy copying data to/from I2C registers
- +*/
- +#define TFA98XX_STATUSREG_MTPB (0x1<<8)
- +#define TFA98XX_STATUSREG_MTPB_POS 8
- +#define TFA98XX_STATUSREG_MTPB_LEN 1
- +#define TFA98XX_STATUSREG_MTPB_MAX 1
- +#define TFA98XX_STATUSREG_MTPB_MSK 0x100
- +/** @} */
- +
- +/** \addtogroup DCCS
- + * @{
- + */
- +/*!
- + * - 0 = Vboost not in window
- + * - 1 = Vboost in window (OK)
- +*/
- +#define TFA9887_STATUSREG_DCCS (0x1<<9)
- +#define TFA9887_STATUSREG_DCCS_POS 9
- +#define TFA9887_STATUSREG_DCCS_MAX 1
- +#define TFA9887_STATUSREG_DCCS_MSK 0x200
- +#define TFA9890_STATUSREG_DCCS (0x1<<9)
- +#define TFA9890_STATUSREG_DCCS_POS 9
- +#define TFA9890_STATUSREG_DCCS_MAX 1
- +#define TFA9890_STATUSREG_DCCS_MSK 0x200
- +#define TFA9895_STATUSREG_DCCS (0x1<<9)
- +#define TFA9895_STATUSREG_DCCS_POS 9
- +#define TFA9895_STATUSREG_DCCS_MAX 1
- +#define TFA9895_STATUSREG_DCCS_MSK 0x200
- +/** @} */
- +
- +
- +/** \addtogroup NOCLK
- + * @{
- + */
- +/*!
- + Flag lost clock from clock generation unit
- + * - 1 = PLL reference clock input disappeared
- + * - 0 = PLL reference clock detected
- +*/
- +#define TFA9897_STATUSREG_NOCLK (0x1<<9)
- +#define TFA9897_STATUSREG_NOCLK_POS 9
- +#define TFA9897_STATUSREG_NOCLK_LEN 1
- +#define TFA9897_STATUSREG_NOCLK_MAX 1
- +#define TFA9897_STATUSREG_NOCLK_MSK 0x200
- +/** @} */
- +
- +/** \addtogroup SPKS
- + * @{
- + */
- +/*!
- + Speaker error flag
- + * - 0 = Speaker is OK
- + * - 1 = Speaker error
- +*/
- +#define TFA98XX_STATUSREG_SPKS (0x1<<10)
- +#define TFA98XX_STATUSREG_SPKS_POS 10
- +#define TFA98XX_STATUSREG_SPKS_LEN 1
- +#define TFA98XX_STATUSREG_SPKS_MAX 1
- +#define TFA98XX_STATUSREG_SPKS_MSK 0x400
- +/** @} */
- +
- +/** \addtogroup ACS
- + * @{
- + */
- +/*!
- + Cold Start flag
- + * - 0 = Not a cold start, already running
- + * - 1 = Cold start (via POR)
- +*/
- +#define TFA98XX_STATUSREG_ACS (0x1<<11)
- +#define TFA98XX_STATUSREG_ACS_POS 11
- +#define TFA98XX_STATUSREG_ACS_LEN 1
- +#define TFA98XX_STATUSREG_ACS_MAX 1
- +#define TFA98XX_STATUSREG_ACS_MSK 0x800
- +/** @} */
- +
- +/** \addtogroup SWS
- + * @{
- + */
- +/*!
- + Flag Engage
- + * - 0 = amplifier is not switching
- + * - 1 = amplifier is switching
- +*/
- +#define TFA98XX_STATUSREG_SWS (0x1<<12)
- +#define TFA98XX_STATUSREG_SWS_POS 12
- +#define TFA98XX_STATUSREG_SWS_LEN 1
- +#define TFA98XX_STATUSREG_SWS_MAX 1
- +#define TFA98XX_STATUSREG_SWS_MSK 0x1000
- +/** @} */
- +
- +/** \addtogroup WDS
- + * @{
- + */
- +/*!
- + Flag watchdog reset
- + * - 0 = no reset due to watchdog
- + * - 1 = reset due to watchdog
- +*/
- +#define TFA98XX_STATUSREG_WDS (0x1<<13)
- +#define TFA98XX_STATUSREG_WDS_POS 13
- +#define TFA98XX_STATUSREG_WDS_LEN 1
- +#define TFA98XX_STATUSREG_WDS_MAX 1
- +#define TFA98XX_STATUSREG_WDS_MSK 0x2000
- +/** @} */
- +
- +/** \addtogroup AMPS
- + * @{
- + */
- +/*!
- + Amplifier is enabled by manager
- + * - 0 = amplifier is not enabled
- + * - 1 = amplifier is enabled
- +*/
- +#define TFA98XX_STATUSREG_AMPS (0x1<<14)
- +#define TFA98XX_STATUSREG_AMPS_POS 14
- +#define TFA98XX_STATUSREG_AMPS_LEN 1
- +#define TFA98XX_STATUSREG_AMPS_MAX 1
- +#define TFA98XX_STATUSREG_AMPS_MSK 0x4000
- +/** @} */
- +
- +/** \addtogroup AREFS
- + * @{
- + */
- +/*!
- + References are enabled by manager
- + * - 0 = references are not enabled
- + * - 1 = references are enabled
- +*/
- +#define TFA98XX_STATUSREG_AREFS (0x1<<15)
- +#define TFA98XX_STATUSREG_AREFS_POS 15
- +#define TFA98XX_STATUSREG_AREFS_LEN 1
- +#define TFA98XX_STATUSREG_AREFS_MAX 1
- +#define TFA98XX_STATUSREG_AREFS_MSK 0x8000
- +/** @} */
- +
- +/** @} */
- +
- +/** BatteryVoltage Register ($01) ********************************************/
- +
- +/** \addtogroup _0x01_BatteryVoltage
- + * @{
- + */
- +#define TFA98XX_BATTERYVOLTAGE 0x01
- +/** \addtogroup BATS
- + * @{
- + */
- +/*!
- + Battery voltage readout; 0[V]..5.5[V]
- +*/
- +#define TFA98XX_BATTERYVOLTAGE_BATS (0x3ff<<0)
- +#define TFA98XX_BATTERYVOLTAGE_BATS_POS 0
- +#define TFA98XX_BATTERYVOLTAGE_BATS_LEN 10
- +#define TFA98XX_BATTERYVOLTAGE_BATS_MAX 1023
- +#define TFA98XX_BATTERYVOLTAGE_BATS_MSK 0x3ff
- +/** @} */
- +
- +/** \addtogroup 10
- + * @{
- + */
- +/*!
- + not used
- +*/
- +#define TFA98XX_BATTERYVOLTAGE_10 (0x3f<<10)
- +#define TFA98XX_BATTERYVOLTAGE_10_POS 10
- +#define TFA98XX_BATTERYVOLTAGE_10_LEN 6
- +#define TFA98XX_BATTERYVOLTAGE_10_MAX 63
- +#define TFA98XX_BATTERYVOLTAGE_10_MSK 0xfc00
- +/** @} */
- +
- +/** @} */
- +
- +/** Temperature Register ($02) ********************************************/
- +
- +/** \addtogroup _0x02_Temperature
- + * @{
- + */
- +#define TFA98XX_TEMPERATURE 0x02
- +/** \addtogroup TEMPS
- + * @{
- + */
- +/*!
- + Temperature readout
- +*/
- +#define TFA98XX_TEMPERATURE_TEMPS (0x1ff<<0)
- +#define TFA98XX_TEMPERATURE_TEMPS_POS 0
- +#define TFA98XX_TEMPERATURE_TEMPS_LEN 9
- +#define TFA98XX_TEMPERATURE_TEMPS_MAX 511
- +#define TFA98XX_TEMPERATURE_TEMPS_MSK 0x1ff
- +/** @} */
- +
- +/** \addtogroup 9
- + * @{
- + */
- +/*!
- + not used
- +*/
- +#define TFA98XX_TEMPERATURE_9 (0x7f<<9)
- +#define TFA98XX_TEMPERATURE_9_POS 9
- +#define TFA98XX_TEMPERATURE_9_LEN 7
- +#define TFA98XX_TEMPERATURE_9_MAX 127
- +#define TFA98XX_TEMPERATURE_9_MSK 0xfe00
- +/** @} */
- +
- +/** @} */
- +
- +/** RevisionNumber Register ($03) ********************************************/
- +
- +/** \addtogroup _0x03_RevisionNumber
- + * @{
- + */
- +#define TFA98XX_REVISIONNUMBER 0x03
- +/** \addtogroup REV
- + * @{
- + */
- +/*!
- + Device type number = 97
- +*/
- +#define TFA98XX_REVISIONNUMBER_REV (0xff<<0)
- +#define TFA98XX_REVISIONNUMBER_REV_POS 0
- +#define TFA98XX_REVISIONNUMBER_REV_LEN 8
- +#define TFA98XX_REVISIONNUMBER_REV_MAX 255
- +#define TFA98XX_REVISIONNUMBER_REV_MSK 0xff
- +/** @} */
- +
- +/** @} */
- +
- +/** AudioReg Register ($04) ********************************************/
- +
- +/** \addtogroup _0x04_AudioReg_TFA9897
- + * @{
- + */
- +#define TFA9897_AUDIOREG 0x04
- +/** \addtogroup 0
- + * @{
- + */
- +/*!
- + reserved
- +*/
- +#define TFA9897_AUDIOREG_0 (0x7<<0)
- +#define TFA9897_AUDIOREG_0_POS 0
- +#define TFA9897_AUDIOREG_0_LEN 3
- +#define TFA9897_AUDIOREG_0_MAX 7
- +#define TFA9897_AUDIOREG_0_MSK 0x7
- +/** @} */
- +
- +/** \addtogroup CHS12
- + * @{
- + */
- +/*!
- + Channel Selection TDM input for Coolflux
- + * - 0 = Stereo
- + * - 1 = Left [default]
- + * - 2 = Right
- + * - 3 = Mono =(L+R)/2
- +*/
- +#define TFA9897_AUDIOREG_CHS12 (0x3<<3)
- +#define TFA9897_AUDIOREG_CHS12_POS 3
- +#define TFA9897_AUDIOREG_CHS12_LEN 2
- +#define TFA9897_AUDIOREG_CHS12_MAX 3
- +#define TFA9897_AUDIOREG_CHS12_MSK 0x18
- +/** @} */
- +
- +/** \addtogroup ILVL
- + * @{
- + */
- +/*!
- + Input level selection control
- + * - 0 = input is -6 dbFS, attenuation is bypassed
- + * - 1 = input is 0 dbFS, attenuated by 6 dBFS
- +*/
- +#define TFA9897_AUDIOREG_ILVL (0x1<<5)
- +#define TFA9897_AUDIOREG_ILVL_POS 5
- +#define TFA9897_AUDIOREG_ILVL_LEN 1
- +#define TFA9897_AUDIOREG_ILVL_MAX 1
- +#define TFA9897_AUDIOREG_ILVL_MSK 0x20
- +/** @} */
- +
- +/** \addtogroup CHSA
- + * @{
- + */
- +/*!
- + Input selection for amplifier
- + * - 0 = TDM data channel1, CoolFlux bypassed
- + * - 1 = TDM data channel2, CoolFlux bypassed
- + * - 2 = Coolflux DSP Output [default]
- + * - 3 = Coolflux DSP Output
- +*/
- +#define TFA9897_AUDIOREG_CHSA (0x3<<6)
- +#define TFA9897_AUDIOREG_CHSA_POS 6
- +#define TFA9897_AUDIOREG_CHSA_LEN 2
- +#define TFA9897_AUDIOREG_CHSA_MAX 3
- +#define TFA9897_AUDIOREG_CHSA_MSK 0xc0
- +/** @} */
- +
- +/** \addtogroup 8
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA9897_AUDIOREG_8 (0xf<<8)
- +#define TFA9897_AUDIOREG_8_POS 8
- +#define TFA9897_AUDIOREG_8_LEN 4
- +#define TFA9897_AUDIOREG_8_MAX 15
- +#define TFA9897_AUDIOREG_8_MSK 0xf00
- +/** @} */
- +
- +/** \addtogroup AUDFS
- + * @{
- + */
- +/*!
- + Audio sample rate setting
- + * - 6 = 32 KHz
- + * - 7 = 44.1 kHz
- + * - 8 = 48 KHz [default]
- + * - Others = Reserved
- +*/
- +#define TFA9897_AUDIOREG_AUDFS (0xf<<12)
- +#define TFA9897_AUDIOREG_AUDFS_POS 12
- +#define TFA9897_AUDIOREG_AUDFS_LEN 4
- +#define TFA9897_AUDIOREG_AUDFS_MAX 15
- +#define TFA9897_AUDIOREG_AUDFS_MSK 0xf000
- +/** @} */
- +
- +/** @} */
- +
- +/** I2SReg Register ($04) ********************************************/
- +
- +/** \addtogroup _0x04_I2SReg_TFA9887
- + * @{
- + */
- +#define TFA9887_I2SREG 0x04
- +/** \addtogroup I2SF
- + * @{
- + */
- +/*!
- + I2SFormat data 1, 2 input and output:
- + * - 0=not used
- + * - 1=not used
- + * - 2=MSB justify
- + * - 3=Philips standard I2S (default)
- + * - 4=LSB Justify 16 bits
- + * - 5=LSB Justify 18 bits
- + * - 6=LSB Justify 20 bits
- + * - 7=LSB Justify 24 bits
- +*/
- +#define TFA9887_I2SREG_I2SF (0x7<<0)
- +#define TFA9887_I2SREG_I2SF_POS 0
- +#define TFA9887_I2SREG_I2SF_LEN 3
- +#define TFA9887_I2SREG_I2SF_MAX 7
- +#define TFA9887_I2SREG_I2SF_MSK 0x7
- +/** @} */
- +
- +/** \addtogroup CHS12
- + * @{
- + */
- +/*!
- + ChannelSelection data1 input (In CoolFlux)
- + * - 0=Stereo
- + * - 1=Left
- + * - 2=Right
- + * - 3=Mono =(L+R)/2
- +*/
- +#define TFA9887_I2SREG_CHS12 (0x3<<3)
- +#define TFA9887_I2SREG_CHS12_POS 3
- +#define TFA9887_I2SREG_CHS12_LEN 2
- +#define TFA9887_I2SREG_CHS12_MAX 3
- +#define TFA9887_I2SREG_CHS12_MSK 0x18
- +/** @} */
- +
- +/** \addtogroup CHS3
- + * @{
- + */
- +/*!
- + ChannelSelection data 3 input (coolflux input, the DCDC converter gets the other signal)
- + * - 0=Left
- + * - 1=Right
- +*/
- +#define TFA9887_I2SREG_CHS3 (0x1<<5)
- +#define TFA9887_I2SREG_CHS3_POS 5
- +#define TFA9887_I2SREG_CHS3_LEN 1
- +#define TFA9887_I2SREG_CHS3_MAX 1
- +#define TFA9887_I2SREG_CHS3_MSK 0x20
- +/** @} */
- +
- +/** \addtogroup CHSA
- + * @{
- + */
- +/*!
- + Input selection for amplifier
- + * - 00b I2S input 1 left channel (CoolFlux bypassed)
- + * - 01b I2S input 1 Right channel (CoolFlux bypassed)
- + * - 10b Output Coolflux DSP
- + * - 11b Output Collflux DSP
- +*/
- +#define TFA9887_I2SREG_CHSA (0x3<<6)
- +#define TFA9887_I2SREG_CHSA_POS 6
- +#define TFA9887_I2SREG_CHSA_LEN 2
- +#define TFA9887_I2SREG_CHSA_MAX 3
- +#define TFA9887_I2SREG_CHSA_MSK 0xc0
- +/** @} */
- +
- +/** \addtogroup I2SDOE
- + * @{
- + */
- +/*!
- + data out tristate 0 = tristate
- +*/
- +#define TFA9887_I2SREG_I2SDOE (0x1<<11)
- +#define TFA9887_I2SREG_I2SDOE_POS 11
- +#define TFA9887_I2SREG_I2SDOE_LEN 1
- +#define TFA9887_I2SREG_I2SDOE_MAX 1
- +#define TFA9887_I2SREG_I2SDOE_MSK 0x800
- +/** @} */
- +
- +/** \addtogroup I2SSR
- + * @{
- + */
- +/*!
- + sample rate setting
- + * - 0000b 8 kHz
- + * - 0001b 11.025 kHz
- + * - 0010b 12 kHz
- + * - 0011b 16 kHz
- + * - 0100b 22.05 kHz
- + * - 0101b 24 kHz
- + * - 0110b 32 kHz
- + * - 0111b 44.1 kHz
- + * - 1000b* 48 KHz
- +*/
- +#define TFA9887_I2SREG_I2SSR (0xf<<12)
- +#define TFA9887_I2SREG_I2SSR_POS 12
- +#define TFA9887_I2SREG_I2SSR_LEN 4
- +#define TFA9887_I2SREG_I2SSR_MAX 15
- +#define TFA9887_I2SREG_I2SSR_MSK 0xf000
- +/** @} */
- +
- +/** @} */
- +
- +/** I2SReg Register ($04) ********************************************/
- +
- +/** \addtogroup _0x04_I2SReg
- + * @{
- + */
- +#define TFA98XX_I2SREG 0x04
- +/** \addtogroup I2SF
- + * @{
- + */
- +/*!
- + I2SFormat data 1 input:
- + * - 0 = Philips standard I2S
- + * - 1 = Philips standard I2S
- + * - 2 = MSB justify
- + * - 3 = Philips standard I2S [default]
- + * - 4 = LSB Justify 16 bits
- + * - 5 = LSB Justify 18 bits
- + * - 6 = LSB Justify 20 bits
- + * - 7 = LSB Justify 24 bits
- +*/
- +#define TFA98XX_I2SREG_I2SF (0x7<<0)
- +#define TFA98XX_I2SREG_I2SF_POS 0
- +#define TFA98XX_I2SREG_I2SF_LEN 3
- +#define TFA98XX_I2SREG_I2SF_MAX 7
- +#define TFA98XX_I2SREG_I2SF_MSK 0x7
- +/** @} */
- +
- +/** \addtogroup CHS12
- + * @{
- + */
- +/*!
- + ChannelSelection data1 input (In CoolFlux)
- + * - 0 = Stereo
- + * - 1 = Left [default]
- + * - 2 = Right
- + * - 3 = Mono =(L+R)/2
- +*/
- +#define TFA98XX_I2SREG_CHS12 (0x3<<3)
- +#define TFA98XX_I2SREG_CHS12_POS 3
- +#define TFA98XX_I2SREG_CHS12_LEN 2
- +#define TFA98XX_I2SREG_CHS12_MAX 3
- +#define TFA98XX_I2SREG_CHS12_MSK 0x18
- +/** @} */
- +
- +/** \addtogroup CHS3
- + * @{
- + */
- +/*!
- + ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal)
- + * - 0 = Left channel to CF DSP right channel to other vamp mux [default]
- + * - 1 = Right channel to CF DSP left channel to other vamp mux
- +*/
- +#define TFA98XX_I2SREG_CHS3 (0x1<<5)
- +#define TFA98XX_I2SREG_CHS3_POS 5
- +#define TFA98XX_I2SREG_CHS3_LEN 1
- +#define TFA98XX_I2SREG_CHS3_MAX 1
- +#define TFA98XX_I2SREG_CHS3_MSK 0x20
- +/** @} */
- +
- +/** \addtogroup CHSA
- + * @{
- + */
- +/*!
- + Input selection for amplifier
- + * - 0 = I2S input 1 left channel (CoolFlux bypassed)
- + * - 1 = I2S input 1 Right channel (CoolFlux bypassed)
- + * - 2 = Output Coolflux DSP [default]
- + * - 3 = Output Collflux DSP
- +*/
- +#define TFA98XX_I2SREG_CHSA (0x3<<6)
- +#define TFA98XX_I2SREG_CHSA_POS 6
- +#define TFA98XX_I2SREG_CHSA_LEN 2
- +#define TFA98XX_I2SREG_CHSA_MAX 3
- +#define TFA98XX_I2SREG_CHSA_MSK 0xc0
- +/** @} */
- +
- +/** \addtogroup I2SDOC
- + * @{
- + */
- +/*!
- + selection data out
- + * - 0 = I2S-TX [default]
- + * - 1 = datai1
- + * - 2 = datai2
- + * - 3 = datai3
- +*/
- +#define TFA9890_I2SREG_I2SDOC (0x3<<8)
- +#define TFA9890_I2SREG_I2SDOC_POS 8
- +#define TFA9890_I2SREG_I2SDOC_LEN 2
- +#define TFA9890_I2SREG_I2SDOC_MAX 3
- +#define TFA9890_I2SREG_I2SDOC_MSK 0x300
- +/** @} */
- +
- +/** \addtogroup DISP
- + * @{
- + */
- +/*!
- + idp protection
- + * - 0 = on
- + * - 1 = off
- +*/
- +#define TFA9890_I2SREG_DISP (0x1<<10)
- +#define TFA9890_I2SREG_DISP_POS 10
- +#define TFA9890_I2SREG_DISP_LEN 1
- +#define TFA9890_I2SREG_DISP_MAX 1
- +#define TFA9890_I2SREG_DISP_MSK 0x400
- +/** @} */
- +
- +/** \addtogroup I2SDOE
- + * @{
- + */
- +/*!
- + Enable data output
- + * - 0 = data output in tristate
- + * - 1 = normal mode [default]
- +*/
- +#define TFA98XX_I2SREG_I2SDOE (0x1<<11)
- +#define TFA98XX_I2SREG_I2SDOE_POS 11
- +#define TFA98XX_I2SREG_I2SDOE_LEN 1
- +#define TFA98XX_I2SREG_I2SDOE_MAX 1
- +#define TFA98XX_I2SREG_I2SDOE_MSK 0x800
- +/** @} */
- +
- +/** \addtogroup I2SSR
- + * @{
- + */
- +/*!
- + sample rate setting
- + * - 0 = 8kHk
- + * - 1 =11.025kHz
- + * - 2 = 12kHz
- + * - 3 = 16kHz
- + * - 4 = 22.05kHz
- + * - 5 = 24kHz
- + * - 6 = 32kHz
- + * - 7 = 44.1kHz
- + * - 8 = 48kHz [default]
- +*/
- +#define TFA98XX_I2SREG_I2SSR (0xf<<12)
- +#define TFA98XX_I2SREG_I2SSR_POS 12
- +#define TFA98XX_I2SREG_I2SSR_LEN 4
- +#define TFA98XX_I2SREG_I2SSR_MAX 15
- +#define TFA98XX_I2SREG_I2SSR_MSK 0xf000
- +/** @} */
- +
- +/** @} */
- +
- +/** bat_prot Register ($05) ********************************************/
- +
- +/** \addtogroup _0x05_bat_prot
- + * @{
- + */
- +#define TFA98XX_BAT_PROT 0x05
- +/** \addtogroup BSSCR
- + * @{
- + */
- +/*!
- + Protection Attack Time
- + * - 0 = 0.56 dB/Sample
- + * - 1 = 1.12 dB/sample
- + * - 2 = 2.32 dB/Sample [default]
- + * - 3 = infinite dB/Sample
- +*/
- +#define TFA989X_BAT_PROT_BSSCR (0x3<<0)
- +#define TFA989X_BAT_PROT_BSSCR_POS 0
- +#define TFA989X_BAT_PROT_BSSCR_LEN 2
- +#define TFA989X_BAT_PROT_BSSCR_MAX 3
- +#define TFA989X_BAT_PROT_BSSCR_MSK 0x3
- +/** @} */
- +
- +/** \addtogroup BSST
- + * @{
- + */
- +/*!
- + ProtectionThreshold
- + * - normal steep
- + * - 0 = 2.73V 2.99V
- + * - 1 = 2.83V 3.09V
- + * - 2 = 2.93V 3.19V
- + * - 3 = 3.03V 3.29V
- + * - 4 = 3.13V 3.39V (default)
- + * - 5 = 3.23V 3.49V
- + * - 6 = 3.33V 3.59V
- + * - 7 = 3.43V 3.69V
- + * - 8 = 3.53V 3.79V
- + * - 9 = 3.63V 3.89V
- + * - 10 = 3.73V 3.99V
- + * - 11 = 3.83V 4.09V
- + * - 12 = 3.93V 4.19V
- + * - 13 = 4.03V 4.29V
- + * - 14 = 4.13V 4.39V
- + * - 15 = 4.23V 4.49V
- +*/
- +#define TFA989X_BAT_PROT_BSST (0xf<<2)
- +#define TFA989X_BAT_PROT_BSST_POS 2
- +#define TFA989X_BAT_PROT_BSST_LEN 4
- +#define TFA989X_BAT_PROT_BSST_MAX 15
- +#define TFA989X_BAT_PROT_BSST_MSK 0x3c
- +/** @} */
- +
- +/** \addtogroup BSSRL
- + * @{
- + */
- +/*!
- + Protection Maximum Reduction
- + * - 0 = 3V
- + * - 1 = 4V
- + * - 2 = 5V [default]
- + * - 3 = not permitted
- +*/
- +#define TFA98XX_BAT_PROT_BSSRL (0x3<<6)
- +#define TFA98XX_BAT_PROT_BSSRL_POS 6
- +#define TFA98XX_BAT_PROT_BSSRL_LEN 2
- +#define TFA98XX_BAT_PROT_BSSRL_MAX 3
- +#define TFA98XX_BAT_PROT_BSSRL_MSK 0xc0
- +/** @} */
- +
- +/** \addtogroup BSSRR
- + * @{
- + */
- +/*!
- + Battery Protection Release Time
- + * - 0 = 0.4 sec
- + * - 1 = 0.8 sec
- + * - 2 = 1.2 sec
- + * - 3 = 1.6 sec [default]
- + * - 4 = 2 sec
- + * - 5 = 2,4 sec
- + * - 6 = 2.8 sec
- + * - 7 = 3.2 sec
- +*/
- +#define TFA98XX_BAT_PROT_BSSRR (0x7<<8)
- +#define TFA98XX_BAT_PROT_BSSRR_POS 8
- +#define TFA98XX_BAT_PROT_BSSRR_LEN 3
- +#define TFA98XX_BAT_PROT_BSSRR_MAX 7
- +#define TFA98XX_BAT_PROT_BSSRR_MSK 0x700
- +/** @} */
- +
- +/** \addtogroup BSSHY
- + * @{
- + */
- +/*!
- + Battery Protection Hysterese
- + * - 0 = No hysterese
- + * - 1 = 0.05V
- + * - 2 = 0.1V [default]
- + * - 3 = 0.2V
- +*/
- +#define TFA98XX_BAT_PROT_BSSHY (0x3<<11)
- +#define TFA98XX_BAT_PROT_BSSHY_POS 11
- +#define TFA98XX_BAT_PROT_BSSHY_LEN 2
- +#define TFA98XX_BAT_PROT_BSSHY_MAX 3
- +#define TFA98XX_BAT_PROT_BSSHY_MSK 0x1800
- +/** @} */
- +
- +/** \addtogroup 13
- + * @{
- + */
- +/*!
- + reset clipper
- + * - 0 = clipper is not reset if CF is bypassed [default]
- + * - 1 = reset the clipper via I2C in case the CF is bypassed
- +*/
- +#define TFA98XX_BAT_PROT_13 (0x1<<13)
- +#define TFA98XX_BAT_PROT_13_POS 13
- +#define TFA98XX_BAT_PROT_13_LEN 1
- +#define TFA98XX_BAT_PROT_13_MAX 1
- +#define TFA98XX_BAT_PROT_13_MSK 0x2000
- +/** @} */
- +
- +/** \addtogroup BSSR
- + * @{
- + */
- +/*!
- + battery voltage for I2C read out only
- + * - 0 = minimum battery value [reset]
- + * - 1 = avarage battery value
- +*/
- +#define TFA98XX_BAT_PROT_BSSR (0x1<<14)
- +#define TFA98XX_BAT_PROT_BSSR_POS 14
- +#define TFA98XX_BAT_PROT_BSSR_LEN 1
- +#define TFA98XX_BAT_PROT_BSSR_MAX 1
- +#define TFA98XX_BAT_PROT_BSSR_MSK 0x4000
- +/** @} */
- +
- +/** \addtogroup BSSBY
- + * @{
- + */
- +/*!
- + bypass clipper battery protection
- + * - 0 = clipper active [device default]
- + * - 1 = clipper bypassed [new default]
- +*/
- +#define TFA989X_BAT_PROT_BSSBY (0x1<<15)
- +#define TFA989X_BAT_PROT_BSSBY_POS 15
- +#define TFA989X_BAT_PROT_BSSBY_LEN 1
- +#define TFA989X_BAT_PROT_BSSBY_MAX 1
- +#define TFA989X_BAT_PROT_BSSBY_MSK 0x8000
- +/** @} */
- +
- +/** @} */
- +
- +/** bat_prot Register ($05) ********************************************/
- +
- +/** \addtogroup _0x05_bat_prot_TFA9887
- + * @{
- + */
- +#define TFA9887_BAT_PROT 0x05
- +/** \addtogroup BSSBY
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA9887_BAT_PROT_BSSBY (0x1<<0)
- +#define TFA9887_BAT_PROT_BSSBY_POS 0
- +#define TFA9887_BAT_PROT_BSSBY_LEN 1
- +#define TFA9887_BAT_PROT_BSSBY_MAX 1
- +#define TFA9887_BAT_PROT_BSSBY_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup BSSCR
- + * @{
- + */
- +/*!
- + 00 = 0.56 dB/Sample
- + * - 01 = 1.12 dB/sample
- + * - 10 = 2.32 dB/Sample (default)
- + * - 11 = infinite dB/Sample
- +*/
- +#define TFA9887_BAT_PROT_BSSCR (0x3<<1)
- +#define TFA9887_BAT_PROT_BSSCR_POS 1
- +#define TFA9887_BAT_PROT_BSSCR_LEN 2
- +#define TFA9887_BAT_PROT_BSSCR_MAX 3
- +#define TFA9887_BAT_PROT_BSSCR_MSK 0x6
- +/** @} */
- +
- +/** \addtogroup BSST
- + * @{
- + */
- +/*!
- + 000 = 2.92V
- + * - 001 = 3.05 V
- + * - 010 = 3.17
- + * - 011 = 3.3 V
- + * - 100 = 3.42 V
- + * - 101 - 3.55 V (default)
- + * - 110 = 3.67 V
- + * - 111 = 3.8 V
- +*/
- +#define TFA9887_BAT_PROT_BSST (0x7<<3)
- +#define TFA9887_BAT_PROT_BSST_POS 3
- +#define TFA9887_BAT_PROT_BSST_LEN 3
- +#define TFA9887_BAT_PROT_BSST_MAX 7
- +#define TFA9887_BAT_PROT_BSST_MSK 0x38
- +/** @} */
- +
- +/** \addtogroup 13
- + * @{
- + */
- +/*!
- + to reset the clipper via I2C in case the CF is bypassed
- +*/
- +#define TFA9887_BAT_PROT_13 (0x1<<13)
- +#define TFA9887_BAT_PROT_13_POS 13
- +#define TFA9887_BAT_PROT_13_LEN 1
- +#define TFA9887_BAT_PROT_13_MAX 1
- +#define TFA9887_BAT_PROT_13_MSK 0x2000
- +/** @} */
- +
- +/** \addtogroup I2SDOC
- + * @{
- + */
- +/*!
- + selection data out
- + * - 0 = I2S-TX; 1 = datai3
- +*/
- +#define TFA9887_BAT_PROT_I2SDOC (0x1<<15)
- +#define TFA9887_BAT_PROT_I2SDOC_POS 15
- +#define TFA9887_BAT_PROT_I2SDOC_LEN 1
- +#define TFA9887_BAT_PROT_I2SDOC_MAX 1
- +#define TFA9887_BAT_PROT_I2SDOC_MSK 0x8000
- +/** @} */
- +
- +/** @} */
- +
- +/** audio_ctr Register ($06) ********************************************/
- +
- +/** \addtogroup _0x06_audio_ctr
- + * @{
- + */
- +#define TFA98XX_AUDIO_CTR 0x06
- +/** \addtogroup DPSA
- + * @{
- + */
- +/*!
- + Enable dynamic powerstage activation
- + * - 0 = dpsa off
- + * - 1 = dpsa on [default]
- +*/
- +#define TFA98XX_AUDIO_CTR_DPSA (0x1<<0)
- +#define TFA98XX_AUDIO_CTR_DPSA_POS 0
- +#define TFA98XX_AUDIO_CTR_DPSA_LEN 1
- +#define TFA98XX_AUDIO_CTR_DPSA_MAX 1
- +#define TFA98XX_AUDIO_CTR_DPSA_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup control slope
- + * @{
- + */
- +/*!
- + 0 = slope 1
- + 1 = slope 1
- + 2 = slope 1
- + 3 = slope 2
- + 4 = slope 1
- + 5 = slope 2
- + 6 = slope 2
- + 7 = slope 3 [default]
- + 8 = slope 1
- + 9 = slope 2
- + 10 = slope 2
- + 11 = slope 3
- + 12 = slope 2
- + 13 = slope 3
- + 14 = slope 3
- + 15 = maximal
- +*/
- +#define TFA98XX_AUDIO_CTR_AMPSL (0xf<<1)
- +#define TFA98XX_AUDIO_CTR_AMPSL_POS 1
- +#define TFA98XX_AUDIO_CTR_AMPSL_LEN 4
- +#define TFA98XX_AUDIO_CTR_AMPSL_MAX 15
- +#define TFA98XX_AUDIO_CTR_AMPSL_MSK 0x1e
- +/** @} */
- +
- +/** \addtogroup CFSM
- + * @{
- + */
- +/*!
- + Soft mute in CoolFlux
- + * - 0= no mute [default]
- + * - 1= muted
- +*/
- +#define TFA98XX_AUDIO_CTR_CFSM (0x1<<5)
- +#define TFA98XX_AUDIO_CTR_CFSM_POS 5
- +#define TFA98XX_AUDIO_CTR_CFSM_LEN 1
- +#define TFA98XX_AUDIO_CTR_CFSM_MAX 1
- +#define TFA98XX_AUDIO_CTR_CFSM_MSK 0x20
- +/** @} */
- +
- +/** \addtogroup 6
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA98XX_AUDIO_CTR_6 (0x1<<6)
- +#define TFA98XX_AUDIO_CTR_6_POS 6
- +#define TFA98XX_AUDIO_CTR_6_LEN 1
- +#define TFA98XX_AUDIO_CTR_6_MAX 1
- +#define TFA98XX_AUDIO_CTR_6_MSK 0x40
- +/** @} */
- +
- +/** \addtogroup BSSS
- + * @{
- + */
- +/*!
- + batsensesteepness
- + * - 0 = 5.4V/V if ctr_supplysense = 1
- + * - 1 = 10.8V/V if ctrl_supplysense = 1
- + * - 0 = 3.13V/V if ctrl_supplysense = 0
- + * - 1 = 6.25V/V if ctrl_supplysense = 0
- +*/
- +#define TFA989X_AUDIO_CTR_BSSS (0x1<<7)
- +#define TFA989X_AUDIO_CTR_BSSS_POS 7
- +#define TFA989X_AUDIO_CTR_BSSS_LEN 1
- +#define TFA989X_AUDIO_CTR_BSSS_MAX 1
- +#define TFA989X_AUDIO_CTR_BSSS_MSK 0x80
- +/** @} */
- +
- +/** \addtogroup VOL
- + * @{
- + */
- +/*!
- + volume control (in CoolFlux)
- +*/
- +#define TFA98XX_AUDIO_CTR_VOL (0xff<<8)
- +#define TFA98XX_AUDIO_CTR_VOL_POS 8
- +#define TFA98XX_AUDIO_CTR_VOL_LEN 8
- +#define TFA98XX_AUDIO_CTR_VOL_MAX 255
- +#define TFA98XX_AUDIO_CTR_VOL_MSK 0xff00
- +/** @} */
- +
- +/** @} */
- +
- +/** DCDCboost Register ($07) ********************************************/
- +
- +/** \addtogroup _0x07_DCDCboost
- + * @{
- + */
- +#define TFA98XX_DCDCBOOST 0x07
- +/** \addtogroup DCVO
- + * @{
- + */
- +/*!
- + Boost Voltage
- + * - 0 = 4.0 V
- + * - 1 = 4.2 V
- + * - 2 = 4.4 V
- + * - 3 = 4.6 V
- + * - 4 = 4.8 V
- + * - 5 = 5.0 V
- + * - 6 = 5.2 V (default)
- + * - 7 = 5.4 V
- +*/
- +#define TFA98XX_DCDCBOOST_DCVO (0x7<<0)
- +#define TFA98XX_DCDCBOOST_DCVO_POS 0
- +#define TFA98XX_DCDCBOOST_DCVO_LEN 3
- +#define TFA98XX_DCDCBOOST_DCVO_MAX 7
- +#define TFA98XX_DCDCBOOST_DCVO_MSK 0x7
- +/** @} */
- +
- +/** \addtogroup DCMCC
- + * @{
- + */
- +/*!
- + for 87,90,95
- + * - 0 = 0.48 A
- + * - 1 = 0.96 A
- + * - 2 = 1.44 A
- + * - 3 = 1.92 A
- + * - 4 = 2.4 A [87/95 default]
- + * - 5 = 2.88 A
- + * - 6 = 3.56 A
- + * - 7 = 3.8 A [90 default]
- +*/
- +#define TFA98XX_DCDCBOOST_DCMCC (0x7<<3)
- +#define TFA98XX_DCDCBOOST_DCMCC_POS 3
- +#define TFA98XX_DCDCBOOST_DCMCC_LEN 3
- +#define TFA98XX_DCDCBOOST_DCMCC_MAX 7
- +#define TFA98XX_DCDCBOOST_DCMCC_MSK 0x38
- +#define TFA9897_DCDCBOOST_DCMCC (0xf<<3)
- +#define TFA9897_DCDCBOOST_DCMCC_POS 3
- +#define TFA9897_DCDCBOOST_DCMCC_LEN 4
- +#define TFA9897_DCDCBOOST_DCMCC_MAX 15
- +#define TFA9897_DCDCBOOST_DCMCC_MSK 0x78
- +
- +/** \addtogroup DCIE
- + * @{
- + */
- +/*!
- + Adaptive / Intelligent boost mode
- + * - 0 = Off
- + * - 1 = On [default]
- +*/
- +#define TFA98XX_DCDCBOOST_DCIE (0x1<<10)
- +#define TFA98XX_DCDCBOOST_DCIE_POS 10
- +#define TFA98XX_DCDCBOOST_DCIE_LEN 1
- +#define TFA98XX_DCDCBOOST_DCIE_MAX 1
- +#define TFA98XX_DCDCBOOST_DCIE_MSK 0x400
- +/** @} */
- +
- +/** \addtogroup DCSR
- + * @{
- + */
- +/*!
- + Soft RampUp/Down mode for DCDC controller
- + * - 0 = Immediate : 0 Cycle
- + * - 1 = Fast (Default) : 32 Cycles/step at 2MHz, 16 cycles/step at 1MHz and 0.5MHz
- +*/
- +#define TFA98XX_DCDCBOOST_DCSR (0x1<<11)
- +#define TFA98XX_DCDCBOOST_DCSR_POS 11
- +#define TFA98XX_DCDCBOOST_DCSR_LEN 1
- +#define TFA98XX_DCDCBOOST_DCSR_MAX 1
- +#define TFA98XX_DCDCBOOST_DCSR_MSK 0x800
- +/** @} */
- +
- +
- +/** @} */
- +
- +/** spkr_calibration Register ($08) ********************************************/
- +
- +/** \addtogroup _0x08_spkr_calibration
- + * @{
- + */
- +#define TFA98XX_SPKR_CALIBRATION 0x08
- +/** \addtogroup TROS
- + * @{
- + */
- +/*!
- + Select external temperature also the ext_temp will be put on the temp read out
- + * - 0 = internal temperature
- + * - 1 = external temperature
- +*/
- +#define TFA98XX_SPKR_CALIBRATION_TROS (0x1<<0)
- +#define TFA98XX_SPKR_CALIBRATION_TROS_POS 0
- +#define TFA98XX_SPKR_CALIBRATION_TROS_LEN 1
- +#define TFA98XX_SPKR_CALIBRATION_TROS_MAX 1
- +#define TFA98XX_SPKR_CALIBRATION_TROS_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup EXTTS
- + * @{
- + */
- +/*!
- + external temperature setting to be given by host
- +*/
- +#define TFA98XX_SPKR_CALIBRATION_EXTTS (0x1ff<<1)
- +#define TFA98XX_SPKR_CALIBRATION_EXTTS_POS 1
- +#define TFA98XX_SPKR_CALIBRATION_EXTTS_LEN 9
- +#define TFA98XX_SPKR_CALIBRATION_EXTTS_MAX 511
- +#define TFA98XX_SPKR_CALIBRATION_EXTTS_MSK 0x3fe
- +/** @} */
- +
- +/** \addtogroup 10
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA98XX_SPKR_CALIBRATION_10 (0x1<<10)
- +#define TFA98XX_SPKR_CALIBRATION_10_POS 10
- +#define TFA98XX_SPKR_CALIBRATION_10_LEN 1
- +#define TFA98XX_SPKR_CALIBRATION_10_MAX 1
- +#define TFA98XX_SPKR_CALIBRATION_10_MSK 0x400
- +/** @} */
- +
- +/** \addtogroup DCSYN
- + * @{
- + */
- +/*!
- + DCDC synchronisation off + 7 positions
- + * - 0 = off + 7 positions
- + * - 1 = off
- + * - 2 = on min
- + * - 3 = on, 3
- + * - 4 = on, 4
- + * - 5 = on, 5
- + * - 6 = on, 6
- + * - 7 = on, max
- +*/
- +#define TFA98XX_SPKR_CALIBRATION_DCSYN (0x7<<11)
- +#define TFA98XX_SPKR_CALIBRATION_DCSYN_POS 11
- +#define TFA98XX_SPKR_CALIBRATION_DCSYN_LEN 3
- +#define TFA98XX_SPKR_CALIBRATION_DCSYN_MAX 7
- +#define TFA98XX_SPKR_CALIBRATION_DCSYN_MSK 0x3800
- +/** @} */
- +
- +
- +/** sys_ctrl Register ($09) ********************************************/
- +
- +/** \addtogroup _0x09_sys_ctrl
- + * @{
- + */
- +#define TFA98XX_SYS_CTRL 0x09
- +/** \addtogroup PWDN
- + * @{
- + */
- +/*!
- + Device Mode
- + * - 0 = Device is set in operating mode
- + * - 1 = Device is set in Powerdown mode [default]
- +*/
- +#define TFA98XX_SYS_CTRL_PWDN (0x1<<0)
- +#define TFA98XX_SYS_CTRL_PWDN_POS 0
- +#define TFA98XX_SYS_CTRL_PWDN_LEN 1
- +#define TFA98XX_SYS_CTRL_PWDN_MAX 1
- +#define TFA98XX_SYS_CTRL_PWDN_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup I2CR
- + * @{
- + */
- +/*!
- + I2C Reset
- + * - 0 = Normal operation [default]
- + * - 1 = Reset all register to default
- +*/
- +#define TFA98XX_SYS_CTRL_I2CR (0x1<<1)
- +#define TFA98XX_SYS_CTRL_I2CR_POS 1
- +#define TFA98XX_SYS_CTRL_I2CR_LEN 1
- +#define TFA98XX_SYS_CTRL_I2CR_MAX 1
- +#define TFA98XX_SYS_CTRL_I2CR_MSK 0x2
- +/** @} */
- +
- +/** \addtogroup CFE
- + * @{
- + */
- +/*!
- + Enable CoolFlux
- + * - 0 = Coolflux OFF
- + * - 1 = Coolflux ON [default]
- +*/
- +#define TFA98XX_SYS_CTRL_CFE (0x1<<2)
- +#define TFA98XX_SYS_CTRL_CFE_POS 2
- +#define TFA98XX_SYS_CTRL_CFE_LEN 1
- +#define TFA98XX_SYS_CTRL_CFE_MAX 1
- +#define TFA98XX_SYS_CTRL_CFE_MSK 0x4
- +/** @} */
- +
- +/** \addtogroup AMPE
- + * @{
- + */
- +/*!
- + Enable Amplifier
- + * - 0 = Amplifier OFF
- + * - 1 = Amplifier ON [default]
- +*/
- +#define TFA98XX_SYS_CTRL_AMPE (0x1<<3)
- +#define TFA98XX_SYS_CTRL_AMPE_POS 3
- +#define TFA98XX_SYS_CTRL_AMPE_LEN 1
- +#define TFA98XX_SYS_CTRL_AMPE_MAX 1
- +#define TFA98XX_SYS_CTRL_AMPE_MSK 0x8
- +/** @} */
- +
- +/** \addtogroup DCA
- + * @{
- + */
- +/*!
- + EnableBoost
- + * - 0 = Boost OFF (Follower mode) [default]
- + * - 1 = Boost ON
- +*/
- +#define TFA98XX_SYS_CTRL_DCA (0x1<<4)
- +#define TFA98XX_SYS_CTRL_DCA_POS 4
- +#define TFA98XX_SYS_CTRL_DCA_LEN 1
- +#define TFA98XX_SYS_CTRL_DCA_MAX 1
- +#define TFA98XX_SYS_CTRL_DCA_MSK 0x10
- +/** @} */
- +
- +/** \addtogroup SBSL
- + * @{
- + */
- +/*!
- + Coolflux configured
- + * - 0 = coolflux not configured [default]
- + * - 1 = coolflux configured
- +*/
- +#define TFA98XX_SYS_CTRL_SBSL (0x1<<5)
- +#define TFA98XX_SYS_CTRL_SBSL_POS 5
- +#define TFA98XX_SYS_CTRL_SBSL_LEN 1
- +#define TFA98XX_SYS_CTRL_SBSL_MAX 1
- +#define TFA98XX_SYS_CTRL_SBSL_MSK 0x20
- +/** @} */
- +
- +/** \addtogroup AMPC
- + * @{
- + */
- +/*!
- + Selection on how Amplifier is enabled
- + * - 0 = Enable amplifier independent of CoolFlux [default]
- + * - 1 = CoolFlux enables amplifier (SW_Bit: cf_enbl_amplifier)
- +*/
- +#define TFA98XX_SYS_CTRL_AMPC (0x1<<6)
- +#define TFA98XX_SYS_CTRL_AMPC_POS 6
- +#define TFA98XX_SYS_CTRL_AMPC_LEN 1
- +#define TFA98XX_SYS_CTRL_AMPC_MAX 1
- +#define TFA98XX_SYS_CTRL_AMPC_MSK 0x40
- +/** @} */
- +
- +/** \addtogroup DCDIS
- + * @{
- + */
- +/*!
- + DCDC not connected
- + * - 0 = normal DCDC functionality [default]
- + * - 1 = DCDC switched off
- +*/
- +#define TFA98XX_SYS_CTRL_DCDIS (0x1<<7)
- +#define TFA98XX_SYS_CTRL_DCDIS_POS 7
- +#define TFA98XX_SYS_CTRL_DCDIS_LEN 1
- +#define TFA98XX_SYS_CTRL_DCDIS_MAX 1
- +#define TFA98XX_SYS_CTRL_DCDIS_MSK 0x80
- +/** @} */
- +
- +/** \addtogroup PSDR
- + * @{
- + */
- +/*!
- + IDDQ test amplifier
- + * - 0 = amplifier is normal mode [default]
- + * - 1 = amplifier is in the test mode
- +*/
- +#define TFA98XX_SYS_CTRL_PSDR (0x1<<8)
- +#define TFA98XX_SYS_CTRL_PSDR_POS 8
- +#define TFA98XX_SYS_CTRL_PSDR_LEN 1
- +#define TFA98XX_SYS_CTRL_PSDR_MAX 1
- +#define TFA98XX_SYS_CTRL_PSDR_MSK 0x100
- +/** @} */
- +
- +/** \addtogroup DCCV
- + * @{
- + */
- +/*!
- + Coil Value
- + * - 0 = 0.7 uH
- + * - 1 = 1.0 uH [new default]
- + * - 2 = 1.5 uH [device default]
- + * - 3 = 2.2 uH
- +*/
- +#define TFA98XX_SYS_CTRL_DCCV (0x3<<9)
- +#define TFA98XX_SYS_CTRL_DCCV_POS 9
- +#define TFA98XX_SYS_CTRL_DCCV_LEN 2
- +#define TFA98XX_SYS_CTRL_DCCV_MAX 3
- +#define TFA98XX_SYS_CTRL_DCCV_MSK 0x600
- +/** @} */
- +
- +/** \addtogroup ISEL
- + * @{
- + */
- +/*!
- + selection input 1 or 2
- + * 0 = input 1 [default]
- + * 1 = input 2
- +*/
- +#define TFA98XX_SYS_CTRL_ISEL (0x1<<13)
- +#define TFA98XX_SYS_CTRL_ISEL_POS 13
- +#define TFA98XX_SYS_CTRL_ISEL_LEN 1
- +#define TFA98XX_SYS_CTRL_ISEL_MAX 1
- +#define TFA98XX_SYS_CTRL_ISEL_MSK 0x2000
- +/** @} */
- +
- +/** \addtogroup INTPAD
- + * @{
- + */
- +/*!
- + INT pad configuration control
- + * - 00 = INT is active low driven all the time
- + * - 01 = INT is active high driven all the time
- + * - 10 = INT pad in pull up mode, driven 0 only when interrupt is raised
- + * - 11 = INT pad in pull down mode, driven 1 only when interrupt is raised
- +*/
- +#define TFA9897_SYS_CTRL_INTPAD (0x3<<12)
- +#define TFA9897_SYS_CTRL_INTPAD_POS 12
- +#define TFA9897_SYS_CTRL_INTPAD_LEN 2
- +#define TFA9897_SYS_CTRL_INTPAD_MAX 3
- +#define TFA9897_SYS_CTRL_INTPAD_MSK 0x3000
- +/** @} */
- +
- +/** \addtogroup IPLL
- + * @{
- + */
- +/*!
- + PLL input refrence clock selection
- + * - 0 = Bit clock BCK [default]
- + * - 1 = Frame Sync FS
- +*/
- +#define TFA98XX_SYS_CTRL_IPLL (0x1<<14)
- +#define TFA98XX_SYS_CTRL_IPLL_POS 14
- +#define TFA98XX_SYS_CTRL_IPLL_LEN 1
- +#define TFA98XX_SYS_CTRL_IPLL_MAX 1
- +#define TFA98XX_SYS_CTRL_IPLL_MSK 0x4000
- +/** @} */
- +
- +/** \addtogroup CFCLK
- + * @{
- + */
- +/*!
- + Coolflux sub-system clock
- + * - 0 = clk_e selected for CF sub-system
- + * - 1 = I2C clock SCL selected for CF sub-system
- +*/
- +#define TFA98XX_SYS_CTRL_CFCLK (0x1<<15)
- +#define TFA98XX_SYS_CTRL_CFCLK_POS 15
- +#define TFA98XX_SYS_CTRL_CFCLK_LEN 1
- +#define TFA98XX_SYS_CTRL_CFCLK_MAX 1
- +#define TFA98XX_SYS_CTRL_CFCLK_MSK 0x8000
- +/** @} */
- +
- +/** @} */
- +
- +/** sys_ctrl Register ($09) ********************************************/
- +
- +/** \addtogroup _0x09_sys_ctrl
- + * @{
- + */
- +#define TFA98XX_SYS_CTRL 0x09
- +/** \addtogroup ISEL
- + * @{
- + */
- +/*!
- + selection input 1 or 2
- + * - 0 = input 1 [default]
- + * - 1 = input 2
- +*/
- +#define TFA9890_SYS_CTRL_ISEL (0x1<<13)
- +#define TFA9890_SYS_CTRL_ISEL_POS 13
- +#define TFA9890_SYS_CTRL_ISEL_LEN 1
- +#define TFA9890_SYS_CTRL_ISEL_MAX 1
- +#define TFA9890_SYS_CTRL_ISEL_MSK 0x2000
- +/** @} */
- +
- +/** @} */
- +
- +/** I2S_sel_reg Register ($0a) ********************************************/
- +
- +/** \addtogroup _0x0a_I2S_sel_reg
- + * @{
- + */
- +#define TFA98XX_I2S_SEL_REG 0x0a
- +#define TFA9890_I2S_SEL_REG_POR 0x3ec3
- +/** \addtogroup DOLS
- + * @{
- + */
- +/*!
- + Output selection dataout left channel
- + * - 0=CurrentSense signal
- + * - 1=Coolflux output 3 (e.g. gain)
- + * - 2=Coolflux output 2 (second channel)
- + * - 3=Coolflux output 1 (main channel) [default]
- + * - 4=datai3 left
- + * - 5=datai3 right
- + * - 6= dcdc feedforward audio current
- +*/
- +#define TFA98XX_I2S_SEL_REG_DOLS (0x7<<0)
- +#define TFA98XX_I2S_SEL_REG_DOLS_POS 0
- +#define TFA98XX_I2S_SEL_REG_DOLS_LEN 3
- +#define TFA98XX_I2S_SEL_REG_DOLS_MAX 7
- +#define TFA98XX_I2S_SEL_REG_DOLS_MSK 0x7
- +/** @} */
- +
- +/** \addtogroup DORS
- + * @{
- + */
- +/*!
- + Output selection dataout right channel
- + * - 0=CurrentSense signal [default]
- + * - 1=Coolflux output 3 (e.g. gain)
- + * - 2=Coolflux output 2 (second channel)
- + * - 3=Coolflux output 1 (main channel)
- + * - 4=datai3 left
- + * - 5=datai3 right
- + * - 6= dcdc feedforward audio current
- +*/
- +#define TFA98XX_I2S_SEL_REG_DORS (0x7<<3)
- +#define TFA98XX_I2S_SEL_REG_DORS_POS 3
- +#define TFA98XX_I2S_SEL_REG_DORS_LEN 3
- +#define TFA98XX_I2S_SEL_REG_DORS_MAX 7
- +#define TFA98XX_I2S_SEL_REG_DORS_MSK 0x38
- +/** @} */
- +
- +/** \addtogroup SPKL
- + * @{
- + */
- +/*!
- + Selection speaker induction
- + * - 0 = 22 uH
- + * - 1 = 27 uH
- + * - 2 = 33 uH
- + * - 3 = 39 uH [default]
- + * - 4 = 47 uH
- + * - 5 = 56 uH
- + * - 6 = 68 uH
- + * - 7 = 82 uH
- +*/
- +#define TFA98XX_I2S_SEL_REG_SPKL (0x7<<6)
- +#define TFA98XX_I2S_SEL_REG_SPKL_POS 6
- +#define TFA98XX_I2S_SEL_REG_SPKL_LEN 3
- +#define TFA98XX_I2S_SEL_REG_SPKL_MAX 7
- +#define TFA98XX_I2S_SEL_REG_SPKL_MSK 0x1c0
- +/** @} */
- +
- +/** \addtogroup SPKR
- + * @{
- + */
- +/*!
- + Selection speaker impedance
- + * - 0 = defined by DSP
- + * - 1 = 4 ohm
- + * - 2 = 6 ohm
- + * - 3 = 8 ohm [default]
- +*/
- +#define TFA98XX_I2S_SEL_REG_SPKR (0x3<<9)
- +#define TFA98XX_I2S_SEL_REG_SPKR_POS 9
- +#define TFA98XX_I2S_SEL_REG_SPKR_LEN 2
- +#define TFA98XX_I2S_SEL_REG_SPKR_MAX 3
- +#define TFA98XX_I2S_SEL_REG_SPKR_MSK 0x600
- +/** @} */
- +
- +/** \addtogroup DCFG
- + * @{
- + */
- +/*!
- + DCDC speaker current compensation gain
- + * - 0 = Off [new default]
- + * - 1 = 70%
- + * - 2 = 75%
- + * - 3 = 80%
- + * - 4 = 85%
- + * - 5 = 90%
- + * - 6 = 95%
- + * - 7 = 100% [device default]
- + * - 8 = 105%
- + * - 9 = 110%
- + * - 10 = 115%
- + * - 11 = 120%
- + * - 12 = 125%
- + * - 13 = 130%
- + * - 14 = 135%
- + * - 15 = 140%
- +*/
- +#define TFA98XX_I2S_SEL_REG_DCFG (0xf<<11)
- +#define TFA98XX_I2S_SEL_REG_DCFG_POS 11
- +#define TFA98XX_I2S_SEL_REG_DCFG_LEN 4
- +#define TFA98XX_I2S_SEL_REG_DCFG_MAX 15
- +#define TFA98XX_I2S_SEL_REG_DCFG_MSK 0x7800
- +/** @} */
- +
- +/** \addtogroup 15
- + * @{
- + */
- +/*!
- + DCDC speaker current compensation sign
- + * - 0 = positive [default]
- + * - 1 = negative
- +*/
- +#define TFA98XX_I2S_SEL_REG_15 (0x1<<15)
- +#define TFA98XX_I2S_SEL_REG_15_POS 15
- +#define TFA98XX_I2S_SEL_REG_15_LEN 1
- +#define TFA98XX_I2S_SEL_REG_15_MAX 1
- +#define TFA98XX_I2S_SEL_REG_15_MSK 0x8000
- +/** @} */
- +
- +/** @} */
- +
- +/** mtpkey2_reg Register ($0b) ********************************************/
- +
- +/** \addtogroup _0x0b_mtpkey2_reg
- + * @{
- + */
- +#define TFA98XX_MTPKEY2_REG 0x0b
- +/** \addtogroup MTPK
- + * @{
- + */
- +/*!
- + 5Ah, 90d To access KEY1_Protected registers (=Default for engineering)
- +*/
- +#define TFA98XX_MTPKEY2_REG_MTPK (0xff<<0)
- +#define TFA98XX_MTPKEY2_REG_MTPK_POS 0
- +#define TFA98XX_MTPKEY2_REG_MTPK_LEN 8
- +#define TFA98XX_MTPKEY2_REG_MTPK_MAX 255
- +#define TFA98XX_MTPKEY2_REG_MTPK_MSK 0xff
- +/** @} */
- +
- +/** \addtogroup 8
- + * @{
- + */
- +/*!
- + not used
- +*/
- +#define TFA98XX_MTPKEY2_REG_8 (0xff<<8)
- +#define TFA98XX_MTPKEY2_REG_8_POS 8
- +#define TFA98XX_MTPKEY2_REG_8_LEN 8
- +#define TFA98XX_MTPKEY2_REG_8_MAX 255
- +#define TFA98XX_MTPKEY2_REG_8_MSK 0xff00
- +/** @} */
- +
- +/** @} */
- +
- +/** voltage_sense_config Register ($0c) ********************************************/
- +
- +/** \addtogroup _0x0c_voltage_sense_config
- + * @{
- + */
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG 0x0c
- +/** \addtogroup VSENA
- + * @{
- + */
- +/*!
- + Voltage sense enabling control bit
- + * - 0 = disables the voltage sense measurment
- + * - 1 = enables the voltage sense measurment
- +*/
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSENA (0x1<<0)
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSENA_POS 0
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSENA_LEN 1
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSENA_MAX 1
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSENA_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup VSPWM
- + * @{
- + */
- +/*!
- + Voltage sense PWM source selection control
- + * - 0 = PWM signal from coolflux output
- + * - 1 = PWM signal from analog clipper module
- +*/
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSPWM (0x1<<1)
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSPWM_POS 1
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSPWM_LEN 1
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSPWM_MAX 1
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_VSPWM_MSK 0x2
- +/** @} */
- +
- +/** \addtogroup 2
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_2 (0x3fff<<2)
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_2_POS 2
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_2_LEN 14
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_2_MAX 16383
- +#define TFA98XX_VOLTAGE_SENSE_CONFIG_2_MSK 0xfffc
- +/** @} */
- +
- +/** cgu_clock_sync_reg Register ($0c) **/
- +#define TFA98XX_CGU_CLOCK_SYNC_REG 0x0c
- +#define TFA9890_CGU_CLOCK_SYNC_REG_POR 0x8000
- +/* Delay count for clock synchronisation */
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_0 (0x1fff<<0)
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_0_POS 0
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_0_MAX 8191
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_0_MSK 0x1fff
- +/* not used */
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_13 (0x3<<13)
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_13_POS 13
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_13_MAX 3
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_13_MSK 0x6000
- +/* Enable CGU clock synchronisation */
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_15 (0x1<<15)
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_15_POS 15
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_15_MAX 1
- +#define TFA98XX_CGU_CLOCK_SYNC_REG_15_MSK 0x8000
- +
- +/** adc_sync_reg Register ($0d) **/
- +#define TFA98XX_ADC_SYNC_REG 0x0d
- +#define TFA9890_ADC_SYNC_REG_POR 0x8000
- +/* Delay count for ADC synchronisation */
- +#define TFA98XX_ADC_SYNC_REG_0 (0x1fff<<0)
- +#define TFA98XX_ADC_SYNC_REG_0_POS 0
- +#define TFA98XX_ADC_SYNC_REG_0_MAX 8191
- +#define TFA98XX_ADC_SYNC_REG_0_MSK 0x1fff
- +/* not used */
- +#define TFA98XX_ADC_SYNC_REG_13 (0x3<<13)
- +#define TFA98XX_ADC_SYNC_REG_13_POS 13
- +#define TFA98XX_ADC_SYNC_REG_13_MAX 3
- +#define TFA98XX_ADC_SYNC_REG_13_MSK 0x6000
- +/* Enable ADC synchronisation */
- +#define TFA98XX_ADC_SYNC_REG_15 (0x1<<15)
- +#define TFA98XX_ADC_SYNC_REG_15_POS 15
- +#define TFA98XX_ADC_SYNC_REG_15_MAX 1
- +#define TFA98XX_ADC_SYNC_REG_15_MSK 0x8000
- +
- +/** reserved_1 Register ($0e) **/
- +#define TFA98XX_RESERVED_1 0x0e
- +#define TFA9890_RESERVED_1_POR 0x0f01
- +/* to switch off dcdc reduction with bat prot */
- +#define TFA98XX_RESERVED_1_0 (0x1<<0)
- +#define TFA98XX_RESERVED_1_0_POS 0
- +#define TFA98XX_RESERVED_1_0_MAX 1
- +#define TFA98XX_RESERVED_1_0_MSK 0x1
- +/* test option for frinch caps */
- +#define TFA98XX_RESERVED_1_1 (0x1<<1)
- +#define TFA98XX_RESERVED_1_1_POS 1
- +#define TFA98XX_RESERVED_1_1_MAX 1
- +#define TFA98XX_RESERVED_1_1_MSK 0x2
- +/* for extra connections digital to analog */
- +#define TFA98XX_RESERVED_1_2 (0x1f<<2)
- +#define TFA98XX_RESERVED_1_2_POS 2
- +#define TFA98XX_RESERVED_1_2_MAX 31
- +#define TFA98XX_RESERVED_1_2_MSK 0x7c
- +/* icomp dem switch */
- +#define TFA98XX_RESERVED_1_7 (0x1<<7)
- +#define TFA98XX_RESERVED_1_7_POS 7
- +#define TFA98XX_RESERVED_1_7_MAX 1
- +#define TFA98XX_RESERVED_1_7_MSK 0x80
- +/* */
- +#define TFA98XX_RESERVED_1_8 (0xff<<8)
- +#define TFA98XX_RESERVED_1_8_POS 8
- +#define TFA98XX_RESERVED_1_8_MAX 255
- +#define TFA98XX_RESERVED_1_8_MSK 0xff00
- +
- +
- +/** @} */
- +
- +/** interrupt_reg Register ($0f) ********************************************/
- +
- +/** \addtogroup _0x0f_interrupt_reg
- + * @{
- + */
- +#define TFA98XX_INTERRUPT_REG 0x0f
- +/** \addtogroup VDDD
- + * @{
- + */
- +/*!
- + mask flag_por for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA98XX_INTERRUPT_REG_VDDD (0x1<<0)
- +#define TFA98XX_INTERRUPT_REG_VDDD_POS 0
- +#define TFA98XX_INTERRUPT_REG_VDDD_LEN 1
- +#define TFA98XX_INTERRUPT_REG_VDDD_MAX 1
- +#define TFA98XX_INTERRUPT_REG_VDDD_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup OTDD
- + * @{
- + */
- +/*!
- + mask flag_otpok for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA98XX_INTERRUPT_REG_OTDD (0x1<<1)
- +#define TFA98XX_INTERRUPT_REG_OTDD_POS 1
- +#define TFA98XX_INTERRUPT_REG_OTDD_LEN 1
- +#define TFA98XX_INTERRUPT_REG_OTDD_MAX 1
- +#define TFA98XX_INTERRUPT_REG_OTDD_MSK 0x2
- +/** @} */
- +
- +/** \addtogroup OVDD
- + * @{
- + */
- +/*!
- + mask flag_ovpok for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA9890_INTERRUPT_REG_OVDD (0x1<<2)
- +#define TFA9890_INTERRUPT_REG_OVDD_POS 2
- +#define TFA9890_INTERRUPT_REG_OVDD_LEN 1
- +#define TFA9890_INTERRUPT_REG_OVDD_MAX 1
- +#define TFA9890_INTERRUPT_REG_OVDD_MSK 0x4
- +/** @} */
- +
- +/** \addtogroup UVDD
- + * @{
- + */
- +/*!
- + mask flag_uvpok for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA9890_INTERRUPT_REG_UVDD (0x1<<3)
- +#define TFA9890_INTERRUPT_REG_UVDD_POS 3
- +#define TFA9890_INTERRUPT_REG_UVDD_LEN 1
- +#define TFA9890_INTERRUPT_REG_UVDD_MAX 1
- +#define TFA9890_INTERRUPT_REG_UVDD_MSK 0x8
- +/** @} */
- +
- +/** \addtogroup OCDD
- + * @{
- + */
- +/*!
- + mask flag_ocp_alarm for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA9890_INTERRUPT_REG_OCDD (0x1<<4)
- +#define TFA9890_INTERRUPT_REG_OCDD_POS 4
- +#define TFA9890_INTERRUPT_REG_OCDD_LEN 1
- +#define TFA9890_INTERRUPT_REG_OCDD_MAX 1
- +#define TFA9890_INTERRUPT_REG_OCDD_MSK 0x10
- +/** @} */
- +
- +/** \addtogroup CLKD
- + * @{
- + */
- +/*!
- + mask flag_clocks_stable for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA9890_INTERRUPT_REG_CLKD (0x1<<5)
- +#define TFA9890_INTERRUPT_REG_CLKD_POS 5
- +#define TFA9890_INTERRUPT_REG_CLKD_LEN 1
- +#define TFA9890_INTERRUPT_REG_CLKD_MAX 1
- +#define TFA9890_INTERRUPT_REG_CLKD_MSK 0x20
- +/** @} */
- +
- +/** \addtogroup DCCD
- + * @{
- + */
- +/*!
- + mask flag_pwrokbst for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA9890_INTERRUPT_REG_DCCD (0x1<<6)
- +#define TFA9890_INTERRUPT_REG_DCCD_POS 6
- +#define TFA9890_INTERRUPT_REG_DCCD_LEN 1
- +#define TFA9890_INTERRUPT_REG_DCCD_MAX 1
- +#define TFA9890_INTERRUPT_REG_DCCD_MSK 0x40
- +/** @} */
- +
- +/** \addtogroup SPKD
- + * @{
- + */
- +/*!
- + mask flag_cf_speakererror for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA9890_INTERRUPT_REG_SPKD (0x1<<7)
- +#define TFA9890_INTERRUPT_REG_SPKD_POS 7
- +#define TFA9890_INTERRUPT_REG_SPKD_LEN 1
- +#define TFA9890_INTERRUPT_REG_SPKD_MAX 1
- +#define TFA9890_INTERRUPT_REG_SPKD_MSK 0x80
- +/** @} */
- +
- +/** \addtogroup WDD
- + * @{
- + */
- +/*!
- + mask flag_watchdog_reset for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA9890_INTERRUPT_REG_WDD (0x1<<8)
- +#define TFA9890_INTERRUPT_REG_WDD_POS 8
- +#define TFA9890_INTERRUPT_REG_WDD_LEN 1
- +#define TFA9890_INTERRUPT_REG_WDD_MAX 1
- +#define TFA9890_INTERRUPT_REG_WDD_MSK 0x100
- +/** @} */
- +
- +/** \addtogroup LCLK
- + * @{
- + */
- +/*!
- + mask flag_lost_clk for interupt generation
- + * - 0 = enable interrupt
- + * - 1 = mask interrupt
- +*/
- +#define TFA9890_INTERRUPT_REG_LCLK (0x1<<9)
- +#define TFA9890_INTERRUPT_REG_LCLK_POS 9
- +#define TFA9890_INTERRUPT_REG_LCLK_LEN 1
- +#define TFA9890_INTERRUPT_REG_LCLK_MAX 1
- +#define TFA9890_INTERRUPT_REG_LCLK_MSK 0x200
- +/** @} */
- +
- +/** \addtogroup 10
- + * @{
- + */
- +/*!
- + Reserved
- +*/
- +#define TFA9890_INTERRUPT_REG_10 (0xf<<10)
- +#define TFA9890_INTERRUPT_REG_10_POS 10
- +#define TFA9890_INTERRUPT_REG_10_LEN 4
- +#define TFA9890_INTERRUPT_REG_10_MAX 15
- +#define TFA9890_INTERRUPT_REG_10_MSK 0x3c00
- +/** @} */
- +
- +/** \addtogroup INT
- + * @{
- + */
- +/*!
- + enabling interrupt
- + * - 0 = interrupt disabled
- + * - 1 = interrupt enabled
- +*/
- +#define TFA9890_INTERRUPT_REG_INT (0x1<<14)
- +#define TFA9890_INTERRUPT_REG_INT_POS 14
- +#define TFA9890_INTERRUPT_REG_INT_LEN 1
- +#define TFA9890_INTERRUPT_REG_INT_MAX 1
- +#define TFA9890_INTERRUPT_REG_INT_MSK 0x4000
- +/** @} */
- +
- +/** \addtogroup INTP
- + * @{
- + */
- +/*!
- + Setting polarity interupt
- + * - 0 = interrupt active low
- + * - 1 = interrupt active high
- +*/
- +#define TFA9890_INTERRUPT_REG_INTP (0x1<<15)
- +#define TFA9890_INTERRUPT_REG_INTP_POS 15
- +#define TFA9890_INTERRUPT_REG_INTP_LEN 1
- +#define TFA9890_INTERRUPT_REG_INTP_MAX 1
- +#define TFA9890_INTERRUPT_REG_INTP_MSK 0x8000
- +/** @} */
- +
- +/** @} */
- +
- +/** pwm_mute_set Register ($41) ********************************************/
- +
- +/** \addtogroup _0x41_pwm_mute_set_TFA9887
- + * @{
- + */
- +#define TFA9887_PWM_MUTE_SET 0x41
- +/** \addtogroup 0
- + * @{
- + */
- +/*!
- + bypass_hp, to bypass the hp filter byhind the CoolFlux
- +*/
- +#define TFA9887_PWM_MUTE_SET_0 (0x1<<0)
- +#define TFA9887_PWM_MUTE_SET_0_POS 0
- +#define TFA9887_PWM_MUTE_SET_0_LEN 1
- +#define TFA9887_PWM_MUTE_SET_0_MAX 1
- +#define TFA9887_PWM_MUTE_SET_0_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup 1
- + * @{
- + */
- +/*!
- + hard mute setting in HW
- + * - 0=no mute
- + * - 1=hard-muted
- +*/
- +#define TFA9887_PWM_MUTE_SET_1 (0x1<<1)
- +#define TFA9887_PWM_MUTE_SET_1_POS 1
- +#define TFA9887_PWM_MUTE_SET_1_LEN 1
- +#define TFA9887_PWM_MUTE_SET_1_MAX 1
- +#define TFA9887_PWM_MUTE_SET_1_MSK 0x2
- +/** @} */
- +
- +/** \addtogroup 2
- + * @{
- + */
- +/*!
- + Soft mute setting in HW
- + * - 0=no mute
- + * - 1=soft-muted
- +*/
- +#define TFA9887_PWM_MUTE_SET_2 (0x1<<2)
- +#define TFA9887_PWM_MUTE_SET_2_POS 2
- +#define TFA9887_PWM_MUTE_SET_2_LEN 1
- +#define TFA9887_PWM_MUTE_SET_2_MAX 1
- +#define TFA9887_PWM_MUTE_SET_2_MSK 0x4
- +/** @} */
- +
- +/** \addtogroup PWMDEL
- + * @{
- + */
- +/*!
- + PWM DelayBits to set the delay
- +*/
- +#define TFA9887_PWM_MUTE_SET_PWMDEL (0x1f<<3)
- +#define TFA9887_PWM_MUTE_SET_PWMDEL_POS 3
- +#define TFA9887_PWM_MUTE_SET_PWMDEL_LEN 5
- +#define TFA9887_PWM_MUTE_SET_PWMDEL_MAX 31
- +#define TFA9887_PWM_MUTE_SET_PWMDEL_MSK 0xf8
- +/** @} */
- +
- +/** \addtogroup PWMSH
- + * @{
- + */
- +/*!
- + PWM Shape
- + * - 0=Single sided
- + * - 1=Double sided
- +*/
- +#define TFA9887_PWM_MUTE_SET_PWMSH (0x1<<8)
- +#define TFA9887_PWM_MUTE_SET_PWMSH_POS 8
- +#define TFA9887_PWM_MUTE_SET_PWMSH_LEN 1
- +#define TFA9887_PWM_MUTE_SET_PWMSH_MAX 1
- +#define TFA9887_PWM_MUTE_SET_PWMSH_MSK 0x100
- +/** @} */
- +
- +/** \addtogroup PWMRE
- + * @{
- + */
- +/*!
- + PWM Bitlength in noise shaper
- + * - 0=7 bits
- + * - 1=8 bits
- +*/
- +#define TFA9887_PWM_MUTE_SET_PWMRE (0x1<<9)
- +#define TFA9887_PWM_MUTE_SET_PWMRE_POS 9
- +#define TFA9887_PWM_MUTE_SET_PWMRE_LEN 1
- +#define TFA9887_PWM_MUTE_SET_PWMRE_MAX 1
- +#define TFA9887_PWM_MUTE_SET_PWMRE_MSK 0x200
- +/** @} */
- +
- +/** @} */
- +
- +/** currentsense3 Register ($48) ********************************************/
- +
- +/** \addtogroup _0x48_currentsense3_TFA9887
- + * @{
- + */
- +#define TFA9887_CURRENTSENSE3 0x48
- +/** \addtogroup 0
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA9887_CURRENTSENSE3_0 (0x1<<0)
- +#define TFA9887_CURRENTSENSE3_0_POS 0
- +#define TFA9887_CURRENTSENSE3_0_LEN 1
- +#define TFA9887_CURRENTSENSE3_0_MAX 1
- +#define TFA9887_CURRENTSENSE3_0_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup 1
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA9887_CURRENTSENSE3_1 (0x1<<1)
- +#define TFA9887_CURRENTSENSE3_1_POS 1
- +#define TFA9887_CURRENTSENSE3_1_LEN 1
- +#define TFA9887_CURRENTSENSE3_1_MAX 1
- +#define TFA9887_CURRENTSENSE3_1_MSK 0x2
- +/** @} */
- +
- +/** \addtogroup 2
- + * @{
- + */
- +/*!
- + HIGH => Prevent dcdc switching during clk_cs_clksh
- + * - LOW => Allow switch of dcdc during clk_cs_clksh
- +*/
- +#define TFA9887_CURRENTSENSE3_2 (0x1<<2)
- +#define TFA9887_CURRENTSENSE3_2_POS 2
- +#define TFA9887_CURRENTSENSE3_2_LEN 1
- +#define TFA9887_CURRENTSENSE3_2_MAX 1
- +#define TFA9887_CURRENTSENSE3_2_MSK 0x4
- +/** @} */
- +
- +/** \addtogroup 7
- + * @{
- + */
- +/*!
- + delayshiftse2
- +*/
- +#define TFA9887_CURRENTSENSE3_7 (0x7f<<7)
- +#define TFA9887_CURRENTSENSE3_7_POS 7
- +#define TFA9887_CURRENTSENSE3_7_LEN 7
- +#define TFA9887_CURRENTSENSE3_7_MAX 127
- +#define TFA9887_CURRENTSENSE3_7_MSK 0x3f80
- +/** @} */
- +
- +/** \addtogroup TCC
- + * @{
- + */
- +/*!
- + sample & hold track time:
- + * - 00 = 2 clock cycles
- + * - 01 = 4 clock cycles
- + * - 10 = 8 clock cycles
- + * - 11 = is no fixed time, but as N1B
- +*/
- +#define TFA9887_CURRENTSENSE3_TCC (0x1f<<1)
- +#define TFA9887_CURRENTSENSE3_TCC_POS 1
- +#define TFA9887_CURRENTSENSE3_TCC_LEN 5
- +#define TFA9887_CURRENTSENSE3_TCC_MAX 31
- +#define TFA9887_CURRENTSENSE3_TCC_MSK 0x3e
- +/** @} */
- +
- +/** @} */
- +
- +/** CurrentSense4 Register ($49) ********************************************/
- +
- +/** \addtogroup _0x49_CurrentSense4
- + * @{
- + */
- +#define TFA98XX_CURRENTSENSE4 0x49
- +/** \addtogroup CLIP
- + * @{
- + */
- +/*!
- + Bypass clip control
- + * - 0 = clip control enabled
- + * - 1 = clip control bypassed
- +*/
- +#define TFA989X_CURRENTSENSE4_CLIP (0x1<<0)
- +#define TFA989X_CURRENTSENSE4_CLIP_POS 0
- +#define TFA989X_CURRENTSENSE4_CLIP_LEN 1
- +#define TFA989X_CURRENTSENSE4_CLIP_MAX 1
- +#define TFA989X_CURRENTSENSE4_CLIP_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup 1
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA98XX_CURRENTSENSE4_1 (0x1<<1)
- +#define TFA98XX_CURRENTSENSE4_1_POS 1
- +#define TFA98XX_CURRENTSENSE4_1_LEN 1
- +#define TFA98XX_CURRENTSENSE4_1_MAX 1
- +#define TFA98XX_CURRENTSENSE4_1_MSK 0x2
- +/** @} */
- +
- +/** \addtogroup 2
- + * @{
- + */
- +/*!
- + to disable clock gating in the coolflux
- +*/
- +#define TFA9897_CURRENTSENSE4_2 (0x1<<2)
- +#define TFA9897_CURRENTSENSE4_2_POS 2
- +#define TFA9897_CURRENTSENSE4_2_LEN 1
- +#define TFA9897_CURRENTSENSE4_2_MAX 1
- +#define TFA9897_CURRENTSENSE4_2_MSK 0x4
- +/** @} */
- +
- +/** \addtogroup 3
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA98XX_CURRENTSENSE4_3 (0x1<<3)
- +#define TFA98XX_CURRENTSENSE4_3_POS 3
- +#define TFA98XX_CURRENTSENSE4_3_LEN 1
- +#define TFA98XX_CURRENTSENSE4_3_MAX 1
- +#define TFA98XX_CURRENTSENSE4_3_MSK 0x8
- +/** @} */
- +
- +/** \addtogroup 4
- + * @{
- + */
- +/*!
- + clock switch for battery protection clipper, it switches back to old frequency
- +*/
- +#define TFA9897_CURRENTSENSE4_4 (0x1<<4)
- +#define TFA9897_CURRENTSENSE4_4_POS 4
- +#define TFA9897_CURRENTSENSE4_4_LEN 1
- +#define TFA9897_CURRENTSENSE4_4_MAX 1
- +#define TFA9897_CURRENTSENSE4_4_MSK 0x10
- +/** @} */
- +
- +/** \addtogroup 5
- + * @{
- + */
- +/*!
- + 8 ohm mode for current sense (gain mode)
- + * - 0 = 4 ohm (default)
- + * - 1 = 8 ohm
- +*/
- +#define TFA9897_CURRENTSENSE4_5 (0x1<<5)
- +#define TFA9897_CURRENTSENSE4_5_POS 5
- +#define TFA9897_CURRENTSENSE4_5_LEN 1
- +#define TFA9897_CURRENTSENSE4_5_MAX 1
- +#define TFA9897_CURRENTSENSE4_5_MSK 0x20
- +/** @} */
- +
- +/** \addtogroup 6
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA98XX_CURRENTSENSE4_6 (0x1<<6)
- +#define TFA98XX_CURRENTSENSE4_6_POS 6
- +#define TFA98XX_CURRENTSENSE4_6_LEN 1
- +#define TFA98XX_CURRENTSENSE4_6_MAX 1
- +#define TFA98XX_CURRENTSENSE4_6_MSK 0x40
- +/** @} */
- +
- +/** \addtogroup 7
- + * @{
- + */
- +/*!
- + delay_sh, tunes S7H delay
- +*/
- +#define TFA9897_CURRENTSENSE4_7 (0x1f<<7)
- +#define TFA9897_CURRENTSENSE4_7_POS 7
- +#define TFA9897_CURRENTSENSE4_7_LEN 5
- +#define TFA9897_CURRENTSENSE4_7_MAX 31
- +#define TFA9897_CURRENTSENSE4_7_MSK 0xf80
- +/** @} */
- +
- +/** \addtogroup 12
- + * @{
- + */
- +/*!
- + Invert the sample/hold clock for current sense ADC
- +*/
- +#define TFA9897_CURRENTSENSE4_12 (0x1<<12)
- +#define TFA9897_CURRENTSENSE4_12_POS 12
- +#define TFA9897_CURRENTSENSE4_12_LEN 1
- +#define TFA9897_CURRENTSENSE4_12_MAX 1
- +#define TFA9897_CURRENTSENSE4_12_MSK 0x1000
- +/** @} */
- +
- +/** \addtogroup 13
- + * @{
- + */
- +/*!
- + Invert neg signal
- +*/
- +#define TFA9897_CURRENTSENSE4_13 (0x1<<13)
- +#define TFA9897_CURRENTSENSE4_13_POS 13
- +#define TFA9897_CURRENTSENSE4_13_LEN 1
- +#define TFA9897_CURRENTSENSE4_13_MAX 1
- +#define TFA9897_CURRENTSENSE4_13_MSK 0x2000
- +/** @} */
- +
- +/** \addtogroup 14
- + * @{
- + */
- +/*!
- + Invert se signal
- +*/
- +#define TFA9897_CURRENTSENSE4_14 (0x1<<14)
- +#define TFA9897_CURRENTSENSE4_14_POS 14
- +#define TFA9897_CURRENTSENSE4_14_LEN 1
- +#define TFA9897_CURRENTSENSE4_14_MAX 1
- +#define TFA9897_CURRENTSENSE4_14_MSK 0x4000
- +/** @} */
- +
- +/** \addtogroup 15
- + * @{
- + */
- +/*!
- + switches between Single Ende and differentail mode; 1 = single ended
- +*/
- +#define TFA9897_CURRENTSENSE4_15 (0x1<<15)
- +#define TFA9897_CURRENTSENSE4_15_POS 15
- +#define TFA9897_CURRENTSENSE4_15_LEN 1
- +#define TFA9897_CURRENTSENSE4_15_MAX 1
- +#define TFA9897_CURRENTSENSE4_15_MSK 0x8000
- +/** @} */
- +
- +/** @} */
- +
- +/** mtp_ctrl_reg3 Register ($62) ********************************************/
- +
- +/** \addtogroup _0x62_mtp_ctrl_reg3
- + * @{
- + */
- +#define TFA98XX_MTP_CTRL_REG3 0x62
- +/** \addtogroup 4
- + * @{
- + */
- +/*!
- + not used
- +*/
- +#define TFA98XX_MTP_CTRL_REG3_4 (0x3<<4)
- +#define TFA98XX_MTP_CTRL_REG3_4_POS 4
- +#define TFA98XX_MTP_CTRL_REG3_4_LEN 2
- +#define TFA98XX_MTP_CTRL_REG3_4_MAX 3
- +#define TFA98XX_MTP_CTRL_REG3_4_MSK 0x30
- +/** @} */
- +
- +/** \addtogroup CIMTP
- + * @{
- + */
- +/*!
- + start copying all the data from i2cregs_mtp to mtp [Key 2 protected]
- +*/
- +#define TFA98XX_MTP_CTRL_REG3_CIMTP (0x1<<11)
- +#define TFA98XX_MTP_CTRL_REG3_CIMTP_POS 11
- +#define TFA98XX_MTP_CTRL_REG3_CIMTP_LEN 1
- +#define TFA98XX_MTP_CTRL_REG3_CIMTP_MAX 1
- +#define TFA98XX_MTP_CTRL_REG3_CIMTP_MSK 0x800
- +/** @} */
- +
- +/** \addtogroup 12
- + * @{
- + */
- +/*!
- + not used
- +*/
- +#define TFA98XX_MTP_CTRL_REG3_12 (0x1<<12)
- +#define TFA98XX_MTP_CTRL_REG3_12_POS 12
- +#define TFA98XX_MTP_CTRL_REG3_12_LEN 1
- +#define TFA98XX_MTP_CTRL_REG3_12_MAX 1
- +#define TFA98XX_MTP_CTRL_REG3_12_MSK 0x1000
- +/** @} */
- +
- +/** @} */
- +
- +/** cf_controls Register ($70) ********************************************/
- +
- +/** \addtogroup _0x70_cf_controls
- + * @{
- + */
- +#define TFA98XX_CF_CONTROLS 0x70
- +/** \addtogroup RST
- + * @{
- + */
- +/*!
- + Reset CoolFlux DSP
- + * - 0 = Reset not active [default]
- + * - 1 = Reset active
- +*/
- +#define TFA98XX_CF_CONTROLS_RST (0x1<<0)
- +#define TFA98XX_CF_CONTROLS_RST_POS 0
- +#define TFA98XX_CF_CONTROLS_RST_LEN 1
- +#define TFA98XX_CF_CONTROLS_RST_MAX 1
- +#define TFA98XX_CF_CONTROLS_RST_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup DMEM
- + * @{
- + */
- +/*!
- + Target memory for access
- + * - 0 = pmem [default]
- + * - 1 = xmem
- + * - 2 = ymem
- + * - 3 = iomem
- +*/
- +#define TFA98XX_CF_CONTROLS_DMEM (0x3<<1)
- +#define TFA98XX_CF_CONTROLS_DMEM_POS 1
- +#define TFA98XX_CF_CONTROLS_DMEM_LEN 2
- +#define TFA98XX_CF_CONTROLS_DMEM_MAX 3
- +#define TFA98XX_CF_CONTROLS_DMEM_MSK 0x6
- +/** @} */
- +
- +/** \addtogroup AIF
- + * @{
- + */
- +/*!
- + Autoincrement-flag for memory-address
- + * - 0 = Autoincrement ON [default]
- + * - 1 = Autoincrement OFF
- +*/
- +#define TFA98XX_CF_CONTROLS_AIF (0x1<<3)
- +#define TFA98XX_CF_CONTROLS_AIF_POS 3
- +#define TFA98XX_CF_CONTROLS_AIF_LEN 1
- +#define TFA98XX_CF_CONTROLS_AIF_MAX 1
- +#define TFA98XX_CF_CONTROLS_AIF_MSK 0x8
- +/** @} */
- +
- +/** \addtogroup CFINT
- + * @{
- + */
- +/*!
- + Interrupt CoolFlux DSP
- +*/
- +#define TFA98XX_CF_CONTROLS_CFINT (0x1<<4)
- +#define TFA98XX_CF_CONTROLS_CFINT_POS 4
- +#define TFA98XX_CF_CONTROLS_CFINT_LEN 1
- +#define TFA98XX_CF_CONTROLS_CFINT_MAX 1
- +#define TFA98XX_CF_CONTROLS_CFINT_MSK 0x10
- +/** @} */
- +
- +/** \addtogroup 5
- + * @{
- + */
- +/*!
- + not used
- +*/
- +#define TFA98XX_CF_CONTROLS_5 (0x7<<5)
- +#define TFA98XX_CF_CONTROLS_5_POS 5
- +#define TFA98XX_CF_CONTROLS_5_LEN 3
- +#define TFA98XX_CF_CONTROLS_5_MAX 7
- +#define TFA98XX_CF_CONTROLS_5_MSK 0xe0
- +/** @} */
- +
- +/** \addtogroup REQ
- + * @{
- + */
- +/*!
- + request for access (8 channels)
- +*/
- +#define TFA98XX_CF_CONTROLS_REQ (0xff<<8)
- +#define TFA98XX_CF_CONTROLS_REQ_POS 8
- +#define TFA98XX_CF_CONTROLS_REQ_LEN 8
- +#define TFA98XX_CF_CONTROLS_REQ_MAX 255
- +#define TFA98XX_CF_CONTROLS_REQ_MSK 0xff00
- +/** @} */
- +
- +/** @} */
- +
- +/** cf_mad Register ($71) ********************************************/
- +
- +/** \addtogroup _0x71_cf_mad
- + * @{
- + */
- +#define TFA98XX_CF_MAD 0x71
- +/** \addtogroup MADD
- + * @{
- + */
- +/*!
- + memory-address to be accessed
- +*/
- +#define TFA98XX_CF_MAD_MADD (0xffff<<0)
- +#define TFA98XX_CF_MAD_MADD_POS 0
- +#define TFA98XX_CF_MAD_MADD_LEN 16
- +#define TFA98XX_CF_MAD_MADD_MAX 65535
- +#define TFA98XX_CF_MAD_MADD_MSK 0xffff
- +/** @} */
- +
- +/** @} */
- +
- +/** cf_mem Register ($72) ********************************************/
- +
- +/** \addtogroup _0x72_cf_mem
- + * @{
- + */
- +#define TFA98XX_CF_MEM 0x72
- +/** \addtogroup MEMA
- + * @{
- + */
- +/*!
- + activate memory access (24- or 32-bits data is written/read to/from memory
- +*/
- +#define TFA98XX_CF_MEM_MEMA (0xffff<<0)
- +#define TFA98XX_CF_MEM_MEMA_POS 0
- +#define TFA98XX_CF_MEM_MEMA_LEN 16
- +#define TFA98XX_CF_MEM_MEMA_MAX 65535
- +#define TFA98XX_CF_MEM_MEMA_MSK 0xffff
- +/** @} */
- +
- +/** @} */
- +
- +/** cf_status Register ($73) ********************************************/
- +
- +/** \addtogroup _0x73_cf_status
- + * @{
- + */
- +#define TFA98XX_CF_STATUS 0x73
- +/** \addtogroup ERR
- + * @{
- + */
- +/*!
- + Coolflux error flags
- +*/
- +#define TFA98XX_CF_STATUS_ERR (0xff<<0)
- +#define TFA98XX_CF_STATUS_ERR_POS 0
- +#define TFA98XX_CF_STATUS_ERR_LEN 8
- +#define TFA98XX_CF_STATUS_ERR_MAX 255
- +#define TFA98XX_CF_STATUS_ERR_MSK 0xff
- +/** @} */
- +
- +/** \addtogroup ACK
- + * @{
- + */
- +/*!
- + acknowledge of requests (8 channels)
- +*/
- +#define TFA98XX_CF_STATUS_ACK (0xff<<8)
- +#define TFA98XX_CF_STATUS_ACK_POS 8
- +#define TFA98XX_CF_STATUS_ACK_LEN 8
- +#define TFA98XX_CF_STATUS_ACK_MAX 255
- +#define TFA98XX_CF_STATUS_ACK_MSK 0xff00
- +/** @} */
- +
- +/** @} */
- +
- +/** mtp_spkr_cal Register ($80) ********************************************/
- +
- +/** \addtogroup _0x80_mtp_spkr_cal
- + * @{
- + */
- +#define TFA98XX_MTP_SPKR_CAL 0x80
- +#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP 0x80
- +#define TFA9890_KEY2PROTECTED_SPKR_CAL_MTP_POR 0x0000
- +
- +/** \addtogroup MTPOTC
- + * @{
- + */
- +/*!
- + Calibration schedule (key2 protected)
- + * - 0 = Calibrate after each POR [default]
- + * - 1 = One time calibration
- +*/
- +#define TFA98XX_MTP_SPKR_CAL_MTPOTC (0x1<<0)
- +#define TFA98XX_MTP_SPKR_CAL_MTPOTC_POS 0
- +#define TFA98XX_MTP_SPKR_CAL_MTPOTC_LEN 1
- +#define TFA98XX_MTP_SPKR_CAL_MTPOTC_MAX 1
- +#define TFA98XX_MTP_SPKR_CAL_MTPOTC_MSK 0x1
- +/** @} */
- +
- +/** \addtogroup MTPEX
- + * @{
- + */
- +/*!
- + (key2 protected)
- + * - calibration of Ron has been executed.
- +*/
- +#define TFA98XX_MTP_SPKR_CAL_MTPEX (0x1<<1)
- +#define TFA98XX_MTP_SPKR_CAL_MTPEX_POS 1
- +#define TFA98XX_MTP_SPKR_CAL_MTPEX_LEN 1
- +#define TFA98XX_MTP_SPKR_CAL_MTPEX_MAX 1
- +#define TFA98XX_MTP_SPKR_CAL_MTPEX_MSK 0x2
- +/** @} */
- +
- +/** \addtogroup 2
- + * @{
- + */
- +/*!
- +
- +*/
- +#define TFA98XX_MTP_SPKR_CAL_2 (0x3fff<<2)
- +#define TFA98XX_MTP_SPKR_CAL_2_POS 2
- +#define TFA98XX_MTP_SPKR_CAL_2_LEN 14
- +#define TFA98XX_MTP_SPKR_CAL_2_MAX 16383
- +#define TFA98XX_MTP_SPKR_CAL_2_MSK 0xfffc
- +/** @} */
- +
- +/** @} */
- +
- +/** MTPF Register ($8f) ********************************************/
- +
- +/** \addtogroup _0x8f_MTPF_TFA9890
- + * @{
- + */
- +#define TFA9890_MTPF 0x8f
- +/** \addtogroup VERSION
- + * @{
- + */
- +/*!
- + (key1 protected)
- +*/
- +#define TFA9890_MTPF_VERSION (0xffff<<0)
- +#define TFA9890_MTPF_VERSION_POS 0
- +#define TFA9890_MTPF_VERSION_LEN 16
- +#define TFA9890_MTPF_VERSION_MAX 65535
- +#define TFA9890_MTPF_VERSION_MSK 0xffff
- +/** @} */
- +
- +/** @} */
- +
- +#endif /* TFA98XX_GENREGS_H_ */
- diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
- index e72f554..50bedd5 100644
- --- a/sound/soc/soc-cache.c
- +++ b/sound/soc/soc-cache.c
- @@ -280,7 +280,7 @@ static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
- unsigned int reg)
- {
- const struct snd_soc_codec_driver *codec_drv;
- - unsigned int min, max, index;
- + int min, max, index;
- codec_drv = codec->driver;
- min = 0;
- @@ -292,7 +292,7 @@ static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
- if (codec_drv->reg_access_default[index].reg < reg)
- min = index + 1;
- else
- - max = index;
- + max = index - 1;
- } while (min <= max);
- return -1;
- }
- diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
- index 7672e72..279540f 100644
- --- a/sound/soc/soc-core.c
- +++ b/sound/soc/soc-core.c
- @@ -1339,7 +1339,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
- struct snd_soc_platform *platform = rtd->platform;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- - struct snd_soc_dapm_widget *play_w, *capture_w;
- int ret;
- dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n",
- @@ -1420,39 +1419,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
- }
- } else {
- - if (!dai_link->params) {
- - /* create the pcm */
- - ret = soc_new_pcm(rtd, num);
- - if (ret < 0) {
- - dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
- - dai_link->stream_name, ret);
- - return ret;
- - }
- - } else {
- - /* link the DAI widgets */
- - play_w = codec_dai->playback_widget;
- - capture_w = cpu_dai->capture_widget;
- - if (play_w && capture_w) {
- - ret = snd_soc_dapm_new_pcm(card, dai_link->params,
- - capture_w, play_w);
- - if (ret != 0) {
- - dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
- - play_w->name, capture_w->name, ret);
- - return ret;
- - }
- - }
- -
- - play_w = cpu_dai->playback_widget;
- - capture_w = codec_dai->capture_widget;
- - if (play_w && capture_w) {
- - ret = snd_soc_dapm_new_pcm(card, dai_link->params,
- - capture_w, play_w);
- - if (ret != 0) {
- - dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
- - play_w->name, capture_w->name, ret);
- - return ret;
- - }
- - }
- + /* create the pcm */
- + ret = soc_new_pcm(rtd, num);
- + if (ret < 0) {
- + dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
- + dai_link->stream_name, ret);
- + return ret;
- }
- }
- diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
- index 7025d68..880ad9e 100644
- --- a/sound/soc/soc-dapm.c
- +++ b/sound/soc/soc-dapm.c
- @@ -1730,10 +1730,14 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
- trace_snd_soc_dapm_walk_done(card);
- - /* Run all the bias changes in parallel */
- - list_for_each_entry(d, &dapm->card->dapm_list, list)
- - async_schedule_domain(dapm_pre_sequence_async, d,
- - &async_domain);
- + /* Run card bias changes at first */
- + dapm_pre_sequence_async(&card->dapm, 0);
- + /* Run other bias changes in parallel */
- + list_for_each_entry(d, &dapm->card->dapm_list, list) {
- + if (d != &card->dapm)
- + async_schedule_domain(dapm_pre_sequence_async, d,
- + &async_domain);
- + }
- async_synchronize_full_domain(&async_domain);
- /* Power down widgets first; try to avoid amplifying pops. */
- @@ -1744,11 +1748,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
- /* Now power up. */
- dapm_seq_run(dapm, &up_list, event, true);
- - /* Run all the bias changes in parallel */
- - list_for_each_entry(d, &dapm->card->dapm_list, list)
- - async_schedule_domain(dapm_post_sequence_async, d,
- - &async_domain);
- + /* Run other bias changes in parallel */
- + list_for_each_entry(d, &dapm->card->dapm_list, list) {
- + if (d != &card->dapm)
- + async_schedule_domain(dapm_post_sequence_async, d,
- + &async_domain);
- + }
- async_synchronize_full_domain(&async_domain);
- + /* Run card bias changes at last */
- + dapm_post_sequence_async(&card->dapm, 0);
- /* do we need to notify any clients that DAPM event is complete */
- list_for_each_entry(d, &card->dapm_list, list) {
- @@ -3014,7 +3022,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
- * @kcontrol: mixer control
- * @ucontrol: Value
- */
- -int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
- +int snd_soc_dapm_get_pin_switch (struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
- @@ -3212,38 +3220,25 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
- static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
- {
- - struct snd_soc_dapm_path *source_p, *sink_p;
- - struct snd_soc_dai *source, *sink;
- - const struct snd_soc_pcm_stream *config = w->params;
- - struct snd_pcm_substream substream;
- + struct snd_soc_dapm_path *source_p;
- + struct snd_soc_dai *source;
- + struct snd_soc_pcm_runtime *rtd = w->rtd;
- + const struct snd_soc_pcm_stream *config = rtd->dai_link->params;
- + struct snd_pcm_substream *substream = w->priv;
- struct snd_pcm_hw_params *params = NULL;
- - u64 fmt;
- - int ret;
- + int ret = 0;
- BUG_ON(!config);
- - BUG_ON(list_empty(&w->sources) || list_empty(&w->sinks));
- + BUG_ON(list_empty(&w->sources));
- - /* We only support a single source and sink, pick the first */
- + /* We only support a single source, pick the first */
- source_p = list_first_entry(&w->sources, struct snd_soc_dapm_path,
- list_sink);
- - sink_p = list_first_entry(&w->sinks, struct snd_soc_dapm_path,
- - list_source);
- -
- - BUG_ON(!source_p || !sink_p);
- - BUG_ON(!sink_p->source || !source_p->sink);
- - BUG_ON(!source_p->source || !sink_p->sink);
- + BUG_ON(!source_p);
- + BUG_ON(!source_p->sink);
- + BUG_ON(!source_p->source);
- source = source_p->source->priv;
- - sink = sink_p->sink->priv;
- -
- - /* Be a little careful as we don't want to overflow the mask array */
- - if (config->formats) {
- - fmt = ffs(config->formats) - 1;
- - } else {
- - dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n",
- - config->formats);
- - fmt = 0;
- - }
- /* Currently very limited parameter selection */
- params = kzalloc(sizeof(*params), GFP_KERNEL);
- @@ -3251,7 +3246,12 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
- ret = -ENOMEM;
- goto out;
- }
- - snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
- + _snd_pcm_hw_params_any(params);
- +
- + hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT)->bits[0] =
- + config->formats;
- + hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT)->bits[1] =
- + config->formats >> 32;
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min =
- config->rate_min;
- @@ -3263,47 +3263,38 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
- hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max
- = config->channels_max;
- - memset(&substream, 0, sizeof(substream));
- -
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- - if (source->driver->ops && source->driver->ops->hw_params) {
- - substream.stream = SNDRV_PCM_STREAM_CAPTURE;
- - ret = source->driver->ops->hw_params(&substream,
- - params, source);
- - if (ret != 0) {
- - dev_err(source->dev,
- - "ASoC: hw_params() failed: %d\n", ret);
- - goto out;
- - }
- + ret = snd_pcm_open_substream(rtd->pcm,
- + source == rtd->codec_dai, NULL, &substream);
- + if (ret < 0) {
- + dev_err(w->dapm->dev, "ASoC: open() failed: %d\n", ret);
- + goto out;
- }
- + w->priv = substream;
- - if (sink->driver->ops && sink->driver->ops->hw_params) {
- - substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
- - ret = sink->driver->ops->hw_params(&substream, params,
- - sink);
- - if (ret != 0) {
- - dev_err(sink->dev,
- - "ASoC: hw_params() failed: %d\n", ret);
- - goto out;
- - }
- + ret = rtd->ops.hw_params(substream, params);
- + if (ret < 0) {
- + dev_err(w->dapm->dev, "ASoC: hw_params() failed: %d\n", ret);
- + goto out;
- + }
- + ret = rtd->ops.prepare(substream);
- + if (ret < 0) {
- + dev_err(w->dapm->dev, "ASoC: prepare() failed: %d\n", ret);
- + goto out;
- + }
- + ret = rtd->ops.trigger(substream, SNDRV_PCM_TRIGGER_START);
- + if (ret < 0) {
- + dev_err(w->dapm->dev, "ASoC: trigger() failed: %d\n", ret);
- + goto out;
- }
- - break;
- -
- - case SND_SOC_DAPM_POST_PMU:
- - ret = snd_soc_dai_digital_mute(sink, 0,
- - SNDRV_PCM_STREAM_PLAYBACK);
- - if (ret != 0 && ret != -ENOTSUPP)
- - dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret);
- - ret = 0;
- break;
- case SND_SOC_DAPM_PRE_PMD:
- - ret = snd_soc_dai_digital_mute(sink, 1,
- - SNDRV_PCM_STREAM_PLAYBACK);
- - if (ret != 0 && ret != -ENOTSUPP)
- - dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret);
- - ret = 0;
- + if (substream) {
- + snd_pcm_release_substream(substream);
- + w->priv = NULL;
- + }
- break;
- default:
- @@ -3316,51 +3307,67 @@ out:
- return ret;
- }
- -int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
- - const struct snd_soc_pcm_stream *params,
- - struct snd_soc_dapm_widget *source,
- - struct snd_soc_dapm_widget *sink)
- +int snd_soc_dapm_new_dai_link_widgets(struct snd_soc_dapm_context *dapm,
- + struct snd_soc_pcm_runtime *rtd)
- {
- struct snd_soc_dapm_route routes[2];
- struct snd_soc_dapm_widget template;
- + struct snd_soc_dapm_widget *source;
- + struct snd_soc_dapm_widget *sink;
- struct snd_soc_dapm_widget *w;
- size_t len;
- char *link_name;
- + int i, ret = 0;
- - len = strlen(source->name) + strlen(sink->name) + 2;
- - link_name = devm_kzalloc(card->dev, len, GFP_KERNEL);
- - if (!link_name)
- - return -ENOMEM;
- - snprintf(link_name, len, "%s-%s", source->name, sink->name);
- + for (i = 0; i < 2; i++) {
- + if (i == 0) {
- + source = rtd->cpu_dai->capture_widget;
- + sink = rtd->codec_dai->playback_widget;
- + } else {
- + source = rtd->codec_dai->capture_widget;
- + sink = rtd->cpu_dai->playback_widget;
- + }
- - memset(&template, 0, sizeof(template));
- - template.reg = SND_SOC_NOPM;
- - template.id = snd_soc_dapm_dai_link;
- - template.name = link_name;
- - template.event = snd_soc_dai_link_event;
- - template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- - SND_SOC_DAPM_PRE_PMD;
- +len = strlen(source->name) + strlen(sink->name) + 2;
- + link_name = devm_kzalloc(dapm->dev, len, GFP_KERNEL);
- + if (!link_name)
- + return -ENOMEM;
- + snprintf(link_name, len, "%s-%s", source->name, sink->name);
- - dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
- + memset(&template, 0, sizeof(template));
- + template.reg = SND_SOC_NOPM;
- + template.id = snd_soc_dapm_dai_link;
- + template.name = link_name;
- + template.event = snd_soc_dai_link_event;
- + template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD;
- - w = snd_soc_dapm_new_control(&card->dapm, &template);
- - if (!w) {
- - dev_err(card->dev, "ASoC: Failed to create %s widget\n",
- - link_name);
- - return -ENOMEM;
- - }
- + dev_dbg(dapm->dev, "ASoC: adding %s widget\n", link_name);
- - w->params = params;
- + w = snd_soc_dapm_new_control(dapm, &template);
- + if (!w) {
- + dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
- + link_name);
- + return -ENOMEM;
- + }
- +
- + w->rtd = rtd;
- - memset(&routes, 0, sizeof(routes));
- + memset(&routes, 0, sizeof(routes));
- - routes[0].source = source->name;
- - routes[0].sink = link_name;
- - routes[1].source = link_name;
- - routes[1].sink = sink->name;
- + routes[0].source = source->name;
- + routes[0].sink = link_name;
- + routes[1].source = link_name;
- + routes[1].sink = sink->name;
- - return snd_soc_dapm_add_routes(&card->dapm, routes,
- - ARRAY_SIZE(routes));
- + ret = snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
- + if (ret < 0) {
- + dev_err(dapm->dev, "ASoC: Failed to add %s route\n",
- + link_name);
- + return ret;
- + }
- + }
- +
- + return ret;
- }
- int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
- @@ -3451,7 +3458,7 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
- break;
- }
- - if (!w->sname)
- + if (!w->sname || !strstr(w->sname, dai_w->name))
- continue;
- if (dai->driver->playback.stream_name &&
- @@ -3778,7 +3785,7 @@ void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
- }
- EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
- -static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
- +static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm)
- {
- struct snd_soc_card *card = dapm->card;
- struct snd_soc_dapm_widget *w;
- @@ -3818,14 +3825,21 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
- */
- void snd_soc_dapm_shutdown(struct snd_soc_card *card)
- {
- - struct snd_soc_codec *codec;
- + struct snd_soc_dapm_context *dapm;
- - list_for_each_entry(codec, &card->codec_dev_list, card_list) {
- - soc_dapm_shutdown_codec(&codec->dapm);
- - if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
- - snd_soc_dapm_set_bias_level(&codec->dapm,
- - SND_SOC_BIAS_OFF);
- + list_for_each_entry(dapm, &card->dapm_list, list) {
- + if (dapm != &card->dapm) {
- + soc_dapm_shutdown_dapm(dapm);
- + if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
- + snd_soc_dapm_set_bias_level(dapm,
- + SND_SOC_BIAS_OFF);
- + }
- }
- +
- + soc_dapm_shutdown_dapm(&card->dapm);
- + if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY)
- + snd_soc_dapm_set_bias_level(&card->dapm,
- + SND_SOC_BIAS_OFF);
- }
- /* Module information */
- diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
- index 0bb5ccc..8e4a579 100644
- --- a/sound/soc/soc-jack.c
- +++ b/sound/soc/soc-jack.c
- @@ -247,7 +247,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
- report = 0;
- if (gpio->jack_status_check)
- - report = gpio->jack_status_check();
- + report = gpio->jack_status_check(gpio);
- snd_soc_jack_report(jack, report, gpio->report);
- }
- @@ -339,7 +339,8 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
- gpio_export(gpios[i].gpio, false);
- /* Update initial jack status */
- - snd_soc_jack_gpio_detect(&gpios[i]);
- + schedule_delayed_work(&gpios[i].work,
- + msecs_to_jiffies(gpios[i].debounce_time));
- }
- return 0;
- diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
- index 9a93bef..4d75a06 100644
- --- a/sound/soc/soc-pcm.c
- +++ b/sound/soc/soc-pcm.c
- @@ -124,6 +124,21 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
- }
- }
- +static void soc_pcm_reverse_direction_for_cpu_dai(struct snd_pcm_substream *substream)
- +{
- + struct snd_soc_pcm_runtime *rtd = substream->private_data;
- +
- + /* reverse the stream direction if the link has
- + params since cpu dai actually come from codec */
- + if (rtd->dai_link->params) {
- + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- + substream->stream = SNDRV_PCM_STREAM_CAPTURE;
- + else
- + substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
- + }
- +}
- +
- +
- /*
- * Called by ALSA when a PCM substream is opened, the runtime->hw record is
- * then initialized and any private data can be allocated. This also calls
- @@ -148,7 +163,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
- /* startup the audio subsystem */
- if (cpu_dai->driver->ops->startup) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "ASoC: can't open interface"
- " %s: %d\n", cpu_dai->name, ret);
- @@ -306,8 +323,11 @@ codec_dai_err:
- platform->driver->ops->close(substream);
- platform_err:
- - if (cpu_dai->driver->ops->shutdown)
- + if (cpu_dai->driver->ops->shutdown) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- cpu_dai->driver->ops->shutdown(substream, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + }
- out:
- mutex_unlock(&rtd->pcm_mutex);
- @@ -384,9 +404,15 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
- * shutdown, for example from stopping clocks.
- */
- snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + snd_soc_dai_digital_mute(cpu_dai, 1, substream->stream);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- - if (cpu_dai->driver->ops->shutdown)
- + if (cpu_dai->driver->ops->shutdown) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- cpu_dai->driver->ops->shutdown(substream, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + }
- if (codec_dai->driver->ops->shutdown)
- codec_dai->driver->ops->shutdown(substream, codec_dai);
- @@ -398,23 +424,26 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
- platform->driver->ops->close(substream);
- cpu_dai->runtime = NULL;
- - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- - if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
- - rtd->dai_link->ignore_pmdown_time) {
- - /* powered down playback stream now */
- - snd_soc_dapm_stream_event(rtd,
- - SNDRV_PCM_STREAM_PLAYBACK,
- + /* dai with params is skipped to avoid the recursive */
- + if (!rtd->dai_link->params) {
- + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- + if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
- + rtd->dai_link->ignore_pmdown_time) {
- + /* powered down playback stream now */
- + snd_soc_dapm_stream_event(rtd,
- + SNDRV_PCM_STREAM_PLAYBACK,
- + SND_SOC_DAPM_STREAM_STOP);
- + } else {
- + /* capture streams can be powered down now */
- + snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
- SND_SOC_DAPM_STREAM_STOP);
- + }
- } else {
- /* start delayed pop wq here for playback streams */
- rtd->pop_wait = 1;
- schedule_delayed_work(&rtd->delayed_work,
- msecs_to_jiffies(rtd->pmdown_time));
- }
- - } else {
- - /* capture streams can be powered down now */
- - snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
- - SND_SOC_DAPM_STREAM_STOP);
- }
- mutex_unlock(&rtd->pcm_mutex);
- @@ -469,7 +498,9 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
- }
- if (cpu_dai->driver->ops->prepare) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "ASoC: DAI prepare error: %d\n",
- ret);
- @@ -477,16 +508,22 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
- }
- }
- - /* cancel any delayed stream shutdown that is pending */
- - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- - rtd->pop_wait) {
- - rtd->pop_wait = 0;
- - cancel_delayed_work(&rtd->delayed_work);
- - }
- + /* dai with params is skipped to avoid the recursive */
- + if (!rtd->dai_link->params) {
- + /* cancel any delayed stream shutdown that is pending */
- + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
- + rtd->pop_wait) {
- + rtd->pop_wait = 0;
- + cancel_delayed_work(&rtd->delayed_work);
- + }
- - snd_soc_dapm_stream_event(rtd, substream->stream,
- - SND_SOC_DAPM_STREAM_START);
- + snd_soc_dapm_stream_event(rtd, substream->stream,
- + SND_SOC_DAPM_STREAM_START);
- + }
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + snd_soc_dai_digital_mute(cpu_dai, 0, substream->stream);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- snd_soc_dai_digital_mute(codec_dai, 0, substream->stream);
- out:
- @@ -497,7 +534,7 @@ out:
- /*
- * Called by ALSA when the hardware params are set by application. This
- * function can also be called multiple times and can allocate buffers
- - * (using snd_pcm_lib_* ). It's non-atomic.
- + * (using snd_pcm_lib_*). It's non-atomic.
- */
- static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
- @@ -529,7 +566,9 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
- }
- if (cpu_dai->driver->ops->hw_params) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "ASoC: %s hw params failed: %d\n",
- cpu_dai->name, ret);
- @@ -555,8 +594,11 @@ out:
- return ret;
- platform_err:
- - if (cpu_dai->driver->ops->hw_free)
- + if (cpu_dai->driver->ops->hw_free) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- cpu_dai->driver->ops->hw_free(substream, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + }
- interface_err:
- if (codec_dai->driver->ops->hw_free)
- @@ -584,8 +626,12 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
- mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- /* apply codec digital mute */
- - if (!codec->active)
- + if (!codec->active) {
- snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + snd_soc_dai_digital_mute(cpu_dai, 1, substream->stream);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + }
- /* free any machine hw params */
- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
- @@ -599,8 +645,11 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
- if (codec_dai->driver->ops->hw_free)
- codec_dai->driver->ops->hw_free(substream, codec_dai);
- - if (cpu_dai->driver->ops->hw_free)
- + if (cpu_dai->driver->ops->hw_free) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- cpu_dai->driver->ops->hw_free(substream, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + }
- mutex_unlock(&rtd->pcm_mutex);
- return 0;
- @@ -627,7 +676,9 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
- }
- if (cpu_dai->driver->ops->trigger) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- if (ret < 0)
- return ret;
- }
- @@ -656,7 +707,9 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
- }
- if (cpu_dai->driver->ops->bespoke_trigger) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- ret = cpu_dai->driver->ops->bespoke_trigger(substream, cmd, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- if (ret < 0)
- return ret;
- }
- @@ -680,8 +733,11 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
- if (platform->driver->ops && platform->driver->ops->pointer)
- offset = platform->driver->ops->pointer(substream);
- - if (cpu_dai->driver->ops->delay)
- + if (cpu_dai->driver->ops->delay) {
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
- + soc_pcm_reverse_direction_for_cpu_dai(substream);
- + }
- if (codec_dai->driver->ops->delay)
- delay += codec_dai->driver->ops->delay(substream, codec_dai);
- @@ -2037,8 +2093,13 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
- snprintf(new_name, sizeof(new_name), "%s %s-%d",
- rtd->dai_link->stream_name, codec_dai->name, num);
- - ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
- - capture, &pcm);
- + /* dai with params can only be used by kernel */
- + if (rtd->dai_link->params)
- + ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
- + playback, capture, &pcm);
- + else
- + ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
- + capture, &pcm);
- }
- if (ret < 0) {
- dev_err(rtd->card->dev, "ASoC: can't create pcm for %s\n",
- @@ -2107,6 +2168,16 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
- }
- pcm->private_free = platform->driver->pcm_free;
- +
- + if (rtd->dai_link->params) {
- + ret = snd_soc_dapm_new_dai_link_widgets(&rtd->card->dapm, rtd);
- + if (ret < 0) {
- + dev_err(rtd->card->dev, "ASoC: Can't link %s: %d\n",
- + rtd->dai_link->name, ret);
- + return ret;
- + }
- + }
- +
- out:
- dev_info(rtd->card->dev, " %s <-> %s mapping ok\n", codec_dai->name,
- cpu_dai->name);
- diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
- index 6484c80..d0bc81d 100644
- --- a/sound/soc/tegra/Kconfig
- +++ b/sound/soc/tegra/Kconfig
- @@ -319,6 +319,19 @@ config SND_SOC_TEGRA_RT5645
- Say Y or M here if you want to add support for SoC audio on Tegra
- boards using the ALC5645 codec. Currently, the supported boards
- are Ardbeg.
- +
- +config SND_SOC_TEGRA_RT5671
- + tristate "SoC Audio support for Tegra boards using a ALC5671 codec"
- + depends on SND_SOC_TEGRA && I2C && TEGRA_DC
- + select SND_SOC_TEGRA30_I2S if !ARCH_TEGRA_2x_SOC
- + select SND_SOC_TEGRA30_SPDIF if !ARCH_TEGRA_2x_SOC
- + select SND_SOC_TFA98XX
- + select SND_SOC_RT5671
- + select SND_SOC_SPDIF
- + select SND_SOC_TEGRA30_DAM if !ARCH_TEGRA_2x_SOC
- + help
- + Say Y or M here if you want to add support for SoC audio on Tegra
- + boards using the ALC5671 codec.
- config SND_SOC_TEGRA_MAX98095
- tristate "SoC Audio support for Tegra boards using a MAX98095 codec"
- diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
- index 0434fa1..7aac85f 100644
- --- a/sound/soc/tegra/Makefile
- +++ b/sound/soc/tegra/Makefile
- @@ -40,6 +40,7 @@ snd-soc-tegra-aic325x-objs := tegra_aic325x.o
- snd-soc-tegra-rt5640-objs := tegra_rt5640.o
- snd-soc-tegra-rt5645-objs := tegra_rt5645.o
- snd-soc-tegra-rt5639-objs := tegra_rt5639.o
- +snd-soc-tegra-rt5671-objs := tegra_rt5671.o
- snd-soc-tegra-max98095-objs := tegra_max98095.o
- snd-soc-tegra-vcm-objs := tegra_vcm.o
- snd-soc-tegra-cs42l73-objs := tegra_cs42l73.o
- @@ -57,6 +58,7 @@ obj-$(CONFIG_SND_SOC_TEGRA_TLV320AIC325X) += snd-soc-tegra-aic325x.o
- obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o
- obj-$(CONFIG_SND_SOC_TEGRA_RT5645) += snd-soc-tegra-rt5645.o
- obj-$(CONFIG_SND_SOC_TEGRA_RT5639) += snd-soc-tegra-rt5639.o
- +obj-$(CONFIG_SND_SOC_TEGRA_RT5671) += snd-soc-tegra-rt5671.o
- obj-$(CONFIG_SND_SOC_TEGRA_MAX98095) += snd-soc-tegra-max98095.o
- obj-$(CONFIG_SND_SOC_TEGRA_P1852) += snd-soc-tegra-vcm.o
- obj-$(CONFIG_SND_SOC_TEGRA_E1853) += snd-soc-tegra-vcm.o
- diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
- index a9f3370..813d472 100644
- --- a/sound/soc/tegra/tegra_asoc_utils.c
- +++ b/sound/soc/tegra/tegra_asoc_utils.c
- @@ -467,12 +467,27 @@ EXPORT_SYMBOL_GPL(tegra_asoc_utils_lock_clk_rate);
- int tegra_asoc_utils_clk_enable(struct tegra_asoc_utils_data *data)
- {
- int err;
- -
- +
- + err = clk_prepare_enable(data->clk_audio_emc);
- + if (err) {
- + dev_err(data->dev, "Can't enable emc: %d\n", err);
- + return err;
- + }
- err = clk_prepare_enable(data->clk_cdev1);
- if (err) {
- dev_err(data->dev, "Can't enable cdev1: %d\n", err);
- + clk_disable_unprepare(data->clk_audio_emc);
- return err;
- }
- + if (!IS_ERR(data->clk_out1)) {
- + err = clk_prepare_enable(data->clk_out1);
- + if (err) {
- + dev_err(data->dev, "Can't enable clk out1: %d\n", err);
- + clk_disable_unprepare(data->clk_cdev1);
- + clk_disable_unprepare(data->clk_audio_emc);
- + return err;
- + }
- + }
- return 0;
- }
- @@ -480,7 +495,10 @@ EXPORT_SYMBOL_GPL(tegra_asoc_utils_clk_enable);
- int tegra_asoc_utils_clk_disable(struct tegra_asoc_utils_data *data)
- {
- + if (!IS_ERR(data->clk_out1))
- + clk_disable_unprepare(data->clk_out1);
- clk_disable_unprepare(data->clk_cdev1);
- + clk_disable_unprepare(data->clk_audio_emc);
- return 0;
- }
- EXPORT_SYMBOL_GPL(tegra_asoc_utils_clk_disable);
- @@ -526,12 +544,19 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
- data->dev = dev;
- data->card = card;
- +
- + data->clk_audio_emc = clk_get_sys("audio", "emc");
- + if (IS_ERR(data->clk_audio_emc)) {
- + dev_err(data->dev, "Can't retrieve clk emc\n");
- + ret = PTR_ERR(data->clk_audio_emc);
- + goto err;
- + }
- data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1");
- if (IS_ERR(data->clk_pll_p_out1)) {
- dev_err(data->dev, "Can't retrieve clk pll_p_out1\n");
- ret = PTR_ERR(data->clk_pll_p_out1);
- - goto err;
- + goto err_put_audio_emc;
- }
- if (of_machine_is_compatible("nvidia,tegra20"))
- @@ -603,6 +628,12 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
- goto err_put_cdev1;
- }
- }
- +
- + ret = clk_prepare_enable(data->clk_audio_emc);
- + if (ret) {
- + dev_err(data->dev, "Can't enable clk emc");
- + goto err_put_out1;
- + }
- ret = clk_prepare_enable(data->clk_cdev1);
- if (ret) {
- @@ -635,6 +666,8 @@ err_put_pll_a:
- clk_put(data->clk_pll_a);
- err_put_pll_p_out1:
- clk_put(data->clk_pll_p_out1);
- +err_put_audio_emc:
- + clk_put(data->clk_audio_emc);
- err:
- return ret;
- }
- @@ -688,6 +721,9 @@ void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
- if (!IS_ERR(data->clk_pll_p_out1))
- clk_put(data->clk_pll_p_out1);
- +
- + if (!IS_ERR(data->clk_audio_emc))
- + clk_put(data->clk_audio_emc);
- }
- EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
- diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
- index 346b01a..cf4ee26 100644
- --- a/sound/soc/tegra/tegra_asoc_utils.h
- +++ b/sound/soc/tegra/tegra_asoc_utils.h
- @@ -45,6 +45,7 @@ struct tegra_asoc_utils_data {
- struct device *dev;
- struct snd_soc_card *card;
- enum tegra_asoc_utils_soc soc;
- + struct clk *clk_audio_emc;
- struct clk *clk_pll_a;
- struct clk *clk_pll_a_out0;
- struct clk *clk_cdev1;
- diff --git a/sound/soc/tegra/tegra_rt5671.c b/sound/soc/tegra/tegra_rt5671.c
- new file mode 100644
- index 0000000..d73b2c0
- --- /dev/null
- +++ b/sound/soc/tegra/tegra_rt5671.c
- @@ -0,0 +1,951 @@
- +/*
- + * tegra_rt5671.c - Tegra machine ASoC driver for boards using ALC5671 codec.
- + *
- + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
- + * Copyright (C) 2016 XiaoMi, Inc.
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License
- + * version 2 as published by the Free Software Foundation.
- + *
- + * This program is distributed in the hope that it will be useful, but
- + * WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- + * General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- + * 02110-1301 USA
- + *
- + */
- +
- +#include <asm/mach-types.h>
- +#include <linux/of.h>
- +#include <linux/clk.h>
- +#include <linux/module.h>
- +#include <linux/platform_device.h>
- +#include <linux/slab.h>
- +#include <linux/gpio.h>
- +#include <linux/of_gpio.h>
- +#include <linux/regulator/consumer.h>
- +#include <linux/delay.h>
- +#include <linux/pm_runtime.h>
- +#include <mach/tegra_asoc_pdata.h>
- +#include <mach/gpio-tegra.h>
- +#include <mach/tegra_rt5640_pdata.h>
- +
- +#include <sound/core.h>
- +#include <sound/jack.h>
- +#include <sound/pcm.h>
- +#include <sound/pcm_params.h>
- +#include <sound/soc.h>
- +#include "../codecs/rt5671.h"
- +
- +#include "tegra_pcm.h"
- +#include "tegra_asoc_utils.h"
- +#include <linux/tfa9887.h>
- +#include "tegra30_ahub.h"
- +#include "tegra30_i2s.h"
- +
- +#define DRV_NAME "tegra-snd-rt5671"
- +
- +#define DAI_LINK_HIFI 0
- +#define DAI_LINK_LEFT_SPK 1
- +#define DAI_LINK_RIGHT_SPK 2
- +#define DAI_LINK_BTSCO 3
- +#define DAI_LINK_FM 4
- +#define NUM_DAI_LINKS 5
- +
- +const char *tegra_rt5671_i2s_dai_name[TEGRA30_NR_I2S_IFC] = {
- + "tegra30-i2s.0",
- + "tegra30-i2s.1",
- + "tegra30-i2s.2",
- + "tegra30-i2s.3",
- + "tegra30-i2s.4",
- +};
- +
- +#define GPIO_SPKR_EN BIT(0)
- +#define GPIO_HP_MUTE BIT(1)
- +#define GPIO_INT_MIC_EN BIT(2)
- +#define GPIO_EXT_MIC_EN BIT(3)
- +#define GPIO_HP_DET BIT(4)
- +
- +struct tegra_rt5671 {
- + struct tegra_asoc_utils_data util_data;
- + struct tegra_asoc_platform_data *pdata;
- + int gpio_requested;
- + int clock_enabled;
- + struct regulator *codec_reg;
- + struct regulator *digital_reg;
- + struct regulator *analog_reg;
- + struct regulator *spk_reg;
- + struct regulator *mic_reg;
- + struct regulator *dmic_reg;
- + struct snd_soc_card *pcard;
- +};
- +
- +static int tegra_rt5671_set_clock(struct snd_soc_pcm_runtime *rtd,
- + int sample_size, int channel, int srate)
- +{
- + struct snd_soc_dai *codec_dai = rtd->codec_dai;
- + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- + struct snd_soc_codec *codec = rtd->codec;
- + struct snd_soc_card *card = codec->card;
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + int err, mclk, rate;
- + unsigned int i2sclock;
- +
- + mclk = 256 * srate;
- + err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
- + if (err < 0) {
- + if (!(machine->util_data.set_mclk % mclk)) {
- + mclk = machine->util_data.set_mclk;
- + } else {
- + dev_err(card->dev, "Can't configure clocks\n");
- + return err;
- + }
- + }
- +
- + rate = clk_get_rate(machine->util_data.clk_cdev1);
- + err = snd_soc_dai_set_pll(codec_dai, 0, RT5671_PLL1_S_MCLK,
- + rate, 512*srate);
- + if (err < 0) {
- + dev_err(card->dev, "codec_dai pll not set\n");
- + return err;
- + }
- + err = snd_soc_dai_set_sysclk(codec_dai, RT5671_SCLK_S_PLL1,
- + 512*srate, SND_SOC_CLOCK_IN);
- + if (err < 0) {
- + dev_err(card->dev, "codec_dai clock not set\n");
- + return err;
- + }
- +
- + /*for 24 bit audio we support only S24_LE (S24_3LE is not supported)
- + which is rendered on bus in 32 bits packet so consider as 32 bit
- + depth in clock calculations, extra 4 is required by codec,
- + God knows why ?*/
- + if (sample_size == 24)
- + i2sclock = srate * channel * 32 * 4;
- + else
- + i2sclock = 0;
- +
- + err = snd_soc_dai_set_sysclk(cpu_dai, 0,
- + i2sclock, SND_SOC_CLOCK_OUT);
- + if (err < 0) {
- + dev_err(card->dev, "cpu_dai clock not set\n");
- + return err;
- + }
- +
- + return 0;
- +}
- +
- +static int tegra_rt5671_startup(struct snd_pcm_substream *substream)
- +{
- + struct snd_soc_pcm_runtime *rtd = substream->private_data;
- + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- + struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- +
- + tegra_asoc_utils_tristate_dap(i2s->id, false);
- +
- + return 0;
- +}
- +
- +static void tegra_rt5671_shutdown(struct snd_pcm_substream *substream)
- +{
- + struct snd_soc_pcm_runtime *rtd = substream->private_data;
- + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- + struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- +
- + tegra_asoc_utils_tristate_dap(i2s->id, true);
- +}
- +
- +static int tegra_rt5671_hw_params(struct snd_pcm_substream *substream,
- + struct snd_pcm_hw_params *params)
- +{
- + struct snd_soc_pcm_runtime *rtd = substream->private_data;
- + struct snd_soc_dai *codec_dai = rtd->codec_dai;
- + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- + struct snd_soc_codec *codec = rtd->codec;
- + struct snd_soc_card *card = codec->card;
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + struct tegra_asoc_platform_data *pdata = machine->pdata;
- + int srate, i2s_daifmt, codec_daifmt;
- + int err, sample_size;
- +
- + srate = params_rate(params);
- +
- + i2s_daifmt = SND_SOC_DAIFMT_NB_NF;
- + i2s_daifmt |= pdata->i2s_param[HIFI_CODEC].is_i2s_master ?
- + SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;
- +
- + switch (params_format(params)) {
- + case SNDRV_PCM_FORMAT_S8:
- + sample_size = 8;
- + break;
- + case SNDRV_PCM_FORMAT_S16_LE:
- + sample_size = 16;
- + break;
- + case SNDRV_PCM_FORMAT_S24_LE:
- + sample_size = 24;
- + break;
- + case SNDRV_PCM_FORMAT_S32_LE:
- + sample_size = 32;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + switch (pdata->i2s_param[HIFI_CODEC].i2s_mode) {
- + case TEGRA_DAIFMT_I2S:
- + i2s_daifmt |= SND_SOC_DAIFMT_I2S;
- + break;
- + case TEGRA_DAIFMT_DSP_A:
- + i2s_daifmt |= SND_SOC_DAIFMT_DSP_A;
- + break;
- + case TEGRA_DAIFMT_DSP_B:
- + i2s_daifmt |= SND_SOC_DAIFMT_DSP_B;
- + break;
- + case TEGRA_DAIFMT_LEFT_J:
- + i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J;
- + break;
- + case TEGRA_DAIFMT_RIGHT_J:
- + i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J;
- + break;
- + default:
- + dev_err(card->dev, "Can't configure i2s format\n");
- + return -EINVAL;
- + }
- +
- + err = tegra_rt5671_set_clock(rtd, sample_size, params_channels(params), srate);
- + if (err < 0) {
- + dev_err(card->dev, "Can't configure clocks\n");
- + return err;
- + }
- +
- + tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
- +
- + codec_daifmt = i2s_daifmt;
- +
- + /*invert the codec bclk polarity when codec is master
- + in DSP mode this is done to match with the negative
- + edge settings of tegra i2s*/
- + if (((i2s_daifmt & SND_SOC_DAIFMT_FORMAT_MASK)
- + == SND_SOC_DAIFMT_DSP_A) &&
- + ((i2s_daifmt & SND_SOC_DAIFMT_MASTER_MASK)
- + == SND_SOC_DAIFMT_CBM_CFM)) {
- + codec_daifmt &= ~(SND_SOC_DAIFMT_INV_MASK);
- + codec_daifmt |= SND_SOC_DAIFMT_IB_NF;
- + }
- +
- + err = snd_soc_dai_set_fmt(codec_dai, codec_daifmt);
- + if (err < 0) {
- + dev_err(card->dev, "codec_dai fmt not set\n");
- + return err;
- + }
- +
- + err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt);
- + if (err < 0) {
- + dev_err(card->dev, "cpu_dai fmt not set\n");
- + return err;
- + }
- +
- + return 0;
- +}
- +
- +static int tegra_hw_free(struct snd_pcm_substream *substream)
- +{
- + struct snd_soc_pcm_runtime *rtd = substream->private_data;
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(rtd->card);
- +
- + tegra_asoc_utils_lock_clk_rate(&machine->util_data, 0);
- +
- + return 0;
- +}
- +
- +static struct snd_soc_ops tegra_rt5671_ops = {
- + .hw_params = tegra_rt5671_hw_params,
- + .hw_free = tegra_hw_free,
- + .startup = tegra_rt5671_startup,
- + .shutdown = tegra_rt5671_shutdown,
- +};
- +
- +static int tegra_rt5671_event_int_spk(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *k, int event)
- +{
- + struct snd_soc_dapm_context *dapm = w->dapm;
- + struct snd_soc_card *card = dapm->card;
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + struct tegra_asoc_platform_data *pdata = machine->pdata;
- + int ret;
- +
- + if (machine->spk_reg) {
- + if (SND_SOC_DAPM_EVENT_ON(event))
- + ret = regulator_enable(machine->spk_reg);
- + else
- + regulator_disable(machine->spk_reg);
- + }
- +
- + if (!(machine->gpio_requested & GPIO_SPKR_EN))
- + return 0;
- +
- + gpio_set_value_cansleep(pdata->gpio_spkr_en,
- + !!SND_SOC_DAPM_EVENT_ON(event));
- +
- + return 0;
- +}
- +
- +static int tegra_rt5671_event_hp(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *k, int event)
- +{
- + struct snd_soc_dapm_context *dapm = w->dapm;
- + struct snd_soc_card *card = dapm->card;
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + struct tegra_asoc_platform_data *pdata = machine->pdata;
- +
- + if (!(machine->gpio_requested & GPIO_HP_MUTE))
- + return 0;
- +
- + gpio_set_value_cansleep(pdata->gpio_hp_mute,
- + SND_SOC_DAPM_EVENT_ON(event));
- +
- + return 0;
- +}
- +
- +static int tegra_rt5671_event_int_mic(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *k, int event)
- +{
- + struct snd_soc_dapm_context *dapm = w->dapm;
- + struct snd_soc_card *card = dapm->card;
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + struct tegra_asoc_platform_data *pdata = machine->pdata;
- + int ret;
- +
- + if (machine->dmic_reg) {
- + if (SND_SOC_DAPM_EVENT_ON(event))
- + ret = regulator_enable(machine->dmic_reg);
- + else
- + regulator_disable(machine->dmic_reg);
- + }
- +
- + if (!(machine->gpio_requested & GPIO_INT_MIC_EN))
- + return 0;
- +
- + gpio_set_value_cansleep(pdata->gpio_int_mic_en,
- + !!SND_SOC_DAPM_EVENT_ON(event));
- +
- + return 0;
- +}
- +
- +static int tegra_rt5671_event_ext_mic(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *k, int event)
- +{
- + struct snd_soc_dapm_context *dapm = w->dapm;
- + struct snd_soc_card *card = dapm->card;
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + struct tegra_asoc_platform_data *pdata = machine->pdata;
- +
- + if (!(machine->gpio_requested & GPIO_EXT_MIC_EN))
- + return 0;
- +
- + gpio_set_value_cansleep(pdata->gpio_ext_mic_en,
- + !SND_SOC_DAPM_EVENT_ON(event));
- +
- + return 0;
- +}
- +
- +static const struct snd_soc_dapm_widget ardbeg_dapm_widgets[] = {
- + SND_SOC_DAPM_SPK("Int Left Spk", tegra_rt5671_event_int_spk),
- + SND_SOC_DAPM_SPK("Int Right Spk", tegra_rt5671_event_int_spk),
- + SND_SOC_DAPM_HP("Headphone Jack", tegra_rt5671_event_hp),
- + SND_SOC_DAPM_MIC("Mic Jack", tegra_rt5671_event_ext_mic),
- + SND_SOC_DAPM_MIC("Int Mic", tegra_rt5671_event_int_mic),
- + SND_SOC_DAPM_HP("BT Headphone", NULL),
- + SND_SOC_DAPM_MIC("BT Mic", NULL),
- + SND_SOC_DAPM_LINE("FM", NULL),
- +};
- +
- +static const struct snd_soc_dapm_route ardbeg_audio_map[] = {
- + {"Headphone Jack", NULL, "HPOR"},
- + {"Headphone Jack", NULL, "HPOL"},
- + {"IN1P", NULL, "Mic Jack"},
- + {"IN1N", NULL, "Mic Jack"},
- + {"micbias2", NULL, "Int Mic"},
- + {"IN2P", NULL, "micbias2"},
- + {"IN2N", NULL, "micbias2"},
- + {"IN4P", NULL, "micbias2"},
- + {"IN4N", NULL, "micbias2"},
- + {"Int Left Spk", NULL, "Left Spk Playback"},
- + {"Int Right Spk", NULL, "Right Spk Playback"},
- + {"BT Headphone", NULL, "BT Playback"},
- + {"BT Capture", NULL, "BT Mic"},
- + {"FM Capture", NULL, "FM"},
- +};
- +
- +static const struct snd_kcontrol_new ardbeg_controls[] = {
- + SOC_DAPM_PIN_SWITCH("Int Left Spk"),
- + SOC_DAPM_PIN_SWITCH("Int Right Spk"),
- + SOC_DAPM_PIN_SWITCH("Headphone Jack"),
- + SOC_DAPM_PIN_SWITCH("Mic Jack"),
- + SOC_DAPM_PIN_SWITCH("Int Mic"),
- + SOC_DAPM_PIN_SWITCH("BT Headphone"),
- + SOC_DAPM_PIN_SWITCH("BT Mic"),
- + SOC_DAPM_PIN_SWITCH("FM"),
- +};
- +
- +static int tegra_rt5671_init(struct snd_soc_pcm_runtime *rtd)
- +{
- + struct snd_soc_codec *codec = rtd->codec;
- + struct snd_soc_card *card = codec->card;
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + struct tegra_asoc_platform_data *pdata = machine->pdata;
- + int ret;
- +
- + if (gpio_is_valid(pdata->gpio_spkr_en)) {
- + ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
- + if (ret) {
- + dev_err(card->dev, "cannot get spkr_en gpio\n");
- + return ret;
- + }
- + machine->gpio_requested |= GPIO_SPKR_EN;
- +
- + gpio_direction_output(pdata->gpio_spkr_en, 0);
- + }
- +
- + if (gpio_is_valid(pdata->gpio_hp_mute)) {
- + ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
- + if (ret) {
- + dev_err(card->dev, "cannot get hp_mute gpio\n");
- + return ret;
- + }
- + machine->gpio_requested |= GPIO_HP_MUTE;
- +
- + gpio_direction_output(pdata->gpio_hp_mute, 0);
- + }
- +
- + if (gpio_is_valid(pdata->gpio_int_mic_en)) {
- + ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
- + if (ret) {
- + dev_err(card->dev, "cannot get int_mic_en gpio\n");
- + } else {
- + machine->gpio_requested |= GPIO_INT_MIC_EN;
- +
- + /* Disable int mic; enable signal is active-high */
- + gpio_direction_output(pdata->gpio_int_mic_en, 0);
- + }
- + }
- +
- + if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
- + ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
- + if (ret) {
- + dev_err(card->dev, "cannot get ext_mic_en gpio\n");
- + } else {
- + machine->gpio_requested |= GPIO_EXT_MIC_EN;
- +
- + /* Disable ext mic; enable signal is active-low */
- + gpio_direction_output(pdata->gpio_ext_mic_en, 1);
- + }
- + }
- +
- + ret = tegra_asoc_utils_register_ctls(&machine->util_data);
- + if (ret < 0)
- + return ret;
- +
- + ret = tegra_rt5671_set_clock(rtd,
- + pdata->i2s_param[HIFI_CODEC].sample_size,
- + pdata->i2s_param[HIFI_CODEC].channels,
- + pdata->i2s_param[HIFI_CODEC].rate);
- + if (ret < 0)
- + return ret;
- +
- + return 0;
- +}
- +
- +static const struct snd_soc_pcm_stream tegra_rt5671_spk_params = {
- + .formats = SNDRV_PCM_FMTBIT_S16_LE,
- + .rate_min = 48000,
- + .rate_max = 48000,
- + .channels_min = 2,
- + .channels_max = 2,
- +
- +};
- +
- +static const struct snd_soc_pcm_stream tegra_rt5671_bt_params = {
- + .formats = SNDRV_PCM_FMTBIT_S16_LE,
- + .rate_min = 8000,
- + .rate_max = 8000,
- + .channels_min = 1,
- + .channels_max = 1,
- +
- +};
- +
- +static const struct snd_soc_pcm_stream tegra_rt5671_fm_params = {
- + .formats = SNDRV_PCM_FMTBIT_S16_LE,
- + .rate_min = 48000,
- + .rate_max = 48000,
- + .channels_min = 2,
- + .channels_max = 2,
- +
- +};
- +
- +static struct snd_soc_dai_link tegra_rt5671_dai[NUM_DAI_LINKS] = {
- + [DAI_LINK_HIFI] = {
- + .name = "rt5671",
- + .stream_name = "rt5671 PCM",
- + .codec_name = "rt5671.0-001c",
- + .platform_name = "tegra30-i2s.0",
- + .cpu_dai_name = "tegra30-i2s.0",
- + .codec_dai_name = "rt5671-aif1",
- + .ignore_pmdown_time = 1,
- + .init = tegra_rt5671_init,
- + .ops = &tegra_rt5671_ops,
- + },
- + [DAI_LINK_LEFT_SPK] = {
- + .name = "rt5671 Left Speaker",
- + .stream_name = "rt5671 Left SPK",
- + .codec_name = "tfa98xx.0-0034",
- + .cpu_dai_name = "rt5671-aif2",
- + .codec_dai_name = "tfa98xx-dai",
- + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- + SND_SOC_DAIFMT_CBS_CFS,
- + .params = &tegra_rt5671_spk_params,
- + .ignore_pmdown_time = 1,
- + },
- + [DAI_LINK_RIGHT_SPK] = {
- + .name = "rt5671 Right Speaker",
- + .stream_name = "rt5671 Right SPK",
- + .codec_name = "tfa98xx.0-0037",
- + .cpu_dai_name = "rt5671-aif2",
- + .codec_dai_name = "tfa98xx-dai",
- + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- + SND_SOC_DAIFMT_CBS_CFS,
- + .params = &tegra_rt5671_spk_params,
- + .ignore_pmdown_time = 1,
- + },
- + [DAI_LINK_BTSCO] = {
- + .name = "BT-SCO",
- + .stream_name = "BT SCO PCM",
- + .codec_name = "rt5671.0-001c",
- + .cpu_name = "spdif-dit.1",
- + .codec_dai_name = "rt5671-aif3",
- + .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
- + SND_SOC_DAIFMT_CBM_CFM,
- + .params = &tegra_rt5671_bt_params,
- + .ignore_pmdown_time = 1,
- + },
- +
- + [DAI_LINK_FM] = {
- + .name = "rt5671 FM",
- + .stream_name = "rt5671 FM",
- + .codec_name = "rt5671.0-001c",
- + .cpu_name = "spdif-dit.3",
- + .codec_dai_name = "rt5671-aif4",
- + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- + SND_SOC_DAIFMT_CBM_CFM,
- + .params = &tegra_rt5671_fm_params,
- + .ignore_pmdown_time = 1,
- + },
- +};
- +
- +static int tegra_rt5671_suspend_post(struct snd_soc_card *card)
- +{
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + int i, suspend_allowed = 1;
- +
- + /*In Voice Call we ignore suspend..so check for that*/
- + for (i = 0; i < machine->pcard->num_links; i++) {
- + if (machine->pcard->dai_link[i].ignore_suspend) {
- + suspend_allowed = 0;
- + break;
- + }
- + }
- +
- + if (suspend_allowed) {
- + /*This may be required if dapm setbias level is not called in
- + some cases, may be due to a wrong dapm map*/
- + if (machine->clock_enabled) {
- + machine->clock_enabled = 0;
- + tegra_asoc_utils_clk_disable(&machine->util_data);
- + }
- + /*TODO: Disable Audio Regulators*/
- + }
- +
- + return 0;
- +}
- +
- +static int tegra_rt5671_resume_pre(struct snd_soc_card *card)
- +{
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + int i, suspend_allowed = 1;
- +
- + /*In Voice Call we ignore suspend..so check for that*/
- + for (i = 0; i < machine->pcard->num_links; i++) {
- + if (machine->pcard->dai_link[i].ignore_suspend) {
- + suspend_allowed = 0;
- + break;
- + }
- + }
- +
- + if (suspend_allowed) {
- + /*This may be required if dapm setbias level is not called in
- + some cases, may be due to a wrong dapm map*/
- + if (!machine->clock_enabled && card->dapm.bias_level != SND_SOC_BIAS_STANDBY &&
- + card->dapm.bias_level != SND_SOC_BIAS_OFF) {
- + machine->clock_enabled = 1;
- + tegra_asoc_utils_clk_enable(&machine->util_data);
- + }
- + /*TODO: Enable Audio Regulators*/
- + }
- +
- + return 0;
- +}
- +
- +static int tegra_rt5671_set_bias_level(struct snd_soc_card *card,
- + struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
- +{
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- +
- + if (dapm == &card->dapm) {
- + if (level != SND_SOC_BIAS_STANDBY &&
- + level != SND_SOC_BIAS_OFF && (!machine->clock_enabled)) {
- + machine->clock_enabled = 1;
- + tegra_asoc_utils_clk_enable(&machine->util_data);
- + }
- + dapm->bias_level = level;
- + }
- +
- + return 0;
- +}
- +
- +static int tegra_rt5671_set_bias_level_post(struct snd_soc_card *card,
- + struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
- +{
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- +
- + if (dapm == &card->dapm) {
- + if ((level == SND_SOC_BIAS_STANDBY ||
- + level == SND_SOC_BIAS_OFF) && machine->clock_enabled) {
- + machine->clock_enabled = 0;
- + tegra_asoc_utils_clk_disable(&machine->util_data);
- + }
- + dapm->bias_level = level;
- + }
- +
- + return 0 ;
- +}
- +
- +static struct snd_soc_codec_conf tegra_rt5671_conf[] = {
- + {
- + .dev_name = "tfa98xx.0-0034",
- + .name_prefix = "Left Spk",
- + },
- + {
- + .dev_name = "tfa98xx.0-0037",
- + .name_prefix = "Right Spk",
- + },
- + {
- + .dev_name = "spdif-dit.1",
- + .name_prefix = "BT",
- + },
- + {
- + .dev_name = "spdif-dit.3",
- + .name_prefix = "FM",
- + },
- +};
- +
- +static struct snd_soc_card snd_soc_tegra_rt5671 = {
- + .name = "tegra-rt5671",
- + .owner = THIS_MODULE,
- + .dai_link = tegra_rt5671_dai,
- + .num_links = ARRAY_SIZE(tegra_rt5671_dai),
- + .codec_conf = tegra_rt5671_conf,
- + .num_configs = ARRAY_SIZE(tegra_rt5671_conf),
- + .suspend_post = tegra_rt5671_suspend_post,
- + .resume_pre = tegra_rt5671_resume_pre,
- + .set_bias_level = tegra_rt5671_set_bias_level,
- + .set_bias_level_post = tegra_rt5671_set_bias_level_post,
- + .controls = ardbeg_controls,
- + .num_controls = ARRAY_SIZE(ardbeg_controls),
- + .dapm_widgets = ardbeg_dapm_widgets,
- + .num_dapm_widgets = ARRAY_SIZE(ardbeg_dapm_widgets),
- + .dapm_routes = ardbeg_audio_map,
- + .num_dapm_routes = ARRAY_SIZE(ardbeg_audio_map),
- + .fully_routed = true,
- +};
- +
- +static int tegra_rt5671_driver_probe(struct platform_device *pdev)
- +{
- + struct snd_soc_card *card = &snd_soc_tegra_rt5671;
- + struct device_node *np = pdev->dev.of_node;
- + struct tegra_rt5671 *machine;
- + struct tegra_asoc_platform_data *pdata = NULL;
- + int ret;
- + int codec_id;
- + u32 val32[7];
- +
- + if (!pdev->dev.platform_data && !pdev->dev.of_node) {
- + dev_err(&pdev->dev, "No platform data supplied\n");
- + return -EINVAL;
- + }
- + if (pdev->dev.platform_data) {
- + pdata = pdev->dev.platform_data;
- + } else if (np) {
- + pdata = kzalloc(sizeof(struct tegra_asoc_platform_data),
- + GFP_KERNEL);
- + if (!pdata) {
- + dev_err(&pdev->dev, "Can't allocate tegra_asoc_platform_data struct\n");
- + return -ENOMEM;
- + }
- +
- + of_property_read_string(np, "nvidia,codec_name",
- + &pdata->codec_name);
- +
- + of_property_read_string(np, "nvidia,codec_dai_name",
- + &pdata->codec_dai_name);
- +
- + pdata->gpio_ldo1_en = of_get_named_gpio(np,
- + "nvidia,ldo-gpios", 0);
- + if (pdata->gpio_ldo1_en < 0)
- + dev_warn(&pdev->dev, "Failed to get LDO_EN GPIO\n");
- +
- + pdata->gpio_hp_det = of_get_named_gpio(np,
- + "nvidia,hp-det-gpios", 0);
- + if (pdata->gpio_hp_det < 0)
- + dev_warn(&pdev->dev, "Failed to get HP Det GPIO\n");
- +
- + pdata->gpio_codec1 = pdata->gpio_codec2 = pdata->gpio_codec3 =
- + pdata->gpio_spkr_en = pdata->gpio_hp_mute =
- + pdata->gpio_int_mic_en = pdata->gpio_ext_mic_en = -1;
- +
- + of_property_read_u32_array(np, "nvidia,i2s-param-hifi", val32,
- + ARRAY_SIZE(val32));
- + pdata->i2s_param[HIFI_CODEC].audio_port_id = (int)val32[0];
- + pdata->i2s_param[HIFI_CODEC].is_i2s_master = (int)val32[1];
- + pdata->i2s_param[HIFI_CODEC].i2s_mode = (int)val32[2];
- + }
- +
- + if (!pdata) {
- + dev_err(&pdev->dev, "No platform data supplied\n");
- + return -EINVAL;
- + }
- +
- + if (pdata->codec_name)
- + card->dai_link->codec_name = pdata->codec_name;
- +
- + if (pdata->codec_dai_name)
- + card->dai_link->codec_dai_name = pdata->codec_dai_name;
- +
- + machine = kzalloc(sizeof(struct tegra_rt5671), GFP_KERNEL);
- + if (!machine) {
- + dev_err(&pdev->dev, "Can't allocate tegra_rt5671 struct\n");
- + if (np)
- + kfree(pdata);
- + return -ENOMEM;
- + }
- +
- + if (gpio_is_valid(pdata->gpio_ldo1_en)) {
- + ret = gpio_request(pdata->gpio_ldo1_en, "rt5671");
- + if (ret)
- + dev_err(&pdev->dev, "Fail gpio_request AUDIO_LDO1\n");
- +
- + ret = gpio_direction_output(pdata->gpio_ldo1_en, 1);
- + if (ret)
- + dev_err(&pdev->dev, "Fail gpio_direction AUDIO_LDO1\n");
- +
- + msleep(200);
- + }
- +
- + machine->pdata = pdata;
- + machine->pcard = card;
- +
- + ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev, card);
- + if (ret)
- + goto err_free_machine;
- + tegra_asoc_utils_clk_disable(&machine->util_data);
- +
- + /*
- + *codec_reg - its a GPIO (in the form of a fixed regulator) that enables
- + *the basic(I2C) power for the codec and must be ON always
- + */
- + if (!gpio_is_valid(pdata->gpio_ldo1_en)) {
- + machine->codec_reg = regulator_get(&pdev->dev, "ldoen");
- + if (IS_ERR(machine->codec_reg))
- + machine->codec_reg = 0;
- + else
- + ret = regulator_enable(machine->codec_reg);
- + }
- +
- + /*
- + *digital_reg - provided the digital power for the codec and must be
- + *ON always
- + */
- + machine->digital_reg = regulator_get(&pdev->dev, "dbvdd");
- + if (IS_ERR(machine->digital_reg))
- + machine->digital_reg = 0;
- + else
- + ret = regulator_enable(machine->digital_reg);
- +
- + /*
- + *analog_reg - provided the analog power for the codec and must be
- + *ON always
- + */
- + machine->analog_reg = regulator_get(&pdev->dev, "avdd");
- + if (IS_ERR(machine->analog_reg))
- + machine->analog_reg = 0;
- + else
- + ret = regulator_enable(machine->analog_reg);
- +
- + /*
- + *mic_reg - provided the micbias power and jack detection power
- + *for the codec and must be ON always
- + */
- + machine->mic_reg = regulator_get(&pdev->dev, "micvdd");
- + if (IS_ERR(machine->mic_reg))
- + machine->mic_reg = 0;
- + else
- + ret = regulator_enable(machine->mic_reg);
- +
- + /*
- + *spk_reg - provided the speaker power and can be turned ON
- + *on need basis, when required
- + */
- + machine->spk_reg = regulator_get(&pdev->dev, "spkvdd");
- + if (IS_ERR(machine->spk_reg))
- + machine->spk_reg = 0;
- + else
- + regulator_disable(machine->spk_reg);
- +
- + /*
- + *dmic_reg - provided the DMIC power and can be turned ON
- + *on need basis, when required
- + */
- + machine->dmic_reg = regulator_get(&pdev->dev, "dmicvdd");
- + if (IS_ERR(machine->dmic_reg))
- + machine->dmic_reg = 0;
- + else
- + regulator_disable(machine->dmic_reg);
- +
- + card->dev = &pdev->dev;
- + platform_set_drvdata(pdev, card);
- + snd_soc_card_set_drvdata(card, machine);
- +
- + codec_id = pdata->i2s_param[HIFI_CODEC].audio_port_id;
- + tegra_rt5671_dai[DAI_LINK_HIFI].cpu_dai_name =
- + tegra_rt5671_i2s_dai_name[codec_id];
- + tegra_rt5671_dai[DAI_LINK_HIFI].platform_name =
- + tegra_rt5671_i2s_dai_name[codec_id];
- +
- + ret = snd_soc_register_card(card);
- + if (ret) {
- + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
- + ret);
- + goto err_fini_utils;
- + }
- +
- + if (!card->instantiated) {
- + ret = -ENODEV;
- + dev_err(&pdev->dev, "sound card not instantiated (%d)\n",
- + ret);
- + goto err_unregister_card;
- + }
- +
- + ret = tegra_asoc_utils_set_parent(&machine->util_data,
- + pdata->i2s_param[HIFI_CODEC].is_i2s_master);
- + if (ret) {
- + dev_err(&pdev->dev, "tegra_asoc_utils_set_parent failed (%d)\n",
- + ret);
- + goto err_unregister_card;
- + }
- +
- + return 0;
- +
- +err_unregister_card:
- + snd_soc_unregister_card(card);
- +err_fini_utils:
- + tegra_asoc_utils_fini(&machine->util_data);
- +err_free_machine:
- + if (np)
- + kfree(machine->pdata);
- +
- + kfree(machine);
- +
- + return ret;
- +}
- +
- +static int tegra_rt5671_driver_remove(struct platform_device *pdev)
- +{
- + struct snd_soc_card *card = platform_get_drvdata(pdev);
- + struct tegra_rt5671 *machine = snd_soc_card_get_drvdata(card);
- + struct tegra_asoc_platform_data *pdata = machine->pdata;
- + struct device_node *np = pdev->dev.of_node;
- +
- + if (machine->gpio_requested & GPIO_EXT_MIC_EN)
- + gpio_free(pdata->gpio_ext_mic_en);
- + if (machine->gpio_requested & GPIO_INT_MIC_EN)
- + gpio_free(pdata->gpio_int_mic_en);
- + if (machine->gpio_requested & GPIO_HP_MUTE)
- + gpio_free(pdata->gpio_hp_mute);
- + if (machine->gpio_requested & GPIO_SPKR_EN)
- + gpio_free(pdata->gpio_spkr_en);
- +
- + if (machine->digital_reg)
- + regulator_put(machine->digital_reg);
- + if (machine->analog_reg)
- + regulator_put(machine->analog_reg);
- + if (machine->mic_reg)
- + regulator_put(machine->mic_reg);
- + if (machine->spk_reg)
- + regulator_put(machine->spk_reg);
- + if (machine->dmic_reg)
- + regulator_put(machine->dmic_reg);
- + if (machine->codec_reg)
- + regulator_put(machine->codec_reg);
- +
- + if (gpio_is_valid(pdata->gpio_ldo1_en)) {
- + gpio_set_value(pdata->gpio_ldo1_en, 0);
- + gpio_free(pdata->gpio_ldo1_en);
- + }
- +
- + snd_soc_unregister_card(card);
- +
- + tegra_asoc_utils_fini(&machine->util_data);
- +
- + if (np)
- + kfree(machine->pdata);
- +
- + kfree(machine);
- +
- + return 0;
- +}
- +
- +static const struct of_device_id tegra_rt5671_of_match[] = {
- + { .compatible = "nvidia,tegra-audio-rt5671", },
- + {},
- +};
- +
- +static struct platform_driver tegra_rt5671_driver = {
- + .driver = {
- + .name = DRV_NAME,
- + .owner = THIS_MODULE,
- + .pm = &snd_soc_pm_ops,
- + .of_match_table = tegra_rt5671_of_match,
- + },
- + .probe = tegra_rt5671_driver_probe,
- + .remove = tegra_rt5671_driver_remove,
- +};
- +
- +static int __init tegra_rt5671_modinit(void)
- +{
- + return platform_driver_register(&tegra_rt5671_driver);
- +}
- +module_init(tegra_rt5671_modinit);
- +
- +static void __exit tegra_rt5671_modexit(void)
- +{
- + platform_driver_unregister(&tegra_rt5671_driver);
- +}
- +module_exit(tegra_rt5671_modexit);
- +
- +MODULE_AUTHOR("Nikesh Oswal <noswal@nvidia.com>");
- +MODULE_DESCRIPTION("Tegra+rt5671 machine ASoC driver");
- +MODULE_LICENSE("GPL");
- +MODULE_ALIAS("platform:" DRV_NAME);
- --
- 2.7.4
Add Comment
Please, Sign In to add comment