xref: /linux/drivers/soundwire/intel_init.c (revision 6d2c66695bf30355bacceb2b0635d3ddaf26cce4)
1d62a7d41SVinod Koul // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2d62a7d41SVinod Koul // Copyright(c) 2015-17 Intel Corporation.
3d62a7d41SVinod Koul 
4d62a7d41SVinod Koul /*
5d62a7d41SVinod Koul  * SDW Intel Init Routines
6d62a7d41SVinod Koul  *
7d62a7d41SVinod Koul  * Initializes and creates SDW devices based on ACPI and Hardware values
8d62a7d41SVinod Koul  */
9d62a7d41SVinod Koul 
10d62a7d41SVinod Koul #include <linux/acpi.h>
114abbd783SPaul Gortmaker #include <linux/export.h>
123fc40449SVinod Koul #include <linux/io.h>
134abbd783SPaul Gortmaker #include <linux/module.h>
14d62a7d41SVinod Koul #include <linux/platform_device.h>
15d62a7d41SVinod Koul #include <linux/soundwire/sdw_intel.h>
16b6109dd6SPierre-Louis Bossart #include "cadence_master.h"
17d62a7d41SVinod Koul #include "intel.h"
18d62a7d41SVinod Koul 
196f11586fSPierre-Louis Bossart #define SDW_LINK_TYPE		4 /* from Intel ACPI documentation */
20d62a7d41SVinod Koul #define SDW_MAX_LINKS		4
21d62a7d41SVinod Koul #define SDW_SHIM_LCAP		0x0
22d62a7d41SVinod Koul #define SDW_SHIM_BASE		0x2C000
23d62a7d41SVinod Koul #define SDW_ALH_BASE		0x2C800
24d62a7d41SVinod Koul #define SDW_LINK_BASE		0x30000
25d62a7d41SVinod Koul #define SDW_LINK_SIZE		0x10000
26d62a7d41SVinod Koul 
27*6d2c6669SPierre-Louis Bossart static int ctrl_link_mask;
28*6d2c6669SPierre-Louis Bossart module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444);
2950302fc7SPierre-Louis Bossart MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)");
3050302fc7SPierre-Louis Bossart 
31*6d2c6669SPierre-Louis Bossart static bool is_link_enabled(struct fwnode_handle *fw_node, int i)
32*6d2c6669SPierre-Louis Bossart {
33*6d2c6669SPierre-Louis Bossart 	struct fwnode_handle *link;
34*6d2c6669SPierre-Louis Bossart 	char name[32];
35*6d2c6669SPierre-Louis Bossart 	u32 quirk_mask = 0;
36*6d2c6669SPierre-Louis Bossart 
37*6d2c6669SPierre-Louis Bossart 	/* Find master handle */
38*6d2c6669SPierre-Louis Bossart 	snprintf(name, sizeof(name),
39*6d2c6669SPierre-Louis Bossart 		 "mipi-sdw-link-%d-subproperties", i);
40*6d2c6669SPierre-Louis Bossart 
41*6d2c6669SPierre-Louis Bossart 	link = fwnode_get_named_child_node(fw_node, name);
42*6d2c6669SPierre-Louis Bossart 	if (!link)
43*6d2c6669SPierre-Louis Bossart 		return false;
44*6d2c6669SPierre-Louis Bossart 
45*6d2c6669SPierre-Louis Bossart 	fwnode_property_read_u32(link,
46*6d2c6669SPierre-Louis Bossart 				 "intel-quirk-mask",
47*6d2c6669SPierre-Louis Bossart 				 &quirk_mask);
48*6d2c6669SPierre-Louis Bossart 
49*6d2c6669SPierre-Louis Bossart 	if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
50*6d2c6669SPierre-Louis Bossart 		return false;
51*6d2c6669SPierre-Louis Bossart 
52*6d2c6669SPierre-Louis Bossart 	return true;
53*6d2c6669SPierre-Louis Bossart }
54*6d2c6669SPierre-Louis Bossart 
55*6d2c6669SPierre-Louis Bossart static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
56d62a7d41SVinod Koul {
57f98f690fSPierre-Louis Bossart 	struct sdw_intel_link_res *link = ctx->links;
58*6d2c6669SPierre-Louis Bossart 	u32 link_mask;
59d62a7d41SVinod Koul 	int i;
60d62a7d41SVinod Koul 
61d62a7d41SVinod Koul 	if (!link)
62d62a7d41SVinod Koul 		return 0;
63d62a7d41SVinod Koul 
64*6d2c6669SPierre-Louis Bossart 	link_mask = ctx->link_mask;
65*6d2c6669SPierre-Louis Bossart 
66*6d2c6669SPierre-Louis Bossart 	for (i = 0; i < ctx->count; i++, link++) {
67*6d2c6669SPierre-Louis Bossart 		if (!(link_mask & BIT(i)))
68*6d2c6669SPierre-Louis Bossart 			continue;
69*6d2c6669SPierre-Louis Bossart 
70d62a7d41SVinod Koul 		if (link->pdev)
71d62a7d41SVinod Koul 			platform_device_unregister(link->pdev);
72d62a7d41SVinod Koul 	}
73d62a7d41SVinod Koul 
74d62a7d41SVinod Koul 	return 0;
75d62a7d41SVinod Koul }
76d62a7d41SVinod Koul 
77*6d2c6669SPierre-Louis Bossart static int
78*6d2c6669SPierre-Louis Bossart sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
79d62a7d41SVinod Koul {
80d62a7d41SVinod Koul 	struct acpi_device *adev;
81d62a7d41SVinod Koul 	int ret, i;
82d62a7d41SVinod Koul 	u8 count;
83d62a7d41SVinod Koul 
84*6d2c6669SPierre-Louis Bossart 	if (acpi_bus_get_device(info->handle, &adev))
85*6d2c6669SPierre-Louis Bossart 		return -EINVAL;
86d62a7d41SVinod Koul 
87d62a7d41SVinod Koul 	/* Found controller, find links supported */
88d62a7d41SVinod Koul 	count = 0;
89d62a7d41SVinod Koul 	ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
90d62a7d41SVinod Koul 					    "mipi-sdw-master-count", &count, 1);
91d62a7d41SVinod Koul 
92*6d2c6669SPierre-Louis Bossart 	/*
93*6d2c6669SPierre-Louis Bossart 	 * In theory we could check the number of links supported in
94*6d2c6669SPierre-Louis Bossart 	 * hardware, but in that step we cannot assume SoundWire IP is
95*6d2c6669SPierre-Louis Bossart 	 * powered.
96*6d2c6669SPierre-Louis Bossart 	 *
97*6d2c6669SPierre-Louis Bossart 	 * In addition, if the BIOS doesn't even provide this
98*6d2c6669SPierre-Louis Bossart 	 * 'master-count' property then all the inits based on link
99*6d2c6669SPierre-Louis Bossart 	 * masks will fail as well.
100*6d2c6669SPierre-Louis Bossart 	 *
101*6d2c6669SPierre-Louis Bossart 	 * We will check the hardware capabilities in the startup() step
102*6d2c6669SPierre-Louis Bossart 	 */
103*6d2c6669SPierre-Louis Bossart 
104d62a7d41SVinod Koul 	if (ret) {
105d62a7d41SVinod Koul 		dev_err(&adev->dev,
106d62a7d41SVinod Koul 			"Failed to read mipi-sdw-master-count: %d\n", ret);
107*6d2c6669SPierre-Louis Bossart 		return -EINVAL;
108d62a7d41SVinod Koul 	}
109d62a7d41SVinod Koul 
110d62a7d41SVinod Koul 	/* Check count is within bounds */
111d62a7d41SVinod Koul 	if (count > SDW_MAX_LINKS) {
112d62a7d41SVinod Koul 		dev_err(&adev->dev, "Link count %d exceeds max %d\n",
113d62a7d41SVinod Koul 			count, SDW_MAX_LINKS);
114*6d2c6669SPierre-Louis Bossart 		return -EINVAL;
1156f7219feSGuennadi Liakhovetski 	}
1166f7219feSGuennadi Liakhovetski 
1176f7219feSGuennadi Liakhovetski 	if (!count) {
118432732b8SPierre-Louis Bossart 		dev_warn(&adev->dev, "No SoundWire links detected\n");
119*6d2c6669SPierre-Louis Bossart 		return -EINVAL;
120*6d2c6669SPierre-Louis Bossart 	}
121*6d2c6669SPierre-Louis Bossart 	dev_dbg(&adev->dev, "ACPI reports %d SDW Link devices\n", count);
122*6d2c6669SPierre-Louis Bossart 
123*6d2c6669SPierre-Louis Bossart 	info->count = count;
124*6d2c6669SPierre-Louis Bossart 	info->link_mask = 0;
125*6d2c6669SPierre-Louis Bossart 
126*6d2c6669SPierre-Louis Bossart 	for (i = 0; i < count; i++) {
127*6d2c6669SPierre-Louis Bossart 		if (ctrl_link_mask && !(ctrl_link_mask & BIT(i))) {
128*6d2c6669SPierre-Louis Bossart 			dev_dbg(&adev->dev,
129*6d2c6669SPierre-Louis Bossart 				"Link %d masked, will not be enabled\n", i);
130*6d2c6669SPierre-Louis Bossart 			continue;
131d62a7d41SVinod Koul 		}
132d62a7d41SVinod Koul 
133*6d2c6669SPierre-Louis Bossart 		if (!is_link_enabled(acpi_fwnode_handle(adev), i)) {
134*6d2c6669SPierre-Louis Bossart 			dev_dbg(&adev->dev,
135*6d2c6669SPierre-Louis Bossart 				"Link %d not selected in firmware\n", i);
136*6d2c6669SPierre-Louis Bossart 			continue;
137*6d2c6669SPierre-Louis Bossart 		}
138*6d2c6669SPierre-Louis Bossart 
139*6d2c6669SPierre-Louis Bossart 		info->link_mask |= BIT(i);
140*6d2c6669SPierre-Louis Bossart 	}
141*6d2c6669SPierre-Louis Bossart 
142*6d2c6669SPierre-Louis Bossart 	return 0;
143*6d2c6669SPierre-Louis Bossart }
144*6d2c6669SPierre-Louis Bossart 
145*6d2c6669SPierre-Louis Bossart static struct sdw_intel_ctx
146*6d2c6669SPierre-Louis Bossart *sdw_intel_probe_controller(struct sdw_intel_res *res)
147*6d2c6669SPierre-Louis Bossart {
148*6d2c6669SPierre-Louis Bossart 	struct platform_device_info pdevinfo;
149*6d2c6669SPierre-Louis Bossart 	struct platform_device *pdev;
150*6d2c6669SPierre-Louis Bossart 	struct sdw_intel_link_res *link;
151*6d2c6669SPierre-Louis Bossart 	struct sdw_intel_ctx *ctx;
152*6d2c6669SPierre-Louis Bossart 	struct acpi_device *adev;
153*6d2c6669SPierre-Louis Bossart 	u32 link_mask;
154*6d2c6669SPierre-Louis Bossart 	int count;
155*6d2c6669SPierre-Louis Bossart 	int i;
156*6d2c6669SPierre-Louis Bossart 
157*6d2c6669SPierre-Louis Bossart 	if (!res)
158*6d2c6669SPierre-Louis Bossart 		return NULL;
159*6d2c6669SPierre-Louis Bossart 
160*6d2c6669SPierre-Louis Bossart 	if (acpi_bus_get_device(res->handle, &adev))
161*6d2c6669SPierre-Louis Bossart 		return NULL;
162*6d2c6669SPierre-Louis Bossart 
163*6d2c6669SPierre-Louis Bossart 	if (!res->count)
164*6d2c6669SPierre-Louis Bossart 		return NULL;
165*6d2c6669SPierre-Louis Bossart 
166*6d2c6669SPierre-Louis Bossart 	count = res->count;
167d62a7d41SVinod Koul 	dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);
168d62a7d41SVinod Koul 
169dd906cc6SPierre-Louis Bossart 	ctx = devm_kzalloc(&adev->dev, sizeof(*ctx), GFP_KERNEL);
170d62a7d41SVinod Koul 	if (!ctx)
171d62a7d41SVinod Koul 		return NULL;
172d62a7d41SVinod Koul 
173d62a7d41SVinod Koul 	ctx->count = count;
174dd906cc6SPierre-Louis Bossart 	ctx->links = devm_kcalloc(&adev->dev, ctx->count,
175dd906cc6SPierre-Louis Bossart 				  sizeof(*ctx->links), GFP_KERNEL);
176d62a7d41SVinod Koul 	if (!ctx->links)
177dd906cc6SPierre-Louis Bossart 		return NULL;
178d62a7d41SVinod Koul 
179*6d2c6669SPierre-Louis Bossart 	ctx->count = count;
180*6d2c6669SPierre-Louis Bossart 	ctx->mmio_base = res->mmio_base;
181*6d2c6669SPierre-Louis Bossart 	ctx->link_mask = res->link_mask;
182*6d2c6669SPierre-Louis Bossart 	ctx->handle = res->handle;
183*6d2c6669SPierre-Louis Bossart 
184d62a7d41SVinod Koul 	link = ctx->links;
185*6d2c6669SPierre-Louis Bossart 	link_mask = ctx->link_mask;
186d62a7d41SVinod Koul 
187d62a7d41SVinod Koul 	/* Create SDW Master devices */
188*6d2c6669SPierre-Louis Bossart 	for (i = 0; i < count; i++, link++) {
1899cd1c5a7SPierre-Louis Bossart 		if (!(link_mask & BIT(i))) {
19050302fc7SPierre-Louis Bossart 			dev_dbg(&adev->dev,
19150302fc7SPierre-Louis Bossart 				"Link %d masked, will not be enabled\n", i);
19250302fc7SPierre-Louis Bossart 			continue;
19350302fc7SPierre-Louis Bossart 		}
19450302fc7SPierre-Louis Bossart 
195*6d2c6669SPierre-Louis Bossart 		link->mmio_base = res->mmio_base;
196f98f690fSPierre-Louis Bossart 		link->registers = res->mmio_base + SDW_LINK_BASE
197d62a7d41SVinod Koul 			+ (SDW_LINK_SIZE * i);
198f98f690fSPierre-Louis Bossart 		link->shim = res->mmio_base + SDW_SHIM_BASE;
199f98f690fSPierre-Louis Bossart 		link->alh = res->mmio_base + SDW_ALH_BASE;
200d62a7d41SVinod Koul 
201f98f690fSPierre-Louis Bossart 		link->ops = res->ops;
2024b206d34SRander Wang 		link->dev = res->dev;
203c46302ecSVinod Koul 
204d62a7d41SVinod Koul 		memset(&pdevinfo, 0, sizeof(pdevinfo));
205d62a7d41SVinod Koul 
206d62a7d41SVinod Koul 		pdevinfo.parent = res->parent;
207*6d2c6669SPierre-Louis Bossart 		pdevinfo.name = "intel-sdw";
208d62a7d41SVinod Koul 		pdevinfo.id = i;
209d62a7d41SVinod Koul 		pdevinfo.fwnode = acpi_fwnode_handle(adev);
2104ab34412SPierre-Louis Bossart 		pdevinfo.data = link;
2114ab34412SPierre-Louis Bossart 		pdevinfo.size_data = sizeof(*link);
212d62a7d41SVinod Koul 
213d62a7d41SVinod Koul 		pdev = platform_device_register_full(&pdevinfo);
214d62a7d41SVinod Koul 		if (IS_ERR(pdev)) {
215d62a7d41SVinod Koul 			dev_err(&adev->dev,
216d62a7d41SVinod Koul 				"platform device creation failed: %ld\n",
217d62a7d41SVinod Koul 				PTR_ERR(pdev));
218*6d2c6669SPierre-Louis Bossart 			goto err;
219d62a7d41SVinod Koul 		}
220d62a7d41SVinod Koul 		link->pdev = pdev;
221d62a7d41SVinod Koul 	}
222d62a7d41SVinod Koul 
223d62a7d41SVinod Koul 	return ctx;
224d62a7d41SVinod Koul 
225*6d2c6669SPierre-Louis Bossart err:
226dd906cc6SPierre-Louis Bossart 	ctx->count = i;
227*6d2c6669SPierre-Louis Bossart 	sdw_intel_cleanup(ctx);
228d62a7d41SVinod Koul 	return NULL;
229d62a7d41SVinod Koul }
230d62a7d41SVinod Koul 
231*6d2c6669SPierre-Louis Bossart static int
232*6d2c6669SPierre-Louis Bossart sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
233*6d2c6669SPierre-Louis Bossart {
234*6d2c6669SPierre-Louis Bossart 	struct acpi_device *adev;
235*6d2c6669SPierre-Louis Bossart 	struct sdw_intel_link_res *link;
236*6d2c6669SPierre-Louis Bossart 	u32 caps;
237*6d2c6669SPierre-Louis Bossart 	u32 link_mask;
238*6d2c6669SPierre-Louis Bossart 	int i;
239*6d2c6669SPierre-Louis Bossart 
240*6d2c6669SPierre-Louis Bossart 	if (acpi_bus_get_device(ctx->handle, &adev))
241*6d2c6669SPierre-Louis Bossart 		return -EINVAL;
242*6d2c6669SPierre-Louis Bossart 
243*6d2c6669SPierre-Louis Bossart 	/* Check SNDWLCAP.LCOUNT */
244*6d2c6669SPierre-Louis Bossart 	caps = ioread32(ctx->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
245*6d2c6669SPierre-Louis Bossart 	caps &= GENMASK(2, 0);
246*6d2c6669SPierre-Louis Bossart 
247*6d2c6669SPierre-Louis Bossart 	/* Check HW supported vs property value */
248*6d2c6669SPierre-Louis Bossart 	if (caps < ctx->count) {
249*6d2c6669SPierre-Louis Bossart 		dev_err(&adev->dev,
250*6d2c6669SPierre-Louis Bossart 			"BIOS master count is larger than hardware capabilities\n");
251*6d2c6669SPierre-Louis Bossart 		return -EINVAL;
252*6d2c6669SPierre-Louis Bossart 	}
253*6d2c6669SPierre-Louis Bossart 
254*6d2c6669SPierre-Louis Bossart 	if (!ctx->links)
255*6d2c6669SPierre-Louis Bossart 		return -EINVAL;
256*6d2c6669SPierre-Louis Bossart 
257*6d2c6669SPierre-Louis Bossart 	link = ctx->links;
258*6d2c6669SPierre-Louis Bossart 	link_mask = ctx->link_mask;
259*6d2c6669SPierre-Louis Bossart 
260*6d2c6669SPierre-Louis Bossart 	/* Startup SDW Master devices */
261*6d2c6669SPierre-Louis Bossart 	for (i = 0; i < ctx->count; i++, link++) {
262*6d2c6669SPierre-Louis Bossart 		if (!(link_mask & BIT(i)))
263*6d2c6669SPierre-Louis Bossart 			continue;
264*6d2c6669SPierre-Louis Bossart 
265*6d2c6669SPierre-Louis Bossart 		intel_master_startup(link->pdev);
266*6d2c6669SPierre-Louis Bossart 	}
267*6d2c6669SPierre-Louis Bossart 
268*6d2c6669SPierre-Louis Bossart 	return 0;
269*6d2c6669SPierre-Louis Bossart }
270*6d2c6669SPierre-Louis Bossart 
271d62a7d41SVinod Koul static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
272d62a7d41SVinod Koul 				     void *cdata, void **return_value)
273d62a7d41SVinod Koul {
274*6d2c6669SPierre-Louis Bossart 	struct sdw_intel_acpi_info *info = cdata;
275d62a7d41SVinod Koul 	struct acpi_device *adev;
2766f11586fSPierre-Louis Bossart 	acpi_status status;
2776f11586fSPierre-Louis Bossart 	u64 adr;
2786f11586fSPierre-Louis Bossart 
2796f11586fSPierre-Louis Bossart 	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
2806f11586fSPierre-Louis Bossart 	if (ACPI_FAILURE(status))
2816f11586fSPierre-Louis Bossart 		return AE_OK; /* keep going */
282d62a7d41SVinod Koul 
283d62a7d41SVinod Koul 	if (acpi_bus_get_device(handle, &adev)) {
284e1c815f4SVinod Koul 		pr_err("%s: Couldn't find ACPI handle\n", __func__);
285d62a7d41SVinod Koul 		return AE_NOT_FOUND;
286d62a7d41SVinod Koul 	}
287d62a7d41SVinod Koul 
288*6d2c6669SPierre-Louis Bossart 	info->handle = handle;
2896f11586fSPierre-Louis Bossart 
2906f11586fSPierre-Louis Bossart 	/*
2916f11586fSPierre-Louis Bossart 	 * On some Intel platforms, multiple children of the HDAS
2926f11586fSPierre-Louis Bossart 	 * device can be found, but only one of them is the SoundWire
2936f11586fSPierre-Louis Bossart 	 * controller. The SNDW device is always exposed with
2946f11586fSPierre-Louis Bossart 	 * Name(_ADR, 0x40000000), with bits 31..28 representing the
2956f11586fSPierre-Louis Bossart 	 * SoundWire link so filter accordingly
2966f11586fSPierre-Louis Bossart 	 */
2976f11586fSPierre-Louis Bossart 	if ((adr & GENMASK(31, 28)) >> 28 != SDW_LINK_TYPE)
2986f11586fSPierre-Louis Bossart 		return AE_OK; /* keep going */
2996f11586fSPierre-Louis Bossart 
3006f11586fSPierre-Louis Bossart 	/* device found, stop namespace walk */
3016f11586fSPierre-Louis Bossart 	return AE_CTRL_TERMINATE;
302d62a7d41SVinod Koul }
303d62a7d41SVinod Koul 
304d62a7d41SVinod Koul /**
305*6d2c6669SPierre-Louis Bossart  * sdw_intel_acpi_scan() - SoundWire Intel init routine
306d62a7d41SVinod Koul  * @parent_handle: ACPI parent handle
307*6d2c6669SPierre-Louis Bossart  * @info: description of what firmware/DSDT tables expose
308d62a7d41SVinod Koul  *
309*6d2c6669SPierre-Louis Bossart  * This scans the namespace and queries firmware to figure out which
310*6d2c6669SPierre-Louis Bossart  * links to enable. A follow-up use of sdw_intel_probe() and
311*6d2c6669SPierre-Louis Bossart  * sdw_intel_startup() is required for creation of devices and bus
312*6d2c6669SPierre-Louis Bossart  * startup
313d62a7d41SVinod Koul  */
314*6d2c6669SPierre-Louis Bossart int sdw_intel_acpi_scan(acpi_handle *parent_handle,
315*6d2c6669SPierre-Louis Bossart 			struct sdw_intel_acpi_info *info)
316d62a7d41SVinod Koul {
317d62a7d41SVinod Koul 	acpi_status status;
318d62a7d41SVinod Koul 
319d62a7d41SVinod Koul 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
320d62a7d41SVinod Koul 				     parent_handle, 1,
321d62a7d41SVinod Koul 				     sdw_intel_acpi_cb,
322*6d2c6669SPierre-Louis Bossart 				     NULL, info, NULL);
323d62a7d41SVinod Koul 	if (ACPI_FAILURE(status))
324*6d2c6669SPierre-Louis Bossart 		return -ENODEV;
325d62a7d41SVinod Koul 
326*6d2c6669SPierre-Louis Bossart 	return sdw_intel_scan_controller(info);
327d62a7d41SVinod Koul }
328*6d2c6669SPierre-Louis Bossart EXPORT_SYMBOL(sdw_intel_acpi_scan);
329d62a7d41SVinod Koul 
330d62a7d41SVinod Koul /**
331*6d2c6669SPierre-Louis Bossart  * sdw_intel_probe() - SoundWire Intel probe routine
332*6d2c6669SPierre-Louis Bossart  * @res: resource data
333*6d2c6669SPierre-Louis Bossart  *
334*6d2c6669SPierre-Louis Bossart  * This registers a platform device for each Master handled by the controller,
335*6d2c6669SPierre-Louis Bossart  * and SoundWire Master and Slave devices will be created by the platform
336*6d2c6669SPierre-Louis Bossart  * device probe. All the information necessary is stored in the context, and
337*6d2c6669SPierre-Louis Bossart  * the res argument pointer can be freed after this step.
338*6d2c6669SPierre-Louis Bossart  * This function will be called after sdw_intel_acpi_scan() by SOF probe.
339*6d2c6669SPierre-Louis Bossart  */
340*6d2c6669SPierre-Louis Bossart struct sdw_intel_ctx
341*6d2c6669SPierre-Louis Bossart *sdw_intel_probe(struct sdw_intel_res *res)
342*6d2c6669SPierre-Louis Bossart {
343*6d2c6669SPierre-Louis Bossart 	return sdw_intel_probe_controller(res);
344*6d2c6669SPierre-Louis Bossart }
345*6d2c6669SPierre-Louis Bossart EXPORT_SYMBOL(sdw_intel_probe);
346*6d2c6669SPierre-Louis Bossart 
347*6d2c6669SPierre-Louis Bossart /**
348*6d2c6669SPierre-Louis Bossart  * sdw_intel_startup() - SoundWire Intel startup
349*6d2c6669SPierre-Louis Bossart  * @ctx: SoundWire context allocated in the probe
350*6d2c6669SPierre-Louis Bossart  *
351*6d2c6669SPierre-Louis Bossart  * Startup Intel SoundWire controller. This function will be called after
352*6d2c6669SPierre-Louis Bossart  * Intel Audio DSP is powered up.
353*6d2c6669SPierre-Louis Bossart  */
354*6d2c6669SPierre-Louis Bossart int sdw_intel_startup(struct sdw_intel_ctx *ctx)
355*6d2c6669SPierre-Louis Bossart {
356*6d2c6669SPierre-Louis Bossart 	return sdw_intel_startup_controller(ctx);
357*6d2c6669SPierre-Louis Bossart }
358*6d2c6669SPierre-Louis Bossart EXPORT_SYMBOL(sdw_intel_startup);
359*6d2c6669SPierre-Louis Bossart /**
360d62a7d41SVinod Koul  * sdw_intel_exit() - SoundWire Intel exit
361*6d2c6669SPierre-Louis Bossart  * @ctx: SoundWire context allocated in the probe
362d62a7d41SVinod Koul  *
363d62a7d41SVinod Koul  * Delete the controller instances created and cleanup
364d62a7d41SVinod Koul  */
365f98f690fSPierre-Louis Bossart void sdw_intel_exit(struct sdw_intel_ctx *ctx)
366d62a7d41SVinod Koul {
367*6d2c6669SPierre-Louis Bossart 	sdw_intel_cleanup(ctx);
368d62a7d41SVinod Koul }
369d62a7d41SVinod Koul EXPORT_SYMBOL(sdw_intel_exit);
370d62a7d41SVinod Koul 
371d62a7d41SVinod Koul MODULE_LICENSE("Dual BSD/GPL");
372d62a7d41SVinod Koul MODULE_DESCRIPTION("Intel Soundwire Init Library");
373