Skip to content
48 changes: 48 additions & 0 deletions include/sound/sdca_asoc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* The MIPI SDCA specification is available for public downloads at
* https://www.mipi.org/mipi-sdca-v1-0-download
*
* Copyright (C) 2025 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/

#ifndef __SDCA_ASOC_H__
#define __SDCA_ASOC_H__

struct device;
struct regmap;
struct sdca_function_data;
struct snd_kcontrol_new;
struct snd_soc_component_driver;
struct snd_soc_dai;
struct snd_soc_dai_driver;
struct snd_soc_dai_ops;
struct snd_soc_dapm_route;
struct snd_soc_dapm_widget;

int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function,
int *num_widgets, int *num_routes, int *num_controls,
int *num_dais);

int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *function,
struct snd_soc_dapm_widget *widgets,
struct snd_soc_dapm_route *routes);
int sdca_asoc_populate_controls(struct device *dev,
struct sdca_function_data *function,
struct snd_kcontrol_new *kctl);
int sdca_asoc_populate_dais(struct device *dev, struct sdca_function_data *function,
struct snd_soc_dai_driver *dais,
const struct snd_soc_dai_ops *ops);

int sdca_asoc_populate_component(struct device *dev,
struct sdca_function_data *function,
struct snd_soc_component_driver *component_drv,
struct snd_soc_dai_driver **dai_drv, int *num_dai_drv,
const struct snd_soc_dai_ops *ops);

int sdca_asoc_get_port(struct device *dev, struct regmap *regmap,
struct sdca_function_data *function,
struct snd_soc_dai *dai);

#endif // __SDCA_ASOC_H__
168 changes: 168 additions & 0 deletions include/sound/sdca_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ struct sdca_function_desc;
*/
#define SDCA_MAX_DELAY_COUNT 256

/*
* Sanity check on size of affected controls data, can be expanded if needed.
*/
#define SDCA_MAX_AFFECTED_COUNT 2048


/**
* enum sdca_function_type - SDCA Function Type codes
* @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features.
Expand Down Expand Up @@ -163,6 +169,28 @@ enum sdca_ot_controls {
SDCA_CTL_OT_NDAI_PACKETTYPE = 0x17,
};

/**
* enum sdca_usage_range - Column definitions for Usage
*/
enum sdca_usage_range {
SDCA_USAGE_NUMBER = 0,
SDCA_USAGE_CBN = 1,
SDCA_USAGE_SAMPLE_RATE = 2,
SDCA_USAGE_SAMPLE_WIDTH = 3,
SDCA_USAGE_FULL_SCALE = 4,
SDCA_USAGE_NOISE_FLOOR = 5,
SDCA_USAGE_TAG = 6,
SDCA_USAGE_NCOLS = 7,
};

/**
* enum sdca_dataport_selector_range - Column definitions for DataPort_Selector
*/
enum sdca_dataport_selector_range {
SDCA_DATAPORT_SELECTOR_NCOLS = 16,
SDCA_DATAPORT_SELECTOR_NROWS = 4,
};

/**
* enum sdca_mu_controls - SDCA Controls for Mixer Unit
*
Expand Down Expand Up @@ -201,6 +229,16 @@ enum sdca_fu_controls {
SDCA_CTL_FU_LATENCY = 0x10,
};

/**
* enum sdca_volume_range - Column definitions for Q7.8dB volumes/gains
*/
enum sdca_volume_range {
SDCA_VOLUME_LINEAR_MIN = 0,
SDCA_VOLUME_LINEAR_MAX = 1,
SDCA_VOLUME_LINEAR_STEP = 2,
SDCA_VOLUME_LINEAR_NCOLS = 3,
};

/**
* enum sdca_xu_controls - SDCA Controls for Extension Unit
*
Expand Down Expand Up @@ -231,6 +269,15 @@ enum sdca_cs_controls {
SDCA_CTL_CS_SAMPLERATEINDEX = 0x10,
};

/**
* enum sdca_samplerateindex_range - Column definitions for SampleRateIndex
*/
enum sdca_samplerateindex_range {
SDCA_SAMPLERATEINDEX_INDEX = 0,
SDCA_SAMPLERATEINDEX_RATE = 1,
SDCA_SAMPLERATEINDEX_NCOLS = 2,
};

/**
* enum sdca_cx_controls - SDCA Controls for Clock Selector
*
Expand All @@ -252,6 +299,14 @@ enum sdca_pde_controls {
SDCA_CTL_PDE_ACTUAL_PS = 0x10,
};

/**
* enum sdca_requested_ps_range - Column definitions for Requested PS
*/
enum sdca_requested_ps_range {
SDCA_REQUESTED_PS_STATE = 0,
SDCA_REQUESTED_PS_NCOLS = 1,
};

/**
* enum sdca_ge_controls - SDCA Controls for Group Unit
*
Expand All @@ -263,6 +318,15 @@ enum sdca_ge_controls {
SDCA_CTL_GE_DETECTED_MODE = 0x02,
};

/**
* enum sdca_selected_mode_range - Column definitions for Selected Mode
*/
enum sdca_selected_mode_range {
SDCA_SELECTED_MODE_INDEX = 0,
SDCA_SELECTED_MODE_TERM_TYPE = 1,
SDCA_SELECTED_MODE_NCOLS = 2,
};

/**
* enum sdca_spe_controls - SDCA Controls for Security & Privacy Unit
*
Expand Down Expand Up @@ -600,6 +664,27 @@ enum sdca_entity0_controls {
#define SDCA_CTL_DEVICE_VERSION_NAME "Device Version"
#define SDCA_CTL_DEVICE_SDCA_VERSION_NAME "Device SDCA Version"

/**
* enum sdca_control_datatype - SDCA Control Data Types
*
* Data Types as described in the SDCA specification v1.0 section
* 7.3.
*/
enum sdca_control_datatype {
SDCA_CTL_DATATYPE_ONEBIT,
SDCA_CTL_DATATYPE_INTEGER,
SDCA_CTL_DATATYPE_SPEC_ENCODED_VALUE,
SDCA_CTL_DATATYPE_BCD,
SDCA_CTL_DATATYPE_Q7P8DB,
SDCA_CTL_DATATYPE_BYTEINDEX,
SDCA_CTL_DATATYPE_POSTURENUMBER,
SDCA_CTL_DATATYPE_DP_INDEX,
SDCA_CTL_DATATYPE_BITINDEX,
SDCA_CTL_DATATYPE_BITMAP,
SDCA_CTL_DATATYPE_GUID,
SDCA_CTL_DATATYPE_IMPDEF,
};

/**
* enum sdca_access_mode - SDCA Control access mode
*
Expand Down Expand Up @@ -653,6 +738,7 @@ struct sdca_control_range {
* @cn_list: A bitmask showing the valid Control Numbers within this Control,
* Control Numbers typically represent channels.
* @range: Buffer describing valid range of values for the Control.
* @type: Format of the data in the Control.
* @mode: Access mode of the Control.
* @layers: Bitmask of access layers of the Control.
* @deferrable: Indicates if the access to the Control can be deferred.
Expand All @@ -669,6 +755,7 @@ struct sdca_control {
u64 cn_list;

struct sdca_control_range range;
enum sdca_control_datatype type;
enum sdca_access_mode mode;
u8 layers;

Expand Down Expand Up @@ -745,6 +832,25 @@ enum sdca_terminal_type {
SDCA_TERM_TYPE_PRIVACY_INDICATORS = 0x747,
};

#define SDCA_TERM_TYPE_LINEIN_STEREO_NAME "LineIn Stereo"
#define SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME "LineIn Front-LR"
#define SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME "LineIn Center-LFE"
#define SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME "LineIn Surround-LR"
#define SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME "LineIn Rear-LR"
#define SDCA_TERM_TYPE_LINEOUT_STEREO_NAME "LineOut Stereo"
#define SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME "LineOut Front-LR"
#define SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME "LineOut Center-LFE"
#define SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME "LineOut Surround-LR"
#define SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME "LineOut Rear-LR"
#define SDCA_TERM_TYPE_MIC_JACK_NAME "Microphone "
#define SDCA_TERM_TYPE_STEREO_JACK_NAME "Speaker Stereo"
#define SDCA_TERM_TYPE_FRONT_LR_JACK_NAME "Speaker Front-LR"
#define SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME "Speaker Center-LFE"
#define SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME "Speaker Surround-LR"
#define SDCA_TERM_TYPE_REAR_LR_JACK_NAME "Speaker Rear-LR"
#define SDCA_TERM_TYPE_HEADPHONE_JACK_NAME "Headphone"
#define SDCA_TERM_TYPE_HEADSET_JACK_NAME "Headset"

/**
* enum sdca_connector_type - SDCA Connector Types
*
Expand Down Expand Up @@ -904,11 +1010,51 @@ enum sdca_entity_type {
SDCA_ENTITY_TYPE_HIDE = 0x31,
};

/**
* struct sdca_ge_control - control entry in the affected controls list
* @id: Entity ID of the Control affected.
* @sel: Control Selector of the Control affected.
* @cn: Control Number of the Control affected.
* @val: Value written to Control for this Mode.
*/
struct sdca_ge_control {
int id;
int sel;
int cn;
int val;
};

/**
* struct sdca_ge_mode - mode entry in the affected controls list
* @controls: Dynamically allocated array of controls written for this Mode.
* @num_controls: Number of controls written in this Mode.
* @val: GE Selector Mode value.
*/
struct sdca_ge_mode {
struct sdca_ge_control *controls;
int num_controls;
int val;
};

/**
* struct sdca_entity_ge - information specific to Group Entities
* @kctl: ALSA control pointer that can be used by linked Entities.
* @modes: Dynamically allocated array of Modes and the Controls written
* in each mode.
* @num_modes: Number of Modes.
*/
struct sdca_entity_ge {
struct snd_kcontrol_new *kctl;
struct sdca_ge_mode *modes;
int num_modes;
};

/**
* struct sdca_entity - information for one SDCA Entity
* @label: String such as "OT 12".
* @id: Identifier used for addressing.
* @type: Type code for the Entity.
* @group: Pointer to Group Entity controlling this one, NULL if N/A.
* @sources: Dynamically allocated array pointing to each input Entity
* connected to this Entity.
* @controls: Dynamically allocated array of Controls.
Expand All @@ -917,12 +1063,14 @@ enum sdca_entity_type {
* @iot: Input/Output Terminal specific Entity properties.
* @cs: Clock Source specific Entity properties.
* @pde: Power Domain Entity specific Entity properties.
* @ge: Group Entity specific Entity properties.
*/
struct sdca_entity {
const char *label;
int id;
enum sdca_entity_type type;

struct sdca_entity *group;
struct sdca_entity **sources;
struct sdca_control *controls;
int num_sources;
Expand All @@ -931,6 +1079,7 @@ struct sdca_entity {
struct sdca_entity_iot iot;
struct sdca_entity_cs cs;
struct sdca_entity_pde pde;
struct sdca_entity_ge ge;
};
};

Expand Down Expand Up @@ -1113,6 +1262,25 @@ struct sdca_function_data {
unsigned int busy_max_delay;
};

static inline u32 sdca_range(struct sdca_control_range *range,
unsigned int col, unsigned int row)
{
return range->data[(row * range->cols) + col];
}

static inline u32 sdca_range_search(struct sdca_control_range *range,
int search_col, int value, int result_col)
{
int i;

for (i = 0; i < range->rows; i++) {
if (sdca_range(range, search_col, i) == value)
return sdca_range(range, result_col, i);
}

return 0;
}

int sdca_parse_function(struct device *dev,
struct sdca_function_desc *desc,
struct sdca_function_data *function);
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sdca/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only

snd-soc-sdca-y := sdca_functions.o sdca_device.o sdca_regmap.o
snd-soc-sdca-y := sdca_functions.o sdca_device.o sdca_regmap.o sdca_asoc.o

obj-$(CONFIG_SND_SOC_SDCA) += snd-soc-sdca.o
Loading
Loading