Skip to content

Commit

Permalink
ASoC: qcom: sc7180: Add support for audio over DP
Browse files Browse the repository at this point in the history
Add support for audio playback over DP in lpass
sc7180 platform driver. Update lpass_variant
structure for hdmi data configuaration.

Signed-off-by: V Sujith Kumar Reddy <[email protected]>
Signed-off-by: Srinivasa Rao <[email protected]>
Tested-by: Srinivas Kandagatla <[email protected]>
Reviewed-by: Srinivas Kandagatla <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
  • Loading branch information
V Sujith Kumar Reddy authored and broonie committed Oct 8, 2020
1 parent 03f20e2 commit 2ad63dc
Showing 1 changed file with 102 additions and 14 deletions.
116 changes: 102 additions & 14 deletions sound/soc/qcom/lpass-sc7180.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,38 +60,65 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
.probe = &asoc_qcom_lpass_cpu_dai_probe,
.ops = &asoc_qcom_lpass_cpu_dai_ops,
},
[LPASS_DP_RX] = {
.id = LPASS_DP_RX,
.name = "Hdmi",
.playback = {
.stream_name = "Hdmi Playback",
.formats = SNDRV_PCM_FMTBIT_S24,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
.rate_max = 48000,
.channels_min = 2,
.channels_max = 2,
},
.ops = &asoc_qcom_lpass_hdmi_dai_ops,
},
};

static int sc7180_lpass_alloc_dma_channel(struct lpass_data *drvdata,
int direction)
int direction, unsigned int dai_id)
{
struct lpass_variant *v = drvdata->variant;
int chan = 0;

if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
chan = find_first_zero_bit(&drvdata->dma_ch_bit_map,
v->rdma_channels);
if (dai_id == LPASS_DP_RX) {
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
chan = find_first_zero_bit(&drvdata->hdmi_dma_ch_bit_map,
v->hdmi_rdma_channels);

if (chan >= v->hdmi_rdma_channels)
return -EBUSY;
}
set_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
} else {
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
chan = find_first_zero_bit(&drvdata->dma_ch_bit_map,
v->rdma_channels);

if (chan >= v->rdma_channels)
return -EBUSY;
} else {
chan = find_next_zero_bit(&drvdata->dma_ch_bit_map,
} else {
chan = find_next_zero_bit(&drvdata->dma_ch_bit_map,
v->wrdma_channel_start +
v->wrdma_channels,
v->wrdma_channel_start);

if (chan >= v->wrdma_channel_start + v->wrdma_channels)
return -EBUSY;
}

set_bit(chan, &drvdata->dma_ch_bit_map);
if (chan >= v->wrdma_channel_start + v->wrdma_channels)
return -EBUSY;
}

set_bit(chan, &drvdata->dma_ch_bit_map);
}
return chan;
}

static int sc7180_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)
static int sc7180_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, unsigned int dai_id)
{
clear_bit(chan, &drvdata->dma_ch_bit_map);
if (dai_id == LPASS_DP_RX)
clear_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
else
clear_bit(chan, &drvdata->dma_ch_bit_map);

return 0;
}
Expand Down Expand Up @@ -144,6 +171,9 @@ static struct lpass_variant sc7180_data = {
.rdma_reg_base = 0xC000,
.rdma_reg_stride = 0x1000,
.rdma_channels = 5,
.hdmi_rdma_reg_base = 0x64000,
.hdmi_rdma_reg_stride = 0x1000,
.hdmi_rdma_channels = 4,
.dmactl_audif_start = 1,
.wrdma_reg_base = 0x18000,
.wrdma_reg_stride = 0x1000,
Expand All @@ -163,7 +193,7 @@ static struct lpass_variant sc7180_data = {
.rdma_dyncclk = REG_FIELD_ID(0xC000, 21, 21, 5, 0x1000),
.rdma_bursten = REG_FIELD_ID(0xC000, 20, 20, 5, 0x1000),
.rdma_wpscnt = REG_FIELD_ID(0xC000, 16, 19, 5, 0x1000),
.rdma_intf = REG_FIELD_ID(0xC000, 12, 15, 5, 0x1000),
.rdma_intf = REG_FIELD_ID(0xC000, 12, 15, 5, 0x1000),
.rdma_fifowm = REG_FIELD_ID(0xC000, 1, 5, 5, 0x1000),
.rdma_enable = REG_FIELD_ID(0xC000, 0, 0, 5, 0x1000),

Expand All @@ -174,6 +204,64 @@ static struct lpass_variant sc7180_data = {
.wrdma_fifowm = REG_FIELD_ID(0x18000, 1, 5, 4, 0x1000),
.wrdma_enable = REG_FIELD_ID(0x18000, 0, 0, 4, 0x1000),

.hdmi_tx_ctl_addr = 0x1000,
.hdmi_legacy_addr = 0x1008,
.hdmi_vbit_addr = 0x610c0,
.hdmi_ch_lsb_addr = 0x61048,
.hdmi_ch_msb_addr = 0x6104c,
.ch_stride = 0x8,
.hdmi_parity_addr = 0x61034,
.hdmi_dmactl_addr = 0x61038,
.hdmi_dma_stride = 0x4,
.hdmi_DP_addr = 0x610c8,
.hdmi_sstream_addr = 0x6101c,
.hdmi_irq_reg_base = 0x63000,
.hdmi_irq_ports = 1,

.hdmi_rdma_dyncclk = REG_FIELD_ID(0x64000, 14, 14, 4, 0x1000),
.hdmi_rdma_bursten = REG_FIELD_ID(0x64000, 13, 13, 4, 0x1000),
.hdmi_rdma_burst8 = REG_FIELD_ID(0x64000, 15, 15, 4, 0x1000),
.hdmi_rdma_burst16 = REG_FIELD_ID(0x64000, 16, 16, 4, 0x1000),
.hdmi_rdma_dynburst = REG_FIELD_ID(0x64000, 18, 18, 4, 0x1000),
.hdmi_rdma_wpscnt = REG_FIELD_ID(0x64000, 10, 12, 4, 0x1000),
.hdmi_rdma_fifowm = REG_FIELD_ID(0x64000, 1, 5, 4, 0x1000),
.hdmi_rdma_enable = REG_FIELD_ID(0x64000, 0, 0, 4, 0x1000),

.sstream_en = REG_FIELD(0x6101c, 0, 0),
.dma_sel = REG_FIELD(0x6101c, 1, 2),
.auto_bbit_en = REG_FIELD(0x6101c, 3, 3),
.layout = REG_FIELD(0x6101c, 4, 4),
.layout_sp = REG_FIELD(0x6101c, 5, 8),
.set_sp_on_en = REG_FIELD(0x6101c, 10, 10),
.dp_audio = REG_FIELD(0x6101c, 11, 11),
.dp_staffing_en = REG_FIELD(0x6101c, 12, 12),
.dp_sp_b_hw_en = REG_FIELD(0x6101c, 13, 13),

.mute = REG_FIELD(0x610c8, 0, 0),
.as_sdp_cc = REG_FIELD(0x610c8, 1, 3),
.as_sdp_ct = REG_FIELD(0x610c8, 4, 7),
.aif_db4 = REG_FIELD(0x610c8, 8, 15),
.frequency = REG_FIELD(0x610c8, 16, 21),
.mst_index = REG_FIELD(0x610c8, 28, 29),
.dptx_index = REG_FIELD(0x610c8, 30, 31),

.soft_reset = REG_FIELD(0x1000, 31, 31),
.force_reset = REG_FIELD(0x1000, 30, 30),

.use_hw_chs = REG_FIELD(0x61038, 0, 0),
.use_hw_usr = REG_FIELD(0x61038, 1, 1),
.hw_chs_sel = REG_FIELD(0x61038, 2, 4),
.hw_usr_sel = REG_FIELD(0x61038, 5, 6),

.replace_vbit = REG_FIELD(0x610c0, 0, 0),
.vbit_stream = REG_FIELD(0x610c0, 1, 1),

.legacy_en = REG_FIELD(0x1008, 0, 0),
.calc_en = REG_FIELD(0x61034, 0, 0),
.lsb_bits = REG_FIELD(0x61048, 0, 31),
.msb_bits = REG_FIELD(0x6104c, 0, 31),


.clk_name = (const char*[]) {
"pcnoc-sway-clk",
"audio-core",
Expand Down

0 comments on commit 2ad63dc

Please sign in to comment.