Loading Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt +23 −2 Original line number Diff line number Diff line Loading @@ -162,10 +162,25 @@ Required properties : Sub node has the required properties mentioned above. Optional properties : - pinctrl-names : This should be defined if a target uses pinctrl framework. See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt. It should specify the names of the configs that pinctrl can install in driver Following are the pinctrl configs that can be installed "smsc_active" : Active configuration of pins, this should specify active config defined in pin groups of used gpio's from reset, refclk, xo-clk and int. "smsc_sleep" : Disabled configuration of pins, this should specify the sleep config defined in pin groups of used gpio's from reset, refclk, xo-clk and int. If pinctrl is being used we need to only define gpio's which drives signals using gpiolib api's like reset and xo-clk gpio in dt, the node name in such cases should be msm_gpio as defined in pinctrl-dtsi. For gpio's only installing active and sleep configs it is not required to specify the gpio in dt file. - smsc,int-gpio: this input gpio indicate HUB suspend status and signal remote wakeup interrupt - smsc,refclk-gpio: this gpio is used to supply the reference clock - smsc,xo-clk-gio: this output gpio is used to control the external XO clock - smsc,xo-clk-gpio: this output gpio is used to control the external XO clock which is supplied to the hub as a reference clock - hub-vbus-supply: this regulator is used to supply the power to downstream ports Loading @@ -178,9 +193,16 @@ Example SMSC HSIC HUB : compatible = "qcom,hsic-smsc-hub"; smsc,model-id = <4604>; ranges; /* If pinctrl is used with all gpio_present */ pinctrl-names = "smsc_active","smsc_sleep"; pinctrl-0 = <&reset_act &refclk_act &int_act>; pinctrl-1 = <&reset_sus &refclk_sus &int_sus>; smsc,reset-gpio = <&pm8941_gpios 8 0x00>; /* If target does not use pinctrl */ smsc,reset-gpio = <&pm8941_gpios 8 0x00>; smsc,refclk-gpio = <&pm8941_gpios 16 0x00>; smsc,int-gpio = <&msmgpio 50 0x00>; /* End if */ hub-int-supply = <&pm8941_l10>; hub-vbus-supply = <&pm8941_mvs1>; Loading @@ -198,4 +220,3 @@ Example SMSC HSIC HUB : hsic,data-pad-offset = <0x2054>; }; }; drivers/misc/smsc_hub.c +72 −27 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/err.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> #include <linux/pinctrl/consumer.h> #include <linux/i2c.h> #include <linux/gpio.h> #include <linux/of_gpio.h> Loading @@ -37,6 +38,7 @@ struct hsic_hub { struct regulator *hsic_hub_reg; struct regulator *int_pad_reg, *hub_vbus_reg; bool enabled; struct pinctrl *smsc_pinctrl; }; static struct hsic_hub *smsc_hub; static struct platform_driver smsc_hub_driver; Loading Loading @@ -240,7 +242,8 @@ static int msm_hsic_hub_init_clock(struct hsic_hub *hub, int init) #define HSIC_HUB_INT_VOL_MAX 2950000 /* uV */ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) { int ret; int ret = 0; struct pinctrl_state *set_state; struct smsc_hub_platform_data *pdata = hub->pdata; if (!init) { Loading @@ -249,16 +252,56 @@ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) regulator_set_voltage(smsc_hub->int_pad_reg, 0, HSIC_HUB_INT_VOL_MAX); } return 0; if (smsc_hub->smsc_pinctrl) { set_state = pinctrl_lookup_state(smsc_hub->smsc_pinctrl, "smsc_sleep"); if (IS_ERR(set_state)) { pr_err("cannot get smsc pinctrl sleep state\n"); ret = PTR_ERR(set_state); goto out; } ret = pinctrl_select_state(smsc_hub->smsc_pinctrl, set_state); } goto out; } /* Get pinctrl if target uses pinctrl */ smsc_hub->smsc_pinctrl = devm_pinctrl_get(smsc_hub->dev); if (IS_ERR(smsc_hub->smsc_pinctrl)) { if (of_property_read_bool(smsc_hub->dev->of_node, "pinctrl-names")) { dev_err(smsc_hub->dev, "Error encountered while getting pinctrl"); ret = PTR_ERR(smsc_hub->smsc_pinctrl); goto out; } dev_dbg(smsc_hub->dev, "Target does not use pinctrl\n"); smsc_hub->smsc_pinctrl = NULL; } if (smsc_hub->smsc_pinctrl) { set_state = pinctrl_lookup_state(smsc_hub->smsc_pinctrl, "smsc_active"); if (IS_ERR(set_state)) { pr_err("cannot get smsc pinctrl active state\n"); ret = PTR_ERR(set_state); goto out; } ret = pinctrl_select_state(smsc_hub->smsc_pinctrl, set_state); if (ret) { pr_err("cannot set smsc pinctrl active state\n"); goto out; } } ret = devm_gpio_request(hub->dev, pdata->hub_reset, "HSIC_HUB_RESET"); if (ret < 0) { dev_err(hub->dev, "gpio request failed for GPIO%d\n", pdata->hub_reset); return ret; goto out; } if (IS_ERR_OR_NULL(smsc_hub->smsc_pinctrl)) { if (pdata->refclk_gpio) { ret = devm_gpio_request(hub->dev, pdata->refclk_gpio, "HSIC_HUB_CLK"); Loading @@ -271,7 +314,7 @@ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) "HSIC_HUB_XO_CLK"); if (ret < 0) { dev_err(hub->dev, "gpio request failed(XO CLK GPIO)\n"); return ret; goto out; } } Loading @@ -280,9 +323,11 @@ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) "HSIC_HUB_INT"); if (ret < 0) { dev_err(hub->dev, "gpio request failed (INT GPIO)\n"); return ret; goto out; } } } if (of_get_property(smsc_hub->dev->of_node, "hub-int-supply", NULL)) { /* Enable LDO if required for external pull-up */ smsc_hub->int_pad_reg = devm_regulator_get(hub->dev, "hub-int"); if (IS_ERR(smsc_hub->int_pad_reg)) { Loading @@ -294,19 +339,19 @@ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) if (ret) { dev_err(hub->dev, "unable to set the voltage\n" " for hsic hub int reg\n"); return ret; goto out; } ret = regulator_enable(smsc_hub->int_pad_reg); if (ret) { dev_err(hub->dev, "unable to enable int reg\n"); regulator_set_voltage(smsc_hub->int_pad_reg, 0, HSIC_HUB_INT_VOL_MAX); return ret; goto out; } } } return 0; out: return ret; } #define HSIC_HUB_VDD_VOL_MIN 1650000 /* uV */ Loading Loading
Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt +23 −2 Original line number Diff line number Diff line Loading @@ -162,10 +162,25 @@ Required properties : Sub node has the required properties mentioned above. Optional properties : - pinctrl-names : This should be defined if a target uses pinctrl framework. See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt. It should specify the names of the configs that pinctrl can install in driver Following are the pinctrl configs that can be installed "smsc_active" : Active configuration of pins, this should specify active config defined in pin groups of used gpio's from reset, refclk, xo-clk and int. "smsc_sleep" : Disabled configuration of pins, this should specify the sleep config defined in pin groups of used gpio's from reset, refclk, xo-clk and int. If pinctrl is being used we need to only define gpio's which drives signals using gpiolib api's like reset and xo-clk gpio in dt, the node name in such cases should be msm_gpio as defined in pinctrl-dtsi. For gpio's only installing active and sleep configs it is not required to specify the gpio in dt file. - smsc,int-gpio: this input gpio indicate HUB suspend status and signal remote wakeup interrupt - smsc,refclk-gpio: this gpio is used to supply the reference clock - smsc,xo-clk-gio: this output gpio is used to control the external XO clock - smsc,xo-clk-gpio: this output gpio is used to control the external XO clock which is supplied to the hub as a reference clock - hub-vbus-supply: this regulator is used to supply the power to downstream ports Loading @@ -178,9 +193,16 @@ Example SMSC HSIC HUB : compatible = "qcom,hsic-smsc-hub"; smsc,model-id = <4604>; ranges; /* If pinctrl is used with all gpio_present */ pinctrl-names = "smsc_active","smsc_sleep"; pinctrl-0 = <&reset_act &refclk_act &int_act>; pinctrl-1 = <&reset_sus &refclk_sus &int_sus>; smsc,reset-gpio = <&pm8941_gpios 8 0x00>; /* If target does not use pinctrl */ smsc,reset-gpio = <&pm8941_gpios 8 0x00>; smsc,refclk-gpio = <&pm8941_gpios 16 0x00>; smsc,int-gpio = <&msmgpio 50 0x00>; /* End if */ hub-int-supply = <&pm8941_l10>; hub-vbus-supply = <&pm8941_mvs1>; Loading @@ -198,4 +220,3 @@ Example SMSC HSIC HUB : hsic,data-pad-offset = <0x2054>; }; };
drivers/misc/smsc_hub.c +72 −27 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/err.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> #include <linux/pinctrl/consumer.h> #include <linux/i2c.h> #include <linux/gpio.h> #include <linux/of_gpio.h> Loading @@ -37,6 +38,7 @@ struct hsic_hub { struct regulator *hsic_hub_reg; struct regulator *int_pad_reg, *hub_vbus_reg; bool enabled; struct pinctrl *smsc_pinctrl; }; static struct hsic_hub *smsc_hub; static struct platform_driver smsc_hub_driver; Loading Loading @@ -240,7 +242,8 @@ static int msm_hsic_hub_init_clock(struct hsic_hub *hub, int init) #define HSIC_HUB_INT_VOL_MAX 2950000 /* uV */ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) { int ret; int ret = 0; struct pinctrl_state *set_state; struct smsc_hub_platform_data *pdata = hub->pdata; if (!init) { Loading @@ -249,16 +252,56 @@ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) regulator_set_voltage(smsc_hub->int_pad_reg, 0, HSIC_HUB_INT_VOL_MAX); } return 0; if (smsc_hub->smsc_pinctrl) { set_state = pinctrl_lookup_state(smsc_hub->smsc_pinctrl, "smsc_sleep"); if (IS_ERR(set_state)) { pr_err("cannot get smsc pinctrl sleep state\n"); ret = PTR_ERR(set_state); goto out; } ret = pinctrl_select_state(smsc_hub->smsc_pinctrl, set_state); } goto out; } /* Get pinctrl if target uses pinctrl */ smsc_hub->smsc_pinctrl = devm_pinctrl_get(smsc_hub->dev); if (IS_ERR(smsc_hub->smsc_pinctrl)) { if (of_property_read_bool(smsc_hub->dev->of_node, "pinctrl-names")) { dev_err(smsc_hub->dev, "Error encountered while getting pinctrl"); ret = PTR_ERR(smsc_hub->smsc_pinctrl); goto out; } dev_dbg(smsc_hub->dev, "Target does not use pinctrl\n"); smsc_hub->smsc_pinctrl = NULL; } if (smsc_hub->smsc_pinctrl) { set_state = pinctrl_lookup_state(smsc_hub->smsc_pinctrl, "smsc_active"); if (IS_ERR(set_state)) { pr_err("cannot get smsc pinctrl active state\n"); ret = PTR_ERR(set_state); goto out; } ret = pinctrl_select_state(smsc_hub->smsc_pinctrl, set_state); if (ret) { pr_err("cannot set smsc pinctrl active state\n"); goto out; } } ret = devm_gpio_request(hub->dev, pdata->hub_reset, "HSIC_HUB_RESET"); if (ret < 0) { dev_err(hub->dev, "gpio request failed for GPIO%d\n", pdata->hub_reset); return ret; goto out; } if (IS_ERR_OR_NULL(smsc_hub->smsc_pinctrl)) { if (pdata->refclk_gpio) { ret = devm_gpio_request(hub->dev, pdata->refclk_gpio, "HSIC_HUB_CLK"); Loading @@ -271,7 +314,7 @@ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) "HSIC_HUB_XO_CLK"); if (ret < 0) { dev_err(hub->dev, "gpio request failed(XO CLK GPIO)\n"); return ret; goto out; } } Loading @@ -280,9 +323,11 @@ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) "HSIC_HUB_INT"); if (ret < 0) { dev_err(hub->dev, "gpio request failed (INT GPIO)\n"); return ret; goto out; } } } if (of_get_property(smsc_hub->dev->of_node, "hub-int-supply", NULL)) { /* Enable LDO if required for external pull-up */ smsc_hub->int_pad_reg = devm_regulator_get(hub->dev, "hub-int"); if (IS_ERR(smsc_hub->int_pad_reg)) { Loading @@ -294,19 +339,19 @@ static int msm_hsic_hub_init_gpio(struct hsic_hub *hub, int init) if (ret) { dev_err(hub->dev, "unable to set the voltage\n" " for hsic hub int reg\n"); return ret; goto out; } ret = regulator_enable(smsc_hub->int_pad_reg); if (ret) { dev_err(hub->dev, "unable to enable int reg\n"); regulator_set_voltage(smsc_hub->int_pad_reg, 0, HSIC_HUB_INT_VOL_MAX); return ret; goto out; } } } return 0; out: return ret; } #define HSIC_HUB_VDD_VOL_MIN 1650000 /* uV */ Loading