@@ -200,6 +200,112 @@ 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 || num_entities > SDCA_MAX_ENTITY_COUNT ) {
221+ dev_err (& slave -> dev ,
222+ "%pfwP: entity number %d is invalid for function type %u\n" ,
223+ function_node , num_entities , 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_dbg (& 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+
297+ fwnode_handle_put (entity_node );
298+ break ;
299+ }
300+
301+ put_entity_node :
302+ fwnode_handle_put (entity_node );
303+ }
304+
305+ return transducer_count ;
306+ }
307+ EXPORT_SYMBOL_NS (sdca_get_mic_count , "SND_SOC_SDCA" );
308+
203309struct raw_init_write {
204310 __le32 addr ;
205311 u8 val ;
0 commit comments