diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index de7df7467c52..73a737bd082e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -124,6 +124,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_PCM5102A select SND_SOC_PCM512x_I2C if I2C select SND_SOC_PCM512x_SPI if SPI_MASTER + select SND_SOC_RK1000 if I2C select SND_SOC_RK312X select SND_SOC_RK3328 select SND_SOC_RK817 if I2C @@ -768,6 +769,10 @@ config SND_SOC_PCM512x_SPI select SND_SOC_PCM512x select REGMAP_SPI +config SND_SOC_RK1000 + tristate "Rockchip RK1000 CODEC" + depends on MFD_RK1000 + config SND_SOC_RK312X select REGMAP_MMIO tristate "Rockchip RK312X CODEC" diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index bdf70a513ce4..f59ce5fa8f25 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -126,6 +126,7 @@ snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-pcm512x-objs := pcm512x.o snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o snd-soc-pcm512x-spi-objs := pcm512x-spi.o +snd-soc-rk1000-objs := rk1000_codec.o snd-soc-rk312x-objs := rk312x_codec.o snd-soc-rk3328-objs := rk3328_codec.o snd-soc-rk817-objs := rk817_codec.o @@ -389,6 +390,7 @@ obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o +obj-$(CONFIG_SND_SOC_RK1000) += snd-soc-rk1000.o obj-$(CONFIG_SND_SOC_RK312X) += snd-soc-rk312x.o obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o obj-$(CONFIG_SND_SOC_RK817) += snd-soc-rk817.o diff --git a/sound/soc/codecs/rk1000_codec.c b/sound/soc/codecs/rk1000_codec.c index 06aaa617969b..c708f01755dd 100644 --- a/sound/soc/codecs/rk1000_codec.c +++ b/sound/soc/codecs/rk1000_codec.c @@ -1,21 +1,9 @@ -/* - * rk1000_codec.c -- rk1000 ALSA Soc Audio driver - * - * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ +// SPDX-License-Identifier: GPL-2.0 +// +// rxk1000_codec.c -- rk1000 ALSA Soc Audio driver +// +// Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd All rights reserved. + #include #include #include @@ -77,7 +65,7 @@ static const struct reg_default rk1000_codec_reg[] = { struct rk1000_codec_priv { struct regmap *regmap; struct regmap *ctlmap; - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct delayed_work pa_delayed_work; struct gpio_desc *spk_en_gpio; /* @@ -88,17 +76,17 @@ struct rk1000_codec_priv { unsigned int pa_enable_time; }; -static void spk_ctrl_fun(struct snd_soc_codec *codec, int status) +static void spk_ctrl_fun(struct snd_soc_component *component, int status) { struct rk1000_codec_priv *rk1000_codec; - rk1000_codec = snd_soc_codec_get_drvdata(codec); + rk1000_codec = snd_soc_component_get_drvdata(component); if (rk1000_codec->spk_en_gpio) gpiod_set_value(rk1000_codec->spk_en_gpio, status); } -static int rk1000_codec_set_bias_level(struct snd_soc_codec *codec, +static int rk1000_codec_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { switch (level) { @@ -106,22 +94,22 @@ static int rk1000_codec_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_PREPARE: - snd_soc_write(codec, ACCELCODEC_R1D, 0x2a); - snd_soc_write(codec, ACCELCODEC_R1E, 0x40); - snd_soc_write(codec, ACCELCODEC_R1F, 0x49); + snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a); + snd_soc_component_write(component, ACCELCODEC_R1E, 0x40); + snd_soc_component_write(component, ACCELCODEC_R1F, 0x49); break; case SND_SOC_BIAS_STANDBY: - snd_soc_write(codec, ACCELCODEC_R1D, 0x2a); - snd_soc_write(codec, ACCELCODEC_R1E, 0x40); - snd_soc_write(codec, ACCELCODEC_R1F, 0x49); + snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a); + snd_soc_component_write(component, ACCELCODEC_R1E, 0x40); + snd_soc_component_write(component, ACCELCODEC_R1F, 0x49); break; case SND_SOC_BIAS_OFF: - spk_ctrl_fun(codec, GPIO_LOW); - snd_soc_write(codec, ACCELCODEC_R1D, 0xFF); - snd_soc_write(codec, ACCELCODEC_R1E, 0xFF); - snd_soc_write(codec, ACCELCODEC_R1F, 0xFF); + spk_ctrl_fun(component, GPIO_LOW); + snd_soc_component_write(component, ACCELCODEC_R1D, 0xFF); + snd_soc_component_write(component, ACCELCODEC_R1E, 0xFF); + snd_soc_component_write(component, ACCELCODEC_R1F, 0xFF); break; } return 0; @@ -130,14 +118,14 @@ static int rk1000_codec_set_bias_level(struct snd_soc_codec *codec, static int rk1000_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { - struct snd_soc_codec *codec = codec_dai->codec; + struct snd_soc_component *component = codec_dai->component; struct rk1000_codec_priv *rk1000_codec; u16 iface = 0; - rk1000_codec = snd_soc_codec_get_drvdata(codec); + rk1000_codec = snd_soc_component_get_drvdata(component); /* setup Vmid and Vref, other module power down */ - snd_soc_write(codec, ACCELCODEC_R1D, 0x2a); - snd_soc_write(codec, ACCELCODEC_R1E, 0x40); + snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a); + snd_soc_component_write(component, ACCELCODEC_R1E, 0x40); /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: @@ -197,7 +185,8 @@ static int rk1000_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - snd_soc_write(codec, ACCELCODEC_R09, iface); + snd_soc_component_write(component, ACCELCODEC_R09, iface); + return 0; } @@ -205,70 +194,72 @@ static int rk1000_codec_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - u16 iface; + u32 iface; struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_component *component = dai->component; unsigned int dai_fmt; dai_fmt = rtd->card->dai_link[0].dai_fmt; - iface = snd_soc_read(codec, ACCELCODEC_R09) & 0x1f3; - snd_soc_write(codec, ACCELCODEC_R0C, 0x17); - snd_soc_write(codec, ACCELCODEC_R04, - ASC_INT_MUTE_L | ASC_INT_MUTE_R | + iface = snd_soc_component_read32(component, ACCELCODEC_R09) & 0x1f3; + snd_soc_component_write(component, ACCELCODEC_R0C, 0x17); + snd_soc_component_write(component, ACCELCODEC_R04, + ASC_INT_MUTE_L | ASC_INT_MUTE_R | ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF); - snd_soc_write(codec, ACCELCODEC_R0B, - ASC_DEC_DISABLE | ASC_INT_DISABLE); + snd_soc_component_write(component, ACCELCODEC_R0B, + ASC_DEC_DISABLE | ASC_INT_DISABLE); if ((dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) iface |= ASC_INVERT_BCLK; - snd_soc_write(codec, ACCELCODEC_R09, iface); - snd_soc_write(codec, ACCELCODEC_R0A, 0xa0); - snd_soc_write(codec, ACCELCODEC_R0B, ASC_DEC_ENABLE | ASC_INT_ENABLE); + snd_soc_component_write(component, ACCELCODEC_R09, iface); + snd_soc_component_write(component, ACCELCODEC_R0A, 0xa0); + snd_soc_component_write(component, ACCELCODEC_R0B, ASC_DEC_ENABLE | ASC_INT_ENABLE); + return 0; } static int rk1000_codec_mute(struct snd_soc_dai *dai, int mute) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_component *component = dai->component; struct rk1000_codec_priv *rk1000_codec; - rk1000_codec = snd_soc_codec_get_drvdata(codec); + rk1000_codec = snd_soc_component_get_drvdata(component); if (mute) { /* AOL */ - snd_soc_write(codec, ACCELCODEC_R17, 0xFF); + snd_soc_component_write(component, ACCELCODEC_R17, 0xFF); /* AOR */ - snd_soc_write(codec, ACCELCODEC_R18, 0xFF); + snd_soc_component_write(component, ACCELCODEC_R18, 0xFF); /* AOM */ - snd_soc_write(codec, ACCELCODEC_R19, 0xFF); + snd_soc_component_write(component, ACCELCODEC_R19, 0xFF); /* soft mute */ - snd_soc_write(codec, ACCELCODEC_R04, - ASC_INT_MUTE_L | ASC_INT_MUTE_R | + snd_soc_component_write(component, ACCELCODEC_R04, + ASC_INT_MUTE_L | ASC_INT_MUTE_R | ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF); } else { /* setup Vmid and Vref, other module power down */ - snd_soc_write(codec, ACCELCODEC_R1D, 0x2a); - snd_soc_write(codec, ACCELCODEC_R1E, 0x40); + snd_soc_component_write(component, ACCELCODEC_R1D, 0x2a); + snd_soc_component_write(component, ACCELCODEC_R1E, 0x40); /* AOL */ - snd_soc_write(codec, ACCELCODEC_R17, - VOLUME_CODEC_PA | ASC_OUTPUT_ACTIVE | + snd_soc_component_write(component, ACCELCODEC_R17, + VOLUME_CODEC_PA | ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN); /* AOR */ - snd_soc_write(codec, ACCELCODEC_R18, - VOLUME_CODEC_PA | ASC_OUTPUT_ACTIVE | + snd_soc_component_write(component, ACCELCODEC_R18, + VOLUME_CODEC_PA | ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN); - snd_soc_write(codec, ACCELCODEC_R04, - ASC_INT_ACTIVE_L | ASC_INT_ACTIVE_R | + snd_soc_component_write(component, ACCELCODEC_R04, + ASC_INT_ACTIVE_L | ASC_INT_ACTIVE_R | ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF); /* AOM */ - snd_soc_write(codec, ACCELCODEC_R19, 0x7F); + snd_soc_component_write(component, ACCELCODEC_R19, 0x7F); #if OUT_CAPLESS - snd_soc_write(codec, ACCELCODEC_R1F, - 0x09 | ASC_PDMIXM_ENABLE); + snd_soc_component_write(component, ACCELCODEC_R1F, + 0x09 | ASC_PDMIXM_ENABLE); #else - snd_soc_write(codec, ACCELCODEC_R1F, - 0x09 | ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE); + snd_soc_component_write(component, ACCELCODEC_R1F, + 0x09 | ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE); #endif } + return 0; } @@ -277,9 +268,9 @@ static void pa_delayedwork(struct work_struct *work) struct rk1000_codec_priv *priv = container_of(work, struct rk1000_codec_priv, pa_delayed_work.work); - struct snd_soc_codec *codec = priv->codec; + struct snd_soc_component *component = priv->component; - spk_ctrl_fun(codec, GPIO_HIGH); + spk_ctrl_fun(component, GPIO_HIGH); } static struct snd_soc_dai_ops rk1000_codec_ops = { @@ -289,9 +280,10 @@ static struct snd_soc_dai_ops rk1000_codec_ops = { }; #define RK1000_CODEC_RATES SNDRV_PCM_RATE_8000_192000 -#define RK1000_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) +#define RK1000_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + static struct snd_soc_dai_driver rk1000_codec_dai[] = { { .name = "rk1000_codec", @@ -314,7 +306,7 @@ static struct snd_soc_dai_driver rk1000_codec_dai[] = { } }; -static void rk1000_codec_reg_init(struct snd_soc_codec *codec) +static void rk1000_codec_reg_init(struct snd_soc_component *component) { struct rk1000_codec_priv *rk1000_codec; unsigned int digital_gain; @@ -322,118 +314,120 @@ static void rk1000_codec_reg_init(struct snd_soc_codec *codec) int ret; mic_vol = VOLUME_INPUT; - rk1000_codec = snd_soc_codec_get_drvdata(codec); - ret = snd_soc_write(codec, ACCELCODEC_R1D, 0x30); - snd_soc_write(codec, ACCELCODEC_R1E, 0x40); + rk1000_codec = snd_soc_component_get_drvdata(component); + ret = snd_soc_component_write(component, ACCELCODEC_R1D, 0x30); + snd_soc_component_write(component, ACCELCODEC_R1E, 0x40); /*Route R-LPF->R-Mixer, L-LPF->L-Mixer*/ - snd_soc_write(codec, ACCELCODEC_R15, 0xC1); + snd_soc_component_write(component, ACCELCODEC_R15, 0xC1); /*With Cap Output, VMID ramp up slow*/ - snd_soc_write(codec, ACCELCODEC_R1A, 0x14); + snd_soc_component_write(component, ACCELCODEC_R1A, 0x14); mdelay(10); - snd_soc_write(codec, ACCELCODEC_R0C, 0x10 | ASC_INPUT_VOL_0DB); - snd_soc_write(codec, ACCELCODEC_R0D, 0x10 | ASC_INPUT_VOL_0DB); + snd_soc_component_write(component, ACCELCODEC_R0C, 0x10 | ASC_INPUT_VOL_0DB); + snd_soc_component_write(component, ACCELCODEC_R0D, 0x10 | ASC_INPUT_VOL_0DB); if (mic_vol > 0x07) { /*Select MIC input*/ - snd_soc_write(codec, ACCELCODEC_R12, - 0x4c | ASC_MIC_INPUT | ASC_MIC_BOOST_20DB); + snd_soc_component_write(component, ACCELCODEC_R12, + 0x4c | ASC_MIC_INPUT | ASC_MIC_BOOST_20DB); mic_vol -= 0x07; - } else + } else { /*Select MIC input*/ - snd_soc_write(codec, ACCELCODEC_R12, 0x4c | ASC_MIC_INPUT); + snd_soc_component_write(component, ACCELCODEC_R12, 0x4c | ASC_MIC_INPUT); + } /*use default value*/ - snd_soc_write(codec, ACCELCODEC_R1C, ASC_DEM_ENABLE); - snd_soc_write(codec, ACCELCODEC_R0E, 0x10 | mic_vol); + snd_soc_component_write(component, ACCELCODEC_R1C, ASC_DEM_ENABLE); + snd_soc_component_write(component, ACCELCODEC_R0E, 0x10 | mic_vol); /* disable route PGA->R/L Mixer, PGA gain 0db. */ - snd_soc_write(codec, ACCELCODEC_R13, 0x05 | 0 << 3); - snd_soc_write(codec, ACCELCODEC_R14, 0x05 | 0 << 3); + snd_soc_component_write(component, ACCELCODEC_R13, 0x05 | 0 << 3); + snd_soc_component_write(component, ACCELCODEC_R14, 0x05 | 0 << 3); /*2soft mute*/ - snd_soc_write(codec, ACCELCODEC_R04, - ASC_INT_MUTE_L | ASC_INT_MUTE_R | - ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF); + snd_soc_component_write(component, ACCELCODEC_R04, + ASC_INT_MUTE_L | ASC_INT_MUTE_R | + ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF); /*2set default SR and clk*/ - snd_soc_write(codec, ACCELCODEC_R0A, FREQ441KHZ | ASC_NORMAL_MODE | - (0x10 << 1) | ASC_CLKNODIV | ASC_CLK_ENABLE); + snd_soc_component_write(component, ACCELCODEC_R0A, FREQ441KHZ | ASC_NORMAL_MODE | + (0x10 << 1) | ASC_CLKNODIV | ASC_CLK_ENABLE); /*2Config audio interface*/ - snd_soc_write(codec, ACCELCODEC_R09, ASC_I2S_MODE | - ASC_16BIT_MODE | ASC_NORMAL_LRCLK | - ASC_LRSWAP_DISABLE | ASC_NORMAL_BCLK); - snd_soc_write(codec, ACCELCODEC_R00, ASC_HPF_ENABLE | - ASC_DSM_MODE_ENABLE | ASC_SCRAMBLE_ENABLE | - ASC_DITHER_ENABLE | ASC_BCLKDIV_4); + snd_soc_component_write(component, ACCELCODEC_R09, ASC_I2S_MODE | + ASC_16BIT_MODE | ASC_NORMAL_LRCLK | + ASC_LRSWAP_DISABLE | ASC_NORMAL_BCLK); + snd_soc_component_write(component, ACCELCODEC_R00, ASC_HPF_ENABLE | + ASC_DSM_MODE_ENABLE | ASC_SCRAMBLE_ENABLE | + ASC_DITHER_ENABLE | ASC_BCLKDIV_4); /*2volume,input,output*/ digital_gain = VOLUME_OUTPUT; - if (snd_soc_read(codec, ACCELCODEC_R05) != 0x0f) { - snd_soc_write(codec, ACCELCODEC_R05, - (digital_gain >> 8) & 0xFF); - snd_soc_write(codec, ACCELCODEC_R06, digital_gain & 0xFF); + if (snd_soc_component_read32(component, ACCELCODEC_R05) != 0x0f) { + snd_soc_component_write(component, ACCELCODEC_R05, + (digital_gain >> 8) & 0xFF); + snd_soc_component_write(component, ACCELCODEC_R06, digital_gain & 0xFF); } - if (snd_soc_read(codec, ACCELCODEC_R07) != 0x0f) { - snd_soc_write(codec, ACCELCODEC_R07, - (digital_gain >> 8) & 0xFF); - snd_soc_write(codec, ACCELCODEC_R08, digital_gain & 0xFF); + if (snd_soc_component_read32(component, ACCELCODEC_R07) != 0x0f) { + snd_soc_component_write(component, ACCELCODEC_R07, + (digital_gain >> 8) & 0xFF); + snd_soc_component_write(component, ACCELCODEC_R08, digital_gain & 0xFF); } - snd_soc_write(codec, ACCELCODEC_R0B, - ASC_DEC_ENABLE | ASC_INT_ENABLE); + snd_soc_component_write(component, ACCELCODEC_R0B, + ASC_DEC_ENABLE | ASC_INT_ENABLE); #if OUT_CAPLESS - snd_soc_write(codec, ACCELCODEC_R1F, - 0x09 | ASC_PDMIXM_ENABLE); + snd_soc_component_write(component, ACCELCODEC_R1F, + 0x09 | ASC_PDMIXM_ENABLE); #else - snd_soc_write(codec, ACCELCODEC_R1F, 0x09 | - ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE); + snd_soc_component_write(component, ACCELCODEC_R1F, 0x09 | + ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE); #endif - snd_soc_write(codec, ACCELCODEC_R17, VOLUME_CODEC_PA | - ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN); - snd_soc_write(codec, ACCELCODEC_R18, VOLUME_CODEC_PA | - ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN); - snd_soc_write(codec, ACCELCODEC_R04, ASC_INT_ACTIVE_L | - ASC_INT_ACTIVE_R | ASC_SIDETONE_L_OFF | - ASC_SIDETONE_R_OFF); - snd_soc_write(codec, ACCELCODEC_R19, 0x7F); + snd_soc_component_write(component, ACCELCODEC_R17, VOLUME_CODEC_PA | + ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN); + snd_soc_component_write(component, ACCELCODEC_R18, VOLUME_CODEC_PA | + ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN); + snd_soc_component_write(component, ACCELCODEC_R04, ASC_INT_ACTIVE_L | + ASC_INT_ACTIVE_R | ASC_SIDETONE_L_OFF | + ASC_SIDETONE_R_OFF); + snd_soc_component_write(component, ACCELCODEC_R19, 0x7F); } -static int rk1000_codec_suspend(struct snd_soc_codec *codec) +static int rk1000_codec_suspend(struct snd_soc_component *component) { - spk_ctrl_fun(codec, GPIO_LOW); - rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); + spk_ctrl_fun(component, GPIO_LOW); + rk1000_codec_set_bias_level(component, SND_SOC_BIAS_OFF); + return 0; } -static int rk1000_codec_resume(struct snd_soc_codec *codec) +static int rk1000_codec_resume(struct snd_soc_component *component) { - rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - spk_ctrl_fun(codec, GPIO_HIGH); + rk1000_codec_set_bias_level(component, SND_SOC_BIAS_PREPARE); + spk_ctrl_fun(component, GPIO_HIGH); + return 0; } -static int rk1000_codec_probe(struct snd_soc_codec *codec) +static int rk1000_codec_probe(struct snd_soc_component *component) { struct rk1000_codec_priv *rk1000_codec; - rk1000_codec = snd_soc_codec_get_drvdata(codec); - rk1000_codec->codec = codec; + rk1000_codec = snd_soc_component_get_drvdata(component); + rk1000_codec->component = component; INIT_DELAYED_WORK(&rk1000_codec->pa_delayed_work, pa_delayedwork); - rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_PREPARE); + rk1000_codec_set_bias_level(component, SND_SOC_BIAS_PREPARE); schedule_delayed_work(&rk1000_codec->pa_delayed_work, msecs_to_jiffies(rk1000_codec->pa_enable_time)); - rk1000_codec_reg_init(codec); + rk1000_codec_reg_init(component); return 0; } -static int rk1000_codec_remove(struct snd_soc_codec *codec) +static void rk1000_codec_remove(struct snd_soc_component *component) { - rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; + rk1000_codec_set_bias_level(component, SND_SOC_BIAS_OFF); } -static struct snd_soc_codec_driver soc_codec_dev_rk1000_codec = { +static const struct snd_soc_component_driver soc_codec_dev_rk1000_codec = { .probe = rk1000_codec_probe, .remove = rk1000_codec_remove, .suspend = rk1000_codec_suspend, @@ -544,9 +538,9 @@ static int rk1000_codec_i2c_probe(struct i2c_client *i2c, regmap_write(rk1000->ctlmap, CODEC_CON, CODEC_ON); - return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rk1000_codec, - rk1000_codec_dai, - ARRAY_SIZE(rk1000_codec_dai)); + return devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_rk1000_codec, + rk1000_codec_dai, + ARRAY_SIZE(rk1000_codec_dai)); } static int rk1000_codec_i2c_remove(struct i2c_client *i2c) @@ -554,7 +548,6 @@ static int rk1000_codec_i2c_remove(struct i2c_client *i2c) struct rk1000_codec_priv *rk1000 = i2c_get_clientdata(i2c); regmap_write(rk1000->ctlmap, CODEC_CON, CODEC_OFF); - snd_soc_unregister_codec(&i2c->dev); return 0; }