forked from Minki/linux
Sign for-mvebu/pinctrl-cleanup
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJTDOboAAoJEN2kpao7fSL4OhoP/0+ceyuOEUdr3+XKBffHWc63 7cSlG5jf8CButeqLUos16evAyLEs5Tpgka2r/CJTakI0b8DcTSAu+KkKpkffcLPA 6mmR1mn2s19yR3JioHjRGSYudG7t62yJWXqdIIlvEJiG9bIFk7oirNtqPw1V0WQP z9EeZEEzoavBXmSMaamvOuOgZpfgziKdY9KKoXfFqNXbvvkyeB9H6PxhU6GqZsrT KUijbOuzNRjSZrfQeAn8+MR6qjUJuoIERzmNCWiJk0x1TJiiry0bVVhFCHLNwTwk /uGa7e+FsjRWfd+rRwgM66qyj+05SptcHZ+nIdUrfcpR6V7MJJKeGkc8v0Tcjx7L JYWYkLA3HbUtpxOVfc4JrNWXQg43In0EZ8Wu2JDZBLp570fgi6KX7eVE/NhAEyx2 UcW0KUpYB31Izs9hPMYa4MCEMRkPziKNFxghKgNqLk49U7gRm1OITYX5bzuMno8i foIdQ22dz6czBAJW7GfRYkF8Os0hWopKZao8r0T5NHsnyUSbWD9UUZWiUSGLpcpi AaEsJDma/F4v44ondJiaxDeOofPjorz8wmjml39RCu+m8rDEY5afqnXsFfLdp2Hh CRN1ae3aQSLChFKAqOlilcIAYcfiJHDjyguoSJqen/QlaeE5CMWublPwlLuq/i1L UcFNWE7hu3R3+ZqU+rgX =w6Su -----END PGP SIGNATURE----- Merge tag 'tags/for-mvebu-pinctrl-cleanup' into mvebu/pinctrl Sign for-mvebu/pinctrl-cleanup
This commit is contained in:
commit
55387764c4
@ -23,6 +23,18 @@
|
||||
|
||||
#include "pinctrl-mvebu.h"
|
||||
|
||||
static void __iomem *mpp_base;
|
||||
|
||||
static int armada_370_mpp_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
return default_mpp_ctrl_get(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
static int armada_370_mpp_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
return default_mpp_ctrl_set(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = {
|
||||
MPP_MODE(0,
|
||||
MPP_FUNCTION(0x0, "gpio", NULL),
|
||||
@ -373,7 +385,7 @@ static struct of_device_id armada_370_pinctrl_of_match[] = {
|
||||
};
|
||||
|
||||
static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = {
|
||||
MPP_REG_CTRL(0, 65),
|
||||
MPP_FUNC_CTRL(0, 65, NULL, armada_370_mpp_ctrl),
|
||||
};
|
||||
|
||||
static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
|
||||
@ -385,6 +397,12 @@ static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
|
||||
static int armada_370_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info;
|
||||
struct resource *res;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mpp_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(mpp_base))
|
||||
return PTR_ERR(mpp_base);
|
||||
|
||||
soc->variant = 0; /* no variants for Armada 370 */
|
||||
soc->controls = mv88f6710_mpp_controls;
|
||||
|
@ -33,6 +33,18 @@
|
||||
|
||||
#include "pinctrl-mvebu.h"
|
||||
|
||||
static void __iomem *mpp_base;
|
||||
|
||||
static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
return default_mpp_ctrl_get(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
static int armada_xp_mpp_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
return default_mpp_ctrl_set(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
enum armada_xp_variant {
|
||||
V_MV78230 = BIT(0),
|
||||
V_MV78260 = BIT(1),
|
||||
@ -366,7 +378,7 @@ static struct of_device_id armada_xp_pinctrl_of_match[] = {
|
||||
};
|
||||
|
||||
static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = {
|
||||
MPP_REG_CTRL(0, 48),
|
||||
MPP_FUNC_CTRL(0, 48, NULL, armada_xp_mpp_ctrl),
|
||||
};
|
||||
|
||||
static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
|
||||
@ -375,7 +387,7 @@ static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
|
||||
};
|
||||
|
||||
static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = {
|
||||
MPP_REG_CTRL(0, 66),
|
||||
MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
|
||||
};
|
||||
|
||||
static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
|
||||
@ -385,7 +397,7 @@ static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
|
||||
};
|
||||
|
||||
static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = {
|
||||
MPP_REG_CTRL(0, 66),
|
||||
MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
|
||||
};
|
||||
|
||||
static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {
|
||||
@ -399,10 +411,16 @@ static int armada_xp_pinctrl_probe(struct platform_device *pdev)
|
||||
struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
|
||||
const struct of_device_id *match =
|
||||
of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
|
||||
struct resource *res;
|
||||
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mpp_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(mpp_base))
|
||||
return PTR_ERR(mpp_base);
|
||||
|
||||
soc->variant = (unsigned) match->data & 0xff;
|
||||
|
||||
switch (soc->variant) {
|
||||
|
@ -49,62 +49,64 @@
|
||||
#define DOVE_SD1_GPIO_SEL BIT(1)
|
||||
#define DOVE_SD0_GPIO_SEL BIT(0)
|
||||
|
||||
#define MPPS_PER_REG 8
|
||||
#define MPP_BITS 4
|
||||
#define MPP_MASK 0xf
|
||||
|
||||
#define CONFIG_PMU BIT(4)
|
||||
|
||||
static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long *config)
|
||||
static void __iomem *mpp_base;
|
||||
|
||||
static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
|
||||
unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
|
||||
return default_mpp_ctrl_get(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
static int dove_mpp_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
return default_mpp_ctrl_set(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
|
||||
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
|
||||
unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
|
||||
unsigned long func;
|
||||
|
||||
if (pmu & (1 << ctrl->pid)) {
|
||||
func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
|
||||
*config = (func >> shift) & MPP_MASK;
|
||||
*config |= CONFIG_PMU;
|
||||
} else {
|
||||
func = readl(DOVE_MPP_VIRT_BASE + off);
|
||||
*config = (func >> shift) & MPP_MASK;
|
||||
}
|
||||
if ((pmu & BIT(pid)) == 0)
|
||||
return default_mpp_ctrl_get(mpp_base, pid, config);
|
||||
|
||||
func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
|
||||
*config = (func >> shift) & MVEBU_MPP_MASK;
|
||||
*config |= CONFIG_PMU;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long config)
|
||||
static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
|
||||
unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
|
||||
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
|
||||
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
|
||||
unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
|
||||
unsigned long func;
|
||||
|
||||
if (config & CONFIG_PMU) {
|
||||
writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
|
||||
func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
|
||||
func &= ~(MPP_MASK << shift);
|
||||
func |= (config & MPP_MASK) << shift;
|
||||
writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
|
||||
} else {
|
||||
writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
|
||||
func = readl(DOVE_MPP_VIRT_BASE + off);
|
||||
func &= ~(MPP_MASK << shift);
|
||||
func |= (config & MPP_MASK) << shift;
|
||||
writel(func, DOVE_MPP_VIRT_BASE + off);
|
||||
if ((config & CONFIG_PMU) == 0) {
|
||||
writel(pmu & ~BIT(pid), DOVE_PMU_MPP_GENERAL_CTRL);
|
||||
return default_mpp_ctrl_set(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
writel(pmu | BIT(pid), DOVE_PMU_MPP_GENERAL_CTRL);
|
||||
func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
|
||||
func &= ~(MVEBU_MPP_MASK << shift);
|
||||
func |= (config & MVEBU_MPP_MASK) << shift;
|
||||
writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long *config)
|
||||
static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
|
||||
unsigned long mask;
|
||||
|
||||
switch (ctrl->pid) {
|
||||
switch (pid) {
|
||||
case 24: /* mpp_camera */
|
||||
mask = DOVE_CAM_GPIO_SEL;
|
||||
break;
|
||||
@ -129,13 +131,12 @@ static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long config)
|
||||
static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
|
||||
unsigned long mask;
|
||||
|
||||
switch (ctrl->pid) {
|
||||
switch (pid) {
|
||||
case 24: /* mpp_camera */
|
||||
mask = DOVE_CAM_GPIO_SEL;
|
||||
break;
|
||||
@ -164,8 +165,7 @@ static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long *config)
|
||||
static int dove_nand_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
|
||||
|
||||
@ -174,8 +174,7 @@ static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long config)
|
||||
static int dove_nand_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
|
||||
|
||||
@ -188,8 +187,7 @@ static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long *config)
|
||||
static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
|
||||
|
||||
@ -198,8 +196,7 @@ static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long config)
|
||||
static int dove_audio0_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
|
||||
|
||||
@ -211,8 +208,7 @@ static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long *config)
|
||||
static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
|
||||
unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
|
||||
@ -238,8 +234,7 @@ static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long config)
|
||||
static int dove_audio1_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
|
||||
unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
|
||||
@ -276,11 +271,11 @@ static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
* break other functions. If you require all mpps as gpio
|
||||
* enforce gpio setting by pinctrl mapping.
|
||||
*/
|
||||
static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
|
||||
static int dove_audio1_ctrl_gpio_req(unsigned pid)
|
||||
{
|
||||
unsigned long config;
|
||||
|
||||
dove_audio1_ctrl_get(ctrl, &config);
|
||||
dove_audio1_ctrl_get(pid, &config);
|
||||
|
||||
switch (config) {
|
||||
case 0x02: /* i2s1 : gpio[56:57] */
|
||||
@ -303,16 +298,14 @@ static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
|
||||
}
|
||||
|
||||
/* mpp[52:57] has gpio pins capable of in and out */
|
||||
static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid,
|
||||
bool input)
|
||||
static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input)
|
||||
{
|
||||
if (pid < 52 || pid > 57)
|
||||
return -ENOTSUPP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long *config)
|
||||
static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
|
||||
unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
|
||||
@ -328,8 +321,7 @@ static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
unsigned long config)
|
||||
static int dove_twsi_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
|
||||
unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
|
||||
@ -356,23 +348,8 @@ static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
|
||||
}
|
||||
|
||||
static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
|
||||
MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl),
|
||||
MPP_REG_CTRL(16, 23),
|
||||
MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(16, 23, NULL, dove_mpp_ctrl),
|
||||
MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
|
||||
MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
|
||||
MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
|
||||
@ -774,6 +751,7 @@ static struct of_device_id dove_pinctrl_of_match[] = {
|
||||
|
||||
static int dove_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
const struct of_device_id *match =
|
||||
of_match_device(dove_pinctrl_of_match, &pdev->dev);
|
||||
pdev->dev.platform_data = (void *)match->data;
|
||||
@ -789,6 +767,11 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
|
||||
}
|
||||
clk_prepare_enable(clk);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mpp_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(mpp_base))
|
||||
return PTR_ERR(mpp_base);
|
||||
|
||||
return mvebu_pinctrl_probe(pdev);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,18 @@
|
||||
|
||||
#include "pinctrl-mvebu.h"
|
||||
|
||||
static void __iomem *mpp_base;
|
||||
|
||||
static int kirkwood_mpp_ctrl_get(unsigned pid, unsigned long *config)
|
||||
{
|
||||
return default_mpp_ctrl_get(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
static int kirkwood_mpp_ctrl_set(unsigned pid, unsigned long config)
|
||||
{
|
||||
return default_mpp_ctrl_set(mpp_base, pid, config);
|
||||
}
|
||||
|
||||
#define V(f6180, f6190, f6192, f6281, f6282, dx4122) \
|
||||
((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \
|
||||
(f6281 << 3) | (f6282 << 4) | (dx4122 << 5))
|
||||
@ -359,7 +371,7 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
|
||||
};
|
||||
|
||||
static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
|
||||
MPP_REG_CTRL(0, 29),
|
||||
MPP_FUNC_CTRL(0, 29, NULL, kirkwood_mpp_ctrl),
|
||||
};
|
||||
|
||||
static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
|
||||
@ -367,7 +379,7 @@ static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
|
||||
};
|
||||
|
||||
static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {
|
||||
MPP_REG_CTRL(0, 35),
|
||||
MPP_FUNC_CTRL(0, 35, NULL, kirkwood_mpp_ctrl),
|
||||
};
|
||||
|
||||
static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
|
||||
@ -376,7 +388,7 @@ static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
|
||||
};
|
||||
|
||||
static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = {
|
||||
MPP_REG_CTRL(0, 49),
|
||||
MPP_FUNC_CTRL(0, 49, NULL, kirkwood_mpp_ctrl),
|
||||
};
|
||||
|
||||
static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = {
|
||||
@ -456,9 +468,16 @@ static struct of_device_id kirkwood_pinctrl_of_match[] = {
|
||||
|
||||
static int kirkwood_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
const struct of_device_id *match =
|
||||
of_match_device(kirkwood_pinctrl_of_match, &pdev->dev);
|
||||
pdev->dev.platform_data = (void *)match->data;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mpp_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(mpp_base))
|
||||
return PTR_ERR(mpp_base);
|
||||
|
||||
return mvebu_pinctrl_probe(pdev);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,6 @@ struct mvebu_pinctrl {
|
||||
struct device *dev;
|
||||
struct pinctrl_dev *pctldev;
|
||||
struct pinctrl_desc desc;
|
||||
void __iomem *base;
|
||||
struct mvebu_pinctrl_group *groups;
|
||||
unsigned num_groups;
|
||||
struct mvebu_pinctrl_function *functions;
|
||||
@ -138,43 +137,6 @@ static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common mpp pin configuration registers on MVEBU are
|
||||
* registers of eight 4-bit values for each mpp setting.
|
||||
* Register offset and bit mask are calculated accordingly below.
|
||||
*/
|
||||
static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl,
|
||||
struct mvebu_pinctrl_group *grp,
|
||||
unsigned long *config)
|
||||
{
|
||||
unsigned pin = grp->gid;
|
||||
unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
|
||||
unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
|
||||
|
||||
*config = readl(pctl->base + off);
|
||||
*config >>= shift;
|
||||
*config &= MPP_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl,
|
||||
struct mvebu_pinctrl_group *grp,
|
||||
unsigned long config)
|
||||
{
|
||||
unsigned pin = grp->gid;
|
||||
unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
|
||||
unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
|
||||
unsigned long reg;
|
||||
|
||||
reg = readl(pctl->base + off);
|
||||
reg &= ~(MPP_MASK << shift);
|
||||
reg |= (config << shift);
|
||||
writel(reg, pctl->base + off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
|
||||
unsigned gid, unsigned long *config)
|
||||
{
|
||||
@ -184,10 +146,7 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
|
||||
if (!grp->ctrl)
|
||||
return -EINVAL;
|
||||
|
||||
if (grp->ctrl->mpp_get)
|
||||
return grp->ctrl->mpp_get(grp->ctrl, config);
|
||||
|
||||
return mvebu_common_mpp_get(pctl, grp, config);
|
||||
return grp->ctrl->mpp_get(grp->pins[0], config);
|
||||
}
|
||||
|
||||
static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
|
||||
@ -202,11 +161,7 @@ static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num_configs; i++) {
|
||||
if (grp->ctrl->mpp_set)
|
||||
ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
|
||||
else
|
||||
ret = mvebu_common_mpp_set(pctl, grp, configs[i]);
|
||||
|
||||
ret = grp->ctrl->mpp_set(grp->pins[0], configs[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
} /* for each config */
|
||||
@ -347,7 +302,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
return -EINVAL;
|
||||
|
||||
if (grp->ctrl->mpp_gpio_req)
|
||||
return grp->ctrl->mpp_gpio_req(grp->ctrl, offset);
|
||||
return grp->ctrl->mpp_gpio_req(offset);
|
||||
|
||||
setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
|
||||
if (!setting)
|
||||
@ -370,7 +325,7 @@ static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
return -EINVAL;
|
||||
|
||||
if (grp->ctrl->mpp_gpio_dir)
|
||||
return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input);
|
||||
return grp->ctrl->mpp_gpio_dir(offset, input);
|
||||
|
||||
setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
|
||||
if (!setting)
|
||||
@ -593,11 +548,12 @@ static int mvebu_pinctrl_build_functions(struct platform_device *pdev,
|
||||
int mvebu_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
|
||||
struct resource *res;
|
||||
struct mvebu_pinctrl *pctl;
|
||||
void __iomem *base;
|
||||
struct pinctrl_pin_desc *pdesc;
|
||||
unsigned gid, n, k;
|
||||
unsigned size, noname = 0;
|
||||
char *noname_buf;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
if (!soc || !soc->controls || !soc->modes) {
|
||||
@ -605,11 +561,6 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
|
||||
GFP_KERNEL);
|
||||
if (!pctl) {
|
||||
@ -623,7 +574,6 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
|
||||
pctl->desc.pmxops = &mvebu_pinmux_ops;
|
||||
pctl->desc.confops = &mvebu_pinconf_ops;
|
||||
pctl->variant = soc->variant;
|
||||
pctl->base = base;
|
||||
pctl->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, pctl);
|
||||
|
||||
@ -633,33 +583,23 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
|
||||
pctl->desc.npins = 0;
|
||||
for (n = 0; n < soc->ncontrols; n++) {
|
||||
struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
|
||||
char *names;
|
||||
|
||||
pctl->desc.npins += ctrl->npins;
|
||||
/* initial control pins */
|
||||
/* initialize control's pins[] array */
|
||||
for (k = 0; k < ctrl->npins; k++)
|
||||
ctrl->pins[k] = ctrl->pid + k;
|
||||
|
||||
/* special soc specific control */
|
||||
if (ctrl->mpp_get || ctrl->mpp_set) {
|
||||
if (!ctrl->name || !ctrl->mpp_get || !ctrl->mpp_set) {
|
||||
dev_err(&pdev->dev, "wrong soc control info\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
* We allow to pass controls with NULL name that we treat
|
||||
* as a range of one-pin groups with generic mvebu register
|
||||
* controls.
|
||||
*/
|
||||
if (!ctrl->name) {
|
||||
pctl->num_groups += ctrl->npins;
|
||||
noname += ctrl->npins;
|
||||
} else {
|
||||
pctl->num_groups += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* generic mvebu register control */
|
||||
names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL);
|
||||
if (!names) {
|
||||
dev_err(&pdev->dev, "failed to alloc mpp names\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (k = 0; k < ctrl->npins; k++)
|
||||
sprintf(names + 8*k, "mpp%d", ctrl->pid+k);
|
||||
ctrl->name = names;
|
||||
pctl->num_groups += ctrl->npins;
|
||||
}
|
||||
|
||||
pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *
|
||||
@ -673,12 +613,17 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
|
||||
pdesc[n].number = n;
|
||||
pctl->desc.pins = pdesc;
|
||||
|
||||
pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups *
|
||||
sizeof(struct mvebu_pinctrl_group), GFP_KERNEL);
|
||||
if (!pctl->groups) {
|
||||
dev_err(&pdev->dev, "failed to alloc pinctrl groups\n");
|
||||
/*
|
||||
* allocate groups and name buffers for unnamed groups.
|
||||
*/
|
||||
size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;
|
||||
p = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
|
||||
if (!p) {
|
||||
dev_err(&pdev->dev, "failed to alloc group data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
pctl->groups = p;
|
||||
noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);
|
||||
|
||||
/* assign mpp controls to groups */
|
||||
gid = 0;
|
||||
@ -690,17 +635,26 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
|
||||
pctl->groups[gid].pins = ctrl->pins;
|
||||
pctl->groups[gid].npins = ctrl->npins;
|
||||
|
||||
/* generic mvebu register control maps to a number of groups */
|
||||
if (!ctrl->mpp_get && !ctrl->mpp_set) {
|
||||
/*
|
||||
* We treat unnamed controls as a range of one-pin groups
|
||||
* with generic mvebu register controls. Use one group for
|
||||
* each in this range and assign a default group name.
|
||||
*/
|
||||
if (!ctrl->name) {
|
||||
pctl->groups[gid].name = noname_buf;
|
||||
pctl->groups[gid].npins = 1;
|
||||
sprintf(noname_buf, "mpp%d", ctrl->pid+0);
|
||||
noname_buf += 8;
|
||||
|
||||
for (k = 1; k < ctrl->npins; k++) {
|
||||
gid++;
|
||||
pctl->groups[gid].gid = gid;
|
||||
pctl->groups[gid].ctrl = ctrl;
|
||||
pctl->groups[gid].name = &ctrl->name[8*k];
|
||||
pctl->groups[gid].name = noname_buf;
|
||||
pctl->groups[gid].pins = &ctrl->pins[k];
|
||||
pctl->groups[gid].npins = 1;
|
||||
sprintf(noname_buf, "mpp%d", ctrl->pid+k);
|
||||
noname_buf += 8;
|
||||
}
|
||||
}
|
||||
gid++;
|
||||
|
@ -28,20 +28,19 @@
|
||||
* between two or more different settings, e.g. assign mpp pin 13 to
|
||||
* uart1 or sata.
|
||||
*
|
||||
* If optional mpp_get/_set functions are set these are used to get/set
|
||||
* a specific mode. Otherwise it is assumed that the mpp control is based
|
||||
* on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir
|
||||
* functions can be used to allow pin settings with varying gpio pins.
|
||||
* The mpp_get/_set functions are mandatory and are used to get/set a
|
||||
* specific mode. The optional mpp_gpio_req/_dir functions can be used
|
||||
* to allow pin settings with varying gpio pins.
|
||||
*/
|
||||
struct mvebu_mpp_ctrl {
|
||||
const char *name;
|
||||
u8 pid;
|
||||
u8 npins;
|
||||
unsigned *pins;
|
||||
int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config);
|
||||
int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config);
|
||||
int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid);
|
||||
int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input);
|
||||
int (*mpp_get)(unsigned pid, unsigned long *config);
|
||||
int (*mpp_set)(unsigned pid, unsigned long config);
|
||||
int (*mpp_gpio_req)(unsigned pid);
|
||||
int (*mpp_gpio_dir)(unsigned pid, bool input);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -114,18 +113,6 @@ struct mvebu_pinctrl_soc_info {
|
||||
int ngpioranges;
|
||||
};
|
||||
|
||||
#define MPP_REG_CTRL(_idl, _idh) \
|
||||
{ \
|
||||
.name = NULL, \
|
||||
.pid = _idl, \
|
||||
.npins = _idh - _idl + 1, \
|
||||
.pins = (unsigned[_idh - _idl + 1]) { }, \
|
||||
.mpp_get = NULL, \
|
||||
.mpp_set = NULL, \
|
||||
.mpp_gpio_req = NULL, \
|
||||
.mpp_gpio_dir = NULL, \
|
||||
}
|
||||
|
||||
#define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
@ -186,6 +173,34 @@ struct mvebu_pinctrl_soc_info {
|
||||
.npins = _npins, \
|
||||
}
|
||||
|
||||
#define MVEBU_MPPS_PER_REG 8
|
||||
#define MVEBU_MPP_BITS 4
|
||||
#define MVEBU_MPP_MASK 0xf
|
||||
|
||||
static inline int default_mpp_ctrl_get(void __iomem *base, unsigned int pid,
|
||||
unsigned long *config)
|
||||
{
|
||||
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
|
||||
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
|
||||
|
||||
*config = (readl(base + off) >> shift) & MVEBU_MPP_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int default_mpp_ctrl_set(void __iomem *base, unsigned int pid,
|
||||
unsigned long config)
|
||||
{
|
||||
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
|
||||
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
|
||||
unsigned long reg;
|
||||
|
||||
reg = readl(base + off) & ~(MVEBU_MPP_MASK << shift);
|
||||
writel(reg | (config << shift), base + off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mvebu_pinctrl_probe(struct platform_device *pdev);
|
||||
int mvebu_pinctrl_remove(struct platform_device *pdev);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user