ASoC: Merge snd_soc_ops into snd_soc_dai_ops
[safe/jmp/linux-2.6] / sound / soc / codecs / cs4270.c
index bf2ab72..7507d46 100644 (file)
@@ -201,7 +201,7 @@ static struct {
  * driver what the input settings can be.  This would need to be implemented
  * for stand-alone mode to work.
  */
-static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
+static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
@@ -251,7 +251,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
  * data for playback only, but ASoC currently does not support different
  * formats for playback vs. record.
  */
-static int cs4270_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
@@ -360,19 +360,20 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
 /*
  * Program the CS4270 with the given hardware parameters.
  *
- * The .dai_ops functions are used to provide board-specific data, like
+ * The .ops functions are used to provide board-specific data, like
  * input frequencies, to this driver.  This function takes that information,
  * combines it with the hardware parameters provided, and programs the
  * hardware accordingly.
  */
 static int cs4270_hw_params(struct snd_pcm_substream *substream,
-                           struct snd_pcm_hw_params *params)
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_codec *codec = socdev->codec;
        struct cs4270_private *cs4270 = codec->private_data;
-       unsigned int ret = 0;
+       int ret;
        unsigned int i;
        unsigned int rate;
        unsigned int ratio;
@@ -450,6 +451,19 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
                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);
@@ -471,7 +485,7 @@ 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_codec_dai *dai, int mute)
+static int cs4270_mute(struct snd_soc_dai *dai, int mute)
 {
        struct snd_soc_codec *codec = dai->codec;
        int reg6;
@@ -490,34 +504,7 @@ static int cs4270_mute(struct snd_soc_codec_dai *dai, int mute)
 
 #endif
 
-static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind);
-
-/*
- * Notify the driver that a new I2C bus has been found.
- *
- * This function is called for each I2C bus in the system.  The function
- * then asks the I2C subsystem to probe that bus at the addresses on which
- * our device (the CS4270) could exist.  If a device is found at one of
- * those addresses, then our probe function (cs4270_i2c_probe) is called.
- */
-static int cs4270_i2c_attach(struct i2c_adapter *adapter)
-{
-       return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
-}
-
-static int cs4270_i2c_detach(struct i2c_client *client)
-{
-       struct snd_soc_codec *codec = i2c_get_clientdata(client);
-
-       i2c_detach_client(client);
-       codec->control_data = NULL;
-
-       kfree(codec->reg_cache);
-       codec->reg_cache = NULL;
-
-       kfree(client);
-       return 0;
-}
+static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
 
 /* A list of non-DAPM controls that the CS4270 supports */
 static const struct snd_kcontrol_new cs4270_snd_controls[] = {
@@ -525,14 +512,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
                CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
 };
 
+static const struct i2c_device_id cs4270_id[] = {
+       {"cs4270", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, cs4270_id);
+
 static struct i2c_driver cs4270_i2c_driver = {
        .driver = {
                .name = "CS4270 I2C",
                .owner = THIS_MODULE,
        },
-       .id =             I2C_DRIVERID_CS4270,
-       .attach_adapter = cs4270_i2c_attach,
-       .detach_client =  cs4270_i2c_detach,
+       .id_table = cs4270_id,
+       .probe = cs4270_i2c_probe,
 };
 
 /*
@@ -561,11 +553,11 @@ static struct snd_soc_device *cs4270_socdev;
  * Note: snd_soc_new_pcms() must be called before this function can be called,
  * because of snd_ctl_add().
  */
-static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
+static int cs4270_i2c_probe(struct i2c_client *i2c_client,
+       const struct i2c_device_id *id)
 {
        struct snd_soc_device *socdev = cs4270_socdev;
        struct snd_soc_codec *codec = socdev->codec;
-       struct i2c_client *i2c_client = NULL;
        int i;
        int ret = 0;
 
@@ -578,12 +570,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
 
        /* Note: codec_dai->codec is NULL here */
 
-       i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!i2c_client) {
-               printk(KERN_ERR "cs4270: could not allocate I2C client\n");
-               return -ENOMEM;
-       }
-
        codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
        if (!codec->reg_cache) {
                printk(KERN_ERR "cs4270: could not allocate register cache\n");
@@ -591,13 +577,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                goto error;
        }
 
-       i2c_set_clientdata(i2c_client, codec);
-       strcpy(i2c_client->name, "CS4270");
-
-       i2c_client->driver = &cs4270_i2c_driver;
-       i2c_client->adapter = adapter;
-       i2c_client->addr = addr;
-
        /* Verify that we have a CS4270 */
 
        ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -612,18 +591,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                goto error;
        }
 
-       printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr);
+       printk(KERN_INFO "cs4270: found device at I2C address %X\n",
+               i2c_client->addr);
        printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
 
-       /* Tell the I2C layer a new client has arrived */
-
-       ret = i2c_attach_client(i2c_client);
-       if (ret) {
-               printk(KERN_ERR "cs4270: could not attach codec, "
-                       "I2C address %x, error code %i\n", addr, ret);
-               goto error;
-       }
-
        codec->control_data = i2c_client;
        codec->read = cs4270_read_reg_cache;
        codec->write = cs4270_i2c_write;
@@ -648,26 +619,23 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                        goto error;
        }
 
+       i2c_set_clientdata(i2c_client, codec);
+
        return 0;
 
 error:
-       if (codec->control_data) {
-               i2c_detach_client(i2c_client);
-               codec->control_data = NULL;
-       }
+       codec->control_data = NULL;
 
        kfree(codec->reg_cache);
        codec->reg_cache = NULL;
        codec->reg_cache_size = 0;
 
-       kfree(i2c_client);
-
        return ret;
 }
 
 #endif /* USE_I2C*/
 
-struct snd_soc_codec_dai cs4270_dai = {
+struct snd_soc_dai cs4270_dai = {
        .name = "CS4270",
        .playback = {
                .stream_name = "Playback",
@@ -727,7 +695,7 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
        if (ret < 0) {
                printk(KERN_ERR "cs4270: failed to create PCMs\n");
-               return ret;
+               goto error_free_codec;
        }
 
 #ifdef USE_I2C
@@ -736,18 +704,17 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = i2c_add_driver(&cs4270_i2c_driver);
        if (ret) {
                printk(KERN_ERR "cs4270: failed to attach driver");
-               snd_soc_free_pcms(socdev);
-               return ret;
+               goto error_free_pcms;
        }
 
        /* Did we find a CS4270 on the I2C bus? */
        if (codec->control_data) {
                /* Initialize codec ops */
                cs4270_dai.ops.hw_params = cs4270_hw_params;
-               cs4270_dai.dai_ops.set_sysclk = cs4270_set_dai_sysclk;
-               cs4270_dai.dai_ops.set_fmt = cs4270_set_dai_fmt;
+               cs4270_dai.ops.set_sysclk = cs4270_set_dai_sysclk;
+               cs4270_dai.ops.set_fmt = cs4270_set_dai_fmt;
 #ifdef CONFIG_SND_SOC_CS4270_HWMUTE
-               cs4270_dai.dai_ops.digital_mute = cs4270_mute;
+               cs4270_dai.ops.digital_mute = cs4270_mute;
 #endif
        } else
                printk(KERN_INFO "cs4270: no I2C device found, "
@@ -759,10 +726,23 @@ static int cs4270_probe(struct platform_device *pdev)
        ret = snd_soc_register_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "cs4270: failed to register card\n");
-               snd_soc_free_pcms(socdev);
-               return ret;
+               goto error_del_driver;
        }
 
+       return 0;
+
+error_del_driver:
+#ifdef USE_I2C
+       i2c_del_driver(&cs4270_i2c_driver);
+
+error_free_pcms:
+#endif
+       snd_soc_free_pcms(socdev);
+
+error_free_codec:
+       kfree(socdev->codec);
+       socdev->codec = NULL;
+
        return ret;
 }
 
@@ -773,8 +753,7 @@ static int cs4270_remove(struct platform_device *pdev)
        snd_soc_free_pcms(socdev);
 
 #ifdef USE_I2C
-       if (socdev->codec->control_data)
-               i2c_del_driver(&cs4270_i2c_driver);
+       i2c_del_driver(&cs4270_i2c_driver);
 #endif
 
        kfree(socdev->codec);