Skip to content

Commit 712242b

Browse files
committed
ASoC: sdca: add sdca_get_mic_count helper
We can get how many mic transducers are connected to the codec. The information will be used for selecting the topology with proper dmic channel number. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent 2baf8c0 commit 712242b

2 files changed

Lines changed: 123 additions & 0 deletions

File tree

include/sound/sdca.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum sdca_quirk {
6565
void sdca_lookup_functions(struct sdw_slave *slave);
6666
void sdca_lookup_swft(struct sdw_slave *slave);
6767
void sdca_lookup_interface_revision(struct sdw_slave *slave);
68+
int sdca_get_mic_count(struct sdw_slave *slave, struct sdca_function_desc *function);
6869
bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk);
6970
int sdca_dev_register_functions(struct sdw_slave *slave);
7071
void sdca_dev_unregister_functions(struct sdw_slave *slave);
@@ -74,6 +75,10 @@ void sdca_dev_unregister_functions(struct sdw_slave *slave);
7475
static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
7576
static inline void sdca_lookup_swft(struct sdw_slave *slave) {}
7677
static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
78+
static inline int sdca_get_mic_count(struct sdw_slave *slave, struct sdca_function_desc *function)
79+
{
80+
return 0;
81+
}
7782
static inline bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
7883
{
7984
return false;

sound/soc/sdca/sdca_functions.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,124 @@ void sdca_lookup_functions(struct sdw_slave *slave)
200200
}
201201
EXPORT_SYMBOL_NS(sdca_lookup_functions, "SND_SOC_SDCA");
202202

203+
int sdca_get_mic_count(struct sdw_slave *slave, struct sdca_function_desc *function)
204+
{
205+
struct fwnode_handle *function_node;
206+
u32 *entity_list __free(kfree) = NULL;
207+
u32 transducer_count = 0;
208+
u32 terminal_type;
209+
int num_entities;
210+
int ret;
211+
int i;
212+
213+
if (!function || !function->node)
214+
return -EINVAL;
215+
216+
function_node = function->node;
217+
218+
num_entities = fwnode_property_count_u32(function_node,
219+
"mipi-sdca-entity-id-list");
220+
if (num_entities < 0) {
221+
dev_err(&slave->dev,
222+
"%pfwP: failed to get entity id list count for function type %u: %d\n",
223+
function_node, function->type, num_entities);
224+
return num_entities;
225+
}
226+
if (num_entities == 0) {
227+
dev_warn(&slave->dev,
228+
"%pfwP: empty entity id list for function type %u\n",
229+
function_node, function->type);
230+
return -ENODATA;
231+
}
232+
if (num_entities > SDCA_MAX_ENTITY_COUNT) {
233+
dev_err(&slave->dev,
234+
"%pfwP: entity number %d is invalid for function type %u\n",
235+
function_node, num_entities, function->type);
236+
return -EINVAL;
237+
}
238+
239+
entity_list = kcalloc(num_entities, sizeof(*entity_list), GFP_KERNEL);
240+
if (!entity_list)
241+
return -ENOMEM;
242+
243+
ret = fwnode_property_read_u32_array(function_node,
244+
"mipi-sdca-entity-id-list",
245+
entity_list, num_entities);
246+
if (ret) {
247+
dev_err(&slave->dev,
248+
"%pfwP: failed to read entity id list for function type %u: %d\n",
249+
function_node, function->type, ret);
250+
return ret;
251+
}
252+
253+
for (i = 0; i < num_entities; i++) {
254+
struct fwnode_handle *entity_node;
255+
const char *entity_label = "<unknown>";
256+
u32 entity_type;
257+
char entity_property[SDCA_PROPERTY_LENGTH];
258+
259+
/* DisCo uses upper-case for hex numbers */
260+
snprintf(entity_property, sizeof(entity_property),
261+
"mipi-sdca-entity-id-0x%X-subproperties", entity_list[i]);
262+
263+
entity_node = fwnode_get_named_child_node(function_node, entity_property);
264+
if (!entity_node) {
265+
dev_dbg(&slave->dev, "%pfwP: missing entity node %s\n",
266+
function_node, entity_property);
267+
continue;
268+
}
269+
270+
fwnode_property_read_string(entity_node, "mipi-sdca-entity-label",
271+
&entity_label);
272+
273+
ret = fwnode_property_read_u32(entity_node, "mipi-sdca-entity-type",
274+
&entity_type);
275+
if (ret) {
276+
dev_info(&slave->dev,
277+
"SDCA function %s (type %u adr 0x%x): entity 0x%x label %s type missing\n",
278+
function->name, function->type, function->adr,
279+
entity_list[i], entity_label);
280+
goto put_entity_node;
281+
}
282+
283+
dev_dbg(&slave->dev,
284+
"SDCA function %s (type %u adr 0x%x): entity 0x%x label %s type 0x%x\n",
285+
function->name, function->type, function->adr,
286+
entity_list[i], entity_label, entity_type);
287+
288+
if (entity_type == SDCA_ENTITY_TYPE_IT) {
289+
ret = fwnode_property_read_u32(entity_node,
290+
"mipi-sdca-terminal-type",
291+
&terminal_type);
292+
if (ret)
293+
goto put_entity_node;
294+
295+
if (terminal_type != SDCA_TERM_TYPE_MICROPHONE_TRANSDUCER &&
296+
terminal_type != SDCA_TERM_TYPE_MICROPHONE_ARRAY_TRANSDUCER)
297+
goto put_entity_node;
298+
299+
ret = fwnode_property_read_u32(entity_node,
300+
"mipi-sdca-terminal-transducer-count",
301+
&transducer_count);
302+
if (ret)
303+
goto put_entity_node;
304+
305+
dev_dbg(&slave->dev,
306+
"SDCA function %s entity %s: mipi-sdca-terminal-type=%#x mipi-sdca-terminal-transducer-count=%u\n",
307+
function->name, entity_label, terminal_type, transducer_count);
308+
309+
fwnode_handle_put(entity_node);
310+
break;
311+
}
312+
313+
put_entity_node:
314+
fwnode_handle_put(entity_node);
315+
}
316+
317+
return transducer_count;
318+
}
319+
EXPORT_SYMBOL_NS(sdca_get_mic_count, "SND_SOC_SDCA");
320+
203321
struct raw_init_write {
204322
__le32 addr;
205323
u8 val;

0 commit comments

Comments
 (0)