Asoc: swr: Bus Driver changes to support new master driver

soundwire bus driver changes to support new soundwire
master driver for Talos/vipertooth.

Change-Id: I70e52a72edd80abc72ccb99b29b1a642debec257
Signed-off-by: Ramprasad Katkam <katkam@codeaurora.org>
This commit is contained in:
Ramprasad Katkam
2018-03-07 16:26:49 +05:30
parent 0bf1f57c59
commit e38aed40db
10 changed files with 136 additions and 70 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -71,6 +71,7 @@ struct swr_port {
u8 ch_mask;
u32 ch_rate;
u8 num_ch;
u8 port_type;
};
enum {
@@ -753,7 +754,8 @@ static const struct snd_kcontrol_new swr_dac_port[] = {
};
static int wsa881x_set_port(struct snd_soc_codec *codec, int port_idx,
u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate)
u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate,
u8 *port_type)
{
struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);
@@ -761,6 +763,7 @@ static int wsa881x_set_port(struct snd_soc_codec *codec, int port_idx,
*num_ch = wsa881x->port[port_idx].num_ch;
*ch_mask = wsa881x->port[port_idx].ch_mask;
*ch_rate = wsa881x->port[port_idx].ch_rate;
*port_type = wsa881x->port[port_idx].port_type;
return 0;
}
@@ -773,6 +776,7 @@ static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
u8 num_ch[WSA881X_MAX_SWR_PORTS];
u8 ch_mask[WSA881X_MAX_SWR_PORTS];
u32 ch_rate[WSA881X_MAX_SWR_PORTS];
u8 port_type[WSA881X_MAX_SWR_PORTS];
u8 num_port = 0;
dev_dbg(codec->dev, "%s: event %d name %s\n", __func__,
@@ -784,53 +788,69 @@ static int wsa881x_enable_swr_dac_port(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_PRE_PMU:
wsa881x_set_port(codec, SWR_DAC_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port]);
&ch_mask[num_port], &ch_rate[num_port],
&port_type[num_port]);
++num_port;
if (wsa881x->comp_enable) {
wsa881x_set_port(codec, SWR_COMP_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port]);
&ch_mask[num_port], &ch_rate[num_port],
&port_type[num_port]);
++num_port;
}
if (wsa881x->boost_enable) {
wsa881x_set_port(codec, SWR_BOOST_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port]);
&ch_mask[num_port], &ch_rate[num_port],
&port_type[num_port]);
++num_port;
}
if (wsa881x->visense_enable) {
wsa881x_set_port(codec, SWR_VISENSE_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port]);
&ch_mask[num_port], &ch_rate[num_port],
&port_type[num_port]);
++num_port;
}
swr_connect_port(wsa881x->swr_slave, &port_id[0], num_port,
&ch_mask[0], &ch_rate[0], &num_ch[0]);
&ch_mask[0], &ch_rate[0], &num_ch[0],
&port_type[0]);
break;
case SND_SOC_DAPM_POST_PMU:
break;
case SND_SOC_DAPM_PRE_PMD:
break;
case SND_SOC_DAPM_POST_PMD:
port_id[num_port] = wsa881x->port[SWR_DAC_PORT].port_id;
wsa881x_set_port(codec, SWR_DAC_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port],
&port_type[num_port]);
++num_port;
if (wsa881x->comp_enable) {
port_id[num_port] =
wsa881x->port[SWR_COMP_PORT].port_id;
wsa881x_set_port(codec, SWR_COMP_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port],
&port_type[num_port]);
++num_port;
}
if (wsa881x->boost_enable) {
port_id[num_port] =
wsa881x->port[SWR_BOOST_PORT].port_id;
wsa881x_set_port(codec, SWR_BOOST_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port],
&port_type[num_port]);
++num_port;
}
if (wsa881x->visense_enable) {
port_id[num_port] =
wsa881x->port[SWR_VISENSE_PORT].port_id;
wsa881x_set_port(codec, SWR_VISENSE_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port],
&port_type[num_port]);
++num_port;
}
swr_disconnect_port(wsa881x->swr_slave, &port_id[0], num_port);
swr_disconnect_port(wsa881x->swr_slave, &port_id[0], num_port,
&ch_mask[0], &port_type[0]);
break;
default:
break;
@@ -1001,7 +1021,8 @@ static const struct snd_soc_dapm_route wsa881x_audio_map[] = {
};
int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port,
unsigned int *ch_mask, unsigned int *ch_rate)
unsigned int *ch_mask, unsigned int *ch_rate,
u8 *port_type)
{
struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);
int i;
@@ -1018,6 +1039,8 @@ int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, u8 num_port,
wsa881x->port[i].ch_mask = ch_mask[i];
wsa881x->port[i].ch_rate = ch_rate[i];
wsa881x->port[i].num_ch = __sw_hweight8(ch_mask[i]);
if (port_type)
wsa881x->port[i].port_type = port_type[i];
}
return 0;
}

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,7 +23,7 @@
#if IS_ENABLED(CONFIG_SND_SOC_WSA881X)
extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port,
u8 num_port, unsigned int *ch_mask,
unsigned int *ch_rate);
unsigned int *ch_rate, u8 *port_type);
extern const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE];
extern struct regmap_config wsa881x_regmap_config;
@@ -35,7 +35,7 @@ void wsa881x_regmap_defaults(struct regmap *regmap, u8 version);
#else
extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port,
u8 num_port, unsigned int *ch_mask,
unsigned int *ch_rate)
unsigned int *ch_rate, u8 *port_type);
{
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -6975,7 +6975,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component)
__func__, codec->component.name);
wsa881x_set_channel_map(codec, &spkleft_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0]);
&ch_rate[0], NULL);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
@@ -6985,7 +6985,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component)
__func__, codec->component.name);
wsa881x_set_channel_map(codec, &spkright_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0]);
&ch_rate[0], NULL);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");

View File

@@ -3075,7 +3075,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component)
__func__, codec->component.name);
wsa881x_set_channel_map(codec, &spkleft_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0]);
&ch_rate[0], NULL);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
@@ -3085,7 +3085,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component)
__func__, codec->component.name);
wsa881x_set_channel_map(codec, &spkright_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0]);
&ch_rate[0], NULL);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -6603,7 +6603,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component)
__func__, codec->component.name);
wsa881x_set_channel_map(codec, &spkleft_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0]);
&ch_rate[0], NULL);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
@@ -6613,7 +6613,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component)
__func__, codec->component.name);
wsa881x_set_channel_map(codec, &spkright_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0]);
&ch_rate[0], NULL);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");

View File

@@ -7126,7 +7126,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component)
__func__, codec->component.name);
wsa881x_set_channel_map(codec, &spkleft_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0]);
&ch_rate[0], NULL);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
@@ -7136,7 +7136,7 @@ static int msm_wsa881x_init(struct snd_soc_component *component)
__func__, codec->component.name);
wsa881x_set_channel_map(codec, &spkright_ports[0],
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
&ch_rate[0]);
&ch_rate[0], NULL);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,16 +38,24 @@ enum {
};
/*
* struct swr_port_info - represent soundwire frame shape
* @dev_id: logical device number of the soundwire slave device
* struct swr_port_info - represents new soundwire frame shape
* with full data ports
* @list: link with other soundwire port info nodes
* @dev_num: logical device number of the soundwire slave device
* @port_en: flag indicates whether the port is enabled
* @port_id: logical port number of the soundwire slave device
* @slave_port_id: logical port number of the soundwire slave device
* @offset1: sample offset indicating the offset of the channel
* from the start of the frame
* @offset2: channel offset indicating offset between to channels
* @hstart: start offset for subframe window.
* @hstop: start offset for subframe window.
* @master_port_id: logical port number of corresponding soundwire master device
* @blk_grp_count: grouping count for n.o of channels.
* @blk_pack_mode: packing mode for channels in each port.
* @sinterval: sample interval indicates spacing from one sample
* event to the next
* @ch_en: channels in a port that need to be enabled
* @ch_en: channels enabled in a port.
* @req_ch: channels requested to be enabled in a port.
* @num_ch: number of channels enabled in a port
* @ch_rate: sampling rate of the channel with which data will be
* transferred
@@ -56,13 +64,20 @@ enum {
* parameters.
*/
struct swr_port_info {
u8 dev_id;
u8 dev_num;
u8 port_en;
u8 port_id;
u8 slave_port_id;
u8 offset1;
u8 offset2;
u8 sinterval;
struct list_head list;
u8 master_port_id;
u8 hstart;
u8 hstop;
u8 blk_grp_count;
u8 blk_pack_mode;
u8 ch_en;
u8 req_ch;
u8 num_ch;
u32 ch_rate;
};
@@ -71,22 +86,24 @@ struct swr_port_info {
* struct swr_params - represent transfer of data from soundwire slave
* to soundwire master
* @tid: transaction ID to track each transaction
* @dev_id: logical device number of the soundwire slave device
* @dev_num: logical device number of the soundwire slave device
* @num_port: number of ports that needs to be configured
* @port_id: array of logical port numbers of the soundwire slave device
* @num_ch: array of number of channels enabled
* @ch_rate: array of sampling rate of different channels that need to
* be configured
* @ch_en: array of channels mask for all the ports
* @port_type: the required master port type
*/
struct swr_params {
u8 tid;
u8 dev_id;
u8 dev_num;
u8 num_port;
u8 port_id[SWR_MAX_DEV_PORT_NUM];
u8 num_ch[SWR_MAX_DEV_PORT_NUM];
u32 ch_rate[SWR_MAX_DEV_PORT_NUM];
u8 ch_en[SWR_MAX_DEV_PORT_NUM];
u8 port_type[SWR_MAX_DEV_PORT_NUM];
};
/*
@@ -127,6 +144,7 @@ struct swr_reg {
* @write: callback for soundwire slave register write
* @get_logical_dev_num: callback to get soundwire slave logical
* device number
* @port_en_mask: bit mask of active ports on soundwire master
*/
struct swr_master {
struct device dev;
@@ -151,8 +169,10 @@ struct swr_master {
const void *buf, size_t len);
int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id,
u8 *dev_num);
void (*slvdev_datapath_control)(struct swr_master *mstr, bool enable);
int (*slvdev_datapath_control)(struct swr_master *mstr, bool enable);
bool (*remove_from_group)(struct swr_master *mstr);
u16 port_en_mask;
};
static inline struct swr_master *to_swr_master(struct device *dev)
@@ -172,6 +192,8 @@ static inline struct swr_master *to_swr_master(struct device *dev)
* @addr: represents "ea-addr" which is unique-id of soundwire slave
* device
* @group_id: group id supported by the slave device
* @slave_irq: irq handle of slave to be invoked by master
* during slave interrupt
*/
struct swr_device {
char name[SOUNDWIRE_NAME_SIZE];
@@ -182,6 +204,7 @@ struct swr_device {
struct device dev;
unsigned long addr;
u8 group_id;
u8 slave_irq;
};
static inline struct swr_device *to_swr_device(struct device *dev)
@@ -277,10 +300,12 @@ extern int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg_addr,
const void *buf, size_t len);
extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port,
u8 *ch_mask, u32 *ch_rate, u8 *num_ch);
u8 *ch_mask, u32 *ch_rate, u8 *num_ch,
u8 *port_type);
extern int swr_disconnect_port(struct swr_device *dev,
u8 *port_id, u8 num_port);
u8 *port_id, u8 num_port, u8 *ch_mask,
u8 *port_type);
extern int swr_set_device_group(struct swr_device *swr_dev, u8 id);

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -268,6 +268,7 @@ int swr_slvdev_datapath_control(struct swr_device *dev, u8 dev_num,
bool enable)
{
struct swr_master *master;
int ret = 0;
if (!dev)
return -ENODEV;
@@ -287,9 +288,9 @@ int swr_slvdev_datapath_control(struct swr_device *dev, u8 dev_num,
}
if (master->slvdev_datapath_control)
master->slvdev_datapath_control(master, enable);
ret = master->slvdev_datapath_control(master, enable);
return 0;
return ret;
}
EXPORT_SYMBOL(swr_slvdev_datapath_control);
@@ -308,7 +309,7 @@ EXPORT_SYMBOL(swr_slvdev_datapath_control);
* and enable master and slave ports
*/
int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port,
u8 *ch_mask, u32 *ch_rate, u8 *num_ch)
u8 *ch_mask, u32 *ch_rate, u8 *num_ch, u8 *port_type)
{
u8 i = 0;
int ret = 0;
@@ -368,13 +369,14 @@ int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port,
mutex_unlock(&master->mlock);
txn->tid = i;
txn->dev_id = dev->dev_num;
txn->dev_num = dev->dev_num;
txn->num_port = num_port;
for (i = 0; i < num_port; i++) {
txn->port_id[i] = port_id[i];
txn->num_ch[i] = num_ch[i];
txn->ch_rate[i] = ch_rate[i];
txn->ch_en[i] = ch_mask[i];
txn->port_type[i] = port_type[i];
}
ret = master->connect_port(master, txn);
return ret;
@@ -391,7 +393,8 @@ EXPORT_SYMBOL(swr_connect_port);
* its ports. This API will call master disconnect_port callback function to
* disable master and slave port and (re)configure frame structure
*/
int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port)
int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port,
u8 *ch_mask, u8 *port_type)
{
u8 i = 0;
int ret;
@@ -445,10 +448,13 @@ int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port)
mutex_unlock(&master->mlock);
txn->tid = i;
txn->dev_id = dev->dev_num;
txn->dev_num = dev->dev_num;
txn->num_port = num_port;
for (i = 0; i < num_port; i++)
for (i = 0; i < num_port; i++) {
txn->port_id[i] = port_id[i];
txn->ch_en[i] = ch_mask[i];
txn->port_type[i] = port_type[i];
}
ret = master->disconnect_port(master, txn);
return ret;
}
@@ -855,13 +861,18 @@ int swr_register_master(struct swr_master *master)
int status = 0;
mutex_lock(&swr_lock);
id = of_alias_get_id(master->dev.of_node, "swr");
if (id >= 0)
master->bus_num = id;
id = idr_alloc(&master_idr, master, master->bus_num,
master->bus_num+1, GFP_KERNEL);
master->bus_num + 1, GFP_KERNEL);
mutex_unlock(&swr_lock);
if (id < 0)
return id;
master->bus_num = id;
master->bus_num = id;
/* Can't register until driver model init */
if (WARN_ON(!soundwire_type.p)) {
status = -EAGAIN;

View File

@@ -667,7 +667,7 @@ static struct swr_port_info *swrm_get_port(struct swr_master *master,
for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
port = &master->port[i];
if (port->port_id == port_id) {
if (port->slave_port_id == port_id) {
dev_dbg(&master->dev, "%s: port_id: %d, index: %d\n",
__func__, port_id, i);
return port;
@@ -688,7 +688,7 @@ static struct swr_port_info *swrm_get_avail_port(struct swr_master *master)
continue;
dev_dbg(&master->dev, "%s: port_id: %d, index: %d\n",
__func__, port->port_id, i);
__func__, port->slave_port_id, i);
return port;
}
@@ -703,7 +703,7 @@ static struct swr_port_info *swrm_get_enabled_port(struct swr_master *master,
for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
port = &master->port[i];
if ((port->port_id == port_id) && (port->port_en == true))
if ((port->slave_port_id == port_id) && (port->port_en == true))
break;
}
if (i == SWR_MSTR_PORT_LEN)
@@ -781,7 +781,7 @@ static void swrm_cleanup_disabled_data_ports(struct swr_master *master,
swrm->write(swrm->handle,
SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank),
value);
swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_id, 0x00,
swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_num, 0x00,
SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank));
dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n",
@@ -806,7 +806,7 @@ inc_loop:
__func__, port_disable_cnt, master->num_port);
}
static void swrm_slvdev_datapath_control(struct swr_master *master,
static int swrm_slvdev_datapath_control(struct swr_master *master,
bool enable)
{
u8 bank;
@@ -819,7 +819,7 @@ static void swrm_slvdev_datapath_control(struct swr_master *master,
if (!swrm) {
pr_err("%s: swrm is null\n", __func__);
return;
return 0;
}
bank = get_inactive_bank_num(swrm);
@@ -848,7 +848,7 @@ static void swrm_slvdev_datapath_control(struct swr_master *master,
* BROADCAST and disabled in GROUP_NONE
*/
if (master->num_port == 0)
return;
return 0;
}
value = swrm->read(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
@@ -875,6 +875,7 @@ static void swrm_slvdev_datapath_control(struct swr_master *master,
pm_runtime_mark_last_busy(&swrm->pdev->dev);
pm_runtime_put_autosuspend(&swrm->pdev->dev);
}
return 0;
}
static void swrm_apply_port_config(struct swr_master *master)
@@ -932,9 +933,9 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
if (!port)
continue;
port_type = mstr_port_type[mport->id];
if (!port->dev_id || (port->dev_id > master->num_dev)) {
if (!port->dev_num || (port->dev_num > master->num_dev)) {
dev_dbg(swrm->dev, "%s: invalid device id = %d\n",
__func__, port->dev_id);
__func__, port->dev_num);
continue;
}
value = ((port->ch_en)
@@ -953,23 +954,23 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
(SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank)), value);
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(port->ch_en, port->dev_id, 0x00,
val[len++] = SWR_REG_VAL_PACK(port->ch_en, port->dev_num, 0x00,
SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank));
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(port->sinterval,
port->dev_id, 0x00,
port->dev_num, 0x00,
SWRS_DP_SAMPLE_CONTROL_1_BANK(port_type, bank));
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(port->offset1,
port->dev_id, 0x00,
port->dev_num, 0x00,
SWRS_DP_OFFSET_CONTROL_1_BANK(port_type, bank));
if (port_type != 0) {
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(port->offset2,
port->dev_id, 0x00,
port->dev_num, 0x00,
SWRS_DP_OFFSET_CONTROL_2_BANK(port_type,
bank));
}
@@ -1028,15 +1029,15 @@ static int swrm_connect_port(struct swr_master *master,
goto port_fail;
}
list_add(&mport->list, &swrm->mport_list);
port->dev_id = portinfo->dev_id;
port->port_id = portinfo->port_id[i];
port->dev_num = portinfo->dev_num;
port->slave_port_id = portinfo->port_id[i];
port->num_ch = portinfo->num_ch[i];
port->ch_rate = portinfo->ch_rate[i];
port->ch_en = portinfo->ch_en[i];
port->port_en = true;
dev_dbg(&master->dev,
"%s: mstr port %d, slv port %d ch_rate %d num_ch %d\n",
__func__, mport->id, port->port_id, port->ch_rate,
__func__, mport->id, port->slave_port_id, port->ch_rate,
port->num_ch);
}
master->num_port += portinfo->num_port;
@@ -1120,7 +1121,7 @@ static int swrm_disconnect_port(struct swr_master *master,
continue;
}
port_type = mstr_port_type[mport_id];
port->dev_id = portinfo->dev_id;
port->dev_num = portinfo->dev_num;
port->port_en = false;
port->ch_en = 0;
value = port->ch_en << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT;
@@ -1132,7 +1133,7 @@ static int swrm_disconnect_port(struct swr_master *master,
swrm->write(swrm->handle,
SWRM_DP_PORT_CTRL_BANK((mport_id+1), bank),
value);
swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_id, 0x00,
swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_num, 0x00,
SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank));
}

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -33,6 +33,7 @@
#define SWRM_COMP_PARAMS_AUTO_ENUM_SLAVES 0x00F00000
#define SWRM_COMP_PARAMS_DATA_LANES 0x07000000
#define SWRM_COMP_MASTER_ID (SWRM_BASE_ADDRESS+0x104)
#define SWRM_INTERRUPT_STATUS (SWRM_BASE_ADDRESS+0x00000200)
#define SWRM_INTERRUPT_STATUS_RMSK 0x1FFFD
@@ -178,6 +179,11 @@
#define SWRM_DP_PORT_CTRL_OFFSET1_SHFT 0x08
#define SWRM_DP_PORT_CTRL_SAMPLE_INTERVAL 0x00
#define SWRM_DIN_DPn_PCM_PORT_CTRL(n) (SWRM_BASE_ADDRESS + \
0x00001054 + 0x100*n)
#define SWRM_MAX_REGISTER SWRM_DIN_DPn_PCM_PORT_CTRL(7)
/* Soundwire Slave Register definition */
#define SWRS_BASE_ADDRESS 0x00