162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * rt5651.c -- RT5651 ALSA SoC audio codec driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2014 Realtek Semiconductor Corp. 662306a36Sopenharmony_ci * Author: Bard Liao <bardliao@realtek.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/module.h> 1062306a36Sopenharmony_ci#include <linux/init.h> 1162306a36Sopenharmony_ci#include <linux/delay.h> 1262306a36Sopenharmony_ci#include <linux/pm.h> 1362306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 1462306a36Sopenharmony_ci#include <linux/i2c.h> 1562306a36Sopenharmony_ci#include <linux/regmap.h> 1662306a36Sopenharmony_ci#include <linux/platform_device.h> 1762306a36Sopenharmony_ci#include <linux/spi/spi.h> 1862306a36Sopenharmony_ci#include <linux/acpi.h> 1962306a36Sopenharmony_ci#include <sound/core.h> 2062306a36Sopenharmony_ci#include <sound/pcm.h> 2162306a36Sopenharmony_ci#include <sound/pcm_params.h> 2262306a36Sopenharmony_ci#include <sound/soc.h> 2362306a36Sopenharmony_ci#include <sound/soc-dapm.h> 2462306a36Sopenharmony_ci#include <sound/initval.h> 2562306a36Sopenharmony_ci#include <sound/tlv.h> 2662306a36Sopenharmony_ci#include <sound/jack.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include "rl6231.h" 2962306a36Sopenharmony_ci#include "rt5651.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define RT5651_DEVICE_ID_VALUE 0x6281 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define RT5651_PR_RANGE_BASE (0xff + 1) 3462306a36Sopenharmony_ci#define RT5651_PR_SPACING 0x100 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define RT5651_PR_BASE (RT5651_PR_RANGE_BASE + (0 * RT5651_PR_SPACING)) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic const struct regmap_range_cfg rt5651_ranges[] = { 3962306a36Sopenharmony_ci { .name = "PR", .range_min = RT5651_PR_BASE, 4062306a36Sopenharmony_ci .range_max = RT5651_PR_BASE + 0xb4, 4162306a36Sopenharmony_ci .selector_reg = RT5651_PRIV_INDEX, 4262306a36Sopenharmony_ci .selector_mask = 0xff, 4362306a36Sopenharmony_ci .selector_shift = 0x0, 4462306a36Sopenharmony_ci .window_start = RT5651_PRIV_DATA, 4562306a36Sopenharmony_ci .window_len = 0x1, }, 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic const struct reg_sequence init_list[] = { 4962306a36Sopenharmony_ci {RT5651_PR_BASE + 0x3d, 0x3e00}, 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic const struct reg_default rt5651_reg[] = { 5362306a36Sopenharmony_ci { 0x00, 0x0000 }, 5462306a36Sopenharmony_ci { 0x02, 0xc8c8 }, 5562306a36Sopenharmony_ci { 0x03, 0xc8c8 }, 5662306a36Sopenharmony_ci { 0x05, 0x0000 }, 5762306a36Sopenharmony_ci { 0x0d, 0x0000 }, 5862306a36Sopenharmony_ci { 0x0e, 0x0000 }, 5962306a36Sopenharmony_ci { 0x0f, 0x0808 }, 6062306a36Sopenharmony_ci { 0x10, 0x0808 }, 6162306a36Sopenharmony_ci { 0x19, 0xafaf }, 6262306a36Sopenharmony_ci { 0x1a, 0xafaf }, 6362306a36Sopenharmony_ci { 0x1b, 0x0c00 }, 6462306a36Sopenharmony_ci { 0x1c, 0x2f2f }, 6562306a36Sopenharmony_ci { 0x1d, 0x2f2f }, 6662306a36Sopenharmony_ci { 0x1e, 0x0000 }, 6762306a36Sopenharmony_ci { 0x27, 0x7860 }, 6862306a36Sopenharmony_ci { 0x28, 0x7070 }, 6962306a36Sopenharmony_ci { 0x29, 0x8080 }, 7062306a36Sopenharmony_ci { 0x2a, 0x5252 }, 7162306a36Sopenharmony_ci { 0x2b, 0x5454 }, 7262306a36Sopenharmony_ci { 0x2f, 0x0000 }, 7362306a36Sopenharmony_ci { 0x30, 0x5000 }, 7462306a36Sopenharmony_ci { 0x3b, 0x0000 }, 7562306a36Sopenharmony_ci { 0x3c, 0x006f }, 7662306a36Sopenharmony_ci { 0x3d, 0x0000 }, 7762306a36Sopenharmony_ci { 0x3e, 0x006f }, 7862306a36Sopenharmony_ci { 0x45, 0x6000 }, 7962306a36Sopenharmony_ci { 0x4d, 0x0000 }, 8062306a36Sopenharmony_ci { 0x4e, 0x0000 }, 8162306a36Sopenharmony_ci { 0x4f, 0x0279 }, 8262306a36Sopenharmony_ci { 0x50, 0x0000 }, 8362306a36Sopenharmony_ci { 0x51, 0x0000 }, 8462306a36Sopenharmony_ci { 0x52, 0x0279 }, 8562306a36Sopenharmony_ci { 0x53, 0xf000 }, 8662306a36Sopenharmony_ci { 0x61, 0x0000 }, 8762306a36Sopenharmony_ci { 0x62, 0x0000 }, 8862306a36Sopenharmony_ci { 0x63, 0x00c0 }, 8962306a36Sopenharmony_ci { 0x64, 0x0000 }, 9062306a36Sopenharmony_ci { 0x65, 0x0000 }, 9162306a36Sopenharmony_ci { 0x66, 0x0000 }, 9262306a36Sopenharmony_ci { 0x70, 0x8000 }, 9362306a36Sopenharmony_ci { 0x71, 0x8000 }, 9462306a36Sopenharmony_ci { 0x73, 0x1104 }, 9562306a36Sopenharmony_ci { 0x74, 0x0c00 }, 9662306a36Sopenharmony_ci { 0x75, 0x1400 }, 9762306a36Sopenharmony_ci { 0x77, 0x0c00 }, 9862306a36Sopenharmony_ci { 0x78, 0x4000 }, 9962306a36Sopenharmony_ci { 0x79, 0x0123 }, 10062306a36Sopenharmony_ci { 0x80, 0x0000 }, 10162306a36Sopenharmony_ci { 0x81, 0x0000 }, 10262306a36Sopenharmony_ci { 0x82, 0x0000 }, 10362306a36Sopenharmony_ci { 0x83, 0x0800 }, 10462306a36Sopenharmony_ci { 0x84, 0x0000 }, 10562306a36Sopenharmony_ci { 0x85, 0x0008 }, 10662306a36Sopenharmony_ci { 0x89, 0x0000 }, 10762306a36Sopenharmony_ci { 0x8e, 0x0004 }, 10862306a36Sopenharmony_ci { 0x8f, 0x1100 }, 10962306a36Sopenharmony_ci { 0x90, 0x0000 }, 11062306a36Sopenharmony_ci { 0x93, 0x2000 }, 11162306a36Sopenharmony_ci { 0x94, 0x0200 }, 11262306a36Sopenharmony_ci { 0xb0, 0x2080 }, 11362306a36Sopenharmony_ci { 0xb1, 0x0000 }, 11462306a36Sopenharmony_ci { 0xb4, 0x2206 }, 11562306a36Sopenharmony_ci { 0xb5, 0x1f00 }, 11662306a36Sopenharmony_ci { 0xb6, 0x0000 }, 11762306a36Sopenharmony_ci { 0xbb, 0x0000 }, 11862306a36Sopenharmony_ci { 0xbc, 0x0000 }, 11962306a36Sopenharmony_ci { 0xbd, 0x0000 }, 12062306a36Sopenharmony_ci { 0xbe, 0x0000 }, 12162306a36Sopenharmony_ci { 0xbf, 0x0000 }, 12262306a36Sopenharmony_ci { 0xc0, 0x0400 }, 12362306a36Sopenharmony_ci { 0xc1, 0x0000 }, 12462306a36Sopenharmony_ci { 0xc2, 0x0000 }, 12562306a36Sopenharmony_ci { 0xcf, 0x0013 }, 12662306a36Sopenharmony_ci { 0xd0, 0x0680 }, 12762306a36Sopenharmony_ci { 0xd1, 0x1c17 }, 12862306a36Sopenharmony_ci { 0xd3, 0xb320 }, 12962306a36Sopenharmony_ci { 0xd9, 0x0809 }, 13062306a36Sopenharmony_ci { 0xfa, 0x0010 }, 13162306a36Sopenharmony_ci { 0xfe, 0x10ec }, 13262306a36Sopenharmony_ci { 0xff, 0x6281 }, 13362306a36Sopenharmony_ci}; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic bool rt5651_volatile_register(struct device *dev, unsigned int reg) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci int i; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rt5651_ranges); i++) { 14062306a36Sopenharmony_ci if ((reg >= rt5651_ranges[i].window_start && 14162306a36Sopenharmony_ci reg <= rt5651_ranges[i].window_start + 14262306a36Sopenharmony_ci rt5651_ranges[i].window_len) || 14362306a36Sopenharmony_ci (reg >= rt5651_ranges[i].range_min && 14462306a36Sopenharmony_ci reg <= rt5651_ranges[i].range_max)) { 14562306a36Sopenharmony_ci return true; 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci switch (reg) { 15062306a36Sopenharmony_ci case RT5651_RESET: 15162306a36Sopenharmony_ci case RT5651_PRIV_DATA: 15262306a36Sopenharmony_ci case RT5651_EQ_CTRL1: 15362306a36Sopenharmony_ci case RT5651_ALC_1: 15462306a36Sopenharmony_ci case RT5651_IRQ_CTRL2: 15562306a36Sopenharmony_ci case RT5651_INT_IRQ_ST: 15662306a36Sopenharmony_ci case RT5651_PGM_REG_ARR1: 15762306a36Sopenharmony_ci case RT5651_PGM_REG_ARR3: 15862306a36Sopenharmony_ci case RT5651_VENDOR_ID: 15962306a36Sopenharmony_ci case RT5651_DEVICE_ID: 16062306a36Sopenharmony_ci return true; 16162306a36Sopenharmony_ci default: 16262306a36Sopenharmony_ci return false; 16362306a36Sopenharmony_ci } 16462306a36Sopenharmony_ci} 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistatic bool rt5651_readable_register(struct device *dev, unsigned int reg) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci int i; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rt5651_ranges); i++) { 17162306a36Sopenharmony_ci if ((reg >= rt5651_ranges[i].window_start && 17262306a36Sopenharmony_ci reg <= rt5651_ranges[i].window_start + 17362306a36Sopenharmony_ci rt5651_ranges[i].window_len) || 17462306a36Sopenharmony_ci (reg >= rt5651_ranges[i].range_min && 17562306a36Sopenharmony_ci reg <= rt5651_ranges[i].range_max)) { 17662306a36Sopenharmony_ci return true; 17762306a36Sopenharmony_ci } 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci switch (reg) { 18162306a36Sopenharmony_ci case RT5651_RESET: 18262306a36Sopenharmony_ci case RT5651_VERSION_ID: 18362306a36Sopenharmony_ci case RT5651_VENDOR_ID: 18462306a36Sopenharmony_ci case RT5651_DEVICE_ID: 18562306a36Sopenharmony_ci case RT5651_HP_VOL: 18662306a36Sopenharmony_ci case RT5651_LOUT_CTRL1: 18762306a36Sopenharmony_ci case RT5651_LOUT_CTRL2: 18862306a36Sopenharmony_ci case RT5651_IN1_IN2: 18962306a36Sopenharmony_ci case RT5651_IN3: 19062306a36Sopenharmony_ci case RT5651_INL1_INR1_VOL: 19162306a36Sopenharmony_ci case RT5651_INL2_INR2_VOL: 19262306a36Sopenharmony_ci case RT5651_DAC1_DIG_VOL: 19362306a36Sopenharmony_ci case RT5651_DAC2_DIG_VOL: 19462306a36Sopenharmony_ci case RT5651_DAC2_CTRL: 19562306a36Sopenharmony_ci case RT5651_ADC_DIG_VOL: 19662306a36Sopenharmony_ci case RT5651_ADC_DATA: 19762306a36Sopenharmony_ci case RT5651_ADC_BST_VOL: 19862306a36Sopenharmony_ci case RT5651_STO1_ADC_MIXER: 19962306a36Sopenharmony_ci case RT5651_STO2_ADC_MIXER: 20062306a36Sopenharmony_ci case RT5651_AD_DA_MIXER: 20162306a36Sopenharmony_ci case RT5651_STO_DAC_MIXER: 20262306a36Sopenharmony_ci case RT5651_DD_MIXER: 20362306a36Sopenharmony_ci case RT5651_DIG_INF_DATA: 20462306a36Sopenharmony_ci case RT5651_PDM_CTL: 20562306a36Sopenharmony_ci case RT5651_REC_L1_MIXER: 20662306a36Sopenharmony_ci case RT5651_REC_L2_MIXER: 20762306a36Sopenharmony_ci case RT5651_REC_R1_MIXER: 20862306a36Sopenharmony_ci case RT5651_REC_R2_MIXER: 20962306a36Sopenharmony_ci case RT5651_HPO_MIXER: 21062306a36Sopenharmony_ci case RT5651_OUT_L1_MIXER: 21162306a36Sopenharmony_ci case RT5651_OUT_L2_MIXER: 21262306a36Sopenharmony_ci case RT5651_OUT_L3_MIXER: 21362306a36Sopenharmony_ci case RT5651_OUT_R1_MIXER: 21462306a36Sopenharmony_ci case RT5651_OUT_R2_MIXER: 21562306a36Sopenharmony_ci case RT5651_OUT_R3_MIXER: 21662306a36Sopenharmony_ci case RT5651_LOUT_MIXER: 21762306a36Sopenharmony_ci case RT5651_PWR_DIG1: 21862306a36Sopenharmony_ci case RT5651_PWR_DIG2: 21962306a36Sopenharmony_ci case RT5651_PWR_ANLG1: 22062306a36Sopenharmony_ci case RT5651_PWR_ANLG2: 22162306a36Sopenharmony_ci case RT5651_PWR_MIXER: 22262306a36Sopenharmony_ci case RT5651_PWR_VOL: 22362306a36Sopenharmony_ci case RT5651_PRIV_INDEX: 22462306a36Sopenharmony_ci case RT5651_PRIV_DATA: 22562306a36Sopenharmony_ci case RT5651_I2S1_SDP: 22662306a36Sopenharmony_ci case RT5651_I2S2_SDP: 22762306a36Sopenharmony_ci case RT5651_ADDA_CLK1: 22862306a36Sopenharmony_ci case RT5651_ADDA_CLK2: 22962306a36Sopenharmony_ci case RT5651_DMIC: 23062306a36Sopenharmony_ci case RT5651_TDM_CTL_1: 23162306a36Sopenharmony_ci case RT5651_TDM_CTL_2: 23262306a36Sopenharmony_ci case RT5651_TDM_CTL_3: 23362306a36Sopenharmony_ci case RT5651_GLB_CLK: 23462306a36Sopenharmony_ci case RT5651_PLL_CTRL1: 23562306a36Sopenharmony_ci case RT5651_PLL_CTRL2: 23662306a36Sopenharmony_ci case RT5651_PLL_MODE_1: 23762306a36Sopenharmony_ci case RT5651_PLL_MODE_2: 23862306a36Sopenharmony_ci case RT5651_PLL_MODE_3: 23962306a36Sopenharmony_ci case RT5651_PLL_MODE_4: 24062306a36Sopenharmony_ci case RT5651_PLL_MODE_5: 24162306a36Sopenharmony_ci case RT5651_PLL_MODE_6: 24262306a36Sopenharmony_ci case RT5651_PLL_MODE_7: 24362306a36Sopenharmony_ci case RT5651_DEPOP_M1: 24462306a36Sopenharmony_ci case RT5651_DEPOP_M2: 24562306a36Sopenharmony_ci case RT5651_DEPOP_M3: 24662306a36Sopenharmony_ci case RT5651_CHARGE_PUMP: 24762306a36Sopenharmony_ci case RT5651_MICBIAS: 24862306a36Sopenharmony_ci case RT5651_A_JD_CTL1: 24962306a36Sopenharmony_ci case RT5651_EQ_CTRL1: 25062306a36Sopenharmony_ci case RT5651_EQ_CTRL2: 25162306a36Sopenharmony_ci case RT5651_ALC_1: 25262306a36Sopenharmony_ci case RT5651_ALC_2: 25362306a36Sopenharmony_ci case RT5651_ALC_3: 25462306a36Sopenharmony_ci case RT5651_JD_CTRL1: 25562306a36Sopenharmony_ci case RT5651_JD_CTRL2: 25662306a36Sopenharmony_ci case RT5651_IRQ_CTRL1: 25762306a36Sopenharmony_ci case RT5651_IRQ_CTRL2: 25862306a36Sopenharmony_ci case RT5651_INT_IRQ_ST: 25962306a36Sopenharmony_ci case RT5651_GPIO_CTRL1: 26062306a36Sopenharmony_ci case RT5651_GPIO_CTRL2: 26162306a36Sopenharmony_ci case RT5651_GPIO_CTRL3: 26262306a36Sopenharmony_ci case RT5651_PGM_REG_ARR1: 26362306a36Sopenharmony_ci case RT5651_PGM_REG_ARR2: 26462306a36Sopenharmony_ci case RT5651_PGM_REG_ARR3: 26562306a36Sopenharmony_ci case RT5651_PGM_REG_ARR4: 26662306a36Sopenharmony_ci case RT5651_PGM_REG_ARR5: 26762306a36Sopenharmony_ci case RT5651_SCB_FUNC: 26862306a36Sopenharmony_ci case RT5651_SCB_CTRL: 26962306a36Sopenharmony_ci case RT5651_BASE_BACK: 27062306a36Sopenharmony_ci case RT5651_MP3_PLUS1: 27162306a36Sopenharmony_ci case RT5651_MP3_PLUS2: 27262306a36Sopenharmony_ci case RT5651_ADJ_HPF_CTRL1: 27362306a36Sopenharmony_ci case RT5651_ADJ_HPF_CTRL2: 27462306a36Sopenharmony_ci case RT5651_HP_CALIB_AMP_DET: 27562306a36Sopenharmony_ci case RT5651_HP_CALIB2: 27662306a36Sopenharmony_ci case RT5651_SV_ZCD1: 27762306a36Sopenharmony_ci case RT5651_SV_ZCD2: 27862306a36Sopenharmony_ci case RT5651_D_MISC: 27962306a36Sopenharmony_ci case RT5651_DUMMY2: 28062306a36Sopenharmony_ci case RT5651_DUMMY3: 28162306a36Sopenharmony_ci return true; 28262306a36Sopenharmony_ci default: 28362306a36Sopenharmony_ci return false; 28462306a36Sopenharmony_ci } 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); 28862306a36Sopenharmony_cistatic const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -6562, 0); 28962306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); 29062306a36Sopenharmony_cistatic const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -1762, 3000); 29162306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ 29462306a36Sopenharmony_cistatic const DECLARE_TLV_DB_RANGE(bst_tlv, 29562306a36Sopenharmony_ci 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 29662306a36Sopenharmony_ci 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 29762306a36Sopenharmony_ci 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), 29862306a36Sopenharmony_ci 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), 29962306a36Sopenharmony_ci 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), 30062306a36Sopenharmony_ci 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), 30162306a36Sopenharmony_ci 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) 30262306a36Sopenharmony_ci); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci/* Interface data select */ 30562306a36Sopenharmony_cistatic const char * const rt5651_data_select[] = { 30662306a36Sopenharmony_ci "Normal", "Swap", "left copy to right", "right copy to left"}; 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(rt5651_if2_dac_enum, RT5651_DIG_INF_DATA, 30962306a36Sopenharmony_ci RT5651_IF2_DAC_SEL_SFT, rt5651_data_select); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(rt5651_if2_adc_enum, RT5651_DIG_INF_DATA, 31262306a36Sopenharmony_ci RT5651_IF2_ADC_SEL_SFT, rt5651_data_select); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_snd_controls[] = { 31562306a36Sopenharmony_ci /* Headphone Output Volume */ 31662306a36Sopenharmony_ci SOC_DOUBLE_TLV("HP Playback Volume", RT5651_HP_VOL, 31762306a36Sopenharmony_ci RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 39, 1, out_vol_tlv), 31862306a36Sopenharmony_ci /* OUTPUT Control */ 31962306a36Sopenharmony_ci SOC_DOUBLE_TLV("OUT Playback Volume", RT5651_LOUT_CTRL1, 32062306a36Sopenharmony_ci RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 39, 1, out_vol_tlv), 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci /* DAC Digital Volume */ 32362306a36Sopenharmony_ci SOC_DOUBLE("DAC2 Playback Switch", RT5651_DAC2_CTRL, 32462306a36Sopenharmony_ci RT5651_M_DAC_L2_VOL_SFT, RT5651_M_DAC_R2_VOL_SFT, 1, 1), 32562306a36Sopenharmony_ci SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5651_DAC1_DIG_VOL, 32662306a36Sopenharmony_ci RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 32762306a36Sopenharmony_ci 175, 0, dac_vol_tlv), 32862306a36Sopenharmony_ci SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5651_DAC2_DIG_VOL, 32962306a36Sopenharmony_ci RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 33062306a36Sopenharmony_ci 175, 0, dac_vol_tlv), 33162306a36Sopenharmony_ci /* IN1/IN2/IN3 Control */ 33262306a36Sopenharmony_ci SOC_SINGLE_TLV("IN1 Boost", RT5651_IN1_IN2, 33362306a36Sopenharmony_ci RT5651_BST_SFT1, 8, 0, bst_tlv), 33462306a36Sopenharmony_ci SOC_SINGLE_TLV("IN2 Boost", RT5651_IN1_IN2, 33562306a36Sopenharmony_ci RT5651_BST_SFT2, 8, 0, bst_tlv), 33662306a36Sopenharmony_ci SOC_SINGLE_TLV("IN3 Boost", RT5651_IN3, 33762306a36Sopenharmony_ci RT5651_BST_SFT1, 8, 0, bst_tlv), 33862306a36Sopenharmony_ci /* INL/INR Volume Control */ 33962306a36Sopenharmony_ci SOC_DOUBLE_TLV("IN Capture Volume", RT5651_INL1_INR1_VOL, 34062306a36Sopenharmony_ci RT5651_INL_VOL_SFT, RT5651_INR_VOL_SFT, 34162306a36Sopenharmony_ci 31, 1, in_vol_tlv), 34262306a36Sopenharmony_ci /* ADC Digital Volume Control */ 34362306a36Sopenharmony_ci SOC_DOUBLE("ADC Capture Switch", RT5651_ADC_DIG_VOL, 34462306a36Sopenharmony_ci RT5651_L_MUTE_SFT, RT5651_R_MUTE_SFT, 1, 1), 34562306a36Sopenharmony_ci SOC_DOUBLE_TLV("ADC Capture Volume", RT5651_ADC_DIG_VOL, 34662306a36Sopenharmony_ci RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 34762306a36Sopenharmony_ci 127, 0, adc_vol_tlv), 34862306a36Sopenharmony_ci SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5651_ADC_DATA, 34962306a36Sopenharmony_ci RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 35062306a36Sopenharmony_ci 127, 0, adc_vol_tlv), 35162306a36Sopenharmony_ci /* ADC Boost Volume Control */ 35262306a36Sopenharmony_ci SOC_DOUBLE_TLV("ADC Boost Gain", RT5651_ADC_BST_VOL, 35362306a36Sopenharmony_ci RT5651_ADC_L_BST_SFT, RT5651_ADC_R_BST_SFT, 35462306a36Sopenharmony_ci 3, 0, adc_bst_tlv), 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci /* ASRC */ 35762306a36Sopenharmony_ci SOC_SINGLE("IF1 ASRC Switch", RT5651_PLL_MODE_1, 35862306a36Sopenharmony_ci RT5651_STO1_T_SFT, 1, 0), 35962306a36Sopenharmony_ci SOC_SINGLE("IF2 ASRC Switch", RT5651_PLL_MODE_1, 36062306a36Sopenharmony_ci RT5651_STO2_T_SFT, 1, 0), 36162306a36Sopenharmony_ci SOC_SINGLE("DMIC ASRC Switch", RT5651_PLL_MODE_1, 36262306a36Sopenharmony_ci RT5651_DMIC_1_M_SFT, 1, 0), 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci SOC_ENUM("ADC IF2 Data Switch", rt5651_if2_adc_enum), 36562306a36Sopenharmony_ci SOC_ENUM("DAC IF2 Data Switch", rt5651_if2_dac_enum), 36662306a36Sopenharmony_ci}; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci/** 36962306a36Sopenharmony_ci * set_dmic_clk - Set parameter of dmic. 37062306a36Sopenharmony_ci * 37162306a36Sopenharmony_ci * @w: DAPM widget. 37262306a36Sopenharmony_ci * @kcontrol: The kcontrol of this widget. 37362306a36Sopenharmony_ci * @event: Event id. 37462306a36Sopenharmony_ci * 37562306a36Sopenharmony_ci */ 37662306a36Sopenharmony_cistatic int set_dmic_clk(struct snd_soc_dapm_widget *w, 37762306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 37862306a36Sopenharmony_ci{ 37962306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 38062306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 38162306a36Sopenharmony_ci int idx, rate; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci rate = rt5651->sysclk / rl6231_get_pre_div(rt5651->regmap, 38462306a36Sopenharmony_ci RT5651_ADDA_CLK1, RT5651_I2S_PD1_SFT); 38562306a36Sopenharmony_ci idx = rl6231_calc_dmic_clk(rate); 38662306a36Sopenharmony_ci if (idx < 0) 38762306a36Sopenharmony_ci dev_err(component->dev, "Failed to set DMIC clock\n"); 38862306a36Sopenharmony_ci else 38962306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_DMIC, RT5651_DMIC_CLK_MASK, 39062306a36Sopenharmony_ci idx << RT5651_DMIC_CLK_SFT); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci return idx; 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci/* Digital Mixer */ 39662306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto1_adc_l_mix[] = { 39762306a36Sopenharmony_ci SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO1_ADC_MIXER, 39862306a36Sopenharmony_ci RT5651_M_STO1_ADC_L1_SFT, 1, 1), 39962306a36Sopenharmony_ci SOC_DAPM_SINGLE("ADC2 Switch", RT5651_STO1_ADC_MIXER, 40062306a36Sopenharmony_ci RT5651_M_STO1_ADC_L2_SFT, 1, 1), 40162306a36Sopenharmony_ci}; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto1_adc_r_mix[] = { 40462306a36Sopenharmony_ci SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO1_ADC_MIXER, 40562306a36Sopenharmony_ci RT5651_M_STO1_ADC_R1_SFT, 1, 1), 40662306a36Sopenharmony_ci SOC_DAPM_SINGLE("ADC2 Switch", RT5651_STO1_ADC_MIXER, 40762306a36Sopenharmony_ci RT5651_M_STO1_ADC_R2_SFT, 1, 1), 40862306a36Sopenharmony_ci}; 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto2_adc_l_mix[] = { 41162306a36Sopenharmony_ci SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO2_ADC_MIXER, 41262306a36Sopenharmony_ci RT5651_M_STO2_ADC_L1_SFT, 1, 1), 41362306a36Sopenharmony_ci SOC_DAPM_SINGLE("ADC2 Switch", RT5651_STO2_ADC_MIXER, 41462306a36Sopenharmony_ci RT5651_M_STO2_ADC_L2_SFT, 1, 1), 41562306a36Sopenharmony_ci}; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto2_adc_r_mix[] = { 41862306a36Sopenharmony_ci SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO2_ADC_MIXER, 41962306a36Sopenharmony_ci RT5651_M_STO2_ADC_R1_SFT, 1, 1), 42062306a36Sopenharmony_ci SOC_DAPM_SINGLE("ADC2 Switch", RT5651_STO2_ADC_MIXER, 42162306a36Sopenharmony_ci RT5651_M_STO2_ADC_R2_SFT, 1, 1), 42262306a36Sopenharmony_ci}; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_dac_l_mix[] = { 42562306a36Sopenharmony_ci SOC_DAPM_SINGLE("Stereo ADC Switch", RT5651_AD_DA_MIXER, 42662306a36Sopenharmony_ci RT5651_M_ADCMIX_L_SFT, 1, 1), 42762306a36Sopenharmony_ci SOC_DAPM_SINGLE("INF1 Switch", RT5651_AD_DA_MIXER, 42862306a36Sopenharmony_ci RT5651_M_IF1_DAC_L_SFT, 1, 1), 42962306a36Sopenharmony_ci}; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_dac_r_mix[] = { 43262306a36Sopenharmony_ci SOC_DAPM_SINGLE("Stereo ADC Switch", RT5651_AD_DA_MIXER, 43362306a36Sopenharmony_ci RT5651_M_ADCMIX_R_SFT, 1, 1), 43462306a36Sopenharmony_ci SOC_DAPM_SINGLE("INF1 Switch", RT5651_AD_DA_MIXER, 43562306a36Sopenharmony_ci RT5651_M_IF1_DAC_R_SFT, 1, 1), 43662306a36Sopenharmony_ci}; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto_dac_l_mix[] = { 43962306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_STO_DAC_MIXER, 44062306a36Sopenharmony_ci RT5651_M_DAC_L1_MIXL_SFT, 1, 1), 44162306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC L2 Switch", RT5651_STO_DAC_MIXER, 44262306a36Sopenharmony_ci RT5651_M_DAC_L2_MIXL_SFT, 1, 1), 44362306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_STO_DAC_MIXER, 44462306a36Sopenharmony_ci RT5651_M_DAC_R1_MIXL_SFT, 1, 1), 44562306a36Sopenharmony_ci}; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto_dac_r_mix[] = { 44862306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_STO_DAC_MIXER, 44962306a36Sopenharmony_ci RT5651_M_DAC_R1_MIXR_SFT, 1, 1), 45062306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC R2 Switch", RT5651_STO_DAC_MIXER, 45162306a36Sopenharmony_ci RT5651_M_DAC_R2_MIXR_SFT, 1, 1), 45262306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_STO_DAC_MIXER, 45362306a36Sopenharmony_ci RT5651_M_DAC_L1_MIXR_SFT, 1, 1), 45462306a36Sopenharmony_ci}; 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_dd_dac_l_mix[] = { 45762306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_DD_MIXER, 45862306a36Sopenharmony_ci RT5651_M_STO_DD_L1_SFT, 1, 1), 45962306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC L2 Switch", RT5651_DD_MIXER, 46062306a36Sopenharmony_ci RT5651_M_STO_DD_L2_SFT, 1, 1), 46162306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC R2 Switch", RT5651_DD_MIXER, 46262306a36Sopenharmony_ci RT5651_M_STO_DD_R2_L_SFT, 1, 1), 46362306a36Sopenharmony_ci}; 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_dd_dac_r_mix[] = { 46662306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_DD_MIXER, 46762306a36Sopenharmony_ci RT5651_M_STO_DD_R1_SFT, 1, 1), 46862306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC R2 Switch", RT5651_DD_MIXER, 46962306a36Sopenharmony_ci RT5651_M_STO_DD_R2_SFT, 1, 1), 47062306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC L2 Switch", RT5651_DD_MIXER, 47162306a36Sopenharmony_ci RT5651_M_STO_DD_L2_R_SFT, 1, 1), 47262306a36Sopenharmony_ci}; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci/* Analog Input Mixer */ 47562306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_rec_l_mix[] = { 47662306a36Sopenharmony_ci SOC_DAPM_SINGLE("INL1 Switch", RT5651_REC_L2_MIXER, 47762306a36Sopenharmony_ci RT5651_M_IN1_L_RM_L_SFT, 1, 1), 47862306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST3 Switch", RT5651_REC_L2_MIXER, 47962306a36Sopenharmony_ci RT5651_M_BST3_RM_L_SFT, 1, 1), 48062306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST2 Switch", RT5651_REC_L2_MIXER, 48162306a36Sopenharmony_ci RT5651_M_BST2_RM_L_SFT, 1, 1), 48262306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST1 Switch", RT5651_REC_L2_MIXER, 48362306a36Sopenharmony_ci RT5651_M_BST1_RM_L_SFT, 1, 1), 48462306a36Sopenharmony_ci}; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_rec_r_mix[] = { 48762306a36Sopenharmony_ci SOC_DAPM_SINGLE("INR1 Switch", RT5651_REC_R2_MIXER, 48862306a36Sopenharmony_ci RT5651_M_IN1_R_RM_R_SFT, 1, 1), 48962306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST3 Switch", RT5651_REC_R2_MIXER, 49062306a36Sopenharmony_ci RT5651_M_BST3_RM_R_SFT, 1, 1), 49162306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST2 Switch", RT5651_REC_R2_MIXER, 49262306a36Sopenharmony_ci RT5651_M_BST2_RM_R_SFT, 1, 1), 49362306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST1 Switch", RT5651_REC_R2_MIXER, 49462306a36Sopenharmony_ci RT5651_M_BST1_RM_R_SFT, 1, 1), 49562306a36Sopenharmony_ci}; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci/* Analog Output Mixer */ 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_out_l_mix[] = { 50062306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST1 Switch", RT5651_OUT_L3_MIXER, 50162306a36Sopenharmony_ci RT5651_M_BST1_OM_L_SFT, 1, 1), 50262306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST2 Switch", RT5651_OUT_L3_MIXER, 50362306a36Sopenharmony_ci RT5651_M_BST2_OM_L_SFT, 1, 1), 50462306a36Sopenharmony_ci SOC_DAPM_SINGLE("INL1 Switch", RT5651_OUT_L3_MIXER, 50562306a36Sopenharmony_ci RT5651_M_IN1_L_OM_L_SFT, 1, 1), 50662306a36Sopenharmony_ci SOC_DAPM_SINGLE("REC MIXL Switch", RT5651_OUT_L3_MIXER, 50762306a36Sopenharmony_ci RT5651_M_RM_L_OM_L_SFT, 1, 1), 50862306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_OUT_L3_MIXER, 50962306a36Sopenharmony_ci RT5651_M_DAC_L1_OM_L_SFT, 1, 1), 51062306a36Sopenharmony_ci}; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_out_r_mix[] = { 51362306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST2 Switch", RT5651_OUT_R3_MIXER, 51462306a36Sopenharmony_ci RT5651_M_BST2_OM_R_SFT, 1, 1), 51562306a36Sopenharmony_ci SOC_DAPM_SINGLE("BST1 Switch", RT5651_OUT_R3_MIXER, 51662306a36Sopenharmony_ci RT5651_M_BST1_OM_R_SFT, 1, 1), 51762306a36Sopenharmony_ci SOC_DAPM_SINGLE("INR1 Switch", RT5651_OUT_R3_MIXER, 51862306a36Sopenharmony_ci RT5651_M_IN1_R_OM_R_SFT, 1, 1), 51962306a36Sopenharmony_ci SOC_DAPM_SINGLE("REC MIXR Switch", RT5651_OUT_R3_MIXER, 52062306a36Sopenharmony_ci RT5651_M_RM_R_OM_R_SFT, 1, 1), 52162306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_OUT_R3_MIXER, 52262306a36Sopenharmony_ci RT5651_M_DAC_R1_OM_R_SFT, 1, 1), 52362306a36Sopenharmony_ci}; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_hpo_mix[] = { 52662306a36Sopenharmony_ci SOC_DAPM_SINGLE("HPO MIX DAC1 Switch", RT5651_HPO_MIXER, 52762306a36Sopenharmony_ci RT5651_M_DAC1_HM_SFT, 1, 1), 52862306a36Sopenharmony_ci SOC_DAPM_SINGLE("HPO MIX HPVOL Switch", RT5651_HPO_MIXER, 52962306a36Sopenharmony_ci RT5651_M_HPVOL_HM_SFT, 1, 1), 53062306a36Sopenharmony_ci}; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_lout_mix[] = { 53362306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_LOUT_MIXER, 53462306a36Sopenharmony_ci RT5651_M_DAC_L1_LM_SFT, 1, 1), 53562306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_LOUT_MIXER, 53662306a36Sopenharmony_ci RT5651_M_DAC_R1_LM_SFT, 1, 1), 53762306a36Sopenharmony_ci SOC_DAPM_SINGLE("OUTVOL L Switch", RT5651_LOUT_MIXER, 53862306a36Sopenharmony_ci RT5651_M_OV_L_LM_SFT, 1, 1), 53962306a36Sopenharmony_ci SOC_DAPM_SINGLE("OUTVOL R Switch", RT5651_LOUT_MIXER, 54062306a36Sopenharmony_ci RT5651_M_OV_R_LM_SFT, 1, 1), 54162306a36Sopenharmony_ci}; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistatic const struct snd_kcontrol_new outvol_l_control = 54462306a36Sopenharmony_ci SOC_DAPM_SINGLE("Switch", RT5651_LOUT_CTRL1, 54562306a36Sopenharmony_ci RT5651_VOL_L_SFT, 1, 1); 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_cistatic const struct snd_kcontrol_new outvol_r_control = 54862306a36Sopenharmony_ci SOC_DAPM_SINGLE("Switch", RT5651_LOUT_CTRL1, 54962306a36Sopenharmony_ci RT5651_VOL_R_SFT, 1, 1); 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_cistatic const struct snd_kcontrol_new lout_l_mute_control = 55262306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5651_LOUT_CTRL1, 55362306a36Sopenharmony_ci RT5651_L_MUTE_SFT, 1, 1); 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_cistatic const struct snd_kcontrol_new lout_r_mute_control = 55662306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5651_LOUT_CTRL1, 55762306a36Sopenharmony_ci RT5651_R_MUTE_SFT, 1, 1); 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_cistatic const struct snd_kcontrol_new hpovol_l_control = 56062306a36Sopenharmony_ci SOC_DAPM_SINGLE("Switch", RT5651_HP_VOL, 56162306a36Sopenharmony_ci RT5651_VOL_L_SFT, 1, 1); 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_cistatic const struct snd_kcontrol_new hpovol_r_control = 56462306a36Sopenharmony_ci SOC_DAPM_SINGLE("Switch", RT5651_HP_VOL, 56562306a36Sopenharmony_ci RT5651_VOL_R_SFT, 1, 1); 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_cistatic const struct snd_kcontrol_new hpo_l_mute_control = 56862306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5651_HP_VOL, 56962306a36Sopenharmony_ci RT5651_L_MUTE_SFT, 1, 1); 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_cistatic const struct snd_kcontrol_new hpo_r_mute_control = 57262306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5651_HP_VOL, 57362306a36Sopenharmony_ci RT5651_R_MUTE_SFT, 1, 1); 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci/* Stereo ADC source */ 57662306a36Sopenharmony_cistatic const char * const rt5651_stereo1_adc1_src[] = {"DD MIX", "ADC"}; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 57962306a36Sopenharmony_ci rt5651_stereo1_adc1_enum, RT5651_STO1_ADC_MIXER, 58062306a36Sopenharmony_ci RT5651_STO1_ADC_1_SRC_SFT, rt5651_stereo1_adc1_src); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto1_adc_l1_mux = 58362306a36Sopenharmony_ci SOC_DAPM_ENUM("Stereo1 ADC L1 source", rt5651_stereo1_adc1_enum); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto1_adc_r1_mux = 58662306a36Sopenharmony_ci SOC_DAPM_ENUM("Stereo1 ADC R1 source", rt5651_stereo1_adc1_enum); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_cistatic const char * const rt5651_stereo1_adc2_src[] = {"DMIC", "DD MIX"}; 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 59162306a36Sopenharmony_ci rt5651_stereo1_adc2_enum, RT5651_STO1_ADC_MIXER, 59262306a36Sopenharmony_ci RT5651_STO1_ADC_2_SRC_SFT, rt5651_stereo1_adc2_src); 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto1_adc_l2_mux = 59562306a36Sopenharmony_ci SOC_DAPM_ENUM("Stereo1 ADC L2 source", rt5651_stereo1_adc2_enum); 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto1_adc_r2_mux = 59862306a36Sopenharmony_ci SOC_DAPM_ENUM("Stereo1 ADC R2 source", rt5651_stereo1_adc2_enum); 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci/* Mono ADC source */ 60162306a36Sopenharmony_cistatic const char * const rt5651_sto2_adc_l1_src[] = {"DD MIXL", "ADCL"}; 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 60462306a36Sopenharmony_ci rt5651_sto2_adc_l1_enum, RT5651_STO1_ADC_MIXER, 60562306a36Sopenharmony_ci RT5651_STO2_ADC_L1_SRC_SFT, rt5651_sto2_adc_l1_src); 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto2_adc_l1_mux = 60862306a36Sopenharmony_ci SOC_DAPM_ENUM("Stereo2 ADC1 left source", rt5651_sto2_adc_l1_enum); 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_cistatic const char * const rt5651_sto2_adc_l2_src[] = {"DMIC L", "DD MIXL"}; 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 61362306a36Sopenharmony_ci rt5651_sto2_adc_l2_enum, RT5651_STO1_ADC_MIXER, 61462306a36Sopenharmony_ci RT5651_STO2_ADC_L2_SRC_SFT, rt5651_sto2_adc_l2_src); 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto2_adc_l2_mux = 61762306a36Sopenharmony_ci SOC_DAPM_ENUM("Stereo2 ADC2 left source", rt5651_sto2_adc_l2_enum); 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_cistatic const char * const rt5651_sto2_adc_r1_src[] = {"DD MIXR", "ADCR"}; 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 62262306a36Sopenharmony_ci rt5651_sto2_adc_r1_enum, RT5651_STO1_ADC_MIXER, 62362306a36Sopenharmony_ci RT5651_STO2_ADC_R1_SRC_SFT, rt5651_sto2_adc_r1_src); 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto2_adc_r1_mux = 62662306a36Sopenharmony_ci SOC_DAPM_ENUM("Stereo2 ADC1 right source", rt5651_sto2_adc_r1_enum); 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_cistatic const char * const rt5651_sto2_adc_r2_src[] = {"DMIC R", "DD MIXR"}; 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 63162306a36Sopenharmony_ci rt5651_sto2_adc_r2_enum, RT5651_STO1_ADC_MIXER, 63262306a36Sopenharmony_ci RT5651_STO2_ADC_R2_SRC_SFT, rt5651_sto2_adc_r2_src); 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_sto2_adc_r2_mux = 63562306a36Sopenharmony_ci SOC_DAPM_ENUM("Stereo2 ADC2 right source", rt5651_sto2_adc_r2_enum); 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci/* DAC2 channel source */ 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_cistatic const char * const rt5651_dac_src[] = {"IF1", "IF2"}; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(rt5651_dac_l2_enum, RT5651_DAC2_CTRL, 64262306a36Sopenharmony_ci RT5651_SEL_DAC_L2_SFT, rt5651_dac_src); 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_dac_l2_mux = 64562306a36Sopenharmony_ci SOC_DAPM_ENUM("DAC2 left channel source", rt5651_dac_l2_enum); 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 64862306a36Sopenharmony_ci rt5651_dac_r2_enum, RT5651_DAC2_CTRL, 64962306a36Sopenharmony_ci RT5651_SEL_DAC_R2_SFT, rt5651_dac_src); 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_dac_r2_mux = 65262306a36Sopenharmony_ci SOC_DAPM_ENUM("DAC2 right channel source", rt5651_dac_r2_enum); 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci/* IF2_ADC channel source */ 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_cistatic const char * const rt5651_adc_src[] = {"IF1 ADC1", "IF1 ADC2"}; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(rt5651_if2_adc_src_enum, RT5651_DIG_INF_DATA, 65962306a36Sopenharmony_ci RT5651_IF2_ADC_SRC_SFT, rt5651_adc_src); 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_if2_adc_src_mux = 66262306a36Sopenharmony_ci SOC_DAPM_ENUM("IF2 ADC channel source", rt5651_if2_adc_src_enum); 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci/* PDM select */ 66562306a36Sopenharmony_cistatic const char * const rt5651_pdm_sel[] = {"DD MIX", "Stereo DAC MIX"}; 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 66862306a36Sopenharmony_ci rt5651_pdm_l_sel_enum, RT5651_PDM_CTL, 66962306a36Sopenharmony_ci RT5651_PDM_L_SEL_SFT, rt5651_pdm_sel); 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 67262306a36Sopenharmony_ci rt5651_pdm_r_sel_enum, RT5651_PDM_CTL, 67362306a36Sopenharmony_ci RT5651_PDM_R_SEL_SFT, rt5651_pdm_sel); 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_pdm_l_mux = 67662306a36Sopenharmony_ci SOC_DAPM_ENUM("PDM L select", rt5651_pdm_l_sel_enum); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_cistatic const struct snd_kcontrol_new rt5651_pdm_r_mux = 67962306a36Sopenharmony_ci SOC_DAPM_ENUM("PDM R select", rt5651_pdm_r_sel_enum); 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_cistatic int rt5651_amp_power_event(struct snd_soc_dapm_widget *w, 68262306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 68362306a36Sopenharmony_ci{ 68462306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 68562306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci switch (event) { 68862306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 68962306a36Sopenharmony_ci /* depop parameters */ 69062306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_PR_BASE + 69162306a36Sopenharmony_ci RT5651_CHPUMP_INT_REG1, 0x0700, 0x0200); 69262306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M2, 69362306a36Sopenharmony_ci RT5651_DEPOP_MASK, RT5651_DEPOP_MAN); 69462306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M1, 69562306a36Sopenharmony_ci RT5651_HP_CP_MASK | RT5651_HP_SG_MASK | 69662306a36Sopenharmony_ci RT5651_HP_CB_MASK, RT5651_HP_CP_PU | 69762306a36Sopenharmony_ci RT5651_HP_SG_DIS | RT5651_HP_CB_PU); 69862306a36Sopenharmony_ci regmap_write(rt5651->regmap, RT5651_PR_BASE + 69962306a36Sopenharmony_ci RT5651_HP_DCC_INT1, 0x9f00); 70062306a36Sopenharmony_ci /* headphone amp power on */ 70162306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_PWR_ANLG1, 70262306a36Sopenharmony_ci RT5651_PWR_FV1 | RT5651_PWR_FV2, 0); 70362306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_PWR_ANLG1, 70462306a36Sopenharmony_ci RT5651_PWR_HA, 70562306a36Sopenharmony_ci RT5651_PWR_HA); 70662306a36Sopenharmony_ci usleep_range(10000, 15000); 70762306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_PWR_ANLG1, 70862306a36Sopenharmony_ci RT5651_PWR_FV1 | RT5651_PWR_FV2 , 70962306a36Sopenharmony_ci RT5651_PWR_FV1 | RT5651_PWR_FV2); 71062306a36Sopenharmony_ci break; 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci default: 71362306a36Sopenharmony_ci return 0; 71462306a36Sopenharmony_ci } 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci return 0; 71762306a36Sopenharmony_ci} 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_cistatic int rt5651_hp_event(struct snd_soc_dapm_widget *w, 72062306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 72162306a36Sopenharmony_ci{ 72262306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 72362306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci switch (event) { 72662306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 72762306a36Sopenharmony_ci /* headphone unmute sequence */ 72862306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M2, 72962306a36Sopenharmony_ci RT5651_DEPOP_MASK | RT5651_DIG_DP_MASK, 73062306a36Sopenharmony_ci RT5651_DEPOP_AUTO | RT5651_DIG_DP_EN); 73162306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_CHARGE_PUMP, 73262306a36Sopenharmony_ci RT5651_PM_HP_MASK, RT5651_PM_HP_HV); 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M3, 73562306a36Sopenharmony_ci RT5651_CP_FQ1_MASK | RT5651_CP_FQ2_MASK | 73662306a36Sopenharmony_ci RT5651_CP_FQ3_MASK, 73762306a36Sopenharmony_ci (RT5651_CP_FQ_192_KHZ << RT5651_CP_FQ1_SFT) | 73862306a36Sopenharmony_ci (RT5651_CP_FQ_12_KHZ << RT5651_CP_FQ2_SFT) | 73962306a36Sopenharmony_ci (RT5651_CP_FQ_192_KHZ << RT5651_CP_FQ3_SFT)); 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci regmap_write(rt5651->regmap, RT5651_PR_BASE + 74262306a36Sopenharmony_ci RT5651_MAMP_INT_REG2, 0x1c00); 74362306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M1, 74462306a36Sopenharmony_ci RT5651_HP_CP_MASK | RT5651_HP_SG_MASK, 74562306a36Sopenharmony_ci RT5651_HP_CP_PD | RT5651_HP_SG_EN); 74662306a36Sopenharmony_ci regmap_update_bits(rt5651->regmap, RT5651_PR_BASE + 74762306a36Sopenharmony_ci RT5651_CHPUMP_INT_REG1, 0x0700, 0x0400); 74862306a36Sopenharmony_ci rt5651->hp_mute = false; 74962306a36Sopenharmony_ci break; 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 75262306a36Sopenharmony_ci rt5651->hp_mute = true; 75362306a36Sopenharmony_ci usleep_range(70000, 75000); 75462306a36Sopenharmony_ci break; 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci default: 75762306a36Sopenharmony_ci return 0; 75862306a36Sopenharmony_ci } 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci return 0; 76162306a36Sopenharmony_ci} 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_cistatic int rt5651_hp_post_event(struct snd_soc_dapm_widget *w, 76462306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 76562306a36Sopenharmony_ci{ 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 76862306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ci switch (event) { 77162306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 77262306a36Sopenharmony_ci if (!rt5651->hp_mute) 77362306a36Sopenharmony_ci usleep_range(80000, 85000); 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_ci break; 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci default: 77862306a36Sopenharmony_ci return 0; 77962306a36Sopenharmony_ci } 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci return 0; 78262306a36Sopenharmony_ci} 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_cistatic int rt5651_bst1_event(struct snd_soc_dapm_widget *w, 78562306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 78662306a36Sopenharmony_ci{ 78762306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci switch (event) { 79062306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 79162306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 79262306a36Sopenharmony_ci RT5651_PWR_BST1_OP2, RT5651_PWR_BST1_OP2); 79362306a36Sopenharmony_ci break; 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 79662306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 79762306a36Sopenharmony_ci RT5651_PWR_BST1_OP2, 0); 79862306a36Sopenharmony_ci break; 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_ci default: 80162306a36Sopenharmony_ci return 0; 80262306a36Sopenharmony_ci } 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci return 0; 80562306a36Sopenharmony_ci} 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_cistatic int rt5651_bst2_event(struct snd_soc_dapm_widget *w, 80862306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 80962306a36Sopenharmony_ci{ 81062306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci switch (event) { 81362306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 81462306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 81562306a36Sopenharmony_ci RT5651_PWR_BST2_OP2, RT5651_PWR_BST2_OP2); 81662306a36Sopenharmony_ci break; 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 81962306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 82062306a36Sopenharmony_ci RT5651_PWR_BST2_OP2, 0); 82162306a36Sopenharmony_ci break; 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_ci default: 82462306a36Sopenharmony_ci return 0; 82562306a36Sopenharmony_ci } 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci return 0; 82862306a36Sopenharmony_ci} 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_cistatic int rt5651_bst3_event(struct snd_soc_dapm_widget *w, 83162306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 83262306a36Sopenharmony_ci{ 83362306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci switch (event) { 83662306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 83762306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 83862306a36Sopenharmony_ci RT5651_PWR_BST3_OP2, RT5651_PWR_BST3_OP2); 83962306a36Sopenharmony_ci break; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 84262306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 84362306a36Sopenharmony_ci RT5651_PWR_BST3_OP2, 0); 84462306a36Sopenharmony_ci break; 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci default: 84762306a36Sopenharmony_ci return 0; 84862306a36Sopenharmony_ci } 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci return 0; 85162306a36Sopenharmony_ci} 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = { 85462306a36Sopenharmony_ci /* ASRC */ 85562306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5651_PLL_MODE_2, 85662306a36Sopenharmony_ci 15, 0, NULL, 0), 85762306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5651_PLL_MODE_2, 85862306a36Sopenharmony_ci 14, 0, NULL, 0), 85962306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("STO1 DAC ASRC", 1, RT5651_PLL_MODE_2, 86062306a36Sopenharmony_ci 13, 0, NULL, 0), 86162306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("STO2 DAC ASRC", 1, RT5651_PLL_MODE_2, 86262306a36Sopenharmony_ci 12, 0, NULL, 0), 86362306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("ADC ASRC", 1, RT5651_PLL_MODE_2, 86462306a36Sopenharmony_ci 11, 0, NULL, 0), 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci /* micbias */ 86762306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1, 86862306a36Sopenharmony_ci RT5651_PWR_LDO_BIT, 0, NULL, 0), 86962306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("micbias1", RT5651_PWR_ANLG2, 87062306a36Sopenharmony_ci RT5651_PWR_MB1_BIT, 0, NULL, 0), 87162306a36Sopenharmony_ci /* Input Lines */ 87262306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC1"), 87362306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC2"), 87462306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC3"), 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("IN1P"), 87762306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("IN2P"), 87862306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("IN2N"), 87962306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("IN3P"), 88062306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("DMIC L1"), 88162306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("DMIC R1"), 88262306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("DMIC CLK", RT5651_DMIC, RT5651_DMIC_1_EN_SFT, 88362306a36Sopenharmony_ci 0, set_dmic_clk, SND_SOC_DAPM_PRE_PMU), 88462306a36Sopenharmony_ci /* Boost */ 88562306a36Sopenharmony_ci SND_SOC_DAPM_PGA_E("BST1", RT5651_PWR_ANLG2, 88662306a36Sopenharmony_ci RT5651_PWR_BST1_BIT, 0, NULL, 0, rt5651_bst1_event, 88762306a36Sopenharmony_ci SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 88862306a36Sopenharmony_ci SND_SOC_DAPM_PGA_E("BST2", RT5651_PWR_ANLG2, 88962306a36Sopenharmony_ci RT5651_PWR_BST2_BIT, 0, NULL, 0, rt5651_bst2_event, 89062306a36Sopenharmony_ci SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 89162306a36Sopenharmony_ci SND_SOC_DAPM_PGA_E("BST3", RT5651_PWR_ANLG2, 89262306a36Sopenharmony_ci RT5651_PWR_BST3_BIT, 0, NULL, 0, rt5651_bst3_event, 89362306a36Sopenharmony_ci SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 89462306a36Sopenharmony_ci /* Input Volume */ 89562306a36Sopenharmony_ci SND_SOC_DAPM_PGA("INL1 VOL", RT5651_PWR_VOL, 89662306a36Sopenharmony_ci RT5651_PWR_IN1_L_BIT, 0, NULL, 0), 89762306a36Sopenharmony_ci SND_SOC_DAPM_PGA("INR1 VOL", RT5651_PWR_VOL, 89862306a36Sopenharmony_ci RT5651_PWR_IN1_R_BIT, 0, NULL, 0), 89962306a36Sopenharmony_ci SND_SOC_DAPM_PGA("INL2 VOL", RT5651_PWR_VOL, 90062306a36Sopenharmony_ci RT5651_PWR_IN2_L_BIT, 0, NULL, 0), 90162306a36Sopenharmony_ci SND_SOC_DAPM_PGA("INR2 VOL", RT5651_PWR_VOL, 90262306a36Sopenharmony_ci RT5651_PWR_IN2_R_BIT, 0, NULL, 0), 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci /* REC Mixer */ 90562306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("RECMIXL", RT5651_PWR_MIXER, RT5651_PWR_RM_L_BIT, 0, 90662306a36Sopenharmony_ci rt5651_rec_l_mix, ARRAY_SIZE(rt5651_rec_l_mix)), 90762306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("RECMIXR", RT5651_PWR_MIXER, RT5651_PWR_RM_R_BIT, 0, 90862306a36Sopenharmony_ci rt5651_rec_r_mix, ARRAY_SIZE(rt5651_rec_r_mix)), 90962306a36Sopenharmony_ci /* ADCs */ 91062306a36Sopenharmony_ci SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0), 91162306a36Sopenharmony_ci SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0), 91262306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("ADC L Power", RT5651_PWR_DIG1, 91362306a36Sopenharmony_ci RT5651_PWR_ADC_L_BIT, 0, NULL, 0), 91462306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("ADC R Power", RT5651_PWR_DIG1, 91562306a36Sopenharmony_ci RT5651_PWR_ADC_R_BIT, 0, NULL, 0), 91662306a36Sopenharmony_ci /* ADC Mux */ 91762306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0, 91862306a36Sopenharmony_ci &rt5651_sto1_adc_l2_mux), 91962306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0, 92062306a36Sopenharmony_ci &rt5651_sto1_adc_r2_mux), 92162306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0, 92262306a36Sopenharmony_ci &rt5651_sto1_adc_l1_mux), 92362306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0, 92462306a36Sopenharmony_ci &rt5651_sto1_adc_r1_mux), 92562306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0, 92662306a36Sopenharmony_ci &rt5651_sto2_adc_l2_mux), 92762306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0, 92862306a36Sopenharmony_ci &rt5651_sto2_adc_l1_mux), 92962306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0, 93062306a36Sopenharmony_ci &rt5651_sto2_adc_r1_mux), 93162306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0, 93262306a36Sopenharmony_ci &rt5651_sto2_adc_r2_mux), 93362306a36Sopenharmony_ci /* ADC Mixer */ 93462306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Stereo1 Filter", RT5651_PWR_DIG2, 93562306a36Sopenharmony_ci RT5651_PWR_ADC_STO1_F_BIT, 0, NULL, 0), 93662306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Stereo2 Filter", RT5651_PWR_DIG2, 93762306a36Sopenharmony_ci RT5651_PWR_ADC_STO2_F_BIT, 0, NULL, 0), 93862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, 93962306a36Sopenharmony_ci rt5651_sto1_adc_l_mix, 94062306a36Sopenharmony_ci ARRAY_SIZE(rt5651_sto1_adc_l_mix)), 94162306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0, 94262306a36Sopenharmony_ci rt5651_sto1_adc_r_mix, 94362306a36Sopenharmony_ci ARRAY_SIZE(rt5651_sto1_adc_r_mix)), 94462306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo2 ADC MIXL", SND_SOC_NOPM, 0, 0, 94562306a36Sopenharmony_ci rt5651_sto2_adc_l_mix, 94662306a36Sopenharmony_ci ARRAY_SIZE(rt5651_sto2_adc_l_mix)), 94762306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo2 ADC MIXR", SND_SOC_NOPM, 0, 0, 94862306a36Sopenharmony_ci rt5651_sto2_adc_r_mix, 94962306a36Sopenharmony_ci ARRAY_SIZE(rt5651_sto2_adc_r_mix)), 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci /* Digital Interface */ 95262306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("I2S1", RT5651_PWR_DIG1, 95362306a36Sopenharmony_ci RT5651_PWR_I2S1_BIT, 0, NULL, 0), 95462306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), 95562306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0), 95662306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0), 95762306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), 95862306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0), 95962306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0), 96062306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), 96162306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("I2S2", RT5651_PWR_DIG1, 96262306a36Sopenharmony_ci RT5651_PWR_I2S2_BIT, 0, NULL, 0), 96362306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), 96462306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), 96562306a36Sopenharmony_ci SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), 96662306a36Sopenharmony_ci SND_SOC_DAPM_MUX("IF2 ADC", SND_SOC_NOPM, 0, 0, 96762306a36Sopenharmony_ci &rt5651_if2_adc_src_mux), 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci /* Digital Interface Select */ 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci SND_SOC_DAPM_MUX("PDM L Mux", RT5651_PDM_CTL, 97262306a36Sopenharmony_ci RT5651_M_PDM_L_SFT, 1, &rt5651_pdm_l_mux), 97362306a36Sopenharmony_ci SND_SOC_DAPM_MUX("PDM R Mux", RT5651_PDM_CTL, 97462306a36Sopenharmony_ci RT5651_M_PDM_R_SFT, 1, &rt5651_pdm_r_mux), 97562306a36Sopenharmony_ci /* Audio Interface */ 97662306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 97762306a36Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), 97862306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), 97962306a36Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci /* Audio DSP */ 98262306a36Sopenharmony_ci SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ci /* Output Side */ 98562306a36Sopenharmony_ci /* DAC mixer before sound effect */ 98662306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, 98762306a36Sopenharmony_ci rt5651_dac_l_mix, ARRAY_SIZE(rt5651_dac_l_mix)), 98862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, 98962306a36Sopenharmony_ci rt5651_dac_r_mix, ARRAY_SIZE(rt5651_dac_r_mix)), 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci /* DAC2 channel Mux */ 99262306a36Sopenharmony_ci SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5651_dac_l2_mux), 99362306a36Sopenharmony_ci SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5651_dac_r2_mux), 99462306a36Sopenharmony_ci SND_SOC_DAPM_PGA("DAC L2 Volume", SND_SOC_NOPM, 0, 0, NULL, 0), 99562306a36Sopenharmony_ci SND_SOC_DAPM_PGA("DAC R2 Volume", SND_SOC_NOPM, 0, 0, NULL, 0), 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Stero1 DAC Power", RT5651_PWR_DIG2, 99862306a36Sopenharmony_ci RT5651_PWR_DAC_STO1_F_BIT, 0, NULL, 0), 99962306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Stero2 DAC Power", RT5651_PWR_DIG2, 100062306a36Sopenharmony_ci RT5651_PWR_DAC_STO2_F_BIT, 0, NULL, 0), 100162306a36Sopenharmony_ci /* DAC Mixer */ 100262306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, 100362306a36Sopenharmony_ci rt5651_sto_dac_l_mix, 100462306a36Sopenharmony_ci ARRAY_SIZE(rt5651_sto_dac_l_mix)), 100562306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, 100662306a36Sopenharmony_ci rt5651_sto_dac_r_mix, 100762306a36Sopenharmony_ci ARRAY_SIZE(rt5651_sto_dac_r_mix)), 100862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("DD MIXL", SND_SOC_NOPM, 0, 0, 100962306a36Sopenharmony_ci rt5651_dd_dac_l_mix, 101062306a36Sopenharmony_ci ARRAY_SIZE(rt5651_dd_dac_l_mix)), 101162306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("DD MIXR", SND_SOC_NOPM, 0, 0, 101262306a36Sopenharmony_ci rt5651_dd_dac_r_mix, 101362306a36Sopenharmony_ci ARRAY_SIZE(rt5651_dd_dac_r_mix)), 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_ci /* DACs */ 101662306a36Sopenharmony_ci SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0), 101762306a36Sopenharmony_ci SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0), 101862306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("DAC L1 Power", RT5651_PWR_DIG1, 101962306a36Sopenharmony_ci RT5651_PWR_DAC_L1_BIT, 0, NULL, 0), 102062306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5651_PWR_DIG1, 102162306a36Sopenharmony_ci RT5651_PWR_DAC_R1_BIT, 0, NULL, 0), 102262306a36Sopenharmony_ci /* OUT Mixer */ 102362306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("OUT MIXL", RT5651_PWR_MIXER, RT5651_PWR_OM_L_BIT, 102462306a36Sopenharmony_ci 0, rt5651_out_l_mix, ARRAY_SIZE(rt5651_out_l_mix)), 102562306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("OUT MIXR", RT5651_PWR_MIXER, RT5651_PWR_OM_R_BIT, 102662306a36Sopenharmony_ci 0, rt5651_out_r_mix, ARRAY_SIZE(rt5651_out_r_mix)), 102762306a36Sopenharmony_ci /* Ouput Volume */ 102862306a36Sopenharmony_ci SND_SOC_DAPM_SWITCH("OUTVOL L", RT5651_PWR_VOL, 102962306a36Sopenharmony_ci RT5651_PWR_OV_L_BIT, 0, &outvol_l_control), 103062306a36Sopenharmony_ci SND_SOC_DAPM_SWITCH("OUTVOL R", RT5651_PWR_VOL, 103162306a36Sopenharmony_ci RT5651_PWR_OV_R_BIT, 0, &outvol_r_control), 103262306a36Sopenharmony_ci SND_SOC_DAPM_SWITCH("HPOVOL L", RT5651_PWR_VOL, 103362306a36Sopenharmony_ci RT5651_PWR_HV_L_BIT, 0, &hpovol_l_control), 103462306a36Sopenharmony_ci SND_SOC_DAPM_SWITCH("HPOVOL R", RT5651_PWR_VOL, 103562306a36Sopenharmony_ci RT5651_PWR_HV_R_BIT, 0, &hpovol_r_control), 103662306a36Sopenharmony_ci SND_SOC_DAPM_PGA("INL1", RT5651_PWR_VOL, 103762306a36Sopenharmony_ci RT5651_PWR_IN1_L_BIT, 0, NULL, 0), 103862306a36Sopenharmony_ci SND_SOC_DAPM_PGA("INR1", RT5651_PWR_VOL, 103962306a36Sopenharmony_ci RT5651_PWR_IN1_R_BIT, 0, NULL, 0), 104062306a36Sopenharmony_ci SND_SOC_DAPM_PGA("INL2", RT5651_PWR_VOL, 104162306a36Sopenharmony_ci RT5651_PWR_IN2_L_BIT, 0, NULL, 0), 104262306a36Sopenharmony_ci SND_SOC_DAPM_PGA("INR2", RT5651_PWR_VOL, 104362306a36Sopenharmony_ci RT5651_PWR_IN2_R_BIT, 0, NULL, 0), 104462306a36Sopenharmony_ci /* HPO/LOUT/Mono Mixer */ 104562306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("HPOL MIX", SND_SOC_NOPM, 0, 0, 104662306a36Sopenharmony_ci rt5651_hpo_mix, ARRAY_SIZE(rt5651_hpo_mix)), 104762306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("HPOR MIX", SND_SOC_NOPM, 0, 0, 104862306a36Sopenharmony_ci rt5651_hpo_mix, ARRAY_SIZE(rt5651_hpo_mix)), 104962306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("HP L Amp", RT5651_PWR_ANLG1, 105062306a36Sopenharmony_ci RT5651_PWR_HP_L_BIT, 0, NULL, 0), 105162306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("HP R Amp", RT5651_PWR_ANLG1, 105262306a36Sopenharmony_ci RT5651_PWR_HP_R_BIT, 0, NULL, 0), 105362306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("LOUT MIX", RT5651_PWR_ANLG1, RT5651_PWR_LM_BIT, 0, 105462306a36Sopenharmony_ci rt5651_lout_mix, ARRAY_SIZE(rt5651_lout_mix)), 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Amp Power", RT5651_PWR_ANLG1, 105762306a36Sopenharmony_ci RT5651_PWR_HA_BIT, 0, rt5651_amp_power_event, 105862306a36Sopenharmony_ci SND_SOC_DAPM_POST_PMU), 105962306a36Sopenharmony_ci SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5651_hp_event, 106062306a36Sopenharmony_ci SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 106162306a36Sopenharmony_ci SND_SOC_DAPM_SWITCH("HPO L Playback", SND_SOC_NOPM, 0, 0, 106262306a36Sopenharmony_ci &hpo_l_mute_control), 106362306a36Sopenharmony_ci SND_SOC_DAPM_SWITCH("HPO R Playback", SND_SOC_NOPM, 0, 0, 106462306a36Sopenharmony_ci &hpo_r_mute_control), 106562306a36Sopenharmony_ci SND_SOC_DAPM_SWITCH("LOUT L Playback", SND_SOC_NOPM, 0, 0, 106662306a36Sopenharmony_ci &lout_l_mute_control), 106762306a36Sopenharmony_ci SND_SOC_DAPM_SWITCH("LOUT R Playback", SND_SOC_NOPM, 0, 0, 106862306a36Sopenharmony_ci &lout_r_mute_control), 106962306a36Sopenharmony_ci SND_SOC_DAPM_POST("HP Post", rt5651_hp_post_event), 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci /* Output Lines */ 107262306a36Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPOL"), 107362306a36Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPOR"), 107462306a36Sopenharmony_ci SND_SOC_DAPM_OUTPUT("LOUTL"), 107562306a36Sopenharmony_ci SND_SOC_DAPM_OUTPUT("LOUTR"), 107662306a36Sopenharmony_ci SND_SOC_DAPM_OUTPUT("PDML"), 107762306a36Sopenharmony_ci SND_SOC_DAPM_OUTPUT("PDMR"), 107862306a36Sopenharmony_ci}; 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_cistatic const struct snd_soc_dapm_route rt5651_dapm_routes[] = { 108162306a36Sopenharmony_ci {"Stero1 DAC Power", NULL, "STO1 DAC ASRC"}, 108262306a36Sopenharmony_ci {"Stero2 DAC Power", NULL, "STO2 DAC ASRC"}, 108362306a36Sopenharmony_ci {"I2S1", NULL, "I2S1 ASRC"}, 108462306a36Sopenharmony_ci {"I2S2", NULL, "I2S2 ASRC"}, 108562306a36Sopenharmony_ci 108662306a36Sopenharmony_ci {"IN1P", NULL, "LDO"}, 108762306a36Sopenharmony_ci {"IN2P", NULL, "LDO"}, 108862306a36Sopenharmony_ci {"IN3P", NULL, "LDO"}, 108962306a36Sopenharmony_ci 109062306a36Sopenharmony_ci {"IN1P", NULL, "MIC1"}, 109162306a36Sopenharmony_ci {"IN2P", NULL, "MIC2"}, 109262306a36Sopenharmony_ci {"IN2N", NULL, "MIC2"}, 109362306a36Sopenharmony_ci {"IN3P", NULL, "MIC3"}, 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_ci {"BST1", NULL, "IN1P"}, 109662306a36Sopenharmony_ci {"BST2", NULL, "IN2P"}, 109762306a36Sopenharmony_ci {"BST2", NULL, "IN2N"}, 109862306a36Sopenharmony_ci {"BST3", NULL, "IN3P"}, 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci {"INL1 VOL", NULL, "IN2P"}, 110162306a36Sopenharmony_ci {"INR1 VOL", NULL, "IN2N"}, 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci {"RECMIXL", "INL1 Switch", "INL1 VOL"}, 110462306a36Sopenharmony_ci {"RECMIXL", "BST3 Switch", "BST3"}, 110562306a36Sopenharmony_ci {"RECMIXL", "BST2 Switch", "BST2"}, 110662306a36Sopenharmony_ci {"RECMIXL", "BST1 Switch", "BST1"}, 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_ci {"RECMIXR", "INR1 Switch", "INR1 VOL"}, 110962306a36Sopenharmony_ci {"RECMIXR", "BST3 Switch", "BST3"}, 111062306a36Sopenharmony_ci {"RECMIXR", "BST2 Switch", "BST2"}, 111162306a36Sopenharmony_ci {"RECMIXR", "BST1 Switch", "BST1"}, 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci {"ADC L", NULL, "RECMIXL"}, 111462306a36Sopenharmony_ci {"ADC L", NULL, "ADC L Power"}, 111562306a36Sopenharmony_ci {"ADC R", NULL, "RECMIXR"}, 111662306a36Sopenharmony_ci {"ADC R", NULL, "ADC R Power"}, 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_ci {"DMIC L1", NULL, "DMIC CLK"}, 111962306a36Sopenharmony_ci {"DMIC R1", NULL, "DMIC CLK"}, 112062306a36Sopenharmony_ci 112162306a36Sopenharmony_ci {"Stereo1 ADC L2 Mux", "DMIC", "DMIC L1"}, 112262306a36Sopenharmony_ci {"Stereo1 ADC L2 Mux", "DD MIX", "DD MIXL"}, 112362306a36Sopenharmony_ci {"Stereo1 ADC L1 Mux", "ADC", "ADC L"}, 112462306a36Sopenharmony_ci {"Stereo1 ADC L1 Mux", "DD MIX", "DD MIXL"}, 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ci {"Stereo1 ADC R1 Mux", "ADC", "ADC R"}, 112762306a36Sopenharmony_ci {"Stereo1 ADC R1 Mux", "DD MIX", "DD MIXR"}, 112862306a36Sopenharmony_ci {"Stereo1 ADC R2 Mux", "DMIC", "DMIC R1"}, 112962306a36Sopenharmony_ci {"Stereo1 ADC R2 Mux", "DD MIX", "DD MIXR"}, 113062306a36Sopenharmony_ci 113162306a36Sopenharmony_ci {"Stereo2 ADC L2 Mux", "DMIC L", "DMIC L1"}, 113262306a36Sopenharmony_ci {"Stereo2 ADC L2 Mux", "DD MIXL", "DD MIXL"}, 113362306a36Sopenharmony_ci {"Stereo2 ADC L1 Mux", "DD MIXL", "DD MIXL"}, 113462306a36Sopenharmony_ci {"Stereo2 ADC L1 Mux", "ADCL", "ADC L"}, 113562306a36Sopenharmony_ci 113662306a36Sopenharmony_ci {"Stereo2 ADC R1 Mux", "DD MIXR", "DD MIXR"}, 113762306a36Sopenharmony_ci {"Stereo2 ADC R1 Mux", "ADCR", "ADC R"}, 113862306a36Sopenharmony_ci {"Stereo2 ADC R2 Mux", "DMIC R", "DMIC R1"}, 113962306a36Sopenharmony_ci {"Stereo2 ADC R2 Mux", "DD MIXR", "DD MIXR"}, 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_ci {"Stereo1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux"}, 114262306a36Sopenharmony_ci {"Stereo1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux"}, 114362306a36Sopenharmony_ci {"Stereo1 ADC MIXL", NULL, "Stereo1 Filter"}, 114462306a36Sopenharmony_ci {"Stereo1 Filter", NULL, "ADC ASRC"}, 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci {"Stereo1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux"}, 114762306a36Sopenharmony_ci {"Stereo1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux"}, 114862306a36Sopenharmony_ci {"Stereo1 ADC MIXR", NULL, "Stereo1 Filter"}, 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci {"Stereo2 ADC MIXL", "ADC1 Switch", "Stereo2 ADC L1 Mux"}, 115162306a36Sopenharmony_ci {"Stereo2 ADC MIXL", "ADC2 Switch", "Stereo2 ADC L2 Mux"}, 115262306a36Sopenharmony_ci {"Stereo2 ADC MIXL", NULL, "Stereo2 Filter"}, 115362306a36Sopenharmony_ci {"Stereo2 Filter", NULL, "ADC ASRC"}, 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci {"Stereo2 ADC MIXR", "ADC1 Switch", "Stereo2 ADC R1 Mux"}, 115662306a36Sopenharmony_ci {"Stereo2 ADC MIXR", "ADC2 Switch", "Stereo2 ADC R2 Mux"}, 115762306a36Sopenharmony_ci {"Stereo2 ADC MIXR", NULL, "Stereo2 Filter"}, 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_ci {"IF1 ADC2", NULL, "Stereo2 ADC MIXL"}, 116062306a36Sopenharmony_ci {"IF1 ADC2", NULL, "Stereo2 ADC MIXR"}, 116162306a36Sopenharmony_ci {"IF1 ADC1", NULL, "Stereo1 ADC MIXL"}, 116262306a36Sopenharmony_ci {"IF1 ADC1", NULL, "Stereo1 ADC MIXR"}, 116362306a36Sopenharmony_ci 116462306a36Sopenharmony_ci {"IF1 ADC1", NULL, "I2S1"}, 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci {"IF2 ADC", "IF1 ADC1", "IF1 ADC1"}, 116762306a36Sopenharmony_ci {"IF2 ADC", "IF1 ADC2", "IF1 ADC2"}, 116862306a36Sopenharmony_ci {"IF2 ADC", NULL, "I2S2"}, 116962306a36Sopenharmony_ci 117062306a36Sopenharmony_ci {"AIF1TX", NULL, "IF1 ADC1"}, 117162306a36Sopenharmony_ci {"AIF1TX", NULL, "IF1 ADC2"}, 117262306a36Sopenharmony_ci {"AIF2TX", NULL, "IF2 ADC"}, 117362306a36Sopenharmony_ci 117462306a36Sopenharmony_ci {"IF1 DAC", NULL, "AIF1RX"}, 117562306a36Sopenharmony_ci {"IF1 DAC", NULL, "I2S1"}, 117662306a36Sopenharmony_ci {"IF2 DAC", NULL, "AIF2RX"}, 117762306a36Sopenharmony_ci {"IF2 DAC", NULL, "I2S2"}, 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_ci {"IF1 DAC1 L", NULL, "IF1 DAC"}, 118062306a36Sopenharmony_ci {"IF1 DAC1 R", NULL, "IF1 DAC"}, 118162306a36Sopenharmony_ci {"IF1 DAC2 L", NULL, "IF1 DAC"}, 118262306a36Sopenharmony_ci {"IF1 DAC2 R", NULL, "IF1 DAC"}, 118362306a36Sopenharmony_ci {"IF2 DAC L", NULL, "IF2 DAC"}, 118462306a36Sopenharmony_ci {"IF2 DAC R", NULL, "IF2 DAC"}, 118562306a36Sopenharmony_ci 118662306a36Sopenharmony_ci {"DAC MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL"}, 118762306a36Sopenharmony_ci {"DAC MIXL", "INF1 Switch", "IF1 DAC1 L"}, 118862306a36Sopenharmony_ci {"DAC MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR"}, 118962306a36Sopenharmony_ci {"DAC MIXR", "INF1 Switch", "IF1 DAC1 R"}, 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci {"Audio DSP", NULL, "DAC MIXL"}, 119262306a36Sopenharmony_ci {"Audio DSP", NULL, "DAC MIXR"}, 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_ci {"DAC L2 Mux", "IF1", "IF1 DAC2 L"}, 119562306a36Sopenharmony_ci {"DAC L2 Mux", "IF2", "IF2 DAC L"}, 119662306a36Sopenharmony_ci {"DAC L2 Volume", NULL, "DAC L2 Mux"}, 119762306a36Sopenharmony_ci 119862306a36Sopenharmony_ci {"DAC R2 Mux", "IF1", "IF1 DAC2 R"}, 119962306a36Sopenharmony_ci {"DAC R2 Mux", "IF2", "IF2 DAC R"}, 120062306a36Sopenharmony_ci {"DAC R2 Volume", NULL, "DAC R2 Mux"}, 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci {"Stereo DAC MIXL", "DAC L1 Switch", "Audio DSP"}, 120362306a36Sopenharmony_ci {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume"}, 120462306a36Sopenharmony_ci {"Stereo DAC MIXL", "DAC R1 Switch", "DAC MIXR"}, 120562306a36Sopenharmony_ci {"Stereo DAC MIXL", NULL, "Stero1 DAC Power"}, 120662306a36Sopenharmony_ci {"Stereo DAC MIXL", NULL, "Stero2 DAC Power"}, 120762306a36Sopenharmony_ci {"Stereo DAC MIXR", "DAC R1 Switch", "Audio DSP"}, 120862306a36Sopenharmony_ci {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume"}, 120962306a36Sopenharmony_ci {"Stereo DAC MIXR", "DAC L1 Switch", "DAC MIXL"}, 121062306a36Sopenharmony_ci {"Stereo DAC MIXR", NULL, "Stero1 DAC Power"}, 121162306a36Sopenharmony_ci {"Stereo DAC MIXR", NULL, "Stero2 DAC Power"}, 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_ci {"PDM L Mux", "Stereo DAC MIX", "Stereo DAC MIXL"}, 121462306a36Sopenharmony_ci {"PDM L Mux", "DD MIX", "DAC MIXL"}, 121562306a36Sopenharmony_ci {"PDM R Mux", "Stereo DAC MIX", "Stereo DAC MIXR"}, 121662306a36Sopenharmony_ci {"PDM R Mux", "DD MIX", "DAC MIXR"}, 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci {"DAC L1", NULL, "Stereo DAC MIXL"}, 121962306a36Sopenharmony_ci {"DAC L1", NULL, "DAC L1 Power"}, 122062306a36Sopenharmony_ci {"DAC R1", NULL, "Stereo DAC MIXR"}, 122162306a36Sopenharmony_ci {"DAC R1", NULL, "DAC R1 Power"}, 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci {"DD MIXL", "DAC L1 Switch", "DAC MIXL"}, 122462306a36Sopenharmony_ci {"DD MIXL", "DAC L2 Switch", "DAC L2 Volume"}, 122562306a36Sopenharmony_ci {"DD MIXL", "DAC R2 Switch", "DAC R2 Volume"}, 122662306a36Sopenharmony_ci {"DD MIXL", NULL, "Stero2 DAC Power"}, 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci {"DD MIXR", "DAC R1 Switch", "DAC MIXR"}, 122962306a36Sopenharmony_ci {"DD MIXR", "DAC R2 Switch", "DAC R2 Volume"}, 123062306a36Sopenharmony_ci {"DD MIXR", "DAC L2 Switch", "DAC L2 Volume"}, 123162306a36Sopenharmony_ci {"DD MIXR", NULL, "Stero2 DAC Power"}, 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_ci {"OUT MIXL", "BST1 Switch", "BST1"}, 123462306a36Sopenharmony_ci {"OUT MIXL", "BST2 Switch", "BST2"}, 123562306a36Sopenharmony_ci {"OUT MIXL", "INL1 Switch", "INL1 VOL"}, 123662306a36Sopenharmony_ci {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, 123762306a36Sopenharmony_ci {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci {"OUT MIXR", "BST2 Switch", "BST2"}, 124062306a36Sopenharmony_ci {"OUT MIXR", "BST1 Switch", "BST1"}, 124162306a36Sopenharmony_ci {"OUT MIXR", "INR1 Switch", "INR1 VOL"}, 124262306a36Sopenharmony_ci {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, 124362306a36Sopenharmony_ci {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci {"HPOVOL L", "Switch", "OUT MIXL"}, 124662306a36Sopenharmony_ci {"HPOVOL R", "Switch", "OUT MIXR"}, 124762306a36Sopenharmony_ci {"OUTVOL L", "Switch", "OUT MIXL"}, 124862306a36Sopenharmony_ci {"OUTVOL R", "Switch", "OUT MIXR"}, 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci {"HPOL MIX", "HPO MIX DAC1 Switch", "DAC L1"}, 125162306a36Sopenharmony_ci {"HPOL MIX", "HPO MIX HPVOL Switch", "HPOVOL L"}, 125262306a36Sopenharmony_ci {"HPOL MIX", NULL, "HP L Amp"}, 125362306a36Sopenharmony_ci {"HPOR MIX", "HPO MIX DAC1 Switch", "DAC R1"}, 125462306a36Sopenharmony_ci {"HPOR MIX", "HPO MIX HPVOL Switch", "HPOVOL R"}, 125562306a36Sopenharmony_ci {"HPOR MIX", NULL, "HP R Amp"}, 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_ci {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, 125862306a36Sopenharmony_ci {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, 125962306a36Sopenharmony_ci {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, 126062306a36Sopenharmony_ci {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, 126162306a36Sopenharmony_ci 126262306a36Sopenharmony_ci {"HP Amp", NULL, "HPOL MIX"}, 126362306a36Sopenharmony_ci {"HP Amp", NULL, "HPOR MIX"}, 126462306a36Sopenharmony_ci {"HP Amp", NULL, "Amp Power"}, 126562306a36Sopenharmony_ci {"HPO L Playback", "Switch", "HP Amp"}, 126662306a36Sopenharmony_ci {"HPO R Playback", "Switch", "HP Amp"}, 126762306a36Sopenharmony_ci {"HPOL", NULL, "HPO L Playback"}, 126862306a36Sopenharmony_ci {"HPOR", NULL, "HPO R Playback"}, 126962306a36Sopenharmony_ci 127062306a36Sopenharmony_ci {"LOUT L Playback", "Switch", "LOUT MIX"}, 127162306a36Sopenharmony_ci {"LOUT R Playback", "Switch", "LOUT MIX"}, 127262306a36Sopenharmony_ci {"LOUTL", NULL, "LOUT L Playback"}, 127362306a36Sopenharmony_ci {"LOUTL", NULL, "Amp Power"}, 127462306a36Sopenharmony_ci {"LOUTR", NULL, "LOUT R Playback"}, 127562306a36Sopenharmony_ci {"LOUTR", NULL, "Amp Power"}, 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_ci {"PDML", NULL, "PDM L Mux"}, 127862306a36Sopenharmony_ci {"PDMR", NULL, "PDM R Mux"}, 127962306a36Sopenharmony_ci}; 128062306a36Sopenharmony_ci 128162306a36Sopenharmony_cistatic int rt5651_hw_params(struct snd_pcm_substream *substream, 128262306a36Sopenharmony_ci struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 128362306a36Sopenharmony_ci{ 128462306a36Sopenharmony_ci struct snd_soc_component *component = dai->component; 128562306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 128662306a36Sopenharmony_ci unsigned int val_len = 0, val_clk, mask_clk; 128762306a36Sopenharmony_ci int pre_div, bclk_ms, frame_size; 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci rt5651->lrck[dai->id] = params_rate(params); 129062306a36Sopenharmony_ci pre_div = rl6231_get_clk_info(rt5651->sysclk, rt5651->lrck[dai->id]); 129162306a36Sopenharmony_ci 129262306a36Sopenharmony_ci if (pre_div < 0) { 129362306a36Sopenharmony_ci dev_err(component->dev, "Unsupported clock setting\n"); 129462306a36Sopenharmony_ci return -EINVAL; 129562306a36Sopenharmony_ci } 129662306a36Sopenharmony_ci frame_size = snd_soc_params_to_frame_size(params); 129762306a36Sopenharmony_ci if (frame_size < 0) { 129862306a36Sopenharmony_ci dev_err(component->dev, "Unsupported frame size: %d\n", frame_size); 129962306a36Sopenharmony_ci return -EINVAL; 130062306a36Sopenharmony_ci } 130162306a36Sopenharmony_ci bclk_ms = frame_size > 32 ? 1 : 0; 130262306a36Sopenharmony_ci rt5651->bclk[dai->id] = rt5651->lrck[dai->id] * (32 << bclk_ms); 130362306a36Sopenharmony_ci 130462306a36Sopenharmony_ci dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n", 130562306a36Sopenharmony_ci rt5651->bclk[dai->id], rt5651->lrck[dai->id]); 130662306a36Sopenharmony_ci dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", 130762306a36Sopenharmony_ci bclk_ms, pre_div, dai->id); 130862306a36Sopenharmony_ci 130962306a36Sopenharmony_ci switch (params_width(params)) { 131062306a36Sopenharmony_ci case 16: 131162306a36Sopenharmony_ci break; 131262306a36Sopenharmony_ci case 20: 131362306a36Sopenharmony_ci val_len |= RT5651_I2S_DL_20; 131462306a36Sopenharmony_ci break; 131562306a36Sopenharmony_ci case 24: 131662306a36Sopenharmony_ci val_len |= RT5651_I2S_DL_24; 131762306a36Sopenharmony_ci break; 131862306a36Sopenharmony_ci case 8: 131962306a36Sopenharmony_ci val_len |= RT5651_I2S_DL_8; 132062306a36Sopenharmony_ci break; 132162306a36Sopenharmony_ci default: 132262306a36Sopenharmony_ci return -EINVAL; 132362306a36Sopenharmony_ci } 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_ci switch (dai->id) { 132662306a36Sopenharmony_ci case RT5651_AIF1: 132762306a36Sopenharmony_ci mask_clk = RT5651_I2S_PD1_MASK; 132862306a36Sopenharmony_ci val_clk = pre_div << RT5651_I2S_PD1_SFT; 132962306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_I2S1_SDP, 133062306a36Sopenharmony_ci RT5651_I2S_DL_MASK, val_len); 133162306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_ADDA_CLK1, mask_clk, val_clk); 133262306a36Sopenharmony_ci break; 133362306a36Sopenharmony_ci case RT5651_AIF2: 133462306a36Sopenharmony_ci mask_clk = RT5651_I2S_BCLK_MS2_MASK | RT5651_I2S_PD2_MASK; 133562306a36Sopenharmony_ci val_clk = pre_div << RT5651_I2S_PD2_SFT; 133662306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_I2S2_SDP, 133762306a36Sopenharmony_ci RT5651_I2S_DL_MASK, val_len); 133862306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_ADDA_CLK1, mask_clk, val_clk); 133962306a36Sopenharmony_ci break; 134062306a36Sopenharmony_ci default: 134162306a36Sopenharmony_ci dev_err(component->dev, "Wrong dai->id: %d\n", dai->id); 134262306a36Sopenharmony_ci return -EINVAL; 134362306a36Sopenharmony_ci } 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_ci return 0; 134662306a36Sopenharmony_ci} 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_cistatic int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 134962306a36Sopenharmony_ci{ 135062306a36Sopenharmony_ci struct snd_soc_component *component = dai->component; 135162306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 135262306a36Sopenharmony_ci unsigned int reg_val = 0; 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 135562306a36Sopenharmony_ci case SND_SOC_DAIFMT_CBM_CFM: 135662306a36Sopenharmony_ci rt5651->master[dai->id] = 1; 135762306a36Sopenharmony_ci break; 135862306a36Sopenharmony_ci case SND_SOC_DAIFMT_CBS_CFS: 135962306a36Sopenharmony_ci reg_val |= RT5651_I2S_MS_S; 136062306a36Sopenharmony_ci rt5651->master[dai->id] = 0; 136162306a36Sopenharmony_ci break; 136262306a36Sopenharmony_ci default: 136362306a36Sopenharmony_ci return -EINVAL; 136462306a36Sopenharmony_ci } 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 136762306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_NF: 136862306a36Sopenharmony_ci break; 136962306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_NF: 137062306a36Sopenharmony_ci reg_val |= RT5651_I2S_BP_INV; 137162306a36Sopenharmony_ci break; 137262306a36Sopenharmony_ci default: 137362306a36Sopenharmony_ci return -EINVAL; 137462306a36Sopenharmony_ci } 137562306a36Sopenharmony_ci 137662306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 137762306a36Sopenharmony_ci case SND_SOC_DAIFMT_I2S: 137862306a36Sopenharmony_ci break; 137962306a36Sopenharmony_ci case SND_SOC_DAIFMT_LEFT_J: 138062306a36Sopenharmony_ci reg_val |= RT5651_I2S_DF_LEFT; 138162306a36Sopenharmony_ci break; 138262306a36Sopenharmony_ci case SND_SOC_DAIFMT_DSP_A: 138362306a36Sopenharmony_ci reg_val |= RT5651_I2S_DF_PCM_A; 138462306a36Sopenharmony_ci break; 138562306a36Sopenharmony_ci case SND_SOC_DAIFMT_DSP_B: 138662306a36Sopenharmony_ci reg_val |= RT5651_I2S_DF_PCM_B; 138762306a36Sopenharmony_ci break; 138862306a36Sopenharmony_ci default: 138962306a36Sopenharmony_ci return -EINVAL; 139062306a36Sopenharmony_ci } 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci switch (dai->id) { 139362306a36Sopenharmony_ci case RT5651_AIF1: 139462306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_I2S1_SDP, 139562306a36Sopenharmony_ci RT5651_I2S_MS_MASK | RT5651_I2S_BP_MASK | 139662306a36Sopenharmony_ci RT5651_I2S_DF_MASK, reg_val); 139762306a36Sopenharmony_ci break; 139862306a36Sopenharmony_ci case RT5651_AIF2: 139962306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_I2S2_SDP, 140062306a36Sopenharmony_ci RT5651_I2S_MS_MASK | RT5651_I2S_BP_MASK | 140162306a36Sopenharmony_ci RT5651_I2S_DF_MASK, reg_val); 140262306a36Sopenharmony_ci break; 140362306a36Sopenharmony_ci default: 140462306a36Sopenharmony_ci dev_err(component->dev, "Wrong dai->id: %d\n", dai->id); 140562306a36Sopenharmony_ci return -EINVAL; 140662306a36Sopenharmony_ci } 140762306a36Sopenharmony_ci return 0; 140862306a36Sopenharmony_ci} 140962306a36Sopenharmony_ci 141062306a36Sopenharmony_cistatic int rt5651_set_dai_sysclk(struct snd_soc_dai *dai, 141162306a36Sopenharmony_ci int clk_id, unsigned int freq, int dir) 141262306a36Sopenharmony_ci{ 141362306a36Sopenharmony_ci struct snd_soc_component *component = dai->component; 141462306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 141562306a36Sopenharmony_ci unsigned int reg_val = 0; 141662306a36Sopenharmony_ci unsigned int pll_bit = 0; 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci if (freq == rt5651->sysclk && clk_id == rt5651->sysclk_src) 141962306a36Sopenharmony_ci return 0; 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci switch (clk_id) { 142262306a36Sopenharmony_ci case RT5651_SCLK_S_MCLK: 142362306a36Sopenharmony_ci reg_val |= RT5651_SCLK_SRC_MCLK; 142462306a36Sopenharmony_ci break; 142562306a36Sopenharmony_ci case RT5651_SCLK_S_PLL1: 142662306a36Sopenharmony_ci reg_val |= RT5651_SCLK_SRC_PLL1; 142762306a36Sopenharmony_ci pll_bit |= RT5651_PWR_PLL; 142862306a36Sopenharmony_ci break; 142962306a36Sopenharmony_ci case RT5651_SCLK_S_RCCLK: 143062306a36Sopenharmony_ci reg_val |= RT5651_SCLK_SRC_RCCLK; 143162306a36Sopenharmony_ci break; 143262306a36Sopenharmony_ci default: 143362306a36Sopenharmony_ci dev_err(component->dev, "Invalid clock id (%d)\n", clk_id); 143462306a36Sopenharmony_ci return -EINVAL; 143562306a36Sopenharmony_ci } 143662306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 143762306a36Sopenharmony_ci RT5651_PWR_PLL, pll_bit); 143862306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_GLB_CLK, 143962306a36Sopenharmony_ci RT5651_SCLK_SRC_MASK, reg_val); 144062306a36Sopenharmony_ci rt5651->sysclk = freq; 144162306a36Sopenharmony_ci rt5651->sysclk_src = clk_id; 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ci dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ci return 0; 144662306a36Sopenharmony_ci} 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_cistatic int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, 144962306a36Sopenharmony_ci unsigned int freq_in, unsigned int freq_out) 145062306a36Sopenharmony_ci{ 145162306a36Sopenharmony_ci struct snd_soc_component *component = dai->component; 145262306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 145362306a36Sopenharmony_ci struct rl6231_pll_code pll_code; 145462306a36Sopenharmony_ci int ret; 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_ci if (source == rt5651->pll_src && freq_in == rt5651->pll_in && 145762306a36Sopenharmony_ci freq_out == rt5651->pll_out) 145862306a36Sopenharmony_ci return 0; 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci if (!freq_in || !freq_out) { 146162306a36Sopenharmony_ci dev_dbg(component->dev, "PLL disabled\n"); 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci rt5651->pll_in = 0; 146462306a36Sopenharmony_ci rt5651->pll_out = 0; 146562306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_GLB_CLK, 146662306a36Sopenharmony_ci RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_MCLK); 146762306a36Sopenharmony_ci return 0; 146862306a36Sopenharmony_ci } 146962306a36Sopenharmony_ci 147062306a36Sopenharmony_ci switch (source) { 147162306a36Sopenharmony_ci case RT5651_PLL1_S_MCLK: 147262306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_GLB_CLK, 147362306a36Sopenharmony_ci RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_MCLK); 147462306a36Sopenharmony_ci break; 147562306a36Sopenharmony_ci case RT5651_PLL1_S_BCLK1: 147662306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_GLB_CLK, 147762306a36Sopenharmony_ci RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_BCLK1); 147862306a36Sopenharmony_ci break; 147962306a36Sopenharmony_ci case RT5651_PLL1_S_BCLK2: 148062306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_GLB_CLK, 148162306a36Sopenharmony_ci RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_BCLK2); 148262306a36Sopenharmony_ci break; 148362306a36Sopenharmony_ci default: 148462306a36Sopenharmony_ci dev_err(component->dev, "Unknown PLL source %d\n", source); 148562306a36Sopenharmony_ci return -EINVAL; 148662306a36Sopenharmony_ci } 148762306a36Sopenharmony_ci 148862306a36Sopenharmony_ci ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); 148962306a36Sopenharmony_ci if (ret < 0) { 149062306a36Sopenharmony_ci dev_err(component->dev, "Unsupported input clock %d\n", freq_in); 149162306a36Sopenharmony_ci return ret; 149262306a36Sopenharmony_ci } 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n", 149562306a36Sopenharmony_ci pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), 149662306a36Sopenharmony_ci pll_code.n_code, pll_code.k_code); 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci snd_soc_component_write(component, RT5651_PLL_CTRL1, 149962306a36Sopenharmony_ci pll_code.n_code << RT5651_PLL_N_SFT | pll_code.k_code); 150062306a36Sopenharmony_ci snd_soc_component_write(component, RT5651_PLL_CTRL2, 150162306a36Sopenharmony_ci ((pll_code.m_bp ? 0 : pll_code.m_code) << RT5651_PLL_M_SFT) | 150262306a36Sopenharmony_ci (pll_code.m_bp << RT5651_PLL_M_BP_SFT)); 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_ci rt5651->pll_in = freq_in; 150562306a36Sopenharmony_ci rt5651->pll_out = freq_out; 150662306a36Sopenharmony_ci rt5651->pll_src = source; 150762306a36Sopenharmony_ci 150862306a36Sopenharmony_ci return 0; 150962306a36Sopenharmony_ci} 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_cistatic int rt5651_set_bias_level(struct snd_soc_component *component, 151262306a36Sopenharmony_ci enum snd_soc_bias_level level) 151362306a36Sopenharmony_ci{ 151462306a36Sopenharmony_ci switch (level) { 151562306a36Sopenharmony_ci case SND_SOC_BIAS_PREPARE: 151662306a36Sopenharmony_ci if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) { 151762306a36Sopenharmony_ci if (snd_soc_component_read(component, RT5651_PLL_MODE_1) & 0x9200) 151862306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_D_MISC, 151962306a36Sopenharmony_ci 0xc00, 0xc00); 152062306a36Sopenharmony_ci } 152162306a36Sopenharmony_ci break; 152262306a36Sopenharmony_ci case SND_SOC_BIAS_STANDBY: 152362306a36Sopenharmony_ci if (SND_SOC_BIAS_OFF == snd_soc_component_get_bias_level(component)) { 152462306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG1, 152562306a36Sopenharmony_ci RT5651_PWR_VREF1 | RT5651_PWR_MB | 152662306a36Sopenharmony_ci RT5651_PWR_BG | RT5651_PWR_VREF2, 152762306a36Sopenharmony_ci RT5651_PWR_VREF1 | RT5651_PWR_MB | 152862306a36Sopenharmony_ci RT5651_PWR_BG | RT5651_PWR_VREF2); 152962306a36Sopenharmony_ci usleep_range(10000, 15000); 153062306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG1, 153162306a36Sopenharmony_ci RT5651_PWR_FV1 | RT5651_PWR_FV2, 153262306a36Sopenharmony_ci RT5651_PWR_FV1 | RT5651_PWR_FV2); 153362306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_D_MISC, 0x1, 0x1); 153462306a36Sopenharmony_ci } 153562306a36Sopenharmony_ci break; 153662306a36Sopenharmony_ci 153762306a36Sopenharmony_ci case SND_SOC_BIAS_OFF: 153862306a36Sopenharmony_ci snd_soc_component_write(component, RT5651_D_MISC, 0x0010); 153962306a36Sopenharmony_ci snd_soc_component_write(component, RT5651_PWR_DIG1, 0x0000); 154062306a36Sopenharmony_ci snd_soc_component_write(component, RT5651_PWR_DIG2, 0x0000); 154162306a36Sopenharmony_ci snd_soc_component_write(component, RT5651_PWR_VOL, 0x0000); 154262306a36Sopenharmony_ci snd_soc_component_write(component, RT5651_PWR_MIXER, 0x0000); 154362306a36Sopenharmony_ci /* Do not touch the LDO voltage select bits on bias-off */ 154462306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG1, 154562306a36Sopenharmony_ci ~RT5651_PWR_LDO_DVO_MASK, 0); 154662306a36Sopenharmony_ci /* Leave PLL1 and jack-detect power as is, all others off */ 154762306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 154862306a36Sopenharmony_ci ~(RT5651_PWR_PLL | RT5651_PWR_JD_M), 0); 154962306a36Sopenharmony_ci break; 155062306a36Sopenharmony_ci 155162306a36Sopenharmony_ci default: 155262306a36Sopenharmony_ci break; 155362306a36Sopenharmony_ci } 155462306a36Sopenharmony_ci 155562306a36Sopenharmony_ci return 0; 155662306a36Sopenharmony_ci} 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_cistatic void rt5651_enable_micbias1_for_ovcd(struct snd_soc_component *component) 155962306a36Sopenharmony_ci{ 156062306a36Sopenharmony_ci struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 156162306a36Sopenharmony_ci 156262306a36Sopenharmony_ci snd_soc_dapm_mutex_lock(dapm); 156362306a36Sopenharmony_ci snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO"); 156462306a36Sopenharmony_ci snd_soc_dapm_force_enable_pin_unlocked(dapm, "micbias1"); 156562306a36Sopenharmony_ci /* OVCD is unreliable when used with RCCLK as sysclk-source */ 156662306a36Sopenharmony_ci snd_soc_dapm_force_enable_pin_unlocked(dapm, "Platform Clock"); 156762306a36Sopenharmony_ci snd_soc_dapm_sync_unlocked(dapm); 156862306a36Sopenharmony_ci snd_soc_dapm_mutex_unlock(dapm); 156962306a36Sopenharmony_ci} 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_cistatic void rt5651_disable_micbias1_for_ovcd(struct snd_soc_component *component) 157262306a36Sopenharmony_ci{ 157362306a36Sopenharmony_ci struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 157462306a36Sopenharmony_ci 157562306a36Sopenharmony_ci snd_soc_dapm_mutex_lock(dapm); 157662306a36Sopenharmony_ci snd_soc_dapm_disable_pin_unlocked(dapm, "Platform Clock"); 157762306a36Sopenharmony_ci snd_soc_dapm_disable_pin_unlocked(dapm, "micbias1"); 157862306a36Sopenharmony_ci snd_soc_dapm_disable_pin_unlocked(dapm, "LDO"); 157962306a36Sopenharmony_ci snd_soc_dapm_sync_unlocked(dapm); 158062306a36Sopenharmony_ci snd_soc_dapm_mutex_unlock(dapm); 158162306a36Sopenharmony_ci} 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_cistatic void rt5651_enable_micbias1_ovcd_irq(struct snd_soc_component *component) 158462306a36Sopenharmony_ci{ 158562306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 158662306a36Sopenharmony_ci 158762306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2, 158862306a36Sopenharmony_ci RT5651_IRQ_MB1_OC_MASK, RT5651_IRQ_MB1_OC_NOR); 158962306a36Sopenharmony_ci rt5651->ovcd_irq_enabled = true; 159062306a36Sopenharmony_ci} 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_cistatic void rt5651_disable_micbias1_ovcd_irq(struct snd_soc_component *component) 159362306a36Sopenharmony_ci{ 159462306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 159562306a36Sopenharmony_ci 159662306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2, 159762306a36Sopenharmony_ci RT5651_IRQ_MB1_OC_MASK, RT5651_IRQ_MB1_OC_BP); 159862306a36Sopenharmony_ci rt5651->ovcd_irq_enabled = false; 159962306a36Sopenharmony_ci} 160062306a36Sopenharmony_ci 160162306a36Sopenharmony_cistatic void rt5651_clear_micbias1_ovcd(struct snd_soc_component *component) 160262306a36Sopenharmony_ci{ 160362306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2, 160462306a36Sopenharmony_ci RT5651_MB1_OC_CLR, 0); 160562306a36Sopenharmony_ci} 160662306a36Sopenharmony_ci 160762306a36Sopenharmony_cistatic bool rt5651_micbias1_ovcd(struct snd_soc_component *component) 160862306a36Sopenharmony_ci{ 160962306a36Sopenharmony_ci int val; 161062306a36Sopenharmony_ci 161162306a36Sopenharmony_ci val = snd_soc_component_read(component, RT5651_IRQ_CTRL2); 161262306a36Sopenharmony_ci dev_dbg(component->dev, "irq ctrl2 %#04x\n", val); 161362306a36Sopenharmony_ci 161462306a36Sopenharmony_ci return (val & RT5651_MB1_OC_CLR); 161562306a36Sopenharmony_ci} 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_cistatic bool rt5651_jack_inserted(struct snd_soc_component *component) 161862306a36Sopenharmony_ci{ 161962306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 162062306a36Sopenharmony_ci int val; 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci if (rt5651->gpiod_hp_det) { 162362306a36Sopenharmony_ci val = gpiod_get_value_cansleep(rt5651->gpiod_hp_det); 162462306a36Sopenharmony_ci dev_dbg(component->dev, "jack-detect gpio %d\n", val); 162562306a36Sopenharmony_ci return val; 162662306a36Sopenharmony_ci } 162762306a36Sopenharmony_ci 162862306a36Sopenharmony_ci val = snd_soc_component_read(component, RT5651_INT_IRQ_ST); 162962306a36Sopenharmony_ci dev_dbg(component->dev, "irq status %#04x\n", val); 163062306a36Sopenharmony_ci 163162306a36Sopenharmony_ci switch (rt5651->jd_src) { 163262306a36Sopenharmony_ci case RT5651_JD1_1: 163362306a36Sopenharmony_ci val &= 0x1000; 163462306a36Sopenharmony_ci break; 163562306a36Sopenharmony_ci case RT5651_JD1_2: 163662306a36Sopenharmony_ci val &= 0x2000; 163762306a36Sopenharmony_ci break; 163862306a36Sopenharmony_ci case RT5651_JD2: 163962306a36Sopenharmony_ci val &= 0x4000; 164062306a36Sopenharmony_ci break; 164162306a36Sopenharmony_ci default: 164262306a36Sopenharmony_ci break; 164362306a36Sopenharmony_ci } 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_ci if (rt5651->jd_active_high) 164662306a36Sopenharmony_ci return val != 0; 164762306a36Sopenharmony_ci else 164862306a36Sopenharmony_ci return val == 0; 164962306a36Sopenharmony_ci} 165062306a36Sopenharmony_ci 165162306a36Sopenharmony_ci/* Jack detect and button-press timings */ 165262306a36Sopenharmony_ci#define JACK_SETTLE_TIME 100 /* milli seconds */ 165362306a36Sopenharmony_ci#define JACK_DETECT_COUNT 5 165462306a36Sopenharmony_ci#define JACK_DETECT_MAXCOUNT 20 /* Aprox. 2 seconds worth of tries */ 165562306a36Sopenharmony_ci#define JACK_UNPLUG_TIME 80 /* milli seconds */ 165662306a36Sopenharmony_ci#define BP_POLL_TIME 10 /* milli seconds */ 165762306a36Sopenharmony_ci#define BP_POLL_MAXCOUNT 200 /* assume something is wrong after this */ 165862306a36Sopenharmony_ci#define BP_THRESHOLD 3 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_cistatic void rt5651_start_button_press_work(struct snd_soc_component *component) 166162306a36Sopenharmony_ci{ 166262306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci rt5651->poll_count = 0; 166562306a36Sopenharmony_ci rt5651->press_count = 0; 166662306a36Sopenharmony_ci rt5651->release_count = 0; 166762306a36Sopenharmony_ci rt5651->pressed = false; 166862306a36Sopenharmony_ci rt5651->press_reported = false; 166962306a36Sopenharmony_ci rt5651_clear_micbias1_ovcd(component); 167062306a36Sopenharmony_ci schedule_delayed_work(&rt5651->bp_work, msecs_to_jiffies(BP_POLL_TIME)); 167162306a36Sopenharmony_ci} 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_cistatic void rt5651_button_press_work(struct work_struct *work) 167462306a36Sopenharmony_ci{ 167562306a36Sopenharmony_ci struct rt5651_priv *rt5651 = 167662306a36Sopenharmony_ci container_of(work, struct rt5651_priv, bp_work.work); 167762306a36Sopenharmony_ci struct snd_soc_component *component = rt5651->component; 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci /* Check the jack was not removed underneath us */ 168062306a36Sopenharmony_ci if (!rt5651_jack_inserted(component)) 168162306a36Sopenharmony_ci return; 168262306a36Sopenharmony_ci 168362306a36Sopenharmony_ci if (rt5651_micbias1_ovcd(component)) { 168462306a36Sopenharmony_ci rt5651->release_count = 0; 168562306a36Sopenharmony_ci rt5651->press_count++; 168662306a36Sopenharmony_ci /* Remember till after JACK_UNPLUG_TIME wait */ 168762306a36Sopenharmony_ci if (rt5651->press_count >= BP_THRESHOLD) 168862306a36Sopenharmony_ci rt5651->pressed = true; 168962306a36Sopenharmony_ci rt5651_clear_micbias1_ovcd(component); 169062306a36Sopenharmony_ci } else { 169162306a36Sopenharmony_ci rt5651->press_count = 0; 169262306a36Sopenharmony_ci rt5651->release_count++; 169362306a36Sopenharmony_ci } 169462306a36Sopenharmony_ci 169562306a36Sopenharmony_ci /* 169662306a36Sopenharmony_ci * The pins get temporarily shorted on jack unplug, so we poll for 169762306a36Sopenharmony_ci * at least JACK_UNPLUG_TIME milli-seconds before reporting a press. 169862306a36Sopenharmony_ci */ 169962306a36Sopenharmony_ci rt5651->poll_count++; 170062306a36Sopenharmony_ci if (rt5651->poll_count < (JACK_UNPLUG_TIME / BP_POLL_TIME)) { 170162306a36Sopenharmony_ci schedule_delayed_work(&rt5651->bp_work, 170262306a36Sopenharmony_ci msecs_to_jiffies(BP_POLL_TIME)); 170362306a36Sopenharmony_ci return; 170462306a36Sopenharmony_ci } 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_ci if (rt5651->pressed && !rt5651->press_reported) { 170762306a36Sopenharmony_ci dev_dbg(component->dev, "headset button press\n"); 170862306a36Sopenharmony_ci snd_soc_jack_report(rt5651->hp_jack, SND_JACK_BTN_0, 170962306a36Sopenharmony_ci SND_JACK_BTN_0); 171062306a36Sopenharmony_ci rt5651->press_reported = true; 171162306a36Sopenharmony_ci } 171262306a36Sopenharmony_ci 171362306a36Sopenharmony_ci if (rt5651->release_count >= BP_THRESHOLD) { 171462306a36Sopenharmony_ci if (rt5651->press_reported) { 171562306a36Sopenharmony_ci dev_dbg(component->dev, "headset button release\n"); 171662306a36Sopenharmony_ci snd_soc_jack_report(rt5651->hp_jack, 0, SND_JACK_BTN_0); 171762306a36Sopenharmony_ci } 171862306a36Sopenharmony_ci /* Re-enable OVCD IRQ to detect next press */ 171962306a36Sopenharmony_ci rt5651_enable_micbias1_ovcd_irq(component); 172062306a36Sopenharmony_ci return; /* Stop polling */ 172162306a36Sopenharmony_ci } 172262306a36Sopenharmony_ci 172362306a36Sopenharmony_ci schedule_delayed_work(&rt5651->bp_work, msecs_to_jiffies(BP_POLL_TIME)); 172462306a36Sopenharmony_ci} 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_cistatic int rt5651_detect_headset(struct snd_soc_component *component) 172762306a36Sopenharmony_ci{ 172862306a36Sopenharmony_ci int i, headset_count = 0, headphone_count = 0; 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci /* 173162306a36Sopenharmony_ci * We get the insertion event before the jack is fully inserted at which 173262306a36Sopenharmony_ci * point the second ring on a TRRS connector may short the 2nd ring and 173362306a36Sopenharmony_ci * sleeve contacts, also the overcurrent detection is not entirely 173462306a36Sopenharmony_ci * reliable. So we try several times with a wait in between until we 173562306a36Sopenharmony_ci * detect the same type JACK_DETECT_COUNT times in a row. 173662306a36Sopenharmony_ci */ 173762306a36Sopenharmony_ci for (i = 0; i < JACK_DETECT_MAXCOUNT; i++) { 173862306a36Sopenharmony_ci /* Clear any previous over-current status flag */ 173962306a36Sopenharmony_ci rt5651_clear_micbias1_ovcd(component); 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci msleep(JACK_SETTLE_TIME); 174262306a36Sopenharmony_ci 174362306a36Sopenharmony_ci /* Check the jack is still connected before checking ovcd */ 174462306a36Sopenharmony_ci if (!rt5651_jack_inserted(component)) 174562306a36Sopenharmony_ci return 0; 174662306a36Sopenharmony_ci 174762306a36Sopenharmony_ci if (rt5651_micbias1_ovcd(component)) { 174862306a36Sopenharmony_ci /* 174962306a36Sopenharmony_ci * Over current detected, there is a short between the 175062306a36Sopenharmony_ci * 2nd ring contact and the ground, so a TRS connector 175162306a36Sopenharmony_ci * without a mic contact and thus plain headphones. 175262306a36Sopenharmony_ci */ 175362306a36Sopenharmony_ci dev_dbg(component->dev, "mic-gnd shorted\n"); 175462306a36Sopenharmony_ci headset_count = 0; 175562306a36Sopenharmony_ci headphone_count++; 175662306a36Sopenharmony_ci if (headphone_count == JACK_DETECT_COUNT) 175762306a36Sopenharmony_ci return SND_JACK_HEADPHONE; 175862306a36Sopenharmony_ci } else { 175962306a36Sopenharmony_ci dev_dbg(component->dev, "mic-gnd open\n"); 176062306a36Sopenharmony_ci headphone_count = 0; 176162306a36Sopenharmony_ci headset_count++; 176262306a36Sopenharmony_ci if (headset_count == JACK_DETECT_COUNT) 176362306a36Sopenharmony_ci return SND_JACK_HEADSET; 176462306a36Sopenharmony_ci } 176562306a36Sopenharmony_ci } 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci dev_err(component->dev, "Error detecting headset vs headphones, bad contact?, assuming headphones\n"); 176862306a36Sopenharmony_ci return SND_JACK_HEADPHONE; 176962306a36Sopenharmony_ci} 177062306a36Sopenharmony_ci 177162306a36Sopenharmony_cistatic bool rt5651_support_button_press(struct rt5651_priv *rt5651) 177262306a36Sopenharmony_ci{ 177362306a36Sopenharmony_ci if (!rt5651->hp_jack) 177462306a36Sopenharmony_ci return false; 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_ci /* Button press support only works with internal jack-detection */ 177762306a36Sopenharmony_ci return (rt5651->hp_jack->status & SND_JACK_MICROPHONE) && 177862306a36Sopenharmony_ci rt5651->gpiod_hp_det == NULL; 177962306a36Sopenharmony_ci} 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_cistatic void rt5651_jack_detect_work(struct work_struct *work) 178262306a36Sopenharmony_ci{ 178362306a36Sopenharmony_ci struct rt5651_priv *rt5651 = 178462306a36Sopenharmony_ci container_of(work, struct rt5651_priv, jack_detect_work); 178562306a36Sopenharmony_ci struct snd_soc_component *component = rt5651->component; 178662306a36Sopenharmony_ci int report; 178762306a36Sopenharmony_ci 178862306a36Sopenharmony_ci if (!rt5651_jack_inserted(component)) { 178962306a36Sopenharmony_ci /* Jack removed, or spurious IRQ? */ 179062306a36Sopenharmony_ci if (rt5651->hp_jack->status & SND_JACK_HEADPHONE) { 179162306a36Sopenharmony_ci if (rt5651->hp_jack->status & SND_JACK_MICROPHONE) { 179262306a36Sopenharmony_ci cancel_delayed_work_sync(&rt5651->bp_work); 179362306a36Sopenharmony_ci rt5651_disable_micbias1_ovcd_irq(component); 179462306a36Sopenharmony_ci rt5651_disable_micbias1_for_ovcd(component); 179562306a36Sopenharmony_ci } 179662306a36Sopenharmony_ci snd_soc_jack_report(rt5651->hp_jack, 0, 179762306a36Sopenharmony_ci SND_JACK_HEADSET | SND_JACK_BTN_0); 179862306a36Sopenharmony_ci dev_dbg(component->dev, "jack unplugged\n"); 179962306a36Sopenharmony_ci } 180062306a36Sopenharmony_ci } else if (!(rt5651->hp_jack->status & SND_JACK_HEADPHONE)) { 180162306a36Sopenharmony_ci /* Jack inserted */ 180262306a36Sopenharmony_ci WARN_ON(rt5651->ovcd_irq_enabled); 180362306a36Sopenharmony_ci rt5651_enable_micbias1_for_ovcd(component); 180462306a36Sopenharmony_ci report = rt5651_detect_headset(component); 180562306a36Sopenharmony_ci dev_dbg(component->dev, "detect report %#02x\n", report); 180662306a36Sopenharmony_ci snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET); 180762306a36Sopenharmony_ci if (rt5651_support_button_press(rt5651)) { 180862306a36Sopenharmony_ci /* Enable ovcd IRQ for button press detect. */ 180962306a36Sopenharmony_ci rt5651_enable_micbias1_ovcd_irq(component); 181062306a36Sopenharmony_ci } else { 181162306a36Sopenharmony_ci /* No more need for overcurrent detect. */ 181262306a36Sopenharmony_ci rt5651_disable_micbias1_for_ovcd(component); 181362306a36Sopenharmony_ci } 181462306a36Sopenharmony_ci } else if (rt5651->ovcd_irq_enabled && rt5651_micbias1_ovcd(component)) { 181562306a36Sopenharmony_ci dev_dbg(component->dev, "OVCD IRQ\n"); 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci /* 181862306a36Sopenharmony_ci * The ovcd IRQ keeps firing while the button is pressed, so 181962306a36Sopenharmony_ci * we disable it and start polling the button until released. 182062306a36Sopenharmony_ci * 182162306a36Sopenharmony_ci * The disable will make the IRQ pin 0 again and since we get 182262306a36Sopenharmony_ci * IRQs on both edges (so as to detect both jack plugin and 182362306a36Sopenharmony_ci * unplug) this means we will immediately get another IRQ. 182462306a36Sopenharmony_ci * The ovcd_irq_enabled check above makes the 2ND IRQ a NOP. 182562306a36Sopenharmony_ci */ 182662306a36Sopenharmony_ci rt5651_disable_micbias1_ovcd_irq(component); 182762306a36Sopenharmony_ci rt5651_start_button_press_work(component); 182862306a36Sopenharmony_ci 182962306a36Sopenharmony_ci /* 183062306a36Sopenharmony_ci * If the jack-detect IRQ flag goes high (unplug) after our 183162306a36Sopenharmony_ci * above rt5651_jack_inserted() check and before we have 183262306a36Sopenharmony_ci * disabled the OVCD IRQ, the IRQ pin will stay high and as 183362306a36Sopenharmony_ci * we react to edges, we miss the unplug event -> recheck. 183462306a36Sopenharmony_ci */ 183562306a36Sopenharmony_ci queue_work(system_long_wq, &rt5651->jack_detect_work); 183662306a36Sopenharmony_ci } 183762306a36Sopenharmony_ci} 183862306a36Sopenharmony_ci 183962306a36Sopenharmony_cistatic irqreturn_t rt5651_irq(int irq, void *data) 184062306a36Sopenharmony_ci{ 184162306a36Sopenharmony_ci struct rt5651_priv *rt5651 = data; 184262306a36Sopenharmony_ci 184362306a36Sopenharmony_ci queue_work(system_power_efficient_wq, &rt5651->jack_detect_work); 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_ci return IRQ_HANDLED; 184662306a36Sopenharmony_ci} 184762306a36Sopenharmony_ci 184862306a36Sopenharmony_cistatic void rt5651_cancel_work(void *data) 184962306a36Sopenharmony_ci{ 185062306a36Sopenharmony_ci struct rt5651_priv *rt5651 = data; 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_ci cancel_work_sync(&rt5651->jack_detect_work); 185362306a36Sopenharmony_ci cancel_delayed_work_sync(&rt5651->bp_work); 185462306a36Sopenharmony_ci} 185562306a36Sopenharmony_ci 185662306a36Sopenharmony_cistatic void rt5651_enable_jack_detect(struct snd_soc_component *component, 185762306a36Sopenharmony_ci struct snd_soc_jack *hp_jack, 185862306a36Sopenharmony_ci struct gpio_desc *gpiod_hp_det) 185962306a36Sopenharmony_ci{ 186062306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 186162306a36Sopenharmony_ci bool using_internal_jack_detect = true; 186262306a36Sopenharmony_ci 186362306a36Sopenharmony_ci /* Select jack detect source */ 186462306a36Sopenharmony_ci switch (rt5651->jd_src) { 186562306a36Sopenharmony_ci case RT5651_JD_NULL: 186662306a36Sopenharmony_ci rt5651->gpiod_hp_det = gpiod_hp_det; 186762306a36Sopenharmony_ci if (!rt5651->gpiod_hp_det) 186862306a36Sopenharmony_ci return; /* No jack detect */ 186962306a36Sopenharmony_ci using_internal_jack_detect = false; 187062306a36Sopenharmony_ci break; 187162306a36Sopenharmony_ci case RT5651_JD1_1: 187262306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_JD_CTRL2, 187362306a36Sopenharmony_ci RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_1); 187462306a36Sopenharmony_ci /* active-low is normal, set inv flag for active-high */ 187562306a36Sopenharmony_ci if (rt5651->jd_active_high) 187662306a36Sopenharmony_ci snd_soc_component_update_bits(component, 187762306a36Sopenharmony_ci RT5651_IRQ_CTRL1, 187862306a36Sopenharmony_ci RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV, 187962306a36Sopenharmony_ci RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV); 188062306a36Sopenharmony_ci else 188162306a36Sopenharmony_ci snd_soc_component_update_bits(component, 188262306a36Sopenharmony_ci RT5651_IRQ_CTRL1, 188362306a36Sopenharmony_ci RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV, 188462306a36Sopenharmony_ci RT5651_JD1_1_IRQ_EN); 188562306a36Sopenharmony_ci break; 188662306a36Sopenharmony_ci case RT5651_JD1_2: 188762306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_JD_CTRL2, 188862306a36Sopenharmony_ci RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_2); 188962306a36Sopenharmony_ci /* active-low is normal, set inv flag for active-high */ 189062306a36Sopenharmony_ci if (rt5651->jd_active_high) 189162306a36Sopenharmony_ci snd_soc_component_update_bits(component, 189262306a36Sopenharmony_ci RT5651_IRQ_CTRL1, 189362306a36Sopenharmony_ci RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV, 189462306a36Sopenharmony_ci RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV); 189562306a36Sopenharmony_ci else 189662306a36Sopenharmony_ci snd_soc_component_update_bits(component, 189762306a36Sopenharmony_ci RT5651_IRQ_CTRL1, 189862306a36Sopenharmony_ci RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV, 189962306a36Sopenharmony_ci RT5651_JD1_2_IRQ_EN); 190062306a36Sopenharmony_ci break; 190162306a36Sopenharmony_ci case RT5651_JD2: 190262306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_JD_CTRL2, 190362306a36Sopenharmony_ci RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD2); 190462306a36Sopenharmony_ci /* active-low is normal, set inv flag for active-high */ 190562306a36Sopenharmony_ci if (rt5651->jd_active_high) 190662306a36Sopenharmony_ci snd_soc_component_update_bits(component, 190762306a36Sopenharmony_ci RT5651_IRQ_CTRL1, 190862306a36Sopenharmony_ci RT5651_JD2_IRQ_EN | RT5651_JD2_INV, 190962306a36Sopenharmony_ci RT5651_JD2_IRQ_EN | RT5651_JD2_INV); 191062306a36Sopenharmony_ci else 191162306a36Sopenharmony_ci snd_soc_component_update_bits(component, 191262306a36Sopenharmony_ci RT5651_IRQ_CTRL1, 191362306a36Sopenharmony_ci RT5651_JD2_IRQ_EN | RT5651_JD2_INV, 191462306a36Sopenharmony_ci RT5651_JD2_IRQ_EN); 191562306a36Sopenharmony_ci break; 191662306a36Sopenharmony_ci default: 191762306a36Sopenharmony_ci dev_err(component->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n"); 191862306a36Sopenharmony_ci return; 191962306a36Sopenharmony_ci } 192062306a36Sopenharmony_ci 192162306a36Sopenharmony_ci if (using_internal_jack_detect) { 192262306a36Sopenharmony_ci /* IRQ output on GPIO1 */ 192362306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1, 192462306a36Sopenharmony_ci RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ); 192562306a36Sopenharmony_ci 192662306a36Sopenharmony_ci /* Enable jack detect power */ 192762306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG2, 192862306a36Sopenharmony_ci RT5651_PWR_JD_M, RT5651_PWR_JD_M); 192962306a36Sopenharmony_ci } 193062306a36Sopenharmony_ci 193162306a36Sopenharmony_ci /* Set OVCD threshold current and scale-factor */ 193262306a36Sopenharmony_ci snd_soc_component_write(component, RT5651_PR_BASE + RT5651_BIAS_CUR4, 193362306a36Sopenharmony_ci 0xa800 | rt5651->ovcd_sf); 193462306a36Sopenharmony_ci 193562306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_MICBIAS, 193662306a36Sopenharmony_ci RT5651_MIC1_OVCD_MASK | 193762306a36Sopenharmony_ci RT5651_MIC1_OVTH_MASK | 193862306a36Sopenharmony_ci RT5651_PWR_CLK12M_MASK | 193962306a36Sopenharmony_ci RT5651_PWR_MB_MASK, 194062306a36Sopenharmony_ci RT5651_MIC1_OVCD_EN | 194162306a36Sopenharmony_ci rt5651->ovcd_th | 194262306a36Sopenharmony_ci RT5651_PWR_MB_PU | 194362306a36Sopenharmony_ci RT5651_PWR_CLK12M_PU); 194462306a36Sopenharmony_ci 194562306a36Sopenharmony_ci /* 194662306a36Sopenharmony_ci * The over-current-detect is only reliable in detecting the absence 194762306a36Sopenharmony_ci * of over-current, when the mic-contact in the jack is short-circuited, 194862306a36Sopenharmony_ci * the hardware periodically retries if it can apply the bias-current 194962306a36Sopenharmony_ci * leading to the ovcd status flip-flopping 1-0-1 with it being 0 about 195062306a36Sopenharmony_ci * 10% of the time, as we poll the ovcd status bit we might hit that 195162306a36Sopenharmony_ci * 10%, so we enable sticky mode and when checking OVCD we clear the 195262306a36Sopenharmony_ci * status, msleep() a bit and then check to get a reliable reading. 195362306a36Sopenharmony_ci */ 195462306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2, 195562306a36Sopenharmony_ci RT5651_MB1_OC_STKY_MASK, RT5651_MB1_OC_STKY_EN); 195662306a36Sopenharmony_ci 195762306a36Sopenharmony_ci rt5651->hp_jack = hp_jack; 195862306a36Sopenharmony_ci if (rt5651_support_button_press(rt5651)) { 195962306a36Sopenharmony_ci rt5651_enable_micbias1_for_ovcd(component); 196062306a36Sopenharmony_ci rt5651_enable_micbias1_ovcd_irq(component); 196162306a36Sopenharmony_ci } 196262306a36Sopenharmony_ci 196362306a36Sopenharmony_ci enable_irq(rt5651->irq); 196462306a36Sopenharmony_ci /* sync initial jack state */ 196562306a36Sopenharmony_ci queue_work(system_power_efficient_wq, &rt5651->jack_detect_work); 196662306a36Sopenharmony_ci} 196762306a36Sopenharmony_ci 196862306a36Sopenharmony_cistatic void rt5651_disable_jack_detect(struct snd_soc_component *component) 196962306a36Sopenharmony_ci{ 197062306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 197162306a36Sopenharmony_ci 197262306a36Sopenharmony_ci disable_irq(rt5651->irq); 197362306a36Sopenharmony_ci rt5651_cancel_work(rt5651); 197462306a36Sopenharmony_ci 197562306a36Sopenharmony_ci if (rt5651_support_button_press(rt5651)) { 197662306a36Sopenharmony_ci rt5651_disable_micbias1_ovcd_irq(component); 197762306a36Sopenharmony_ci rt5651_disable_micbias1_for_ovcd(component); 197862306a36Sopenharmony_ci snd_soc_jack_report(rt5651->hp_jack, 0, SND_JACK_BTN_0); 197962306a36Sopenharmony_ci } 198062306a36Sopenharmony_ci 198162306a36Sopenharmony_ci rt5651->hp_jack = NULL; 198262306a36Sopenharmony_ci} 198362306a36Sopenharmony_ci 198462306a36Sopenharmony_cistatic int rt5651_set_jack(struct snd_soc_component *component, 198562306a36Sopenharmony_ci struct snd_soc_jack *jack, void *data) 198662306a36Sopenharmony_ci{ 198762306a36Sopenharmony_ci if (jack) 198862306a36Sopenharmony_ci rt5651_enable_jack_detect(component, jack, data); 198962306a36Sopenharmony_ci else 199062306a36Sopenharmony_ci rt5651_disable_jack_detect(component); 199162306a36Sopenharmony_ci 199262306a36Sopenharmony_ci return 0; 199362306a36Sopenharmony_ci} 199462306a36Sopenharmony_ci 199562306a36Sopenharmony_ci/* 199662306a36Sopenharmony_ci * Note on some platforms the platform code may need to add device-properties, 199762306a36Sopenharmony_ci * rather then relying only on properties set by the firmware. Therefor the 199862306a36Sopenharmony_ci * property parsing MUST be done from the component driver's probe function, 199962306a36Sopenharmony_ci * rather then from the i2c driver's probe function, so that the platform-code 200062306a36Sopenharmony_ci * can attach extra properties before calling snd_soc_register_card(). 200162306a36Sopenharmony_ci */ 200262306a36Sopenharmony_cistatic void rt5651_apply_properties(struct snd_soc_component *component) 200362306a36Sopenharmony_ci{ 200462306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 200562306a36Sopenharmony_ci u32 val; 200662306a36Sopenharmony_ci 200762306a36Sopenharmony_ci if (device_property_read_bool(component->dev, "realtek,in2-differential")) 200862306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_IN1_IN2, 200962306a36Sopenharmony_ci RT5651_IN_DF2, RT5651_IN_DF2); 201062306a36Sopenharmony_ci 201162306a36Sopenharmony_ci if (device_property_read_bool(component->dev, "realtek,dmic-en")) 201262306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1, 201362306a36Sopenharmony_ci RT5651_GP2_PIN_MASK, RT5651_GP2_PIN_DMIC1_SCL); 201462306a36Sopenharmony_ci 201562306a36Sopenharmony_ci if (device_property_read_u32(component->dev, 201662306a36Sopenharmony_ci "realtek,jack-detect-source", &val) == 0) 201762306a36Sopenharmony_ci rt5651->jd_src = val; 201862306a36Sopenharmony_ci 201962306a36Sopenharmony_ci if (device_property_read_bool(component->dev, "realtek,jack-detect-not-inverted")) 202062306a36Sopenharmony_ci rt5651->jd_active_high = true; 202162306a36Sopenharmony_ci 202262306a36Sopenharmony_ci /* 202362306a36Sopenharmony_ci * Testing on various boards has shown that good defaults for the OVCD 202462306a36Sopenharmony_ci * threshold and scale-factor are 2000µA and 0.75. For an effective 202562306a36Sopenharmony_ci * limit of 1500µA, this seems to be more reliable then 1500µA and 1.0. 202662306a36Sopenharmony_ci */ 202762306a36Sopenharmony_ci rt5651->ovcd_th = RT5651_MIC1_OVTH_2000UA; 202862306a36Sopenharmony_ci rt5651->ovcd_sf = RT5651_MIC_OVCD_SF_0P75; 202962306a36Sopenharmony_ci 203062306a36Sopenharmony_ci if (device_property_read_u32(component->dev, 203162306a36Sopenharmony_ci "realtek,over-current-threshold-microamp", &val) == 0) { 203262306a36Sopenharmony_ci switch (val) { 203362306a36Sopenharmony_ci case 600: 203462306a36Sopenharmony_ci rt5651->ovcd_th = RT5651_MIC1_OVTH_600UA; 203562306a36Sopenharmony_ci break; 203662306a36Sopenharmony_ci case 1500: 203762306a36Sopenharmony_ci rt5651->ovcd_th = RT5651_MIC1_OVTH_1500UA; 203862306a36Sopenharmony_ci break; 203962306a36Sopenharmony_ci case 2000: 204062306a36Sopenharmony_ci rt5651->ovcd_th = RT5651_MIC1_OVTH_2000UA; 204162306a36Sopenharmony_ci break; 204262306a36Sopenharmony_ci default: 204362306a36Sopenharmony_ci dev_warn(component->dev, "Warning: Invalid over-current-threshold-microamp value: %d, defaulting to 2000uA\n", 204462306a36Sopenharmony_ci val); 204562306a36Sopenharmony_ci } 204662306a36Sopenharmony_ci } 204762306a36Sopenharmony_ci 204862306a36Sopenharmony_ci if (device_property_read_u32(component->dev, 204962306a36Sopenharmony_ci "realtek,over-current-scale-factor", &val) == 0) { 205062306a36Sopenharmony_ci if (val <= RT5651_OVCD_SF_1P5) 205162306a36Sopenharmony_ci rt5651->ovcd_sf = val << RT5651_MIC_OVCD_SF_SFT; 205262306a36Sopenharmony_ci else 205362306a36Sopenharmony_ci dev_warn(component->dev, "Warning: Invalid over-current-scale-factor value: %d, defaulting to 0.75\n", 205462306a36Sopenharmony_ci val); 205562306a36Sopenharmony_ci } 205662306a36Sopenharmony_ci} 205762306a36Sopenharmony_ci 205862306a36Sopenharmony_cistatic int rt5651_probe(struct snd_soc_component *component) 205962306a36Sopenharmony_ci{ 206062306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 206162306a36Sopenharmony_ci 206262306a36Sopenharmony_ci rt5651->component = component; 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_ci snd_soc_component_update_bits(component, RT5651_PWR_ANLG1, 206562306a36Sopenharmony_ci RT5651_PWR_LDO_DVO_MASK, RT5651_PWR_LDO_DVO_1_2V); 206662306a36Sopenharmony_ci 206762306a36Sopenharmony_ci snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); 206862306a36Sopenharmony_ci 206962306a36Sopenharmony_ci rt5651_apply_properties(component); 207062306a36Sopenharmony_ci 207162306a36Sopenharmony_ci return 0; 207262306a36Sopenharmony_ci} 207362306a36Sopenharmony_ci 207462306a36Sopenharmony_ci#ifdef CONFIG_PM 207562306a36Sopenharmony_cistatic int rt5651_suspend(struct snd_soc_component *component) 207662306a36Sopenharmony_ci{ 207762306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci regcache_cache_only(rt5651->regmap, true); 208062306a36Sopenharmony_ci regcache_mark_dirty(rt5651->regmap); 208162306a36Sopenharmony_ci return 0; 208262306a36Sopenharmony_ci} 208362306a36Sopenharmony_ci 208462306a36Sopenharmony_cistatic int rt5651_resume(struct snd_soc_component *component) 208562306a36Sopenharmony_ci{ 208662306a36Sopenharmony_ci struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component); 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_ci regcache_cache_only(rt5651->regmap, false); 208962306a36Sopenharmony_ci snd_soc_component_cache_sync(component); 209062306a36Sopenharmony_ci 209162306a36Sopenharmony_ci return 0; 209262306a36Sopenharmony_ci} 209362306a36Sopenharmony_ci#else 209462306a36Sopenharmony_ci#define rt5651_suspend NULL 209562306a36Sopenharmony_ci#define rt5651_resume NULL 209662306a36Sopenharmony_ci#endif 209762306a36Sopenharmony_ci 209862306a36Sopenharmony_ci#define RT5651_STEREO_RATES SNDRV_PCM_RATE_8000_96000 209962306a36Sopenharmony_ci#define RT5651_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 210062306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) 210162306a36Sopenharmony_ci 210262306a36Sopenharmony_cistatic const struct snd_soc_dai_ops rt5651_aif_dai_ops = { 210362306a36Sopenharmony_ci .hw_params = rt5651_hw_params, 210462306a36Sopenharmony_ci .set_fmt = rt5651_set_dai_fmt, 210562306a36Sopenharmony_ci .set_sysclk = rt5651_set_dai_sysclk, 210662306a36Sopenharmony_ci .set_pll = rt5651_set_dai_pll, 210762306a36Sopenharmony_ci}; 210862306a36Sopenharmony_ci 210962306a36Sopenharmony_cistatic struct snd_soc_dai_driver rt5651_dai[] = { 211062306a36Sopenharmony_ci { 211162306a36Sopenharmony_ci .name = "rt5651-aif1", 211262306a36Sopenharmony_ci .id = RT5651_AIF1, 211362306a36Sopenharmony_ci .playback = { 211462306a36Sopenharmony_ci .stream_name = "AIF1 Playback", 211562306a36Sopenharmony_ci .channels_min = 1, 211662306a36Sopenharmony_ci .channels_max = 2, 211762306a36Sopenharmony_ci .rates = RT5651_STEREO_RATES, 211862306a36Sopenharmony_ci .formats = RT5651_FORMATS, 211962306a36Sopenharmony_ci }, 212062306a36Sopenharmony_ci .capture = { 212162306a36Sopenharmony_ci .stream_name = "AIF1 Capture", 212262306a36Sopenharmony_ci .channels_min = 1, 212362306a36Sopenharmony_ci .channels_max = 2, 212462306a36Sopenharmony_ci .rates = RT5651_STEREO_RATES, 212562306a36Sopenharmony_ci .formats = RT5651_FORMATS, 212662306a36Sopenharmony_ci }, 212762306a36Sopenharmony_ci .ops = &rt5651_aif_dai_ops, 212862306a36Sopenharmony_ci }, 212962306a36Sopenharmony_ci { 213062306a36Sopenharmony_ci .name = "rt5651-aif2", 213162306a36Sopenharmony_ci .id = RT5651_AIF2, 213262306a36Sopenharmony_ci .playback = { 213362306a36Sopenharmony_ci .stream_name = "AIF2 Playback", 213462306a36Sopenharmony_ci .channels_min = 1, 213562306a36Sopenharmony_ci .channels_max = 2, 213662306a36Sopenharmony_ci .rates = RT5651_STEREO_RATES, 213762306a36Sopenharmony_ci .formats = RT5651_FORMATS, 213862306a36Sopenharmony_ci }, 213962306a36Sopenharmony_ci .capture = { 214062306a36Sopenharmony_ci .stream_name = "AIF2 Capture", 214162306a36Sopenharmony_ci .channels_min = 1, 214262306a36Sopenharmony_ci .channels_max = 2, 214362306a36Sopenharmony_ci .rates = RT5651_STEREO_RATES, 214462306a36Sopenharmony_ci .formats = RT5651_FORMATS, 214562306a36Sopenharmony_ci }, 214662306a36Sopenharmony_ci .ops = &rt5651_aif_dai_ops, 214762306a36Sopenharmony_ci }, 214862306a36Sopenharmony_ci}; 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_cistatic const struct snd_soc_component_driver soc_component_dev_rt5651 = { 215162306a36Sopenharmony_ci .probe = rt5651_probe, 215262306a36Sopenharmony_ci .suspend = rt5651_suspend, 215362306a36Sopenharmony_ci .resume = rt5651_resume, 215462306a36Sopenharmony_ci .set_bias_level = rt5651_set_bias_level, 215562306a36Sopenharmony_ci .set_jack = rt5651_set_jack, 215662306a36Sopenharmony_ci .controls = rt5651_snd_controls, 215762306a36Sopenharmony_ci .num_controls = ARRAY_SIZE(rt5651_snd_controls), 215862306a36Sopenharmony_ci .dapm_widgets = rt5651_dapm_widgets, 215962306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets), 216062306a36Sopenharmony_ci .dapm_routes = rt5651_dapm_routes, 216162306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), 216262306a36Sopenharmony_ci .use_pmdown_time = 1, 216362306a36Sopenharmony_ci .endianness = 1, 216462306a36Sopenharmony_ci}; 216562306a36Sopenharmony_ci 216662306a36Sopenharmony_cistatic const struct regmap_config rt5651_regmap = { 216762306a36Sopenharmony_ci .reg_bits = 8, 216862306a36Sopenharmony_ci .val_bits = 16, 216962306a36Sopenharmony_ci 217062306a36Sopenharmony_ci .max_register = RT5651_DEVICE_ID + 1 + (ARRAY_SIZE(rt5651_ranges) * 217162306a36Sopenharmony_ci RT5651_PR_SPACING), 217262306a36Sopenharmony_ci .volatile_reg = rt5651_volatile_register, 217362306a36Sopenharmony_ci .readable_reg = rt5651_readable_register, 217462306a36Sopenharmony_ci 217562306a36Sopenharmony_ci .cache_type = REGCACHE_MAPLE, 217662306a36Sopenharmony_ci .reg_defaults = rt5651_reg, 217762306a36Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(rt5651_reg), 217862306a36Sopenharmony_ci .ranges = rt5651_ranges, 217962306a36Sopenharmony_ci .num_ranges = ARRAY_SIZE(rt5651_ranges), 218062306a36Sopenharmony_ci .use_single_read = true, 218162306a36Sopenharmony_ci .use_single_write = true, 218262306a36Sopenharmony_ci}; 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_ci#if defined(CONFIG_OF) 218562306a36Sopenharmony_cistatic const struct of_device_id rt5651_of_match[] = { 218662306a36Sopenharmony_ci { .compatible = "realtek,rt5651", }, 218762306a36Sopenharmony_ci {}, 218862306a36Sopenharmony_ci}; 218962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, rt5651_of_match); 219062306a36Sopenharmony_ci#endif 219162306a36Sopenharmony_ci 219262306a36Sopenharmony_ci#ifdef CONFIG_ACPI 219362306a36Sopenharmony_cistatic const struct acpi_device_id rt5651_acpi_match[] = { 219462306a36Sopenharmony_ci { "10EC5651", 0 }, 219562306a36Sopenharmony_ci { "10EC5640", 0 }, 219662306a36Sopenharmony_ci { }, 219762306a36Sopenharmony_ci}; 219862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, rt5651_acpi_match); 219962306a36Sopenharmony_ci#endif 220062306a36Sopenharmony_ci 220162306a36Sopenharmony_cistatic const struct i2c_device_id rt5651_i2c_id[] = { 220262306a36Sopenharmony_ci { "rt5651", 0 }, 220362306a36Sopenharmony_ci { } 220462306a36Sopenharmony_ci}; 220562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, rt5651_i2c_id); 220662306a36Sopenharmony_ci 220762306a36Sopenharmony_ci/* 220862306a36Sopenharmony_ci * Note this function MUST not look at device-properties, see the comment 220962306a36Sopenharmony_ci * above rt5651_apply_properties(). 221062306a36Sopenharmony_ci */ 221162306a36Sopenharmony_cistatic int rt5651_i2c_probe(struct i2c_client *i2c) 221262306a36Sopenharmony_ci{ 221362306a36Sopenharmony_ci struct rt5651_priv *rt5651; 221462306a36Sopenharmony_ci int ret; 221562306a36Sopenharmony_ci int err; 221662306a36Sopenharmony_ci 221762306a36Sopenharmony_ci rt5651 = devm_kzalloc(&i2c->dev, sizeof(*rt5651), 221862306a36Sopenharmony_ci GFP_KERNEL); 221962306a36Sopenharmony_ci if (NULL == rt5651) 222062306a36Sopenharmony_ci return -ENOMEM; 222162306a36Sopenharmony_ci 222262306a36Sopenharmony_ci i2c_set_clientdata(i2c, rt5651); 222362306a36Sopenharmony_ci 222462306a36Sopenharmony_ci rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap); 222562306a36Sopenharmony_ci if (IS_ERR(rt5651->regmap)) { 222662306a36Sopenharmony_ci ret = PTR_ERR(rt5651->regmap); 222762306a36Sopenharmony_ci dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 222862306a36Sopenharmony_ci ret); 222962306a36Sopenharmony_ci return ret; 223062306a36Sopenharmony_ci } 223162306a36Sopenharmony_ci 223262306a36Sopenharmony_ci err = regmap_read(rt5651->regmap, RT5651_DEVICE_ID, &ret); 223362306a36Sopenharmony_ci if (err) 223462306a36Sopenharmony_ci return err; 223562306a36Sopenharmony_ci 223662306a36Sopenharmony_ci if (ret != RT5651_DEVICE_ID_VALUE) { 223762306a36Sopenharmony_ci dev_err(&i2c->dev, 223862306a36Sopenharmony_ci "Device with ID register %#x is not rt5651\n", ret); 223962306a36Sopenharmony_ci return -ENODEV; 224062306a36Sopenharmony_ci } 224162306a36Sopenharmony_ci 224262306a36Sopenharmony_ci regmap_write(rt5651->regmap, RT5651_RESET, 0); 224362306a36Sopenharmony_ci 224462306a36Sopenharmony_ci ret = regmap_register_patch(rt5651->regmap, init_list, 224562306a36Sopenharmony_ci ARRAY_SIZE(init_list)); 224662306a36Sopenharmony_ci if (ret != 0) 224762306a36Sopenharmony_ci dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); 224862306a36Sopenharmony_ci 224962306a36Sopenharmony_ci rt5651->irq = i2c->irq; 225062306a36Sopenharmony_ci rt5651->hp_mute = true; 225162306a36Sopenharmony_ci 225262306a36Sopenharmony_ci INIT_DELAYED_WORK(&rt5651->bp_work, rt5651_button_press_work); 225362306a36Sopenharmony_ci INIT_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work); 225462306a36Sopenharmony_ci 225562306a36Sopenharmony_ci /* Make sure work is stopped on probe-error / remove */ 225662306a36Sopenharmony_ci ret = devm_add_action_or_reset(&i2c->dev, rt5651_cancel_work, rt5651); 225762306a36Sopenharmony_ci if (ret) 225862306a36Sopenharmony_ci return ret; 225962306a36Sopenharmony_ci 226062306a36Sopenharmony_ci ret = devm_request_irq(&i2c->dev, rt5651->irq, rt5651_irq, 226162306a36Sopenharmony_ci IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING 226262306a36Sopenharmony_ci | IRQF_ONESHOT | IRQF_NO_AUTOEN, "rt5651", rt5651); 226362306a36Sopenharmony_ci if (ret) { 226462306a36Sopenharmony_ci dev_warn(&i2c->dev, "Failed to reguest IRQ %d: %d\n", 226562306a36Sopenharmony_ci rt5651->irq, ret); 226662306a36Sopenharmony_ci rt5651->irq = -ENXIO; 226762306a36Sopenharmony_ci } 226862306a36Sopenharmony_ci 226962306a36Sopenharmony_ci ret = devm_snd_soc_register_component(&i2c->dev, 227062306a36Sopenharmony_ci &soc_component_dev_rt5651, 227162306a36Sopenharmony_ci rt5651_dai, ARRAY_SIZE(rt5651_dai)); 227262306a36Sopenharmony_ci 227362306a36Sopenharmony_ci return ret; 227462306a36Sopenharmony_ci} 227562306a36Sopenharmony_ci 227662306a36Sopenharmony_cistatic struct i2c_driver rt5651_i2c_driver = { 227762306a36Sopenharmony_ci .driver = { 227862306a36Sopenharmony_ci .name = "rt5651", 227962306a36Sopenharmony_ci .acpi_match_table = ACPI_PTR(rt5651_acpi_match), 228062306a36Sopenharmony_ci .of_match_table = of_match_ptr(rt5651_of_match), 228162306a36Sopenharmony_ci }, 228262306a36Sopenharmony_ci .probe = rt5651_i2c_probe, 228362306a36Sopenharmony_ci .id_table = rt5651_i2c_id, 228462306a36Sopenharmony_ci}; 228562306a36Sopenharmony_cimodule_i2c_driver(rt5651_i2c_driver); 228662306a36Sopenharmony_ci 228762306a36Sopenharmony_ciMODULE_DESCRIPTION("ASoC RT5651 driver"); 228862306a36Sopenharmony_ciMODULE_AUTHOR("Bard Liao <bardliao@realtek.com>"); 228962306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 2290