1194 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3* alc5632.c -- ALC5632 ALSA SoC Audio Codec4*5* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>6*7* Authors: Leon Romanovsky <leon@leon.nu>8* Andrey Danin <danindrey@mail.ru>9* Ilya Petrov <ilya.muromec@gmail.com>10* Marc Dietrich <marvin24@gmx.de>11*12* Based on alc5623.c by Arnaud Patard13*/14 15#include <linux/module.h>16#include <linux/kernel.h>17#include <linux/init.h>18#include <linux/delay.h>19#include <linux/pm.h>20#include <linux/i2c.h>21#include <linux/slab.h>22#include <linux/regmap.h>23#include <sound/core.h>24#include <sound/pcm.h>25#include <sound/pcm_params.h>26#include <sound/tlv.h>27#include <sound/soc.h>28#include <sound/initval.h>29 30#include "alc5632.h"31 32/*33 * ALC5632 register cache34 */35static const struct reg_default alc5632_reg_defaults[] = {36 { 2, 0x8080 }, /* R2 - Speaker Output Volume */37 { 4, 0x8080 }, /* R4 - Headphone Output Volume */38 { 6, 0x8080 }, /* R6 - AUXOUT Volume */39 { 8, 0xC800 }, /* R8 - Phone Input */40 { 10, 0xE808 }, /* R10 - LINE_IN Volume */41 { 12, 0x1010 }, /* R12 - STEREO DAC Input Volume */42 { 14, 0x0808 }, /* R14 - MIC Input Volume */43 { 16, 0xEE0F }, /* R16 - Stereo DAC and MIC Routing Control */44 { 18, 0xCBCB }, /* R18 - ADC Record Gain */45 { 20, 0x7F7F }, /* R20 - ADC Record Mixer Control */46 { 24, 0xE010 }, /* R24 - Voice DAC Volume */47 { 28, 0x8008 }, /* R28 - Output Mixer Control */48 { 34, 0x0000 }, /* R34 - Microphone Control */49 { 36, 0x00C0 }, /* R36 - Codec Digital MIC/Digital Boost50 Control */51 { 46, 0x0000 }, /* R46 - Stereo DAC/Voice DAC/Stereo ADC52 Function Select */53 { 52, 0x8000 }, /* R52 - Main Serial Data Port Control54 (Stereo I2S) */55 { 54, 0x0000 }, /* R54 - Extend Serial Data Port Control56 (VoDAC_I2S/PCM) */57 { 58, 0x0000 }, /* R58 - Power Management Addition 1 */58 { 60, 0x0000 }, /* R60 - Power Management Addition 2 */59 { 62, 0x8000 }, /* R62 - Power Management Addition 3 */60 { 64, 0x0C0A }, /* R64 - General Purpose Control Register 1 */61 { 66, 0x0000 }, /* R66 - General Purpose Control Register 2 */62 { 68, 0x0000 }, /* R68 - PLL1 Control */63 { 70, 0x0000 }, /* R70 - PLL2 Control */64 { 76, 0xBE3E }, /* R76 - GPIO Pin Configuration */65 { 78, 0xBE3E }, /* R78 - GPIO Pin Polarity */66 { 80, 0x0000 }, /* R80 - GPIO Pin Sticky */67 { 82, 0x0000 }, /* R82 - GPIO Pin Wake Up */68 { 86, 0x0000 }, /* R86 - Pin Sharing */69 { 90, 0x0009 }, /* R90 - Soft Volume Control Setting */70 { 92, 0x0000 }, /* R92 - GPIO_Output Pin Control */71 { 94, 0x3000 }, /* R94 - MISC Control */72 { 96, 0x3075 }, /* R96 - Stereo DAC Clock Control_1 */73 { 98, 0x1010 }, /* R98 - Stereo DAC Clock Control_2 */74 { 100, 0x3110 }, /* R100 - VoDAC_PCM Clock Control_1 */75 { 104, 0x0553 }, /* R104 - Pseudo Stereo and Spatial Effect76 Block Control */77 { 106, 0x0000 }, /* R106 - Private Register Address */78};79 80/* codec private data */81struct alc5632_priv {82 struct regmap *regmap;83 u8 id;84 unsigned int sysclk;85};86 87static bool alc5632_volatile_register(struct device *dev,88 unsigned int reg)89{90 switch (reg) {91 case ALC5632_RESET:92 case ALC5632_PWR_DOWN_CTRL_STATUS:93 case ALC5632_GPIO_PIN_STATUS:94 case ALC5632_OVER_CURR_STATUS:95 case ALC5632_HID_CTRL_DATA:96 case ALC5632_EQ_CTRL:97 case ALC5632_VENDOR_ID1:98 case ALC5632_VENDOR_ID2:99 return true;100 101 default:102 break;103 }104 105 return false;106}107 108static inline int alc5632_reset(struct regmap *map)109{110 return regmap_write(map, ALC5632_RESET, 0x59B4);111}112 113static int amp_mixer_event(struct snd_soc_dapm_widget *w,114 struct snd_kcontrol *kcontrol, int event)115{116 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);117 118 /* to power-on/off class-d amp generators/speaker */119 /* need to write to 'index-46h' register : */120 /* so write index num (here 0x46) to reg 0x6a */121 /* and then 0xffff/0 to reg 0x6c */122 snd_soc_component_write(component, ALC5632_HID_CTRL_INDEX, 0x46);123 124 switch (event) {125 case SND_SOC_DAPM_PRE_PMU:126 snd_soc_component_write(component, ALC5632_HID_CTRL_DATA, 0xFFFF);127 break;128 case SND_SOC_DAPM_POST_PMD:129 snd_soc_component_write(component, ALC5632_HID_CTRL_DATA, 0);130 break;131 }132 133 return 0;134}135 136/*137 * ALC5632 Controls138 */139 140/* -34.5db min scale, 1.5db steps, no mute */141static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);142/* -46.5db min scale, 1.5db steps, no mute */143static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);144/* -16.5db min scale, 1.5db steps, no mute */145static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);146static const DECLARE_TLV_DB_RANGE(boost_tlv,147 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),148 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0)149);150/* 0db min scale, 6 db steps, no mute */151static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);152/* 0db min scalem 0.75db steps, no mute */153static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0);154 155static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {156 /* left starts at bit 8, right at bit 0 */157 /* 31 steps (5 bit), -46.5db scale */158 SOC_DOUBLE_TLV("Speaker Playback Volume",159 ALC5632_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),160 /* bit 15 mutes left, bit 7 right */161 SOC_DOUBLE("Speaker Playback Switch",162 ALC5632_SPK_OUT_VOL, 15, 7, 1, 1),163 SOC_DOUBLE_TLV("Headphone Playback Volume",164 ALC5632_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),165 SOC_DOUBLE("Headphone Playback Switch",166 ALC5632_HP_OUT_VOL, 15, 7, 1, 1),167};168 169static const struct snd_kcontrol_new alc5632_snd_controls[] = {170 SOC_DOUBLE_TLV("Auxout Playback Volume",171 ALC5632_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),172 SOC_DOUBLE("Auxout Playback Switch",173 ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),174 SOC_SINGLE_TLV("Voice DAC Playback Volume",175 ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),176 SOC_SINGLE("Voice DAC Playback Switch",177 ALC5632_VOICE_DAC_VOL, 12, 1, 1),178 SOC_SINGLE_TLV("Phone Playback Volume",179 ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),180 SOC_DOUBLE_TLV("LineIn Playback Volume",181 ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),182 SOC_DOUBLE_TLV("Master Playback Volume",183 ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),184 SOC_DOUBLE("Master Playback Switch",185 ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),186 SOC_SINGLE_TLV("Mic1 Playback Volume",187 ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),188 SOC_SINGLE_TLV("Mic2 Playback Volume",189 ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),190 SOC_DOUBLE_TLV("Rec Capture Volume",191 ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),192 SOC_SINGLE_TLV("Mic 1 Boost Volume",193 ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv),194 SOC_SINGLE_TLV("Mic 2 Boost Volume",195 ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv),196 SOC_SINGLE_TLV("DMIC Boost Capture Volume",197 ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),198 SOC_SINGLE("DMIC En Capture Switch",199 ALC5632_DIGI_BOOST_CTRL, 15, 1, 0),200 SOC_SINGLE("DMIC PreFilter Capture Switch",201 ALC5632_DIGI_BOOST_CTRL, 12, 1, 0),202};203 204/*205 * DAPM Controls206 */207static const struct snd_kcontrol_new alc5632_hp_mixer_controls[] = {208SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5632_LINE_IN_VOL, 15, 1, 1),209SOC_DAPM_SINGLE("PHONE2HP Playback Switch", ALC5632_PHONE_IN_VOL, 15, 1, 1),210SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 15, 1, 1),211SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 11, 1, 1),212SOC_DAPM_SINGLE("VOICE2HP Playback Switch", ALC5632_VOICE_DAC_VOL, 15, 1, 1),213};214 215static const struct snd_kcontrol_new alc5632_hpl_mixer_controls[] = {216SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5632_ADC_REC_GAIN, 15, 1, 1),217SOC_DAPM_SINGLE("DACL2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 3, 1, 1),218};219 220static const struct snd_kcontrol_new alc5632_hpr_mixer_controls[] = {221SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5632_ADC_REC_GAIN, 7, 1, 1),222SOC_DAPM_SINGLE("DACR2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 2, 1, 1),223};224 225static const struct snd_kcontrol_new alc5632_mono_mixer_controls[] = {226SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5632_ADC_REC_GAIN, 14, 1, 1),227SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5632_ADC_REC_GAIN, 6, 1, 1),228SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5632_LINE_IN_VOL, 13, 1, 1),229SOC_DAPM_SINGLE("MIC12MONO Playback Switch",230 ALC5632_MIC_ROUTING_CTRL, 13, 1, 1),231SOC_DAPM_SINGLE("MIC22MONO Playback Switch",232 ALC5632_MIC_ROUTING_CTRL, 9, 1, 1),233SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5632_MIC_ROUTING_CTRL, 0, 1, 1),234SOC_DAPM_SINGLE("VOICE2MONO Playback Switch", ALC5632_VOICE_DAC_VOL, 13, 1, 1),235};236 237static const struct snd_kcontrol_new alc5632_speaker_mixer_controls[] = {238SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5632_LINE_IN_VOL, 14, 1, 1),239SOC_DAPM_SINGLE("PHONE2SPK Playback Switch", ALC5632_PHONE_IN_VOL, 14, 1, 1),240SOC_DAPM_SINGLE("MIC12SPK Playback Switch",241 ALC5632_MIC_ROUTING_CTRL, 14, 1, 1),242SOC_DAPM_SINGLE("MIC22SPK Playback Switch",243 ALC5632_MIC_ROUTING_CTRL, 10, 1, 1),244SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5632_MIC_ROUTING_CTRL, 1, 1, 1),245SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),246};247 248/* Left Record Mixer */249static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {250SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),251SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),252SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),253SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),254SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),255SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),256SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),257};258 259/* Right Record Mixer */260static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {261SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),262SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),263SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),264SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),265SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),266SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),267SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),268};269 270/* Dmic Mixer */271static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = {272SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1),273};274static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = {275SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1),276};277 278static const char * const alc5632_spk_n_sour_sel[] = {279 "RN/-R", "RP/+R", "LN/-R", "Mute"};280static const char * const alc5632_hpl_out_input_sel[] = {281 "Vmid", "HP Left Mix"};282static const char * const alc5632_hpr_out_input_sel[] = {283 "Vmid", "HP Right Mix"};284static const char * const alc5632_spkout_input_sel[] = {285 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};286static const char * const alc5632_aux_out_input_sel[] = {287 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};288static const char * const alc5632_adcr_func_sel[] = {289 "Stereo ADC", "Voice ADC"};290static const char * const alc5632_i2s_out_sel[] = {291 "ADC LR", "Voice Stereo Digital"};292 293/* auxout output mux */294static SOC_ENUM_SINGLE_DECL(alc5632_aux_out_input_enum,295 ALC5632_OUTPUT_MIXER_CTRL, 6,296 alc5632_aux_out_input_sel);297static const struct snd_kcontrol_new alc5632_auxout_mux_controls =298SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum);299 300/* speaker output mux */301static SOC_ENUM_SINGLE_DECL(alc5632_spkout_input_enum,302 ALC5632_OUTPUT_MIXER_CTRL, 10,303 alc5632_spkout_input_sel);304static const struct snd_kcontrol_new alc5632_spkout_mux_controls =305SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum);306 307/* headphone left output mux */308static SOC_ENUM_SINGLE_DECL(alc5632_hpl_out_input_enum,309 ALC5632_OUTPUT_MIXER_CTRL, 9,310 alc5632_hpl_out_input_sel);311static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls =312SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum);313 314/* headphone right output mux */315static SOC_ENUM_SINGLE_DECL(alc5632_hpr_out_input_enum,316 ALC5632_OUTPUT_MIXER_CTRL, 8,317 alc5632_hpr_out_input_sel);318static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls =319SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum);320 321/* speaker output N select */322static SOC_ENUM_SINGLE_DECL(alc5632_spk_n_sour_enum,323 ALC5632_OUTPUT_MIXER_CTRL, 14,324 alc5632_spk_n_sour_sel);325static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls =326SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum);327 328/* speaker amplifier */329static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"};330static SOC_ENUM_SINGLE_DECL(alc5632_amp_enum,331 ALC5632_OUTPUT_MIXER_CTRL, 13,332 alc5632_amp_names);333static const struct snd_kcontrol_new alc5632_amp_mux_controls =334 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);335 336/* ADC output select */337static SOC_ENUM_SINGLE_DECL(alc5632_adcr_func_enum,338 ALC5632_DAC_FUNC_SELECT, 5,339 alc5632_adcr_func_sel);340static const struct snd_kcontrol_new alc5632_adcr_func_controls =341 SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);342 343/* I2S out select */344static SOC_ENUM_SINGLE_DECL(alc5632_i2s_out_enum,345 ALC5632_I2S_OUT_CTL, 5,346 alc5632_i2s_out_sel);347static const struct snd_kcontrol_new alc5632_i2s_out_controls =348 SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);349 350static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {351/* Muxes */352SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,353 &alc5632_auxout_mux_controls),354SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,355 &alc5632_spkout_mux_controls),356SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,357 &alc5632_hpl_out_mux_controls),358SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,359 &alc5632_hpr_out_mux_controls),360SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,361 &alc5632_spkoutn_mux_controls),362SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,363 &alc5632_adcr_func_controls),364SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0,365 &alc5632_i2s_out_controls),366 367/* output mixers */368SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,369 &alc5632_hp_mixer_controls[0],370 ARRAY_SIZE(alc5632_hp_mixer_controls)),371SND_SOC_DAPM_MIXER("HPR Mix", ALC5632_PWR_MANAG_ADD2, 4, 0,372 &alc5632_hpr_mixer_controls[0],373 ARRAY_SIZE(alc5632_hpr_mixer_controls)),374SND_SOC_DAPM_MIXER("HPL Mix", ALC5632_PWR_MANAG_ADD2, 5, 0,375 &alc5632_hpl_mixer_controls[0],376 ARRAY_SIZE(alc5632_hpl_mixer_controls)),377SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),378SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,379 &alc5632_mono_mixer_controls[0],380 ARRAY_SIZE(alc5632_mono_mixer_controls)),381SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,382 &alc5632_speaker_mixer_controls[0],383 ARRAY_SIZE(alc5632_speaker_mixer_controls)),384SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0,385 &alc5632_dmicl_mixer_controls[0],386 ARRAY_SIZE(alc5632_dmicl_mixer_controls)),387SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0,388 &alc5632_dmicr_mixer_controls[0],389 ARRAY_SIZE(alc5632_dmicr_mixer_controls)),390 391/* input mixers */392SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,393 &alc5632_captureL_mixer_controls[0],394 ARRAY_SIZE(alc5632_captureL_mixer_controls)),395SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,396 &alc5632_captureR_mixer_controls[0],397 ARRAY_SIZE(alc5632_captureR_mixer_controls)),398 399SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0),400SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0),401SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),402SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),403SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0),404SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0),405 406SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0),407SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0),408SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0),409SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0),410SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0),411 412SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),413SND_SOC_DAPM_MIXER("DAC Right Channel",414 ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),415SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),416SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),417SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),418SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0),419SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0),420 421SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),422SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),423SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),424SND_SOC_DAPM_PGA("Right Speaker", ALC5632_PWR_MANAG_ADD3, 12, 0, NULL, 0),425SND_SOC_DAPM_PGA("Aux Out", ALC5632_PWR_MANAG_ADD3, 14, 0, NULL, 0),426SND_SOC_DAPM_PGA("Left LineIn", ALC5632_PWR_MANAG_ADD3, 7, 0, NULL, 0),427SND_SOC_DAPM_PGA("Right LineIn", ALC5632_PWR_MANAG_ADD3, 6, 0, NULL, 0),428SND_SOC_DAPM_PGA("Phone", ALC5632_PWR_MANAG_ADD3, 5, 0, NULL, 0),429SND_SOC_DAPM_PGA("Phone ADMix", ALC5632_PWR_MANAG_ADD3, 4, 0, NULL, 0),430SND_SOC_DAPM_PGA("MIC1 PGA", ALC5632_PWR_MANAG_ADD3, 3, 0, NULL, 0),431SND_SOC_DAPM_PGA("MIC2 PGA", ALC5632_PWR_MANAG_ADD3, 2, 0, NULL, 0),432SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5632_PWR_MANAG_ADD3, 1, 0, NULL, 0),433SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5632_PWR_MANAG_ADD3, 0, 0, NULL, 0),434SND_SOC_DAPM_SUPPLY("MICBIAS1", ALC5632_PWR_MANAG_ADD1, 3, 0, NULL, 0),435SND_SOC_DAPM_SUPPLY("MICBIAS2", ALC5632_PWR_MANAG_ADD1, 2, 0, NULL, 0),436 437SND_SOC_DAPM_PGA_E("D Amp", ALC5632_PWR_MANAG_ADD2, 14, 0, NULL, 0,438 amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),439SND_SOC_DAPM_PGA("AB Amp", ALC5632_PWR_MANAG_ADD2, 15, 0, NULL, 0),440SND_SOC_DAPM_MUX("AB-D Amp Mux", ALC5632_PWR_MANAG_ADD1, 10, 0,441 &alc5632_amp_mux_controls),442 443SND_SOC_DAPM_OUTPUT("AUXOUT"),444SND_SOC_DAPM_OUTPUT("HPL"),445SND_SOC_DAPM_OUTPUT("HPR"),446SND_SOC_DAPM_OUTPUT("SPKOUT"),447SND_SOC_DAPM_OUTPUT("SPKOUTN"),448 449SND_SOC_DAPM_INPUT("LINEINL"),450SND_SOC_DAPM_INPUT("LINEINR"),451SND_SOC_DAPM_INPUT("PHONEP"),452SND_SOC_DAPM_INPUT("PHONEN"),453SND_SOC_DAPM_INPUT("DMICDAT"),454SND_SOC_DAPM_INPUT("MIC1"),455SND_SOC_DAPM_INPUT("MIC2"),456SND_SOC_DAPM_VMID("Vmid"),457};458 459 460static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {461 /* Playback streams */462 {"Left DAC", NULL, "AIFRXL"},463 {"Right DAC", NULL, "AIFRXR"},464 465 /* virtual mixer - mixes left & right channels */466 {"I2S Mix", NULL, "Left DAC"},467 {"I2S Mix", NULL, "Right DAC"},468 {"Line Mix", NULL, "Right LineIn"},469 {"Line Mix", NULL, "Left LineIn"},470 {"Phone Mix", NULL, "Phone"},471 {"Phone Mix", NULL, "Phone ADMix"},472 {"AUXOUT", NULL, "Aux Out"},473 474 /* DAC */475 {"DAC Right Channel", NULL, "I2S Mix"},476 {"DAC Left Channel", NULL, "I2S Mix"},477 478 /* HP mixer */479 {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},480 {"HPL Mix", NULL, "HP Mix"},481 {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},482 {"HPR Mix", NULL, "HP Mix"},483 {"HP Mix", "LI2HP Playback Switch", "Line Mix"},484 {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},485 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},486 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},487 {"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"},488 {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},489 {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},490 {"HPOut Mix", NULL, "HP Mix"},491 {"HPOut Mix", NULL, "HPR Mix"},492 {"HPOut Mix", NULL, "HPL Mix"},493 494 /* speaker mixer */495 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},496 {"Speaker Mix", "PHONE2SPK Playback Switch", "Phone Mix"},497 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},498 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},499 {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},500 {"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"},501 502 /* mono mixer */503 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},504 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},505 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},506 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},507 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},508 {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},509 {"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"},510 511 /* Left record mixer */512 {"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"},513 {"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"},514 {"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"},515 {"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"},516 {"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"},517 {"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"},518 {"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"},519 520 /*Right record mixer */521 {"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"},522 {"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"},523 {"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"},524 {"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"},525 {"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"},526 {"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"},527 {"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"},528 529 /* headphone left mux */530 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},531 {"Left Headphone Mux", "Vmid", "Vmid"},532 533 /* headphone right mux */534 {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},535 {"Right Headphone Mux", "Vmid", "Vmid"},536 537 /* speaker out mux */538 {"SpeakerOut Mux", "Vmid", "Vmid"},539 {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},540 {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},541 {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},542 543 /* Mono/Aux Out mux */544 {"AuxOut Mux", "Vmid", "Vmid"},545 {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},546 {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},547 {"AuxOut Mux", "Mono Mix", "Mono Mix"},548 549 /* output pga */550 {"HPL", NULL, "Left Headphone"},551 {"Left Headphone", NULL, "Left Headphone Mux"},552 {"HPR", NULL, "Right Headphone"},553 {"Right Headphone", NULL, "Right Headphone Mux"},554 {"Aux Out", NULL, "AuxOut Mux"},555 556 /* input pga */557 {"Left LineIn", NULL, "LINEINL"},558 {"Right LineIn", NULL, "LINEINR"},559 {"Phone", NULL, "PHONEP"},560 {"MIC1 Pre Amp", NULL, "MIC1"},561 {"MIC2 Pre Amp", NULL, "MIC2"},562 {"MIC1 PGA", NULL, "MIC1 Pre Amp"},563 {"MIC2 PGA", NULL, "MIC2 Pre Amp"},564 565 /* left ADC */566 {"Left ADC", NULL, "Left Capture Mix"},567 {"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"},568 {"Left ADC", NULL, "DMICL Mix"},569 {"ADCLR", NULL, "Left ADC"},570 571 /* right ADC */572 {"Right ADC", NULL, "Right Capture Mix"},573 {"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"},574 {"Right ADC", NULL, "DMICR Mix"},575 {"ADCR Mux", "Stereo ADC", "Right ADC"},576 {"ADCR Mux", "Voice ADC", "Right ADC"},577 {"ADCLR", NULL, "ADCR Mux"},578 {"VAIFTX", NULL, "ADCR Mux"},579 580 /* Digital I2S out */581 {"I2SOut Mux", "ADC LR", "ADCLR"},582 {"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"},583 {"AIFTXL", NULL, "I2SOut Mux"},584 {"AIFTXR", NULL, "I2SOut Mux"},585 586 /* Voice Mix */587 {"Voice DAC", NULL, "VAIFRX"},588 {"Voice Mix", NULL, "Voice DAC"},589 590 /* Speaker Output */591 {"SpeakerOut N Mux", "RN/-R", "Left Speaker"},592 {"SpeakerOut N Mux", "RP/+R", "Left Speaker"},593 {"SpeakerOut N Mux", "LN/-R", "Left Speaker"},594 {"SpeakerOut N Mux", "Mute", "Vmid"},595 596 {"SpeakerOut N Mux", "RN/-R", "Right Speaker"},597 {"SpeakerOut N Mux", "RP/+R", "Right Speaker"},598 {"SpeakerOut N Mux", "LN/-R", "Right Speaker"},599 {"SpeakerOut N Mux", "Mute", "Vmid"},600 601 {"AB Amp", NULL, "SpeakerOut Mux"},602 {"D Amp", NULL, "SpeakerOut Mux"},603 {"AB-D Amp Mux", "AB Amp", "AB Amp"},604 {"AB-D Amp Mux", "D Amp", "D Amp"},605 {"Left Speaker", NULL, "AB-D Amp Mux"},606 {"Right Speaker", NULL, "AB-D Amp Mux"},607 608 {"SPKOUT", NULL, "Left Speaker"},609 {"SPKOUT", NULL, "Right Speaker"},610 611 {"SPKOUTN", NULL, "SpeakerOut N Mux"},612 613};614 615/* PLL divisors */616struct _pll_div {617 u32 pll_in;618 u32 pll_out;619 u16 regvalue;620};621 622/* Note : pll code from original alc5632 driver. Not sure of how good it is */623/* useful only for master mode */624static const struct _pll_div codec_master_pll_div[] = {625 626 { 2048000, 8192000, 0x0ea0},627 { 3686400, 8192000, 0x4e27},628 { 12000000, 8192000, 0x456b},629 { 13000000, 8192000, 0x495f},630 { 13100000, 8192000, 0x0320},631 { 2048000, 11289600, 0xf637},632 { 3686400, 11289600, 0x2f22},633 { 12000000, 11289600, 0x3e2f},634 { 13000000, 11289600, 0x4d5b},635 { 13100000, 11289600, 0x363b},636 { 2048000, 16384000, 0x1ea0},637 { 3686400, 16384000, 0x9e27},638 { 12000000, 16384000, 0x452b},639 { 13000000, 16384000, 0x542f},640 { 13100000, 16384000, 0x03a0},641 { 2048000, 16934400, 0xe625},642 { 3686400, 16934400, 0x9126},643 { 12000000, 16934400, 0x4d2c},644 { 13000000, 16934400, 0x742f},645 { 13100000, 16934400, 0x3c27},646 { 2048000, 22579200, 0x2aa0},647 { 3686400, 22579200, 0x2f20},648 { 12000000, 22579200, 0x7e2f},649 { 13000000, 22579200, 0x742f},650 { 13100000, 22579200, 0x3c27},651 { 2048000, 24576000, 0x2ea0},652 { 3686400, 24576000, 0xee27},653 { 12000000, 24576000, 0x2915},654 { 13000000, 24576000, 0x772e},655 { 13100000, 24576000, 0x0d20},656};657 658/* FOUT = MCLK*(N+2)/((M+2)*(K+2))659 N: bit 15:8 (div 2 .. div 257)660 K: bit 6:4 typical 2661 M: bit 3:0 (div 2 .. div 17)662 663 same as for 5623 - thanks!664*/665 666static const struct _pll_div codec_slave_pll_div[] = {667 668 { 1024000, 16384000, 0x3ea0},669 { 1411200, 22579200, 0x3ea0},670 { 1536000, 24576000, 0x3ea0},671 { 2048000, 16384000, 0x1ea0},672 { 2822400, 22579200, 0x1ea0},673 { 3072000, 24576000, 0x1ea0},674 675};676 677static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,678 int source, unsigned int freq_in, unsigned int freq_out)679{680 int i;681 struct snd_soc_component *component = codec_dai->component;682 int gbl_clk = 0, pll_div = 0;683 u16 reg;684 685 if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK)686 return -EINVAL;687 688 /* Disable PLL power */689 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,690 ALC5632_PWR_ADD2_PLL1,691 0);692 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,693 ALC5632_PWR_ADD2_PLL2,694 0);695 696 /* pll is not used in slave mode */697 reg = snd_soc_component_read(component, ALC5632_DAI_CONTROL);698 if (reg & ALC5632_DAI_SDP_SLAVE_MODE)699 return 0;700 701 if (!freq_in || !freq_out)702 return 0;703 704 switch (pll_id) {705 case ALC5632_PLL_FR_MCLK:706 for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {707 if (codec_master_pll_div[i].pll_in == freq_in708 && codec_master_pll_div[i].pll_out == freq_out) {709 /* PLL source from MCLK */710 pll_div = codec_master_pll_div[i].regvalue;711 break;712 }713 }714 break;715 case ALC5632_PLL_FR_BCLK:716 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {717 if (codec_slave_pll_div[i].pll_in == freq_in718 && codec_slave_pll_div[i].pll_out == freq_out) {719 /* PLL source from Bitclk */720 gbl_clk = ALC5632_PLL_FR_BCLK;721 pll_div = codec_slave_pll_div[i].regvalue;722 break;723 }724 }725 break;726 case ALC5632_PLL_FR_VBCLK:727 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {728 if (codec_slave_pll_div[i].pll_in == freq_in729 && codec_slave_pll_div[i].pll_out == freq_out) {730 /* PLL source from voice clock */731 gbl_clk = ALC5632_PLL_FR_VBCLK;732 pll_div = codec_slave_pll_div[i].regvalue;733 break;734 }735 }736 break;737 default:738 return -EINVAL;739 }740 741 if (!pll_div)742 return -EINVAL;743 744 /* choose MCLK/BCLK/VBCLK */745 snd_soc_component_write(component, ALC5632_GPCR2, gbl_clk);746 /* choose PLL1 clock rate */747 snd_soc_component_write(component, ALC5632_PLL1_CTRL, pll_div);748 /* enable PLL1 */749 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,750 ALC5632_PWR_ADD2_PLL1,751 ALC5632_PWR_ADD2_PLL1);752 /* enable PLL2 */753 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,754 ALC5632_PWR_ADD2_PLL2,755 ALC5632_PWR_ADD2_PLL2);756 /* use PLL1 as main SYSCLK */757 snd_soc_component_update_bits(component, ALC5632_GPCR1,758 ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,759 ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);760 761 return 0;762}763 764struct _coeff_div {765 u16 fs;766 u16 regvalue;767};768 769/* codec hifi mclk (after PLL) clock divider coefficients */770/* values inspired from column BCLK=32Fs of Appendix A table */771static const struct _coeff_div coeff_div[] = {772 {512*1, 0x3075},773};774 775static int get_coeff(struct snd_soc_component *component, int rate)776{777 struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);778 int i;779 780 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {781 if (coeff_div[i].fs * rate == alc5632->sysclk)782 return i;783 }784 return -EINVAL;785}786 787/*788 * Clock after PLL and dividers789 */790static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,791 int clk_id, unsigned int freq, int dir)792{793 struct snd_soc_component *component = codec_dai->component;794 struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);795 796 switch (freq) {797 case 4096000:798 case 8192000:799 case 11289600:800 case 12288000:801 case 16384000:802 case 16934400:803 case 18432000:804 case 22579200:805 case 24576000:806 alc5632->sysclk = freq;807 return 0;808 }809 return -EINVAL;810}811 812static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,813 unsigned int fmt)814{815 struct snd_soc_component *component = codec_dai->component;816 u16 iface = 0;817 818 /* set audio interface clocking */819 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {820 case SND_SOC_DAIFMT_CBP_CFP:821 iface = ALC5632_DAI_SDP_MASTER_MODE;822 break;823 case SND_SOC_DAIFMT_CBC_CFC:824 iface = ALC5632_DAI_SDP_SLAVE_MODE;825 break;826 default:827 return -EINVAL;828 }829 830 /* interface format */831 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {832 case SND_SOC_DAIFMT_I2S:833 iface |= ALC5632_DAI_I2S_DF_I2S;834 break;835 case SND_SOC_DAIFMT_LEFT_J:836 iface |= ALC5632_DAI_I2S_DF_LEFT;837 break;838 case SND_SOC_DAIFMT_DSP_A:839 iface |= ALC5632_DAI_I2S_DF_PCM_A;840 break;841 case SND_SOC_DAIFMT_DSP_B:842 iface |= ALC5632_DAI_I2S_DF_PCM_B;843 break;844 default:845 return -EINVAL;846 }847 848 /* clock inversion */849 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {850 case SND_SOC_DAIFMT_NB_NF:851 break;852 case SND_SOC_DAIFMT_IB_IF:853 iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;854 break;855 case SND_SOC_DAIFMT_IB_NF:856 iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;857 break;858 case SND_SOC_DAIFMT_NB_IF:859 break;860 default:861 return -EINVAL;862 }863 864 return snd_soc_component_write(component, ALC5632_DAI_CONTROL, iface);865}866 867static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,868 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)869{870 struct snd_soc_component *component = dai->component;871 int coeff, rate;872 u16 iface;873 874 iface = snd_soc_component_read(component, ALC5632_DAI_CONTROL);875 iface &= ~ALC5632_DAI_I2S_DL_MASK;876 877 /* bit size */878 switch (params_width(params)) {879 case 16:880 iface |= ALC5632_DAI_I2S_DL_16;881 break;882 case 20:883 iface |= ALC5632_DAI_I2S_DL_20;884 break;885 case 24:886 iface |= ALC5632_DAI_I2S_DL_24;887 break;888 default:889 return -EINVAL;890 }891 892 /* set iface & srate */893 snd_soc_component_write(component, ALC5632_DAI_CONTROL, iface);894 rate = params_rate(params);895 coeff = get_coeff(component, rate);896 if (coeff < 0)897 return -EINVAL;898 899 coeff = coeff_div[coeff].regvalue;900 snd_soc_component_write(component, ALC5632_DAC_CLK_CTRL1, coeff);901 902 return 0;903}904 905static int alc5632_mute(struct snd_soc_dai *dai, int mute, int direction)906{907 struct snd_soc_component *component = dai->component;908 u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L909 |ALC5632_MISC_HP_DEPOP_MUTE_R;910 u16 mute_reg = snd_soc_component_read(component, ALC5632_MISC_CTRL) & ~hp_mute;911 912 if (mute)913 mute_reg |= hp_mute;914 915 return snd_soc_component_write(component, ALC5632_MISC_CTRL, mute_reg);916}917 918#define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)919 920#define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD)921 922#define ALC5632_ADD1_POWER_EN \923 (ALC5632_PWR_ADD1_DAC_REF \924 | ALC5632_PWR_ADD1_SOFTGEN_EN \925 | ALC5632_PWR_ADD1_HP_OUT_AMP \926 | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \927 | ALC5632_PWR_ADD1_MAIN_BIAS)928 929static void enable_power_depop(struct snd_soc_component *component)930{931 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,932 ALC5632_PWR_ADD1_SOFTGEN_EN,933 ALC5632_PWR_ADD1_SOFTGEN_EN);934 935 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD3,936 ALC5632_ADD3_POWER_EN,937 ALC5632_ADD3_POWER_EN);938 939 snd_soc_component_update_bits(component, ALC5632_MISC_CTRL,940 ALC5632_MISC_HP_DEPOP_MODE2_EN,941 ALC5632_MISC_HP_DEPOP_MODE2_EN);942 943 /* "normal" mode: 0 @ 26 */944 /* set all PR0-7 mixers to 0 */945 snd_soc_component_update_bits(component, ALC5632_PWR_DOWN_CTRL_STATUS,946 ALC5632_PWR_DOWN_CTRL_STATUS_MASK,947 0);948 949 msleep(500);950 951 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,952 ALC5632_ADD2_POWER_EN,953 ALC5632_ADD2_POWER_EN);954 955 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,956 ALC5632_ADD1_POWER_EN,957 ALC5632_ADD1_POWER_EN);958 959 /* disable HP Depop2 */960 snd_soc_component_update_bits(component, ALC5632_MISC_CTRL,961 ALC5632_MISC_HP_DEPOP_MODE2_EN,962 0);963 964}965 966static int alc5632_set_bias_level(struct snd_soc_component *component,967 enum snd_soc_bias_level level)968{969 switch (level) {970 case SND_SOC_BIAS_ON:971 enable_power_depop(component);972 break;973 case SND_SOC_BIAS_PREPARE:974 break;975 case SND_SOC_BIAS_STANDBY:976 /* everything off except vref/vmid, */977 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,978 ALC5632_PWR_MANAG_ADD1_MASK,979 ALC5632_PWR_ADD1_MAIN_BIAS);980 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,981 ALC5632_PWR_MANAG_ADD2_MASK,982 ALC5632_PWR_ADD2_VREF);983 /* "normal" mode: 0 @ 26 */984 snd_soc_component_update_bits(component, ALC5632_PWR_DOWN_CTRL_STATUS,985 ALC5632_PWR_DOWN_CTRL_STATUS_MASK,986 0xffff ^ (ALC5632_PWR_VREF_PR3987 | ALC5632_PWR_VREF_PR2));988 break;989 case SND_SOC_BIAS_OFF:990 /* everything off, dac mute, inactive */991 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,992 ALC5632_PWR_MANAG_ADD2_MASK, 0);993 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD3,994 ALC5632_PWR_MANAG_ADD3_MASK, 0);995 snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,996 ALC5632_PWR_MANAG_ADD1_MASK, 0);997 break;998 }999 return 0;1000}1001 1002#define ALC5632_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \1003 | SNDRV_PCM_FMTBIT_S24_LE \1004 | SNDRV_PCM_FMTBIT_S32_LE)1005 1006static const struct snd_soc_dai_ops alc5632_dai_ops = {1007 .hw_params = alc5632_pcm_hw_params,1008 .mute_stream = alc5632_mute,1009 .set_fmt = alc5632_set_dai_fmt,1010 .set_sysclk = alc5632_set_dai_sysclk,1011 .set_pll = alc5632_set_dai_pll,1012 .no_capture_mute = 1,1013};1014 1015static struct snd_soc_dai_driver alc5632_dai = {1016 .name = "alc5632-hifi",1017 .playback = {1018 .stream_name = "HiFi Playback",1019 .channels_min = 1,1020 .channels_max = 2,1021 .rate_min = 8000,1022 .rate_max = 48000,1023 .rates = SNDRV_PCM_RATE_8000_48000,1024 .formats = ALC5632_FORMATS,},1025 .capture = {1026 .stream_name = "HiFi Capture",1027 .channels_min = 1,1028 .channels_max = 2,1029 .rate_min = 8000,1030 .rate_max = 48000,1031 .rates = SNDRV_PCM_RATE_8000_48000,1032 .formats = ALC5632_FORMATS,},1033 1034 .ops = &alc5632_dai_ops,1035 .symmetric_rate = 1,1036};1037 1038#ifdef CONFIG_PM1039static int alc5632_resume(struct snd_soc_component *component)1040{1041 struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);1042 1043 regcache_sync(alc5632->regmap);1044 1045 return 0;1046}1047#else1048#define alc5632_resume NULL1049#endif1050 1051static int alc5632_probe(struct snd_soc_component *component)1052{1053 struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);1054 1055 switch (alc5632->id) {1056 case 0x5c:1057 snd_soc_add_component_controls(component, alc5632_vol_snd_controls,1058 ARRAY_SIZE(alc5632_vol_snd_controls));1059 break;1060 default:1061 return -EINVAL;1062 }1063 1064 return 0;1065}1066 1067static const struct snd_soc_component_driver soc_component_device_alc5632 = {1068 .probe = alc5632_probe,1069 .resume = alc5632_resume,1070 .set_bias_level = alc5632_set_bias_level,1071 .controls = alc5632_snd_controls,1072 .num_controls = ARRAY_SIZE(alc5632_snd_controls),1073 .dapm_widgets = alc5632_dapm_widgets,1074 .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets),1075 .dapm_routes = alc5632_dapm_routes,1076 .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),1077 .suspend_bias_off = 1,1078 .idle_bias_on = 1,1079 .use_pmdown_time = 1,1080 .endianness = 1,1081};1082 1083static const struct regmap_config alc5632_regmap = {1084 .reg_bits = 8,1085 .val_bits = 16,1086 1087 .max_register = ALC5632_MAX_REGISTER,1088 .reg_defaults = alc5632_reg_defaults,1089 .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults),1090 .volatile_reg = alc5632_volatile_register,1091 .cache_type = REGCACHE_RBTREE,1092};1093 1094static const struct i2c_device_id alc5632_i2c_table[] = {1095 {"alc5632", 0x5c},1096 {}1097};1098MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);1099 1100/*1101 * alc5632 2 wire address is determined by A1 pin1102 * state during powerup.1103 * low = 0x1a1104 * high = 0x1b1105 */1106static int alc5632_i2c_probe(struct i2c_client *client)1107{1108 struct alc5632_priv *alc5632;1109 int ret, ret1, ret2;1110 unsigned int vid1, vid2;1111 const struct i2c_device_id *id;1112 1113 alc5632 = devm_kzalloc(&client->dev,1114 sizeof(struct alc5632_priv), GFP_KERNEL);1115 if (alc5632 == NULL)1116 return -ENOMEM;1117 1118 i2c_set_clientdata(client, alc5632);1119 1120 alc5632->regmap = devm_regmap_init_i2c(client, &alc5632_regmap);1121 if (IS_ERR(alc5632->regmap)) {1122 ret = PTR_ERR(alc5632->regmap);1123 dev_err(&client->dev, "regmap_init() failed: %d\n", ret);1124 return ret;1125 }1126 1127 ret1 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID1, &vid1);1128 ret2 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID2, &vid2);1129 if (ret1 != 0 || ret2 != 0) {1130 dev_err(&client->dev,1131 "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2);1132 return -EIO;1133 }1134 1135 vid2 >>= 8;1136 1137 id = i2c_match_id(alc5632_i2c_table, client);1138 1139 if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) {1140 dev_err(&client->dev,1141 "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2);1142 return -EINVAL;1143 }1144 1145 ret = alc5632_reset(alc5632->regmap);1146 if (ret < 0) {1147 dev_err(&client->dev, "Failed to issue reset\n");1148 return ret;1149 }1150 1151 alc5632->id = vid2;1152 switch (alc5632->id) {1153 case 0x5c:1154 alc5632_dai.name = "alc5632-hifi";1155 break;1156 default:1157 return -EINVAL;1158 }1159 1160 ret = devm_snd_soc_register_component(&client->dev,1161 &soc_component_device_alc5632, &alc5632_dai, 1);1162 1163 if (ret < 0) {1164 dev_err(&client->dev, "Failed to register component: %d\n", ret);1165 return ret;1166 }1167 1168 return ret;1169}1170 1171#ifdef CONFIG_OF1172static const struct of_device_id alc5632_of_match[] = {1173 { .compatible = "realtek,alc5632", },1174 { }1175};1176MODULE_DEVICE_TABLE(of, alc5632_of_match);1177#endif1178 1179/* i2c codec control layer */1180static struct i2c_driver alc5632_i2c_driver = {1181 .driver = {1182 .name = "alc5632",1183 .of_match_table = of_match_ptr(alc5632_of_match),1184 },1185 .probe = alc5632_i2c_probe,1186 .id_table = alc5632_i2c_table,1187};1188 1189module_i2c_driver(alc5632_i2c_driver);1190 1191MODULE_DESCRIPTION("ASoC ALC5632 driver");1192MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");1193MODULE_LICENSE("GPL");1194