44#include "adt.h"
55#include "dart.h"
66#include "i2c.h"
7+ #include "spmi.h"
78#include "iodev.h"
89#include "malloc.h"
910#include "pmgr.h"
@@ -33,6 +34,7 @@ struct usb_drd_regs {
3334#define FMT_DRD_PATH "/arm-io/usb-drd%u"
3435// HPM_PATH string is at most
3536// "/arm-io/i2cX" (12) + "/" + hpmBusManagerX (14) + "/" + "hpmX" (4) + '\0'
37+ // "/arm-io/nub-spmi-aX" (19) + "/" + "hpmX" (4) + '\0'
3638#define MAX_HPM_PATH_LEN 40
3739
3840static tps6598x_irq_state_t tps6598x_irq_state [USB_IODEV_COUNT ];
@@ -231,14 +233,6 @@ struct iodev iodev_usb_vuart = {
231233 .lock = SPINLOCK_INIT ,
232234};
233235
234- void usb_spmi_init (void )
235- {
236- for (int idx = 0 ; idx < USB_IODEV_COUNT ; ++ idx )
237- usb_phy_bringup (idx ); /* Fails on missing devices, just continue */
238-
239- usb_is_initialized = true;
240- }
241-
242236typedef void (* hpm_callback_t )(tps6598x_dev_t * tps , u32 idx , void * data );
243237
244238static int hpm_index (const char * name )
@@ -297,6 +291,41 @@ static int hpm_for_each_in_i2c_bus(const char *i2c_path, hpm_callback_t cb, void
297291 return 0 ;
298292}
299293
294+ static int hpm_for_each_in_spmi_bus (const char * spmi_path , hpm_callback_t cb , void * data )
295+ {
296+ char hpm_path [MAX_HPM_PATH_LEN ];
297+
298+ int node = adt_path_offset (adt , spmi_path );
299+ if (node < 0 )
300+ return 0 ;
301+
302+ spmi_dev_t * spmi = spmi_init (spmi_path );
303+ if (!spmi ) {
304+ printf ("usb: spmi init failed for %s\n" , spmi_path );
305+ return -1 ;
306+ }
307+
308+ ADT_FOREACH_CHILD (adt , node )
309+ {
310+ const char * name = adt_get_name (adt , node );
311+ int idx = hpm_index (name );
312+ if (idx < 0 ) continue ;
313+ snprintf (hpm_path , sizeof (hpm_path ), "%s/%s" , spmi_path , name );
314+
315+ tps6598x_dev_t * tps = tps6598x_init_spmi (hpm_path , spmi );
316+ if (!tps ) {
317+ printf ("usb: tps6598x_init_spmi failed for %s.\n" , hpm_path );
318+ continue ;
319+ }
320+ cb (tps , idx , data );
321+ tps6598x_shutdown (tps );
322+ }
323+
324+ spmi_shutdown (spmi );
325+
326+ return 0 ;
327+ }
328+
300329static void hpm_init_callback (tps6598x_dev_t * tps , u32 idx , void * )
301330{
302331 if (tps6598x_powerup (tps ) < 0 ) {
@@ -331,15 +360,6 @@ void usb_init(void)
331360 if (usb_is_initialized )
332361 return ;
333362
334- /*
335- * M3/M4 models do not use i2c, but instead SPMI with a new controller.
336- * We can get USB going for now by just bringing up the phys.
337- */
338- if (adt_path_offset (adt , "/arm-io/nub-spmi-a0/hpm0" ) > 0 ) {
339- usb_spmi_init ();
340- return ;
341- }
342-
343363 /*
344364 * A7-A11 uses a custom internal otg controller with the peripheral part
345365 * being dwc2.
@@ -350,11 +370,21 @@ void usb_init(void)
350370 return ;
351371 }
352372
353- if (adt_is_compatible (adt , 0 , "J180dAP" ))
354- if (hpm_for_each_in_i2c_bus ("/arm-io/i2c3" , hpm_init_callback , NULL ) < 0 )
373+ /*
374+ * M3/M4 models do not use i2c, but instead SPMI with a new controller.
375+ */
376+ if (adt_path_offset (adt , "/arm-io/nub-spmi-a0/hpm0" ) > 0 ) {
377+ if (hpm_for_each_in_spmi_bus ("/arm-io/nub-spmi-a0" , hpm_init_callback , NULL ) < 0 )
355378 return ;
356- if (hpm_for_each_in_i2c_bus ("/arm-io/i2c0" , hpm_init_callback , NULL ) < 0 )
357- return ;
379+ if (hpm_for_each_in_spmi_bus ("/arm-io/nub-spmi-a1" , hpm_init_callback , NULL ) < 0 )
380+ return ;
381+ } else {
382+ if (adt_is_compatible (adt , 0 , "J180dAP" ))
383+ if (hpm_for_each_in_i2c_bus ("/arm-io/i2c3" , hpm_init_callback , NULL ) < 0 )
384+ return ;
385+ if (hpm_for_each_in_i2c_bus ("/arm-io/i2c0" , hpm_init_callback , NULL ) < 0 )
386+ return ;
387+ }
358388
359389 for (int idx = 0 ; idx < USB_IODEV_COUNT ; ++ idx )
360390 usb_phy_bringup (idx ); /* Fails on missing devices, just continue */
@@ -364,22 +394,21 @@ void usb_init(void)
364394
365395void usb_hpm_restore_irqs (bool force )
366396{
367- /*
368- * Do not try to restore irqs on M3/M4 which don't use i2c
369- */
370- if (adt_path_offset (adt , "/arm-io/nub-spmi-a0/hpm0" ) > 0 )
371- return ;
372-
373397 /*
374398 * Do not try to restore irqs on A7-A11 which don't use i2c
375399 */
376400 if (adt_path_offset (adt , "/arm-io/otgphyctrl" ) > 0 &&
377401 adt_path_offset (adt , "/arm-io/usb-complex" ) > 0 )
378402 return ;
379403
380- if (adt_is_compatible (adt , 0 , "J180dAP" ))
381- hpm_for_each_in_i2c_bus ("/arm-io/i2c3" , hpm_restore_irqs_callback , & force );
382- hpm_for_each_in_i2c_bus ("/arm-io/i2c0" , hpm_restore_irqs_callback , & force );
404+ if (adt_path_offset (adt , "/arm-io/nub-spmi-a0/hpm0" ) > 0 ) {
405+ hpm_for_each_in_spmi_bus ("/arm-io/nub-spmi-a0" , hpm_restore_irqs_callback , & force );
406+ hpm_for_each_in_spmi_bus ("/arm-io/nub-spmi-a1" , hpm_restore_irqs_callback , & force );
407+ } else {
408+ if (adt_is_compatible (adt , 0 , "J180dAP" ))
409+ hpm_for_each_in_i2c_bus ("/arm-io/i2c3" , hpm_restore_irqs_callback , & force );
410+ hpm_for_each_in_i2c_bus ("/arm-io/i2c0" , hpm_restore_irqs_callback , & force );
411+ }
383412}
384413
385414void usb_iodev_init (void )
0 commit comments