Merge remote-tracking branches 'asoc/topic/rt5659', 'asoc/topic/rt5660', 'asoc/topic...
authorMark Brown <broonie@kernel.org>
Thu, 29 Sep 2016 19:44:37 +0000 (12:44 -0700)
committerMark Brown <broonie@kernel.org>
Thu, 29 Sep 2016 19:44:37 +0000 (12:44 -0700)
1  2  3  4  5 
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/rt5659.c
sound/soc/codecs/rt5677.c
sound/soc/codecs/uda134x.c
sound/soc/samsung/s3c24xx_uda134x.c

diff --combined sound/soc/codecs/Kconfig
@@@@@@ -92,7 -92,6 -92,6 -92,6 -92,6 +92,7 @@@@@@ config SND_SOC_ALL_CODEC
        select SND_SOC_MAX9877 if I2C
        select SND_SOC_MC13783 if MFD_MC13XXX
        select SND_SOC_ML26124 if I2C
 ++++   select SND_SOC_NAU8810 if I2C
        select SND_SOC_NAU8825 if I2C
        select SND_SOC_HDMI_CODEC
        select SND_SOC_PCM1681 if I2C
        select SND_SOC_RT5645 if I2C
        select SND_SOC_RT5651 if I2C
        select SND_SOC_RT5659 if I2C
++ ++   select SND_SOC_RT5660 if I2C
++ ++   select SND_SOC_RT5663 if I2C
        select SND_SOC_RT5670 if I2C
        select SND_SOC_RT5677 if I2C && SPI_MASTER
        select SND_SOC_SGTL5000 if I2C
@@@@@@ -646,6 -645,6 -647,8 -645,6 -645,6 +648,8 @@@@@@ config SND_SOC_RL623
        default y if SND_SOC_RT5645=y
        default y if SND_SOC_RT5651=y
        default y if SND_SOC_RT5659=y
++ ++   default y if SND_SOC_RT5660=y
++ ++   default y if SND_SOC_RT5663=y
        default y if SND_SOC_RT5670=y
        default y if SND_SOC_RT5677=y
        default m if SND_SOC_RT5514=m
        default m if SND_SOC_RT5645=m
        default m if SND_SOC_RT5651=m
        default m if SND_SOC_RT5659=m
++ ++   default m if SND_SOC_RT5660=m
++ ++   default m if SND_SOC_RT5663=m
        default m if SND_SOC_RT5670=m
        default m if SND_SOC_RT5677=m
     
@@@@@@ -666,6 -665,6 -671,7 -665,6 -665,6 +672,7 @@@@@@ config SND_SOC_RL6347
     
     config SND_SOC_RT286
        tristate
++ ++   select SND_SOC_RT5663
        depends on I2C
     
     config SND_SOC_RT298
@@@@@@ -698,6 -697,6 -704,12 -697,6 -697,6 +705,12 @@@@@@ config SND_SOC_RT565
     config SND_SOC_RT5659
        tristate
     
++ ++config SND_SOC_RT5660
++ ++   tristate
++ ++
++ ++config SND_SOC_RT5663
++ ++   tristate
++ ++
     config SND_SOC_RT5670
        tristate
     
@@@@@@ -1065,10 -1064,6 -1077,6 -1064,6 -1064,6 +1078,10 @@@@@@ config SND_SOC_MC1378
     config SND_SOC_ML26124
        tristate
     
 ++++config SND_SOC_NAU8810
 ++++   tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
 ++++   depends on I2C
 ++++
     config SND_SOC_NAU8825
        tristate
     
@@@@@@ -86,7 -86,6 -86,6 -86,6 -86,6 +86,7 @@@@@@ snd-soc-max9850-objs := max9850.
     snd-soc-max9860-objs := max9860.o
     snd-soc-mc13783-objs := mc13783.o
     snd-soc-ml26124-objs := ml26124.o
 ++++snd-soc-nau8810-objs := nau8810.o
     snd-soc-nau8825-objs := nau8825.o
     snd-soc-hdmi-codec-objs := hdmi-codec.o
     snd-soc-pcm1681-objs := pcm1681.o
@@@@@@ -113,6 -112,6 -112,8 -112,6 -112,6 +113,8 @@@@@@ snd-soc-rt5640-objs := rt5640.
     snd-soc-rt5645-objs := rt5645.o
     snd-soc-rt5651-objs := rt5651.o
     snd-soc-rt5659-objs := rt5659.o
++ ++snd-soc-rt5660-objs := rt5660.o
++ ++snd-soc-rt5663-objs := rt5663.o
     snd-soc-rt5670-objs := rt5670.o
     snd-soc-rt5677-objs := rt5677.o
     snd-soc-rt5677-spi-objs := rt5677-spi.o
@@@@@@ -308,7 -307,6 -309,6 -307,6 -307,6 +310,7 @@@@@@ obj-$(CONFIG_SND_SOC_MAX9850)   += snd-so
     obj-$(CONFIG_SND_SOC_MAX9860)      += snd-soc-max9860.o
     obj-$(CONFIG_SND_SOC_MC13783)      += snd-soc-mc13783.o
     obj-$(CONFIG_SND_SOC_ML26124)      += snd-soc-ml26124.o
 ++++obj-$(CONFIG_SND_SOC_NAU8810)   += snd-soc-nau8810.o
     obj-$(CONFIG_SND_SOC_NAU8825)   += snd-soc-nau8825.o
     obj-$(CONFIG_SND_SOC_HDMI_CODEC)   += snd-soc-hdmi-codec.o
     obj-$(CONFIG_SND_SOC_PCM1681)      += snd-soc-pcm1681.o
@@@@@@ -335,6 -333,6 -335,8 -333,6 -333,6 +337,8 @@@@@@ obj-$(CONFIG_SND_SOC_RT5640)    += snd-soc
     obj-$(CONFIG_SND_SOC_RT5645)       += snd-soc-rt5645.o
     obj-$(CONFIG_SND_SOC_RT5651)       += snd-soc-rt5651.o
     obj-$(CONFIG_SND_SOC_RT5659)       += snd-soc-rt5659.o
++ ++obj-$(CONFIG_SND_SOC_RT5660)       += snd-soc-rt5660.o
++ ++obj-$(CONFIG_SND_SOC_RT5663)       += snd-soc-rt5663.o
     obj-$(CONFIG_SND_SOC_RT5670)       += snd-soc-rt5670.o
     obj-$(CONFIG_SND_SOC_RT5677)       += snd-soc-rt5677.o
     obj-$(CONFIG_SND_SOC_RT5677_SPI)   += snd-soc-rt5677-spi.o
@@@@@@ -9,6 -9,7 -9,6 -9,6 -9,6 +9,7 @@@@@@
      * published by the Free Software Foundation.
      */
     
+ +++#include <linux/clk.h>
     #include <linux/module.h>
     #include <linux/moduleparam.h>
     #include <linux/init.h>
@@@@@@ -3565,7 -3566,9 -3565,7 -3565,7 -3565,7 +3566,9 @@@@@@ static int rt5659_set_bclk_ratio(struc
     static int rt5659_set_bias_level(struct snd_soc_codec *codec,
                        enum snd_soc_bias_level level)
     {
+ +++   struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
        struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+ +++   int ret;
     
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
                        RT5659_PWR_FV1 | RT5659_PWR_FV2);
                break;
     
+ +++   case SND_SOC_BIAS_STANDBY:
+ +++           if (dapm->bias_level == SND_SOC_BIAS_OFF) {
+ +++                   ret = clk_prepare_enable(rt5659->mclk);
+ +++                   if (ret) {
+ +++                           dev_err(codec->dev,
+ +++                                   "failed to enable MCLK: %d\n", ret);
+ +++                           return ret;
+ +++                   }
+ +++           }
+ +++           break;
+ +++
        case SND_SOC_BIAS_OFF:
                regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1,
                        RT5659_PWR_LDO, 0);
                        RT5659_PWR_MB | RT5659_PWR_VREF2);
                regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC,
                        RT5659_DIG_GATE_CTRL, 0);
+ +++           clk_disable_unprepare(rt5659->mclk);
                break;
     
        default:
@@@@@@ -3722,14 -3737,12 -3722,12 -3722,12 -3722,12 +3737,14 @@@@@@ static struct snd_soc_codec_driver soc_
        .resume = rt5659_resume,
        .set_bias_level = rt5659_set_bias_level,
        .idle_bias_off = true,
 ----   .controls = rt5659_snd_controls,
 ----   .num_controls = ARRAY_SIZE(rt5659_snd_controls),
 ----   .dapm_widgets = rt5659_dapm_widgets,
 ----   .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets),
 ----   .dapm_routes = rt5659_dapm_routes,
 ----   .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes),
 ++++   .component_driver = {
 ++++           .controls               = rt5659_snd_controls,
 ++++           .num_controls           = ARRAY_SIZE(rt5659_snd_controls),
 ++++           .dapm_widgets           = rt5659_dapm_widgets,
 ++++           .num_dapm_widgets       = ARRAY_SIZE(rt5659_dapm_widgets),
 ++++           .dapm_routes            = rt5659_dapm_routes,
 ++++           .num_dapm_routes        = ARRAY_SIZE(rt5659_dapm_routes),
 ++++   },
     };
     
     
@@@@@@ -4022,6 -4035,15 -4020,6 -4020,6 -4020,6 +4037,15 @@@@@@ static int rt5659_i2c_probe(struct i2c_
     
        regmap_write(rt5659->regmap, RT5659_RESET, 0);
     
+ +++   /* Check if MCLK provided */
+ +++   rt5659->mclk = devm_clk_get(&i2c->dev, "mclk");
+ +++   if (IS_ERR(rt5659->mclk)) {
+ +++           if (PTR_ERR(rt5659->mclk) != -ENOENT)
+ +++                   return PTR_ERR(rt5659->mclk);
+ +++           /* Otherwise mark the mclk pointer to NULL */
+ +++           rt5659->mclk = NULL;
+ +++   }
+ +++
        rt5659_calibrate(rt5659);
     
        /* line in diff mode*/
                if (ret)
                        dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
     
+ +++           /* Enable IRQ output for GPIO1 pin any way */
+ +++           regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
+ +++                              RT5659_GP1_PIN_MASK, RT5659_GP1_PIN_IRQ);
        }
     
        return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
@@@@@@ -9,6 -9,6 -9,6 -9,7 -9,6 +9,7 @@@@@@
      * published by the Free Software Foundation.
      */
     
+++ +#include <linux/acpi.h>
     #include <linux/fs.h>
     #include <linux/module.h>
     #include <linux/moduleparam.h>
     
     #define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING))
     
+++ +/* GPIO indexes defined by ACPI */
+++ +enum {
+++ +   RT5677_GPIO_PLUG_DET            = 0,
+++ +   RT5677_GPIO_MIC_PRESENT_L       = 1,
+++ +   RT5677_GPIO_HOTWORD_DET_L       = 2,
+++ +   RT5677_GPIO_DSP_INT             = 3,
+++ +   RT5677_GPIO_HP_AMP_SHDN_L       = 4,
+++ +};
+++ +
     static const struct regmap_range_cfg rt5677_ranges[] = {
        {
                .name = "PR",
@@@@@@ -4657,7 -4657,7 -4657,7 -4667,7 -4657,7 +4667,7 @@@@@@ static int rt5677_to_irq(struct gpio_ch
        return regmap_irq_get_virq(data, irq);
     }
     
 ----static struct gpio_chip rt5677_template_chip = {
 ++++static const struct gpio_chip rt5677_template_chip = {
        .label                  = "rt5677",
        .owner                  = THIS_MODULE,
        .direction_output       = rt5677_gpio_direction_out,
@@@@@@ -4974,14 -4974,12 -4974,12 -4984,12 -4974,12 +4984,14 @@@@@@ static struct snd_soc_codec_driver soc_
        .resume = rt5677_resume,
        .set_bias_level = rt5677_set_bias_level,
        .idle_bias_off = true,
 ----   .controls = rt5677_snd_controls,
 ----   .num_controls = ARRAY_SIZE(rt5677_snd_controls),
 ----   .dapm_widgets = rt5677_dapm_widgets,
 ----   .num_dapm_widgets = ARRAY_SIZE(rt5677_dapm_widgets),
 ----   .dapm_routes = rt5677_dapm_routes,
 ----   .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes),
 ++++   .component_driver = {
 ++++           .controls               = rt5677_snd_controls,
 ++++           .num_controls           = ARRAY_SIZE(rt5677_snd_controls),
 ++++           .dapm_widgets           = rt5677_dapm_widgets,
 ++++           .num_dapm_widgets       = ARRAY_SIZE(rt5677_dapm_widgets),
 ++++           .dapm_routes            = rt5677_dapm_routes,
 ++++           .num_dapm_routes        = ARRAY_SIZE(rt5677_dapm_routes),
 ++++   },
     };
     
     static const struct regmap_config rt5677_regmap_physical = {
@@@@@@ -5020,10 -5018,10 -5018,10 -5028,47 -5018,10 +5030,47 @@@@@@ static const struct regmap_config rt567
     static const struct i2c_device_id rt5677_i2c_id[] = {
        { "rt5677", RT5677 },
        { "rt5676", RT5676 },
+++ +   { "RT5677CE:00", RT5677 },
        { }
     };
     MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
     
+++ +static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false };
+++ +static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false };
+++ +static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false };
+++ +
+++ +static const struct acpi_gpio_mapping bdw_rt5677_gpios[] = {
+++ +   { "plug-det-gpios", &plug_det_gpio, 1 },
+++ +   { "mic-present-gpios", &mic_present_gpio, 1 },
+++ +   { "headphone-enable-gpios", &headphone_enable_gpio, 1 },
+++ +   { NULL },
+++ +};
+++ +
+++ +static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677,
+++ +           struct device *dev)
+++ +{
+++ +   int ret;
+++ +   u32 val;
+++ +
+++ +   ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev),
+++ +                   bdw_rt5677_gpios);
+++ +   if (ret)
+++ +           dev_warn(dev, "Failed to add driver gpios\n");
+++ +
+++ +   if (!device_property_read_u32(dev, "DCLK", &val))
+++ +           rt5677->pdata.dmic2_clk_pin = val;
+++ +
+++ +   rt5677->pdata.in1_diff = device_property_read_bool(dev, "IN1");
+++ +   rt5677->pdata.in2_diff = device_property_read_bool(dev, "IN2");
+++ +   rt5677->pdata.lout1_diff = device_property_read_bool(dev, "OUT1");
+++ +   rt5677->pdata.lout2_diff = device_property_read_bool(dev, "OUT2");
+++ +   rt5677->pdata.lout3_diff = device_property_read_bool(dev, "OUT3");
+++ +
+++ +   device_property_read_u32(dev, "JD1", &rt5677->pdata.jd1_gpio);
+++ +   device_property_read_u32(dev, "JD2", &rt5677->pdata.jd2_gpio);
+++ +   device_property_read_u32(dev, "JD3", &rt5677->pdata.jd3_gpio);
+++ +}
+++ +
     static void rt5677_read_device_properties(struct rt5677_priv *rt5677,
                struct device *dev)
     {
@@@@@@ -5129,8 -5127,8 -5127,8 -5174,12 -5127,8 +5176,12 @@@@@@ static int rt5677_i2c_probe(struct i2c_
     
        if (pdata)
                rt5677->pdata = *pdata;
--- -   else
+++ +   else if (i2c->dev.of_node)
                rt5677_read_device_properties(rt5677, &i2c->dev);
+++ +   else if (ACPI_HANDLE(&i2c->dev))
+++ +           rt5677_read_acpi_properties(rt5677, &i2c->dev);
+++ +   else
+++ +           return -EINVAL;
     
        /* pow-ldo2 and reset are optional. The codec pins may be statically
         * connected on the board without gpios. If the gpio device property
@@@@@@ -523,12 -523,10 -523,10 -523,10 -523,10 +523,12 @@@@@@ static struct snd_soc_codec_driver soc_
        .set_bias_level = uda134x_set_bias_level,
        .suspend_bias_off = true,
     
 ----   .dapm_widgets = uda134x_dapm_widgets,
 ----   .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets),
 ----   .dapm_routes = uda134x_dapm_routes,
 ----   .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes),
 ++++   .component_driver = {
 ++++           .dapm_widgets           = uda134x_dapm_widgets,
 ++++           .num_dapm_widgets       = ARRAY_SIZE(uda134x_dapm_widgets),
 ++++           .dapm_routes            = uda134x_dapm_routes,
 ++++           .num_dapm_routes        = ARRAY_SIZE(uda134x_dapm_routes),
 ++++   },
     };
     
     static const struct regmap_config uda134x_regmap_config = {
@@@@@@ -546,6 -544,6 -544,6 -544,6 -544,7 +546,7 @@@@@@ static int uda134x_codec_probe(struct p
     {
        struct uda134x_platform_data *pd = pdev->dev.platform_data;
        struct uda134x_priv *uda134x;
++++    int ret;
     
        if (!pd) {
                dev_err(&pdev->dev, "Missing L3 bitbang function\n");
        uda134x->pd = pd;
        platform_set_drvdata(pdev, uda134x);
     
++++    if (pd->l3.use_gpios) {
++++            ret = l3_set_gpio_ops(&pdev->dev, &uda134x->pd->l3);
++++            if (ret < 0)
++++                    return ret;
++++    }
++++ 
        uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd,
                &uda134x_regmap_config);
        if (IS_ERR(uda134x->regmap))
@@@@@@ -54,29 -54,28 -54,28 -54,28 -54,26 +54,27 @@@@@@ static struct snd_pcm_hw_constraint_lis
     };
     #endif
     
---- static struct platform_device *s3c24xx_uda134x_snd_device;
---- 
     static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
     {
 ----   int ret = 0;
 ++++   struct snd_soc_pcm_runtime *rtd = substream->private_data;
 ++++   struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
     #ifdef ENFORCE_RATES
        struct snd_pcm_runtime *runtime = substream->runtime;
     #endif
 ++++   int ret = 0;
     
        mutex_lock(&clk_lock);
----    pr_debug("%s %d\n", __func__, clk_users);
++++ 
        if (clk_users == 0) {
----            xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
++++            xtal = clk_get(rtd->dev, "xtal");
                if (IS_ERR(xtal)) {
----                    printk(KERN_ERR "%s cannot get xtal\n", __func__);
++++                    dev_err(rtd->dev, "%s cannot get xtal\n", __func__);
                        ret = PTR_ERR(xtal);
                } else {
 ----                   pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
 ----                                  "pclk");
 ++++                   pclk = clk_get(cpu_dai->dev, "iis");
                        if (IS_ERR(pclk)) {
----                            printk(KERN_ERR "%s cannot get pclk\n",
----                                   __func__);
++++                            dev_err(rtd->dev, "%s cannot get pclk\n",
++++                                    __func__);
                                clk_put(xtal);
                                ret = PTR_ERR(pclk);
                        }
                                                 SNDRV_PCM_HW_PARAM_RATE,
                                                 &hw_constraints_rates);
                if (ret < 0)
----                    printk(KERN_ERR "%s cannot set constraints\n",
----                           __func__);
++++                    dev_err(rtd->dev, "%s cannot set constraints\n",
++++                            __func__);
     #endif
        }
        return ret;
     static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
     {
        mutex_lock(&clk_lock);
----    pr_debug("%s %d\n", __func__, clk_users);
        clk_users -= 1;
        if (clk_users == 0) {
                clk_put(xtal);
@@@@@@ -159,18 -158,18 -158,18 -158,18 -155,19 +156,19 @@@@@@ static int s3c24xx_uda134x_hw_params(st
                clk_source = S3C24XX_CLKSRC_PCLK;
                div = bi % 33;
        }
----    pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
++++ 
++++    dev_dbg(rtd->dev, "%s desired rate %lu, %d\n", __func__, rate, bi);
     
        clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
----    pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
----             fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
----             clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
----             div, clk, err);
++++ 
++++    dev_dbg(rtd->dev, "%s will use: %s %s %d sysclk %d err %ld\n", __func__,
++++            fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
++++            clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
++++            div, clk, err);
     
        if ((err * 100 / rate) > 5) {
----            printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
----                   "too different from desired (%ld%%)\n",
----                   err * 100 / rate);
++++            dev_err(rtd->dev, "effective frequency too different "
++++                              "from desired (%ld%%)\n", err * 100 / rate);
                return -EINVAL;
        }
     
@@@@@@ -227,115 -226,115 -226,115 -226,115 -224,27 +225,27 @@@@@@ static struct snd_soc_card snd_soc_s3c2
        .num_links = 1,
     };
     
---- static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
---- 
---- static void setdat(int v)
---- {
----    gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
---- }
---- 
---- static void setclk(int v)
---- {
----    gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
---- }
---- 
---- static void setmode(int v)
---- {
----    gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
---- }
---- 
---- /* FIXME - This must be codec platform data but in which board file ?? */
---- static struct uda134x_platform_data s3c24xx_uda134x = {
----    .l3 = {
----            .setdat = setdat,
----            .setclk = setclk,
----            .setmode = setmode,
----            .data_hold = 1,
----            .data_setup = 1,
----            .clock_high = 1,
----            .mode_hold = 1,
----            .mode = 1,
----            .mode_setup = 1,
----    },
---- };
---- 
---- static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
---- {
----    if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
----            printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
----                   "l3 %s pin already in use", fun);
----            return -EBUSY;
----    }
----    gpio_direction_output(pin, 0);
----    return 0;
---- }
---- 
     static int s3c24xx_uda134x_probe(struct platform_device *pdev)
     {
++++    struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x;
        int ret;
     
----    printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
++++    platform_set_drvdata(pdev, card);
++++    card->dev = &pdev->dev;
     
----    s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
----    if (s3c24xx_uda134x_l3_pins == NULL) {
----            printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
----                   "unable to find platform data\n");
----            return -ENODEV;
----    }
----    s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
----    s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
---- 
----    if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
----                                  "data") < 0)
----            return -EBUSY;
----    if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
----                                  "clk") < 0) {
----            gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
----            return -EBUSY;
----    }
----    if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
----                                  "mode") < 0) {
----            gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
----            gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
----            return -EBUSY;
----    }
---- 
----    s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
----    if (!s3c24xx_uda134x_snd_device) {
----            printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
----                   "Unable to register\n");
----            return -ENOMEM;
----    }
---- 
----    platform_set_drvdata(s3c24xx_uda134x_snd_device,
----                         &snd_soc_s3c24xx_uda134x);
----    platform_device_add_data(s3c24xx_uda134x_snd_device, &s3c24xx_uda134x, sizeof(s3c24xx_uda134x));
----    ret = platform_device_add(s3c24xx_uda134x_snd_device);
----    if (ret) {
----            printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
----            platform_device_put(s3c24xx_uda134x_snd_device);
----    }
++++    ret = devm_snd_soc_register_card(&pdev->dev, card);
++++    if (ret)
++++            dev_err(&pdev->dev, "failed to register card: %d\n", ret);
     
        return ret;
     }
     
---- static int s3c24xx_uda134x_remove(struct platform_device *pdev)
---- {
----    platform_device_unregister(s3c24xx_uda134x_snd_device);
----    gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
----    gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
----    gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
----    return 0;
---- }
---- 
     static struct platform_driver s3c24xx_uda134x_driver = {
        .probe  = s3c24xx_uda134x_probe,
----    .remove = s3c24xx_uda134x_remove,
        .driver = {
                .name = "s3c24xx_uda134x",
        },
     };
---- 
     module_platform_driver(s3c24xx_uda134x_driver);
     
     MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");