usb: of: add an api to get dr_mode by the phy node
Some USB phy drivers have different handling for the controller in each dr_mode. But the phy driver does not have visibility to the dr_mode of the controller. This adds an api to return the dr_mode of the controller which associates the given phy node. Signed-off-by: Bin Liu <b-liu@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
fa4dce2022
commit
98bfb39466
|
@ -17,6 +17,7 @@
|
|||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/of.h>
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
const char *usb_otg_state_string(enum usb_otg_state state)
|
||||
{
|
||||
|
@ -106,24 +107,71 @@ static const char *const usb_dr_modes[] = {
|
|||
[USB_DR_MODE_OTG] = "otg",
|
||||
};
|
||||
|
||||
static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
|
||||
if (!strcmp(usb_dr_modes[i], str))
|
||||
return i;
|
||||
|
||||
return USB_DR_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
enum usb_dr_mode usb_get_dr_mode(struct device *dev)
|
||||
{
|
||||
const char *dr_mode;
|
||||
int err, i;
|
||||
int err;
|
||||
|
||||
err = device_property_read_string(dev, "dr_mode", &dr_mode);
|
||||
if (err < 0)
|
||||
return USB_DR_MODE_UNKNOWN;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
|
||||
if (!strcmp(dr_mode, usb_dr_modes[i]))
|
||||
return i;
|
||||
|
||||
return USB_DR_MODE_UNKNOWN;
|
||||
return usb_get_dr_mode_from_string(dr_mode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_get_dr_mode);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
* of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device
|
||||
* which is associated with the given phy device_node
|
||||
* @np: Pointer to the given phy device_node
|
||||
*
|
||||
* In dts a usb controller associates with phy devices. The function gets
|
||||
* the string from property 'dr_mode' of the controller associated with the
|
||||
* given phy device node, and returns the correspondig enum usb_dr_mode.
|
||||
*/
|
||||
enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
|
||||
{
|
||||
struct device_node *controller = NULL;
|
||||
struct device_node *phy;
|
||||
const char *dr_mode;
|
||||
int index;
|
||||
int err;
|
||||
|
||||
do {
|
||||
controller = of_find_node_with_property(controller, "phys");
|
||||
index = 0;
|
||||
do {
|
||||
phy = of_parse_phandle(controller, "phys", index);
|
||||
of_node_put(phy);
|
||||
if (phy == phy_np)
|
||||
goto finish;
|
||||
index++;
|
||||
} while (phy);
|
||||
} while (controller);
|
||||
|
||||
finish:
|
||||
err = of_property_read_string(controller, "dr_mode", &dr_mode);
|
||||
of_node_put(controller);
|
||||
|
||||
if (err < 0)
|
||||
return USB_DR_MODE_UNKNOWN;
|
||||
|
||||
return usb_get_dr_mode_from_string(dr_mode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy);
|
||||
|
||||
/**
|
||||
* of_usb_host_tpl_support - to get if Targeted Peripheral List is supported
|
||||
* for given targeted hosts (non-PC hosts)
|
||||
|
|
|
@ -12,10 +12,15 @@
|
|||
#include <linux/usb/phy.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np);
|
||||
bool of_usb_host_tpl_support(struct device_node *np);
|
||||
int of_usb_update_otg_caps(struct device_node *np,
|
||||
struct usb_otg_caps *otg_caps);
|
||||
#else
|
||||
enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
|
||||
{
|
||||
return USB_DR_MODE_UNKNOWN;
|
||||
}
|
||||
static inline bool of_usb_host_tpl_support(struct device_node *np)
|
||||
{
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue