@@ -34,8 +34,9 @@ static const char *const cv1800b_power_domain_desc[] = {
[VDDIO_SD0_SPI] = "VDDIO_SD0_SPI",
};
-static int cv1800b_get_pull_up(struct cv1800_pin *pin, const u32 *psmap)
+static int cv1800b_get_pull_up(const struct sophgo_pin *sp, const u32 *psmap)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
u32 pstate = psmap[pin->power_domain];
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
@@ -54,8 +55,9 @@ static int cv1800b_get_pull_up(struct cv1800_pin *pin, const u32 *psmap)
return -ENOTSUPP;
}
-static int cv1800b_get_pull_down(struct cv1800_pin *pin, const u32 *psmap)
+static int cv1800b_get_pull_down(const struct sophgo_pin *sp, const u32 *psmap)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
u32 pstate = psmap[pin->power_domain];
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
@@ -108,9 +110,10 @@ static const u32 cv1800b_eth_oc_map[] = {
17800
};
-static int cv1800b_get_oc_map(struct cv1800_pin *pin, const u32 *psmap,
+static int cv1800b_get_oc_map(const struct sophgo_pin *sp, const u32 *psmap,
const u32 **map)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
u32 pstate = psmap[pin->power_domain];
@@ -153,9 +156,10 @@ static const u32 cv1800b_18od33_3v3_schmitt_map[] = {
1100000
};
-static int cv1800b_get_schmitt_map(struct cv1800_pin *pin, const u32 *psmap,
+static int cv1800b_get_schmitt_map(const struct sophgo_pin *sp, const u32 *psmap,
const u32 **map)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
u32 pstate = psmap[pin->power_domain];
@@ -177,11 +181,11 @@ static int cv1800b_get_schmitt_map(struct cv1800_pin *pin, const u32 *psmap,
return -ENOTSUPP;
}
-static const struct cv1800_vddio_cfg_ops cv1800b_vddio_cfg_ops = {
+static const struct sophgo_vddio_cfg_ops cv1800b_vddio_cfg_ops = {
.get_pull_up = cv1800b_get_pull_up,
.get_pull_down = cv1800b_get_pull_down,
.get_oc_map = cv1800b_get_oc_map,
- .get_schmitt_map = cv1800b_get_schmitt_map,
+ .get_schmitt_map = cv1800b_get_schmitt_map,
};
static const struct pinctrl_pin_desc cv1800b_pins[] = {
@@ -433,13 +437,14 @@ static const struct cv1800_pin cv1800b_pin_data[ARRAY_SIZE(cv1800b_pins)] = {
CV1800_PINCONF_AREA_SYS, 0x120, 5),
};
-static const struct cv1800_pinctrl_data cv1800b_pindata = {
+static const struct sophgo_pinctrl_data cv1800b_pindata = {
.pins = cv1800b_pins,
.pindata = cv1800b_pin_data,
.pdnames = cv1800b_power_domain_desc,
.vddio_ops = &cv1800b_vddio_cfg_ops,
.npins = ARRAY_SIZE(cv1800b_pins),
- .npd = ARRAY_SIZE(cv1800b_power_domain_desc),
+ .npds = ARRAY_SIZE(cv1800b_power_domain_desc),
+ .pinsize = sizeof(struct cv1800_pin),
};
static const struct of_device_id cv1800b_pinctrl_ids[] = {
@@ -40,8 +40,9 @@ static const char *const cv1812h_power_domain_desc[] = {
[VDDIO_VIVO] = "VDDIO_VIVO",
};
-static int cv1812h_get_pull_up(struct cv1800_pin *pin, const u32 *psmap)
+static int cv1812h_get_pull_up(const struct sophgo_pin *sp, const u32 *psmap)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
u32 pstate = psmap[pin->power_domain];
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
@@ -60,8 +61,9 @@ static int cv1812h_get_pull_up(struct cv1800_pin *pin, const u32 *psmap)
return -ENOTSUPP;
}
-static int cv1812h_get_pull_down(struct cv1800_pin *pin, const u32 *psmap)
+static int cv1812h_get_pull_down(const struct sophgo_pin *sp, const u32 *psmap)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
u32 pstate = psmap[pin->power_domain];
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
@@ -114,9 +116,10 @@ static const u32 cv1812h_eth_oc_map[] = {
17800
};
-static int cv1812h_get_oc_map(struct cv1800_pin *pin, const u32 *psmap,
+static int cv1812h_get_oc_map(const struct sophgo_pin *sp, const u32 *psmap,
const u32 **map)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
u32 pstate = psmap[pin->power_domain];
@@ -159,9 +162,10 @@ static const u32 cv1812h_18od33_3v3_schmitt_map[] = {
1100000
};
-static int cv1812h_get_schmitt_map(struct cv1800_pin *pin, const u32 *psmap,
+static int cv1812h_get_schmitt_map(const struct sophgo_pin *sp, const u32 *psmap,
const u32 **map)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
u32 pstate = psmap[pin->power_domain];
@@ -183,11 +187,11 @@ static int cv1812h_get_schmitt_map(struct cv1800_pin *pin, const u32 *psmap,
return -ENOTSUPP;
}
-static const struct cv1800_vddio_cfg_ops cv1812h_vddio_cfg_ops = {
+static const struct sophgo_vddio_cfg_ops cv1812h_vddio_cfg_ops = {
.get_pull_up = cv1812h_get_pull_up,
.get_pull_down = cv1812h_get_pull_down,
.get_oc_map = cv1812h_get_oc_map,
- .get_schmitt_map = cv1812h_get_schmitt_map,
+ .get_schmitt_map = cv1812h_get_schmitt_map,
};
static const struct pinctrl_pin_desc cv1812h_pins[] = {
@@ -742,13 +746,14 @@ static const struct cv1800_pin cv1812h_pin_data[ARRAY_SIZE(cv1812h_pins)] = {
CV1800_PINCONF_AREA_RTC, 0x028),
};
-static const struct cv1800_pinctrl_data cv1812h_pindata = {
+static const struct sophgo_pinctrl_data cv1812h_pindata = {
.pins = cv1812h_pins,
.pindata = cv1812h_pin_data,
.pdnames = cv1812h_power_domain_desc,
.vddio_ops = &cv1812h_vddio_cfg_ops,
.npins = ARRAY_SIZE(cv1812h_pins),
- .npd = ARRAY_SIZE(cv1812h_power_domain_desc),
+ .npds = ARRAY_SIZE(cv1812h_power_domain_desc),
+ .pinsize = sizeof(struct cv1800_pin),
};
static const struct of_device_id cv1812h_pinctrl_ids[] = {
@@ -24,30 +24,16 @@
#include <dt-bindings/pinctrl/pinctrl-cv18xx.h>
-#include "../core.h"
#include "../pinctrl-utils.h"
#include "../pinconf.h"
#include "../pinmux.h"
#include "pinctrl-cv18xx.h"
-struct cv1800_pinctrl {
- struct device *dev;
- struct pinctrl_dev *pctl_dev;
- const struct cv1800_pinctrl_data *data;
- struct pinctrl_desc pdesc;
+struct cv1800_priv {
u32 *power_cfg;
-
- struct mutex mutex;
- raw_spinlock_t lock;
-
void __iomem *regs[2];
};
-struct cv1800_pin_mux_config {
- struct cv1800_pin *pin;
- u32 config;
-};
-
static unsigned int cv1800_dt_get_pin(u32 value)
{
return value & GENMASK(15, 0);
@@ -68,38 +54,42 @@ static unsigned int cv1800_dt_get_pin_mux2(u32 value)
static int cv1800_cmp_pin(const void *key, const void *pivot)
{
- const struct cv1800_pin *pin = pivot;
+ const struct sophgo_pin *pin = pivot;
int pin_id = (long)key;
- int pivid = pin->pin;
+ int pivid = pin->id;
return pin_id - pivid;
}
-static int cv1800_set_power_cfg(struct cv1800_pinctrl *pctrl,
+static int cv1800_set_power_cfg(struct sophgo_pinctrl *pctrl,
u8 domain, u32 cfg)
{
- if (domain >= pctrl->data->npd)
+ struct cv1800_priv *priv = pctrl->priv_ctrl;
+
+ if (domain >= pctrl->data->npds)
return -ENOTSUPP;
- if (pctrl->power_cfg[domain] && pctrl->power_cfg[domain] != cfg)
+ if (priv->power_cfg[domain] && priv->power_cfg[domain] != cfg)
return -EINVAL;
- pctrl->power_cfg[domain] = cfg;
+ priv->power_cfg[domain] = cfg;
return 0;
}
-static int cv1800_get_power_cfg(struct cv1800_pinctrl *pctrl,
+static int cv1800_get_power_cfg(struct sophgo_pinctrl *pctrl,
u8 domain)
{
- return pctrl->power_cfg[domain];
+ struct cv1800_priv *priv = pctrl->priv_ctrl;
+
+ return priv->power_cfg[domain];
}
-static struct cv1800_pin *cv1800_get_pin(struct cv1800_pinctrl *pctrl,
- unsigned long pin)
+static const struct sophgo_pin *cv1800_get_pin(struct sophgo_pinctrl *pctrl,
+ unsigned long pin)
{
return bsearch((void *)pin, pctrl->data->pindata, pctrl->data->npins,
- sizeof(struct cv1800_pin), cv1800_cmp_pin);
+ pctrl->data->pinsize, cv1800_cmp_pin);
}
#define PIN_BGA_ID_OFFSET 8
@@ -112,7 +102,7 @@ static const char *const io_type_desc[] = {
"ETH"
};
-static const char *cv1800_get_power_cfg_desc(struct cv1800_pinctrl *pctrl,
+static const char *cv1800_get_power_cfg_desc(struct sophgo_pinctrl *pctrl,
u8 domain)
{
return pctrl->data->pdnames[domain];
@@ -121,53 +111,57 @@ static const char *cv1800_get_power_cfg_desc(struct cv1800_pinctrl *pctrl,
static void cv1800_pctrl_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *seq, unsigned int pin_id)
{
- struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
- struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);
+ struct sophgo_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct cv1800_priv *priv = pctrl->priv_ctrl;
+ const struct sophgo_pin *sp = cv1800_get_pin(pctrl, pin_id);
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
+ u32 pin_hwid = pin->pin.id;
u32 value;
void __iomem *reg;
- if (pin->pin >> PIN_BGA_ID_OFFSET)
+ if (pin_hwid >> PIN_BGA_ID_OFFSET)
seq_printf(seq, "pos: %c%u ",
- 'A' + (pin->pin >> PIN_BGA_ID_OFFSET) - 1,
- pin->pin & PIN_BGA_ID_MASK);
+ 'A' + (pin_hwid >> PIN_BGA_ID_OFFSET) - 1,
+ pin_hwid & PIN_BGA_ID_MASK);
else
- seq_printf(seq, "pos: %u ", pin->pin);
+ seq_printf(seq, "pos: %u ", pin_hwid);
seq_printf(seq, "power-domain: %s ",
cv1800_get_power_cfg_desc(pctrl, pin->power_domain));
seq_printf(seq, "type: %s ", io_type_desc[type]);
- reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux);
+ reg = cv1800_pinctrl_get_component_addr(priv, &pin->mux);
value = readl(reg);
seq_printf(seq, "mux: 0x%08x ", value);
- if (pin->flags & CV1800_PIN_HAVE_MUX2) {
- reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux2);
+ if (pin->pin.flags & CV1800_PIN_HAVE_MUX2) {
+ reg = cv1800_pinctrl_get_component_addr(priv, &pin->mux2);
value = readl(reg);
seq_printf(seq, "mux2: 0x%08x ", value);
}
if (type == IO_TYPE_1V8_ONLY || type == IO_TYPE_1V8_OR_3V3) {
- reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->conf);
+ reg = cv1800_pinctrl_get_component_addr(priv, &pin->conf);
value = readl(reg);
seq_printf(seq, "conf: 0x%08x ", value);
}
}
-static int cv1800_verify_pinmux_config(const struct cv1800_pin_mux_config *config)
+static int cv1800_verify_pinmux_config(const struct sophgo_pin_mux_config *config)
{
+ struct cv1800_pin *pin = sophgo_to_cv1800_pin(config->pin);
unsigned int mux = cv1800_dt_get_pin_mux(config->config);
unsigned int mux2 = cv1800_dt_get_pin_mux2(config->config);
- if (mux > config->pin->mux.max)
+ if (mux > pin->mux.max)
return -EINVAL;
- if (config->pin->flags & CV1800_PIN_HAVE_MUX2) {
- if (mux != config->pin->mux2.pfunc)
+ if (pin->pin.flags & CV1800_PIN_HAVE_MUX2) {
+ if (mux != pin->mux2.pfunc)
return -EINVAL;
- if (mux2 > config->pin->mux2.max)
+ if (mux2 > pin->mux2.max)
return -EINVAL;
} else {
if (mux2 != PIN_MUX_INVALD)
@@ -177,9 +171,10 @@ static int cv1800_verify_pinmux_config(const struct cv1800_pin_mux_config *confi
return 0;
}
-static int cv1800_verify_pin_group(const struct cv1800_pin_mux_config *mux,
+static int cv1800_verify_pin_group(const struct sophgo_pin_mux_config *mux,
unsigned long npins)
{
+ struct cv1800_pin *pin;
enum cv1800_pin_io_type type;
u8 power_domain;
int i;
@@ -187,12 +182,15 @@ static int cv1800_verify_pin_group(const struct cv1800_pin_mux_config *mux,
if (npins == 1)
return 0;
- type = cv1800_pin_io_type(mux[0].pin);
- power_domain = mux[0].pin->power_domain;
+ pin = sophgo_to_cv1800_pin(mux[0].pin);
+ type = cv1800_pin_io_type(pin);
+ power_domain = pin->power_domain;
for (i = 0; i < npins; i++) {
- if (type != cv1800_pin_io_type(mux[i].pin) ||
- power_domain != mux[i].pin->power_domain)
+ pin = sophgo_to_cv1800_pin(mux[i].pin);
+
+ if (type != cv1800_pin_io_type(pin) ||
+ power_domain != pin->power_domain)
return -ENOTSUPP;
}
@@ -204,7 +202,7 @@ static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
struct pinctrl_map **maps,
unsigned int *num_maps)
{
- struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct sophgo_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
struct device *dev = pctrl->dev;
struct device_node *child;
struct pinctrl_map *map;
@@ -230,7 +228,8 @@ static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
for_each_available_child_of_node(np, child) {
int npins = of_property_count_u32_elems(child, "pinmux");
unsigned int *pins;
- struct cv1800_pin_mux_config *pinmuxs;
+ struct sophgo_pin_mux_config *pinmuxs;
+ struct cv1800_pin *pin;
u32 config, power;
int i;
@@ -303,8 +302,8 @@ static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
goto dt_failed;
}
- ret = cv1800_set_power_cfg(pctrl, pinmuxs[0].pin->power_domain,
- power);
+ pin = sophgo_to_cv1800_pin(pinmuxs[0].pin);
+ ret = cv1800_set_power_cfg(pctrl, pin->power_domain, power);
if (ret)
goto dt_failed;
@@ -371,9 +370,10 @@ static const struct pinctrl_ops cv1800_pctrl_ops = {
static int cv1800_pmx_set_mux(struct pinctrl_dev *pctldev,
unsigned int fsel, unsigned int gsel)
{
- struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct sophgo_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct cv1800_priv *priv = pctrl->priv_ctrl;
const struct group_desc *group;
- const struct cv1800_pin_mux_config *configs;
+ const struct sophgo_pin_mux_config *configs;
unsigned int i;
group = pinctrl_generic_get_group(pctldev, gsel);
@@ -383,7 +383,7 @@ static int cv1800_pmx_set_mux(struct pinctrl_dev *pctldev,
configs = group->data;
for (i = 0; i < group->grp.npins; i++) {
- const struct cv1800_pin *pin = configs[i].pin;
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(configs[i].pin);
u32 value = configs[i].config;
void __iomem *reg_mux;
void __iomem *reg_mux2;
@@ -391,8 +391,8 @@ static int cv1800_pmx_set_mux(struct pinctrl_dev *pctldev,
u32 mux;
u32 mux2;
- reg_mux = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux);
- reg_mux2 = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux2);
+ reg_mux = cv1800_pinctrl_get_component_addr(priv, &pin->mux);
+ reg_mux2 = cv1800_pinctrl_get_component_addr(priv, &pin->mux2);
mux = cv1800_dt_get_pin_mux(value);
mux2 = cv1800_dt_get_pin_mux2(value);
@@ -421,25 +421,28 @@ static const struct pinmux_ops cv1800_pmx_ops = {
#define PIN_IO_BUS_HOLD BIT(10)
#define PIN_IO_OUT_FAST_SLEW BIT(11)
-static u32 cv1800_pull_down_typical_resistor(struct cv1800_pinctrl *pctrl,
- struct cv1800_pin *pin)
+static u32 cv1800_pull_down_typical_resistor(struct sophgo_pinctrl *pctrl,
+ const struct sophgo_pin *pin,
+ const u32 *power_cfg)
{
- return pctrl->data->vddio_ops->get_pull_down(pin, pctrl->power_cfg);
+ return pctrl->data->vddio_ops->get_pull_down(pin, power_cfg);
}
-static u32 cv1800_pull_up_typical_resistor(struct cv1800_pinctrl *pctrl,
- struct cv1800_pin *pin)
+static u32 cv1800_pull_up_typical_resistor(struct sophgo_pinctrl *pctrl,
+ const struct sophgo_pin *pin,
+ const u32 *power_cfg)
{
- return pctrl->data->vddio_ops->get_pull_up(pin, pctrl->power_cfg);
+ return pctrl->data->vddio_ops->get_pull_up(pin, power_cfg);
}
-static int cv1800_pinctrl_oc2reg(struct cv1800_pinctrl *pctrl,
- struct cv1800_pin *pin, u32 target)
+static int cv1800_pinctrl_oc2reg(struct sophgo_pinctrl *pctrl,
+ const struct sophgo_pin *pin,
+ const u32 *power_cfg, u32 target)
{
const u32 *map;
int i, len;
- len = pctrl->data->vddio_ops->get_oc_map(pin, pctrl->power_cfg, &map);
+ len = pctrl->data->vddio_ops->get_oc_map(pin, power_cfg, &map);
if (len < 0)
return len;
@@ -451,13 +454,14 @@ static int cv1800_pinctrl_oc2reg(struct cv1800_pinctrl *pctrl,
return -EINVAL;
}
-static int cv1800_pinctrl_reg2oc(struct cv1800_pinctrl *pctrl,
- struct cv1800_pin *pin, u32 reg)
+static int cv1800_pinctrl_reg2oc(struct sophgo_pinctrl *pctrl,
+ const struct sophgo_pin *pin,
+ const u32 *power_cfg, u32 reg)
{
const u32 *map;
int len;
- len = pctrl->data->vddio_ops->get_oc_map(pin, pctrl->power_cfg, &map);
+ len = pctrl->data->vddio_ops->get_oc_map(pin, power_cfg, &map);
if (len < 0)
return len;
@@ -467,14 +471,14 @@ static int cv1800_pinctrl_reg2oc(struct cv1800_pinctrl *pctrl,
return map[reg];
}
-static int cv1800_pinctrl_schmitt2reg(struct cv1800_pinctrl *pctrl,
- struct cv1800_pin *pin, u32 target)
+static int cv1800_pinctrl_schmitt2reg(struct sophgo_pinctrl *pctrl,
+ const struct sophgo_pin *pin,
+ const u32 *power_cfg, u32 target)
{
const u32 *map;
int i, len;
- len = pctrl->data->vddio_ops->get_schmitt_map(pin, pctrl->power_cfg,
- &map);
+ len = pctrl->data->vddio_ops->get_schmitt_map(pin, power_cfg, &map);
if (len < 0)
return len;
@@ -486,14 +490,14 @@ static int cv1800_pinctrl_schmitt2reg(struct cv1800_pinctrl *pctrl,
return -EINVAL;
}
-static int cv1800_pinctrl_reg2schmitt(struct cv1800_pinctrl *pctrl,
- struct cv1800_pin *pin, u32 reg)
+static int cv1800_pinctrl_reg2schmitt(struct sophgo_pinctrl *pctrl,
+ const struct sophgo_pin *pin,
+ const u32 *power_cfg, u32 reg)
{
const u32 *map;
int len;
- len = pctrl->data->vddio_ops->get_schmitt_map(pin, pctrl->power_cfg,
- &map);
+ len = pctrl->data->vddio_ops->get_schmitt_map(pin, power_cfg, &map);
if (len < 0)
return len;
@@ -506,9 +510,11 @@ static int cv1800_pinctrl_reg2schmitt(struct cv1800_pinctrl *pctrl,
static int cv1800_pconf_get(struct pinctrl_dev *pctldev,
unsigned int pin_id, unsigned long *config)
{
- struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct sophgo_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct cv1800_priv *priv = pctrl->priv_ctrl;
int param = pinconf_to_config_param(*config);
- struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);
+ const struct sophgo_pin *sp = cv1800_get_pin(pctrl, pin_id);
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type;
u32 value;
u32 arg;
@@ -522,28 +528,28 @@ static int cv1800_pconf_get(struct pinctrl_dev *pctldev,
if (type == IO_TYPE_ETH || type == IO_TYPE_AUDIO)
return -ENOTSUPP;
- value = readl(cv1800_pinctrl_get_component_addr(pctrl, &pin->conf));
+ value = readl(cv1800_pinctrl_get_component_addr(priv, &pin->conf));
switch (param) {
case PIN_CONFIG_BIAS_PULL_DOWN:
enabled = FIELD_GET(PIN_IO_PULLDOWN, value);
- arg = cv1800_pull_down_typical_resistor(pctrl, pin);
+ arg = cv1800_pull_down_typical_resistor(pctrl, sp, priv->power_cfg);
break;
case PIN_CONFIG_BIAS_PULL_UP:
enabled = FIELD_GET(PIN_IO_PULLUP, value);
- arg = cv1800_pull_up_typical_resistor(pctrl, pin);
+ arg = cv1800_pull_up_typical_resistor(pctrl, sp, priv->power_cfg);
break;
case PIN_CONFIG_DRIVE_STRENGTH_UA:
enabled = true;
arg = FIELD_GET(PIN_IO_DRIVE, value);
- ret = cv1800_pinctrl_reg2oc(pctrl, pin, arg);
+ ret = cv1800_pinctrl_reg2oc(pctrl, sp, priv->power_cfg, arg);
if (ret < 0)
return ret;
arg = ret;
break;
case PIN_CONFIG_INPUT_SCHMITT_UV:
arg = FIELD_GET(PIN_IO_SCHMITT, value);
- ret = cv1800_pinctrl_reg2schmitt(pctrl, pin, arg);
+ ret = cv1800_pinctrl_reg2schmitt(pctrl, sp, priv->power_cfg, arg);
if (ret < 0)
return ret;
arg = ret;
@@ -570,12 +576,14 @@ static int cv1800_pconf_get(struct pinctrl_dev *pctldev,
return enabled ? 0 : -EINVAL;
}
-static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,
- struct cv1800_pin *pin,
+static int cv1800_pinconf_compute_config(struct sophgo_pinctrl *pctrl,
+ const struct sophgo_pin *sp,
unsigned long *configs,
unsigned int num_configs,
u32 *value, u32 *mask)
{
+ struct cv1800_priv *priv = pctrl->priv_ctrl;
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
int i;
u32 v = 0, m = 0;
enum cv1800_pin_io_type type;
@@ -604,7 +612,8 @@ static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,
m |= PIN_IO_PULLUP;
break;
case PIN_CONFIG_DRIVE_STRENGTH_UA:
- ret = cv1800_pinctrl_oc2reg(pctrl, pin, arg);
+ ret = cv1800_pinctrl_oc2reg(pctrl, sp,
+ priv->power_cfg, arg);
if (ret < 0)
return ret;
v &= ~PIN_IO_DRIVE;
@@ -612,7 +621,8 @@ static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,
m |= PIN_IO_DRIVE;
break;
case PIN_CONFIG_INPUT_SCHMITT_UV:
- ret = cv1800_pinctrl_schmitt2reg(pctrl, pin, arg);
+ ret = cv1800_pinctrl_schmitt2reg(pctrl, sp,
+ priv->power_cfg, arg);
if (ret < 0)
return ret;
v &= ~PIN_IO_SCHMITT;
@@ -643,19 +653,22 @@ static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,
return 0;
}
-static int cv1800_pin_set_config(struct cv1800_pinctrl *pctrl,
+static int cv1800_pin_set_config(struct sophgo_pinctrl *pctrl,
unsigned int pin_id,
u32 value, u32 mask)
{
- struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);
+ struct cv1800_priv *priv = pctrl->priv_ctrl;
+ const struct sophgo_pin *sp = cv1800_get_pin(pctrl, pin_id);
+ struct cv1800_pin *pin;
unsigned long flags;
void __iomem *addr;
u32 reg;
- if (!pin)
+ if (!sp)
return -EINVAL;
+ pin = sophgo_to_cv1800_pin(sp);
- addr = cv1800_pinctrl_get_component_addr(pctrl, &pin->conf);
+ addr = cv1800_pinctrl_get_component_addr(priv, &pin->conf);
raw_spin_lock_irqsave(&pctrl->lock, flags);
reg = readl(addr);
@@ -671,14 +684,14 @@ static int cv1800_pconf_set(struct pinctrl_dev *pctldev,
unsigned int pin_id, unsigned long *configs,
unsigned int num_configs)
{
- struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
- struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);
+ struct sophgo_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ const struct sophgo_pin *sp = cv1800_get_pin(pctrl, pin_id);
u32 value, mask;
- if (!pin)
- return -ENODEV;
+ if (!sp)
+ return -EINVAL;
- if (cv1800_pinconf_compute_config(pctrl, pin,
+ if (cv1800_pinconf_compute_config(pctrl, sp,
configs, num_configs,
&value, &mask))
return -ENOTSUPP;
@@ -691,9 +704,9 @@ static int cv1800_pconf_group_set(struct pinctrl_dev *pctldev,
unsigned long *configs,
unsigned int num_configs)
{
- struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct sophgo_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct group_desc *group;
- const struct cv1800_pin_mux_config *pinmuxs;
+ const struct sophgo_pin_mux_config *pinmuxs;
u32 value, mask;
int i;
@@ -724,33 +737,38 @@ static const struct pinconf_ops cv1800_pconf_ops = {
int cv1800_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct cv1800_pinctrl *pctrl;
- const struct cv1800_pinctrl_data *pctrl_data;
+ struct sophgo_pinctrl *pctrl;
+ struct cv1800_priv *priv;
+ const struct sophgo_pinctrl_data *pctrl_data;
int ret;
pctrl_data = device_get_match_data(dev);
if (!pctrl_data)
return -ENODEV;
- if (pctrl_data->npins == 0 || pctrl_data->npd == 0)
+ if (pctrl_data->npins == 0 || pctrl_data->npds == 0)
return dev_err_probe(dev, -EINVAL, "invalid pin data\n");
pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
return -ENOMEM;
- pctrl->power_cfg = devm_kcalloc(dev, pctrl_data->npd,
- sizeof(u32), GFP_KERNEL);
- if (!pctrl->power_cfg)
+ priv = devm_kzalloc(dev, sizeof(struct cv1800_priv), GFP_KERNEL);
+ if (!priv)
return -ENOMEM;
- pctrl->regs[0] = devm_platform_ioremap_resource_byname(pdev, "sys");
- if (IS_ERR(pctrl->regs[0]))
- return PTR_ERR(pctrl->regs[0]);
+ priv->power_cfg = devm_kcalloc(dev, pctrl_data->npds,
+ sizeof(u32), GFP_KERNEL);
+ if (!priv->power_cfg)
+ return -ENOMEM;
+
+ priv->regs[0] = devm_platform_ioremap_resource_byname(pdev, "sys");
+ if (IS_ERR(priv->regs[0]))
+ return PTR_ERR(priv->regs[0]);
- pctrl->regs[1] = devm_platform_ioremap_resource_byname(pdev, "rtc");
- if (IS_ERR(pctrl->regs[1]))
- return PTR_ERR(pctrl->regs[1]);
+ priv->regs[1] = devm_platform_ioremap_resource_byname(pdev, "rtc");
+ if (IS_ERR(priv->regs[1]))
+ return PTR_ERR(priv->regs[1]);
pctrl->pdesc.name = dev_name(dev);
pctrl->pdesc.pins = pctrl_data->pins;
@@ -761,6 +779,7 @@ int cv1800_pinctrl_probe(struct platform_device *pdev)
pctrl->pdesc.owner = THIS_MODULE;
pctrl->data = pctrl_data;
+ pctrl->priv_ctrl = priv;
pctrl->dev = dev;
raw_spin_lock_init(&pctrl->lock);
mutex_init(&pctrl->mutex);
@@ -768,11 +787,11 @@ int cv1800_pinctrl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pctrl);
ret = devm_pinctrl_register_and_init(dev, &pctrl->pdesc,
- pctrl, &pctrl->pctl_dev);
+ pctrl, &pctrl->pctrl_dev);
if (ret)
return dev_err_probe(dev, ret,
"fail to register pinctrl driver\n");
- return pinctrl_enable(pctrl->pctl_dev);
+ return pinctrl_enable(pctrl->pctrl_dev);
}
EXPORT_SYMBOL_GPL(cv1800_pinctrl_probe);
@@ -8,13 +8,14 @@
#include <linux/bits.h>
#include <linux/bitfield.h>
-#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
+#include "pinctrl-sophgo.h"
+
enum cv1800_pin_io_type {
IO_TYPE_1V8_ONLY = 0,
IO_TYPE_1V8_OR_3V3 = 1,
@@ -49,48 +50,22 @@ struct cv1800_pinconf {
#define CV1800_PIN_FLAG_IO_TYPE(type) \
FIELD_PREP_CONST(CV1800_PIN_IO_TYPE, type)
struct cv1800_pin {
- u16 pin;
- u16 flags;
+ struct sophgo_pin pin;
u8 power_domain;
struct cv1800_pinmux mux;
struct cv1800_pinmux2 mux2;
struct cv1800_pinconf conf;
};
+#define sophgo_to_cv1800_pin(_pin) \
+ container_of((_pin), struct cv1800_pin, pin)
+
#define PIN_POWER_STATE_1V8 1800
#define PIN_POWER_STATE_3V3 3300
-/**
- * struct cv1800_vddio_cfg_ops - pin vddio operations
- *
- * @get_pull_up: get resistor for pull up;
- * @get_pull_down: get resistor for pull down.
- * @get_oc_map: get mapping for typical low level output current value to
- * register value map.
- * @get_schmitt_map: get mapping for register value to typical schmitt
- * threshold.
- */
-struct cv1800_vddio_cfg_ops {
- int (*get_pull_up)(struct cv1800_pin *pin, const u32 *psmap);
- int (*get_pull_down)(struct cv1800_pin *pin, const u32 *psmap);
- int (*get_oc_map)(struct cv1800_pin *pin, const u32 *psmap,
- const u32 **map);
- int (*get_schmitt_map)(struct cv1800_pin *pin, const u32 *psmap,
- const u32 **map);
-};
-
-struct cv1800_pinctrl_data {
- const struct pinctrl_pin_desc *pins;
- const struct cv1800_pin *pindata;
- const char * const *pdnames;
- const struct cv1800_vddio_cfg_ops *vddio_ops;
- u16 npins;
- u16 npd;
-};
-
-static inline enum cv1800_pin_io_type cv1800_pin_io_type(struct cv1800_pin *pin)
+static inline enum cv1800_pin_io_type cv1800_pin_io_type(const struct cv1800_pin *pin)
{
- return FIELD_GET(CV1800_PIN_IO_TYPE, pin->flags);
+ return FIELD_GET(CV1800_PIN_IO_TYPE, pin->pin.flags);
};
int cv1800_pinctrl_probe(struct platform_device *pdev);
@@ -98,9 +73,11 @@ int cv1800_pinctrl_probe(struct platform_device *pdev);
#define CV1800_FUNC_PIN(_id, _power_domain, _type, \
_mux_area, _mux_offset, _mux_func_max) \
{ \
- .pin = (_id), \
+ .pin = { \
+ .id = (_id), \
+ .flags = CV1800_PIN_FLAG_IO_TYPE(_type), \
+ }, \
.power_domain = (_power_domain), \
- .flags = CV1800_PIN_FLAG_IO_TYPE(_type), \
.mux = { \
.area = (_mux_area), \
.offset = (_mux_offset), \
@@ -112,9 +89,11 @@ int cv1800_pinctrl_probe(struct platform_device *pdev);
_mux_area, _mux_offset, _mux_func_max, \
_conf_area, _conf_offset) \
{ \
- .pin = (_id), \
+ .pin = { \
+ .id = (_id), \
+ .flags = CV1800_PIN_FLAG_IO_TYPE(_type), \
+ }, \
.power_domain = (_power_domain), \
- .flags = CV1800_PIN_FLAG_IO_TYPE(_type), \
.mux = { \
.area = (_mux_area), \
.offset = (_mux_offset), \
@@ -132,10 +111,12 @@ int cv1800_pinctrl_probe(struct platform_device *pdev);
_mux2_func_max, \
_conf_area, _conf_offset) \
{ \
- .pin = (_id), \
+ .pin = { \
+ .id = (_id), \
+ .flags = CV1800_PIN_FLAG_IO_TYPE(_type) | \
+ CV1800_PIN_HAVE_MUX2, \
+ }, \
.power_domain = (_power_domain), \
- .flags = CV1800_PIN_FLAG_IO_TYPE(_type) | \
- CV1800_PIN_HAVE_MUX2, \
.mux = { \
.area = (_mux_area), \
.offset = (_mux_offset), \
@@ -40,8 +40,9 @@ static const char *const sg2000_power_domain_desc[] = {
[VDDIO_VIVO] = "VDDIO_VIVO",
};
-static int sg2000_get_pull_up(struct cv1800_pin *pin, const u32 *psmap)
+static int sg2000_get_pull_up(const struct sophgo_pin *sp, const u32 *psmap)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
u32 pstate = psmap[pin->power_domain];
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
@@ -60,8 +61,9 @@ static int sg2000_get_pull_up(struct cv1800_pin *pin, const u32 *psmap)
return -ENOTSUPP;
}
-static int sg2000_get_pull_down(struct cv1800_pin *pin, const u32 *psmap)
+static int sg2000_get_pull_down(const struct sophgo_pin *sp, const u32 *psmap)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
u32 pstate = psmap[pin->power_domain];
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
@@ -114,9 +116,10 @@ static const u32 sg2000_eth_oc_map[] = {
17800
};
-static int sg2000_get_oc_map(struct cv1800_pin *pin, const u32 *psmap,
+static int sg2000_get_oc_map(const struct sophgo_pin *sp, const u32 *psmap,
const u32 **map)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
u32 pstate = psmap[pin->power_domain];
@@ -159,9 +162,10 @@ static const u32 sg2000_18od33_3v3_schmitt_map[] = {
1100000
};
-static int sg2000_get_schmitt_map(struct cv1800_pin *pin, const u32 *psmap,
+static int sg2000_get_schmitt_map(const struct sophgo_pin *sp, const u32 *psmap,
const u32 **map)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
u32 pstate = psmap[pin->power_domain];
@@ -183,11 +187,11 @@ static int sg2000_get_schmitt_map(struct cv1800_pin *pin, const u32 *psmap,
return -ENOTSUPP;
}
-static const struct cv1800_vddio_cfg_ops sg2000_vddio_cfg_ops = {
+static const struct sophgo_vddio_cfg_ops sg2000_vddio_cfg_ops = {
.get_pull_up = sg2000_get_pull_up,
.get_pull_down = sg2000_get_pull_down,
.get_oc_map = sg2000_get_oc_map,
- .get_schmitt_map = sg2000_get_schmitt_map,
+ .get_schmitt_map = sg2000_get_schmitt_map,
};
static const struct pinctrl_pin_desc sg2000_pins[] = {
@@ -742,13 +746,14 @@ static const struct cv1800_pin sg2000_pin_data[ARRAY_SIZE(sg2000_pins)] = {
CV1800_PINCONF_AREA_RTC, 0x028),
};
-static const struct cv1800_pinctrl_data sg2000_pindata = {
+static const struct sophgo_pinctrl_data sg2000_pindata = {
.pins = sg2000_pins,
.pindata = sg2000_pin_data,
.pdnames = sg2000_power_domain_desc,
.vddio_ops = &sg2000_vddio_cfg_ops,
.npins = ARRAY_SIZE(sg2000_pins),
- .npd = ARRAY_SIZE(sg2000_power_domain_desc),
+ .npds = ARRAY_SIZE(sg2000_power_domain_desc),
+ .pinsize = sizeof(struct cv1800_pin),
};
static const struct of_device_id sg2000_pinctrl_ids[] = {
@@ -34,8 +34,9 @@ static const char *const sg2002_power_domain_desc[] = {
[VDDIO_SD1] = "VDDIO_SD1",
};
-static int sg2002_get_pull_up(struct cv1800_pin *pin, const u32 *psmap)
+static int sg2002_get_pull_up(const struct sophgo_pin *sp, const u32 *psmap)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
u32 pstate = psmap[pin->power_domain];
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
@@ -54,8 +55,9 @@ static int sg2002_get_pull_up(struct cv1800_pin *pin, const u32 *psmap)
return -ENOTSUPP;
}
-static int sg2002_get_pull_down(struct cv1800_pin *pin, const u32 *psmap)
+static int sg2002_get_pull_down(const struct sophgo_pin *sp, const u32 *psmap)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
u32 pstate = psmap[pin->power_domain];
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
@@ -108,9 +110,10 @@ static const u32 sg2002_eth_oc_map[] = {
17800
};
-static int sg2002_get_oc_map(struct cv1800_pin *pin, const u32 *psmap,
+static int sg2002_get_oc_map(const struct sophgo_pin *sp, const u32 *psmap,
const u32 **map)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
u32 pstate = psmap[pin->power_domain];
@@ -153,9 +156,10 @@ static const u32 sg2002_18od33_3v3_schmitt_map[] = {
1100000
};
-static int sg2002_get_schmitt_map(struct cv1800_pin *pin, const u32 *psmap,
+static int sg2002_get_schmitt_map(const struct sophgo_pin *sp, const u32 *psmap,
const u32 **map)
{
+ const struct cv1800_pin *pin = sophgo_to_cv1800_pin(sp);
enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
u32 pstate = psmap[pin->power_domain];
@@ -177,11 +181,11 @@ static int sg2002_get_schmitt_map(struct cv1800_pin *pin, const u32 *psmap,
return -ENOTSUPP;
}
-static const struct cv1800_vddio_cfg_ops sg2002_vddio_cfg_ops = {
+static const struct sophgo_vddio_cfg_ops sg2002_vddio_cfg_ops = {
.get_pull_up = sg2002_get_pull_up,
.get_pull_down = sg2002_get_pull_down,
.get_oc_map = sg2002_get_oc_map,
- .get_schmitt_map = sg2002_get_schmitt_map,
+ .get_schmitt_map = sg2002_get_schmitt_map,
};
static const struct pinctrl_pin_desc sg2002_pins[] = {
@@ -513,13 +517,14 @@ static const struct cv1800_pin sg2002_pin_data[ARRAY_SIZE(sg2002_pins)] = {
CV1800_PINCONF_AREA_SYS, 0xc84),
};
-static const struct cv1800_pinctrl_data sg2002_pindata = {
+static const struct sophgo_pinctrl_data sg2002_pindata = {
.pins = sg2002_pins,
.pindata = sg2002_pin_data,
.pdnames = sg2002_power_domain_desc,
.vddio_ops = &sg2002_vddio_cfg_ops,
.npins = ARRAY_SIZE(sg2002_pins),
- .npd = ARRAY_SIZE(sg2002_power_domain_desc),
+ .npds = ARRAY_SIZE(sg2002_power_domain_desc),
+ .pinsize = sizeof(struct cv1800_pin),
};
static const struct of_device_id sg2002_pinctrl_ids[] = {
new file mode 100644
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024 Inochi Amaoto <inochiama@outlook.com>
+ */
+
+#ifndef _PINCTRL_SOPHGO_H
+#define _PINCTRL_SOPHGO_H
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/spinlock.h>
+
+#include "../core.h"
+
+struct sophgo_pin {
+ u16 id;
+ u16 flags;
+};
+
+struct sophgo_pin_mux_config {
+ const struct sophgo_pin *pin;
+ u32 config;
+};
+
+/**
+ * struct sophgo_vddio_cfg_ops - pin vddio operations
+ *
+ * @get_pull_up: get resistor for pull up;
+ * @get_pull_down: get resistor for pull down.
+ * @get_oc_map: get mapping for typical low level output current value to
+ * register value map.
+ * @get_schmitt_map: get mapping for register value to typical schmitt
+ * threshold.
+ */
+struct sophgo_vddio_cfg_ops {
+ int (*get_pull_up)(const struct sophgo_pin *pin, const u32 *psmap);
+ int (*get_pull_down)(const struct sophgo_pin *pin, const u32 *psmap);
+ int (*get_oc_map)(const struct sophgo_pin *pin, const u32 *psmap,
+ const u32 **map);
+ int (*get_schmitt_map)(const struct sophgo_pin *pin, const u32 *psmap,
+ const u32 **map);
+};
+
+struct sophgo_pinctrl_data {
+ const struct pinctrl_pin_desc *pins;
+ const void *pindata;
+ const char * const *pdnames;
+ const struct sophgo_vddio_cfg_ops *vddio_ops;
+ u16 npins;
+ u16 npds;
+ u16 pinsize;
+};
+
+struct sophgo_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pctrl_dev;
+ const struct sophgo_pinctrl_data *data;
+ struct pinctrl_desc pdesc;
+
+ struct mutex mutex;
+ raw_spinlock_t lock;
+ void *priv_ctrl;
+};
+
+#endif /* _PINCTRL_SOPHGO_H */
To share DT parsing and vddio code, it is necessary to introduce some generic data structure to abstract the different cv18xx series and the incoming sg2042 series. Signed-off-by: Inochi Amaoto <inochiama@gmail.com> --- drivers/pinctrl/sophgo/pinctrl-cv1800b.c | 21 +- drivers/pinctrl/sophgo/pinctrl-cv1812h.c | 21 +- drivers/pinctrl/sophgo/pinctrl-cv18xx.c | 243 ++++++++++++----------- drivers/pinctrl/sophgo/pinctrl-cv18xx.h | 61 ++---- drivers/pinctrl/sophgo/pinctrl-sg2000.c | 21 +- drivers/pinctrl/sophgo/pinctrl-sg2002.c | 21 +- drivers/pinctrl/sophgo/pinctrl-sophgo.h | 66 ++++++ 7 files changed, 270 insertions(+), 184 deletions(-) create mode 100644 drivers/pinctrl/sophgo/pinctrl-sophgo.h