ASoC: Add missing __devexit and __devinit annotations
[safe/jmp/linux-2.6] / sound / soc / codecs / ssm2602.c
index 0e522e7..d2ff1cd 100644 (file)
@@ -151,21 +151,6 @@ SOC_ENUM("Capture Source", ssm2602_enum[0]),
 SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
 };
 
-/* add non dapm controls */
-static int ssm2602_add_controls(struct snd_soc_codec *codec)
-{
-       int err, i;
-
-       for (i = 0; i < ARRAY_SIZE(ssm2602_snd_controls); i++) {
-               err = snd_ctl_add(codec->card,
-                       snd_soc_cnew(&ssm2602_snd_controls[i], codec, NULL));
-               if (err < 0)
-                       return err;
-       }
-
-       return 0;
-}
-
 /* Output Mixer */
 static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = {
 SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
@@ -225,7 +210,6 @@ static int ssm2602_add_widgets(struct snd_soc_codec *codec)
 
        snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
 
-       snd_soc_dapm_new_widgets(codec);
        return 0;
 }
 
@@ -285,12 +269,13 @@ static inline int get_coeff(int mclk, int rate)
 }
 
 static int ssm2602_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+       struct snd_pcm_hw_params *params,
+       struct snd_soc_dai *dai)
 {
        u16 srate;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
-       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_codec *codec = socdev->card->codec;
        struct ssm2602_priv *ssm2602 = codec->private_data;
        struct i2c_client *i2c = codec->control_data;
        u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
@@ -330,11 +315,12 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int ssm2602_startup(struct snd_pcm_substream *substream)
+static int ssm2602_startup(struct snd_pcm_substream *substream,
+                          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 snd_soc_codec *codec = socdev->card->codec;
        struct ssm2602_priv *ssm2602 = codec->private_data;
        struct i2c_client *i2c = codec->control_data;
        struct snd_pcm_runtime *master_runtime;
@@ -349,15 +335,17 @@ static int ssm2602_startup(struct snd_pcm_substream *substream)
                        master_runtime->sample_bits,
                        master_runtime->rate);
 
-               snd_pcm_hw_constraint_minmax(substream->runtime,
-                                            SNDRV_PCM_HW_PARAM_RATE,
-                                            master_runtime->rate,
-                                            master_runtime->rate);
+               if (master_runtime->rate != 0)
+                       snd_pcm_hw_constraint_minmax(substream->runtime,
+                                                    SNDRV_PCM_HW_PARAM_RATE,
+                                                    master_runtime->rate,
+                                                    master_runtime->rate);
 
-               snd_pcm_hw_constraint_minmax(substream->runtime,
-                                            SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
-                                            master_runtime->sample_bits,
-                                            master_runtime->sample_bits);
+               if (master_runtime->sample_bits != 0)
+                       snd_pcm_hw_constraint_minmax(substream->runtime,
+                                                    SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+                                                    master_runtime->sample_bits,
+                                                    master_runtime->sample_bits);
 
                ssm2602->slave_substream = substream;
        } else
@@ -366,23 +354,26 @@ static int ssm2602_startup(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
+static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
+                              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 snd_soc_codec *codec = socdev->card->codec;
        /* set active */
        ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
 
        return 0;
 }
 
-static void ssm2602_shutdown(struct snd_pcm_substream *substream)
+static void ssm2602_shutdown(struct snd_pcm_substream *substream,
+                            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 snd_soc_codec *codec = socdev->card->codec;
        struct ssm2602_priv *ssm2602 = codec->private_data;
+
        /* deactivate */
        if (!codec->active)
                ssm2602_write(codec, SSM2602_ACTIVE, 0);
@@ -450,10 +441,10 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
                iface |= 0x0001;
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               iface |= 0x0003;
+               iface |= 0x0013;
                break;
        case SND_SOC_DAIFMT_DSP_B:
-               iface |= 0x0013;
+               iface |= 0x0003;
                break;
        default:
                return -EINVAL;
@@ -508,11 +499,22 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
-               SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
-               SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
-               SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
-               SNDRV_PCM_RATE_96000)
+#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\
+               SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
+               SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+
+#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+               SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_ops ssm2602_dai_ops = {
+       .startup        = ssm2602_startup,
+       .prepare        = ssm2602_pcm_prepare,
+       .hw_params      = ssm2602_hw_params,
+       .shutdown       = ssm2602_shutdown,
+       .digital_mute   = ssm2602_mute,
+       .set_sysclk     = ssm2602_set_dai_sysclk,
+       .set_fmt        = ssm2602_set_dai_fmt,
+};
 
 struct snd_soc_dai ssm2602_dai = {
        .name = "SSM2602",
@@ -521,31 +523,21 @@ struct snd_soc_dai ssm2602_dai = {
                .channels_min = 2,
                .channels_max = 2,
                .rates = SSM2602_RATES,
-               .formats = SNDRV_PCM_FMTBIT_S32_LE,},
+               .formats = SSM2602_FORMATS,},
        .capture = {
                .stream_name = "Capture",
                .channels_min = 2,
                .channels_max = 2,
                .rates = SSM2602_RATES,
-               .formats = SNDRV_PCM_FMTBIT_S32_LE,},
-       .ops = {
-               .startup = ssm2602_startup,
-               .prepare = ssm2602_pcm_prepare,
-               .hw_params = ssm2602_hw_params,
-               .shutdown = ssm2602_shutdown,
-       },
-       .dai_ops = {
-               .digital_mute = ssm2602_mute,
-               .set_sysclk = ssm2602_set_dai_sysclk,
-               .set_fmt = ssm2602_set_dai_fmt,
-       }
+               .formats = SSM2602_FORMATS,},
+       .ops = &ssm2602_dai_ops,
 };
 EXPORT_SYMBOL_GPL(ssm2602_dai);
 
 static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_codec *codec = socdev->card->codec;
 
        ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
        return 0;
@@ -554,7 +546,7 @@ static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
 static int ssm2602_resume(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_codec *codec = socdev->card->codec;
        int i;
        u8 data[2];
        u16 *cache = codec->reg_cache;
@@ -576,7 +568,7 @@ static int ssm2602_resume(struct platform_device *pdev)
  */
 static int ssm2602_init(struct snd_soc_device *socdev)
 {
-       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_codec *codec = socdev->card->codec;
        int reg, ret = 0;
 
        codec->name = "SSM2602";
@@ -617,19 +609,12 @@ static int ssm2602_init(struct snd_soc_device *socdev)
                        APANA_ENABLE_MIC_BOOST);
        ssm2602_write(codec, SSM2602_PWR, 0);
 
-       ssm2602_add_controls(codec);
+       snd_soc_add_controls(codec, ssm2602_snd_controls,
+                               ARRAY_SIZE(ssm2602_snd_controls));
        ssm2602_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
-       if (ret < 0) {
-               pr_err("ssm2602: failed to register card\n");
-               goto card_err;
-       }
 
        return ret;
 
-card_err:
-       snd_soc_free_pcms(socdev);
-       snd_soc_dapm_free(socdev);
 pcm_err:
        kfree(codec->reg_cache);
        return ret;
@@ -648,7 +633,7 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c,
                             const struct i2c_device_id *id)
 {
        struct snd_soc_device *socdev = ssm2602_socdev;
-       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_codec *codec = socdev->card->codec;
        int ret;
 
        i2c_set_clientdata(i2c, codec);
@@ -742,7 +727,7 @@ static int ssm2602_probe(struct platform_device *pdev)
        }
 
        codec->private_data = ssm2602;
-       socdev->codec = codec;
+       socdev->card->codec = codec;
        mutex_init(&codec->mutex);
        INIT_LIST_HEAD(&codec->dapm_widgets);
        INIT_LIST_HEAD(&codec->dapm_paths);
@@ -763,7 +748,7 @@ static int ssm2602_probe(struct platform_device *pdev)
 static int ssm2602_remove(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_codec *codec = socdev->card->codec;
 
        if (codec->control_data)
                ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -788,6 +773,18 @@ struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
 
+static int __init ssm2602_modinit(void)
+{
+       return snd_soc_register_dai(&ssm2602_dai);
+}
+module_init(ssm2602_modinit);
+
+static void __exit ssm2602_exit(void)
+{
+       snd_soc_unregister_dai(&ssm2602_dai);
+}
+module_exit(ssm2602_exit);
+
 MODULE_DESCRIPTION("ASoC ssm2602 driver");
 MODULE_AUTHOR("Cliff Cai");
 MODULE_LICENSE("GPL");