18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * rt5616.c -- RT5616 ALSA SoC audio codec driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2015 Realtek Semiconductor Corp. 68c2ecf20Sopenharmony_ci * Author: Bard Liao <bardliao@realtek.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/module.h> 108c2ecf20Sopenharmony_ci#include <linux/moduleparam.h> 118c2ecf20Sopenharmony_ci#include <linux/init.h> 128c2ecf20Sopenharmony_ci#include <linux/clk.h> 138c2ecf20Sopenharmony_ci#include <linux/delay.h> 148c2ecf20Sopenharmony_ci#include <linux/pm.h> 158c2ecf20Sopenharmony_ci#include <linux/i2c.h> 168c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 178c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 188c2ecf20Sopenharmony_ci#include <sound/core.h> 198c2ecf20Sopenharmony_ci#include <sound/pcm.h> 208c2ecf20Sopenharmony_ci#include <sound/pcm_params.h> 218c2ecf20Sopenharmony_ci#include <sound/soc.h> 228c2ecf20Sopenharmony_ci#include <sound/soc-dapm.h> 238c2ecf20Sopenharmony_ci#include <sound/initval.h> 248c2ecf20Sopenharmony_ci#include <sound/tlv.h> 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#include "rl6231.h" 278c2ecf20Sopenharmony_ci#include "rt5616.h" 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define RT5616_PR_RANGE_BASE (0xff + 1) 308c2ecf20Sopenharmony_ci#define RT5616_PR_SPACING 0x100 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define RT5616_PR_BASE (RT5616_PR_RANGE_BASE + (0 * RT5616_PR_SPACING)) 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic const struct regmap_range_cfg rt5616_ranges[] = { 358c2ecf20Sopenharmony_ci { 368c2ecf20Sopenharmony_ci .name = "PR", 378c2ecf20Sopenharmony_ci .range_min = RT5616_PR_BASE, 388c2ecf20Sopenharmony_ci .range_max = RT5616_PR_BASE + 0xf8, 398c2ecf20Sopenharmony_ci .selector_reg = RT5616_PRIV_INDEX, 408c2ecf20Sopenharmony_ci .selector_mask = 0xff, 418c2ecf20Sopenharmony_ci .selector_shift = 0x0, 428c2ecf20Sopenharmony_ci .window_start = RT5616_PRIV_DATA, 438c2ecf20Sopenharmony_ci .window_len = 0x1, 448c2ecf20Sopenharmony_ci }, 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic const struct reg_sequence init_list[] = { 488c2ecf20Sopenharmony_ci {RT5616_PR_BASE + 0x3d, 0x3e00}, 498c2ecf20Sopenharmony_ci {RT5616_PR_BASE + 0x25, 0x6110}, 508c2ecf20Sopenharmony_ci {RT5616_PR_BASE + 0x20, 0x611f}, 518c2ecf20Sopenharmony_ci {RT5616_PR_BASE + 0x21, 0x4040}, 528c2ecf20Sopenharmony_ci {RT5616_PR_BASE + 0x23, 0x0004}, 538c2ecf20Sopenharmony_ci}; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define RT5616_INIT_REG_LEN ARRAY_SIZE(init_list) 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic const struct reg_default rt5616_reg[] = { 588c2ecf20Sopenharmony_ci { 0x00, 0x0021 }, 598c2ecf20Sopenharmony_ci { 0x02, 0xc8c8 }, 608c2ecf20Sopenharmony_ci { 0x03, 0xc8c8 }, 618c2ecf20Sopenharmony_ci { 0x05, 0x0000 }, 628c2ecf20Sopenharmony_ci { 0x0d, 0x0000 }, 638c2ecf20Sopenharmony_ci { 0x0f, 0x0808 }, 648c2ecf20Sopenharmony_ci { 0x19, 0xafaf }, 658c2ecf20Sopenharmony_ci { 0x1c, 0x2f2f }, 668c2ecf20Sopenharmony_ci { 0x1e, 0x0000 }, 678c2ecf20Sopenharmony_ci { 0x27, 0x7860 }, 688c2ecf20Sopenharmony_ci { 0x29, 0x8080 }, 698c2ecf20Sopenharmony_ci { 0x2a, 0x5252 }, 708c2ecf20Sopenharmony_ci { 0x3b, 0x0000 }, 718c2ecf20Sopenharmony_ci { 0x3c, 0x006f }, 728c2ecf20Sopenharmony_ci { 0x3d, 0x0000 }, 738c2ecf20Sopenharmony_ci { 0x3e, 0x006f }, 748c2ecf20Sopenharmony_ci { 0x45, 0x6000 }, 758c2ecf20Sopenharmony_ci { 0x4d, 0x0000 }, 768c2ecf20Sopenharmony_ci { 0x4e, 0x0000 }, 778c2ecf20Sopenharmony_ci { 0x4f, 0x0279 }, 788c2ecf20Sopenharmony_ci { 0x50, 0x0000 }, 798c2ecf20Sopenharmony_ci { 0x51, 0x0000 }, 808c2ecf20Sopenharmony_ci { 0x52, 0x0279 }, 818c2ecf20Sopenharmony_ci { 0x53, 0xf000 }, 828c2ecf20Sopenharmony_ci { 0x61, 0x0000 }, 838c2ecf20Sopenharmony_ci { 0x62, 0x0000 }, 848c2ecf20Sopenharmony_ci { 0x63, 0x00c0 }, 858c2ecf20Sopenharmony_ci { 0x64, 0x0000 }, 868c2ecf20Sopenharmony_ci { 0x65, 0x0000 }, 878c2ecf20Sopenharmony_ci { 0x66, 0x0000 }, 888c2ecf20Sopenharmony_ci { 0x70, 0x8000 }, 898c2ecf20Sopenharmony_ci { 0x73, 0x1104 }, 908c2ecf20Sopenharmony_ci { 0x74, 0x0c00 }, 918c2ecf20Sopenharmony_ci { 0x80, 0x0000 }, 928c2ecf20Sopenharmony_ci { 0x81, 0x0000 }, 938c2ecf20Sopenharmony_ci { 0x82, 0x0000 }, 948c2ecf20Sopenharmony_ci { 0x8b, 0x0600 }, 958c2ecf20Sopenharmony_ci { 0x8e, 0x0004 }, 968c2ecf20Sopenharmony_ci { 0x8f, 0x1100 }, 978c2ecf20Sopenharmony_ci { 0x90, 0x0000 }, 988c2ecf20Sopenharmony_ci { 0x91, 0x0c00 }, 998c2ecf20Sopenharmony_ci { 0x92, 0x0000 }, 1008c2ecf20Sopenharmony_ci { 0x93, 0x2000 }, 1018c2ecf20Sopenharmony_ci { 0x94, 0x0200 }, 1028c2ecf20Sopenharmony_ci { 0x95, 0x0000 }, 1038c2ecf20Sopenharmony_ci { 0xb0, 0x2080 }, 1048c2ecf20Sopenharmony_ci { 0xb1, 0x0000 }, 1058c2ecf20Sopenharmony_ci { 0xb2, 0x0000 }, 1068c2ecf20Sopenharmony_ci { 0xb4, 0x2206 }, 1078c2ecf20Sopenharmony_ci { 0xb5, 0x1f00 }, 1088c2ecf20Sopenharmony_ci { 0xb6, 0x0000 }, 1098c2ecf20Sopenharmony_ci { 0xb7, 0x0000 }, 1108c2ecf20Sopenharmony_ci { 0xbb, 0x0000 }, 1118c2ecf20Sopenharmony_ci { 0xbc, 0x0000 }, 1128c2ecf20Sopenharmony_ci { 0xbd, 0x0000 }, 1138c2ecf20Sopenharmony_ci { 0xbe, 0x0000 }, 1148c2ecf20Sopenharmony_ci { 0xbf, 0x0000 }, 1158c2ecf20Sopenharmony_ci { 0xc0, 0x0100 }, 1168c2ecf20Sopenharmony_ci { 0xc1, 0x0000 }, 1178c2ecf20Sopenharmony_ci { 0xc2, 0x0000 }, 1188c2ecf20Sopenharmony_ci { 0xc8, 0x0000 }, 1198c2ecf20Sopenharmony_ci { 0xc9, 0x0000 }, 1208c2ecf20Sopenharmony_ci { 0xca, 0x0000 }, 1218c2ecf20Sopenharmony_ci { 0xcb, 0x0000 }, 1228c2ecf20Sopenharmony_ci { 0xcc, 0x0000 }, 1238c2ecf20Sopenharmony_ci { 0xcd, 0x0000 }, 1248c2ecf20Sopenharmony_ci { 0xce, 0x0000 }, 1258c2ecf20Sopenharmony_ci { 0xcf, 0x0013 }, 1268c2ecf20Sopenharmony_ci { 0xd0, 0x0680 }, 1278c2ecf20Sopenharmony_ci { 0xd1, 0x1c17 }, 1288c2ecf20Sopenharmony_ci { 0xd3, 0xb320 }, 1298c2ecf20Sopenharmony_ci { 0xd4, 0x0000 }, 1308c2ecf20Sopenharmony_ci { 0xd6, 0x0000 }, 1318c2ecf20Sopenharmony_ci { 0xd7, 0x0000 }, 1328c2ecf20Sopenharmony_ci { 0xd9, 0x0809 }, 1338c2ecf20Sopenharmony_ci { 0xda, 0x0000 }, 1348c2ecf20Sopenharmony_ci { 0xfa, 0x0010 }, 1358c2ecf20Sopenharmony_ci { 0xfb, 0x0000 }, 1368c2ecf20Sopenharmony_ci { 0xfc, 0x0000 }, 1378c2ecf20Sopenharmony_ci { 0xfe, 0x10ec }, 1388c2ecf20Sopenharmony_ci { 0xff, 0x6281 }, 1398c2ecf20Sopenharmony_ci}; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistruct rt5616_priv { 1428c2ecf20Sopenharmony_ci struct snd_soc_component *component; 1438c2ecf20Sopenharmony_ci struct delayed_work patch_work; 1448c2ecf20Sopenharmony_ci struct regmap *regmap; 1458c2ecf20Sopenharmony_ci struct clk *mclk; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci int sysclk; 1488c2ecf20Sopenharmony_ci int sysclk_src; 1498c2ecf20Sopenharmony_ci int lrck[RT5616_AIFS]; 1508c2ecf20Sopenharmony_ci int bclk[RT5616_AIFS]; 1518c2ecf20Sopenharmony_ci int master[RT5616_AIFS]; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci int pll_src; 1548c2ecf20Sopenharmony_ci int pll_in; 1558c2ecf20Sopenharmony_ci int pll_out; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci}; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic bool rt5616_volatile_register(struct device *dev, unsigned int reg) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci int i; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) { 1648c2ecf20Sopenharmony_ci if (reg >= rt5616_ranges[i].range_min && 1658c2ecf20Sopenharmony_ci reg <= rt5616_ranges[i].range_max) 1668c2ecf20Sopenharmony_ci return true; 1678c2ecf20Sopenharmony_ci } 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci switch (reg) { 1708c2ecf20Sopenharmony_ci case RT5616_RESET: 1718c2ecf20Sopenharmony_ci case RT5616_PRIV_DATA: 1728c2ecf20Sopenharmony_ci case RT5616_EQ_CTRL1: 1738c2ecf20Sopenharmony_ci case RT5616_DRC_AGC_1: 1748c2ecf20Sopenharmony_ci case RT5616_IRQ_CTRL2: 1758c2ecf20Sopenharmony_ci case RT5616_INT_IRQ_ST: 1768c2ecf20Sopenharmony_ci case RT5616_PGM_REG_ARR1: 1778c2ecf20Sopenharmony_ci case RT5616_PGM_REG_ARR3: 1788c2ecf20Sopenharmony_ci case RT5616_VENDOR_ID: 1798c2ecf20Sopenharmony_ci case RT5616_DEVICE_ID: 1808c2ecf20Sopenharmony_ci return true; 1818c2ecf20Sopenharmony_ci default: 1828c2ecf20Sopenharmony_ci return false; 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci} 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_cistatic bool rt5616_readable_register(struct device *dev, unsigned int reg) 1878c2ecf20Sopenharmony_ci{ 1888c2ecf20Sopenharmony_ci int i; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) { 1918c2ecf20Sopenharmony_ci if (reg >= rt5616_ranges[i].range_min && 1928c2ecf20Sopenharmony_ci reg <= rt5616_ranges[i].range_max) 1938c2ecf20Sopenharmony_ci return true; 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci switch (reg) { 1978c2ecf20Sopenharmony_ci case RT5616_RESET: 1988c2ecf20Sopenharmony_ci case RT5616_VERSION_ID: 1998c2ecf20Sopenharmony_ci case RT5616_VENDOR_ID: 2008c2ecf20Sopenharmony_ci case RT5616_DEVICE_ID: 2018c2ecf20Sopenharmony_ci case RT5616_HP_VOL: 2028c2ecf20Sopenharmony_ci case RT5616_LOUT_CTRL1: 2038c2ecf20Sopenharmony_ci case RT5616_LOUT_CTRL2: 2048c2ecf20Sopenharmony_ci case RT5616_IN1_IN2: 2058c2ecf20Sopenharmony_ci case RT5616_INL1_INR1_VOL: 2068c2ecf20Sopenharmony_ci case RT5616_DAC1_DIG_VOL: 2078c2ecf20Sopenharmony_ci case RT5616_ADC_DIG_VOL: 2088c2ecf20Sopenharmony_ci case RT5616_ADC_BST_VOL: 2098c2ecf20Sopenharmony_ci case RT5616_STO1_ADC_MIXER: 2108c2ecf20Sopenharmony_ci case RT5616_AD_DA_MIXER: 2118c2ecf20Sopenharmony_ci case RT5616_STO_DAC_MIXER: 2128c2ecf20Sopenharmony_ci case RT5616_REC_L1_MIXER: 2138c2ecf20Sopenharmony_ci case RT5616_REC_L2_MIXER: 2148c2ecf20Sopenharmony_ci case RT5616_REC_R1_MIXER: 2158c2ecf20Sopenharmony_ci case RT5616_REC_R2_MIXER: 2168c2ecf20Sopenharmony_ci case RT5616_HPO_MIXER: 2178c2ecf20Sopenharmony_ci case RT5616_OUT_L1_MIXER: 2188c2ecf20Sopenharmony_ci case RT5616_OUT_L2_MIXER: 2198c2ecf20Sopenharmony_ci case RT5616_OUT_L3_MIXER: 2208c2ecf20Sopenharmony_ci case RT5616_OUT_R1_MIXER: 2218c2ecf20Sopenharmony_ci case RT5616_OUT_R2_MIXER: 2228c2ecf20Sopenharmony_ci case RT5616_OUT_R3_MIXER: 2238c2ecf20Sopenharmony_ci case RT5616_LOUT_MIXER: 2248c2ecf20Sopenharmony_ci case RT5616_PWR_DIG1: 2258c2ecf20Sopenharmony_ci case RT5616_PWR_DIG2: 2268c2ecf20Sopenharmony_ci case RT5616_PWR_ANLG1: 2278c2ecf20Sopenharmony_ci case RT5616_PWR_ANLG2: 2288c2ecf20Sopenharmony_ci case RT5616_PWR_MIXER: 2298c2ecf20Sopenharmony_ci case RT5616_PWR_VOL: 2308c2ecf20Sopenharmony_ci case RT5616_PRIV_INDEX: 2318c2ecf20Sopenharmony_ci case RT5616_PRIV_DATA: 2328c2ecf20Sopenharmony_ci case RT5616_I2S1_SDP: 2338c2ecf20Sopenharmony_ci case RT5616_ADDA_CLK1: 2348c2ecf20Sopenharmony_ci case RT5616_ADDA_CLK2: 2358c2ecf20Sopenharmony_ci case RT5616_GLB_CLK: 2368c2ecf20Sopenharmony_ci case RT5616_PLL_CTRL1: 2378c2ecf20Sopenharmony_ci case RT5616_PLL_CTRL2: 2388c2ecf20Sopenharmony_ci case RT5616_HP_OVCD: 2398c2ecf20Sopenharmony_ci case RT5616_DEPOP_M1: 2408c2ecf20Sopenharmony_ci case RT5616_DEPOP_M2: 2418c2ecf20Sopenharmony_ci case RT5616_DEPOP_M3: 2428c2ecf20Sopenharmony_ci case RT5616_CHARGE_PUMP: 2438c2ecf20Sopenharmony_ci case RT5616_PV_DET_SPK_G: 2448c2ecf20Sopenharmony_ci case RT5616_MICBIAS: 2458c2ecf20Sopenharmony_ci case RT5616_A_JD_CTL1: 2468c2ecf20Sopenharmony_ci case RT5616_A_JD_CTL2: 2478c2ecf20Sopenharmony_ci case RT5616_EQ_CTRL1: 2488c2ecf20Sopenharmony_ci case RT5616_EQ_CTRL2: 2498c2ecf20Sopenharmony_ci case RT5616_WIND_FILTER: 2508c2ecf20Sopenharmony_ci case RT5616_DRC_AGC_1: 2518c2ecf20Sopenharmony_ci case RT5616_DRC_AGC_2: 2528c2ecf20Sopenharmony_ci case RT5616_DRC_AGC_3: 2538c2ecf20Sopenharmony_ci case RT5616_SVOL_ZC: 2548c2ecf20Sopenharmony_ci case RT5616_JD_CTRL1: 2558c2ecf20Sopenharmony_ci case RT5616_JD_CTRL2: 2568c2ecf20Sopenharmony_ci case RT5616_IRQ_CTRL1: 2578c2ecf20Sopenharmony_ci case RT5616_IRQ_CTRL2: 2588c2ecf20Sopenharmony_ci case RT5616_INT_IRQ_ST: 2598c2ecf20Sopenharmony_ci case RT5616_GPIO_CTRL1: 2608c2ecf20Sopenharmony_ci case RT5616_GPIO_CTRL2: 2618c2ecf20Sopenharmony_ci case RT5616_GPIO_CTRL3: 2628c2ecf20Sopenharmony_ci case RT5616_PGM_REG_ARR1: 2638c2ecf20Sopenharmony_ci case RT5616_PGM_REG_ARR2: 2648c2ecf20Sopenharmony_ci case RT5616_PGM_REG_ARR3: 2658c2ecf20Sopenharmony_ci case RT5616_PGM_REG_ARR4: 2668c2ecf20Sopenharmony_ci case RT5616_PGM_REG_ARR5: 2678c2ecf20Sopenharmony_ci case RT5616_SCB_FUNC: 2688c2ecf20Sopenharmony_ci case RT5616_SCB_CTRL: 2698c2ecf20Sopenharmony_ci case RT5616_BASE_BACK: 2708c2ecf20Sopenharmony_ci case RT5616_MP3_PLUS1: 2718c2ecf20Sopenharmony_ci case RT5616_MP3_PLUS2: 2728c2ecf20Sopenharmony_ci case RT5616_ADJ_HPF_CTRL1: 2738c2ecf20Sopenharmony_ci case RT5616_ADJ_HPF_CTRL2: 2748c2ecf20Sopenharmony_ci case RT5616_HP_CALIB_AMP_DET: 2758c2ecf20Sopenharmony_ci case RT5616_HP_CALIB2: 2768c2ecf20Sopenharmony_ci case RT5616_SV_ZCD1: 2778c2ecf20Sopenharmony_ci case RT5616_SV_ZCD2: 2788c2ecf20Sopenharmony_ci case RT5616_D_MISC: 2798c2ecf20Sopenharmony_ci case RT5616_DUMMY2: 2808c2ecf20Sopenharmony_ci case RT5616_DUMMY3: 2818c2ecf20Sopenharmony_ci return true; 2828c2ecf20Sopenharmony_ci default: 2838c2ecf20Sopenharmony_ci return false; 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci} 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); 2888c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); 2898c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); 2908c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); 2918c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ 2948c2ecf20Sopenharmony_cistatic const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(bst_tlv, 2958c2ecf20Sopenharmony_ci 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 2968c2ecf20Sopenharmony_ci 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 2978c2ecf20Sopenharmony_ci 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), 2988c2ecf20Sopenharmony_ci 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), 2998c2ecf20Sopenharmony_ci 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), 3008c2ecf20Sopenharmony_ci 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), 3018c2ecf20Sopenharmony_ci 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), 3028c2ecf20Sopenharmony_ci); 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_snd_controls[] = { 3058c2ecf20Sopenharmony_ci /* Headphone Output Volume */ 3068c2ecf20Sopenharmony_ci SOC_DOUBLE("HP Playback Switch", RT5616_HP_VOL, 3078c2ecf20Sopenharmony_ci RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1), 3088c2ecf20Sopenharmony_ci SOC_DOUBLE("HPVOL Playback Switch", RT5616_HP_VOL, 3098c2ecf20Sopenharmony_ci RT5616_VOL_L_SFT, RT5616_VOL_R_SFT, 1, 1), 3108c2ecf20Sopenharmony_ci SOC_DOUBLE_TLV("HP Playback Volume", RT5616_HP_VOL, 3118c2ecf20Sopenharmony_ci RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv), 3128c2ecf20Sopenharmony_ci /* OUTPUT Control */ 3138c2ecf20Sopenharmony_ci SOC_DOUBLE("OUT Playback Switch", RT5616_LOUT_CTRL1, 3148c2ecf20Sopenharmony_ci RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1), 3158c2ecf20Sopenharmony_ci SOC_DOUBLE("OUT Channel Switch", RT5616_LOUT_CTRL1, 3168c2ecf20Sopenharmony_ci RT5616_VOL_L_SFT, RT5616_VOL_R_SFT, 1, 1), 3178c2ecf20Sopenharmony_ci SOC_DOUBLE_TLV("OUT Playback Volume", RT5616_LOUT_CTRL1, 3188c2ecf20Sopenharmony_ci RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv), 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci /* DAC Digital Volume */ 3218c2ecf20Sopenharmony_ci SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5616_DAC1_DIG_VOL, 3228c2ecf20Sopenharmony_ci RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 3238c2ecf20Sopenharmony_ci 175, 0, dac_vol_tlv), 3248c2ecf20Sopenharmony_ci /* IN1/IN2 Control */ 3258c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("IN1 Boost Volume", RT5616_IN1_IN2, 3268c2ecf20Sopenharmony_ci RT5616_BST_SFT1, 8, 0, bst_tlv), 3278c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("IN2 Boost Volume", RT5616_IN1_IN2, 3288c2ecf20Sopenharmony_ci RT5616_BST_SFT2, 8, 0, bst_tlv), 3298c2ecf20Sopenharmony_ci /* INL/INR Volume Control */ 3308c2ecf20Sopenharmony_ci SOC_DOUBLE_TLV("IN Capture Volume", RT5616_INL1_INR1_VOL, 3318c2ecf20Sopenharmony_ci RT5616_INL_VOL_SFT, RT5616_INR_VOL_SFT, 3328c2ecf20Sopenharmony_ci 31, 1, in_vol_tlv), 3338c2ecf20Sopenharmony_ci /* ADC Digital Volume Control */ 3348c2ecf20Sopenharmony_ci SOC_DOUBLE("ADC Capture Switch", RT5616_ADC_DIG_VOL, 3358c2ecf20Sopenharmony_ci RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1), 3368c2ecf20Sopenharmony_ci SOC_DOUBLE_TLV("ADC Capture Volume", RT5616_ADC_DIG_VOL, 3378c2ecf20Sopenharmony_ci RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 3388c2ecf20Sopenharmony_ci 127, 0, adc_vol_tlv), 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci /* ADC Boost Volume Control */ 3418c2ecf20Sopenharmony_ci SOC_DOUBLE_TLV("ADC Boost Volume", RT5616_ADC_BST_VOL, 3428c2ecf20Sopenharmony_ci RT5616_ADC_L_BST_SFT, RT5616_ADC_R_BST_SFT, 3438c2ecf20Sopenharmony_ci 3, 0, adc_bst_tlv), 3448c2ecf20Sopenharmony_ci}; 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_cistatic int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, 3478c2ecf20Sopenharmony_ci struct snd_soc_dapm_widget *sink) 3488c2ecf20Sopenharmony_ci{ 3498c2ecf20Sopenharmony_ci unsigned int val; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci val = snd_soc_component_read(snd_soc_dapm_to_component(source->dapm), RT5616_GLB_CLK); 3528c2ecf20Sopenharmony_ci val &= RT5616_SCLK_SRC_MASK; 3538c2ecf20Sopenharmony_ci if (val == RT5616_SCLK_SRC_PLL1) 3548c2ecf20Sopenharmony_ci return 1; 3558c2ecf20Sopenharmony_ci else 3568c2ecf20Sopenharmony_ci return 0; 3578c2ecf20Sopenharmony_ci} 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci/* Digital Mixer */ 3608c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_sto1_adc_l_mix[] = { 3618c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("ADC1 Switch", RT5616_STO1_ADC_MIXER, 3628c2ecf20Sopenharmony_ci RT5616_M_STO1_ADC_L1_SFT, 1, 1), 3638c2ecf20Sopenharmony_ci}; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_sto1_adc_r_mix[] = { 3668c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("ADC1 Switch", RT5616_STO1_ADC_MIXER, 3678c2ecf20Sopenharmony_ci RT5616_M_STO1_ADC_R1_SFT, 1, 1), 3688c2ecf20Sopenharmony_ci}; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_dac_l_mix[] = { 3718c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Stereo ADC Switch", RT5616_AD_DA_MIXER, 3728c2ecf20Sopenharmony_ci RT5616_M_ADCMIX_L_SFT, 1, 1), 3738c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("INF1 Switch", RT5616_AD_DA_MIXER, 3748c2ecf20Sopenharmony_ci RT5616_M_IF1_DAC_L_SFT, 1, 1), 3758c2ecf20Sopenharmony_ci}; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_dac_r_mix[] = { 3788c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Stereo ADC Switch", RT5616_AD_DA_MIXER, 3798c2ecf20Sopenharmony_ci RT5616_M_ADCMIX_R_SFT, 1, 1), 3808c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("INF1 Switch", RT5616_AD_DA_MIXER, 3818c2ecf20Sopenharmony_ci RT5616_M_IF1_DAC_R_SFT, 1, 1), 3828c2ecf20Sopenharmony_ci}; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_sto_dac_l_mix[] = { 3858c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_STO_DAC_MIXER, 3868c2ecf20Sopenharmony_ci RT5616_M_DAC_L1_MIXL_SFT, 1, 1), 3878c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_STO_DAC_MIXER, 3888c2ecf20Sopenharmony_ci RT5616_M_DAC_R1_MIXL_SFT, 1, 1), 3898c2ecf20Sopenharmony_ci}; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_sto_dac_r_mix[] = { 3928c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_STO_DAC_MIXER, 3938c2ecf20Sopenharmony_ci RT5616_M_DAC_R1_MIXR_SFT, 1, 1), 3948c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_STO_DAC_MIXER, 3958c2ecf20Sopenharmony_ci RT5616_M_DAC_L1_MIXR_SFT, 1, 1), 3968c2ecf20Sopenharmony_ci}; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci/* Analog Input Mixer */ 3998c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_rec_l_mix[] = { 4008c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("INL1 Switch", RT5616_REC_L2_MIXER, 4018c2ecf20Sopenharmony_ci RT5616_M_IN1_L_RM_L_SFT, 1, 1), 4028c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("BST2 Switch", RT5616_REC_L2_MIXER, 4038c2ecf20Sopenharmony_ci RT5616_M_BST2_RM_L_SFT, 1, 1), 4048c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("BST1 Switch", RT5616_REC_L2_MIXER, 4058c2ecf20Sopenharmony_ci RT5616_M_BST1_RM_L_SFT, 1, 1), 4068c2ecf20Sopenharmony_ci}; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_rec_r_mix[] = { 4098c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("INR1 Switch", RT5616_REC_R2_MIXER, 4108c2ecf20Sopenharmony_ci RT5616_M_IN1_R_RM_R_SFT, 1, 1), 4118c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("BST2 Switch", RT5616_REC_R2_MIXER, 4128c2ecf20Sopenharmony_ci RT5616_M_BST2_RM_R_SFT, 1, 1), 4138c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("BST1 Switch", RT5616_REC_R2_MIXER, 4148c2ecf20Sopenharmony_ci RT5616_M_BST1_RM_R_SFT, 1, 1), 4158c2ecf20Sopenharmony_ci}; 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci/* Analog Output Mixer */ 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_out_l_mix[] = { 4208c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("BST1 Switch", RT5616_OUT_L3_MIXER, 4218c2ecf20Sopenharmony_ci RT5616_M_BST1_OM_L_SFT, 1, 1), 4228c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("BST2 Switch", RT5616_OUT_L3_MIXER, 4238c2ecf20Sopenharmony_ci RT5616_M_BST2_OM_L_SFT, 1, 1), 4248c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("INL1 Switch", RT5616_OUT_L3_MIXER, 4258c2ecf20Sopenharmony_ci RT5616_M_IN1_L_OM_L_SFT, 1, 1), 4268c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("REC MIXL Switch", RT5616_OUT_L3_MIXER, 4278c2ecf20Sopenharmony_ci RT5616_M_RM_L_OM_L_SFT, 1, 1), 4288c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_OUT_L3_MIXER, 4298c2ecf20Sopenharmony_ci RT5616_M_DAC_L1_OM_L_SFT, 1, 1), 4308c2ecf20Sopenharmony_ci}; 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_out_r_mix[] = { 4338c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("BST2 Switch", RT5616_OUT_R3_MIXER, 4348c2ecf20Sopenharmony_ci RT5616_M_BST2_OM_R_SFT, 1, 1), 4358c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("BST1 Switch", RT5616_OUT_R3_MIXER, 4368c2ecf20Sopenharmony_ci RT5616_M_BST1_OM_R_SFT, 1, 1), 4378c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("INR1 Switch", RT5616_OUT_R3_MIXER, 4388c2ecf20Sopenharmony_ci RT5616_M_IN1_R_OM_R_SFT, 1, 1), 4398c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("REC MIXR Switch", RT5616_OUT_R3_MIXER, 4408c2ecf20Sopenharmony_ci RT5616_M_RM_R_OM_R_SFT, 1, 1), 4418c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_OUT_R3_MIXER, 4428c2ecf20Sopenharmony_ci RT5616_M_DAC_R1_OM_R_SFT, 1, 1), 4438c2ecf20Sopenharmony_ci}; 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_hpo_mix[] = { 4468c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC1 Switch", RT5616_HPO_MIXER, 4478c2ecf20Sopenharmony_ci RT5616_M_DAC1_HM_SFT, 1, 1), 4488c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("HPVOL Switch", RT5616_HPO_MIXER, 4498c2ecf20Sopenharmony_ci RT5616_M_HPVOL_HM_SFT, 1, 1), 4508c2ecf20Sopenharmony_ci}; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt5616_lout_mix[] = { 4538c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_LOUT_MIXER, 4548c2ecf20Sopenharmony_ci RT5616_M_DAC_L1_LM_SFT, 1, 1), 4558c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_LOUT_MIXER, 4568c2ecf20Sopenharmony_ci RT5616_M_DAC_R1_LM_SFT, 1, 1), 4578c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("OUTVOL L Switch", RT5616_LOUT_MIXER, 4588c2ecf20Sopenharmony_ci RT5616_M_OV_L_LM_SFT, 1, 1), 4598c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("OUTVOL R Switch", RT5616_LOUT_MIXER, 4608c2ecf20Sopenharmony_ci RT5616_M_OV_R_LM_SFT, 1, 1), 4618c2ecf20Sopenharmony_ci}; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_cistatic int rt5616_adc_event(struct snd_soc_dapm_widget *w, 4648c2ecf20Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 4658c2ecf20Sopenharmony_ci{ 4668c2ecf20Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci switch (event) { 4698c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 4708c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_ADC_DIG_VOL, 4718c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE, 0); 4728c2ecf20Sopenharmony_ci break; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMD: 4758c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_ADC_DIG_VOL, 4768c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE, 4778c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE); 4788c2ecf20Sopenharmony_ci break; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci default: 4818c2ecf20Sopenharmony_ci return 0; 4828c2ecf20Sopenharmony_ci } 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci return 0; 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cistatic int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w, 4888c2ecf20Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 4898c2ecf20Sopenharmony_ci{ 4908c2ecf20Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci switch (event) { 4938c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 4948c2ecf20Sopenharmony_ci /* depop parameters */ 4958c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M2, 4968c2ecf20Sopenharmony_ci RT5616_DEPOP_MASK, RT5616_DEPOP_MAN); 4978c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 4988c2ecf20Sopenharmony_ci RT5616_HP_CP_MASK | RT5616_HP_SG_MASK | 4998c2ecf20Sopenharmony_ci RT5616_HP_CB_MASK, RT5616_HP_CP_PU | 5008c2ecf20Sopenharmony_ci RT5616_HP_SG_DIS | RT5616_HP_CB_PU); 5018c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PR_BASE + 5028c2ecf20Sopenharmony_ci RT5616_HP_DCC_INT1, 0x9f00); 5038c2ecf20Sopenharmony_ci /* headphone amp power on */ 5048c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, 5058c2ecf20Sopenharmony_ci RT5616_PWR_FV1 | RT5616_PWR_FV2, 0); 5068c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_VOL, 5078c2ecf20Sopenharmony_ci RT5616_PWR_HV_L | RT5616_PWR_HV_R, 5088c2ecf20Sopenharmony_ci RT5616_PWR_HV_L | RT5616_PWR_HV_R); 5098c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, 5108c2ecf20Sopenharmony_ci RT5616_PWR_HP_L | RT5616_PWR_HP_R | 5118c2ecf20Sopenharmony_ci RT5616_PWR_HA, RT5616_PWR_HP_L | 5128c2ecf20Sopenharmony_ci RT5616_PWR_HP_R | RT5616_PWR_HA); 5138c2ecf20Sopenharmony_ci msleep(50); 5148c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, 5158c2ecf20Sopenharmony_ci RT5616_PWR_FV1 | RT5616_PWR_FV2, 5168c2ecf20Sopenharmony_ci RT5616_PWR_FV1 | RT5616_PWR_FV2); 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_CHARGE_PUMP, 5198c2ecf20Sopenharmony_ci RT5616_PM_HP_MASK, RT5616_PM_HP_HV); 5208c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PR_BASE + 5218c2ecf20Sopenharmony_ci RT5616_CHOP_DAC_ADC, 0x0200, 0x0200); 5228c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 5238c2ecf20Sopenharmony_ci RT5616_HP_CO_MASK | RT5616_HP_SG_MASK, 5248c2ecf20Sopenharmony_ci RT5616_HP_CO_EN | RT5616_HP_SG_EN); 5258c2ecf20Sopenharmony_ci break; 5268c2ecf20Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 5278c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PR_BASE + 5288c2ecf20Sopenharmony_ci RT5616_CHOP_DAC_ADC, 0x0200, 0x0); 5298c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 5308c2ecf20Sopenharmony_ci RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK | 5318c2ecf20Sopenharmony_ci RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS | 5328c2ecf20Sopenharmony_ci RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS); 5338c2ecf20Sopenharmony_ci /* headphone amp power down */ 5348c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 5358c2ecf20Sopenharmony_ci RT5616_SMT_TRIG_MASK | 5368c2ecf20Sopenharmony_ci RT5616_HP_CD_PD_MASK | RT5616_HP_CO_MASK | 5378c2ecf20Sopenharmony_ci RT5616_HP_CP_MASK | RT5616_HP_SG_MASK | 5388c2ecf20Sopenharmony_ci RT5616_HP_CB_MASK, 5398c2ecf20Sopenharmony_ci RT5616_SMT_TRIG_DIS | RT5616_HP_CD_PD_EN | 5408c2ecf20Sopenharmony_ci RT5616_HP_CO_DIS | RT5616_HP_CP_PD | 5418c2ecf20Sopenharmony_ci RT5616_HP_SG_EN | RT5616_HP_CB_PD); 5428c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, 5438c2ecf20Sopenharmony_ci RT5616_PWR_HP_L | RT5616_PWR_HP_R | 5448c2ecf20Sopenharmony_ci RT5616_PWR_HA, 0); 5458c2ecf20Sopenharmony_ci break; 5468c2ecf20Sopenharmony_ci default: 5478c2ecf20Sopenharmony_ci return 0; 5488c2ecf20Sopenharmony_ci } 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci return 0; 5518c2ecf20Sopenharmony_ci} 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_cistatic int rt5616_hp_event(struct snd_soc_dapm_widget *w, 5548c2ecf20Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 5558c2ecf20Sopenharmony_ci{ 5568c2ecf20Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci switch (event) { 5598c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 5608c2ecf20Sopenharmony_ci /* headphone unmute sequence */ 5618c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M3, 5628c2ecf20Sopenharmony_ci RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK | 5638c2ecf20Sopenharmony_ci RT5616_CP_FQ3_MASK, 5648c2ecf20Sopenharmony_ci RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ1_SFT | 5658c2ecf20Sopenharmony_ci RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT | 5668c2ecf20Sopenharmony_ci RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ3_SFT); 5678c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PR_BASE + 5688c2ecf20Sopenharmony_ci RT5616_MAMP_INT_REG2, 0xfc00); 5698c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 5708c2ecf20Sopenharmony_ci RT5616_SMT_TRIG_MASK, RT5616_SMT_TRIG_EN); 5718c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 5728c2ecf20Sopenharmony_ci RT5616_RSTN_MASK, RT5616_RSTN_EN); 5738c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 5748c2ecf20Sopenharmony_ci RT5616_RSTN_MASK | RT5616_HP_L_SMT_MASK | 5758c2ecf20Sopenharmony_ci RT5616_HP_R_SMT_MASK, RT5616_RSTN_DIS | 5768c2ecf20Sopenharmony_ci RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN); 5778c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_HP_VOL, 5788c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE, 0); 5798c2ecf20Sopenharmony_ci msleep(100); 5808c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 5818c2ecf20Sopenharmony_ci RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK | 5828c2ecf20Sopenharmony_ci RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS | 5838c2ecf20Sopenharmony_ci RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS); 5848c2ecf20Sopenharmony_ci msleep(20); 5858c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_HP_CALIB_AMP_DET, 5868c2ecf20Sopenharmony_ci RT5616_HPD_PS_MASK, RT5616_HPD_PS_EN); 5878c2ecf20Sopenharmony_ci break; 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 5908c2ecf20Sopenharmony_ci /* headphone mute sequence */ 5918c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M3, 5928c2ecf20Sopenharmony_ci RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK | 5938c2ecf20Sopenharmony_ci RT5616_CP_FQ3_MASK, 5948c2ecf20Sopenharmony_ci RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ1_SFT | 5958c2ecf20Sopenharmony_ci RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT | 5968c2ecf20Sopenharmony_ci RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ3_SFT); 5978c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PR_BASE + 5988c2ecf20Sopenharmony_ci RT5616_MAMP_INT_REG2, 0xfc00); 5998c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 6008c2ecf20Sopenharmony_ci RT5616_HP_SG_MASK, RT5616_HP_SG_EN); 6018c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 6028c2ecf20Sopenharmony_ci RT5616_RSTP_MASK, RT5616_RSTP_EN); 6038c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_DEPOP_M1, 6048c2ecf20Sopenharmony_ci RT5616_RSTP_MASK | RT5616_HP_L_SMT_MASK | 6058c2ecf20Sopenharmony_ci RT5616_HP_R_SMT_MASK, RT5616_RSTP_DIS | 6068c2ecf20Sopenharmony_ci RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN); 6078c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_HP_CALIB_AMP_DET, 6088c2ecf20Sopenharmony_ci RT5616_HPD_PS_MASK, RT5616_HPD_PS_DIS); 6098c2ecf20Sopenharmony_ci msleep(90); 6108c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_HP_VOL, 6118c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE, 6128c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE); 6138c2ecf20Sopenharmony_ci msleep(30); 6148c2ecf20Sopenharmony_ci break; 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci default: 6178c2ecf20Sopenharmony_ci return 0; 6188c2ecf20Sopenharmony_ci } 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci return 0; 6218c2ecf20Sopenharmony_ci} 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_cistatic int rt5616_lout_event(struct snd_soc_dapm_widget *w, 6248c2ecf20Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 6258c2ecf20Sopenharmony_ci{ 6268c2ecf20Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci switch (event) { 6298c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 6308c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, 6318c2ecf20Sopenharmony_ci RT5616_PWR_LM, RT5616_PWR_LM); 6328c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_LOUT_CTRL1, 6338c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE, 0); 6348c2ecf20Sopenharmony_ci break; 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 6378c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_LOUT_CTRL1, 6388c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE, 6398c2ecf20Sopenharmony_ci RT5616_L_MUTE | RT5616_R_MUTE); 6408c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, 6418c2ecf20Sopenharmony_ci RT5616_PWR_LM, 0); 6428c2ecf20Sopenharmony_ci break; 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci default: 6458c2ecf20Sopenharmony_ci return 0; 6468c2ecf20Sopenharmony_ci } 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci return 0; 6498c2ecf20Sopenharmony_ci} 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_cistatic int rt5616_bst1_event(struct snd_soc_dapm_widget *w, 6528c2ecf20Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 6538c2ecf20Sopenharmony_ci{ 6548c2ecf20Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci switch (event) { 6578c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 6588c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG2, 6598c2ecf20Sopenharmony_ci RT5616_PWR_BST1_OP2, RT5616_PWR_BST1_OP2); 6608c2ecf20Sopenharmony_ci break; 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 6638c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG2, 6648c2ecf20Sopenharmony_ci RT5616_PWR_BST1_OP2, 0); 6658c2ecf20Sopenharmony_ci break; 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci default: 6688c2ecf20Sopenharmony_ci return 0; 6698c2ecf20Sopenharmony_ci } 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci return 0; 6728c2ecf20Sopenharmony_ci} 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_cistatic int rt5616_bst2_event(struct snd_soc_dapm_widget *w, 6758c2ecf20Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 6768c2ecf20Sopenharmony_ci{ 6778c2ecf20Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci switch (event) { 6808c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 6818c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG2, 6828c2ecf20Sopenharmony_ci RT5616_PWR_BST2_OP2, RT5616_PWR_BST2_OP2); 6838c2ecf20Sopenharmony_ci break; 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 6868c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG2, 6878c2ecf20Sopenharmony_ci RT5616_PWR_BST2_OP2, 0); 6888c2ecf20Sopenharmony_ci break; 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci default: 6918c2ecf20Sopenharmony_ci return 0; 6928c2ecf20Sopenharmony_ci } 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci return 0; 6958c2ecf20Sopenharmony_ci} 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget rt5616_dapm_widgets[] = { 6988c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("PLL1", RT5616_PWR_ANLG2, 6998c2ecf20Sopenharmony_ci RT5616_PWR_PLL_BIT, 0, NULL, 0), 7008c2ecf20Sopenharmony_ci /* Input Side */ 7018c2ecf20Sopenharmony_ci /* micbias */ 7028c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("LDO", RT5616_PWR_ANLG1, 7038c2ecf20Sopenharmony_ci RT5616_PWR_LDO_BIT, 0, NULL, 0), 7048c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("micbias1", RT5616_PWR_ANLG2, 7058c2ecf20Sopenharmony_ci RT5616_PWR_MB1_BIT, 0, NULL, 0), 7068c2ecf20Sopenharmony_ci 7078c2ecf20Sopenharmony_ci /* Input Lines */ 7088c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC1"), 7098c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC2"), 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("IN1P"), 7128c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("IN2P"), 7138c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("IN2N"), 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci /* Boost */ 7168c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA_E("BST1", RT5616_PWR_ANLG2, 7178c2ecf20Sopenharmony_ci RT5616_PWR_BST1_BIT, 0, NULL, 0, rt5616_bst1_event, 7188c2ecf20Sopenharmony_ci SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 7198c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA_E("BST2", RT5616_PWR_ANLG2, 7208c2ecf20Sopenharmony_ci RT5616_PWR_BST2_BIT, 0, NULL, 0, rt5616_bst2_event, 7218c2ecf20Sopenharmony_ci SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 7228c2ecf20Sopenharmony_ci /* Input Volume */ 7238c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("INL1 VOL", RT5616_PWR_VOL, 7248c2ecf20Sopenharmony_ci RT5616_PWR_IN1_L_BIT, 0, NULL, 0), 7258c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("INR1 VOL", RT5616_PWR_VOL, 7268c2ecf20Sopenharmony_ci RT5616_PWR_IN1_R_BIT, 0, NULL, 0), 7278c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("INL2 VOL", RT5616_PWR_VOL, 7288c2ecf20Sopenharmony_ci RT5616_PWR_IN2_L_BIT, 0, NULL, 0), 7298c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("INR2 VOL", RT5616_PWR_VOL, 7308c2ecf20Sopenharmony_ci RT5616_PWR_IN2_R_BIT, 0, NULL, 0), 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci /* REC Mixer */ 7338c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("RECMIXL", RT5616_PWR_MIXER, RT5616_PWR_RM_L_BIT, 0, 7348c2ecf20Sopenharmony_ci rt5616_rec_l_mix, ARRAY_SIZE(rt5616_rec_l_mix)), 7358c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("RECMIXR", RT5616_PWR_MIXER, RT5616_PWR_RM_R_BIT, 0, 7368c2ecf20Sopenharmony_ci rt5616_rec_r_mix, ARRAY_SIZE(rt5616_rec_r_mix)), 7378c2ecf20Sopenharmony_ci /* ADCs */ 7388c2ecf20Sopenharmony_ci SND_SOC_DAPM_ADC_E("ADC L", NULL, RT5616_PWR_DIG1, 7398c2ecf20Sopenharmony_ci RT5616_PWR_ADC_L_BIT, 0, rt5616_adc_event, 7408c2ecf20Sopenharmony_ci SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), 7418c2ecf20Sopenharmony_ci SND_SOC_DAPM_ADC_E("ADC R", NULL, RT5616_PWR_DIG1, 7428c2ecf20Sopenharmony_ci RT5616_PWR_ADC_R_BIT, 0, rt5616_adc_event, 7438c2ecf20Sopenharmony_ci SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ci /* ADC Mixer */ 7468c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("stereo1 filter", RT5616_PWR_DIG2, 7478c2ecf20Sopenharmony_ci RT5616_PWR_ADC_STO1_F_BIT, 0, NULL, 0), 7488c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, 7498c2ecf20Sopenharmony_ci rt5616_sto1_adc_l_mix, 7508c2ecf20Sopenharmony_ci ARRAY_SIZE(rt5616_sto1_adc_l_mix)), 7518c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0, 7528c2ecf20Sopenharmony_ci rt5616_sto1_adc_r_mix, 7538c2ecf20Sopenharmony_ci ARRAY_SIZE(rt5616_sto1_adc_r_mix)), 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_ci /* Digital Interface */ 7568c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("I2S1", RT5616_PWR_DIG1, 7578c2ecf20Sopenharmony_ci RT5616_PWR_I2S1_BIT, 0, NULL, 0), 7588c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), 7598c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0), 7608c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0), 7618c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("IF1 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_ci /* Digital Interface Select */ 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci /* Audio Interface */ 7668c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 7678c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), 7688c2ecf20Sopenharmony_ci 7698c2ecf20Sopenharmony_ci /* Audio DSP */ 7708c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci /* Output Side */ 7738c2ecf20Sopenharmony_ci /* DAC mixer before sound effect */ 7748c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, 7758c2ecf20Sopenharmony_ci rt5616_dac_l_mix, ARRAY_SIZE(rt5616_dac_l_mix)), 7768c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, 7778c2ecf20Sopenharmony_ci rt5616_dac_r_mix, ARRAY_SIZE(rt5616_dac_r_mix)), 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Stero1 DAC Power", RT5616_PWR_DIG2, 7808c2ecf20Sopenharmony_ci RT5616_PWR_DAC_STO1_F_BIT, 0, NULL, 0), 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci /* DAC Mixer */ 7838c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, 7848c2ecf20Sopenharmony_ci rt5616_sto_dac_l_mix, 7858c2ecf20Sopenharmony_ci ARRAY_SIZE(rt5616_sto_dac_l_mix)), 7868c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, 7878c2ecf20Sopenharmony_ci rt5616_sto_dac_r_mix, 7888c2ecf20Sopenharmony_ci ARRAY_SIZE(rt5616_sto_dac_r_mix)), 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_ci /* DACs */ 7918c2ecf20Sopenharmony_ci SND_SOC_DAPM_DAC("DAC L1", NULL, RT5616_PWR_DIG1, 7928c2ecf20Sopenharmony_ci RT5616_PWR_DAC_L1_BIT, 0), 7938c2ecf20Sopenharmony_ci SND_SOC_DAPM_DAC("DAC R1", NULL, RT5616_PWR_DIG1, 7948c2ecf20Sopenharmony_ci RT5616_PWR_DAC_R1_BIT, 0), 7958c2ecf20Sopenharmony_ci /* OUT Mixer */ 7968c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("OUT MIXL", RT5616_PWR_MIXER, RT5616_PWR_OM_L_BIT, 7978c2ecf20Sopenharmony_ci 0, rt5616_out_l_mix, ARRAY_SIZE(rt5616_out_l_mix)), 7988c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("OUT MIXR", RT5616_PWR_MIXER, RT5616_PWR_OM_R_BIT, 7998c2ecf20Sopenharmony_ci 0, rt5616_out_r_mix, ARRAY_SIZE(rt5616_out_r_mix)), 8008c2ecf20Sopenharmony_ci /* Output Volume */ 8018c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("OUTVOL L", RT5616_PWR_VOL, 8028c2ecf20Sopenharmony_ci RT5616_PWR_OV_L_BIT, 0, NULL, 0), 8038c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("OUTVOL R", RT5616_PWR_VOL, 8048c2ecf20Sopenharmony_ci RT5616_PWR_OV_R_BIT, 0, NULL, 0), 8058c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("HPOVOL L", RT5616_PWR_VOL, 8068c2ecf20Sopenharmony_ci RT5616_PWR_HV_L_BIT, 0, NULL, 0), 8078c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("HPOVOL R", RT5616_PWR_VOL, 8088c2ecf20Sopenharmony_ci RT5616_PWR_HV_R_BIT, 0, NULL, 0), 8098c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM, 8108c2ecf20Sopenharmony_ci 0, 0, NULL, 0), 8118c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM, 8128c2ecf20Sopenharmony_ci 0, 0, NULL, 0), 8138c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM, 8148c2ecf20Sopenharmony_ci 0, 0, NULL, 0), 8158c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("INL1", RT5616_PWR_VOL, 8168c2ecf20Sopenharmony_ci RT5616_PWR_IN1_L_BIT, 0, NULL, 0), 8178c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("INR1", RT5616_PWR_VOL, 8188c2ecf20Sopenharmony_ci RT5616_PWR_IN1_R_BIT, 0, NULL, 0), 8198c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("INL2", RT5616_PWR_VOL, 8208c2ecf20Sopenharmony_ci RT5616_PWR_IN2_L_BIT, 0, NULL, 0), 8218c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("INR2", RT5616_PWR_VOL, 8228c2ecf20Sopenharmony_ci RT5616_PWR_IN2_R_BIT, 0, NULL, 0), 8238c2ecf20Sopenharmony_ci /* HPO/LOUT/Mono Mixer */ 8248c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0, 8258c2ecf20Sopenharmony_ci rt5616_hpo_mix, ARRAY_SIZE(rt5616_hpo_mix)), 8268c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0, 8278c2ecf20Sopenharmony_ci rt5616_lout_mix, ARRAY_SIZE(rt5616_lout_mix)), 8288c2ecf20Sopenharmony_ci 8298c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA_S("HP amp", 1, SND_SOC_NOPM, 0, 0, 8308c2ecf20Sopenharmony_ci rt5616_hp_event, SND_SOC_DAPM_PRE_PMD | 8318c2ecf20Sopenharmony_ci SND_SOC_DAPM_POST_PMU), 8328c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA_S("LOUT amp", 1, SND_SOC_NOPM, 0, 0, 8338c2ecf20Sopenharmony_ci rt5616_lout_event, SND_SOC_DAPM_PRE_PMD | 8348c2ecf20Sopenharmony_ci SND_SOC_DAPM_POST_PMU), 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, SND_SOC_NOPM, 0, 0, 8378c2ecf20Sopenharmony_ci rt5616_charge_pump_event, SND_SOC_DAPM_POST_PMU | 8388c2ecf20Sopenharmony_ci SND_SOC_DAPM_PRE_PMD), 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci /* Output Lines */ 8418c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPOL"), 8428c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPOR"), 8438c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("LOUTL"), 8448c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("LOUTR"), 8458c2ecf20Sopenharmony_ci}; 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route rt5616_dapm_routes[] = { 8488c2ecf20Sopenharmony_ci {"IN1P", NULL, "LDO"}, 8498c2ecf20Sopenharmony_ci {"IN2P", NULL, "LDO"}, 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci {"IN1P", NULL, "MIC1"}, 8528c2ecf20Sopenharmony_ci {"IN2P", NULL, "MIC2"}, 8538c2ecf20Sopenharmony_ci {"IN2N", NULL, "MIC2"}, 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci {"BST1", NULL, "IN1P"}, 8568c2ecf20Sopenharmony_ci {"BST2", NULL, "IN2P"}, 8578c2ecf20Sopenharmony_ci {"BST2", NULL, "IN2N"}, 8588c2ecf20Sopenharmony_ci {"BST1", NULL, "micbias1"}, 8598c2ecf20Sopenharmony_ci {"BST2", NULL, "micbias1"}, 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_ci {"INL1 VOL", NULL, "IN2P"}, 8628c2ecf20Sopenharmony_ci {"INR1 VOL", NULL, "IN2N"}, 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci {"RECMIXL", "INL1 Switch", "INL1 VOL"}, 8658c2ecf20Sopenharmony_ci {"RECMIXL", "BST2 Switch", "BST2"}, 8668c2ecf20Sopenharmony_ci {"RECMIXL", "BST1 Switch", "BST1"}, 8678c2ecf20Sopenharmony_ci 8688c2ecf20Sopenharmony_ci {"RECMIXR", "INR1 Switch", "INR1 VOL"}, 8698c2ecf20Sopenharmony_ci {"RECMIXR", "BST2 Switch", "BST2"}, 8708c2ecf20Sopenharmony_ci {"RECMIXR", "BST1 Switch", "BST1"}, 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci {"ADC L", NULL, "RECMIXL"}, 8738c2ecf20Sopenharmony_ci {"ADC R", NULL, "RECMIXR"}, 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci {"Stereo1 ADC MIXL", "ADC1 Switch", "ADC L"}, 8768c2ecf20Sopenharmony_ci {"Stereo1 ADC MIXL", NULL, "stereo1 filter"}, 8778c2ecf20Sopenharmony_ci {"stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll}, 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci {"Stereo1 ADC MIXR", "ADC1 Switch", "ADC R"}, 8808c2ecf20Sopenharmony_ci {"Stereo1 ADC MIXR", NULL, "stereo1 filter"}, 8818c2ecf20Sopenharmony_ci {"stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll}, 8828c2ecf20Sopenharmony_ci 8838c2ecf20Sopenharmony_ci {"IF1 ADC1", NULL, "Stereo1 ADC MIXL"}, 8848c2ecf20Sopenharmony_ci {"IF1 ADC1", NULL, "Stereo1 ADC MIXR"}, 8858c2ecf20Sopenharmony_ci {"IF1 ADC1", NULL, "I2S1"}, 8868c2ecf20Sopenharmony_ci 8878c2ecf20Sopenharmony_ci {"AIF1TX", NULL, "IF1 ADC1"}, 8888c2ecf20Sopenharmony_ci 8898c2ecf20Sopenharmony_ci {"IF1 DAC", NULL, "AIF1RX"}, 8908c2ecf20Sopenharmony_ci {"IF1 DAC", NULL, "I2S1"}, 8918c2ecf20Sopenharmony_ci 8928c2ecf20Sopenharmony_ci {"IF1 DAC1 L", NULL, "IF1 DAC"}, 8938c2ecf20Sopenharmony_ci {"IF1 DAC1 R", NULL, "IF1 DAC"}, 8948c2ecf20Sopenharmony_ci 8958c2ecf20Sopenharmony_ci {"DAC MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL"}, 8968c2ecf20Sopenharmony_ci {"DAC MIXL", "INF1 Switch", "IF1 DAC1 L"}, 8978c2ecf20Sopenharmony_ci {"DAC MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR"}, 8988c2ecf20Sopenharmony_ci {"DAC MIXR", "INF1 Switch", "IF1 DAC1 R"}, 8998c2ecf20Sopenharmony_ci 9008c2ecf20Sopenharmony_ci {"Audio DSP", NULL, "DAC MIXL"}, 9018c2ecf20Sopenharmony_ci {"Audio DSP", NULL, "DAC MIXR"}, 9028c2ecf20Sopenharmony_ci 9038c2ecf20Sopenharmony_ci {"Stereo DAC MIXL", "DAC L1 Switch", "Audio DSP"}, 9048c2ecf20Sopenharmony_ci {"Stereo DAC MIXL", "DAC R1 Switch", "DAC MIXR"}, 9058c2ecf20Sopenharmony_ci {"Stereo DAC MIXL", NULL, "Stero1 DAC Power"}, 9068c2ecf20Sopenharmony_ci {"Stereo DAC MIXR", "DAC R1 Switch", "Audio DSP"}, 9078c2ecf20Sopenharmony_ci {"Stereo DAC MIXR", "DAC L1 Switch", "DAC MIXL"}, 9088c2ecf20Sopenharmony_ci {"Stereo DAC MIXR", NULL, "Stero1 DAC Power"}, 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_ci {"DAC L1", NULL, "Stereo DAC MIXL"}, 9118c2ecf20Sopenharmony_ci {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll}, 9128c2ecf20Sopenharmony_ci {"DAC R1", NULL, "Stereo DAC MIXR"}, 9138c2ecf20Sopenharmony_ci {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll}, 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_ci {"OUT MIXL", "BST1 Switch", "BST1"}, 9168c2ecf20Sopenharmony_ci {"OUT MIXL", "BST2 Switch", "BST2"}, 9178c2ecf20Sopenharmony_ci {"OUT MIXL", "INL1 Switch", "INL1 VOL"}, 9188c2ecf20Sopenharmony_ci {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, 9198c2ecf20Sopenharmony_ci {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_ci {"OUT MIXR", "BST2 Switch", "BST2"}, 9228c2ecf20Sopenharmony_ci {"OUT MIXR", "BST1 Switch", "BST1"}, 9238c2ecf20Sopenharmony_ci {"OUT MIXR", "INR1 Switch", "INR1 VOL"}, 9248c2ecf20Sopenharmony_ci {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, 9258c2ecf20Sopenharmony_ci {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, 9268c2ecf20Sopenharmony_ci 9278c2ecf20Sopenharmony_ci {"HPOVOL L", NULL, "OUT MIXL"}, 9288c2ecf20Sopenharmony_ci {"HPOVOL R", NULL, "OUT MIXR"}, 9298c2ecf20Sopenharmony_ci {"OUTVOL L", NULL, "OUT MIXL"}, 9308c2ecf20Sopenharmony_ci {"OUTVOL R", NULL, "OUT MIXR"}, 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci {"DAC 1", NULL, "DAC L1"}, 9338c2ecf20Sopenharmony_ci {"DAC 1", NULL, "DAC R1"}, 9348c2ecf20Sopenharmony_ci {"HPOVOL", NULL, "HPOVOL L"}, 9358c2ecf20Sopenharmony_ci {"HPOVOL", NULL, "HPOVOL R"}, 9368c2ecf20Sopenharmony_ci {"HPO MIX", "DAC1 Switch", "DAC 1"}, 9378c2ecf20Sopenharmony_ci {"HPO MIX", "HPVOL Switch", "HPOVOL"}, 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, 9408c2ecf20Sopenharmony_ci {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, 9418c2ecf20Sopenharmony_ci {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, 9428c2ecf20Sopenharmony_ci {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_ci {"HP amp", NULL, "HPO MIX"}, 9458c2ecf20Sopenharmony_ci {"HP amp", NULL, "Charge Pump"}, 9468c2ecf20Sopenharmony_ci {"HPOL", NULL, "HP amp"}, 9478c2ecf20Sopenharmony_ci {"HPOR", NULL, "HP amp"}, 9488c2ecf20Sopenharmony_ci 9498c2ecf20Sopenharmony_ci {"LOUT amp", NULL, "LOUT MIX"}, 9508c2ecf20Sopenharmony_ci {"LOUT amp", NULL, "Charge Pump"}, 9518c2ecf20Sopenharmony_ci {"LOUTL", NULL, "LOUT amp"}, 9528c2ecf20Sopenharmony_ci {"LOUTR", NULL, "LOUT amp"}, 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci}; 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_cistatic int rt5616_hw_params(struct snd_pcm_substream *substream, 9578c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params, 9588c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 9598c2ecf20Sopenharmony_ci{ 9608c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 9618c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); 9628c2ecf20Sopenharmony_ci unsigned int val_len = 0, val_clk, mask_clk; 9638c2ecf20Sopenharmony_ci int pre_div, bclk_ms, frame_size; 9648c2ecf20Sopenharmony_ci 9658c2ecf20Sopenharmony_ci rt5616->lrck[dai->id] = params_rate(params); 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_ci pre_div = rl6231_get_clk_info(rt5616->sysclk, rt5616->lrck[dai->id]); 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci if (pre_div < 0) { 9708c2ecf20Sopenharmony_ci dev_err(component->dev, "Unsupported clock setting\n"); 9718c2ecf20Sopenharmony_ci return -EINVAL; 9728c2ecf20Sopenharmony_ci } 9738c2ecf20Sopenharmony_ci frame_size = snd_soc_params_to_frame_size(params); 9748c2ecf20Sopenharmony_ci if (frame_size < 0) { 9758c2ecf20Sopenharmony_ci dev_err(component->dev, "Unsupported frame size: %d\n", frame_size); 9768c2ecf20Sopenharmony_ci return -EINVAL; 9778c2ecf20Sopenharmony_ci } 9788c2ecf20Sopenharmony_ci bclk_ms = frame_size > 32 ? 1 : 0; 9798c2ecf20Sopenharmony_ci rt5616->bclk[dai->id] = rt5616->lrck[dai->id] * (32 << bclk_ms); 9808c2ecf20Sopenharmony_ci 9818c2ecf20Sopenharmony_ci dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n", 9828c2ecf20Sopenharmony_ci rt5616->bclk[dai->id], rt5616->lrck[dai->id]); 9838c2ecf20Sopenharmony_ci dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", 9848c2ecf20Sopenharmony_ci bclk_ms, pre_div, dai->id); 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci switch (params_format(params)) { 9878c2ecf20Sopenharmony_ci case SNDRV_PCM_FORMAT_S16_LE: 9888c2ecf20Sopenharmony_ci break; 9898c2ecf20Sopenharmony_ci case SNDRV_PCM_FORMAT_S20_3LE: 9908c2ecf20Sopenharmony_ci val_len |= RT5616_I2S_DL_20; 9918c2ecf20Sopenharmony_ci break; 9928c2ecf20Sopenharmony_ci case SNDRV_PCM_FORMAT_S24_LE: 9938c2ecf20Sopenharmony_ci val_len |= RT5616_I2S_DL_24; 9948c2ecf20Sopenharmony_ci break; 9958c2ecf20Sopenharmony_ci case SNDRV_PCM_FORMAT_S8: 9968c2ecf20Sopenharmony_ci val_len |= RT5616_I2S_DL_8; 9978c2ecf20Sopenharmony_ci break; 9988c2ecf20Sopenharmony_ci default: 9998c2ecf20Sopenharmony_ci return -EINVAL; 10008c2ecf20Sopenharmony_ci } 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci mask_clk = RT5616_I2S_PD1_MASK; 10038c2ecf20Sopenharmony_ci val_clk = pre_div << RT5616_I2S_PD1_SFT; 10048c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_I2S1_SDP, 10058c2ecf20Sopenharmony_ci RT5616_I2S_DL_MASK, val_len); 10068c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_ADDA_CLK1, mask_clk, val_clk); 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_ci return 0; 10098c2ecf20Sopenharmony_ci} 10108c2ecf20Sopenharmony_ci 10118c2ecf20Sopenharmony_cistatic int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 10128c2ecf20Sopenharmony_ci{ 10138c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 10148c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); 10158c2ecf20Sopenharmony_ci unsigned int reg_val = 0; 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 10188c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_CBM_CFM: 10198c2ecf20Sopenharmony_ci rt5616->master[dai->id] = 1; 10208c2ecf20Sopenharmony_ci break; 10218c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_CBS_CFS: 10228c2ecf20Sopenharmony_ci reg_val |= RT5616_I2S_MS_S; 10238c2ecf20Sopenharmony_ci rt5616->master[dai->id] = 0; 10248c2ecf20Sopenharmony_ci break; 10258c2ecf20Sopenharmony_ci default: 10268c2ecf20Sopenharmony_ci return -EINVAL; 10278c2ecf20Sopenharmony_ci } 10288c2ecf20Sopenharmony_ci 10298c2ecf20Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 10308c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_NB_NF: 10318c2ecf20Sopenharmony_ci break; 10328c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_IB_NF: 10338c2ecf20Sopenharmony_ci reg_val |= RT5616_I2S_BP_INV; 10348c2ecf20Sopenharmony_ci break; 10358c2ecf20Sopenharmony_ci default: 10368c2ecf20Sopenharmony_ci return -EINVAL; 10378c2ecf20Sopenharmony_ci } 10388c2ecf20Sopenharmony_ci 10398c2ecf20Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 10408c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_I2S: 10418c2ecf20Sopenharmony_ci break; 10428c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_LEFT_J: 10438c2ecf20Sopenharmony_ci reg_val |= RT5616_I2S_DF_LEFT; 10448c2ecf20Sopenharmony_ci break; 10458c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_DSP_A: 10468c2ecf20Sopenharmony_ci reg_val |= RT5616_I2S_DF_PCM_A; 10478c2ecf20Sopenharmony_ci break; 10488c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_DSP_B: 10498c2ecf20Sopenharmony_ci reg_val |= RT5616_I2S_DF_PCM_B; 10508c2ecf20Sopenharmony_ci break; 10518c2ecf20Sopenharmony_ci default: 10528c2ecf20Sopenharmony_ci return -EINVAL; 10538c2ecf20Sopenharmony_ci } 10548c2ecf20Sopenharmony_ci 10558c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_I2S1_SDP, 10568c2ecf20Sopenharmony_ci RT5616_I2S_MS_MASK | RT5616_I2S_BP_MASK | 10578c2ecf20Sopenharmony_ci RT5616_I2S_DF_MASK, reg_val); 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_ci return 0; 10608c2ecf20Sopenharmony_ci} 10618c2ecf20Sopenharmony_ci 10628c2ecf20Sopenharmony_cistatic int rt5616_set_dai_sysclk(struct snd_soc_dai *dai, 10638c2ecf20Sopenharmony_ci int clk_id, unsigned int freq, int dir) 10648c2ecf20Sopenharmony_ci{ 10658c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 10668c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); 10678c2ecf20Sopenharmony_ci unsigned int reg_val = 0; 10688c2ecf20Sopenharmony_ci 10698c2ecf20Sopenharmony_ci if (freq == rt5616->sysclk && clk_id == rt5616->sysclk_src) 10708c2ecf20Sopenharmony_ci return 0; 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_ci switch (clk_id) { 10738c2ecf20Sopenharmony_ci case RT5616_SCLK_S_MCLK: 10748c2ecf20Sopenharmony_ci reg_val |= RT5616_SCLK_SRC_MCLK; 10758c2ecf20Sopenharmony_ci break; 10768c2ecf20Sopenharmony_ci case RT5616_SCLK_S_PLL1: 10778c2ecf20Sopenharmony_ci reg_val |= RT5616_SCLK_SRC_PLL1; 10788c2ecf20Sopenharmony_ci break; 10798c2ecf20Sopenharmony_ci default: 10808c2ecf20Sopenharmony_ci dev_err(component->dev, "Invalid clock id (%d)\n", clk_id); 10818c2ecf20Sopenharmony_ci return -EINVAL; 10828c2ecf20Sopenharmony_ci } 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_GLB_CLK, 10858c2ecf20Sopenharmony_ci RT5616_SCLK_SRC_MASK, reg_val); 10868c2ecf20Sopenharmony_ci rt5616->sysclk = freq; 10878c2ecf20Sopenharmony_ci rt5616->sysclk_src = clk_id; 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_ci return 0; 10928c2ecf20Sopenharmony_ci} 10938c2ecf20Sopenharmony_ci 10948c2ecf20Sopenharmony_cistatic int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, 10958c2ecf20Sopenharmony_ci unsigned int freq_in, unsigned int freq_out) 10968c2ecf20Sopenharmony_ci{ 10978c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 10988c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); 10998c2ecf20Sopenharmony_ci struct rl6231_pll_code pll_code; 11008c2ecf20Sopenharmony_ci int ret; 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_ci if (source == rt5616->pll_src && freq_in == rt5616->pll_in && 11038c2ecf20Sopenharmony_ci freq_out == rt5616->pll_out) 11048c2ecf20Sopenharmony_ci return 0; 11058c2ecf20Sopenharmony_ci 11068c2ecf20Sopenharmony_ci if (!freq_in || !freq_out) { 11078c2ecf20Sopenharmony_ci dev_dbg(component->dev, "PLL disabled\n"); 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ci rt5616->pll_in = 0; 11108c2ecf20Sopenharmony_ci rt5616->pll_out = 0; 11118c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_GLB_CLK, 11128c2ecf20Sopenharmony_ci RT5616_SCLK_SRC_MASK, 11138c2ecf20Sopenharmony_ci RT5616_SCLK_SRC_MCLK); 11148c2ecf20Sopenharmony_ci return 0; 11158c2ecf20Sopenharmony_ci } 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_ci switch (source) { 11188c2ecf20Sopenharmony_ci case RT5616_PLL1_S_MCLK: 11198c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_GLB_CLK, 11208c2ecf20Sopenharmony_ci RT5616_PLL1_SRC_MASK, 11218c2ecf20Sopenharmony_ci RT5616_PLL1_SRC_MCLK); 11228c2ecf20Sopenharmony_ci break; 11238c2ecf20Sopenharmony_ci case RT5616_PLL1_S_BCLK1: 11248c2ecf20Sopenharmony_ci case RT5616_PLL1_S_BCLK2: 11258c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_GLB_CLK, 11268c2ecf20Sopenharmony_ci RT5616_PLL1_SRC_MASK, 11278c2ecf20Sopenharmony_ci RT5616_PLL1_SRC_BCLK1); 11288c2ecf20Sopenharmony_ci break; 11298c2ecf20Sopenharmony_ci default: 11308c2ecf20Sopenharmony_ci dev_err(component->dev, "Unknown PLL source %d\n", source); 11318c2ecf20Sopenharmony_ci return -EINVAL; 11328c2ecf20Sopenharmony_ci } 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_ci ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); 11358c2ecf20Sopenharmony_ci if (ret < 0) { 11368c2ecf20Sopenharmony_ci dev_err(component->dev, "Unsupport input clock %d\n", freq_in); 11378c2ecf20Sopenharmony_ci return ret; 11388c2ecf20Sopenharmony_ci } 11398c2ecf20Sopenharmony_ci 11408c2ecf20Sopenharmony_ci dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n", 11418c2ecf20Sopenharmony_ci pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), 11428c2ecf20Sopenharmony_ci pll_code.n_code, pll_code.k_code); 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PLL_CTRL1, 11458c2ecf20Sopenharmony_ci pll_code.n_code << RT5616_PLL_N_SFT | pll_code.k_code); 11468c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PLL_CTRL2, 11478c2ecf20Sopenharmony_ci (pll_code.m_bp ? 0 : pll_code.m_code) << 11488c2ecf20Sopenharmony_ci RT5616_PLL_M_SFT | 11498c2ecf20Sopenharmony_ci pll_code.m_bp << RT5616_PLL_M_BP_SFT); 11508c2ecf20Sopenharmony_ci 11518c2ecf20Sopenharmony_ci rt5616->pll_in = freq_in; 11528c2ecf20Sopenharmony_ci rt5616->pll_out = freq_out; 11538c2ecf20Sopenharmony_ci rt5616->pll_src = source; 11548c2ecf20Sopenharmony_ci 11558c2ecf20Sopenharmony_ci return 0; 11568c2ecf20Sopenharmony_ci} 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_cistatic int rt5616_set_bias_level(struct snd_soc_component *component, 11598c2ecf20Sopenharmony_ci enum snd_soc_bias_level level) 11608c2ecf20Sopenharmony_ci{ 11618c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); 11628c2ecf20Sopenharmony_ci int ret; 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci switch (level) { 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_ci case SND_SOC_BIAS_ON: 11678c2ecf20Sopenharmony_ci break; 11688c2ecf20Sopenharmony_ci 11698c2ecf20Sopenharmony_ci case SND_SOC_BIAS_PREPARE: 11708c2ecf20Sopenharmony_ci /* 11718c2ecf20Sopenharmony_ci * SND_SOC_BIAS_PREPARE is called while preparing for a 11728c2ecf20Sopenharmony_ci * transition to ON or away from ON. If current bias_level 11738c2ecf20Sopenharmony_ci * is SND_SOC_BIAS_ON, then it is preparing for a transition 11748c2ecf20Sopenharmony_ci * away from ON. Disable the clock in that case, otherwise 11758c2ecf20Sopenharmony_ci * enable it. 11768c2ecf20Sopenharmony_ci */ 11778c2ecf20Sopenharmony_ci if (IS_ERR(rt5616->mclk)) 11788c2ecf20Sopenharmony_ci break; 11798c2ecf20Sopenharmony_ci 11808c2ecf20Sopenharmony_ci if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) { 11818c2ecf20Sopenharmony_ci clk_disable_unprepare(rt5616->mclk); 11828c2ecf20Sopenharmony_ci } else { 11838c2ecf20Sopenharmony_ci ret = clk_prepare_enable(rt5616->mclk); 11848c2ecf20Sopenharmony_ci if (ret) 11858c2ecf20Sopenharmony_ci return ret; 11868c2ecf20Sopenharmony_ci } 11878c2ecf20Sopenharmony_ci break; 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_ci case SND_SOC_BIAS_STANDBY: 11908c2ecf20Sopenharmony_ci if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { 11918c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, 11928c2ecf20Sopenharmony_ci RT5616_PWR_VREF1 | RT5616_PWR_MB | 11938c2ecf20Sopenharmony_ci RT5616_PWR_BG | RT5616_PWR_VREF2, 11948c2ecf20Sopenharmony_ci RT5616_PWR_VREF1 | RT5616_PWR_MB | 11958c2ecf20Sopenharmony_ci RT5616_PWR_BG | RT5616_PWR_VREF2); 11968c2ecf20Sopenharmony_ci mdelay(10); 11978c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_PWR_ANLG1, 11988c2ecf20Sopenharmony_ci RT5616_PWR_FV1 | RT5616_PWR_FV2, 11998c2ecf20Sopenharmony_ci RT5616_PWR_FV1 | RT5616_PWR_FV2); 12008c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_D_MISC, 12018c2ecf20Sopenharmony_ci RT5616_D_GATE_EN, 12028c2ecf20Sopenharmony_ci RT5616_D_GATE_EN); 12038c2ecf20Sopenharmony_ci } 12048c2ecf20Sopenharmony_ci break; 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_ci case SND_SOC_BIAS_OFF: 12078c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT5616_D_MISC, RT5616_D_GATE_EN, 0); 12088c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PWR_DIG1, 0x0000); 12098c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PWR_DIG2, 0x0000); 12108c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PWR_VOL, 0x0000); 12118c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PWR_MIXER, 0x0000); 12128c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PWR_ANLG1, 0x0000); 12138c2ecf20Sopenharmony_ci snd_soc_component_write(component, RT5616_PWR_ANLG2, 0x0000); 12148c2ecf20Sopenharmony_ci break; 12158c2ecf20Sopenharmony_ci 12168c2ecf20Sopenharmony_ci default: 12178c2ecf20Sopenharmony_ci break; 12188c2ecf20Sopenharmony_ci } 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ci return 0; 12218c2ecf20Sopenharmony_ci} 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_cistatic int rt5616_probe(struct snd_soc_component *component) 12248c2ecf20Sopenharmony_ci{ 12258c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); 12268c2ecf20Sopenharmony_ci 12278c2ecf20Sopenharmony_ci /* Check if MCLK provided */ 12288c2ecf20Sopenharmony_ci rt5616->mclk = devm_clk_get(component->dev, "mclk"); 12298c2ecf20Sopenharmony_ci if (PTR_ERR(rt5616->mclk) == -EPROBE_DEFER) 12308c2ecf20Sopenharmony_ci return -EPROBE_DEFER; 12318c2ecf20Sopenharmony_ci 12328c2ecf20Sopenharmony_ci rt5616->component = component; 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci return 0; 12358c2ecf20Sopenharmony_ci} 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 12388c2ecf20Sopenharmony_cistatic int rt5616_suspend(struct snd_soc_component *component) 12398c2ecf20Sopenharmony_ci{ 12408c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); 12418c2ecf20Sopenharmony_ci 12428c2ecf20Sopenharmony_ci regcache_cache_only(rt5616->regmap, true); 12438c2ecf20Sopenharmony_ci regcache_mark_dirty(rt5616->regmap); 12448c2ecf20Sopenharmony_ci 12458c2ecf20Sopenharmony_ci return 0; 12468c2ecf20Sopenharmony_ci} 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_cistatic int rt5616_resume(struct snd_soc_component *component) 12498c2ecf20Sopenharmony_ci{ 12508c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component); 12518c2ecf20Sopenharmony_ci 12528c2ecf20Sopenharmony_ci regcache_cache_only(rt5616->regmap, false); 12538c2ecf20Sopenharmony_ci regcache_sync(rt5616->regmap); 12548c2ecf20Sopenharmony_ci return 0; 12558c2ecf20Sopenharmony_ci} 12568c2ecf20Sopenharmony_ci#else 12578c2ecf20Sopenharmony_ci#define rt5616_suspend NULL 12588c2ecf20Sopenharmony_ci#define rt5616_resume NULL 12598c2ecf20Sopenharmony_ci#endif 12608c2ecf20Sopenharmony_ci 12618c2ecf20Sopenharmony_ci#define RT5616_STEREO_RATES SNDRV_PCM_RATE_8000_192000 12628c2ecf20Sopenharmony_ci#define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 12638c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_cistatic const struct snd_soc_dai_ops rt5616_aif_dai_ops = { 12668c2ecf20Sopenharmony_ci .hw_params = rt5616_hw_params, 12678c2ecf20Sopenharmony_ci .set_fmt = rt5616_set_dai_fmt, 12688c2ecf20Sopenharmony_ci .set_sysclk = rt5616_set_dai_sysclk, 12698c2ecf20Sopenharmony_ci .set_pll = rt5616_set_dai_pll, 12708c2ecf20Sopenharmony_ci}; 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver rt5616_dai[] = { 12738c2ecf20Sopenharmony_ci { 12748c2ecf20Sopenharmony_ci .name = "rt5616-aif1", 12758c2ecf20Sopenharmony_ci .id = RT5616_AIF1, 12768c2ecf20Sopenharmony_ci .playback = { 12778c2ecf20Sopenharmony_ci .stream_name = "AIF1 Playback", 12788c2ecf20Sopenharmony_ci .channels_min = 1, 12798c2ecf20Sopenharmony_ci .channels_max = 2, 12808c2ecf20Sopenharmony_ci .rates = RT5616_STEREO_RATES, 12818c2ecf20Sopenharmony_ci .formats = RT5616_FORMATS, 12828c2ecf20Sopenharmony_ci }, 12838c2ecf20Sopenharmony_ci .capture = { 12848c2ecf20Sopenharmony_ci .stream_name = "AIF1 Capture", 12858c2ecf20Sopenharmony_ci .channels_min = 1, 12868c2ecf20Sopenharmony_ci .channels_max = 2, 12878c2ecf20Sopenharmony_ci .rates = RT5616_STEREO_RATES, 12888c2ecf20Sopenharmony_ci .formats = RT5616_FORMATS, 12898c2ecf20Sopenharmony_ci }, 12908c2ecf20Sopenharmony_ci .ops = &rt5616_aif_dai_ops, 12918c2ecf20Sopenharmony_ci }, 12928c2ecf20Sopenharmony_ci}; 12938c2ecf20Sopenharmony_ci 12948c2ecf20Sopenharmony_cistatic const struct snd_soc_component_driver soc_component_dev_rt5616 = { 12958c2ecf20Sopenharmony_ci .probe = rt5616_probe, 12968c2ecf20Sopenharmony_ci .suspend = rt5616_suspend, 12978c2ecf20Sopenharmony_ci .resume = rt5616_resume, 12988c2ecf20Sopenharmony_ci .set_bias_level = rt5616_set_bias_level, 12998c2ecf20Sopenharmony_ci .controls = rt5616_snd_controls, 13008c2ecf20Sopenharmony_ci .num_controls = ARRAY_SIZE(rt5616_snd_controls), 13018c2ecf20Sopenharmony_ci .dapm_widgets = rt5616_dapm_widgets, 13028c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets), 13038c2ecf20Sopenharmony_ci .dapm_routes = rt5616_dapm_routes, 13048c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes), 13058c2ecf20Sopenharmony_ci .use_pmdown_time = 1, 13068c2ecf20Sopenharmony_ci .endianness = 1, 13078c2ecf20Sopenharmony_ci .non_legacy_dai_naming = 1, 13088c2ecf20Sopenharmony_ci}; 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_cistatic const struct regmap_config rt5616_regmap = { 13118c2ecf20Sopenharmony_ci .reg_bits = 8, 13128c2ecf20Sopenharmony_ci .val_bits = 16, 13138c2ecf20Sopenharmony_ci .use_single_read = true, 13148c2ecf20Sopenharmony_ci .use_single_write = true, 13158c2ecf20Sopenharmony_ci .max_register = RT5616_DEVICE_ID + 1 + (ARRAY_SIZE(rt5616_ranges) * 13168c2ecf20Sopenharmony_ci RT5616_PR_SPACING), 13178c2ecf20Sopenharmony_ci .volatile_reg = rt5616_volatile_register, 13188c2ecf20Sopenharmony_ci .readable_reg = rt5616_readable_register, 13198c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 13208c2ecf20Sopenharmony_ci .reg_defaults = rt5616_reg, 13218c2ecf20Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(rt5616_reg), 13228c2ecf20Sopenharmony_ci .ranges = rt5616_ranges, 13238c2ecf20Sopenharmony_ci .num_ranges = ARRAY_SIZE(rt5616_ranges), 13248c2ecf20Sopenharmony_ci}; 13258c2ecf20Sopenharmony_ci 13268c2ecf20Sopenharmony_cistatic const struct i2c_device_id rt5616_i2c_id[] = { 13278c2ecf20Sopenharmony_ci { "rt5616", 0 }, 13288c2ecf20Sopenharmony_ci { } 13298c2ecf20Sopenharmony_ci}; 13308c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, rt5616_i2c_id); 13318c2ecf20Sopenharmony_ci 13328c2ecf20Sopenharmony_ci#if defined(CONFIG_OF) 13338c2ecf20Sopenharmony_cistatic const struct of_device_id rt5616_of_match[] = { 13348c2ecf20Sopenharmony_ci { .compatible = "realtek,rt5616", }, 13358c2ecf20Sopenharmony_ci {}, 13368c2ecf20Sopenharmony_ci}; 13378c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, rt5616_of_match); 13388c2ecf20Sopenharmony_ci#endif 13398c2ecf20Sopenharmony_ci 13408c2ecf20Sopenharmony_cistatic int rt5616_i2c_probe(struct i2c_client *i2c, 13418c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 13428c2ecf20Sopenharmony_ci{ 13438c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616; 13448c2ecf20Sopenharmony_ci unsigned int val; 13458c2ecf20Sopenharmony_ci int ret; 13468c2ecf20Sopenharmony_ci 13478c2ecf20Sopenharmony_ci rt5616 = devm_kzalloc(&i2c->dev, sizeof(struct rt5616_priv), 13488c2ecf20Sopenharmony_ci GFP_KERNEL); 13498c2ecf20Sopenharmony_ci if (!rt5616) 13508c2ecf20Sopenharmony_ci return -ENOMEM; 13518c2ecf20Sopenharmony_ci 13528c2ecf20Sopenharmony_ci i2c_set_clientdata(i2c, rt5616); 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci rt5616->regmap = devm_regmap_init_i2c(i2c, &rt5616_regmap); 13558c2ecf20Sopenharmony_ci if (IS_ERR(rt5616->regmap)) { 13568c2ecf20Sopenharmony_ci ret = PTR_ERR(rt5616->regmap); 13578c2ecf20Sopenharmony_ci dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 13588c2ecf20Sopenharmony_ci ret); 13598c2ecf20Sopenharmony_ci return ret; 13608c2ecf20Sopenharmony_ci } 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_ci regmap_read(rt5616->regmap, RT5616_DEVICE_ID, &val); 13638c2ecf20Sopenharmony_ci if (val != 0x6281) { 13648c2ecf20Sopenharmony_ci dev_err(&i2c->dev, 13658c2ecf20Sopenharmony_ci "Device with ID register %#x is not rt5616\n", 13668c2ecf20Sopenharmony_ci val); 13678c2ecf20Sopenharmony_ci return -ENODEV; 13688c2ecf20Sopenharmony_ci } 13698c2ecf20Sopenharmony_ci regmap_write(rt5616->regmap, RT5616_RESET, 0); 13708c2ecf20Sopenharmony_ci regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1, 13718c2ecf20Sopenharmony_ci RT5616_PWR_VREF1 | RT5616_PWR_MB | 13728c2ecf20Sopenharmony_ci RT5616_PWR_BG | RT5616_PWR_VREF2, 13738c2ecf20Sopenharmony_ci RT5616_PWR_VREF1 | RT5616_PWR_MB | 13748c2ecf20Sopenharmony_ci RT5616_PWR_BG | RT5616_PWR_VREF2); 13758c2ecf20Sopenharmony_ci mdelay(10); 13768c2ecf20Sopenharmony_ci regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1, 13778c2ecf20Sopenharmony_ci RT5616_PWR_FV1 | RT5616_PWR_FV2, 13788c2ecf20Sopenharmony_ci RT5616_PWR_FV1 | RT5616_PWR_FV2); 13798c2ecf20Sopenharmony_ci 13808c2ecf20Sopenharmony_ci ret = regmap_register_patch(rt5616->regmap, init_list, 13818c2ecf20Sopenharmony_ci ARRAY_SIZE(init_list)); 13828c2ecf20Sopenharmony_ci if (ret != 0) 13838c2ecf20Sopenharmony_ci dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); 13848c2ecf20Sopenharmony_ci 13858c2ecf20Sopenharmony_ci regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1, 13868c2ecf20Sopenharmony_ci RT5616_PWR_LDO_DVO_MASK, RT5616_PWR_LDO_DVO_1_2V); 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci return devm_snd_soc_register_component(&i2c->dev, 13898c2ecf20Sopenharmony_ci &soc_component_dev_rt5616, 13908c2ecf20Sopenharmony_ci rt5616_dai, ARRAY_SIZE(rt5616_dai)); 13918c2ecf20Sopenharmony_ci} 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_cistatic int rt5616_i2c_remove(struct i2c_client *i2c) 13948c2ecf20Sopenharmony_ci{ 13958c2ecf20Sopenharmony_ci return 0; 13968c2ecf20Sopenharmony_ci} 13978c2ecf20Sopenharmony_ci 13988c2ecf20Sopenharmony_cistatic void rt5616_i2c_shutdown(struct i2c_client *client) 13998c2ecf20Sopenharmony_ci{ 14008c2ecf20Sopenharmony_ci struct rt5616_priv *rt5616 = i2c_get_clientdata(client); 14018c2ecf20Sopenharmony_ci 14028c2ecf20Sopenharmony_ci regmap_write(rt5616->regmap, RT5616_HP_VOL, 0xc8c8); 14038c2ecf20Sopenharmony_ci regmap_write(rt5616->regmap, RT5616_LOUT_CTRL1, 0xc8c8); 14048c2ecf20Sopenharmony_ci} 14058c2ecf20Sopenharmony_ci 14068c2ecf20Sopenharmony_cistatic struct i2c_driver rt5616_i2c_driver = { 14078c2ecf20Sopenharmony_ci .driver = { 14088c2ecf20Sopenharmony_ci .name = "rt5616", 14098c2ecf20Sopenharmony_ci .of_match_table = of_match_ptr(rt5616_of_match), 14108c2ecf20Sopenharmony_ci }, 14118c2ecf20Sopenharmony_ci .probe = rt5616_i2c_probe, 14128c2ecf20Sopenharmony_ci .remove = rt5616_i2c_remove, 14138c2ecf20Sopenharmony_ci .shutdown = rt5616_i2c_shutdown, 14148c2ecf20Sopenharmony_ci .id_table = rt5616_i2c_id, 14158c2ecf20Sopenharmony_ci}; 14168c2ecf20Sopenharmony_cimodule_i2c_driver(rt5616_i2c_driver); 14178c2ecf20Sopenharmony_ci 14188c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("ASoC RT5616 driver"); 14198c2ecf20Sopenharmony_ciMODULE_AUTHOR("Bard Liao <bardliao@realtek.com>"); 14208c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 1421