summaryrefslogtreecommitdiff
path: root/Documentation/drivers/soundwire.md
blob: 9c48b75b371f34a9d0783fec873972e19bb6f976 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
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
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
# SoundWire Implementation in coreboot

## Introduction

SoundWire is an audio interface specification from the MIPI Alliance.

- Low complexity
- Low power
- Low latency
- Two pins (clock and data)
- Multi-drop capable
- Multiple audio streams
- Embedded control/command channel

The main *SoundWire Specification* is at version 1.2 and can be downloaded from
<https://mipi.org> but it is unfortunately only available to MIPI Alliance members.

There is a separate *SoundWire Discovery and Configuration (DisCo) Specification* which
is at version 1.0 and is available for non-members after providing name and email at
<https://resources.mipi.org/disco_soundwire>.

The coreboot implementation is based on the SoundWire DisCo Specification which defines
object hierarchy and properties for providing topology and configuration information to
OS kernel drivers via ACPI or DeviceTree.

SoundWire itself is architecture independent and the coreboot basic definition is also not
specific to any to any SoC.  The examples in this document use ACPI to generate properties,
but the same structures and properties would be needed in a DeviceTree implementation.

## Bus

The SoundWire bus commonly consists of two pins:

* Clock: A common clock signal distributed from the master to all of the slaves.
* Data: A shared data signal that can be driven by any of the devices, and has a defined
value when no device is driving it.

While most designs have one data lane it is possible for a multi-lane device to have up
to 8 data lanes and thus would have more than two pins.

A SoundWire bus consists of one master device, up to 11 slave devices, and an optional
monitor interface for debug.

SoundWire is an enumerable bus, but not a discoverable one.  That means it is required
for firmware to provide details about the connected devices to the OS.

### Controller

A SoundWire controller contains one or more master devices.  The handling of multiple
masters is left up to the implementation, they may share a clock or be operated
independently or entirely in tandem.  The master devices connected to a controller are
also referred to as links.

In coreboot the controller device is provided by the SoC or an add-in PCI card.

### Master

A SoundWire master (or link) device is responsible for clock and data handling, bus
management, and bit slot allocation.

In coreboot the definition of the master device is left up to the controller and the
mainboard should only need to know the controller's SoundWire topology (number of masters)
to configure `devicetree.cb`.

It may however be expected to provide some additional SoC-specific configuration data to
the controller, such as an input clock rate or a list of available masters that cannot
be determined at run time.

### Slave

SoundWire slave devices are connected to a master and respond to the two-wire control
information on the SoundWire bus.  There can be up to 11 slave devices on a bus and they
are capable of interrupting and waking the host.

Slave devices may also have master links which can be connected to other slave devices.
It is also possible for a multi-lane slave device to have multiple data lanes connected
to different combinations of master and slave devices.

In coreboot the slave device is defined by a codec driver which should be found in the
source tree at `src/drivers/soundwire`.

The mainboard provides:

* Master link that this slave device is connected to.
* Unique ID that this codec responds to on the SoundWire bus.
* Multi-lane mapping. (optional)

The codec driver provides:

* Slave device properties.
* Audio Mode properties including bus frequencies and sampling rates.
* Data Port 1-14 properties such as word lengths, interrupt support, channels.
* Data Port 0 and Bulk Register Access properties. (optional)

### Monitor

A SoundWire monitor device is defined that allows for test equipment to snoop the bus and
take over and issue commands.  The monitor interface is not defined for coreboot.

### Example SoundWire Bus

```
+---------------+                                       +---------------+
|               |                       Clock Signal    |               |
|    Master     |-------+-------------------------------|    Slave      |
|   Interface   |       |               Data Signal     |  Interface 1  |
|               |-------|-------+-----------------------|               |
+---------------+       |       |                       +---------------+
                        |       |
                        |       |
                        |       |
                     +--+-------+--+
                     |             |
                     |   Slave     |
                     | Interface 2 |
                     |             |
                     +-------------+
```

## coreboot

The coreboot implementation of SoundWire integrates with the device model and takes
advantage of the hierarchical nature of `devicetree.cb` to populate the topology.

The architecture-independent SoundWire tables are defined at

    src/include/device/soundwire.h

Support for new devices comes in three forms:

1. New controller and master drivers.  The first implementation in coreboot is for an Intel
SoC but the SoundWire specification is in wide use on various ARM SoCs.

    Controller drivers can be implemented in `src/soc` or `src/drivers` and should
    strive to re-use code as much as possible between different SoC generations from the
    same vendor.

2. New codec drivers.  These should be implemented for each codec that is added which
supports SoundWire.  The properties vary between codecs and careful study of the data sheet
is necessary to ensure proper operation.

    Codec drivers should be implemented in `src/drivers/soundwire` as separate chip drivers.
    As every codec is different there may not be opportunities of code re-use except between
    similar codecs from the same vendor.

3. New mainboards with SoundWire support.  The mainboard will combine controllers and codecs
to form a topology that is described in `devicetree.cb`.  Some devices may need to provide
board-specific configuration information, and multi-lane devices will need to provide the
master/slave lane map.

## ACPI Implementation

The implementation for x86 devices relies on ACPI for providing device properties to the OS
kernel drivers.

The ACPI implementation can be found at

    src/acpi/soundwire.c

And used by including

    #include <acpi/acpi_soundwire.h>

### Controller

The controller driver should populate a `struct soundwire_controller`:

```c
/**
 * struct soundwire_controller - SoundWire controller properties.
 * @master_count: Number of masters present on this device.
 * @master_list: One entry for each master device.
 */
struct soundwire_controller {
	unsigned int master_list_count;
	struct soundwire_link master_list[SOUNDWIRE_MAX_DEV];
};
```

Once the detail of the master links are specified in the `master_list` variable, the controller
properties for the ACPI object can be generated:

```c
struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
soundwire_gen_controller(dsd, &soc_controller, NULL);
acpi_dp_write(dsd);
```

If the controller needs to generate custom properties for links it can provide a callback
function to `soundwire_gen_controller()` instead of passing NULL:

```c
static void controller_link_prop_cb(struct acpi_dp *dsd, unsigned int id,
                                    struct soundwire_controller *controller)
{
	acpi_dp_add_integer(dsd, "custom-link-property", 1);
}
```

### Codec

The codec driver should populate a *struct soundwire_codec* with necessary properties:

```c
/**
 * struct soundwire_codec - Contains all configuration for a SoundWire codec slave device.
 * @slave: Properties for slave device.
 * @audio_mode: Properties for Audio Mode for Data Ports 1-14.
 * @dpn: Properties for Data Ports 1-14.
 * @multilane: Properties for slave multilane device. (optional)
 * @dp0_bra_mode: Properties for Bulk Register Access mode for Data Port 0. (optional)
 * @dp0: Properties for Data Port 0 for Bulk Register Access. (optional)
 */
struct soundwire_codec {
	struct soundwire_slave *slave;
	struct soundwire_audio_mode *audio_mode[SOUNDWIRE_MAX_DEV];
	struct soundwire_dpn_entry dpn[SOUNDWIRE_MAX_DPN - SOUNDWIRE_MIN_DPN];
	struct soundwire_multilane *multilane;
	struct soundwire_bra_mode *dp0_bra_mode[SOUNDWIRE_MAX_DEV];
	struct soundwire_dp0 *dp0;
};
```

Many of these properties are optional, and depending on the codec will not be supported.

#### Slave Device Properties

These properties provide information about the codec device and what features it supports:

* Wake capability
* Clock stop behavior
* Clock and channel state machine behavior
* Features like register pages, broadcast read, bank delay, and high performance PHY

#### Multi-lane Slave Device Properties

Most slave devices have a single data pin and a single lane, but it is possible for up to
7 other lanes to be supported on a device.  These lanes can be connected to other master
links or to other slave devices.

If a codec supports this feature it must indicate that by providing an entry for
`struct soundwire_multilane` in the chip configuration.

```c
/**
 * struct drivers_soundwire_example_config - Example codec configuration.
 * @multilane: Multi-lane slave configuration.
 */
struct drivers_soundwire_example_config {
	struct soundwire_multilane multilane;
};
```

The mainboard is required to provide the lane map in `devicetree.cb` for any codec that has
multiple lanes connected.  This includes the definition up to 7 entries that indicate which
lane number on the slave devices (array index starting at 1) maps to which other device:

```
chip drivers/soundwire/multilane_codec
	register "multilane.lane_mapping" = "{
		{
			# Slave Lane 1 maps to Master Lane 2
			.lane = 1,
			.direction = MASTER_LANE,
			.connection.master_lane = 2
		},
		{
			# Slave Lane 3 maps to Slave Link B
			.lane = 3,
			.direction = SLAVE_LINK,
			.connection.slave_link = 1
		}
	}"
	device generic 0.0 on end
end
```

#### Data Port 0 Properties

SoundWire Data Port 0 (DP0) is a special port used for control and status operation relating
to the whole device interface, and as a special data port for bulk read/write operations.

The properties for data port 0 are different from that of data ports 1-14 and are about the
control channel behavior and the overall bulk register mode.

Data port 0 is not required to be supported by the slave device.

#### Bulk Register Access Mode Properties

Bulk Register Access (BRA) is an optional mechanism for transporting higher bandwidth of
register operations than the typical command mechanism.  The BRA protocol is a particular
format of the data on the (optional) data port 0 connection between the master and slave.

The BRA protocol may have alignment or timing requirements that are directly related to the
bus frequencies.  As a result there may be several configurations listed, for symmetry with
the audio modes paired with data ports 1-14.

#### Data Port 1-14 Properties

Data ports 1-14 are typically dedicated to streaming audio payloads, and each data port can
have from 1 to 8 channels.  There are different levels of data ports, with some registers
being required and supported on all data ports and some optional registers only being used
on some data ports.

Data ports can have both a sink and a source component, and the codec may support one or
both of these on each port.

Similar to data port 0 the properties defined here describe the capabilities and supported
features of each data port, and they may be configured separately.  For example the Maxim
MAX98373 codec supports a 32bit source data port for speaker output, and a 16bit sink data
port for speaker sense data.

#### Audio Mode Properties

Each data port may be tied to one or more audio modes.  The audio mode describes the actual
audio capabilities of the codec, including supported frequencies and sample rates.  These
modes can be shared by multiple data ports and do not need to be duplicated.

For example:

```
static struct soundwire_audio_mode audio_mode = {
	.bus_frequency_max = 24 * MHz,
	.bus_frequency_min = 24 * KHz,
	.max_sampling_frequency = 192 * KHz,
	.min_sampling_frequency = 8 * KHz,
};
static struct soundwire_dpn codec_dp1 = {
    [...]
	.port_audio_mode_count = 1,
	.port_audio_mode_list = {0}
};
static struct soundwire_dpn codec_dp3 = {
    [...]
	.port_audio_mode_count = 1,
	.port_audio_mode_list = {0}
};
```

### Generating Codec Properties

Once the properties are known it can generate the ACPI code with:

```c
struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
soundwire_gen_codec(dsd, &soundwire_codec, NULL);
acpi_dp_write(dsd);
```

If the codec needs to generate custom properties for links it can provide a callback
function to `soundwire_gen_codec()` instead of passing NULL:

```c
static void codec_dp_prop_cb(struct acpi_dp *dsd, unsigned int id,
                             struct soundwire_codec *codec)
{
	acpi_dp_add_integer(dsd, "custom-dp-property", 1);
}
```

#### Codec Address

SoundWire slave devices use a SoundWire defined ACPI _ADR that requires a 64-bit integer
and uses the master link ID and slave device unique ID to form a unique address for the
device on this controller.

SoundWire addresses must be distinguishable from all other slave devices on the same master
link, so multiple instances of the same manufacturer and part on the same master link will
need different unique IDs.  The value is typically determined by strapping pins on the codec
chip and can be decoded for this table with the codec datasheet and board schematics.

```c
/**
 * struct soundwire_address - SoundWire ACPI Device Address Encoding.
 * @version: SoundWire specification version from &enum soundwire_version.
 * @link_id: Zero-based SoundWire Link Number.
 * @unique_id: Unique ID for multiple devices.
 * @manufacturer_id: Manufacturer ID from include/device/mipi_ids.h.
 * @part_id: Vendor defined part ID.
 * @class: MIPI class encoding in &enum mipi_class.
 */
struct soundwire_address {
	enum soundwire_version version;
	uint8_t link_id;
	uint8_t unique_id;
	uint16_t manufacturer_id;
	uint16_t part_id;
	enum mipi_class class;
};
```

This ACPI address can be generated by calling the provided acpigen function:

    acpigen_write_ADR_soundwire_device(const struct soundwire_address *sdw);

### Mainboard

The mainboard needs to select appropriate drivers in `Kconfig` and define the topology in
`devicetree.cb` with the controllers and codecs that exist on the board.

The topology uses the **generic** device to describe SoundWire:

```c
struct generic_path {
	unsigned int id;       /* SoundWire Master Link ID */
	unsigned int subid;    /* SoundWire Slave Unique ID */
};
```

This allows devices to be specified in `devicetree.cb` with the necessary information to
generate ACPI address and device properties.

```
chip drivers/intel/soundwire
	# SoundWire Controller 0
	device generic 0 on
		chip drivers/soundwire/codec1
			# SoundWire Link 0 ID 0
			device generic 0.0 on end
		end
		chip drivers/soundwire/codec2
			# SoundWire Link 1 ID 2
			device generic 1.2 on end
		end
	end
end
```

## Volteer Example

This is an example of an Intel Tiger Lake reference board using SoundWire Link 0 for the
headphone codec connection, and Link 1 for connecting two speaker amps for stereo speakers.

The mainboard can be found at

    src/mainboard/google/volteer

```
  +------------------+         +-------------------+
  |                  |         | Headphone Codec   |
  | Intel Tiger Lake |    +--->| Realtek ALC5682   |
  |    SoundWire     |    |    |       ID 1        |
  |    Controller    |    |    +-------------------+
  |                  |    |
  |           Link 0 +----+    +-------------------+
  |                  |         | Left Speaker Amp  |
  |           Link 1 +----+--->| Maxim MAX98373    |
  |                  |    |    |       ID 3        |
  |           Link 2 |    |    +-------------------+
  |                  |    |
  |           Link 3 |    |    +-------------------+
  |                  |    |    | Right Speaker Amp |
  +------------------+    +--->| Maxim MAX98373    |
                               |       ID 7        |
                               +-------------------+
```

This implementation requires a controller driver for the Intel Tigerlake SoC and a codec
driver for the Realtek and Maxim chips.  If those drivers did not already exist they would
need to be added and reviewed separately before adding the support to the mainboard.

The volteer example requires some `Kconfig` options to be selected:

```
config BOARD_GOOGLE_BASEBOARD_VOLTEER
	select DRIVERS_INTEL_SOUNDWIRE
	select DRIVERS_SOUNDWIRE_ALC5682
	select DRIVERS_SOUNDWIRE_MAX98373
```

And the following `devicetree.cb` entries to define this topology:

```
device pci 1f.3 on
	chip drivers/intel/soundwire
		# SoundWire Controller 0
		device generic 0 on
			chip drivers/soundwire/alc5682
				# SoundWire Link 0 ID 1
				register "desc" = ""Headphone Jack""
				device generic 0.1 on end
			end
			chip drivers/soundwire/max98373
				# SoundWire Link 0 ID 1
				register "desc" = ""Left Speaker Amp""
				device generic 1.3 on end
			end
			chip drivers/soundwire/max98373
				# SoundWire Link 1 ID 7
				register "desc" = ""Right Speaker Amp""
				device generic 1.7 on end
			end
		end
	end
end
```