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 (int node )
@@ -297,6 +291,40 @@ static int hpm_for_each_in_i2c_bus(const char *i2c_path, hpm_callback_t *cb, voi
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+ int idx = hpm_index (node );
311+ if (idx < 0 ) continue ;
312+ snprintf (hpm_path , sizeof (hpm_path ), "%s/%s" , spmi_path , name );
313+
314+ tps6598x_dev_t * tps = tps6598x_init_spmi (hpm_path , spmi );
315+ if (!tps ) {
316+ printf ("usb: tps6598x_init_spmi failed for %s.\n" , hpm_path );
317+ continue ;
318+ }
319+ cb (tps , idx , data );
320+ tps6598x_shutdown (tps );
321+ }
322+
323+ spmi_shutdown (spmi );
324+
325+ return 0 ;
326+ }
327+
300328static void hpm_init_callback (tps6598x_dev_t * tps , u32 idx , void * data )
301329{
302330 if (tps6598x_powerup (tps ) < 0 ) {
@@ -331,15 +359,6 @@ void usb_init(void)
331359 if (usb_is_initialized )
332360 return ;
333361
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-
343362 /*
344363 * A7-A11 uses a custom internal otg controller with the peripheral part
345364 * being dwc2.
@@ -350,11 +369,21 @@ void usb_init(void)
350369 return ;
351370 }
352371
353- if (adt_is_compatible (adt , 0 , "J180dAP" ))
372+ /*
373+ * M3/M4 models do not use i2c, but instead SPMI with a new controller.
374+ */
375+ if (adt_path_offset (adt , "/arm-io/nub-spmi-a0/hpm0" ) > 0 ) {
376+ if (hpm_for_each_in_spmi_bus ("/arm-io/nub-spmi-a0" , hpm_init_callback , NULL ) < 0 )
377+ return ;
378+ if (hpm_for_each_in_spmi_bus ("/arm-io/nub-spmi-a1" , hpm_init_callback , NULL ) < 0 )
379+ return ;
380+ } else {
381+ if (adt_is_compatible (adt , 0 , "J180dAP" ))
382+ if (hpm_for_each_in_i2c_bus ("/arm-io/i2c3" , hpm_init_callback , NULL ) < 0 )
383+ return ;
354384 if (hpm_for_each_in_i2c_bus ("/arm-io/i2c3" , hpm_init_callback , NULL ) < 0 )
355385 return ;
356- if (hpm_for_each_in_i2c_bus ("/arm-io/i2c3" , hpm_init_callback , NULL ) < 0 )
357- return ;
386+ }
358387
359388 for (int idx = 0 ; idx < USB_IODEV_COUNT ; ++ idx )
360389 usb_phy_bringup (idx ); /* Fails on missing devices, just continue */
@@ -364,22 +393,21 @@ void usb_init(void)
364393
365394void usb_hpm_restore_irqs (bool force )
366395{
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-
373396 /*
374397 * Do not try to restore irqs on A7-A11 which don't use i2c
375398 */
376399 if (adt_path_offset (adt , "/arm-io/otgphyctrl" ) > 0 &&
377400 adt_path_offset (adt , "/arm-io/usb-complex" ) > 0 )
378401 return ;
379402
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 );
403+ if (adt_path_offset (adt , "/arm-io/nub-spmi-a0/hpm0" ) > 0 ) {
404+ hpm_for_each_in_spmi_bus ("/arm-io/nub-spmi-a0" , hpm_restore_irqs_callback , & force );
405+ hpm_for_each_in_spmi_bus ("/arm-io/nub-spmi-a1" , hpm_restore_irqs_callback , & force );
406+ } else {
407+ if (adt_is_compatible (adt , 0 , "J180dAP" ))
408+ hpm_for_each_in_i2c_bus ("/arm-io/i2c3" , hpm_restore_irqs_callback , & force );
409+ hpm_for_each_in_i2c_bus ("/arm-io/i2c0" , hpm_restore_irqs_callback , & force );
410+ }
383411}
384412
385413void usb_iodev_init (void )
0 commit comments