Commit 16a4851d authored by Joachim Eastwood's avatar Joachim Eastwood Committed by Linus Walleij

pinctrl: lpc18xx: add the missing group function map

Add the required group function map and fill it at probe using
the pin capabilities information already present in the driver.
Signed-off-by: default avatarJoachim Eastwood <manabian@gmail.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 6dce6d24
...@@ -46,12 +46,6 @@ ...@@ -46,12 +46,6 @@
#define LPC18XX_SCU_FUNC_PER_PIN 8 #define LPC18XX_SCU_FUNC_PER_PIN 8
struct lpc18xx_scu_data {
struct pinctrl_dev *pctl;
void __iomem *base;
struct clk *clk;
};
/* LPC18xx pin types */ /* LPC18xx pin types */
enum { enum {
TYPE_ND, /* Normal-drive */ TYPE_ND, /* Normal-drive */
...@@ -113,10 +107,11 @@ enum { ...@@ -113,10 +107,11 @@ enum {
FUNC_UART3, FUNC_UART3,
FUNC_USB0, FUNC_USB0,
FUNC_USB1, FUNC_USB1,
FUNC_MAX
}; };
static const char *const lpc18xx_function_names[] = { static const char *const lpc18xx_function_names[] = {
[FUNC_R] = "", [FUNC_R] = "reserved",
[FUNC_ADC] = "adc", [FUNC_ADC] = "adc",
[FUNC_ADCTRIG] = "adctrig", [FUNC_ADCTRIG] = "adctrig",
[FUNC_CAN0] = "can0", [FUNC_CAN0] = "can0",
...@@ -168,6 +163,18 @@ static const char *const lpc18xx_function_names[] = { ...@@ -168,6 +163,18 @@ static const char *const lpc18xx_function_names[] = {
[FUNC_USB1] = "usb1", [FUNC_USB1] = "usb1",
}; };
struct lpc18xx_pmx_func {
const char **groups;
unsigned ngroups;
};
struct lpc18xx_scu_data {
struct pinctrl_dev *pctl;
void __iomem *base;
struct clk *clk;
struct lpc18xx_pmx_func func[FUNC_MAX];
};
struct lpc18xx_pin_caps { struct lpc18xx_pin_caps {
unsigned int offset; unsigned int offset;
unsigned char functions[LPC18XX_SCU_FUNC_PER_PIN]; unsigned char functions[LPC18XX_SCU_FUNC_PER_PIN];
...@@ -962,6 +969,11 @@ static int lpc18xx_pmx_get_func_groups(struct pinctrl_dev *pctldev, ...@@ -962,6 +969,11 @@ static int lpc18xx_pmx_get_func_groups(struct pinctrl_dev *pctldev,
const char *const **groups, const char *const **groups,
unsigned *const num_groups) unsigned *const num_groups)
{ {
struct lpc18xx_scu_data *scu = pinctrl_dev_get_drvdata(pctldev);
*groups = scu->func[function].groups;
*num_groups = scu->func[function].ngroups;
return 0; return 0;
} }
...@@ -1081,6 +1093,57 @@ static struct pinctrl_desc lpc18xx_scu_desc = { ...@@ -1081,6 +1093,57 @@ static struct pinctrl_desc lpc18xx_scu_desc = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static bool lpc18xx_valid_pin_function(unsigned pin, unsigned function)
{
struct lpc18xx_pin_caps *p = lpc18xx_pins[pin].drv_data;
int i;
if (function == FUNC_DAC && p->analog == DAC)
return true;
if (function == FUNC_ADC && p->analog)
return true;
if (function == FUNC_I2C0 && p->type == TYPE_I2C0)
return true;
if (function == FUNC_USB1 && p->type == TYPE_USB1)
return true;
for (i = 0; i < LPC18XX_SCU_FUNC_PER_PIN; i++) {
if (function == p->functions[i])
return true;
}
return false;
}
static int lpc18xx_create_group_func_map(struct device *dev,
struct lpc18xx_scu_data *scu)
{
u16 pins[ARRAY_SIZE(lpc18xx_pins)];
int func, ngroups, i;
for (func = 0; func < FUNC_MAX; ngroups = 0, func++) {
for (i = 0; i < ARRAY_SIZE(lpc18xx_pins); i++) {
if (lpc18xx_valid_pin_function(i, func))
pins[ngroups++] = i;
}
scu->func[func].ngroups = ngroups;
scu->func[func].groups = devm_kzalloc(dev, ngroups *
sizeof(char *), GFP_KERNEL);
if (!scu->func[func].groups)
return -ENOMEM;
for (i = 0; i < ngroups; i++)
scu->func[func].groups[i] = lpc18xx_pins[pins[i]].name;
}
return 0;
}
static int lpc18xx_scu_probe(struct platform_device *pdev) static int lpc18xx_scu_probe(struct platform_device *pdev)
{ {
struct lpc18xx_scu_data *scu; struct lpc18xx_scu_data *scu;
...@@ -1102,6 +1165,12 @@ static int lpc18xx_scu_probe(struct platform_device *pdev) ...@@ -1102,6 +1165,12 @@ static int lpc18xx_scu_probe(struct platform_device *pdev)
return PTR_ERR(scu->clk); return PTR_ERR(scu->clk);
} }
ret = lpc18xx_create_group_func_map(&pdev->dev, scu);
if (ret) {
dev_err(&pdev->dev, "Unable to create group func map.\n");
return ret;
}
ret = clk_prepare_enable(scu->clk); ret = clk_prepare_enable(scu->clk);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Unable to enable clock.\n"); dev_err(&pdev->dev, "Unable to enable clock.\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment