Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/sound/spacemit,k1-i2s.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: K1 I2S controller
title: SpacemiT K1/K3 I2S controller

description:
The I2S bus (Inter-IC sound bus) is a serial link for digital
Expand All @@ -15,27 +15,54 @@ maintainers:

allOf:
- $ref: dai-common.yaml#
- if:
properties:
compatible:
contains:
const: spacemit,k3-i2s
then:
properties:
clocks:
minItems: 7
clock-names:
minItems: 7
else:
properties:
clocks:
maxItems: 4
clock-names:
maxItems: 4

properties:
compatible:
const: spacemit,k1-i2s
enum:
- spacemit,k1-i2s
- spacemit,k3-i2s

reg:
maxItems: 1

clocks:
minItems: 4
items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- description: clock for I2S sysclk divider
- description: clock for I2S common sysclk
- description: clock for I2S common bclk

clock-names:
minItems: 4
items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- const: sysclk_div
- const: c_sysclk
- const: c_bclk

dmas:
minItems: 1
Expand Down
36 changes: 35 additions & 1 deletion sound/soc/spacemit/k1_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ struct spacemit_i2s_dev {
struct clk *sysclk;
struct clk *bclk;
struct clk *sspa_clk;
struct clk *sysclk_div;
struct clk *c_sysclk;
struct clk *c_bclk;

struct snd_dmaengine_dai_dma_data capture_dma_data;
struct snd_dmaengine_dai_dma_data playback_dma_data;
Expand Down Expand Up @@ -206,6 +209,14 @@ static int spacemit_i2s_hw_params(struct snd_pcm_substream *substream,
params_rate(params) *
data_bits;

ret = clk_set_rate(i2s->c_sysclk, bclk_rate * 2);
if (ret)
return ret;

ret = clk_set_rate(i2s->c_bclk, bclk_rate);
if (ret)
return ret;

ret = clk_set_rate(i2s->bclk, bclk_rate);
if (ret)
return ret;
Expand All @@ -217,10 +228,17 @@ static int spacemit_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
unsigned int freq, int dir)
{
struct spacemit_i2s_dev *i2s = dev_get_drvdata(cpu_dai->dev);
int ret;

if (freq == 0)
return 0;

if (i2s->sysclk_div) {
ret = clk_set_rate(i2s->sysclk_div, freq);
if (ret)
return ret;
}

return clk_set_rate(i2s->sysclk, freq);
}

Expand Down Expand Up @@ -436,6 +454,21 @@ static int spacemit_i2s_probe(struct platform_device *pdev)
return dev_err_probe(i2s->dev, PTR_ERR(i2s->sspa_clk),
"failed to enable sspa clock\n");

i2s->sysclk_div = devm_clk_get_optional_enabled(i2s->dev, "sysclk_div");
if (IS_ERR(i2s->sysclk_div))
return dev_err_probe(i2s->dev, PTR_ERR(i2s->sysclk_div),
"failed to enable sysclk_div clock\n");

i2s->c_sysclk = devm_clk_get_optional_enabled(i2s->dev, "c_sysclk");
if (IS_ERR(i2s->c_sysclk))
return dev_err_probe(i2s->dev, PTR_ERR(i2s->c_sysclk),
"failed to enable c_sysclk clock\n");

i2s->c_bclk = devm_clk_get_optional_enabled(i2s->dev, "c_bclk");
if (IS_ERR(i2s->c_bclk))
return dev_err_probe(i2s->dev, PTR_ERR(i2s->c_bclk),
"failed to enable c_bclk clock\n");

i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(i2s->base))
return dev_err_probe(i2s->dev, PTR_ERR(i2s->base), "failed to map registers\n");
Expand All @@ -462,6 +495,7 @@ static int spacemit_i2s_probe(struct platform_device *pdev)

static const struct of_device_id spacemit_i2s_of_match[] = {
{ .compatible = "spacemit,k1-i2s", },
{ .compatible = "spacemit,k3-i2s", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, spacemit_i2s_of_match);
Expand All @@ -476,4 +510,4 @@ static struct platform_driver spacemit_i2s_driver = {
module_platform_driver(spacemit_i2s_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("I2S bus driver for SpacemiT K1 SoC");
MODULE_DESCRIPTION("I2S bus driver for SpacemiT K1/K3 SoC");