Loading Documentation/devicetree/bindings/usb/ice40-hcd.txt +13 −0 Original line number Diff line number Diff line Loading @@ -16,9 +16,16 @@ Required properties: loading - config-done-gpio: gpio used to indicate the configuration status - vcc-en-gpio: gpio used to enable the chip power supply - pinctrl-names : List of pin configuration strings. "default" and "sleep" states are supported. - pinctrl-0 : Phandle of "default" pin config state - pinctrl-1 : Phandle of "sleep" pin config state Optional properties: - interrupts: IRQ lines used by this controller - clocks: List of clock phandles. - clock-names: List of clock names. Supported clock name string is "xo" - clk-en-gpio: gpio used to enable the 19.2 MHZ clock to the bridge chip. If it is not present, assume that the clock is available on the bridge chip board. Loading @@ -41,5 +48,11 @@ Optional properties: lattice,slave-select-gpio = <&msmgpio 118 0>; lattice,config-done-gpio = <&msmgpio 115 0>; lattice,vcc-en-gpio = <&msmgpio 117 0>; clocks = <&clock_rpm clk_bb_clk2_pin>; clock-names = "xo"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&ice40_default>; pinctrl-1 = <&ice40_sleep>; }; }; arch/arm/configs/msm8916_defconfig +2 −0 Original line number Diff line number Diff line Loading @@ -341,7 +341,9 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_EHSET=y CONFIG_USB_ICE40_HCD=m CONFIG_USB_ACM=y CONFIG_USB_CCID_BRIDGE=y CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y Loading drivers/usb/host/ice40-hcd.c +79 −21 Original line number Diff line number Diff line Loading @@ -27,19 +27,20 @@ #include <linux/uaccess.h> #include <linux/debugfs.h> #include <linux/pm_runtime.h> #include <linux/clk.h> #include <linux/regulator/consumer.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/spinlock.h> #include <linux/firmware.h> #include <linux/spi/spi.h> #include <linux/pinctrl/consumer.h> #include <linux/usb.h> #include <linux/usb/hcd.h> #include <linux/usb/ch9.h> #include <linux/usb/ch11.h> #include <asm/unaligned.h> #include <mach/gpiomux.h> #define CREATE_TRACE_POINTS #include <trace/events/ice40.h> Loading Loading @@ -151,6 +152,9 @@ struct ice40_hcd { struct workqueue_struct *wq; struct work_struct async_work; struct clk *xo_clk; struct pinctrl *pinctrl; int reset_gpio; int slave_select_gpio; int config_done_gpio; Loading Loading @@ -1368,6 +1372,8 @@ static void ice40_spi_power_off(struct ice40_hcd *ihcd) regulator_disable(ihcd->gpio_vcc); if (ihcd->clk_en_gpio) gpio_direction_output(ihcd->clk_en_gpio, 0); if (ihcd->xo_clk) clk_disable_unprepare(ihcd->xo_clk); ihcd->powered = false; } Loading @@ -1376,11 +1382,19 @@ static int ice40_spi_power_up(struct ice40_hcd *ihcd) { int ret; if (ihcd->xo_clk) { ret = clk_prepare_enable(ihcd->xo_clk); if (ret < 0) { pr_err("fail to enable xo clk %d\n", ret); goto out; } } if (ihcd->clk_en_gpio) { ret = gpio_direction_output(ihcd->clk_en_gpio, 1); if (ret < 0) { pr_err("fail to enabel clk %d\n", ret); goto out; pr_err("fail to enable clk %d\n", ret); goto disable_xo; } } Loading Loading @@ -1424,17 +1438,13 @@ disable_gpio_vcc: disable_clk: if (ihcd->clk_en_gpio) gpio_direction_output(ihcd->clk_en_gpio, 0); disable_xo: if (ihcd->xo_clk) clk_disable_unprepare(ihcd->xo_clk); out: return ret; } static struct gpiomux_setting slave_select_setting = { .func = GPIOMUX_FUNC_GPIO, .drv = GPIOMUX_DRV_2MA, .pull = GPIOMUX_PULL_NONE, .dir = GPIOMUX_OUT_LOW, }; #define CONFIG_LOAD_FREQ_MAX_HZ 25000000 static int ice40_spi_cache_fw(struct ice40_hcd *ihcd) { Loading Loading @@ -1497,7 +1507,6 @@ out: static int ice40_spi_load_fw(struct ice40_hcd *ihcd) { int ret, i; struct gpiomux_setting old_setting; ret = gpio_direction_output(ihcd->reset_gpio, 0); if (ret < 0) { Loading @@ -1524,32 +1533,37 @@ static int ice40_spi_load_fw(struct ice40_hcd *ihcd) */ spi_bus_lock(ihcd->spi->master); ret = msm_gpiomux_write(ihcd->slave_select_gpio, GPIOMUX_SUSPENDED, &slave_select_setting, &old_setting); ret = gpio_request(ihcd->slave_select_gpio, "ice40_spi_cs"); if (ret < 0) { pr_err("fail to select the slave %d\n", ret); pr_err("fail to request slave select gpio %d\n", ret); spi_bus_unlock(ihcd->spi->master); goto out; } ret = gpio_direction_output(ihcd->slave_select_gpio, 0); if (ret < 0) { pr_err("fail to drive slave select gpio %d\n", ret); gpio_free(ihcd->slave_select_gpio); spi_bus_unlock(ihcd->spi->master); goto out; } ret = ice40_spi_power_up(ihcd); if (ret < 0) { pr_err("fail to power up the chip\n"); gpio_free(ihcd->slave_select_gpio); spi_bus_unlock(ihcd->spi->master); goto out; } /* * The databook says 1200 usec is required before the * chip becomes ready for the SPI transfer. */ usleep_range(1200, 1250); ret = msm_gpiomux_write(ihcd->slave_select_gpio, GPIOMUX_SUSPENDED, &old_setting, NULL); if (ret < 0) { pr_err("fail to de-select the slave %d\n", ret); goto power_off; } gpio_direction_output(ihcd->slave_select_gpio, 1); gpio_free(ihcd->slave_select_gpio); ret = spi_sync_locked(ihcd->spi, ihcd->fmsg); Loading Loading @@ -1599,6 +1613,32 @@ out: return ret; } static int ice40_spi_init_clocks(struct ice40_hcd *ihcd) { int ret = 0; /* * XO clock is the only supported clock. So no need to parse * the clock-names string. If there is no clock-names property, * there will not be XO clock. * * This XO clock can be either direct clock or pin control clock. * if it is pin control clock, clk_en gpio is used to control * the clock. */ if (!of_get_property(ihcd->spi->dev.of_node, "clock-names", NULL)) return 0; ihcd->xo_clk = devm_clk_get(&ihcd->spi->dev, "xo"); if (IS_ERR(ihcd->xo_clk)) { ret = PTR_ERR(ihcd->xo_clk); if (ret != -EPROBE_DEFER) pr_err("fail to get xo clk %d\n", ret); } return ret; } static int ice40_spi_init_regulators(struct ice40_hcd *ihcd) { int ret; Loading Loading @@ -1656,6 +1696,13 @@ static int ice40_spi_request_gpios(struct ice40_hcd *ihcd) { int ret; ihcd->pinctrl = devm_pinctrl_get_select_default(&ihcd->spi->dev); if (IS_ERR(ihcd->pinctrl)) { ret = PTR_ERR(ihcd->pinctrl); pr_err("fail to get pinctrl info %d\n", ret); goto out; } ret = devm_gpio_request(&ihcd->spi->dev, ihcd->reset_gpio, "ice40_reset"); if (ret < 0) { Loading Loading @@ -1952,6 +1999,12 @@ static int ice40_spi_probe(struct spi_device *spi) goto out; } ret = ice40_spi_init_clocks(ihcd); if (ret) { pr_err("fail to init clocks\n"); goto out; } ret = ice40_spi_init_regulators(ihcd); if (ret) { pr_err("fail to init regulators\n"); Loading Loading @@ -2062,6 +2115,7 @@ static int ice40_spi_remove(struct spi_device *spi) { struct usb_hcd *hcd = spi_get_drvdata(spi); struct ice40_hcd *ihcd = hcd_to_ihcd(hcd); struct pinctrl_state *s; debugfs_remove_recursive(ihcd->dbg_root); Loading @@ -2070,6 +2124,10 @@ static int ice40_spi_remove(struct spi_device *spi) destroy_workqueue(ihcd->wq); ice40_spi_power_off(ihcd); s = pinctrl_lookup_state(ihcd->pinctrl, PINCTRL_STATE_SLEEP); if (!IS_ERR(s)) pinctrl_select_state(ihcd->pinctrl, s); pm_runtime_disable(&spi->dev); pm_relax(&spi->dev); Loading Loading
Documentation/devicetree/bindings/usb/ice40-hcd.txt +13 −0 Original line number Diff line number Diff line Loading @@ -16,9 +16,16 @@ Required properties: loading - config-done-gpio: gpio used to indicate the configuration status - vcc-en-gpio: gpio used to enable the chip power supply - pinctrl-names : List of pin configuration strings. "default" and "sleep" states are supported. - pinctrl-0 : Phandle of "default" pin config state - pinctrl-1 : Phandle of "sleep" pin config state Optional properties: - interrupts: IRQ lines used by this controller - clocks: List of clock phandles. - clock-names: List of clock names. Supported clock name string is "xo" - clk-en-gpio: gpio used to enable the 19.2 MHZ clock to the bridge chip. If it is not present, assume that the clock is available on the bridge chip board. Loading @@ -41,5 +48,11 @@ Optional properties: lattice,slave-select-gpio = <&msmgpio 118 0>; lattice,config-done-gpio = <&msmgpio 115 0>; lattice,vcc-en-gpio = <&msmgpio 117 0>; clocks = <&clock_rpm clk_bb_clk2_pin>; clock-names = "xo"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&ice40_default>; pinctrl-1 = <&ice40_sleep>; }; };
arch/arm/configs/msm8916_defconfig +2 −0 Original line number Diff line number Diff line Loading @@ -341,7 +341,9 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_EHSET=y CONFIG_USB_ICE40_HCD=m CONFIG_USB_ACM=y CONFIG_USB_CCID_BRIDGE=y CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y Loading
drivers/usb/host/ice40-hcd.c +79 −21 Original line number Diff line number Diff line Loading @@ -27,19 +27,20 @@ #include <linux/uaccess.h> #include <linux/debugfs.h> #include <linux/pm_runtime.h> #include <linux/clk.h> #include <linux/regulator/consumer.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/spinlock.h> #include <linux/firmware.h> #include <linux/spi/spi.h> #include <linux/pinctrl/consumer.h> #include <linux/usb.h> #include <linux/usb/hcd.h> #include <linux/usb/ch9.h> #include <linux/usb/ch11.h> #include <asm/unaligned.h> #include <mach/gpiomux.h> #define CREATE_TRACE_POINTS #include <trace/events/ice40.h> Loading Loading @@ -151,6 +152,9 @@ struct ice40_hcd { struct workqueue_struct *wq; struct work_struct async_work; struct clk *xo_clk; struct pinctrl *pinctrl; int reset_gpio; int slave_select_gpio; int config_done_gpio; Loading Loading @@ -1368,6 +1372,8 @@ static void ice40_spi_power_off(struct ice40_hcd *ihcd) regulator_disable(ihcd->gpio_vcc); if (ihcd->clk_en_gpio) gpio_direction_output(ihcd->clk_en_gpio, 0); if (ihcd->xo_clk) clk_disable_unprepare(ihcd->xo_clk); ihcd->powered = false; } Loading @@ -1376,11 +1382,19 @@ static int ice40_spi_power_up(struct ice40_hcd *ihcd) { int ret; if (ihcd->xo_clk) { ret = clk_prepare_enable(ihcd->xo_clk); if (ret < 0) { pr_err("fail to enable xo clk %d\n", ret); goto out; } } if (ihcd->clk_en_gpio) { ret = gpio_direction_output(ihcd->clk_en_gpio, 1); if (ret < 0) { pr_err("fail to enabel clk %d\n", ret); goto out; pr_err("fail to enable clk %d\n", ret); goto disable_xo; } } Loading Loading @@ -1424,17 +1438,13 @@ disable_gpio_vcc: disable_clk: if (ihcd->clk_en_gpio) gpio_direction_output(ihcd->clk_en_gpio, 0); disable_xo: if (ihcd->xo_clk) clk_disable_unprepare(ihcd->xo_clk); out: return ret; } static struct gpiomux_setting slave_select_setting = { .func = GPIOMUX_FUNC_GPIO, .drv = GPIOMUX_DRV_2MA, .pull = GPIOMUX_PULL_NONE, .dir = GPIOMUX_OUT_LOW, }; #define CONFIG_LOAD_FREQ_MAX_HZ 25000000 static int ice40_spi_cache_fw(struct ice40_hcd *ihcd) { Loading Loading @@ -1497,7 +1507,6 @@ out: static int ice40_spi_load_fw(struct ice40_hcd *ihcd) { int ret, i; struct gpiomux_setting old_setting; ret = gpio_direction_output(ihcd->reset_gpio, 0); if (ret < 0) { Loading @@ -1524,32 +1533,37 @@ static int ice40_spi_load_fw(struct ice40_hcd *ihcd) */ spi_bus_lock(ihcd->spi->master); ret = msm_gpiomux_write(ihcd->slave_select_gpio, GPIOMUX_SUSPENDED, &slave_select_setting, &old_setting); ret = gpio_request(ihcd->slave_select_gpio, "ice40_spi_cs"); if (ret < 0) { pr_err("fail to select the slave %d\n", ret); pr_err("fail to request slave select gpio %d\n", ret); spi_bus_unlock(ihcd->spi->master); goto out; } ret = gpio_direction_output(ihcd->slave_select_gpio, 0); if (ret < 0) { pr_err("fail to drive slave select gpio %d\n", ret); gpio_free(ihcd->slave_select_gpio); spi_bus_unlock(ihcd->spi->master); goto out; } ret = ice40_spi_power_up(ihcd); if (ret < 0) { pr_err("fail to power up the chip\n"); gpio_free(ihcd->slave_select_gpio); spi_bus_unlock(ihcd->spi->master); goto out; } /* * The databook says 1200 usec is required before the * chip becomes ready for the SPI transfer. */ usleep_range(1200, 1250); ret = msm_gpiomux_write(ihcd->slave_select_gpio, GPIOMUX_SUSPENDED, &old_setting, NULL); if (ret < 0) { pr_err("fail to de-select the slave %d\n", ret); goto power_off; } gpio_direction_output(ihcd->slave_select_gpio, 1); gpio_free(ihcd->slave_select_gpio); ret = spi_sync_locked(ihcd->spi, ihcd->fmsg); Loading Loading @@ -1599,6 +1613,32 @@ out: return ret; } static int ice40_spi_init_clocks(struct ice40_hcd *ihcd) { int ret = 0; /* * XO clock is the only supported clock. So no need to parse * the clock-names string. If there is no clock-names property, * there will not be XO clock. * * This XO clock can be either direct clock or pin control clock. * if it is pin control clock, clk_en gpio is used to control * the clock. */ if (!of_get_property(ihcd->spi->dev.of_node, "clock-names", NULL)) return 0; ihcd->xo_clk = devm_clk_get(&ihcd->spi->dev, "xo"); if (IS_ERR(ihcd->xo_clk)) { ret = PTR_ERR(ihcd->xo_clk); if (ret != -EPROBE_DEFER) pr_err("fail to get xo clk %d\n", ret); } return ret; } static int ice40_spi_init_regulators(struct ice40_hcd *ihcd) { int ret; Loading Loading @@ -1656,6 +1696,13 @@ static int ice40_spi_request_gpios(struct ice40_hcd *ihcd) { int ret; ihcd->pinctrl = devm_pinctrl_get_select_default(&ihcd->spi->dev); if (IS_ERR(ihcd->pinctrl)) { ret = PTR_ERR(ihcd->pinctrl); pr_err("fail to get pinctrl info %d\n", ret); goto out; } ret = devm_gpio_request(&ihcd->spi->dev, ihcd->reset_gpio, "ice40_reset"); if (ret < 0) { Loading Loading @@ -1952,6 +1999,12 @@ static int ice40_spi_probe(struct spi_device *spi) goto out; } ret = ice40_spi_init_clocks(ihcd); if (ret) { pr_err("fail to init clocks\n"); goto out; } ret = ice40_spi_init_regulators(ihcd); if (ret) { pr_err("fail to init regulators\n"); Loading Loading @@ -2062,6 +2115,7 @@ static int ice40_spi_remove(struct spi_device *spi) { struct usb_hcd *hcd = spi_get_drvdata(spi); struct ice40_hcd *ihcd = hcd_to_ihcd(hcd); struct pinctrl_state *s; debugfs_remove_recursive(ihcd->dbg_root); Loading @@ -2070,6 +2124,10 @@ static int ice40_spi_remove(struct spi_device *spi) destroy_workqueue(ihcd->wq); ice40_spi_power_off(ihcd); s = pinctrl_lookup_state(ihcd->pinctrl, PINCTRL_STATE_SLEEP); if (!IS_ERR(s)) pinctrl_select_state(ihcd->pinctrl, s); pm_runtime_disable(&spi->dev); pm_relax(&spi->dev); Loading