2013-05-21 20:20:30

by Dongjin Kim

[permalink] [raw]
Subject: [PATCH 1/2] usb: misc: usb3503: Add to select the ports to disable

This patch is to disable the USB ports unconnected to USB3503. In order to
disable the port, 'port_off_mask' must be set.

* Disable PORT1 only
.port_off_mask = USB3503_OFF_PORT1;

* Disable PORT1 and PORT3 only
.port_off_mask = USB3503_OFF_PORT1 | USB3503_OFF_PORT3;

* Enables all ports
.port_off_mask = 0;

Signed-off-by: Dongjin Kim <[email protected]>
---
drivers/usb/misc/usb3503.c | 19 ++++++++++---------
include/linux/platform_data/usb3503.h | 5 +++++
2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
index d3a1cce..ab24bb3 100644
--- a/drivers/usb/misc/usb3503.c
+++ b/drivers/usb/misc/usb3503.c
@@ -42,9 +42,6 @@
#define USB3503_NRD 0x09

#define USB3503_PDS 0x0a
-#define USB3503_PORT1 (1 << 1)
-#define USB3503_PORT2 (1 << 2)
-#define USB3503_PORT3 (1 << 3)

#define USB3503_SP_ILOCK 0xe7
#define USB3503_SPILOCK_CONNECT (1 << 1)
@@ -56,6 +53,7 @@
struct usb3503 {
enum usb3503_mode mode;
struct i2c_client *client;
+ u8 port_off_mask;
int gpio_intn;
int gpio_reset;
int gpio_connect;
@@ -134,12 +132,14 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
goto err_hubmode;
}

- /* PDS : Port2,3 Disable For Self Powered Operation */
- err = usb3503_set_bits(i2c, USB3503_PDS,
- (USB3503_PORT2 | USB3503_PORT3));
- if (err < 0) {
- dev_err(&i2c->dev, "PDS failed (%d)\n", err);
- goto err_hubmode;
+ /* PDS : Disable For Self Powered Operation */
+ if (hub->port_off_mask) {
+ err = usb3503_set_bits(i2c, USB3503_PDS,
+ hub->port_off_mask);
+ if (err < 0) {
+ dev_err(&i2c->dev, "PDS failed (%d)\n", err);
+ goto err_hubmode;
+ }
}

/* CFG1 : SELF_BUS_PWR -> Self-Powerd operation */
@@ -197,6 +197,7 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
hub->client = i2c;

if (pdata) {
+ hub->port_off_mask = pdata->port_off_mask;
hub->gpio_intn = pdata->gpio_intn;
hub->gpio_connect = pdata->gpio_connect;
hub->gpio_reset = pdata->gpio_reset;
diff --git a/include/linux/platform_data/usb3503.h b/include/linux/platform_data/usb3503.h
index 85dcc70..1d1b6ef 100644
--- a/include/linux/platform_data/usb3503.h
+++ b/include/linux/platform_data/usb3503.h
@@ -3,6 +3,10 @@

#define USB3503_I2C_NAME "usb3503"

+#define USB3503_OFF_PORT1 (1 << 1)
+#define USB3503_OFF_PORT2 (1 << 2)
+#define USB3503_OFF_PORT3 (1 << 3)
+
enum usb3503_mode {
USB3503_MODE_UNKNOWN,
USB3503_MODE_HUB,
@@ -11,6 +15,7 @@ enum usb3503_mode {

struct usb3503_platform_data {
enum usb3503_mode initial_mode;
+ u8 port_off_mask;
int gpio_intn;
int gpio_connect;
int gpio_reset;
--
1.7.9.5


2013-05-21 20:20:42

by Dongjin Kim

[permalink] [raw]
Subject: [PATCH 2/2] usb: misc: usb3503: Adding device tree entry 'disabled-ports'

This patch is to add a property 'disabled-ports' representing the unused port
of USB3503. USB3503 can support up to 3 USB host port and each ports can be
controlled to be enabled or disabled. Do not describe this property if all
ports must be enabled.

You can represent the ports to disable in the device tree.

usb3503@08{
...
disabled-ports = <2 3>;
...
};

Signed-off-by: Dongjin Kim <[email protected]>
---
Documentation/devicetree/bindings/usb/usb3503.txt | 5 +++++
drivers/usb/misc/usb3503.c | 14 ++++++++++++++
2 files changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt
index 6813a71..8c5be48 100644
--- a/Documentation/devicetree/bindings/usb/usb3503.txt
+++ b/Documentation/devicetree/bindings/usb/usb3503.txt
@@ -4,6 +4,10 @@ Required properties:
- compatible: Should be "smsc,usb3503".
- reg: Specifies the i2c slave address, it should be 0x08.
- connect-gpios: Should specify GPIO for connect.
+- disabled-ports: Should specify the ports unused.
+ '1' or '2' or '3' are availe for this property to describe the port
+ number. 1~3 property values are possible to be desribed.
+ Do not describe this property if all ports have to be enabled.
- intn-gpios: Should specify GPIO for interrupt.
- reset-gpios: Should specify GPIO for reset.
- initial-mode: Should specify initial mode.
@@ -14,6 +18,7 @@ Examples:
compatible = "smsc,usb3503";
reg = <0x08>;
connect-gpios = <&gpx3 0 1>;
+ disabled-ports = <2 3>;
intn-gpios = <&gpx3 4 1>;
reset-gpios = <&gpx3 5 1>;
initial-mode = <1>;
diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
index ab24bb3..1908ec6 100644
--- a/drivers/usb/misc/usb3503.c
+++ b/drivers/usb/misc/usb3503.c
@@ -186,6 +186,8 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
struct usb3503 *hub;
int err = -ENOMEM;
u32 mode = USB3503_MODE_UNKNOWN;
+ const u32 *property;
+ int len;

hub = kzalloc(sizeof(struct usb3503), GFP_KERNEL);
if (!hub) {
@@ -203,6 +205,18 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
hub->gpio_reset = pdata->gpio_reset;
hub->mode = pdata->initial_mode;
} else if (np) {
+ hub->port_off_mask = 0;
+
+ property = of_get_property(np, "disabled-ports", &len);
+ if (property && (len / sizeof(u32)) > 0) {
+ int i;
+ for (i = 0; i < len / sizeof(u32); i++) {
+ u32 port = be32_to_cpu(property[i]);
+ if ((1 <= port) && (port <= 3))
+ hub->port_off_mask |= (1 << port);
+ }
+ }
+
hub->gpio_intn = of_get_named_gpio(np, "connect-gpios", 0);
if (hub->gpio_intn == -EPROBE_DEFER)
return -EPROBE_DEFER;
--
1.7.9.5