1*aa923ef1SMichal Sojka /* 2*aa923ef1SMichal Sojka * Provides code common for host and device side USB. 3*aa923ef1SMichal Sojka * 4*aa923ef1SMichal Sojka * This program is free software; you can redistribute it and/or 5*aa923ef1SMichal Sojka * modify it under the terms of the GNU General Public License as 6*aa923ef1SMichal Sojka * published by the Free Software Foundation, version 2. 7*aa923ef1SMichal Sojka * 8*aa923ef1SMichal Sojka * If either host side (ie. CONFIG_USB=y) or device side USB stack 9*aa923ef1SMichal Sojka * (ie. CONFIG_USB_GADGET=y) is compiled in the kernel, this module is 10*aa923ef1SMichal Sojka * compiled-in as well. Otherwise, if either of the two stacks is 11*aa923ef1SMichal Sojka * compiled as module, this file is compiled as module as well. 12*aa923ef1SMichal Sojka */ 13*aa923ef1SMichal Sojka 14*aa923ef1SMichal Sojka #include <linux/kernel.h> 15*aa923ef1SMichal Sojka #include <linux/module.h> 16*aa923ef1SMichal Sojka #include <linux/of.h> 17*aa923ef1SMichal Sojka #include <linux/usb/ch9.h> 18*aa923ef1SMichal Sojka #include <linux/usb/of.h> 19*aa923ef1SMichal Sojka #include <linux/usb/otg.h> 20*aa923ef1SMichal Sojka 21*aa923ef1SMichal Sojka const char *usb_otg_state_string(enum usb_otg_state state) 22*aa923ef1SMichal Sojka { 23*aa923ef1SMichal Sojka static const char *const names[] = { 24*aa923ef1SMichal Sojka [OTG_STATE_A_IDLE] = "a_idle", 25*aa923ef1SMichal Sojka [OTG_STATE_A_WAIT_VRISE] = "a_wait_vrise", 26*aa923ef1SMichal Sojka [OTG_STATE_A_WAIT_BCON] = "a_wait_bcon", 27*aa923ef1SMichal Sojka [OTG_STATE_A_HOST] = "a_host", 28*aa923ef1SMichal Sojka [OTG_STATE_A_SUSPEND] = "a_suspend", 29*aa923ef1SMichal Sojka [OTG_STATE_A_PERIPHERAL] = "a_peripheral", 30*aa923ef1SMichal Sojka [OTG_STATE_A_WAIT_VFALL] = "a_wait_vfall", 31*aa923ef1SMichal Sojka [OTG_STATE_A_VBUS_ERR] = "a_vbus_err", 32*aa923ef1SMichal Sojka [OTG_STATE_B_IDLE] = "b_idle", 33*aa923ef1SMichal Sojka [OTG_STATE_B_SRP_INIT] = "b_srp_init", 34*aa923ef1SMichal Sojka [OTG_STATE_B_PERIPHERAL] = "b_peripheral", 35*aa923ef1SMichal Sojka [OTG_STATE_B_WAIT_ACON] = "b_wait_acon", 36*aa923ef1SMichal Sojka [OTG_STATE_B_HOST] = "b_host", 37*aa923ef1SMichal Sojka }; 38*aa923ef1SMichal Sojka 39*aa923ef1SMichal Sojka if (state < 0 || state >= ARRAY_SIZE(names)) 40*aa923ef1SMichal Sojka return "UNDEFINED"; 41*aa923ef1SMichal Sojka 42*aa923ef1SMichal Sojka return names[state]; 43*aa923ef1SMichal Sojka } 44*aa923ef1SMichal Sojka EXPORT_SYMBOL_GPL(usb_otg_state_string); 45*aa923ef1SMichal Sojka 46*aa923ef1SMichal Sojka static const char *const speed_names[] = { 47*aa923ef1SMichal Sojka [USB_SPEED_UNKNOWN] = "UNKNOWN", 48*aa923ef1SMichal Sojka [USB_SPEED_LOW] = "low-speed", 49*aa923ef1SMichal Sojka [USB_SPEED_FULL] = "full-speed", 50*aa923ef1SMichal Sojka [USB_SPEED_HIGH] = "high-speed", 51*aa923ef1SMichal Sojka [USB_SPEED_WIRELESS] = "wireless", 52*aa923ef1SMichal Sojka [USB_SPEED_SUPER] = "super-speed", 53*aa923ef1SMichal Sojka }; 54*aa923ef1SMichal Sojka 55*aa923ef1SMichal Sojka const char *usb_speed_string(enum usb_device_speed speed) 56*aa923ef1SMichal Sojka { 57*aa923ef1SMichal Sojka if (speed < 0 || speed >= ARRAY_SIZE(speed_names)) 58*aa923ef1SMichal Sojka speed = USB_SPEED_UNKNOWN; 59*aa923ef1SMichal Sojka return speed_names[speed]; 60*aa923ef1SMichal Sojka } 61*aa923ef1SMichal Sojka EXPORT_SYMBOL_GPL(usb_speed_string); 62*aa923ef1SMichal Sojka 63*aa923ef1SMichal Sojka const char *usb_state_string(enum usb_device_state state) 64*aa923ef1SMichal Sojka { 65*aa923ef1SMichal Sojka static const char *const names[] = { 66*aa923ef1SMichal Sojka [USB_STATE_NOTATTACHED] = "not attached", 67*aa923ef1SMichal Sojka [USB_STATE_ATTACHED] = "attached", 68*aa923ef1SMichal Sojka [USB_STATE_POWERED] = "powered", 69*aa923ef1SMichal Sojka [USB_STATE_RECONNECTING] = "reconnecting", 70*aa923ef1SMichal Sojka [USB_STATE_UNAUTHENTICATED] = "unauthenticated", 71*aa923ef1SMichal Sojka [USB_STATE_DEFAULT] = "default", 72*aa923ef1SMichal Sojka [USB_STATE_ADDRESS] = "addressed", 73*aa923ef1SMichal Sojka [USB_STATE_CONFIGURED] = "configured", 74*aa923ef1SMichal Sojka [USB_STATE_SUSPENDED] = "suspended", 75*aa923ef1SMichal Sojka }; 76*aa923ef1SMichal Sojka 77*aa923ef1SMichal Sojka if (state < 0 || state >= ARRAY_SIZE(names)) 78*aa923ef1SMichal Sojka return "UNKNOWN"; 79*aa923ef1SMichal Sojka 80*aa923ef1SMichal Sojka return names[state]; 81*aa923ef1SMichal Sojka } 82*aa923ef1SMichal Sojka EXPORT_SYMBOL_GPL(usb_state_string); 83*aa923ef1SMichal Sojka 84*aa923ef1SMichal Sojka #ifdef CONFIG_OF 85*aa923ef1SMichal Sojka static const char *const usb_dr_modes[] = { 86*aa923ef1SMichal Sojka [USB_DR_MODE_UNKNOWN] = "", 87*aa923ef1SMichal Sojka [USB_DR_MODE_HOST] = "host", 88*aa923ef1SMichal Sojka [USB_DR_MODE_PERIPHERAL] = "peripheral", 89*aa923ef1SMichal Sojka [USB_DR_MODE_OTG] = "otg", 90*aa923ef1SMichal Sojka }; 91*aa923ef1SMichal Sojka 92*aa923ef1SMichal Sojka /** 93*aa923ef1SMichal Sojka * of_usb_get_dr_mode - Get dual role mode for given device_node 94*aa923ef1SMichal Sojka * @np: Pointer to the given device_node 95*aa923ef1SMichal Sojka * 96*aa923ef1SMichal Sojka * The function gets phy interface string from property 'dr_mode', 97*aa923ef1SMichal Sojka * and returns the correspondig enum usb_dr_mode 98*aa923ef1SMichal Sojka */ 99*aa923ef1SMichal Sojka enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) 100*aa923ef1SMichal Sojka { 101*aa923ef1SMichal Sojka const char *dr_mode; 102*aa923ef1SMichal Sojka int err, i; 103*aa923ef1SMichal Sojka 104*aa923ef1SMichal Sojka err = of_property_read_string(np, "dr_mode", &dr_mode); 105*aa923ef1SMichal Sojka if (err < 0) 106*aa923ef1SMichal Sojka return USB_DR_MODE_UNKNOWN; 107*aa923ef1SMichal Sojka 108*aa923ef1SMichal Sojka for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++) 109*aa923ef1SMichal Sojka if (!strcmp(dr_mode, usb_dr_modes[i])) 110*aa923ef1SMichal Sojka return i; 111*aa923ef1SMichal Sojka 112*aa923ef1SMichal Sojka return USB_DR_MODE_UNKNOWN; 113*aa923ef1SMichal Sojka } 114*aa923ef1SMichal Sojka EXPORT_SYMBOL_GPL(of_usb_get_dr_mode); 115*aa923ef1SMichal Sojka 116*aa923ef1SMichal Sojka /** 117*aa923ef1SMichal Sojka * of_usb_get_maximum_speed - Get maximum requested speed for a given USB 118*aa923ef1SMichal Sojka * controller. 119*aa923ef1SMichal Sojka * @np: Pointer to the given device_node 120*aa923ef1SMichal Sojka * 121*aa923ef1SMichal Sojka * The function gets the maximum speed string from property "maximum-speed", 122*aa923ef1SMichal Sojka * and returns the corresponding enum usb_device_speed. 123*aa923ef1SMichal Sojka */ 124*aa923ef1SMichal Sojka enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np) 125*aa923ef1SMichal Sojka { 126*aa923ef1SMichal Sojka const char *maximum_speed; 127*aa923ef1SMichal Sojka int err; 128*aa923ef1SMichal Sojka int i; 129*aa923ef1SMichal Sojka 130*aa923ef1SMichal Sojka err = of_property_read_string(np, "maximum-speed", &maximum_speed); 131*aa923ef1SMichal Sojka if (err < 0) 132*aa923ef1SMichal Sojka return USB_SPEED_UNKNOWN; 133*aa923ef1SMichal Sojka 134*aa923ef1SMichal Sojka for (i = 0; i < ARRAY_SIZE(speed_names); i++) 135*aa923ef1SMichal Sojka if (strcmp(maximum_speed, speed_names[i]) == 0) 136*aa923ef1SMichal Sojka return i; 137*aa923ef1SMichal Sojka 138*aa923ef1SMichal Sojka return USB_SPEED_UNKNOWN; 139*aa923ef1SMichal Sojka } 140*aa923ef1SMichal Sojka EXPORT_SYMBOL_GPL(of_usb_get_maximum_speed); 141*aa923ef1SMichal Sojka 142*aa923ef1SMichal Sojka /** 143*aa923ef1SMichal Sojka * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported 144*aa923ef1SMichal Sojka * for given targeted hosts (non-PC hosts) 145*aa923ef1SMichal Sojka * @np: Pointer to the given device_node 146*aa923ef1SMichal Sojka * 147*aa923ef1SMichal Sojka * The function gets if the targeted hosts support TPL or not 148*aa923ef1SMichal Sojka */ 149*aa923ef1SMichal Sojka bool of_usb_host_tpl_support(struct device_node *np) 150*aa923ef1SMichal Sojka { 151*aa923ef1SMichal Sojka if (of_find_property(np, "tpl-support", NULL)) 152*aa923ef1SMichal Sojka return true; 153*aa923ef1SMichal Sojka 154*aa923ef1SMichal Sojka return false; 155*aa923ef1SMichal Sojka } 156*aa923ef1SMichal Sojka EXPORT_SYMBOL_GPL(of_usb_host_tpl_support); 157*aa923ef1SMichal Sojka #endif 158*aa923ef1SMichal Sojka 159*aa923ef1SMichal Sojka MODULE_LICENSE("GPL"); 160