@@ -200,6 +200,124 @@ void sdca_lookup_functions(struct sdw_slave *slave)
200200}
201201EXPORT_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+
203321struct raw_init_write {
204322 __le32 addr ;
205323 u8 val ;
0 commit comments