Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/sdca/sdca_device.c
50904 views
1
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2
// Copyright(c) 2024 Intel Corporation
3
4
/*
5
* The MIPI SDCA specification is available for public downloads at
6
* https://www.mipi.org/mipi-sdca-v1-0-download
7
*/
8
9
#include <linux/acpi.h>
10
#include <linux/device.h>
11
#include <linux/dmi.h>
12
#include <linux/module.h>
13
#include <linux/property.h>
14
#include <linux/soundwire/sdw.h>
15
#include <sound/sdca.h>
16
#include <sound/sdca_function.h>
17
18
void sdca_lookup_interface_revision(struct sdw_slave *slave)
19
{
20
struct fwnode_handle *fwnode = slave->dev.fwnode;
21
22
/*
23
* if this property is not present, then the sdca_interface_revision will
24
* remain zero, which will be considered as 'not defined' or 'invalid'.
25
*/
26
fwnode_property_read_u32(fwnode, "mipi-sdw-sdca-interface-revision",
27
&slave->sdca_data.interface_revision);
28
}
29
EXPORT_SYMBOL_NS(sdca_lookup_interface_revision, "SND_SOC_SDCA");
30
31
static void devm_acpi_table_put(void *ptr)
32
{
33
acpi_put_table((struct acpi_table_header *)ptr);
34
}
35
36
void sdca_lookup_swft(struct sdw_slave *slave)
37
{
38
acpi_status status;
39
40
status = acpi_get_table(ACPI_SIG_SWFT, 0,
41
(struct acpi_table_header **)&slave->sdca_data.swft);
42
if (ACPI_FAILURE(status))
43
dev_info(&slave->dev, "SWFT not available\n");
44
else
45
devm_add_action_or_reset(&slave->dev, devm_acpi_table_put,
46
&slave->sdca_data.swft);
47
}
48
EXPORT_SYMBOL_NS(sdca_lookup_swft, "SND_SOC_SDCA");
49
50
static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave)
51
{
52
struct sdw_slave_id *id = &slave->id;
53
int i;
54
55
/*
56
* The RT712_VA relies on the v06r04 draft, and the
57
* RT712_VB on a more recent v08r01 draft.
58
*/
59
if (slave->sdca_data.interface_revision < 0x0801)
60
return false;
61
62
if (id->mfg_id != 0x025d)
63
return false;
64
65
if (id->part_id != 0x712 &&
66
id->part_id != 0x713 &&
67
id->part_id != 0x716 &&
68
id->part_id != 0x717)
69
return false;
70
71
for (i = 0; i < slave->sdca_data.num_functions; i++) {
72
if (slave->sdca_data.function[i].type == SDCA_FUNCTION_TYPE_SMART_MIC)
73
return true;
74
}
75
76
return false;
77
}
78
79
static bool sdca_device_quirk_skip_func_type_patching(struct sdw_slave *slave)
80
{
81
const char *vendor, *sku;
82
83
vendor = dmi_get_system_info(DMI_SYS_VENDOR);
84
sku = dmi_get_system_info(DMI_PRODUCT_SKU);
85
86
if (vendor && sku &&
87
!strcmp(vendor, "Dell Inc.") &&
88
(!strcmp(sku, "0C62") || !strcmp(sku, "0C63") || !strcmp(sku, "0C6B")) &&
89
slave->sdca_data.interface_revision == 0x061c &&
90
slave->id.mfg_id == 0x01fa && slave->id.part_id == 0x4243)
91
return true;
92
93
return false;
94
}
95
96
bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
97
{
98
switch (quirk) {
99
case SDCA_QUIRKS_RT712_VB:
100
return sdca_device_quirk_rt712_vb(slave);
101
case SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING:
102
return sdca_device_quirk_skip_func_type_patching(slave);
103
default:
104
break;
105
}
106
return false;
107
}
108
EXPORT_SYMBOL_NS(sdca_device_quirk_match, "SND_SOC_SDCA");
109
110