soc: soundwire: Update ssp period for fractional sample rates

Frame sync for fractional sample rates is different. Update
ssp period based on frame sync of fractional sample rate
for synchronization of the data channels.

Change-Id: I25eaa5195abcdfad54cfed09beb0abe5aff2499a
Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org>
This commit is contained in:
Sudheer Papothi
2019-11-15 23:06:41 +05:30
parent edc7d1364c
commit 8a8b12b245
2 changed files with 45 additions and 3 deletions

View File

@@ -26,6 +26,7 @@
#include "swr-mstr-ctrl.h"
#define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */
#define SWRM_FRAME_SYNC_SEL_NATIVE 3675 /* 3.675KHz */
#define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700
#define SWRM_SYS_SUSPEND_WAIT 1
@@ -882,6 +883,39 @@ static void enable_bank_switch(struct swr_mstr_ctrl *swrm, u8 bank,
SWRS_SCP_FRAME_CTRL_BANK(bank));
}
static void swrm_switch_frame_shape(struct swr_mstr_ctrl *swrm, int mclk_freq)
{
u8 bank;
u32 n_row, n_col;
u32 value = 0;
u32 row = 0, col = 0;
u8 ssp_period = 0;
int frame_sync = SWRM_FRAME_SYNC_SEL;
if (mclk_freq == MCLK_FREQ_NATIVE) {
n_col = SWR_MAX_COL;
col = SWRM_COL_16;
n_row = SWR_ROW_64;
row = SWRM_ROW_64;
frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE;
} else {
n_col = SWR_MIN_COL;
col = SWRM_COL_02;
n_row = SWR_ROW_50;
row = SWRM_ROW_50;
frame_sync = SWRM_FRAME_SYNC_SEL;
}
bank = get_inactive_bank_num(swrm);
ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync);
dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period);
value = ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
(n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
enable_bank_switch(swrm, bank, n_row, n_col);
}
static struct swr_port_info *swrm_get_port_req(struct swrm_mports *mport,
u8 slv_port, u8 dev_num)
{
@@ -1196,6 +1230,7 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK |
SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK);
u8 inactive_bank;
int frame_sync = SWRM_FRAME_SYNC_SEL;
if (!swrm) {
pr_err("%s: swrm is null\n", __func__);
@@ -1278,13 +1313,15 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
n_col ? 16 : 2);
n_row = SWR_ROW_64;
row = SWRM_ROW_64;
frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE;
} else {
dev_dbg(swrm->dev, "setting 50 x %d frameshape\n",
n_col ? 16 : 2);
n_row = SWR_ROW_50;
row = SWRM_ROW_50;
frame_sync = SWRM_FRAME_SYNC_SEL;
}
ssp_period = swrm_get_ssp_period(swrm, row, col, SWRM_FRAME_SYNC_SEL);
ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync);
dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period);
value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
@@ -2991,8 +3028,13 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
if (swrm->state == SWR_MSTR_DOWN)
dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n",
__func__, swrm->state);
else
else {
swrm->mclk_freq = *(int *)data;
swrm->bus_clk = swrm->mclk_freq;
swrm_switch_frame_shape(swrm,
swrm->bus_clk);
swrm_device_suspend(&pdev->dev);
}
/*
* add delay to ensure clk release happen
* if interrupt triggered for clk stop,

View File

@@ -25,7 +25,7 @@
#define SWR_ROW_48 0
#define SWR_ROW_50 1
#define SWR_ROW_64 2
#define SWR_ROW_64 3
#define SWR_MAX_COL 7 /* Cols = 16 */
#define SWR_MIN_COL 0 /* Cols = 2 */