mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-10-24 14:54:17 +10:00
soundwire updates for 6.16
Couple of small core changes for
- sdw_assign_device_num() logic simplification, using internal slave id
for irqs and optimizing computing of port params in specific stream
states
- Intel driver updates for ACE3+ microphone privacy status reporting
and enabling the status in HDA Intel driver
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmhBMgcACgkQfBQHDyUj
g0elyQ/8CqVJ4y6M1i2MgV+efGewspmvzt2WM9a82LA1wzSz668YxEaa50aplWwh
c2jqqL702zOsbH5gX+H31tDM0wuder9zn5qxQML4JCUbw/Ec7cQSUOeVse+v9Rbg
Fnb5MdxGXShSnOMjXA+H6JZ4Kt2TF759Q3wd4dmba0VBTIasVtyxW/qhFT997bJp
SziLBT38dEG3WOBf8I+4qPsDg6NfJtUsn8H3oMJBD4ng8/uTD1BR5GZp3YsyH5X8
2najQHVUFfGhWM8jLAniBZUBjeAMpGcKHjZxbKiizO3gGrCmetVao3PD1L0WYJP7
macqODWQ+C3JGuk8aEvrgQ5YZpls/DF1BJDxABmq9u+8IYPFYTKzQdA+YKOmQPGB
zli+F/GgBT5fCBIDb1UzZxGf5NC/mRN50eTPkd8ZnN2lA+OAsJs6Bnzh8c9BdMqY
9haG0kY6sgDQVy1f3SSDI+JwAOEecVi6x6jhXKWdc++JyXEL57L3njHeXNA7kd+K
esDQREVYXZ9Te17g1CL2/uQSWi/nMbPGQ0bPr0Y6CMzbMom1EguUE1FzPpIgct9K
+3qPs9h6g2zUaUW0CtY1e0WGWUEG/XzBw8OHvTem4320yiSVSnhgF7QTtA4N+nIz
cH870V3S8enqKU0V6HqDA5kwvfhh1SS8K1wnkRhFGDC3m/nhlRA=
=izGg
-----END PGP SIGNATURE-----
Merge tag 'soundwire-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire
Pull soundwire updates from Vinod Koul:
"A couple of small core changes and an Intel driver change:
- sdw_assign_device_num() logic simplification, using internal slave
id for irqs and optimizing computing of port params in specific
stream states
- Intel driver updates for ACE3+ microphone privacy status reporting
and enabling the status in HDA Intel driver"
* tag 'soundwire-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
soundwire: only compute port params in specific stream states
ASoC: SOF: Intel: hda: Set the mic_privacy flag for soundwire with ACE3+
soundwire: intel: Add awareness of ACE3+ microphone privacy
soundwire: bus: Add internal slave ID and use for IRQs
soundwire: bus: Simplify sdw_assign_device_num()
This commit is contained in:
commit
a479ebb269
@ -56,6 +56,8 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ida_init(&bus->slave_ida);
|
||||
|
||||
ret = sdw_master_device_add(bus, parent, fwnode);
|
||||
if (ret < 0) {
|
||||
dev_err(parent, "Failed to add master device at link %d\n",
|
||||
@ -751,41 +753,36 @@ err:
|
||||
static int sdw_assign_device_num(struct sdw_slave *slave)
|
||||
{
|
||||
struct sdw_bus *bus = slave->bus;
|
||||
int ret, dev_num;
|
||||
bool new_device = false;
|
||||
struct device *dev = bus->dev;
|
||||
int ret;
|
||||
|
||||
/* check first if device number is assigned, if so reuse that */
|
||||
if (!slave->dev_num) {
|
||||
if (!slave->dev_num_sticky) {
|
||||
int dev_num;
|
||||
|
||||
mutex_lock(&slave->bus->bus_lock);
|
||||
dev_num = sdw_get_device_num(slave);
|
||||
mutex_unlock(&slave->bus->bus_lock);
|
||||
if (dev_num < 0) {
|
||||
dev_err(bus->dev, "Get dev_num failed: %d\n",
|
||||
dev_num);
|
||||
dev_err(dev, "Get dev_num failed: %d\n", dev_num);
|
||||
return dev_num;
|
||||
}
|
||||
slave->dev_num = dev_num;
|
||||
|
||||
slave->dev_num_sticky = dev_num;
|
||||
new_device = true;
|
||||
} else {
|
||||
slave->dev_num = slave->dev_num_sticky;
|
||||
dev_dbg(dev, "Slave already registered, reusing dev_num: %d\n",
|
||||
slave->dev_num_sticky);
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_device)
|
||||
dev_dbg(bus->dev,
|
||||
"Slave already registered, reusing dev_num:%d\n",
|
||||
slave->dev_num);
|
||||
|
||||
/* Clear the slave->dev_num to transfer message on device 0 */
|
||||
dev_num = slave->dev_num;
|
||||
slave->dev_num = 0;
|
||||
|
||||
ret = sdw_write_no_pm(slave, SDW_SCP_DEVNUMBER, dev_num);
|
||||
ret = sdw_write_no_pm(slave, SDW_SCP_DEVNUMBER, slave->dev_num_sticky);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "Program device_num %d failed: %d\n",
|
||||
dev_num, ret);
|
||||
dev_err(dev, "Program device_num %d failed: %d\n",
|
||||
slave->dev_num_sticky, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -793,7 +790,7 @@ static int sdw_assign_device_num(struct sdw_slave *slave)
|
||||
slave->dev_num = slave->dev_num_sticky;
|
||||
|
||||
if (bus->ops && bus->ops->new_peripheral_assigned)
|
||||
bus->ops->new_peripheral_assigned(bus, slave, dev_num);
|
||||
bus->ops->new_peripheral_assigned(bus, slave, slave->dev_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -105,9 +105,17 @@ static int sdw_drv_probe(struct device *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ida_alloc_max(&slave->bus->slave_ida, SDW_FW_MAX_DEVICES, GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to allocated ID: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
slave->index = ret;
|
||||
|
||||
ret = drv->probe(slave, id);
|
||||
if (ret) {
|
||||
dev_pm_domain_detach(dev, false);
|
||||
ida_free(&slave->bus->slave_ida, slave->index);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -174,6 +182,8 @@ static int sdw_drv_remove(struct device *dev)
|
||||
|
||||
dev_pm_domain_detach(dev, false);
|
||||
|
||||
ida_free(&slave->bus->slave_ida, slave->index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -204,6 +204,13 @@ static void _sdw_compute_port_params(struct sdw_bus *bus,
|
||||
port_bo = 1;
|
||||
|
||||
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
|
||||
/*
|
||||
* Only runtimes with CONFIGURED, PREPARED, ENABLED, and DISABLED
|
||||
* states should be included in the bandwidth calculation.
|
||||
*/
|
||||
if (m_rt->stream->state > SDW_STREAM_DISABLED ||
|
||||
m_rt->stream->state < SDW_STREAM_CONFIGURED)
|
||||
continue;
|
||||
sdw_compute_master_ports(m_rt, ¶ms[i], &port_bo, hstop);
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ struct hdac_bus;
|
||||
* @shim_lock: mutex to handle access to shared SHIM registers
|
||||
* @shim_mask: global pointer to check SHIM register initialization
|
||||
* @clock_stop_quirks: mask defining requested behavior on pm_suspend
|
||||
* @mic_privacy: ACE version supports microphone privacy
|
||||
* @link_mask: global mask needed for power-up/down sequences
|
||||
* @cdns: Cadence master descriptor
|
||||
* @list: used to walk-through all masters exposed by the same controller
|
||||
@ -42,6 +43,7 @@ struct sdw_intel_link_res {
|
||||
struct mutex *shim_lock; /* protect shared registers */
|
||||
u32 *shim_mask;
|
||||
u32 clock_stop_quirks;
|
||||
bool mic_privacy;
|
||||
u32 link_mask;
|
||||
struct sdw_cdns *cdns;
|
||||
struct list_head list;
|
||||
|
||||
@ -76,6 +76,12 @@ static int intel_reg_show(struct seq_file *s_file, void *data)
|
||||
ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_IOCTL);
|
||||
ret += intel_sprintf(vs_s, false, buf, ret, SDW_SHIM2_INTEL_VS_ACTMCTL);
|
||||
|
||||
if (sdw->link_res->mic_privacy) {
|
||||
ret += scnprintf(buf + ret, RD_BUF - ret, "\nVS PVCCS\n");
|
||||
ret += intel_sprintf(vs_s, false, buf, ret,
|
||||
SDW_SHIM2_INTEL_VS_PVCCS);
|
||||
}
|
||||
|
||||
seq_printf(s_file, "%s", buf);
|
||||
kfree(buf);
|
||||
|
||||
|
||||
@ -77,6 +77,7 @@ static struct sdw_intel_link_dev *intel_link_dev_register(struct sdw_intel_res *
|
||||
link->shim = res->mmio_base + SDW_SHIM2_GENERIC_BASE(link_id);
|
||||
link->shim_vs = res->mmio_base + SDW_SHIM2_VS_BASE(link_id);
|
||||
link->shim_lock = res->eml_lock;
|
||||
link->mic_privacy = res->mic_privacy;
|
||||
}
|
||||
|
||||
link->ops = res->ops;
|
||||
|
||||
@ -31,7 +31,7 @@ int sdw_irq_create(struct sdw_bus *bus,
|
||||
{
|
||||
bus->irq_chip.name = dev_name(bus->dev);
|
||||
|
||||
bus->domain = irq_domain_create_linear(fwnode, SDW_MAX_DEVICES,
|
||||
bus->domain = irq_domain_create_linear(fwnode, SDW_FW_MAX_DEVICES,
|
||||
&sdw_domain_ops, bus);
|
||||
if (!bus->domain) {
|
||||
dev_err(bus->dev, "Failed to add IRQ domain\n");
|
||||
@ -50,12 +50,12 @@ static void sdw_irq_dispose_mapping(void *data)
|
||||
{
|
||||
struct sdw_slave *slave = data;
|
||||
|
||||
irq_dispose_mapping(irq_find_mapping(slave->bus->domain, slave->dev_num));
|
||||
irq_dispose_mapping(slave->irq);
|
||||
}
|
||||
|
||||
void sdw_irq_create_mapping(struct sdw_slave *slave)
|
||||
{
|
||||
slave->irq = irq_create_mapping(slave->bus->domain, slave->dev_num);
|
||||
slave->irq = irq_create_mapping(slave->bus->domain, slave->index);
|
||||
if (!slave->irq)
|
||||
dev_warn(&slave->dev, "Failed to map IRQ\n");
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <linux/bug.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/lockdep_types.h>
|
||||
@ -50,6 +51,7 @@ struct sdw_slave;
|
||||
|
||||
#define SDW_FRAME_CTRL_BITS 48
|
||||
#define SDW_MAX_DEVICES 11
|
||||
#define SDW_FW_MAX_DEVICES 16
|
||||
|
||||
#define SDW_MAX_PORTS 15
|
||||
#define SDW_VALID_PORT_RANGE(n) ((n) < SDW_MAX_PORTS && (n) >= 1)
|
||||
@ -630,6 +632,7 @@ struct sdw_slave_ops {
|
||||
* struct sdw_slave - SoundWire Slave
|
||||
* @id: MIPI device ID
|
||||
* @dev: Linux device
|
||||
* @index: internal ID for this slave
|
||||
* @irq: IRQ number
|
||||
* @status: Status reported by the Slave
|
||||
* @bus: Bus handle
|
||||
@ -661,6 +664,7 @@ struct sdw_slave_ops {
|
||||
struct sdw_slave {
|
||||
struct sdw_slave_id id;
|
||||
struct device dev;
|
||||
int index;
|
||||
int irq;
|
||||
enum sdw_slave_status status;
|
||||
struct sdw_bus *bus;
|
||||
@ -968,6 +972,7 @@ struct sdw_stream_runtime {
|
||||
* @md: Master device
|
||||
* @bus_lock_key: bus lock key associated to @bus_lock
|
||||
* @bus_lock: bus lock
|
||||
* @slave_ida: IDA for allocating internal slave IDs
|
||||
* @slaves: list of Slaves on this bus
|
||||
* @msg_lock_key: message lock key associated to @msg_lock
|
||||
* @msg_lock: message lock
|
||||
@ -1010,6 +1015,7 @@ struct sdw_bus {
|
||||
struct sdw_master_device *md;
|
||||
struct lock_class_key bus_lock_key;
|
||||
struct mutex bus_lock;
|
||||
struct ida slave_ida;
|
||||
struct list_head slaves;
|
||||
struct lock_class_key msg_lock_key;
|
||||
struct mutex msg_lock;
|
||||
|
||||
@ -189,6 +189,9 @@
|
||||
#define SDW_SHIM3_INTEL_VS_ACTMCTL_DOAISE2 BIT(14)
|
||||
#define SDW_SHIM3_INTEL_VS_ACTMCTL_CLDE BIT(15)
|
||||
|
||||
/* ACE3+ Mic privacy control and status register */
|
||||
#define SDW_SHIM2_INTEL_VS_PVCCS 0x10
|
||||
|
||||
/**
|
||||
* struct sdw_intel_stream_params_data: configuration passed during
|
||||
* the @params_stream callback, e.g. for interaction with DSP
|
||||
@ -331,6 +334,7 @@ struct sdw_intel_ctx {
|
||||
* @shim_base: sdw shim base.
|
||||
* @alh_base: sdw alh base.
|
||||
* @ext: extended HDaudio link support
|
||||
* @mic_privacy: ACE version supports microphone privacy
|
||||
* @hbus: hdac_bus pointer, needed for power management
|
||||
* @eml_lock: mutex protecting shared registers in the HDaudio multi-link
|
||||
* space
|
||||
@ -349,6 +353,7 @@ struct sdw_intel_res {
|
||||
u32 shim_base;
|
||||
u32 alh_base;
|
||||
bool ext;
|
||||
bool mic_privacy;
|
||||
struct hdac_bus *hbus;
|
||||
struct mutex *eml_lock;
|
||||
};
|
||||
|
||||
@ -192,6 +192,9 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev)
|
||||
res.ext = true;
|
||||
res.ops = &sdw_ace2x_callback;
|
||||
|
||||
/* ACE3+ supports microphone privacy */
|
||||
if (chip->hw_ip_version >= SOF_INTEL_ACE_3_0)
|
||||
res.mic_privacy = true;
|
||||
}
|
||||
res.irq = sdev->ipc_irq;
|
||||
res.handle = hdev->info.handle;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user