mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 02:24:24 +02:00
ASoC: SDCA: Add support for IT/OT Entity properties
Add support for parsing the Input/Output Terminal Entity properties from DisCo/ACPI. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> Link: https://patch.msgid.link/20250205113801.3699902-9-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
f87c2a2750
commit
5c93b20f6d
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/types.h>
|
||||
|
||||
struct device;
|
||||
struct sdca_entity;
|
||||
struct sdca_function_desc;
|
||||
|
||||
/*
|
||||
|
|
@ -671,6 +672,118 @@ struct sdca_control {
|
|||
bool has_fixed;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sdca_terminal_type - SDCA Terminal Types
|
||||
*
|
||||
* Indicate what a Terminal Entity is used for, see in section 6.2.3
|
||||
* of the SDCA v1.0 specification.
|
||||
*/
|
||||
enum sdca_terminal_type {
|
||||
/* Table 77 - Data Port*/
|
||||
SDCA_TERM_TYPE_GENERIC = 0x101,
|
||||
SDCA_TERM_TYPE_ULTRASOUND = 0x180,
|
||||
SDCA_TERM_TYPE_CAPTURE_DIRECT_PCM_MIC = 0x181,
|
||||
SDCA_TERM_TYPE_RAW_PDM_MIC = 0x182,
|
||||
SDCA_TERM_TYPE_SPEECH = 0x183,
|
||||
SDCA_TERM_TYPE_VOICE = 0x184,
|
||||
SDCA_TERM_TYPE_SECONDARY_PCM_MIC = 0x185,
|
||||
SDCA_TERM_TYPE_ACOUSTIC_CONTEXT_AWARENESS = 0x186,
|
||||
SDCA_TERM_TYPE_DTOD_STREAM = 0x187,
|
||||
SDCA_TERM_TYPE_REFERENCE_STREAM = 0x188,
|
||||
SDCA_TERM_TYPE_SENSE_CAPTURE = 0x189,
|
||||
SDCA_TERM_TYPE_STREAMING_MIC = 0x18A,
|
||||
SDCA_TERM_TYPE_OPTIMIZATION_STREAM = 0x190,
|
||||
SDCA_TERM_TYPE_PDM_RENDER_STREAM = 0x191,
|
||||
SDCA_TERM_TYPE_COMPANION_DATA = 0x192,
|
||||
/* Table 78 - Transducer */
|
||||
SDCA_TERM_TYPE_MICROPHONE_TRANSDUCER = 0x201,
|
||||
SDCA_TERM_TYPE_MICROPHONE_ARRAY_TRANSDUCER = 0x205,
|
||||
SDCA_TERM_TYPE_PRIMARY_FULL_RANGE_SPEAKER = 0x380,
|
||||
SDCA_TERM_TYPE_PRIMARY_LFE_SPEAKER = 0x381,
|
||||
SDCA_TERM_TYPE_PRIMARY_TWEETER_SPEAKER = 0x382,
|
||||
SDCA_TERM_TYPE_PRIMARY_ULTRASOUND_SPEAKER = 0x383,
|
||||
SDCA_TERM_TYPE_SECONDARY_FULL_RANGE_SPEAKER = 0x390,
|
||||
SDCA_TERM_TYPE_SECONDARY_LFE_SPEAKER = 0x391,
|
||||
SDCA_TERM_TYPE_SECONDARY_TWEETER_SPEAKER = 0x392,
|
||||
SDCA_TERM_TYPE_SECONDARY_ULTRASOUND_SPEAKER = 0x393,
|
||||
SDCA_TERM_TYPE_TERTIARY_FULL_RANGE_SPEAKER = 0x3A0,
|
||||
SDCA_TERM_TYPE_TERTIARY_LFE_SPEAKER = 0x3A1,
|
||||
SDCA_TERM_TYPE_TERTIARY_TWEETER_SPEAKER = 0x3A2,
|
||||
SDCA_TERM_TYPE_TERTIARY_ULTRASOUND_SPEAKER = 0x3A3,
|
||||
SDCA_TERM_TYPE_SPDIF = 0x605,
|
||||
SDCA_TERM_TYPE_NDAI_DISPLAY_AUDIO = 0x610,
|
||||
SDCA_TERM_TYPE_NDAI_USB = 0x612,
|
||||
SDCA_TERM_TYPE_NDAI_BLUETOOTH_MAIN = 0x614,
|
||||
SDCA_TERM_TYPE_NDAI_BLUETOOTH_ALTERNATE = 0x615,
|
||||
SDCA_TERM_TYPE_NDAI_BLUETOOTH_BOTH = 0x616,
|
||||
SDCA_TERM_TYPE_LINEIN_STEREO = 0x680,
|
||||
SDCA_TERM_TYPE_LINEIN_FRONT_LR = 0x681,
|
||||
SDCA_TERM_TYPE_LINEIN_CENTER_LFE = 0x682,
|
||||
SDCA_TERM_TYPE_LINEIN_SURROUND_LR = 0x683,
|
||||
SDCA_TERM_TYPE_LINEIN_REAR_LR = 0x684,
|
||||
SDCA_TERM_TYPE_LINEOUT_STEREO = 0x690,
|
||||
SDCA_TERM_TYPE_LINEOUT_FRONT_LR = 0x691,
|
||||
SDCA_TERM_TYPE_LINEOUT_CENTER_LFE = 0x692,
|
||||
SDCA_TERM_TYPE_LINEOUT_SURROUND_LR = 0x693,
|
||||
SDCA_TERM_TYPE_LINEOUT_REAR_LR = 0x694,
|
||||
SDCA_TERM_TYPE_MIC_JACK = 0x6A0,
|
||||
SDCA_TERM_TYPE_STEREO_JACK = 0x6B0,
|
||||
SDCA_TERM_TYPE_FRONT_LR_JACK = 0x6B1,
|
||||
SDCA_TERM_TYPE_CENTER_LFE_JACK = 0x6B2,
|
||||
SDCA_TERM_TYPE_SURROUND_LR_JACK = 0x6B3,
|
||||
SDCA_TERM_TYPE_REAR_LR_JACK = 0x6B4,
|
||||
SDCA_TERM_TYPE_HEADPHONE_JACK = 0x6C0,
|
||||
SDCA_TERM_TYPE_HEADSET_JACK = 0x6D0,
|
||||
/* Table 79 - System */
|
||||
SDCA_TERM_TYPE_SENSE_DATA = 0x280,
|
||||
SDCA_TERM_TYPE_PRIVACY_SIGNALING = 0x741,
|
||||
SDCA_TERM_TYPE_PRIVACY_INDICATORS = 0x747,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sdca_connector_type - SDCA Connector Types
|
||||
*
|
||||
* Indicate the type of Connector that a Terminal Entity represents,
|
||||
* see section 6.2.4 of the SDCA v1.0 specification.
|
||||
*/
|
||||
enum sdca_connector_type {
|
||||
SDCA_CONN_TYPE_UNKNOWN = 0x00,
|
||||
SDCA_CONN_TYPE_2P5MM_JACK = 0x01,
|
||||
SDCA_CONN_TYPE_3P5MM_JACK = 0x02,
|
||||
SDCA_CONN_TYPE_QUARTER_INCH_JACK = 0x03,
|
||||
SDCA_CONN_TYPE_XLR = 0x05,
|
||||
SDCA_CONN_TYPE_SPDIF_OPTICAL = 0x06,
|
||||
SDCA_CONN_TYPE_RCA = 0x07,
|
||||
SDCA_CONN_TYPE_DIN = 0x0E,
|
||||
SDCA_CONN_TYPE_MINI_DIN = 0x0F,
|
||||
SDCA_CONN_TYPE_EIAJ_OPTICAL = 0x13,
|
||||
SDCA_CONN_TYPE_HDMI = 0x14,
|
||||
SDCA_CONN_TYPE_DISPLAYPORT = 0x17,
|
||||
SDCA_CONN_TYPE_LIGHTNING = 0x1B,
|
||||
SDCA_CONN_TYPE_USB_C = 0x1E,
|
||||
SDCA_CONN_TYPE_OTHER = 0xFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sdca_entity_iot - information specific to Input/Output Entities
|
||||
* @clock: Pointer to the Entity providing this Terminal's clock.
|
||||
* @type: Usage of the Terminal Entity.
|
||||
* @connector: Physical Connector of the Terminal Entity.
|
||||
* @reference: Physical Jack number of the Terminal Entity.
|
||||
* @num_transducer: Number of transducers attached to the Terminal Entity.
|
||||
* @is_dataport: Boolean indicating if this Terminal represents a Dataport.
|
||||
*/
|
||||
struct sdca_entity_iot {
|
||||
struct sdca_entity *clock;
|
||||
|
||||
enum sdca_terminal_type type;
|
||||
enum sdca_connector_type connector;
|
||||
int reference;
|
||||
int num_transducer;
|
||||
|
||||
bool is_dataport;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sdca_entity_type - SDCA Entity Type codes
|
||||
* @SDCA_ENTITY_TYPE_ENTITY_0: Entity 0, not actually from the
|
||||
|
|
@ -732,6 +845,7 @@ enum sdca_entity_type {
|
|||
* @controls: Dynamically allocated array of Controls.
|
||||
* @num_sources: Number of sources for the Entity.
|
||||
* @num_controls: Number of Controls for the Entity.
|
||||
* @iot: Input/Output Terminal specific Entity properties.
|
||||
*/
|
||||
struct sdca_entity {
|
||||
const char *label;
|
||||
|
|
@ -742,6 +856,9 @@ struct sdca_entity {
|
|||
struct sdca_control *controls;
|
||||
int num_sources;
|
||||
int num_controls;
|
||||
union {
|
||||
struct sdca_entity_iot iot;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -818,6 +818,69 @@ static int find_sdca_entity_controls(struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool find_sdca_iot_dataport(struct sdca_entity_iot *terminal)
|
||||
{
|
||||
switch (terminal->type) {
|
||||
case SDCA_TERM_TYPE_GENERIC:
|
||||
case SDCA_TERM_TYPE_ULTRASOUND:
|
||||
case SDCA_TERM_TYPE_CAPTURE_DIRECT_PCM_MIC:
|
||||
case SDCA_TERM_TYPE_RAW_PDM_MIC:
|
||||
case SDCA_TERM_TYPE_SPEECH:
|
||||
case SDCA_TERM_TYPE_VOICE:
|
||||
case SDCA_TERM_TYPE_SECONDARY_PCM_MIC:
|
||||
case SDCA_TERM_TYPE_ACOUSTIC_CONTEXT_AWARENESS:
|
||||
case SDCA_TERM_TYPE_DTOD_STREAM:
|
||||
case SDCA_TERM_TYPE_REFERENCE_STREAM:
|
||||
case SDCA_TERM_TYPE_SENSE_CAPTURE:
|
||||
case SDCA_TERM_TYPE_STREAMING_MIC:
|
||||
case SDCA_TERM_TYPE_OPTIMIZATION_STREAM:
|
||||
case SDCA_TERM_TYPE_PDM_RENDER_STREAM:
|
||||
case SDCA_TERM_TYPE_COMPANION_DATA:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int find_sdca_entity_iot(struct device *dev,
|
||||
struct fwnode_handle *entity_node,
|
||||
struct sdca_entity *entity)
|
||||
{
|
||||
struct sdca_entity_iot *terminal = &entity->iot;
|
||||
u32 tmp;
|
||||
int ret;
|
||||
|
||||
ret = fwnode_property_read_u32(entity_node, "mipi-sdca-terminal-type", &tmp);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: terminal type missing: %d\n", entity->label, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
terminal->type = tmp;
|
||||
terminal->is_dataport = find_sdca_iot_dataport(terminal);
|
||||
|
||||
ret = fwnode_property_read_u32(entity_node,
|
||||
"mipi-sdca-terminal-reference-number", &tmp);
|
||||
if (!ret)
|
||||
terminal->reference = tmp;
|
||||
|
||||
ret = fwnode_property_read_u32(entity_node,
|
||||
"mipi-sdca-terminal-connector-type", &tmp);
|
||||
if (!ret)
|
||||
terminal->connector = tmp;
|
||||
|
||||
ret = fwnode_property_read_u32(entity_node,
|
||||
"mipi-sdca-terminal-transducer-count", &tmp);
|
||||
if (!ret)
|
||||
terminal->num_transducer = tmp;
|
||||
|
||||
dev_info(dev, "%s: terminal type %#x ref %#x conn %#x count %d\n",
|
||||
entity->label, terminal->type, terminal->reference,
|
||||
terminal->connector, terminal->num_transducer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_sdca_entity(struct device *dev,
|
||||
struct fwnode_handle *function_node,
|
||||
struct fwnode_handle *entity_node,
|
||||
|
|
@ -845,6 +908,17 @@ static int find_sdca_entity(struct device *dev,
|
|||
dev_info(dev, "%s: entity %#x type %#x\n",
|
||||
entity->label, entity->id, entity->type);
|
||||
|
||||
switch (entity->type) {
|
||||
case SDCA_ENTITY_TYPE_IT:
|
||||
case SDCA_ENTITY_TYPE_OT:
|
||||
ret = find_sdca_entity_iot(dev, entity_node, entity);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = find_sdca_entity_controls(dev, entity_node, entity);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -943,6 +1017,46 @@ static struct sdca_entity *find_sdca_entity_by_label(struct sdca_function_data *
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int find_sdca_entity_connection_iot(struct device *dev,
|
||||
struct sdca_function_data *function,
|
||||
struct fwnode_handle *entity_node,
|
||||
struct sdca_entity *entity)
|
||||
{
|
||||
struct sdca_entity_iot *terminal = &entity->iot;
|
||||
struct fwnode_handle *clock_node;
|
||||
struct sdca_entity *clock_entity;
|
||||
const char *clock_label;
|
||||
int ret;
|
||||
|
||||
clock_node = fwnode_get_named_child_node(entity_node,
|
||||
"mipi-sdca-terminal-clock-connection");
|
||||
if (!clock_node)
|
||||
return 0;
|
||||
|
||||
ret = fwnode_property_read_string(clock_node, "mipi-sdca-entity-label",
|
||||
&clock_label);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: clock label missing: %d\n", entity->label, ret);
|
||||
fwnode_handle_put(clock_node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
clock_entity = find_sdca_entity_by_label(function, clock_label);
|
||||
if (!clock_entity) {
|
||||
dev_err(dev, "%s: failed to find clock with label %s\n",
|
||||
entity->label, clock_label);
|
||||
fwnode_handle_put(clock_node);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
terminal->clock = clock_entity;
|
||||
|
||||
dev_info(dev, "%s -> %s\n", clock_entity->label, entity->label);
|
||||
|
||||
fwnode_handle_put(clock_node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_sdca_entity_connection(struct device *dev,
|
||||
struct sdca_function_data *function,
|
||||
struct fwnode_handle *entity_node,
|
||||
|
|
@ -953,6 +1067,19 @@ static int find_sdca_entity_connection(struct device *dev,
|
|||
u64 pin_list;
|
||||
int i, ret;
|
||||
|
||||
switch (entity->type) {
|
||||
case SDCA_ENTITY_TYPE_IT:
|
||||
case SDCA_ENTITY_TYPE_OT:
|
||||
ret = find_sdca_entity_connection_iot(dev, function,
|
||||
entity_node, entity);
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = fwnode_property_read_u64(entity_node, "mipi-sdca-input-pin-list", &pin_list);
|
||||
if (ret == -EINVAL) {
|
||||
/* Allow missing pin lists, assume no pins. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user