18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * rt274.c -- RT274 ALSA SoC audio codec driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2017 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/delay.h> 138c2ecf20Sopenharmony_ci#include <linux/pm.h> 148c2ecf20Sopenharmony_ci#include <linux/i2c.h> 158c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 168c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 178c2ecf20Sopenharmony_ci#include <linux/dmi.h> 188c2ecf20Sopenharmony_ci#include <linux/acpi.h> 198c2ecf20Sopenharmony_ci#include <sound/core.h> 208c2ecf20Sopenharmony_ci#include <sound/pcm.h> 218c2ecf20Sopenharmony_ci#include <sound/pcm_params.h> 228c2ecf20Sopenharmony_ci#include <sound/soc.h> 238c2ecf20Sopenharmony_ci#include <sound/soc-dapm.h> 248c2ecf20Sopenharmony_ci#include <sound/initval.h> 258c2ecf20Sopenharmony_ci#include <sound/tlv.h> 268c2ecf20Sopenharmony_ci#include <sound/jack.h> 278c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include "rl6347a.h" 308c2ecf20Sopenharmony_ci#include "rt274.h" 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define RT274_VENDOR_ID 0x10ec0274 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistruct rt274_priv { 358c2ecf20Sopenharmony_ci struct reg_default *index_cache; 368c2ecf20Sopenharmony_ci int index_cache_size; 378c2ecf20Sopenharmony_ci struct regmap *regmap; 388c2ecf20Sopenharmony_ci struct snd_soc_component *component; 398c2ecf20Sopenharmony_ci struct i2c_client *i2c; 408c2ecf20Sopenharmony_ci struct snd_soc_jack *jack; 418c2ecf20Sopenharmony_ci struct delayed_work jack_detect_work; 428c2ecf20Sopenharmony_ci int sys_clk; 438c2ecf20Sopenharmony_ci int clk_id; 448c2ecf20Sopenharmony_ci int fs; 458c2ecf20Sopenharmony_ci bool master; 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic const struct reg_default rt274_index_def[] = { 498c2ecf20Sopenharmony_ci { 0x00, 0x1004 }, 508c2ecf20Sopenharmony_ci { 0x01, 0xaaaa }, 518c2ecf20Sopenharmony_ci { 0x02, 0x88aa }, 528c2ecf20Sopenharmony_ci { 0x03, 0x0002 }, 538c2ecf20Sopenharmony_ci { 0x04, 0xaa09 }, 548c2ecf20Sopenharmony_ci { 0x05, 0x0700 }, 558c2ecf20Sopenharmony_ci { 0x06, 0x6110 }, 568c2ecf20Sopenharmony_ci { 0x07, 0x0200 }, 578c2ecf20Sopenharmony_ci { 0x08, 0xa807 }, 588c2ecf20Sopenharmony_ci { 0x09, 0x0021 }, 598c2ecf20Sopenharmony_ci { 0x0a, 0x7770 }, 608c2ecf20Sopenharmony_ci { 0x0b, 0x7770 }, 618c2ecf20Sopenharmony_ci { 0x0c, 0x002b }, 628c2ecf20Sopenharmony_ci { 0x0d, 0x2420 }, 638c2ecf20Sopenharmony_ci { 0x0e, 0x65c0 }, 648c2ecf20Sopenharmony_ci { 0x0f, 0x7770 }, 658c2ecf20Sopenharmony_ci { 0x10, 0x0420 }, 668c2ecf20Sopenharmony_ci { 0x11, 0x7418 }, 678c2ecf20Sopenharmony_ci { 0x12, 0x6bd0 }, 688c2ecf20Sopenharmony_ci { 0x13, 0x645f }, 698c2ecf20Sopenharmony_ci { 0x14, 0x0400 }, 708c2ecf20Sopenharmony_ci { 0x15, 0x8ccc }, 718c2ecf20Sopenharmony_ci { 0x16, 0x4c50 }, 728c2ecf20Sopenharmony_ci { 0x17, 0xff00 }, 738c2ecf20Sopenharmony_ci { 0x18, 0x0003 }, 748c2ecf20Sopenharmony_ci { 0x19, 0x2c11 }, 758c2ecf20Sopenharmony_ci { 0x1a, 0x830b }, 768c2ecf20Sopenharmony_ci { 0x1b, 0x4e4b }, 778c2ecf20Sopenharmony_ci { 0x1c, 0x0000 }, 788c2ecf20Sopenharmony_ci { 0x1d, 0x0000 }, 798c2ecf20Sopenharmony_ci { 0x1e, 0x0000 }, 808c2ecf20Sopenharmony_ci { 0x1f, 0x0000 }, 818c2ecf20Sopenharmony_ci { 0x20, 0x51ff }, 828c2ecf20Sopenharmony_ci { 0x21, 0x8000 }, 838c2ecf20Sopenharmony_ci { 0x22, 0x8f00 }, 848c2ecf20Sopenharmony_ci { 0x23, 0x88f4 }, 858c2ecf20Sopenharmony_ci { 0x24, 0x0000 }, 868c2ecf20Sopenharmony_ci { 0x25, 0x0000 }, 878c2ecf20Sopenharmony_ci { 0x26, 0x0000 }, 888c2ecf20Sopenharmony_ci { 0x27, 0x0000 }, 898c2ecf20Sopenharmony_ci { 0x28, 0x0000 }, 908c2ecf20Sopenharmony_ci { 0x29, 0x3000 }, 918c2ecf20Sopenharmony_ci { 0x2a, 0x0000 }, 928c2ecf20Sopenharmony_ci { 0x2b, 0x0000 }, 938c2ecf20Sopenharmony_ci { 0x2c, 0x0f00 }, 948c2ecf20Sopenharmony_ci { 0x2d, 0x100f }, 958c2ecf20Sopenharmony_ci { 0x2e, 0x2902 }, 968c2ecf20Sopenharmony_ci { 0x2f, 0xe280 }, 978c2ecf20Sopenharmony_ci { 0x30, 0x1000 }, 988c2ecf20Sopenharmony_ci { 0x31, 0x8400 }, 998c2ecf20Sopenharmony_ci { 0x32, 0x5aaa }, 1008c2ecf20Sopenharmony_ci { 0x33, 0x8420 }, 1018c2ecf20Sopenharmony_ci { 0x34, 0xa20c }, 1028c2ecf20Sopenharmony_ci { 0x35, 0x096a }, 1038c2ecf20Sopenharmony_ci { 0x36, 0x5757 }, 1048c2ecf20Sopenharmony_ci { 0x37, 0xfe05 }, 1058c2ecf20Sopenharmony_ci { 0x38, 0x4901 }, 1068c2ecf20Sopenharmony_ci { 0x39, 0x110a }, 1078c2ecf20Sopenharmony_ci { 0x3a, 0x0010 }, 1088c2ecf20Sopenharmony_ci { 0x3b, 0x60d9 }, 1098c2ecf20Sopenharmony_ci { 0x3c, 0xf214 }, 1108c2ecf20Sopenharmony_ci { 0x3d, 0xc2ba }, 1118c2ecf20Sopenharmony_ci { 0x3e, 0xa928 }, 1128c2ecf20Sopenharmony_ci { 0x3f, 0x0000 }, 1138c2ecf20Sopenharmony_ci { 0x40, 0x9800 }, 1148c2ecf20Sopenharmony_ci { 0x41, 0x0000 }, 1158c2ecf20Sopenharmony_ci { 0x42, 0x2000 }, 1168c2ecf20Sopenharmony_ci { 0x43, 0x3d90 }, 1178c2ecf20Sopenharmony_ci { 0x44, 0x4900 }, 1188c2ecf20Sopenharmony_ci { 0x45, 0x5289 }, 1198c2ecf20Sopenharmony_ci { 0x46, 0x0004 }, 1208c2ecf20Sopenharmony_ci { 0x47, 0xa47a }, 1218c2ecf20Sopenharmony_ci { 0x48, 0xd049 }, 1228c2ecf20Sopenharmony_ci { 0x49, 0x0049 }, 1238c2ecf20Sopenharmony_ci { 0x4a, 0xa83b }, 1248c2ecf20Sopenharmony_ci { 0x4b, 0x0777 }, 1258c2ecf20Sopenharmony_ci { 0x4c, 0x065c }, 1268c2ecf20Sopenharmony_ci { 0x4d, 0x7fff }, 1278c2ecf20Sopenharmony_ci { 0x4e, 0x7fff }, 1288c2ecf20Sopenharmony_ci { 0x4f, 0x0000 }, 1298c2ecf20Sopenharmony_ci { 0x50, 0x0000 }, 1308c2ecf20Sopenharmony_ci { 0x51, 0x0000 }, 1318c2ecf20Sopenharmony_ci { 0x52, 0xbf5f }, 1328c2ecf20Sopenharmony_ci { 0x53, 0x3320 }, 1338c2ecf20Sopenharmony_ci { 0x54, 0xcc00 }, 1348c2ecf20Sopenharmony_ci { 0x55, 0x0000 }, 1358c2ecf20Sopenharmony_ci { 0x56, 0x3f00 }, 1368c2ecf20Sopenharmony_ci { 0x57, 0x0000 }, 1378c2ecf20Sopenharmony_ci { 0x58, 0x0000 }, 1388c2ecf20Sopenharmony_ci { 0x59, 0x0000 }, 1398c2ecf20Sopenharmony_ci { 0x5a, 0x1300 }, 1408c2ecf20Sopenharmony_ci { 0x5b, 0x005f }, 1418c2ecf20Sopenharmony_ci { 0x5c, 0x0000 }, 1428c2ecf20Sopenharmony_ci { 0x5d, 0x1001 }, 1438c2ecf20Sopenharmony_ci { 0x5e, 0x1000 }, 1448c2ecf20Sopenharmony_ci { 0x5f, 0x0000 }, 1458c2ecf20Sopenharmony_ci { 0x60, 0x5554 }, 1468c2ecf20Sopenharmony_ci { 0x61, 0xffc0 }, 1478c2ecf20Sopenharmony_ci { 0x62, 0xa000 }, 1488c2ecf20Sopenharmony_ci { 0x63, 0xd010 }, 1498c2ecf20Sopenharmony_ci { 0x64, 0x0000 }, 1508c2ecf20Sopenharmony_ci { 0x65, 0x3fb1 }, 1518c2ecf20Sopenharmony_ci { 0x66, 0x1881 }, 1528c2ecf20Sopenharmony_ci { 0x67, 0xc810 }, 1538c2ecf20Sopenharmony_ci { 0x68, 0x2000 }, 1548c2ecf20Sopenharmony_ci { 0x69, 0xfff0 }, 1558c2ecf20Sopenharmony_ci { 0x6a, 0x0300 }, 1568c2ecf20Sopenharmony_ci { 0x6b, 0x5060 }, 1578c2ecf20Sopenharmony_ci { 0x6c, 0x0000 }, 1588c2ecf20Sopenharmony_ci { 0x6d, 0x0000 }, 1598c2ecf20Sopenharmony_ci { 0x6e, 0x0c25 }, 1608c2ecf20Sopenharmony_ci { 0x6f, 0x0c0b }, 1618c2ecf20Sopenharmony_ci { 0x70, 0x8000 }, 1628c2ecf20Sopenharmony_ci { 0x71, 0x4008 }, 1638c2ecf20Sopenharmony_ci { 0x72, 0x0000 }, 1648c2ecf20Sopenharmony_ci { 0x73, 0x0800 }, 1658c2ecf20Sopenharmony_ci { 0x74, 0xa28f }, 1668c2ecf20Sopenharmony_ci { 0x75, 0xa050 }, 1678c2ecf20Sopenharmony_ci { 0x76, 0x7fe8 }, 1688c2ecf20Sopenharmony_ci { 0x77, 0xdb8c }, 1698c2ecf20Sopenharmony_ci { 0x78, 0x0000 }, 1708c2ecf20Sopenharmony_ci { 0x79, 0x0000 }, 1718c2ecf20Sopenharmony_ci { 0x7a, 0x2a96 }, 1728c2ecf20Sopenharmony_ci { 0x7b, 0x800f }, 1738c2ecf20Sopenharmony_ci { 0x7c, 0x0200 }, 1748c2ecf20Sopenharmony_ci { 0x7d, 0x1600 }, 1758c2ecf20Sopenharmony_ci { 0x7e, 0x0000 }, 1768c2ecf20Sopenharmony_ci { 0x7f, 0x0000 }, 1778c2ecf20Sopenharmony_ci}; 1788c2ecf20Sopenharmony_ci#define INDEX_CACHE_SIZE ARRAY_SIZE(rt274_index_def) 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic const struct reg_default rt274_reg[] = { 1818c2ecf20Sopenharmony_ci { 0x00170500, 0x00000400 }, 1828c2ecf20Sopenharmony_ci { 0x00220000, 0x00000031 }, 1838c2ecf20Sopenharmony_ci { 0x00239000, 0x00000057 }, 1848c2ecf20Sopenharmony_ci { 0x0023a000, 0x00000057 }, 1858c2ecf20Sopenharmony_ci { 0x00270500, 0x00000400 }, 1868c2ecf20Sopenharmony_ci { 0x00370500, 0x00000400 }, 1878c2ecf20Sopenharmony_ci { 0x00870500, 0x00000400 }, 1888c2ecf20Sopenharmony_ci { 0x00920000, 0x00000031 }, 1898c2ecf20Sopenharmony_ci { 0x00935000, 0x00000097 }, 1908c2ecf20Sopenharmony_ci { 0x00936000, 0x00000097 }, 1918c2ecf20Sopenharmony_ci { 0x00970500, 0x00000400 }, 1928c2ecf20Sopenharmony_ci { 0x00b37000, 0x00000400 }, 1938c2ecf20Sopenharmony_ci { 0x00b37200, 0x00000400 }, 1948c2ecf20Sopenharmony_ci { 0x00b37300, 0x00000400 }, 1958c2ecf20Sopenharmony_ci { 0x00c37000, 0x00000400 }, 1968c2ecf20Sopenharmony_ci { 0x00c37100, 0x00000400 }, 1978c2ecf20Sopenharmony_ci { 0x01270500, 0x00000400 }, 1988c2ecf20Sopenharmony_ci { 0x01370500, 0x00000400 }, 1998c2ecf20Sopenharmony_ci { 0x01371f00, 0x411111f0 }, 2008c2ecf20Sopenharmony_ci { 0x01937000, 0x00000000 }, 2018c2ecf20Sopenharmony_ci { 0x01970500, 0x00000400 }, 2028c2ecf20Sopenharmony_ci { 0x02050000, 0x0000001b }, 2038c2ecf20Sopenharmony_ci { 0x02139000, 0x00000080 }, 2048c2ecf20Sopenharmony_ci { 0x0213a000, 0x00000080 }, 2058c2ecf20Sopenharmony_ci { 0x02170100, 0x00000001 }, 2068c2ecf20Sopenharmony_ci { 0x02170500, 0x00000400 }, 2078c2ecf20Sopenharmony_ci { 0x02170700, 0x00000000 }, 2088c2ecf20Sopenharmony_ci { 0x02270100, 0x00000000 }, 2098c2ecf20Sopenharmony_ci { 0x02370100, 0x00000000 }, 2108c2ecf20Sopenharmony_ci { 0x01970700, 0x00000020 }, 2118c2ecf20Sopenharmony_ci { 0x00830000, 0x00000097 }, 2128c2ecf20Sopenharmony_ci { 0x00930000, 0x00000097 }, 2138c2ecf20Sopenharmony_ci { 0x01270700, 0x00000000 }, 2148c2ecf20Sopenharmony_ci}; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic bool rt274_volatile_register(struct device *dev, unsigned int reg) 2178c2ecf20Sopenharmony_ci{ 2188c2ecf20Sopenharmony_ci switch (reg) { 2198c2ecf20Sopenharmony_ci case 0 ... 0xff: 2208c2ecf20Sopenharmony_ci case RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): 2218c2ecf20Sopenharmony_ci case RT274_GET_HP_SENSE: 2228c2ecf20Sopenharmony_ci case RT274_GET_MIC_SENSE: 2238c2ecf20Sopenharmony_ci case RT274_PROC_COEF: 2248c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_MIC, 0): 2258c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_HP_OUT, 0): 2268c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT0, 0): 2278c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT1, 0): 2288c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN1, 0): 2298c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN2, 0): 2308c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0): 2318c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0): 2328c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0): 2338c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0): 2348c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC1, 0): 2358c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC2, 0): 2368c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_MIC, 0): 2378c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE1, 0): 2388c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE2, 0): 2398c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_HP_OUT, 0): 2408c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_HP_OUT, 0): 2418c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN1, 0): 2428c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN2, 0): 2438c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0): 2448c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC2, 0): 2458c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_MIC, 0): 2468c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE1, 0): 2478c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE2, 0): 2488c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0): 2498c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_HP_OUT, 0): 2508c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_MIC, 0): 2518c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_INLINE_CMD, 0): 2528c2ecf20Sopenharmony_ci return true; 2538c2ecf20Sopenharmony_ci default: 2548c2ecf20Sopenharmony_ci return false; 2558c2ecf20Sopenharmony_ci } 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_cistatic bool rt274_readable_register(struct device *dev, unsigned int reg) 2618c2ecf20Sopenharmony_ci{ 2628c2ecf20Sopenharmony_ci switch (reg) { 2638c2ecf20Sopenharmony_ci case 0 ... 0xff: 2648c2ecf20Sopenharmony_ci case RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): 2658c2ecf20Sopenharmony_ci case RT274_GET_HP_SENSE: 2668c2ecf20Sopenharmony_ci case RT274_GET_MIC_SENSE: 2678c2ecf20Sopenharmony_ci case RT274_SET_AUDIO_POWER: 2688c2ecf20Sopenharmony_ci case RT274_SET_HPO_POWER: 2698c2ecf20Sopenharmony_ci case RT274_SET_DMIC1_POWER: 2708c2ecf20Sopenharmony_ci case RT274_LOUT_MUX: 2718c2ecf20Sopenharmony_ci case RT274_HPO_MUX: 2728c2ecf20Sopenharmony_ci case RT274_ADC0_MUX: 2738c2ecf20Sopenharmony_ci case RT274_ADC1_MUX: 2748c2ecf20Sopenharmony_ci case RT274_SET_MIC: 2758c2ecf20Sopenharmony_ci case RT274_SET_PIN_HPO: 2768c2ecf20Sopenharmony_ci case RT274_SET_PIN_LOUT3: 2778c2ecf20Sopenharmony_ci case RT274_SET_PIN_DMIC1: 2788c2ecf20Sopenharmony_ci case RT274_SET_AMP_GAIN_HPO: 2798c2ecf20Sopenharmony_ci case RT274_SET_DMIC2_DEFAULT: 2808c2ecf20Sopenharmony_ci case RT274_DAC0L_GAIN: 2818c2ecf20Sopenharmony_ci case RT274_DAC0R_GAIN: 2828c2ecf20Sopenharmony_ci case RT274_DAC1L_GAIN: 2838c2ecf20Sopenharmony_ci case RT274_DAC1R_GAIN: 2848c2ecf20Sopenharmony_ci case RT274_ADCL_GAIN: 2858c2ecf20Sopenharmony_ci case RT274_ADCR_GAIN: 2868c2ecf20Sopenharmony_ci case RT274_MIC_GAIN: 2878c2ecf20Sopenharmony_ci case RT274_HPOL_GAIN: 2888c2ecf20Sopenharmony_ci case RT274_HPOR_GAIN: 2898c2ecf20Sopenharmony_ci case RT274_LOUTL_GAIN: 2908c2ecf20Sopenharmony_ci case RT274_LOUTR_GAIN: 2918c2ecf20Sopenharmony_ci case RT274_DAC_FORMAT: 2928c2ecf20Sopenharmony_ci case RT274_ADC_FORMAT: 2938c2ecf20Sopenharmony_ci case RT274_COEF_INDEX: 2948c2ecf20Sopenharmony_ci case RT274_PROC_COEF: 2958c2ecf20Sopenharmony_ci case RT274_SET_AMP_GAIN_ADC_IN1: 2968c2ecf20Sopenharmony_ci case RT274_SET_AMP_GAIN_ADC_IN2: 2978c2ecf20Sopenharmony_ci case RT274_SET_POWER(RT274_DAC_OUT0): 2988c2ecf20Sopenharmony_ci case RT274_SET_POWER(RT274_DAC_OUT1): 2998c2ecf20Sopenharmony_ci case RT274_SET_POWER(RT274_ADC_IN1): 3008c2ecf20Sopenharmony_ci case RT274_SET_POWER(RT274_ADC_IN2): 3018c2ecf20Sopenharmony_ci case RT274_SET_POWER(RT274_DMIC2): 3028c2ecf20Sopenharmony_ci case RT274_SET_POWER(RT274_MIC): 3038c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_MIC, 0): 3048c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_HP_OUT, 0): 3058c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT0, 0): 3068c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT1, 0): 3078c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN1, 0): 3088c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN2, 0): 3098c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0): 3108c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0): 3118c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0): 3128c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0): 3138c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC1, 0): 3148c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC2, 0): 3158c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_MIC, 0): 3168c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE1, 0): 3178c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE2, 0): 3188c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_HP_OUT, 0): 3198c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_HP_OUT, 0): 3208c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN1, 0): 3218c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN2, 0): 3228c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0): 3238c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC2, 0): 3248c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_MIC, 0): 3258c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE1, 0): 3268c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE2, 0): 3278c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0): 3288c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_HP_OUT, 0): 3298c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_MIC, 0): 3308c2ecf20Sopenharmony_ci case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_INLINE_CMD, 0): 3318c2ecf20Sopenharmony_ci return true; 3328c2ecf20Sopenharmony_ci default: 3338c2ecf20Sopenharmony_ci return false; 3348c2ecf20Sopenharmony_ci } 3358c2ecf20Sopenharmony_ci} 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 3388c2ecf20Sopenharmony_cistatic void rt274_index_sync(struct snd_soc_component *component) 3398c2ecf20Sopenharmony_ci{ 3408c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 3418c2ecf20Sopenharmony_ci int i; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci for (i = 0; i < INDEX_CACHE_SIZE; i++) { 3448c2ecf20Sopenharmony_ci snd_soc_component_write(component, rt274->index_cache[i].reg, 3458c2ecf20Sopenharmony_ci rt274->index_cache[i].def); 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci} 3488c2ecf20Sopenharmony_ci#endif 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cistatic int rt274_jack_detect(struct rt274_priv *rt274, bool *hp, bool *mic) 3518c2ecf20Sopenharmony_ci{ 3528c2ecf20Sopenharmony_ci unsigned int buf; 3538c2ecf20Sopenharmony_ci int ret; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci *hp = false; 3568c2ecf20Sopenharmony_ci *mic = false; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci if (!rt274->component) 3598c2ecf20Sopenharmony_ci return -EINVAL; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci ret = regmap_read(rt274->regmap, RT274_GET_HP_SENSE, &buf); 3628c2ecf20Sopenharmony_ci if (ret) 3638c2ecf20Sopenharmony_ci return ret; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci *hp = buf & 0x80000000; 3668c2ecf20Sopenharmony_ci ret = regmap_read(rt274->regmap, RT274_GET_MIC_SENSE, &buf); 3678c2ecf20Sopenharmony_ci if (ret) 3688c2ecf20Sopenharmony_ci return ret; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci *mic = buf & 0x80000000; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci pr_debug("*hp = %d *mic = %d\n", *hp, *mic); 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci return 0; 3758c2ecf20Sopenharmony_ci} 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_cistatic void rt274_jack_detect_work(struct work_struct *work) 3788c2ecf20Sopenharmony_ci{ 3798c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = 3808c2ecf20Sopenharmony_ci container_of(work, struct rt274_priv, jack_detect_work.work); 3818c2ecf20Sopenharmony_ci int status = 0; 3828c2ecf20Sopenharmony_ci bool hp = false; 3838c2ecf20Sopenharmony_ci bool mic = false; 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci if (rt274_jack_detect(rt274, &hp, &mic) < 0) 3868c2ecf20Sopenharmony_ci return; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci if (hp) 3898c2ecf20Sopenharmony_ci status |= SND_JACK_HEADPHONE; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci if (mic) 3928c2ecf20Sopenharmony_ci status |= SND_JACK_MICROPHONE; 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci snd_soc_jack_report(rt274->jack, status, 3958c2ecf20Sopenharmony_ci SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); 3968c2ecf20Sopenharmony_ci} 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_cistatic irqreturn_t rt274_irq(int irq, void *data); 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_cistatic int rt274_mic_detect(struct snd_soc_component *component, 4018c2ecf20Sopenharmony_ci struct snd_soc_jack *jack, void *data) 4028c2ecf20Sopenharmony_ci{ 4038c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci rt274->jack = jack; 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci if (jack == NULL) { 4088c2ecf20Sopenharmony_ci /* Disable jack detection */ 4098c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, 4108c2ecf20Sopenharmony_ci RT274_IRQ_EN, RT274_IRQ_DIS); 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci return 0; 4138c2ecf20Sopenharmony_ci } 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, 4168c2ecf20Sopenharmony_ci RT274_IRQ_EN, RT274_IRQ_EN); 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci /* Send an initial report */ 4198c2ecf20Sopenharmony_ci rt274_irq(0, rt274); 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci return 0; 4228c2ecf20Sopenharmony_ci} 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); 4258c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt274_snd_controls[] = { 4288c2ecf20Sopenharmony_ci SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT274_DAC0L_GAIN, 4298c2ecf20Sopenharmony_ci RT274_DAC0R_GAIN, 0, 0x7f, 0, out_vol_tlv), 4308c2ecf20Sopenharmony_ci SOC_DOUBLE_R_TLV("DAC1 Playback Volume", RT274_DAC1L_GAIN, 4318c2ecf20Sopenharmony_ci RT274_DAC1R_GAIN, 0, 0x7f, 0, out_vol_tlv), 4328c2ecf20Sopenharmony_ci SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT274_ADCL_GAIN, 4338c2ecf20Sopenharmony_ci RT274_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv), 4348c2ecf20Sopenharmony_ci SOC_DOUBLE_R("ADC0 Capture Switch", RT274_ADCL_GAIN, 4358c2ecf20Sopenharmony_ci RT274_ADCR_GAIN, RT274_MUTE_SFT, 1, 1), 4368c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("AMIC Volume", RT274_MIC_GAIN, 4378c2ecf20Sopenharmony_ci 0, 0x3, 0, mic_vol_tlv), 4388c2ecf20Sopenharmony_ci}; 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new hpol_enable_control = 4418c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_HPOL_GAIN, 4428c2ecf20Sopenharmony_ci RT274_MUTE_SFT, 1, 1); 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new hpor_enable_control = 4458c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_HPOR_GAIN, 4468c2ecf20Sopenharmony_ci RT274_MUTE_SFT, 1, 1); 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new loutl_enable_control = 4498c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_LOUTL_GAIN, 4508c2ecf20Sopenharmony_ci RT274_MUTE_SFT, 1, 1); 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new loutr_enable_control = 4538c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_LOUTR_GAIN, 4548c2ecf20Sopenharmony_ci RT274_MUTE_SFT, 1, 1); 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci/* ADC0 source */ 4578c2ecf20Sopenharmony_cistatic const char * const rt274_adc_src[] = { 4588c2ecf20Sopenharmony_ci "Mic", "Line1", "Line2", "Dmic" 4598c2ecf20Sopenharmony_ci}; 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 4628c2ecf20Sopenharmony_ci rt274_adc0_enum, RT274_ADC0_MUX, RT274_ADC_SEL_SFT, 4638c2ecf20Sopenharmony_ci rt274_adc_src); 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt274_adc0_mux = 4668c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("ADC 0 source", rt274_adc0_enum); 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL( 4698c2ecf20Sopenharmony_ci rt274_adc1_enum, RT274_ADC1_MUX, RT274_ADC_SEL_SFT, 4708c2ecf20Sopenharmony_ci rt274_adc_src); 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt274_adc1_mux = 4738c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("ADC 1 source", rt274_adc1_enum); 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_cistatic const char * const rt274_dac_src[] = { 4768c2ecf20Sopenharmony_ci "DAC OUT0", "DAC OUT1" 4778c2ecf20Sopenharmony_ci}; 4788c2ecf20Sopenharmony_ci/* HP-OUT source */ 4798c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(rt274_hpo_enum, RT274_HPO_MUX, 4808c2ecf20Sopenharmony_ci 0, rt274_dac_src); 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt274_hpo_mux = 4838c2ecf20Sopenharmony_ciSOC_DAPM_ENUM("HPO source", rt274_hpo_enum); 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci/* Line out source */ 4868c2ecf20Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(rt274_lout_enum, RT274_LOUT_MUX, 4878c2ecf20Sopenharmony_ci 0, rt274_dac_src); 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new rt274_lout_mux = 4908c2ecf20Sopenharmony_ciSOC_DAPM_ENUM("LOUT source", rt274_lout_enum); 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget rt274_dapm_widgets[] = { 4938c2ecf20Sopenharmony_ci /* Input Lines */ 4948c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("DMIC1 Pin"), 4958c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("DMIC2 Pin"), 4968c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC"), 4978c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("LINE1"), 4988c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("LINE2"), 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci /* DMIC */ 5018c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0), 5028c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0), 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci /* ADCs */ 5058c2ecf20Sopenharmony_ci SND_SOC_DAPM_ADC("ADC 0", NULL, RT274_SET_STREAMID_ADC1, 4, 0), 5068c2ecf20Sopenharmony_ci SND_SOC_DAPM_ADC("ADC 1", NULL, RT274_SET_STREAMID_ADC2, 4, 0), 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci /* ADC Mux */ 5098c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("ADC 0 Mux", SND_SOC_NOPM, 0, 0, 5108c2ecf20Sopenharmony_ci &rt274_adc0_mux), 5118c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("ADC 1 Mux", SND_SOC_NOPM, 0, 0, 5128c2ecf20Sopenharmony_ci &rt274_adc1_mux), 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci /* Audio Interface */ 5158c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("AIF1RXL", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 5168c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("AIF1RXR", "AIF1 Playback", 1, SND_SOC_NOPM, 0, 0), 5178c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("AIF1TXL", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), 5188c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("AIF1TXR", "AIF1 Capture", 1, SND_SOC_NOPM, 0, 0), 5198c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("AIF2RXL", "AIF1 Playback", 2, SND_SOC_NOPM, 0, 0), 5208c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("AIF2RXR", "AIF1 Playback", 3, SND_SOC_NOPM, 0, 0), 5218c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("AIF2TXL", "AIF1 Capture", 2, SND_SOC_NOPM, 0, 0), 5228c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("AIF2TXR", "AIF1 Capture", 3, SND_SOC_NOPM, 0, 0), 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci /* Output Side */ 5258c2ecf20Sopenharmony_ci /* DACs */ 5268c2ecf20Sopenharmony_ci SND_SOC_DAPM_DAC("DAC 0", NULL, RT274_SET_STREAMID_DAC0, 4, 0), 5278c2ecf20Sopenharmony_ci SND_SOC_DAPM_DAC("DAC 1", NULL, RT274_SET_STREAMID_DAC1, 4, 0), 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci /* Output Mux */ 5308c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("HPO Mux", SND_SOC_NOPM, 0, 0, &rt274_hpo_mux), 5318c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("LOUT Mux", SND_SOC_NOPM, 0, 0, &rt274_lout_mux), 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("HP Power", RT274_SET_PIN_HPO, 5348c2ecf20Sopenharmony_ci RT274_SET_PIN_SFT, 0, NULL, 0), 5358c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("LOUT Power", RT274_SET_PIN_LOUT3, 5368c2ecf20Sopenharmony_ci RT274_SET_PIN_SFT, 0, NULL, 0), 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci /* Output Mixer */ 5398c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("DAC OUT0", SND_SOC_NOPM, 0, 0, 5408c2ecf20Sopenharmony_ci NULL, 0), 5418c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("DAC OUT1", SND_SOC_NOPM, 0, 0, 5428c2ecf20Sopenharmony_ci NULL, 0), 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci /* Output Pga */ 5458c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("LOUT L", SND_SOC_NOPM, 0, 0, 5468c2ecf20Sopenharmony_ci &loutl_enable_control), 5478c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("LOUT R", SND_SOC_NOPM, 0, 0, 5488c2ecf20Sopenharmony_ci &loutr_enable_control), 5498c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("HPO L", SND_SOC_NOPM, 0, 0, 5508c2ecf20Sopenharmony_ci &hpol_enable_control), 5518c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("HPO R", SND_SOC_NOPM, 0, 0, 5528c2ecf20Sopenharmony_ci &hpor_enable_control), 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci /* Output Lines */ 5558c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPO Pin"), 5568c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("SPDIF"), 5578c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("LINE3"), 5588c2ecf20Sopenharmony_ci}; 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route rt274_dapm_routes[] = { 5618c2ecf20Sopenharmony_ci {"DMIC1", NULL, "DMIC1 Pin"}, 5628c2ecf20Sopenharmony_ci {"DMIC2", NULL, "DMIC2 Pin"}, 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci {"ADC 0 Mux", "Mic", "MIC"}, 5658c2ecf20Sopenharmony_ci {"ADC 0 Mux", "Dmic", "DMIC1"}, 5668c2ecf20Sopenharmony_ci {"ADC 0 Mux", "Line1", "LINE1"}, 5678c2ecf20Sopenharmony_ci {"ADC 0 Mux", "Line2", "LINE2"}, 5688c2ecf20Sopenharmony_ci {"ADC 1 Mux", "Mic", "MIC"}, 5698c2ecf20Sopenharmony_ci {"ADC 1 Mux", "Dmic", "DMIC2"}, 5708c2ecf20Sopenharmony_ci {"ADC 1 Mux", "Line1", "LINE1"}, 5718c2ecf20Sopenharmony_ci {"ADC 1 Mux", "Line2", "LINE2"}, 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci {"ADC 0", NULL, "ADC 0 Mux"}, 5748c2ecf20Sopenharmony_ci {"ADC 1", NULL, "ADC 1 Mux"}, 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci {"AIF1TXL", NULL, "ADC 0"}, 5778c2ecf20Sopenharmony_ci {"AIF1TXR", NULL, "ADC 0"}, 5788c2ecf20Sopenharmony_ci {"AIF2TXL", NULL, "ADC 1"}, 5798c2ecf20Sopenharmony_ci {"AIF2TXR", NULL, "ADC 1"}, 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci {"DAC 0", NULL, "AIF1RXL"}, 5828c2ecf20Sopenharmony_ci {"DAC 0", NULL, "AIF1RXR"}, 5838c2ecf20Sopenharmony_ci {"DAC 1", NULL, "AIF2RXL"}, 5848c2ecf20Sopenharmony_ci {"DAC 1", NULL, "AIF2RXR"}, 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci {"DAC OUT0", NULL, "DAC 0"}, 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci {"DAC OUT1", NULL, "DAC 1"}, 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci {"LOUT Mux", "DAC OUT0", "DAC OUT0"}, 5918c2ecf20Sopenharmony_ci {"LOUT Mux", "DAC OUT1", "DAC OUT1"}, 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci {"LOUT L", "Switch", "LOUT Mux"}, 5948c2ecf20Sopenharmony_ci {"LOUT R", "Switch", "LOUT Mux"}, 5958c2ecf20Sopenharmony_ci {"LOUT L", NULL, "LOUT Power"}, 5968c2ecf20Sopenharmony_ci {"LOUT R", NULL, "LOUT Power"}, 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci {"LINE3", NULL, "LOUT L"}, 5998c2ecf20Sopenharmony_ci {"LINE3", NULL, "LOUT R"}, 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci {"HPO Mux", "DAC OUT0", "DAC OUT0"}, 6028c2ecf20Sopenharmony_ci {"HPO Mux", "DAC OUT1", "DAC OUT1"}, 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci {"HPO L", "Switch", "HPO Mux"}, 6058c2ecf20Sopenharmony_ci {"HPO R", "Switch", "HPO Mux"}, 6068c2ecf20Sopenharmony_ci {"HPO L", NULL, "HP Power"}, 6078c2ecf20Sopenharmony_ci {"HPO R", NULL, "HP Power"}, 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci {"HPO Pin", NULL, "HPO L"}, 6108c2ecf20Sopenharmony_ci {"HPO Pin", NULL, "HPO R"}, 6118c2ecf20Sopenharmony_ci}; 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_cistatic int rt274_hw_params(struct snd_pcm_substream *substream, 6148c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params, 6158c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 6168c2ecf20Sopenharmony_ci{ 6178c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 6188c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 6198c2ecf20Sopenharmony_ci unsigned int val = 0; 6208c2ecf20Sopenharmony_ci int d_len_code = 0, c_len_code = 0; 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci switch (params_rate(params)) { 6238c2ecf20Sopenharmony_ci /* bit 14 0:48K 1:44.1K */ 6248c2ecf20Sopenharmony_ci case 44100: 6258c2ecf20Sopenharmony_ci case 48000: 6268c2ecf20Sopenharmony_ci break; 6278c2ecf20Sopenharmony_ci default: 6288c2ecf20Sopenharmony_ci dev_err(component->dev, "Unsupported sample rate %d\n", 6298c2ecf20Sopenharmony_ci params_rate(params)); 6308c2ecf20Sopenharmony_ci return -EINVAL; 6318c2ecf20Sopenharmony_ci } 6328c2ecf20Sopenharmony_ci switch (rt274->sys_clk) { 6338c2ecf20Sopenharmony_ci case 12288000: 6348c2ecf20Sopenharmony_ci case 24576000: 6358c2ecf20Sopenharmony_ci if (params_rate(params) != 48000) { 6368c2ecf20Sopenharmony_ci dev_err(component->dev, "Sys_clk is not matched (%d %d)\n", 6378c2ecf20Sopenharmony_ci params_rate(params), rt274->sys_clk); 6388c2ecf20Sopenharmony_ci return -EINVAL; 6398c2ecf20Sopenharmony_ci } 6408c2ecf20Sopenharmony_ci break; 6418c2ecf20Sopenharmony_ci case 11289600: 6428c2ecf20Sopenharmony_ci case 22579200: 6438c2ecf20Sopenharmony_ci if (params_rate(params) != 44100) { 6448c2ecf20Sopenharmony_ci dev_err(component->dev, "Sys_clk is not matched (%d %d)\n", 6458c2ecf20Sopenharmony_ci params_rate(params), rt274->sys_clk); 6468c2ecf20Sopenharmony_ci return -EINVAL; 6478c2ecf20Sopenharmony_ci } 6488c2ecf20Sopenharmony_ci break; 6498c2ecf20Sopenharmony_ci } 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci if (params_channels(params) <= 16) { 6528c2ecf20Sopenharmony_ci /* bit 3:0 Number of Channel */ 6538c2ecf20Sopenharmony_ci val |= (params_channels(params) - 1); 6548c2ecf20Sopenharmony_ci } else { 6558c2ecf20Sopenharmony_ci dev_err(component->dev, "Unsupported channels %d\n", 6568c2ecf20Sopenharmony_ci params_channels(params)); 6578c2ecf20Sopenharmony_ci return -EINVAL; 6588c2ecf20Sopenharmony_ci } 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci switch (params_width(params)) { 6618c2ecf20Sopenharmony_ci /* bit 6:4 Bits per Sample */ 6628c2ecf20Sopenharmony_ci case 16: 6638c2ecf20Sopenharmony_ci d_len_code = 0; 6648c2ecf20Sopenharmony_ci c_len_code = 0; 6658c2ecf20Sopenharmony_ci val |= (0x1 << 4); 6668c2ecf20Sopenharmony_ci break; 6678c2ecf20Sopenharmony_ci case 32: 6688c2ecf20Sopenharmony_ci d_len_code = 2; 6698c2ecf20Sopenharmony_ci c_len_code = 3; 6708c2ecf20Sopenharmony_ci val |= (0x4 << 4); 6718c2ecf20Sopenharmony_ci break; 6728c2ecf20Sopenharmony_ci case 20: 6738c2ecf20Sopenharmony_ci d_len_code = 1; 6748c2ecf20Sopenharmony_ci c_len_code = 1; 6758c2ecf20Sopenharmony_ci val |= (0x2 << 4); 6768c2ecf20Sopenharmony_ci break; 6778c2ecf20Sopenharmony_ci case 24: 6788c2ecf20Sopenharmony_ci d_len_code = 2; 6798c2ecf20Sopenharmony_ci c_len_code = 2; 6808c2ecf20Sopenharmony_ci val |= (0x3 << 4); 6818c2ecf20Sopenharmony_ci break; 6828c2ecf20Sopenharmony_ci case 8: 6838c2ecf20Sopenharmony_ci d_len_code = 3; 6848c2ecf20Sopenharmony_ci c_len_code = 0; 6858c2ecf20Sopenharmony_ci break; 6868c2ecf20Sopenharmony_ci default: 6878c2ecf20Sopenharmony_ci return -EINVAL; 6888c2ecf20Sopenharmony_ci } 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci if (rt274->master) 6918c2ecf20Sopenharmony_ci c_len_code = 0x3; 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 6948c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, 0xc018, d_len_code << 3 | c_len_code << 14); 6958c2ecf20Sopenharmony_ci dev_dbg(component->dev, "format val = 0x%x\n", val); 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_DAC_FORMAT, 0x407f, val); 6988c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_ADC_FORMAT, 0x407f, val); 6998c2ecf20Sopenharmony_ci 7008c2ecf20Sopenharmony_ci return 0; 7018c2ecf20Sopenharmony_ci} 7028c2ecf20Sopenharmony_ci 7038c2ecf20Sopenharmony_cistatic int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 7048c2ecf20Sopenharmony_ci{ 7058c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 7068c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 7078c2ecf20Sopenharmony_ci 7088c2ecf20Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 7098c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_CBM_CFM: 7108c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 7118c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_M); 7128c2ecf20Sopenharmony_ci rt274->master = true; 7138c2ecf20Sopenharmony_ci break; 7148c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_CBS_CFS: 7158c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 7168c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_S); 7178c2ecf20Sopenharmony_ci rt274->master = false; 7188c2ecf20Sopenharmony_ci break; 7198c2ecf20Sopenharmony_ci default: 7208c2ecf20Sopenharmony_ci return -EINVAL; 7218c2ecf20Sopenharmony_ci } 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 7248c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_I2S: 7258c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_I2S_CTRL1, 7268c2ecf20Sopenharmony_ci RT274_I2S_FMT_MASK, RT274_I2S_FMT_I2S); 7278c2ecf20Sopenharmony_ci break; 7288c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_LEFT_J: 7298c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_I2S_CTRL1, 7308c2ecf20Sopenharmony_ci RT274_I2S_FMT_MASK, RT274_I2S_FMT_LJ); 7318c2ecf20Sopenharmony_ci break; 7328c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_DSP_A: 7338c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_I2S_CTRL1, 7348c2ecf20Sopenharmony_ci RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMA); 7358c2ecf20Sopenharmony_ci break; 7368c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_DSP_B: 7378c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_I2S_CTRL1, 7388c2ecf20Sopenharmony_ci RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMB); 7398c2ecf20Sopenharmony_ci break; 7408c2ecf20Sopenharmony_ci default: 7418c2ecf20Sopenharmony_ci return -EINVAL; 7428c2ecf20Sopenharmony_ci } 7438c2ecf20Sopenharmony_ci /* bit 15 Stream Type 0:PCM 1:Non-PCM */ 7448c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_DAC_FORMAT, 0x8000, 0); 7458c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_ADC_FORMAT, 0x8000, 0); 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_ci return 0; 7488c2ecf20Sopenharmony_ci} 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_cistatic int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, 7518c2ecf20Sopenharmony_ci unsigned int freq_in, unsigned int freq_out) 7528c2ecf20Sopenharmony_ci{ 7538c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 7548c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 7558c2ecf20Sopenharmony_ci 7568c2ecf20Sopenharmony_ci switch (source) { 7578c2ecf20Sopenharmony_ci case RT274_PLL2_S_MCLK: 7588c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_PLL2_CTRL, 7598c2ecf20Sopenharmony_ci RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_MCLK); 7608c2ecf20Sopenharmony_ci break; 7618c2ecf20Sopenharmony_ci default: 7628c2ecf20Sopenharmony_ci dev_warn(component->dev, "invalid pll source, use BCLK\n"); 7638c2ecf20Sopenharmony_ci fallthrough; 7648c2ecf20Sopenharmony_ci case RT274_PLL2_S_BCLK: 7658c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_PLL2_CTRL, 7668c2ecf20Sopenharmony_ci RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_BCLK); 7678c2ecf20Sopenharmony_ci break; 7688c2ecf20Sopenharmony_ci } 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_ci if (source == RT274_PLL2_S_BCLK) { 7718c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_MCLK_CTRL, 7728c2ecf20Sopenharmony_ci (0x3 << 12), (0x3 << 12)); 7738c2ecf20Sopenharmony_ci switch (rt274->fs) { 7748c2ecf20Sopenharmony_ci case 50: 7758c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7a, 0xaab6); 7768c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7b, 0x0301); 7778c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7c, 0x04fe); 7788c2ecf20Sopenharmony_ci break; 7798c2ecf20Sopenharmony_ci case 64: 7808c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7a, 0xaa96); 7818c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7b, 0x8003); 7828c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7c, 0x081e); 7838c2ecf20Sopenharmony_ci break; 7848c2ecf20Sopenharmony_ci case 128: 7858c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7a, 0xaa96); 7868c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7b, 0x8003); 7878c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7c, 0x080e); 7888c2ecf20Sopenharmony_ci break; 7898c2ecf20Sopenharmony_ci default: 7908c2ecf20Sopenharmony_ci dev_warn(component->dev, "invalid freq_in, assume 4.8M\n"); 7918c2ecf20Sopenharmony_ci fallthrough; 7928c2ecf20Sopenharmony_ci case 100: 7938c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7a, 0xaab6); 7948c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7b, 0x0301); 7958c2ecf20Sopenharmony_ci snd_soc_component_write(component, 0x7c, 0x047e); 7968c2ecf20Sopenharmony_ci break; 7978c2ecf20Sopenharmony_ci } 7988c2ecf20Sopenharmony_ci } 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci return 0; 8018c2ecf20Sopenharmony_ci} 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_cistatic int rt274_set_dai_sysclk(struct snd_soc_dai *dai, 8048c2ecf20Sopenharmony_ci int clk_id, unsigned int freq, int dir) 8058c2ecf20Sopenharmony_ci{ 8068c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 8078c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 8088c2ecf20Sopenharmony_ci unsigned int clk_src, mclk_en; 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci dev_dbg(component->dev, "%s freq=%d\n", __func__, freq); 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_ci switch (clk_id) { 8138c2ecf20Sopenharmony_ci case RT274_SCLK_S_MCLK: 8148c2ecf20Sopenharmony_ci mclk_en = RT274_MCLK_MODE_EN; 8158c2ecf20Sopenharmony_ci clk_src = RT274_CLK_SRC_MCLK; 8168c2ecf20Sopenharmony_ci break; 8178c2ecf20Sopenharmony_ci case RT274_SCLK_S_PLL1: 8188c2ecf20Sopenharmony_ci mclk_en = RT274_MCLK_MODE_DIS; 8198c2ecf20Sopenharmony_ci clk_src = RT274_CLK_SRC_MCLK; 8208c2ecf20Sopenharmony_ci break; 8218c2ecf20Sopenharmony_ci case RT274_SCLK_S_PLL2: 8228c2ecf20Sopenharmony_ci mclk_en = RT274_MCLK_MODE_EN; 8238c2ecf20Sopenharmony_ci clk_src = RT274_CLK_SRC_PLL2; 8248c2ecf20Sopenharmony_ci break; 8258c2ecf20Sopenharmony_ci default: 8268c2ecf20Sopenharmony_ci mclk_en = RT274_MCLK_MODE_DIS; 8278c2ecf20Sopenharmony_ci clk_src = RT274_CLK_SRC_MCLK; 8288c2ecf20Sopenharmony_ci dev_warn(component->dev, "invalid sysclk source, use PLL1\n"); 8298c2ecf20Sopenharmony_ci break; 8308c2ecf20Sopenharmony_ci } 8318c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_MCLK_CTRL, 8328c2ecf20Sopenharmony_ci RT274_MCLK_MODE_MASK, mclk_en); 8338c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, RT274_CLK_CTRL, 8348c2ecf20Sopenharmony_ci RT274_CLK_SRC_MASK, clk_src); 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_ci switch (freq) { 8378c2ecf20Sopenharmony_ci case 19200000: 8388c2ecf20Sopenharmony_ci if (clk_id == RT274_SCLK_S_MCLK) { 8398c2ecf20Sopenharmony_ci dev_err(component->dev, "Should not use MCLK\n"); 8408c2ecf20Sopenharmony_ci return -EINVAL; 8418c2ecf20Sopenharmony_ci } 8428c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 8438c2ecf20Sopenharmony_ci RT274_I2S_CTRL2, 0x40, 0x40); 8448c2ecf20Sopenharmony_ci break; 8458c2ecf20Sopenharmony_ci case 24000000: 8468c2ecf20Sopenharmony_ci if (clk_id == RT274_SCLK_S_MCLK) { 8478c2ecf20Sopenharmony_ci dev_err(component->dev, "Should not use MCLK\n"); 8488c2ecf20Sopenharmony_ci return -EINVAL; 8498c2ecf20Sopenharmony_ci } 8508c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 8518c2ecf20Sopenharmony_ci RT274_I2S_CTRL2, 0x40, 0x0); 8528c2ecf20Sopenharmony_ci break; 8538c2ecf20Sopenharmony_ci case 12288000: 8548c2ecf20Sopenharmony_ci case 11289600: 8558c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 8568c2ecf20Sopenharmony_ci RT274_MCLK_CTRL, 0x1fcf, 0x0008); 8578c2ecf20Sopenharmony_ci break; 8588c2ecf20Sopenharmony_ci case 24576000: 8598c2ecf20Sopenharmony_ci case 22579200: 8608c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 8618c2ecf20Sopenharmony_ci RT274_MCLK_CTRL, 0x1fcf, 0x1543); 8628c2ecf20Sopenharmony_ci break; 8638c2ecf20Sopenharmony_ci default: 8648c2ecf20Sopenharmony_ci dev_err(component->dev, "Unsupported system clock\n"); 8658c2ecf20Sopenharmony_ci return -EINVAL; 8668c2ecf20Sopenharmony_ci } 8678c2ecf20Sopenharmony_ci 8688c2ecf20Sopenharmony_ci rt274->sys_clk = freq; 8698c2ecf20Sopenharmony_ci rt274->clk_id = clk_id; 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_ci return 0; 8728c2ecf20Sopenharmony_ci} 8738c2ecf20Sopenharmony_ci 8748c2ecf20Sopenharmony_cistatic int rt274_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) 8758c2ecf20Sopenharmony_ci{ 8768c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 8778c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio); 8808c2ecf20Sopenharmony_ci rt274->fs = ratio; 8818c2ecf20Sopenharmony_ci if ((ratio / 50) == 0) 8828c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 8838c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, 0x1000, 0x1000); 8848c2ecf20Sopenharmony_ci else 8858c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 8868c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, 0x1000, 0x0); 8878c2ecf20Sopenharmony_ci 8888c2ecf20Sopenharmony_ci 8898c2ecf20Sopenharmony_ci return 0; 8908c2ecf20Sopenharmony_ci} 8918c2ecf20Sopenharmony_ci 8928c2ecf20Sopenharmony_cistatic int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 8938c2ecf20Sopenharmony_ci unsigned int rx_mask, int slots, int slot_width) 8948c2ecf20Sopenharmony_ci 8958c2ecf20Sopenharmony_ci{ 8968c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 8978c2ecf20Sopenharmony_ci 8988c2ecf20Sopenharmony_ci if (rx_mask || tx_mask) { 8998c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 9008c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_EN); 9018c2ecf20Sopenharmony_ci } else { 9028c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 9038c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_DIS); 9048c2ecf20Sopenharmony_ci return 0; 9058c2ecf20Sopenharmony_ci } 9068c2ecf20Sopenharmony_ci 9078c2ecf20Sopenharmony_ci switch (slots) { 9088c2ecf20Sopenharmony_ci case 4: 9098c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 9108c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_4CH); 9118c2ecf20Sopenharmony_ci break; 9128c2ecf20Sopenharmony_ci case 2: 9138c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, 9148c2ecf20Sopenharmony_ci RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_2CH); 9158c2ecf20Sopenharmony_ci break; 9168c2ecf20Sopenharmony_ci default: 9178c2ecf20Sopenharmony_ci dev_err(component->dev, 9188c2ecf20Sopenharmony_ci "Support 2 or 4 slots TDM only\n"); 9198c2ecf20Sopenharmony_ci return -EINVAL; 9208c2ecf20Sopenharmony_ci } 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_ci return 0; 9238c2ecf20Sopenharmony_ci} 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_cistatic int rt274_set_bias_level(struct snd_soc_component *component, 9268c2ecf20Sopenharmony_ci enum snd_soc_bias_level level) 9278c2ecf20Sopenharmony_ci{ 9288c2ecf20Sopenharmony_ci switch (level) { 9298c2ecf20Sopenharmony_ci case SND_SOC_BIAS_PREPARE: 9308c2ecf20Sopenharmony_ci if (SND_SOC_BIAS_STANDBY == 9318c2ecf20Sopenharmony_ci snd_soc_component_get_bias_level(component)) { 9328c2ecf20Sopenharmony_ci snd_soc_component_write(component, 9338c2ecf20Sopenharmony_ci RT274_SET_AUDIO_POWER, AC_PWRST_D0); 9348c2ecf20Sopenharmony_ci } 9358c2ecf20Sopenharmony_ci break; 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci case SND_SOC_BIAS_STANDBY: 9388c2ecf20Sopenharmony_ci snd_soc_component_write(component, 9398c2ecf20Sopenharmony_ci RT274_SET_AUDIO_POWER, AC_PWRST_D3); 9408c2ecf20Sopenharmony_ci break; 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_ci default: 9438c2ecf20Sopenharmony_ci break; 9448c2ecf20Sopenharmony_ci } 9458c2ecf20Sopenharmony_ci 9468c2ecf20Sopenharmony_ci return 0; 9478c2ecf20Sopenharmony_ci} 9488c2ecf20Sopenharmony_ci 9498c2ecf20Sopenharmony_cistatic irqreturn_t rt274_irq(int irq, void *data) 9508c2ecf20Sopenharmony_ci{ 9518c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = data; 9528c2ecf20Sopenharmony_ci bool hp = false; 9538c2ecf20Sopenharmony_ci bool mic = false; 9548c2ecf20Sopenharmony_ci int ret, status = 0; 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_ci /* Clear IRQ */ 9578c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, 9588c2ecf20Sopenharmony_ci RT274_IRQ_CLR, RT274_IRQ_CLR); 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_ci ret = rt274_jack_detect(rt274, &hp, &mic); 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_ci if (ret == 0) { 9638c2ecf20Sopenharmony_ci if (hp) 9648c2ecf20Sopenharmony_ci status |= SND_JACK_HEADPHONE; 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci if (mic) 9678c2ecf20Sopenharmony_ci status |= SND_JACK_MICROPHONE; 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci snd_soc_jack_report(rt274->jack, status, 9708c2ecf20Sopenharmony_ci SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci pm_wakeup_event(&rt274->i2c->dev, 300); 9738c2ecf20Sopenharmony_ci } 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_ci return IRQ_HANDLED; 9768c2ecf20Sopenharmony_ci} 9778c2ecf20Sopenharmony_ci 9788c2ecf20Sopenharmony_cistatic int rt274_probe(struct snd_soc_component *component) 9798c2ecf20Sopenharmony_ci{ 9808c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 9818c2ecf20Sopenharmony_ci 9828c2ecf20Sopenharmony_ci rt274->component = component; 9838c2ecf20Sopenharmony_ci 9848c2ecf20Sopenharmony_ci if (rt274->i2c->irq) { 9858c2ecf20Sopenharmony_ci INIT_DELAYED_WORK(&rt274->jack_detect_work, 9868c2ecf20Sopenharmony_ci rt274_jack_detect_work); 9878c2ecf20Sopenharmony_ci schedule_delayed_work(&rt274->jack_detect_work, 9888c2ecf20Sopenharmony_ci msecs_to_jiffies(1250)); 9898c2ecf20Sopenharmony_ci } 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci return 0; 9928c2ecf20Sopenharmony_ci} 9938c2ecf20Sopenharmony_ci 9948c2ecf20Sopenharmony_cistatic void rt274_remove(struct snd_soc_component *component) 9958c2ecf20Sopenharmony_ci{ 9968c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci cancel_delayed_work_sync(&rt274->jack_detect_work); 9998c2ecf20Sopenharmony_ci} 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 10028c2ecf20Sopenharmony_cistatic int rt274_suspend(struct snd_soc_component *component) 10038c2ecf20Sopenharmony_ci{ 10048c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci regcache_cache_only(rt274->regmap, true); 10078c2ecf20Sopenharmony_ci regcache_mark_dirty(rt274->regmap); 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci return 0; 10108c2ecf20Sopenharmony_ci} 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_cistatic int rt274_resume(struct snd_soc_component *component) 10138c2ecf20Sopenharmony_ci{ 10148c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); 10158c2ecf20Sopenharmony_ci 10168c2ecf20Sopenharmony_ci regcache_cache_only(rt274->regmap, false); 10178c2ecf20Sopenharmony_ci rt274_index_sync(component); 10188c2ecf20Sopenharmony_ci regcache_sync(rt274->regmap); 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_ci return 0; 10218c2ecf20Sopenharmony_ci} 10228c2ecf20Sopenharmony_ci#else 10238c2ecf20Sopenharmony_ci#define rt274_suspend NULL 10248c2ecf20Sopenharmony_ci#define rt274_resume NULL 10258c2ecf20Sopenharmony_ci#endif 10268c2ecf20Sopenharmony_ci 10278c2ecf20Sopenharmony_ci#define RT274_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 10288c2ecf20Sopenharmony_ci#define RT274_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 10298c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) 10308c2ecf20Sopenharmony_ci 10318c2ecf20Sopenharmony_cistatic const struct snd_soc_dai_ops rt274_aif_dai_ops = { 10328c2ecf20Sopenharmony_ci .hw_params = rt274_hw_params, 10338c2ecf20Sopenharmony_ci .set_fmt = rt274_set_dai_fmt, 10348c2ecf20Sopenharmony_ci .set_sysclk = rt274_set_dai_sysclk, 10358c2ecf20Sopenharmony_ci .set_pll = rt274_set_dai_pll, 10368c2ecf20Sopenharmony_ci .set_bclk_ratio = rt274_set_bclk_ratio, 10378c2ecf20Sopenharmony_ci .set_tdm_slot = rt274_set_tdm_slot, 10388c2ecf20Sopenharmony_ci}; 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver rt274_dai[] = { 10418c2ecf20Sopenharmony_ci { 10428c2ecf20Sopenharmony_ci .name = "rt274-aif1", 10438c2ecf20Sopenharmony_ci .id = RT274_AIF1, 10448c2ecf20Sopenharmony_ci .playback = { 10458c2ecf20Sopenharmony_ci .stream_name = "AIF1 Playback", 10468c2ecf20Sopenharmony_ci .channels_min = 1, 10478c2ecf20Sopenharmony_ci .channels_max = 2, 10488c2ecf20Sopenharmony_ci .rates = RT274_STEREO_RATES, 10498c2ecf20Sopenharmony_ci .formats = RT274_FORMATS, 10508c2ecf20Sopenharmony_ci }, 10518c2ecf20Sopenharmony_ci .capture = { 10528c2ecf20Sopenharmony_ci .stream_name = "AIF1 Capture", 10538c2ecf20Sopenharmony_ci .channels_min = 1, 10548c2ecf20Sopenharmony_ci .channels_max = 2, 10558c2ecf20Sopenharmony_ci .rates = RT274_STEREO_RATES, 10568c2ecf20Sopenharmony_ci .formats = RT274_FORMATS, 10578c2ecf20Sopenharmony_ci }, 10588c2ecf20Sopenharmony_ci .ops = &rt274_aif_dai_ops, 10598c2ecf20Sopenharmony_ci .symmetric_rates = 1, 10608c2ecf20Sopenharmony_ci }, 10618c2ecf20Sopenharmony_ci}; 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_cistatic const struct snd_soc_component_driver soc_component_dev_rt274 = { 10648c2ecf20Sopenharmony_ci .probe = rt274_probe, 10658c2ecf20Sopenharmony_ci .remove = rt274_remove, 10668c2ecf20Sopenharmony_ci .suspend = rt274_suspend, 10678c2ecf20Sopenharmony_ci .resume = rt274_resume, 10688c2ecf20Sopenharmony_ci .set_bias_level = rt274_set_bias_level, 10698c2ecf20Sopenharmony_ci .set_jack = rt274_mic_detect, 10708c2ecf20Sopenharmony_ci .controls = rt274_snd_controls, 10718c2ecf20Sopenharmony_ci .num_controls = ARRAY_SIZE(rt274_snd_controls), 10728c2ecf20Sopenharmony_ci .dapm_widgets = rt274_dapm_widgets, 10738c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(rt274_dapm_widgets), 10748c2ecf20Sopenharmony_ci .dapm_routes = rt274_dapm_routes, 10758c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(rt274_dapm_routes), 10768c2ecf20Sopenharmony_ci .use_pmdown_time = 1, 10778c2ecf20Sopenharmony_ci .endianness = 1, 10788c2ecf20Sopenharmony_ci .non_legacy_dai_naming = 1, 10798c2ecf20Sopenharmony_ci}; 10808c2ecf20Sopenharmony_ci 10818c2ecf20Sopenharmony_cistatic const struct regmap_config rt274_regmap = { 10828c2ecf20Sopenharmony_ci .reg_bits = 32, 10838c2ecf20Sopenharmony_ci .val_bits = 32, 10848c2ecf20Sopenharmony_ci .max_register = 0x05bfffff, 10858c2ecf20Sopenharmony_ci .volatile_reg = rt274_volatile_register, 10868c2ecf20Sopenharmony_ci .readable_reg = rt274_readable_register, 10878c2ecf20Sopenharmony_ci .reg_write = rl6347a_hw_write, 10888c2ecf20Sopenharmony_ci .reg_read = rl6347a_hw_read, 10898c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 10908c2ecf20Sopenharmony_ci .reg_defaults = rt274_reg, 10918c2ecf20Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(rt274_reg), 10928c2ecf20Sopenharmony_ci}; 10938c2ecf20Sopenharmony_ci 10948c2ecf20Sopenharmony_ci#ifdef CONFIG_OF 10958c2ecf20Sopenharmony_cistatic const struct of_device_id rt274_of_match[] = { 10968c2ecf20Sopenharmony_ci {.compatible = "realtek,rt274"}, 10978c2ecf20Sopenharmony_ci {}, 10988c2ecf20Sopenharmony_ci}; 10998c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, rt274_of_match); 11008c2ecf20Sopenharmony_ci#endif 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_cistatic const struct i2c_device_id rt274_i2c_id[] = { 11038c2ecf20Sopenharmony_ci {"rt274", 0}, 11048c2ecf20Sopenharmony_ci {} 11058c2ecf20Sopenharmony_ci}; 11068c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, rt274_i2c_id); 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_ci#ifdef CONFIG_ACPI 11098c2ecf20Sopenharmony_cistatic const struct acpi_device_id rt274_acpi_match[] = { 11108c2ecf20Sopenharmony_ci { "10EC0274", 0 }, 11118c2ecf20Sopenharmony_ci { "INT34C2", 0 }, 11128c2ecf20Sopenharmony_ci {}, 11138c2ecf20Sopenharmony_ci}; 11148c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, rt274_acpi_match); 11158c2ecf20Sopenharmony_ci#endif 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_cistatic int rt274_i2c_probe(struct i2c_client *i2c, 11188c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 11198c2ecf20Sopenharmony_ci{ 11208c2ecf20Sopenharmony_ci struct rt274_priv *rt274; 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_ci int ret; 11238c2ecf20Sopenharmony_ci unsigned int val; 11248c2ecf20Sopenharmony_ci 11258c2ecf20Sopenharmony_ci rt274 = devm_kzalloc(&i2c->dev, sizeof(*rt274), 11268c2ecf20Sopenharmony_ci GFP_KERNEL); 11278c2ecf20Sopenharmony_ci if (rt274 == NULL) 11288c2ecf20Sopenharmony_ci return -ENOMEM; 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci rt274->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt274_regmap); 11318c2ecf20Sopenharmony_ci if (IS_ERR(rt274->regmap)) { 11328c2ecf20Sopenharmony_ci ret = PTR_ERR(rt274->regmap); 11338c2ecf20Sopenharmony_ci dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 11348c2ecf20Sopenharmony_ci ret); 11358c2ecf20Sopenharmony_ci return ret; 11368c2ecf20Sopenharmony_ci } 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_ci ret = regmap_read(rt274->regmap, 11398c2ecf20Sopenharmony_ci RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val); 11408c2ecf20Sopenharmony_ci if (ret) 11418c2ecf20Sopenharmony_ci return ret; 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_ci if (val != RT274_VENDOR_ID) { 11448c2ecf20Sopenharmony_ci dev_err(&i2c->dev, 11458c2ecf20Sopenharmony_ci "Device with ID register %#x is not rt274\n", val); 11468c2ecf20Sopenharmony_ci return -ENODEV; 11478c2ecf20Sopenharmony_ci } 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_ci rt274->index_cache = devm_kmemdup(&i2c->dev, rt274_index_def, 11508c2ecf20Sopenharmony_ci sizeof(rt274_index_def), GFP_KERNEL); 11518c2ecf20Sopenharmony_ci if (!rt274->index_cache) 11528c2ecf20Sopenharmony_ci return -ENOMEM; 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_ci rt274->index_cache_size = INDEX_CACHE_SIZE; 11558c2ecf20Sopenharmony_ci rt274->i2c = i2c; 11568c2ecf20Sopenharmony_ci i2c_set_clientdata(i2c, rt274); 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci /* reset codec */ 11598c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_RESET, 0); 11608c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, 0x1a, 0x4000, 0x4000); 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci /* Set Pad PDB is floating */ 11638c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, RT274_PAD_CTRL12, 0x3, 0x0); 11648c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_COEF5b_INDEX, 0x01); 11658c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_COEF5b_COEF, 0x8540); 11668c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, 0x6f, 0x0100, 0x0100); 11678c2ecf20Sopenharmony_ci /* Combo jack auto detect */ 11688c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, 0x4a, 0x201b); 11698c2ecf20Sopenharmony_ci /* Aux mode off */ 11708c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, 0x6f, 0x3000, 0x2000); 11718c2ecf20Sopenharmony_ci /* HP DC Calibration */ 11728c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, 0x6f, 0xf, 0x0); 11738c2ecf20Sopenharmony_ci /* Set NID=58h.Index 00h [15]= 1b; */ 11748c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_COEF58_INDEX, 0x00); 11758c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_COEF58_COEF, 0xb888); 11768c2ecf20Sopenharmony_ci msleep(500); 11778c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, 0x6f, 0xf, 0xb); 11788c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_COEF58_INDEX, 0x00); 11798c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_COEF58_COEF, 0x3888); 11808c2ecf20Sopenharmony_ci /* Set pin widget */ 11818c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_SET_PIN_HPO, 0x40); 11828c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_SET_PIN_LOUT3, 0x40); 11838c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_SET_MIC, 0x20); 11848c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_SET_PIN_DMIC1, 0x20); 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, RT274_I2S_CTRL2, 0xc004, 0x4004); 11878c2ecf20Sopenharmony_ci regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, 11888c2ecf20Sopenharmony_ci RT274_GPI2_SEL_MASK, RT274_GPI2_SEL_DMIC_CLK); 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci /* jack detection */ 11918c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_UNSOLICITED_HP_OUT, 0x81); 11928c2ecf20Sopenharmony_ci regmap_write(rt274->regmap, RT274_UNSOLICITED_MIC, 0x82); 11938c2ecf20Sopenharmony_ci 11948c2ecf20Sopenharmony_ci if (rt274->i2c->irq) { 11958c2ecf20Sopenharmony_ci ret = request_threaded_irq(rt274->i2c->irq, NULL, rt274_irq, 11968c2ecf20Sopenharmony_ci IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt274", rt274); 11978c2ecf20Sopenharmony_ci if (ret != 0) { 11988c2ecf20Sopenharmony_ci dev_err(&i2c->dev, 11998c2ecf20Sopenharmony_ci "Failed to reguest IRQ: %d\n", ret); 12008c2ecf20Sopenharmony_ci return ret; 12018c2ecf20Sopenharmony_ci } 12028c2ecf20Sopenharmony_ci } 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci ret = devm_snd_soc_register_component(&i2c->dev, 12058c2ecf20Sopenharmony_ci &soc_component_dev_rt274, 12068c2ecf20Sopenharmony_ci rt274_dai, ARRAY_SIZE(rt274_dai)); 12078c2ecf20Sopenharmony_ci 12088c2ecf20Sopenharmony_ci return ret; 12098c2ecf20Sopenharmony_ci} 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_cistatic int rt274_i2c_remove(struct i2c_client *i2c) 12128c2ecf20Sopenharmony_ci{ 12138c2ecf20Sopenharmony_ci struct rt274_priv *rt274 = i2c_get_clientdata(i2c); 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci if (i2c->irq) 12168c2ecf20Sopenharmony_ci free_irq(i2c->irq, rt274); 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ci return 0; 12198c2ecf20Sopenharmony_ci} 12208c2ecf20Sopenharmony_ci 12218c2ecf20Sopenharmony_ci 12228c2ecf20Sopenharmony_cistatic struct i2c_driver rt274_i2c_driver = { 12238c2ecf20Sopenharmony_ci .driver = { 12248c2ecf20Sopenharmony_ci .name = "rt274", 12258c2ecf20Sopenharmony_ci .acpi_match_table = ACPI_PTR(rt274_acpi_match), 12268c2ecf20Sopenharmony_ci#ifdef CONFIG_OF 12278c2ecf20Sopenharmony_ci .of_match_table = of_match_ptr(rt274_of_match), 12288c2ecf20Sopenharmony_ci#endif 12298c2ecf20Sopenharmony_ci }, 12308c2ecf20Sopenharmony_ci .probe = rt274_i2c_probe, 12318c2ecf20Sopenharmony_ci .remove = rt274_i2c_remove, 12328c2ecf20Sopenharmony_ci .id_table = rt274_i2c_id, 12338c2ecf20Sopenharmony_ci}; 12348c2ecf20Sopenharmony_ci 12358c2ecf20Sopenharmony_cimodule_i2c_driver(rt274_i2c_driver); 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("ASoC RT274 driver"); 12388c2ecf20Sopenharmony_ciMODULE_AUTHOR("Bard Liao <bardliao@realtek.com>"); 12398c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 1240