SoundWire子系统概述¶
SoundWire是由MIPI联盟于2015年批准的一项新接口。 SoundWire用于传输通常与音频功能相关的数据。SoundWire接口经过优化,可将音频设备集成到移动或移动启发式系统中。
SoundWire是具有数据和时钟线的2针多点接口。 它有助于开发低成本,高效,高性能的系统。 SoundWire接口的广泛关键特性包括
通过单个两针接口传输所有有效负载数据通道,控制信息和设置命令。
通过使用DDR(双倍数据速率)数据传输来降低时钟频率,从而降低功耗。
时钟缩放和可选的多个数据通道可在数据速率方面提供广泛的灵活性,以满足系统要求。
设备状态监视,包括中断式警报到Master。
SoundWire协议最多支持十一个Slave接口。 所有接口共享包含数据和时钟线的公共总线。 每个Slave最多可以支持14个数据端口。 13个数据端口专用于音频传输。 数据端口0专用于Bulk控制信息的传输,每个音频数据端口(1..14)可以在发送或接收模式下最多支持8个通道(通常是固定方向,但规范允许配置方向)。 但是,带宽限制约为19.2..24.576Mbits/s,不允许同时传输11*13*8个通道。
下图显示了SoundWire Master和两个Slave设备之间的连接示例。
+---------------+ +---------------+
| | Clock Signal | |
| Master |-------+-------------------------------| Slave |
| Interface | | Data Signal | Interface 1 |
| |-------|-------+-----------------------| |
+---------------+ | | +---------------+
| |
| |
| |
+--+-------+--+
| |
| Slave |
| Interface 2 |
| |
+-------------+
术语¶
MIPI SoundWire规范使用术语“device”来指代Master或Slave接口,这当然可能令人困惑。 在本概述和代码中,我们仅使用术语interface来指代硬件。 我们遵循Linux设备模型,通过将连接到总线上的每个Slave接口映射为由特定驱动程序管理的设备。 Linux SoundWire子系统提供了一个框架来实现SoundWire Slave驱动程序,该框架提供了一个API,允许第三方供应商启用实现定义的功能,而常见的设置/配置任务由总线处理。
总线:实现SoundWire Linux总线,该总线处理SoundWire协议。 编程所有MIPI定义的Slave寄存器。 代表SoundWire Master。 系统中可能存在总线的多个实例。
Slave:注册为SoundWire Slave设备(Linux设备)。 多个Slave设备可以注册到总线实例。
Slave驱动程序:控制Slave设备的驱动程序。 MIPI指定的寄存器由总线直接控制(并通过Master驱动程序/接口传输)。 任何实现定义的Slave寄存器都由Slave驱动程序控制。 实际上,预计Slave驱动程序依赖于regmap,并且不请求直接寄存器访问。
编程接口(SoundWire Master接口驱动程序)¶
SoundWire总线支持SoundWire Master实现和SoundWire Slave设备的编程接口。 所有代码都使用SoC设计人员和第三方供应商常用的“sdw”前缀。
每个SoundWire Master接口都需要注册到总线。 总线实现API来读取标准Master MIPI属性,并且还提供Master ops中的回调,供Master驱动程序实现其自己的功能以提供功能信息。 此时尚未实现DT支持,但是由于可以使用device_property_
API启用功能,因此添加DT支持应该很简单。
Master接口以及Master接口功能基于板文件,DT或ACPI进行注册。
以下是注册SoundWire总线的总线API
int sdw_bus_master_add(struct sdw_bus *bus,
struct device *parent,
struct fwnode_handle)
{
sdw_master_device_add(bus, parent, fwnode);
mutex_init(&bus->lock);
INIT_LIST_HEAD(&bus->slaves);
/* Check ACPI for Slave devices */
sdw_acpi_find_slaves(bus);
/* Check DT for Slave devices */
sdw_of_find_slaves(bus);
return 0;
}
这将为Master设备初始化sdw_bus对象。 向总线提供“sdw_master_ops”和“sdw_master_port_ops”回调函数。
总线使用“sdw_master_ops”以硬件特定的方式控制总线。 它包括总线控制功能,例如在总线上发送SoundWire读取/写入消息,设置时钟频率和流同步点(SSP)。 “sdw_master_ops”结构从总线中抽象出Master的硬件详细信息。
总线使用“sdw_master_port_ops”来设置Master接口端口的端口参数。 MIPI规范未定义Master接口端口寄存器映射,因此总线调用“sdw_master_port_ops”回调函数来执行端口操作,例如“端口准备”,“端口传输参数设置”,“端口启用和禁用”。 然后,Master驱动程序的实现可以执行特定于硬件的配置。
编程接口(SoundWire Slave驱动程序)¶
MIPI规范要求每个Slave接口公开一个唯一的48位标识符,该标识符存储在6个只读dev_id寄存器中。 此dev_id标识符包含供应商和部件信息,以及一个字段,用于区分相同的组件。 附加的类字段当前未使用。 Slave驱动程序是为特定的供应商和部件标识符编写的,总线基于这两个ID枚举Slave设备。 Slave设备和驱动程序的匹配是基于这两个ID完成的。 总线在设备和驱动程序ID成功匹配后调用Slave驱动程序的探测。 在Master和Slave设备之间强制执行父/子关系(逻辑表示形式与物理连接对齐)。
有关Master/Slave依赖关系的信息存储在平台数据,板文件,ACPI或DT中。 MIPI软件规范为具有多个Master接口的控制器定义了附加的link_id参数。 dev_id寄存器仅在链接范围内是唯一的,link_id在控制器范围内是唯一的。 dev_id和link_id在系统级别上不一定是唯一的,但是父/子信息用于避免歧义。
static const struct sdw_device_id slave_id[] = {
SDW_SLAVE_ENTRY(0x025d, 0x700, 0),
{},
};
MODULE_DEVICE_TABLE(sdw, slave_id);
static struct sdw_driver slave_sdw_driver = {
.driver = {
.name = "slave_xxx",
.pm = &slave_runtime_pm,
},
.probe = slave_sdw_probe,
.remove = slave_sdw_remove,
.ops = &slave_slave_ops,
.id_table = slave_id,
};
对于功能,总线实现API来读取标准Slave MIPI属性,并且还提供Slave ops中的回调,供Slave驱动程序实现自己的功能以提供功能信息。 总线需要知道一组Slave功能来编程Slave寄存器并控制总线重新配置。
链接¶
SoundWire MIPI规范1.1可在以下网址获得:https://members.mipi.org/wg/All-Members/document/70290
SoundWire MIPI DisCo(发现和配置)规范可在以下网址获得:https://www.mipi.org/specifications/mipi-disco-soundwire
(通过注册公开访问,或者MIPI会员可以直接访问)
MIPI联盟制造商ID页面:mid.mipi.org