diff options
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 | |||
3 | Required 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 | |||
41 | Example: | ||
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 | |||
3 | Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding | ||
4 | part and usage. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "marvell,88f6710-pinctrl" | ||
8 | |||
9 | Available mpp pins/groups and functions: | ||
10 | Note: brackets (x) are not part of the mpp name for marvell,function and given | ||
11 | only for more detailed description in this document. | ||
12 | |||
13 | name pins functions | ||
14 | ================================================================================ | ||
15 | mpp0 0 gpio, uart0(rxd) | ||
16 | mpp1 1 gpo, uart0(txd) | ||
17 | mpp2 2 gpio, i2c0(sck), uart0(txd) | ||
18 | mpp3 3 gpio, i2c0(sda), uart0(rxd) | ||
19 | mpp4 4 gpio, cpu_pd(vdd) | ||
20 | mpp5 5 gpo, ge0(txclko), uart1(txd), spi1(clk), audio(mclk) | ||
21 | mpp6 6 gpio, ge0(txd0), sata0(prsnt), tdm(rst), audio(sdo) | ||
22 | mpp7 7 gpo, ge0(txd1), tdm(tdx), audio(lrclk) | ||
23 | mpp8 8 gpio, ge0(txd2), uart0(rts), tdm(drx), audio(bclk) | ||
24 | mpp9 9 gpo, ge0(txd3), uart1(txd), sd0(clk), audio(spdifo) | ||
25 | mpp10 10 gpio, ge0(txctl), uart0(cts), tdm(fsync), audio(sdi) | ||
26 | mpp11 11 gpio, ge0(rxd0), uart1(rxd), sd0(cmd), spi0(cs1), | ||
27 | sata1(prsnt), spi1(cs1) | ||
28 | mpp12 12 gpio, ge0(rxd1), i2c1(sda), sd0(d0), spi1(cs0), | ||
29 | audio(spdifi) | ||
30 | mpp13 13 gpio, ge0(rxd2), i2c1(sck), sd0(d1), tdm(pclk), | ||
31 | audio(rmclk) | ||
32 | mpp14 14 gpio, ge0(rxd3), pcie(clkreq0), sd0(d2), spi1(mosi), | ||
33 | spi0(cs2) | ||
34 | mpp15 15 gpio, ge0(rxctl), pcie(clkreq1), sd0(d3), spi1(miso), | ||
35 | spi0(cs3) | ||
36 | mpp16 16 gpio, ge0(rxclk), uart1(rxd), tdm(int), audio(extclk) | ||
37 | mpp17 17 gpo, ge(mdc) | ||
38 | mpp18 18 gpio, ge(mdio) | ||
39 | mpp19 19 gpio, ge0(txclk), ge1(txclkout), tdm(pclk) | ||
40 | mpp20 20 gpo, ge0(txd4), ge1(txd0) | ||
41 | mpp21 21 gpo, ge0(txd5), ge1(txd1), uart1(txd) | ||
42 | mpp22 22 gpo, ge0(txd6), ge1(txd2), uart0(rts) | ||
43 | mpp23 23 gpo, ge0(txd7), ge1(txd3), spi1(mosi) | ||
44 | mpp24 24 gpio, ge0(col), ge1(txctl), spi1(cs0) | ||
45 | mpp25 25 gpio, ge0(rxerr), ge1(rxd0), uart1(rxd) | ||
46 | mpp26 26 gpio, ge0(crs), ge1(rxd1), spi1(miso) | ||
47 | mpp27 27 gpio, ge0(rxd4), ge1(rxd2), uart0(cts) | ||
48 | mpp28 28 gpio, ge0(rxd5), ge1(rxd3) | ||
49 | mpp29 29 gpio, ge0(rxd6), ge1(rxctl), i2c1(sda) | ||
50 | mpp30 30 gpio, ge0(rxd7), ge1(rxclk), i2c1(sck) | ||
51 | mpp31 31 gpio, tclk, ge0(txerr) | ||
52 | mpp32 32 gpio, spi0(cs0) | ||
53 | mpp33 33 gpio, dev(bootcs), spi0(cs0) | ||
54 | mpp34 34 gpo, dev(wen0), spi0(mosi) | ||
55 | mpp35 35 gpo, dev(oen), spi0(sck) | ||
56 | mpp36 36 gpo, dev(a1), spi0(miso) | ||
57 | mpp37 37 gpo, dev(a0), sata0(prsnt) | ||
58 | mpp38 38 gpio, dev(ready), uart1(cts), uart0(cts) | ||
59 | mpp39 39 gpo, dev(ad0), audio(spdifo) | ||
60 | mpp40 40 gpio, dev(ad1), uart1(rts), uart0(rts) | ||
61 | mpp41 41 gpio, dev(ad2), uart1(rxd) | ||
62 | mpp42 42 gpo, dev(ad3), uart1(txd) | ||
63 | mpp43 43 gpo, dev(ad4), audio(bclk) | ||
64 | mpp44 44 gpo, dev(ad5), audio(mclk) | ||
65 | mpp45 45 gpo, dev(ad6), audio(lrclk) | ||
66 | mpp46 46 gpo, dev(ad7), audio(sdo) | ||
67 | mpp47 47 gpo, dev(ad8), sd0(clk), audio(spdifo) | ||
68 | mpp48 48 gpio, dev(ad9), uart0(rts), sd0(cmd), sata1(prsnt), | ||
69 | spi0(cs1) | ||
70 | mpp49 49 gpio, dev(ad10), pcie(clkreq1), sd0(d0), spi1(cs0), | ||
71 | audio(spdifi) | ||
72 | mpp50 50 gpio, dev(ad11), uart0(cts), sd0(d1), spi1(miso), | ||
73 | audio(rmclk) | ||
74 | mpp51 51 gpio, dev(ad12), i2c1(sda), sd0(d2), spi1(mosi) | ||
75 | mpp52 52 gpio, dev(ad13), i2c1(sck), sd0(d3), spi1(sck) | ||
76 | mpp53 53 gpio, dev(ad14), sd0(clk), tdm(pclk), spi0(cs2), | ||
77 | pcie(clkreq1) | ||
78 | mpp54 54 gpo, dev(ad15), tdm(dtx) | ||
79 | mpp55 55 gpio, dev(cs1), uart1(txd), tdm(rst), sata1(prsnt), | ||
80 | sata0(prsnt) | ||
81 | mpp56 56 gpio, dev(cs2), uart1(cts), uart0(cts), spi0(cs3), | ||
82 | pcie(clkreq0), spi1(cs1) | ||
83 | mpp57 57 gpio, dev(cs3), uart1(rxd), tdm(fsync), sata0(prsnt), | ||
84 | audio(sdo) | ||
85 | mpp58 58 gpio, dev(cs0), uart1(rts), tdm(int), audio(extclk), | ||
86 | uart0(rts) | ||
87 | mpp59 59 gpo, dev(ale0), uart1(rts), uart0(rts), audio(bclk) | ||
88 | mpp60 60 gpio, dev(ale1), uart1(rxd), sata0(prsnt), pcie(rst-out), | ||
89 | audio(sdi) | ||
90 | mpp61 61 gpo, dev(wen1), uart1(txd), audio(rclk) | ||
91 | mpp62 62 gpio, dev(a2), uart1(cts), tdm(drx), pcie(clkreq0), | ||
92 | audio(mclk), uart0(cts) | ||
93 | mpp63 63 gpo, spi0(sck), tclk | ||
94 | mpp64 64 gpio, spi0(miso), spi0-1(cs1) | ||
95 | mpp65 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 | |||
3 | Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding | ||
4 | part and usage. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "marvell,mv78230-pinctrl", "marvell,mv78260-pinctrl", | ||
8 | "marvell,mv78460-pinctrl" | ||
9 | |||
10 | This driver supports all Armada XP variants, i.e. mv78230, mv78260, and mv78460. | ||
11 | |||
12 | Available mpp pins/groups and functions: | ||
13 | Note: brackets (x) are not part of the mpp name for marvell,function and given | ||
14 | only for more detailed description in this document. | ||
15 | |||
16 | * Marvell Armada XP (all variants) | ||
17 | |||
18 | name pins functions | ||
19 | ================================================================================ | ||
20 | mpp0 0 gpio, ge0(txclko), lcd(d0) | ||
21 | mpp1 1 gpio, ge0(txd0), lcd(d1) | ||
22 | mpp2 2 gpio, ge0(txd1), lcd(d2) | ||
23 | mpp3 3 gpio, ge0(txd2), lcd(d3) | ||
24 | mpp4 4 gpio, ge0(txd3), lcd(d4) | ||
25 | mpp5 5 gpio, ge0(txctl), lcd(d5) | ||
26 | mpp6 6 gpio, ge0(rxd0), lcd(d6) | ||
27 | mpp7 7 gpio, ge0(rxd1), lcd(d7) | ||
28 | mpp8 8 gpio, ge0(rxd2), lcd(d8) | ||
29 | mpp9 9 gpio, ge0(rxd3), lcd(d9) | ||
30 | mpp10 10 gpio, ge0(rxctl), lcd(d10) | ||
31 | mpp11 11 gpio, ge0(rxclk), lcd(d11) | ||
32 | mpp12 12 gpio, ge0(txd4), ge1(txd0), lcd(d12) | ||
33 | mpp13 13 gpio, ge0(txd5), ge1(txd1), lcd(d13) | ||
34 | mpp14 14 gpio, ge0(txd6), ge1(txd2), lcd(d15) | ||
35 | mpp15 15 gpio, ge0(txd7), ge1(txd3), lcd(d16) | ||
36 | mpp16 16 gpio, ge0(txd7), ge1(txd3), lcd(d16) | ||
37 | mpp17 17 gpio, ge0(col), ge1(txctl), lcd(d17) | ||
38 | mpp18 18 gpio, ge0(rxerr), ge1(rxd0), lcd(d18), ptp(trig) | ||
39 | mpp19 19 gpio, ge0(crs), ge1(rxd1), lcd(d19), ptp(evreq) | ||
40 | mpp20 20 gpio, ge0(rxd4), ge1(rxd2), lcd(d20), ptp(clk) | ||
41 | mpp21 21 gpio, ge0(rxd5), ge1(rxd3), lcd(d21), mem(bat) | ||
42 | mpp22 22 gpio, ge0(rxd6), ge1(rxctl), lcd(d22), sata0(prsnt) | ||
43 | mpp23 23 gpio, ge0(rxd7), ge1(rxclk), lcd(d23), sata1(prsnt) | ||
44 | mpp24 24 gpio, lcd(hsync), sata1(prsnt), nf(bootcs-re), tdm(rst) | ||
45 | mpp25 25 gpio, lcd(vsync), sata0(prsnt), nf(bootcs-we), tdm(pclk) | ||
46 | mpp26 26 gpio, lcd(clk), tdm(fsync), vdd(cpu1-pd) | ||
47 | mpp27 27 gpio, lcd(e), tdm(dtx), ptp(trig) | ||
48 | mpp28 28 gpio, lcd(pwm), tdm(drx), ptp(evreq) | ||
49 | mpp29 29 gpio, lcd(ref-clk), tdm(int0), ptp(clk), vdd(cpu0-pd) | ||
50 | mpp30 30 gpio, tdm(int1), sd0(clk) | ||
51 | mpp31 31 gpio, tdm(int2), sd0(cmd), vdd(cpu0-pd) | ||
52 | mpp32 32 gpio, tdm(int3), sd0(d0), vdd(cpu1-pd) | ||
53 | mpp33 33 gpio, tdm(int4), sd0(d1), mem(bat) | ||
54 | mpp34 34 gpio, tdm(int5), sd0(d2), sata0(prsnt) | ||
55 | mpp35 35 gpio, tdm(int6), sd0(d3), sata1(prsnt) | ||
56 | mpp36 36 gpio, spi(mosi) | ||
57 | mpp37 37 gpio, spi(miso) | ||
58 | mpp38 38 gpio, spi(sck) | ||
59 | mpp39 39 gpio, spi(cs0) | ||
60 | mpp40 40 gpio, spi(cs1), uart2(cts), lcd(vga-hsync), vdd(cpu1-pd), | ||
61 | pcie(clkreq0) | ||
62 | mpp41 41 gpio, spi(cs2), uart2(rts), lcd(vga-vsync), sata1(prsnt), | ||
63 | pcie(clkreq1) | ||
64 | mpp42 42 gpio, uart2(rxd), uart0(cts), tdm(int7), tdm-1(timer), | ||
65 | vdd(cpu0-pd) | ||
66 | mpp43 43 gpio, uart2(txd), uart0(rts), spi(cs3), pcie(rstout), | ||
67 | vdd(cpu2-3-pd){1} | ||
68 | mpp44 44 gpio, uart2(cts), uart3(rxd), spi(cs4), pcie(clkreq2), | ||
69 | mem(bat) | ||
70 | mpp45 45 gpio, uart2(rts), uart3(txd), spi(cs5), sata1(prsnt) | ||
71 | mpp46 46 gpio, uart3(rts), uart1(rts), spi(cs6), sata0(prsnt) | ||
72 | mpp47 47 gpio, uart3(cts), uart1(cts), spi(cs7), pcie(clkreq3), | ||
73 | ref(clkout) | ||
74 | mpp48 48 gpio, tclk, dev(burst/last) | ||
75 | |||
76 | * Marvell Armada XP (mv78260 and mv78460 only) | ||
77 | |||
78 | name pins functions | ||
79 | ================================================================================ | ||
80 | mpp49 49 gpio, dev(we3) | ||
81 | mpp50 50 gpio, dev(we2) | ||
82 | mpp51 51 gpio, dev(ad16) | ||
83 | mpp52 52 gpio, dev(ad17) | ||
84 | mpp53 53 gpio, dev(ad18) | ||
85 | mpp54 54 gpio, dev(ad19) | ||
86 | mpp55 55 gpio, dev(ad20), vdd(cpu0-pd) | ||
87 | mpp56 56 gpio, dev(ad21), vdd(cpu1-pd) | ||
88 | mpp57 57 gpio, dev(ad22), vdd(cpu2-3-pd){1} | ||
89 | mpp58 58 gpio, dev(ad23) | ||
90 | mpp59 59 gpio, dev(ad24) | ||
91 | mpp60 60 gpio, dev(ad25) | ||
92 | mpp61 61 gpio, dev(ad26) | ||
93 | mpp62 62 gpio, dev(ad27) | ||
94 | mpp63 63 gpio, dev(ad28) | ||
95 | mpp64 64 gpio, dev(ad29) | ||
96 | mpp65 65 gpio, dev(ad30) | ||
97 | mpp66 66 gpio, dev(ad31) | ||
98 | |||
99 | Notes: | ||
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 | |||
3 | Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding | ||
4 | part and usage. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "marvell,dove-pinctrl" | ||
8 | - clocks: (optional) phandle of pdma clock | ||
9 | |||
10 | Available mpp pins/groups and functions: | ||
11 | Note: brackets (x) are not part of the mpp name for marvell,function and given | ||
12 | only for more detailed description in this document. | ||
13 | |||
14 | name pins functions | ||
15 | ================================================================================ | ||
16 | mpp0 0 gpio, pmu, uart2(rts), sdio0(cd), lcd0(pwm) | ||
17 | mpp1 1 gpio, pmu, uart2(cts), sdio0(wp), lcd1(pwm) | ||
18 | mpp2 2 gpio, pmu, uart2(txd), sdio0(buspwr), sata(prsnt), | ||
19 | uart1(rts) | ||
20 | mpp3 3 gpio, pmu, uart2(rxd), sdio0(ledctrl), sata(act), | ||
21 | uart1(cts), lcd-spi(cs1) | ||
22 | mpp4 4 gpio, pmu, uart3(rts), sdio1(cd), spi1(miso) | ||
23 | mpp5 5 gpio, pmu, uart3(cts), sdio1(wp), spi1(cs) | ||
24 | mpp6 6 gpio, pmu, uart3(txd), sdio1(buspwr), spi1(mosi) | ||
25 | mpp7 7 gpio, pmu, uart3(rxd), sdio1(ledctrl), spi1(sck) | ||
26 | mpp8 8 gpio, pmu, watchdog(rstout) | ||
27 | mpp9 9 gpio, pmu, pex1(clkreq) | ||
28 | mpp10 10 gpio, pmu, ssp(sclk) | ||
29 | mpp11 11 gpio, pmu, sata(prsnt), sata-1(act), sdio0(ledctrl), | ||
30 | sdio1(ledctrl), pex0(clkreq) | ||
31 | mpp12 12 gpio, pmu, uart2(rts), audio0(extclk), sdio1(cd), sata(act) | ||
32 | mpp13 13 gpio, pmu, uart2(cts), audio1(extclk), sdio1(wp), | ||
33 | ssp(extclk) | ||
34 | mpp14 14 gpio, pmu, uart2(txd), sdio1(buspwr), ssp(rxd) | ||
35 | mpp15 15 gpio, pmu, uart2(rxd), sdio1(ledctrl), ssp(sfrm) | ||
36 | mpp16 16 gpio, uart3(rts), sdio0(cd), ac97(sdi1), lcd-spi(cs1) | ||
37 | mpp17 17 gpio, uart3(cts), sdio0(wp), ac97(sdi2), twsi(sda), | ||
38 | ac97-1(sysclko) | ||
39 | mpp18 18 gpio, uart3(txd), sdio0(buspwr), ac97(sdi3), lcd0(pwm) | ||
40 | mpp19 19 gpio, uart3(rxd), sdio0(ledctrl), twsi(sck) | ||
41 | mpp20 20 gpio, sdio0(cd), sdio1(cd), spi1(miso), lcd-spi(miso), | ||
42 | ac97(sysclko) | ||
43 | mpp21 21 gpio, sdio0(wp), sdio1(wp), spi1(cs), lcd-spi(cs0), | ||
44 | uart1(cts), ssp(sfrm) | ||
45 | mpp22 22 gpio, sdio0(buspwr), sdio1(buspwr), spi1(mosi), | ||
46 | lcd-spi(mosi), uart1(cts), ssp(txd) | ||
47 | mpp23 23 gpio, sdio0(ledctrl), sdio1(ledctrl), spi1(sck), | ||
48 | lcd-spi(sck), ssp(sclk) | ||
49 | mpp_camera 24-39 gpio, camera | ||
50 | mpp_sdio0 40-45 gpio, sdio0 | ||
51 | mpp_sdio1 46-51 gpio, sdio1 | ||
52 | mpp_audio1 52-57 gpio, i2s1/spdifo, i2s1, spdifo, twsi, ssp/spdifo, ssp, | ||
53 | ssp/twsi | ||
54 | mpp_spi0 58-61 gpio, spi0 | ||
55 | mpp_uart1 62-63 gpio, uart1 | ||
56 | mpp_nand 64-71 gpo, nand | ||
57 | audio0 - i2s, ac97 | ||
58 | twsi - none, opt1, opt2, opt3 | ||
59 | |||
60 | Notes: | ||
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 | |||
3 | Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding | ||
4 | part and usage. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "marvell,88f6180-pinctrl", | ||
8 | "marvell,88f6190-pinctrl", "marvell,88f6192-pinctrl", | ||
9 | "marvell,88f6281-pinctrl", "marvell,88f6282-pinctrl" | ||
10 | |||
11 | This driver supports all kirkwood variants, i.e. 88f6180, 88f619x, and 88f628x. | ||
12 | |||
13 | Available mpp pins/groups and functions: | ||
14 | Note: brackets (x) are not part of the mpp name for marvell,function and given | ||
15 | only for more detailed description in this document. | ||
16 | |||
17 | * Marvell Kirkwood 88f6180 | ||
18 | |||
19 | name pins functions | ||
20 | ================================================================================ | ||
21 | mpp0 0 gpio, nand(io2), spi(cs) | ||
22 | mpp1 1 gpo, nand(io3), spi(mosi) | ||
23 | mpp2 2 gpo, nand(io4), spi(sck) | ||
24 | mpp3 3 gpo, nand(io5), spi(miso) | ||
25 | mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk) | ||
26 | mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig) | ||
27 | mpp6 6 sysrst(out), spi(mosi), ptp(trig) | ||
28 | mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig) | ||
29 | mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk), | ||
30 | mii(col) | ||
31 | mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq), | ||
32 | mii(crs) | ||
33 | mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig) | ||
34 | mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq), | ||
35 | ptp-2(trig) | ||
36 | mpp12 12 gpo, sdio(clk) | ||
37 | mpp13 13 gpio, sdio(cmd), uart1(txd) | ||
38 | mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col) | ||
39 | mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd) | ||
40 | mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs) | ||
41 | mpp17 17 gpio, sdio(d3) | ||
42 | mpp18 18 gpo, nand(io0) | ||
43 | mpp19 19 gpo, nand(io1) | ||
44 | mpp20 20 gpio, mii(rxerr) | ||
45 | mpp21 21 gpio, audio(spdifi) | ||
46 | mpp22 22 gpio, audio(spdifo) | ||
47 | mpp23 23 gpio, audio(rmclk) | ||
48 | mpp24 24 gpio, audio(bclk) | ||
49 | mpp25 25 gpio, audio(sdo) | ||
50 | mpp26 26 gpio, audio(lrclk) | ||
51 | mpp27 27 gpio, audio(mclk) | ||
52 | mpp28 28 gpio, audio(sdi) | ||
53 | mpp29 29 gpio, audio(extclk) | ||
54 | |||
55 | * Marvell Kirkwood 88f6190 | ||
56 | |||
57 | name pins functions | ||
58 | ================================================================================ | ||
59 | mpp0 0 gpio, nand(io2), spi(cs) | ||
60 | mpp1 1 gpo, nand(io3), spi(mosi) | ||
61 | mpp2 2 gpo, nand(io4), spi(sck) | ||
62 | mpp3 3 gpo, nand(io5), spi(miso) | ||
63 | mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk) | ||
64 | mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act) | ||
65 | mpp6 6 sysrst(out), spi(mosi), ptp(trig) | ||
66 | mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig) | ||
67 | mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk), | ||
68 | mii(col), mii-1(rxerr) | ||
69 | mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq), | ||
70 | mii(crs), sata0(prsnt) | ||
71 | mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig) | ||
72 | mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq), | ||
73 | ptp-2(trig), sata0(act) | ||
74 | mpp12 12 gpo, sdio(clk) | ||
75 | mpp13 13 gpio, sdio(cmd), uart1(txd) | ||
76 | mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col) | ||
77 | mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act) | ||
78 | mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs) | ||
79 | mpp17 17 gpio, sdio(d3), sata0(prsnt) | ||
80 | mpp18 18 gpo, nand(io0) | ||
81 | mpp19 19 gpo, nand(io1) | ||
82 | mpp20 20 gpio, ge1(txd0) | ||
83 | mpp21 21 gpio, ge1(txd1), sata0(act) | ||
84 | mpp22 22 gpio, ge1(txd2) | ||
85 | mpp23 23 gpio, ge1(txd3), sata0(prsnt) | ||
86 | mpp24 24 gpio, ge1(rxd0) | ||
87 | mpp25 25 gpio, ge1(rxd1) | ||
88 | mpp26 26 gpio, ge1(rxd2) | ||
89 | mpp27 27 gpio, ge1(rxd3) | ||
90 | mpp28 28 gpio, ge1(col) | ||
91 | mpp29 29 gpio, ge1(txclk) | ||
92 | mpp30 30 gpio, ge1(rxclk) | ||
93 | mpp31 31 gpio, ge1(rxclk) | ||
94 | mpp32 32 gpio, ge1(txclko) | ||
95 | mpp33 33 gpo, ge1(txclk) | ||
96 | mpp34 34 gpio, ge1(txen) | ||
97 | mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr) | ||
98 | |||
99 | * Marvell Kirkwood 88f6192 | ||
100 | |||
101 | name pins functions | ||
102 | ================================================================================ | ||
103 | mpp0 0 gpio, nand(io2), spi(cs) | ||
104 | mpp1 1 gpo, nand(io3), spi(mosi) | ||
105 | mpp2 2 gpo, nand(io4), spi(sck) | ||
106 | mpp3 3 gpo, nand(io5), spi(miso) | ||
107 | mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk), sata1(act) | ||
108 | mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act) | ||
109 | mpp6 6 sysrst(out), spi(mosi), ptp(trig) | ||
110 | mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig) | ||
111 | mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk), | ||
112 | mii(col), mii-1(rxerr), sata1(prsnt) | ||
113 | mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq), | ||
114 | mii(crs), sata0(prsnt) | ||
115 | mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig), sata1(act) | ||
116 | mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq), | ||
117 | ptp-2(trig), sata0(act) | ||
118 | mpp12 12 gpo, sdio(clk) | ||
119 | mpp13 13 gpio, sdio(cmd), uart1(txd) | ||
120 | mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt) | ||
121 | mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act) | ||
122 | mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs), | ||
123 | sata1(act) | ||
124 | mpp17 17 gpio, sdio(d3), sata0(prsnt) | ||
125 | mpp18 18 gpo, nand(io0) | ||
126 | mpp19 19 gpo, nand(io1) | ||
127 | mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi), | ||
128 | sata1(act) | ||
129 | mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql), | ||
130 | audio(spdifo) | ||
131 | mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk), | ||
132 | sata1(prsnt) | ||
133 | mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql), | ||
134 | audio(bclk) | ||
135 | mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo) | ||
136 | mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk) | ||
137 | mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk) | ||
138 | mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi) | ||
139 | mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk) | ||
140 | mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst) | ||
141 | mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk) | ||
142 | mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs) | ||
143 | mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx) | ||
144 | mpp33 33 gpo, ge1(txclk), tdm(drx) | ||
145 | mpp34 34 gpio, ge1(txen), tdm(spi-cs1) | ||
146 | mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql) | ||
147 | |||
148 | * Marvell Kirkwood 88f6281 | ||
149 | |||
150 | name pins functions | ||
151 | ================================================================================ | ||
152 | mpp0 0 gpio, nand(io2), spi(cs) | ||
153 | mpp1 1 gpo, nand(io3), spi(mosi) | ||
154 | mpp2 2 gpo, nand(io4), spi(sck) | ||
155 | mpp3 3 gpo, nand(io5), spi(miso) | ||
156 | mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk), sata1(act) | ||
157 | mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act) | ||
158 | mpp6 6 sysrst(out), spi(mosi), ptp(trig) | ||
159 | mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig) | ||
160 | mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk), | ||
161 | mii(col), mii-1(rxerr), sata1(prsnt) | ||
162 | mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq), | ||
163 | mii(crs), sata0(prsnt) | ||
164 | mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig), sata1(act) | ||
165 | mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq), | ||
166 | ptp-2(trig), sata0(act) | ||
167 | mpp12 12 gpio, sdio(clk) | ||
168 | mpp13 13 gpio, sdio(cmd), uart1(txd) | ||
169 | mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt) | ||
170 | mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act) | ||
171 | mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs), | ||
172 | sata1(act) | ||
173 | mpp17 17 gpio, sdio(d3), sata0(prsnt) | ||
174 | mpp18 18 gpo, nand(io0) | ||
175 | mpp19 19 gpo, nand(io1) | ||
176 | mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi), | ||
177 | sata1(act) | ||
178 | mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql), | ||
179 | audio(spdifo) | ||
180 | mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk), | ||
181 | sata1(prsnt) | ||
182 | mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql), | ||
183 | audio(bclk) | ||
184 | mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo) | ||
185 | mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk) | ||
186 | mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk) | ||
187 | mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi) | ||
188 | mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk) | ||
189 | mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst) | ||
190 | mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk) | ||
191 | mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs) | ||
192 | mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx) | ||
193 | mpp33 33 gpo, ge1(txclk), tdm(drx) | ||
194 | mpp34 34 gpio, ge1(txen), tdm(spi-cs1), sata1(act) | ||
195 | mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql) | ||
196 | mpp36 36 gpio, ts(mp0), tdm(spi-cs1), audio(spdifi) | ||
197 | mpp37 37 gpio, ts(mp1), tdm(tx2ql), audio(spdifo) | ||
198 | mpp38 38 gpio, ts(mp2), tdm(rx2ql), audio(rmclk) | ||
199 | mpp39 39 gpio, ts(mp3), tdm(spi-cs0), audio(bclk) | ||
200 | mpp40 40 gpio, ts(mp4), tdm(spi-sck), audio(sdo) | ||
201 | mpp41 41 gpio, ts(mp5), tdm(spi-miso), audio(lrclk) | ||
202 | mpp42 42 gpio, ts(mp6), tdm(spi-mosi), audio(mclk) | ||
203 | mpp43 43 gpio, ts(mp7), tdm(int), audio(sdi) | ||
204 | mpp44 44 gpio, ts(mp8), tdm(rst), audio(extclk) | ||
205 | mpp45 45 gpio, ts(mp9), tdm(pclk) | ||
206 | mpp46 46 gpio, ts(mp10), tdm(fs) | ||
207 | mpp47 47 gpio, ts(mp11), tdm(drx) | ||
208 | mpp48 48 gpio, ts(mp12), tdm(dtx) | ||
209 | mpp49 49 gpio, ts(mp9), tdm(rx0ql), ptp(clk) | ||
210 | |||
211 | * Marvell Kirkwood 88f6282 | ||
212 | |||
213 | name pins functions | ||
214 | ================================================================================ | ||
215 | mpp0 0 gpio, nand(io2), spi(cs) | ||
216 | mpp1 1 gpo, nand(io3), spi(mosi) | ||
217 | mpp2 2 gpo, nand(io4), spi(sck) | ||
218 | mpp3 3 gpo, nand(io5), spi(miso) | ||
219 | mpp4 4 gpio, nand(io6), uart0(rxd), sata1(act), lcd(hsync) | ||
220 | mpp5 5 gpo, nand(io7), uart0(txd), sata0(act), lcd(vsync) | ||
221 | mpp6 6 sysrst(out), spi(mosi) | ||
222 | mpp7 7 gpo, spi(cs), lcd(pwm) | ||
223 | mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), mii(col), | ||
224 | mii-1(rxerr), sata1(prsnt) | ||
225 | mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), mii(crs), | ||
226 | sata0(prsnt) | ||
227 | mpp10 10 gpo, spi(sck), uart0(txd), sata1(act) | ||
228 | mpp11 11 gpio, spi(miso), uart0(rxd), sata0(act) | ||
229 | mpp12 12 gpo, sdio(clk), audio(spdifo), spi(mosi), twsi(sda) | ||
230 | mpp13 13 gpio, sdio(cmd), uart1(txd), audio(rmclk), lcd(pwm) | ||
231 | mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt), | ||
232 | audio(spdifi), audio-1(sdi) | ||
233 | mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act), | ||
234 | spi(cs) | ||
235 | mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs), | ||
236 | sata1(act), lcd(extclk) | ||
237 | mpp17 17 gpio, sdio(d3), sata0(prsnt), sata1(act), twsi1(sck) | ||
238 | mpp18 18 gpo, nand(io0), pex(clkreq) | ||
239 | mpp19 19 gpo, nand(io1) | ||
240 | mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi), | ||
241 | sata1(act), lcd(d0) | ||
242 | mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql), | ||
243 | audio(spdifo), lcd(d1) | ||
244 | mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk), | ||
245 | sata1(prsnt), lcd(d2) | ||
246 | mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql), | ||
247 | audio(bclk), lcd(d3) | ||
248 | mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo), | ||
249 | lcd(d4) | ||
250 | mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk), | ||
251 | lcd(d5) | ||
252 | mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk), | ||
253 | lcd(d6) | ||
254 | mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi), | ||
255 | lcd(d7) | ||
256 | mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk), | ||
257 | lcd(d8) | ||
258 | mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst), lcd(d9) | ||
259 | mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk), lcd(d10) | ||
260 | mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs), lcd(d11) | ||
261 | mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx), lcd(d12) | ||
262 | mpp33 33 gpo, ge1(txclk), tdm(drx), lcd(d13) | ||
263 | mpp34 34 gpio, ge1(txen), tdm(spi-cs1), sata1(act), lcd(d14) | ||
264 | mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql), | ||
265 | lcd(d15) | ||
266 | mpp36 36 gpio, ts(mp0), tdm(spi-cs1), audio(spdifi), twsi1(sda) | ||
267 | mpp37 37 gpio, ts(mp1), tdm(tx2ql), audio(spdifo), twsi1(sck) | ||
268 | mpp38 38 gpio, ts(mp2), tdm(rx2ql), audio(rmclk), lcd(d18) | ||
269 | mpp39 39 gpio, ts(mp3), tdm(spi-cs0), audio(bclk), lcd(d19) | ||
270 | mpp40 40 gpio, ts(mp4), tdm(spi-sck), audio(sdo), lcd(d20) | ||
271 | mpp41 41 gpio, ts(mp5), tdm(spi-miso), audio(lrclk), lcd(d21) | ||
272 | mpp42 42 gpio, ts(mp6), tdm(spi-mosi), audio(mclk), lcd(d22) | ||
273 | mpp43 43 gpio, ts(mp7), tdm(int), audio(sdi), lcd(d23) | ||
274 | mpp44 44 gpio, ts(mp8), tdm(rst), audio(extclk), lcd(clk) | ||
275 | mpp45 45 gpio, ts(mp9), tdm(pclk), lcd(e) | ||
276 | mpp46 46 gpio, ts(mp10), tdm(fs), lcd(hsync) | ||
277 | mpp47 47 gpio, ts(mp11), tdm(drx), lcd(vsync) | ||
278 | mpp48 48 gpio, ts(mp12), tdm(dtx), lcd(d16) | ||
279 | mpp49 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 | |||
3 | The 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 | ||
5 | driver using this core driver. | ||
6 | |||
7 | Please refer to pinctrl-bindings.txt in this directory for details of the | ||
8 | common pinctrl bindings used by client devices, including the meaning of the | ||
9 | phrase "pin configuration node". | ||
10 | |||
11 | A Marvell SoC pin configuration node is a node of a group of pins which can | ||
12 | be used for a specific device or function. Each node requires one or more | ||
13 | mpp pins or group of pins and a mpp function common to all pins. | ||
14 | |||
15 | Required properties for pinctrl driver: | ||
16 | - compatible: "marvell,<soc>-pinctrl" | ||
17 | Please refer to each marvell,<soc>-pinctrl.txt binding doc for supported SoCs. | ||
18 | |||
19 | Required 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 | |||
26 | Examples: | ||
27 | |||
28 | uart1: 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 | |||
38 | pinctrl: 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" | |||
21 | CONFIG_SERIAL_8250=y | 21 | CONFIG_SERIAL_8250=y |
22 | CONFIG_SERIAL_8250_CONSOLE=y | 22 | CONFIG_SERIAL_8250_CONSOLE=y |
23 | CONFIG_SERIAL_OF_PLATFORM=y | 23 | CONFIG_SERIAL_OF_PLATFORM=y |
24 | CONFIG_GPIOLIB=y | ||
25 | CONFIG_GPIO_SYSFS=y | ||
24 | CONFIG_EXT2_FS=y | 26 | CONFIG_EXT2_FS=y |
25 | CONFIG_EXT3_FS=y | 27 | CONFIG_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 | |||
13 | menu "Marvell SOC with device tree" | 13 | menu "Marvell SOC with device tree" |
14 | 14 | ||
15 | config MACH_ARMADA_370_XP | 15 | config 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 | |||
20 | config 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 | 28 | config 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 | ||
24 | endmenu | 36 | endmenu |
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 | ||
153 | config GPIO_MVEBU | ||
154 | def_bool y | ||
155 | depends on ARCH_MVEBU | ||
156 | select GPIO_GENERIC | ||
157 | select GENERIC_IRQ_CHIP | ||
158 | |||
153 | config GPIO_MXC | 159 | config 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 | |||
41 | obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o | 41 | obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o |
42 | obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o | 42 | obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o |
43 | obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o | 43 | obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o |
44 | obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o | ||
44 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o | 45 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o |
45 | obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o | 46 | obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o |
46 | obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o | 47 | obj-$(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 | |||
76 | struct 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 | */ | ||
90 | static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) | ||
91 | { | ||
92 | return mvchip->membase + GPIO_OUT_OFF; | ||
93 | } | ||
94 | |||
95 | static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) | ||
96 | { | ||
97 | return mvchip->membase + GPIO_IO_CONF_OFF; | ||
98 | } | ||
99 | |||
100 | static inline void __iomem *mvebu_gpioreg_in_pol(struct mvebu_gpio_chip *mvchip) | ||
101 | { | ||
102 | return mvchip->membase + GPIO_IN_POL_OFF; | ||
103 | } | ||
104 | |||
105 | static inline void __iomem *mvebu_gpioreg_data_in(struct mvebu_gpio_chip *mvchip) | ||
106 | { | ||
107 | return mvchip->membase + GPIO_DATA_IN_OFF; | ||
108 | } | ||
109 | |||
110 | static 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 | |||
126 | static 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 | |||
144 | static 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 | |||
166 | int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) | ||
167 | { | ||
168 | return pinctrl_request_gpio(chip->base + pin); | ||
169 | } | ||
170 | |||
171 | void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) | ||
172 | { | ||
173 | pinctrl_free_gpio(chip->base + pin); | ||
174 | } | ||
175 | |||
176 | static 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 | |||
193 | static 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 | |||
209 | static 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 | |||
232 | static 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 | |||
256 | static 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 | */ | ||
266 | static 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 | |||
277 | static 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 | |||
289 | static 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 | |||
301 | static 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 | |||
313 | static 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 | |||
351 | static 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 | |||
409 | static 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 | |||
444 | static 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 | }; | ||
455 | MODULE_DEVICE_TABLE(platform, mvebu_gpio_ids); | ||
456 | |||
457 | static 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 | }; | ||
474 | MODULE_DEVICE_TABLE(of, mvebu_gpio_of_match); | ||
475 | |||
476 | static 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 | |||
665 | static 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 | |||
675 | static int __init mvebu_gpio_init(void) | ||
676 | { | ||
677 | return platform_driver_register(&mvebu_gpio_driver); | ||
678 | } | ||
679 | postcore_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 | ||
148 | config PINCTRL_MVEBU | ||
149 | bool | ||
150 | depends on ARCH_MVEBU | ||
151 | select PINMUX | ||
152 | select PINCONF | ||
153 | |||
154 | config PINCTRL_DOVE | ||
155 | bool | ||
156 | select PINCTRL_MVEBU | ||
157 | |||
158 | config PINCTRL_KIRKWOOD | ||
159 | bool | ||
160 | select PINCTRL_MVEBU | ||
161 | |||
162 | config PINCTRL_ARMADA_370 | ||
163 | bool | ||
164 | select PINCTRL_MVEBU | ||
165 | |||
166 | config PINCTRL_ARMADA_XP | ||
167 | bool | ||
168 | select PINCTRL_MVEBU | ||
169 | |||
148 | source "drivers/pinctrl/spear/Kconfig" | 170 | source "drivers/pinctrl/spear/Kconfig" |
149 | 171 | ||
150 | endmenu | 172 | endmenu |
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 | |||
29 | obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o | 29 | obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o |
30 | obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o | 30 | obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o |
31 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o | 31 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o |
32 | obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o | ||
33 | obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o | ||
34 | obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o | ||
35 | obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o | ||
36 | obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o | ||
32 | 37 | ||
33 | obj-$(CONFIG_PLAT_SPEAR) += spear/ | 38 | obj-$(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 | |||
26 | static 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 | |||
368 | static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info; | ||
369 | |||
370 | static struct of_device_id armada_370_pinctrl_of_match[] __devinitdata = { | ||
371 | { .compatible = "marvell,mv88f6710-pinctrl" }, | ||
372 | { }, | ||
373 | }; | ||
374 | |||
375 | static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = { | ||
376 | MPP_REG_CTRL(0, 65), | ||
377 | }; | ||
378 | |||
379 | static 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 | |||
385 | static 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 | |||
402 | static int __devexit armada_370_pinctrl_remove(struct platform_device *pdev) | ||
403 | { | ||
404 | return mvebu_pinctrl_remove(pdev); | ||
405 | } | ||
406 | |||
407 | static 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 | |||
417 | module_platform_driver(armada_370_pinctrl_driver); | ||
418 | |||
419 | MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); | ||
420 | MODULE_DESCRIPTION("Marvell Armada 370 pinctrl driver"); | ||
421 | MODULE_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 | |||
36 | enum 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 | |||
44 | static 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 | |||
350 | static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info; | ||
351 | |||
352 | static 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 | |||
368 | static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = { | ||
369 | MPP_REG_CTRL(0, 48), | ||
370 | }; | ||
371 | |||
372 | static 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 | |||
377 | static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = { | ||
378 | MPP_REG_CTRL(0, 66), | ||
379 | }; | ||
380 | |||
381 | static 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 | |||
387 | static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = { | ||
388 | MPP_REG_CTRL(0, 66), | ||
389 | }; | ||
390 | |||
391 | static 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 | |||
397 | static 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 | |||
449 | static int __devexit armada_xp_pinctrl_remove(struct platform_device *pdev) | ||
450 | { | ||
451 | return mvebu_pinctrl_remove(pdev); | ||
452 | } | ||
453 | |||
454 | static 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 | |||
464 | module_platform_driver(armada_xp_pinctrl_driver); | ||
465 | |||
466 | MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); | ||
467 | MODULE_DESCRIPTION("Marvell Armada XP pinctrl driver"); | ||
468 | MODULE_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 | |||
55 | static 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 | |||
70 | static 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 | |||
89 | static 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 | |||
120 | static 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 | |||
155 | static 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 | |||
165 | static 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 | |||
179 | static 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 | |||
189 | static 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 | |||
202 | static 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 | |||
229 | static 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 | */ | ||
259 | static 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 */ | ||
286 | static 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 | |||
294 | static 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 | |||
311 | static 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 | |||
338 | static 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 | |||
367 | static 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 | |||
556 | static 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 | |||
562 | static 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 | |||
572 | static struct clk *clk; | ||
573 | |||
574 | static struct of_device_id dove_pinctrl_of_match[] __devinitdata = { | ||
575 | { .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info }, | ||
576 | { } | ||
577 | }; | ||
578 | |||
579 | static 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 | |||
596 | static 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 | |||
606 | static 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 | |||
616 | module_platform_driver(dove_pinctrl_driver); | ||
617 | |||
618 | MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>"); | ||
619 | MODULE_DESCRIPTION("Marvell Dove pinctrl driver"); | ||
620 | MODULE_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 | |||
28 | enum 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 | |||
36 | static 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 | |||
360 | static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = { | ||
361 | MPP_REG_CTRL(0, 29), | ||
362 | }; | ||
363 | |||
364 | static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = { | ||
365 | MPP_GPIO_RANGE(0, 0, 0, 30), | ||
366 | }; | ||
367 | |||
368 | static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = { | ||
369 | MPP_REG_CTRL(0, 35), | ||
370 | }; | ||
371 | |||
372 | static 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 | |||
377 | static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = { | ||
378 | MPP_REG_CTRL(0, 49), | ||
379 | }; | ||
380 | |||
381 | static 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 | |||
386 | static 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 | |||
396 | static 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 | |||
406 | static 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 | |||
416 | static 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 | |||
426 | static 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 | |||
436 | static 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 | |||
445 | static 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 | |||
453 | static int __devexit kirkwood_pinctrl_remove(struct platform_device *pdev) | ||
454 | { | ||
455 | return mvebu_pinctrl_remove(pdev); | ||
456 | } | ||
457 | |||
458 | static 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 | |||
468 | module_platform_driver(kirkwood_pinctrl_driver); | ||
469 | |||
470 | MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>"); | ||
471 | MODULE_DESCRIPTION("Marvell Kirkwood pinctrl driver"); | ||
472 | MODULE_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 | |||
34 | struct mvebu_pinctrl_function { | ||
35 | const char *name; | ||
36 | const char **groups; | ||
37 | unsigned num_groups; | ||
38 | }; | ||
39 | |||
40 | struct 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 | |||
50 | struct 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 | |||
62 | static 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 | |||
75 | static 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 | |||
86 | static 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 | |||
101 | static 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 | |||
116 | static 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 | |||
131 | static 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 | */ | ||
147 | static 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 | |||
162 | static 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 | |||
179 | static 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 | |||
194 | static 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 | |||
209 | static 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 | |||
267 | static 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 | |||
273 | static 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 | |||
280 | static 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 | |||
288 | static 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 | |||
299 | static 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 | |||
327 | static 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 | |||
348 | static 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 | |||
373 | static 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 | |||
382 | static 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 | |||
388 | static 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 | |||
395 | static 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 | |||
405 | static 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 | |||
468 | static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, | ||
469 | struct pinctrl_map *map, unsigned num_maps) | ||
470 | { | ||
471 | kfree(map); | ||
472 | } | ||
473 | |||
474 | static 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 | |||
482 | static 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 | |||
498 | static 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 | |||
572 | int __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 | |||
749 | int __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 | */ | ||
36 | struct 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 | */ | ||
70 | struct 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 | */ | ||
88 | struct 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 | */ | ||
107 | struct 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 | |||
189 | int mvebu_pinctrl_probe(struct platform_device *pdev); | ||
190 | int mvebu_pinctrl_remove(struct platform_device *pdev); | ||
191 | |||
192 | #endif | ||