esoc: Snapshot esoc drivers

Snapshot esoc components, headers and UAPI headers from
msm-3.18@24d0c1f91eb2850
(Merge "msm: mdss: dp: handle fast attention events")

Change-Id: I55e7ea4359c1f5b855f082e66d5816316da2fd48
Signed-off-by: Abhimanyu Kapur <abhimany@codeaurora.org>
(cherry picked from commit 5d8ee90e7f7e576b877813535d08a4123bedc49e)
Signed-off-by: Channagoud Kadabi <ckadabi@codeaurora.org>
diff --git a/drivers/esoc/esoc-mdm-pon.c b/drivers/esoc/esoc-mdm-pon.c
new file mode 100644
index 0000000..47d54db
--- /dev/null
+++ b/drivers/esoc/esoc-mdm-pon.c
@@ -0,0 +1,220 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "esoc-mdm.h"
+
+/* This function can be called from atomic context. */
+static int mdm4x_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic)
+{
+	int soft_reset_direction_assert = 0,
+	    soft_reset_direction_de_assert = 1;
+
+	if (mdm->soft_reset_inverted) {
+		soft_reset_direction_assert = 1;
+		soft_reset_direction_de_assert = 0;
+	}
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+			soft_reset_direction_assert);
+	/*
+	 * Allow PS hold assert to be detected
+	 */
+	if (!atomic)
+		usleep_range(8000, 9000);
+	else
+		mdelay(6);
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+			soft_reset_direction_de_assert);
+	return 0;
+}
+
+/* This function can be called from atomic context. */
+static int mdm9x55_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic)
+{
+	int soft_reset_direction_assert = 0,
+	    soft_reset_direction_de_assert = 1;
+
+	if (mdm->soft_reset_inverted) {
+		soft_reset_direction_assert = 1;
+		soft_reset_direction_de_assert = 0;
+	}
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+			soft_reset_direction_assert);
+	/*
+	 * Allow PS hold assert to be detected
+	 */
+	if (!atomic)
+		usleep_range(203000, 300000);
+	else
+		mdelay(203);
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+			soft_reset_direction_de_assert);
+	return 0;
+}
+
+
+static int mdm4x_do_first_power_on(struct mdm_ctrl *mdm)
+{
+	int i;
+	int pblrdy;
+	struct device *dev = mdm->dev;
+
+	dev_dbg(dev, "Powering on modem for the first time\n");
+	mdm_toggle_soft_reset(mdm, false);
+	/* Add a delay to allow PON sequence to complete*/
+	mdelay(50);
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1);
+	if (gpio_is_valid(MDM_GPIO(mdm, MDM2AP_PBLRDY))) {
+		for (i = 0; i  < MDM_PBLRDY_CNT; i++) {
+			pblrdy = gpio_get_value(MDM_GPIO(mdm, MDM2AP_PBLRDY));
+			if (pblrdy)
+				break;
+			usleep_range(5000, 6000);
+		}
+		dev_dbg(dev, "pblrdy i:%d\n", i);
+		mdelay(200);
+	}
+	/*
+	 * No PBLRDY gpio associated with this modem
+	 * Send request for image. Let userspace confirm establishment of
+	 * link to external modem.
+	 */
+	else
+		esoc_clink_queue_request(ESOC_REQ_IMG, mdm->esoc);
+	return 0;
+}
+
+static int mdm4x_power_down(struct mdm_ctrl *mdm)
+{
+	struct device *dev = mdm->dev;
+	int soft_reset_direction = mdm->soft_reset_inverted ? 1 : 0;
+	/* Assert the soft reset line whether mdm2ap_status went low or not */
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+					soft_reset_direction);
+	dev_dbg(dev, "Doing a hard reset\n");
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+						soft_reset_direction);
+	/*
+	 * Currently, there is a debounce timer on the charm PMIC. It is
+	 * necessary to hold the PMIC RESET low for 400ms
+	 * for the reset to fully take place. Sleep here to ensure the
+	 * reset has occurred before the function exits.
+	 */
+	mdelay(400);
+	return 0;
+}
+
+static int mdm9x55_power_down(struct mdm_ctrl *mdm)
+{
+	struct device *dev = mdm->dev;
+	int soft_reset_direction = mdm->soft_reset_inverted ? 1 : 0;
+	/* Assert the soft reset line whether mdm2ap_status went low or not */
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+					soft_reset_direction);
+	dev_dbg(dev, "Doing a hard reset\n");
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+						soft_reset_direction);
+	/*
+	 * Currently, there is a debounce timer on the charm PMIC. It is
+	 * necessary to hold the PMIC RESET low for 406ms
+	 * for the reset to fully take place. Sleep here to ensure the
+	 * reset has occurred before the function exits.
+	 */
+	mdelay(406);
+	return 0;
+}
+
+static void mdm4x_cold_reset(struct mdm_ctrl *mdm)
+{
+	dev_dbg(mdm->dev, "Triggering mdm cold reset");
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+			!!mdm->soft_reset_inverted);
+	mdelay(300);
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+			!mdm->soft_reset_inverted);
+}
+
+static void mdm9x55_cold_reset(struct mdm_ctrl *mdm)
+{
+	dev_dbg(mdm->dev, "Triggering mdm cold reset");
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+			!!mdm->soft_reset_inverted);
+	mdelay(334);
+	gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+			!mdm->soft_reset_inverted);
+}
+
+static int mdm4x_pon_dt_init(struct mdm_ctrl *mdm)
+{
+	int val;
+	struct device_node *node = mdm->dev->of_node;
+	enum of_gpio_flags flags = OF_GPIO_ACTIVE_LOW;
+
+	val = of_get_named_gpio_flags(node, "qcom,ap2mdm-soft-reset-gpio",
+						0, &flags);
+	if (val >= 0) {
+		MDM_GPIO(mdm, AP2MDM_SOFT_RESET) = val;
+		if (flags & OF_GPIO_ACTIVE_LOW)
+			mdm->soft_reset_inverted = 1;
+		return 0;
+	} else
+		return -EIO;
+}
+
+static int mdm4x_pon_setup(struct mdm_ctrl *mdm)
+{
+	struct device *dev = mdm->dev;
+
+	if (gpio_is_valid(MDM_GPIO(mdm, AP2MDM_SOFT_RESET))) {
+		if (gpio_request(MDM_GPIO(mdm, AP2MDM_SOFT_RESET),
+					 "AP2MDM_SOFT_RESET")) {
+			dev_err(dev, "Cannot config AP2MDM_SOFT_RESET gpio\n");
+			return -EIO;
+		}
+	}
+	return 0;
+}
+
+struct mdm_pon_ops mdm9x25_pon_ops = {
+	.pon = mdm4x_do_first_power_on,
+	.soft_reset = mdm4x_toggle_soft_reset,
+	.poff_force = mdm4x_power_down,
+	.cold_reset = mdm4x_cold_reset,
+	.dt_init = mdm4x_pon_dt_init,
+	.setup = mdm4x_pon_setup,
+};
+
+struct mdm_pon_ops mdm9x35_pon_ops = {
+	.pon = mdm4x_do_first_power_on,
+	.soft_reset = mdm4x_toggle_soft_reset,
+	.poff_force = mdm4x_power_down,
+	.cold_reset = mdm4x_cold_reset,
+	.dt_init = mdm4x_pon_dt_init,
+	.setup = mdm4x_pon_setup,
+};
+
+struct mdm_pon_ops mdm9x45_pon_ops = {
+	.pon = mdm4x_do_first_power_on,
+	.soft_reset = mdm4x_toggle_soft_reset,
+	.poff_force = mdm4x_power_down,
+	.cold_reset = mdm4x_cold_reset,
+	.dt_init = mdm4x_pon_dt_init,
+	.setup = mdm4x_pon_setup,
+};
+
+struct mdm_pon_ops mdm9x55_pon_ops = {
+	.pon = mdm4x_do_first_power_on,
+	.soft_reset = mdm9x55_toggle_soft_reset,
+	.poff_force = mdm9x55_power_down,
+	.cold_reset = mdm9x55_cold_reset,
+	.dt_init = mdm4x_pon_dt_init,
+	.setup = mdm4x_pon_setup,
+};