Blame view

drivers/soundwire/intel_init.c 11.4 KB
d62a7d41f   Vinod Koul   soundwire: intel:...
1
2
3
4
5
6
7
8
9
10
  // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
  // Copyright(c) 2015-17 Intel Corporation.
  
  /*
   * SDW Intel Init Routines
   *
   * Initializes and creates SDW devices based on ACPI and Hardware values
   */
  
  #include <linux/acpi.h>
4abbd783d   Paul Gortmaker   soundwire: intel:...
11
  #include <linux/export.h>
4a98a6b2f   Bard Liao   soundwire: intel/...
12
  #include <linux/interrupt.h>
3fc40449a   Vinod Koul   soundwire: intel:...
13
  #include <linux/io.h>
4abbd783d   Paul Gortmaker   soundwire: intel:...
14
  #include <linux/module.h>
d62a7d41f   Vinod Koul   soundwire: intel:...
15
  #include <linux/platform_device.h>
ebf878edd   Pierre-Louis Bossart   soundwire: intel:...
16
  #include <linux/pm_runtime.h>
d62a7d41f   Vinod Koul   soundwire: intel:...
17
  #include <linux/soundwire/sdw_intel.h>
b6109dd6d   Pierre-Louis Bossart   soundwire: intel:...
18
  #include "cadence_master.h"
d62a7d41f   Vinod Koul   soundwire: intel:...
19
  #include "intel.h"
6f11586f4   Pierre-Louis Bossart   soundwire: intel:...
20
  #define SDW_LINK_TYPE		4 /* from Intel ACPI documentation */
d62a7d41f   Vinod Koul   soundwire: intel:...
21
22
23
24
25
26
  #define SDW_MAX_LINKS		4
  #define SDW_SHIM_LCAP		0x0
  #define SDW_SHIM_BASE		0x2C000
  #define SDW_ALH_BASE		0x2C800
  #define SDW_LINK_BASE		0x30000
  #define SDW_LINK_SIZE		0x10000
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
27
28
  static int ctrl_link_mask;
  module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444);
50302fc7b   Pierre-Louis Bossart   soundwire: intel_...
29
  MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)");
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  static bool is_link_enabled(struct fwnode_handle *fw_node, int i)
  {
  	struct fwnode_handle *link;
  	char name[32];
  	u32 quirk_mask = 0;
  
  	/* Find master handle */
  	snprintf(name, sizeof(name),
  		 "mipi-sdw-link-%d-subproperties", i);
  
  	link = fwnode_get_named_child_node(fw_node, name);
  	if (!link)
  		return false;
  
  	fwnode_property_read_u32(link,
  				 "intel-quirk-mask",
  				 &quirk_mask);
  
  	if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
  		return false;
  
  	return true;
  }
  
  static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
d62a7d41f   Vinod Koul   soundwire: intel:...
55
  {
f98f690fb   Pierre-Louis Bossart   soundwire: intel:...
56
  	struct sdw_intel_link_res *link = ctx->links;
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
57
  	u32 link_mask;
d62a7d41f   Vinod Koul   soundwire: intel:...
58
59
60
61
  	int i;
  
  	if (!link)
  		return 0;
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
62
63
64
65
66
  	link_mask = ctx->link_mask;
  
  	for (i = 0; i < ctx->count; i++, link++) {
  		if (!(link_mask & BIT(i)))
  			continue;
ebf878edd   Pierre-Louis Bossart   soundwire: intel:...
67
68
  		if (link->pdev) {
  			pm_runtime_disable(&link->pdev->dev);
d62a7d41f   Vinod Koul   soundwire: intel:...
69
  			platform_device_unregister(link->pdev);
ebf878edd   Pierre-Louis Bossart   soundwire: intel:...
70
  		}
ab996b297   Pierre-Louis Bossart   soundwire: intel_...
71
72
73
  
  		if (!link->clock_stop_quirks)
  			pm_runtime_put_noidle(link->dev);
d62a7d41f   Vinod Koul   soundwire: intel:...
74
  	}
d62a7d41f   Vinod Koul   soundwire: intel:...
75
76
  	return 0;
  }
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
77
78
  static int
  sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
d62a7d41f   Vinod Koul   soundwire: intel:...
79
  {
d62a7d41f   Vinod Koul   soundwire: intel:...
80
81
82
  	struct acpi_device *adev;
  	int ret, i;
  	u8 count;
d62a7d41f   Vinod Koul   soundwire: intel:...
83

6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
84
85
  	if (acpi_bus_get_device(info->handle, &adev))
  		return -EINVAL;
d62a7d41f   Vinod Koul   soundwire: intel:...
86
87
88
89
  
  	/* Found controller, find links supported */
  	count = 0;
  	ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
505ccb006   Pierre-Louis Bossart   soundwire: intel_...
90
  					    "mipi-sdw-master-count", &count, 1);
d62a7d41f   Vinod Koul   soundwire: intel:...
91

6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
92
93
94
95
96
97
98
99
100
101
102
  	/*
  	 * In theory we could check the number of links supported in
  	 * hardware, but in that step we cannot assume SoundWire IP is
  	 * powered.
  	 *
  	 * In addition, if the BIOS doesn't even provide this
  	 * 'master-count' property then all the inits based on link
  	 * masks will fail as well.
  	 *
  	 * We will check the hardware capabilities in the startup() step
  	 */
d62a7d41f   Vinod Koul   soundwire: intel:...
103
104
105
106
  	if (ret) {
  		dev_err(&adev->dev,
  			"Failed to read mipi-sdw-master-count: %d
  ", ret);
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
107
  		return -EINVAL;
d62a7d41f   Vinod Koul   soundwire: intel:...
108
  	}
d62a7d41f   Vinod Koul   soundwire: intel:...
109
110
111
112
  	/* Check count is within bounds */
  	if (count > SDW_MAX_LINKS) {
  		dev_err(&adev->dev, "Link count %d exceeds max %d
  ",
505ccb006   Pierre-Louis Bossart   soundwire: intel_...
113
  			count, SDW_MAX_LINKS);
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
114
  		return -EINVAL;
6f7219fec   Guennadi Liakhovetski   soundwire: intel:...
115
116
117
  	}
  
  	if (!count) {
432732b80   Pierre-Louis Bossart   soundwire: intel_...
118
119
  		dev_warn(&adev->dev, "No SoundWire links detected
  ");
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
  		return -EINVAL;
  	}
  	dev_dbg(&adev->dev, "ACPI reports %d SDW Link devices
  ", count);
  
  	info->count = count;
  	info->link_mask = 0;
  
  	for (i = 0; i < count; i++) {
  		if (ctrl_link_mask && !(ctrl_link_mask & BIT(i))) {
  			dev_dbg(&adev->dev,
  				"Link %d masked, will not be enabled
  ", i);
  			continue;
  		}
  
  		if (!is_link_enabled(acpi_fwnode_handle(adev), i)) {
  			dev_dbg(&adev->dev,
  				"Link %d not selected in firmware
  ", i);
  			continue;
  		}
  
  		info->link_mask |= BIT(i);
d62a7d41f   Vinod Koul   soundwire: intel:...
144
  	}
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
145
146
  	return 0;
  }
12b161468   Pierre-Louis Bossart   soundwire: intel_...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  #define HDA_DSP_REG_ADSPIC2             (0x10)
  #define HDA_DSP_REG_ADSPIS2             (0x14)
  #define HDA_DSP_REG_ADSPIC2_SNDW        BIT(5)
  
  /**
   * sdw_intel_enable_irq() - enable/disable Intel SoundWire IRQ
   * @mmio_base: The mmio base of the control register
   * @enable: true if enable
   */
  void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable)
  {
  	u32 val;
  
  	val = readl(mmio_base + HDA_DSP_REG_ADSPIC2);
  
  	if (enable)
  		val |= HDA_DSP_REG_ADSPIC2_SNDW;
  	else
  		val &= ~HDA_DSP_REG_ADSPIC2_SNDW;
  
  	writel(val, mmio_base + HDA_DSP_REG_ADSPIC2);
  }
8459cea75   Pierre-Louis Bossart   soundwire: intel_...
169
  EXPORT_SYMBOL_NS(sdw_intel_enable_irq, SOUNDWIRE_INTEL_INIT);
12b161468   Pierre-Louis Bossart   soundwire: intel_...
170

4a98a6b2f   Bard Liao   soundwire: intel/...
171
172
173
174
175
176
177
178
179
180
181
182
  irqreturn_t sdw_intel_thread(int irq, void *dev_id)
  {
  	struct sdw_intel_ctx *ctx = dev_id;
  	struct sdw_intel_link_res *link;
  
  	list_for_each_entry(link, &ctx->link_list, list)
  		sdw_cdns_irq(irq, link->cdns);
  
  	sdw_intel_enable_irq(ctx->mmio_base, true);
  	return IRQ_HANDLED;
  }
  EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT);
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
183
184
185
186
187
188
189
190
  static struct sdw_intel_ctx
  *sdw_intel_probe_controller(struct sdw_intel_res *res)
  {
  	struct platform_device_info pdevinfo;
  	struct platform_device *pdev;
  	struct sdw_intel_link_res *link;
  	struct sdw_intel_ctx *ctx;
  	struct acpi_device *adev;
a81844034   Bard Liao   Soundwire: intel_...
191
192
193
  	struct sdw_slave *slave;
  	struct list_head *node;
  	struct sdw_bus *bus;
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
194
  	u32 link_mask;
a81844034   Bard Liao   Soundwire: intel_...
195
  	int num_slaves = 0;
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
196
197
198
199
200
201
202
203
204
205
206
207
208
  	int count;
  	int i;
  
  	if (!res)
  		return NULL;
  
  	if (acpi_bus_get_device(res->handle, &adev))
  		return NULL;
  
  	if (!res->count)
  		return NULL;
  
  	count = res->count;
d62a7d41f   Vinod Koul   soundwire: intel:...
209
210
  	dev_dbg(&adev->dev, "Creating %d SDW Link devices
  ", count);
dd906cc61   Pierre-Louis Bossart   soundwire: intel_...
211
  	ctx = devm_kzalloc(&adev->dev, sizeof(*ctx), GFP_KERNEL);
d62a7d41f   Vinod Koul   soundwire: intel:...
212
213
214
215
  	if (!ctx)
  		return NULL;
  
  	ctx->count = count;
dd906cc61   Pierre-Louis Bossart   soundwire: intel_...
216
217
  	ctx->links = devm_kcalloc(&adev->dev, ctx->count,
  				  sizeof(*ctx->links), GFP_KERNEL);
d62a7d41f   Vinod Koul   soundwire: intel:...
218
  	if (!ctx->links)
dd906cc61   Pierre-Louis Bossart   soundwire: intel_...
219
  		return NULL;
d62a7d41f   Vinod Koul   soundwire: intel:...
220

6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
221
222
223
224
  	ctx->count = count;
  	ctx->mmio_base = res->mmio_base;
  	ctx->link_mask = res->link_mask;
  	ctx->handle = res->handle;
4a17c441c   Pierre-Louis Bossart   soundwire: intel:...
225
  	mutex_init(&ctx->shim_lock);
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
226

d62a7d41f   Vinod Koul   soundwire: intel:...
227
  	link = ctx->links;
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
228
  	link_mask = ctx->link_mask;
d62a7d41f   Vinod Koul   soundwire: intel:...
229

4a98a6b2f   Bard Liao   soundwire: intel/...
230
  	INIT_LIST_HEAD(&ctx->link_list);
d62a7d41f   Vinod Koul   soundwire: intel:...
231
  	/* Create SDW Master devices */
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
232
  	for (i = 0; i < count; i++, link++) {
9cd1c5a72   Pierre-Louis Bossart   soundwire: intel_...
233
  		if (!(link_mask & BIT(i))) {
50302fc7b   Pierre-Louis Bossart   soundwire: intel_...
234
235
236
  			dev_dbg(&adev->dev,
  				"Link %d masked, will not be enabled
  ", i);
50302fc7b   Pierre-Louis Bossart   soundwire: intel_...
237
238
  			continue;
  		}
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
239
  		link->mmio_base = res->mmio_base;
f98f690fb   Pierre-Louis Bossart   soundwire: intel:...
240
  		link->registers = res->mmio_base + SDW_LINK_BASE
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
241
  			+ (SDW_LINK_SIZE * i);
f98f690fb   Pierre-Louis Bossart   soundwire: intel:...
242
243
  		link->shim = res->mmio_base + SDW_SHIM_BASE;
  		link->alh = res->mmio_base + SDW_ALH_BASE;
d62a7d41f   Vinod Koul   soundwire: intel:...
244

f98f690fb   Pierre-Louis Bossart   soundwire: intel:...
245
  		link->ops = res->ops;
4b206d34b   Rander Wang   soundwire: intel:...
246
  		link->dev = res->dev;
c46302ec5   Vinod Koul   soundwire: intel:...
247

a320f41ea   Pierre-Louis Bossart   soundwire: intel:...
248
  		link->clock_stop_quirks = res->clock_stop_quirks;
4a17c441c   Pierre-Louis Bossart   soundwire: intel:...
249
250
  		link->shim_lock = &ctx->shim_lock;
  		link->shim_mask = &ctx->shim_mask;
de763fa88   Pierre-Louis Bossart   soundwire: intel:...
251
  		link->link_mask = link_mask;
4a17c441c   Pierre-Louis Bossart   soundwire: intel:...
252

d62a7d41f   Vinod Koul   soundwire: intel:...
253
254
255
  		memset(&pdevinfo, 0, sizeof(pdevinfo));
  
  		pdevinfo.parent = res->parent;
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
256
  		pdevinfo.name = "intel-sdw";
d62a7d41f   Vinod Koul   soundwire: intel:...
257
258
  		pdevinfo.id = i;
  		pdevinfo.fwnode = acpi_fwnode_handle(adev);
4ab34412f   Pierre-Louis Bossart   soundwire: intel_...
259
260
  		pdevinfo.data = link;
  		pdevinfo.size_data = sizeof(*link);
d62a7d41f   Vinod Koul   soundwire: intel:...
261
262
263
264
265
266
267
  
  		pdev = platform_device_register_full(&pdevinfo);
  		if (IS_ERR(pdev)) {
  			dev_err(&adev->dev,
  				"platform device creation failed: %ld
  ",
  				PTR_ERR(pdev));
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
268
  			goto err;
d62a7d41f   Vinod Koul   soundwire: intel:...
269
  		}
d62a7d41f   Vinod Koul   soundwire: intel:...
270
  		link->pdev = pdev;
4a98a6b2f   Bard Liao   soundwire: intel/...
271
272
273
  		link->cdns = platform_get_drvdata(pdev);
  
  		list_add_tail(&link->list, &ctx->link_list);
a81844034   Bard Liao   Soundwire: intel_...
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  		bus = &link->cdns->bus;
  		/* Calculate number of slaves */
  		list_for_each(node, &bus->slaves)
  			num_slaves++;
  	}
  
  	ctx->ids = devm_kcalloc(&adev->dev, num_slaves,
  				sizeof(*ctx->ids), GFP_KERNEL);
  	if (!ctx->ids)
  		goto err;
  
  	ctx->num_slaves = num_slaves;
  	i = 0;
  	list_for_each_entry(link, &ctx->link_list, list) {
  		bus = &link->cdns->bus;
  		list_for_each_entry(slave, &bus->slaves, node) {
  			ctx->ids[i].id = slave->id;
  			ctx->ids[i].link_id = bus->link_id;
  			i++;
  		}
d62a7d41f   Vinod Koul   soundwire: intel:...
294
295
296
  	}
  
  	return ctx;
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
297
  err:
dd906cc61   Pierre-Louis Bossart   soundwire: intel_...
298
  	ctx->count = i;
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
299
  	sdw_intel_cleanup(ctx);
d62a7d41f   Vinod Koul   soundwire: intel:...
300
301
  	return NULL;
  }
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
  static int
  sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
  {
  	struct acpi_device *adev;
  	struct sdw_intel_link_res *link;
  	u32 caps;
  	u32 link_mask;
  	int i;
  
  	if (acpi_bus_get_device(ctx->handle, &adev))
  		return -EINVAL;
  
  	/* Check SNDWLCAP.LCOUNT */
  	caps = ioread32(ctx->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
  	caps &= GENMASK(2, 0);
  
  	/* Check HW supported vs property value */
  	if (caps < ctx->count) {
  		dev_err(&adev->dev,
  			"BIOS master count is larger than hardware capabilities
  ");
  		return -EINVAL;
  	}
  
  	if (!ctx->links)
  		return -EINVAL;
  
  	link = ctx->links;
  	link_mask = ctx->link_mask;
  
  	/* Startup SDW Master devices */
  	for (i = 0; i < ctx->count; i++, link++) {
  		if (!(link_mask & BIT(i)))
  			continue;
  
  		intel_master_startup(link->pdev);
ab996b297   Pierre-Louis Bossart   soundwire: intel_...
338
339
340
341
342
343
344
345
346
347
  
  		if (!link->clock_stop_quirks) {
  			/*
  			 * we need to prevent the parent PCI device
  			 * from entering pm_runtime suspend, so that
  			 * power rails to the SoundWire IP are not
  			 * turned off.
  			 */
  			pm_runtime_get_noresume(link->dev);
  		}
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
348
349
350
351
  	}
  
  	return 0;
  }
d62a7d41f   Vinod Koul   soundwire: intel:...
352
  static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
505ccb006   Pierre-Louis Bossart   soundwire: intel_...
353
  				     void *cdata, void **return_value)
d62a7d41f   Vinod Koul   soundwire: intel:...
354
  {
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
355
  	struct sdw_intel_acpi_info *info = cdata;
d62a7d41f   Vinod Koul   soundwire: intel:...
356
  	struct acpi_device *adev;
6f11586f4   Pierre-Louis Bossart   soundwire: intel:...
357
358
359
360
361
362
  	acpi_status status;
  	u64 adr;
  
  	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
  	if (ACPI_FAILURE(status))
  		return AE_OK; /* keep going */
d62a7d41f   Vinod Koul   soundwire: intel:...
363
364
  
  	if (acpi_bus_get_device(handle, &adev)) {
e1c815f4b   Vinod Koul   soundwire: intel:...
365
366
  		pr_err("%s: Couldn't find ACPI handle
  ", __func__);
d62a7d41f   Vinod Koul   soundwire: intel:...
367
368
  		return AE_NOT_FOUND;
  	}
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
369
  	info->handle = handle;
6f11586f4   Pierre-Louis Bossart   soundwire: intel:...
370
371
372
373
374
375
376
377
  
  	/*
  	 * On some Intel platforms, multiple children of the HDAS
  	 * device can be found, but only one of them is the SoundWire
  	 * controller. The SNDW device is always exposed with
  	 * Name(_ADR, 0x40000000), with bits 31..28 representing the
  	 * SoundWire link so filter accordingly
  	 */
c30f92984   Vinod Koul   soundwire: intel_...
378
  	if (FIELD_GET(GENMASK(31, 28), adr) != SDW_LINK_TYPE)
6f11586f4   Pierre-Louis Bossart   soundwire: intel:...
379
380
381
382
  		return AE_OK; /* keep going */
  
  	/* device found, stop namespace walk */
  	return AE_CTRL_TERMINATE;
d62a7d41f   Vinod Koul   soundwire: intel:...
383
384
385
  }
  
  /**
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
386
   * sdw_intel_acpi_scan() - SoundWire Intel init routine
d62a7d41f   Vinod Koul   soundwire: intel:...
387
   * @parent_handle: ACPI parent handle
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
388
   * @info: description of what firmware/DSDT tables expose
d62a7d41f   Vinod Koul   soundwire: intel:...
389
   *
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
390
391
392
393
   * This scans the namespace and queries firmware to figure out which
   * links to enable. A follow-up use of sdw_intel_probe() and
   * sdw_intel_startup() is required for creation of devices and bus
   * startup
d62a7d41f   Vinod Koul   soundwire: intel:...
394
   */
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
395
396
  int sdw_intel_acpi_scan(acpi_handle *parent_handle,
  			struct sdw_intel_acpi_info *info)
d62a7d41f   Vinod Koul   soundwire: intel:...
397
398
399
400
  {
  	acpi_status status;
  
  	status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
505ccb006   Pierre-Louis Bossart   soundwire: intel_...
401
402
  				     parent_handle, 1,
  				     sdw_intel_acpi_cb,
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
403
  				     NULL, info, NULL);
d62a7d41f   Vinod Koul   soundwire: intel:...
404
  	if (ACPI_FAILURE(status))
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
405
  		return -ENODEV;
d62a7d41f   Vinod Koul   soundwire: intel:...
406

6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
407
  	return sdw_intel_scan_controller(info);
d62a7d41f   Vinod Koul   soundwire: intel:...
408
  }
8459cea75   Pierre-Louis Bossart   soundwire: intel_...
409
  EXPORT_SYMBOL_NS(sdw_intel_acpi_scan, SOUNDWIRE_INTEL_INIT);
d62a7d41f   Vinod Koul   soundwire: intel:...
410
411
  
  /**
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
412
413
414
415
416
417
418
419
420
421
422
423
424
425
   * sdw_intel_probe() - SoundWire Intel probe routine
   * @res: resource data
   *
   * This registers a platform device for each Master handled by the controller,
   * and SoundWire Master and Slave devices will be created by the platform
   * device probe. All the information necessary is stored in the context, and
   * the res argument pointer can be freed after this step.
   * This function will be called after sdw_intel_acpi_scan() by SOF probe.
   */
  struct sdw_intel_ctx
  *sdw_intel_probe(struct sdw_intel_res *res)
  {
  	return sdw_intel_probe_controller(res);
  }
8459cea75   Pierre-Louis Bossart   soundwire: intel_...
426
  EXPORT_SYMBOL_NS(sdw_intel_probe, SOUNDWIRE_INTEL_INIT);
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
427
428
429
430
431
432
433
434
435
436
437
438
  
  /**
   * sdw_intel_startup() - SoundWire Intel startup
   * @ctx: SoundWire context allocated in the probe
   *
   * Startup Intel SoundWire controller. This function will be called after
   * Intel Audio DSP is powered up.
   */
  int sdw_intel_startup(struct sdw_intel_ctx *ctx)
  {
  	return sdw_intel_startup_controller(ctx);
  }
8459cea75   Pierre-Louis Bossart   soundwire: intel_...
439
  EXPORT_SYMBOL_NS(sdw_intel_startup, SOUNDWIRE_INTEL_INIT);
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
440
  /**
d62a7d41f   Vinod Koul   soundwire: intel:...
441
   * sdw_intel_exit() - SoundWire Intel exit
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
442
   * @ctx: SoundWire context allocated in the probe
d62a7d41f   Vinod Koul   soundwire: intel:...
443
444
445
   *
   * Delete the controller instances created and cleanup
   */
f98f690fb   Pierre-Louis Bossart   soundwire: intel:...
446
  void sdw_intel_exit(struct sdw_intel_ctx *ctx)
d62a7d41f   Vinod Koul   soundwire: intel:...
447
  {
6d2c66695   Pierre-Louis Bossart   soundwire: intel:...
448
  	sdw_intel_cleanup(ctx);
d62a7d41f   Vinod Koul   soundwire: intel:...
449
  }
8459cea75   Pierre-Louis Bossart   soundwire: intel_...
450
  EXPORT_SYMBOL_NS(sdw_intel_exit, SOUNDWIRE_INTEL_INIT);
d62a7d41f   Vinod Koul   soundwire: intel:...
451

ab2c91329   Rander Wang   soundwire: intel:...
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
  void sdw_intel_process_wakeen_event(struct sdw_intel_ctx *ctx)
  {
  	struct sdw_intel_link_res *link;
  	u32 link_mask;
  	int i;
  
  	if (!ctx->links)
  		return;
  
  	link = ctx->links;
  	link_mask = ctx->link_mask;
  
  	/* Startup SDW Master devices */
  	for (i = 0; i < ctx->count; i++, link++) {
  		if (!(link_mask & BIT(i)))
  			continue;
  
  		intel_master_process_wakeen_event(link->pdev);
  	}
  }
  EXPORT_SYMBOL_NS(sdw_intel_process_wakeen_event, SOUNDWIRE_INTEL_INIT);
d62a7d41f   Vinod Koul   soundwire: intel:...
473
474
  MODULE_LICENSE("Dual BSD/GPL");
  MODULE_DESCRIPTION("Intel Soundwire Init Library");