Skip to content

Commit 4f67848

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 4f67848

2 files changed

Lines changed: 109 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: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,110 @@ 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: no entity list found for function type %u\n",
223+
function_node, function->type);
224+
return -EINVAL;
225+
}
226+
227+
entity_list = kcalloc(num_entities, sizeof(*entity_list), GFP_KERNEL);
228+
if (!entity_list)
229+
return -ENOMEM;
230+
231+
ret = fwnode_property_read_u32_array(function_node,
232+
"mipi-sdca-entity-id-list",
233+
entity_list, num_entities);
234+
if (ret) {
235+
dev_err(&slave->dev,
236+
"%pfwP: failed to read entity id list for function type %u: %d\n",
237+
function_node, function->type, ret);
238+
return ret;
239+
}
240+
241+
for (i = 0; i < num_entities; i++) {
242+
struct fwnode_handle *entity_node;
243+
const char *entity_label = "<unknown>";
244+
u32 entity_type;
245+
char entity_property[SDCA_PROPERTY_LENGTH];
246+
247+
/* DisCo uses upper-case for hex numbers */
248+
snprintf(entity_property, sizeof(entity_property),
249+
"mipi-sdca-entity-id-0x%X-subproperties", entity_list[i]);
250+
251+
entity_node = fwnode_get_named_child_node(function_node, entity_property);
252+
if (!entity_node) {
253+
dev_dbg(&slave->dev, "%pfwP: missing entity node %s\n",
254+
function_node, entity_property);
255+
continue;
256+
}
257+
258+
fwnode_property_read_string(entity_node, "mipi-sdca-entity-label",
259+
&entity_label);
260+
261+
ret = fwnode_property_read_u32(entity_node, "mipi-sdca-entity-type",
262+
&entity_type);
263+
if (ret) {
264+
dev_info(&slave->dev,
265+
"SDCA function %s (type %u adr 0x%x): entity 0x%x label %s type missing\n",
266+
function->name, function->type, function->adr,
267+
entity_list[i], entity_label);
268+
goto put_entity_node;
269+
}
270+
271+
dev_dbg(&slave->dev,
272+
"SDCA function %s (type %u adr 0x%x): entity 0x%x label %s type 0x%x\n",
273+
function->name, function->type, function->adr,
274+
entity_list[i], entity_label, entity_type);
275+
276+
if (entity_type == SDCA_ENTITY_TYPE_IT) {
277+
ret = fwnode_property_read_u32(entity_node,
278+
"mipi-sdca-terminal-type",
279+
&terminal_type);
280+
if (ret)
281+
goto put_entity_node;
282+
283+
if (terminal_type != SDCA_TERM_TYPE_MICROPHONE_TRANSDUCER &&
284+
terminal_type != SDCA_TERM_TYPE_MICROPHONE_ARRAY_TRANSDUCER)
285+
goto put_entity_node;
286+
287+
ret = fwnode_property_read_u32(entity_node,
288+
"mipi-sdca-terminal-transducer-count",
289+
&transducer_count);
290+
if (ret)
291+
goto put_entity_node;
292+
293+
dev_info(&slave->dev,
294+
"SDCA function %s entity %s: mipi-sdca-terminal-type=%#x mipi-sdca-terminal-transducer-count=%u\n",
295+
function->name, entity_label, terminal_type, transducer_count);
296+
break;
297+
}
298+
299+
put_entity_node:
300+
fwnode_handle_put(entity_node);
301+
}
302+
303+
return transducer_count;
304+
}
305+
EXPORT_SYMBOL_NS(sdca_get_mic_count, "SND_SOC_SDCA");
306+
203307
struct raw_init_write {
204308
__le32 addr;
205309
u8 val;

0 commit comments

Comments
 (0)