From 36de3d9a1a856a88f3c7f98d4a3a2ec0fd2cd407 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 7 May 2014 09:04:14 +0200 Subject: usb: usb5303: add support for reference clock specified in device tree USB3503 chip supports 8 values of reference clock. The value is specified by REF_SEL[1:0] pins and INT_N line. This patch add support for getting 'refclk' clock, enabling it and setting INT_N line according to the value of the gathered clock. If no clock has been specified, driver defaults to the old behaviour (assuming that clock has been specified by REF_SEL pins from primary reference clock frequencies table). Signed-off-by: Marek Szyprowski Change-Id: I3453e714f9a793640b8cb6c0b4ccf699661ec934 --- drivers/usb/misc/usb3503.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index a31641e18d1..52cb7549b77 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include @@ -57,10 +58,12 @@ struct usb3503 { enum usb3503_mode mode; struct regmap *regmap; struct device *dev; + struct clk *clk; u8 port_off_mask; int gpio_intn; int gpio_reset; int gpio_connect; + bool secondary_ref_clk; }; static int usb3503_reset(struct usb3503 *hub, int state) @@ -186,6 +189,25 @@ static int usb3503_probe(struct usb3503 *hub) } else if (np) { hub->port_off_mask = 0; + hub->clk = devm_clk_get(dev, "refclk"); + if (!IS_ERR(hub->clk)) { + unsigned long rate; + + clk_prepare_enable(hub->clk); + rate = clk_get_rate(hub->clk); + + if (rate == 38400000 || rate == 26000000 || + rate == 19200000 || rate == 12000000) + hub->secondary_ref_clk = 0; + else if (rate == 24000000 || rate == 27000000 || + rate == 25000000 || rate == 50000000) + hub->secondary_ref_clk = 1; + else + dev_err(dev, + "unsupported reference clock rate (%d)\n", + rate); + } + property = of_get_property(np, "disabled-ports", &len); if (property && (len / sizeof(u32)) > 0) { int i; @@ -213,8 +235,10 @@ static int usb3503_probe(struct usb3503 *hub) dev_err(dev, "Ports disabled with no control interface\n"); if (gpio_is_valid(hub->gpio_intn)) { - err = devm_gpio_request_one(dev, hub->gpio_intn, - GPIOF_OUT_INIT_HIGH, "usb3503 intn"); + int val = hub->secondary_ref_clk ? GPIOF_OUT_INIT_LOW : + GPIOF_OUT_INIT_HIGH; + err = devm_gpio_request_one(dev, hub->gpio_intn, val, + "usb3503 intn"); if (err) { dev_err(dev, "unable to request GPIO %d as connect pin (%d)\n", -- cgit v1.2.3