ASoC: rockchip: i2s: add pcm transfer mode support.
authorSugar Zhang <sugar.zhang@rock-chips.com>
Fri, 24 Jul 2015 10:04:31 +0000 (18:04 +0800)
committerSugar Zhang <sugar.zhang@rock-chips.com>
Fri, 24 Jul 2015 10:04:31 +0000 (18:04 +0800)
usage: add i2s dts property "rockchip,xfer-mode"

rockchip,xfer-mode = <0>: i2s transfer mode.
rockchip,xfer-mode = <1>: pcm transfer mode.

if not define, use i2s transfer mode default.
pcm transfer mode is usually used for bt/modem voice.

Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Documentation/devicetree/bindings/sound/rockchip-i2s.txt
sound/soc/rockchip/rk_i2s.c
sound/soc/rockchip/rk_i2s.h

index 6915841b1928999ed1ad436ec110b8b89829126c..10adac26c593e17c541e613beabdda198fd0de0e 100644 (file)
@@ -6,6 +6,7 @@ Required SoC Specific Properties:
 - reg: physical base address of the controller and length of memory mapped
   region.
 - i2s-id: i2s controller id,
+- rockchip,xfer-mode: transfer mode select, 0:i2s, 1: pcm.
 - clocks: must include clock specifiers corresponding to entries in the
   clock-names property.
 - clocks-names: list of clock names sorted in the same order as the clocks
index f241e082d58db7eb77fee268cd5e25de7f7c8766..3e0fe9c59f39783f0828de49eecfba5b6fdd2dca 100755 (executable)
@@ -63,6 +63,7 @@ struct rk_i2s_dev {
        struct regmap *regmap;
        bool tx_start;
        bool rx_start;
+       int xfer_mode; /* 0: i2s, 1: pcm */
 #ifdef CLK_SET_LATER
        struct delayed_work clk_delayed_work;
 #endif
@@ -709,6 +710,19 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
                goto err_unregister_component;
        }
 
+       ret = of_property_read_u32(node, "rockchip,xfer-mode", &i2s->xfer_mode);
+       if (ret < 0)
+               i2s->xfer_mode = I2S_XFER_MODE;
+
+       if (PCM_XFER_MODE == i2s->xfer_mode) {
+               regmap_update_bits(i2s->regmap, I2S_TXCR,
+                                  I2S_TXCR_TFS_MASK,
+                                  I2S_TXCR_TFS_PCM);
+               regmap_update_bits(i2s->regmap, I2S_RXCR,
+                                  I2S_RXCR_TFS_MASK,
+                                  I2S_RXCR_TFS_PCM);
+       }
+
        rockchip_snd_txctrl(i2s, 0);
        rockchip_snd_rxctrl(i2s, 0);
 
@@ -774,6 +788,15 @@ static int rockchip_i2s_resume(struct device *dev)
                return ret;
        ret = regmap_reinit_cache(i2s->regmap, &rockchip_i2s_regmap_config);
 
+       if (PCM_XFER_MODE == i2s->xfer_mode) {
+               regmap_update_bits(i2s->regmap, I2S_TXCR,
+                                  I2S_TXCR_TFS_MASK,
+                                  I2S_TXCR_TFS_PCM);
+               regmap_update_bits(i2s->regmap, I2S_RXCR,
+                                  I2S_RXCR_TFS_MASK,
+                                  I2S_RXCR_TFS_PCM);
+       }
+
        pm_runtime_put(dev);
 
        dev_dbg(i2s->dev, "%s\n", __func__);
index 9cec8821274a1472b1bff6158873b3823f94ddc1..d2dcfb74b2e0d68c75f4f89ec6182aadcb36d11b 100644 (file)
@@ -48,6 +48,7 @@
 #define I2S_TXCR_TFS_SHIFT     5
 #define I2S_TXCR_TFS_I2S       (0 << I2S_TXCR_TFS_SHIFT)
 #define I2S_TXCR_TFS_PCM       (1 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_MASK      (1 << I2S_TXCR_TFS_SHIFT)
 #define I2S_TXCR_VDW_SHIFT     0
 #define I2S_TXCR_VDW(x)                ((x - 1) << I2S_TXCR_VDW_SHIFT)
 #define I2S_TXCR_VDW_MASK      (0x1f << I2S_TXCR_VDW_SHIFT)
@@ -74,6 +75,7 @@
 #define I2S_RXCR_TFS_SHIFT     5
 #define I2S_RXCR_TFS_I2S       (0 << I2S_RXCR_TFS_SHIFT)
 #define I2S_RXCR_TFS_PCM       (1 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_MASK      (1 << I2S_RXCR_TFS_SHIFT)
 #define I2S_RXCR_VDW_SHIFT     0
 #define I2S_RXCR_VDW(x)                ((x - 1) << I2S_RXCR_VDW_SHIFT)
 #define I2S_RXCR_VDW_MASK      (0x1f << I2S_RXCR_VDW_SHIFT)
 #define I2S_CHANNEL_4  4
 #define I2S_CHANNEL_2  2
 
+#define I2S_XFER_MODE  0
+#define PCM_XFER_MODE  1
+
 #endif /* __RK_I2S_H__ */