Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * ak4671.c  --  audio driver for AK4671
0004  *
0005  * Copyright (C) 2009 Samsung Electronics Co.Ltd
0006  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/i2c.h>
0012 #include <linux/delay.h>
0013 #include <linux/regmap.h>
0014 #include <linux/slab.h>
0015 #include <sound/soc.h>
0016 #include <sound/initval.h>
0017 #include <sound/tlv.h>
0018 
0019 #include "ak4671.h"
0020 
0021 
0022 /* ak4671 register cache & default register settings */
0023 static const struct reg_default ak4671_reg_defaults[] = {
0024     { 0x00, 0x00 }, /* AK4671_AD_DA_POWER_MANAGEMENT    (0x00)  */
0025     { 0x01, 0xf6 }, /* AK4671_PLL_MODE_SELECT0      (0x01)  */
0026     { 0x02, 0x00 }, /* AK4671_PLL_MODE_SELECT1      (0x02)  */
0027     { 0x03, 0x02 }, /* AK4671_FORMAT_SELECT         (0x03)  */
0028     { 0x04, 0x00 }, /* AK4671_MIC_SIGNAL_SELECT     (0x04)  */
0029     { 0x05, 0x55 }, /* AK4671_MIC_AMP_GAIN          (0x05)  */
0030     { 0x06, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT0  (0x06)  */
0031     { 0x07, 0x00 }, /* AK4671_MIXING_POWER_MANAGEMENT1  (0x07)  */
0032     { 0x08, 0xb5 }, /* AK4671_OUTPUT_VOLUME_CONTROL     (0x08)  */
0033     { 0x09, 0x00 }, /* AK4671_LOUT1_SIGNAL_SELECT       (0x09)  */
0034     { 0x0a, 0x00 }, /* AK4671_ROUT1_SIGNAL_SELECT       (0x0a)  */
0035     { 0x0b, 0x00 }, /* AK4671_LOUT2_SIGNAL_SELECT       (0x0b)  */
0036     { 0x0c, 0x00 }, /* AK4671_ROUT2_SIGNAL_SELECT       (0x0c)  */
0037     { 0x0d, 0x00 }, /* AK4671_LOUT3_SIGNAL_SELECT       (0x0d)  */
0038     { 0x0e, 0x00 }, /* AK4671_ROUT3_SIGNAL_SELECT       (0x0e)  */
0039     { 0x0f, 0x00 }, /* AK4671_LOUT1_POWER_MANAGERMENT   (0x0f)  */
0040     { 0x10, 0x00 }, /* AK4671_LOUT2_POWER_MANAGERMENT   (0x10)  */
0041     { 0x11, 0x80 }, /* AK4671_LOUT3_POWER_MANAGERMENT   (0x11)  */
0042     { 0x12, 0x91 }, /* AK4671_LCH_INPUT_VOLUME_CONTROL  (0x12)  */
0043     { 0x13, 0x91 }, /* AK4671_RCH_INPUT_VOLUME_CONTROL  (0x13)  */
0044     { 0x14, 0xe1 }, /* AK4671_ALC_REFERENCE_SELECT      (0x14)  */
0045     { 0x15, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL    (0x15)  */
0046     { 0x16, 0x00 }, /* AK4671_ALC_TIMER_SELECT      (0x16)  */
0047     { 0x17, 0x00 }, /* AK4671_ALC_MODE_CONTROL      (0x17)  */
0048     { 0x18, 0x02 }, /* AK4671_MODE_CONTROL1         (0x18)  */
0049     { 0x19, 0x01 }, /* AK4671_MODE_CONTROL2         (0x19)  */
0050     { 0x1a, 0x18 }, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a)  */
0051     { 0x1b, 0x18 }, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b)  */
0052     { 0x1c, 0x00 }, /* AK4671_SIDETONE_A_CONTROL        (0x1c)  */
0053     { 0x1d, 0x02 }, /* AK4671_DIGITAL_FILTER_SELECT     (0x1d)  */
0054     { 0x1e, 0x00 }, /* AK4671_FIL3_COEFFICIENT0     (0x1e)  */
0055     { 0x1f, 0x00 }, /* AK4671_FIL3_COEFFICIENT1     (0x1f)  */
0056     { 0x20, 0x00 }, /* AK4671_FIL3_COEFFICIENT2     (0x20)  */
0057     { 0x21, 0x00 }, /* AK4671_FIL3_COEFFICIENT3     (0x21)  */
0058     { 0x22, 0x00 }, /* AK4671_EQ_COEFFICIENT0       (0x22)  */
0059     { 0x23, 0x00 }, /* AK4671_EQ_COEFFICIENT1       (0x23)  */
0060     { 0x24, 0x00 }, /* AK4671_EQ_COEFFICIENT2       (0x24)  */
0061     { 0x25, 0x00 }, /* AK4671_EQ_COEFFICIENT3       (0x25)  */
0062     { 0x26, 0x00 }, /* AK4671_EQ_COEFFICIENT4       (0x26)  */
0063     { 0x27, 0x00 }, /* AK4671_EQ_COEFFICIENT5       (0x27)  */
0064     { 0x28, 0xa9 }, /* AK4671_FIL1_COEFFICIENT0     (0x28)  */
0065     { 0x29, 0x1f }, /* AK4671_FIL1_COEFFICIENT1     (0x29)  */
0066     { 0x2a, 0xad }, /* AK4671_FIL1_COEFFICIENT2     (0x2a)  */
0067     { 0x2b, 0x20 }, /* AK4671_FIL1_COEFFICIENT3     (0x2b)  */
0068     { 0x2c, 0x00 }, /* AK4671_FIL2_COEFFICIENT0     (0x2c)  */
0069     { 0x2d, 0x00 }, /* AK4671_FIL2_COEFFICIENT1     (0x2d)  */
0070     { 0x2e, 0x00 }, /* AK4671_FIL2_COEFFICIENT2     (0x2e)  */
0071     { 0x2f, 0x00 }, /* AK4671_FIL2_COEFFICIENT3     (0x2f)  */
0072     { 0x30, 0x00 }, /* AK4671_DIGITAL_FILTER_SELECT2    (0x30)  */
0073 
0074     { 0x32, 0x00 }, /* AK4671_E1_COEFFICIENT0       (0x32)  */
0075     { 0x33, 0x00 }, /* AK4671_E1_COEFFICIENT1       (0x33)  */
0076     { 0x34, 0x00 }, /* AK4671_E1_COEFFICIENT2       (0x34)  */
0077     { 0x35, 0x00 }, /* AK4671_E1_COEFFICIENT3       (0x35)  */
0078     { 0x36, 0x00 }, /* AK4671_E1_COEFFICIENT4       (0x36)  */
0079     { 0x37, 0x00 }, /* AK4671_E1_COEFFICIENT5       (0x37)  */
0080     { 0x38, 0x00 }, /* AK4671_E2_COEFFICIENT0       (0x38)  */
0081     { 0x39, 0x00 }, /* AK4671_E2_COEFFICIENT1       (0x39)  */
0082     { 0x3a, 0x00 }, /* AK4671_E2_COEFFICIENT2       (0x3a)  */
0083     { 0x3b, 0x00 }, /* AK4671_E2_COEFFICIENT3       (0x3b)  */
0084     { 0x3c, 0x00 }, /* AK4671_E2_COEFFICIENT4       (0x3c)  */
0085     { 0x3d, 0x00 }, /* AK4671_E2_COEFFICIENT5       (0x3d)  */
0086     { 0x3e, 0x00 }, /* AK4671_E3_COEFFICIENT0       (0x3e)  */
0087     { 0x3f, 0x00 }, /* AK4671_E3_COEFFICIENT1       (0x3f)  */
0088     { 0x40, 0x00 }, /* AK4671_E3_COEFFICIENT2       (0x40)  */
0089     { 0x41, 0x00 }, /* AK4671_E3_COEFFICIENT3       (0x41)  */
0090     { 0x42, 0x00 }, /* AK4671_E3_COEFFICIENT4       (0x42)  */
0091     { 0x43, 0x00 }, /* AK4671_E3_COEFFICIENT5       (0x43)  */
0092     { 0x44, 0x00 }, /* AK4671_E4_COEFFICIENT0       (0x44)  */
0093     { 0x45, 0x00 }, /* AK4671_E4_COEFFICIENT1       (0x45)  */
0094     { 0x46, 0x00 }, /* AK4671_E4_COEFFICIENT2       (0x46)  */
0095     { 0x47, 0x00 }, /* AK4671_E4_COEFFICIENT3       (0x47)  */
0096     { 0x48, 0x00 }, /* AK4671_E4_COEFFICIENT4       (0x48)  */
0097     { 0x49, 0x00 }, /* AK4671_E4_COEFFICIENT5       (0x49)  */
0098     { 0x4a, 0x00 }, /* AK4671_E5_COEFFICIENT0       (0x4a)  */
0099     { 0x4b, 0x00 }, /* AK4671_E5_COEFFICIENT1       (0x4b)  */
0100     { 0x4c, 0x00 }, /* AK4671_E5_COEFFICIENT2       (0x4c)  */
0101     { 0x4d, 0x00 }, /* AK4671_E5_COEFFICIENT3       (0x4d)  */
0102     { 0x4e, 0x00 }, /* AK4671_E5_COEFFICIENT4       (0x4e)  */
0103     { 0x4f, 0x00 }, /* AK4671_E5_COEFFICIENT5       (0x4f)  */
0104     { 0x50, 0x88 }, /* AK4671_EQ_CONTROL_250HZ_100HZ    (0x50)  */
0105     { 0x51, 0x88 }, /* AK4671_EQ_CONTROL_3500HZ_1KHZ    (0x51)  */
0106     { 0x52, 0x08 }, /* AK4671_EQ_CONTRO_10KHZ       (0x52)  */
0107     { 0x53, 0x00 }, /* AK4671_PCM_IF_CONTROL0       (0x53)  */
0108     { 0x54, 0x00 }, /* AK4671_PCM_IF_CONTROL1       (0x54)  */
0109     { 0x55, 0x00 }, /* AK4671_PCM_IF_CONTROL2       (0x55)  */
0110     { 0x56, 0x18 }, /* AK4671_DIGITAL_VOLUME_B_CONTROL  (0x56)  */
0111     { 0x57, 0x18 }, /* AK4671_DIGITAL_VOLUME_C_CONTROL  (0x57)  */
0112     { 0x58, 0x00 }, /* AK4671_SIDETONE_VOLUME_CONTROL   (0x58)  */
0113     { 0x59, 0x00 }, /* AK4671_DIGITAL_MIXING_CONTROL2   (0x59)  */
0114     { 0x5a, 0x00 }, /* AK4671_SAR_ADC_CONTROL       (0x5a)  */
0115 };
0116 
0117 /*
0118  * LOUT1/ROUT1 output volume control:
0119  * from -24 to 6 dB in 6 dB steps (mute instead of -30 dB)
0120  */
0121 static DECLARE_TLV_DB_SCALE(out1_tlv, -3000, 600, 1);
0122 
0123 /*
0124  * LOUT2/ROUT2 output volume control:
0125  * from -33 to 6 dB in 3 dB steps (mute instead of -33 dB)
0126  */
0127 static DECLARE_TLV_DB_SCALE(out2_tlv, -3300, 300, 1);
0128 
0129 /*
0130  * LOUT3/ROUT3 output volume control:
0131  * from -6 to 3 dB in 3 dB steps
0132  */
0133 static DECLARE_TLV_DB_SCALE(out3_tlv, -600, 300, 0);
0134 
0135 /*
0136  * Mic amp gain control:
0137  * from -15 to 30 dB in 3 dB steps
0138  * REVISIT: The actual min value(0x01) is -12 dB and the reg value 0x00 is not
0139  * available
0140  */
0141 static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -1500, 300, 0);
0142 
0143 static const struct snd_kcontrol_new ak4671_snd_controls[] = {
0144     /* Common playback gain controls */
0145     SOC_SINGLE_TLV("Line Output1 Playback Volume",
0146             AK4671_OUTPUT_VOLUME_CONTROL, 0, 0x6, 0, out1_tlv),
0147     SOC_SINGLE_TLV("Headphone Output2 Playback Volume",
0148             AK4671_OUTPUT_VOLUME_CONTROL, 4, 0xd, 0, out2_tlv),
0149     SOC_SINGLE_TLV("Line Output3 Playback Volume",
0150             AK4671_LOUT3_POWER_MANAGERMENT, 6, 0x3, 0, out3_tlv),
0151 
0152     /* Common capture gain controls */
0153     SOC_DOUBLE_TLV("Mic Amp Capture Volume",
0154             AK4671_MIC_AMP_GAIN, 0, 4, 0xf, 0, mic_amp_tlv),
0155 };
0156 
0157 /* event handlers */
0158 static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
0159         struct snd_kcontrol *kcontrol, int event)
0160 {
0161     struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0162 
0163     switch (event) {
0164     case SND_SOC_DAPM_POST_PMU:
0165         snd_soc_component_update_bits(component, AK4671_LOUT2_POWER_MANAGERMENT,
0166                     AK4671_MUTEN, AK4671_MUTEN);
0167         break;
0168     case SND_SOC_DAPM_PRE_PMD:
0169         snd_soc_component_update_bits(component, AK4671_LOUT2_POWER_MANAGERMENT,
0170                     AK4671_MUTEN, 0);
0171         break;
0172     }
0173 
0174     return 0;
0175 }
0176 
0177 /* Output Mixers */
0178 static const struct snd_kcontrol_new ak4671_lout1_mixer_controls[] = {
0179     SOC_DAPM_SINGLE("DACL", AK4671_LOUT1_SIGNAL_SELECT, 0, 1, 0),
0180     SOC_DAPM_SINGLE("LINL1", AK4671_LOUT1_SIGNAL_SELECT, 1, 1, 0),
0181     SOC_DAPM_SINGLE("LINL2", AK4671_LOUT1_SIGNAL_SELECT, 2, 1, 0),
0182     SOC_DAPM_SINGLE("LINL3", AK4671_LOUT1_SIGNAL_SELECT, 3, 1, 0),
0183     SOC_DAPM_SINGLE("LINL4", AK4671_LOUT1_SIGNAL_SELECT, 4, 1, 0),
0184     SOC_DAPM_SINGLE("LOOPL", AK4671_LOUT1_SIGNAL_SELECT, 5, 1, 0),
0185 };
0186 
0187 static const struct snd_kcontrol_new ak4671_rout1_mixer_controls[] = {
0188     SOC_DAPM_SINGLE("DACR", AK4671_ROUT1_SIGNAL_SELECT, 0, 1, 0),
0189     SOC_DAPM_SINGLE("RINR1", AK4671_ROUT1_SIGNAL_SELECT, 1, 1, 0),
0190     SOC_DAPM_SINGLE("RINR2", AK4671_ROUT1_SIGNAL_SELECT, 2, 1, 0),
0191     SOC_DAPM_SINGLE("RINR3", AK4671_ROUT1_SIGNAL_SELECT, 3, 1, 0),
0192     SOC_DAPM_SINGLE("RINR4", AK4671_ROUT1_SIGNAL_SELECT, 4, 1, 0),
0193     SOC_DAPM_SINGLE("LOOPR", AK4671_ROUT1_SIGNAL_SELECT, 5, 1, 0),
0194 };
0195 
0196 static const struct snd_kcontrol_new ak4671_lout2_mixer_controls[] = {
0197     SOC_DAPM_SINGLE("DACHL", AK4671_LOUT2_SIGNAL_SELECT, 0, 1, 0),
0198     SOC_DAPM_SINGLE("LINH1", AK4671_LOUT2_SIGNAL_SELECT, 1, 1, 0),
0199     SOC_DAPM_SINGLE("LINH2", AK4671_LOUT2_SIGNAL_SELECT, 2, 1, 0),
0200     SOC_DAPM_SINGLE("LINH3", AK4671_LOUT2_SIGNAL_SELECT, 3, 1, 0),
0201     SOC_DAPM_SINGLE("LINH4", AK4671_LOUT2_SIGNAL_SELECT, 4, 1, 0),
0202     SOC_DAPM_SINGLE("LOOPHL", AK4671_LOUT2_SIGNAL_SELECT, 5, 1, 0),
0203 };
0204 
0205 static const struct snd_kcontrol_new ak4671_rout2_mixer_controls[] = {
0206     SOC_DAPM_SINGLE("DACHR", AK4671_ROUT2_SIGNAL_SELECT, 0, 1, 0),
0207     SOC_DAPM_SINGLE("RINH1", AK4671_ROUT2_SIGNAL_SELECT, 1, 1, 0),
0208     SOC_DAPM_SINGLE("RINH2", AK4671_ROUT2_SIGNAL_SELECT, 2, 1, 0),
0209     SOC_DAPM_SINGLE("RINH3", AK4671_ROUT2_SIGNAL_SELECT, 3, 1, 0),
0210     SOC_DAPM_SINGLE("RINH4", AK4671_ROUT2_SIGNAL_SELECT, 4, 1, 0),
0211     SOC_DAPM_SINGLE("LOOPHR", AK4671_ROUT2_SIGNAL_SELECT, 5, 1, 0),
0212 };
0213 
0214 static const struct snd_kcontrol_new ak4671_lout3_mixer_controls[] = {
0215     SOC_DAPM_SINGLE("DACSL", AK4671_LOUT3_SIGNAL_SELECT, 0, 1, 0),
0216     SOC_DAPM_SINGLE("LINS1", AK4671_LOUT3_SIGNAL_SELECT, 1, 1, 0),
0217     SOC_DAPM_SINGLE("LINS2", AK4671_LOUT3_SIGNAL_SELECT, 2, 1, 0),
0218     SOC_DAPM_SINGLE("LINS3", AK4671_LOUT3_SIGNAL_SELECT, 3, 1, 0),
0219     SOC_DAPM_SINGLE("LINS4", AK4671_LOUT3_SIGNAL_SELECT, 4, 1, 0),
0220     SOC_DAPM_SINGLE("LOOPSL", AK4671_LOUT3_SIGNAL_SELECT, 5, 1, 0),
0221 };
0222 
0223 static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
0224     SOC_DAPM_SINGLE("DACSR", AK4671_ROUT3_SIGNAL_SELECT, 0, 1, 0),
0225     SOC_DAPM_SINGLE("RINS1", AK4671_ROUT3_SIGNAL_SELECT, 1, 1, 0),
0226     SOC_DAPM_SINGLE("RINS2", AK4671_ROUT3_SIGNAL_SELECT, 2, 1, 0),
0227     SOC_DAPM_SINGLE("RINS3", AK4671_ROUT3_SIGNAL_SELECT, 3, 1, 0),
0228     SOC_DAPM_SINGLE("RINS4", AK4671_ROUT3_SIGNAL_SELECT, 4, 1, 0),
0229     SOC_DAPM_SINGLE("LOOPSR", AK4671_ROUT3_SIGNAL_SELECT, 5, 1, 0),
0230 };
0231 
0232 /* Input MUXs */
0233 static const char *ak4671_lin_mux_texts[] =
0234         {"LIN1", "LIN2", "LIN3", "LIN4"};
0235 static SOC_ENUM_SINGLE_DECL(ak4671_lin_mux_enum,
0236                 AK4671_MIC_SIGNAL_SELECT, 0,
0237                 ak4671_lin_mux_texts);
0238 static const struct snd_kcontrol_new ak4671_lin_mux_control =
0239     SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
0240 
0241 static const char *ak4671_rin_mux_texts[] =
0242         {"RIN1", "RIN2", "RIN3", "RIN4"};
0243 static SOC_ENUM_SINGLE_DECL(ak4671_rin_mux_enum,
0244                 AK4671_MIC_SIGNAL_SELECT, 2,
0245                 ak4671_rin_mux_texts);
0246 static const struct snd_kcontrol_new ak4671_rin_mux_control =
0247     SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
0248 
0249 static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
0250     /* Inputs */
0251     SND_SOC_DAPM_INPUT("LIN1"),
0252     SND_SOC_DAPM_INPUT("RIN1"),
0253     SND_SOC_DAPM_INPUT("LIN2"),
0254     SND_SOC_DAPM_INPUT("RIN2"),
0255     SND_SOC_DAPM_INPUT("LIN3"),
0256     SND_SOC_DAPM_INPUT("RIN3"),
0257     SND_SOC_DAPM_INPUT("LIN4"),
0258     SND_SOC_DAPM_INPUT("RIN4"),
0259 
0260     /* Outputs */
0261     SND_SOC_DAPM_OUTPUT("LOUT1"),
0262     SND_SOC_DAPM_OUTPUT("ROUT1"),
0263     SND_SOC_DAPM_OUTPUT("LOUT2"),
0264     SND_SOC_DAPM_OUTPUT("ROUT2"),
0265     SND_SOC_DAPM_OUTPUT("LOUT3"),
0266     SND_SOC_DAPM_OUTPUT("ROUT3"),
0267 
0268     /* DAC */
0269     SND_SOC_DAPM_DAC("DAC Left", "Left HiFi Playback",
0270             AK4671_AD_DA_POWER_MANAGEMENT, 6, 0),
0271     SND_SOC_DAPM_DAC("DAC Right", "Right HiFi Playback",
0272             AK4671_AD_DA_POWER_MANAGEMENT, 7, 0),
0273 
0274     /* ADC */
0275     SND_SOC_DAPM_ADC("ADC Left", "Left HiFi Capture",
0276             AK4671_AD_DA_POWER_MANAGEMENT, 4, 0),
0277     SND_SOC_DAPM_ADC("ADC Right", "Right HiFi Capture",
0278             AK4671_AD_DA_POWER_MANAGEMENT, 5, 0),
0279 
0280     /* PGA */
0281     SND_SOC_DAPM_PGA("LOUT2 Mix Amp",
0282             AK4671_LOUT2_POWER_MANAGERMENT, 5, 0, NULL, 0),
0283     SND_SOC_DAPM_PGA("ROUT2 Mix Amp",
0284             AK4671_LOUT2_POWER_MANAGERMENT, 6, 0, NULL, 0),
0285 
0286     SND_SOC_DAPM_PGA("LIN1 Mixing Circuit",
0287             AK4671_MIXING_POWER_MANAGEMENT1, 0, 0, NULL, 0),
0288     SND_SOC_DAPM_PGA("RIN1 Mixing Circuit",
0289             AK4671_MIXING_POWER_MANAGEMENT1, 1, 0, NULL, 0),
0290     SND_SOC_DAPM_PGA("LIN2 Mixing Circuit",
0291             AK4671_MIXING_POWER_MANAGEMENT1, 2, 0, NULL, 0),
0292     SND_SOC_DAPM_PGA("RIN2 Mixing Circuit",
0293             AK4671_MIXING_POWER_MANAGEMENT1, 3, 0, NULL, 0),
0294     SND_SOC_DAPM_PGA("LIN3 Mixing Circuit",
0295             AK4671_MIXING_POWER_MANAGEMENT1, 4, 0, NULL, 0),
0296     SND_SOC_DAPM_PGA("RIN3 Mixing Circuit",
0297             AK4671_MIXING_POWER_MANAGEMENT1, 5, 0, NULL, 0),
0298     SND_SOC_DAPM_PGA("LIN4 Mixing Circuit",
0299             AK4671_MIXING_POWER_MANAGEMENT1, 6, 0, NULL, 0),
0300     SND_SOC_DAPM_PGA("RIN4 Mixing Circuit",
0301             AK4671_MIXING_POWER_MANAGEMENT1, 7, 0, NULL, 0),
0302 
0303     /* Output Mixers */
0304     SND_SOC_DAPM_MIXER("LOUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 0, 0,
0305             &ak4671_lout1_mixer_controls[0],
0306             ARRAY_SIZE(ak4671_lout1_mixer_controls)),
0307     SND_SOC_DAPM_MIXER("ROUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 1, 0,
0308             &ak4671_rout1_mixer_controls[0],
0309             ARRAY_SIZE(ak4671_rout1_mixer_controls)),
0310     SND_SOC_DAPM_MIXER_E("LOUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
0311             0, 0, &ak4671_lout2_mixer_controls[0],
0312             ARRAY_SIZE(ak4671_lout2_mixer_controls),
0313             ak4671_out2_event,
0314             SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
0315     SND_SOC_DAPM_MIXER_E("ROUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
0316             1, 0, &ak4671_rout2_mixer_controls[0],
0317             ARRAY_SIZE(ak4671_rout2_mixer_controls),
0318             ak4671_out2_event,
0319             SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
0320     SND_SOC_DAPM_MIXER("LOUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 0, 0,
0321             &ak4671_lout3_mixer_controls[0],
0322             ARRAY_SIZE(ak4671_lout3_mixer_controls)),
0323     SND_SOC_DAPM_MIXER("ROUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 1, 0,
0324             &ak4671_rout3_mixer_controls[0],
0325             ARRAY_SIZE(ak4671_rout3_mixer_controls)),
0326 
0327     /* Input MUXs */
0328     SND_SOC_DAPM_MUX("LIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 2, 0,
0329             &ak4671_lin_mux_control),
0330     SND_SOC_DAPM_MUX("RIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 3, 0,
0331             &ak4671_rin_mux_control),
0332 
0333     /* Mic Power */
0334     SND_SOC_DAPM_MICBIAS("Mic Bias", AK4671_AD_DA_POWER_MANAGEMENT, 1, 0),
0335 
0336     /* Supply */
0337     SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
0338 };
0339 
0340 static const struct snd_soc_dapm_route ak4671_intercon[] = {
0341     {"DAC Left", NULL, "PMPLL"},
0342     {"DAC Right", NULL, "PMPLL"},
0343     {"ADC Left", NULL, "PMPLL"},
0344     {"ADC Right", NULL, "PMPLL"},
0345 
0346     /* Outputs */
0347     {"LOUT1", NULL, "LOUT1 Mixer"},
0348     {"ROUT1", NULL, "ROUT1 Mixer"},
0349     {"LOUT2", NULL, "LOUT2 Mix Amp"},
0350     {"ROUT2", NULL, "ROUT2 Mix Amp"},
0351     {"LOUT3", NULL, "LOUT3 Mixer"},
0352     {"ROUT3", NULL, "ROUT3 Mixer"},
0353 
0354     {"LOUT1 Mixer", "DACL", "DAC Left"},
0355     {"ROUT1 Mixer", "DACR", "DAC Right"},
0356     {"LOUT2 Mixer", "DACHL", "DAC Left"},
0357     {"ROUT2 Mixer", "DACHR", "DAC Right"},
0358     {"LOUT2 Mix Amp", NULL, "LOUT2 Mixer"},
0359     {"ROUT2 Mix Amp", NULL, "ROUT2 Mixer"},
0360     {"LOUT3 Mixer", "DACSL", "DAC Left"},
0361     {"ROUT3 Mixer", "DACSR", "DAC Right"},
0362 
0363     /* Inputs */
0364     {"LIN MUX", "LIN1", "LIN1"},
0365     {"LIN MUX", "LIN2", "LIN2"},
0366     {"LIN MUX", "LIN3", "LIN3"},
0367     {"LIN MUX", "LIN4", "LIN4"},
0368 
0369     {"RIN MUX", "RIN1", "RIN1"},
0370     {"RIN MUX", "RIN2", "RIN2"},
0371     {"RIN MUX", "RIN3", "RIN3"},
0372     {"RIN MUX", "RIN4", "RIN4"},
0373 
0374     {"LIN1", NULL, "Mic Bias"},
0375     {"RIN1", NULL, "Mic Bias"},
0376     {"LIN2", NULL, "Mic Bias"},
0377     {"RIN2", NULL, "Mic Bias"},
0378 
0379     {"ADC Left", NULL, "LIN MUX"},
0380     {"ADC Right", NULL, "RIN MUX"},
0381 
0382     /* Analog Loops */
0383     {"LIN1 Mixing Circuit", NULL, "LIN1"},
0384     {"RIN1 Mixing Circuit", NULL, "RIN1"},
0385     {"LIN2 Mixing Circuit", NULL, "LIN2"},
0386     {"RIN2 Mixing Circuit", NULL, "RIN2"},
0387     {"LIN3 Mixing Circuit", NULL, "LIN3"},
0388     {"RIN3 Mixing Circuit", NULL, "RIN3"},
0389     {"LIN4 Mixing Circuit", NULL, "LIN4"},
0390     {"RIN4 Mixing Circuit", NULL, "RIN4"},
0391 
0392     {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
0393     {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
0394     {"LOUT2 Mixer", "LINH1", "LIN1 Mixing Circuit"},
0395     {"ROUT2 Mixer", "RINH1", "RIN1 Mixing Circuit"},
0396     {"LOUT3 Mixer", "LINS1", "LIN1 Mixing Circuit"},
0397     {"ROUT3 Mixer", "RINS1", "RIN1 Mixing Circuit"},
0398 
0399     {"LOUT1 Mixer", "LINL2", "LIN2 Mixing Circuit"},
0400     {"ROUT1 Mixer", "RINR2", "RIN2 Mixing Circuit"},
0401     {"LOUT2 Mixer", "LINH2", "LIN2 Mixing Circuit"},
0402     {"ROUT2 Mixer", "RINH2", "RIN2 Mixing Circuit"},
0403     {"LOUT3 Mixer", "LINS2", "LIN2 Mixing Circuit"},
0404     {"ROUT3 Mixer", "RINS2", "RIN2 Mixing Circuit"},
0405 
0406     {"LOUT1 Mixer", "LINL3", "LIN3 Mixing Circuit"},
0407     {"ROUT1 Mixer", "RINR3", "RIN3 Mixing Circuit"},
0408     {"LOUT2 Mixer", "LINH3", "LIN3 Mixing Circuit"},
0409     {"ROUT2 Mixer", "RINH3", "RIN3 Mixing Circuit"},
0410     {"LOUT3 Mixer", "LINS3", "LIN3 Mixing Circuit"},
0411     {"ROUT3 Mixer", "RINS3", "RIN3 Mixing Circuit"},
0412 
0413     {"LOUT1 Mixer", "LINL4", "LIN4 Mixing Circuit"},
0414     {"ROUT1 Mixer", "RINR4", "RIN4 Mixing Circuit"},
0415     {"LOUT2 Mixer", "LINH4", "LIN4 Mixing Circuit"},
0416     {"ROUT2 Mixer", "RINH4", "RIN4 Mixing Circuit"},
0417     {"LOUT3 Mixer", "LINS4", "LIN4 Mixing Circuit"},
0418     {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
0419 };
0420 
0421 static int ak4671_hw_params(struct snd_pcm_substream *substream,
0422         struct snd_pcm_hw_params *params,
0423         struct snd_soc_dai *dai)
0424 {
0425     struct snd_soc_component *component = dai->component;
0426     u8 fs;
0427 
0428     fs = snd_soc_component_read(component, AK4671_PLL_MODE_SELECT0);
0429     fs &= ~AK4671_FS;
0430 
0431     switch (params_rate(params)) {
0432     case 8000:
0433         fs |= AK4671_FS_8KHZ;
0434         break;
0435     case 12000:
0436         fs |= AK4671_FS_12KHZ;
0437         break;
0438     case 16000:
0439         fs |= AK4671_FS_16KHZ;
0440         break;
0441     case 24000:
0442         fs |= AK4671_FS_24KHZ;
0443         break;
0444     case 11025:
0445         fs |= AK4671_FS_11_025KHZ;
0446         break;
0447     case 22050:
0448         fs |= AK4671_FS_22_05KHZ;
0449         break;
0450     case 32000:
0451         fs |= AK4671_FS_32KHZ;
0452         break;
0453     case 44100:
0454         fs |= AK4671_FS_44_1KHZ;
0455         break;
0456     case 48000:
0457         fs |= AK4671_FS_48KHZ;
0458         break;
0459     default:
0460         return -EINVAL;
0461     }
0462 
0463     snd_soc_component_write(component, AK4671_PLL_MODE_SELECT0, fs);
0464 
0465     return 0;
0466 }
0467 
0468 static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
0469         unsigned int freq, int dir)
0470 {
0471     struct snd_soc_component *component = dai->component;
0472     u8 pll;
0473 
0474     pll = snd_soc_component_read(component, AK4671_PLL_MODE_SELECT0);
0475     pll &= ~AK4671_PLL;
0476 
0477     switch (freq) {
0478     case 11289600:
0479         pll |= AK4671_PLL_11_2896MHZ;
0480         break;
0481     case 12000000:
0482         pll |= AK4671_PLL_12MHZ;
0483         break;
0484     case 12288000:
0485         pll |= AK4671_PLL_12_288MHZ;
0486         break;
0487     case 13000000:
0488         pll |= AK4671_PLL_13MHZ;
0489         break;
0490     case 13500000:
0491         pll |= AK4671_PLL_13_5MHZ;
0492         break;
0493     case 19200000:
0494         pll |= AK4671_PLL_19_2MHZ;
0495         break;
0496     case 24000000:
0497         pll |= AK4671_PLL_24MHZ;
0498         break;
0499     case 26000000:
0500         pll |= AK4671_PLL_26MHZ;
0501         break;
0502     case 27000000:
0503         pll |= AK4671_PLL_27MHZ;
0504         break;
0505     default:
0506         return -EINVAL;
0507     }
0508 
0509     snd_soc_component_write(component, AK4671_PLL_MODE_SELECT0, pll);
0510 
0511     return 0;
0512 }
0513 
0514 static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0515 {
0516     struct snd_soc_component *component = dai->component;
0517     u8 mode;
0518     u8 format;
0519 
0520     /* set master/slave audio interface */
0521     mode = snd_soc_component_read(component, AK4671_PLL_MODE_SELECT1);
0522 
0523     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0524     case SND_SOC_DAIFMT_CBP_CFP:
0525         mode |= AK4671_M_S;
0526         break;
0527     case SND_SOC_DAIFMT_CBP_CFC:
0528         mode &= ~(AK4671_M_S);
0529         break;
0530     default:
0531         return -EINVAL;
0532     }
0533 
0534     /* interface format */
0535     format = snd_soc_component_read(component, AK4671_FORMAT_SELECT);
0536     format &= ~AK4671_DIF;
0537 
0538     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0539     case SND_SOC_DAIFMT_I2S:
0540         format |= AK4671_DIF_I2S_MODE;
0541         break;
0542     case SND_SOC_DAIFMT_LEFT_J:
0543         format |= AK4671_DIF_MSB_MODE;
0544         break;
0545     case SND_SOC_DAIFMT_DSP_A:
0546         format |= AK4671_DIF_DSP_MODE;
0547         format |= AK4671_BCKP;
0548         format |= AK4671_MSBS;
0549         break;
0550     default:
0551         return -EINVAL;
0552     }
0553 
0554     /* set mode and format */
0555     snd_soc_component_write(component, AK4671_PLL_MODE_SELECT1, mode);
0556     snd_soc_component_write(component, AK4671_FORMAT_SELECT, format);
0557 
0558     return 0;
0559 }
0560 
0561 static int ak4671_set_bias_level(struct snd_soc_component *component,
0562         enum snd_soc_bias_level level)
0563 {
0564     switch (level) {
0565     case SND_SOC_BIAS_ON:
0566     case SND_SOC_BIAS_PREPARE:
0567     case SND_SOC_BIAS_STANDBY:
0568         snd_soc_component_update_bits(component, AK4671_AD_DA_POWER_MANAGEMENT,
0569                     AK4671_PMVCM, AK4671_PMVCM);
0570         break;
0571     case SND_SOC_BIAS_OFF:
0572         snd_soc_component_write(component, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
0573         break;
0574     }
0575     return 0;
0576 }
0577 
0578 #define AK4671_RATES        (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
0579                 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
0580                 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
0581                 SNDRV_PCM_RATE_48000)
0582 
0583 #define AK4671_FORMATS      SNDRV_PCM_FMTBIT_S16_LE
0584 
0585 static const struct snd_soc_dai_ops ak4671_dai_ops = {
0586     .hw_params  = ak4671_hw_params,
0587     .set_sysclk = ak4671_set_dai_sysclk,
0588     .set_fmt    = ak4671_set_dai_fmt,
0589 };
0590 
0591 static struct snd_soc_dai_driver ak4671_dai = {
0592     .name = "ak4671-hifi",
0593     .playback = {
0594         .stream_name = "Playback",
0595         .channels_min = 1,
0596         .channels_max = 2,
0597         .rates = AK4671_RATES,
0598         .formats = AK4671_FORMATS,},
0599     .capture = {
0600         .stream_name = "Capture",
0601         .channels_min = 1,
0602         .channels_max = 2,
0603         .rates = AK4671_RATES,
0604         .formats = AK4671_FORMATS,},
0605     .ops = &ak4671_dai_ops,
0606 };
0607 
0608 static const struct snd_soc_component_driver soc_component_dev_ak4671 = {
0609     .set_bias_level     = ak4671_set_bias_level,
0610     .controls       = ak4671_snd_controls,
0611     .num_controls       = ARRAY_SIZE(ak4671_snd_controls),
0612     .dapm_widgets       = ak4671_dapm_widgets,
0613     .num_dapm_widgets   = ARRAY_SIZE(ak4671_dapm_widgets),
0614     .dapm_routes        = ak4671_intercon,
0615     .num_dapm_routes    = ARRAY_SIZE(ak4671_intercon),
0616     .idle_bias_on       = 1,
0617     .use_pmdown_time    = 1,
0618     .endianness     = 1,
0619 };
0620 
0621 static const struct regmap_config ak4671_regmap = {
0622     .reg_bits = 8,
0623     .val_bits = 8,
0624 
0625     .max_register = AK4671_SAR_ADC_CONTROL,
0626     .reg_defaults = ak4671_reg_defaults,
0627     .num_reg_defaults = ARRAY_SIZE(ak4671_reg_defaults),
0628     .cache_type = REGCACHE_RBTREE,
0629 };
0630 
0631 static int ak4671_i2c_probe(struct i2c_client *client)
0632 {
0633     struct regmap *regmap;
0634     int ret;
0635 
0636     regmap = devm_regmap_init_i2c(client, &ak4671_regmap);
0637     if (IS_ERR(regmap)) {
0638         ret = PTR_ERR(regmap);
0639         dev_err(&client->dev, "Failed to create regmap: %d\n", ret);
0640         return ret;
0641     }
0642 
0643     ret = devm_snd_soc_register_component(&client->dev,
0644             &soc_component_dev_ak4671, &ak4671_dai, 1);
0645     return ret;
0646 }
0647 
0648 static const struct i2c_device_id ak4671_i2c_id[] = {
0649     { "ak4671", 0 },
0650     { }
0651 };
0652 MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
0653 
0654 static struct i2c_driver ak4671_i2c_driver = {
0655     .driver = {
0656         .name = "ak4671-codec",
0657     },
0658     .probe_new = ak4671_i2c_probe,
0659     .id_table = ak4671_i2c_id,
0660 };
0661 
0662 module_i2c_driver(ak4671_i2c_driver);
0663 
0664 MODULE_DESCRIPTION("ASoC AK4671 codec driver");
0665 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
0666 MODULE_LICENSE("GPL");