Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9281f50 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes Id0dc3b7b,I1172ff7f,Id181fd5e into msm-3.10

* changes:
  defconfig: msm8916: Enable USB-UICC support
  USB: ice40-hcd: Add pinctrl support
  USB: ice40-hcd: Add XO clock support
parents 7490fb25 2dde3598
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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.
@@ -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>;
		};
	};
+2 −0
Original line number Diff line number Diff line
@@ -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
+79 −21
Original line number Diff line number Diff line
@@ -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>
@@ -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;
@@ -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;
}
@@ -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;
		}
	}

@@ -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)
{
@@ -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) {
@@ -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);

@@ -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;
@@ -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) {
@@ -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");
@@ -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);

@@ -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);