aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/soc/jz4740/jz4740-i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/jz4740/jz4740-i2s.c')
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c78
1 files changed, 49 insertions, 29 deletions
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 9d5405881209..6f6f8dad0356 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -49,12 +49,8 @@
#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
-#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
-#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
-#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_MASK \
- (0xf << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET)
-#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_MASK \
- (0x1f << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET)
+#define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
+#define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
@@ -83,16 +79,23 @@
#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
#define JZ_AIC_CLK_DIV_MASK 0xf
-#define I2SDIV_DV_SHIFT 8
+#define I2SDIV_DV_SHIFT 0
#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
#define I2SDIV_IDV_SHIFT 8
#define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
enum jz47xx_i2s_version {
JZ_I2S_JZ4740,
+ JZ_I2S_JZ4760,
+ JZ_I2S_JZ4770,
JZ_I2S_JZ4780,
};
+struct i2s_soc_info {
+ enum jz47xx_i2s_version version;
+ struct snd_soc_dai_driver *dai;
+};
+
struct jz4740_i2s {
struct resource *mem;
void __iomem *base;
@@ -104,7 +107,7 @@ struct jz4740_i2s {
struct snd_dmaengine_dai_dma_data playback_dma_data;
struct snd_dmaengine_dai_dma_data capture_dma_data;
- enum jz47xx_i2s_version version;
+ const struct i2s_soc_info *soc_info;
};
static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
@@ -284,7 +287,7 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
- if (i2s->version >= JZ_I2S_JZ4780) {
+ if (i2s->soc_info->version >= JZ_I2S_JZ4770) {
div_reg &= ~I2SDIV_IDV_MASK;
div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
} else {
@@ -398,9 +401,9 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
&i2s->capture_dma_data);
- if (i2s->version >= JZ_I2S_JZ4780) {
- conf = (7 << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
- (8 << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
+ if (i2s->soc_info->version >= JZ_I2S_JZ4760) {
+ conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
+ (8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
JZ_AIC_CONF_I2S |
JZ_AIC_CONF_INTERNAL_CODEC;
@@ -457,7 +460,17 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
.ops = &jz4740_i2s_dai_ops,
};
-static struct snd_soc_dai_driver jz4780_i2s_dai = {
+static const struct i2s_soc_info jz4740_i2s_soc_info = {
+ .version = JZ_I2S_JZ4740,
+ .dai = &jz4740_i2s_dai,
+};
+
+static const struct i2s_soc_info jz4760_i2s_soc_info = {
+ .version = JZ_I2S_JZ4760,
+ .dai = &jz4740_i2s_dai,
+};
+
+static struct snd_soc_dai_driver jz4770_i2s_dai = {
.probe = jz4740_i2s_dai_probe,
.remove = jz4740_i2s_dai_remove,
.playback = {
@@ -475,6 +488,16 @@ static struct snd_soc_dai_driver jz4780_i2s_dai = {
.ops = &jz4740_i2s_dai_ops,
};
+static const struct i2s_soc_info jz4770_i2s_soc_info = {
+ .version = JZ_I2S_JZ4770,
+ .dai = &jz4770_i2s_dai,
+};
+
+static const struct i2s_soc_info jz4780_i2s_soc_info = {
+ .version = JZ_I2S_JZ4780,
+ .dai = &jz4770_i2s_dai,
+};
+
static const struct snd_soc_component_driver jz4740_i2s_component = {
.name = "jz4740-i2s",
.suspend = jz4740_i2s_suspend,
@@ -483,8 +506,10 @@ static const struct snd_soc_component_driver jz4740_i2s_component = {
#ifdef CONFIG_OF
static const struct of_device_id jz4740_of_matches[] = {
- { .compatible = "ingenic,jz4740-i2s", .data = (void *)JZ_I2S_JZ4740 },
- { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 },
+ { .compatible = "ingenic,jz4740-i2s", .data = &jz4740_i2s_soc_info },
+ { .compatible = "ingenic,jz4760-i2s", .data = &jz4760_i2s_soc_info },
+ { .compatible = "ingenic,jz4770-i2s", .data = &jz4770_i2s_soc_info },
+ { .compatible = "ingenic,jz4780-i2s", .data = &jz4780_i2s_soc_info },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, jz4740_of_matches);
@@ -492,45 +517,40 @@ MODULE_DEVICE_TABLE(of, jz4740_of_matches);
static int jz4740_i2s_dev_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct jz4740_i2s *i2s;
struct resource *mem;
int ret;
- i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
+ i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
if (!i2s)
return -ENOMEM;
- i2s->version =
- (enum jz47xx_i2s_version)of_device_get_match_data(&pdev->dev);
+ i2s->soc_info = device_get_match_data(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2s->base = devm_ioremap_resource(&pdev->dev, mem);
+ i2s->base = devm_ioremap_resource(dev, mem);
if (IS_ERR(i2s->base))
return PTR_ERR(i2s->base);
i2s->phys_base = mem->start;
- i2s->clk_aic = devm_clk_get(&pdev->dev, "aic");
+ i2s->clk_aic = devm_clk_get(dev, "aic");
if (IS_ERR(i2s->clk_aic))
return PTR_ERR(i2s->clk_aic);
- i2s->clk_i2s = devm_clk_get(&pdev->dev, "i2s");
+ i2s->clk_i2s = devm_clk_get(dev, "i2s");
if (IS_ERR(i2s->clk_i2s))
return PTR_ERR(i2s->clk_i2s);
platform_set_drvdata(pdev, i2s);
- if (i2s->version == JZ_I2S_JZ4780)
- ret = devm_snd_soc_register_component(&pdev->dev,
- &jz4740_i2s_component, &jz4780_i2s_dai, 1);
- else
- ret = devm_snd_soc_register_component(&pdev->dev,
- &jz4740_i2s_component, &jz4740_i2s_dai, 1);
-
+ ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
+ i2s->soc_info->dai, 1);
if (ret)
return ret;
- return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
+ return devm_snd_dmaengine_pcm_register(dev, NULL,
SND_DMAENGINE_PCM_FLAG_COMPAT);
}