aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-mvebu.txt53
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt95
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt100
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt72
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt279
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt46
-rw-r--r--arch/arm/boot/dts/armada-370.dtsi44
-rw-r--r--arch/arm/boot/dts/armada-xp-db.dts4
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78230.dtsi57
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78260.dtsi70
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78460.dtsi70
-rw-r--r--arch/arm/configs/mvebu_defconfig2
-rw-r--r--arch/arm/mach-mvebu/Kconfig18
-rw-r--r--arch/arm/mach-mvebu/include/mach/gpio.h1
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-mvebu.c679
-rw-r--r--drivers/pinctrl/Kconfig22
-rw-r--r--drivers/pinctrl/Makefile5
-rw-r--r--drivers/pinctrl/pinctrl-armada-370.c421
-rw-r--r--drivers/pinctrl/pinctrl-armada-xp.c468
-rw-r--r--drivers/pinctrl/pinctrl-dove.c620
-rw-r--r--drivers/pinctrl/pinctrl-kirkwood.c472
-rw-r--r--drivers/pinctrl/pinctrl-mvebu.c754
-rw-r--r--drivers/pinctrl/pinctrl-mvebu.h192
25 files changed, 4546 insertions, 5 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
new file mode 100644
index 000000000000..a6f3bec1da7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
@@ -0,0 +1,53 @@
1* Marvell EBU GPIO controller
2
3Required properties:
4
5- compatible : Should be "marvell,orion-gpio", "marvell,mv78200-gpio"
6 or "marvell,armadaxp-gpio". "marvell,orion-gpio" should be used for
7 Orion, Kirkwood, Dove, Discovery (except MV78200) and Armada
8 370. "marvell,mv78200-gpio" should be used for the Discovery
9 MV78200. "marvel,armadaxp-gpio" should be used for all Armada XP
10 SoCs (MV78230, MV78260, MV78460).
11
12- reg: Address and length of the register set for the device. Only one
13 entry is expected, except for the "marvell,armadaxp-gpio" variant
14 for which two entries are expected: one for the general registers,
15 one for the per-cpu registers.
16
17- interrupts: The list of interrupts that are used for all the pins
18 managed by this GPIO bank. There can be more than one interrupt
19 (example: 1 interrupt per 8 pins on Armada XP, which means 4
20 interrupts per bank of 32 GPIOs).
21
22- interrupt-controller: identifies the node as an interrupt controller
23
24- #interrupt-cells: specifies the number of cells needed to encode an
25 interrupt source. Should be two.
26 The first cell is the GPIO number.
27 The second cell is used to specify flags:
28 bits[3:0] trigger type and level flags:
29 1 = low-to-high edge triggered.
30 2 = high-to-low edge triggered.
31 4 = active high level-sensitive.
32 8 = active low level-sensitive.
33
34- gpio-controller: marks the device node as a gpio controller
35
36- ngpios: number of GPIOs this controller has
37
38- #gpio-cells: Should be two. The first cell is the pin number. The
39 second cell is reserved for flags, unused at the moment.
40
41Example:
42
43 gpio0: gpio@d0018100 {
44 compatible = "marvell,armadaxp-gpio";
45 reg = <0xd0018100 0x40>,
46 <0xd0018800 0x30>;
47 ngpios = <32>;
48 gpio-controller;
49 #gpio-cells = <2>;
50 interrupt-controller;
51 #interrupt-cells = <2>;
52 interrupts = <16>, <17>, <18>, <19>;
53 };
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt
new file mode 100644
index 000000000000..01ef408e205f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt
@@ -0,0 +1,95 @@
1* Marvell Armada 370 SoC pinctrl driver for mpp
2
3Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
4part and usage.
5
6Required properties:
7- compatible: "marvell,88f6710-pinctrl"
8
9Available mpp pins/groups and functions:
10Note: brackets (x) are not part of the mpp name for marvell,function and given
11only for more detailed description in this document.
12
13name pins functions
14================================================================================
15mpp0 0 gpio, uart0(rxd)
16mpp1 1 gpo, uart0(txd)
17mpp2 2 gpio, i2c0(sck), uart0(txd)
18mpp3 3 gpio, i2c0(sda), uart0(rxd)
19mpp4 4 gpio, cpu_pd(vdd)
20mpp5 5 gpo, ge0(txclko), uart1(txd), spi1(clk), audio(mclk)
21mpp6 6 gpio, ge0(txd0), sata0(prsnt), tdm(rst), audio(sdo)
22mpp7 7 gpo, ge0(txd1), tdm(tdx), audio(lrclk)
23mpp8 8 gpio, ge0(txd2), uart0(rts), tdm(drx), audio(bclk)
24mpp9 9 gpo, ge0(txd3), uart1(txd), sd0(clk), audio(spdifo)
25mpp10 10 gpio, ge0(txctl), uart0(cts), tdm(fsync), audio(sdi)
26mpp11 11 gpio, ge0(rxd0), uart1(rxd), sd0(cmd), spi0(cs1),
27 sata1(prsnt), spi1(cs1)
28mpp12 12 gpio, ge0(rxd1), i2c1(sda), sd0(d0), spi1(cs0),
29 audio(spdifi)
30mpp13 13 gpio, ge0(rxd2), i2c1(sck), sd0(d1), tdm(pclk),
31 audio(rmclk)
32mpp14 14 gpio, ge0(rxd3), pcie(clkreq0), sd0(d2), spi1(mosi),
33 spi0(cs2)
34mpp15 15 gpio, ge0(rxctl), pcie(clkreq1), sd0(d3), spi1(miso),
35 spi0(cs3)
36mpp16 16 gpio, ge0(rxclk), uart1(rxd), tdm(int), audio(extclk)
37mpp17 17 gpo, ge(mdc)
38mpp18 18 gpio, ge(mdio)
39mpp19 19 gpio, ge0(txclk), ge1(txclkout), tdm(pclk)
40mpp20 20 gpo, ge0(txd4), ge1(txd0)
41mpp21 21 gpo, ge0(txd5), ge1(txd1), uart1(txd)
42mpp22 22 gpo, ge0(txd6), ge1(txd2), uart0(rts)
43mpp23 23 gpo, ge0(txd7), ge1(txd3), spi1(mosi)
44mpp24 24 gpio, ge0(col), ge1(txctl), spi1(cs0)
45mpp25 25 gpio, ge0(rxerr), ge1(rxd0), uart1(rxd)
46mpp26 26 gpio, ge0(crs), ge1(rxd1), spi1(miso)
47mpp27 27 gpio, ge0(rxd4), ge1(rxd2), uart0(cts)
48mpp28 28 gpio, ge0(rxd5), ge1(rxd3)
49mpp29 29 gpio, ge0(rxd6), ge1(rxctl), i2c1(sda)
50mpp30 30 gpio, ge0(rxd7), ge1(rxclk), i2c1(sck)
51mpp31 31 gpio, tclk, ge0(txerr)
52mpp32 32 gpio, spi0(cs0)
53mpp33 33 gpio, dev(bootcs), spi0(cs0)
54mpp34 34 gpo, dev(wen0), spi0(mosi)
55mpp35 35 gpo, dev(oen), spi0(sck)
56mpp36 36 gpo, dev(a1), spi0(miso)
57mpp37 37 gpo, dev(a0), sata0(prsnt)
58mpp38 38 gpio, dev(ready), uart1(cts), uart0(cts)
59mpp39 39 gpo, dev(ad0), audio(spdifo)
60mpp40 40 gpio, dev(ad1), uart1(rts), uart0(rts)
61mpp41 41 gpio, dev(ad2), uart1(rxd)
62mpp42 42 gpo, dev(ad3), uart1(txd)
63mpp43 43 gpo, dev(ad4), audio(bclk)
64mpp44 44 gpo, dev(ad5), audio(mclk)
65mpp45 45 gpo, dev(ad6), audio(lrclk)
66mpp46 46 gpo, dev(ad7), audio(sdo)
67mpp47 47 gpo, dev(ad8), sd0(clk), audio(spdifo)
68mpp48 48 gpio, dev(ad9), uart0(rts), sd0(cmd), sata1(prsnt),
69 spi0(cs1)
70mpp49 49 gpio, dev(ad10), pcie(clkreq1), sd0(d0), spi1(cs0),
71 audio(spdifi)
72mpp50 50 gpio, dev(ad11), uart0(cts), sd0(d1), spi1(miso),
73 audio(rmclk)
74mpp51 51 gpio, dev(ad12), i2c1(sda), sd0(d2), spi1(mosi)
75mpp52 52 gpio, dev(ad13), i2c1(sck), sd0(d3), spi1(sck)
76mpp53 53 gpio, dev(ad14), sd0(clk), tdm(pclk), spi0(cs2),
77 pcie(clkreq1)
78mpp54 54 gpo, dev(ad15), tdm(dtx)
79mpp55 55 gpio, dev(cs1), uart1(txd), tdm(rst), sata1(prsnt),
80 sata0(prsnt)
81mpp56 56 gpio, dev(cs2), uart1(cts), uart0(cts), spi0(cs3),
82 pcie(clkreq0), spi1(cs1)
83mpp57 57 gpio, dev(cs3), uart1(rxd), tdm(fsync), sata0(prsnt),
84 audio(sdo)
85mpp58 58 gpio, dev(cs0), uart1(rts), tdm(int), audio(extclk),
86 uart0(rts)
87mpp59 59 gpo, dev(ale0), uart1(rts), uart0(rts), audio(bclk)
88mpp60 60 gpio, dev(ale1), uart1(rxd), sata0(prsnt), pcie(rst-out),
89 audio(sdi)
90mpp61 61 gpo, dev(wen1), uart1(txd), audio(rclk)
91mpp62 62 gpio, dev(a2), uart1(cts), tdm(drx), pcie(clkreq0),
92 audio(mclk), uart0(cts)
93mpp63 63 gpo, spi0(sck), tclk
94mpp64 64 gpio, spi0(miso), spi0-1(cs1)
95mpp65 65 gpio, spi0(mosi), spi0-1(cs2)
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt
new file mode 100644
index 000000000000..bfa0a2e5e0cb
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt
@@ -0,0 +1,100 @@
1* Marvell Armada XP SoC pinctrl driver for mpp
2
3Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
4part and usage.
5
6Required properties:
7- compatible: "marvell,mv78230-pinctrl", "marvell,mv78260-pinctrl",
8 "marvell,mv78460-pinctrl"
9
10This driver supports all Armada XP variants, i.e. mv78230, mv78260, and mv78460.
11
12Available mpp pins/groups and functions:
13Note: brackets (x) are not part of the mpp name for marvell,function and given
14only for more detailed description in this document.
15
16* Marvell Armada XP (all variants)
17
18name pins functions
19================================================================================
20mpp0 0 gpio, ge0(txclko), lcd(d0)
21mpp1 1 gpio, ge0(txd0), lcd(d1)
22mpp2 2 gpio, ge0(txd1), lcd(d2)
23mpp3 3 gpio, ge0(txd2), lcd(d3)
24mpp4 4 gpio, ge0(txd3), lcd(d4)
25mpp5 5 gpio, ge0(txctl), lcd(d5)
26mpp6 6 gpio, ge0(rxd0), lcd(d6)
27mpp7 7 gpio, ge0(rxd1), lcd(d7)
28mpp8 8 gpio, ge0(rxd2), lcd(d8)
29mpp9 9 gpio, ge0(rxd3), lcd(d9)
30mpp10 10 gpio, ge0(rxctl), lcd(d10)
31mpp11 11 gpio, ge0(rxclk), lcd(d11)
32mpp12 12 gpio, ge0(txd4), ge1(txd0), lcd(d12)
33mpp13 13 gpio, ge0(txd5), ge1(txd1), lcd(d13)
34mpp14 14 gpio, ge0(txd6), ge1(txd2), lcd(d15)
35mpp15 15 gpio, ge0(txd7), ge1(txd3), lcd(d16)
36mpp16 16 gpio, ge0(txd7), ge1(txd3), lcd(d16)
37mpp17 17 gpio, ge0(col), ge1(txctl), lcd(d17)
38mpp18 18 gpio, ge0(rxerr), ge1(rxd0), lcd(d18), ptp(trig)
39mpp19 19 gpio, ge0(crs), ge1(rxd1), lcd(d19), ptp(evreq)
40mpp20 20 gpio, ge0(rxd4), ge1(rxd2), lcd(d20), ptp(clk)
41mpp21 21 gpio, ge0(rxd5), ge1(rxd3), lcd(d21), mem(bat)
42mpp22 22 gpio, ge0(rxd6), ge1(rxctl), lcd(d22), sata0(prsnt)
43mpp23 23 gpio, ge0(rxd7), ge1(rxclk), lcd(d23), sata1(prsnt)
44mpp24 24 gpio, lcd(hsync), sata1(prsnt), nf(bootcs-re), tdm(rst)
45mpp25 25 gpio, lcd(vsync), sata0(prsnt), nf(bootcs-we), tdm(pclk)
46mpp26 26 gpio, lcd(clk), tdm(fsync), vdd(cpu1-pd)
47mpp27 27 gpio, lcd(e), tdm(dtx), ptp(trig)
48mpp28 28 gpio, lcd(pwm), tdm(drx), ptp(evreq)
49mpp29 29 gpio, lcd(ref-clk), tdm(int0), ptp(clk), vdd(cpu0-pd)
50mpp30 30 gpio, tdm(int1), sd0(clk)
51mpp31 31 gpio, tdm(int2), sd0(cmd), vdd(cpu0-pd)
52mpp32 32 gpio, tdm(int3), sd0(d0), vdd(cpu1-pd)
53mpp33 33 gpio, tdm(int4), sd0(d1), mem(bat)
54mpp34 34 gpio, tdm(int5), sd0(d2), sata0(prsnt)
55mpp35 35 gpio, tdm(int6), sd0(d3), sata1(prsnt)
56mpp36 36 gpio, spi(mosi)
57mpp37 37 gpio, spi(miso)
58mpp38 38 gpio, spi(sck)
59mpp39 39 gpio, spi(cs0)
60mpp40 40 gpio, spi(cs1), uart2(cts), lcd(vga-hsync), vdd(cpu1-pd),
61 pcie(clkreq0)
62mpp41 41 gpio, spi(cs2), uart2(rts), lcd(vga-vsync), sata1(prsnt),
63 pcie(clkreq1)
64mpp42 42 gpio, uart2(rxd), uart0(cts), tdm(int7), tdm-1(timer),
65 vdd(cpu0-pd)
66mpp43 43 gpio, uart2(txd), uart0(rts), spi(cs3), pcie(rstout),
67 vdd(cpu2-3-pd){1}
68mpp44 44 gpio, uart2(cts), uart3(rxd), spi(cs4), pcie(clkreq2),
69 mem(bat)
70mpp45 45 gpio, uart2(rts), uart3(txd), spi(cs5), sata1(prsnt)
71mpp46 46 gpio, uart3(rts), uart1(rts), spi(cs6), sata0(prsnt)
72mpp47 47 gpio, uart3(cts), uart1(cts), spi(cs7), pcie(clkreq3),
73 ref(clkout)
74mpp48 48 gpio, tclk, dev(burst/last)
75
76* Marvell Armada XP (mv78260 and mv78460 only)
77
78name pins functions
79================================================================================
80mpp49 49 gpio, dev(we3)
81mpp50 50 gpio, dev(we2)
82mpp51 51 gpio, dev(ad16)
83mpp52 52 gpio, dev(ad17)
84mpp53 53 gpio, dev(ad18)
85mpp54 54 gpio, dev(ad19)
86mpp55 55 gpio, dev(ad20), vdd(cpu0-pd)
87mpp56 56 gpio, dev(ad21), vdd(cpu1-pd)
88mpp57 57 gpio, dev(ad22), vdd(cpu2-3-pd){1}
89mpp58 58 gpio, dev(ad23)
90mpp59 59 gpio, dev(ad24)
91mpp60 60 gpio, dev(ad25)
92mpp61 61 gpio, dev(ad26)
93mpp62 62 gpio, dev(ad27)
94mpp63 63 gpio, dev(ad28)
95mpp64 64 gpio, dev(ad29)
96mpp65 65 gpio, dev(ad30)
97mpp66 66 gpio, dev(ad31)
98
99Notes:
100* {1} vdd(cpu2-3-pd) only available on mv78460.
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt
new file mode 100644
index 000000000000..a648aaad6110
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt
@@ -0,0 +1,72 @@
1* Marvell Dove SoC pinctrl driver for mpp
2
3Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
4part and usage.
5
6Required properties:
7- compatible: "marvell,dove-pinctrl"
8- clocks: (optional) phandle of pdma clock
9
10Available mpp pins/groups and functions:
11Note: brackets (x) are not part of the mpp name for marvell,function and given
12only for more detailed description in this document.
13
14name pins functions
15================================================================================
16mpp0 0 gpio, pmu, uart2(rts), sdio0(cd), lcd0(pwm)
17mpp1 1 gpio, pmu, uart2(cts), sdio0(wp), lcd1(pwm)
18mpp2 2 gpio, pmu, uart2(txd), sdio0(buspwr), sata(prsnt),
19 uart1(rts)
20mpp3 3 gpio, pmu, uart2(rxd), sdio0(ledctrl), sata(act),
21 uart1(cts), lcd-spi(cs1)
22mpp4 4 gpio, pmu, uart3(rts), sdio1(cd), spi1(miso)
23mpp5 5 gpio, pmu, uart3(cts), sdio1(wp), spi1(cs)
24mpp6 6 gpio, pmu, uart3(txd), sdio1(buspwr), spi1(mosi)
25mpp7 7 gpio, pmu, uart3(rxd), sdio1(ledctrl), spi1(sck)
26mpp8 8 gpio, pmu, watchdog(rstout)
27mpp9 9 gpio, pmu, pex1(clkreq)
28mpp10 10 gpio, pmu, ssp(sclk)
29mpp11 11 gpio, pmu, sata(prsnt), sata-1(act), sdio0(ledctrl),
30 sdio1(ledctrl), pex0(clkreq)
31mpp12 12 gpio, pmu, uart2(rts), audio0(extclk), sdio1(cd), sata(act)
32mpp13 13 gpio, pmu, uart2(cts), audio1(extclk), sdio1(wp),
33 ssp(extclk)
34mpp14 14 gpio, pmu, uart2(txd), sdio1(buspwr), ssp(rxd)
35mpp15 15 gpio, pmu, uart2(rxd), sdio1(ledctrl), ssp(sfrm)
36mpp16 16 gpio, uart3(rts), sdio0(cd), ac97(sdi1), lcd-spi(cs1)
37mpp17 17 gpio, uart3(cts), sdio0(wp), ac97(sdi2), twsi(sda),
38 ac97-1(sysclko)
39mpp18 18 gpio, uart3(txd), sdio0(buspwr), ac97(sdi3), lcd0(pwm)
40mpp19 19 gpio, uart3(rxd), sdio0(ledctrl), twsi(sck)
41mpp20 20 gpio, sdio0(cd), sdio1(cd), spi1(miso), lcd-spi(miso),
42 ac97(sysclko)
43mpp21 21 gpio, sdio0(wp), sdio1(wp), spi1(cs), lcd-spi(cs0),
44 uart1(cts), ssp(sfrm)
45mpp22 22 gpio, sdio0(buspwr), sdio1(buspwr), spi1(mosi),
46 lcd-spi(mosi), uart1(cts), ssp(txd)
47mpp23 23 gpio, sdio0(ledctrl), sdio1(ledctrl), spi1(sck),
48 lcd-spi(sck), ssp(sclk)
49mpp_camera 24-39 gpio, camera
50mpp_sdio0 40-45 gpio, sdio0
51mpp_sdio1 46-51 gpio, sdio1
52mpp_audio1 52-57 gpio, i2s1/spdifo, i2s1, spdifo, twsi, ssp/spdifo, ssp,
53 ssp/twsi
54mpp_spi0 58-61 gpio, spi0
55mpp_uart1 62-63 gpio, uart1
56mpp_nand 64-71 gpo, nand
57audio0 - i2s, ac97
58twsi - none, opt1, opt2, opt3
59
60Notes:
61* group "mpp_audio1" allows the following functions and gpio pins:
62 - gpio : gpio on pins 52-57
63 - i2s1/spdifo : audio1 i2s on pins 52-55 and spdifo on 57, no gpios
64 - i2s1 : audio1 i2s on pins 52-55, gpio on pins 56,57
65 - spdifo : spdifo on pin 57, gpio on pins 52-55
66 - twsi : twsi on pins 56,57, gpio on pins 52-55
67 - ssp/spdifo : ssp on pins 52-55, spdifo on pin 57, no gpios
68 - ssp : ssp on pins 52-55, gpio on pins 56,57
69 - ssp/twsi : ssp on pins 52-55, twsi on pins 56,57, no gpios
70* group "audio0" internally muxes i2s0 or ac97 controller to the dedicated
71 audio0 pins.
72* group "twsi" internally muxes twsi controller to the dedicated or option pins.
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt
new file mode 100644
index 000000000000..361bccb7ec89
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt
@@ -0,0 +1,279 @@
1* Marvell Kirkwood SoC pinctrl driver for mpp
2
3Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
4part and usage.
5
6Required properties:
7- compatible: "marvell,88f6180-pinctrl",
8 "marvell,88f6190-pinctrl", "marvell,88f6192-pinctrl",
9 "marvell,88f6281-pinctrl", "marvell,88f6282-pinctrl"
10
11This driver supports all kirkwood variants, i.e. 88f6180, 88f619x, and 88f628x.
12
13Available mpp pins/groups and functions:
14Note: brackets (x) are not part of the mpp name for marvell,function and given
15only for more detailed description in this document.
16
17* Marvell Kirkwood 88f6180
18
19name pins functions
20================================================================================
21mpp0 0 gpio, nand(io2), spi(cs)
22mpp1 1 gpo, nand(io3), spi(mosi)
23mpp2 2 gpo, nand(io4), spi(sck)
24mpp3 3 gpo, nand(io5), spi(miso)
25mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk)
26mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig)
27mpp6 6 sysrst(out), spi(mosi), ptp(trig)
28mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig)
29mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk),
30 mii(col)
31mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq),
32 mii(crs)
33mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig)
34mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq),
35 ptp-2(trig)
36mpp12 12 gpo, sdio(clk)
37mpp13 13 gpio, sdio(cmd), uart1(txd)
38mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col)
39mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd)
40mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs)
41mpp17 17 gpio, sdio(d3)
42mpp18 18 gpo, nand(io0)
43mpp19 19 gpo, nand(io1)
44mpp20 20 gpio, mii(rxerr)
45mpp21 21 gpio, audio(spdifi)
46mpp22 22 gpio, audio(spdifo)
47mpp23 23 gpio, audio(rmclk)
48mpp24 24 gpio, audio(bclk)
49mpp25 25 gpio, audio(sdo)
50mpp26 26 gpio, audio(lrclk)
51mpp27 27 gpio, audio(mclk)
52mpp28 28 gpio, audio(sdi)
53mpp29 29 gpio, audio(extclk)
54
55* Marvell Kirkwood 88f6190
56
57name pins functions
58================================================================================
59mpp0 0 gpio, nand(io2), spi(cs)
60mpp1 1 gpo, nand(io3), spi(mosi)
61mpp2 2 gpo, nand(io4), spi(sck)
62mpp3 3 gpo, nand(io5), spi(miso)
63mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk)
64mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act)
65mpp6 6 sysrst(out), spi(mosi), ptp(trig)
66mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig)
67mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk),
68 mii(col), mii-1(rxerr)
69mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq),
70 mii(crs), sata0(prsnt)
71mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig)
72mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq),
73 ptp-2(trig), sata0(act)
74mpp12 12 gpo, sdio(clk)
75mpp13 13 gpio, sdio(cmd), uart1(txd)
76mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col)
77mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act)
78mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs)
79mpp17 17 gpio, sdio(d3), sata0(prsnt)
80mpp18 18 gpo, nand(io0)
81mpp19 19 gpo, nand(io1)
82mpp20 20 gpio, ge1(txd0)
83mpp21 21 gpio, ge1(txd1), sata0(act)
84mpp22 22 gpio, ge1(txd2)
85mpp23 23 gpio, ge1(txd3), sata0(prsnt)
86mpp24 24 gpio, ge1(rxd0)
87mpp25 25 gpio, ge1(rxd1)
88mpp26 26 gpio, ge1(rxd2)
89mpp27 27 gpio, ge1(rxd3)
90mpp28 28 gpio, ge1(col)
91mpp29 29 gpio, ge1(txclk)
92mpp30 30 gpio, ge1(rxclk)
93mpp31 31 gpio, ge1(rxclk)
94mpp32 32 gpio, ge1(txclko)
95mpp33 33 gpo, ge1(txclk)
96mpp34 34 gpio, ge1(txen)
97mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr)
98
99* Marvell Kirkwood 88f6192
100
101name pins functions
102================================================================================
103mpp0 0 gpio, nand(io2), spi(cs)
104mpp1 1 gpo, nand(io3), spi(mosi)
105mpp2 2 gpo, nand(io4), spi(sck)
106mpp3 3 gpo, nand(io5), spi(miso)
107mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk), sata1(act)
108mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act)
109mpp6 6 sysrst(out), spi(mosi), ptp(trig)
110mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig)
111mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk),
112 mii(col), mii-1(rxerr), sata1(prsnt)
113mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq),
114 mii(crs), sata0(prsnt)
115mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig), sata1(act)
116mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq),
117 ptp-2(trig), sata0(act)
118mpp12 12 gpo, sdio(clk)
119mpp13 13 gpio, sdio(cmd), uart1(txd)
120mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt)
121mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act)
122mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs),
123 sata1(act)
124mpp17 17 gpio, sdio(d3), sata0(prsnt)
125mpp18 18 gpo, nand(io0)
126mpp19 19 gpo, nand(io1)
127mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi),
128 sata1(act)
129mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql),
130 audio(spdifo)
131mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk),
132 sata1(prsnt)
133mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql),
134 audio(bclk)
135mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo)
136mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk)
137mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk)
138mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi)
139mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk)
140mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst)
141mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk)
142mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs)
143mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx)
144mpp33 33 gpo, ge1(txclk), tdm(drx)
145mpp34 34 gpio, ge1(txen), tdm(spi-cs1)
146mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql)
147
148* Marvell Kirkwood 88f6281
149
150name pins functions
151================================================================================
152mpp0 0 gpio, nand(io2), spi(cs)
153mpp1 1 gpo, nand(io3), spi(mosi)
154mpp2 2 gpo, nand(io4), spi(sck)
155mpp3 3 gpo, nand(io5), spi(miso)
156mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk), sata1(act)
157mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act)
158mpp6 6 sysrst(out), spi(mosi), ptp(trig)
159mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig)
160mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk),
161 mii(col), mii-1(rxerr), sata1(prsnt)
162mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq),
163 mii(crs), sata0(prsnt)
164mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig), sata1(act)
165mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq),
166 ptp-2(trig), sata0(act)
167mpp12 12 gpio, sdio(clk)
168mpp13 13 gpio, sdio(cmd), uart1(txd)
169mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt)
170mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act)
171mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs),
172 sata1(act)
173mpp17 17 gpio, sdio(d3), sata0(prsnt)
174mpp18 18 gpo, nand(io0)
175mpp19 19 gpo, nand(io1)
176mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi),
177 sata1(act)
178mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql),
179 audio(spdifo)
180mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk),
181 sata1(prsnt)
182mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql),
183 audio(bclk)
184mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo)
185mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk)
186mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk)
187mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi)
188mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk)
189mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst)
190mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk)
191mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs)
192mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx)
193mpp33 33 gpo, ge1(txclk), tdm(drx)
194mpp34 34 gpio, ge1(txen), tdm(spi-cs1), sata1(act)
195mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql)
196mpp36 36 gpio, ts(mp0), tdm(spi-cs1), audio(spdifi)
197mpp37 37 gpio, ts(mp1), tdm(tx2ql), audio(spdifo)
198mpp38 38 gpio, ts(mp2), tdm(rx2ql), audio(rmclk)
199mpp39 39 gpio, ts(mp3), tdm(spi-cs0), audio(bclk)
200mpp40 40 gpio, ts(mp4), tdm(spi-sck), audio(sdo)
201mpp41 41 gpio, ts(mp5), tdm(spi-miso), audio(lrclk)
202mpp42 42 gpio, ts(mp6), tdm(spi-mosi), audio(mclk)
203mpp43 43 gpio, ts(mp7), tdm(int), audio(sdi)
204mpp44 44 gpio, ts(mp8), tdm(rst), audio(extclk)
205mpp45 45 gpio, ts(mp9), tdm(pclk)
206mpp46 46 gpio, ts(mp10), tdm(fs)
207mpp47 47 gpio, ts(mp11), tdm(drx)
208mpp48 48 gpio, ts(mp12), tdm(dtx)
209mpp49 49 gpio, ts(mp9), tdm(rx0ql), ptp(clk)
210
211* Marvell Kirkwood 88f6282
212
213name pins functions
214================================================================================
215mpp0 0 gpio, nand(io2), spi(cs)
216mpp1 1 gpo, nand(io3), spi(mosi)
217mpp2 2 gpo, nand(io4), spi(sck)
218mpp3 3 gpo, nand(io5), spi(miso)
219mpp4 4 gpio, nand(io6), uart0(rxd), sata1(act), lcd(hsync)
220mpp5 5 gpo, nand(io7), uart0(txd), sata0(act), lcd(vsync)
221mpp6 6 sysrst(out), spi(mosi)
222mpp7 7 gpo, spi(cs), lcd(pwm)
223mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), mii(col),
224 mii-1(rxerr), sata1(prsnt)
225mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), mii(crs),
226 sata0(prsnt)
227mpp10 10 gpo, spi(sck), uart0(txd), sata1(act)
228mpp11 11 gpio, spi(miso), uart0(rxd), sata0(act)
229mpp12 12 gpo, sdio(clk), audio(spdifo), spi(mosi), twsi(sda)
230mpp13 13 gpio, sdio(cmd), uart1(txd), audio(rmclk), lcd(pwm)
231mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt),
232 audio(spdifi), audio-1(sdi)
233mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act),
234 spi(cs)
235mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs),
236 sata1(act), lcd(extclk)
237mpp17 17 gpio, sdio(d3), sata0(prsnt), sata1(act), twsi1(sck)
238mpp18 18 gpo, nand(io0), pex(clkreq)
239mpp19 19 gpo, nand(io1)
240mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi),
241 sata1(act), lcd(d0)
242mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql),
243 audio(spdifo), lcd(d1)
244mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk),
245 sata1(prsnt), lcd(d2)
246mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql),
247 audio(bclk), lcd(d3)
248mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo),
249 lcd(d4)
250mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk),
251 lcd(d5)
252mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk),
253 lcd(d6)
254mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi),
255 lcd(d7)
256mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk),
257 lcd(d8)
258mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst), lcd(d9)
259mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk), lcd(d10)
260mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs), lcd(d11)
261mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx), lcd(d12)
262mpp33 33 gpo, ge1(txclk), tdm(drx), lcd(d13)
263mpp34 34 gpio, ge1(txen), tdm(spi-cs1), sata1(act), lcd(d14)
264mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql),
265 lcd(d15)
266mpp36 36 gpio, ts(mp0), tdm(spi-cs1), audio(spdifi), twsi1(sda)
267mpp37 37 gpio, ts(mp1), tdm(tx2ql), audio(spdifo), twsi1(sck)
268mpp38 38 gpio, ts(mp2), tdm(rx2ql), audio(rmclk), lcd(d18)
269mpp39 39 gpio, ts(mp3), tdm(spi-cs0), audio(bclk), lcd(d19)
270mpp40 40 gpio, ts(mp4), tdm(spi-sck), audio(sdo), lcd(d20)
271mpp41 41 gpio, ts(mp5), tdm(spi-miso), audio(lrclk), lcd(d21)
272mpp42 42 gpio, ts(mp6), tdm(spi-mosi), audio(mclk), lcd(d22)
273mpp43 43 gpio, ts(mp7), tdm(int), audio(sdi), lcd(d23)
274mpp44 44 gpio, ts(mp8), tdm(rst), audio(extclk), lcd(clk)
275mpp45 45 gpio, ts(mp9), tdm(pclk), lcd(e)
276mpp46 46 gpio, ts(mp10), tdm(fs), lcd(hsync)
277mpp47 47 gpio, ts(mp11), tdm(drx), lcd(vsync)
278mpp48 48 gpio, ts(mp12), tdm(dtx), lcd(d16)
279mpp49 49 gpo, tdm(rx0ql), pex(clkreq), lcd(d17)
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt
new file mode 100644
index 000000000000..0a26c3aa4e6d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt
@@ -0,0 +1,46 @@
1* Marvell SoC pinctrl core driver for mpp
2
3The pinctrl driver enables Marvell SoCs to configure the multi-purpose pins
4(mpp) to a specific function. For each SoC family there is a SoC specific
5driver using this core driver.
6
7Please refer to pinctrl-bindings.txt in this directory for details of the
8common pinctrl bindings used by client devices, including the meaning of the
9phrase "pin configuration node".
10
11A Marvell SoC pin configuration node is a node of a group of pins which can
12be used for a specific device or function. Each node requires one or more
13mpp pins or group of pins and a mpp function common to all pins.
14
15Required properties for pinctrl driver:
16- compatible: "marvell,<soc>-pinctrl"
17 Please refer to each marvell,<soc>-pinctrl.txt binding doc for supported SoCs.
18
19Required properties for pin configuration node:
20- marvell,pins: string array of mpp pins or group of pins to be muxed.
21- marvell,function: string representing a function to mux to for all
22 marvell,pins given in this pin configuration node. The function has to be
23 common for all marvell,pins. Please refer to marvell,<soc>-pinctrl.txt for
24 valid pin/pin group names and available function names for each SoC.
25
26Examples:
27
28uart1: serial@12100 {
29 compatible = "ns16550a";
30 reg = <0x12100 0x100>;
31 reg-shift = <2>;
32 interrupts = <7>;
33
34 pinctrl-0 = <&pmx_uart1_sw>;
35 pinctrl-names = "default";
36};
37
38pinctrl: pinctrl@d0200 {
39 compatible = "marvell,dove-pinctrl";
40 reg = <0xd0200 0x20>;
41
42 pmx_uart1_sw: pmx-uart1-sw {
43 marvell,pins = "mpp_uart1";
44 marvell,function = "uart1";
45 };
46};
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 3228ccc83332..2069151afe01 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -21,6 +21,12 @@
21 model = "Marvell Armada 370 family SoC"; 21 model = "Marvell Armada 370 family SoC";
22 compatible = "marvell,armada370", "marvell,armada-370-xp"; 22 compatible = "marvell,armada370", "marvell,armada-370-xp";
23 23
24 aliases {
25 gpio0 = &gpio0;
26 gpio1 = &gpio1;
27 gpio2 = &gpio2;
28 };
29
24 mpic: interrupt-controller@d0020000 { 30 mpic: interrupt-controller@d0020000 {
25 reg = <0xd0020a00 0x1d0>, 31 reg = <0xd0020a00 0x1d0>,
26 <0xd0021870 0x58>; 32 <0xd0021870 0x58>;
@@ -31,5 +37,43 @@
31 compatible = "marvell,armada-370-xp-system-controller"; 37 compatible = "marvell,armada-370-xp-system-controller";
32 reg = <0xd0018200 0x100>; 38 reg = <0xd0018200 0x100>;
33 }; 39 };
40
41 pinctrl {
42 compatible = "marvell,mv88f6710-pinctrl";
43 reg = <0xd0018000 0x38>;
44 };
45
46 gpio0: gpio@d0018100 {
47 compatible = "marvell,orion-gpio";
48 reg = <0xd0018100 0x40>;
49 ngpios = <32>;
50 gpio-controller;
51 #gpio-cells = <2>;
52 interrupt-controller;
53 #interrupts-cells = <2>;
54 interrupts = <82>, <83>, <84>, <85>;
55 };
56
57 gpio1: gpio@d0018140 {
58 compatible = "marvell,orion-gpio";
59 reg = <0xd0018140 0x40>;
60 ngpios = <32>;
61 gpio-controller;
62 #gpio-cells = <2>;
63 interrupt-controller;
64 #interrupts-cells = <2>;
65 interrupts = <87>, <88>, <89>, <90>;
66 };
67
68 gpio2: gpio@d0018180 {
69 compatible = "marvell,orion-gpio";
70 reg = <0xd0018180 0x40>;
71 ngpios = <2>;
72 gpio-controller;
73 #gpio-cells = <2>;
74 interrupt-controller;
75 #interrupts-cells = <2>;
76 interrupts = <91>;
77 };
34 }; 78 };
35}; 79};
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index f97040d4258d..b1fc728515e9 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -14,11 +14,11 @@
14 */ 14 */
15 15
16/dts-v1/; 16/dts-v1/;
17/include/ "armada-xp.dtsi" 17/include/ "armada-xp-mv78460.dtsi"
18 18
19/ { 19/ {
20 model = "Marvell Armada XP Evaluation Board"; 20 model = "Marvell Armada XP Evaluation Board";
21 compatible = "marvell,axp-db", "marvell,armadaxp", "marvell,armada-370-xp"; 21 compatible = "marvell,axp-db", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
22 22
23 chosen { 23 chosen {
24 bootargs = "console=ttyS0,115200 earlyprintk"; 24 bootargs = "console=ttyS0,115200 earlyprintk";
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
new file mode 100644
index 000000000000..ea355192be6f
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -0,0 +1,57 @@
1/*
2 * Device Tree Include file for Marvell Armada XP family SoC
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 *
12 * Contains definitions specific to the Armada XP MV78230 SoC that are not
13 * common to all Armada XP SoCs.
14 */
15
16/include/ "armada-xp.dtsi"
17
18/ {
19 model = "Marvell Armada XP MV78230 SoC";
20 compatible = "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp";
21
22 aliases {
23 gpio0 = &gpio0;
24 gpio1 = &gpio1;
25 };
26
27 soc {
28 pinctrl {
29 compatible = "marvell,mv78230-pinctrl";
30 reg = <0xd0018000 0x38>;
31 };
32
33 gpio0: gpio@d0018100 {
34 compatible = "marvell,armadaxp-gpio";
35 reg = <0xd0018100 0x40>,
36 <0xd0018800 0x30>;
37 ngpios = <32>;
38 gpio-controller;
39 #gpio-cells = <2>;
40 interrupt-controller;
41 #interrupts-cells = <2>;
42 interrupts = <16>, <17>, <18>, <19>;
43 };
44
45 gpio1: gpio@d0018140 {
46 compatible = "marvell,armadaxp-gpio";
47 reg = <0xd0018140 0x40>,
48 <0xd0018840 0x30>;
49 ngpios = <17>;
50 gpio-controller;
51 #gpio-cells = <2>;
52 interrupt-controller;
53 #interrupts-cells = <2>;
54 interrupts = <20>, <21>, <22>;
55 };
56 };
57};
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
new file mode 100644
index 000000000000..2057863f3dfa
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -0,0 +1,70 @@
1/*
2 * Device Tree Include file for Marvell Armada XP family SoC
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 *
12 * Contains definitions specific to the Armada XP MV78260 SoC that are not
13 * common to all Armada XP SoCs.
14 */
15
16/include/ "armada-xp.dtsi"
17
18/ {
19 model = "Marvell Armada XP MV78260 SoC";
20 compatible = "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp";
21
22 aliases {
23 gpio0 = &gpio0;
24 gpio1 = &gpio1;
25 gpio2 = &gpio2;
26 };
27
28 soc {
29 pinctrl {
30 compatible = "marvell,mv78260-pinctrl";
31 reg = <0xd0018000 0x38>;
32 };
33
34 gpio0: gpio@d0018100 {
35 compatible = "marvell,armadaxp-gpio";
36 reg = <0xd0018100 0x40>,
37 <0xd0018800 0x30>;
38 ngpios = <32>;
39 gpio-controller;
40 #gpio-cells = <2>;
41 interrupt-controller;
42 #interrupts-cells = <2>;
43 interrupts = <16>, <17>, <18>, <19>;
44 };
45
46 gpio1: gpio@d0018140 {
47 compatible = "marvell,armadaxp-gpio";
48 reg = <0xd0018140 0x40>,
49 <0xd0018840 0x30>;
50 ngpios = <32>;
51 gpio-controller;
52 #gpio-cells = <2>;
53 interrupt-controller;
54 #interrupts-cells = <2>;
55 interrupts = <20>, <21>, <22>, <23>;
56 };
57
58 gpio2: gpio@d0018180 {
59 compatible = "marvell,armadaxp-gpio";
60 reg = <0xd0018180 0x40>,
61 <0xd0018870 0x30>;
62 ngpios = <3>;
63 gpio-controller;
64 #gpio-cells = <2>;
65 interrupt-controller;
66 #interrupts-cells = <2>;
67 interrupts = <24>;
68 };
69 };
70};
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
new file mode 100644
index 000000000000..ffac98373792
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -0,0 +1,70 @@
1/*
2 * Device Tree Include file for Marvell Armada XP family SoC
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 *
12 * Contains definitions specific to the Armada XP MV78460 SoC that are not
13 * common to all Armada XP SoCs.
14 */
15
16/include/ "armada-xp.dtsi"
17
18/ {
19 model = "Marvell Armada XP MV78460 SoC";
20 compatible = "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
21
22 aliases {
23 gpio0 = &gpio0;
24 gpio1 = &gpio1;
25 gpio2 = &gpio2;
26 };
27
28 soc {
29 pinctrl {
30 compatible = "marvell,mv78460-pinctrl";
31 reg = <0xd0018000 0x38>;
32 };
33
34 gpio0: gpio@d0018100 {
35 compatible = "marvell,armadaxp-gpio";
36 reg = <0xd0018100 0x40>,
37 <0xd0018800 0x30>;
38 ngpios = <32>;
39 gpio-controller;
40 #gpio-cells = <2>;
41 interrupt-controller;
42 #interrupts-cells = <2>;
43 interrupts = <16>, <17>, <18>, <19>;
44 };
45
46 gpio1: gpio@d0018140 {
47 compatible = "marvell,armadaxp-gpio";
48 reg = <0xd0018140 0x40>,
49 <0xd0018840 0x30>;
50 ngpios = <32>;
51 gpio-controller;
52 #gpio-cells = <2>;
53 interrupt-controller;
54 #interrupts-cells = <2>;
55 interrupts = <20>, <21>, <22>, <23>;
56 };
57
58 gpio2: gpio@d0018180 {
59 compatible = "marvell,armadaxp-gpio";
60 reg = <0xd0018180 0x40>,
61 <0xd0018870 0x30>;
62 ngpios = <3>;
63 gpio-controller;
64 #gpio-cells = <2>;
65 interrupt-controller;
66 #interrupts-cells = <2>;
67 interrupts = <24>;
68 };
69 };
70 };
diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig
index 2e86b31c33cf..7bcf850eddcd 100644
--- a/arch/arm/configs/mvebu_defconfig
+++ b/arch/arm/configs/mvebu_defconfig
@@ -21,6 +21,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
21CONFIG_SERIAL_8250=y 21CONFIG_SERIAL_8250=y
22CONFIG_SERIAL_8250_CONSOLE=y 22CONFIG_SERIAL_8250_CONSOLE=y
23CONFIG_SERIAL_OF_PLATFORM=y 23CONFIG_SERIAL_OF_PLATFORM=y
24CONFIG_GPIOLIB=y
25CONFIG_GPIO_SYSFS=y
24CONFIG_EXT2_FS=y 26CONFIG_EXT2_FS=y
25CONFIG_EXT3_FS=y 27CONFIG_EXT3_FS=y
26# CONFIG_EXT3_FS_XATTR is not set 28# CONFIG_EXT3_FS_XATTR is not set
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 7b270358536e..26a817d81a70 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -13,13 +13,25 @@ if ARCH_MVEBU
13menu "Marvell SOC with device tree" 13menu "Marvell SOC with device tree"
14 14
15config MACH_ARMADA_370_XP 15config MACH_ARMADA_370_XP
16 bool "Marvell Armada 370 and Aramada XP boards" 16 bool
17 select ARMADA_370_XP_TIMER 17 select ARMADA_370_XP_TIMER
18 select CPU_V7 18 select CPU_V7
19
20config MACH_ARMADA_370
21 bool "Marvell Armada 370 boards"
22 select MACH_ARMADA_370_XP
23 select PINCTRL_ARMADA_370
19 help 24 help
25 Say 'Y' here if you want your kernel to support boards based
26 on the Marvell Armada 370 SoC with device tree.
20 27
21 Say 'Y' here if you want your kernel to support boards based on 28config MACH_ARMADA_XP
22 Marvell Armada 370 or Armada XP with device tree. 29 bool "Marvell Armada XP boards"
30 select MACH_ARMADA_370_XP
31 select PINCTRL_ARMADA_XP
32 help
33 Say 'Y' here if you want your kernel to support boards based
34 on the Marvell Armada XP SoC with device tree.
23 35
24endmenu 36endmenu
25 37
diff --git a/arch/arm/mach-mvebu/include/mach/gpio.h b/arch/arm/mach-mvebu/include/mach/gpio.h
new file mode 100644
index 000000000000..40a8c178f10d
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/gpio.h
@@ -0,0 +1 @@
/* empty */
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ba7926f5c099..66a59510887f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -150,6 +150,12 @@ config GPIO_MSM_V2
150 Qualcomm MSM chips. Most of the pins on the MSM can be 150 Qualcomm MSM chips. Most of the pins on the MSM can be
151 selected for GPIO, and are controlled by this driver. 151 selected for GPIO, and are controlled by this driver.
152 152
153config GPIO_MVEBU
154 def_bool y
155 depends on ARCH_MVEBU
156 select GPIO_GENERIC
157 select GENERIC_IRQ_CHIP
158
153config GPIO_MXC 159config GPIO_MXC
154 def_bool y 160 def_bool y
155 depends on ARCH_MXC 161 depends on ARCH_MXC
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 153caceeb053..1a33e6716e10 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
41obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o 41obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o
42obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o 42obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o
43obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o 43obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o
44obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
44obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o 45obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
45obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o 46obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
46obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o 47obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
new file mode 100644
index 000000000000..902af437eaf2
--- /dev/null
+++ b/drivers/gpio/gpio-mvebu.c
@@ -0,0 +1,679 @@
1/*
2 * GPIO driver for Marvell SoCs
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 * Andrew Lunn <andrew@lunn.ch>
8 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13 *
14 * This driver is a fairly straightforward GPIO driver for the
15 * complete family of Marvell EBU SoC platforms (Orion, Dove,
16 * Kirkwood, Discovery, Armada 370/XP). The only complexity of this
17 * driver is the different register layout that exists between the
18 * non-SMP platforms (Orion, Dove, Kirkwood, Armada 370) and the SMP
19 * platforms (MV78200 from the Discovery family and the Armada
20 * XP). Therefore, this driver handles three variants of the GPIO
21 * block:
22 * - the basic variant, called "orion-gpio", with the simplest
23 * register set. Used on Orion, Dove, Kirkwoord, Armada 370 and
24 * non-SMP Discovery systems
25 * - the mv78200 variant for MV78200 Discovery systems. This variant
26 * turns the edge mask and level mask registers into CPU0 edge
27 * mask/level mask registers, and adds CPU1 edge mask/level mask
28 * registers.
29 * - the armadaxp variant for Armada XP systems. This variant keeps
30 * the normal cause/edge mask/level mask registers when the global
31 * interrupts are used, but adds per-CPU cause/edge mask/level mask
32 * registers n a separate memory area for the per-CPU GPIO
33 * interrupts.
34 */
35
36#include <linux/module.h>
37#include <linux/gpio.h>
38#include <linux/irq.h>
39#include <linux/slab.h>
40#include <linux/irqdomain.h>
41#include <linux/io.h>
42#include <linux/of_irq.h>
43#include <linux/of_device.h>
44#include <linux/platform_device.h>
45#include <linux/pinctrl/consumer.h>
46
47/*
48 * GPIO unit register offsets.
49 */
50#define GPIO_OUT_OFF 0x0000
51#define GPIO_IO_CONF_OFF 0x0004
52#define GPIO_BLINK_EN_OFF 0x0008
53#define GPIO_IN_POL_OFF 0x000c
54#define GPIO_DATA_IN_OFF 0x0010
55#define GPIO_EDGE_CAUSE_OFF 0x0014
56#define GPIO_EDGE_MASK_OFF 0x0018
57#define GPIO_LEVEL_MASK_OFF 0x001c
58
59/* The MV78200 has per-CPU registers for edge mask and level mask */
60#define GPIO_EDGE_MASK_MV78200_OFF(cpu) ((cpu) ? 0x30 : 0x18)
61#define GPIO_LEVEL_MASK_MV78200_OFF(cpu) ((cpu) ? 0x34 : 0x1C)
62
63/* The Armada XP has per-CPU registers for interrupt cause, interrupt
64 * mask and interrupt level mask. Those are relative to the
65 * percpu_membase. */
66#define GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu) ((cpu) * 0x4)
67#define GPIO_EDGE_MASK_ARMADAXP_OFF(cpu) (0x10 + (cpu) * 0x4)
68#define GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu) (0x20 + (cpu) * 0x4)
69
70#define MVEBU_GPIO_SOC_VARIANT_ORION 0x1
71#define MVEBU_GPIO_SOC_VARIANT_MV78200 0x2
72#define MVEBU_GPIO_SOC_VARIANT_ARMADAXP 0x3
73
74#define MVEBU_MAX_GPIO_PER_BANK 32
75
76struct mvebu_gpio_chip {
77 struct gpio_chip chip;
78 spinlock_t lock;
79 void __iomem *membase;
80 void __iomem *percpu_membase;
81 unsigned int irqbase;
82 struct irq_domain *domain;
83 int soc_variant;
84};
85
86/*
87 * Functions returning addresses of individual registers for a given
88 * GPIO controller.
89 */
90static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip)
91{
92 return mvchip->membase + GPIO_OUT_OFF;
93}
94
95static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip)
96{
97 return mvchip->membase + GPIO_IO_CONF_OFF;
98}
99
100static inline void __iomem *mvebu_gpioreg_in_pol(struct mvebu_gpio_chip *mvchip)
101{
102 return mvchip->membase + GPIO_IN_POL_OFF;
103}
104
105static inline void __iomem *mvebu_gpioreg_data_in(struct mvebu_gpio_chip *mvchip)
106{
107 return mvchip->membase + GPIO_DATA_IN_OFF;
108}
109
110static inline void __iomem *mvebu_gpioreg_edge_cause(struct mvebu_gpio_chip *mvchip)
111{
112 int cpu;
113
114 switch(mvchip->soc_variant) {
115 case MVEBU_GPIO_SOC_VARIANT_ORION:
116 case MVEBU_GPIO_SOC_VARIANT_MV78200:
117 return mvchip->membase + GPIO_EDGE_CAUSE_OFF;
118 case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
119 cpu = smp_processor_id();
120 return mvchip->percpu_membase + GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu);
121 default:
122 BUG();
123 }
124}
125
126static inline void __iomem *mvebu_gpioreg_edge_mask(struct mvebu_gpio_chip *mvchip)
127{
128 int cpu;
129
130 switch(mvchip->soc_variant) {
131 case MVEBU_GPIO_SOC_VARIANT_ORION:
132 return mvchip->membase + GPIO_EDGE_MASK_OFF;
133 case MVEBU_GPIO_SOC_VARIANT_MV78200:
134 cpu = smp_processor_id();
135 return mvchip->membase + GPIO_EDGE_MASK_MV78200_OFF(cpu);
136 case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
137 cpu = smp_processor_id();
138 return mvchip->percpu_membase + GPIO_EDGE_MASK_ARMADAXP_OFF(cpu);
139 default:
140 BUG();
141 }
142}
143
144static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip)
145{
146 int cpu;
147
148 switch(mvchip->soc_variant) {
149 case MVEBU_GPIO_SOC_VARIANT_ORION:
150 return mvchip->membase + GPIO_LEVEL_MASK_OFF;
151 case MVEBU_GPIO_SOC_VARIANT_MV78200:
152 cpu = smp_processor_id();
153 return mvchip->membase + GPIO_LEVEL_MASK_MV78200_OFF(cpu);
154 case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
155 cpu = smp_processor_id();
156 return mvchip->percpu_membase + GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu);
157 default:
158 BUG();
159 }
160}
161
162/*
163 * Functions implementing the gpio_chip methods
164 */
165
166int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin)
167{
168 return pinctrl_request_gpio(chip->base + pin);
169}
170
171void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin)
172{
173 pinctrl_free_gpio(chip->base + pin);
174}
175
176static void mvebu_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
177{
178 struct mvebu_gpio_chip *mvchip =
179 container_of(chip, struct mvebu_gpio_chip, chip);
180 unsigned long flags;
181 u32 u;
182
183 spin_lock_irqsave(&mvchip->lock, flags);
184 u = readl_relaxed(mvebu_gpioreg_out(mvchip));
185 if (value)
186 u |= 1 << pin;
187 else
188 u &= ~(1 << pin);
189 writel_relaxed(u, mvebu_gpioreg_out(mvchip));
190 spin_unlock_irqrestore(&mvchip->lock, flags);
191}
192
193static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin)
194{
195 struct mvebu_gpio_chip *mvchip =
196 container_of(chip, struct mvebu_gpio_chip, chip);
197 u32 u;
198
199 if (readl_relaxed(mvebu_gpioreg_io_conf(mvchip)) & (1 << pin)) {
200 u = readl_relaxed(mvebu_gpioreg_data_in(mvchip)) ^
201 readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
202 } else {
203 u = readl_relaxed(mvebu_gpioreg_out(mvchip));
204 }
205
206 return (u >> pin) & 1;
207}
208
209static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
210{
211 struct mvebu_gpio_chip *mvchip =
212 container_of(chip, struct mvebu_gpio_chip, chip);
213 unsigned long flags;
214 int ret;
215 u32 u;
216
217 /* Check with the pinctrl driver whether this pin is usable as
218 * an input GPIO */
219 ret = pinctrl_gpio_direction_input(chip->base + pin);
220 if (ret)
221 return ret;
222
223 spin_lock_irqsave(&mvchip->lock, flags);
224 u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
225 u |= 1 << pin;
226 writel_relaxed(u, mvebu_gpioreg_io_conf(mvchip));
227 spin_unlock_irqrestore(&mvchip->lock, flags);
228
229 return 0;
230}
231
232static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
233 int value)
234{
235 struct mvebu_gpio_chip *mvchip =
236 container_of(chip, struct mvebu_gpio_chip, chip);
237 unsigned long flags;
238 int ret;
239 u32 u;
240
241 /* Check with the pinctrl driver whether this pin is usable as
242 * an output GPIO */
243 ret = pinctrl_gpio_direction_output(chip->base + pin);
244 if (ret)
245 return ret;
246
247 spin_lock_irqsave(&mvchip->lock, flags);
248 u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
249 u &= ~(1 << pin);
250 writel_relaxed(u, mvebu_gpioreg_io_conf(mvchip));
251 spin_unlock_irqrestore(&mvchip->lock, flags);
252
253 return 0;
254}
255
256static int mvebu_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
257{
258 struct mvebu_gpio_chip *mvchip =
259 container_of(chip, struct mvebu_gpio_chip, chip);
260 return irq_create_mapping(mvchip->domain, pin);
261}
262
263/*
264 * Functions implementing the irq_chip methods
265 */
266static void mvebu_gpio_irq_ack(struct irq_data *d)
267{
268 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
269 struct mvebu_gpio_chip *mvchip = gc->private;
270 u32 mask = ~(1 << (d->irq - gc->irq_base));
271
272 irq_gc_lock(gc);
273 writel_relaxed(mask, mvebu_gpioreg_edge_cause(mvchip));
274 irq_gc_unlock(gc);
275}
276
277static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
278{
279 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
280 struct mvebu_gpio_chip *mvchip = gc->private;
281 u32 mask = 1 << (d->irq - gc->irq_base);
282
283 irq_gc_lock(gc);
284 gc->mask_cache &= ~mask;
285 writel_relaxed(gc->mask_cache, mvebu_gpioreg_edge_mask(mvchip));
286 irq_gc_unlock(gc);
287}
288
289static void mvebu_gpio_edge_irq_unmask(struct irq_data *d)
290{
291 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
292 struct mvebu_gpio_chip *mvchip = gc->private;
293 u32 mask = 1 << (d->irq - gc->irq_base);
294
295 irq_gc_lock(gc);
296 gc->mask_cache |= mask;
297 writel_relaxed(gc->mask_cache, mvebu_gpioreg_edge_mask(mvchip));
298 irq_gc_unlock(gc);
299}
300
301static void mvebu_gpio_level_irq_mask(struct irq_data *d)
302{
303 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
304 struct mvebu_gpio_chip *mvchip = gc->private;
305 u32 mask = 1 << (d->irq - gc->irq_base);
306
307 irq_gc_lock(gc);
308 gc->mask_cache &= ~mask;
309 writel_relaxed(gc->mask_cache, mvebu_gpioreg_level_mask(mvchip));
310 irq_gc_unlock(gc);
311}
312
313static void mvebu_gpio_level_irq_unmask(struct irq_data *d)
314{
315 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
316 struct mvebu_gpio_chip *mvchip = gc->private;
317 u32 mask = 1 << (d->irq - gc->irq_base);
318
319 irq_gc_lock(gc);
320 gc->mask_cache |= mask;
321 writel_relaxed(gc->mask_cache, mvebu_gpioreg_level_mask(mvchip));
322 irq_gc_unlock(gc);
323}
324
325/*****************************************************************************
326 * MVEBU GPIO IRQ
327 *
328 * GPIO_IN_POL register controls whether GPIO_DATA_IN will hold the same
329 * value of the line or the opposite value.
330 *
331 * Level IRQ handlers: DATA_IN is used directly as cause register.
332 * Interrupt are masked by LEVEL_MASK registers.
333 * Edge IRQ handlers: Change in DATA_IN are latched in EDGE_CAUSE.
334 * Interrupt are masked by EDGE_MASK registers.
335 * Both-edge handlers: Similar to regular Edge handlers, but also swaps
336 * the polarity to catch the next line transaction.
337 * This is a race condition that might not perfectly
338 * work on some use cases.
339 *
340 * Every eight GPIO lines are grouped (OR'ed) before going up to main
341 * cause register.
342 *
343 * EDGE cause mask
344 * data-in /--------| |-----| |----\
345 * -----| |----- ---- to main cause reg
346 * X \----------------| |----/
347 * polarity LEVEL mask
348 *
349 ****************************************************************************/
350
351static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type)
352{
353 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
354 struct irq_chip_type *ct = irq_data_get_chip_type(d);
355 struct mvebu_gpio_chip *mvchip = gc->private;
356 int pin;
357 u32 u;
358
359 pin = d->hwirq;
360
361 u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)) & (1 << pin);
362 if (!u) {
363 return -EINVAL;
364 }
365
366 type &= IRQ_TYPE_SENSE_MASK;
367 if (type == IRQ_TYPE_NONE)
368 return -EINVAL;
369
370 /* Check if we need to change chip and handler */
371 if (!(ct->type & type))
372 if (irq_setup_alt_chip(d, type))
373 return -EINVAL;
374
375 /*
376 * Configure interrupt polarity.
377 */
378 switch(type) {
379 case IRQ_TYPE_EDGE_RISING:
380 case IRQ_TYPE_LEVEL_HIGH:
381 u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
382 u &= ~(1 << pin);
383 writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip));
384 case IRQ_TYPE_EDGE_FALLING:
385 case IRQ_TYPE_LEVEL_LOW:
386 u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
387 u |= 1 << pin;
388 writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip));
389 case IRQ_TYPE_EDGE_BOTH: {
390 u32 v;
391
392 v = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)) ^
393 readl_relaxed(mvebu_gpioreg_data_in(mvchip));
394
395 /*
396 * set initial polarity based on current input level
397 */
398 u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
399 if (v & (1 << pin))
400 u |= 1 << pin; /* falling */
401 else
402 u &= ~(1 << pin); /* rising */
403 writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip));
404 }
405 }
406 return 0;
407}
408
409static void mvebu_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
410{
411 struct mvebu_gpio_chip *mvchip = irq_get_handler_data(irq);
412 u32 cause, type;
413 int i;
414
415 if (mvchip == NULL)
416 return;
417
418 cause = readl_relaxed(mvebu_gpioreg_data_in(mvchip)) &
419 readl_relaxed(mvebu_gpioreg_level_mask(mvchip));
420 cause |= readl_relaxed(mvebu_gpioreg_edge_cause(mvchip)) &
421 readl_relaxed(mvebu_gpioreg_edge_mask(mvchip));
422
423 for (i = 0; i < mvchip->chip.ngpio; i++) {
424 int irq;
425
426 irq = mvchip->irqbase + i;
427
428 if (!(cause & (1 << i)))
429 continue;
430
431 type = irqd_get_trigger_type(irq_get_irq_data(irq));
432 if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
433 /* Swap polarity (race with GPIO line) */
434 u32 polarity;
435
436 polarity = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
437 polarity ^= 1 << i;
438 writel_relaxed(polarity, mvebu_gpioreg_in_pol(mvchip));
439 }
440 generic_handle_irq(irq);
441 }
442}
443
444static struct platform_device_id mvebu_gpio_ids[] = {
445 {
446 .name = "orion-gpio",
447 }, {
448 .name = "mv78200-gpio",
449 }, {
450 .name = "armadaxp-gpio",
451 }, {
452 /* sentinel */
453 },
454};
455MODULE_DEVICE_TABLE(platform, mvebu_gpio_ids);
456
457static struct of_device_id mvebu_gpio_of_match[] __devinitdata = {
458 {
459 .compatible = "marvell,orion-gpio",
460 .data = (void*) MVEBU_GPIO_SOC_VARIANT_ORION,
461 },
462 {
463 .compatible = "marvell,mv78200-gpio",
464 .data = (void*) MVEBU_GPIO_SOC_VARIANT_MV78200,
465 },
466 {
467 .compatible = "marvell,armadaxp-gpio",
468 .data = (void*) MVEBU_GPIO_SOC_VARIANT_ARMADAXP,
469 },
470 {
471 /* sentinel */
472 },
473};
474MODULE_DEVICE_TABLE(of, mvebu_gpio_of_match);
475
476static int __devinit mvebu_gpio_probe(struct platform_device *pdev)
477{
478 struct mvebu_gpio_chip *mvchip;
479 const struct of_device_id *match;
480 struct device_node *np = pdev->dev.of_node;
481 struct resource *res;
482 struct irq_chip_generic *gc;
483 struct irq_chip_type *ct;
484 unsigned int ngpios;
485 int soc_variant;
486 int i, cpu, id;
487
488 match = of_match_device(mvebu_gpio_of_match, &pdev->dev);
489 if (match)
490 soc_variant = (int) match->data;
491 else
492 soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION;
493
494 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
495 if (! res) {
496 dev_err(&pdev->dev, "Cannot get memory resource\n");
497 return -ENODEV;
498 }
499
500 mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL);
501 if (! mvchip){
502 dev_err(&pdev->dev, "Cannot allocate memory\n");
503 return -ENOMEM;
504 }
505
506 if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) {
507 dev_err(&pdev->dev, "Missing ngpios OF property\n");
508 return -ENODEV;
509 }
510
511 id = of_alias_get_id(pdev->dev.of_node, "gpio");
512 if (id < 0) {
513 dev_err(&pdev->dev, "Couldn't get OF id\n");
514 return id;
515 }
516
517 mvchip->soc_variant = soc_variant;
518 mvchip->chip.label = dev_name(&pdev->dev);
519 mvchip->chip.dev = &pdev->dev;
520 mvchip->chip.request = mvebu_gpio_request;
521 mvchip->chip.direction_input = mvebu_gpio_direction_input;
522 mvchip->chip.get = mvebu_gpio_get;
523 mvchip->chip.direction_output = mvebu_gpio_direction_output;
524 mvchip->chip.set = mvebu_gpio_set;
525 mvchip->chip.to_irq = mvebu_gpio_to_irq;
526 mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK;
527 mvchip->chip.ngpio = ngpios;
528 mvchip->chip.can_sleep = 0;
529#ifdef CONFIG_OF
530 mvchip->chip.of_node = np;
531#endif
532
533 spin_lock_init(&mvchip->lock);
534 mvchip->membase = devm_request_and_ioremap(&pdev->dev, res);
535 if (! mvchip->membase) {
536 dev_err(&pdev->dev, "Cannot ioremap\n");
537 kfree(mvchip->chip.label);
538 return -ENOMEM;
539 }
540
541 /* The Armada XP has a second range of registers for the
542 * per-CPU registers */
543 if (soc_variant == MVEBU_GPIO_SOC_VARIANT_ARMADAXP) {
544 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
545 if (! res) {
546 dev_err(&pdev->dev, "Cannot get memory resource\n");
547 kfree(mvchip->chip.label);
548 return -ENODEV;
549 }
550
551 mvchip->percpu_membase = devm_request_and_ioremap(&pdev->dev, res);
552 if (! mvchip->percpu_membase) {
553 dev_err(&pdev->dev, "Cannot ioremap\n");
554 kfree(mvchip->chip.label);
555 return -ENOMEM;
556 }
557 }
558
559 /*
560 * Mask and clear GPIO interrupts.
561 */
562 switch(soc_variant) {
563 case MVEBU_GPIO_SOC_VARIANT_ORION:
564 writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
565 writel_relaxed(0, mvchip->membase + GPIO_EDGE_MASK_OFF);
566 writel_relaxed(0, mvchip->membase + GPIO_LEVEL_MASK_OFF);
567 break;
568 case MVEBU_GPIO_SOC_VARIANT_MV78200:
569 writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
570 for (cpu = 0; cpu < 2; cpu++) {
571 writel_relaxed(0, mvchip->membase +
572 GPIO_EDGE_MASK_MV78200_OFF(cpu));
573 writel_relaxed(0, mvchip->membase +
574 GPIO_LEVEL_MASK_MV78200_OFF(cpu));
575 }
576 break;
577 case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
578 writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
579 writel_relaxed(0, mvchip->membase + GPIO_EDGE_MASK_OFF);
580 writel_relaxed(0, mvchip->membase + GPIO_LEVEL_MASK_OFF);
581 for (cpu = 0; cpu < 4; cpu++) {
582 writel_relaxed(0, mvchip->percpu_membase +
583 GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu));
584 writel_relaxed(0, mvchip->percpu_membase +
585 GPIO_EDGE_MASK_ARMADAXP_OFF(cpu));
586 writel_relaxed(0, mvchip->percpu_membase +
587 GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu));
588 }
589 break;
590 default:
591 BUG();
592 }
593
594 gpiochip_add(&mvchip->chip);
595
596 /* Some gpio controllers do not provide irq support */
597 if (!of_irq_count(np))
598 return 0;
599
600 /* Setup the interrupt handlers. Each chip can have up to 4
601 * interrupt handlers, with each handler dealing with 8 GPIO
602 * pins. */
603 for (i = 0; i < 4; i++) {
604 int irq;
605 irq = platform_get_irq(pdev, i);
606 if (irq < 0)
607 continue;
608 irq_set_handler_data(irq, mvchip);
609 irq_set_chained_handler(irq, mvebu_gpio_irq_handler);
610 }
611
612 mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1);
613 if (mvchip->irqbase < 0) {
614 dev_err(&pdev->dev, "no irqs\n");
615 kfree(mvchip->chip.label);
616 return -ENOMEM;
617 }
618
619 gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase,
620 mvchip->membase, handle_level_irq);
621 if (! gc) {
622 dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n");
623 kfree(mvchip->chip.label);
624 return -ENOMEM;
625 }
626
627 gc->private = mvchip;
628 ct = &gc->chip_types[0];
629 ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
630 ct->chip.irq_mask = mvebu_gpio_level_irq_mask;
631 ct->chip.irq_unmask = mvebu_gpio_level_irq_unmask;
632 ct->chip.irq_set_type = mvebu_gpio_irq_set_type;
633 ct->chip.name = mvchip->chip.label;
634
635 ct = &gc->chip_types[1];
636 ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
637 ct->chip.irq_ack = mvebu_gpio_irq_ack;
638 ct->chip.irq_mask = mvebu_gpio_edge_irq_mask;
639 ct->chip.irq_unmask = mvebu_gpio_edge_irq_unmask;
640 ct->chip.irq_set_type = mvebu_gpio_irq_set_type;
641 ct->handler = handle_edge_irq;
642 ct->chip.name = mvchip->chip.label;
643
644 irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE,
645 IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
646
647 /* Setup irq domain on top of the generic chip. */
648 mvchip->domain = irq_domain_add_legacy(np, mvchip->chip.ngpio,
649 mvchip->irqbase, 0,
650 &irq_domain_simple_ops,
651 mvchip);
652 if (!mvchip->domain) {
653 dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
654 mvchip->chip.label);
655 irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST,
656 IRQ_LEVEL | IRQ_NOPROBE);
657 kfree(gc);
658 kfree(mvchip->chip.label);
659 return -ENODEV;
660 }
661
662 return 0;
663}
664
665static struct platform_driver mvebu_gpio_driver = {
666 .driver = {
667 .name = "mvebu-gpio",
668 .owner = THIS_MODULE,
669 .of_match_table = mvebu_gpio_of_match,
670 },
671 .probe = mvebu_gpio_probe,
672 .id_table = mvebu_gpio_ids,
673};
674
675static int __init mvebu_gpio_init(void)
676{
677 return platform_driver_register(&mvebu_gpio_driver);
678}
679postcore_initcall(mvebu_gpio_init);
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 54e3588bef62..a75414496369 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -145,6 +145,28 @@ config PINCTRL_COH901
145 COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 145 COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
146 ports of 8 GPIO pins each. 146 ports of 8 GPIO pins each.
147 147
148config PINCTRL_MVEBU
149 bool
150 depends on ARCH_MVEBU
151 select PINMUX
152 select PINCONF
153
154config PINCTRL_DOVE
155 bool
156 select PINCTRL_MVEBU
157
158config PINCTRL_KIRKWOOD
159 bool
160 select PINCTRL_MVEBU
161
162config PINCTRL_ARMADA_370
163 bool
164 select PINCTRL_MVEBU
165
166config PINCTRL_ARMADA_XP
167 bool
168 select PINCTRL_MVEBU
169
148source "drivers/pinctrl/spear/Kconfig" 170source "drivers/pinctrl/spear/Kconfig"
149 171
150endmenu 172endmenu
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f40b1f81ff2c..f2ea0504efc7 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -29,5 +29,10 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
29obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o 29obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
30obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o 30obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
31obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o 31obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
32obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
33obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
34obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
35obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
36obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
32 37
33obj-$(CONFIG_PLAT_SPEAR) += spear/ 38obj-$(CONFIG_PLAT_SPEAR) += spear/
diff --git a/drivers/pinctrl/pinctrl-armada-370.c b/drivers/pinctrl/pinctrl-armada-370.c
new file mode 100644
index 000000000000..c907647de6ad
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-armada-370.c
@@ -0,0 +1,421 @@
1/*
2 * Marvell Armada 370 pinctrl driver based on mvebu pinctrl core
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/clk.h>
20#include <linux/of.h>
21#include <linux/of_device.h>
22#include <linux/pinctrl/pinctrl.h>
23
24#include "pinctrl-mvebu.h"
25
26static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = {
27 MPP_MODE(0,
28 MPP_FUNCTION(0x0, "gpio", NULL),
29 MPP_FUNCTION(0x1, "uart0", "rxd")),
30 MPP_MODE(1,
31 MPP_FUNCTION(0x0, "gpo", NULL),
32 MPP_FUNCTION(0x1, "uart0", "txd")),
33 MPP_MODE(2,
34 MPP_FUNCTION(0x0, "gpio", NULL),
35 MPP_FUNCTION(0x1, "i2c0", "sck"),
36 MPP_FUNCTION(0x2, "uart0", "txd")),
37 MPP_MODE(3,
38 MPP_FUNCTION(0x0, "gpio", NULL),
39 MPP_FUNCTION(0x1, "i2c0", "sda"),
40 MPP_FUNCTION(0x2, "uart0", "rxd")),
41 MPP_MODE(4,
42 MPP_FUNCTION(0x0, "gpio", NULL),
43 MPP_FUNCTION(0x1, "cpu_pd", "vdd")),
44 MPP_MODE(5,
45 MPP_FUNCTION(0x0, "gpo", NULL),
46 MPP_FUNCTION(0x1, "ge0", "txclko"),
47 MPP_FUNCTION(0x2, "uart1", "txd"),
48 MPP_FUNCTION(0x4, "spi1", "clk"),
49 MPP_FUNCTION(0x5, "audio", "mclk")),
50 MPP_MODE(6,
51 MPP_FUNCTION(0x0, "gpio", NULL),
52 MPP_FUNCTION(0x1, "ge0", "txd0"),
53 MPP_FUNCTION(0x2, "sata0", "prsnt"),
54 MPP_FUNCTION(0x4, "tdm", "rst"),
55 MPP_FUNCTION(0x5, "audio", "sdo")),
56 MPP_MODE(7,
57 MPP_FUNCTION(0x0, "gpo", NULL),
58 MPP_FUNCTION(0x1, "ge0", "txd1"),
59 MPP_FUNCTION(0x4, "tdm", "tdx"),
60 MPP_FUNCTION(0x5, "audio", "lrclk")),
61 MPP_MODE(8,
62 MPP_FUNCTION(0x0, "gpio", NULL),
63 MPP_FUNCTION(0x1, "ge0", "txd2"),
64 MPP_FUNCTION(0x2, "uart0", "rts"),
65 MPP_FUNCTION(0x4, "tdm", "drx"),
66 MPP_FUNCTION(0x5, "audio", "bclk")),
67 MPP_MODE(9,
68 MPP_FUNCTION(0x0, "gpo", NULL),
69 MPP_FUNCTION(0x1, "ge0", "txd3"),
70 MPP_FUNCTION(0x2, "uart1", "txd"),
71 MPP_FUNCTION(0x3, "sd0", "clk"),
72 MPP_FUNCTION(0x5, "audio", "spdifo")),
73 MPP_MODE(10,
74 MPP_FUNCTION(0x0, "gpio", NULL),
75 MPP_FUNCTION(0x1, "ge0", "txctl"),
76 MPP_FUNCTION(0x2, "uart0", "cts"),
77 MPP_FUNCTION(0x4, "tdm", "fsync"),
78 MPP_FUNCTION(0x5, "audio", "sdi")),
79 MPP_MODE(11,
80 MPP_FUNCTION(0x0, "gpio", NULL),
81 MPP_FUNCTION(0x1, "ge0", "rxd0"),
82 MPP_FUNCTION(0x2, "uart1", "rxd"),
83 MPP_FUNCTION(0x3, "sd0", "cmd"),
84 MPP_FUNCTION(0x4, "spi0", "cs1"),
85 MPP_FUNCTION(0x5, "sata1", "prsnt"),
86 MPP_FUNCTION(0x6, "spi1", "cs1")),
87 MPP_MODE(12,
88 MPP_FUNCTION(0x0, "gpio", NULL),
89 MPP_FUNCTION(0x1, "ge0", "rxd1"),
90 MPP_FUNCTION(0x2, "i2c1", "sda"),
91 MPP_FUNCTION(0x3, "sd0", "d0"),
92 MPP_FUNCTION(0x4, "spi1", "cs0"),
93 MPP_FUNCTION(0x5, "audio", "spdifi")),
94 MPP_MODE(13,
95 MPP_FUNCTION(0x0, "gpio", NULL),
96 MPP_FUNCTION(0x1, "ge0", "rxd2"),
97 MPP_FUNCTION(0x2, "i2c1", "sck"),
98 MPP_FUNCTION(0x3, "sd0", "d1"),
99 MPP_FUNCTION(0x4, "tdm", "pclk"),
100 MPP_FUNCTION(0x5, "audio", "rmclk")),
101 MPP_MODE(14,
102 MPP_FUNCTION(0x0, "gpio", NULL),
103 MPP_FUNCTION(0x1, "ge0", "rxd3"),
104 MPP_FUNCTION(0x2, "pcie", "clkreq0"),
105 MPP_FUNCTION(0x3, "sd0", "d2"),
106 MPP_FUNCTION(0x4, "spi1", "mosi"),
107 MPP_FUNCTION(0x5, "spi0", "cs2")),
108 MPP_MODE(15,
109 MPP_FUNCTION(0x0, "gpio", NULL),
110 MPP_FUNCTION(0x1, "ge0", "rxctl"),
111 MPP_FUNCTION(0x2, "pcie", "clkreq1"),
112 MPP_FUNCTION(0x3, "sd0", "d3"),
113 MPP_FUNCTION(0x4, "spi1", "miso"),
114 MPP_FUNCTION(0x5, "spi0", "cs3")),
115 MPP_MODE(16,
116 MPP_FUNCTION(0x0, "gpio", NULL),
117 MPP_FUNCTION(0x1, "ge0", "rxclk"),
118 MPP_FUNCTION(0x2, "uart1", "rxd"),
119 MPP_FUNCTION(0x4, "tdm", "int"),
120 MPP_FUNCTION(0x5, "audio", "extclk")),
121 MPP_MODE(17,
122 MPP_FUNCTION(0x0, "gpo", NULL),
123 MPP_FUNCTION(0x1, "ge", "mdc")),
124 MPP_MODE(18,
125 MPP_FUNCTION(0x0, "gpio", NULL),
126 MPP_FUNCTION(0x1, "ge", "mdio")),
127 MPP_MODE(19,
128 MPP_FUNCTION(0x0, "gpio", NULL),
129 MPP_FUNCTION(0x1, "ge0", "txclk"),
130 MPP_FUNCTION(0x2, "ge1", "txclkout"),
131 MPP_FUNCTION(0x4, "tdm", "pclk")),
132 MPP_MODE(20,
133 MPP_FUNCTION(0x0, "gpo", NULL),
134 MPP_FUNCTION(0x1, "ge0", "txd4"),
135 MPP_FUNCTION(0x2, "ge1", "txd0")),
136 MPP_MODE(21,
137 MPP_FUNCTION(0x0, "gpo", NULL),
138 MPP_FUNCTION(0x1, "ge0", "txd5"),
139 MPP_FUNCTION(0x2, "ge1", "txd1"),
140 MPP_FUNCTION(0x4, "uart1", "txd")),
141 MPP_MODE(22,
142 MPP_FUNCTION(0x0, "gpo", NULL),
143 MPP_FUNCTION(0x1, "ge0", "txd6"),
144 MPP_FUNCTION(0x2, "ge1", "txd2"),
145 MPP_FUNCTION(0x4, "uart0", "rts")),
146 MPP_MODE(23,
147 MPP_FUNCTION(0x0, "gpo", NULL),
148 MPP_FUNCTION(0x1, "ge0", "txd7"),
149 MPP_FUNCTION(0x2, "ge1", "txd3"),
150 MPP_FUNCTION(0x4, "spi1", "mosi")),
151 MPP_MODE(24,
152 MPP_FUNCTION(0x0, "gpio", NULL),
153 MPP_FUNCTION(0x1, "ge0", "col"),
154 MPP_FUNCTION(0x2, "ge1", "txctl"),
155 MPP_FUNCTION(0x4, "spi1", "cs0")),
156 MPP_MODE(25,
157 MPP_FUNCTION(0x0, "gpio", NULL),
158 MPP_FUNCTION(0x1, "ge0", "rxerr"),
159 MPP_FUNCTION(0x2, "ge1", "rxd0"),
160 MPP_FUNCTION(0x4, "uart1", "rxd")),
161 MPP_MODE(26,
162 MPP_FUNCTION(0x0, "gpio", NULL),
163 MPP_FUNCTION(0x1, "ge0", "crs"),
164 MPP_FUNCTION(0x2, "ge1", "rxd1"),
165 MPP_FUNCTION(0x4, "spi1", "miso")),
166 MPP_MODE(27,
167 MPP_FUNCTION(0x0, "gpio", NULL),
168 MPP_FUNCTION(0x1, "ge0", "rxd4"),
169 MPP_FUNCTION(0x2, "ge1", "rxd2"),
170 MPP_FUNCTION(0x4, "uart0", "cts")),
171 MPP_MODE(28,
172 MPP_FUNCTION(0x0, "gpio", NULL),
173 MPP_FUNCTION(0x1, "ge0", "rxd5"),
174 MPP_FUNCTION(0x2, "ge1", "rxd3")),
175 MPP_MODE(29,
176 MPP_FUNCTION(0x0, "gpio", NULL),
177 MPP_FUNCTION(0x1, "ge0", "rxd6"),
178 MPP_FUNCTION(0x2, "ge1", "rxctl"),
179 MPP_FUNCTION(0x4, "i2c1", "sda")),
180 MPP_MODE(30,
181 MPP_FUNCTION(0x0, "gpio", NULL),
182 MPP_FUNCTION(0x1, "ge0", "rxd7"),
183 MPP_FUNCTION(0x2, "ge1", "rxclk"),
184 MPP_FUNCTION(0x4, "i2c1", "sck")),
185 MPP_MODE(31,
186 MPP_FUNCTION(0x0, "gpio", NULL),
187 MPP_FUNCTION(0x3, "tclk", NULL),
188 MPP_FUNCTION(0x4, "ge0", "txerr")),
189 MPP_MODE(32,
190 MPP_FUNCTION(0x0, "gpio", NULL),
191 MPP_FUNCTION(0x1, "spi0", "cs0")),
192 MPP_MODE(33,
193 MPP_FUNCTION(0x0, "gpio", NULL),
194 MPP_FUNCTION(0x1, "dev", "bootcs"),
195 MPP_FUNCTION(0x2, "spi0", "cs0")),
196 MPP_MODE(34,
197 MPP_FUNCTION(0x0, "gpo", NULL),
198 MPP_FUNCTION(0x1, "dev", "wen0"),
199 MPP_FUNCTION(0x2, "spi0", "mosi")),
200 MPP_MODE(35,
201 MPP_FUNCTION(0x0, "gpo", NULL),
202 MPP_FUNCTION(0x1, "dev", "oen"),
203 MPP_FUNCTION(0x2, "spi0", "sck")),
204 MPP_MODE(36,
205 MPP_FUNCTION(0x0, "gpo", NULL),
206 MPP_FUNCTION(0x1, "dev", "a1"),
207 MPP_FUNCTION(0x2, "spi0", "miso")),
208 MPP_MODE(37,
209 MPP_FUNCTION(0x0, "gpo", NULL),
210 MPP_FUNCTION(0x1, "dev", "a0"),
211 MPP_FUNCTION(0x2, "sata0", "prsnt")),
212 MPP_MODE(38,
213 MPP_FUNCTION(0x0, "gpio", NULL),
214 MPP_FUNCTION(0x1, "dev", "ready"),
215 MPP_FUNCTION(0x2, "uart1", "cts"),
216 MPP_FUNCTION(0x3, "uart0", "cts")),
217 MPP_MODE(39,
218 MPP_FUNCTION(0x0, "gpo", NULL),
219 MPP_FUNCTION(0x1, "dev", "ad0"),
220 MPP_FUNCTION(0x2, "audio", "spdifo")),
221 MPP_MODE(40,
222 MPP_FUNCTION(0x0, "gpio", NULL),
223 MPP_FUNCTION(0x1, "dev", "ad1"),
224 MPP_FUNCTION(0x2, "uart1", "rts"),
225 MPP_FUNCTION(0x3, "uart0", "rts")),
226 MPP_MODE(41,
227 MPP_FUNCTION(0x0, "gpio", NULL),
228 MPP_FUNCTION(0x1, "dev", "ad2"),
229 MPP_FUNCTION(0x2, "uart1", "rxd")),
230 MPP_MODE(42,
231 MPP_FUNCTION(0x0, "gpo", NULL),
232 MPP_FUNCTION(0x1, "dev", "ad3"),
233 MPP_FUNCTION(0x2, "uart1", "txd")),
234 MPP_MODE(43,
235 MPP_FUNCTION(0x0, "gpo", NULL),
236 MPP_FUNCTION(0x1, "dev", "ad4"),
237 MPP_FUNCTION(0x2, "audio", "bclk")),
238 MPP_MODE(44,
239 MPP_FUNCTION(0x0, "gpo", NULL),
240 MPP_FUNCTION(0x1, "dev", "ad5"),
241 MPP_FUNCTION(0x2, "audio", "mclk")),
242 MPP_MODE(45,
243 MPP_FUNCTION(0x0, "gpo", NULL),
244 MPP_FUNCTION(0x1, "dev", "ad6"),
245 MPP_FUNCTION(0x2, "audio", "lrclk")),
246 MPP_MODE(46,
247 MPP_FUNCTION(0x0, "gpo", NULL),
248 MPP_FUNCTION(0x1, "dev", "ad7"),
249 MPP_FUNCTION(0x2, "audio", "sdo")),
250 MPP_MODE(47,
251 MPP_FUNCTION(0x0, "gpo", NULL),
252 MPP_FUNCTION(0x1, "dev", "ad8"),
253 MPP_FUNCTION(0x3, "sd0", "clk"),
254 MPP_FUNCTION(0x5, "audio", "spdifo")),
255 MPP_MODE(48,
256 MPP_FUNCTION(0x0, "gpio", NULL),
257 MPP_FUNCTION(0x1, "dev", "ad9"),
258 MPP_FUNCTION(0x2, "uart0", "rts"),
259 MPP_FUNCTION(0x3, "sd0", "cmd"),
260 MPP_FUNCTION(0x4, "sata1", "prsnt"),
261 MPP_FUNCTION(0x5, "spi0", "cs1")),
262 MPP_MODE(49,
263 MPP_FUNCTION(0x0, "gpio", NULL),
264 MPP_FUNCTION(0x1, "dev", "ad10"),
265 MPP_FUNCTION(0x2, "pcie", "clkreq1"),
266 MPP_FUNCTION(0x3, "sd0", "d0"),
267 MPP_FUNCTION(0x4, "spi1", "cs0"),
268 MPP_FUNCTION(0x5, "audio", "spdifi")),
269 MPP_MODE(50,
270 MPP_FUNCTION(0x0, "gpio", NULL),
271 MPP_FUNCTION(0x1, "dev", "ad11"),
272 MPP_FUNCTION(0x2, "uart0", "cts"),
273 MPP_FUNCTION(0x3, "sd0", "d1"),
274 MPP_FUNCTION(0x4, "spi1", "miso"),
275 MPP_FUNCTION(0x5, "audio", "rmclk")),
276 MPP_MODE(51,
277 MPP_FUNCTION(0x0, "gpio", NULL),
278 MPP_FUNCTION(0x1, "dev", "ad12"),
279 MPP_FUNCTION(0x2, "i2c1", "sda"),
280 MPP_FUNCTION(0x3, "sd0", "d2"),
281 MPP_FUNCTION(0x4, "spi1", "mosi")),
282 MPP_MODE(52,
283 MPP_FUNCTION(0x0, "gpio", NULL),
284 MPP_FUNCTION(0x1, "dev", "ad13"),
285 MPP_FUNCTION(0x2, "i2c1", "sck"),
286 MPP_FUNCTION(0x3, "sd0", "d3"),
287 MPP_FUNCTION(0x4, "spi1", "sck")),
288 MPP_MODE(53,
289 MPP_FUNCTION(0x0, "gpio", NULL),
290 MPP_FUNCTION(0x1, "dev", "ad14"),
291 MPP_FUNCTION(0x2, "sd0", "clk"),
292 MPP_FUNCTION(0x3, "tdm", "pclk"),
293 MPP_FUNCTION(0x4, "spi0", "cs2"),
294 MPP_FUNCTION(0x5, "pcie", "clkreq1")),
295 MPP_MODE(54,
296 MPP_FUNCTION(0x0, "gpo", NULL),
297 MPP_FUNCTION(0x1, "dev", "ad15"),
298 MPP_FUNCTION(0x3, "tdm", "dtx")),
299 MPP_MODE(55,
300 MPP_FUNCTION(0x0, "gpio", NULL),
301 MPP_FUNCTION(0x1, "dev", "cs1"),
302 MPP_FUNCTION(0x2, "uart1", "txd"),
303 MPP_FUNCTION(0x3, "tdm", "rst"),
304 MPP_FUNCTION(0x4, "sata1", "prsnt"),
305 MPP_FUNCTION(0x5, "sata0", "prsnt")),
306 MPP_MODE(56,
307 MPP_FUNCTION(0x0, "gpio", NULL),
308 MPP_FUNCTION(0x1, "dev", "cs2"),
309 MPP_FUNCTION(0x2, "uart1", "cts"),
310 MPP_FUNCTION(0x3, "uart0", "cts"),
311 MPP_FUNCTION(0x4, "spi0", "cs3"),
312 MPP_FUNCTION(0x5, "pcie", "clkreq0"),
313 MPP_FUNCTION(0x6, "spi1", "cs1")),
314 MPP_MODE(57,
315 MPP_FUNCTION(0x0, "gpio", NULL),
316 MPP_FUNCTION(0x1, "dev", "cs3"),
317 MPP_FUNCTION(0x2, "uart1", "rxd"),
318 MPP_FUNCTION(0x3, "tdm", "fsync"),
319 MPP_FUNCTION(0x4, "sata0", "prsnt"),
320 MPP_FUNCTION(0x5, "audio", "sdo")),
321 MPP_MODE(58,
322 MPP_FUNCTION(0x0, "gpio", NULL),
323 MPP_FUNCTION(0x1, "dev", "cs0"),
324 MPP_FUNCTION(0x2, "uart1", "rts"),
325 MPP_FUNCTION(0x3, "tdm", "int"),
326 MPP_FUNCTION(0x5, "audio", "extclk"),
327 MPP_FUNCTION(0x6, "uart0", "rts")),
328 MPP_MODE(59,
329 MPP_FUNCTION(0x0, "gpo", NULL),
330 MPP_FUNCTION(0x1, "dev", "ale0"),
331 MPP_FUNCTION(0x2, "uart1", "rts"),
332 MPP_FUNCTION(0x3, "uart0", "rts"),
333 MPP_FUNCTION(0x5, "audio", "bclk")),
334 MPP_MODE(60,
335 MPP_FUNCTION(0x0, "gpio", NULL),
336 MPP_FUNCTION(0x1, "dev", "ale1"),
337 MPP_FUNCTION(0x2, "uart1", "rxd"),
338 MPP_FUNCTION(0x3, "sata0", "prsnt"),
339 MPP_FUNCTION(0x4, "pcie", "rst-out"),
340 MPP_FUNCTION(0x5, "audio", "sdi")),
341 MPP_MODE(61,
342 MPP_FUNCTION(0x0, "gpo", NULL),
343 MPP_FUNCTION(0x1, "dev", "wen1"),
344 MPP_FUNCTION(0x2, "uart1", "txd"),
345 MPP_FUNCTION(0x5, "audio", "rclk")),
346 MPP_MODE(62,
347 MPP_FUNCTION(0x0, "gpio", NULL),
348 MPP_FUNCTION(0x1, "dev", "a2"),
349 MPP_FUNCTION(0x2, "uart1", "cts"),
350 MPP_FUNCTION(0x3, "tdm", "drx"),
351 MPP_FUNCTION(0x4, "pcie", "clkreq0"),
352 MPP_FUNCTION(0x5, "audio", "mclk"),
353 MPP_FUNCTION(0x6, "uart0", "cts")),
354 MPP_MODE(63,
355 MPP_FUNCTION(0x0, "gpo", NULL),
356 MPP_FUNCTION(0x1, "spi0", "sck"),
357 MPP_FUNCTION(0x2, "tclk", NULL)),
358 MPP_MODE(64,
359 MPP_FUNCTION(0x0, "gpio", NULL),
360 MPP_FUNCTION(0x1, "spi0", "miso"),
361 MPP_FUNCTION(0x2, "spi0-1", "cs1")),
362 MPP_MODE(65,
363 MPP_FUNCTION(0x0, "gpio", NULL),
364 MPP_FUNCTION(0x1, "spi0", "mosi"),
365 MPP_FUNCTION(0x2, "spi0-1", "cs2")),
366};
367
368static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info;
369
370static struct of_device_id armada_370_pinctrl_of_match[] __devinitdata = {
371 { .compatible = "marvell,mv88f6710-pinctrl" },
372 { },
373};
374
375static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = {
376 MPP_REG_CTRL(0, 65),
377};
378
379static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
380 MPP_GPIO_RANGE(0, 0, 0, 32),
381 MPP_GPIO_RANGE(1, 32, 32, 32),
382 MPP_GPIO_RANGE(2, 64, 64, 2),
383};
384
385static int __devinit armada_370_pinctrl_probe(struct platform_device *pdev)
386{
387 struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info;
388
389 soc->variant = 0; /* no variants for Armada 370 */
390 soc->controls = mv88f6710_mpp_controls;
391 soc->ncontrols = ARRAY_SIZE(mv88f6710_mpp_controls);
392 soc->modes = mv88f6710_mpp_modes;
393 soc->nmodes = ARRAY_SIZE(mv88f6710_mpp_modes);
394 soc->gpioranges = mv88f6710_mpp_gpio_ranges;
395 soc->ngpioranges = ARRAY_SIZE(mv88f6710_mpp_gpio_ranges);
396
397 pdev->dev.platform_data = soc;
398
399 return mvebu_pinctrl_probe(pdev);
400}
401
402static int __devexit armada_370_pinctrl_remove(struct platform_device *pdev)
403{
404 return mvebu_pinctrl_remove(pdev);
405}
406
407static struct platform_driver armada_370_pinctrl_driver = {
408 .driver = {
409 .name = "armada-370-pinctrl",
410 .owner = THIS_MODULE,
411 .of_match_table = of_match_ptr(armada_370_pinctrl_of_match),
412 },
413 .probe = armada_370_pinctrl_probe,
414 .remove = __devexit_p(armada_370_pinctrl_remove),
415};
416
417module_platform_driver(armada_370_pinctrl_driver);
418
419MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
420MODULE_DESCRIPTION("Marvell Armada 370 pinctrl driver");
421MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-armada-xp.c b/drivers/pinctrl/pinctrl-armada-xp.c
new file mode 100644
index 000000000000..40bd52a46b4e
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-armada-xp.c
@@ -0,0 +1,468 @@
1/*
2 * Marvell Armada XP pinctrl driver based on mvebu pinctrl core
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This file supports the three variants of Armada XP SoCs that are
14 * available: mv78230, mv78260 and mv78460. From a pin muxing
15 * perspective, the mv78230 has 49 MPP pins. The mv78260 and mv78460
16 * both have 67 MPP pins (more GPIOs and address lines for the memory
17 * bus mainly). The only difference between the mv78260 and the
18 * mv78460 in terms of pin muxing is the addition of two functions on
19 * pins 43 and 56 to access the VDD of the CPU2 and 3 (mv78260 has two
20 * cores, mv78460 has four cores).
21 */
22
23#include <linux/err.h>
24#include <linux/init.h>
25#include <linux/io.h>
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/clk.h>
29#include <linux/of.h>
30#include <linux/of_device.h>
31#include <linux/pinctrl/pinctrl.h>
32#include <linux/bitops.h>
33
34#include "pinctrl-mvebu.h"
35
36enum armada_xp_variant {
37 V_MV78230 = BIT(0),
38 V_MV78260 = BIT(1),
39 V_MV78460 = BIT(2),
40 V_MV78230_PLUS = (V_MV78230 | V_MV78260 | V_MV78460),
41 V_MV78260_PLUS = (V_MV78260 | V_MV78460),
42};
43
44static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
45 MPP_MODE(0,
46 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
47 MPP_VAR_FUNCTION(0x1, "ge0", "txclko", V_MV78230_PLUS),
48 MPP_VAR_FUNCTION(0x4, "lcd", "d0", V_MV78230_PLUS)),
49 MPP_MODE(1,
50 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
51 MPP_VAR_FUNCTION(0x1, "ge0", "txd0", V_MV78230_PLUS),
52 MPP_VAR_FUNCTION(0x4, "lcd", "d1", V_MV78230_PLUS)),
53 MPP_MODE(2,
54 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
55 MPP_VAR_FUNCTION(0x1, "ge0", "txd1", V_MV78230_PLUS),
56 MPP_VAR_FUNCTION(0x4, "lcd", "d2", V_MV78230_PLUS)),
57 MPP_MODE(3,
58 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
59 MPP_VAR_FUNCTION(0x1, "ge0", "txd2", V_MV78230_PLUS),
60 MPP_VAR_FUNCTION(0x4, "lcd", "d3", V_MV78230_PLUS)),
61 MPP_MODE(4,
62 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
63 MPP_VAR_FUNCTION(0x1, "ge0", "txd3", V_MV78230_PLUS),
64 MPP_VAR_FUNCTION(0x4, "lcd", "d4", V_MV78230_PLUS)),
65 MPP_MODE(5,
66 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
67 MPP_VAR_FUNCTION(0x1, "ge0", "txctl", V_MV78230_PLUS),
68 MPP_VAR_FUNCTION(0x4, "lcd", "d5", V_MV78230_PLUS)),
69 MPP_MODE(6,
70 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
71 MPP_VAR_FUNCTION(0x1, "ge0", "rxd0", V_MV78230_PLUS),
72 MPP_VAR_FUNCTION(0x4, "lcd", "d6", V_MV78230_PLUS)),
73 MPP_MODE(7,
74 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
75 MPP_VAR_FUNCTION(0x1, "ge0", "rxd1", V_MV78230_PLUS),
76 MPP_VAR_FUNCTION(0x4, "lcd", "d7", V_MV78230_PLUS)),
77 MPP_MODE(8,
78 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
79 MPP_VAR_FUNCTION(0x1, "ge0", "rxd2", V_MV78230_PLUS),
80 MPP_VAR_FUNCTION(0x4, "lcd", "d8", V_MV78230_PLUS)),
81 MPP_MODE(9,
82 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
83 MPP_VAR_FUNCTION(0x1, "ge0", "rxd3", V_MV78230_PLUS),
84 MPP_VAR_FUNCTION(0x4, "lcd", "d9", V_MV78230_PLUS)),
85 MPP_MODE(10,
86 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
87 MPP_VAR_FUNCTION(0x1, "ge0", "rxctl", V_MV78230_PLUS),
88 MPP_VAR_FUNCTION(0x4, "lcd", "d10", V_MV78230_PLUS)),
89 MPP_MODE(11,
90 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
91 MPP_VAR_FUNCTION(0x1, "ge0", "rxclk", V_MV78230_PLUS),
92 MPP_VAR_FUNCTION(0x4, "lcd", "d11", V_MV78230_PLUS)),
93 MPP_MODE(12,
94 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
95 MPP_VAR_FUNCTION(0x1, "ge0", "txd4", V_MV78230_PLUS),
96 MPP_VAR_FUNCTION(0x2, "ge1", "clkout", V_MV78230_PLUS),
97 MPP_VAR_FUNCTION(0x4, "lcd", "d12", V_MV78230_PLUS)),
98 MPP_MODE(13,
99 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
100 MPP_VAR_FUNCTION(0x1, "ge0", "txd5", V_MV78230_PLUS),
101 MPP_VAR_FUNCTION(0x2, "ge1", "txd0", V_MV78230_PLUS),
102 MPP_VAR_FUNCTION(0x4, "lcd", "d13", V_MV78230_PLUS)),
103 MPP_MODE(14,
104 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
105 MPP_VAR_FUNCTION(0x1, "ge0", "txd6", V_MV78230_PLUS),
106 MPP_VAR_FUNCTION(0x2, "ge1", "txd1", V_MV78230_PLUS),
107 MPP_VAR_FUNCTION(0x4, "lcd", "d14", V_MV78230_PLUS)),
108 MPP_MODE(15,
109 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
110 MPP_VAR_FUNCTION(0x1, "ge0", "txd7", V_MV78230_PLUS),
111 MPP_VAR_FUNCTION(0x2, "ge1", "txd2", V_MV78230_PLUS),
112 MPP_VAR_FUNCTION(0x4, "lcd", "d15", V_MV78230_PLUS)),
113 MPP_MODE(16,
114 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
115 MPP_VAR_FUNCTION(0x1, "ge0", "txclk", V_MV78230_PLUS),
116 MPP_VAR_FUNCTION(0x2, "ge1", "txd3", V_MV78230_PLUS),
117 MPP_VAR_FUNCTION(0x4, "lcd", "d16", V_MV78230_PLUS)),
118 MPP_MODE(17,
119 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
120 MPP_VAR_FUNCTION(0x1, "ge0", "col", V_MV78230_PLUS),
121 MPP_VAR_FUNCTION(0x2, "ge1", "txctl", V_MV78230_PLUS),
122 MPP_VAR_FUNCTION(0x4, "lcd", "d17", V_MV78230_PLUS)),
123 MPP_MODE(18,
124 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
125 MPP_VAR_FUNCTION(0x1, "ge0", "rxerr", V_MV78230_PLUS),
126 MPP_VAR_FUNCTION(0x2, "ge1", "rxd0", V_MV78230_PLUS),
127 MPP_VAR_FUNCTION(0x3, "ptp", "trig", V_MV78230_PLUS),
128 MPP_VAR_FUNCTION(0x4, "lcd", "d18", V_MV78230_PLUS)),
129 MPP_MODE(19,
130 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
131 MPP_VAR_FUNCTION(0x1, "ge0", "crs", V_MV78230_PLUS),
132 MPP_VAR_FUNCTION(0x2, "ge1", "rxd1", V_MV78230_PLUS),
133 MPP_VAR_FUNCTION(0x3, "ptp", "evreq", V_MV78230_PLUS),
134 MPP_VAR_FUNCTION(0x4, "lcd", "d19", V_MV78230_PLUS)),
135 MPP_MODE(20,
136 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
137 MPP_VAR_FUNCTION(0x1, "ge0", "rxd4", V_MV78230_PLUS),
138 MPP_VAR_FUNCTION(0x2, "ge1", "rxd2", V_MV78230_PLUS),
139 MPP_VAR_FUNCTION(0x3, "ptp", "clk", V_MV78230_PLUS),
140 MPP_VAR_FUNCTION(0x4, "lcd", "d20", V_MV78230_PLUS)),
141 MPP_MODE(21,
142 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
143 MPP_VAR_FUNCTION(0x1, "ge0", "rxd5", V_MV78230_PLUS),
144 MPP_VAR_FUNCTION(0x2, "ge1", "rxd3", V_MV78230_PLUS),
145 MPP_VAR_FUNCTION(0x3, "mem", "bat", V_MV78230_PLUS),
146 MPP_VAR_FUNCTION(0x4, "lcd", "d21", V_MV78230_PLUS)),
147 MPP_MODE(22,
148 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
149 MPP_VAR_FUNCTION(0x1, "ge0", "rxd6", V_MV78230_PLUS),
150 MPP_VAR_FUNCTION(0x2, "ge1", "rxctl", V_MV78230_PLUS),
151 MPP_VAR_FUNCTION(0x3, "sata0", "prsnt", V_MV78230_PLUS),
152 MPP_VAR_FUNCTION(0x4, "lcd", "d22", V_MV78230_PLUS)),
153 MPP_MODE(23,
154 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
155 MPP_VAR_FUNCTION(0x1, "ge0", "rxd7", V_MV78230_PLUS),
156 MPP_VAR_FUNCTION(0x2, "ge1", "rxclk", V_MV78230_PLUS),
157 MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS),
158 MPP_VAR_FUNCTION(0x4, "lcd", "d23", V_MV78230_PLUS)),
159 MPP_MODE(24,
160 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
161 MPP_VAR_FUNCTION(0x1, "sata1", "prsnt", V_MV78230_PLUS),
162 MPP_VAR_FUNCTION(0x2, "nf", "bootcs-re", V_MV78230_PLUS),
163 MPP_VAR_FUNCTION(0x3, "tdm", "rst", V_MV78230_PLUS),
164 MPP_VAR_FUNCTION(0x4, "lcd", "hsync", V_MV78230_PLUS)),
165 MPP_MODE(25,
166 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
167 MPP_VAR_FUNCTION(0x1, "sata0", "prsnt", V_MV78230_PLUS),
168 MPP_VAR_FUNCTION(0x2, "nf", "bootcs-we", V_MV78230_PLUS),
169 MPP_VAR_FUNCTION(0x3, "tdm", "pclk", V_MV78230_PLUS),
170 MPP_VAR_FUNCTION(0x4, "lcd", "vsync", V_MV78230_PLUS)),
171 MPP_MODE(26,
172 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
173 MPP_VAR_FUNCTION(0x3, "tdm", "fsync", V_MV78230_PLUS),
174 MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS),
175 MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)),
176 MPP_MODE(27,
177 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
178 MPP_VAR_FUNCTION(0x1, "ptp", "trig", V_MV78230_PLUS),
179 MPP_VAR_FUNCTION(0x3, "tdm", "dtx", V_MV78230_PLUS),
180 MPP_VAR_FUNCTION(0x4, "lcd", "e", V_MV78230_PLUS)),
181 MPP_MODE(28,
182 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
183 MPP_VAR_FUNCTION(0x1, "ptp", "evreq", V_MV78230_PLUS),
184 MPP_VAR_FUNCTION(0x3, "tdm", "drx", V_MV78230_PLUS),
185 MPP_VAR_FUNCTION(0x4, "lcd", "pwm", V_MV78230_PLUS)),
186 MPP_MODE(29,
187 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
188 MPP_VAR_FUNCTION(0x1, "ptp", "clk", V_MV78230_PLUS),
189 MPP_VAR_FUNCTION(0x3, "tdm", "int0", V_MV78230_PLUS),
190 MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS),
191 MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
192 MPP_MODE(30,
193 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
194 MPP_VAR_FUNCTION(0x1, "sd0", "clk", V_MV78230_PLUS),
195 MPP_VAR_FUNCTION(0x3, "tdm", "int1", V_MV78230_PLUS)),
196 MPP_MODE(31,
197 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
198 MPP_VAR_FUNCTION(0x1, "sd0", "cmd", V_MV78230_PLUS),
199 MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS),
200 MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
201 MPP_MODE(32,
202 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
203 MPP_VAR_FUNCTION(0x1, "sd0", "d0", V_MV78230_PLUS),
204 MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS),
205 MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)),
206 MPP_MODE(33,
207 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
208 MPP_VAR_FUNCTION(0x1, "sd0", "d1", V_MV78230_PLUS),
209 MPP_VAR_FUNCTION(0x3, "tdm", "int4", V_MV78230_PLUS),
210 MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS)),
211 MPP_MODE(34,
212 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
213 MPP_VAR_FUNCTION(0x1, "sd0", "d2", V_MV78230_PLUS),
214 MPP_VAR_FUNCTION(0x2, "sata0", "prsnt", V_MV78230_PLUS),
215 MPP_VAR_FUNCTION(0x3, "tdm", "int5", V_MV78230_PLUS)),
216 MPP_MODE(35,
217 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
218 MPP_VAR_FUNCTION(0x1, "sd0", "d3", V_MV78230_PLUS),
219 MPP_VAR_FUNCTION(0x2, "sata1", "prsnt", V_MV78230_PLUS),
220 MPP_VAR_FUNCTION(0x3, "tdm", "int6", V_MV78230_PLUS)),
221 MPP_MODE(36,
222 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
223 MPP_VAR_FUNCTION(0x1, "spi", "mosi", V_MV78230_PLUS)),
224 MPP_MODE(37,
225 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
226 MPP_VAR_FUNCTION(0x1, "spi", "miso", V_MV78230_PLUS)),
227 MPP_MODE(38,
228 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
229 MPP_VAR_FUNCTION(0x1, "spi", "sck", V_MV78230_PLUS)),
230 MPP_MODE(39,
231 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
232 MPP_VAR_FUNCTION(0x1, "spi", "cs0", V_MV78230_PLUS)),
233 MPP_MODE(40,
234 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
235 MPP_VAR_FUNCTION(0x1, "spi", "cs1", V_MV78230_PLUS),
236 MPP_VAR_FUNCTION(0x2, "uart2", "cts", V_MV78230_PLUS),
237 MPP_VAR_FUNCTION(0x3, "vdd", "cpu1-pd", V_MV78230_PLUS),
238 MPP_VAR_FUNCTION(0x4, "lcd", "vga-hsync", V_MV78230_PLUS),
239 MPP_VAR_FUNCTION(0x5, "pcie", "clkreq0", V_MV78230_PLUS)),
240 MPP_MODE(41,
241 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
242 MPP_VAR_FUNCTION(0x1, "spi", "cs2", V_MV78230_PLUS),
243 MPP_VAR_FUNCTION(0x2, "uart2", "rts", V_MV78230_PLUS),
244 MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS),
245 MPP_VAR_FUNCTION(0x4, "lcd", "vga-vsync", V_MV78230_PLUS),
246 MPP_VAR_FUNCTION(0x5, "pcie", "clkreq1", V_MV78230_PLUS)),
247 MPP_MODE(42,
248 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
249 MPP_VAR_FUNCTION(0x1, "uart2", "rxd", V_MV78230_PLUS),
250 MPP_VAR_FUNCTION(0x2, "uart0", "cts", V_MV78230_PLUS),
251 MPP_VAR_FUNCTION(0x3, "tdm", "int7", V_MV78230_PLUS),
252 MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS),
253 MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
254 MPP_MODE(43,
255 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
256 MPP_VAR_FUNCTION(0x1, "uart2", "txd", V_MV78230_PLUS),
257 MPP_VAR_FUNCTION(0x2, "uart0", "rts", V_MV78230_PLUS),
258 MPP_VAR_FUNCTION(0x3, "spi", "cs3", V_MV78230_PLUS),
259 MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS),
260 MPP_VAR_FUNCTION(0x5, "vdd", "cpu2-3-pd", V_MV78460)),
261 MPP_MODE(44,
262 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
263 MPP_VAR_FUNCTION(0x1, "uart2", "cts", V_MV78230_PLUS),
264 MPP_VAR_FUNCTION(0x2, "uart3", "rxd", V_MV78230_PLUS),
265 MPP_VAR_FUNCTION(0x3, "spi", "cs4", V_MV78230_PLUS),
266 MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS),
267 MPP_VAR_FUNCTION(0x5, "pcie", "clkreq2", V_MV78230_PLUS)),
268 MPP_MODE(45,
269 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
270 MPP_VAR_FUNCTION(0x1, "uart2", "rts", V_MV78230_PLUS),
271 MPP_VAR_FUNCTION(0x2, "uart3", "txd", V_MV78230_PLUS),
272 MPP_VAR_FUNCTION(0x3, "spi", "cs5", V_MV78230_PLUS),
273 MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V_MV78230_PLUS)),
274 MPP_MODE(46,
275 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
276 MPP_VAR_FUNCTION(0x1, "uart3", "rts", V_MV78230_PLUS),
277 MPP_VAR_FUNCTION(0x2, "uart1", "rts", V_MV78230_PLUS),
278 MPP_VAR_FUNCTION(0x3, "spi", "cs6", V_MV78230_PLUS),
279 MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V_MV78230_PLUS)),
280 MPP_MODE(47,
281 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
282 MPP_VAR_FUNCTION(0x1, "uart3", "cts", V_MV78230_PLUS),
283 MPP_VAR_FUNCTION(0x2, "uart1", "cts", V_MV78230_PLUS),
284 MPP_VAR_FUNCTION(0x3, "spi", "cs7", V_MV78230_PLUS),
285 MPP_VAR_FUNCTION(0x4, "ref", "clkout", V_MV78230_PLUS),
286 MPP_VAR_FUNCTION(0x5, "pcie", "clkreq3", V_MV78230_PLUS)),
287 MPP_MODE(48,
288 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
289 MPP_VAR_FUNCTION(0x1, "tclk", NULL, V_MV78230_PLUS),
290 MPP_VAR_FUNCTION(0x2, "dev", "burst/last", V_MV78230_PLUS)),
291 MPP_MODE(49,
292 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
293 MPP_VAR_FUNCTION(0x1, "dev", "we3", V_MV78260_PLUS)),
294 MPP_MODE(50,
295 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
296 MPP_VAR_FUNCTION(0x1, "dev", "we2", V_MV78260_PLUS)),
297 MPP_MODE(51,
298 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
299 MPP_VAR_FUNCTION(0x1, "dev", "ad16", V_MV78260_PLUS)),
300 MPP_MODE(52,
301 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
302 MPP_VAR_FUNCTION(0x1, "dev", "ad17", V_MV78260_PLUS)),
303 MPP_MODE(53,
304 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
305 MPP_VAR_FUNCTION(0x1, "dev", "ad18", V_MV78260_PLUS)),
306 MPP_MODE(54,
307 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
308 MPP_VAR_FUNCTION(0x1, "dev", "ad19", V_MV78260_PLUS)),
309 MPP_MODE(55,
310 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
311 MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS),
312 MPP_VAR_FUNCTION(0x2, "vdd", "cpu0-pd", V_MV78260_PLUS)),
313 MPP_MODE(56,
314 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
315 MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS),
316 MPP_VAR_FUNCTION(0x2, "vdd", "cpu1-pd", V_MV78260_PLUS)),
317 MPP_MODE(57,
318 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
319 MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS),
320 MPP_VAR_FUNCTION(0x2, "vdd", "cpu2-3-pd", V_MV78460)),
321 MPP_MODE(58,
322 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
323 MPP_VAR_FUNCTION(0x1, "dev", "ad23", V_MV78260_PLUS)),
324 MPP_MODE(59,
325 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
326 MPP_VAR_FUNCTION(0x1, "dev", "ad24", V_MV78260_PLUS)),
327 MPP_MODE(60,
328 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
329 MPP_VAR_FUNCTION(0x1, "dev", "ad25", V_MV78260_PLUS)),
330 MPP_MODE(61,
331 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
332 MPP_VAR_FUNCTION(0x1, "dev", "ad26", V_MV78260_PLUS)),
333 MPP_MODE(62,
334 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
335 MPP_VAR_FUNCTION(0x1, "dev", "ad27", V_MV78260_PLUS)),
336 MPP_MODE(63,
337 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
338 MPP_VAR_FUNCTION(0x1, "dev", "ad28", V_MV78260_PLUS)),
339 MPP_MODE(64,
340 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
341 MPP_VAR_FUNCTION(0x1, "dev", "ad29", V_MV78260_PLUS)),
342 MPP_MODE(65,
343 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
344 MPP_VAR_FUNCTION(0x1, "dev", "ad30", V_MV78260_PLUS)),
345 MPP_MODE(66,
346 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
347 MPP_VAR_FUNCTION(0x1, "dev", "ad31", V_MV78260_PLUS)),
348};
349
350static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info;
351
352static struct of_device_id armada_xp_pinctrl_of_match[] __devinitdata = {
353 {
354 .compatible = "marvell,mv78230-pinctrl",
355 .data = (void *) V_MV78230,
356 },
357 {
358 .compatible = "marvell,mv78260-pinctrl",
359 .data = (void *) V_MV78260,
360 },
361 {
362 .compatible = "marvell,mv78460-pinctrl",
363 .data = (void *) V_MV78460,
364 },
365 { },
366};
367
368static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = {
369 MPP_REG_CTRL(0, 48),
370};
371
372static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
373 MPP_GPIO_RANGE(0, 0, 0, 32),
374 MPP_GPIO_RANGE(1, 32, 32, 17),
375};
376
377static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = {
378 MPP_REG_CTRL(0, 66),
379};
380
381static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
382 MPP_GPIO_RANGE(0, 0, 0, 32),
383 MPP_GPIO_RANGE(1, 32, 32, 32),
384 MPP_GPIO_RANGE(2, 64, 64, 3),
385};
386
387static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = {
388 MPP_REG_CTRL(0, 66),
389};
390
391static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {
392 MPP_GPIO_RANGE(0, 0, 0, 32),
393 MPP_GPIO_RANGE(1, 32, 32, 32),
394 MPP_GPIO_RANGE(2, 64, 64, 3),
395};
396
397static int __devinit armada_xp_pinctrl_probe(struct platform_device *pdev)
398{
399 struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
400 const struct of_device_id *match =
401 of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
402
403 if (!match)
404 return -ENODEV;
405
406 soc->variant = (unsigned) match->data & 0xff;
407
408 switch (soc->variant) {
409 case V_MV78230:
410 soc->controls = mv78230_mpp_controls;
411 soc->ncontrols = ARRAY_SIZE(mv78230_mpp_controls);
412 soc->modes = armada_xp_mpp_modes;
413 /* We don't necessarily want the full list of the
414 * armada_xp_mpp_modes, but only the first 'n' ones
415 * that are available on this SoC */
416 soc->nmodes = mv78230_mpp_controls[0].npins;
417 soc->gpioranges = mv78230_mpp_gpio_ranges;
418 soc->ngpioranges = ARRAY_SIZE(mv78230_mpp_gpio_ranges);
419 break;
420 case V_MV78260:
421 soc->controls = mv78260_mpp_controls;
422 soc->ncontrols = ARRAY_SIZE(mv78260_mpp_controls);
423 soc->modes = armada_xp_mpp_modes;
424 /* We don't necessarily want the full list of the
425 * armada_xp_mpp_modes, but only the first 'n' ones
426 * that are available on this SoC */
427 soc->nmodes = mv78260_mpp_controls[0].npins;
428 soc->gpioranges = mv78260_mpp_gpio_ranges;
429 soc->ngpioranges = ARRAY_SIZE(mv78260_mpp_gpio_ranges);
430 break;
431 case V_MV78460:
432 soc->controls = mv78460_mpp_controls;
433 soc->ncontrols = ARRAY_SIZE(mv78460_mpp_controls);
434 soc->modes = armada_xp_mpp_modes;
435 /* We don't necessarily want the full list of the
436 * armada_xp_mpp_modes, but only the first 'n' ones
437 * that are available on this SoC */
438 soc->nmodes = mv78460_mpp_controls[0].npins;
439 soc->gpioranges = mv78460_mpp_gpio_ranges;
440 soc->ngpioranges = ARRAY_SIZE(mv78460_mpp_gpio_ranges);
441 break;
442 }
443
444 pdev->dev.platform_data = soc;
445
446 return mvebu_pinctrl_probe(pdev);
447}
448
449static int __devexit armada_xp_pinctrl_remove(struct platform_device *pdev)
450{
451 return mvebu_pinctrl_remove(pdev);
452}
453
454static struct platform_driver armada_xp_pinctrl_driver = {
455 .driver = {
456 .name = "armada-xp-pinctrl",
457 .owner = THIS_MODULE,
458 .of_match_table = of_match_ptr(armada_xp_pinctrl_of_match),
459 },
460 .probe = armada_xp_pinctrl_probe,
461 .remove = __devexit_p(armada_xp_pinctrl_remove),
462};
463
464module_platform_driver(armada_xp_pinctrl_driver);
465
466MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
467MODULE_DESCRIPTION("Marvell Armada XP pinctrl driver");
468MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-dove.c b/drivers/pinctrl/pinctrl-dove.c
new file mode 100644
index 000000000000..ffe74b27d66d
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-dove.c
@@ -0,0 +1,620 @@
1/*
2 * Marvell Dove pinctrl driver based on mvebu pinctrl core
3 *
4 * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/err.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/module.h>
16#include <linux/bitops.h>
17#include <linux/platform_device.h>
18#include <linux/clk.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/pinctrl/pinctrl.h>
22
23#include "pinctrl-mvebu.h"
24
25#define DOVE_SB_REGS_VIRT_BASE 0xfde00000
26#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200)
27#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10)
28#define DOVE_AU0_AC97_SEL BIT(16)
29#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C)
30#define DOVE_TWSI_ENABLE_OPTION1 BIT(7)
31#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030)
32#define DOVE_TWSI_ENABLE_OPTION2 BIT(20)
33#define DOVE_TWSI_ENABLE_OPTION3 BIT(21)
34#define DOVE_TWSI_OPTION3_GPIO BIT(22)
35#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034)
36#define DOVE_SSP_ON_AU1 BIT(0)
37#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c)
38#define DOVE_AU1_SPDIFO_GPIO_EN BIT(1)
39#define DOVE_NAND_GPIO_EN BIT(0)
40#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400)
41#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40)
42#define DOVE_SPI_GPIO_SEL BIT(5)
43#define DOVE_UART1_GPIO_SEL BIT(4)
44#define DOVE_AU1_GPIO_SEL BIT(3)
45#define DOVE_CAM_GPIO_SEL BIT(2)
46#define DOVE_SD1_GPIO_SEL BIT(1)
47#define DOVE_SD0_GPIO_SEL BIT(0)
48
49#define MPPS_PER_REG 8
50#define MPP_BITS 4
51#define MPP_MASK 0xf
52
53#define CONFIG_PMU BIT(4)
54
55static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
56 unsigned long *config)
57{
58 unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
59 unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
60 unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
61 unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off);
62
63 if (pmu & (1 << ctrl->pid))
64 *config = CONFIG_PMU;
65 else
66 *config = (mpp >> shift) & MPP_MASK;
67 return 0;
68}
69
70static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
71 unsigned long config)
72{
73 unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
74 unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
75 unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
76 unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off);
77
78 if (config == CONFIG_PMU)
79 writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
80 else {
81 writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
82 mpp &= ~(MPP_MASK << shift);
83 mpp |= config << shift;
84 writel(mpp, DOVE_MPP_VIRT_BASE + off);
85 }
86 return 0;
87}
88
89static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
90 unsigned long *config)
91{
92 unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
93 unsigned long mask;
94
95 switch (ctrl->pid) {
96 case 24: /* mpp_camera */
97 mask = DOVE_CAM_GPIO_SEL;
98 break;
99 case 40: /* mpp_sdio0 */
100 mask = DOVE_SD0_GPIO_SEL;
101 break;
102 case 46: /* mpp_sdio1 */
103 mask = DOVE_SD1_GPIO_SEL;
104 break;
105 case 58: /* mpp_spi0 */
106 mask = DOVE_SPI_GPIO_SEL;
107 break;
108 case 62: /* mpp_uart1 */
109 mask = DOVE_UART1_GPIO_SEL;
110 break;
111 default:
112 return -EINVAL;
113 }
114
115 *config = ((mpp4 & mask) != 0);
116
117 return 0;
118}
119
120static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
121 unsigned long config)
122{
123 unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
124 unsigned long mask;
125
126 switch (ctrl->pid) {
127 case 24: /* mpp_camera */
128 mask = DOVE_CAM_GPIO_SEL;
129 break;
130 case 40: /* mpp_sdio0 */
131 mask = DOVE_SD0_GPIO_SEL;
132 break;
133 case 46: /* mpp_sdio1 */
134 mask = DOVE_SD1_GPIO_SEL;
135 break;
136 case 58: /* mpp_spi0 */
137 mask = DOVE_SPI_GPIO_SEL;
138 break;
139 case 62: /* mpp_uart1 */
140 mask = DOVE_UART1_GPIO_SEL;
141 break;
142 default:
143 return -EINVAL;
144 }
145
146 mpp4 &= ~mask;
147 if (config)
148 mpp4 |= mask;
149
150 writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
151
152 return 0;
153}
154
155static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
156 unsigned long *config)
157{
158 unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
159
160 *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0);
161
162 return 0;
163}
164
165static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
166 unsigned long config)
167{
168 unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
169
170 gmpp &= ~DOVE_NAND_GPIO_EN;
171 if (config)
172 gmpp |= DOVE_NAND_GPIO_EN;
173
174 writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
175
176 return 0;
177}
178
179static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
180 unsigned long *config)
181{
182 unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
183
184 *config = ((pmu & DOVE_AU0_AC97_SEL) != 0);
185
186 return 0;
187}
188
189static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
190 unsigned long config)
191{
192 unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
193
194 pmu &= ~DOVE_AU0_AC97_SEL;
195 if (config)
196 pmu |= DOVE_AU0_AC97_SEL;
197 writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL);
198
199 return 0;
200}
201
202static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
203 unsigned long *config)
204{
205 unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
206 unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
207 unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
208 unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
209
210 *config = 0;
211 if (mpp4 & DOVE_AU1_GPIO_SEL)
212 *config |= BIT(3);
213 if (sspc1 & DOVE_SSP_ON_AU1)
214 *config |= BIT(2);
215 if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN)
216 *config |= BIT(1);
217 if (gcfg2 & DOVE_TWSI_OPTION3_GPIO)
218 *config |= BIT(0);
219
220 /* SSP/TWSI only if I2S1 not set*/
221 if ((*config & BIT(3)) == 0)
222 *config &= ~(BIT(2) | BIT(0));
223 /* TWSI only if SPDIFO not set*/
224 if ((*config & BIT(1)) == 0)
225 *config &= ~BIT(0);
226 return 0;
227}
228
229static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
230 unsigned long config)
231{
232 unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
233 unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
234 unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
235 unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
236
237 if (config & BIT(0))
238 gcfg2 |= DOVE_TWSI_OPTION3_GPIO;
239 if (config & BIT(1))
240 gmpp |= DOVE_AU1_SPDIFO_GPIO_EN;
241 if (config & BIT(2))
242 sspc1 |= DOVE_SSP_ON_AU1;
243 if (config & BIT(3))
244 mpp4 |= DOVE_AU1_GPIO_SEL;
245
246 writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
247 writel(sspc1, DOVE_SSP_CTRL_STATUS_1);
248 writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
249 writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
250
251 return 0;
252}
253
254/* mpp[52:57] gpio pins depend heavily on current config;
255 * gpio_req does not try to mux in gpio capabilities to not
256 * break other functions. If you require all mpps as gpio
257 * enforce gpio setting by pinctrl mapping.
258 */
259static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
260{
261 unsigned long config;
262
263 dove_audio1_ctrl_get(ctrl, &config);
264
265 switch (config) {
266 case 0x02: /* i2s1 : gpio[56:57] */
267 case 0x0e: /* ssp : gpio[56:57] */
268 if (pid >= 56)
269 return 0;
270 return -ENOTSUPP;
271 case 0x08: /* spdifo : gpio[52:55] */
272 case 0x0b: /* twsi : gpio[52:55] */
273 if (pid <= 55)
274 return 0;
275 return -ENOTSUPP;
276 case 0x0a: /* all gpio */
277 return 0;
278 /* 0x00 : i2s1/spdifo : no gpio */
279 /* 0x0c : ssp/spdifo : no gpio */
280 /* 0x0f : ssp/twsi : no gpio */
281 }
282 return -ENOTSUPP;
283}
284
285/* mpp[52:57] has gpio pins capable of in and out */
286static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid,
287 bool input)
288{
289 if (pid < 52 || pid > 57)
290 return -ENOTSUPP;
291 return 0;
292}
293
294static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
295 unsigned long *config)
296{
297 unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
298 unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
299
300 *config = 0;
301 if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1)
302 *config = 1;
303 else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2)
304 *config = 2;
305 else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3)
306 *config = 3;
307
308 return 0;
309}
310
311static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
312 unsigned long config)
313{
314 unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
315 unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
316
317 gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1;
318 gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION2);
319
320 switch (config) {
321 case 1:
322 gcfg1 |= DOVE_TWSI_ENABLE_OPTION1;
323 break;
324 case 2:
325 gcfg2 |= DOVE_TWSI_ENABLE_OPTION2;
326 break;
327 case 3:
328 gcfg2 |= DOVE_TWSI_ENABLE_OPTION3;
329 break;
330 }
331
332 writel(gcfg1, DOVE_GLOBAL_CONFIG_1);
333 writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
334
335 return 0;
336}
337
338static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
339 MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl),
340 MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl),
341 MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl),
342 MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl),
343 MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl),
344 MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl),
345 MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl),
346 MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl),
347 MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl),
348 MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl),
349 MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl),
350 MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl),
351 MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl),
352 MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl),
353 MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl),
354 MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl),
355 MPP_REG_CTRL(16, 23),
356 MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
357 MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
358 MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
359 MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl),
360 MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl),
361 MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl),
362 MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl),
363 MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl),
364 MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl),
365};
366
367static struct mvebu_mpp_mode dove_mpp_modes[] = {
368 MPP_MODE(0,
369 MPP_FUNCTION(0x00, "gpio", NULL),
370 MPP_FUNCTION(0x02, "uart2", "rts"),
371 MPP_FUNCTION(0x03, "sdio0", "cd"),
372 MPP_FUNCTION(0x0f, "lcd0", "pwm"),
373 MPP_FUNCTION(0x10, "pmu", NULL)),
374 MPP_MODE(1,
375 MPP_FUNCTION(0x00, "gpio", NULL),
376 MPP_FUNCTION(0x02, "uart2", "cts"),
377 MPP_FUNCTION(0x03, "sdio0", "wp"),
378 MPP_FUNCTION(0x0f, "lcd1", "pwm"),
379 MPP_FUNCTION(0x10, "pmu", NULL)),
380 MPP_MODE(2,
381 MPP_FUNCTION(0x00, "gpio", NULL),
382 MPP_FUNCTION(0x01, "sata", "prsnt"),
383 MPP_FUNCTION(0x02, "uart2", "txd"),
384 MPP_FUNCTION(0x03, "sdio0", "buspwr"),
385 MPP_FUNCTION(0x04, "uart1", "rts"),
386 MPP_FUNCTION(0x10, "pmu", NULL)),
387 MPP_MODE(3,
388 MPP_FUNCTION(0x00, "gpio", NULL),
389 MPP_FUNCTION(0x01, "sata", "act"),
390 MPP_FUNCTION(0x02, "uart2", "rxd"),
391 MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
392 MPP_FUNCTION(0x04, "uart1", "cts"),
393 MPP_FUNCTION(0x0f, "lcd-spi", "cs1"),
394 MPP_FUNCTION(0x10, "pmu", NULL)),
395 MPP_MODE(4,
396 MPP_FUNCTION(0x00, "gpio", NULL),
397 MPP_FUNCTION(0x02, "uart3", "rts"),
398 MPP_FUNCTION(0x03, "sdio1", "cd"),
399 MPP_FUNCTION(0x04, "spi1", "miso"),
400 MPP_FUNCTION(0x10, "pmu", NULL)),
401 MPP_MODE(5,
402 MPP_FUNCTION(0x00, "gpio", NULL),
403 MPP_FUNCTION(0x02, "uart3", "cts"),
404 MPP_FUNCTION(0x03, "sdio1", "wp"),
405 MPP_FUNCTION(0x04, "spi1", "cs"),
406 MPP_FUNCTION(0x10, "pmu", NULL)),
407 MPP_MODE(6,
408 MPP_FUNCTION(0x00, "gpio", NULL),
409 MPP_FUNCTION(0x02, "uart3", "txd"),
410 MPP_FUNCTION(0x03, "sdio1", "buspwr"),
411 MPP_FUNCTION(0x04, "spi1", "mosi"),
412 MPP_FUNCTION(0x10, "pmu", NULL)),
413 MPP_MODE(7,
414 MPP_FUNCTION(0x00, "gpio", NULL),
415 MPP_FUNCTION(0x02, "uart3", "rxd"),
416 MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
417 MPP_FUNCTION(0x04, "spi1", "sck"),
418 MPP_FUNCTION(0x10, "pmu", NULL)),
419 MPP_MODE(8,
420 MPP_FUNCTION(0x00, "gpio", NULL),
421 MPP_FUNCTION(0x01, "watchdog", "rstout"),
422 MPP_FUNCTION(0x10, "pmu", NULL)),
423 MPP_MODE(9,
424 MPP_FUNCTION(0x00, "gpio", NULL),
425 MPP_FUNCTION(0x05, "pex1", "clkreq"),
426 MPP_FUNCTION(0x10, "pmu", NULL)),
427 MPP_MODE(10,
428 MPP_FUNCTION(0x00, "gpio", NULL),
429 MPP_FUNCTION(0x05, "ssp", "sclk"),
430 MPP_FUNCTION(0x10, "pmu", NULL)),
431 MPP_MODE(11,
432 MPP_FUNCTION(0x00, "gpio", NULL),
433 MPP_FUNCTION(0x01, "sata", "prsnt"),
434 MPP_FUNCTION(0x02, "sata-1", "act"),
435 MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
436 MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
437 MPP_FUNCTION(0x05, "pex0", "clkreq"),
438 MPP_FUNCTION(0x10, "pmu", NULL)),
439 MPP_MODE(12,
440 MPP_FUNCTION(0x00, "gpio", NULL),
441 MPP_FUNCTION(0x01, "sata", "act"),
442 MPP_FUNCTION(0x02, "uart2", "rts"),
443 MPP_FUNCTION(0x03, "audio0", "extclk"),
444 MPP_FUNCTION(0x04, "sdio1", "cd"),
445 MPP_FUNCTION(0x10, "pmu", NULL)),
446 MPP_MODE(13,
447 MPP_FUNCTION(0x00, "gpio", NULL),
448 MPP_FUNCTION(0x02, "uart2", "cts"),
449 MPP_FUNCTION(0x03, "audio1", "extclk"),
450 MPP_FUNCTION(0x04, "sdio1", "wp"),
451 MPP_FUNCTION(0x05, "ssp", "extclk"),
452 MPP_FUNCTION(0x10, "pmu", NULL)),
453 MPP_MODE(14,
454 MPP_FUNCTION(0x00, "gpio", NULL),
455 MPP_FUNCTION(0x02, "uart2", "txd"),
456 MPP_FUNCTION(0x04, "sdio1", "buspwr"),
457 MPP_FUNCTION(0x05, "ssp", "rxd"),
458 MPP_FUNCTION(0x10, "pmu", NULL)),
459 MPP_MODE(15,
460 MPP_FUNCTION(0x00, "gpio", NULL),
461 MPP_FUNCTION(0x02, "uart2", "rxd"),
462 MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
463 MPP_FUNCTION(0x05, "ssp", "sfrm"),
464 MPP_FUNCTION(0x10, "pmu", NULL)),
465 MPP_MODE(16,
466 MPP_FUNCTION(0x00, "gpio", NULL),
467 MPP_FUNCTION(0x02, "uart3", "rts"),
468 MPP_FUNCTION(0x03, "sdio0", "cd"),
469 MPP_FUNCTION(0x04, "lcd-spi", "cs1"),
470 MPP_FUNCTION(0x05, "ac97", "sdi1")),
471 MPP_MODE(17,
472 MPP_FUNCTION(0x00, "gpio", NULL),
473 MPP_FUNCTION(0x01, "ac97-1", "sysclko"),
474 MPP_FUNCTION(0x02, "uart3", "cts"),
475 MPP_FUNCTION(0x03, "sdio0", "wp"),
476 MPP_FUNCTION(0x04, "twsi", "sda"),
477 MPP_FUNCTION(0x05, "ac97", "sdi2")),
478 MPP_MODE(18,
479 MPP_FUNCTION(0x00, "gpio", NULL),
480 MPP_FUNCTION(0x02, "uart3", "txd"),
481 MPP_FUNCTION(0x03, "sdio0", "buspwr"),
482 MPP_FUNCTION(0x04, "lcd0", "pwm"),
483 MPP_FUNCTION(0x05, "ac97", "sdi3")),
484 MPP_MODE(19,
485 MPP_FUNCTION(0x00, "gpio", NULL),
486 MPP_FUNCTION(0x02, "uart3", "rxd"),
487 MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
488 MPP_FUNCTION(0x04, "twsi", "sck")),
489 MPP_MODE(20,
490 MPP_FUNCTION(0x00, "gpio", NULL),
491 MPP_FUNCTION(0x01, "ac97", "sysclko"),
492 MPP_FUNCTION(0x02, "lcd-spi", "miso"),
493 MPP_FUNCTION(0x03, "sdio1", "cd"),
494 MPP_FUNCTION(0x05, "sdio0", "cd"),
495 MPP_FUNCTION(0x06, "spi1", "miso")),
496 MPP_MODE(21,
497 MPP_FUNCTION(0x00, "gpio", NULL),
498 MPP_FUNCTION(0x01, "uart1", "rts"),
499 MPP_FUNCTION(0x02, "lcd-spi", "cs0"),
500 MPP_FUNCTION(0x03, "sdio1", "wp"),
501 MPP_FUNCTION(0x04, "ssp", "sfrm"),
502 MPP_FUNCTION(0x05, "sdio0", "wp"),
503 MPP_FUNCTION(0x06, "spi1", "cs")),
504 MPP_MODE(22,
505 MPP_FUNCTION(0x00, "gpio", NULL),
506 MPP_FUNCTION(0x01, "uart1", "cts"),
507 MPP_FUNCTION(0x02, "lcd-spi", "mosi"),
508 MPP_FUNCTION(0x03, "sdio1", "buspwr"),
509 MPP_FUNCTION(0x04, "ssp", "txd"),
510 MPP_FUNCTION(0x05, "sdio0", "buspwr"),
511 MPP_FUNCTION(0x06, "spi1", "mosi")),
512 MPP_MODE(23,
513 MPP_FUNCTION(0x00, "gpio", NULL),
514 MPP_FUNCTION(0x02, "lcd-spi", "sck"),
515 MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
516 MPP_FUNCTION(0x04, "ssp", "sclk"),
517 MPP_FUNCTION(0x05, "sdio0", "ledctrl"),
518 MPP_FUNCTION(0x06, "spi1", "sck")),
519 MPP_MODE(24,
520 MPP_FUNCTION(0x00, "camera", NULL),
521 MPP_FUNCTION(0x01, "gpio", NULL)),
522 MPP_MODE(40,
523 MPP_FUNCTION(0x00, "sdio0", NULL),
524 MPP_FUNCTION(0x01, "gpio", NULL)),
525 MPP_MODE(46,
526 MPP_FUNCTION(0x00, "sdio1", NULL),
527 MPP_FUNCTION(0x01, "gpio", NULL)),
528 MPP_MODE(52,
529 MPP_FUNCTION(0x00, "i2s1/spdifo", NULL),
530 MPP_FUNCTION(0x02, "i2s1", NULL),
531 MPP_FUNCTION(0x08, "spdifo", NULL),
532 MPP_FUNCTION(0x0a, "gpio", NULL),
533 MPP_FUNCTION(0x0b, "twsi", NULL),
534 MPP_FUNCTION(0x0c, "ssp/spdifo", NULL),
535 MPP_FUNCTION(0x0e, "ssp", NULL),
536 MPP_FUNCTION(0x0f, "ssp/twsi", NULL)),
537 MPP_MODE(58,
538 MPP_FUNCTION(0x00, "spi0", NULL),
539 MPP_FUNCTION(0x01, "gpio", NULL)),
540 MPP_MODE(62,
541 MPP_FUNCTION(0x00, "uart1", NULL),
542 MPP_FUNCTION(0x01, "gpio", NULL)),
543 MPP_MODE(64,
544 MPP_FUNCTION(0x00, "nand", NULL),
545 MPP_FUNCTION(0x01, "gpo", NULL)),
546 MPP_MODE(72,
547 MPP_FUNCTION(0x00, "i2s", NULL),
548 MPP_FUNCTION(0x01, "ac97", NULL)),
549 MPP_MODE(73,
550 MPP_FUNCTION(0x00, "twsi-none", NULL),
551 MPP_FUNCTION(0x01, "twsi-opt1", NULL),
552 MPP_FUNCTION(0x02, "twsi-opt2", NULL),
553 MPP_FUNCTION(0x03, "twsi-opt3", NULL)),
554};
555
556static struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = {
557 MPP_GPIO_RANGE(0, 0, 0, 32),
558 MPP_GPIO_RANGE(1, 32, 32, 32),
559 MPP_GPIO_RANGE(2, 64, 64, 8),
560};
561
562static struct mvebu_pinctrl_soc_info dove_pinctrl_info = {
563 .controls = dove_mpp_controls,
564 .ncontrols = ARRAY_SIZE(dove_mpp_controls),
565 .modes = dove_mpp_modes,
566 .nmodes = ARRAY_SIZE(dove_mpp_modes),
567 .gpioranges = dove_mpp_gpio_ranges,
568 .ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges),
569 .variant = 0,
570};
571
572static struct clk *clk;
573
574static struct of_device_id dove_pinctrl_of_match[] __devinitdata = {
575 { .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info },
576 { }
577};
578
579static int __devinit dove_pinctrl_probe(struct platform_device *pdev)
580{
581 const struct of_device_id *match =
582 of_match_device(dove_pinctrl_of_match, &pdev->dev);
583 pdev->dev.platform_data = match->data;
584
585 /*
586 * General MPP Configuration Register is part of pdma registers.
587 * grab clk to make sure it is ticking.
588 */
589 clk = devm_clk_get(&pdev->dev, NULL);
590 if (!IS_ERR(clk))
591 clk_prepare_enable(clk);
592
593 return mvebu_pinctrl_probe(pdev);
594}
595
596static int __devexit dove_pinctrl_remove(struct platform_device *pdev)
597{
598 int ret;
599
600 ret = mvebu_pinctrl_remove(pdev);
601 if (!IS_ERR(clk))
602 clk_disable_unprepare(clk);
603 return ret;
604}
605
606static struct platform_driver dove_pinctrl_driver = {
607 .driver = {
608 .name = "dove-pinctrl",
609 .owner = THIS_MODULE,
610 .of_match_table = of_match_ptr(dove_pinctrl_of_match),
611 },
612 .probe = dove_pinctrl_probe,
613 .remove = __devexit_p(dove_pinctrl_remove),
614};
615
616module_platform_driver(dove_pinctrl_driver);
617
618MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>");
619MODULE_DESCRIPTION("Marvell Dove pinctrl driver");
620MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-kirkwood.c b/drivers/pinctrl/pinctrl-kirkwood.c
new file mode 100644
index 000000000000..9a74ef674a0e
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-kirkwood.c
@@ -0,0 +1,472 @@
1/*
2 * Marvell Kirkwood pinctrl driver based on mvebu pinctrl core
3 *
4 * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/err.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/module.h>
16#include <linux/platform_device.h>
17#include <linux/clk.h>
18#include <linux/of.h>
19#include <linux/of_device.h>
20#include <linux/pinctrl/pinctrl.h>
21
22#include "pinctrl-mvebu.h"
23
24#define V(f6180, f6190, f6192, f6281, f6282) \
25 ((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \
26 (f6281 << 3) | (f6282 << 4))
27
28enum kirkwood_variant {
29 VARIANT_MV88F6180 = V(1, 0, 0, 0, 0),
30 VARIANT_MV88F6190 = V(0, 1, 0, 0, 0),
31 VARIANT_MV88F6192 = V(0, 0, 1, 0, 0),
32 VARIANT_MV88F6281 = V(0, 0, 0, 1, 0),
33 VARIANT_MV88F6282 = V(0, 0, 0, 0, 1),
34};
35
36static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
37 MPP_MODE(0,
38 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
39 MPP_VAR_FUNCTION(0x1, "nand", "io2", V(1, 1, 1, 1, 1)),
40 MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1))),
41 MPP_MODE(1,
42 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
43 MPP_VAR_FUNCTION(0x1, "nand", "io3", V(1, 1, 1, 1, 1)),
44 MPP_VAR_FUNCTION(0x2, "spi", "mosi", V(1, 1, 1, 1, 1))),
45 MPP_MODE(2,
46 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
47 MPP_VAR_FUNCTION(0x1, "nand", "io4", V(1, 1, 1, 1, 1)),
48 MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1))),
49 MPP_MODE(3,
50 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
51 MPP_VAR_FUNCTION(0x1, "nand", "io5", V(1, 1, 1, 1, 1)),
52 MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1))),
53 MPP_MODE(4,
54 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
55 MPP_VAR_FUNCTION(0x1, "nand", "io6", V(1, 1, 1, 1, 1)),
56 MPP_VAR_FUNCTION(0x2, "uart0", "rxd", V(1, 1, 1, 1, 1)),
57 MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)),
58 MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1)),
59 MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0))),
60 MPP_MODE(5,
61 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
62 MPP_VAR_FUNCTION(0x1, "nand", "io7", V(1, 1, 1, 1, 1)),
63 MPP_VAR_FUNCTION(0x2, "uart0", "txd", V(1, 1, 1, 1, 1)),
64 MPP_VAR_FUNCTION(0x4, "ptp", "trig", V(1, 1, 1, 1, 0)),
65 MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)),
66 MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))),
67 MPP_MODE(6,
68 MPP_VAR_FUNCTION(0x0, "sysrst", "out", V(1, 1, 1, 1, 1)),
69 MPP_VAR_FUNCTION(0x1, "spi", "mosi", V(1, 1, 1, 1, 1)),
70 MPP_VAR_FUNCTION(0x2, "ptp", "trig", V(1, 1, 1, 1, 0))),
71 MPP_MODE(7,
72 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
73 MPP_VAR_FUNCTION(0x1, "pex", "rsto", V(1, 1, 1, 1, 0)),
74 MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1)),
75 MPP_VAR_FUNCTION(0x3, "ptp", "trig", V(1, 1, 1, 1, 0)),
76 MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))),
77 MPP_MODE(8,
78 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
79 MPP_VAR_FUNCTION(0x1, "twsi0", "sda", V(1, 1, 1, 1, 1)),
80 MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)),
81 MPP_VAR_FUNCTION(0x3, "uart1", "rts", V(1, 1, 1, 1, 1)),
82 MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr", V(0, 1, 1, 1, 1)),
83 MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)),
84 MPP_VAR_FUNCTION(0xc, "ptp", "clk", V(1, 1, 1, 1, 0)),
85 MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))),
86 MPP_MODE(9,
87 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
88 MPP_VAR_FUNCTION(0x1, "twsi0", "sck", V(1, 1, 1, 1, 1)),
89 MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)),
90 MPP_VAR_FUNCTION(0x3, "uart1", "cts", V(1, 1, 1, 1, 1)),
91 MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)),
92 MPP_VAR_FUNCTION(0xc, "ptp", "evreq", V(1, 1, 1, 1, 0)),
93 MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))),
94 MPP_MODE(10,
95 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
96 MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1)),
97 MPP_VAR_FUNCTION(0X3, "uart0", "txd", V(1, 1, 1, 1, 1)),
98 MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)),
99 MPP_VAR_FUNCTION(0xc, "ptp", "trig", V(1, 1, 1, 1, 0))),
100 MPP_MODE(11,
101 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
102 MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1)),
103 MPP_VAR_FUNCTION(0x3, "uart0", "rxd", V(1, 1, 1, 1, 1)),
104 MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq", V(1, 1, 1, 1, 0)),
105 MPP_VAR_FUNCTION(0xc, "ptp-2", "trig", V(1, 1, 1, 1, 0)),
106 MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0)),
107 MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1))),
108 MPP_MODE(12,
109 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 0, 1)),
110 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)),
111 MPP_VAR_FUNCTION(0x1, "sdio", "clk", V(1, 1, 1, 1, 1)),
112 MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1)),
113 MPP_VAR_FUNCTION(0xb, "spi", "mosi", V(0, 0, 0, 0, 1)),
114 MPP_VAR_FUNCTION(0xd, "twsi1", "sda", V(0, 0, 0, 0, 1))),
115 MPP_MODE(13,
116 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
117 MPP_VAR_FUNCTION(0x1, "sdio", "cmd", V(1, 1, 1, 1, 1)),
118 MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)),
119 MPP_VAR_FUNCTION(0xa, "audio", "rmclk", V(0, 0, 0, 0, 1)),
120 MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))),
121 MPP_MODE(14,
122 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
123 MPP_VAR_FUNCTION(0x1, "sdio", "d0", V(1, 1, 1, 1, 1)),
124 MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)),
125 MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V(0, 0, 1, 1, 1)),
126 MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1)),
127 MPP_VAR_FUNCTION(0xb, "audio-1", "sdi", V(0, 0, 0, 0, 1)),
128 MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))),
129 MPP_MODE(15,
130 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
131 MPP_VAR_FUNCTION(0x1, "sdio", "d1", V(1, 1, 1, 1, 1)),
132 MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)),
133 MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)),
134 MPP_VAR_FUNCTION(0x4, "sata0", "act", V(0, 1, 1, 1, 1)),
135 MPP_VAR_FUNCTION(0xb, "spi", "cs", V(0, 0, 0, 0, 1))),
136 MPP_MODE(16,
137 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
138 MPP_VAR_FUNCTION(0x1, "sdio", "d2", V(1, 1, 1, 1, 1)),
139 MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)),
140 MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)),
141 MPP_VAR_FUNCTION(0x4, "sata1", "act", V(0, 0, 1, 1, 1)),
142 MPP_VAR_FUNCTION(0xb, "lcd", "extclk", V(0, 0, 0, 0, 1)),
143 MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))),
144 MPP_MODE(17,
145 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
146 MPP_VAR_FUNCTION(0x1, "sdio", "d3", V(1, 1, 1, 1, 1)),
147 MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V(0, 1, 1, 1, 1)),
148 MPP_VAR_FUNCTION(0xa, "sata1", "act", V(0, 0, 0, 0, 1)),
149 MPP_VAR_FUNCTION(0xd, "twsi1", "sck", V(0, 0, 0, 0, 1))),
150 MPP_MODE(18,
151 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
152 MPP_VAR_FUNCTION(0x1, "nand", "io0", V(1, 1, 1, 1, 1)),
153 MPP_VAR_FUNCTION(0x2, "pex", "clkreq", V(0, 0, 0, 0, 1))),
154 MPP_MODE(19,
155 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
156 MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1))),
157 MPP_MODE(20,
158 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
159 MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1)),
160 MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)),
161 MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1)),
162 MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1)),
163 MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)),
164 MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1)),
165 MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0))),
166 MPP_MODE(21,
167 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
168 MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1)),
169 MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1)),
170 MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1)),
171 MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0)),
172 MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1)),
173 MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)),
174 MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1))),
175 MPP_MODE(22,
176 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
177 MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1)),
178 MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1)),
179 MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1)),
180 MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0)),
181 MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1)),
182 MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)),
183 MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1))),
184 MPP_MODE(23,
185 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
186 MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1)),
187 MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1)),
188 MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1)),
189 MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0)),
190 MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1)),
191 MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)),
192 MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1))),
193 MPP_MODE(24,
194 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
195 MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1)),
196 MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1)),
197 MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1)),
198 MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0)),
199 MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1)),
200 MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1))),
201 MPP_MODE(25,
202 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
203 MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1)),
204 MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1)),
205 MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1)),
206 MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0)),
207 MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1)),
208 MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1))),
209 MPP_MODE(26,
210 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
211 MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1)),
212 MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1)),
213 MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1)),
214 MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0)),
215 MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1)),
216 MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1))),
217 MPP_MODE(27,
218 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
219 MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1)),
220 MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1)),
221 MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1)),
222 MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0)),
223 MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1)),
224 MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1))),
225 MPP_MODE(28,
226 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
227 MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1)),
228 MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1)),
229 MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1)),
230 MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0)),
231 MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1)),
232 MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1))),
233 MPP_MODE(29,
234 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
235 MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1)),
236 MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1)),
237 MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1)),
238 MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0)),
239 MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1))),
240 MPP_MODE(30,
241 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
242 MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 1, 1, 1)),
243 MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 1, 1, 1)),
244 MPP_VAR_FUNCTION(0x3, "ge1", "rxctl", V(0, 1, 1, 1, 1)),
245 MPP_VAR_FUNCTION(0xb, "lcd", "d10", V(0, 0, 0, 0, 1))),
246 MPP_MODE(31,
247 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
248 MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 1, 1, 1)),
249 MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 1, 1, 1)),
250 MPP_VAR_FUNCTION(0x3, "ge1", "rxclk", V(0, 1, 1, 1, 1)),
251 MPP_VAR_FUNCTION(0xb, "lcd", "d11", V(0, 0, 0, 0, 1))),
252 MPP_MODE(32,
253 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
254 MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 1, 1, 1)),
255 MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 1, 1, 1)),
256 MPP_VAR_FUNCTION(0x3, "ge1", "txclko", V(0, 1, 1, 1, 1)),
257 MPP_VAR_FUNCTION(0xb, "lcd", "d12", V(0, 0, 0, 0, 1))),
258 MPP_MODE(33,
259 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 1, 1, 1, 1)),
260 MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 1, 1, 1)),
261 MPP_VAR_FUNCTION(0x3, "ge1", "txctl", V(0, 1, 1, 1, 1)),
262 MPP_VAR_FUNCTION(0xb, "lcd", "d13", V(0, 0, 0, 0, 1))),
263 MPP_MODE(34,
264 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
265 MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 1, 1, 1)),
266 MPP_VAR_FUNCTION(0x3, "ge1", "txen", V(0, 1, 1, 1, 1)),
267 MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1)),
268 MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1))),
269 MPP_MODE(35,
270 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
271 MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)),
272 MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1)),
273 MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)),
274 MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1)),
275 MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1))),
276 MPP_MODE(36,
277 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
278 MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1)),
279 MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1)),
280 MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1)),
281 MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1))),
282 MPP_MODE(37,
283 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
284 MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1)),
285 MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1)),
286 MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1)),
287 MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1))),
288 MPP_MODE(38,
289 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
290 MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1)),
291 MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1)),
292 MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1)),
293 MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1))),
294 MPP_MODE(39,
295 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
296 MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1)),
297 MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1)),
298 MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1)),
299 MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1))),
300 MPP_MODE(40,
301 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
302 MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1)),
303 MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1)),
304 MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1)),
305 MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1))),
306 MPP_MODE(41,
307 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
308 MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1)),
309 MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1)),
310 MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1)),
311 MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1))),
312 MPP_MODE(42,
313 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
314 MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1)),
315 MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1)),
316 MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1)),
317 MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1))),
318 MPP_MODE(43,
319 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
320 MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1)),
321 MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1)),
322 MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1)),
323 MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1))),
324 MPP_MODE(44,
325 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
326 MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1)),
327 MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1)),
328 MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1)),
329 MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1))),
330 MPP_MODE(45,
331 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
332 MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 1)),
333 MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 0, 1, 1)),
334 MPP_VAR_FUNCTION(0xb, "lcd", "e", V(0, 0, 0, 0, 1))),
335 MPP_MODE(46,
336 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
337 MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 0, 1, 1)),
338 MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 0, 1, 1)),
339 MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1))),
340 MPP_MODE(47,
341 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
342 MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 0, 1, 1)),
343 MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 0, 1, 1)),
344 MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))),
345 MPP_MODE(48,
346 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
347 MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 0, 1, 1)),
348 MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 0, 1, 1)),
349 MPP_VAR_FUNCTION(0xb, "lcd", "d16", V(0, 0, 0, 0, 1))),
350 MPP_MODE(49,
351 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)),
352 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 0, 0, 0, 1)),
353 MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 0)),
354 MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 0, 1, 1)),
355 MPP_VAR_FUNCTION(0x5, "ptp", "clk", V(0, 0, 0, 1, 0)),
356 MPP_VAR_FUNCTION(0xa, "pex", "clkreq", V(0, 0, 0, 0, 1)),
357 MPP_VAR_FUNCTION(0xb, "lcd", "d17", V(0, 0, 0, 0, 1))),
358};
359
360static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
361 MPP_REG_CTRL(0, 29),
362};
363
364static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
365 MPP_GPIO_RANGE(0, 0, 0, 30),
366};
367
368static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {
369 MPP_REG_CTRL(0, 35),
370};
371
372static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
373 MPP_GPIO_RANGE(0, 0, 0, 32),
374 MPP_GPIO_RANGE(1, 32, 32, 4),
375};
376
377static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = {
378 MPP_REG_CTRL(0, 49),
379};
380
381static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = {
382 MPP_GPIO_RANGE(0, 0, 0, 32),
383 MPP_GPIO_RANGE(1, 32, 32, 18),
384};
385
386static struct mvebu_pinctrl_soc_info mv88f6180_info = {
387 .variant = VARIANT_MV88F6180,
388 .controls = mv88f6180_mpp_controls,
389 .ncontrols = ARRAY_SIZE(mv88f6180_mpp_controls),
390 .modes = mv88f6xxx_mpp_modes,
391 .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
392 .gpioranges = mv88f6180_gpio_ranges,
393 .ngpioranges = ARRAY_SIZE(mv88f6180_gpio_ranges),
394};
395
396static struct mvebu_pinctrl_soc_info mv88f6190_info = {
397 .variant = VARIANT_MV88F6190,
398 .controls = mv88f619x_mpp_controls,
399 .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls),
400 .modes = mv88f6xxx_mpp_modes,
401 .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
402 .gpioranges = mv88f619x_gpio_ranges,
403 .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges),
404};
405
406static struct mvebu_pinctrl_soc_info mv88f6192_info = {
407 .variant = VARIANT_MV88F6192,
408 .controls = mv88f619x_mpp_controls,
409 .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls),
410 .modes = mv88f6xxx_mpp_modes,
411 .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
412 .gpioranges = mv88f619x_gpio_ranges,
413 .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges),
414};
415
416static struct mvebu_pinctrl_soc_info mv88f6281_info = {
417 .variant = VARIANT_MV88F6281,
418 .controls = mv88f628x_mpp_controls,
419 .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls),
420 .modes = mv88f6xxx_mpp_modes,
421 .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
422 .gpioranges = mv88f628x_gpio_ranges,
423 .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges),
424};
425
426static struct mvebu_pinctrl_soc_info mv88f6282_info = {
427 .variant = VARIANT_MV88F6282,
428 .controls = mv88f628x_mpp_controls,
429 .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls),
430 .modes = mv88f6xxx_mpp_modes,
431 .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
432 .gpioranges = mv88f628x_gpio_ranges,
433 .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges),
434};
435
436static struct of_device_id kirkwood_pinctrl_of_match[] __devinitdata = {
437 { .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info },
438 { .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info },
439 { .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info },
440 { .compatible = "marvell,88f6281-pinctrl", .data = &mv88f6281_info },
441 { .compatible = "marvell,88f6282-pinctrl", .data = &mv88f6282_info },
442 { }
443};
444
445static int __devinit kirkwood_pinctrl_probe(struct platform_device *pdev)
446{
447 const struct of_device_id *match =
448 of_match_device(kirkwood_pinctrl_of_match, &pdev->dev);
449 pdev->dev.platform_data = match->data;
450 return mvebu_pinctrl_probe(pdev);
451}
452
453static int __devexit kirkwood_pinctrl_remove(struct platform_device *pdev)
454{
455 return mvebu_pinctrl_remove(pdev);
456}
457
458static struct platform_driver kirkwood_pinctrl_driver = {
459 .driver = {
460 .name = "kirkwood-pinctrl",
461 .owner = THIS_MODULE,
462 .of_match_table = of_match_ptr(kirkwood_pinctrl_of_match),
463 },
464 .probe = kirkwood_pinctrl_probe,
465 .remove = __devexit_p(kirkwood_pinctrl_remove),
466};
467
468module_platform_driver(kirkwood_pinctrl_driver);
469
470MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>");
471MODULE_DESCRIPTION("Marvell Kirkwood pinctrl driver");
472MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/pinctrl-mvebu.c
new file mode 100644
index 000000000000..8e6266c6249a
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mvebu.c
@@ -0,0 +1,754 @@
1/*
2 * Marvell MVEBU pinctrl core driver
3 *
4 * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/platform_device.h>
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/io.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/of_platform.h>
20#include <linux/err.h>
21#include <linux/gpio.h>
22#include <linux/pinctrl/machine.h>
23#include <linux/pinctrl/pinconf.h>
24#include <linux/pinctrl/pinctrl.h>
25#include <linux/pinctrl/pinmux.h>
26
27#include "core.h"
28#include "pinctrl-mvebu.h"
29
30#define MPPS_PER_REG 8
31#define MPP_BITS 4
32#define MPP_MASK 0xf
33
34struct mvebu_pinctrl_function {
35 const char *name;
36 const char **groups;
37 unsigned num_groups;
38};
39
40struct mvebu_pinctrl_group {
41 const char *name;
42 struct mvebu_mpp_ctrl *ctrl;
43 struct mvebu_mpp_ctrl_setting *settings;
44 unsigned num_settings;
45 unsigned gid;
46 unsigned *pins;
47 unsigned npins;
48};
49
50struct mvebu_pinctrl {
51 struct device *dev;
52 struct pinctrl_dev *pctldev;
53 struct pinctrl_desc desc;
54 void __iomem *base;
55 struct mvebu_pinctrl_group *groups;
56 unsigned num_groups;
57 struct mvebu_pinctrl_function *functions;
58 unsigned num_functions;
59 u8 variant;
60};
61
62static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid(
63 struct mvebu_pinctrl *pctl, unsigned pid)
64{
65 unsigned n;
66 for (n = 0; n < pctl->num_groups; n++) {
67 if (pid >= pctl->groups[n].pins[0] &&
68 pid < pctl->groups[n].pins[0] +
69 pctl->groups[n].npins)
70 return &pctl->groups[n];
71 }
72 return NULL;
73}
74
75static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name(
76 struct mvebu_pinctrl *pctl, const char *name)
77{
78 unsigned n;
79 for (n = 0; n < pctl->num_groups; n++) {
80 if (strcmp(name, pctl->groups[n].name) == 0)
81 return &pctl->groups[n];
82 }
83 return NULL;
84}
85
86static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val(
87 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
88 unsigned long config)
89{
90 unsigned n;
91 for (n = 0; n < grp->num_settings; n++) {
92 if (config == grp->settings[n].val) {
93 if (!pctl->variant || (pctl->variant &
94 grp->settings[n].variant))
95 return &grp->settings[n];
96 }
97 }
98 return NULL;
99}
100
101static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name(
102 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
103 const char *name)
104{
105 unsigned n;
106 for (n = 0; n < grp->num_settings; n++) {
107 if (strcmp(name, grp->settings[n].name) == 0) {
108 if (!pctl->variant || (pctl->variant &
109 grp->settings[n].variant))
110 return &grp->settings[n];
111 }
112 }
113 return NULL;
114}
115
116static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting(
117 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp)
118{
119 unsigned n;
120 for (n = 0; n < grp->num_settings; n++) {
121 if (grp->settings[n].flags &
122 (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
123 if (!pctl->variant || (pctl->variant &
124 grp->settings[n].variant))
125 return &grp->settings[n];
126 }
127 }
128 return NULL;
129}
130
131static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
132 struct mvebu_pinctrl *pctl, const char *name)
133{
134 unsigned n;
135 for (n = 0; n < pctl->num_functions; n++) {
136 if (strcmp(name, pctl->functions[n].name) == 0)
137 return &pctl->functions[n];
138 }
139 return NULL;
140}
141
142/*
143 * Common mpp pin configuration registers on MVEBU are
144 * registers of eight 4-bit values for each mpp setting.
145 * Register offset and bit mask are calculated accordingly below.
146 */
147static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl,
148 struct mvebu_pinctrl_group *grp,
149 unsigned long *config)
150{
151 unsigned pin = grp->gid;
152 unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
153 unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
154
155 *config = readl(pctl->base + off);
156 *config >>= shift;
157 *config &= MPP_MASK;
158
159 return 0;
160}
161
162static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl,
163 struct mvebu_pinctrl_group *grp,
164 unsigned long config)
165{
166 unsigned pin = grp->gid;
167 unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
168 unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
169 unsigned long reg;
170
171 reg = readl(pctl->base + off);
172 reg &= ~(MPP_MASK << shift);
173 reg |= (config << shift);
174 writel(reg, pctl->base + off);
175
176 return 0;
177}
178
179static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
180 unsigned gid, unsigned long *config)
181{
182 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
183 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
184
185 if (!grp->ctrl)
186 return -EINVAL;
187
188 if (grp->ctrl->mpp_get)
189 return grp->ctrl->mpp_get(grp->ctrl, config);
190
191 return mvebu_common_mpp_get(pctl, grp, config);
192}
193
194static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
195 unsigned gid, unsigned long config)
196{
197 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
198 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
199
200 if (!grp->ctrl)
201 return -EINVAL;
202
203 if (grp->ctrl->mpp_set)
204 return grp->ctrl->mpp_set(grp->ctrl, config);
205
206 return mvebu_common_mpp_set(pctl, grp, config);
207}
208
209static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
210 struct seq_file *s, unsigned gid)
211{
212 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
213 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
214 struct mvebu_mpp_ctrl_setting *curr;
215 unsigned long config;
216 unsigned n;
217
218 if (mvebu_pinconf_group_get(pctldev, gid, &config))
219 return;
220
221 curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config);
222
223 if (curr) {
224 seq_printf(s, "current: %s", curr->name);
225 if (curr->subname)
226 seq_printf(s, "(%s)", curr->subname);
227 if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
228 seq_printf(s, "(");
229 if (curr->flags & MVEBU_SETTING_GPI)
230 seq_printf(s, "i");
231 if (curr->flags & MVEBU_SETTING_GPO)
232 seq_printf(s, "o");
233 seq_printf(s, ")");
234 }
235 } else
236 seq_printf(s, "current: UNKNOWN");
237
238 if (grp->num_settings > 1) {
239 seq_printf(s, ", available = [");
240 for (n = 0; n < grp->num_settings; n++) {
241 if (curr == &grp->settings[n])
242 continue;
243
244 /* skip unsupported settings for this variant */
245 if (pctl->variant &&
246 !(pctl->variant & grp->settings[n].variant))
247 continue;
248
249 seq_printf(s, " %s", grp->settings[n].name);
250 if (grp->settings[n].subname)
251 seq_printf(s, "(%s)", grp->settings[n].subname);
252 if (grp->settings[n].flags &
253 (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
254 seq_printf(s, "(");
255 if (grp->settings[n].flags & MVEBU_SETTING_GPI)
256 seq_printf(s, "i");
257 if (grp->settings[n].flags & MVEBU_SETTING_GPO)
258 seq_printf(s, "o");
259 seq_printf(s, ")");
260 }
261 }
262 seq_printf(s, " ]");
263 }
264 return;
265}
266
267static struct pinconf_ops mvebu_pinconf_ops = {
268 .pin_config_group_get = mvebu_pinconf_group_get,
269 .pin_config_group_set = mvebu_pinconf_group_set,
270 .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show,
271};
272
273static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
274{
275 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
276
277 return pctl->num_functions;
278}
279
280static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev,
281 unsigned fid)
282{
283 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
284
285 return pctl->functions[fid].name;
286}
287
288static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid,
289 const char * const **groups,
290 unsigned * const num_groups)
291{
292 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
293
294 *groups = pctl->functions[fid].groups;
295 *num_groups = pctl->functions[fid].num_groups;
296 return 0;
297}
298
299static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
300 unsigned gid)
301{
302 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
303 struct mvebu_pinctrl_function *func = &pctl->functions[fid];
304 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
305 struct mvebu_mpp_ctrl_setting *setting;
306 int ret;
307
308 setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
309 func->name);
310 if (!setting) {
311 dev_err(pctl->dev,
312 "unable to find setting %s in group %s\n",
313 func->name, func->groups[gid]);
314 return -EINVAL;
315 }
316
317 ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
318 if (ret) {
319 dev_err(pctl->dev, "cannot set group %s to %s\n",
320 func->groups[gid], func->name);
321 return ret;
322 }
323
324 return 0;
325}
326
327static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
328 struct pinctrl_gpio_range *range, unsigned offset)
329{
330 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
331 struct mvebu_pinctrl_group *grp;
332 struct mvebu_mpp_ctrl_setting *setting;
333
334 grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
335 if (!grp)
336 return -EINVAL;
337
338 if (grp->ctrl->mpp_gpio_req)
339 return grp->ctrl->mpp_gpio_req(grp->ctrl, offset);
340
341 setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
342 if (!setting)
343 return -ENOTSUPP;
344
345 return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
346}
347
348static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
349 struct pinctrl_gpio_range *range, unsigned offset, bool input)
350{
351 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
352 struct mvebu_pinctrl_group *grp;
353 struct mvebu_mpp_ctrl_setting *setting;
354
355 grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
356 if (!grp)
357 return -EINVAL;
358
359 if (grp->ctrl->mpp_gpio_dir)
360 return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input);
361
362 setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
363 if (!setting)
364 return -ENOTSUPP;
365
366 if ((input && (setting->flags & MVEBU_SETTING_GPI)) ||
367 (!input && (setting->flags & MVEBU_SETTING_GPO)))
368 return 0;
369
370 return -ENOTSUPP;
371}
372
373static struct pinmux_ops mvebu_pinmux_ops = {
374 .get_functions_count = mvebu_pinmux_get_funcs_count,
375 .get_function_name = mvebu_pinmux_get_func_name,
376 .get_function_groups = mvebu_pinmux_get_groups,
377 .gpio_request_enable = mvebu_pinmux_gpio_request_enable,
378 .gpio_set_direction = mvebu_pinmux_gpio_set_direction,
379 .enable = mvebu_pinmux_enable,
380};
381
382static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
383{
384 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
385 return pctl->num_groups;
386}
387
388static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
389 unsigned gid)
390{
391 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
392 return pctl->groups[gid].name;
393}
394
395static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
396 unsigned gid, const unsigned **pins,
397 unsigned *num_pins)
398{
399 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
400 *pins = pctl->groups[gid].pins;
401 *num_pins = pctl->groups[gid].npins;
402 return 0;
403}
404
405static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
406 struct device_node *np,
407 struct pinctrl_map **map,
408 unsigned *num_maps)
409{
410 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
411 struct property *prop;
412 const char *function;
413 const char *group;
414 int ret, nmaps, n;
415
416 *map = NULL;
417 *num_maps = 0;
418
419 ret = of_property_read_string(np, "marvell,function", &function);
420 if (ret) {
421 dev_err(pctl->dev,
422 "missing marvell,function in node %s\n", np->name);
423 return 0;
424 }
425
426 nmaps = of_property_count_strings(np, "marvell,pins");
427 if (nmaps < 0) {
428 dev_err(pctl->dev,
429 "missing marvell,pins in node %s\n", np->name);
430 return 0;
431 }
432
433 *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
434 if (map == NULL) {
435 dev_err(pctl->dev,
436 "cannot allocate pinctrl_map memory for %s\n",
437 np->name);
438 return -ENOMEM;
439 }
440
441 n = 0;
442 of_property_for_each_string(np, "marvell,pins", prop, group) {
443 struct mvebu_pinctrl_group *grp =
444 mvebu_pinctrl_find_group_by_name(pctl, group);
445
446 if (!grp) {
447 dev_err(pctl->dev, "unknown pin %s", group);
448 continue;
449 }
450
451 if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, function)) {
452 dev_err(pctl->dev, "unsupported function %s on pin %s",
453 function, group);
454 continue;
455 }
456
457 (*map)[n].type = PIN_MAP_TYPE_MUX_GROUP;
458 (*map)[n].data.mux.group = group;
459 (*map)[n].data.mux.function = function;
460 n++;
461 }
462
463 *num_maps = nmaps;
464
465 return 0;
466}
467
468static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
469 struct pinctrl_map *map, unsigned num_maps)
470{
471 kfree(map);
472}
473
474static struct pinctrl_ops mvebu_pinctrl_ops = {
475 .get_groups_count = mvebu_pinctrl_get_groups_count,
476 .get_group_name = mvebu_pinctrl_get_group_name,
477 .get_group_pins = mvebu_pinctrl_get_group_pins,
478 .dt_node_to_map = mvebu_pinctrl_dt_node_to_map,
479 .dt_free_map = mvebu_pinctrl_dt_free_map,
480};
481
482static int __devinit _add_function(struct mvebu_pinctrl_function *funcs,
483 const char *name)
484{
485 while (funcs->num_groups) {
486 /* function already there */
487 if (strcmp(funcs->name, name) == 0) {
488 funcs->num_groups++;
489 return -EEXIST;
490 }
491 funcs++;
492 }
493 funcs->name = name;
494 funcs->num_groups = 1;
495 return 0;
496}
497
498static int __devinit mvebu_pinctrl_build_functions(struct platform_device *pdev,
499 struct mvebu_pinctrl *pctl)
500{
501 struct mvebu_pinctrl_function *funcs;
502 int num = 0;
503 int n, s;
504
505 /* we allocate functions for number of pins and hope
506 * there are less unique functions than pins available */
507 funcs = devm_kzalloc(&pdev->dev, pctl->desc.npins *
508 sizeof(struct mvebu_pinctrl_function), GFP_KERNEL);
509 if (!funcs)
510 return -ENOMEM;
511
512 for (n = 0; n < pctl->num_groups; n++) {
513 struct mvebu_pinctrl_group *grp = &pctl->groups[n];
514 for (s = 0; s < grp->num_settings; s++) {
515 /* skip unsupported settings on this variant */
516 if (pctl->variant &&
517 !(pctl->variant & grp->settings[s].variant))
518 continue;
519
520 /* check for unique functions and count groups */
521 if (_add_function(funcs, grp->settings[s].name))
522 continue;
523
524 num++;
525 }
526 }
527
528 /* with the number of unique functions and it's groups known,
529 reallocate functions and assign group names */
530 funcs = krealloc(funcs, num * sizeof(struct mvebu_pinctrl_function),
531 GFP_KERNEL);
532 if (!funcs)
533 return -ENOMEM;
534
535 pctl->num_functions = num;
536 pctl->functions = funcs;
537
538 for (n = 0; n < pctl->num_groups; n++) {
539 struct mvebu_pinctrl_group *grp = &pctl->groups[n];
540 for (s = 0; s < grp->num_settings; s++) {
541 struct mvebu_pinctrl_function *f;
542 const char **groups;
543
544 /* skip unsupported settings on this variant */
545 if (pctl->variant &&
546 !(pctl->variant & grp->settings[s].variant))
547 continue;
548
549 f = mvebu_pinctrl_find_function_by_name(pctl,
550 grp->settings[s].name);
551
552 /* allocate group name array if not done already */
553 if (!f->groups) {
554 f->groups = devm_kzalloc(&pdev->dev,
555 f->num_groups * sizeof(char *),
556 GFP_KERNEL);
557 if (!f->groups)
558 return -ENOMEM;
559 }
560
561 /* find next free group name and assign current name */
562 groups = f->groups;
563 while (*groups)
564 groups++;
565 *groups = grp->name;
566 }
567 }
568
569 return 0;
570}
571
572int __devinit mvebu_pinctrl_probe(struct platform_device *pdev)
573{
574 struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
575 struct device_node *np = pdev->dev.of_node;
576 struct mvebu_pinctrl *pctl;
577 void __iomem *base;
578 struct pinctrl_pin_desc *pdesc;
579 unsigned gid, n, k;
580 int ret;
581
582 if (!soc || !soc->controls || !soc->modes) {
583 dev_err(&pdev->dev, "wrong pinctrl soc info\n");
584 return -EINVAL;
585 }
586
587 base = of_iomap(np, 0);
588 if (!base) {
589 dev_err(&pdev->dev, "unable to get base address\n");
590 return -ENODEV;
591 }
592
593 pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
594 GFP_KERNEL);
595 if (!pctl) {
596 dev_err(&pdev->dev, "unable to alloc driver\n");
597 return -ENOMEM;
598 }
599
600 pctl->desc.name = dev_name(&pdev->dev);
601 pctl->desc.owner = THIS_MODULE;
602 pctl->desc.pctlops = &mvebu_pinctrl_ops;
603 pctl->desc.pmxops = &mvebu_pinmux_ops;
604 pctl->desc.confops = &mvebu_pinconf_ops;
605 pctl->variant = soc->variant;
606 pctl->base = base;
607 pctl->dev = &pdev->dev;
608 platform_set_drvdata(pdev, pctl);
609
610 /* count controls and create names for mvebu generic
611 register controls; also does sanity checks */
612 pctl->num_groups = 0;
613 pctl->desc.npins = 0;
614 for (n = 0; n < soc->ncontrols; n++) {
615 struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
616 char *names;
617
618 pctl->desc.npins += ctrl->npins;
619 /* initial control pins */
620 for (k = 0; k < ctrl->npins; k++)
621 ctrl->pins[k] = ctrl->pid + k;
622
623 /* special soc specific control */
624 if (ctrl->mpp_get || ctrl->mpp_set) {
625 if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) {
626 dev_err(&pdev->dev, "wrong soc control info\n");
627 return -EINVAL;
628 }
629 pctl->num_groups += 1;
630 continue;
631 }
632
633 /* generic mvebu register control */
634 names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL);
635 if (!names) {
636 dev_err(&pdev->dev, "failed to alloc mpp names\n");
637 return -ENOMEM;
638 }
639 for (k = 0; k < ctrl->npins; k++)
640 sprintf(names + 8*k, "mpp%d", ctrl->pid+k);
641 ctrl->name = names;
642 pctl->num_groups += ctrl->npins;
643 }
644
645 pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *
646 sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
647 if (!pdesc) {
648 dev_err(&pdev->dev, "failed to alloc pinctrl pins\n");
649 return -ENOMEM;
650 }
651
652 for (n = 0; n < pctl->desc.npins; n++)
653 pdesc[n].number = n;
654 pctl->desc.pins = pdesc;
655
656 pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups *
657 sizeof(struct mvebu_pinctrl_group), GFP_KERNEL);
658 if (!pctl->groups) {
659 dev_err(&pdev->dev, "failed to alloc pinctrl groups\n");
660 return -ENOMEM;
661 }
662
663 /* assign mpp controls to groups */
664 gid = 0;
665 for (n = 0; n < soc->ncontrols; n++) {
666 struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
667 pctl->groups[gid].gid = gid;
668 pctl->groups[gid].ctrl = ctrl;
669 pctl->groups[gid].name = ctrl->name;
670 pctl->groups[gid].pins = ctrl->pins;
671 pctl->groups[gid].npins = ctrl->npins;
672
673 /* generic mvebu register control maps to a number of groups */
674 if (!ctrl->mpp_get && !ctrl->mpp_set) {
675 pctl->groups[gid].npins = 1;
676
677 for (k = 1; k < ctrl->npins; k++) {
678 gid++;
679 pctl->groups[gid].gid = gid;
680 pctl->groups[gid].ctrl = ctrl;
681 pctl->groups[gid].name = &ctrl->name[8*k];
682 pctl->groups[gid].pins = &ctrl->pins[k];
683 pctl->groups[gid].npins = 1;
684 }
685 }
686 gid++;
687 }
688
689 /* assign mpp modes to groups */
690 for (n = 0; n < soc->nmodes; n++) {
691 struct mvebu_mpp_mode *mode = &soc->modes[n];
692 struct mvebu_pinctrl_group *grp =
693 mvebu_pinctrl_find_group_by_pid(pctl, mode->pid);
694 unsigned num_settings;
695
696 if (!grp) {
697 dev_warn(&pdev->dev, "unknown pinctrl group %d\n",
698 mode->pid);
699 continue;
700 }
701
702 for (num_settings = 0; ;) {
703 struct mvebu_mpp_ctrl_setting *set =
704 &mode->settings[num_settings];
705
706 if (!set->name)
707 break;
708 num_settings++;
709
710 /* skip unsupported settings for this variant */
711 if (pctl->variant && !(pctl->variant & set->variant))
712 continue;
713
714 /* find gpio/gpo/gpi settings */
715 if (strcmp(set->name, "gpio") == 0)
716 set->flags = MVEBU_SETTING_GPI |
717 MVEBU_SETTING_GPO;
718 else if (strcmp(set->name, "gpo") == 0)
719 set->flags = MVEBU_SETTING_GPO;
720 else if (strcmp(set->name, "gpi") == 0)
721 set->flags = MVEBU_SETTING_GPI;
722 }
723
724 grp->settings = mode->settings;
725 grp->num_settings = num_settings;
726 }
727
728 ret = mvebu_pinctrl_build_functions(pdev, pctl);
729 if (ret) {
730 dev_err(&pdev->dev, "unable to build functions\n");
731 return ret;
732 }
733
734 pctl->pctldev = pinctrl_register(&pctl->desc, &pdev->dev, pctl);
735 if (!pctl->pctldev) {
736 dev_err(&pdev->dev, "unable to register pinctrl driver\n");
737 return -EINVAL;
738 }
739
740 dev_info(&pdev->dev, "registered pinctrl driver\n");
741
742 /* register gpio ranges */
743 for (n = 0; n < soc->ngpioranges; n++)
744 pinctrl_add_gpio_range(pctl->pctldev, &soc->gpioranges[n]);
745
746 return 0;
747}
748
749int __devexit mvebu_pinctrl_remove(struct platform_device *pdev)
750{
751 struct mvebu_pinctrl *pctl = platform_get_drvdata(pdev);
752 pinctrl_unregister(pctl->pctldev);
753 return 0;
754}
diff --git a/drivers/pinctrl/pinctrl-mvebu.h b/drivers/pinctrl/pinctrl-mvebu.h
new file mode 100644
index 000000000000..90bd3beee860
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mvebu.h
@@ -0,0 +1,192 @@
1/*
2 * Marvell MVEBU pinctrl driver
3 *
4 * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef __PINCTRL_MVEBU_H__
14#define __PINCTRL_MVEBU_H__
15
16/**
17 * struct mvebu_mpp_ctrl - describe a mpp control
18 * @name: name of the control group
19 * @pid: first pin id handled by this control
20 * @npins: number of pins controlled by this control
21 * @mpp_get: (optional) special function to get mpp setting
22 * @mpp_set: (optional) special function to set mpp setting
23 * @mpp_gpio_req: (optional) special function to request gpio
24 * @mpp_gpio_dir: (optional) special function to set gpio direction
25 *
26 * A mpp_ctrl describes a muxable unit, e.g. pin, group of pins, or
27 * internal function, inside the SoC. Each muxable unit can be switched
28 * between two or more different settings, e.g. assign mpp pin 13 to
29 * uart1 or sata.
30 *
31 * If optional mpp_get/_set functions are set these are used to get/set
32 * a specific mode. Otherwise it is assumed that the mpp control is based
33 * on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir
34 * functions can be used to allow pin settings with varying gpio pins.
35 */
36struct mvebu_mpp_ctrl {
37 const char *name;
38 u8 pid;
39 u8 npins;
40 unsigned *pins;
41 int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config);
42 int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config);
43 int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid);
44 int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input);
45};
46
47/**
48 * struct mvebu_mpp_ctrl_setting - describe a mpp ctrl setting
49 * @val: ctrl setting value
50 * @name: ctrl setting name, e.g. uart2, spi0 - unique per mpp_mode
51 * @subname: (optional) additional ctrl setting name, e.g. rts, cts
52 * @variant: (optional) variant identifier mask
53 * @flags: (private) flags to store gpi/gpo/gpio capabilities
54 *
55 * A ctrl_setting describes a specific internal mux function that a mpp pin
56 * can be switched to. The value (val) will be written in the corresponding
57 * register for common mpp pin configuration registers on MVEBU. SoC specific
58 * mpp_get/_set function may use val to distinguish between different settings.
59 *
60 * The name will be used to switch to this setting in DT description, e.g.
61 * marvell,function = "uart2". subname is only for debugging purposes.
62 *
63 * If name is one of "gpi", "gpo", "gpio" gpio capabilities are
64 * parsed during initialization and stored in flags.
65 *
66 * The variant can be used to combine different revisions of one SoC to a
67 * common pinctrl driver. It is matched (AND) with variant of soc_info to
68 * determine if a setting is available on the current SoC revision.
69 */
70struct mvebu_mpp_ctrl_setting {
71 u8 val;
72 const char *name;
73 const char *subname;
74 u8 variant;
75 u8 flags;
76#define MVEBU_SETTING_GPO (1 << 0)
77#define MVEBU_SETTING_GPI (1 << 1)
78};
79
80/**
81 * struct mvebu_mpp_mode - link ctrl and settings
82 * @pid: first pin id handled by this mode
83 * @settings: list of settings available for this mode
84 *
85 * A mode connects all available settings with the corresponding mpp_ctrl
86 * given by pid.
87 */
88struct mvebu_mpp_mode {
89 u8 pid;
90 struct mvebu_mpp_ctrl_setting *settings;
91};
92
93/**
94 * struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu
95 * @variant: variant mask of soc_info
96 * @controls: list of available mvebu_mpp_ctrls
97 * @ncontrols: number of available mvebu_mpp_ctrls
98 * @modes: list of available mvebu_mpp_modes
99 * @nmodes: number of available mvebu_mpp_modes
100 * @gpioranges: list of pinctrl_gpio_ranges
101 * @ngpioranges: number of available pinctrl_gpio_ranges
102 *
103 * This struct describes all pinctrl related information for a specific SoC.
104 * If variant is unequal 0 it will be matched (AND) with variant of each
105 * setting and allows to distinguish between different revisions of one SoC.
106 */
107struct mvebu_pinctrl_soc_info {
108 u8 variant;
109 struct mvebu_mpp_ctrl *controls;
110 int ncontrols;
111 struct mvebu_mpp_mode *modes;
112 int nmodes;
113 struct pinctrl_gpio_range *gpioranges;
114 int ngpioranges;
115};
116
117#define MPP_REG_CTRL(_idl, _idh) \
118 { \
119 .name = NULL, \
120 .pid = _idl, \
121 .npins = _idh - _idl + 1, \
122 .pins = (unsigned[_idh - _idl + 1]) { }, \
123 .mpp_get = NULL, \
124 .mpp_set = NULL, \
125 .mpp_gpio_req = NULL, \
126 .mpp_gpio_dir = NULL, \
127 }
128
129#define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \
130 { \
131 .name = _name, \
132 .pid = _idl, \
133 .npins = _idh - _idl + 1, \
134 .pins = (unsigned[_idh - _idl + 1]) { }, \
135 .mpp_get = _func ## _get, \
136 .mpp_set = _func ## _set, \
137 .mpp_gpio_req = NULL, \
138 .mpp_gpio_dir = NULL, \
139 }
140
141#define MPP_FUNC_GPIO_CTRL(_idl, _idh, _name, _func) \
142 { \
143 .name = _name, \
144 .pid = _idl, \
145 .npins = _idh - _idl + 1, \
146 .pins = (unsigned[_idh - _idl + 1]) { }, \
147 .mpp_get = _func ## _get, \
148 .mpp_set = _func ## _set, \
149 .mpp_gpio_req = _func ## _gpio_req, \
150 .mpp_gpio_dir = _func ## _gpio_dir, \
151 }
152
153#define _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \
154 { \
155 .val = _val, \
156 .name = _name, \
157 .subname = _subname, \
158 .variant = _mask, \
159 .flags = 0, \
160 }
161
162#if defined(CONFIG_DEBUG_FS)
163#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \
164 _MPP_VAR_FUNCTION(_val, _name, _subname, _mask)
165#else
166#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \
167 _MPP_VAR_FUNCTION(_val, _name, NULL, _mask)
168#endif
169
170#define MPP_FUNCTION(_val, _name, _subname) \
171 MPP_VAR_FUNCTION(_val, _name, _subname, (u8)-1)
172
173#define MPP_MODE(_id, ...) \
174 { \
175 .pid = _id, \
176 .settings = (struct mvebu_mpp_ctrl_setting[]){ \
177 __VA_ARGS__, { } }, \
178 }
179
180#define MPP_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins) \
181 { \
182 .name = "mvebu-gpio", \
183 .id = _id, \
184 .pin_base = _pinbase, \
185 .base = _gpiobase, \
186 .npins = _npins, \
187 }
188
189int mvebu_pinctrl_probe(struct platform_device *pdev);
190int mvebu_pinctrl_remove(struct platform_device *pdev);
191
192#endif