162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci* alc5632.c -- ALC5632 ALSA SoC Audio Codec 462306a36Sopenharmony_ci* 562306a36Sopenharmony_ci* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> 662306a36Sopenharmony_ci* 762306a36Sopenharmony_ci* Authors: Leon Romanovsky <leon@leon.nu> 862306a36Sopenharmony_ci* Andrey Danin <danindrey@mail.ru> 962306a36Sopenharmony_ci* Ilya Petrov <ilya.muromec@gmail.com> 1062306a36Sopenharmony_ci* Marc Dietrich <marvin24@gmx.de> 1162306a36Sopenharmony_ci* 1262306a36Sopenharmony_ci* Based on alc5623.c by Arnaud Patard 1362306a36Sopenharmony_ci*/ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/module.h> 1662306a36Sopenharmony_ci#include <linux/kernel.h> 1762306a36Sopenharmony_ci#include <linux/init.h> 1862306a36Sopenharmony_ci#include <linux/delay.h> 1962306a36Sopenharmony_ci#include <linux/pm.h> 2062306a36Sopenharmony_ci#include <linux/i2c.h> 2162306a36Sopenharmony_ci#include <linux/slab.h> 2262306a36Sopenharmony_ci#include <linux/regmap.h> 2362306a36Sopenharmony_ci#include <sound/core.h> 2462306a36Sopenharmony_ci#include <sound/pcm.h> 2562306a36Sopenharmony_ci#include <sound/pcm_params.h> 2662306a36Sopenharmony_ci#include <sound/tlv.h> 2762306a36Sopenharmony_ci#include <sound/soc.h> 2862306a36Sopenharmony_ci#include <sound/initval.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include "alc5632.h" 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 3362306a36Sopenharmony_ci * ALC5632 register cache 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_cistatic const struct reg_default alc5632_reg_defaults[] = { 3662306a36Sopenharmony_ci { 2, 0x8080 }, /* R2 - Speaker Output Volume */ 3762306a36Sopenharmony_ci { 4, 0x8080 }, /* R4 - Headphone Output Volume */ 3862306a36Sopenharmony_ci { 6, 0x8080 }, /* R6 - AUXOUT Volume */ 3962306a36Sopenharmony_ci { 8, 0xC800 }, /* R8 - Phone Input */ 4062306a36Sopenharmony_ci { 10, 0xE808 }, /* R10 - LINE_IN Volume */ 4162306a36Sopenharmony_ci { 12, 0x1010 }, /* R12 - STEREO DAC Input Volume */ 4262306a36Sopenharmony_ci { 14, 0x0808 }, /* R14 - MIC Input Volume */ 4362306a36Sopenharmony_ci { 16, 0xEE0F }, /* R16 - Stereo DAC and MIC Routing Control */ 4462306a36Sopenharmony_ci { 18, 0xCBCB }, /* R18 - ADC Record Gain */ 4562306a36Sopenharmony_ci { 20, 0x7F7F }, /* R20 - ADC Record Mixer Control */ 4662306a36Sopenharmony_ci { 24, 0xE010 }, /* R24 - Voice DAC Volume */ 4762306a36Sopenharmony_ci { 28, 0x8008 }, /* R28 - Output Mixer Control */ 4862306a36Sopenharmony_ci { 34, 0x0000 }, /* R34 - Microphone Control */ 4962306a36Sopenharmony_ci { 36, 0x00C0 }, /* R36 - Codec Digital MIC/Digital Boost 5062306a36Sopenharmony_ci Control */ 5162306a36Sopenharmony_ci { 46, 0x0000 }, /* R46 - Stereo DAC/Voice DAC/Stereo ADC 5262306a36Sopenharmony_ci Function Select */ 5362306a36Sopenharmony_ci { 52, 0x8000 }, /* R52 - Main Serial Data Port Control 5462306a36Sopenharmony_ci (Stereo I2S) */ 5562306a36Sopenharmony_ci { 54, 0x0000 }, /* R54 - Extend Serial Data Port Control 5662306a36Sopenharmony_ci (VoDAC_I2S/PCM) */ 5762306a36Sopenharmony_ci { 58, 0x0000 }, /* R58 - Power Management Addition 1 */ 5862306a36Sopenharmony_ci { 60, 0x0000 }, /* R60 - Power Management Addition 2 */ 5962306a36Sopenharmony_ci { 62, 0x8000 }, /* R62 - Power Management Addition 3 */ 6062306a36Sopenharmony_ci { 64, 0x0C0A }, /* R64 - General Purpose Control Register 1 */ 6162306a36Sopenharmony_ci { 66, 0x0000 }, /* R66 - General Purpose Control Register 2 */ 6262306a36Sopenharmony_ci { 68, 0x0000 }, /* R68 - PLL1 Control */ 6362306a36Sopenharmony_ci { 70, 0x0000 }, /* R70 - PLL2 Control */ 6462306a36Sopenharmony_ci { 76, 0xBE3E }, /* R76 - GPIO Pin Configuration */ 6562306a36Sopenharmony_ci { 78, 0xBE3E }, /* R78 - GPIO Pin Polarity */ 6662306a36Sopenharmony_ci { 80, 0x0000 }, /* R80 - GPIO Pin Sticky */ 6762306a36Sopenharmony_ci { 82, 0x0000 }, /* R82 - GPIO Pin Wake Up */ 6862306a36Sopenharmony_ci { 86, 0x0000 }, /* R86 - Pin Sharing */ 6962306a36Sopenharmony_ci { 90, 0x0009 }, /* R90 - Soft Volume Control Setting */ 7062306a36Sopenharmony_ci { 92, 0x0000 }, /* R92 - GPIO_Output Pin Control */ 7162306a36Sopenharmony_ci { 94, 0x3000 }, /* R94 - MISC Control */ 7262306a36Sopenharmony_ci { 96, 0x3075 }, /* R96 - Stereo DAC Clock Control_1 */ 7362306a36Sopenharmony_ci { 98, 0x1010 }, /* R98 - Stereo DAC Clock Control_2 */ 7462306a36Sopenharmony_ci { 100, 0x3110 }, /* R100 - VoDAC_PCM Clock Control_1 */ 7562306a36Sopenharmony_ci { 104, 0x0553 }, /* R104 - Pseudo Stereo and Spatial Effect 7662306a36Sopenharmony_ci Block Control */ 7762306a36Sopenharmony_ci { 106, 0x0000 }, /* R106 - Private Register Address */ 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci/* codec private data */ 8162306a36Sopenharmony_cistruct alc5632_priv { 8262306a36Sopenharmony_ci struct regmap *regmap; 8362306a36Sopenharmony_ci u8 id; 8462306a36Sopenharmony_ci unsigned int sysclk; 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic bool alc5632_volatile_register(struct device *dev, 8862306a36Sopenharmony_ci unsigned int reg) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci switch (reg) { 9162306a36Sopenharmony_ci case ALC5632_RESET: 9262306a36Sopenharmony_ci case ALC5632_PWR_DOWN_CTRL_STATUS: 9362306a36Sopenharmony_ci case ALC5632_GPIO_PIN_STATUS: 9462306a36Sopenharmony_ci case ALC5632_OVER_CURR_STATUS: 9562306a36Sopenharmony_ci case ALC5632_HID_CTRL_DATA: 9662306a36Sopenharmony_ci case ALC5632_EQ_CTRL: 9762306a36Sopenharmony_ci case ALC5632_VENDOR_ID1: 9862306a36Sopenharmony_ci case ALC5632_VENDOR_ID2: 9962306a36Sopenharmony_ci return true; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci default: 10262306a36Sopenharmony_ci break; 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci return false; 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic inline int alc5632_reset(struct regmap *map) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci return regmap_write(map, ALC5632_RESET, 0x59B4); 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_cistatic int amp_mixer_event(struct snd_soc_dapm_widget *w, 11462306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci /* to power-on/off class-d amp generators/speaker */ 11962306a36Sopenharmony_ci /* need to write to 'index-46h' register : */ 12062306a36Sopenharmony_ci /* so write index num (here 0x46) to reg 0x6a */ 12162306a36Sopenharmony_ci /* and then 0xffff/0 to reg 0x6c */ 12262306a36Sopenharmony_ci snd_soc_component_write(component, ALC5632_HID_CTRL_INDEX, 0x46); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci switch (event) { 12562306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMU: 12662306a36Sopenharmony_ci snd_soc_component_write(component, ALC5632_HID_CTRL_DATA, 0xFFFF); 12762306a36Sopenharmony_ci break; 12862306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMD: 12962306a36Sopenharmony_ci snd_soc_component_write(component, ALC5632_HID_CTRL_DATA, 0); 13062306a36Sopenharmony_ci break; 13162306a36Sopenharmony_ci } 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci return 0; 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci/* 13762306a36Sopenharmony_ci * ALC5632 Controls 13862306a36Sopenharmony_ci */ 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci/* -34.5db min scale, 1.5db steps, no mute */ 14162306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0); 14262306a36Sopenharmony_ci/* -46.5db min scale, 1.5db steps, no mute */ 14362306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0); 14462306a36Sopenharmony_ci/* -16.5db min scale, 1.5db steps, no mute */ 14562306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); 14662306a36Sopenharmony_cistatic const DECLARE_TLV_DB_RANGE(boost_tlv, 14762306a36Sopenharmony_ci 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), 14862306a36Sopenharmony_ci 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0) 14962306a36Sopenharmony_ci); 15062306a36Sopenharmony_ci/* 0db min scale, 6 db steps, no mute */ 15162306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); 15262306a36Sopenharmony_ci/* 0db min scalem 0.75db steps, no mute */ 15362306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_vol_snd_controls[] = { 15662306a36Sopenharmony_ci /* left starts at bit 8, right at bit 0 */ 15762306a36Sopenharmony_ci /* 31 steps (5 bit), -46.5db scale */ 15862306a36Sopenharmony_ci SOC_DOUBLE_TLV("Speaker Playback Volume", 15962306a36Sopenharmony_ci ALC5632_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), 16062306a36Sopenharmony_ci /* bit 15 mutes left, bit 7 right */ 16162306a36Sopenharmony_ci SOC_DOUBLE("Speaker Playback Switch", 16262306a36Sopenharmony_ci ALC5632_SPK_OUT_VOL, 15, 7, 1, 1), 16362306a36Sopenharmony_ci SOC_DOUBLE_TLV("Headphone Playback Volume", 16462306a36Sopenharmony_ci ALC5632_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), 16562306a36Sopenharmony_ci SOC_DOUBLE("Headphone Playback Switch", 16662306a36Sopenharmony_ci ALC5632_HP_OUT_VOL, 15, 7, 1, 1), 16762306a36Sopenharmony_ci}; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_snd_controls[] = { 17062306a36Sopenharmony_ci SOC_DOUBLE_TLV("Auxout Playback Volume", 17162306a36Sopenharmony_ci ALC5632_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv), 17262306a36Sopenharmony_ci SOC_DOUBLE("Auxout Playback Switch", 17362306a36Sopenharmony_ci ALC5632_AUX_OUT_VOL, 15, 7, 1, 1), 17462306a36Sopenharmony_ci SOC_SINGLE_TLV("Voice DAC Playback Volume", 17562306a36Sopenharmony_ci ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv), 17662306a36Sopenharmony_ci SOC_SINGLE("Voice DAC Playback Switch", 17762306a36Sopenharmony_ci ALC5632_VOICE_DAC_VOL, 12, 1, 1), 17862306a36Sopenharmony_ci SOC_SINGLE_TLV("Phone Playback Volume", 17962306a36Sopenharmony_ci ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv), 18062306a36Sopenharmony_ci SOC_DOUBLE_TLV("LineIn Playback Volume", 18162306a36Sopenharmony_ci ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), 18262306a36Sopenharmony_ci SOC_DOUBLE_TLV("Master Playback Volume", 18362306a36Sopenharmony_ci ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv), 18462306a36Sopenharmony_ci SOC_DOUBLE("Master Playback Switch", 18562306a36Sopenharmony_ci ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1), 18662306a36Sopenharmony_ci SOC_SINGLE_TLV("Mic1 Playback Volume", 18762306a36Sopenharmony_ci ALC5632_MIC_VOL, 8, 31, 1, vol_tlv), 18862306a36Sopenharmony_ci SOC_SINGLE_TLV("Mic2 Playback Volume", 18962306a36Sopenharmony_ci ALC5632_MIC_VOL, 0, 31, 1, vol_tlv), 19062306a36Sopenharmony_ci SOC_DOUBLE_TLV("Rec Capture Volume", 19162306a36Sopenharmony_ci ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv), 19262306a36Sopenharmony_ci SOC_SINGLE_TLV("Mic 1 Boost Volume", 19362306a36Sopenharmony_ci ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv), 19462306a36Sopenharmony_ci SOC_SINGLE_TLV("Mic 2 Boost Volume", 19562306a36Sopenharmony_ci ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv), 19662306a36Sopenharmony_ci SOC_SINGLE_TLV("DMIC Boost Capture Volume", 19762306a36Sopenharmony_ci ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv), 19862306a36Sopenharmony_ci SOC_SINGLE("DMIC En Capture Switch", 19962306a36Sopenharmony_ci ALC5632_DIGI_BOOST_CTRL, 15, 1, 0), 20062306a36Sopenharmony_ci SOC_SINGLE("DMIC PreFilter Capture Switch", 20162306a36Sopenharmony_ci ALC5632_DIGI_BOOST_CTRL, 12, 1, 0), 20262306a36Sopenharmony_ci}; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci/* 20562306a36Sopenharmony_ci * DAPM Controls 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_hp_mixer_controls[] = { 20862306a36Sopenharmony_ciSOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5632_LINE_IN_VOL, 15, 1, 1), 20962306a36Sopenharmony_ciSOC_DAPM_SINGLE("PHONE2HP Playback Switch", ALC5632_PHONE_IN_VOL, 15, 1, 1), 21062306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 15, 1, 1), 21162306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 11, 1, 1), 21262306a36Sopenharmony_ciSOC_DAPM_SINGLE("VOICE2HP Playback Switch", ALC5632_VOICE_DAC_VOL, 15, 1, 1), 21362306a36Sopenharmony_ci}; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_hpl_mixer_controls[] = { 21662306a36Sopenharmony_ciSOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5632_ADC_REC_GAIN, 15, 1, 1), 21762306a36Sopenharmony_ciSOC_DAPM_SINGLE("DACL2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 3, 1, 1), 21862306a36Sopenharmony_ci}; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_hpr_mixer_controls[] = { 22162306a36Sopenharmony_ciSOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5632_ADC_REC_GAIN, 7, 1, 1), 22262306a36Sopenharmony_ciSOC_DAPM_SINGLE("DACR2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 2, 1, 1), 22362306a36Sopenharmony_ci}; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_mono_mixer_controls[] = { 22662306a36Sopenharmony_ciSOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5632_ADC_REC_GAIN, 14, 1, 1), 22762306a36Sopenharmony_ciSOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5632_ADC_REC_GAIN, 6, 1, 1), 22862306a36Sopenharmony_ciSOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5632_LINE_IN_VOL, 13, 1, 1), 22962306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC12MONO Playback Switch", 23062306a36Sopenharmony_ci ALC5632_MIC_ROUTING_CTRL, 13, 1, 1), 23162306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC22MONO Playback Switch", 23262306a36Sopenharmony_ci ALC5632_MIC_ROUTING_CTRL, 9, 1, 1), 23362306a36Sopenharmony_ciSOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5632_MIC_ROUTING_CTRL, 0, 1, 1), 23462306a36Sopenharmony_ciSOC_DAPM_SINGLE("VOICE2MONO Playback Switch", ALC5632_VOICE_DAC_VOL, 13, 1, 1), 23562306a36Sopenharmony_ci}; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_speaker_mixer_controls[] = { 23862306a36Sopenharmony_ciSOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5632_LINE_IN_VOL, 14, 1, 1), 23962306a36Sopenharmony_ciSOC_DAPM_SINGLE("PHONE2SPK Playback Switch", ALC5632_PHONE_IN_VOL, 14, 1, 1), 24062306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC12SPK Playback Switch", 24162306a36Sopenharmony_ci ALC5632_MIC_ROUTING_CTRL, 14, 1, 1), 24262306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC22SPK Playback Switch", 24362306a36Sopenharmony_ci ALC5632_MIC_ROUTING_CTRL, 10, 1, 1), 24462306a36Sopenharmony_ciSOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5632_MIC_ROUTING_CTRL, 1, 1, 1), 24562306a36Sopenharmony_ciSOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1), 24662306a36Sopenharmony_ci}; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci/* Left Record Mixer */ 24962306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = { 25062306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), 25162306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), 25262306a36Sopenharmony_ciSOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), 25362306a36Sopenharmony_ciSOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), 25462306a36Sopenharmony_ciSOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), 25562306a36Sopenharmony_ciSOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), 25662306a36Sopenharmony_ciSOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), 25762306a36Sopenharmony_ci}; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci/* Right Record Mixer */ 26062306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = { 26162306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), 26262306a36Sopenharmony_ciSOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), 26362306a36Sopenharmony_ciSOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), 26462306a36Sopenharmony_ciSOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), 26562306a36Sopenharmony_ciSOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), 26662306a36Sopenharmony_ciSOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), 26762306a36Sopenharmony_ciSOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci/* Dmic Mixer */ 27162306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = { 27262306a36Sopenharmony_ciSOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1), 27362306a36Sopenharmony_ci}; 27462306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = { 27562306a36Sopenharmony_ciSOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1), 27662306a36Sopenharmony_ci}; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_cistatic const char * const alc5632_spk_n_sour_sel[] = { 27962306a36Sopenharmony_ci "RN/-R", "RP/+R", "LN/-R", "Mute"}; 28062306a36Sopenharmony_cistatic const char * const alc5632_hpl_out_input_sel[] = { 28162306a36Sopenharmony_ci "Vmid", "HP Left Mix"}; 28262306a36Sopenharmony_cistatic const char * const alc5632_hpr_out_input_sel[] = { 28362306a36Sopenharmony_ci "Vmid", "HP Right Mix"}; 28462306a36Sopenharmony_cistatic const char * const alc5632_spkout_input_sel[] = { 28562306a36Sopenharmony_ci "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 28662306a36Sopenharmony_cistatic const char * const alc5632_aux_out_input_sel[] = { 28762306a36Sopenharmony_ci "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 28862306a36Sopenharmony_cistatic const char * const alc5632_adcr_func_sel[] = { 28962306a36Sopenharmony_ci "Stereo ADC", "Voice ADC"}; 29062306a36Sopenharmony_cistatic const char * const alc5632_i2s_out_sel[] = { 29162306a36Sopenharmony_ci "ADC LR", "Voice Stereo Digital"}; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci/* auxout output mux */ 29462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(alc5632_aux_out_input_enum, 29562306a36Sopenharmony_ci ALC5632_OUTPUT_MIXER_CTRL, 6, 29662306a36Sopenharmony_ci alc5632_aux_out_input_sel); 29762306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_auxout_mux_controls = 29862306a36Sopenharmony_ciSOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci/* speaker output mux */ 30162306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(alc5632_spkout_input_enum, 30262306a36Sopenharmony_ci ALC5632_OUTPUT_MIXER_CTRL, 10, 30362306a36Sopenharmony_ci alc5632_spkout_input_sel); 30462306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_spkout_mux_controls = 30562306a36Sopenharmony_ciSOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci/* headphone left output mux */ 30862306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(alc5632_hpl_out_input_enum, 30962306a36Sopenharmony_ci ALC5632_OUTPUT_MIXER_CTRL, 9, 31062306a36Sopenharmony_ci alc5632_hpl_out_input_sel); 31162306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = 31262306a36Sopenharmony_ciSOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci/* headphone right output mux */ 31562306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(alc5632_hpr_out_input_enum, 31662306a36Sopenharmony_ci ALC5632_OUTPUT_MIXER_CTRL, 8, 31762306a36Sopenharmony_ci alc5632_hpr_out_input_sel); 31862306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = 31962306a36Sopenharmony_ciSOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci/* speaker output N select */ 32262306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(alc5632_spk_n_sour_enum, 32362306a36Sopenharmony_ci ALC5632_OUTPUT_MIXER_CTRL, 14, 32462306a36Sopenharmony_ci alc5632_spk_n_sour_sel); 32562306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = 32662306a36Sopenharmony_ciSOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci/* speaker amplifier */ 32962306a36Sopenharmony_cistatic const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; 33062306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(alc5632_amp_enum, 33162306a36Sopenharmony_ci ALC5632_OUTPUT_MIXER_CTRL, 13, 33262306a36Sopenharmony_ci alc5632_amp_names); 33362306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_amp_mux_controls = 33462306a36Sopenharmony_ci SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci/* ADC output select */ 33762306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(alc5632_adcr_func_enum, 33862306a36Sopenharmony_ci ALC5632_DAC_FUNC_SELECT, 5, 33962306a36Sopenharmony_ci alc5632_adcr_func_sel); 34062306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_adcr_func_controls = 34162306a36Sopenharmony_ci SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci/* I2S out select */ 34462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(alc5632_i2s_out_enum, 34562306a36Sopenharmony_ci ALC5632_I2S_OUT_CTL, 5, 34662306a36Sopenharmony_ci alc5632_i2s_out_sel); 34762306a36Sopenharmony_cistatic const struct snd_kcontrol_new alc5632_i2s_out_controls = 34862306a36Sopenharmony_ci SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = { 35162306a36Sopenharmony_ci/* Muxes */ 35262306a36Sopenharmony_ciSND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0, 35362306a36Sopenharmony_ci &alc5632_auxout_mux_controls), 35462306a36Sopenharmony_ciSND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0, 35562306a36Sopenharmony_ci &alc5632_spkout_mux_controls), 35662306a36Sopenharmony_ciSND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, 35762306a36Sopenharmony_ci &alc5632_hpl_out_mux_controls), 35862306a36Sopenharmony_ciSND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, 35962306a36Sopenharmony_ci &alc5632_hpr_out_mux_controls), 36062306a36Sopenharmony_ciSND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, 36162306a36Sopenharmony_ci &alc5632_spkoutn_mux_controls), 36262306a36Sopenharmony_ciSND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, 36362306a36Sopenharmony_ci &alc5632_adcr_func_controls), 36462306a36Sopenharmony_ciSND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0, 36562306a36Sopenharmony_ci &alc5632_i2s_out_controls), 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci/* output mixers */ 36862306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, 36962306a36Sopenharmony_ci &alc5632_hp_mixer_controls[0], 37062306a36Sopenharmony_ci ARRAY_SIZE(alc5632_hp_mixer_controls)), 37162306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("HPR Mix", ALC5632_PWR_MANAG_ADD2, 4, 0, 37262306a36Sopenharmony_ci &alc5632_hpr_mixer_controls[0], 37362306a36Sopenharmony_ci ARRAY_SIZE(alc5632_hpr_mixer_controls)), 37462306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("HPL Mix", ALC5632_PWR_MANAG_ADD2, 5, 0, 37562306a36Sopenharmony_ci &alc5632_hpl_mixer_controls[0], 37662306a36Sopenharmony_ci ARRAY_SIZE(alc5632_hpl_mixer_controls)), 37762306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 37862306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0, 37962306a36Sopenharmony_ci &alc5632_mono_mixer_controls[0], 38062306a36Sopenharmony_ci ARRAY_SIZE(alc5632_mono_mixer_controls)), 38162306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0, 38262306a36Sopenharmony_ci &alc5632_speaker_mixer_controls[0], 38362306a36Sopenharmony_ci ARRAY_SIZE(alc5632_speaker_mixer_controls)), 38462306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0, 38562306a36Sopenharmony_ci &alc5632_dmicl_mixer_controls[0], 38662306a36Sopenharmony_ci ARRAY_SIZE(alc5632_dmicl_mixer_controls)), 38762306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0, 38862306a36Sopenharmony_ci &alc5632_dmicr_mixer_controls[0], 38962306a36Sopenharmony_ci ARRAY_SIZE(alc5632_dmicr_mixer_controls)), 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci/* input mixers */ 39262306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0, 39362306a36Sopenharmony_ci &alc5632_captureL_mixer_controls[0], 39462306a36Sopenharmony_ci ARRAY_SIZE(alc5632_captureL_mixer_controls)), 39562306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0, 39662306a36Sopenharmony_ci &alc5632_captureR_mixer_controls[0], 39762306a36Sopenharmony_ci ARRAY_SIZE(alc5632_captureR_mixer_controls)), 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ciSND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0), 40062306a36Sopenharmony_ciSND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0), 40162306a36Sopenharmony_ciSND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0), 40262306a36Sopenharmony_ciSND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0), 40362306a36Sopenharmony_ciSND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0), 40462306a36Sopenharmony_ciSND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0), 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ciSND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0), 40762306a36Sopenharmony_ciSND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0), 40862306a36Sopenharmony_ciSND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0), 40962306a36Sopenharmony_ciSND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0), 41062306a36Sopenharmony_ciSND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0), 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0), 41362306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("DAC Right Channel", 41462306a36Sopenharmony_ci ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0), 41562306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0), 41662306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 41762306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 41862306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 41962306a36Sopenharmony_ciSND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0), 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0), 42262306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0), 42362306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0), 42462306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Right Speaker", ALC5632_PWR_MANAG_ADD3, 12, 0, NULL, 0), 42562306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Aux Out", ALC5632_PWR_MANAG_ADD3, 14, 0, NULL, 0), 42662306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Left LineIn", ALC5632_PWR_MANAG_ADD3, 7, 0, NULL, 0), 42762306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Right LineIn", ALC5632_PWR_MANAG_ADD3, 6, 0, NULL, 0), 42862306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Phone", ALC5632_PWR_MANAG_ADD3, 5, 0, NULL, 0), 42962306a36Sopenharmony_ciSND_SOC_DAPM_PGA("Phone ADMix", ALC5632_PWR_MANAG_ADD3, 4, 0, NULL, 0), 43062306a36Sopenharmony_ciSND_SOC_DAPM_PGA("MIC1 PGA", ALC5632_PWR_MANAG_ADD3, 3, 0, NULL, 0), 43162306a36Sopenharmony_ciSND_SOC_DAPM_PGA("MIC2 PGA", ALC5632_PWR_MANAG_ADD3, 2, 0, NULL, 0), 43262306a36Sopenharmony_ciSND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5632_PWR_MANAG_ADD3, 1, 0, NULL, 0), 43362306a36Sopenharmony_ciSND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5632_PWR_MANAG_ADD3, 0, 0, NULL, 0), 43462306a36Sopenharmony_ciSND_SOC_DAPM_SUPPLY("MICBIAS1", ALC5632_PWR_MANAG_ADD1, 3, 0, NULL, 0), 43562306a36Sopenharmony_ciSND_SOC_DAPM_SUPPLY("MICBIAS2", ALC5632_PWR_MANAG_ADD1, 2, 0, NULL, 0), 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ciSND_SOC_DAPM_PGA_E("D Amp", ALC5632_PWR_MANAG_ADD2, 14, 0, NULL, 0, 43862306a36Sopenharmony_ci amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 43962306a36Sopenharmony_ciSND_SOC_DAPM_PGA("AB Amp", ALC5632_PWR_MANAG_ADD2, 15, 0, NULL, 0), 44062306a36Sopenharmony_ciSND_SOC_DAPM_MUX("AB-D Amp Mux", ALC5632_PWR_MANAG_ADD1, 10, 0, 44162306a36Sopenharmony_ci &alc5632_amp_mux_controls), 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ciSND_SOC_DAPM_OUTPUT("AUXOUT"), 44462306a36Sopenharmony_ciSND_SOC_DAPM_OUTPUT("HPL"), 44562306a36Sopenharmony_ciSND_SOC_DAPM_OUTPUT("HPR"), 44662306a36Sopenharmony_ciSND_SOC_DAPM_OUTPUT("SPKOUT"), 44762306a36Sopenharmony_ciSND_SOC_DAPM_OUTPUT("SPKOUTN"), 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ciSND_SOC_DAPM_INPUT("LINEINL"), 45062306a36Sopenharmony_ciSND_SOC_DAPM_INPUT("LINEINR"), 45162306a36Sopenharmony_ciSND_SOC_DAPM_INPUT("PHONEP"), 45262306a36Sopenharmony_ciSND_SOC_DAPM_INPUT("PHONEN"), 45362306a36Sopenharmony_ciSND_SOC_DAPM_INPUT("DMICDAT"), 45462306a36Sopenharmony_ciSND_SOC_DAPM_INPUT("MIC1"), 45562306a36Sopenharmony_ciSND_SOC_DAPM_INPUT("MIC2"), 45662306a36Sopenharmony_ciSND_SOC_DAPM_VMID("Vmid"), 45762306a36Sopenharmony_ci}; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_cistatic const struct snd_soc_dapm_route alc5632_dapm_routes[] = { 46162306a36Sopenharmony_ci /* Playback streams */ 46262306a36Sopenharmony_ci {"Left DAC", NULL, "AIFRXL"}, 46362306a36Sopenharmony_ci {"Right DAC", NULL, "AIFRXR"}, 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci /* virtual mixer - mixes left & right channels */ 46662306a36Sopenharmony_ci {"I2S Mix", NULL, "Left DAC"}, 46762306a36Sopenharmony_ci {"I2S Mix", NULL, "Right DAC"}, 46862306a36Sopenharmony_ci {"Line Mix", NULL, "Right LineIn"}, 46962306a36Sopenharmony_ci {"Line Mix", NULL, "Left LineIn"}, 47062306a36Sopenharmony_ci {"Phone Mix", NULL, "Phone"}, 47162306a36Sopenharmony_ci {"Phone Mix", NULL, "Phone ADMix"}, 47262306a36Sopenharmony_ci {"AUXOUT", NULL, "Aux Out"}, 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci /* DAC */ 47562306a36Sopenharmony_ci {"DAC Right Channel", NULL, "I2S Mix"}, 47662306a36Sopenharmony_ci {"DAC Left Channel", NULL, "I2S Mix"}, 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci /* HP mixer */ 47962306a36Sopenharmony_ci {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"}, 48062306a36Sopenharmony_ci {"HPL Mix", NULL, "HP Mix"}, 48162306a36Sopenharmony_ci {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"}, 48262306a36Sopenharmony_ci {"HPR Mix", NULL, "HP Mix"}, 48362306a36Sopenharmony_ci {"HP Mix", "LI2HP Playback Switch", "Line Mix"}, 48462306a36Sopenharmony_ci {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"}, 48562306a36Sopenharmony_ci {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, 48662306a36Sopenharmony_ci {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, 48762306a36Sopenharmony_ci {"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"}, 48862306a36Sopenharmony_ci {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"}, 48962306a36Sopenharmony_ci {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"}, 49062306a36Sopenharmony_ci {"HPOut Mix", NULL, "HP Mix"}, 49162306a36Sopenharmony_ci {"HPOut Mix", NULL, "HPR Mix"}, 49262306a36Sopenharmony_ci {"HPOut Mix", NULL, "HPL Mix"}, 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci /* speaker mixer */ 49562306a36Sopenharmony_ci {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, 49662306a36Sopenharmony_ci {"Speaker Mix", "PHONE2SPK Playback Switch", "Phone Mix"}, 49762306a36Sopenharmony_ci {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, 49862306a36Sopenharmony_ci {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, 49962306a36Sopenharmony_ci {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"}, 50062306a36Sopenharmony_ci {"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"}, 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci /* mono mixer */ 50362306a36Sopenharmony_ci {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, 50462306a36Sopenharmony_ci {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, 50562306a36Sopenharmony_ci {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, 50662306a36Sopenharmony_ci {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, 50762306a36Sopenharmony_ci {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, 50862306a36Sopenharmony_ci {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"}, 50962306a36Sopenharmony_ci {"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"}, 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci /* Left record mixer */ 51262306a36Sopenharmony_ci {"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"}, 51362306a36Sopenharmony_ci {"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"}, 51462306a36Sopenharmony_ci {"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"}, 51562306a36Sopenharmony_ci {"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"}, 51662306a36Sopenharmony_ci {"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"}, 51762306a36Sopenharmony_ci {"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"}, 51862306a36Sopenharmony_ci {"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"}, 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci /*Right record mixer */ 52162306a36Sopenharmony_ci {"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"}, 52262306a36Sopenharmony_ci {"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"}, 52362306a36Sopenharmony_ci {"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"}, 52462306a36Sopenharmony_ci {"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"}, 52562306a36Sopenharmony_ci {"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"}, 52662306a36Sopenharmony_ci {"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"}, 52762306a36Sopenharmony_ci {"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"}, 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci /* headphone left mux */ 53062306a36Sopenharmony_ci {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, 53162306a36Sopenharmony_ci {"Left Headphone Mux", "Vmid", "Vmid"}, 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci /* headphone right mux */ 53462306a36Sopenharmony_ci {"Right Headphone Mux", "HP Right Mix", "HPR Mix"}, 53562306a36Sopenharmony_ci {"Right Headphone Mux", "Vmid", "Vmid"}, 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci /* speaker out mux */ 53862306a36Sopenharmony_ci {"SpeakerOut Mux", "Vmid", "Vmid"}, 53962306a36Sopenharmony_ci {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"}, 54062306a36Sopenharmony_ci {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"}, 54162306a36Sopenharmony_ci {"SpeakerOut Mux", "Mono Mix", "Mono Mix"}, 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci /* Mono/Aux Out mux */ 54462306a36Sopenharmony_ci {"AuxOut Mux", "Vmid", "Vmid"}, 54562306a36Sopenharmony_ci {"AuxOut Mux", "HPOut Mix", "HPOut Mix"}, 54662306a36Sopenharmony_ci {"AuxOut Mux", "Speaker Mix", "Speaker Mix"}, 54762306a36Sopenharmony_ci {"AuxOut Mux", "Mono Mix", "Mono Mix"}, 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci /* output pga */ 55062306a36Sopenharmony_ci {"HPL", NULL, "Left Headphone"}, 55162306a36Sopenharmony_ci {"Left Headphone", NULL, "Left Headphone Mux"}, 55262306a36Sopenharmony_ci {"HPR", NULL, "Right Headphone"}, 55362306a36Sopenharmony_ci {"Right Headphone", NULL, "Right Headphone Mux"}, 55462306a36Sopenharmony_ci {"Aux Out", NULL, "AuxOut Mux"}, 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci /* input pga */ 55762306a36Sopenharmony_ci {"Left LineIn", NULL, "LINEINL"}, 55862306a36Sopenharmony_ci {"Right LineIn", NULL, "LINEINR"}, 55962306a36Sopenharmony_ci {"Phone", NULL, "PHONEP"}, 56062306a36Sopenharmony_ci {"MIC1 Pre Amp", NULL, "MIC1"}, 56162306a36Sopenharmony_ci {"MIC2 Pre Amp", NULL, "MIC2"}, 56262306a36Sopenharmony_ci {"MIC1 PGA", NULL, "MIC1 Pre Amp"}, 56362306a36Sopenharmony_ci {"MIC2 PGA", NULL, "MIC2 Pre Amp"}, 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci /* left ADC */ 56662306a36Sopenharmony_ci {"Left ADC", NULL, "Left Capture Mix"}, 56762306a36Sopenharmony_ci {"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"}, 56862306a36Sopenharmony_ci {"Left ADC", NULL, "DMICL Mix"}, 56962306a36Sopenharmony_ci {"ADCLR", NULL, "Left ADC"}, 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci /* right ADC */ 57262306a36Sopenharmony_ci {"Right ADC", NULL, "Right Capture Mix"}, 57362306a36Sopenharmony_ci {"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"}, 57462306a36Sopenharmony_ci {"Right ADC", NULL, "DMICR Mix"}, 57562306a36Sopenharmony_ci {"ADCR Mux", "Stereo ADC", "Right ADC"}, 57662306a36Sopenharmony_ci {"ADCR Mux", "Voice ADC", "Right ADC"}, 57762306a36Sopenharmony_ci {"ADCLR", NULL, "ADCR Mux"}, 57862306a36Sopenharmony_ci {"VAIFTX", NULL, "ADCR Mux"}, 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci /* Digital I2S out */ 58162306a36Sopenharmony_ci {"I2SOut Mux", "ADC LR", "ADCLR"}, 58262306a36Sopenharmony_ci {"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"}, 58362306a36Sopenharmony_ci {"AIFTXL", NULL, "I2SOut Mux"}, 58462306a36Sopenharmony_ci {"AIFTXR", NULL, "I2SOut Mux"}, 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci /* Voice Mix */ 58762306a36Sopenharmony_ci {"Voice DAC", NULL, "VAIFRX"}, 58862306a36Sopenharmony_ci {"Voice Mix", NULL, "Voice DAC"}, 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci /* Speaker Output */ 59162306a36Sopenharmony_ci {"SpeakerOut N Mux", "RN/-R", "Left Speaker"}, 59262306a36Sopenharmony_ci {"SpeakerOut N Mux", "RP/+R", "Left Speaker"}, 59362306a36Sopenharmony_ci {"SpeakerOut N Mux", "LN/-R", "Left Speaker"}, 59462306a36Sopenharmony_ci {"SpeakerOut N Mux", "Mute", "Vmid"}, 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci {"SpeakerOut N Mux", "RN/-R", "Right Speaker"}, 59762306a36Sopenharmony_ci {"SpeakerOut N Mux", "RP/+R", "Right Speaker"}, 59862306a36Sopenharmony_ci {"SpeakerOut N Mux", "LN/-R", "Right Speaker"}, 59962306a36Sopenharmony_ci {"SpeakerOut N Mux", "Mute", "Vmid"}, 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_ci {"AB Amp", NULL, "SpeakerOut Mux"}, 60262306a36Sopenharmony_ci {"D Amp", NULL, "SpeakerOut Mux"}, 60362306a36Sopenharmony_ci {"AB-D Amp Mux", "AB Amp", "AB Amp"}, 60462306a36Sopenharmony_ci {"AB-D Amp Mux", "D Amp", "D Amp"}, 60562306a36Sopenharmony_ci {"Left Speaker", NULL, "AB-D Amp Mux"}, 60662306a36Sopenharmony_ci {"Right Speaker", NULL, "AB-D Amp Mux"}, 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci {"SPKOUT", NULL, "Left Speaker"}, 60962306a36Sopenharmony_ci {"SPKOUT", NULL, "Right Speaker"}, 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci {"SPKOUTN", NULL, "SpeakerOut N Mux"}, 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci}; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci/* PLL divisors */ 61662306a36Sopenharmony_cistruct _pll_div { 61762306a36Sopenharmony_ci u32 pll_in; 61862306a36Sopenharmony_ci u32 pll_out; 61962306a36Sopenharmony_ci u16 regvalue; 62062306a36Sopenharmony_ci}; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci/* Note : pll code from original alc5632 driver. Not sure of how good it is */ 62362306a36Sopenharmony_ci/* useful only for master mode */ 62462306a36Sopenharmony_cistatic const struct _pll_div codec_master_pll_div[] = { 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci { 2048000, 8192000, 0x0ea0}, 62762306a36Sopenharmony_ci { 3686400, 8192000, 0x4e27}, 62862306a36Sopenharmony_ci { 12000000, 8192000, 0x456b}, 62962306a36Sopenharmony_ci { 13000000, 8192000, 0x495f}, 63062306a36Sopenharmony_ci { 13100000, 8192000, 0x0320}, 63162306a36Sopenharmony_ci { 2048000, 11289600, 0xf637}, 63262306a36Sopenharmony_ci { 3686400, 11289600, 0x2f22}, 63362306a36Sopenharmony_ci { 12000000, 11289600, 0x3e2f}, 63462306a36Sopenharmony_ci { 13000000, 11289600, 0x4d5b}, 63562306a36Sopenharmony_ci { 13100000, 11289600, 0x363b}, 63662306a36Sopenharmony_ci { 2048000, 16384000, 0x1ea0}, 63762306a36Sopenharmony_ci { 3686400, 16384000, 0x9e27}, 63862306a36Sopenharmony_ci { 12000000, 16384000, 0x452b}, 63962306a36Sopenharmony_ci { 13000000, 16384000, 0x542f}, 64062306a36Sopenharmony_ci { 13100000, 16384000, 0x03a0}, 64162306a36Sopenharmony_ci { 2048000, 16934400, 0xe625}, 64262306a36Sopenharmony_ci { 3686400, 16934400, 0x9126}, 64362306a36Sopenharmony_ci { 12000000, 16934400, 0x4d2c}, 64462306a36Sopenharmony_ci { 13000000, 16934400, 0x742f}, 64562306a36Sopenharmony_ci { 13100000, 16934400, 0x3c27}, 64662306a36Sopenharmony_ci { 2048000, 22579200, 0x2aa0}, 64762306a36Sopenharmony_ci { 3686400, 22579200, 0x2f20}, 64862306a36Sopenharmony_ci { 12000000, 22579200, 0x7e2f}, 64962306a36Sopenharmony_ci { 13000000, 22579200, 0x742f}, 65062306a36Sopenharmony_ci { 13100000, 22579200, 0x3c27}, 65162306a36Sopenharmony_ci { 2048000, 24576000, 0x2ea0}, 65262306a36Sopenharmony_ci { 3686400, 24576000, 0xee27}, 65362306a36Sopenharmony_ci { 12000000, 24576000, 0x2915}, 65462306a36Sopenharmony_ci { 13000000, 24576000, 0x772e}, 65562306a36Sopenharmony_ci { 13100000, 24576000, 0x0d20}, 65662306a36Sopenharmony_ci}; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci/* FOUT = MCLK*(N+2)/((M+2)*(K+2)) 65962306a36Sopenharmony_ci N: bit 15:8 (div 2 .. div 257) 66062306a36Sopenharmony_ci K: bit 6:4 typical 2 66162306a36Sopenharmony_ci M: bit 3:0 (div 2 .. div 17) 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci same as for 5623 - thanks! 66462306a36Sopenharmony_ci*/ 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_cistatic const struct _pll_div codec_slave_pll_div[] = { 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci { 1024000, 16384000, 0x3ea0}, 66962306a36Sopenharmony_ci { 1411200, 22579200, 0x3ea0}, 67062306a36Sopenharmony_ci { 1536000, 24576000, 0x3ea0}, 67162306a36Sopenharmony_ci { 2048000, 16384000, 0x1ea0}, 67262306a36Sopenharmony_ci { 2822400, 22579200, 0x1ea0}, 67362306a36Sopenharmony_ci { 3072000, 24576000, 0x1ea0}, 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci}; 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_cistatic int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 67862306a36Sopenharmony_ci int source, unsigned int freq_in, unsigned int freq_out) 67962306a36Sopenharmony_ci{ 68062306a36Sopenharmony_ci int i; 68162306a36Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 68262306a36Sopenharmony_ci int gbl_clk = 0, pll_div = 0; 68362306a36Sopenharmony_ci u16 reg; 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK) 68662306a36Sopenharmony_ci return -EINVAL; 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_ci /* Disable PLL power */ 68962306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2, 69062306a36Sopenharmony_ci ALC5632_PWR_ADD2_PLL1, 69162306a36Sopenharmony_ci 0); 69262306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2, 69362306a36Sopenharmony_ci ALC5632_PWR_ADD2_PLL2, 69462306a36Sopenharmony_ci 0); 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci /* pll is not used in slave mode */ 69762306a36Sopenharmony_ci reg = snd_soc_component_read(component, ALC5632_DAI_CONTROL); 69862306a36Sopenharmony_ci if (reg & ALC5632_DAI_SDP_SLAVE_MODE) 69962306a36Sopenharmony_ci return 0; 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci if (!freq_in || !freq_out) 70262306a36Sopenharmony_ci return 0; 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_ci switch (pll_id) { 70562306a36Sopenharmony_ci case ALC5632_PLL_FR_MCLK: 70662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) { 70762306a36Sopenharmony_ci if (codec_master_pll_div[i].pll_in == freq_in 70862306a36Sopenharmony_ci && codec_master_pll_div[i].pll_out == freq_out) { 70962306a36Sopenharmony_ci /* PLL source from MCLK */ 71062306a36Sopenharmony_ci pll_div = codec_master_pll_div[i].regvalue; 71162306a36Sopenharmony_ci break; 71262306a36Sopenharmony_ci } 71362306a36Sopenharmony_ci } 71462306a36Sopenharmony_ci break; 71562306a36Sopenharmony_ci case ALC5632_PLL_FR_BCLK: 71662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) { 71762306a36Sopenharmony_ci if (codec_slave_pll_div[i].pll_in == freq_in 71862306a36Sopenharmony_ci && codec_slave_pll_div[i].pll_out == freq_out) { 71962306a36Sopenharmony_ci /* PLL source from Bitclk */ 72062306a36Sopenharmony_ci gbl_clk = ALC5632_PLL_FR_BCLK; 72162306a36Sopenharmony_ci pll_div = codec_slave_pll_div[i].regvalue; 72262306a36Sopenharmony_ci break; 72362306a36Sopenharmony_ci } 72462306a36Sopenharmony_ci } 72562306a36Sopenharmony_ci break; 72662306a36Sopenharmony_ci case ALC5632_PLL_FR_VBCLK: 72762306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) { 72862306a36Sopenharmony_ci if (codec_slave_pll_div[i].pll_in == freq_in 72962306a36Sopenharmony_ci && codec_slave_pll_div[i].pll_out == freq_out) { 73062306a36Sopenharmony_ci /* PLL source from voice clock */ 73162306a36Sopenharmony_ci gbl_clk = ALC5632_PLL_FR_VBCLK; 73262306a36Sopenharmony_ci pll_div = codec_slave_pll_div[i].regvalue; 73362306a36Sopenharmony_ci break; 73462306a36Sopenharmony_ci } 73562306a36Sopenharmony_ci } 73662306a36Sopenharmony_ci break; 73762306a36Sopenharmony_ci default: 73862306a36Sopenharmony_ci return -EINVAL; 73962306a36Sopenharmony_ci } 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci if (!pll_div) 74262306a36Sopenharmony_ci return -EINVAL; 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci /* choose MCLK/BCLK/VBCLK */ 74562306a36Sopenharmony_ci snd_soc_component_write(component, ALC5632_GPCR2, gbl_clk); 74662306a36Sopenharmony_ci /* choose PLL1 clock rate */ 74762306a36Sopenharmony_ci snd_soc_component_write(component, ALC5632_PLL1_CTRL, pll_div); 74862306a36Sopenharmony_ci /* enable PLL1 */ 74962306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2, 75062306a36Sopenharmony_ci ALC5632_PWR_ADD2_PLL1, 75162306a36Sopenharmony_ci ALC5632_PWR_ADD2_PLL1); 75262306a36Sopenharmony_ci /* enable PLL2 */ 75362306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2, 75462306a36Sopenharmony_ci ALC5632_PWR_ADD2_PLL2, 75562306a36Sopenharmony_ci ALC5632_PWR_ADD2_PLL2); 75662306a36Sopenharmony_ci /* use PLL1 as main SYSCLK */ 75762306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_GPCR1, 75862306a36Sopenharmony_ci ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1, 75962306a36Sopenharmony_ci ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1); 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci return 0; 76262306a36Sopenharmony_ci} 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_cistruct _coeff_div { 76562306a36Sopenharmony_ci u16 fs; 76662306a36Sopenharmony_ci u16 regvalue; 76762306a36Sopenharmony_ci}; 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci/* codec hifi mclk (after PLL) clock divider coefficients */ 77062306a36Sopenharmony_ci/* values inspired from column BCLK=32Fs of Appendix A table */ 77162306a36Sopenharmony_cistatic const struct _coeff_div coeff_div[] = { 77262306a36Sopenharmony_ci {512*1, 0x3075}, 77362306a36Sopenharmony_ci}; 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_cistatic int get_coeff(struct snd_soc_component *component, int rate) 77662306a36Sopenharmony_ci{ 77762306a36Sopenharmony_ci struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component); 77862306a36Sopenharmony_ci int i; 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 78162306a36Sopenharmony_ci if (coeff_div[i].fs * rate == alc5632->sysclk) 78262306a36Sopenharmony_ci return i; 78362306a36Sopenharmony_ci } 78462306a36Sopenharmony_ci return -EINVAL; 78562306a36Sopenharmony_ci} 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci/* 78862306a36Sopenharmony_ci * Clock after PLL and dividers 78962306a36Sopenharmony_ci */ 79062306a36Sopenharmony_cistatic int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai, 79162306a36Sopenharmony_ci int clk_id, unsigned int freq, int dir) 79262306a36Sopenharmony_ci{ 79362306a36Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 79462306a36Sopenharmony_ci struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component); 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_ci switch (freq) { 79762306a36Sopenharmony_ci case 4096000: 79862306a36Sopenharmony_ci case 8192000: 79962306a36Sopenharmony_ci case 11289600: 80062306a36Sopenharmony_ci case 12288000: 80162306a36Sopenharmony_ci case 16384000: 80262306a36Sopenharmony_ci case 16934400: 80362306a36Sopenharmony_ci case 18432000: 80462306a36Sopenharmony_ci case 22579200: 80562306a36Sopenharmony_ci case 24576000: 80662306a36Sopenharmony_ci alc5632->sysclk = freq; 80762306a36Sopenharmony_ci return 0; 80862306a36Sopenharmony_ci } 80962306a36Sopenharmony_ci return -EINVAL; 81062306a36Sopenharmony_ci} 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_cistatic int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai, 81362306a36Sopenharmony_ci unsigned int fmt) 81462306a36Sopenharmony_ci{ 81562306a36Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 81662306a36Sopenharmony_ci u16 iface = 0; 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci /* set audio interface clocking */ 81962306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 82062306a36Sopenharmony_ci case SND_SOC_DAIFMT_CBP_CFP: 82162306a36Sopenharmony_ci iface = ALC5632_DAI_SDP_MASTER_MODE; 82262306a36Sopenharmony_ci break; 82362306a36Sopenharmony_ci case SND_SOC_DAIFMT_CBC_CFC: 82462306a36Sopenharmony_ci iface = ALC5632_DAI_SDP_SLAVE_MODE; 82562306a36Sopenharmony_ci break; 82662306a36Sopenharmony_ci default: 82762306a36Sopenharmony_ci return -EINVAL; 82862306a36Sopenharmony_ci } 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci /* interface format */ 83162306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 83262306a36Sopenharmony_ci case SND_SOC_DAIFMT_I2S: 83362306a36Sopenharmony_ci iface |= ALC5632_DAI_I2S_DF_I2S; 83462306a36Sopenharmony_ci break; 83562306a36Sopenharmony_ci case SND_SOC_DAIFMT_LEFT_J: 83662306a36Sopenharmony_ci iface |= ALC5632_DAI_I2S_DF_LEFT; 83762306a36Sopenharmony_ci break; 83862306a36Sopenharmony_ci case SND_SOC_DAIFMT_DSP_A: 83962306a36Sopenharmony_ci iface |= ALC5632_DAI_I2S_DF_PCM_A; 84062306a36Sopenharmony_ci break; 84162306a36Sopenharmony_ci case SND_SOC_DAIFMT_DSP_B: 84262306a36Sopenharmony_ci iface |= ALC5632_DAI_I2S_DF_PCM_B; 84362306a36Sopenharmony_ci break; 84462306a36Sopenharmony_ci default: 84562306a36Sopenharmony_ci return -EINVAL; 84662306a36Sopenharmony_ci } 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_ci /* clock inversion */ 84962306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 85062306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_NF: 85162306a36Sopenharmony_ci break; 85262306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_IF: 85362306a36Sopenharmony_ci iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL; 85462306a36Sopenharmony_ci break; 85562306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_NF: 85662306a36Sopenharmony_ci iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL; 85762306a36Sopenharmony_ci break; 85862306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_IF: 85962306a36Sopenharmony_ci break; 86062306a36Sopenharmony_ci default: 86162306a36Sopenharmony_ci return -EINVAL; 86262306a36Sopenharmony_ci } 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci return snd_soc_component_write(component, ALC5632_DAI_CONTROL, iface); 86562306a36Sopenharmony_ci} 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_cistatic int alc5632_pcm_hw_params(struct snd_pcm_substream *substream, 86862306a36Sopenharmony_ci struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 86962306a36Sopenharmony_ci{ 87062306a36Sopenharmony_ci struct snd_soc_component *component = dai->component; 87162306a36Sopenharmony_ci int coeff, rate; 87262306a36Sopenharmony_ci u16 iface; 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci iface = snd_soc_component_read(component, ALC5632_DAI_CONTROL); 87562306a36Sopenharmony_ci iface &= ~ALC5632_DAI_I2S_DL_MASK; 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci /* bit size */ 87862306a36Sopenharmony_ci switch (params_width(params)) { 87962306a36Sopenharmony_ci case 16: 88062306a36Sopenharmony_ci iface |= ALC5632_DAI_I2S_DL_16; 88162306a36Sopenharmony_ci break; 88262306a36Sopenharmony_ci case 20: 88362306a36Sopenharmony_ci iface |= ALC5632_DAI_I2S_DL_20; 88462306a36Sopenharmony_ci break; 88562306a36Sopenharmony_ci case 24: 88662306a36Sopenharmony_ci iface |= ALC5632_DAI_I2S_DL_24; 88762306a36Sopenharmony_ci break; 88862306a36Sopenharmony_ci default: 88962306a36Sopenharmony_ci return -EINVAL; 89062306a36Sopenharmony_ci } 89162306a36Sopenharmony_ci 89262306a36Sopenharmony_ci /* set iface & srate */ 89362306a36Sopenharmony_ci snd_soc_component_write(component, ALC5632_DAI_CONTROL, iface); 89462306a36Sopenharmony_ci rate = params_rate(params); 89562306a36Sopenharmony_ci coeff = get_coeff(component, rate); 89662306a36Sopenharmony_ci if (coeff < 0) 89762306a36Sopenharmony_ci return -EINVAL; 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci coeff = coeff_div[coeff].regvalue; 90062306a36Sopenharmony_ci snd_soc_component_write(component, ALC5632_DAC_CLK_CTRL1, coeff); 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci return 0; 90362306a36Sopenharmony_ci} 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_cistatic int alc5632_mute(struct snd_soc_dai *dai, int mute, int direction) 90662306a36Sopenharmony_ci{ 90762306a36Sopenharmony_ci struct snd_soc_component *component = dai->component; 90862306a36Sopenharmony_ci u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L 90962306a36Sopenharmony_ci |ALC5632_MISC_HP_DEPOP_MUTE_R; 91062306a36Sopenharmony_ci u16 mute_reg = snd_soc_component_read(component, ALC5632_MISC_CTRL) & ~hp_mute; 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci if (mute) 91362306a36Sopenharmony_ci mute_reg |= hp_mute; 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci return snd_soc_component_write(component, ALC5632_MISC_CTRL, mute_reg); 91662306a36Sopenharmony_ci} 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci#define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF) 91962306a36Sopenharmony_ci 92062306a36Sopenharmony_ci#define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD) 92162306a36Sopenharmony_ci 92262306a36Sopenharmony_ci#define ALC5632_ADD1_POWER_EN \ 92362306a36Sopenharmony_ci (ALC5632_PWR_ADD1_DAC_REF \ 92462306a36Sopenharmony_ci | ALC5632_PWR_ADD1_SOFTGEN_EN \ 92562306a36Sopenharmony_ci | ALC5632_PWR_ADD1_HP_OUT_AMP \ 92662306a36Sopenharmony_ci | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \ 92762306a36Sopenharmony_ci | ALC5632_PWR_ADD1_MAIN_BIAS) 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_cistatic void enable_power_depop(struct snd_soc_component *component) 93062306a36Sopenharmony_ci{ 93162306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1, 93262306a36Sopenharmony_ci ALC5632_PWR_ADD1_SOFTGEN_EN, 93362306a36Sopenharmony_ci ALC5632_PWR_ADD1_SOFTGEN_EN); 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD3, 93662306a36Sopenharmony_ci ALC5632_ADD3_POWER_EN, 93762306a36Sopenharmony_ci ALC5632_ADD3_POWER_EN); 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_MISC_CTRL, 94062306a36Sopenharmony_ci ALC5632_MISC_HP_DEPOP_MODE2_EN, 94162306a36Sopenharmony_ci ALC5632_MISC_HP_DEPOP_MODE2_EN); 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci /* "normal" mode: 0 @ 26 */ 94462306a36Sopenharmony_ci /* set all PR0-7 mixers to 0 */ 94562306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_DOWN_CTRL_STATUS, 94662306a36Sopenharmony_ci ALC5632_PWR_DOWN_CTRL_STATUS_MASK, 94762306a36Sopenharmony_ci 0); 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci msleep(500); 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2, 95262306a36Sopenharmony_ci ALC5632_ADD2_POWER_EN, 95362306a36Sopenharmony_ci ALC5632_ADD2_POWER_EN); 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1, 95662306a36Sopenharmony_ci ALC5632_ADD1_POWER_EN, 95762306a36Sopenharmony_ci ALC5632_ADD1_POWER_EN); 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci /* disable HP Depop2 */ 96062306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_MISC_CTRL, 96162306a36Sopenharmony_ci ALC5632_MISC_HP_DEPOP_MODE2_EN, 96262306a36Sopenharmony_ci 0); 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_ci} 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_cistatic int alc5632_set_bias_level(struct snd_soc_component *component, 96762306a36Sopenharmony_ci enum snd_soc_bias_level level) 96862306a36Sopenharmony_ci{ 96962306a36Sopenharmony_ci switch (level) { 97062306a36Sopenharmony_ci case SND_SOC_BIAS_ON: 97162306a36Sopenharmony_ci enable_power_depop(component); 97262306a36Sopenharmony_ci break; 97362306a36Sopenharmony_ci case SND_SOC_BIAS_PREPARE: 97462306a36Sopenharmony_ci break; 97562306a36Sopenharmony_ci case SND_SOC_BIAS_STANDBY: 97662306a36Sopenharmony_ci /* everything off except vref/vmid, */ 97762306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1, 97862306a36Sopenharmony_ci ALC5632_PWR_MANAG_ADD1_MASK, 97962306a36Sopenharmony_ci ALC5632_PWR_ADD1_MAIN_BIAS); 98062306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2, 98162306a36Sopenharmony_ci ALC5632_PWR_MANAG_ADD2_MASK, 98262306a36Sopenharmony_ci ALC5632_PWR_ADD2_VREF); 98362306a36Sopenharmony_ci /* "normal" mode: 0 @ 26 */ 98462306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_DOWN_CTRL_STATUS, 98562306a36Sopenharmony_ci ALC5632_PWR_DOWN_CTRL_STATUS_MASK, 98662306a36Sopenharmony_ci 0xffff ^ (ALC5632_PWR_VREF_PR3 98762306a36Sopenharmony_ci | ALC5632_PWR_VREF_PR2)); 98862306a36Sopenharmony_ci break; 98962306a36Sopenharmony_ci case SND_SOC_BIAS_OFF: 99062306a36Sopenharmony_ci /* everything off, dac mute, inactive */ 99162306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2, 99262306a36Sopenharmony_ci ALC5632_PWR_MANAG_ADD2_MASK, 0); 99362306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD3, 99462306a36Sopenharmony_ci ALC5632_PWR_MANAG_ADD3_MASK, 0); 99562306a36Sopenharmony_ci snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1, 99662306a36Sopenharmony_ci ALC5632_PWR_MANAG_ADD1_MASK, 0); 99762306a36Sopenharmony_ci break; 99862306a36Sopenharmony_ci } 99962306a36Sopenharmony_ci return 0; 100062306a36Sopenharmony_ci} 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci#define ALC5632_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \ 100362306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE \ 100462306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_cistatic const struct snd_soc_dai_ops alc5632_dai_ops = { 100762306a36Sopenharmony_ci .hw_params = alc5632_pcm_hw_params, 100862306a36Sopenharmony_ci .mute_stream = alc5632_mute, 100962306a36Sopenharmony_ci .set_fmt = alc5632_set_dai_fmt, 101062306a36Sopenharmony_ci .set_sysclk = alc5632_set_dai_sysclk, 101162306a36Sopenharmony_ci .set_pll = alc5632_set_dai_pll, 101262306a36Sopenharmony_ci .no_capture_mute = 1, 101362306a36Sopenharmony_ci}; 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_cistatic struct snd_soc_dai_driver alc5632_dai = { 101662306a36Sopenharmony_ci .name = "alc5632-hifi", 101762306a36Sopenharmony_ci .playback = { 101862306a36Sopenharmony_ci .stream_name = "HiFi Playback", 101962306a36Sopenharmony_ci .channels_min = 1, 102062306a36Sopenharmony_ci .channels_max = 2, 102162306a36Sopenharmony_ci .rate_min = 8000, 102262306a36Sopenharmony_ci .rate_max = 48000, 102362306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_48000, 102462306a36Sopenharmony_ci .formats = ALC5632_FORMATS,}, 102562306a36Sopenharmony_ci .capture = { 102662306a36Sopenharmony_ci .stream_name = "HiFi Capture", 102762306a36Sopenharmony_ci .channels_min = 1, 102862306a36Sopenharmony_ci .channels_max = 2, 102962306a36Sopenharmony_ci .rate_min = 8000, 103062306a36Sopenharmony_ci .rate_max = 48000, 103162306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_48000, 103262306a36Sopenharmony_ci .formats = ALC5632_FORMATS,}, 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci .ops = &alc5632_dai_ops, 103562306a36Sopenharmony_ci .symmetric_rate = 1, 103662306a36Sopenharmony_ci}; 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci#ifdef CONFIG_PM 103962306a36Sopenharmony_cistatic int alc5632_resume(struct snd_soc_component *component) 104062306a36Sopenharmony_ci{ 104162306a36Sopenharmony_ci struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component); 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci regcache_sync(alc5632->regmap); 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_ci return 0; 104662306a36Sopenharmony_ci} 104762306a36Sopenharmony_ci#else 104862306a36Sopenharmony_ci#define alc5632_resume NULL 104962306a36Sopenharmony_ci#endif 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_cistatic int alc5632_probe(struct snd_soc_component *component) 105262306a36Sopenharmony_ci{ 105362306a36Sopenharmony_ci struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component); 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_ci switch (alc5632->id) { 105662306a36Sopenharmony_ci case 0x5c: 105762306a36Sopenharmony_ci snd_soc_add_component_controls(component, alc5632_vol_snd_controls, 105862306a36Sopenharmony_ci ARRAY_SIZE(alc5632_vol_snd_controls)); 105962306a36Sopenharmony_ci break; 106062306a36Sopenharmony_ci default: 106162306a36Sopenharmony_ci return -EINVAL; 106262306a36Sopenharmony_ci } 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci return 0; 106562306a36Sopenharmony_ci} 106662306a36Sopenharmony_ci 106762306a36Sopenharmony_cistatic const struct snd_soc_component_driver soc_component_device_alc5632 = { 106862306a36Sopenharmony_ci .probe = alc5632_probe, 106962306a36Sopenharmony_ci .resume = alc5632_resume, 107062306a36Sopenharmony_ci .set_bias_level = alc5632_set_bias_level, 107162306a36Sopenharmony_ci .controls = alc5632_snd_controls, 107262306a36Sopenharmony_ci .num_controls = ARRAY_SIZE(alc5632_snd_controls), 107362306a36Sopenharmony_ci .dapm_widgets = alc5632_dapm_widgets, 107462306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets), 107562306a36Sopenharmony_ci .dapm_routes = alc5632_dapm_routes, 107662306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), 107762306a36Sopenharmony_ci .suspend_bias_off = 1, 107862306a36Sopenharmony_ci .idle_bias_on = 1, 107962306a36Sopenharmony_ci .use_pmdown_time = 1, 108062306a36Sopenharmony_ci .endianness = 1, 108162306a36Sopenharmony_ci}; 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_cistatic const struct regmap_config alc5632_regmap = { 108462306a36Sopenharmony_ci .reg_bits = 8, 108562306a36Sopenharmony_ci .val_bits = 16, 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci .max_register = ALC5632_MAX_REGISTER, 108862306a36Sopenharmony_ci .reg_defaults = alc5632_reg_defaults, 108962306a36Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults), 109062306a36Sopenharmony_ci .volatile_reg = alc5632_volatile_register, 109162306a36Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 109262306a36Sopenharmony_ci}; 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_cistatic const struct i2c_device_id alc5632_i2c_table[] = { 109562306a36Sopenharmony_ci {"alc5632", 0x5c}, 109662306a36Sopenharmony_ci {} 109762306a36Sopenharmony_ci}; 109862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, alc5632_i2c_table); 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci/* 110162306a36Sopenharmony_ci * alc5632 2 wire address is determined by A1 pin 110262306a36Sopenharmony_ci * state during powerup. 110362306a36Sopenharmony_ci * low = 0x1a 110462306a36Sopenharmony_ci * high = 0x1b 110562306a36Sopenharmony_ci */ 110662306a36Sopenharmony_cistatic int alc5632_i2c_probe(struct i2c_client *client) 110762306a36Sopenharmony_ci{ 110862306a36Sopenharmony_ci struct alc5632_priv *alc5632; 110962306a36Sopenharmony_ci int ret, ret1, ret2; 111062306a36Sopenharmony_ci unsigned int vid1, vid2; 111162306a36Sopenharmony_ci const struct i2c_device_id *id; 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci alc5632 = devm_kzalloc(&client->dev, 111462306a36Sopenharmony_ci sizeof(struct alc5632_priv), GFP_KERNEL); 111562306a36Sopenharmony_ci if (alc5632 == NULL) 111662306a36Sopenharmony_ci return -ENOMEM; 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_ci i2c_set_clientdata(client, alc5632); 111962306a36Sopenharmony_ci 112062306a36Sopenharmony_ci alc5632->regmap = devm_regmap_init_i2c(client, &alc5632_regmap); 112162306a36Sopenharmony_ci if (IS_ERR(alc5632->regmap)) { 112262306a36Sopenharmony_ci ret = PTR_ERR(alc5632->regmap); 112362306a36Sopenharmony_ci dev_err(&client->dev, "regmap_init() failed: %d\n", ret); 112462306a36Sopenharmony_ci return ret; 112562306a36Sopenharmony_ci } 112662306a36Sopenharmony_ci 112762306a36Sopenharmony_ci ret1 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID1, &vid1); 112862306a36Sopenharmony_ci ret2 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID2, &vid2); 112962306a36Sopenharmony_ci if (ret1 != 0 || ret2 != 0) { 113062306a36Sopenharmony_ci dev_err(&client->dev, 113162306a36Sopenharmony_ci "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2); 113262306a36Sopenharmony_ci return -EIO; 113362306a36Sopenharmony_ci } 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ci vid2 >>= 8; 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci id = i2c_match_id(alc5632_i2c_table, client); 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_ci if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) { 114062306a36Sopenharmony_ci dev_err(&client->dev, 114162306a36Sopenharmony_ci "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2); 114262306a36Sopenharmony_ci return -EINVAL; 114362306a36Sopenharmony_ci } 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ci ret = alc5632_reset(alc5632->regmap); 114662306a36Sopenharmony_ci if (ret < 0) { 114762306a36Sopenharmony_ci dev_err(&client->dev, "Failed to issue reset\n"); 114862306a36Sopenharmony_ci return ret; 114962306a36Sopenharmony_ci } 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_ci alc5632->id = vid2; 115262306a36Sopenharmony_ci switch (alc5632->id) { 115362306a36Sopenharmony_ci case 0x5c: 115462306a36Sopenharmony_ci alc5632_dai.name = "alc5632-hifi"; 115562306a36Sopenharmony_ci break; 115662306a36Sopenharmony_ci default: 115762306a36Sopenharmony_ci return -EINVAL; 115862306a36Sopenharmony_ci } 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ci ret = devm_snd_soc_register_component(&client->dev, 116162306a36Sopenharmony_ci &soc_component_device_alc5632, &alc5632_dai, 1); 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci if (ret < 0) { 116462306a36Sopenharmony_ci dev_err(&client->dev, "Failed to register component: %d\n", ret); 116562306a36Sopenharmony_ci return ret; 116662306a36Sopenharmony_ci } 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ci return ret; 116962306a36Sopenharmony_ci} 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci#ifdef CONFIG_OF 117262306a36Sopenharmony_cistatic const struct of_device_id alc5632_of_match[] = { 117362306a36Sopenharmony_ci { .compatible = "realtek,alc5632", }, 117462306a36Sopenharmony_ci { } 117562306a36Sopenharmony_ci}; 117662306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, alc5632_of_match); 117762306a36Sopenharmony_ci#endif 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_ci/* i2c codec control layer */ 118062306a36Sopenharmony_cistatic struct i2c_driver alc5632_i2c_driver = { 118162306a36Sopenharmony_ci .driver = { 118262306a36Sopenharmony_ci .name = "alc5632", 118362306a36Sopenharmony_ci .of_match_table = of_match_ptr(alc5632_of_match), 118462306a36Sopenharmony_ci }, 118562306a36Sopenharmony_ci .probe = alc5632_i2c_probe, 118662306a36Sopenharmony_ci .id_table = alc5632_i2c_table, 118762306a36Sopenharmony_ci}; 118862306a36Sopenharmony_ci 118962306a36Sopenharmony_cimodule_i2c_driver(alc5632_i2c_driver); 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ciMODULE_DESCRIPTION("ASoC ALC5632 driver"); 119262306a36Sopenharmony_ciMODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>"); 119362306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 1194