1a3a83d9aSKuninori Morimoto /* 2a3a83d9aSKuninori Morimoto * ak4642.c -- AK4642/AK4643 ALSA Soc Audio driver 3a3a83d9aSKuninori Morimoto * 4a3a83d9aSKuninori Morimoto * Copyright (C) 2009 Renesas Solutions Corp. 5a3a83d9aSKuninori Morimoto * Kuninori Morimoto <morimoto.kuninori@renesas.com> 6a3a83d9aSKuninori Morimoto * 7a3a83d9aSKuninori Morimoto * Based on wm8731.c by Richard Purdie 8a3a83d9aSKuninori Morimoto * Based on ak4535.c by Richard Purdie 9a3a83d9aSKuninori Morimoto * Based on wm8753.c by Liam Girdwood 10a3a83d9aSKuninori Morimoto * 11a3a83d9aSKuninori Morimoto * This program is free software; you can redistribute it and/or modify 12a3a83d9aSKuninori Morimoto * it under the terms of the GNU General Public License version 2 as 13a3a83d9aSKuninori Morimoto * published by the Free Software Foundation. 14a3a83d9aSKuninori Morimoto */ 15a3a83d9aSKuninori Morimoto 16a3a83d9aSKuninori Morimoto /* ** CAUTION ** 17a3a83d9aSKuninori Morimoto * 18a3a83d9aSKuninori Morimoto * This is very simple driver. 19a3a83d9aSKuninori Morimoto * It can use headphone output / stereo input only 20a3a83d9aSKuninori Morimoto * 2120211391SKuninori Morimoto * AK4642 is tested. 22a3a83d9aSKuninori Morimoto * AK4643 is tested. 23a9317e8bSKuninori Morimoto * AK4648 is tested. 24a3a83d9aSKuninori Morimoto */ 25a3a83d9aSKuninori Morimoto 26171a0138SKuninori Morimoto #include <linux/clk.h> 27171a0138SKuninori Morimoto #include <linux/clk-provider.h> 28a3a83d9aSKuninori Morimoto #include <linux/delay.h> 29a3a83d9aSKuninori Morimoto #include <linux/i2c.h> 305a0e3ad6STejun Heo #include <linux/slab.h> 31bbf1453eSKuninori Morimoto #include <linux/of_device.h> 32da155d5bSPaul Gortmaker #include <linux/module.h> 334574cd94SMark Brown #include <linux/regmap.h> 34ce6120ccSLiam Girdwood #include <sound/soc.h> 35a3a83d9aSKuninori Morimoto #include <sound/initval.h> 36a300de3cSKuninori Morimoto #include <sound/tlv.h> 37a3a83d9aSKuninori Morimoto 38a3a83d9aSKuninori Morimoto #define PW_MGMT1 0x00 39a3a83d9aSKuninori Morimoto #define PW_MGMT2 0x01 40a3a83d9aSKuninori Morimoto #define SG_SL1 0x02 41a3a83d9aSKuninori Morimoto #define SG_SL2 0x03 42a3a83d9aSKuninori Morimoto #define MD_CTL1 0x04 43a3a83d9aSKuninori Morimoto #define MD_CTL2 0x05 44a3a83d9aSKuninori Morimoto #define TIMER 0x06 45a3a83d9aSKuninori Morimoto #define ALC_CTL1 0x07 46a3a83d9aSKuninori Morimoto #define ALC_CTL2 0x08 47a3a83d9aSKuninori Morimoto #define L_IVC 0x09 48a3a83d9aSKuninori Morimoto #define L_DVC 0x0a 49a3a83d9aSKuninori Morimoto #define ALC_CTL3 0x0b 50a3a83d9aSKuninori Morimoto #define R_IVC 0x0c 51a3a83d9aSKuninori Morimoto #define R_DVC 0x0d 52a3a83d9aSKuninori Morimoto #define MD_CTL3 0x0e 53a3a83d9aSKuninori Morimoto #define MD_CTL4 0x0f 54a3a83d9aSKuninori Morimoto #define PW_MGMT3 0x10 55a3a83d9aSKuninori Morimoto #define DF_S 0x11 56a3a83d9aSKuninori Morimoto #define FIL3_0 0x12 57a3a83d9aSKuninori Morimoto #define FIL3_1 0x13 58a3a83d9aSKuninori Morimoto #define FIL3_2 0x14 59a3a83d9aSKuninori Morimoto #define FIL3_3 0x15 60a3a83d9aSKuninori Morimoto #define EQ_0 0x16 61a3a83d9aSKuninori Morimoto #define EQ_1 0x17 62a3a83d9aSKuninori Morimoto #define EQ_2 0x18 63a3a83d9aSKuninori Morimoto #define EQ_3 0x19 64a3a83d9aSKuninori Morimoto #define EQ_4 0x1a 65a3a83d9aSKuninori Morimoto #define EQ_5 0x1b 66a3a83d9aSKuninori Morimoto #define FIL1_0 0x1c 67a3a83d9aSKuninori Morimoto #define FIL1_1 0x1d 68a3a83d9aSKuninori Morimoto #define FIL1_2 0x1e 69f8ea6cebSAxel Lin #define FIL1_3 0x1f /* The maximum valid register for ak4642 */ 70a3a83d9aSKuninori Morimoto #define PW_MGMT4 0x20 71a3a83d9aSKuninori Morimoto #define MD_CTL5 0x21 72a3a83d9aSKuninori Morimoto #define LO_MS 0x22 73a3a83d9aSKuninori Morimoto #define HP_MS 0x23 74f8ea6cebSAxel Lin #define SPK_MS 0x24 /* The maximum valid register for ak4643 */ 75f8ea6cebSAxel Lin #define EQ_FBEQAB 0x25 76f8ea6cebSAxel Lin #define EQ_FBEQCD 0x26 77f8ea6cebSAxel Lin #define EQ_FBEQE 0x27 /* The maximum valid register for ak4648 */ 78a3a83d9aSKuninori Morimoto 79a3471239SKuninori Morimoto /* PW_MGMT1*/ 80a3471239SKuninori Morimoto #define PMVCM (1 << 6) /* VCOM Power Management */ 81a3471239SKuninori Morimoto #define PMMIN (1 << 5) /* MIN Input Power Management */ 82a3471239SKuninori Morimoto #define PMDAC (1 << 2) /* DAC Power Management */ 83a3471239SKuninori Morimoto #define PMADL (1 << 0) /* MIC Amp Lch and ADC Lch Power Management */ 84a3471239SKuninori Morimoto 850643ce8fSKuninori Morimoto /* PW_MGMT2 */ 860643ce8fSKuninori Morimoto #define HPMTN (1 << 6) 870643ce8fSKuninori Morimoto #define PMHPL (1 << 5) 880643ce8fSKuninori Morimoto #define PMHPR (1 << 4) 890643ce8fSKuninori Morimoto #define MS (1 << 3) /* master/slave select */ 900643ce8fSKuninori Morimoto #define MCKO (1 << 1) 910643ce8fSKuninori Morimoto #define PMPLL (1 << 0) 920643ce8fSKuninori Morimoto 930643ce8fSKuninori Morimoto #define PMHP_MASK (PMHPL | PMHPR) 940643ce8fSKuninori Morimoto #define PMHP PMHP_MASK 950643ce8fSKuninori Morimoto 96a3471239SKuninori Morimoto /* PW_MGMT3 */ 97a3471239SKuninori Morimoto #define PMADR (1 << 0) /* MIC L / ADC R Power Management */ 98a3471239SKuninori Morimoto 99a3471239SKuninori Morimoto /* SG_SL1 */ 100a3471239SKuninori Morimoto #define MINS (1 << 6) /* Switch from MIN to Speaker */ 101a3471239SKuninori Morimoto #define DACL (1 << 4) /* Switch from DAC to Stereo or Receiver */ 102a3471239SKuninori Morimoto #define PMMP (1 << 2) /* MPWR pin Power Management */ 103a3471239SKuninori Morimoto #define MGAIN0 (1 << 0) /* MIC amp gain*/ 104a3471239SKuninori Morimoto 10539c26180STakeshi Kihara /* SG_SL2 */ 10639c26180STakeshi Kihara #define LOPS (1 << 6) /* Stero Line-out Power Save Mode */ 10739c26180STakeshi Kihara 108a3471239SKuninori Morimoto /* TIMER */ 109da731845SSascha Hauer #define ZTM(param) ((param & 0x3) << 4) /* ALC Zero Crossing TimeOut */ 110a3471239SKuninori Morimoto #define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2)) 111a3471239SKuninori Morimoto 112a3471239SKuninori Morimoto /* ALC_CTL1 */ 113a3471239SKuninori Morimoto #define ALC (1 << 5) /* ALC Enable */ 114a3471239SKuninori Morimoto #define LMTH0 (1 << 0) /* ALC Limiter / Recovery Level */ 115a3471239SKuninori Morimoto 1164b6316b4SKuninori Morimoto /* MD_CTL1 */ 1174b6316b4SKuninori Morimoto #define PLL3 (1 << 7) 1184b6316b4SKuninori Morimoto #define PLL2 (1 << 6) 1194b6316b4SKuninori Morimoto #define PLL1 (1 << 5) 1204b6316b4SKuninori Morimoto #define PLL0 (1 << 4) 1214b6316b4SKuninori Morimoto #define PLL_MASK (PLL3 | PLL2 | PLL1 | PLL0) 1224b6316b4SKuninori Morimoto 1230643ce8fSKuninori Morimoto #define BCKO_MASK (1 << 3) 1240643ce8fSKuninori Morimoto #define BCKO_64 BCKO_MASK 1250643ce8fSKuninori Morimoto 126cb9c130aSKuninori Morimoto #define DIF_MASK (3 << 0) 127cb9c130aSKuninori Morimoto #define DSP (0 << 0) 128cb9c130aSKuninori Morimoto #define RIGHT_J (1 << 0) 129cb9c130aSKuninori Morimoto #define LEFT_J (2 << 0) 130cb9c130aSKuninori Morimoto #define I2S (3 << 0) 131cb9c130aSKuninori Morimoto 1321ad747caSKuninori Morimoto /* MD_CTL2 */ 133544637bfSKuninori Morimoto #define FSs(val) (((val & 0x7) << 0) | ((val & 0x8) << 2)) 134544637bfSKuninori Morimoto #define PSs(val) ((val & 0x3) << 6) 1351ad747caSKuninori Morimoto 136a3471239SKuninori Morimoto /* MD_CTL3 */ 137a3471239SKuninori Morimoto #define BST1 (1 << 3) 138a3471239SKuninori Morimoto 139a3471239SKuninori Morimoto /* MD_CTL4 */ 140a3471239SKuninori Morimoto #define DACH (1 << 0) 141a3a83d9aSKuninori Morimoto 142d815c703SSascha Hauer struct ak4642_drvdata { 143d815c703SSascha Hauer const struct regmap_config *regmap_config; 1445cd15e29SSascha Hauer int extended_frequencies; 145d815c703SSascha Hauer }; 146d815c703SSascha Hauer 147d815c703SSascha Hauer struct ak4642_priv { 148d815c703SSascha Hauer const struct ak4642_drvdata *drvdata; 149171a0138SKuninori Morimoto struct clk *mcko; 150d815c703SSascha Hauer }; 151d815c703SSascha Hauer 152a300de3cSKuninori Morimoto /* 153a300de3cSKuninori Morimoto * Playback Volume (table 39) 154a300de3cSKuninori Morimoto * 155a300de3cSKuninori Morimoto * max : 0x00 : +12.0 dB 156a300de3cSKuninori Morimoto * ( 0.5 dB step ) 157a300de3cSKuninori Morimoto * min : 0xFE : -115.0 dB 158a300de3cSKuninori Morimoto * mute: 0xFF 159a300de3cSKuninori Morimoto */ 1601f99e44cSKuninori Morimoto static const DECLARE_TLV_DB_SCALE(out_tlv, -11550, 50, 1); 161a300de3cSKuninori Morimoto 162a300de3cSKuninori Morimoto static const struct snd_kcontrol_new ak4642_snd_controls[] = { 163a300de3cSKuninori Morimoto 164a300de3cSKuninori Morimoto SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC, 165a300de3cSKuninori Morimoto 0, 0xFF, 1, out_tlv), 166370f83a1SSascha Hauer SOC_SINGLE("ALC Capture Switch", ALC_CTL1, 5, 1, 0), 167370f83a1SSascha Hauer SOC_SINGLE("ALC Capture ZC Switch", ALC_CTL1, 4, 1, 1), 168a300de3cSKuninori Morimoto }; 169a300de3cSKuninori Morimoto 170e555cf36SKuninori Morimoto static const struct snd_kcontrol_new ak4642_headphone_control = 171e555cf36SKuninori Morimoto SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0); 17224747daeSKuninori Morimoto 173e8c83dbfSKuninori Morimoto static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = { 174e8c83dbfSKuninori Morimoto SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0), 175e8c83dbfSKuninori Morimoto }; 176e8c83dbfSKuninori Morimoto 17739c26180STakeshi Kihara /* event handlers */ 17839c26180STakeshi Kihara static int ak4642_lout_event(struct snd_soc_dapm_widget *w, 17939c26180STakeshi Kihara struct snd_kcontrol *kcontrol, int event) 18039c26180STakeshi Kihara { 18139c26180STakeshi Kihara struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 18239c26180STakeshi Kihara 18339c26180STakeshi Kihara switch (event) { 18439c26180STakeshi Kihara case SND_SOC_DAPM_PRE_PMD: 18539c26180STakeshi Kihara case SND_SOC_DAPM_PRE_PMU: 18639c26180STakeshi Kihara /* Power save mode ON */ 18739c26180STakeshi Kihara snd_soc_update_bits(codec, SG_SL2, LOPS, LOPS); 18839c26180STakeshi Kihara break; 18939c26180STakeshi Kihara case SND_SOC_DAPM_POST_PMU: 19039c26180STakeshi Kihara case SND_SOC_DAPM_POST_PMD: 19139c26180STakeshi Kihara /* Power save mode OFF */ 19239c26180STakeshi Kihara mdelay(300); 19339c26180STakeshi Kihara snd_soc_update_bits(codec, SG_SL2, LOPS, 0); 19439c26180STakeshi Kihara break; 19539c26180STakeshi Kihara } 19639c26180STakeshi Kihara 19739c26180STakeshi Kihara return 0; 19839c26180STakeshi Kihara } 19939c26180STakeshi Kihara 20024747daeSKuninori Morimoto static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = { 20124747daeSKuninori Morimoto 20224747daeSKuninori Morimoto /* Outputs */ 20324747daeSKuninori Morimoto SND_SOC_DAPM_OUTPUT("HPOUTL"), 20424747daeSKuninori Morimoto SND_SOC_DAPM_OUTPUT("HPOUTR"), 205e8c83dbfSKuninori Morimoto SND_SOC_DAPM_OUTPUT("LINEOUT"), 20624747daeSKuninori Morimoto 207e555cf36SKuninori Morimoto SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0), 208e555cf36SKuninori Morimoto SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0), 209e555cf36SKuninori Morimoto SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0, 210e555cf36SKuninori Morimoto &ak4642_headphone_control), 21124747daeSKuninori Morimoto 212e555cf36SKuninori Morimoto SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0), 21324747daeSKuninori Morimoto 21439c26180STakeshi Kihara SND_SOC_DAPM_MIXER_E("LINEOUT Mixer", PW_MGMT1, 3, 0, 215e8c83dbfSKuninori Morimoto &ak4642_lout_mixer_controls[0], 21639c26180STakeshi Kihara ARRAY_SIZE(ak4642_lout_mixer_controls), 21739c26180STakeshi Kihara ak4642_lout_event, 21839c26180STakeshi Kihara SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 21939c26180STakeshi Kihara SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 220e8c83dbfSKuninori Morimoto 22124747daeSKuninori Morimoto /* DAC */ 222379c4b05SKuninori Morimoto SND_SOC_DAPM_DAC("DAC", NULL, PW_MGMT1, 2, 0), 22324747daeSKuninori Morimoto }; 22424747daeSKuninori Morimoto 22524747daeSKuninori Morimoto static const struct snd_soc_dapm_route ak4642_intercon[] = { 22624747daeSKuninori Morimoto 22724747daeSKuninori Morimoto /* Outputs */ 228e555cf36SKuninori Morimoto {"HPOUTL", NULL, "HPL Out"}, 229e555cf36SKuninori Morimoto {"HPOUTR", NULL, "HPR Out"}, 230e8c83dbfSKuninori Morimoto {"LINEOUT", NULL, "LINEOUT Mixer"}, 23124747daeSKuninori Morimoto 232e555cf36SKuninori Morimoto {"HPL Out", NULL, "Headphone Enable"}, 233e555cf36SKuninori Morimoto {"HPR Out", NULL, "Headphone Enable"}, 234e555cf36SKuninori Morimoto 235e555cf36SKuninori Morimoto {"Headphone Enable", "Switch", "DACH"}, 236e555cf36SKuninori Morimoto 237e555cf36SKuninori Morimoto {"DACH", NULL, "DAC"}, 238e555cf36SKuninori Morimoto 239e8c83dbfSKuninori Morimoto {"LINEOUT Mixer", "DACL", "DAC"}, 240379c4b05SKuninori Morimoto 241379c4b05SKuninori Morimoto { "DAC", NULL, "Playback" }, 24224747daeSKuninori Morimoto }; 243a300de3cSKuninori Morimoto 244a3a83d9aSKuninori Morimoto /* 245a3a83d9aSKuninori Morimoto * ak4642 register cache 246a3a83d9aSKuninori Morimoto */ 247f8ea6cebSAxel Lin static const struct reg_default ak4643_reg[] = { 2484574cd94SMark Brown { 0, 0x00 }, { 1, 0x00 }, { 2, 0x01 }, { 3, 0x00 }, 2494574cd94SMark Brown { 4, 0x02 }, { 5, 0x00 }, { 6, 0x00 }, { 7, 0x00 }, 2504574cd94SMark Brown { 8, 0xe1 }, { 9, 0xe1 }, { 10, 0x18 }, { 11, 0x00 }, 2514574cd94SMark Brown { 12, 0xe1 }, { 13, 0x18 }, { 14, 0x11 }, { 15, 0x08 }, 2524574cd94SMark Brown { 16, 0x00 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x00 }, 2534574cd94SMark Brown { 20, 0x00 }, { 21, 0x00 }, { 22, 0x00 }, { 23, 0x00 }, 2544574cd94SMark Brown { 24, 0x00 }, { 25, 0x00 }, { 26, 0x00 }, { 27, 0x00 }, 2554574cd94SMark Brown { 28, 0x00 }, { 29, 0x00 }, { 30, 0x00 }, { 31, 0x00 }, 2564574cd94SMark Brown { 32, 0x00 }, { 33, 0x00 }, { 34, 0x00 }, { 35, 0x00 }, 2574574cd94SMark Brown { 36, 0x00 }, 258a3a83d9aSKuninori Morimoto }; 259a3a83d9aSKuninori Morimoto 260f8ea6cebSAxel Lin /* The default settings for 0x0 ~ 0x1f registers are the same for ak4642 261f8ea6cebSAxel Lin and ak4643. So we reuse the ak4643 reg_default for ak4642. 262f8ea6cebSAxel Lin The valid registers for ak4642 are 0x0 ~ 0x1f which is a subset of ak4643, 263f8ea6cebSAxel Lin so define NUM_AK4642_REG_DEFAULTS for ak4642. 264f8ea6cebSAxel Lin */ 265f8ea6cebSAxel Lin #define ak4642_reg ak4643_reg 266f8ea6cebSAxel Lin #define NUM_AK4642_REG_DEFAULTS (FIL1_3 + 1) 267f8ea6cebSAxel Lin 2684574cd94SMark Brown static const struct reg_default ak4648_reg[] = { 2694574cd94SMark Brown { 0, 0x00 }, { 1, 0x00 }, { 2, 0x01 }, { 3, 0x00 }, 2704574cd94SMark Brown { 4, 0x02 }, { 5, 0x00 }, { 6, 0x00 }, { 7, 0x00 }, 2714574cd94SMark Brown { 8, 0xe1 }, { 9, 0xe1 }, { 10, 0x18 }, { 11, 0x00 }, 2724574cd94SMark Brown { 12, 0xe1 }, { 13, 0x18 }, { 14, 0x11 }, { 15, 0xb8 }, 2734574cd94SMark Brown { 16, 0x00 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x00 }, 2744574cd94SMark Brown { 20, 0x00 }, { 21, 0x00 }, { 22, 0x00 }, { 23, 0x00 }, 2754574cd94SMark Brown { 24, 0x00 }, { 25, 0x00 }, { 26, 0x00 }, { 27, 0x00 }, 2764574cd94SMark Brown { 28, 0x00 }, { 29, 0x00 }, { 30, 0x00 }, { 31, 0x00 }, 2774574cd94SMark Brown { 32, 0x00 }, { 33, 0x00 }, { 34, 0x00 }, { 35, 0x00 }, 2784574cd94SMark Brown { 36, 0x00 }, { 37, 0x88 }, { 38, 0x88 }, { 39, 0x08 }, 279a9317e8bSKuninori Morimoto }; 280a9317e8bSKuninori Morimoto 281a3a83d9aSKuninori Morimoto static int ak4642_dai_startup(struct snd_pcm_substream *substream, 282a3a83d9aSKuninori Morimoto struct snd_soc_dai *dai) 283a3a83d9aSKuninori Morimoto { 284a3a83d9aSKuninori Morimoto int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 285a3a83d9aSKuninori Morimoto struct snd_soc_codec *codec = dai->codec; 286a3a83d9aSKuninori Morimoto 287a3a83d9aSKuninori Morimoto if (is_play) { 288a3a83d9aSKuninori Morimoto /* 289a3a83d9aSKuninori Morimoto * start headphone output 290a3a83d9aSKuninori Morimoto * 291a3a83d9aSKuninori Morimoto * PLL, Master Mode 292a3a83d9aSKuninori Morimoto * Audio I/F Format :MSB justified (ADC & DAC) 293a3a83d9aSKuninori Morimoto * Bass Boost Level : Middle 294a3a83d9aSKuninori Morimoto * 295a3a83d9aSKuninori Morimoto * This operation came from example code of 296a3a83d9aSKuninori Morimoto * "ASAHI KASEI AK4642" (japanese) manual p97. 297a3a83d9aSKuninori Morimoto */ 298b91470bbSAxel Lin snd_soc_write(codec, L_IVC, 0x91); /* volume */ 299b91470bbSAxel Lin snd_soc_write(codec, R_IVC, 0x91); /* volume */ 300a3a83d9aSKuninori Morimoto } else { 301a3a83d9aSKuninori Morimoto /* 302a3a83d9aSKuninori Morimoto * start stereo input 303a3a83d9aSKuninori Morimoto * 304a3a83d9aSKuninori Morimoto * PLL Master Mode 305a3a83d9aSKuninori Morimoto * Audio I/F Format:MSB justified (ADC & DAC) 306a3a83d9aSKuninori Morimoto * Pre MIC AMP:+20dB 307a3a83d9aSKuninori Morimoto * MIC Power On 308a3a83d9aSKuninori Morimoto * ALC setting:Refer to Table 35 309a3a83d9aSKuninori Morimoto * ALC bit=“1” 310a3a83d9aSKuninori Morimoto * 311a3a83d9aSKuninori Morimoto * This operation came from example code of 312a3a83d9aSKuninori Morimoto * "ASAHI KASEI AK4642" (japanese) manual p94. 313a3a83d9aSKuninori Morimoto */ 3147b5bfb82SPhil Edworthy snd_soc_update_bits(codec, SG_SL1, PMMP | MGAIN0, PMMP | MGAIN0); 315b91470bbSAxel Lin snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); 316b91470bbSAxel Lin snd_soc_write(codec, ALC_CTL1, ALC | LMTH0); 317ed2dd7daSKuninori Morimoto snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL); 318a3471239SKuninori Morimoto snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR); 319a3a83d9aSKuninori Morimoto } 320a3a83d9aSKuninori Morimoto 321a3a83d9aSKuninori Morimoto return 0; 322a3a83d9aSKuninori Morimoto } 323a3a83d9aSKuninori Morimoto 324a3a83d9aSKuninori Morimoto static void ak4642_dai_shutdown(struct snd_pcm_substream *substream, 325a3a83d9aSKuninori Morimoto struct snd_soc_dai *dai) 326a3a83d9aSKuninori Morimoto { 327a3a83d9aSKuninori Morimoto int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 328a3a83d9aSKuninori Morimoto struct snd_soc_codec *codec = dai->codec; 329a3a83d9aSKuninori Morimoto 330a3a83d9aSKuninori Morimoto if (is_play) { 331a3a83d9aSKuninori Morimoto } else { 332a3a83d9aSKuninori Morimoto /* stop stereo input */ 333a3471239SKuninori Morimoto snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0); 334a3471239SKuninori Morimoto snd_soc_update_bits(codec, PW_MGMT3, PMADR, 0); 335a3471239SKuninori Morimoto snd_soc_update_bits(codec, ALC_CTL1, ALC, 0); 336a3a83d9aSKuninori Morimoto } 337a3a83d9aSKuninori Morimoto } 338a3a83d9aSKuninori Morimoto 339a3a83d9aSKuninori Morimoto static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai, 340a3a83d9aSKuninori Morimoto int clk_id, unsigned int freq, int dir) 341a3a83d9aSKuninori Morimoto { 342a3a83d9aSKuninori Morimoto struct snd_soc_codec *codec = codec_dai->codec; 3435cd15e29SSascha Hauer struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec); 3444b6316b4SKuninori Morimoto u8 pll; 3455cd15e29SSascha Hauer int extended_freq = 0; 346a3a83d9aSKuninori Morimoto 3474b6316b4SKuninori Morimoto switch (freq) { 3484b6316b4SKuninori Morimoto case 11289600: 3494b6316b4SKuninori Morimoto pll = PLL2; 3504b6316b4SKuninori Morimoto break; 3514b6316b4SKuninori Morimoto case 12288000: 3524b6316b4SKuninori Morimoto pll = PLL2 | PLL0; 3534b6316b4SKuninori Morimoto break; 3544b6316b4SKuninori Morimoto case 12000000: 3554b6316b4SKuninori Morimoto pll = PLL2 | PLL1; 3564b6316b4SKuninori Morimoto break; 3574b6316b4SKuninori Morimoto case 24000000: 3584b6316b4SKuninori Morimoto pll = PLL2 | PLL1 | PLL0; 3594b6316b4SKuninori Morimoto break; 3604b6316b4SKuninori Morimoto case 13500000: 3614b6316b4SKuninori Morimoto pll = PLL3 | PLL2; 3624b6316b4SKuninori Morimoto break; 3634b6316b4SKuninori Morimoto case 27000000: 3644b6316b4SKuninori Morimoto pll = PLL3 | PLL2 | PLL0; 3654b6316b4SKuninori Morimoto break; 3665cd15e29SSascha Hauer case 19200000: 3675cd15e29SSascha Hauer pll = PLL3; 3685cd15e29SSascha Hauer extended_freq = 1; 3695cd15e29SSascha Hauer break; 3705cd15e29SSascha Hauer case 13000000: 3715cd15e29SSascha Hauer pll = PLL3 | PLL2 | PLL1; 3725cd15e29SSascha Hauer extended_freq = 1; 3735cd15e29SSascha Hauer break; 3745cd15e29SSascha Hauer case 26000000: 3755cd15e29SSascha Hauer pll = PLL3 | PLL2 | PLL1 | PLL0; 3765cd15e29SSascha Hauer extended_freq = 1; 3775cd15e29SSascha Hauer break; 3784b6316b4SKuninori Morimoto default: 3794b6316b4SKuninori Morimoto return -EINVAL; 3804b6316b4SKuninori Morimoto } 3815cd15e29SSascha Hauer 3825cd15e29SSascha Hauer if (extended_freq && !priv->drvdata->extended_frequencies) 3835cd15e29SSascha Hauer return -EINVAL; 3845cd15e29SSascha Hauer 3854b6316b4SKuninori Morimoto snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll); 3864b6316b4SKuninori Morimoto 387a3a83d9aSKuninori Morimoto return 0; 388a3a83d9aSKuninori Morimoto } 389a3a83d9aSKuninori Morimoto 3900643ce8fSKuninori Morimoto static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 3910643ce8fSKuninori Morimoto { 3920643ce8fSKuninori Morimoto struct snd_soc_codec *codec = dai->codec; 3930643ce8fSKuninori Morimoto u8 data; 3940643ce8fSKuninori Morimoto u8 bcko; 3950643ce8fSKuninori Morimoto 3960643ce8fSKuninori Morimoto data = MCKO | PMPLL; /* use MCKO */ 3970643ce8fSKuninori Morimoto bcko = 0; 3980643ce8fSKuninori Morimoto 3990643ce8fSKuninori Morimoto /* set master/slave audio interface */ 4000643ce8fSKuninori Morimoto switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 4010643ce8fSKuninori Morimoto case SND_SOC_DAIFMT_CBM_CFM: 4020643ce8fSKuninori Morimoto data |= MS; 4030643ce8fSKuninori Morimoto bcko = BCKO_64; 4040643ce8fSKuninori Morimoto break; 4050643ce8fSKuninori Morimoto case SND_SOC_DAIFMT_CBS_CFS: 4060643ce8fSKuninori Morimoto break; 4070643ce8fSKuninori Morimoto default: 4080643ce8fSKuninori Morimoto return -EINVAL; 4090643ce8fSKuninori Morimoto } 410bd7fdbcaSKuninori Morimoto snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data); 4110643ce8fSKuninori Morimoto snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); 4120643ce8fSKuninori Morimoto 413cb9c130aSKuninori Morimoto /* format type */ 414cb9c130aSKuninori Morimoto data = 0; 415cb9c130aSKuninori Morimoto switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 416cb9c130aSKuninori Morimoto case SND_SOC_DAIFMT_LEFT_J: 417cb9c130aSKuninori Morimoto data = LEFT_J; 418cb9c130aSKuninori Morimoto break; 419cb9c130aSKuninori Morimoto case SND_SOC_DAIFMT_I2S: 420cb9c130aSKuninori Morimoto data = I2S; 421cb9c130aSKuninori Morimoto break; 422cb9c130aSKuninori Morimoto /* FIXME 423cb9c130aSKuninori Morimoto * Please add RIGHT_J / DSP support here 424cb9c130aSKuninori Morimoto */ 425cb9c130aSKuninori Morimoto default: 426cb9c130aSKuninori Morimoto return -EINVAL; 427cb9c130aSKuninori Morimoto } 428cb9c130aSKuninori Morimoto snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data); 429cb9c130aSKuninori Morimoto 4300643ce8fSKuninori Morimoto return 0; 4310643ce8fSKuninori Morimoto } 4320643ce8fSKuninori Morimoto 433171a0138SKuninori Morimoto static int ak4642_set_mcko(struct snd_soc_codec *codec, 434171a0138SKuninori Morimoto u32 frequency) 435171a0138SKuninori Morimoto { 436171a0138SKuninori Morimoto u32 fs_list[] = { 437171a0138SKuninori Morimoto [0] = 8000, 438171a0138SKuninori Morimoto [1] = 12000, 439171a0138SKuninori Morimoto [2] = 16000, 440171a0138SKuninori Morimoto [3] = 24000, 441171a0138SKuninori Morimoto [4] = 7350, 442171a0138SKuninori Morimoto [5] = 11025, 443171a0138SKuninori Morimoto [6] = 14700, 444171a0138SKuninori Morimoto [7] = 22050, 445171a0138SKuninori Morimoto [10] = 32000, 446171a0138SKuninori Morimoto [11] = 48000, 447171a0138SKuninori Morimoto [14] = 29400, 448171a0138SKuninori Morimoto [15] = 44100, 449171a0138SKuninori Morimoto }; 450171a0138SKuninori Morimoto u32 ps_list[] = { 451171a0138SKuninori Morimoto [0] = 256, 452171a0138SKuninori Morimoto [1] = 128, 453171a0138SKuninori Morimoto [2] = 64, 454171a0138SKuninori Morimoto [3] = 32 455171a0138SKuninori Morimoto }; 456171a0138SKuninori Morimoto int ps, fs; 457171a0138SKuninori Morimoto 458171a0138SKuninori Morimoto for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) { 459171a0138SKuninori Morimoto for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) { 460171a0138SKuninori Morimoto if (frequency == ps_list[ps] * fs_list[fs]) { 461544637bfSKuninori Morimoto snd_soc_write(codec, MD_CTL2, 462544637bfSKuninori Morimoto PSs(ps) | FSs(fs)); 463171a0138SKuninori Morimoto return 0; 464171a0138SKuninori Morimoto } 465171a0138SKuninori Morimoto } 466171a0138SKuninori Morimoto } 467171a0138SKuninori Morimoto 468171a0138SKuninori Morimoto return 0; 469171a0138SKuninori Morimoto } 470171a0138SKuninori Morimoto 4711ad747caSKuninori Morimoto static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, 4721ad747caSKuninori Morimoto struct snd_pcm_hw_params *params, 4731ad747caSKuninori Morimoto struct snd_soc_dai *dai) 4741ad747caSKuninori Morimoto { 4751ad747caSKuninori Morimoto struct snd_soc_codec *codec = dai->codec; 476171a0138SKuninori Morimoto struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec); 477171a0138SKuninori Morimoto u32 rate = clk_get_rate(priv->mcko); 4781ad747caSKuninori Morimoto 479171a0138SKuninori Morimoto if (!rate) 480171a0138SKuninori Morimoto rate = params_rate(params) * 256; 4811ad747caSKuninori Morimoto 482171a0138SKuninori Morimoto return ak4642_set_mcko(codec, rate); 483a3a83d9aSKuninori Morimoto } 484a3a83d9aSKuninori Morimoto 485ed2dd7daSKuninori Morimoto static int ak4642_set_bias_level(struct snd_soc_codec *codec, 486ed2dd7daSKuninori Morimoto enum snd_soc_bias_level level) 487ed2dd7daSKuninori Morimoto { 488ed2dd7daSKuninori Morimoto switch (level) { 489ed2dd7daSKuninori Morimoto case SND_SOC_BIAS_OFF: 490ed2dd7daSKuninori Morimoto snd_soc_write(codec, PW_MGMT1, 0x00); 491ed2dd7daSKuninori Morimoto break; 492ed2dd7daSKuninori Morimoto default: 493ed2dd7daSKuninori Morimoto snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM); 494ed2dd7daSKuninori Morimoto break; 495ed2dd7daSKuninori Morimoto } 496ed2dd7daSKuninori Morimoto 497ed2dd7daSKuninori Morimoto return 0; 498ed2dd7daSKuninori Morimoto } 499ed2dd7daSKuninori Morimoto 50085e7652dSLars-Peter Clausen static const struct snd_soc_dai_ops ak4642_dai_ops = { 501a3a83d9aSKuninori Morimoto .startup = ak4642_dai_startup, 502a3a83d9aSKuninori Morimoto .shutdown = ak4642_dai_shutdown, 503a3a83d9aSKuninori Morimoto .set_sysclk = ak4642_dai_set_sysclk, 5040643ce8fSKuninori Morimoto .set_fmt = ak4642_dai_set_fmt, 5051ad747caSKuninori Morimoto .hw_params = ak4642_dai_hw_params, 506a3a83d9aSKuninori Morimoto }; 507a3a83d9aSKuninori Morimoto 508f0fba2adSLiam Girdwood static struct snd_soc_dai_driver ak4642_dai = { 509f0fba2adSLiam Girdwood .name = "ak4642-hifi", 510a3a83d9aSKuninori Morimoto .playback = { 511a3a83d9aSKuninori Morimoto .stream_name = "Playback", 512c01673e0SKuninori Morimoto .channels_min = 2, 513a3a83d9aSKuninori Morimoto .channels_max = 2, 514a3a83d9aSKuninori Morimoto .rates = SNDRV_PCM_RATE_8000_48000, 515a3a83d9aSKuninori Morimoto .formats = SNDRV_PCM_FMTBIT_S16_LE }, 516a3a83d9aSKuninori Morimoto .capture = { 517a3a83d9aSKuninori Morimoto .stream_name = "Capture", 518c01673e0SKuninori Morimoto .channels_min = 2, 519a3a83d9aSKuninori Morimoto .channels_max = 2, 520a3a83d9aSKuninori Morimoto .rates = SNDRV_PCM_RATE_8000_48000, 521a3a83d9aSKuninori Morimoto .formats = SNDRV_PCM_FMTBIT_S16_LE }, 522a3a83d9aSKuninori Morimoto .ops = &ak4642_dai_ops, 5231ad747caSKuninori Morimoto .symmetric_rates = 1, 524a3a83d9aSKuninori Morimoto }; 525a3a83d9aSKuninori Morimoto 526a2ebd586SPeter Ujfalusi static int ak4642_suspend(struct snd_soc_codec *codec) 527a2ebd586SPeter Ujfalusi { 528a2ebd586SPeter Ujfalusi struct regmap *regmap = dev_get_regmap(codec->dev, NULL); 529a2ebd586SPeter Ujfalusi 530a2ebd586SPeter Ujfalusi regcache_cache_only(regmap, true); 531a2ebd586SPeter Ujfalusi regcache_mark_dirty(regmap); 532a2ebd586SPeter Ujfalusi return 0; 533a2ebd586SPeter Ujfalusi } 534a2ebd586SPeter Ujfalusi 535f0fba2adSLiam Girdwood static int ak4642_resume(struct snd_soc_codec *codec) 536a3a83d9aSKuninori Morimoto { 5374574cd94SMark Brown struct regmap *regmap = dev_get_regmap(codec->dev, NULL); 5384574cd94SMark Brown 539a2ebd586SPeter Ujfalusi regcache_cache_only(regmap, false); 5404574cd94SMark Brown regcache_sync(regmap); 541a3a83d9aSKuninori Morimoto return 0; 542a3a83d9aSKuninori Morimoto } 543171a0138SKuninori Morimoto static int ak4642_probe(struct snd_soc_codec *codec) 544171a0138SKuninori Morimoto { 545171a0138SKuninori Morimoto struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec); 546171a0138SKuninori Morimoto 547171a0138SKuninori Morimoto if (priv->mcko) 548171a0138SKuninori Morimoto ak4642_set_mcko(codec, clk_get_rate(priv->mcko)); 549171a0138SKuninori Morimoto 550171a0138SKuninori Morimoto return 0; 551171a0138SKuninori Morimoto } 552171a0138SKuninori Morimoto 553f0fba2adSLiam Girdwood static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { 554171a0138SKuninori Morimoto .probe = ak4642_probe, 555a2ebd586SPeter Ujfalusi .suspend = ak4642_suspend, 556f0fba2adSLiam Girdwood .resume = ak4642_resume, 557ed2dd7daSKuninori Morimoto .set_bias_level = ak4642_set_bias_level, 5583a6ce00eSKuninori Morimoto .component_driver = { 559a8ca52b7SMark Brown .controls = ak4642_snd_controls, 560a8ca52b7SMark Brown .num_controls = ARRAY_SIZE(ak4642_snd_controls), 561a9317e8bSKuninori Morimoto .dapm_widgets = ak4642_dapm_widgets, 562a9317e8bSKuninori Morimoto .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), 563a9317e8bSKuninori Morimoto .dapm_routes = ak4642_intercon, 564a9317e8bSKuninori Morimoto .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), 5653a6ce00eSKuninori Morimoto }, 566a9317e8bSKuninori Morimoto }; 567a9317e8bSKuninori Morimoto 5684574cd94SMark Brown static const struct regmap_config ak4642_regmap = { 5694574cd94SMark Brown .reg_bits = 8, 5704574cd94SMark Brown .val_bits = 8, 571f8ea6cebSAxel Lin .max_register = FIL1_3, 5724574cd94SMark Brown .reg_defaults = ak4642_reg, 573f8ea6cebSAxel Lin .num_reg_defaults = NUM_AK4642_REG_DEFAULTS, 574d3030d11SMark Brown .cache_type = REGCACHE_RBTREE, 575f8ea6cebSAxel Lin }; 576f8ea6cebSAxel Lin 577f8ea6cebSAxel Lin static const struct regmap_config ak4643_regmap = { 578f8ea6cebSAxel Lin .reg_bits = 8, 579f8ea6cebSAxel Lin .val_bits = 8, 580f8ea6cebSAxel Lin .max_register = SPK_MS, 581f8ea6cebSAxel Lin .reg_defaults = ak4643_reg, 582f8ea6cebSAxel Lin .num_reg_defaults = ARRAY_SIZE(ak4643_reg), 583d3030d11SMark Brown .cache_type = REGCACHE_RBTREE, 5844574cd94SMark Brown }; 5854574cd94SMark Brown 5864574cd94SMark Brown static const struct regmap_config ak4648_regmap = { 5874574cd94SMark Brown .reg_bits = 8, 5884574cd94SMark Brown .val_bits = 8, 589f8ea6cebSAxel Lin .max_register = EQ_FBEQE, 5904574cd94SMark Brown .reg_defaults = ak4648_reg, 5914574cd94SMark Brown .num_reg_defaults = ARRAY_SIZE(ak4648_reg), 592d3030d11SMark Brown .cache_type = REGCACHE_RBTREE, 593f0fba2adSLiam Girdwood }; 594a3a83d9aSKuninori Morimoto 595d815c703SSascha Hauer static const struct ak4642_drvdata ak4642_drvdata = { 596d815c703SSascha Hauer .regmap_config = &ak4642_regmap, 597d815c703SSascha Hauer }; 598d815c703SSascha Hauer 599d815c703SSascha Hauer static const struct ak4642_drvdata ak4643_drvdata = { 600f8ea6cebSAxel Lin .regmap_config = &ak4643_regmap, 601d815c703SSascha Hauer }; 602d815c703SSascha Hauer 603d815c703SSascha Hauer static const struct ak4642_drvdata ak4648_drvdata = { 604d815c703SSascha Hauer .regmap_config = &ak4648_regmap, 6055cd15e29SSascha Hauer .extended_frequencies = 1, 606d815c703SSascha Hauer }; 607d815c703SSascha Hauer 608171a0138SKuninori Morimoto #ifdef CONFIG_COMMON_CLK 609171a0138SKuninori Morimoto static struct clk *ak4642_of_parse_mcko(struct device *dev) 610171a0138SKuninori Morimoto { 611171a0138SKuninori Morimoto struct device_node *np = dev->of_node; 612171a0138SKuninori Morimoto struct clk *clk; 613171a0138SKuninori Morimoto const char *clk_name = np->name; 614171a0138SKuninori Morimoto const char *parent_clk_name = NULL; 615171a0138SKuninori Morimoto u32 rate; 616171a0138SKuninori Morimoto 617171a0138SKuninori Morimoto if (of_property_read_u32(np, "clock-frequency", &rate)) 618171a0138SKuninori Morimoto return NULL; 619171a0138SKuninori Morimoto 620171a0138SKuninori Morimoto if (of_property_read_bool(np, "clocks")) 621171a0138SKuninori Morimoto parent_clk_name = of_clk_get_parent_name(np, 0); 622171a0138SKuninori Morimoto 623171a0138SKuninori Morimoto of_property_read_string(np, "clock-output-names", &clk_name); 624171a0138SKuninori Morimoto 625b6bf3289SStephen Boyd clk = clk_register_fixed_rate(dev, clk_name, parent_clk_name, 0, rate); 626171a0138SKuninori Morimoto if (!IS_ERR(clk)) 627171a0138SKuninori Morimoto of_clk_add_provider(np, of_clk_src_simple_get, clk); 628171a0138SKuninori Morimoto 629171a0138SKuninori Morimoto return clk; 630171a0138SKuninori Morimoto } 631171a0138SKuninori Morimoto #else 632171a0138SKuninori Morimoto #define ak4642_of_parse_mcko(d) 0 633171a0138SKuninori Morimoto #endif 634171a0138SKuninori Morimoto 63527204ca8SKiran Padwal static const struct of_device_id ak4642_of_match[]; 6367a79e94eSBill Pemberton static int ak4642_i2c_probe(struct i2c_client *i2c, 637a3a83d9aSKuninori Morimoto const struct i2c_device_id *id) 638a3a83d9aSKuninori Morimoto { 6392719a752SKuninori Morimoto struct device *dev = &i2c->dev; 6402719a752SKuninori Morimoto struct device_node *np = dev->of_node; 641d815c703SSascha Hauer const struct ak4642_drvdata *drvdata = NULL; 6424574cd94SMark Brown struct regmap *regmap; 643d815c703SSascha Hauer struct ak4642_priv *priv; 644171a0138SKuninori Morimoto struct clk *mcko = NULL; 645bbf1453eSKuninori Morimoto 646bbf1453eSKuninori Morimoto if (np) { 647bbf1453eSKuninori Morimoto const struct of_device_id *of_id; 648bbf1453eSKuninori Morimoto 649171a0138SKuninori Morimoto mcko = ak4642_of_parse_mcko(dev); 650171a0138SKuninori Morimoto if (IS_ERR(mcko)) 651171a0138SKuninori Morimoto mcko = NULL; 652171a0138SKuninori Morimoto 6532719a752SKuninori Morimoto of_id = of_match_device(ak4642_of_match, dev); 654bbf1453eSKuninori Morimoto if (of_id) 655d815c703SSascha Hauer drvdata = of_id->data; 656bbf1453eSKuninori Morimoto } else { 657d815c703SSascha Hauer drvdata = (const struct ak4642_drvdata *)id->driver_data; 658bbf1453eSKuninori Morimoto } 659bbf1453eSKuninori Morimoto 660d815c703SSascha Hauer if (!drvdata) { 6612719a752SKuninori Morimoto dev_err(dev, "Unknown device type\n"); 662bbf1453eSKuninori Morimoto return -EINVAL; 663bbf1453eSKuninori Morimoto } 664bbf1453eSKuninori Morimoto 6652719a752SKuninori Morimoto priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 666d815c703SSascha Hauer if (!priv) 667d815c703SSascha Hauer return -ENOMEM; 668d815c703SSascha Hauer 669d815c703SSascha Hauer priv->drvdata = drvdata; 670171a0138SKuninori Morimoto priv->mcko = mcko; 671d815c703SSascha Hauer 672d815c703SSascha Hauer i2c_set_clientdata(i2c, priv); 673d815c703SSascha Hauer 674d815c703SSascha Hauer regmap = devm_regmap_init_i2c(i2c, drvdata->regmap_config); 6754574cd94SMark Brown if (IS_ERR(regmap)) 6764574cd94SMark Brown return PTR_ERR(regmap); 6774574cd94SMark Brown 6782719a752SKuninori Morimoto return snd_soc_register_codec(dev, 6794574cd94SMark Brown &soc_codec_dev_ak4642, &ak4642_dai, 1); 680a3a83d9aSKuninori Morimoto } 681a3a83d9aSKuninori Morimoto 6827a79e94eSBill Pemberton static int ak4642_i2c_remove(struct i2c_client *client) 683a3a83d9aSKuninori Morimoto { 684f0fba2adSLiam Girdwood snd_soc_unregister_codec(&client->dev); 685a3a83d9aSKuninori Morimoto return 0; 686a3a83d9aSKuninori Morimoto } 687a3a83d9aSKuninori Morimoto 68827204ca8SKiran Padwal static const struct of_device_id ak4642_of_match[] = { 689d815c703SSascha Hauer { .compatible = "asahi-kasei,ak4642", .data = &ak4642_drvdata}, 690d815c703SSascha Hauer { .compatible = "asahi-kasei,ak4643", .data = &ak4643_drvdata}, 691d815c703SSascha Hauer { .compatible = "asahi-kasei,ak4648", .data = &ak4648_drvdata}, 692bbf1453eSKuninori Morimoto {}, 693bbf1453eSKuninori Morimoto }; 694bbf1453eSKuninori Morimoto MODULE_DEVICE_TABLE(of, ak4642_of_match); 695bbf1453eSKuninori Morimoto 696a3a83d9aSKuninori Morimoto static const struct i2c_device_id ak4642_i2c_id[] = { 697d815c703SSascha Hauer { "ak4642", (kernel_ulong_t)&ak4642_drvdata }, 698d815c703SSascha Hauer { "ak4643", (kernel_ulong_t)&ak4643_drvdata }, 699d815c703SSascha Hauer { "ak4648", (kernel_ulong_t)&ak4648_drvdata }, 700a3a83d9aSKuninori Morimoto { } 701a3a83d9aSKuninori Morimoto }; 702a3a83d9aSKuninori Morimoto MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id); 703a3a83d9aSKuninori Morimoto 704a3a83d9aSKuninori Morimoto static struct i2c_driver ak4642_i2c_driver = { 705a3a83d9aSKuninori Morimoto .driver = { 706f0fba2adSLiam Girdwood .name = "ak4642-codec", 707bbf1453eSKuninori Morimoto .of_match_table = ak4642_of_match, 708a3a83d9aSKuninori Morimoto }, 709a3a83d9aSKuninori Morimoto .probe = ak4642_i2c_probe, 7107a79e94eSBill Pemberton .remove = ak4642_i2c_remove, 711a3a83d9aSKuninori Morimoto .id_table = ak4642_i2c_id, 712a3a83d9aSKuninori Morimoto }; 713a3a83d9aSKuninori Morimoto 7142f54d2a1SMark Brown module_i2c_driver(ak4642_i2c_driver); 715a3a83d9aSKuninori Morimoto 716a3a83d9aSKuninori Morimoto MODULE_DESCRIPTION("Soc AK4642 driver"); 717a3a83d9aSKuninori Morimoto MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>"); 718a3a83d9aSKuninori Morimoto MODULE_LICENSE("GPL"); 719