Loading include/soc/soundwire.h +8 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ */ #ifndef _LINUX_SOUNDWIRE_H #ifndef _LINUX_SOUNDWIRE_H Loading @@ -10,6 +10,13 @@ #include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h> #include <linux/irqdomain.h> #include <linux/irqdomain.h> #define SWR_CLK_RATE_0P6MHZ 600000 #define SWR_CLK_RATE_1P2MHZ 1200000 #define SWR_CLK_RATE_2P4MHZ 2400000 #define SWR_CLK_RATE_4P8MHZ 4800000 #define SWR_CLK_RATE_9P6MHZ 9600000 #define SWR_CLK_RATE_11P2896MHZ 1128960 extern struct bus_type soundwire_type; extern struct bus_type soundwire_type; /* Soundwire supports max. of 8 channels per port */ /* Soundwire supports max. of 8 channels per port */ Loading include/soc/swr-wcd.h +2 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* /* * Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2015, 2017-2020 The Linux Foundation. All rights reserved. */ */ #ifndef _LINUX_SWR_WCD_H #ifndef _LINUX_SWR_WCD_H Loading Loading @@ -32,6 +32,7 @@ struct swr_mstr_port { }; }; #define MCLK_FREQ 9600000 #define MCLK_FREQ 9600000 #define MCLK_FREQ_LP 600000 #define MCLK_FREQ_NATIVE 11289600 #define MCLK_FREQ_NATIVE 11289600 #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ Loading soc/swr-mstr-ctrl.c +110 −12 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ */ #include <linux/irq.h> #include <linux/irq.h> Loading @@ -25,6 +25,8 @@ #include "swrm_registers.h" #include "swrm_registers.h" #include "swr-mstr-ctrl.h" #include "swr-mstr-ctrl.h" #define SWR_NUM_PORTS 4 /* TODO - Get this info from DT */ #define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */ #define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */ #define SWRM_FRAME_SYNC_SEL_NATIVE 3675 /* 3.675KHz */ #define SWRM_FRAME_SYNC_SEL_NATIVE 3675 /* 3.675KHz */ #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 Loading Loading @@ -94,6 +96,42 @@ static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm); static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq) { int clk_div = 0; u8 div_val = 0; if (!mclk_freq || !bus_clk_freq) return 0; clk_div = (mclk_freq / bus_clk_freq); switch (clk_div) { case 32: div_val = 5; break; case 16: div_val = 4; break; case 8: div_val = 3; break; case 4: div_val = 2; break; case 2: div_val = 1; break; case 1: default: div_val = 0; break; } return div_val; } static bool swrm_is_msm_variant(int val) static bool swrm_is_msm_variant(int val) { { return (val == SWRM_VERSION_1_3); return (val == SWRM_VERSION_1_3); Loading Loading @@ -955,6 +993,49 @@ static bool swrm_remove_from_group(struct swr_master *master) return is_removed; return is_removed; } } int swrm_get_clk_div_rate(int mclk_freq, int bus_clk_freq) { if (!bus_clk_freq) return mclk_freq; if (mclk_freq == SWR_CLK_RATE_9P6MHZ) { if (bus_clk_freq <= SWR_CLK_RATE_0P6MHZ) bus_clk_freq = SWR_CLK_RATE_0P6MHZ; else if (bus_clk_freq <= SWR_CLK_RATE_1P2MHZ) bus_clk_freq = SWR_CLK_RATE_1P2MHZ; else if (bus_clk_freq <= SWR_CLK_RATE_2P4MHZ) bus_clk_freq = SWR_CLK_RATE_2P4MHZ; else if(bus_clk_freq <= SWR_CLK_RATE_4P8MHZ) bus_clk_freq = SWR_CLK_RATE_4P8MHZ; else if(bus_clk_freq <= SWR_CLK_RATE_9P6MHZ) bus_clk_freq = SWR_CLK_RATE_9P6MHZ; } else if (mclk_freq == SWR_CLK_RATE_11P2896MHZ) bus_clk_freq = SWR_CLK_RATE_11P2896MHZ; return bus_clk_freq; } static int swrm_update_bus_clk(struct swr_mstr_ctrl *swrm) { int ret = 0; int agg_clk = 0; int i; for (i = 0; i < SWR_MSTR_PORT_LEN; i++) agg_clk += swrm->mport_cfg[i].ch_rate; if (agg_clk) swrm->bus_clk = swrm_get_clk_div_rate(swrm->mclk_freq, agg_clk); else swrm->bus_clk = swrm->mclk_freq; dev_dbg(swrm->dev, "%s: all_port_clk: %d, bus_clk: %d\n", __func__, agg_clk, swrm->bus_clk); return ret; } static void swrm_disable_ports(struct swr_master *master, static void swrm_disable_ports(struct swr_master *master, u8 bank) u8 bank) { { Loading Loading @@ -1221,13 +1302,15 @@ static void swrm_apply_port_config(struct swr_master *master) static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) { { u8 bank; u8 bank; u32 value, n_row, n_col; u32 value = 0, n_row = 0, n_col = 0; u32 row = 0, col = 0; u32 row = 0, col = 0; int bus_clk_div_factor; int ret; int ret; u8 ssp_period = 0; u8 ssp_period = 0; struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_BMSK | SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); u8 inactive_bank; u8 inactive_bank; int frame_sync = SWRM_FRAME_SYNC_SEL; int frame_sync = SWRM_FRAME_SYNC_SEL; Loading Loading @@ -1288,13 +1371,17 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) clear_bit(DISABLE_PENDING, &swrm->port_req_pending); clear_bit(DISABLE_PENDING, &swrm->port_req_pending); swrm_disable_ports(master, bank); swrm_disable_ports(master, bank); } } dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d\n", dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d freq %d\n", __func__, enable, swrm->num_cfg_devs); __func__, enable, swrm->num_cfg_devs, swrm->mclk_freq); if (enable) { if (enable) { /* set col = 16 */ /* set col = 16 */ n_col = SWR_MAX_COL; n_col = SWR_MAX_COL; col = SWRM_COL_16; col = SWRM_COL_16; if (swrm->bus_clk == MCLK_FREQ_LP) { n_col = SWR_MIN_COL; col = SWRM_COL_02; } } else { } else { /* /* * Do not change to col = 2 if there are still active ports * Do not change to col = 2 if there are still active ports Loading @@ -1309,25 +1396,26 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) } } /* Use default 50 * x, frame shape. Change based on mclk */ /* Use default 50 * x, frame shape. Change based on mclk */ if (swrm->mclk_freq == MCLK_FREQ_NATIVE) { if (swrm->mclk_freq == MCLK_FREQ_NATIVE) { dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", col); n_col ? 16 : 2); n_row = SWR_ROW_64; n_row = SWR_ROW_64; row = SWRM_ROW_64; row = SWRM_ROW_64; frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE; frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE; } else { } else { dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", col); n_col ? 16 : 2); n_row = SWR_ROW_50; n_row = SWR_ROW_50; row = SWRM_ROW_50; row = SWRM_ROW_50; frame_sync = SWRM_FRAME_SYNC_SEL; frame_sync = SWRM_FRAME_SYNC_SEL; } } ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync); ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync); dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); bus_clk_div_factor = swrm_get_clk_div(swrm->mclk_freq, swrm->bus_clk); dev_dbg(swrm->dev, "%s: ssp_period: %d, bus_clk_div:%d \n", __func__, ssp_period, bus_clk_div_factor); value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value &= (~mask); value &= (~mask); value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | (bus_clk_div_factor << SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_SHFT) | ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); Loading Loading @@ -1431,6 +1519,11 @@ static int swrm_connect_port(struct swr_master *master, mport->port_en = true; mport->port_en = true; mport->req_ch |= mstr_ch_msk; mport->req_ch |= mstr_ch_msk; master->port_en_mask |= (1 << mstr_port_id); master->port_en_mask |= (1 << mstr_port_id); if (swrm->clk_stop_mode0_supp && (mport->ch_rate < portinfo->ch_rate[i])) { mport->ch_rate = portinfo->ch_rate[i]; swrm_update_bus_clk(swrm); } } } master->num_port += portinfo->num_port; master->num_port += portinfo->num_port; set_bit(ENABLE_PENDING, &swrm->port_req_pending); set_bit(ENABLE_PENDING, &swrm->port_req_pending); Loading Loading @@ -1493,6 +1586,10 @@ static int swrm_disconnect_port(struct swr_master *master, } } port_req->req_ch &= ~portinfo->ch_en[i]; port_req->req_ch &= ~portinfo->ch_en[i]; mport->req_ch &= ~mstr_ch_mask; mport->req_ch &= ~mstr_ch_mask; if (swrm->clk_stop_mode0_supp && !mport->req_ch) { mport->ch_rate = 0; swrm_update_bus_clk(swrm); } } } master->num_port -= portinfo->num_port; master->num_port -= portinfo->num_port; set_bit(DISABLE_PENDING, &swrm->port_req_pending); set_bit(DISABLE_PENDING, &swrm->port_req_pending); Loading Loading @@ -2402,9 +2499,10 @@ static int swrm_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", __func__, "qcom,swr-num-dev"); __func__, "qcom,swr-num-dev"); } else { } else { if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) { if (swrm->num_dev > SWRM_NUM_AUTO_ENUM_SLAVES) { dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES); __func__, swrm->num_dev, SWRM_NUM_AUTO_ENUM_SLAVES); ret = -EINVAL; ret = -EINVAL; goto err_pdata_fail; goto err_pdata_fail; } } Loading soc/swr-mstr-ctrl.h +4 −3 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ */ #ifndef _SWR_WCD_CTRL_H #ifndef _SWR_WCD_CTRL_H Loading @@ -26,6 +26,7 @@ #define SWR_ROW_48 0 #define SWR_ROW_48 0 #define SWR_ROW_50 1 #define SWR_ROW_50 1 #define SWR_ROW_64 3 #define SWR_ROW_64 3 #define SWR_COL_04 1 /* Cols = 4 */ #define SWR_MAX_COL 7 /* Cols = 16 */ #define SWR_MAX_COL 7 /* Cols = 16 */ #define SWR_MIN_COL 0 /* Cols = 2 */ #define SWR_MIN_COL 0 /* Cols = 2 */ Loading @@ -42,7 +43,7 @@ #define SWR_MAX_CH_PER_PORT 8 #define SWR_MAX_CH_PER_PORT 8 #define SWR_MAX_SLAVE_DEVICES 11 #define SWRM_NUM_AUTO_ENUM_SLAVES 6 enum { enum { SWR_MSTR_PAUSE, SWR_MSTR_PAUSE, Loading Loading @@ -81,7 +82,6 @@ struct swrm_mports { bool port_en; bool port_en; u8 ch_en; u8 ch_en; u8 req_ch; u8 req_ch; u8 ch_rate; u8 offset1; u8 offset1; u8 offset2; u8 offset2; u8 sinterval; u8 sinterval; Loading @@ -91,6 +91,7 @@ struct swrm_mports { u8 blk_pack_mode; u8 blk_pack_mode; u8 word_length; u8 word_length; u8 lane_ctrl; u8 lane_ctrl; u32 ch_rate; }; }; struct swrm_port_type { struct swrm_port_type { Loading Loading
include/soc/soundwire.h +8 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ */ #ifndef _LINUX_SOUNDWIRE_H #ifndef _LINUX_SOUNDWIRE_H Loading @@ -10,6 +10,13 @@ #include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h> #include <linux/irqdomain.h> #include <linux/irqdomain.h> #define SWR_CLK_RATE_0P6MHZ 600000 #define SWR_CLK_RATE_1P2MHZ 1200000 #define SWR_CLK_RATE_2P4MHZ 2400000 #define SWR_CLK_RATE_4P8MHZ 4800000 #define SWR_CLK_RATE_9P6MHZ 9600000 #define SWR_CLK_RATE_11P2896MHZ 1128960 extern struct bus_type soundwire_type; extern struct bus_type soundwire_type; /* Soundwire supports max. of 8 channels per port */ /* Soundwire supports max. of 8 channels per port */ Loading
include/soc/swr-wcd.h +2 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* /* * Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2015, 2017-2020 The Linux Foundation. All rights reserved. */ */ #ifndef _LINUX_SWR_WCD_H #ifndef _LINUX_SWR_WCD_H Loading Loading @@ -32,6 +32,7 @@ struct swr_mstr_port { }; }; #define MCLK_FREQ 9600000 #define MCLK_FREQ 9600000 #define MCLK_FREQ_LP 600000 #define MCLK_FREQ_NATIVE 11289600 #define MCLK_FREQ_NATIVE 11289600 #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ #if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \ Loading
soc/swr-mstr-ctrl.c +110 −12 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ */ #include <linux/irq.h> #include <linux/irq.h> Loading @@ -25,6 +25,8 @@ #include "swrm_registers.h" #include "swrm_registers.h" #include "swr-mstr-ctrl.h" #include "swr-mstr-ctrl.h" #define SWR_NUM_PORTS 4 /* TODO - Get this info from DT */ #define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */ #define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */ #define SWRM_FRAME_SYNC_SEL_NATIVE 3675 /* 3.675KHz */ #define SWRM_FRAME_SYNC_SEL_NATIVE 3675 /* 3.675KHz */ #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 Loading Loading @@ -94,6 +96,42 @@ static void swrm_unlock_sleep(struct swr_mstr_ctrl *swrm); static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr); static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val); static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq) { int clk_div = 0; u8 div_val = 0; if (!mclk_freq || !bus_clk_freq) return 0; clk_div = (mclk_freq / bus_clk_freq); switch (clk_div) { case 32: div_val = 5; break; case 16: div_val = 4; break; case 8: div_val = 3; break; case 4: div_val = 2; break; case 2: div_val = 1; break; case 1: default: div_val = 0; break; } return div_val; } static bool swrm_is_msm_variant(int val) static bool swrm_is_msm_variant(int val) { { return (val == SWRM_VERSION_1_3); return (val == SWRM_VERSION_1_3); Loading Loading @@ -955,6 +993,49 @@ static bool swrm_remove_from_group(struct swr_master *master) return is_removed; return is_removed; } } int swrm_get_clk_div_rate(int mclk_freq, int bus_clk_freq) { if (!bus_clk_freq) return mclk_freq; if (mclk_freq == SWR_CLK_RATE_9P6MHZ) { if (bus_clk_freq <= SWR_CLK_RATE_0P6MHZ) bus_clk_freq = SWR_CLK_RATE_0P6MHZ; else if (bus_clk_freq <= SWR_CLK_RATE_1P2MHZ) bus_clk_freq = SWR_CLK_RATE_1P2MHZ; else if (bus_clk_freq <= SWR_CLK_RATE_2P4MHZ) bus_clk_freq = SWR_CLK_RATE_2P4MHZ; else if(bus_clk_freq <= SWR_CLK_RATE_4P8MHZ) bus_clk_freq = SWR_CLK_RATE_4P8MHZ; else if(bus_clk_freq <= SWR_CLK_RATE_9P6MHZ) bus_clk_freq = SWR_CLK_RATE_9P6MHZ; } else if (mclk_freq == SWR_CLK_RATE_11P2896MHZ) bus_clk_freq = SWR_CLK_RATE_11P2896MHZ; return bus_clk_freq; } static int swrm_update_bus_clk(struct swr_mstr_ctrl *swrm) { int ret = 0; int agg_clk = 0; int i; for (i = 0; i < SWR_MSTR_PORT_LEN; i++) agg_clk += swrm->mport_cfg[i].ch_rate; if (agg_clk) swrm->bus_clk = swrm_get_clk_div_rate(swrm->mclk_freq, agg_clk); else swrm->bus_clk = swrm->mclk_freq; dev_dbg(swrm->dev, "%s: all_port_clk: %d, bus_clk: %d\n", __func__, agg_clk, swrm->bus_clk); return ret; } static void swrm_disable_ports(struct swr_master *master, static void swrm_disable_ports(struct swr_master *master, u8 bank) u8 bank) { { Loading Loading @@ -1221,13 +1302,15 @@ static void swrm_apply_port_config(struct swr_master *master) static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) { { u8 bank; u8 bank; u32 value, n_row, n_col; u32 value = 0, n_row = 0, n_col = 0; u32 row = 0, col = 0; u32 row = 0, col = 0; int bus_clk_div_factor; int ret; int ret; u8 ssp_period = 0; u8 ssp_period = 0; struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master); int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_BMSK | SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); u8 inactive_bank; u8 inactive_bank; int frame_sync = SWRM_FRAME_SYNC_SEL; int frame_sync = SWRM_FRAME_SYNC_SEL; Loading Loading @@ -1288,13 +1371,17 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) clear_bit(DISABLE_PENDING, &swrm->port_req_pending); clear_bit(DISABLE_PENDING, &swrm->port_req_pending); swrm_disable_ports(master, bank); swrm_disable_ports(master, bank); } } dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d\n", dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d freq %d\n", __func__, enable, swrm->num_cfg_devs); __func__, enable, swrm->num_cfg_devs, swrm->mclk_freq); if (enable) { if (enable) { /* set col = 16 */ /* set col = 16 */ n_col = SWR_MAX_COL; n_col = SWR_MAX_COL; col = SWRM_COL_16; col = SWRM_COL_16; if (swrm->bus_clk == MCLK_FREQ_LP) { n_col = SWR_MIN_COL; col = SWRM_COL_02; } } else { } else { /* /* * Do not change to col = 2 if there are still active ports * Do not change to col = 2 if there are still active ports Loading @@ -1309,25 +1396,26 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) } } /* Use default 50 * x, frame shape. Change based on mclk */ /* Use default 50 * x, frame shape. Change based on mclk */ if (swrm->mclk_freq == MCLK_FREQ_NATIVE) { if (swrm->mclk_freq == MCLK_FREQ_NATIVE) { dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", col); n_col ? 16 : 2); n_row = SWR_ROW_64; n_row = SWR_ROW_64; row = SWRM_ROW_64; row = SWRM_ROW_64; frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE; frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE; } else { } else { dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", col); n_col ? 16 : 2); n_row = SWR_ROW_50; n_row = SWR_ROW_50; row = SWRM_ROW_50; row = SWRM_ROW_50; frame_sync = SWRM_FRAME_SYNC_SEL; frame_sync = SWRM_FRAME_SYNC_SEL; } } ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync); ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync); dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); bus_clk_div_factor = swrm_get_clk_div(swrm->mclk_freq, swrm->bus_clk); dev_dbg(swrm->dev, "%s: ssp_period: %d, bus_clk_div:%d \n", __func__, ssp_period, bus_clk_div_factor); value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); value &= (~mask); value &= (~mask); value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | (bus_clk_div_factor << SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_SHFT) | ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); Loading Loading @@ -1431,6 +1519,11 @@ static int swrm_connect_port(struct swr_master *master, mport->port_en = true; mport->port_en = true; mport->req_ch |= mstr_ch_msk; mport->req_ch |= mstr_ch_msk; master->port_en_mask |= (1 << mstr_port_id); master->port_en_mask |= (1 << mstr_port_id); if (swrm->clk_stop_mode0_supp && (mport->ch_rate < portinfo->ch_rate[i])) { mport->ch_rate = portinfo->ch_rate[i]; swrm_update_bus_clk(swrm); } } } master->num_port += portinfo->num_port; master->num_port += portinfo->num_port; set_bit(ENABLE_PENDING, &swrm->port_req_pending); set_bit(ENABLE_PENDING, &swrm->port_req_pending); Loading Loading @@ -1493,6 +1586,10 @@ static int swrm_disconnect_port(struct swr_master *master, } } port_req->req_ch &= ~portinfo->ch_en[i]; port_req->req_ch &= ~portinfo->ch_en[i]; mport->req_ch &= ~mstr_ch_mask; mport->req_ch &= ~mstr_ch_mask; if (swrm->clk_stop_mode0_supp && !mport->req_ch) { mport->ch_rate = 0; swrm_update_bus_clk(swrm); } } } master->num_port -= portinfo->num_port; master->num_port -= portinfo->num_port; set_bit(DISABLE_PENDING, &swrm->port_req_pending); set_bit(DISABLE_PENDING, &swrm->port_req_pending); Loading Loading @@ -2402,9 +2499,10 @@ static int swrm_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n", __func__, "qcom,swr-num-dev"); __func__, "qcom,swr-num-dev"); } else { } else { if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) { if (swrm->num_dev > SWRM_NUM_AUTO_ENUM_SLAVES) { dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n", __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES); __func__, swrm->num_dev, SWRM_NUM_AUTO_ENUM_SLAVES); ret = -EINVAL; ret = -EINVAL; goto err_pdata_fail; goto err_pdata_fail; } } Loading
soc/swr-mstr-ctrl.h +4 −3 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ */ #ifndef _SWR_WCD_CTRL_H #ifndef _SWR_WCD_CTRL_H Loading @@ -26,6 +26,7 @@ #define SWR_ROW_48 0 #define SWR_ROW_48 0 #define SWR_ROW_50 1 #define SWR_ROW_50 1 #define SWR_ROW_64 3 #define SWR_ROW_64 3 #define SWR_COL_04 1 /* Cols = 4 */ #define SWR_MAX_COL 7 /* Cols = 16 */ #define SWR_MAX_COL 7 /* Cols = 16 */ #define SWR_MIN_COL 0 /* Cols = 2 */ #define SWR_MIN_COL 0 /* Cols = 2 */ Loading @@ -42,7 +43,7 @@ #define SWR_MAX_CH_PER_PORT 8 #define SWR_MAX_CH_PER_PORT 8 #define SWR_MAX_SLAVE_DEVICES 11 #define SWRM_NUM_AUTO_ENUM_SLAVES 6 enum { enum { SWR_MSTR_PAUSE, SWR_MSTR_PAUSE, Loading Loading @@ -81,7 +82,6 @@ struct swrm_mports { bool port_en; bool port_en; u8 ch_en; u8 ch_en; u8 req_ch; u8 req_ch; u8 ch_rate; u8 offset1; u8 offset1; u8 offset2; u8 offset2; u8 sinterval; u8 sinterval; Loading @@ -91,6 +91,7 @@ struct swrm_mports { u8 blk_pack_mode; u8 blk_pack_mode; u8 word_length; u8 word_length; u8 lane_ctrl; u8 lane_ctrl; u32 ch_rate; }; }; struct swrm_port_type { struct swrm_port_type { Loading