Skip to content

Commit 478fc2f

Browse files
committed
ASoC/soundwire: add initial support for SDCA
Merge series from Bard Liao <yung-chuan.liao@linux.intel.com>: We need to get rt712 version by reading SDCA version and functions. This patch series adds initial support for SDCA and add a helper to tell if the codec is RT712_VB. This series may go via the ASoC tree with Vinod's Acked-by tag. Bard Liao (1): soundwire: sdw_intel: include linux/acpi.h Pierre-Louis Bossart (10): ASoC/soundwire: remove sdw_slave_extended_id ASoC: SDCA: add initial module soundwire: slave: lookup SDCA version and functions ASoC: SDCA: add quirk function for RT712_VB match ASoC: rt712-sdca: detect the SMART_MIC function during the probe stage ASoC: soc-acpi: introduce new 'machine check' callback ASoC: sdw_utils: add SmartMic DAI for RT712 VB ASoC: sdw_utils: add SmartMic DAI for RT713 VB ASoC: Intel: soc-acpi: add is_device_rt712_vb() helper ASoC: SOF: Intel: hda: use machine_check() for SoundWire drivers/soundwire/Kconfig | 1 + drivers/soundwire/amd_init.c | 12 +- drivers/soundwire/intel_init.c | 13 +- drivers/soundwire/slave.c | 14 ++ include/linux/soundwire/sdw.h | 9 +- include/linux/soundwire/sdw_amd.h | 7 +- include/linux/soundwire/sdw_intel.h | 8 +- include/sound/sdca.h | 62 +++++++ include/sound/sdca_function.h | 55 ++++++ include/sound/soc-acpi.h | 8 +- sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/amd/ps/pci-ps.c | 3 +- sound/soc/codecs/rt712-sdca-sdw.c | 1 + sound/soc/codecs/rt712-sdca.c | 38 +++- sound/soc/codecs/rt712-sdca.h | 1 + sound/soc/intel/Kconfig | 5 + sound/soc/intel/common/Makefile | 3 + .../intel/common/soc-acpi-intel-mtl-match.c | 51 ++++++ .../intel/common/soc-acpi-intel-sdca-quirks.c | 42 +++++ .../intel/common/soc-acpi-intel-sdca-quirks.h | 14 ++ sound/soc/sdca/Kconfig | 11 ++ sound/soc/sdca/Makefile | 5 + sound/soc/sdca/sdca_device.c | 67 +++++++ sound/soc/sdca/sdca_functions.c | 173 ++++++++++++++++++ sound/soc/sdw_utils/soc_sdw_utils.c | 18 +- sound/soc/soc-acpi.c | 30 +-- sound/soc/sof/amd/acp-common.c | 3 +- sound/soc/sof/intel/hda.c | 19 +- 29 files changed, 610 insertions(+), 65 deletions(-) create mode 100644 include/sound/sdca.h create mode 100644 include/sound/sdca_function.h create mode 100644 sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c create mode 100644 sound/soc/intel/common/soc-acpi-intel-sdca-quirks.h create mode 100644 sound/soc/sdca/Kconfig create mode 100644 sound/soc/sdca/Makefile create mode 100644 sound/soc/sdca/sdca_device.c create mode 100644 sound/soc/sdca/sdca_functions.c -- 2.43.0
2 parents 42fb516 + e92edcf commit 478fc2f

29 files changed

Lines changed: 610 additions & 65 deletions

drivers/soundwire/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
menuconfig SOUNDWIRE
77
tristate "SoundWire support"
88
depends on ACPI || OF
9+
depends on SND_SOC_SDCA_OPTIONAL
910
help
1011
SoundWire is a 2-Pin interface with data and clock line ratified
1112
by the MIPI Alliance. SoundWire is used for transporting data

drivers/soundwire/amd_init.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ EXPORT_SYMBOL_NS(sdw_amd_probe, SOUNDWIRE_AMD_INIT);
177177
void sdw_amd_exit(struct sdw_amd_ctx *ctx)
178178
{
179179
sdw_amd_cleanup(ctx);
180-
kfree(ctx->ids);
180+
kfree(ctx->peripherals);
181181
kfree(ctx);
182182
}
183183
EXPORT_SYMBOL_NS(sdw_amd_exit, SOUNDWIRE_AMD_INIT);
@@ -204,19 +204,19 @@ int sdw_amd_get_slave_info(struct sdw_amd_ctx *ctx)
204204
num_slaves++;
205205
}
206206

207-
ctx->ids = kcalloc(num_slaves, sizeof(*ctx->ids), GFP_KERNEL);
208-
if (!ctx->ids)
207+
ctx->peripherals = kmalloc(struct_size(ctx->peripherals, array, num_slaves),
208+
GFP_KERNEL);
209+
if (!ctx->peripherals)
209210
return -ENOMEM;
210-
ctx->num_slaves = num_slaves;
211+
ctx->peripherals->num_peripherals = num_slaves;
211212
for (index = 0; index < ctx->count; index++) {
212213
if (!(ctx->link_mask & BIT(index)))
213214
continue;
214215
amd_manager = dev_get_drvdata(&ctx->pdev[index]->dev);
215216
if (amd_manager) {
216217
bus = &amd_manager->bus;
217218
list_for_each_entry(slave, &bus->slaves, node) {
218-
ctx->ids[i].id = slave->id;
219-
ctx->ids[i].link_id = bus->link_id;
219+
ctx->peripherals->array[i] = slave;
220220
i++;
221221
}
222222
}

drivers/soundwire/intel_init.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,17 +252,16 @@ static struct sdw_intel_ctx
252252
num_slaves++;
253253
}
254254

255-
ctx->ids = kcalloc(num_slaves, sizeof(*ctx->ids), GFP_KERNEL);
256-
if (!ctx->ids)
255+
ctx->peripherals = kmalloc(struct_size(ctx->peripherals, array, num_slaves),
256+
GFP_KERNEL);
257+
if (!ctx->peripherals)
257258
goto err;
258-
259-
ctx->num_slaves = num_slaves;
259+
ctx->peripherals->num_peripherals = num_slaves;
260260
i = 0;
261261
list_for_each_entry(link, &ctx->link_list, list) {
262262
bus = &link->cdns->bus;
263263
list_for_each_entry(slave, &bus->slaves, node) {
264-
ctx->ids[i].id = slave->id;
265-
ctx->ids[i].link_id = bus->link_id;
264+
ctx->peripherals->array[i] = slave;
266265
i++;
267266
}
268267
}
@@ -371,7 +370,7 @@ void sdw_intel_exit(struct sdw_intel_ctx *ctx)
371370
}
372371

373372
sdw_intel_cleanup(ctx);
374-
kfree(ctx->ids);
373+
kfree(ctx->peripherals);
375374
kfree(ctx->ldev);
376375
kfree(ctx);
377376
}

drivers/soundwire/slave.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/of.h>
66
#include <linux/soundwire/sdw.h>
77
#include <linux/soundwire/sdw_type.h>
8+
#include <sound/sdca.h>
89
#include "bus.h"
910
#include "sysfs_local.h"
1011

@@ -70,6 +71,17 @@ int sdw_slave_add(struct sdw_bus *bus,
7071
list_add_tail(&slave->node, &bus->slaves);
7172
mutex_unlock(&bus->bus_lock);
7273

74+
/*
75+
* The Soundwire driver probe may optionally register SDCA
76+
* sub-devices, one per Function. This means the information
77+
* on the SDCA revision and the number/type of Functions need
78+
* to be extracted from platform firmware before the SoundWire
79+
* driver probe, and as a consequence before the SoundWire
80+
* device_register() below.
81+
*/
82+
sdca_lookup_interface_revision(slave);
83+
sdca_lookup_functions(slave);
84+
7385
ret = device_register(&slave->dev);
7486
if (ret) {
7587
dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);
@@ -259,3 +271,5 @@ int sdw_of_find_slaves(struct sdw_bus *bus)
259271

260272
return 0;
261273
}
274+
275+
MODULE_IMPORT_NS(SND_SOC_SDCA);

include/linux/soundwire/sdw.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/irqdomain.h>
1111
#include <linux/mod_devicetable.h>
1212
#include <linux/bitfield.h>
13+
#include <sound/sdca.h>
1314

1415
struct sdw_bus;
1516
struct sdw_slave;
@@ -488,9 +489,9 @@ struct sdw_slave_id {
488489
__u8 sdw_version:4;
489490
};
490491

491-
struct sdw_extended_slave_id {
492-
int link_id;
493-
struct sdw_slave_id id;
492+
struct sdw_peripherals {
493+
int num_peripherals;
494+
struct sdw_slave *array[];
494495
};
495496

496497
/*
@@ -663,6 +664,7 @@ struct sdw_slave_ops {
663664
* @is_mockup_device: status flag used to squelch errors in the command/control
664665
* protocol for SoundWire mockup devices
665666
* @sdw_dev_lock: mutex used to protect callbacks/remove races
667+
* @sdca_data: structure containing all device data for SDCA helpers
666668
*/
667669
struct sdw_slave {
668670
struct sdw_slave_id id;
@@ -686,6 +688,7 @@ struct sdw_slave {
686688
bool first_interrupt_done;
687689
bool is_mockup_device;
688690
struct mutex sdw_dev_lock; /* protect callbacks/remove races */
691+
struct sdca_device_data sdca_data;
689692
};
690693

691694
#define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev)

include/linux/soundwire/sdw_amd.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,16 @@ struct sdw_amd_acpi_info {
115115
* struct sdw_amd_ctx - context allocated by the controller driver probe
116116
*
117117
* @count: link count
118-
* @num_slaves: total number of devices exposed across all enabled links
119118
* @link_mask: bit-wise mask listing SoundWire links reported by the
120119
* Controller
121-
* @ids: array of slave_id, representing Slaves exposed across all enabled
122-
* links
123120
* @pdev: platform device structure
121+
* @peripherals: array representing Peripherals exposed across all enabled links
124122
*/
125123
struct sdw_amd_ctx {
126124
int count;
127-
int num_slaves;
128125
u32 link_mask;
129-
struct sdw_extended_slave_id *ids;
130126
struct platform_device *pdev[AMD_SDW_MAX_MANAGER_COUNT];
127+
struct sdw_peripherals *peripherals;
131128
};
132129

133130
/**

include/linux/soundwire/sdw_intel.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#ifndef __SDW_INTEL_H
55
#define __SDW_INTEL_H
66

7+
#include <linux/acpi.h>
78
#include <linux/irqreturn.h>
89
#include <linux/soundwire/sdw.h>
910

@@ -286,31 +287,28 @@ struct hdac_bus;
286287
* hardware capabilities after all power dependencies are settled.
287288
* @link_mask: bit-wise mask listing SoundWire links reported by the
288289
* Controller
289-
* @num_slaves: total number of devices exposed across all enabled links
290290
* @handle: ACPI parent handle
291291
* @ldev: information for each link (controller-specific and kept
292292
* opaque here)
293-
* @ids: array of slave_id, representing Slaves exposed across all enabled
294-
* links
295293
* @link_list: list to handle interrupts across all links
296294
* @shim_lock: mutex to handle concurrent rmw access to shared SHIM registers.
297295
* @shim_mask: flags to track initialization of SHIM shared registers
298296
* @shim_base: sdw shim base.
299297
* @alh_base: sdw alh base.
298+
* @peripherals: array representing Peripherals exposed across all enabled links
300299
*/
301300
struct sdw_intel_ctx {
302301
int count;
303302
void __iomem *mmio_base;
304303
u32 link_mask;
305-
int num_slaves;
306304
acpi_handle handle;
307305
struct sdw_intel_link_dev **ldev;
308-
struct sdw_extended_slave_id *ids;
309306
struct list_head link_list;
310307
struct mutex shim_lock; /* lock for access to shared SHIM registers */
311308
u32 shim_mask;
312309
u32 shim_base;
313310
u32 alh_base;
311+
struct sdw_peripherals *peripherals;
314312
};
315313

316314
/**

include/sound/sdca.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2+
/*
3+
* The MIPI SDCA specification is available for public downloads at
4+
* https://www.mipi.org/mipi-sdca-v1-0-download
5+
*
6+
* Copyright(c) 2024 Intel Corporation
7+
*/
8+
9+
#ifndef __SDCA_H__
10+
#define __SDCA_H__
11+
12+
struct sdw_slave;
13+
14+
#define SDCA_MAX_FUNCTION_COUNT 8
15+
16+
/**
17+
* sdca_device_desc - short descriptor for an SDCA Function
18+
* @adr: ACPI address (used for SDCA register access)
19+
* @type: Function topology type
20+
* @name: human-readable string
21+
*/
22+
struct sdca_function_desc {
23+
u64 adr;
24+
u32 type;
25+
const char *name;
26+
};
27+
28+
/**
29+
* sdca_device_data - structure containing all SDCA related information
30+
* @sdca_interface_revision: value read from _DSD property, mainly to check
31+
* for changes between silicon versions
32+
* @num_functions: total number of supported SDCA functions. Invalid/unsupported
33+
* functions will be skipped.
34+
* @sdca_func: array of function descriptors
35+
*/
36+
struct sdca_device_data {
37+
u32 interface_revision;
38+
int num_functions;
39+
struct sdca_function_desc sdca_func[SDCA_MAX_FUNCTION_COUNT];
40+
};
41+
42+
enum sdca_quirk {
43+
SDCA_QUIRKS_RT712_VB,
44+
};
45+
46+
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
47+
48+
void sdca_lookup_functions(struct sdw_slave *slave);
49+
void sdca_lookup_interface_revision(struct sdw_slave *slave);
50+
bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk);
51+
52+
#else
53+
54+
static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
55+
static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
56+
static inline bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
57+
{
58+
return false;
59+
}
60+
#endif
61+
62+
#endif

include/sound/sdca_function.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2+
/*
3+
* The MIPI SDCA specification is available for public downloads at
4+
* https://www.mipi.org/mipi-sdca-v1-0-download
5+
*
6+
* Copyright(c) 2024 Intel Corporation
7+
*/
8+
9+
#ifndef __SDCA_FUNCTION_H__
10+
#define __SDCA_FUNCTION_H__
11+
12+
/*
13+
* SDCA Function Types from SDCA specification v1.0a Section 5.1.2
14+
* all Function types not described are reserved
15+
* Note that SIMPLE_AMP, SIMPLE_MIC and SIMPLE_JACK Function Types
16+
* are NOT defined in SDCA 1.0a, but they were defined in earlier
17+
* drafts and are planned for 1.1.
18+
*/
19+
20+
enum sdca_function_type {
21+
SDCA_FUNCTION_TYPE_SMART_AMP = 0x01, /* Amplifier with protection features */
22+
SDCA_FUNCTION_TYPE_SIMPLE_AMP = 0x02, /* subset of SmartAmp */
23+
SDCA_FUNCTION_TYPE_SMART_MIC = 0x03, /* Smart microphone with acoustic triggers */
24+
SDCA_FUNCTION_TYPE_SIMPLE_MIC = 0x04, /* subset of SmartMic */
25+
SDCA_FUNCTION_TYPE_SPEAKER_MIC = 0x05, /* Combination of SmartMic and SmartAmp */
26+
SDCA_FUNCTION_TYPE_UAJ = 0x06, /* 3.5mm Universal Audio jack */
27+
SDCA_FUNCTION_TYPE_RJ = 0x07, /* Retaskable jack */
28+
SDCA_FUNCTION_TYPE_SIMPLE_JACK = 0x08, /* Subset of UAJ */
29+
SDCA_FUNCTION_TYPE_HID = 0x0A, /* Human Interface Device, for e.g. buttons */
30+
SDCA_FUNCTION_TYPE_IMP_DEF = 0x1F, /* Implementation-defined function */
31+
};
32+
33+
/* Human-readable names used for kernel logs and Function device registration/bind */
34+
#define SDCA_FUNCTION_TYPE_SMART_AMP_NAME "SmartAmp"
35+
#define SDCA_FUNCTION_TYPE_SIMPLE_AMP_NAME "SimpleAmp"
36+
#define SDCA_FUNCTION_TYPE_SMART_MIC_NAME "SmartMic"
37+
#define SDCA_FUNCTION_TYPE_SIMPLE_MIC_NAME "SimpleMic"
38+
#define SDCA_FUNCTION_TYPE_SPEAKER_MIC_NAME "SpeakerMic"
39+
#define SDCA_FUNCTION_TYPE_UAJ_NAME "UAJ"
40+
#define SDCA_FUNCTION_TYPE_RJ_NAME "RJ"
41+
#define SDCA_FUNCTION_TYPE_SIMPLE_NAME "SimpleJack"
42+
#define SDCA_FUNCTION_TYPE_HID_NAME "HID"
43+
44+
enum sdca_entity0_controls {
45+
SDCA_CONTROL_ENTITY_0_COMMIT_GROUP_MASK = 0x01,
46+
SDCA_CONTROL_ENTITY_0_INTSTAT_CLEAR = 0x02,
47+
SDCA_CONTROL_ENTITY_0_INT_ENABLE = 0x03,
48+
SDCA_CONTROL_ENTITY_0_FUNCTION_SDCA_VERSION = 0x04,
49+
SDCA_CONTROL_ENTITY_0_FUNCTION_TOPOLOGY = 0x05,
50+
SDCA_CONTROL_ENTITY_0_FUNCTION_MANUFACTURER_ID = 0x06,
51+
SDCA_CONTROL_ENTITY_0_FUNCTION_ID = 0x07,
52+
SDCA_CONTROL_ENTITY_0_FUNCTION_VERSION = 0x08
53+
};
54+
55+
#endif

include/sound/soc-acpi.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ struct snd_soc_acpi_link_adr {
185185
* ACPI ID alone is not sufficient, wrong or misleading
186186
* @quirk_data: data used to uniquely identify a machine, usually a list of
187187
* audio codecs whose presence if checked with ACPI
188+
* @machine_check: pointer to quirk function. The functionality is similar to
189+
* the use of @machine_quirk, except that the return value is a boolean: the intent
190+
* is to skip a machine if the additional hardware/firmware verification invalidates
191+
* the initial selection in the snd_soc_acpi_mach table.
188192
* @pdata: intended for platform data or machine specific-ops. This structure
189193
* is not constant since this field may be updated at run-time
190194
* @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
@@ -203,6 +207,7 @@ struct snd_soc_acpi_mach {
203207
const char *board;
204208
struct snd_soc_acpi_mach * (*machine_quirk)(void *arg);
205209
const void *quirk_data;
210+
bool (*machine_check)(void *arg);
206211
void *pdata;
207212
struct snd_soc_acpi_mach_params mach_params;
208213
const char *sof_tplg_filename;
@@ -233,7 +238,6 @@ static inline bool snd_soc_acpi_sof_parent(struct device *dev)
233238

234239
bool snd_soc_acpi_sdw_link_slaves_found(struct device *dev,
235240
const struct snd_soc_acpi_link_adr *link,
236-
struct sdw_extended_slave_id *ids,
237-
int num_slaves);
241+
struct sdw_peripherals *peripherals);
238242

239243
#endif

0 commit comments

Comments
 (0)