lkml.org 
[lkml]   [2023]   [Aug]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH 1/7] ASoC: sunxi: sun4i-i2s: Prepare for runtime DIN pin selection
    Date
    The R329 and D1 support multiple I2S data input pins, but to use these
    they require explicit mapping to channels.

    Add a mapping of DIN pins to the 16 channels in the sun4i_i2s struct
    then use that to write the channel mapping register.

    For now the mapping is always to DIN0, identical to the previous
    behaviour.

    Signed-off-by: John Watts <contact@jookia.org>
    ---
    sound/soc/sunxi/sun4i-i2s.c | 40 +++++++++++++++++++++++++++++++++----
    1 file changed, 36 insertions(+), 4 deletions(-)

    diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
    index 669d712bbe9f..d8f999ecaf05 100644
    --- a/sound/soc/sunxi/sun4i-i2s.c
    +++ b/sound/soc/sunxi/sun4i-i2s.c
    @@ -216,6 +216,7 @@ struct sun4i_i2s {
    unsigned int mclk_freq;
    unsigned int slots;
    unsigned int slot_width;
    + u8 channel_dins[16];

    struct snd_dmaengine_dai_dma_data capture_dma_data;
    struct snd_dmaengine_dai_dma_data playback_dma_data;
    @@ -233,6 +234,13 @@ struct sun4i_i2s_clk_div {
    u8 val;
    };

    +static int sun4i_i2s_read_channel_dins(struct device *dev, struct sun4i_i2s *i2s)
    +{
    + /* Use DIN pin 0 by default */
    + memset(i2s->channel_dins, 0, sizeof(i2s->channel_dins));
    + return 0;
    +}
    +
    static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
    { .div = 2, .val = 0 },
    { .div = 4, .val = 1 },
    @@ -527,6 +535,25 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
    return 0;
    }

    +static void sun50i_h6_write_channel_map(const struct sun4i_i2s *i2s,
    + unsigned int reg,
    + unsigned int channel_start)
    +{
    + unsigned int reg_value = 0;
    +
    + /* Loop backwards so we can shift values in */
    + for (int i = 3; i >= 0; i--) {
    + int channel = channel_start + i;
    + u8 din = i2s->channel_dins[channel];
    + u8 slot = channel; /* Map slot to channel */
    +
    + reg_value <<= 8;
    + reg_value |= (din << 4) | slot;
    + }
    +
    + regmap_write(i2s->regmap, reg, reg_value);
    +}
    +
    static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
    unsigned int channels, unsigned int slots,
    unsigned int slot_width)
    @@ -537,10 +564,10 @@ static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
    regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0xFEDCBA98);
    regmap_write(i2s->regmap, SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x76543210);
    if (i2s->variant->num_din_pins > 1) {
    - regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP0_REG, 0x0F0E0D0C);
    - regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP1_REG, 0x0B0A0908);
    - regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP2_REG, 0x07060504);
    - regmap_write(i2s->regmap, SUN50I_R329_I2S_RX_CHAN_MAP3_REG, 0x03020100);
    + sun50i_h6_write_channel_map(i2s, SUN50I_R329_I2S_RX_CHAN_MAP0_REG, 12);
    + sun50i_h6_write_channel_map(i2s, SUN50I_R329_I2S_RX_CHAN_MAP1_REG, 8);
    + sun50i_h6_write_channel_map(i2s, SUN50I_R329_I2S_RX_CHAN_MAP2_REG, 4);
    + sun50i_h6_write_channel_map(i2s, SUN50I_R329_I2S_RX_CHAN_MAP3_REG, 0);
    } else {
    regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0xFEDCBA98);
    regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x76543210);
    @@ -1559,6 +1586,11 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
    }
    }

    + if (sun4i_i2s_read_channel_dins(&pdev->dev, i2s)) {
    + dev_err(&pdev->dev, "Invalid channel DINs\n");
    + return -EINVAL;
    + }
    +
    i2s->playback_dma_data.addr = res->start +
    i2s->variant->reg_offset_txdata;
    i2s->playback_dma_data.maxburst = 8;
    --
    2.41.0
    \
     
     \ /
      Last update: 2023-08-11 22:15    [W:3.453 / U:0.556 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site