diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2014-05-07 09:04:14 +0200 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-11-18 11:47:49 +0900 |
commit | 67ff66690fece77a51099129b2aa87c06a2a8805 (patch) | |
tree | baf17c740457bb84e47ee99b315474680b33ed5a /drivers/usb | |
parent | 0d3201717cc87dca62d3e20e7d91a024f2adcadd (diff) | |
download | linux-3.10-67ff66690fece77a51099129b2aa87c06a2a8805.tar.gz linux-3.10-67ff66690fece77a51099129b2aa87c06a2a8805.tar.bz2 linux-3.10-67ff66690fece77a51099129b2aa87c06a2a8805.zip |
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 <m.szyprowski@samsung.com>
Change-Id: I3453e714f9a793640b8cb6c0b4ccf699661ec934
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/misc/usb3503.c | 28 |
1 files 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 <linux/clk.h> #include <linux/i2c.h> #include <linux/gpio.h> #include <linux/delay.h> @@ -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", |