Skip to content

Commit 170abca

Browse files
Sugar Zhangbroonie
authored andcommitted
ASoC: rockchip: i2s: configure the sdio pins' iomux mode
There are 3 i2s sdio pins, which iomux mode is as follows: - sdi3_sdo1 - sdi2_sdo2 - sdi1_sdo3 we need to configure these pins' iomux mode via the GRF register when use multi channel playback/capture. Signed-off-by: Sugar Zhang <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent 1a695a9 commit 170abca

File tree

3 files changed

+70
-9
lines changed

3 files changed

+70
-9
lines changed

Documentation/devicetree/bindings/sound/rockchip-i2s.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ Required properties:
2323
- rockchip,playback-channels: max playback channels, if not set, 8 channels default.
2424
- rockchip,capture-channels: max capture channels, if not set, 2 channels default.
2525

26+
Required properties for controller which support multi channels
27+
playback/capture:
28+
29+
- rockchip,grf: the phandle of the syscon node for GRF register.
30+
2631
Example for rk3288 I2S controller:
2732

2833
i2s@ff890000 {

sound/soc/rockchip/rockchip_i2s.c

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
*/
1212

1313
#include <linux/module.h>
14+
#include <linux/mfd/syscon.h>
1415
#include <linux/delay.h>
1516
#include <linux/of_gpio.h>
17+
#include <linux/of_device.h>
1618
#include <linux/clk.h>
1719
#include <linux/pm_runtime.h>
1820
#include <linux/regmap.h>
@@ -23,6 +25,11 @@
2325

2426
#define DRV_NAME "rockchip-i2s"
2527

28+
struct rk_i2s_pins {
29+
u32 reg_offset;
30+
u32 shift;
31+
};
32+
2633
struct rk_i2s_dev {
2734
struct device *dev;
2835

@@ -33,6 +40,7 @@ struct rk_i2s_dev {
3340
struct snd_dmaengine_dai_dma_data playback_dma_data;
3441

3542
struct regmap *regmap;
43+
struct regmap *grf;
3644

3745
/*
3846
* Used to indicate the tx/rx status.
@@ -42,6 +50,7 @@ struct rk_i2s_dev {
4250
bool tx_start;
4351
bool rx_start;
4452
bool is_master_mode;
53+
const struct rk_i2s_pins *pins;
4554
};
4655

4756
static int i2s_runtime_suspend(struct device *dev)
@@ -300,6 +309,30 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
300309
I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
301310
val);
302311

312+
if (!IS_ERR(i2s->grf) && i2s->pins) {
313+
regmap_read(i2s->regmap, I2S_TXCR, &val);
314+
val &= I2S_TXCR_CSR_MASK;
315+
316+
switch (val) {
317+
case I2S_CHN_4:
318+
val = I2S_IO_4CH_OUT_6CH_IN;
319+
break;
320+
case I2S_CHN_6:
321+
val = I2S_IO_6CH_OUT_4CH_IN;
322+
break;
323+
case I2S_CHN_8:
324+
val = I2S_IO_8CH_OUT_2CH_IN;
325+
break;
326+
default:
327+
val = I2S_IO_2CH_OUT_8CH_IN;
328+
break;
329+
}
330+
331+
val <<= i2s->pins->shift;
332+
val |= (I2S_IO_DIRECTION_MASK << i2s->pins->shift) << 16;
333+
regmap_write(i2s->grf, i2s->pins->reg_offset, val);
334+
}
335+
303336
regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
304337
I2S_DMACR_TDL(16));
305338
regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
@@ -485,9 +518,23 @@ static const struct regmap_config rockchip_i2s_regmap_config = {
485518
.cache_type = REGCACHE_FLAT,
486519
};
487520

521+
static const struct rk_i2s_pins rk3399_i2s_pins = {
522+
.reg_offset = 0xe220,
523+
.shift = 11,
524+
};
525+
526+
static const struct of_device_id rockchip_i2s_match[] = {
527+
{ .compatible = "rockchip,rk3066-i2s", },
528+
{ .compatible = "rockchip,rk3188-i2s", },
529+
{ .compatible = "rockchip,rk3288-i2s", },
530+
{ .compatible = "rockchip,rk3399-i2s", .data = &rk3399_i2s_pins },
531+
{},
532+
};
533+
488534
static int rockchip_i2s_probe(struct platform_device *pdev)
489535
{
490536
struct device_node *node = pdev->dev.of_node;
537+
const struct of_device_id *of_id;
491538
struct rk_i2s_dev *i2s;
492539
struct snd_soc_dai_driver *soc_dai;
493540
struct resource *res;
@@ -501,6 +548,17 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
501548
return -ENOMEM;
502549
}
503550

551+
i2s->dev = &pdev->dev;
552+
553+
i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
554+
if (!IS_ERR(i2s->grf)) {
555+
of_id = of_match_device(rockchip_i2s_match, &pdev->dev);
556+
if (!of_id || !of_id->data)
557+
return -EINVAL;
558+
559+
i2s->pins = of_id->data;
560+
}
561+
504562
/* try to prepare related clocks */
505563
i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk");
506564
if (IS_ERR(i2s->hclk)) {
@@ -540,7 +598,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
540598
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
541599
i2s->capture_dma_data.maxburst = 4;
542600

543-
i2s->dev = &pdev->dev;
544601
dev_set_drvdata(&pdev->dev, i2s);
545602

546603
pm_runtime_enable(&pdev->dev);
@@ -606,14 +663,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev)
606663
return 0;
607664
}
608665

609-
static const struct of_device_id rockchip_i2s_match[] = {
610-
{ .compatible = "rockchip,rk3066-i2s", },
611-
{ .compatible = "rockchip,rk3188-i2s", },
612-
{ .compatible = "rockchip,rk3288-i2s", },
613-
{ .compatible = "rockchip,rk3399-i2s", },
614-
{},
615-
};
616-
617666
static const struct dev_pm_ops rockchip_i2s_pm_ops = {
618667
SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume,
619668
NULL)

sound/soc/rockchip/rockchip_i2s.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,11 @@ enum {
236236
#define I2S_TXDR (0x0024)
237237
#define I2S_RXDR (0x0028)
238238

239+
/* io direction cfg register */
240+
#define I2S_IO_DIRECTION_MASK (7)
241+
#define I2S_IO_8CH_OUT_2CH_IN (0)
242+
#define I2S_IO_6CH_OUT_4CH_IN (4)
243+
#define I2S_IO_4CH_OUT_6CH_IN (6)
244+
#define I2S_IO_2CH_OUT_8CH_IN (7)
245+
239246
#endif /* _ROCKCHIP_IIS_H */

0 commit comments

Comments
 (0)