18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * cs42l56.c -- CS42L56 ALSA SoC audio driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2014 CirrusLogic, Inc. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Author: Brian Austin <brian.austin@cirrus.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/moduleparam.h> 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/init.h> 148c2ecf20Sopenharmony_ci#include <linux/delay.h> 158c2ecf20Sopenharmony_ci#include <linux/pm.h> 168c2ecf20Sopenharmony_ci#include <linux/i2c.h> 178c2ecf20Sopenharmony_ci#include <linux/input.h> 188c2ecf20Sopenharmony_ci#include <linux/regmap.h> 198c2ecf20Sopenharmony_ci#include <linux/slab.h> 208c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 218c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 228c2ecf20Sopenharmony_ci#include <linux/regulator/consumer.h> 238c2ecf20Sopenharmony_ci#include <linux/of_device.h> 248c2ecf20Sopenharmony_ci#include <linux/of_gpio.h> 258c2ecf20Sopenharmony_ci#include <sound/core.h> 268c2ecf20Sopenharmony_ci#include <sound/pcm.h> 278c2ecf20Sopenharmony_ci#include <sound/pcm_params.h> 288c2ecf20Sopenharmony_ci#include <sound/soc.h> 298c2ecf20Sopenharmony_ci#include <sound/soc-dapm.h> 308c2ecf20Sopenharmony_ci#include <sound/initval.h> 318c2ecf20Sopenharmony_ci#include <sound/tlv.h> 328c2ecf20Sopenharmony_ci#include <sound/cs42l56.h> 338c2ecf20Sopenharmony_ci#include "cs42l56.h" 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define CS42L56_NUM_SUPPLIES 3 368c2ecf20Sopenharmony_cistatic const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = { 378c2ecf20Sopenharmony_ci "VA", 388c2ecf20Sopenharmony_ci "VCP", 398c2ecf20Sopenharmony_ci "VLDO", 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistruct cs42l56_private { 438c2ecf20Sopenharmony_ci struct regmap *regmap; 448c2ecf20Sopenharmony_ci struct snd_soc_component *component; 458c2ecf20Sopenharmony_ci struct device *dev; 468c2ecf20Sopenharmony_ci struct cs42l56_platform_data pdata; 478c2ecf20Sopenharmony_ci struct regulator_bulk_data supplies[CS42L56_NUM_SUPPLIES]; 488c2ecf20Sopenharmony_ci u32 mclk; 498c2ecf20Sopenharmony_ci u8 mclk_prediv; 508c2ecf20Sopenharmony_ci u8 mclk_div2; 518c2ecf20Sopenharmony_ci u8 mclk_ratio; 528c2ecf20Sopenharmony_ci u8 iface; 538c2ecf20Sopenharmony_ci u8 iface_fmt; 548c2ecf20Sopenharmony_ci u8 iface_inv; 558c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT) 568c2ecf20Sopenharmony_ci struct input_dev *beep; 578c2ecf20Sopenharmony_ci struct work_struct beep_work; 588c2ecf20Sopenharmony_ci int beep_rate; 598c2ecf20Sopenharmony_ci#endif 608c2ecf20Sopenharmony_ci}; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistatic const struct reg_default cs42l56_reg_defaults[] = { 638c2ecf20Sopenharmony_ci { 3, 0x7f }, /* r03 - Power Ctl 1 */ 648c2ecf20Sopenharmony_ci { 4, 0xff }, /* r04 - Power Ctl 2 */ 658c2ecf20Sopenharmony_ci { 5, 0x00 }, /* ro5 - Clocking Ctl 1 */ 668c2ecf20Sopenharmony_ci { 6, 0x0b }, /* r06 - Clocking Ctl 2 */ 678c2ecf20Sopenharmony_ci { 7, 0x00 }, /* r07 - Serial Format */ 688c2ecf20Sopenharmony_ci { 8, 0x05 }, /* r08 - Class H Ctl */ 698c2ecf20Sopenharmony_ci { 9, 0x0c }, /* r09 - Misc Ctl */ 708c2ecf20Sopenharmony_ci { 10, 0x80 }, /* r0a - INT Status */ 718c2ecf20Sopenharmony_ci { 11, 0x00 }, /* r0b - Playback Ctl */ 728c2ecf20Sopenharmony_ci { 12, 0x0c }, /* r0c - DSP Mute Ctl */ 738c2ecf20Sopenharmony_ci { 13, 0x00 }, /* r0d - ADCA Mixer Volume */ 748c2ecf20Sopenharmony_ci { 14, 0x00 }, /* r0e - ADCB Mixer Volume */ 758c2ecf20Sopenharmony_ci { 15, 0x00 }, /* r0f - PCMA Mixer Volume */ 768c2ecf20Sopenharmony_ci { 16, 0x00 }, /* r10 - PCMB Mixer Volume */ 778c2ecf20Sopenharmony_ci { 17, 0x00 }, /* r11 - Analog Input Advisory Volume */ 788c2ecf20Sopenharmony_ci { 18, 0x00 }, /* r12 - Digital Input Advisory Volume */ 798c2ecf20Sopenharmony_ci { 19, 0x00 }, /* r13 - Master A Volume */ 808c2ecf20Sopenharmony_ci { 20, 0x00 }, /* r14 - Master B Volume */ 818c2ecf20Sopenharmony_ci { 21, 0x00 }, /* r15 - Beep Freq / On Time */ 828c2ecf20Sopenharmony_ci { 22, 0x00 }, /* r16 - Beep Volume / Off Time */ 838c2ecf20Sopenharmony_ci { 23, 0x00 }, /* r17 - Beep Tone Ctl */ 848c2ecf20Sopenharmony_ci { 24, 0x88 }, /* r18 - Tone Ctl */ 858c2ecf20Sopenharmony_ci { 25, 0x00 }, /* r19 - Channel Mixer & Swap */ 868c2ecf20Sopenharmony_ci { 26, 0x00 }, /* r1a - AIN Ref Config / ADC Mux */ 878c2ecf20Sopenharmony_ci { 27, 0xa0 }, /* r1b - High-Pass Filter Ctl */ 888c2ecf20Sopenharmony_ci { 28, 0x00 }, /* r1c - Misc ADC Ctl */ 898c2ecf20Sopenharmony_ci { 29, 0x00 }, /* r1d - Gain & Bias Ctl */ 908c2ecf20Sopenharmony_ci { 30, 0x00 }, /* r1e - PGAA Mux & Volume */ 918c2ecf20Sopenharmony_ci { 31, 0x00 }, /* r1f - PGAB Mux & Volume */ 928c2ecf20Sopenharmony_ci { 32, 0x00 }, /* r20 - ADCA Attenuator */ 938c2ecf20Sopenharmony_ci { 33, 0x00 }, /* r21 - ADCB Attenuator */ 948c2ecf20Sopenharmony_ci { 34, 0x00 }, /* r22 - ALC Enable & Attack Rate */ 958c2ecf20Sopenharmony_ci { 35, 0xbf }, /* r23 - ALC Release Rate */ 968c2ecf20Sopenharmony_ci { 36, 0x00 }, /* r24 - ALC Threshold */ 978c2ecf20Sopenharmony_ci { 37, 0x00 }, /* r25 - Noise Gate Ctl */ 988c2ecf20Sopenharmony_ci { 38, 0x00 }, /* r26 - ALC, Limiter, SFT, ZeroCross */ 998c2ecf20Sopenharmony_ci { 39, 0x00 }, /* r27 - Analog Mute, LO & HP Mux */ 1008c2ecf20Sopenharmony_ci { 40, 0x00 }, /* r28 - HP A Volume */ 1018c2ecf20Sopenharmony_ci { 41, 0x00 }, /* r29 - HP B Volume */ 1028c2ecf20Sopenharmony_ci { 42, 0x00 }, /* r2a - LINEOUT A Volume */ 1038c2ecf20Sopenharmony_ci { 43, 0x00 }, /* r2b - LINEOUT B Volume */ 1048c2ecf20Sopenharmony_ci { 44, 0x00 }, /* r2c - Limit Threshold Ctl */ 1058c2ecf20Sopenharmony_ci { 45, 0x7f }, /* r2d - Limiter Ctl & Release Rate */ 1068c2ecf20Sopenharmony_ci { 46, 0x00 }, /* r2e - Limiter Attack Rate */ 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic bool cs42l56_readable_register(struct device *dev, unsigned int reg) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci switch (reg) { 1128c2ecf20Sopenharmony_ci case CS42L56_CHIP_ID_1 ... CS42L56_LIM_ATTACK_RATE: 1138c2ecf20Sopenharmony_ci return true; 1148c2ecf20Sopenharmony_ci default: 1158c2ecf20Sopenharmony_ci return false; 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci} 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistatic bool cs42l56_volatile_register(struct device *dev, unsigned int reg) 1208c2ecf20Sopenharmony_ci{ 1218c2ecf20Sopenharmony_ci switch (reg) { 1228c2ecf20Sopenharmony_ci case CS42L56_INT_STATUS: 1238c2ecf20Sopenharmony_ci return true; 1248c2ecf20Sopenharmony_ci default: 1258c2ecf20Sopenharmony_ci return false; 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(beep_tlv, -5000, 200, 0); 1308c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(hl_tlv, -6000, 50, 0); 1318c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(adv_tlv, -10200, 50, 0); 1328c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, 0); 1338c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0); 1348c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(preamp_tlv, 0, 1000, 0); 1358c2ecf20Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_RANGE(ngnb_tlv, 1388c2ecf20Sopenharmony_ci 0, 1, TLV_DB_SCALE_ITEM(-8200, 600, 0), 1398c2ecf20Sopenharmony_ci 2, 5, TLV_DB_SCALE_ITEM(-7600, 300, 0) 1408c2ecf20Sopenharmony_ci); 1418c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_RANGE(ngb_tlv, 1428c2ecf20Sopenharmony_ci 0, 2, TLV_DB_SCALE_ITEM(-6400, 600, 0), 1438c2ecf20Sopenharmony_ci 3, 7, TLV_DB_SCALE_ITEM(-4600, 300, 0) 1448c2ecf20Sopenharmony_ci); 1458c2ecf20Sopenharmony_cistatic const DECLARE_TLV_DB_RANGE(alc_tlv, 1468c2ecf20Sopenharmony_ci 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0), 1478c2ecf20Sopenharmony_ci 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0) 1488c2ecf20Sopenharmony_ci); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic const char * const beep_config_text[] = { 1518c2ecf20Sopenharmony_ci "Off", "Single", "Multiple", "Continuous" 1528c2ecf20Sopenharmony_ci}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic const struct soc_enum beep_config_enum = 1558c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 6, 1568c2ecf20Sopenharmony_ci ARRAY_SIZE(beep_config_text), beep_config_text); 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic const char * const beep_pitch_text[] = { 1598c2ecf20Sopenharmony_ci "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5", 1608c2ecf20Sopenharmony_ci "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7" 1618c2ecf20Sopenharmony_ci}; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_cistatic const struct soc_enum beep_pitch_enum = 1648c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 4, 1658c2ecf20Sopenharmony_ci ARRAY_SIZE(beep_pitch_text), beep_pitch_text); 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic const char * const beep_ontime_text[] = { 1688c2ecf20Sopenharmony_ci "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s", 1698c2ecf20Sopenharmony_ci "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s", 1708c2ecf20Sopenharmony_ci "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s" 1718c2ecf20Sopenharmony_ci}; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic const struct soc_enum beep_ontime_enum = 1748c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 0, 1758c2ecf20Sopenharmony_ci ARRAY_SIZE(beep_ontime_text), beep_ontime_text); 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic const char * const beep_offtime_text[] = { 1788c2ecf20Sopenharmony_ci "1.23 s", "2.58 s", "3.90 s", "5.20 s", 1798c2ecf20Sopenharmony_ci "6.60 s", "8.05 s", "9.35 s", "10.80 s" 1808c2ecf20Sopenharmony_ci}; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic const struct soc_enum beep_offtime_enum = 1838c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_OFFTIME, 5, 1848c2ecf20Sopenharmony_ci ARRAY_SIZE(beep_offtime_text), beep_offtime_text); 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_cistatic const char * const beep_treble_text[] = { 1878c2ecf20Sopenharmony_ci "5kHz", "7kHz", "10kHz", "15kHz" 1888c2ecf20Sopenharmony_ci}; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic const struct soc_enum beep_treble_enum = 1918c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 3, 1928c2ecf20Sopenharmony_ci ARRAY_SIZE(beep_treble_text), beep_treble_text); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_cistatic const char * const beep_bass_text[] = { 1958c2ecf20Sopenharmony_ci "50Hz", "100Hz", "200Hz", "250Hz" 1968c2ecf20Sopenharmony_ci}; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic const struct soc_enum beep_bass_enum = 1998c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1, 2008c2ecf20Sopenharmony_ci ARRAY_SIZE(beep_bass_text), beep_bass_text); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic const char * const pgaa_mux_text[] = { 2038c2ecf20Sopenharmony_ci "AIN1A", "AIN2A", "AIN3A"}; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_cistatic const struct soc_enum pgaa_mux_enum = 2068c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_PGAA_MUX_VOLUME, 0, 2078c2ecf20Sopenharmony_ci ARRAY_SIZE(pgaa_mux_text), 2088c2ecf20Sopenharmony_ci pgaa_mux_text); 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new pgaa_mux = 2118c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", pgaa_mux_enum); 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_cistatic const char * const pgab_mux_text[] = { 2148c2ecf20Sopenharmony_ci "AIN1B", "AIN2B", "AIN3B"}; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic const struct soc_enum pgab_mux_enum = 2178c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_PGAB_MUX_VOLUME, 0, 2188c2ecf20Sopenharmony_ci ARRAY_SIZE(pgab_mux_text), 2198c2ecf20Sopenharmony_ci pgab_mux_text); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new pgab_mux = 2228c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", pgab_mux_enum); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cistatic const char * const adca_mux_text[] = { 2258c2ecf20Sopenharmony_ci "PGAA", "AIN1A", "AIN2A", "AIN3A"}; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic const struct soc_enum adca_mux_enum = 2288c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 0, 2298c2ecf20Sopenharmony_ci ARRAY_SIZE(adca_mux_text), 2308c2ecf20Sopenharmony_ci adca_mux_text); 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new adca_mux = 2338c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", adca_mux_enum); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic const char * const adcb_mux_text[] = { 2368c2ecf20Sopenharmony_ci "PGAB", "AIN1B", "AIN2B", "AIN3B"}; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cistatic const struct soc_enum adcb_mux_enum = 2398c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 2, 2408c2ecf20Sopenharmony_ci ARRAY_SIZE(adcb_mux_text), 2418c2ecf20Sopenharmony_ci adcb_mux_text); 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new adcb_mux = 2448c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", adcb_mux_enum); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_cistatic const char * const left_swap_text[] = { 2478c2ecf20Sopenharmony_ci "Left", "LR 2", "Right"}; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic const char * const right_swap_text[] = { 2508c2ecf20Sopenharmony_ci "Right", "LR 2", "Left"}; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic const unsigned int swap_values[] = { 0, 1, 3 }; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_cistatic const struct soc_enum adca_swap_enum = 2558c2ecf20Sopenharmony_ci SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 0, 3, 2568c2ecf20Sopenharmony_ci ARRAY_SIZE(left_swap_text), 2578c2ecf20Sopenharmony_ci left_swap_text, 2588c2ecf20Sopenharmony_ci swap_values); 2598c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new adca_swap_mux = 2608c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", adca_swap_enum); 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_cistatic const struct soc_enum pcma_swap_enum = 2638c2ecf20Sopenharmony_ci SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 4, 3, 2648c2ecf20Sopenharmony_ci ARRAY_SIZE(left_swap_text), 2658c2ecf20Sopenharmony_ci left_swap_text, 2668c2ecf20Sopenharmony_ci swap_values); 2678c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new pcma_swap_mux = 2688c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", pcma_swap_enum); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic const struct soc_enum adcb_swap_enum = 2718c2ecf20Sopenharmony_ci SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 2, 3, 2728c2ecf20Sopenharmony_ci ARRAY_SIZE(right_swap_text), 2738c2ecf20Sopenharmony_ci right_swap_text, 2748c2ecf20Sopenharmony_ci swap_values); 2758c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new adcb_swap_mux = 2768c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", adcb_swap_enum); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_cistatic const struct soc_enum pcmb_swap_enum = 2798c2ecf20Sopenharmony_ci SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 6, 3, 2808c2ecf20Sopenharmony_ci ARRAY_SIZE(right_swap_text), 2818c2ecf20Sopenharmony_ci right_swap_text, 2828c2ecf20Sopenharmony_ci swap_values); 2838c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new pcmb_swap_mux = 2848c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", pcmb_swap_enum); 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new hpa_switch = 2878c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1); 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new hpb_switch = 2908c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 4, 1, 1); 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new loa_switch = 2938c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 2, 1, 1); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new lob_switch = 2968c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 0, 1, 1); 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_cistatic const char * const hploa_input_text[] = { 2998c2ecf20Sopenharmony_ci "DACA", "PGAA"}; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_cistatic const struct soc_enum lineouta_input_enum = 3028c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 2, 3038c2ecf20Sopenharmony_ci ARRAY_SIZE(hploa_input_text), 3048c2ecf20Sopenharmony_ci hploa_input_text); 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new lineouta_input = 3078c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", lineouta_input_enum); 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_cistatic const struct soc_enum hpa_input_enum = 3108c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 0, 3118c2ecf20Sopenharmony_ci ARRAY_SIZE(hploa_input_text), 3128c2ecf20Sopenharmony_ci hploa_input_text); 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new hpa_input = 3158c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", hpa_input_enum); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic const char * const hplob_input_text[] = { 3188c2ecf20Sopenharmony_ci "DACB", "PGAB"}; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_cistatic const struct soc_enum lineoutb_input_enum = 3218c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 3, 3228c2ecf20Sopenharmony_ci ARRAY_SIZE(hplob_input_text), 3238c2ecf20Sopenharmony_ci hplob_input_text); 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new lineoutb_input = 3268c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", lineoutb_input_enum); 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_cistatic const struct soc_enum hpb_input_enum = 3298c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 1, 3308c2ecf20Sopenharmony_ci ARRAY_SIZE(hplob_input_text), 3318c2ecf20Sopenharmony_ci hplob_input_text); 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new hpb_input = 3348c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", hpb_input_enum); 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_cistatic const char * const dig_mux_text[] = { 3378c2ecf20Sopenharmony_ci "ADC", "DSP"}; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_cistatic const struct soc_enum dig_mux_enum = 3408c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_MISC_CTL, 7, 3418c2ecf20Sopenharmony_ci ARRAY_SIZE(dig_mux_text), 3428c2ecf20Sopenharmony_ci dig_mux_text); 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new dig_mux = 3458c2ecf20Sopenharmony_ci SOC_DAPM_ENUM("Route", dig_mux_enum); 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_cistatic const char * const hpf_freq_text[] = { 3488c2ecf20Sopenharmony_ci "1.8Hz", "119Hz", "236Hz", "464Hz" 3498c2ecf20Sopenharmony_ci}; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cistatic const struct soc_enum hpfa_freq_enum = 3528c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 0, 3538c2ecf20Sopenharmony_ci ARRAY_SIZE(hpf_freq_text), hpf_freq_text); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_cistatic const struct soc_enum hpfb_freq_enum = 3568c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 2, 3578c2ecf20Sopenharmony_ci ARRAY_SIZE(hpf_freq_text), hpf_freq_text); 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_cistatic const char * const ng_delay_text[] = { 3608c2ecf20Sopenharmony_ci "50ms", "100ms", "150ms", "200ms" 3618c2ecf20Sopenharmony_ci}; 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_cistatic const struct soc_enum ng_delay_enum = 3648c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE(CS42L56_NOISE_GATE_CTL, 0, 3658c2ecf20Sopenharmony_ci ARRAY_SIZE(ng_delay_text), ng_delay_text); 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new cs42l56_snd_controls[] = { 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L56_MASTER_A_VOLUME, 3708c2ecf20Sopenharmony_ci CS42L56_MASTER_B_VOLUME, 0, 0x34, 0xE4, adv_tlv), 3718c2ecf20Sopenharmony_ci SOC_DOUBLE("Master Mute Switch", CS42L56_DSP_MUTE_CTL, 0, 1, 1, 1), 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L56_ADCA_MIX_VOLUME, 3748c2ecf20Sopenharmony_ci CS42L56_ADCB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv), 3758c2ecf20Sopenharmony_ci SOC_DOUBLE("ADC Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 6, 7, 1, 1), 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", CS42L56_PCMA_MIX_VOLUME, 3788c2ecf20Sopenharmony_ci CS42L56_PCMB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv), 3798c2ecf20Sopenharmony_ci SOC_DOUBLE("PCM Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 4, 5, 1, 1), 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Analog Advisory Volume", 3828c2ecf20Sopenharmony_ci CS42L56_ANAINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv), 3838c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Digital Advisory Volume", 3848c2ecf20Sopenharmony_ci CS42L56_DIGINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv), 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L56_PGAA_MUX_VOLUME, 3878c2ecf20Sopenharmony_ci CS42L56_PGAB_MUX_VOLUME, 0, 0x34, 0x24, pga_tlv), 3888c2ecf20Sopenharmony_ci SOC_DOUBLE_R_TLV("ADC Volume", CS42L56_ADCA_ATTENUATOR, 3898c2ecf20Sopenharmony_ci CS42L56_ADCB_ATTENUATOR, 0, 0x00, 1, adc_tlv), 3908c2ecf20Sopenharmony_ci SOC_DOUBLE("ADC Mute Switch", CS42L56_MISC_ADC_CTL, 2, 3, 1, 1), 3918c2ecf20Sopenharmony_ci SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1), 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME, 3948c2ecf20Sopenharmony_ci CS42L56_HPB_VOLUME, 0, 0x44, 0x48, hl_tlv), 3958c2ecf20Sopenharmony_ci SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME, 3968c2ecf20Sopenharmony_ci CS42L56_LOB_VOLUME, 0, 0x44, 0x48, hl_tlv), 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL, 3998c2ecf20Sopenharmony_ci 0, 0x00, 1, tone_tlv), 4008c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Treble Shelving Volume", CS42L56_TONE_CTL, 4018c2ecf20Sopenharmony_ci 4, 0x00, 1, tone_tlv), 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci SOC_DOUBLE_TLV("PGA Preamp Volume", CS42L56_GAIN_BIAS_CTL, 4048c2ecf20Sopenharmony_ci 4, 6, 0x02, 1, preamp_tlv), 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci SOC_SINGLE("DSP Switch", CS42L56_PLAYBACK_CTL, 7, 1, 1), 4078c2ecf20Sopenharmony_ci SOC_SINGLE("Gang Playback Switch", CS42L56_PLAYBACK_CTL, 4, 1, 1), 4088c2ecf20Sopenharmony_ci SOC_SINGLE("Gang ADC Switch", CS42L56_MISC_ADC_CTL, 7, 1, 1), 4098c2ecf20Sopenharmony_ci SOC_SINGLE("Gang PGA Switch", CS42L56_MISC_ADC_CTL, 6, 1, 1), 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci SOC_SINGLE("PCMA Invert", CS42L56_PLAYBACK_CTL, 2, 1, 1), 4128c2ecf20Sopenharmony_ci SOC_SINGLE("PCMB Invert", CS42L56_PLAYBACK_CTL, 3, 1, 1), 4138c2ecf20Sopenharmony_ci SOC_SINGLE("ADCA Invert", CS42L56_MISC_ADC_CTL, 2, 1, 1), 4148c2ecf20Sopenharmony_ci SOC_SINGLE("ADCB Invert", CS42L56_MISC_ADC_CTL, 3, 1, 1), 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci SOC_DOUBLE("HPF Switch", CS42L56_HPF_CTL, 5, 7, 1, 1), 4178c2ecf20Sopenharmony_ci SOC_DOUBLE("HPF Freeze Switch", CS42L56_HPF_CTL, 4, 6, 1, 1), 4188c2ecf20Sopenharmony_ci SOC_ENUM("HPFA Corner Freq", hpfa_freq_enum), 4198c2ecf20Sopenharmony_ci SOC_ENUM("HPFB Corner Freq", hpfb_freq_enum), 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci SOC_SINGLE("Analog Soft Ramp", CS42L56_MISC_CTL, 4, 1, 1), 4228c2ecf20Sopenharmony_ci SOC_DOUBLE("Analog Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC, 4238c2ecf20Sopenharmony_ci 7, 5, 1, 1), 4248c2ecf20Sopenharmony_ci SOC_SINGLE("Analog Zero Cross", CS42L56_MISC_CTL, 3, 1, 1), 4258c2ecf20Sopenharmony_ci SOC_DOUBLE("Analog Zero Cross Disable", CS42L56_ALC_LIM_SFT_ZC, 4268c2ecf20Sopenharmony_ci 6, 4, 1, 1), 4278c2ecf20Sopenharmony_ci SOC_SINGLE("Digital Soft Ramp", CS42L56_MISC_CTL, 2, 1, 1), 4288c2ecf20Sopenharmony_ci SOC_SINGLE("Digital Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC, 4298c2ecf20Sopenharmony_ci 3, 1, 1), 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci SOC_SINGLE("HL Deemphasis", CS42L56_PLAYBACK_CTL, 6, 1, 1), 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci SOC_SINGLE("ALC Switch", CS42L56_ALC_EN_ATTACK_RATE, 6, 1, 1), 4348c2ecf20Sopenharmony_ci SOC_SINGLE("ALC Limit All Switch", CS42L56_ALC_RELEASE_RATE, 7, 1, 1), 4358c2ecf20Sopenharmony_ci SOC_SINGLE_RANGE("ALC Attack", CS42L56_ALC_EN_ATTACK_RATE, 4368c2ecf20Sopenharmony_ci 0, 0, 0x3f, 0), 4378c2ecf20Sopenharmony_ci SOC_SINGLE_RANGE("ALC Release", CS42L56_ALC_RELEASE_RATE, 4388c2ecf20Sopenharmony_ci 0, 0x3f, 0, 0), 4398c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("ALC MAX", CS42L56_ALC_THRESHOLD, 4408c2ecf20Sopenharmony_ci 5, 0x07, 1, alc_tlv), 4418c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("ALC MIN", CS42L56_ALC_THRESHOLD, 4428c2ecf20Sopenharmony_ci 2, 0x07, 1, alc_tlv), 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci SOC_SINGLE("Limiter Switch", CS42L56_LIM_CTL_RELEASE_RATE, 7, 1, 1), 4458c2ecf20Sopenharmony_ci SOC_SINGLE("Limit All Switch", CS42L56_LIM_CTL_RELEASE_RATE, 6, 1, 1), 4468c2ecf20Sopenharmony_ci SOC_SINGLE_RANGE("Limiter Attack", CS42L56_LIM_ATTACK_RATE, 4478c2ecf20Sopenharmony_ci 0, 0, 0x3f, 0), 4488c2ecf20Sopenharmony_ci SOC_SINGLE_RANGE("Limiter Release", CS42L56_LIM_CTL_RELEASE_RATE, 4498c2ecf20Sopenharmony_ci 0, 0x3f, 0, 0), 4508c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Limiter MAX", CS42L56_LIM_THRESHOLD_CTL, 4518c2ecf20Sopenharmony_ci 5, 0x07, 1, alc_tlv), 4528c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("Limiter Cushion", CS42L56_ALC_THRESHOLD, 4538c2ecf20Sopenharmony_ci 2, 0x07, 1, alc_tlv), 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci SOC_SINGLE("NG Switch", CS42L56_NOISE_GATE_CTL, 6, 1, 1), 4568c2ecf20Sopenharmony_ci SOC_SINGLE("NG All Switch", CS42L56_NOISE_GATE_CTL, 7, 1, 1), 4578c2ecf20Sopenharmony_ci SOC_SINGLE("NG Boost Switch", CS42L56_NOISE_GATE_CTL, 5, 1, 1), 4588c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("NG Unboost Threshold", CS42L56_NOISE_GATE_CTL, 4598c2ecf20Sopenharmony_ci 2, 0x07, 1, ngnb_tlv), 4608c2ecf20Sopenharmony_ci SOC_SINGLE_TLV("NG Boost Threshold", CS42L56_NOISE_GATE_CTL, 4618c2ecf20Sopenharmony_ci 2, 0x07, 1, ngb_tlv), 4628c2ecf20Sopenharmony_ci SOC_ENUM("NG Delay", ng_delay_enum), 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci SOC_ENUM("Beep Config", beep_config_enum), 4658c2ecf20Sopenharmony_ci SOC_ENUM("Beep Pitch", beep_pitch_enum), 4668c2ecf20Sopenharmony_ci SOC_ENUM("Beep on Time", beep_ontime_enum), 4678c2ecf20Sopenharmony_ci SOC_ENUM("Beep off Time", beep_offtime_enum), 4688c2ecf20Sopenharmony_ci SOC_SINGLE_SX_TLV("Beep Volume", CS42L56_BEEP_FREQ_OFFTIME, 4698c2ecf20Sopenharmony_ci 0, 0x07, 0x23, beep_tlv), 4708c2ecf20Sopenharmony_ci SOC_SINGLE("Beep Tone Ctl Switch", CS42L56_BEEP_TONE_CFG, 0, 1, 1), 4718c2ecf20Sopenharmony_ci SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum), 4728c2ecf20Sopenharmony_ci SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum), 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci}; 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = { 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci SND_SOC_DAPM_SIGGEN("Beep"), 4798c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("VBUF", CS42L56_PWRCTL_1, 5, 1, NULL, 0), 4808c2ecf20Sopenharmony_ci SND_SOC_DAPM_MICBIAS("MIC1 Bias", CS42L56_PWRCTL_1, 4, 1), 4818c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L56_PWRCTL_1, 3, 1, NULL, 0), 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("AIN1A"), 4848c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("AIN2A"), 4858c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("AIN1B"), 4868c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("AIN2B"), 4878c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("AIN3A"), 4888c2ecf20Sopenharmony_ci SND_SOC_DAPM_INPUT("AIN3B"), 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, 4918c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0), 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci SND_SOC_DAPM_AIF_IN("SDIN", NULL, 0, 4948c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0), 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("Digital Output Mux", SND_SOC_NOPM, 4978c2ecf20Sopenharmony_ci 0, 0, &dig_mux), 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("PGAA", SND_SOC_NOPM, 0, 0, NULL, 0), 5008c2ecf20Sopenharmony_ci SND_SOC_DAPM_PGA("PGAB", SND_SOC_NOPM, 0, 0, NULL, 0), 5018c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("PGAA Input Mux", 5028c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, &pgaa_mux), 5038c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("PGAB Input Mux", 5048c2ecf20Sopenharmony_ci SND_SOC_NOPM, 0, 0, &pgab_mux), 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("ADCA Mux", SND_SOC_NOPM, 5078c2ecf20Sopenharmony_ci 0, 0, &adca_mux), 5088c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("ADCB Mux", SND_SOC_NOPM, 5098c2ecf20Sopenharmony_ci 0, 0, &adcb_mux), 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1), 5128c2ecf20Sopenharmony_ci SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1), 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("ADCA Swap Mux", SND_SOC_NOPM, 0, 0, 5158c2ecf20Sopenharmony_ci &adca_swap_mux), 5168c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("ADCB Swap Mux", SND_SOC_NOPM, 0, 0, 5178c2ecf20Sopenharmony_ci &adcb_swap_mux), 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("PCMA Swap Mux", SND_SOC_NOPM, 0, 0, 5208c2ecf20Sopenharmony_ci &pcma_swap_mux), 5218c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("PCMB Swap Mux", SND_SOC_NOPM, 0, 0, 5228c2ecf20Sopenharmony_ci &pcmb_swap_mux), 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0), 5258c2ecf20Sopenharmony_ci SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0), 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPA"), 5288c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("LOA"), 5298c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPB"), 5308c2ecf20Sopenharmony_ci SND_SOC_DAPM_OUTPUT("LOB"), 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Headphone Right", 5338c2ecf20Sopenharmony_ci CS42L56_PWRCTL_2, 4, 1, &hpb_switch), 5348c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Headphone Left", 5358c2ecf20Sopenharmony_ci CS42L56_PWRCTL_2, 6, 1, &hpa_switch), 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Lineout Right", 5388c2ecf20Sopenharmony_ci CS42L56_PWRCTL_2, 0, 1, &lob_switch), 5398c2ecf20Sopenharmony_ci SND_SOC_DAPM_SWITCH("Lineout Left", 5408c2ecf20Sopenharmony_ci CS42L56_PWRCTL_2, 2, 1, &loa_switch), 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("LINEOUTA Input Mux", SND_SOC_NOPM, 5438c2ecf20Sopenharmony_ci 0, 0, &lineouta_input), 5448c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("LINEOUTB Input Mux", SND_SOC_NOPM, 5458c2ecf20Sopenharmony_ci 0, 0, &lineoutb_input), 5468c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("HPA Input Mux", SND_SOC_NOPM, 5478c2ecf20Sopenharmony_ci 0, 0, &hpa_input), 5488c2ecf20Sopenharmony_ci SND_SOC_DAPM_MUX("HPB Input Mux", SND_SOC_NOPM, 5498c2ecf20Sopenharmony_ci 0, 0, &hpb_input), 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci}; 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route cs42l56_audio_map[] = { 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci {"HiFi Capture", "DSP", "Digital Output Mux"}, 5568c2ecf20Sopenharmony_ci {"HiFi Capture", "ADC", "Digital Output Mux"}, 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci {"Digital Output Mux", NULL, "ADCA"}, 5598c2ecf20Sopenharmony_ci {"Digital Output Mux", NULL, "ADCB"}, 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci {"ADCB", NULL, "ADCB Swap Mux"}, 5628c2ecf20Sopenharmony_ci {"ADCA", NULL, "ADCA Swap Mux"}, 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci {"ADCA Swap Mux", NULL, "ADCA"}, 5658c2ecf20Sopenharmony_ci {"ADCB Swap Mux", NULL, "ADCB"}, 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_ci {"DACA", "Left", "ADCA Swap Mux"}, 5688c2ecf20Sopenharmony_ci {"DACA", "LR 2", "ADCA Swap Mux"}, 5698c2ecf20Sopenharmony_ci {"DACA", "Right", "ADCA Swap Mux"}, 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci {"DACB", "Left", "ADCB Swap Mux"}, 5728c2ecf20Sopenharmony_ci {"DACB", "LR 2", "ADCB Swap Mux"}, 5738c2ecf20Sopenharmony_ci {"DACB", "Right", "ADCB Swap Mux"}, 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci {"ADCA Mux", NULL, "AIN3A"}, 5768c2ecf20Sopenharmony_ci {"ADCA Mux", NULL, "AIN2A"}, 5778c2ecf20Sopenharmony_ci {"ADCA Mux", NULL, "AIN1A"}, 5788c2ecf20Sopenharmony_ci {"ADCA Mux", NULL, "PGAA"}, 5798c2ecf20Sopenharmony_ci {"ADCB Mux", NULL, "AIN3B"}, 5808c2ecf20Sopenharmony_ci {"ADCB Mux", NULL, "AIN2B"}, 5818c2ecf20Sopenharmony_ci {"ADCB Mux", NULL, "AIN1B"}, 5828c2ecf20Sopenharmony_ci {"ADCB Mux", NULL, "PGAB"}, 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci {"PGAA", "AIN1A", "PGAA Input Mux"}, 5858c2ecf20Sopenharmony_ci {"PGAA", "AIN2A", "PGAA Input Mux"}, 5868c2ecf20Sopenharmony_ci {"PGAA", "AIN3A", "PGAA Input Mux"}, 5878c2ecf20Sopenharmony_ci {"PGAB", "AIN1B", "PGAB Input Mux"}, 5888c2ecf20Sopenharmony_ci {"PGAB", "AIN2B", "PGAB Input Mux"}, 5898c2ecf20Sopenharmony_ci {"PGAB", "AIN3B", "PGAB Input Mux"}, 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci {"PGAA Input Mux", NULL, "AIN1A"}, 5928c2ecf20Sopenharmony_ci {"PGAA Input Mux", NULL, "AIN2A"}, 5938c2ecf20Sopenharmony_ci {"PGAA Input Mux", NULL, "AIN3A"}, 5948c2ecf20Sopenharmony_ci {"PGAB Input Mux", NULL, "AIN1B"}, 5958c2ecf20Sopenharmony_ci {"PGAB Input Mux", NULL, "AIN2B"}, 5968c2ecf20Sopenharmony_ci {"PGAB Input Mux", NULL, "AIN3B"}, 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci {"LOB", "Switch", "LINEOUTB Input Mux"}, 5998c2ecf20Sopenharmony_ci {"LOA", "Switch", "LINEOUTA Input Mux"}, 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci {"LINEOUTA Input Mux", "PGAA", "PGAA"}, 6028c2ecf20Sopenharmony_ci {"LINEOUTB Input Mux", "PGAB", "PGAB"}, 6038c2ecf20Sopenharmony_ci {"LINEOUTA Input Mux", "DACA", "DACA"}, 6048c2ecf20Sopenharmony_ci {"LINEOUTB Input Mux", "DACB", "DACB"}, 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci {"HPA", "Switch", "HPB Input Mux"}, 6078c2ecf20Sopenharmony_ci {"HPB", "Switch", "HPA Input Mux"}, 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci {"HPA Input Mux", "PGAA", "PGAA"}, 6108c2ecf20Sopenharmony_ci {"HPB Input Mux", "PGAB", "PGAB"}, 6118c2ecf20Sopenharmony_ci {"HPA Input Mux", "DACA", "DACA"}, 6128c2ecf20Sopenharmony_ci {"HPB Input Mux", "DACB", "DACB"}, 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci {"DACA", NULL, "PCMA Swap Mux"}, 6158c2ecf20Sopenharmony_ci {"DACB", NULL, "PCMB Swap Mux"}, 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci {"PCMB Swap Mux", "Left", "HiFi Playback"}, 6188c2ecf20Sopenharmony_ci {"PCMB Swap Mux", "LR 2", "HiFi Playback"}, 6198c2ecf20Sopenharmony_ci {"PCMB Swap Mux", "Right", "HiFi Playback"}, 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci {"PCMA Swap Mux", "Left", "HiFi Playback"}, 6228c2ecf20Sopenharmony_ci {"PCMA Swap Mux", "LR 2", "HiFi Playback"}, 6238c2ecf20Sopenharmony_ci {"PCMA Swap Mux", "Right", "HiFi Playback"}, 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci}; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_cistruct cs42l56_clk_para { 6288c2ecf20Sopenharmony_ci u32 mclk; 6298c2ecf20Sopenharmony_ci u32 srate; 6308c2ecf20Sopenharmony_ci u8 ratio; 6318c2ecf20Sopenharmony_ci}; 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_cistatic const struct cs42l56_clk_para clk_ratio_table[] = { 6348c2ecf20Sopenharmony_ci /* 8k */ 6358c2ecf20Sopenharmony_ci { 6000000, 8000, CS42L56_MCLK_LRCLK_768 }, 6368c2ecf20Sopenharmony_ci { 6144000, 8000, CS42L56_MCLK_LRCLK_750 }, 6378c2ecf20Sopenharmony_ci { 12000000, 8000, CS42L56_MCLK_LRCLK_768 }, 6388c2ecf20Sopenharmony_ci { 12288000, 8000, CS42L56_MCLK_LRCLK_750 }, 6398c2ecf20Sopenharmony_ci { 24000000, 8000, CS42L56_MCLK_LRCLK_768 }, 6408c2ecf20Sopenharmony_ci { 24576000, 8000, CS42L56_MCLK_LRCLK_750 }, 6418c2ecf20Sopenharmony_ci /* 11.025k */ 6428c2ecf20Sopenharmony_ci { 5644800, 11025, CS42L56_MCLK_LRCLK_512}, 6438c2ecf20Sopenharmony_ci { 11289600, 11025, CS42L56_MCLK_LRCLK_512}, 6448c2ecf20Sopenharmony_ci { 22579200, 11025, CS42L56_MCLK_LRCLK_512 }, 6458c2ecf20Sopenharmony_ci /* 11.0294k */ 6468c2ecf20Sopenharmony_ci { 6000000, 110294, CS42L56_MCLK_LRCLK_544 }, 6478c2ecf20Sopenharmony_ci { 12000000, 110294, CS42L56_MCLK_LRCLK_544 }, 6488c2ecf20Sopenharmony_ci { 24000000, 110294, CS42L56_MCLK_LRCLK_544 }, 6498c2ecf20Sopenharmony_ci /* 12k */ 6508c2ecf20Sopenharmony_ci { 6000000, 12000, CS42L56_MCLK_LRCLK_500 }, 6518c2ecf20Sopenharmony_ci { 6144000, 12000, CS42L56_MCLK_LRCLK_512 }, 6528c2ecf20Sopenharmony_ci { 12000000, 12000, CS42L56_MCLK_LRCLK_500 }, 6538c2ecf20Sopenharmony_ci { 12288000, 12000, CS42L56_MCLK_LRCLK_512 }, 6548c2ecf20Sopenharmony_ci { 24000000, 12000, CS42L56_MCLK_LRCLK_500 }, 6558c2ecf20Sopenharmony_ci { 24576000, 12000, CS42L56_MCLK_LRCLK_512 }, 6568c2ecf20Sopenharmony_ci /* 16k */ 6578c2ecf20Sopenharmony_ci { 6000000, 16000, CS42L56_MCLK_LRCLK_375 }, 6588c2ecf20Sopenharmony_ci { 6144000, 16000, CS42L56_MCLK_LRCLK_384 }, 6598c2ecf20Sopenharmony_ci { 12000000, 16000, CS42L56_MCLK_LRCLK_375 }, 6608c2ecf20Sopenharmony_ci { 12288000, 16000, CS42L56_MCLK_LRCLK_384 }, 6618c2ecf20Sopenharmony_ci { 24000000, 16000, CS42L56_MCLK_LRCLK_375 }, 6628c2ecf20Sopenharmony_ci { 24576000, 16000, CS42L56_MCLK_LRCLK_384 }, 6638c2ecf20Sopenharmony_ci /* 22.050k */ 6648c2ecf20Sopenharmony_ci { 5644800, 22050, CS42L56_MCLK_LRCLK_256 }, 6658c2ecf20Sopenharmony_ci { 11289600, 22050, CS42L56_MCLK_LRCLK_256 }, 6668c2ecf20Sopenharmony_ci { 22579200, 22050, CS42L56_MCLK_LRCLK_256 }, 6678c2ecf20Sopenharmony_ci /* 22.0588k */ 6688c2ecf20Sopenharmony_ci { 6000000, 220588, CS42L56_MCLK_LRCLK_272 }, 6698c2ecf20Sopenharmony_ci { 12000000, 220588, CS42L56_MCLK_LRCLK_272 }, 6708c2ecf20Sopenharmony_ci { 24000000, 220588, CS42L56_MCLK_LRCLK_272 }, 6718c2ecf20Sopenharmony_ci /* 24k */ 6728c2ecf20Sopenharmony_ci { 6000000, 24000, CS42L56_MCLK_LRCLK_250 }, 6738c2ecf20Sopenharmony_ci { 6144000, 24000, CS42L56_MCLK_LRCLK_256 }, 6748c2ecf20Sopenharmony_ci { 12000000, 24000, CS42L56_MCLK_LRCLK_250 }, 6758c2ecf20Sopenharmony_ci { 12288000, 24000, CS42L56_MCLK_LRCLK_256 }, 6768c2ecf20Sopenharmony_ci { 24000000, 24000, CS42L56_MCLK_LRCLK_250 }, 6778c2ecf20Sopenharmony_ci { 24576000, 24000, CS42L56_MCLK_LRCLK_256 }, 6788c2ecf20Sopenharmony_ci /* 32k */ 6798c2ecf20Sopenharmony_ci { 6000000, 32000, CS42L56_MCLK_LRCLK_187P5 }, 6808c2ecf20Sopenharmony_ci { 6144000, 32000, CS42L56_MCLK_LRCLK_192 }, 6818c2ecf20Sopenharmony_ci { 12000000, 32000, CS42L56_MCLK_LRCLK_187P5 }, 6828c2ecf20Sopenharmony_ci { 12288000, 32000, CS42L56_MCLK_LRCLK_192 }, 6838c2ecf20Sopenharmony_ci { 24000000, 32000, CS42L56_MCLK_LRCLK_187P5 }, 6848c2ecf20Sopenharmony_ci { 24576000, 32000, CS42L56_MCLK_LRCLK_192 }, 6858c2ecf20Sopenharmony_ci /* 44.118k */ 6868c2ecf20Sopenharmony_ci { 6000000, 44118, CS42L56_MCLK_LRCLK_136 }, 6878c2ecf20Sopenharmony_ci { 12000000, 44118, CS42L56_MCLK_LRCLK_136 }, 6888c2ecf20Sopenharmony_ci { 24000000, 44118, CS42L56_MCLK_LRCLK_136 }, 6898c2ecf20Sopenharmony_ci /* 44.1k */ 6908c2ecf20Sopenharmony_ci { 5644800, 44100, CS42L56_MCLK_LRCLK_128 }, 6918c2ecf20Sopenharmony_ci { 11289600, 44100, CS42L56_MCLK_LRCLK_128 }, 6928c2ecf20Sopenharmony_ci { 22579200, 44100, CS42L56_MCLK_LRCLK_128 }, 6938c2ecf20Sopenharmony_ci /* 48k */ 6948c2ecf20Sopenharmony_ci { 6000000, 48000, CS42L56_MCLK_LRCLK_125 }, 6958c2ecf20Sopenharmony_ci { 6144000, 48000, CS42L56_MCLK_LRCLK_128 }, 6968c2ecf20Sopenharmony_ci { 12000000, 48000, CS42L56_MCLK_LRCLK_125 }, 6978c2ecf20Sopenharmony_ci { 12288000, 48000, CS42L56_MCLK_LRCLK_128 }, 6988c2ecf20Sopenharmony_ci { 24000000, 48000, CS42L56_MCLK_LRCLK_125 }, 6998c2ecf20Sopenharmony_ci { 24576000, 48000, CS42L56_MCLK_LRCLK_128 }, 7008c2ecf20Sopenharmony_ci}; 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_cistatic int cs42l56_get_mclk_ratio(int mclk, int rate) 7038c2ecf20Sopenharmony_ci{ 7048c2ecf20Sopenharmony_ci int i; 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(clk_ratio_table); i++) { 7078c2ecf20Sopenharmony_ci if (clk_ratio_table[i].mclk == mclk && 7088c2ecf20Sopenharmony_ci clk_ratio_table[i].srate == rate) 7098c2ecf20Sopenharmony_ci return clk_ratio_table[i].ratio; 7108c2ecf20Sopenharmony_ci } 7118c2ecf20Sopenharmony_ci return -EINVAL; 7128c2ecf20Sopenharmony_ci} 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_cistatic int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai, 7158c2ecf20Sopenharmony_ci int clk_id, unsigned int freq, int dir) 7168c2ecf20Sopenharmony_ci{ 7178c2ecf20Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 7188c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci switch (freq) { 7218c2ecf20Sopenharmony_ci case CS42L56_MCLK_5P6448MHZ: 7228c2ecf20Sopenharmony_ci case CS42L56_MCLK_6MHZ: 7238c2ecf20Sopenharmony_ci case CS42L56_MCLK_6P144MHZ: 7248c2ecf20Sopenharmony_ci cs42l56->mclk_div2 = 0; 7258c2ecf20Sopenharmony_ci cs42l56->mclk_prediv = 0; 7268c2ecf20Sopenharmony_ci break; 7278c2ecf20Sopenharmony_ci case CS42L56_MCLK_11P2896MHZ: 7288c2ecf20Sopenharmony_ci case CS42L56_MCLK_12MHZ: 7298c2ecf20Sopenharmony_ci case CS42L56_MCLK_12P288MHZ: 7308c2ecf20Sopenharmony_ci cs42l56->mclk_div2 = CS42L56_MCLK_DIV2; 7318c2ecf20Sopenharmony_ci cs42l56->mclk_prediv = 0; 7328c2ecf20Sopenharmony_ci break; 7338c2ecf20Sopenharmony_ci case CS42L56_MCLK_22P5792MHZ: 7348c2ecf20Sopenharmony_ci case CS42L56_MCLK_24MHZ: 7358c2ecf20Sopenharmony_ci case CS42L56_MCLK_24P576MHZ: 7368c2ecf20Sopenharmony_ci cs42l56->mclk_div2 = CS42L56_MCLK_DIV2; 7378c2ecf20Sopenharmony_ci cs42l56->mclk_prediv = CS42L56_MCLK_PREDIV; 7388c2ecf20Sopenharmony_ci break; 7398c2ecf20Sopenharmony_ci default: 7408c2ecf20Sopenharmony_ci return -EINVAL; 7418c2ecf20Sopenharmony_ci } 7428c2ecf20Sopenharmony_ci cs42l56->mclk = freq; 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_CLKCTL_1, 7458c2ecf20Sopenharmony_ci CS42L56_MCLK_PREDIV_MASK, 7468c2ecf20Sopenharmony_ci cs42l56->mclk_prediv); 7478c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_CLKCTL_1, 7488c2ecf20Sopenharmony_ci CS42L56_MCLK_DIV2_MASK, 7498c2ecf20Sopenharmony_ci cs42l56->mclk_div2); 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci return 0; 7528c2ecf20Sopenharmony_ci} 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_cistatic int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 7558c2ecf20Sopenharmony_ci{ 7568c2ecf20Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 7578c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 7608c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_CBM_CFM: 7618c2ecf20Sopenharmony_ci cs42l56->iface = CS42L56_MASTER_MODE; 7628c2ecf20Sopenharmony_ci break; 7638c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_CBS_CFS: 7648c2ecf20Sopenharmony_ci cs42l56->iface = CS42L56_SLAVE_MODE; 7658c2ecf20Sopenharmony_ci break; 7668c2ecf20Sopenharmony_ci default: 7678c2ecf20Sopenharmony_ci return -EINVAL; 7688c2ecf20Sopenharmony_ci } 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_ci /* interface format */ 7718c2ecf20Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 7728c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_I2S: 7738c2ecf20Sopenharmony_ci cs42l56->iface_fmt = CS42L56_DIG_FMT_I2S; 7748c2ecf20Sopenharmony_ci break; 7758c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_LEFT_J: 7768c2ecf20Sopenharmony_ci cs42l56->iface_fmt = CS42L56_DIG_FMT_LEFT_J; 7778c2ecf20Sopenharmony_ci break; 7788c2ecf20Sopenharmony_ci default: 7798c2ecf20Sopenharmony_ci return -EINVAL; 7808c2ecf20Sopenharmony_ci } 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci /* sclk inversion */ 7838c2ecf20Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 7848c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_NB_NF: 7858c2ecf20Sopenharmony_ci cs42l56->iface_inv = 0; 7868c2ecf20Sopenharmony_ci break; 7878c2ecf20Sopenharmony_ci case SND_SOC_DAIFMT_IB_NF: 7888c2ecf20Sopenharmony_ci cs42l56->iface_inv = CS42L56_SCLK_INV; 7898c2ecf20Sopenharmony_ci break; 7908c2ecf20Sopenharmony_ci default: 7918c2ecf20Sopenharmony_ci return -EINVAL; 7928c2ecf20Sopenharmony_ci } 7938c2ecf20Sopenharmony_ci 7948c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_CLKCTL_1, 7958c2ecf20Sopenharmony_ci CS42L56_MS_MODE_MASK, cs42l56->iface); 7968c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_SERIAL_FMT, 7978c2ecf20Sopenharmony_ci CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt); 7988c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_CLKCTL_1, 7998c2ecf20Sopenharmony_ci CS42L56_SCLK_INV_MASK, cs42l56->iface_inv); 8008c2ecf20Sopenharmony_ci return 0; 8018c2ecf20Sopenharmony_ci} 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_cistatic int cs42l56_mute(struct snd_soc_dai *dai, int mute, int direction) 8048c2ecf20Sopenharmony_ci{ 8058c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ci if (mute) { 8088c2ecf20Sopenharmony_ci /* Hit the DSP Mixer first */ 8098c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL, 8108c2ecf20Sopenharmony_ci CS42L56_ADCAMIX_MUTE_MASK | 8118c2ecf20Sopenharmony_ci CS42L56_ADCBMIX_MUTE_MASK | 8128c2ecf20Sopenharmony_ci CS42L56_PCMAMIX_MUTE_MASK | 8138c2ecf20Sopenharmony_ci CS42L56_PCMBMIX_MUTE_MASK | 8148c2ecf20Sopenharmony_ci CS42L56_MSTB_MUTE_MASK | 8158c2ecf20Sopenharmony_ci CS42L56_MSTA_MUTE_MASK, 8168c2ecf20Sopenharmony_ci CS42L56_MUTE_ALL); 8178c2ecf20Sopenharmony_ci /* Mute ADC's */ 8188c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL, 8198c2ecf20Sopenharmony_ci CS42L56_ADCA_MUTE_MASK | 8208c2ecf20Sopenharmony_ci CS42L56_ADCB_MUTE_MASK, 8218c2ecf20Sopenharmony_ci CS42L56_MUTE_ALL); 8228c2ecf20Sopenharmony_ci /* HP And LO */ 8238c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME, 8248c2ecf20Sopenharmony_ci CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL); 8258c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME, 8268c2ecf20Sopenharmony_ci CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL); 8278c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME, 8288c2ecf20Sopenharmony_ci CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL); 8298c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME, 8308c2ecf20Sopenharmony_ci CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL); 8318c2ecf20Sopenharmony_ci } else { 8328c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL, 8338c2ecf20Sopenharmony_ci CS42L56_ADCAMIX_MUTE_MASK | 8348c2ecf20Sopenharmony_ci CS42L56_ADCBMIX_MUTE_MASK | 8358c2ecf20Sopenharmony_ci CS42L56_PCMAMIX_MUTE_MASK | 8368c2ecf20Sopenharmony_ci CS42L56_PCMBMIX_MUTE_MASK | 8378c2ecf20Sopenharmony_ci CS42L56_MSTB_MUTE_MASK | 8388c2ecf20Sopenharmony_ci CS42L56_MSTA_MUTE_MASK, 8398c2ecf20Sopenharmony_ci CS42L56_UNMUTE); 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL, 8428c2ecf20Sopenharmony_ci CS42L56_ADCA_MUTE_MASK | 8438c2ecf20Sopenharmony_ci CS42L56_ADCB_MUTE_MASK, 8448c2ecf20Sopenharmony_ci CS42L56_UNMUTE); 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME, 8478c2ecf20Sopenharmony_ci CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE); 8488c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME, 8498c2ecf20Sopenharmony_ci CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE); 8508c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME, 8518c2ecf20Sopenharmony_ci CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE); 8528c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME, 8538c2ecf20Sopenharmony_ci CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE); 8548c2ecf20Sopenharmony_ci } 8558c2ecf20Sopenharmony_ci return 0; 8568c2ecf20Sopenharmony_ci} 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_cistatic int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream, 8598c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params, 8608c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 8618c2ecf20Sopenharmony_ci{ 8628c2ecf20Sopenharmony_ci struct snd_soc_component *component = dai->component; 8638c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); 8648c2ecf20Sopenharmony_ci int ratio; 8658c2ecf20Sopenharmony_ci 8668c2ecf20Sopenharmony_ci ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params)); 8678c2ecf20Sopenharmony_ci if (ratio >= 0) { 8688c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_CLKCTL_2, 8698c2ecf20Sopenharmony_ci CS42L56_CLK_RATIO_MASK, ratio); 8708c2ecf20Sopenharmony_ci } else { 8718c2ecf20Sopenharmony_ci dev_err(component->dev, "unsupported mclk/sclk/lrclk ratio\n"); 8728c2ecf20Sopenharmony_ci return -EINVAL; 8738c2ecf20Sopenharmony_ci } 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci return 0; 8768c2ecf20Sopenharmony_ci} 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_cistatic int cs42l56_set_bias_level(struct snd_soc_component *component, 8798c2ecf20Sopenharmony_ci enum snd_soc_bias_level level) 8808c2ecf20Sopenharmony_ci{ 8818c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); 8828c2ecf20Sopenharmony_ci int ret; 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci switch (level) { 8858c2ecf20Sopenharmony_ci case SND_SOC_BIAS_ON: 8868c2ecf20Sopenharmony_ci break; 8878c2ecf20Sopenharmony_ci case SND_SOC_BIAS_PREPARE: 8888c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_CLKCTL_1, 8898c2ecf20Sopenharmony_ci CS42L56_MCLK_DIS_MASK, 0); 8908c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_PWRCTL_1, 8918c2ecf20Sopenharmony_ci CS42L56_PDN_ALL_MASK, 0); 8928c2ecf20Sopenharmony_ci break; 8938c2ecf20Sopenharmony_ci case SND_SOC_BIAS_STANDBY: 8948c2ecf20Sopenharmony_ci if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { 8958c2ecf20Sopenharmony_ci regcache_cache_only(cs42l56->regmap, false); 8968c2ecf20Sopenharmony_ci regcache_sync(cs42l56->regmap); 8978c2ecf20Sopenharmony_ci ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies), 8988c2ecf20Sopenharmony_ci cs42l56->supplies); 8998c2ecf20Sopenharmony_ci if (ret != 0) { 9008c2ecf20Sopenharmony_ci dev_err(cs42l56->dev, 9018c2ecf20Sopenharmony_ci "Failed to enable regulators: %d\n", 9028c2ecf20Sopenharmony_ci ret); 9038c2ecf20Sopenharmony_ci return ret; 9048c2ecf20Sopenharmony_ci } 9058c2ecf20Sopenharmony_ci } 9068c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_PWRCTL_1, 9078c2ecf20Sopenharmony_ci CS42L56_PDN_ALL_MASK, 1); 9088c2ecf20Sopenharmony_ci break; 9098c2ecf20Sopenharmony_ci case SND_SOC_BIAS_OFF: 9108c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_PWRCTL_1, 9118c2ecf20Sopenharmony_ci CS42L56_PDN_ALL_MASK, 1); 9128c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_CLKCTL_1, 9138c2ecf20Sopenharmony_ci CS42L56_MCLK_DIS_MASK, 1); 9148c2ecf20Sopenharmony_ci regcache_cache_only(cs42l56->regmap, true); 9158c2ecf20Sopenharmony_ci regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), 9168c2ecf20Sopenharmony_ci cs42l56->supplies); 9178c2ecf20Sopenharmony_ci break; 9188c2ecf20Sopenharmony_ci } 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_ci return 0; 9218c2ecf20Sopenharmony_ci} 9228c2ecf20Sopenharmony_ci 9238c2ecf20Sopenharmony_ci#define CS42L56_RATES (SNDRV_PCM_RATE_8000_48000) 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_ci#define CS42L56_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ 9268c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | \ 9278c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S32_LE) 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_cistatic const struct snd_soc_dai_ops cs42l56_ops = { 9318c2ecf20Sopenharmony_ci .hw_params = cs42l56_pcm_hw_params, 9328c2ecf20Sopenharmony_ci .mute_stream = cs42l56_mute, 9338c2ecf20Sopenharmony_ci .set_fmt = cs42l56_set_dai_fmt, 9348c2ecf20Sopenharmony_ci .set_sysclk = cs42l56_set_sysclk, 9358c2ecf20Sopenharmony_ci .no_capture_mute = 1, 9368c2ecf20Sopenharmony_ci}; 9378c2ecf20Sopenharmony_ci 9388c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver cs42l56_dai = { 9398c2ecf20Sopenharmony_ci .name = "cs42l56", 9408c2ecf20Sopenharmony_ci .playback = { 9418c2ecf20Sopenharmony_ci .stream_name = "HiFi Playback", 9428c2ecf20Sopenharmony_ci .channels_min = 1, 9438c2ecf20Sopenharmony_ci .channels_max = 2, 9448c2ecf20Sopenharmony_ci .rates = CS42L56_RATES, 9458c2ecf20Sopenharmony_ci .formats = CS42L56_FORMATS, 9468c2ecf20Sopenharmony_ci }, 9478c2ecf20Sopenharmony_ci .capture = { 9488c2ecf20Sopenharmony_ci .stream_name = "HiFi Capture", 9498c2ecf20Sopenharmony_ci .channels_min = 1, 9508c2ecf20Sopenharmony_ci .channels_max = 2, 9518c2ecf20Sopenharmony_ci .rates = CS42L56_RATES, 9528c2ecf20Sopenharmony_ci .formats = CS42L56_FORMATS, 9538c2ecf20Sopenharmony_ci }, 9548c2ecf20Sopenharmony_ci .ops = &cs42l56_ops, 9558c2ecf20Sopenharmony_ci}; 9568c2ecf20Sopenharmony_ci 9578c2ecf20Sopenharmony_cistatic int beep_freq[] = { 9588c2ecf20Sopenharmony_ci 261, 522, 585, 667, 706, 774, 889, 1000, 9598c2ecf20Sopenharmony_ci 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 9608c2ecf20Sopenharmony_ci}; 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_cistatic void cs42l56_beep_work(struct work_struct *work) 9638c2ecf20Sopenharmony_ci{ 9648c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = 9658c2ecf20Sopenharmony_ci container_of(work, struct cs42l56_private, beep_work); 9668c2ecf20Sopenharmony_ci struct snd_soc_component *component = cs42l56->component; 9678c2ecf20Sopenharmony_ci struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 9688c2ecf20Sopenharmony_ci int i; 9698c2ecf20Sopenharmony_ci int val = 0; 9708c2ecf20Sopenharmony_ci int best = 0; 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci if (cs42l56->beep_rate) { 9738c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(beep_freq); i++) { 9748c2ecf20Sopenharmony_ci if (abs(cs42l56->beep_rate - beep_freq[i]) < 9758c2ecf20Sopenharmony_ci abs(cs42l56->beep_rate - beep_freq[best])) 9768c2ecf20Sopenharmony_ci best = i; 9778c2ecf20Sopenharmony_ci } 9788c2ecf20Sopenharmony_ci 9798c2ecf20Sopenharmony_ci dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n", 9808c2ecf20Sopenharmony_ci beep_freq[best], cs42l56->beep_rate); 9818c2ecf20Sopenharmony_ci 9828c2ecf20Sopenharmony_ci val = (best << CS42L56_BEEP_RATE_SHIFT); 9838c2ecf20Sopenharmony_ci 9848c2ecf20Sopenharmony_ci snd_soc_dapm_enable_pin(dapm, "Beep"); 9858c2ecf20Sopenharmony_ci } else { 9868c2ecf20Sopenharmony_ci dev_dbg(component->dev, "Disabling beep\n"); 9878c2ecf20Sopenharmony_ci snd_soc_dapm_disable_pin(dapm, "Beep"); 9888c2ecf20Sopenharmony_ci } 9898c2ecf20Sopenharmony_ci 9908c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_BEEP_FREQ_ONTIME, 9918c2ecf20Sopenharmony_ci CS42L56_BEEP_FREQ_MASK, val); 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci snd_soc_dapm_sync(dapm); 9948c2ecf20Sopenharmony_ci} 9958c2ecf20Sopenharmony_ci 9968c2ecf20Sopenharmony_ci/* For usability define a way of injecting beep events for the device - 9978c2ecf20Sopenharmony_ci * many systems will not have a keyboard. 9988c2ecf20Sopenharmony_ci */ 9998c2ecf20Sopenharmony_cistatic int cs42l56_beep_event(struct input_dev *dev, unsigned int type, 10008c2ecf20Sopenharmony_ci unsigned int code, int hz) 10018c2ecf20Sopenharmony_ci{ 10028c2ecf20Sopenharmony_ci struct snd_soc_component *component = input_get_drvdata(dev); 10038c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); 10048c2ecf20Sopenharmony_ci 10058c2ecf20Sopenharmony_ci dev_dbg(component->dev, "Beep event %x %x\n", code, hz); 10068c2ecf20Sopenharmony_ci 10078c2ecf20Sopenharmony_ci switch (code) { 10088c2ecf20Sopenharmony_ci case SND_BELL: 10098c2ecf20Sopenharmony_ci if (hz) 10108c2ecf20Sopenharmony_ci hz = 261; 10118c2ecf20Sopenharmony_ci case SND_TONE: 10128c2ecf20Sopenharmony_ci break; 10138c2ecf20Sopenharmony_ci default: 10148c2ecf20Sopenharmony_ci return -1; 10158c2ecf20Sopenharmony_ci } 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_ci /* Kick the beep from a workqueue */ 10188c2ecf20Sopenharmony_ci cs42l56->beep_rate = hz; 10198c2ecf20Sopenharmony_ci schedule_work(&cs42l56->beep_work); 10208c2ecf20Sopenharmony_ci return 0; 10218c2ecf20Sopenharmony_ci} 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_cistatic ssize_t cs42l56_beep_set(struct device *dev, 10248c2ecf20Sopenharmony_ci struct device_attribute *attr, 10258c2ecf20Sopenharmony_ci const char *buf, size_t count) 10268c2ecf20Sopenharmony_ci{ 10278c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = dev_get_drvdata(dev); 10288c2ecf20Sopenharmony_ci long int time; 10298c2ecf20Sopenharmony_ci int ret; 10308c2ecf20Sopenharmony_ci 10318c2ecf20Sopenharmony_ci ret = kstrtol(buf, 10, &time); 10328c2ecf20Sopenharmony_ci if (ret != 0) 10338c2ecf20Sopenharmony_ci return ret; 10348c2ecf20Sopenharmony_ci 10358c2ecf20Sopenharmony_ci input_event(cs42l56->beep, EV_SND, SND_TONE, time); 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_ci return count; 10388c2ecf20Sopenharmony_ci} 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_cistatic DEVICE_ATTR(beep, 0200, NULL, cs42l56_beep_set); 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_cistatic void cs42l56_init_beep(struct snd_soc_component *component) 10438c2ecf20Sopenharmony_ci{ 10448c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); 10458c2ecf20Sopenharmony_ci int ret; 10468c2ecf20Sopenharmony_ci 10478c2ecf20Sopenharmony_ci cs42l56->beep = devm_input_allocate_device(component->dev); 10488c2ecf20Sopenharmony_ci if (!cs42l56->beep) { 10498c2ecf20Sopenharmony_ci dev_err(component->dev, "Failed to allocate beep device\n"); 10508c2ecf20Sopenharmony_ci return; 10518c2ecf20Sopenharmony_ci } 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci INIT_WORK(&cs42l56->beep_work, cs42l56_beep_work); 10548c2ecf20Sopenharmony_ci cs42l56->beep_rate = 0; 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_ci cs42l56->beep->name = "CS42L56 Beep Generator"; 10578c2ecf20Sopenharmony_ci cs42l56->beep->phys = dev_name(component->dev); 10588c2ecf20Sopenharmony_ci cs42l56->beep->id.bustype = BUS_I2C; 10598c2ecf20Sopenharmony_ci 10608c2ecf20Sopenharmony_ci cs42l56->beep->evbit[0] = BIT_MASK(EV_SND); 10618c2ecf20Sopenharmony_ci cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); 10628c2ecf20Sopenharmony_ci cs42l56->beep->event = cs42l56_beep_event; 10638c2ecf20Sopenharmony_ci cs42l56->beep->dev.parent = component->dev; 10648c2ecf20Sopenharmony_ci input_set_drvdata(cs42l56->beep, component); 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_ci ret = input_register_device(cs42l56->beep); 10678c2ecf20Sopenharmony_ci if (ret != 0) { 10688c2ecf20Sopenharmony_ci cs42l56->beep = NULL; 10698c2ecf20Sopenharmony_ci dev_err(component->dev, "Failed to register beep device\n"); 10708c2ecf20Sopenharmony_ci } 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_ci ret = device_create_file(component->dev, &dev_attr_beep); 10738c2ecf20Sopenharmony_ci if (ret != 0) { 10748c2ecf20Sopenharmony_ci dev_err(component->dev, "Failed to create keyclick file: %d\n", 10758c2ecf20Sopenharmony_ci ret); 10768c2ecf20Sopenharmony_ci } 10778c2ecf20Sopenharmony_ci} 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_cistatic void cs42l56_free_beep(struct snd_soc_component *component) 10808c2ecf20Sopenharmony_ci{ 10818c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); 10828c2ecf20Sopenharmony_ci 10838c2ecf20Sopenharmony_ci device_remove_file(component->dev, &dev_attr_beep); 10848c2ecf20Sopenharmony_ci cancel_work_sync(&cs42l56->beep_work); 10858c2ecf20Sopenharmony_ci cs42l56->beep = NULL; 10868c2ecf20Sopenharmony_ci 10878c2ecf20Sopenharmony_ci snd_soc_component_update_bits(component, CS42L56_BEEP_TONE_CFG, 10888c2ecf20Sopenharmony_ci CS42L56_BEEP_EN_MASK, 0); 10898c2ecf20Sopenharmony_ci} 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_cistatic int cs42l56_probe(struct snd_soc_component *component) 10928c2ecf20Sopenharmony_ci{ 10938c2ecf20Sopenharmony_ci cs42l56_init_beep(component); 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_ci return 0; 10968c2ecf20Sopenharmony_ci} 10978c2ecf20Sopenharmony_ci 10988c2ecf20Sopenharmony_cistatic void cs42l56_remove(struct snd_soc_component *component) 10998c2ecf20Sopenharmony_ci{ 11008c2ecf20Sopenharmony_ci cs42l56_free_beep(component); 11018c2ecf20Sopenharmony_ci} 11028c2ecf20Sopenharmony_ci 11038c2ecf20Sopenharmony_cistatic const struct snd_soc_component_driver soc_component_dev_cs42l56 = { 11048c2ecf20Sopenharmony_ci .probe = cs42l56_probe, 11058c2ecf20Sopenharmony_ci .remove = cs42l56_remove, 11068c2ecf20Sopenharmony_ci .set_bias_level = cs42l56_set_bias_level, 11078c2ecf20Sopenharmony_ci .controls = cs42l56_snd_controls, 11088c2ecf20Sopenharmony_ci .num_controls = ARRAY_SIZE(cs42l56_snd_controls), 11098c2ecf20Sopenharmony_ci .dapm_widgets = cs42l56_dapm_widgets, 11108c2ecf20Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), 11118c2ecf20Sopenharmony_ci .dapm_routes = cs42l56_audio_map, 11128c2ecf20Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map), 11138c2ecf20Sopenharmony_ci .suspend_bias_off = 1, 11148c2ecf20Sopenharmony_ci .idle_bias_on = 1, 11158c2ecf20Sopenharmony_ci .use_pmdown_time = 1, 11168c2ecf20Sopenharmony_ci .endianness = 1, 11178c2ecf20Sopenharmony_ci .non_legacy_dai_naming = 1, 11188c2ecf20Sopenharmony_ci}; 11198c2ecf20Sopenharmony_ci 11208c2ecf20Sopenharmony_cistatic const struct regmap_config cs42l56_regmap = { 11218c2ecf20Sopenharmony_ci .reg_bits = 8, 11228c2ecf20Sopenharmony_ci .val_bits = 8, 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ci .max_register = CS42L56_MAX_REGISTER, 11258c2ecf20Sopenharmony_ci .reg_defaults = cs42l56_reg_defaults, 11268c2ecf20Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(cs42l56_reg_defaults), 11278c2ecf20Sopenharmony_ci .readable_reg = cs42l56_readable_register, 11288c2ecf20Sopenharmony_ci .volatile_reg = cs42l56_volatile_register, 11298c2ecf20Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 11308c2ecf20Sopenharmony_ci}; 11318c2ecf20Sopenharmony_ci 11328c2ecf20Sopenharmony_cistatic int cs42l56_handle_of_data(struct i2c_client *i2c_client, 11338c2ecf20Sopenharmony_ci struct cs42l56_platform_data *pdata) 11348c2ecf20Sopenharmony_ci{ 11358c2ecf20Sopenharmony_ci struct device_node *np = i2c_client->dev.of_node; 11368c2ecf20Sopenharmony_ci u32 val32; 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_ci if (of_property_read_bool(np, "cirrus,ain1a-reference-cfg")) 11398c2ecf20Sopenharmony_ci pdata->ain1a_ref_cfg = true; 11408c2ecf20Sopenharmony_ci 11418c2ecf20Sopenharmony_ci if (of_property_read_bool(np, "cirrus,ain2a-reference-cfg")) 11428c2ecf20Sopenharmony_ci pdata->ain2a_ref_cfg = true; 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_ci if (of_property_read_bool(np, "cirrus,ain1b-reference-cfg")) 11458c2ecf20Sopenharmony_ci pdata->ain1b_ref_cfg = true; 11468c2ecf20Sopenharmony_ci 11478c2ecf20Sopenharmony_ci if (of_property_read_bool(np, "cirrus,ain2b-reference-cfg")) 11488c2ecf20Sopenharmony_ci pdata->ain2b_ref_cfg = true; 11498c2ecf20Sopenharmony_ci 11508c2ecf20Sopenharmony_ci if (of_property_read_u32(np, "cirrus,micbias-lvl", &val32) >= 0) 11518c2ecf20Sopenharmony_ci pdata->micbias_lvl = val32; 11528c2ecf20Sopenharmony_ci 11538c2ecf20Sopenharmony_ci if (of_property_read_u32(np, "cirrus,chgfreq-divisor", &val32) >= 0) 11548c2ecf20Sopenharmony_ci pdata->chgfreq = val32; 11558c2ecf20Sopenharmony_ci 11568c2ecf20Sopenharmony_ci if (of_property_read_u32(np, "cirrus,adaptive-pwr-cfg", &val32) >= 0) 11578c2ecf20Sopenharmony_ci pdata->adaptive_pwr = val32; 11588c2ecf20Sopenharmony_ci 11598c2ecf20Sopenharmony_ci if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0) 11608c2ecf20Sopenharmony_ci pdata->hpfa_freq = val32; 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0) 11638c2ecf20Sopenharmony_ci pdata->hpfb_freq = val32; 11648c2ecf20Sopenharmony_ci 11658c2ecf20Sopenharmony_ci pdata->gpio_nreset = of_get_named_gpio(np, "cirrus,gpio-nreset", 0); 11668c2ecf20Sopenharmony_ci 11678c2ecf20Sopenharmony_ci return 0; 11688c2ecf20Sopenharmony_ci} 11698c2ecf20Sopenharmony_ci 11708c2ecf20Sopenharmony_cistatic int cs42l56_i2c_probe(struct i2c_client *i2c_client, 11718c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 11728c2ecf20Sopenharmony_ci{ 11738c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56; 11748c2ecf20Sopenharmony_ci struct cs42l56_platform_data *pdata = 11758c2ecf20Sopenharmony_ci dev_get_platdata(&i2c_client->dev); 11768c2ecf20Sopenharmony_ci int ret, i; 11778c2ecf20Sopenharmony_ci unsigned int devid = 0; 11788c2ecf20Sopenharmony_ci unsigned int alpha_rev, metal_rev; 11798c2ecf20Sopenharmony_ci unsigned int reg; 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_ci cs42l56 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l56), GFP_KERNEL); 11828c2ecf20Sopenharmony_ci if (cs42l56 == NULL) 11838c2ecf20Sopenharmony_ci return -ENOMEM; 11848c2ecf20Sopenharmony_ci cs42l56->dev = &i2c_client->dev; 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci cs42l56->regmap = devm_regmap_init_i2c(i2c_client, &cs42l56_regmap); 11878c2ecf20Sopenharmony_ci if (IS_ERR(cs42l56->regmap)) { 11888c2ecf20Sopenharmony_ci ret = PTR_ERR(cs42l56->regmap); 11898c2ecf20Sopenharmony_ci dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); 11908c2ecf20Sopenharmony_ci return ret; 11918c2ecf20Sopenharmony_ci } 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_ci if (pdata) { 11948c2ecf20Sopenharmony_ci cs42l56->pdata = *pdata; 11958c2ecf20Sopenharmony_ci } else { 11968c2ecf20Sopenharmony_ci if (i2c_client->dev.of_node) { 11978c2ecf20Sopenharmony_ci ret = cs42l56_handle_of_data(i2c_client, 11988c2ecf20Sopenharmony_ci &cs42l56->pdata); 11998c2ecf20Sopenharmony_ci if (ret != 0) 12008c2ecf20Sopenharmony_ci return ret; 12018c2ecf20Sopenharmony_ci } 12028c2ecf20Sopenharmony_ci } 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci if (cs42l56->pdata.gpio_nreset) { 12058c2ecf20Sopenharmony_ci ret = gpio_request_one(cs42l56->pdata.gpio_nreset, 12068c2ecf20Sopenharmony_ci GPIOF_OUT_INIT_HIGH, "CS42L56 /RST"); 12078c2ecf20Sopenharmony_ci if (ret < 0) { 12088c2ecf20Sopenharmony_ci dev_err(&i2c_client->dev, 12098c2ecf20Sopenharmony_ci "Failed to request /RST %d: %d\n", 12108c2ecf20Sopenharmony_ci cs42l56->pdata.gpio_nreset, ret); 12118c2ecf20Sopenharmony_ci return ret; 12128c2ecf20Sopenharmony_ci } 12138c2ecf20Sopenharmony_ci gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 0); 12148c2ecf20Sopenharmony_ci gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 1); 12158c2ecf20Sopenharmony_ci } 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ci i2c_set_clientdata(i2c_client, cs42l56); 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(cs42l56->supplies); i++) 12218c2ecf20Sopenharmony_ci cs42l56->supplies[i].supply = cs42l56_supply_names[i]; 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_ci ret = devm_regulator_bulk_get(&i2c_client->dev, 12248c2ecf20Sopenharmony_ci ARRAY_SIZE(cs42l56->supplies), 12258c2ecf20Sopenharmony_ci cs42l56->supplies); 12268c2ecf20Sopenharmony_ci if (ret != 0) { 12278c2ecf20Sopenharmony_ci dev_err(&i2c_client->dev, 12288c2ecf20Sopenharmony_ci "Failed to request supplies: %d\n", ret); 12298c2ecf20Sopenharmony_ci return ret; 12308c2ecf20Sopenharmony_ci } 12318c2ecf20Sopenharmony_ci 12328c2ecf20Sopenharmony_ci ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies), 12338c2ecf20Sopenharmony_ci cs42l56->supplies); 12348c2ecf20Sopenharmony_ci if (ret != 0) { 12358c2ecf20Sopenharmony_ci dev_err(&i2c_client->dev, 12368c2ecf20Sopenharmony_ci "Failed to enable supplies: %d\n", ret); 12378c2ecf20Sopenharmony_ci return ret; 12388c2ecf20Sopenharmony_ci } 12398c2ecf20Sopenharmony_ci 12408c2ecf20Sopenharmony_ci ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, ®); 12418c2ecf20Sopenharmony_ci devid = reg & CS42L56_CHIP_ID_MASK; 12428c2ecf20Sopenharmony_ci if (devid != CS42L56_DEVID) { 12438c2ecf20Sopenharmony_ci dev_err(&i2c_client->dev, 12448c2ecf20Sopenharmony_ci "CS42L56 Device ID (%X). Expected %X\n", 12458c2ecf20Sopenharmony_ci devid, CS42L56_DEVID); 12468c2ecf20Sopenharmony_ci ret = -EINVAL; 12478c2ecf20Sopenharmony_ci goto err_enable; 12488c2ecf20Sopenharmony_ci } 12498c2ecf20Sopenharmony_ci alpha_rev = reg & CS42L56_AREV_MASK; 12508c2ecf20Sopenharmony_ci metal_rev = reg & CS42L56_MTLREV_MASK; 12518c2ecf20Sopenharmony_ci 12528c2ecf20Sopenharmony_ci dev_info(&i2c_client->dev, "Cirrus Logic CS42L56 "); 12538c2ecf20Sopenharmony_ci dev_info(&i2c_client->dev, "Alpha Rev %X Metal Rev %X\n", 12548c2ecf20Sopenharmony_ci alpha_rev, metal_rev); 12558c2ecf20Sopenharmony_ci 12568c2ecf20Sopenharmony_ci if (cs42l56->pdata.ain1a_ref_cfg) 12578c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, 12588c2ecf20Sopenharmony_ci CS42L56_AIN1A_REF_MASK, 12598c2ecf20Sopenharmony_ci CS42L56_AIN1A_REF_MASK); 12608c2ecf20Sopenharmony_ci 12618c2ecf20Sopenharmony_ci if (cs42l56->pdata.ain1b_ref_cfg) 12628c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, 12638c2ecf20Sopenharmony_ci CS42L56_AIN1B_REF_MASK, 12648c2ecf20Sopenharmony_ci CS42L56_AIN1B_REF_MASK); 12658c2ecf20Sopenharmony_ci 12668c2ecf20Sopenharmony_ci if (cs42l56->pdata.ain2a_ref_cfg) 12678c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, 12688c2ecf20Sopenharmony_ci CS42L56_AIN2A_REF_MASK, 12698c2ecf20Sopenharmony_ci CS42L56_AIN2A_REF_MASK); 12708c2ecf20Sopenharmony_ci 12718c2ecf20Sopenharmony_ci if (cs42l56->pdata.ain2b_ref_cfg) 12728c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, 12738c2ecf20Sopenharmony_ci CS42L56_AIN2B_REF_MASK, 12748c2ecf20Sopenharmony_ci CS42L56_AIN2B_REF_MASK); 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_ci if (cs42l56->pdata.micbias_lvl) 12778c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_GAIN_BIAS_CTL, 12788c2ecf20Sopenharmony_ci CS42L56_MIC_BIAS_MASK, 12798c2ecf20Sopenharmony_ci cs42l56->pdata.micbias_lvl); 12808c2ecf20Sopenharmony_ci 12818c2ecf20Sopenharmony_ci if (cs42l56->pdata.chgfreq) 12828c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL, 12838c2ecf20Sopenharmony_ci CS42L56_CHRG_FREQ_MASK, 12848c2ecf20Sopenharmony_ci cs42l56->pdata.chgfreq); 12858c2ecf20Sopenharmony_ci 12868c2ecf20Sopenharmony_ci if (cs42l56->pdata.hpfb_freq) 12878c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL, 12888c2ecf20Sopenharmony_ci CS42L56_HPFB_FREQ_MASK, 12898c2ecf20Sopenharmony_ci cs42l56->pdata.hpfb_freq); 12908c2ecf20Sopenharmony_ci 12918c2ecf20Sopenharmony_ci if (cs42l56->pdata.hpfa_freq) 12928c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL, 12938c2ecf20Sopenharmony_ci CS42L56_HPFA_FREQ_MASK, 12948c2ecf20Sopenharmony_ci cs42l56->pdata.hpfa_freq); 12958c2ecf20Sopenharmony_ci 12968c2ecf20Sopenharmony_ci if (cs42l56->pdata.adaptive_pwr) 12978c2ecf20Sopenharmony_ci regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL, 12988c2ecf20Sopenharmony_ci CS42L56_ADAPT_PWR_MASK, 12998c2ecf20Sopenharmony_ci cs42l56->pdata.adaptive_pwr); 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_ci ret = devm_snd_soc_register_component(&i2c_client->dev, 13028c2ecf20Sopenharmony_ci &soc_component_dev_cs42l56, &cs42l56_dai, 1); 13038c2ecf20Sopenharmony_ci if (ret < 0) 13048c2ecf20Sopenharmony_ci goto err_enable; 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_ci return 0; 13078c2ecf20Sopenharmony_ci 13088c2ecf20Sopenharmony_cierr_enable: 13098c2ecf20Sopenharmony_ci regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), 13108c2ecf20Sopenharmony_ci cs42l56->supplies); 13118c2ecf20Sopenharmony_ci return ret; 13128c2ecf20Sopenharmony_ci} 13138c2ecf20Sopenharmony_ci 13148c2ecf20Sopenharmony_cistatic int cs42l56_i2c_remove(struct i2c_client *client) 13158c2ecf20Sopenharmony_ci{ 13168c2ecf20Sopenharmony_ci struct cs42l56_private *cs42l56 = i2c_get_clientdata(client); 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), 13198c2ecf20Sopenharmony_ci cs42l56->supplies); 13208c2ecf20Sopenharmony_ci return 0; 13218c2ecf20Sopenharmony_ci} 13228c2ecf20Sopenharmony_ci 13238c2ecf20Sopenharmony_cistatic const struct of_device_id cs42l56_of_match[] = { 13248c2ecf20Sopenharmony_ci { .compatible = "cirrus,cs42l56", }, 13258c2ecf20Sopenharmony_ci { } 13268c2ecf20Sopenharmony_ci}; 13278c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, cs42l56_of_match); 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_ci 13308c2ecf20Sopenharmony_cistatic const struct i2c_device_id cs42l56_id[] = { 13318c2ecf20Sopenharmony_ci { "cs42l56", 0 }, 13328c2ecf20Sopenharmony_ci { } 13338c2ecf20Sopenharmony_ci}; 13348c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, cs42l56_id); 13358c2ecf20Sopenharmony_ci 13368c2ecf20Sopenharmony_cistatic struct i2c_driver cs42l56_i2c_driver = { 13378c2ecf20Sopenharmony_ci .driver = { 13388c2ecf20Sopenharmony_ci .name = "cs42l56", 13398c2ecf20Sopenharmony_ci .of_match_table = cs42l56_of_match, 13408c2ecf20Sopenharmony_ci }, 13418c2ecf20Sopenharmony_ci .id_table = cs42l56_id, 13428c2ecf20Sopenharmony_ci .probe = cs42l56_i2c_probe, 13438c2ecf20Sopenharmony_ci .remove = cs42l56_i2c_remove, 13448c2ecf20Sopenharmony_ci}; 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_cimodule_i2c_driver(cs42l56_i2c_driver); 13478c2ecf20Sopenharmony_ci 13488c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("ASoC CS42L56 driver"); 13498c2ecf20Sopenharmony_ciMODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); 13508c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 1351