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:
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
@@ -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");
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
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;
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user