Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98bfb394 authored by Bin Liu's avatar Bin Liu Committed by Felipe Balbi
Browse files

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: default avatarBin Liu <b-liu@ti.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent fa4dce20
Loading
Loading
Loading
Loading
+54 −6
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/usb/ch9.h>
#include <linux/usb/ch9.h>
#include <linux/usb/of.h>
#include <linux/usb/of.h>
#include <linux/usb/otg.h>
#include <linux/usb/otg.h>
#include <linux/of_platform.h>


const char *usb_otg_state_string(enum usb_otg_state state)
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",
	[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)
enum usb_dr_mode usb_get_dr_mode(struct device *dev)
{
{
	const char *dr_mode;
	const char *dr_mode;
	int err, i;
	int err;


	err = device_property_read_string(dev, "dr_mode", &dr_mode);
	err = device_property_read_string(dev, "dr_mode", &dr_mode);
	if (err < 0)
	if (err < 0)
		return USB_DR_MODE_UNKNOWN;
		return USB_DR_MODE_UNKNOWN;


	for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
	return usb_get_dr_mode_from_string(dr_mode);
		if (!strcmp(dr_mode, usb_dr_modes[i]))
			return i;

	return USB_DR_MODE_UNKNOWN;
}
}
EXPORT_SYMBOL_GPL(usb_get_dr_mode);
EXPORT_SYMBOL_GPL(usb_get_dr_mode);


#ifdef CONFIG_OF
#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
 * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported
 * for given targeted hosts (non-PC hosts)
 * for given targeted hosts (non-PC hosts)
+5 −0
Original line number Original line Diff line number Diff line
@@ -12,10 +12,15 @@
#include <linux/usb/phy.h>
#include <linux/usb/phy.h>


#if IS_ENABLED(CONFIG_OF)
#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);
bool of_usb_host_tpl_support(struct device_node *np);
int of_usb_update_otg_caps(struct device_node *np,
int of_usb_update_otg_caps(struct device_node *np,
			struct usb_otg_caps *otg_caps);
			struct usb_otg_caps *otg_caps);
#else
#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)
static inline bool of_usb_host_tpl_support(struct device_node *np)
{
{
	return false;
	return false;