ASoC/mpc5200: Track DMA position by period number instead of bytes
[safe/jmp/linux-2.6] / sound / soc / codecs / cs4270.c
index e5f5afd..ffe122d 100644 (file)
  *
  * Current features/limitations:
  *
- * 1) Software mode is supported.  Stand-alone mode is not supported.
- * 2) Only I2C is supported, not SPI
- * 3) Only Master mode is supported, not Slave.
- * 4) The machine driver's 'startup' function must call
- *    cs4270_set_dai_sysclk() with the value of MCLK.
- * 5) Only I2S and left-justified modes are supported
- * 6) Power management is not supported
- * 7) The only supported control is volume and hardware mute (if enabled)
+ * - Software mode is supported.  Stand-alone mode is not supported.
+ * - Only I2C is supported, not SPI
+ * - Support for master and slave mode
+ * - The machine driver's 'startup' function must call
+ *   cs4270_set_dai_sysclk() with the value of MCLK.
+ * - Only I2S and left-justified modes are supported
+ * - Power management is supported
  */
 
 #include <linux/module.h>
@@ -28,6 +27,7 @@
 #include <sound/soc.h>
 #include <sound/initval.h>
 #include <linux/i2c.h>
+#include <linux/delay.h>
 
 #include "cs4270.h"
 
@@ -57,6 +57,7 @@
 #define CS4270_FIRSTREG        0x01
 #define CS4270_LASTREG 0x08
 #define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)
+#define CS4270_I2C_INCR        0x80
 
 /* Bit masks for the CS4270 registers */
 #define CS4270_CHIPID_ID       0xF0
@@ -65,6 +66,8 @@
 #define CS4270_PWRCTL_PDN_ADC  0x20
 #define CS4270_PWRCTL_PDN_DAC  0x02
 #define CS4270_PWRCTL_PDN      0x01
+#define CS4270_PWRCTL_PDN_ALL  \
+       (CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
 #define CS4270_MODE_SPEED_MASK 0x30
 #define CS4270_MODE_1X         0x00
 #define CS4270_MODE_2X         0x10
@@ -109,6 +112,8 @@ struct cs4270_private {
        u8 reg_cache[CS4270_NUMREGS];
        unsigned int mclk; /* Input frequency of the MCLK pin */
        unsigned int mode; /* The mode (I2S or left-justified) */
+       unsigned int slave_mode;
+       unsigned int manual_mute;
 };
 
 /**
@@ -149,7 +154,7 @@ struct cs4270_mode_ratios {
        u8 mclk;
 };
 
-static struct cs4270_mode_ratios[] = {
+static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
        {64, CS4270_MODE_4X, CS4270_MODE_DIV1},
 #ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
        {96, CS4270_MODE_4X, CS4270_MODE_DIV15},
@@ -212,7 +217,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        rates &= ~SNDRV_PCM_RATE_KNOT;
 
        if (!rates) {
-               printk(KERN_ERR "cs4270: could not find a valid sample rate\n");
+               dev_err(codec->dev, "could not find a valid sample rate\n");
                return -EINVAL;
        }
 
@@ -247,13 +252,27 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
        struct cs4270_private *cs4270 = codec->private_data;
        int ret = 0;
 
+       /* set DAI format */
        switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
        case SND_SOC_DAIFMT_LEFT_J:
                cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
                break;
        default:
-               printk(KERN_ERR "cs4270: invalid DAI format\n");
+               dev_err(codec->dev, "invalid dai format\n");
+               ret = -EINVAL;
+       }
+
+       /* set master/slave audio interface */
+       switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               cs4270->slave_mode = 1;
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               cs4270->slave_mode = 0;
+               break;
+       default:
+               /* all other modes are unsupported by the hardware */
                ret = -EINVAL;
        }
 
@@ -281,10 +300,10 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec)
        s32 length;
 
        length = i2c_smbus_read_i2c_block_data(i2c_client,
-               CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache);
+               CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache);
 
        if (length != CS4270_NUMREGS) {
-               printk(KERN_ERR "cs4270: I2C read failure, addr=0x%x\n",
+               dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
                       i2c_client->addr);
                return -EIO;
        }
@@ -340,7 +359,7 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
        if (cache[reg - CS4270_FIRSTREG] != value) {
                struct i2c_client *client = codec->control_data;
                if (i2c_smbus_write_byte_data(client, reg, value)) {
-                       printk(KERN_ERR "cs4270: I2C write failed\n");
+                       dev_err(codec->dev, "i2c write failed\n");
                        return -EIO;
                }
 
@@ -391,33 +410,28 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
 
        if (i == NUM_MCLK_RATIOS) {
                /* We did not find a matching ratio */
-               printk(KERN_ERR "cs4270: could not find matching ratio\n");
+               dev_err(codec->dev, "could not find matching ratio\n");
                return -EINVAL;
        }
 
-       /* Freeze and power-down the codec */
-
-       ret = snd_soc_write(codec, CS4270_PWRCTL, CS4270_PWRCTL_FREEZE |
-                           CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC |
-                           CS4270_PWRCTL_PDN);
-       if (ret < 0) {
-               printk(KERN_ERR "cs4270: I2C write failed\n");
-               return ret;
-       }
-
-       /* Program the mode control register */
+       /* Set the sample rate */
 
        reg = snd_soc_read(codec, CS4270_MODE);
        reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
-       reg |= cs4270_mode_ratios[i].speed_mode | cs4270_mode_ratios[i].mclk;
+       reg |= cs4270_mode_ratios[i].mclk;
+
+       if (cs4270->slave_mode)
+               reg |= CS4270_MODE_SLAVE;
+       else
+               reg |= cs4270_mode_ratios[i].speed_mode;
 
        ret = snd_soc_write(codec, CS4270_MODE, reg);
        if (ret < 0) {
-               printk(KERN_ERR "cs4270: I2C write failed\n");
+               dev_err(codec->dev, "i2c write failed\n");
                return ret;
        }
 
-       /* Program the format register */
+       /* Set the DAI format */
 
        reg = snd_soc_read(codec, CS4270_FORMAT);
        reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
@@ -430,54 +444,21 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
                reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
                break;
        default:
-               printk(KERN_ERR "cs4270: unknown format\n");
+               dev_err(codec->dev, "unknown dai format\n");
                return -EINVAL;
        }
 
        ret = snd_soc_write(codec, CS4270_FORMAT, reg);
        if (ret < 0) {
-               printk(KERN_ERR "cs4270: I2C write failed\n");
-               return ret;
-       }
-
-       /* Disable auto-mute.  This feature appears to be buggy, because in
-          some situations, auto-mute will not deactivate when it should. */
-
-       reg = snd_soc_read(codec, CS4270_MUTE);
-       reg &= ~CS4270_MUTE_AUTO;
-       ret = snd_soc_write(codec, CS4270_MUTE, reg);
-       if (ret < 0) {
-               printk(KERN_ERR "cs4270: I2C write failed\n");
-               return ret;
-       }
-
-       /* Disable automatic volume control.  It's enabled by default, and
-        * it causes volume change commands to be delayed, sometimes until
-        * after playback has started.
-        */
-
-       reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
-       reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
-       ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
-       if (ret < 0) {
-               printk(KERN_ERR "I2C write failed\n");
-               return ret;
-       }
-
-       /* Thaw and power-up the codec */
-
-       ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
-       if (ret < 0) {
-               printk(KERN_ERR "cs4270: I2C write failed\n");
+               dev_err(codec->dev, "i2c write failed\n");
                return ret;
        }
 
        return ret;
 }
 
-#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
 /**
- * cs4270_mute - enable/disable the CS4270 external mute
+ * cs4270_dai_mute - enable/disable the CS4270 external mute
  * @dai: the SOC DAI
  * @mute: 0 = disable mute, 1 = enable mute
  *
@@ -486,30 +467,65 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
  * board does not have the MUTEA or MUTEB pins connected to such circuitry,
  * then this function will do nothing.
  */
-static int cs4270_mute(struct snd_soc_dai *dai, int mute)
+static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
 {
        struct snd_soc_codec *codec = dai->codec;
+       struct cs4270_private *cs4270 = codec->private_data;
        int reg6;
 
        reg6 = snd_soc_read(codec, CS4270_MUTE);
 
        if (mute)
-               reg6 |= CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B |
-                       CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
-       else
-               reg6 &= ~(CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B |
-                         CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
+               reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
+       else {
+               reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
+               reg6 |= cs4270->manual_mute;
+       }
 
        return snd_soc_write(codec, CS4270_MUTE, reg6);
 }
-#else
-#define cs4270_mute NULL
-#endif
+
+/**
+ * cs4270_soc_put_mute - put callback for the 'Master Playback switch'
+ *                      alsa control.
+ * @kcontrol: mixer control
+ * @ucontrol: control element information
+ *
+ * This function basically passes the arguments on to the generic
+ * snd_soc_put_volsw() function and saves the mute information in
+ * our private data structure. This is because we want to prevent
+ * cs4270_dai_mute() neglecting the user's decision to manually
+ * mute the codec's output.
+ *
+ * Returns 0 for success.
+ */
+static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct cs4270_private *cs4270 = codec->private_data;
+       int left = !ucontrol->value.integer.value[0];
+       int right = !ucontrol->value.integer.value[1];
+
+       cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
+                             (right ? CS4270_MUTE_DAC_B : 0);
+
+       return snd_soc_put_volsw(kcontrol, ucontrol);
+}
 
 /* A list of non-DAPM controls that the CS4270 supports */
 static const struct snd_kcontrol_new cs4270_snd_controls[] = {
        SOC_DOUBLE_R("Master Playback Volume",
-               CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
+               CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1),
+       SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
+       SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
+       SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
+       SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
+       SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
+       SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
+       SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
+       SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
+               snd_soc_get_volsw, cs4270_soc_put_mute),
 };
 
 /*
@@ -525,6 +541,13 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
  */
 static struct snd_soc_codec *cs4270_codec;
 
+static struct snd_soc_dai_ops cs4270_dai_ops = {
+       .hw_params      = cs4270_hw_params,
+       .set_sysclk     = cs4270_set_dai_sysclk,
+       .set_fmt        = cs4270_set_dai_fmt,
+       .digital_mute   = cs4270_dai_mute,
+};
+
 struct snd_soc_dai cs4270_dai = {
        .name = "cs4270",
        .playback = {
@@ -541,12 +564,7 @@ struct snd_soc_dai cs4270_dai = {
                .rates = 0,
                .formats = CS4270_FORMATS,
        },
-       .ops = {
-               .hw_params = cs4270_hw_params,
-               .set_sysclk = cs4270_set_dai_sysclk,
-               .set_fmt = cs4270_set_dai_fmt,
-               .digital_mute = cs4270_mute,
-       },
+       .ops = &cs4270_dai_ops,
 };
 EXPORT_SYMBOL_GPL(cs4270_dai);
 
@@ -561,7 +579,6 @@ static int cs4270_probe(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
        struct snd_soc_codec *codec = cs4270_codec;
-       unsigned int i;
        int ret;
 
        /* Connect the codec to the socdev.  snd_soc_new_pcms() needs this. */
@@ -570,34 +587,15 @@ static int cs4270_probe(struct platform_device *pdev)
        /* Register PCMs */
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
        if (ret < 0) {
-               printk(KERN_ERR "cs4270: failed to create PCMs\n");
+               dev_err(codec->dev, "failed to create pcms\n");
                return ret;
        }
 
        /* Add the non-DAPM controls */
-       for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) {
-               struct snd_kcontrol *kctrl;
-
-               kctrl = snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL);
-               if (!kctrl) {
-                       printk(KERN_ERR "cs4270: error creating control '%s'\n",
-                              cs4270_snd_controls[i].name);
-                       ret = -ENOMEM;
-                       goto error_free_pcms;
-               }
-
-               ret = snd_ctl_add(codec->card, kctrl);
-               if (ret < 0) {
-                       printk(KERN_ERR "cs4270: error adding control '%s'\n",
-                              cs4270_snd_controls[i].name);
-                       goto error_free_pcms;
-               }
-       }
-
-       /* And finally, register the socdev */
-       ret = snd_soc_init_card(socdev);
+       ret = snd_soc_add_controls(codec, cs4270_snd_controls,
+                               ARRAY_SIZE(cs4270_snd_controls));
        if (ret < 0) {
-               printk(KERN_ERR "cs4270: failed to register card\n");
+               dev_err(codec->dev, "failed to add controls\n");
                goto error_free_pcms;
        }
 
@@ -637,15 +635,16 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 {
        struct snd_soc_codec *codec;
        struct cs4270_private *cs4270;
+       unsigned int reg;
        int ret;
 
        /* For now, we only support one cs4270 device in the system.  See the
         * comment for cs4270_codec.
         */
        if (cs4270_codec) {
-               printk(KERN_ERR "cs4270: ignoring CS4270 at addr %X\n",
+               dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
                       i2c_client->addr);
-               printk(KERN_ERR "cs4270: only one CS4270 per board allowed\n");
+               dev_err(&i2c_client->dev, "only one per board allowed\n");
                /* Should we return something other than ENODEV here? */
                return -ENODEV;
        }
@@ -654,35 +653,35 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 
        ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
        if (ret < 0) {
-               printk(KERN_ERR "cs4270: failed to read I2C at addr %X\n",
+               dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
                       i2c_client->addr);
                return ret;
        }
        /* The top four bits of the chip ID should be 1100. */
        if ((ret & 0xF0) != 0xC0) {
-               printk(KERN_ERR "cs4270: device at addr %X is not a CS4270\n",
+               dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
                       i2c_client->addr);
                return -ENODEV;
        }
 
-       printk(KERN_INFO "cs4270: found device at I2C address %X\n",
+       dev_info(&i2c_client->dev, "found device at i2c address %X\n",
                i2c_client->addr);
-       printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
+       dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
 
        /* Allocate enough space for the snd_soc_codec structure
           and our private data together. */
        cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
        if (!cs4270) {
-               printk(KERN_ERR "cs4270: Could not allocate codec structure\n");
+               dev_err(&i2c_client->dev, "could not allocate codec\n");
                return -ENOMEM;
        }
        codec = &cs4270->codec;
-       cs4270_codec = codec;
 
        mutex_init(&codec->mutex);
        INIT_LIST_HEAD(&codec->dapm_widgets);
        INIT_LIST_HEAD(&codec->dapm_paths);
 
+       codec->dev = &i2c_client->dev;
        codec->name = "CS4270";
        codec->owner = THIS_MODULE;
        codec->dai = &cs4270_dai;
@@ -698,17 +697,53 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 
        ret = cs4270_fill_cache(codec);
        if (ret < 0) {
-               printk(KERN_ERR "cs4270: failed to fill register cache\n");
+               dev_err(&i2c_client->dev, "failed to fill register cache\n");
                goto error_free_codec;
        }
 
+       /* Disable auto-mute.  This feature appears to be buggy.  In some
+        * situations, auto-mute will not deactivate when it should, so we want
+        * this feature disabled by default.  An application (e.g. alsactl) can
+        * re-enabled it by using the controls.
+        */
+
+       reg = cs4270_read_reg_cache(codec, CS4270_MUTE);
+       reg &= ~CS4270_MUTE_AUTO;
+       ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
+       if (ret < 0) {
+               dev_err(&i2c_client->dev, "i2c write failed\n");
+               return ret;
+       }
+
+       /* Disable automatic volume control.  The hardware enables, and it
+        * causes volume change commands to be delayed, sometimes until after
+        * playback has started.  An application (e.g. alsactl) can
+        * re-enabled it by using the controls.
+        */
+
+       reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
+       reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
+       ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
+       if (ret < 0) {
+               dev_err(&i2c_client->dev, "i2c write failed\n");
+               return ret;
+       }
+
+       /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI
+        * structure for each CS4270 device, but the machine driver needs to
+        * have a pointer to the DAI structure, so for now it must be a global
+        * variable.
+        */
+       cs4270_dai.dev = &i2c_client->dev;
+
        /* Register the DAI.  If all the other ASoC driver have already
         * registered, then this will call our probe function, so
         * cs4270_codec needs to be ready.
         */
+       cs4270_codec = codec;
        ret = snd_soc_register_dai(&cs4270_dai);
        if (ret < 0) {
-               printk(KERN_ERR "cs4270: failed to register DAIe\n");
+               dev_err(&i2c_client->dev, "failed to register DAIe\n");
                goto error_free_codec;
        }
 
@@ -718,6 +753,8 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 
 error_free_codec:
        kfree(cs4270);
+       cs4270_codec = NULL;
+       cs4270_dai.dev = NULL;
 
        return ret;
 }
@@ -733,6 +770,8 @@ static int cs4270_i2c_remove(struct i2c_client *i2c_client)
        struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
 
        kfree(cs4270);
+       cs4270_codec = NULL;
+       cs4270_dai.dev = NULL;
 
        return 0;
 }
@@ -746,6 +785,56 @@ static struct i2c_device_id cs4270_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, cs4270_id);
 
+#ifdef CONFIG_PM
+
+/* This suspend/resume implementation can handle both - a simple standby
+ * where the codec remains powered, and a full suspend, where the voltage
+ * domain the codec is connected to is teared down and/or any other hardware
+ * reset condition is asserted.
+ *
+ * The codec's own power saving features are enabled in the suspend callback,
+ * and all registers are written back to the hardware when resuming.
+ */
+
+static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+       struct snd_soc_codec *codec = cs4270_codec;
+       int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
+
+       return snd_soc_write(codec, CS4270_PWRCTL, reg);
+}
+
+static int cs4270_soc_resume(struct platform_device *pdev)
+{
+       struct snd_soc_codec *codec = cs4270_codec;
+       struct i2c_client *i2c_client = codec->control_data;
+       int reg;
+
+       /* In case the device was put to hard reset during sleep, we need to
+        * wait 500ns here before any I2C communication. */
+       ndelay(500);
+
+       /* first restore the entire register cache ... */
+       for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
+               u8 val = snd_soc_read(codec, reg);
+
+               if (i2c_smbus_write_byte_data(i2c_client, reg, val)) {
+                       dev_err(codec->dev, "i2c write failed\n");
+                       return -EIO;
+               }
+       }
+
+       /* ... then disable the power-down bits */
+       reg = snd_soc_read(codec, CS4270_PWRCTL);
+       reg &= ~CS4270_PWRCTL_PDN_ALL;
+
+       return snd_soc_write(codec, CS4270_PWRCTL, reg);
+}
+#else
+#define cs4270_soc_suspend     NULL
+#define cs4270_soc_resume      NULL
+#endif /* CONFIG_PM */
+
 /*
  * cs4270_i2c_driver - I2C device identification
  *
@@ -770,13 +859,15 @@ static struct i2c_driver cs4270_i2c_driver = {
  */
 struct snd_soc_codec_device soc_codec_device_cs4270 = {
        .probe =        cs4270_probe,
-       .remove =       cs4270_remove
+       .remove =       cs4270_remove,
+       .suspend =      cs4270_soc_suspend,
+       .resume =       cs4270_soc_resume,
 };
 EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
 
 static int __init cs4270_init(void)
 {
-       printk(KERN_INFO "Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
+       pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
 
        return i2c_add_driver(&cs4270_i2c_driver);
 }