Skip to content

Commit 1032fa5

Browse files
committed
More minor SDCA changes
Merge series from Charles Keepax <[email protected]>: A small chain with some patches that seem to have got lost in the process. One small additional bug fix for the regmap callbacks, and one small feature addition for the control parsing. Charles Keepax (2): ASoC: SDCA: Fix some holes in the regmap readable/writeable helpers ASoC: SDCA: Add support for -cn- value properties include/sound/sdca_function.h | 14 ++--- sound/soc/sdca/sdca_functions.c | 99 +++++++++++++++++++++------------ sound/soc/sdca/sdca_regmap.c | 29 ++++++++-- 3 files changed, 92 insertions(+), 50 deletions(-) -- 2.39.5
2 parents da98e8b + 50a4795 commit 1032fa5

File tree

3 files changed

+92
-50
lines changed

3 files changed

+92
-50
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: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,18 @@ bool sdca_regmap_readable(struct sdca_function_data *function, unsigned int reg)
7272
if (!control)
7373
return false;
7474

75+
if (!(BIT(SDW_SDCA_CTL_CNUM(reg)) & control->cn_list))
76+
return false;
77+
7578
switch (control->mode) {
7679
case SDCA_ACCESS_MODE_RW:
7780
case SDCA_ACCESS_MODE_RO:
78-
case SDCA_ACCESS_MODE_DUAL:
7981
case SDCA_ACCESS_MODE_RW1S:
8082
case SDCA_ACCESS_MODE_RW1C:
83+
if (SDW_SDCA_NEXT_CTL(0) & reg)
84+
return false;
85+
fallthrough;
86+
case SDCA_ACCESS_MODE_DUAL:
8187
/* No access to registers marked solely for device use */
8288
return control->layers & ~SDCA_ACCESS_LAYER_DEVICE;
8389
default:
@@ -104,11 +110,17 @@ bool sdca_regmap_writeable(struct sdca_function_data *function, unsigned int reg
104110
if (!control)
105111
return false;
106112

113+
if (!(BIT(SDW_SDCA_CTL_CNUM(reg)) & control->cn_list))
114+
return false;
115+
107116
switch (control->mode) {
108117
case SDCA_ACCESS_MODE_RW:
109-
case SDCA_ACCESS_MODE_DUAL:
110118
case SDCA_ACCESS_MODE_RW1S:
111119
case SDCA_ACCESS_MODE_RW1C:
120+
if (SDW_SDCA_NEXT_CTL(0) & reg)
121+
return false;
122+
fallthrough;
123+
case SDCA_ACCESS_MODE_DUAL:
112124
/* No access to registers marked solely for device use */
113125
return control->layers & ~SDCA_ACCESS_LAYER_DEVICE;
114126
default:
@@ -241,7 +253,7 @@ int sdca_regmap_populate_constants(struct device *dev,
241253
struct sdca_function_data *function,
242254
struct reg_default *consts)
243255
{
244-
int i, j, k;
256+
int i, j, k, l;
245257

246258
for (i = 0, k = 0; i < function->num_entities; i++) {
247259
struct sdca_entity *entity = &function->entities[i];
@@ -253,13 +265,15 @@ int sdca_regmap_populate_constants(struct device *dev,
253265
if (control->mode != SDCA_ACCESS_MODE_DC)
254266
continue;
255267

268+
l = 0;
256269
for_each_set_bit(cn, (unsigned long *)&control->cn_list,
257270
BITS_PER_TYPE(control->cn_list)) {
258271
consts[k].reg = SDW_SDCA_CTL(function->desc->adr,
259272
entity->id,
260273
control->sel, cn);
261-
consts[k].def = control->value;
274+
consts[k].def = control->values[l];
262275
k++;
276+
l++;
263277
}
264278
}
265279
}
@@ -283,7 +297,7 @@ EXPORT_SYMBOL_NS(sdca_regmap_populate_constants, "SND_SOC_SDCA");
283297
int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap,
284298
struct sdca_function_data *function)
285299
{
286-
int i, j;
300+
int i, j, k;
287301
int ret;
288302

289303
for (i = 0; i < function->num_entities; i++) {
@@ -299,16 +313,19 @@ int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap,
299313
if (!control->has_default && !control->has_fixed)
300314
continue;
301315

316+
k = 0;
302317
for_each_set_bit(cn, (unsigned long *)&control->cn_list,
303318
BITS_PER_TYPE(control->cn_list)) {
304319
unsigned int reg;
305320

306321
reg = SDW_SDCA_CTL(function->desc->adr, entity->id,
307322
control->sel, cn);
308323

309-
ret = regmap_write(regmap, reg, control->value);
324+
ret = regmap_write(regmap, reg, control->values[k]);
310325
if (ret)
311326
return ret;
327+
328+
k++;
312329
}
313330
}
314331
}

0 commit comments

Comments
 (0)