static int stm_ste_disable_ape_on_mipi60(void)
{
	int retval;

	retval = nmk_config_pins_sleep(ARRAY_AND_SIZE(mop500_stm_mipi60_pins));
	if (retval)
		STM_ERR("Failed to disable MIPI60\n");
	else {
		retval = nmk_config_pins(ARRAY_AND_SIZE(mop500_ske_pins));
		if (retval)
			STM_ERR("Failed to enable SKE gpio\n");
	}
	return retval;
}
static int stm_disable_modem_microsd(void)
{
	int retval;

	/* Reconfigure GPIO for SD */
	retval = nmk_config_pins_sleep(ARRAY_AND_SIZE(mop500_sdi0_pins));
	if (retval)
		STM_ERR("Failed to disable STM MODEM on MICRO SD "
		"and to reconfigure GPIO for SD\n");

	return retval;
}
/* Enable VAUX3 to power on buffer on STM MICRO SD cable */
static int enable_vaux3_for_microsd_cable(void)
{
	int error;

	regulator_aux3 = regulator_get(&ux500_stm_device.dev, "v-SD-STM");

	if (IS_ERR(regulator_aux3)) {
		error = PTR_ERR(regulator_aux3);
		STM_ERR("Failed to get regulator, supply: v-SD-STM\n");
		return error;
	}

	error = regulator_enable(regulator_aux3);

	if (error) {
		STM_ERR("Unable to enable regulator on SD card connector\n");
		return error;
	}

	STM_WARN("Regulator on SD card connector power on.\n");
	return error;
}
static int stm_disable_ape_microsd(void)
{
	int retval;

	/* Disable altC1 on GPIO23-28 (STMAPE) */
	prcmu_disable_stm_ape();

	/* Reconfigure GPIO for SD */
	retval = nmk_config_pins_sleep(ARRAY_AND_SIZE(mop500_sdi0_pins));
	if (retval)
		STM_ERR("Failed to disable STM APE on MICRO SD "
		"and to reconfigure GPIO for SD\n");

	return retval;
}
/* Enable or disable micro sd card buffers on HREF */
static void control_level_shifter_for_microsd(int gpio_dir)
{
	int gpio[2];

	if (machine_is_u8540()) {
		static struct regulator *regu_sdio;

		if (gpio_dir) {
			regu_sdio = regulator_get(&ux500_stm_device.dev,
					"vmmc_io");
			if (IS_ERR(regu_sdio)) {
				regu_sdio = NULL;
				STM_ERR("Failed to get regulator vmmc_io\n");
				return;
			}

			regulator_disable(regu_sdio);
			prcmu_set_sdmmc_psw(gpio_dir);
			regulator_set_voltage(regu_sdio, 2750000, 3000000);
			regulator_enable(regu_sdio);
			usleep_range(3000, 4000);
		} else if (regu_sdio) {
			regulator_disable(regu_sdio);
			regulator_put(regu_sdio);
			regu_sdio = NULL;
		}
		return;
	}

	if (machine_is_hrefv60() || machine_is_u9540() || machine_is_a9500()) {
		gpio[0] = HREFV60_SDMMC_EN_GPIO;
		gpio[1] = HREFV60_SDMMC_1V8_3V_GPIO;
	} else if (machine_is_u8520()) {
		gpio[0] = U8520_SDMMC_EN_GPIO;
		gpio[1] = U8520_SDMMC_1V8_3V_GPIO;
	} else {
		gpio[0] = MOP500_EGPIO(17);
		gpio[1] = MOP500_EGPIO(18);
	}

	/* Select the default 2.9V and enable / disable level shifter */
	gpio_direction_output(gpio[1], 0);
	gpio_direction_output(gpio[0], gpio_dir);
}
static int stm_enable_modem_microsd(void)
{
	int retval;

	/*
	 * Configure STM APE on GPIO23,GPIO28,GPIO27,GPIO26,GPIO25
	 * On HREF board an external SD buffer exist (ST6G3244ME)
	 * to perform level conversion from 1.8v to 3.3V on SD card
	 * signals. When STM is redirected on micro SD connector
	 * GPIO18,GP19,GPIO20 are configured in standard GPIO mode
	 * and are used to configure direction on external SD buffer
	 * ST6G3244ME.
	 */

	retval = nmk_config_pins(ARRAY_AND_SIZE(mop500_stm_modem_microsd_pins));
	if (retval)
		STM_ERR("Failed to enable STM MODEM on MICRO SD\n");

	return retval;
}
static int stm_ste_connection(enum stm_connection_type con_type)
{
	int retval = -EINVAL;

	/* Check if connection type has been changed */
	if (con_type == stm_current_connection)
		return 0;

	if (con_type != STM_DISCONNECT) {
		/*  Always enable MIPI34 GPIO pins */
		retval = nmk_config_pins(
				ARRAY_AND_SIZE(mop500_stm_mipi34_pins));
		if (retval) {
			STM_ERR("Failed to enable MIPI34\n");
			goto stm_ste_connection_error;
		}
	}

	switch (con_type) {
	case STM_DEFAULT_CONNECTION:
	case STM_STE_MODEM_ON_MIPI34_NONE_ON_MIPI60:
		/* Enable altC3 on GPIO70-74 (STMMOD) & GPIO75-76 (UARTMOD) */
		prcmu_enable_stm_mod_uart();
		retval = stm_ste_disable_ape_on_mipi60();
		break;

	case STM_STE_APE_ON_MIPI34_NONE_ON_MIPI60:
		/* Disable altC3 on GPIO70-74 (STMMOD) & GPIO75-76 (UARTMOD) */
		prcmu_disable_stm_mod_uart();
		retval = stm_ste_disable_ape_on_mipi60();
		break;

	case STM_STE_MODEM_ON_MIPI34_APE_ON_MIPI60:
		/* Enable altC3 on GPIO70-74 (STMMOD) and GPIO75-76 (UARTMOD) */
		prcmu_enable_stm_mod_uart();
		/* Enable APE on MIPI60 */
		if (!machine_is_snowball())
			retval = nmk_config_pins_sleep(ARRAY_AND_SIZE(mop500_ske_pins));
		if (retval)
			STM_ERR("Failed to disable SKE GPIO\n");
		else {
			retval = nmk_config_pins(
					ARRAY_AND_SIZE(mop500_stm_mipi60_pins));
			if (retval)
				STM_ERR("Failed to enable MIPI60\n");
		}
		break;

	case STM_STE_MODEM_ON_MICROSD:
		/* Disable APE on micro SD */
		retval = stm_disable_ape_microsd();
		/* Enable modem on micro SD */
		if (!retval)
			retval = stm_enable_modem_microsd();
		/* Enable SD card buffer and regulator on href */
		if (!retval && (stm_current_connection
			!= STM_STE_APE_ON_MICROSD)) {
			enable_level_shifter_for_microsd();
			enable_vaux3_for_microsd_cable();
		}
		break;

	case STM_STE_APE_ON_MICROSD:
		/* Disable modem on micro SD */
		retval = stm_disable_modem_microsd();
		/* Enable ape on micro SD */
		if (!retval)
			retval = stm_enable_ape_microsd();
		/* Enable SD card buffer and regulator on href */
		if (!retval && (stm_current_connection
			!= STM_STE_MODEM_ON_MICROSD)) {
			enable_level_shifter_for_microsd();
			enable_vaux3_for_microsd_cable();
		}
		break;

	case STM_DISCONNECT:
		retval = nmk_config_pins_sleep(
				ARRAY_AND_SIZE(mop500_stm_mipi34_pins));
		if (retval)
			STM_ERR("Failed to disable MIPI34\n");

		retval = stm_ste_disable_ape_on_mipi60();
		if (retval)
			STM_ERR("Failed to disable MIPI60\n");

		retval = stm_disable_modem_microsd();
		if (retval)
			STM_ERR("Failed to disable modem on microsd\n");

		retval = stm_disable_ape_microsd();
		if (retval)
			STM_ERR("Failed to disable ape on microsd\n");
		break;

	default:
		STM_ERR("Bad connection type\n");
		goto stm_ste_connection_error;
	}

	/* Disable power for microsd */
	if ((stm_current_connection == STM_STE_MODEM_ON_MICROSD)
	|| (stm_current_connection == STM_STE_APE_ON_MICROSD)) {
		if ((con_type != STM_STE_MODEM_ON_MICROSD)
		&& (con_type != STM_STE_APE_ON_MICROSD)) {
			disable_vaux3_for_microsd_cable();
			disable_level_shifter_for_microsd();
		}
	}

	stm_current_connection = con_type;

stm_ste_connection_error:
	return retval;
}