ASoC: samsung: i2s: Supported high resolution rates 42/136342/7
authorJaechul Lee <jcsing.lee@samsung.com>
Thu, 22 Jun 2017 02:03:27 +0000 (11:03 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 3 Jul 2017 03:22:18 +0000 (03:22 +0000)
This driver can support more frequencies over 96KHz. There are no reasons to
limit the frequency range below 96KHz. If codecs/amps or something else can't
support high resolution rate, the constraints would be set rates properly
because each drivers has its own limits.

This patch was tested with 192KHz audio stream on exynos5433

Change-Id: I35233199f1b1ee10239793780e9bb14fdc590aca
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
sound/soc/samsung/i2s.c

index 9456c78c90514c4497456e158327bb6d18bef758..4dd7636ddefc2e21ac6e26aae3c2449dc928e936 100644 (file)
@@ -55,6 +55,7 @@ struct samsung_i2s_variant_regs {
 struct samsung_i2s_dai_data {
        int dai_type;
        u32 quirks;
+       unsigned int rates;
        const struct samsung_i2s_variant_regs *i2s_variant_regs;
 };
 
@@ -1054,14 +1055,28 @@ static const struct snd_soc_component_driver samsung_i2s_component = {
        .name           = "samsung-i2s",
 };
 
-#define SAMSUNG_I2S_RATES      SNDRV_PCM_RATE_8000_96000
-
 #define SAMSUNG_I2S_FMTS       (SNDRV_PCM_FMTBIT_S8 | \
                                        SNDRV_PCM_FMTBIT_S16_LE | \
                                        SNDRV_PCM_FMTBIT_S24_LE)
 
+static const struct of_device_id exynos_i2s_match[];
+
+static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data(
+                                               struct platform_device *pdev)
+{
+       if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+               const struct of_device_id *match;
+               match = of_match_node(exynos_i2s_match, pdev->dev.of_node);
+               return match ? match->data : NULL;
+       } else {
+               return (struct samsung_i2s_dai_data *)
+                               platform_get_device_id(pdev)->driver_data;
+       }
+}
+
 static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
 {
+       const struct samsung_i2s_dai_data *i2s_dai_data;
        struct i2s_dai *i2s;
        int ret;
 
@@ -1069,6 +1084,8 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
        if (i2s == NULL)
                return NULL;
 
+       i2s_dai_data = samsung_i2s_get_driver_data(pdev);
+
        i2s->pdev = pdev;
        i2s->pri_dai = NULL;
        i2s->sec_dai = NULL;
@@ -1080,13 +1097,13 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
        i2s->i2s_dai_drv.resume = i2s_resume;
        i2s->i2s_dai_drv.playback.channels_min = 1;
        i2s->i2s_dai_drv.playback.channels_max = 2;
-       i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES;
+       i2s->i2s_dai_drv.playback.rates = i2s_dai_data->rates;
        i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
 
        if (!sec) {
                i2s->i2s_dai_drv.capture.channels_min = 1;
                i2s->i2s_dai_drv.capture.channels_max = 2;
-               i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
+               i2s->i2s_dai_drv.capture.rates = i2s_dai_data->rates;
                i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
                dev_set_drvdata(&i2s->pdev->dev, i2s);
        } else {        /* Create a new platform_device for Secondary */
@@ -1105,21 +1122,6 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
        return i2s;
 }
 
-static const struct of_device_id exynos_i2s_match[];
-
-static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data(
-                                               struct platform_device *pdev)
-{
-       if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
-               const struct of_device_id *match;
-               match = of_match_node(exynos_i2s_match, pdev->dev.of_node);
-               return match ? match->data : NULL;
-       } else {
-               return (struct samsung_i2s_dai_data *)
-                               platform_get_device_id(pdev)->driver_data;
-       }
-}
-
 #ifdef CONFIG_PM
 static int i2s_runtime_suspend(struct device *dev)
 {
@@ -1442,6 +1444,7 @@ static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = {
 static const struct samsung_i2s_dai_data i2sv3_dai_type = {
        .dai_type = TYPE_PRI,
        .quirks = QUIRK_NO_MUXPSR,
+       .rates = SNDRV_PCM_RATE_8000_96000,
        .i2s_variant_regs = &i2sv3_regs,
 };
 
@@ -1449,6 +1452,7 @@ static const struct samsung_i2s_dai_data i2sv5_dai_type = {
        .dai_type = TYPE_PRI,
        .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
                        QUIRK_SUPPORTS_IDMA,
+       .rates = SNDRV_PCM_RATE_8000_96000,
        .i2s_variant_regs = &i2sv3_regs,
 };
 
@@ -1456,6 +1460,7 @@ static const struct samsung_i2s_dai_data i2sv6_dai_type = {
        .dai_type = TYPE_PRI,
        .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
                        QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA,
+       .rates = SNDRV_PCM_RATE_8000_96000,
        .i2s_variant_regs = &i2sv6_regs,
 };
 
@@ -1463,12 +1468,14 @@ static const struct samsung_i2s_dai_data i2sv7_dai_type = {
        .dai_type = TYPE_PRI,
        .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
                        QUIRK_SUPPORTS_TDM,
+       .rates = SNDRV_PCM_RATE_8000_192000,
        .i2s_variant_regs = &i2sv7_regs,
 };
 
 static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = {
        .dai_type = TYPE_PRI,
        .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR,
+       .rates = SNDRV_PCM_RATE_8000_96000,
        .i2s_variant_regs = &i2sv5_i2s1_regs,
 };