Skip to content

Commit 50a4795

Browse files
charleskeepaxbroonie
authored andcommitted
ASoC: SDCA: Add support for -cn- value properties
Many of the DisCo properties that specify Control values have an additional variant that specifies a separate value for each Control Number. Add support for these. Signed-off-by: Charles Keepax <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 061fade commit 50a4795

File tree

3 files changed

+78
-48
lines changed

3 files changed

+78
-48
lines changed

include/sound/sdca_function.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -742,14 +742,14 @@ struct sdca_control_range {
742742
* struct sdca_control - information for one SDCA Control
743743
* @label: Name for the Control, from SDCA Specification v1.0, section 7.1.7.
744744
* @sel: Identifier used for addressing.
745-
* @value: Holds the Control value for constants and defaults.
746745
* @nbits: Number of bits used in the Control.
747-
* @interrupt_position: SCDA interrupt line that will alert to changes on this
748-
* Control.
746+
* @values: Holds the Control value for constants and defaults.
749747
* @cn_list: A bitmask showing the valid Control Numbers within this Control,
750748
* Control Numbers typically represent channels.
751-
* @range: Buffer describing valid range of values for the Control.
749+
* @interrupt_position: SCDA interrupt line that will alert to changes on this
750+
* Control.
752751
* @type: Format of the data in the Control.
752+
* @range: Buffer describing valid range of values for the Control.
753753
* @mode: Access mode of the Control.
754754
* @layers: Bitmask of access layers of the Control.
755755
* @deferrable: Indicates if the access to the Control can be deferred.
@@ -760,13 +760,13 @@ struct sdca_control {
760760
const char *label;
761761
int sel;
762762

763-
int value;
764763
int nbits;
765-
int interrupt_position;
764+
int *values;
766765
u64 cn_list;
766+
int interrupt_position;
767767

768-
struct sdca_control_range range;
769768
enum sdca_control_datatype type;
769+
struct sdca_control_range range;
770770
enum sdca_access_mode mode;
771771
u8 layers;
772772

sound/soc/sdca/sdca_functions.c

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,43 @@ static int find_sdca_control_range(struct device *dev,
814814
return 0;
815815
}
816816

817+
static int find_sdca_control_value(struct device *dev, struct sdca_entity *entity,
818+
struct fwnode_handle *control_node,
819+
struct sdca_control *control,
820+
const char * const label)
821+
{
822+
char property[SDCA_PROPERTY_LENGTH];
823+
bool global = true;
824+
int ret, cn, i;
825+
u32 tmp;
826+
827+
snprintf(property, sizeof(property), "mipi-sdca-control-%s", label);
828+
829+
ret = fwnode_property_read_u32(control_node, property, &tmp);
830+
if (ret == -EINVAL)
831+
global = false;
832+
else if (ret)
833+
return ret;
834+
835+
i = 0;
836+
for_each_set_bit(cn, (unsigned long *)&control->cn_list,
837+
BITS_PER_TYPE(control->cn_list)) {
838+
if (!global) {
839+
snprintf(property, sizeof(property),
840+
"mipi-sdca-control-cn-%d-%s", cn, label);
841+
842+
ret = fwnode_property_read_u32(control_node, property, &tmp);
843+
if (ret)
844+
return ret;
845+
}
846+
847+
control->values[i] = tmp;
848+
i++;
849+
}
850+
851+
return 0;
852+
}
853+
817854
/*
818855
* TODO: Add support for -cn- properties, allowing different channels to have
819856
* different defaults etc.
@@ -843,44 +880,44 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
843880

844881
control->layers = tmp;
845882

883+
ret = fwnode_property_read_u64(control_node, "mipi-sdca-control-cn-list",
884+
&control->cn_list);
885+
if (ret == -EINVAL) {
886+
/* Spec allows not specifying cn-list if only the first number is used */
887+
control->cn_list = 0x1;
888+
} else if (ret || !control->cn_list) {
889+
dev_err(dev, "%s: control %#x: cn list missing: %d\n",
890+
entity->label, control->sel, ret);
891+
return ret;
892+
}
893+
894+
control->values = devm_kzalloc(dev, hweight64(control->cn_list), GFP_KERNEL);
895+
if (!control->values)
896+
return -ENOMEM;
897+
846898
switch (control->mode) {
847899
case SDCA_ACCESS_MODE_DC:
848-
ret = fwnode_property_read_u32(control_node,
849-
"mipi-sdca-control-dc-value",
850-
&tmp);
900+
ret = find_sdca_control_value(dev, entity, control_node, control,
901+
"dc-value");
851902
if (ret) {
852903
dev_err(dev, "%s: control %#x: dc value missing: %d\n",
853904
entity->label, control->sel, ret);
854905
return ret;
855906
}
856907

857-
control->value = tmp;
858908
control->has_fixed = true;
859909
break;
860910
case SDCA_ACCESS_MODE_RW:
861911
case SDCA_ACCESS_MODE_DUAL:
862-
ret = fwnode_property_read_u32(control_node,
863-
"mipi-sdca-control-default-value",
864-
&tmp);
865-
if (!ret) {
866-
control->value = tmp;
912+
ret = find_sdca_control_value(dev, entity, control_node, control,
913+
"default-value");
914+
if (!ret)
867915
control->has_default = true;
868-
}
869-
870-
ret = fwnode_property_read_u32(control_node,
871-
"mipi-sdca-control-fixed-value",
872-
&tmp);
873-
if (!ret) {
874-
if (control->has_default && control->value != tmp) {
875-
dev_err(dev,
876-
"%s: control %#x: default and fixed value don't match\n",
877-
entity->label, control->sel);
878-
return -EINVAL;
879-
}
880916

881-
control->value = tmp;
917+
ret = find_sdca_control_value(dev, entity, control_node, control,
918+
"fixed-value");
919+
if (!ret)
882920
control->has_fixed = true;
883-
}
884921
fallthrough;
885922
case SDCA_ACCESS_MODE_RO:
886923
control->deferrable = fwnode_property_read_bool(control_node,
@@ -897,17 +934,6 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
897934
return ret;
898935
}
899936

900-
ret = fwnode_property_read_u64(control_node, "mipi-sdca-control-cn-list",
901-
&control->cn_list);
902-
if (ret == -EINVAL) {
903-
/* Spec allows not specifying cn-list if only the first number is used */
904-
control->cn_list = 0x1;
905-
} else if (ret || !control->cn_list) {
906-
dev_err(dev, "%s: control %#x: cn list missing: %d\n",
907-
entity->label, control->sel, ret);
908-
return ret;
909-
}
910-
911937
ret = fwnode_property_read_u32(control_node,
912938
"mipi-sdca-control-interrupt-position",
913939
&tmp);
@@ -923,11 +949,10 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
923949
control->type = find_sdca_control_datatype(entity, control);
924950
control->nbits = find_sdca_control_bits(entity, control);
925951

926-
dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d value %#x %s\n",
952+
dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d %s\n",
927953
entity->label, control->label, control->sel,
928954
control->mode, control->layers, control->cn_list,
929-
control->interrupt_position, control->value,
930-
control->deferrable ? "deferrable" : "");
955+
control->interrupt_position, control->deferrable ? "deferrable" : "");
931956

932957
return 0;
933958
}

sound/soc/sdca/sdca_regmap.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ int sdca_regmap_populate_constants(struct device *dev,
253253
struct sdca_function_data *function,
254254
struct reg_default *consts)
255255
{
256-
int i, j, k;
256+
int i, j, k, l;
257257

258258
for (i = 0, k = 0; i < function->num_entities; i++) {
259259
struct sdca_entity *entity = &function->entities[i];
@@ -265,13 +265,15 @@ int sdca_regmap_populate_constants(struct device *dev,
265265
if (control->mode != SDCA_ACCESS_MODE_DC)
266266
continue;
267267

268+
l = 0;
268269
for_each_set_bit(cn, (unsigned long *)&control->cn_list,
269270
BITS_PER_TYPE(control->cn_list)) {
270271
consts[k].reg = SDW_SDCA_CTL(function->desc->adr,
271272
entity->id,
272273
control->sel, cn);
273-
consts[k].def = control->value;
274+
consts[k].def = control->values[l];
274275
k++;
276+
l++;
275277
}
276278
}
277279
}
@@ -295,7 +297,7 @@ EXPORT_SYMBOL_NS(sdca_regmap_populate_constants, "SND_SOC_SDCA");
295297
int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap,
296298
struct sdca_function_data *function)
297299
{
298-
int i, j;
300+
int i, j, k;
299301
int ret;
300302

301303
for (i = 0; i < function->num_entities; i++) {
@@ -311,16 +313,19 @@ int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap,
311313
if (!control->has_default && !control->has_fixed)
312314
continue;
313315

316+
k = 0;
314317
for_each_set_bit(cn, (unsigned long *)&control->cn_list,
315318
BITS_PER_TYPE(control->cn_list)) {
316319
unsigned int reg;
317320

318321
reg = SDW_SDCA_CTL(function->desc->adr, entity->id,
319322
control->sel, cn);
320323

321-
ret = regmap_write(regmap, reg, control->value);
324+
ret = regmap_write(regmap, reg, control->values[k]);
322325
if (ret)
323326
return ret;
327+
328+
k++;
324329
}
325330
}
326331
}

0 commit comments

Comments
 (0)