summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/tegra
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/tegra')
-rw-r--r--drivers/pinctrl/tegra/pinctrl-tegra.c52
-rw-r--r--drivers/pinctrl/tegra/pinctrl-tegra.h5
-rw-r--r--drivers/pinctrl/tegra/pinctrl-tegra194.c47
3 files changed, 76 insertions, 28 deletions
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
index cefbbb8d1a68..21661f6490d6 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
@@ -275,11 +275,57 @@ static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
return 0;
}
+static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int offset)
+{
+ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+ const struct tegra_pingroup *group;
+ u32 value;
+
+ if (!pmx->soc->sfsel_in_mux)
+ return 0;
+
+ group = &pmx->soc->groups[offset];
+
+ if (group->mux_reg < 0 || group->sfsel_bit < 0)
+ return -EINVAL;
+
+ value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
+ value &= ~BIT(group->sfsel_bit);
+ pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
+
+ return 0;
+}
+
+static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int offset)
+{
+ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+ const struct tegra_pingroup *group;
+ u32 value;
+
+ if (!pmx->soc->sfsel_in_mux)
+ return;
+
+ group = &pmx->soc->groups[offset];
+
+ if (group->mux_reg < 0 || group->sfsel_bit < 0)
+ return;
+
+ value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
+ value |= BIT(group->sfsel_bit);
+ pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
+}
+
static const struct pinmux_ops tegra_pinmux_ops = {
.get_functions_count = tegra_pinctrl_get_funcs_count,
.get_function_name = tegra_pinctrl_get_func_name,
.get_function_groups = tegra_pinctrl_get_func_groups,
.set_mux = tegra_pinctrl_set_mux,
+ .gpio_request_enable = tegra_pinctrl_gpio_request_enable,
+ .gpio_disable_free = tegra_pinctrl_gpio_disable_free,
};
static int tegra_pinconf_reg(struct tegra_pmx *pmx,
@@ -689,12 +735,12 @@ const struct dev_pm_ops tegra_pinctrl_pm = {
.resume = &tegra_pinctrl_resume
};
-static bool gpio_node_has_range(const char *compatible)
+static bool tegra_pinctrl_gpio_node_has_range(struct tegra_pmx *pmx)
{
struct device_node *np;
bool has_prop = false;
- np = of_find_compatible_node(NULL, NULL, compatible);
+ np = of_find_compatible_node(NULL, NULL, pmx->soc->gpio_compatible);
if (!np)
return has_prop;
@@ -794,7 +840,7 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
tegra_pinctrl_clear_parked_bits(pmx);
- if (!gpio_node_has_range(pmx->soc->gpio_compatible))
+ if (pmx->soc->ngpios > 0 && !tegra_pinctrl_gpio_node_has_range(pmx))
pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
platform_set_drvdata(pdev, pmx);
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.h b/drivers/pinctrl/tegra/pinctrl-tegra.h
index 0fc82eea9cf1..fcad7f74c5a2 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.h
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.h
@@ -107,7 +107,8 @@ struct tegra_function {
* drvup, slwr, slwf, and drvtype parameters.
* @drv_bank: Drive fields register bank.
* @hsm_bit: High Speed Mode register bit.
- * @schmitt_bit: Scmitt register bit.
+ * @sfsel_bit: GPIO/SFIO selection register bit.
+ * @schmitt_bit: Schmitt register bit.
* @lpmd_bit: Low Power Mode register bit.
* @drvdn_bit: Drive Down register bit.
* @drvdn_width: Drive Down field width.
@@ -153,6 +154,7 @@ struct tegra_pingroup {
s32 ioreset_bit:6;
s32 rcv_sel_bit:6;
s32 hsm_bit:6;
+ s32 sfsel_bit:6;
s32 schmitt_bit:6;
s32 lpmd_bit:6;
s32 drvdn_bit:6;
@@ -192,6 +194,7 @@ struct tegra_pinctrl_soc_data {
bool hsm_in_mux;
bool schmitt_in_mux;
bool drvtype_in_mux;
+ bool sfsel_in_mux;
};
extern const struct dev_pm_ops tegra_pinctrl_pm;
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra194.c b/drivers/pinctrl/tegra/pinctrl-tegra194.c
index daf44cf240c9..2e0b5f7bb095 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra194.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra194.c
@@ -24,17 +24,14 @@
/* Define unique ID for each pins */
enum pin_id {
- TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0 = 256,
- TEGRA_PIN_PEX_L5_RST_N_PGG1 = 257,
- TEGRA_PIN_NUM_GPIOS = 258,
+ TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0,
+ TEGRA_PIN_PEX_L5_RST_N_PGG1,
};
/* Table for pin descriptor */
static const struct pinctrl_pin_desc tegra194_pins[] = {
- PINCTRL_PIN(TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0,
- "TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0"),
- PINCTRL_PIN(TEGRA_PIN_PEX_L5_RST_N_PGG1,
- "TEGRA_PIN_PEX_L5_RST_N_PGG1"),
+ PINCTRL_PIN(TEGRA_PIN_PEX_L5_CLKREQ_N_PGG0, "PEX_L5_CLKREQ_N_PGG0"),
+ PINCTRL_PIN(TEGRA_PIN_PEX_L5_RST_N_PGG1, "PEX_L5_RST_N_PGG1"),
};
static const unsigned int pex_l5_clkreq_n_pgg0_pins[] = {
@@ -59,6 +56,7 @@ enum tegra_mux_dt {
{ \
.name = #lid, \
}
+
static struct tegra_function tegra194_functions[] = {
TEGRA_PIN_FUNCTION(rsvd0),
TEGRA_PIN_FUNCTION(rsvd1),
@@ -70,7 +68,7 @@ static struct tegra_function tegra194_functions[] = {
#define DRV_PINGROUP_ENTRY_Y(r, drvdn_b, drvdn_w, drvup_b, \
drvup_w, slwr_b, slwr_w, slwf_b, \
slwf_w, bank) \
- .drv_reg = ((r)), \
+ .drv_reg = ((r)), \
.drv_bank = bank, \
.drvdn_bit = drvdn_b, \
.drvdn_width = drvdn_w, \
@@ -89,7 +87,7 @@ static struct tegra_function tegra194_functions[] = {
.hsm_bit = -1, \
.mux_bank = bank, \
.mux_bit = 0, \
- .pupd_reg = ((r)), \
+ .pupd_reg = ((r)), \
.pupd_bank = bank, \
.pupd_bit = 2, \
.tri_reg = ((r)), \
@@ -97,6 +95,7 @@ static struct tegra_function tegra194_functions[] = {
.tri_bit = 4, \
.einput_bit = e_input, \
.odrain_bit = e_od, \
+ .sfsel_bit = 10, \
.schmitt_bit = schmitt_b, \
.drvtype_bit = 13, \
.drv_reg = -1, \
@@ -109,20 +108,20 @@ static struct tegra_function tegra194_functions[] = {
#define PINGROUP(pg_name, f0, f1, f2, f3, r, bank, pupd, e_lpbk, \
e_input, e_lpdr, e_od, schmitt_b, drvtype, io_rail) \
- { \
- .name = #pg_name, \
- .pins = pg_name##_pins, \
- .npins = ARRAY_SIZE(pg_name##_pins), \
- .funcs = { \
- TEGRA_MUX_##f0, \
- TEGRA_MUX_##f1, \
- TEGRA_MUX_##f2, \
- TEGRA_MUX_##f3, \
- }, \
- PIN_PINGROUP_ENTRY_Y(r, bank, pupd, e_lpbk, \
- e_input, e_od, \
- schmitt_b, drvtype), \
- drive_##pg_name, \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = ARRAY_SIZE(pg_name##_pins), \
+ .funcs = { \
+ TEGRA_MUX_##f0, \
+ TEGRA_MUX_##f1, \
+ TEGRA_MUX_##f2, \
+ TEGRA_MUX_##f3, \
+ }, \
+ PIN_PINGROUP_ENTRY_Y(r, bank, pupd, e_lpbk, \
+ e_input, e_od, \
+ schmitt_b, drvtype), \
+ drive_##pg_name, \
}
static const struct tegra_pingroup tegra194_groups[] = {
@@ -133,7 +132,6 @@ static const struct tegra_pingroup tegra194_groups[] = {
};
static const struct tegra_pinctrl_soc_data tegra194_pinctrl = {
- .ngpios = TEGRA_PIN_NUM_GPIOS,
.pins = tegra194_pins,
.npins = ARRAY_SIZE(tegra194_pins),
.functions = tegra194_functions,
@@ -143,6 +141,7 @@ static const struct tegra_pinctrl_soc_data tegra194_pinctrl = {
.hsm_in_mux = true,
.schmitt_in_mux = true,
.drvtype_in_mux = true,
+ .sfsel_in_mux = true,
};
static int tegra194_pinctrl_probe(struct platform_device *pdev)