ASoC: Add I2S support for Allwinner H3 SoCs
Subsystems (4)
v3 cover ASoC: Add I2S support for Allwinner H3 SoCs
From: Marcus Cooper <[email protected]>
Hi All,
please find attached a series of patches to bring i2s support to the Allwinner H3 SoC. This has been tested with the following setups:
A20 Olimex EVB connected to a pcm5102
Orange Pi 2 connected to a uda1380
Orange Pi 2 hdmi audio playback
Pine 64 connected to the audio DAC board
To get i2s working some additional patches are required which will be delivered later. For now they have been pushed here
https://github.com/codekipper/linux-sunxi/commits/sunxi-audio-h3
I don't own a A33 device which uses the i2s block for the audio codec so if someone could test against that it would be much appreciated.
I'm also wondering if there is a preferred way of setting the lrclk size in the dts?..currently it is set to the sample width but for example the pcm5102a wants it to be 32 bits whatever the sample rate.
Thanks in advance,
CK
---
v4 changes compared to v3 are:
- moved clkdiv variant adjustment out of function
- used PTR_ERR_OR_ZERO for checks
- tidy up of extra lines and lines over 80 chars.
- reduced names of polarity, wss and sr reg fields.
- added reviewed-by to commit messages
- added comments for functionality that hasn't been implemented yet.
v3 changes compared to v2 are:
- initial changes to prepare driver for newer SoCs has been broken down into smaller patches
- reduce use of regmap fields to where just needed.
- clkdiv expansion will be delivered later.
- defines for H3 variant segregated.
- fixed regmap config issue with SUN8I_I2S_FIFO_TX_REG.
v2 changes compared to v1 are:
- massive refactoring to remove duplicate code making use of regmap_fields.
- extending the clock divisors.
- removed code that should be delivered when we support 20/24bits
---
Marcus Cooper (11):
ASoC: sun4i-i2s: Add clkdiv offsets to quirks
ASoC: sun4i-i2s: Add regmap config to quirks
ASoC: sun4i-i2s: Add TX FIFO offset to quirks
ASoC: sun4i-i2s: Add regmap fields for channels
ASoC: sun4i-i2s: Add regfields for word size select and sample
resolution
ASoC: sun4i-i2s: bclk and lrclk polarity tidyup
ASoC: sun4i-i2s: Add mclk enable regmap field
ASoC: sun4i-i2s: Add regmap field to set DAI format
ASoC: sun4i-i2s: Check for slave select bit
ASoC: sun4i-i2s: Update global enable with bitmask
ASoC: sun4i-i2s: Add support for H3
.../devicetree/bindings/sound/sun4i-i2s.txt | 2 + sound/soc/sunxi/sun4i-i2s.c | 444 ++++++++++++++++++--- 2 files changed, 391 insertions(+), 55 deletions(-)
Signature · 1 line
2.14.1
PATCH v3 1/11 ASoC: sun4i-i2s: Add clkdiv offsets to quirks
From: Marcus Cooper <[email protected]>
The BCLKDIV and MCLKDIV found on newer SoCs start from an offset of 1. Add the functionality to adjust the division values according to the needs to the device being used.
--- sound/soc/sunxi/sun4i-i2s.c | 8 ++++++++ 1 file changed, 8 insertions(+)
sound/soc/sunxi/sun4i-i2s.c +8 -0
@@ -94,9 +94,13 @@* struct sun4i_i2s_quirks - Differences between SoC variants. * * @has_reset: SoC needs reset deasserted. +* @mclk_offset: Value by which mclkdiv needs to be adjusted. +* @bclk_offset: Value by which bclkdiv needs to be adjusted. */ struct sun4i_i2s_quirks {bool has_reset; +unsigned int mclk_offset; +unsigned int bclk_offset; };struct sun4i_i2s {
@@ -237,6 +241,10 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,if (mclk_div <0 )return -EINVAL ; +/* Adjust the clock division values if needed */ + bclk_div += i2s->variant->bclk_offset; + mclk_div += i2s->variant->mclk_offset; + regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG, SUN4I_I2S_CLK_DIV_BCLK(bclk_div) | SUN4I_I2S_CLK_DIV_MCLK(mclk_div) |
Signature · 1 line
2.14.1
Re: [linux-sunxi] [PATCH v3 01/11] ASoC: sun4i-i2s: Add clkdiv offsets to quirks
Quoted 7 lines · On Sat, Aug 12, 2017 at 7:00 PM, <[email protected]…
From: Marcus Cooper <[email protected]>
The BCLKDIV and MCLKDIV found on newer SoCs start from an offset of 1. Add the functionality to adjust the division values according to the needs to the device being used.
Signed-off-by Marcus Cooper <[email protected]>
Mark Brown
maintainerApplied "ASoC: sun4i-i2s: Add clkdiv offsets to quirks" to the asoc tree
In reply to [email protected]The patch
ASoC: sun4i-i2s: Add clkdiv offsets to quirks
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 1 line
From
0aef27cab880d9612331350c008aec00cbb3d247Mon Sep 17 00:00:00 2001
From: Marcus Cooper <[email protected]>
Date: Sat, 12 Aug 2017 13:00:49 +0200
Subject: [PATCH] ASoC: sun4i-i2s: Add clkdiv offsets to quirks
The BCLKDIV and MCLKDIV found on newer SoCs start from an offset of 1. Add the functionality to adjust the division values according to the needs to the device being used.
--- sound/soc/sunxi/sun4i-i2s.c | 8 ++++++++ 1 file changed, 8 insertions(+)
sound/soc/sunxi/sun4i-i2s.c +8 -0
@@ -94,9 +94,13 @@* struct sun4i_i2s_quirks - Differences between SoC variants. * * @has_reset: SoC needs reset deasserted. +* @mclk_offset: Value by which mclkdiv needs to be adjusted. +* @bclk_offset: Value by which bclkdiv needs to be adjusted. */ struct sun4i_i2s_quirks {bool has_reset; +unsigned int mclk_offset; +unsigned int bclk_offset; };struct sun4i_i2s {
@@ -237,6 +241,10 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,if (mclk_div <0 )return -EINVAL ; +/* Adjust the clock division values if needed */ + bclk_div += i2s->variant->bclk_offset; + mclk_div += i2s->variant->mclk_offset; + regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG, SUN4I_I2S_CLK_DIV_BCLK(bclk_div) | SUN4I_I2S_CLK_DIV_MCLK(mclk_div) |
Signature · 1 line
2.13.2
PATCH v3 2/11 ASoC: sun4i-i2s: Add regmap config to quirks
In reply to [email protected]From: Marcus Cooper <[email protected]>
The newer SoCs have a larger range than the original SoC that this driver was developed for. By adding the regmap config to the quirks then the driver can initialise the managed register map correctly.
--- sound/soc/sunxi/sun4i-i2s.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
sound/soc/sunxi/sun4i-i2s.c +7 -3
@@ -94,11 +94,13 @@* struct sun4i_i2s_quirks - Differences between SoC variants. * * @has_reset: SoC needs reset deasserted. +* @sun4i_i2s_regmap: regmap config to use. * @mclk_offset: Value by which mclkdiv needs to be adjusted. * @bclk_offset: Value by which bclkdiv needs to be adjusted. */ struct sun4i_i2s_quirks {bool has_reset; +const struct regmap_config *sun4i_i2s_regmap;unsigned int mclk_offset;unsigned int bclk_offset; };
@@ -674,11 +676,13 @@ static int sun4i_i2s_runtime_suspend(struct device *dev) }static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { - .has_reset = false, + .has_reset = false, + .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, };static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { - .has_reset = true, + .has_reset = true, + .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, };static int sun4i_i2s_probe (struct platform_device *pdev)
@@ -717,7 +721,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev) } i2s->regmap =devm_regmap_init_mmio (&pdev->dev, regs, - &sun4i_i2s_regmap_config); + i2s->variant->sun4i_i2s_regmap);if (IS_ERR (i2s->regmap)) {dev_err (&pdev->dev,"Regmap initialisation failed\n" );return PTR_ERR (i2s->regmap);
Signature · 1 line
2.14.1
PATCH v3 3/11 ASoC: sun4i-i2s: Add TX FIFO offset to quirks
In reply to [email protected]From: Marcus Cooper <[email protected]>
It has been seen that the newer SoCs have a different TX FIFO address. Add this to the quirks structure.
--- sound/soc/sunxi/sun4i-i2s.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
sound/soc/sunxi/sun4i-i2s.c +6 -1
@@ -94,12 +94,14 @@* struct sun4i_i2s_quirks - Differences between SoC variants. * * @has_reset: SoC needs reset deasserted. +* @reg_offset_txdata: offset of the tx fifo. * @sun4i_i2s_regmap: regmap config to use. * @mclk_offset: Value by which mclkdiv needs to be adjusted. * @bclk_offset: Value by which bclkdiv needs to be adjusted. */ struct sun4i_i2s_quirks {bool has_reset; +unsigned int reg_offset_txdata;/* TX FIFO */ const struct regmap_config *sun4i_i2s_regmap;unsigned int mclk_offset;unsigned int bclk_offset;
@@ -677,11 +679,13 @@ static int sun4i_i2s_runtime_suspend(struct device *dev)static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .has_reset = false, + .reg_offset_txdata =SUN4I_I2S_FIFO_TX_REG , .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, };static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .has_reset = true, + .reg_offset_txdata =SUN4I_I2S_FIFO_TX_REG , .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, };
@@ -750,7 +754,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev) } } - i2s->playback_dma_data.addr = res->start +SUN4I_I2S_FIFO_TX_REG ; + i2s->playback_dma_data.addr = res->start + + i2s->variant->reg_offset_txdata; i2s->playback_dma_data.maxburst =8 ; i2s->capture_dma_data.addr = res->start +SUN4I_I2S_FIFO_RX_REG ;
Signature · 1 line
2.14.1
PATCH v3 4/11 ASoC: sun4i-i2s: Add regmap fields for channels
In reply to [email protected]From: Marcus Cooper <[email protected]>
On the original i2s block the channel mapping and selection were configured for stereo audio by default: This is not the case with the newer SoCs and they are also located at different offsets.
To support the newer SoC then regmap fields have been added to the quirks and these are initialised to their correct settings during probing.
--- sound/soc/sunxi/sun4i-i2s.c | 84 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 8 deletions(-)
sound/soc/sunxi/sun4i-i2s.c +76 -8
@@ -82,7 +82,7 @@#define SUN4I_I2S_TX_CNT_REG 0x2c#define SUN4I_I2S_TX_CHAN_SEL_REG 0x30 -#define SUN4I_I2S_TX_CHAN_SEL (num_chan) (((num_chan) - 1) << 0) +#define SUN4I_I2S_CHAN_SEL (num_chan) (((num_chan) - 1) << 0)#define SUN4I_I2S_TX_CHAN_MAP_REG 0x34#define SUN4I_I2S_TX_CHAN_MAP (chan, sample) ((sample) << (chan << 2))
@@ -98,6 +98,10 @@* @sun4i_i2s_regmap: regmap config to use. * @mclk_offset: Value by which mclkdiv needs to be adjusted. * @bclk_offset: Value by which bclkdiv needs to be adjusted. +* @field_txchanmap: location of the tx channel mapping register. +* @field_rxchanmap: location of the rx channel mapping register. +* @field_txchansel: location of the tx channel select bit fields. +* @field_rxchansel: location of the rx channel select bit fields. */ struct sun4i_i2s_quirks {bool has_reset;
@@ -105,6 +109,12 @@ struct sun4i_i2s_quirks {const struct regmap_config *sun4i_i2s_regmap;unsigned int mclk_offset;unsigned int bclk_offset; + +/* Register fields for i2s */ +struct reg_field field_txchanmap; +struct reg_field field_rxchanmap; +struct reg_field field_txchansel; +struct reg_field field_rxchansel; };struct sun4i_i2s {
@@ -118,6 +128,12 @@ struct sun4i_i2s {struct snd_dmaengine_dai_dma_data capture_dma_data;struct snd_dmaengine_dai_dma_data playback_dma_data; +/* Register fields for i2s */ +struct regmap_field *field_txchanmap; +struct regmap_field *field_rxchanmap; +struct regmap_field *field_txchansel; +struct regmap_field *field_rxchansel; +const struct sun4i_i2s_quirks *variant; };
@@ -268,6 +284,17 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,if (params_channels (params) !=2 )return -EINVAL ; +/* Map the channels for playback and capture */ +regmap_field_write (i2s->field_txchanmap,0x76543210 ); +regmap_field_write (i2s->field_rxchanmap,0x00003210 ); + +/* Configure the channels */ +regmap_field_write (i2s->field_txchansel, +SUN4I_I2S_CHAN_SEL (params_channels (params))); + +regmap_field_write (i2s->field_rxchansel, +SUN4I_I2S_CHAN_SEL (params_channels (params))); +switch (params_physical_width (params)) {case 16 : width =DMA_SLAVE_BUSWIDTH_2_BYTES ;
@@ -490,13 +517,6 @@ static int sun4i_i2s_startup(struct snd_pcm_substream *substream,SUN4I_I2S_CTRL_SDO_EN_MASK , SUN4I_I2S_CTRL_SDO_EN(0)); -/* Enable the first two channels */ -regmap_write (i2s->regmap,SUN4I_I2S_TX_CHAN_SEL_REG , -SUN4I_I2S_TX_CHAN_SEL (2 )); - -/* Map them to the two first samples coming in */ -regmap_write (i2s->regmap,SUN4I_I2S_TX_CHAN_MAP_REG , -SUN4I_I2S_TX_CHAN_MAP (0 ,0 ) |SUN4I_I2S_TX_CHAN_MAP (1 ,1 ));return clk_prepare_enable (i2s->mod_clk); }
@@ -681,14 +701,56 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .has_reset = false, .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), + .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), + .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), + .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), };static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .has_reset = true, .reg_offset_txdata =SUN4I_I2S_FIFO_TX_REG , .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_txchanmap =REG_FIELD (SUN4I_I2S_TX_CHAN_MAP_REG ,0 ,31 ), + .field_rxchanmap =REG_FIELD (SUN4I_I2S_RX_CHAN_MAP_REG ,0 ,31 ), + .field_txchansel =REG_FIELD (SUN4I_I2S_TX_CHAN_SEL_REG ,0 ,2 ), + .field_rxchansel =REG_FIELD (SUN4I_I2S_RX_CHAN_SEL_REG ,0 ,2 ), }; +static int sun4i_i2s_init_regmap_fields (struct device *dev, +struct sun4i_i2s *i2s) +{ +int ret; + + i2s->field_txchanmap = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_txchanmap); + ret =PTR_ERR_OR_ZERO (i2s->field_txchanmap); + +if (!ret) { + i2s->field_rxchanmap = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_rxchanmap); + ret =PTR_ERR_OR_ZERO (i2s->field_rxchanmap); + } + +if (!ret) { + i2s->field_txchansel = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_txchansel); + ret =PTR_ERR_OR_ZERO (i2s->field_txchansel); + } + +if (!ret) { + i2s->field_rxchansel = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_rxchansel); + ret =PTR_ERR_OR_ZERO (i2s->field_rxchansel); + } + +return ret; +} +static int sun4i_i2s_probe (struct platform_device *pdev) {struct sun4i_i2s *i2s;
@@ -782,6 +844,12 @@ static int sun4i_i2s_probe(struct platform_device *pdev) goto err_suspend; } + ret =sun4i_i2s_init_regmap_fields (&pdev->dev, i2s); +if (ret) { +dev_err (&pdev->dev,"Could not initialise regmap fields\n" ); + goto err_suspend; + } +return 0 ; err_suspend:
Signature · 1 line
2.14.1
Re: [linux-sunxi] [PATCH v3 04/11] ASoC: sun4i-i2s: Add regmap fields for channels
Quoted 20 lines · On Sat, Aug 12, 2017 at 7:00 PM, <[email protected]…
From: Marcus Cooper <[email protected]>
On the original i2s block the channel mapping and selection were configured for stereo audio by default: This is not the case with the newer SoCs and they are also located at different offsets.
To support the newer SoC then regmap fields have been added to the quirks and these are initialised to their correct settings during probing.
Signed-off-by Marcus Cooper <[email protected]>Reviewed-by Chen-Yu Tsai <[email protected]>--- sound/soc/sunxi/sun4i-i2s.c | 84 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 8 deletions(-)sound/soc/sunxi/sun4i-i2s.c +0
-0
[...]
Quoted 39 lines
sound/soc/sunxi/sun4i-i2s.c +27
-0@@ -681,14 +701,56 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .has_reset = false, .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), + .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), + .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), + .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), };static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .has_reset = true, .reg_offset_txdata =SUN4I_I2S_FIFO_TX_REG , .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_txchanmap =REG_FIELD (SUN4I_I2S_TX_CHAN_MAP_REG ,0 ,31 ), + .field_rxchanmap =REG_FIELD (SUN4I_I2S_RX_CHAN_MAP_REG ,0 ,31 ), + .field_txchansel =REG_FIELD (SUN4I_I2S_TX_CHAN_SEL_REG ,0 ,2 ), + .field_rxchansel =REG_FIELD (SUN4I_I2S_RX_CHAN_SEL_REG ,0 ,2 ), }; +static int sun4i_i2s_init_regmap_fields (struct device *dev, +struct sun4i_i2s *i2s) +{ +int ret; + + i2s->field_txchanmap = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_txchanmap); + ret =PTR_ERR_OR_ZERO (i2s->field_txchanmap); + +if (!ret) { + i2s->field_rxchanmap = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_rxchanmap); + ret =PTR_ERR_OR_ZERO (i2s->field_rxchanmap); + } + +if (!ret) { + i2s->field_txchansel =
sound/soc/sunxi/sun4i-i2s.c static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { · line 748
Quoted 10 lines
sound/soc/sunxi/sun4i-i2s.c +10
-0+devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_txchansel); + ret =PTR_ERR_OR_ZERO (i2s->field_txchansel); + } + +if (!ret) { + i2s->field_rxchansel = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_rxchansel); + ret =PTR_ERR_OR_ZERO (i2s->field_rxchansel);
I'm quite sure this was not what we meant when we recommended the usage of PTR_ERR_OR_ZERO...
Rather you should have kept the
if (PTR_ERR(...))
return PTR_ERR(...);for all but the last conditional blocks. For the last one just
return PTR_ERR_OR_ZERO(...);
Returning early, as opposed to what you have here, is also easier to read. People looking at it will notice early on that if something wrong happens, you bail out. Instead with this structure, people have to read down a long list of ifs that aren't doing anything. Not to mention that you have to indent every code block except the first one by one tab, reducing any screen real estate you have.
ChenYu
Quoted 8 lines
sound/soc/sunxi/sun4i-i2s.c +5
-0+ } + +return ret; +} +static int sun4i_i2s_probe (struct platform_device *pdev) {struct sun4i_i2s *i2s;
[...]
PATCH v3 5/11 ASoC: sun4i-i2s: Add regfields for word size select and sample resolution
In reply to [email protected]From: Marcus Cooper <[email protected]>
On newer SoCs the location of the slot width select and sample resolution are different and also there is a bigger range of support.
For the current supported rates then an offset is required.
--- sound/soc/sunxi/sun4i-i2s.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
sound/soc/sunxi/sun4i-i2s.c +30 -3
@@ -98,6 +98,9 @@* @sun4i_i2s_regmap: regmap config to use. * @mclk_offset: Value by which mclkdiv needs to be adjusted. * @bclk_offset: Value by which bclkdiv needs to be adjusted. +* @fmt_offset: Value by which wss and sr needs to be adjusted. +* @field_fmt_wss: regmap field to set word select size. +* @field_fmt_sr: regmap field to set sample resolution. * @field_txchanmap: location of the tx channel mapping register. * @field_rxchanmap: location of the rx channel mapping register. * @field_txchansel: location of the tx channel select bit fields.
@@ -109,8 +112,11 @@ struct sun4i_i2s_quirks {const struct regmap_config *sun4i_i2s_regmap;unsigned int mclk_offset;unsigned int bclk_offset; +unsigned int fmt_offset;/* Register fields for i2s */ +struct reg_field field_fmt_wss; +struct reg_field field_fmt_sr;struct reg_field field_txchanmap;struct reg_field field_rxchanmap;struct reg_field field_txchansel;
@@ -129,6 +135,8 @@ struct sun4i_i2s {struct snd_dmaengine_dai_dma_data playback_dma_data;/* Register fields for i2s */ +struct regmap_field *field_fmt_wss; +struct regmap_field *field_fmt_sr;struct regmap_field *field_txchanmap;struct regmap_field *field_rxchanmap;struct regmap_field *field_txchansel;
@@ -314,9 +322,10 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,return -EINVAL ; } -regmap_update_bits (i2s->regmap,SUN4I_I2S_FMT0_REG , -SUN4I_I2S_FMT0_WSS_MASK |SUN4I_I2S_FMT0_SR_MASK , -SUN4I_I2S_FMT0_WSS (wss) |SUN4I_I2S_FMT0_SR (sr)); +regmap_field_write (i2s->field_fmt_wss, + wss + i2s->variant->fmt_offset); +regmap_field_write (i2s->field_fmt_sr, + sr + i2s->variant->fmt_offset);return sun4i_i2s_set_clk_rate (i2s,params_rate (params),params_width (params));
@@ -701,6 +710,8 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .has_reset = false, .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), + .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -711,6 +722,8 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .has_reset = true, .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), + .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -748,6 +761,20 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev, ret =PTR_ERR_OR_ZERO (i2s->field_rxchansel); } +if (!ret) { + i2s->field_fmt_wss = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_fmt_wss); + ret =PTR_ERR_OR_ZERO (i2s->field_fmt_wss); + } + +if (!ret) { + i2s->field_fmt_sr = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_fmt_sr); + ret =PTR_ERR_OR_ZERO (i2s->field_fmt_sr); + } +return ret; }
Signature · 1 line
2.14.1
PATCH v3 6/11 ASoC: sun4i-i2s: bclk and lrclk polarity tidyup
In reply to [email protected]From: Marcus Cooper <[email protected]>
On newer SoCs the bit fields for the blck and lrclk polarity are in a different locations. Use regmap fields to set the polarity bits as intended.
--- sound/soc/sunxi/sun4i-i2s.c | 47 ++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-)
sound/soc/sunxi/sun4i-i2s.c +34 -13
@@ -50,6 +50,8 @@#define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0)#define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0)#define SUN4I_I2S_FMT0_FMT_I2S (0 << 0) +#define SUN4I_I2S_FMT0_POLARITY_INVERTED (1) +#define SUN4I_I2S_FMT0_POLARITY_NORMAL (0)#define SUN4I_I2S_FMT1_REG 0x08#define SUN4I_I2S_FIFO_TX_REG 0x0c
@@ -101,6 +103,8 @@* @fmt_offset: Value by which wss and sr needs to be adjusted. * @field_fmt_wss: regmap field to set word select size. * @field_fmt_sr: regmap field to set sample resolution. +* @field_fmt_bclk: regmap field to set clk polarity. +* @field_fmt_lrclk: regmap field to set frame polarity. * @field_txchanmap: location of the tx channel mapping register. * @field_rxchanmap: location of the rx channel mapping register. * @field_txchansel: location of the tx channel select bit fields.
@@ -117,6 +121,8 @@ struct sun4i_i2s_quirks {/* Register fields for i2s */ struct reg_field field_fmt_wss;struct reg_field field_fmt_sr; +struct reg_field field_fmt_bclk; +struct reg_field field_fmt_lrclk;struct reg_field field_txchanmap;struct reg_field field_rxchanmap;struct reg_field field_txchansel;
@@ -137,6 +143,8 @@ struct sun4i_i2s {/* Register fields for i2s */ struct regmap_field *field_fmt_wss;struct regmap_field *field_fmt_sr; +struct regmap_field *field_fmt_bclk; +struct regmap_field *field_fmt_lrclk;struct regmap_field *field_txchanmap;struct regmap_field *field_rxchanmap;struct regmap_field *field_txchansel;
@@ -335,6 +343,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) {struct sun4i_i2s *i2s =snd_soc_dai_get_drvdata (dai);u32 val; +u32 bclk_polarity =SUN4I_I2S_FMT0_POLARITY_NORMAL ; +u32 lrclk_polarity =SUN4I_I2S_FMT0_POLARITY_NORMAL ;/* DAI Mode */ switch (fmt &SND_SOC_DAIFMT_FORMAT_MASK ) {
@@ -359,32 +369,25 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)switch (fmt &SND_SOC_DAIFMT_INV_MASK ) {case SND_SOC_DAIFMT_IB_IF :/* Invert both clocks */ - val =SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED | -SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED ; + bclk_polarity =SUN4I_I2S_FMT0_POLARITY_INVERTED ; + lrclk_polarity =SUN4I_I2S_FMT0_POLARITY_INVERTED ;break ;case SND_SOC_DAIFMT_IB_NF :/* Invert bit clock */ - val =SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED | -SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL ; + bclk_polarity =SUN4I_I2S_FMT0_POLARITY_INVERTED ;break ;case SND_SOC_DAIFMT_NB_IF :/* Invert frame clock */ - val =SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED | -SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL ; + lrclk_polarity =SUN4I_I2S_FMT0_POLARITY_INVERTED ;break ;case SND_SOC_DAIFMT_NB_NF : -/* Nothing to do for both normal cases */ - val =SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL | -SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL ;break ;default :return -EINVAL ; } -regmap_update_bits (i2s->regmap,SUN4I_I2S_FMT0_REG , -SUN4I_I2S_FMT0_BCLK_POLARITY_MASK | -SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK , - val); +regmap_field_write (i2s->field_fmt_bclk, bclk_polarity); +regmap_field_write (i2s->field_fmt_lrclk, lrclk_polarity);/* DAI clock master masks */ switch (fmt &SND_SOC_DAIFMT_MASTER_MASK ) {
@@ -712,6 +715,8 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), + .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), + .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -724,6 +729,8 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), + .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), + .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -775,6 +782,20 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev, ret =PTR_ERR_OR_ZERO (i2s->field_fmt_sr); } +if (!ret) { + i2s->field_fmt_bclk = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_fmt_bclk); + ret =PTR_ERR_OR_ZERO (i2s->field_fmt_bclk); + } + +if (!ret) { + i2s->field_fmt_lrclk = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_fmt_lrclk); + ret =PTR_ERR_OR_ZERO (i2s->field_fmt_lrclk); + } +return ret; }
Signature · 1 line
2.14.1
PATCH v3 7/11 ASoC: sun4i-i2s: Add mclk enable regmap field
In reply to [email protected]From: Marcus Cooper <[email protected]>
The location of the mclk output enable bit is different on newer SoCs. Use a regmap field to enable it.
--- sound/soc/sunxi/sun4i-i2s.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
sound/soc/sunxi/sun4i-i2s.c +18 -5
@@ -101,6 +101,7 @@* @mclk_offset: Value by which mclkdiv needs to be adjusted. * @bclk_offset: Value by which bclkdiv needs to be adjusted. * @fmt_offset: Value by which wss and sr needs to be adjusted. +* @field_clkdiv_mclk_en: regmap field to enable mclk output. * @field_fmt_wss: regmap field to set word select size. * @field_fmt_sr: regmap field to set sample resolution. * @field_fmt_bclk: regmap field to set clk polarity.
@@ -119,6 +120,7 @@ struct sun4i_i2s_quirks {unsigned int fmt_offset;/* Register fields for i2s */ +struct reg_field field_clkdiv_mclk_en;struct reg_field field_fmt_wss;struct reg_field field_fmt_sr;struct reg_field field_fmt_bclk;
@@ -141,6 +143,7 @@ struct sun4i_i2s {struct snd_dmaengine_dai_dma_data playback_dma_data;/* Register fields for i2s */ +struct regmap_field *field_clkdiv_mclk_en;struct regmap_field *field_fmt_wss;struct regmap_field *field_fmt_sr;struct regmap_field *field_fmt_bclk;
@@ -283,8 +286,9 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,regmap_write (i2s->regmap,SUN4I_I2S_CLK_DIV_REG ,SUN4I_I2S_CLK_DIV_BCLK (bclk_div) | -SUN4I_I2S_CLK_DIV_MCLK (mclk_div) | -SUN4I_I2S_CLK_DIV_MCLK_EN ); +SUN4I_I2S_CLK_DIV_MCLK (mclk_div)); + +regmap_field_write (i2s->field_clkdiv_mclk_en,1 );return 0 ; }
@@ -713,6 +717,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .has_reset = false, .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
@@ -727,6 +732,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .has_reset = true, .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
@@ -742,10 +748,17 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev, {int ret; - i2s->field_txchanmap = + i2s->field_clkdiv_mclk_en =devm_regmap_field_alloc (dev, i2s->regmap, - i2s->variant->field_txchanmap); - ret =PTR_ERR_OR_ZERO (i2s->field_txchanmap); + i2s->variant->field_clkdiv_mclk_en); + ret =PTR_ERR_OR_ZERO (i2s->field_clkdiv_mclk_en); + +if (!ret) { + i2s->field_txchanmap = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_txchanmap); + ret =PTR_ERR_OR_ZERO (i2s->field_txchanmap); + }if (!ret) { i2s->field_rxchanmap =
Signature · 1 line
2.14.1
PATCH v3 8/11 ASoC: sun4i-i2s: Add regmap field to set DAI format
In reply to [email protected]From: Marcus Cooper <[email protected]>
On the newer SoCs the bits to configure the operational mode are located in a different register. Add a regmap field so that this location can be configured.
--- sound/soc/sunxi/sun4i-i2s.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
sound/soc/sunxi/sun4i-i2s.c +13 -3
@@ -106,6 +106,7 @@* @field_fmt_sr: regmap field to set sample resolution. * @field_fmt_bclk: regmap field to set clk polarity. * @field_fmt_lrclk: regmap field to set frame polarity. +* @field_fmt_mode: regmap field to set the operational mode. * @field_txchanmap: location of the tx channel mapping register. * @field_rxchanmap: location of the rx channel mapping register. * @field_txchansel: location of the tx channel select bit fields.
@@ -125,6 +126,7 @@ struct sun4i_i2s_quirks {struct reg_field field_fmt_sr;struct reg_field field_fmt_bclk;struct reg_field field_fmt_lrclk; +struct reg_field field_fmt_mode;struct reg_field field_txchanmap;struct reg_field field_rxchanmap;struct reg_field field_txchansel;
@@ -148,6 +150,7 @@ struct sun4i_i2s {struct regmap_field *field_fmt_sr;struct regmap_field *field_fmt_bclk;struct regmap_field *field_fmt_lrclk; +struct regmap_field *field_fmt_mode;struct regmap_field *field_txchanmap;struct regmap_field *field_rxchanmap;struct regmap_field *field_txchansel;
@@ -365,9 +368,7 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)return -EINVAL ; } -regmap_update_bits (i2s->regmap,SUN4I_I2S_FMT0_REG , -SUN4I_I2S_FMT0_FMT_MASK , - val); +regmap_field_write (i2s->field_fmt_mode, val);/* DAI clock polarity */ switch (fmt &SND_SOC_DAIFMT_INV_MASK ) {
@@ -722,6 +723,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -737,6 +739,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
@@ -781,6 +784,13 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev, ret =PTR_ERR_OR_ZERO (i2s->field_rxchansel); } +if (!ret) { + i2s->field_fmt_mode = +devm_regmap_field_alloc (dev, i2s->regmap, + i2s->variant->field_fmt_mode); + ret =PTR_ERR_OR_ZERO (i2s->field_fmt_mode); + } +if (!ret) { i2s->field_fmt_wss = devm_regmap_field_alloc(dev, i2s->regmap,
Signature · 1 line
2.14.1
PATCH v3 9/11 ASoC: sun4i-i2s: Check for slave select bit
In reply to [email protected]From: Marcus Cooper <[email protected]>
The newer SoCs do not have this setting. Instead they set the pin direction. Add a check to see if the bit is valid and if so set it accordingly.
--- sound/soc/sunxi/sun4i-i2s.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-)
sound/soc/sunxi/sun4i-i2s.c +21 -16
@@ -96,6 +96,7 @@* struct sun4i_i2s_quirks - Differences between SoC variants. * * @has_reset: SoC needs reset deasserted. +* @has_slave_select_bit: SoC has a bit to enable slave mode. * @reg_offset_txdata: offset of the tx fifo. * @sun4i_i2s_regmap: regmap config to use. * @mclk_offset: Value by which mclkdiv needs to be adjusted.
@@ -114,6 +115,7 @@*/ struct sun4i_i2s_quirks {bool has_reset; +bool has_slave_select_bit;unsigned int reg_offset_txdata;/* TX FIFO */ const struct regmap_config *sun4i_i2s_regmap;unsigned int mclk_offset;
@@ -394,24 +396,25 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)regmap_field_write (i2s->field_fmt_bclk, bclk_polarity);regmap_field_write (i2s->field_fmt_lrclk, lrclk_polarity); -/* DAI clock master masks */ -switch (fmt &SND_SOC_DAIFMT_MASTER_MASK ) { -case SND_SOC_DAIFMT_CBS_CFS : -/* BCLK and LRCLK master */ - val =SUN4I_I2S_CTRL_MODE_MASTER ; -break ; -case SND_SOC_DAIFMT_CBM_CFM : -/* BCLK and LRCLK slave */ - val =SUN4I_I2S_CTRL_MODE_SLAVE ; -break ; -default : -return -EINVAL ; +if (i2s->variant->has_slave_select_bit) { +/* DAI clock master masks */ +switch (fmt &SND_SOC_DAIFMT_MASTER_MASK ) { +case SND_SOC_DAIFMT_CBS_CFS : +/* BCLK and LRCLK master */ + val =SUN4I_I2S_CTRL_MODE_MASTER ; +break ; +case SND_SOC_DAIFMT_CBM_CFM : +/* BCLK and LRCLK slave */ + val =SUN4I_I2S_CTRL_MODE_SLAVE ; +break ; +default : +return -EINVAL ; + } +regmap_update_bits (i2s->regmap,SUN4I_I2S_CTRL_REG , +SUN4I_I2S_CTRL_MODE_MASK , + val); } -regmap_update_bits (i2s->regmap,SUN4I_I2S_CTRL_REG , -SUN4I_I2S_CTRL_MODE_MASK , - val); -/* Set significant bits in our FIFOs */ regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
@@ -723,6 +726,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .has_slave_select_bit = true, .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
@@ -739,6 +743,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .has_slave_select_bit = true, .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
Signature · 1 line
2.14.1
PATCH v3 10/11 ASoC: sun4i-i2s: Update global enable with bitmask
In reply to [email protected]From: Marcus Cooper <[email protected]>
The default value of the config register is different on newer SoCs and therefore enabling/disabling with a register write will clear bits used to set the direction of the clock and frame pins.
--- sound/soc/sunxi/sun4i-i2s.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
sound/soc/sunxi/sun4i-i2s.c +4 -3
@@ -529,8 +529,8 @@ static int sun4i_i2s_startup(struct snd_pcm_substream *substream,struct sun4i_i2s *i2s =snd_soc_dai_get_drvdata (dai);/* Enable the whole hardware block */ -regmap_write (i2s->regmap,SUN4I_I2S_CTRL_REG , -SUN4I_I2S_CTRL_GL_EN ); +regmap_update_bits (i2s->regmap,SUN4I_I2S_CTRL_REG , +SUN4I_I2S_CTRL_GL_EN ,SUN4I_I2S_CTRL_GL_EN );/* Enable the first output line */ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
@@ -553,7 +553,8 @@ static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream, SUN4I_I2S_CTRL_SDO_EN_MASK, 0);/* Disable the whole hardware block */ -regmap_write (i2s->regmap,SUN4I_I2S_CTRL_REG ,0 ); +regmap_update_bits (i2s->regmap,SUN4I_I2S_CTRL_REG , +SUN4I_I2S_CTRL_GL_EN ,0 ); } static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
Signature · 1 line
2.14.1
PATCH v3 11/11 ASoC: sun4i-i2s: Add support for H3
In reply to [email protected]From: Marcus Cooper <[email protected]>
The sun8i-h3 introduces a lot of changes to the i2s block such as different register locations, extended clock division and more operational modes. As we have to consider the earlier implementation then these changes need to be isolated.
None of the new functionality has been implemented yet, the driver has just been expanded to allow it work on the H3 SoC.
--- .../devicetree/bindings/sound/sun4i-i2s.txt | 2 + sound/soc/sunxi/sun4i-i2s.c | 176 ++++++++++++++++++++- 2 files changed, 176 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/sound/sun4i-i2s.txt +2 -0
@@ -8,6 +8,7 @@ Required properties: - compatible: should be one of the following: - "allwinner,sun4i-a10-i2s" - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - reg: physical base address of the controller and length of memory mapped region. - interrupts: should contain the I2S interrupt.
@@ -22,6 +23,7 @@ Required properties: Required properties for the following compatibles: - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - resets: phandle to the reset line for this codec Example:
sound/soc/sunxi/sun4i-i2s.c +174 -2
281 lines not on this page · raw message
Signature · 1 line
2.14.1
Re: [linux-sunxi] [PATCH v3 11/11] ASoC: sun4i-i2s: Add support for H3
Quoted 41 lines · On Sat, Aug 12, 2017 at 7:00 PM, <[email protected]> wrote:
From: Marcus Cooper <[email protected]>
The sun8i-h3 introduces a lot of changes to the i2s block such as different register locations, extended clock division and more operational modes. As we have to consider the earlier implementation then these changes need to be isolated.
None of the new functionality has been implemented yet, the driver has just been expanded to allow it work on the H3 SoC.
Signed-off-by Marcus Cooper <[email protected]>--- .../devicetree/bindings/sound/sun4i-i2s.txt | 2 + sound/soc/sunxi/sun4i-i2s.c | 176 ++++++++++++++++++++- 2 files changed, 176 insertions(+), 2 deletions(-)Documentation/devicetree/bindings/sound/sun4i-i2s.txt +2
-0@@ -8,6 +8,7 @@ Required properties: - compatible: should be one of the following: - "allwinner,sun4i-a10-i2s" - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - reg: physical base address of the controller and length of memory mapped region. - interrupts: should contain the I2S interrupt.@@ -22,6 +23,7 @@ Required properties: Required properties for the following compatibles: - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - resets: phandle to the reset line for this codec Example:sound/soc/sunxi/sun4i-i2s.c +0
-0
sound/soc/sunxi/sun4i-i2s.c line 100
Quoted 9 lines
sound/soc/sunxi/sun4i-i2s.c +6
-0@@ -92,11 +92,41 @@#define SUN4I_I2S_RX_CHAN_SEL_REG 0x38#define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c +/* Defines required for sun8i-h3 support */ +#define SUN8I_I2S_CTRL_BCLK_OUT BIT(18) +#define SUN8I_I2S_CTRL_LRCK_OUT BIT(17) + +#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) +#define SUN8I_I2S_FMT0_LRCK_PERIOD (period) ((period << 8) - 1)
I'm pretty sure this should be ((period - 1) << 8).
Once fixed,
P.S. the version tag for this series in the subject is wrong.
Re: [linux-sunxi] [PATCH v3 11/11] ASoC: sun4i-i2s: Add support for H3
Quoted 54 lines · Chen-Yu Tsai
Quoted 41 lines · On Sat, Aug 12, 2017 at 7:00 PM, <[email protected]> wrote:
From: Marcus Cooper <[email protected]>
The sun8i-h3 introduces a lot of changes to the i2s block such as different register locations, extended clock division and more operational modes. As we have to consider the earlier implementation then these changes need to be isolated.
None of the new functionality has been implemented yet, the driver has just been expanded to allow it work on the H3 SoC.
Signed-off-by Marcus Cooper <[email protected]>--- .../devicetree/bindings/sound/sun4i-i2s.txt | 2 + sound/soc/sunxi/sun4i-i2s.c | 176 ++++++++++++++++++++- 2 files changed, 176 insertions(+), 2 deletions(-)Documentation/devicetree/bindings/sound/sun4i-i2s.txt +2
-0@@ -8,6 +8,7 @@ Required properties: - compatible: should be one of the following: - "allwinner,sun4i-a10-i2s" - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - reg: physical base address of the controller and length of memory mapped region. - interrupts: should contain the I2S interrupt.@@ -22,6 +23,7 @@ Required properties: Required properties for the following compatibles: - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - resets: phandle to the reset line for this codec Example:sound/soc/sunxi/sun4i-i2s.c +0
-0sound/soc/sunxi/sun4i-i2s.c line 100
Quoted 9 lines
sound/soc/sunxi/sun4i-i2s.c +6
-0@@ -92,11 +92,41 @@#define SUN4I_I2S_RX_CHAN_SEL_REG 0x38#define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c +/* Defines required for sun8i-h3 support */ +#define SUN8I_I2S_CTRL_BCLK_OUT BIT(18) +#define SUN8I_I2S_CTRL_LRCK_OUT BIT(17) + +#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) +#define SUN8I_I2S_FMT0_LRCK_PERIOD (period) ((period << 8) - 1)I'm pretty sure this should be ((period - 1) << 8).
Quoted 5 lines
Once fixed,
Reviewed-by Chen-Yu Tsai <[email protected]>
P.S. the version tag for this series in the subject is wrong.
Hi Wens,
thanks for the reviews..I've ack'd them all and will push again once tested. BR,
CK