@@ -200,6 +200,110 @@ 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: 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 - EINVAL ;
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+ fwnode_handle_put (entity_node );
269+ continue ;
270+ }
271+
272+ dev_dbg (& slave -> dev ,
273+ "SDCA function %s (type %u adr 0x%x): entity 0x%x label %s type 0x%x\n" ,
274+ function -> name , function -> type , function -> adr ,
275+ entity_list [i ], entity_label , entity_type );
276+
277+ if (entity_type == SDCA_ENTITY_TYPE_IT ) {
278+ ret = fwnode_property_read_u32 (entity_node ,
279+ "mipi-sdca-terminal-type" ,
280+ & terminal_type );
281+ if (ret )
282+ continue ;
283+
284+ if (terminal_type != SDCA_TERM_TYPE_MICROPHONE_TRANSDUCER &&
285+ terminal_type != SDCA_TERM_TYPE_MICROPHONE_ARRAY_TRANSDUCER )
286+ continue ;
287+
288+ ret = fwnode_property_read_u32 (entity_node ,
289+ "mipi-sdca-terminal-transducer-count" ,
290+ & transducer_count );
291+ if (ret )
292+ continue ;
293+
294+ dev_info (& slave -> dev ,
295+ "SDCA function %s entity %s: iot mipi-sdca-terminal-type=%#x mipi-sdca-terminal-transducer-count=%u\n" ,
296+ function -> name , entity_label , terminal_type , transducer_count );
297+ break ;
298+ }
299+
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+
203307struct raw_init_write {
204308 __le32 addr ;
205309 u8 val ;
0 commit comments