NVIDIA: SAUCE: mmc: tegra: use gpio for voltage switching on fpga

Use dt property "nvidia,voltage-switch-gpio" parsed from DT
to select voltage level and toggle it for switching voltage
from 3.3V to 1.8V to support SD3.0 cards on FPGA.

http://nvbugs/2836586
http://nvbugs/2849456
http://nvbugs/4333277

Signed-off-by: Aniruddha Rao <anrao@nvidia.com>
(cherry-picked from commit b99819f98ef04c50b4a050a9f49e7e3c223868b1 and
and edited by anrao to work in k5.9)
Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Acked-by: Noah Wager <noah.wager@canonical.com>
Acked-by: Jacob Martin <jacob.martin@canonical.com>
Signed-off-by: Noah Wager <noah.wager@canonical.com>
This commit is contained in:
Aniruddha Rao
2020-07-27 12:22:27 +05:30
committed by Noah Wager
parent f6761eb922
commit 769780f8a1
+31 -1
View File
@@ -26,6 +26,8 @@
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <soc/tegra/common.h>
#include <soc/tegra/fuse.h>
@@ -213,6 +215,7 @@ struct sdhci_tegra {
u32 stream_id;
bool skip_clk_rst;
struct tegra_prod *prod_list;
int volt_switch_gpio;
};
static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
@@ -548,8 +551,20 @@ static int tegra_sdhci_set_padctrl(struct sdhci_host *host, int voltage,
sdhci_writel(host, reg,
SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
}
} else {
/* Toggle power gpio for switching voltage on FPGA */
if (gpio_is_valid(tegra_host->volt_switch_gpio)) {
if (voltage == MMC_SIGNAL_VOLTAGE_330) {
gpio_set_value(tegra_host->volt_switch_gpio, 1);
dev_info(mmc_dev(host->mmc),
"3.3V set by voltage switch gpio\n");
} else {
gpio_set_value(tegra_host->volt_switch_gpio, 0);
dev_info(mmc_dev(host->mmc),
"1.8V set by voltage switch gpio\n");
}
return 0;
}
/* Dual Voltage PADS Voltage selection */
if (!tegra_host->pad_control_available)
return 0;
@@ -1726,6 +1741,7 @@ static void sdhci_tegra_program_stream_id(struct sdhci_host *host)
static int sdhci_tegra_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const struct sdhci_tegra_soc_data *soc_data;
struct sdhci_host *host;
struct sdhci_pltfm_host *pltfm_host;
@@ -1874,6 +1890,20 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
usleep_range(2000, 4000);
}
tegra_host->volt_switch_gpio = of_get_named_gpio(np,
"nvidia,voltage-switch-gpio", 0);
if (gpio_is_valid(tegra_host->volt_switch_gpio)) {
rc = gpio_request(tegra_host->volt_switch_gpio, "sdhci_power");
if (rc)
dev_err(mmc_dev(host->mmc),
"failed to allocate gpio for voltage switch, "
"err: %d\n", rc);
gpio_direction_output(tegra_host->volt_switch_gpio, 1);
gpio_set_value(tegra_host->volt_switch_gpio, 1);
dev_info(mmc_dev(host->mmc),
"3.3V set initially by voltage switch gpio\n");
}
rc = sdhci_tegra_add_host(host);
if (rc)
goto err_add_host;