mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-14 21:01:29 +00:00
Pin control subsystem changes for kernel 3.5:
- Generic Device Tree bindings and hooks for drivers so we can move over modern drivers to using this. - Device Tree bindings for Tegra SoCs. - Funneling some devicetree helper code for the drivers/of subsystem. - New pin control drivers for: - Freescale MXS - Freescale i.MX51 - Freescale i.MX53 - All of these use Device Tree bindings. - Dummy pinctrl handles for stepwise migration to pinctrl, akin to dummy regulators. - Minor non-urgent fixes and improvments. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJPuiZMAAoJEEEQszewGV1zMK4P/RP+RvKs3KnFaAUF/tM2QSll /65BW8SJlaXrbMv5IC4iBvUx1sH/fDNtNjTHIwwlNBlrxPl6TVecvZZq+yBnl7yp Wue0A/xdD0nsD7O/85khVE4WnDJbWpgOdX/9CTVbc6tmTAsb9pGBH2120dtLdcLe X+GRKnf5D05ySHaGKO8j0PB1MLjF/SV3GhGfrYpn0dtW/XVWNmRczLgm0p11qhMd kOLoqjcJUp/p3HYtUjKKnwj/3z0d88YjegsiSelTp9Gdnjp/3c2LrRN91mXdIiMc IGZrp+AQWQ0zg3QrH91gAD7V+f+URrd+IK2EU5PdBO1fqNXgaotGujsX0lqnwycN 8PbXnrUhMhtM4oVjUdLioTP98wIN8Y5tTDoPoVUPtA3921aCVQoE/Pf9/VXBwzEZ O/nmW0hz7e1OraEq4a/vsD715iuxV92lQzJpzMWYjySFyIGur/VCLLWQo95WWK5d Foiif1FTuN+1ueONlI5JHqhFp1HZs0ldVDxR/V8G+ueUNlgQmlypgC3lI++WjXnt uaQS6Hq0NlOKivhlu/uJ098ft7gf2utJLSBOfKPoILgyfksvEGfegJ8tql2YW/vS 42d0jQGrnhi4nctxzGN3zmr4Ys0BU97JP/9Rq+ZbPUL+SDF7e3y4pv+uTLI4ip6v fyHZTFW6CTXbBD3k1qy9 =RgIp -----END PGP SIGNATURE----- Merge tag 'pinctrl-for-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl Pull pin control subsystem changes from Linus Walleij: - Generic Device Tree bindings and hooks for drivers so we can move over modern drivers to using this. - Device Tree bindings for Tegra SoCs. - Funneling some devicetree helper code for the drivers/of subsystem. - New pin control drivers for: * Freescale MXS * Freescale i.MX51 * Freescale i.MX53 All of these use Device Tree bindings. - Dummy pinctrl handles for stepwise migration to pinctrl, akin to dummy regulators. - Minor non-urgent fixes and improvments. Fix up trivial conflicts in Documentation/driver-model/devres.txt and drivers/pinctrl/core.c, * tag 'pinctrl-for-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (46 commits) pinctrl: pinctrl-imx: add imx51 pinctrl driver pinctrl: pinctrl-imx: add imx53 pinctrl driver pinctrl: pinctrl-pxa3xx: remove empty pinmux disable function pinctrl: pinctrl-mxs: remove empty pinmux disable function pinctrl: pinctrl-imx: remove empty pinmux disable function pinctrl: make pinmux disable function optional pinctrl: a minor error checking improvement for pinconf pinctrl: mxs: skip gpio nodes for group creation pinctrl: mxs: create group for pin config node pinctrl: (cosmetic) fix two entries in DocBook comments pinctrl: add more info to error msgs in pin_request pinctrl: add pinctrl-mxs support pinctrl: pinctrl-imx: add imx6q pinctrl driver pinctrl: pinctrl-imx: add imx pinctrl core driver dt: add of_get_child_count helper function pinctrl: support gpio request deferred probing pinctrl: add pinctrl_provide_dummies interface for platforms to use pinctrl: enhance reporting of errors when loading from DT pinctrl: add kerneldoc for pinctrl_ops device tree functions pinctrl: propagate map validation errors ...
This commit is contained in:
commit
3d1482fe7a
@ -0,0 +1,95 @@
|
||||
* Freescale IOMUX Controller (IOMUXC) for i.MX
|
||||
|
||||
The IOMUX Controller (IOMUXC), together with the IOMUX, enables the IC
|
||||
to share one PAD to several functional blocks. The sharing is done by
|
||||
multiplexing the PAD input/output signals. For each PAD there are up to
|
||||
8 muxing options (called ALT modes). Since different modules require
|
||||
different PAD settings (like pull up, keeper, etc) the IOMUXC controls
|
||||
also the PAD settings parameters.
|
||||
|
||||
Please refer to pinctrl-bindings.txt in this directory for details of the
|
||||
common pinctrl bindings used by client devices, including the meaning of the
|
||||
phrase "pin configuration node".
|
||||
|
||||
Freescale IMX pin configuration node is a node of a group of pins which can be
|
||||
used for a specific device or function. This node represents both mux and config
|
||||
of the pins in that group. The 'mux' selects the function mode(also named mux
|
||||
mode) this pin can work on and the 'config' configures various pad settings
|
||||
such as pull-up, open drain, drive strength, etc.
|
||||
|
||||
Required properties for iomux controller:
|
||||
- compatible: "fsl,<soc>-iomuxc"
|
||||
Please refer to each fsl,<soc>-pinctrl.txt binding doc for supported SoCs.
|
||||
|
||||
Required properties for pin configuration node:
|
||||
- fsl,pins: two integers array, represents a group of pins mux and config
|
||||
setting. The format is fsl,pins = <PIN_FUNC_ID CONFIG>, PIN_FUNC_ID is a
|
||||
pin working on a specific function, CONFIG is the pad setting value like
|
||||
pull-up on this pin. Please refer to fsl,<soc>-pinctrl.txt for the valid
|
||||
pins and functions of each SoC.
|
||||
|
||||
Bits used for CONFIG:
|
||||
NO_PAD_CTL(1 << 31): indicate this pin does not need config.
|
||||
|
||||
SION(1 << 30): Software Input On Field.
|
||||
Force the selected mux mode input path no matter of MUX_MODE functionality.
|
||||
By default the input path is determined by functionality of the selected
|
||||
mux mode (regular).
|
||||
|
||||
Other bits are used for PAD setting.
|
||||
Please refer to each fsl,<soc>-pinctrl,txt binding doc for SoC specific part
|
||||
of bits definitions.
|
||||
|
||||
NOTE:
|
||||
Some requirements for using fsl,imx-pinctrl binding:
|
||||
1. We have pin function node defined under iomux controller node to represent
|
||||
what pinmux functions this SoC supports.
|
||||
2. The pin configuration node intends to work on a specific function should
|
||||
to be defined under that specific function node.
|
||||
The function node's name should represent well about what function
|
||||
this group of pins in this pin configuration node are working on.
|
||||
3. The driver can use the function node's name and pin configuration node's
|
||||
name describe the pin function and group hierarchy.
|
||||
For example, Linux IMX pinctrl driver takes the function node's name
|
||||
as the function name and pin configuration node's name as group name to
|
||||
create the map table.
|
||||
4. Each pin configuration node should have a phandle, devices can set pins
|
||||
configurations by referring to the phandle of that pin configuration node.
|
||||
|
||||
Examples:
|
||||
usdhc@0219c000 { /* uSDHC4 */
|
||||
fsl,card-wired;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc4_1>;
|
||||
};
|
||||
|
||||
iomuxc@020e0000 {
|
||||
compatible = "fsl,imx6q-iomuxc";
|
||||
reg = <0x020e0000 0x4000>;
|
||||
|
||||
/* shared pinctrl settings */
|
||||
usdhc4 {
|
||||
pinctrl_usdhc4_1: usdhc4grp-1 {
|
||||
fsl,pins = <1386 0x17059 /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
|
||||
1392 0x10059 /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
|
||||
1462 0x17059 /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
|
||||
1470 0x17059 /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
|
||||
1478 0x17059 /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
|
||||
1486 0x17059 /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
|
||||
1493 0x17059 /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */
|
||||
1501 0x17059 /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */
|
||||
1509 0x17059 /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */
|
||||
1517 0x17059>; /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */
|
||||
};
|
||||
};
|
||||
....
|
||||
};
|
||||
Refer to the IOMUXC controller chapter in imx6q datasheet,
|
||||
0x17059 means enable hysteresis, 47KOhm Pull Up, 50Mhz speed,
|
||||
80Ohm driver strength and Fast Slew Rate.
|
||||
User should refer to each SoC spec to set the correct value.
|
||||
|
||||
TODO: when dtc macro support is available, we can change above raw data
|
||||
to dt macro which can get better readability in dts file.
|
787
Documentation/devicetree/bindings/pinctrl/fsl,imx51-pinctrl.txt
Normal file
787
Documentation/devicetree/bindings/pinctrl/fsl,imx51-pinctrl.txt
Normal file
@ -0,0 +1,787 @@
|
||||
* Freescale IMX51 IOMUX Controller
|
||||
|
||||
Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
|
||||
and usage.
|
||||
|
||||
Required properties:
|
||||
- compatible: "fsl,imx51-iomuxc"
|
||||
- fsl,pins: two integers array, represents a group of pins mux and config
|
||||
setting. The format is fsl,pins = <PIN_FUNC_ID CONFIG>, PIN_FUNC_ID is a
|
||||
pin working on a specific function, CONFIG is the pad setting value like
|
||||
pull-up for this pin. Please refer to imx51 datasheet for the valid pad
|
||||
config settings.
|
||||
|
||||
CONFIG bits definition:
|
||||
PAD_CTL_HVE (1 << 13)
|
||||
PAD_CTL_HYS (1 << 8)
|
||||
PAD_CTL_PKE (1 << 7)
|
||||
PAD_CTL_PUE (1 << 6)
|
||||
PAD_CTL_PUS_100K_DOWN (0 << 4)
|
||||
PAD_CTL_PUS_47K_UP (1 << 4)
|
||||
PAD_CTL_PUS_100K_UP (2 << 4)
|
||||
PAD_CTL_PUS_22K_UP (3 << 4)
|
||||
PAD_CTL_ODE (1 << 3)
|
||||
PAD_CTL_DSE_LOW (0 << 1)
|
||||
PAD_CTL_DSE_MED (1 << 1)
|
||||
PAD_CTL_DSE_HIGH (2 << 1)
|
||||
PAD_CTL_DSE_MAX (3 << 1)
|
||||
PAD_CTL_SRE_FAST (1 << 0)
|
||||
PAD_CTL_SRE_SLOW (0 << 0)
|
||||
|
||||
See below for available PIN_FUNC_ID for imx51:
|
||||
MX51_PAD_EIM_D16__AUD4_RXFS 0
|
||||
MX51_PAD_EIM_D16__AUD5_TXD 1
|
||||
MX51_PAD_EIM_D16__EIM_D16 2
|
||||
MX51_PAD_EIM_D16__GPIO2_0 3
|
||||
MX51_PAD_EIM_D16__I2C1_SDA 4
|
||||
MX51_PAD_EIM_D16__UART2_CTS 5
|
||||
MX51_PAD_EIM_D16__USBH2_DATA0 6
|
||||
MX51_PAD_EIM_D17__AUD5_RXD 7
|
||||
MX51_PAD_EIM_D17__EIM_D17 8
|
||||
MX51_PAD_EIM_D17__GPIO2_1 9
|
||||
MX51_PAD_EIM_D17__UART2_RXD 10
|
||||
MX51_PAD_EIM_D17__UART3_CTS 11
|
||||
MX51_PAD_EIM_D17__USBH2_DATA1 12
|
||||
MX51_PAD_EIM_D18__AUD5_TXC 13
|
||||
MX51_PAD_EIM_D18__EIM_D18 14
|
||||
MX51_PAD_EIM_D18__GPIO2_2 15
|
||||
MX51_PAD_EIM_D18__UART2_TXD 16
|
||||
MX51_PAD_EIM_D18__UART3_RTS 17
|
||||
MX51_PAD_EIM_D18__USBH2_DATA2 18
|
||||
MX51_PAD_EIM_D19__AUD4_RXC 19
|
||||
MX51_PAD_EIM_D19__AUD5_TXFS 20
|
||||
MX51_PAD_EIM_D19__EIM_D19 21
|
||||
MX51_PAD_EIM_D19__GPIO2_3 22
|
||||
MX51_PAD_EIM_D19__I2C1_SCL 23
|
||||
MX51_PAD_EIM_D19__UART2_RTS 24
|
||||
MX51_PAD_EIM_D19__USBH2_DATA3 25
|
||||
MX51_PAD_EIM_D20__AUD4_TXD 26
|
||||
MX51_PAD_EIM_D20__EIM_D20 27
|
||||
MX51_PAD_EIM_D20__GPIO2_4 28
|
||||
MX51_PAD_EIM_D20__SRTC_ALARM_DEB 29
|
||||
MX51_PAD_EIM_D20__USBH2_DATA4 30
|
||||
MX51_PAD_EIM_D21__AUD4_RXD 31
|
||||
MX51_PAD_EIM_D21__EIM_D21 32
|
||||
MX51_PAD_EIM_D21__GPIO2_5 33
|
||||
MX51_PAD_EIM_D21__SRTC_ALARM_DEB 34
|
||||
MX51_PAD_EIM_D21__USBH2_DATA5 35
|
||||
MX51_PAD_EIM_D22__AUD4_TXC 36
|
||||
MX51_PAD_EIM_D22__EIM_D22 37
|
||||
MX51_PAD_EIM_D22__GPIO2_6 38
|
||||
MX51_PAD_EIM_D22__USBH2_DATA6 39
|
||||
MX51_PAD_EIM_D23__AUD4_TXFS 40
|
||||
MX51_PAD_EIM_D23__EIM_D23 41
|
||||
MX51_PAD_EIM_D23__GPIO2_7 42
|
||||
MX51_PAD_EIM_D23__SPDIF_OUT1 43
|
||||
MX51_PAD_EIM_D23__USBH2_DATA7 44
|
||||
MX51_PAD_EIM_D24__AUD6_RXFS 45
|
||||
MX51_PAD_EIM_D24__EIM_D24 46
|
||||
MX51_PAD_EIM_D24__GPIO2_8 47
|
||||
MX51_PAD_EIM_D24__I2C2_SDA 48
|
||||
MX51_PAD_EIM_D24__UART3_CTS 49
|
||||
MX51_PAD_EIM_D24__USBOTG_DATA0 50
|
||||
MX51_PAD_EIM_D25__EIM_D25 51
|
||||
MX51_PAD_EIM_D25__KEY_COL6 52
|
||||
MX51_PAD_EIM_D25__UART2_CTS 53
|
||||
MX51_PAD_EIM_D25__UART3_RXD 54
|
||||
MX51_PAD_EIM_D25__USBOTG_DATA1 55
|
||||
MX51_PAD_EIM_D26__EIM_D26 56
|
||||
MX51_PAD_EIM_D26__KEY_COL7 57
|
||||
MX51_PAD_EIM_D26__UART2_RTS 58
|
||||
MX51_PAD_EIM_D26__UART3_TXD 59
|
||||
MX51_PAD_EIM_D26__USBOTG_DATA2 60
|
||||
MX51_PAD_EIM_D27__AUD6_RXC 61
|
||||
MX51_PAD_EIM_D27__EIM_D27 62
|
||||
MX51_PAD_EIM_D27__GPIO2_9 63
|
||||
MX51_PAD_EIM_D27__I2C2_SCL 64
|
||||
MX51_PAD_EIM_D27__UART3_RTS 65
|
||||
MX51_PAD_EIM_D27__USBOTG_DATA3 66
|
||||
MX51_PAD_EIM_D28__AUD6_TXD 67
|
||||
MX51_PAD_EIM_D28__EIM_D28 68
|
||||
MX51_PAD_EIM_D28__KEY_ROW4 69
|
||||
MX51_PAD_EIM_D28__USBOTG_DATA4 70
|
||||
MX51_PAD_EIM_D29__AUD6_RXD 71
|
||||
MX51_PAD_EIM_D29__EIM_D29 72
|
||||
MX51_PAD_EIM_D29__KEY_ROW5 73
|
||||
MX51_PAD_EIM_D29__USBOTG_DATA5 74
|
||||
MX51_PAD_EIM_D30__AUD6_TXC 75
|
||||
MX51_PAD_EIM_D30__EIM_D30 76
|
||||
MX51_PAD_EIM_D30__KEY_ROW6 77
|
||||
MX51_PAD_EIM_D30__USBOTG_DATA6 78
|
||||
MX51_PAD_EIM_D31__AUD6_TXFS 79
|
||||
MX51_PAD_EIM_D31__EIM_D31 80
|
||||
MX51_PAD_EIM_D31__KEY_ROW7 81
|
||||
MX51_PAD_EIM_D31__USBOTG_DATA7 82
|
||||
MX51_PAD_EIM_A16__EIM_A16 83
|
||||
MX51_PAD_EIM_A16__GPIO2_10 84
|
||||
MX51_PAD_EIM_A16__OSC_FREQ_SEL0 85
|
||||
MX51_PAD_EIM_A17__EIM_A17 86
|
||||
MX51_PAD_EIM_A17__GPIO2_11 87
|
||||
MX51_PAD_EIM_A17__OSC_FREQ_SEL1 88
|
||||
MX51_PAD_EIM_A18__BOOT_LPB0 89
|
||||
MX51_PAD_EIM_A18__EIM_A18 90
|
||||
MX51_PAD_EIM_A18__GPIO2_12 91
|
||||
MX51_PAD_EIM_A19__BOOT_LPB1 92
|
||||
MX51_PAD_EIM_A19__EIM_A19 93
|
||||
MX51_PAD_EIM_A19__GPIO2_13 94
|
||||
MX51_PAD_EIM_A20__BOOT_UART_SRC0 95
|
||||
MX51_PAD_EIM_A20__EIM_A20 96
|
||||
MX51_PAD_EIM_A20__GPIO2_14 97
|
||||
MX51_PAD_EIM_A21__BOOT_UART_SRC1 98
|
||||
MX51_PAD_EIM_A21__EIM_A21 99
|
||||
MX51_PAD_EIM_A21__GPIO2_15 100
|
||||
MX51_PAD_EIM_A22__EIM_A22 101
|
||||
MX51_PAD_EIM_A22__GPIO2_16 102
|
||||
MX51_PAD_EIM_A23__BOOT_HPN_EN 103
|
||||
MX51_PAD_EIM_A23__EIM_A23 104
|
||||
MX51_PAD_EIM_A23__GPIO2_17 105
|
||||
MX51_PAD_EIM_A24__EIM_A24 106
|
||||
MX51_PAD_EIM_A24__GPIO2_18 107
|
||||
MX51_PAD_EIM_A24__USBH2_CLK 108
|
||||
MX51_PAD_EIM_A25__DISP1_PIN4 109
|
||||
MX51_PAD_EIM_A25__EIM_A25 110
|
||||
MX51_PAD_EIM_A25__GPIO2_19 111
|
||||
MX51_PAD_EIM_A25__USBH2_DIR 112
|
||||
MX51_PAD_EIM_A26__CSI1_DATA_EN 113
|
||||
MX51_PAD_EIM_A26__DISP2_EXT_CLK 114
|
||||
MX51_PAD_EIM_A26__EIM_A26 115
|
||||
MX51_PAD_EIM_A26__GPIO2_20 116
|
||||
MX51_PAD_EIM_A26__USBH2_STP 117
|
||||
MX51_PAD_EIM_A27__CSI2_DATA_EN 118
|
||||
MX51_PAD_EIM_A27__DISP1_PIN1 119
|
||||
MX51_PAD_EIM_A27__EIM_A27 120
|
||||
MX51_PAD_EIM_A27__GPIO2_21 121
|
||||
MX51_PAD_EIM_A27__USBH2_NXT 122
|
||||
MX51_PAD_EIM_EB0__EIM_EB0 123
|
||||
MX51_PAD_EIM_EB1__EIM_EB1 124
|
||||
MX51_PAD_EIM_EB2__AUD5_RXFS 125
|
||||
MX51_PAD_EIM_EB2__CSI1_D2 126
|
||||
MX51_PAD_EIM_EB2__EIM_EB2 127
|
||||
MX51_PAD_EIM_EB2__FEC_MDIO 128
|
||||
MX51_PAD_EIM_EB2__GPIO2_22 129
|
||||
MX51_PAD_EIM_EB2__GPT_CMPOUT1 130
|
||||
MX51_PAD_EIM_EB3__AUD5_RXC 131
|
||||
MX51_PAD_EIM_EB3__CSI1_D3 132
|
||||
MX51_PAD_EIM_EB3__EIM_EB3 133
|
||||
MX51_PAD_EIM_EB3__FEC_RDATA1 134
|
||||
MX51_PAD_EIM_EB3__GPIO2_23 135
|
||||
MX51_PAD_EIM_EB3__GPT_CMPOUT2 136
|
||||
MX51_PAD_EIM_OE__EIM_OE 137
|
||||
MX51_PAD_EIM_OE__GPIO2_24 138
|
||||
MX51_PAD_EIM_CS0__EIM_CS0 139
|
||||
MX51_PAD_EIM_CS0__GPIO2_25 140
|
||||
MX51_PAD_EIM_CS1__EIM_CS1 141
|
||||
MX51_PAD_EIM_CS1__GPIO2_26 142
|
||||
MX51_PAD_EIM_CS2__AUD5_TXD 143
|
||||
MX51_PAD_EIM_CS2__CSI1_D4 144
|
||||
MX51_PAD_EIM_CS2__EIM_CS2 145
|
||||
MX51_PAD_EIM_CS2__FEC_RDATA2 146
|
||||
MX51_PAD_EIM_CS2__GPIO2_27 147
|
||||
MX51_PAD_EIM_CS2__USBOTG_STP 148
|
||||
MX51_PAD_EIM_CS3__AUD5_RXD 149
|
||||
MX51_PAD_EIM_CS3__CSI1_D5 150
|
||||
MX51_PAD_EIM_CS3__EIM_CS3 151
|
||||
MX51_PAD_EIM_CS3__FEC_RDATA3 152
|
||||
MX51_PAD_EIM_CS3__GPIO2_28 153
|
||||
MX51_PAD_EIM_CS3__USBOTG_NXT 154
|
||||
MX51_PAD_EIM_CS4__AUD5_TXC 155
|
||||
MX51_PAD_EIM_CS4__CSI1_D6 156
|
||||
MX51_PAD_EIM_CS4__EIM_CS4 157
|
||||
MX51_PAD_EIM_CS4__FEC_RX_ER 158
|
||||
MX51_PAD_EIM_CS4__GPIO2_29 159
|
||||
MX51_PAD_EIM_CS4__USBOTG_CLK 160
|
||||
MX51_PAD_EIM_CS5__AUD5_TXFS 161
|
||||
MX51_PAD_EIM_CS5__CSI1_D7 162
|
||||
MX51_PAD_EIM_CS5__DISP1_EXT_CLK 163
|
||||
MX51_PAD_EIM_CS5__EIM_CS5 164
|
||||
MX51_PAD_EIM_CS5__FEC_CRS 165
|
||||
MX51_PAD_EIM_CS5__GPIO2_30 166
|
||||
MX51_PAD_EIM_CS5__USBOTG_DIR 167
|
||||
MX51_PAD_EIM_DTACK__EIM_DTACK 168
|
||||
MX51_PAD_EIM_DTACK__GPIO2_31 169
|
||||
MX51_PAD_EIM_LBA__EIM_LBA 170
|
||||
MX51_PAD_EIM_LBA__GPIO3_1 171
|
||||
MX51_PAD_EIM_CRE__EIM_CRE 172
|
||||
MX51_PAD_EIM_CRE__GPIO3_2 173
|
||||
MX51_PAD_DRAM_CS1__DRAM_CS1 174
|
||||
MX51_PAD_NANDF_WE_B__GPIO3_3 175
|
||||
MX51_PAD_NANDF_WE_B__NANDF_WE_B 176
|
||||
MX51_PAD_NANDF_WE_B__PATA_DIOW 177
|
||||
MX51_PAD_NANDF_WE_B__SD3_DATA0 178
|
||||
MX51_PAD_NANDF_RE_B__GPIO3_4 179
|
||||
MX51_PAD_NANDF_RE_B__NANDF_RE_B 180
|
||||
MX51_PAD_NANDF_RE_B__PATA_DIOR 181
|
||||
MX51_PAD_NANDF_RE_B__SD3_DATA1 182
|
||||
MX51_PAD_NANDF_ALE__GPIO3_5 183
|
||||
MX51_PAD_NANDF_ALE__NANDF_ALE 184
|
||||
MX51_PAD_NANDF_ALE__PATA_BUFFER_EN 185
|
||||
MX51_PAD_NANDF_CLE__GPIO3_6 186
|
||||
MX51_PAD_NANDF_CLE__NANDF_CLE 187
|
||||
MX51_PAD_NANDF_CLE__PATA_RESET_B 188
|
||||
MX51_PAD_NANDF_WP_B__GPIO3_7 189
|
||||
MX51_PAD_NANDF_WP_B__NANDF_WP_B 190
|
||||
MX51_PAD_NANDF_WP_B__PATA_DMACK 191
|
||||
MX51_PAD_NANDF_WP_B__SD3_DATA2 192
|
||||
MX51_PAD_NANDF_RB0__ECSPI2_SS1 193
|
||||
MX51_PAD_NANDF_RB0__GPIO3_8 194
|
||||
MX51_PAD_NANDF_RB0__NANDF_RB0 195
|
||||
MX51_PAD_NANDF_RB0__PATA_DMARQ 196
|
||||
MX51_PAD_NANDF_RB0__SD3_DATA3 197
|
||||
MX51_PAD_NANDF_RB1__CSPI_MOSI 198
|
||||
MX51_PAD_NANDF_RB1__ECSPI2_RDY 199
|
||||
MX51_PAD_NANDF_RB1__GPIO3_9 200
|
||||
MX51_PAD_NANDF_RB1__NANDF_RB1 201
|
||||
MX51_PAD_NANDF_RB1__PATA_IORDY 202
|
||||
MX51_PAD_NANDF_RB1__SD4_CMD 203
|
||||
MX51_PAD_NANDF_RB2__DISP2_WAIT 204
|
||||
MX51_PAD_NANDF_RB2__ECSPI2_SCLK 205
|
||||
MX51_PAD_NANDF_RB2__FEC_COL 206
|
||||
MX51_PAD_NANDF_RB2__GPIO3_10 207
|
||||
MX51_PAD_NANDF_RB2__NANDF_RB2 208
|
||||
MX51_PAD_NANDF_RB2__USBH3_H3_DP 209
|
||||
MX51_PAD_NANDF_RB2__USBH3_NXT 210
|
||||
MX51_PAD_NANDF_RB3__DISP1_WAIT 211
|
||||
MX51_PAD_NANDF_RB3__ECSPI2_MISO 212
|
||||
MX51_PAD_NANDF_RB3__FEC_RX_CLK 213
|
||||
MX51_PAD_NANDF_RB3__GPIO3_11 214
|
||||
MX51_PAD_NANDF_RB3__NANDF_RB3 215
|
||||
MX51_PAD_NANDF_RB3__USBH3_CLK 216
|
||||
MX51_PAD_NANDF_RB3__USBH3_H3_DM 217
|
||||
MX51_PAD_GPIO_NAND__GPIO_NAND 218
|
||||
MX51_PAD_GPIO_NAND__PATA_INTRQ 219
|
||||
MX51_PAD_NANDF_CS0__GPIO3_16 220
|
||||
MX51_PAD_NANDF_CS0__NANDF_CS0 221
|
||||
MX51_PAD_NANDF_CS1__GPIO3_17 222
|
||||
MX51_PAD_NANDF_CS1__NANDF_CS1 223
|
||||
MX51_PAD_NANDF_CS2__CSPI_SCLK 224
|
||||
MX51_PAD_NANDF_CS2__FEC_TX_ER 225
|
||||
MX51_PAD_NANDF_CS2__GPIO3_18 226
|
||||
MX51_PAD_NANDF_CS2__NANDF_CS2 227
|
||||
MX51_PAD_NANDF_CS2__PATA_CS_0 228
|
||||
MX51_PAD_NANDF_CS2__SD4_CLK 229
|
||||
MX51_PAD_NANDF_CS2__USBH3_H1_DP 230
|
||||
MX51_PAD_NANDF_CS3__FEC_MDC 231
|
||||
MX51_PAD_NANDF_CS3__GPIO3_19 232
|
||||
MX51_PAD_NANDF_CS3__NANDF_CS3 233
|
||||
MX51_PAD_NANDF_CS3__PATA_CS_1 234
|
||||
MX51_PAD_NANDF_CS3__SD4_DAT0 235
|
||||
MX51_PAD_NANDF_CS3__USBH3_H1_DM 236
|
||||
MX51_PAD_NANDF_CS4__FEC_TDATA1 237
|
||||
MX51_PAD_NANDF_CS4__GPIO3_20 238
|
||||
MX51_PAD_NANDF_CS4__NANDF_CS4 239
|
||||
MX51_PAD_NANDF_CS4__PATA_DA_0 240
|
||||
MX51_PAD_NANDF_CS4__SD4_DAT1 241
|
||||
MX51_PAD_NANDF_CS4__USBH3_STP 242
|
||||
MX51_PAD_NANDF_CS5__FEC_TDATA2 243
|
||||
MX51_PAD_NANDF_CS5__GPIO3_21 244
|
||||
MX51_PAD_NANDF_CS5__NANDF_CS5 245
|
||||
MX51_PAD_NANDF_CS5__PATA_DA_1 246
|
||||
MX51_PAD_NANDF_CS5__SD4_DAT2 247
|
||||
MX51_PAD_NANDF_CS5__USBH3_DIR 248
|
||||
MX51_PAD_NANDF_CS6__CSPI_SS3 249
|
||||
MX51_PAD_NANDF_CS6__FEC_TDATA3 250
|
||||
MX51_PAD_NANDF_CS6__GPIO3_22 251
|
||||
MX51_PAD_NANDF_CS6__NANDF_CS6 252
|
||||
MX51_PAD_NANDF_CS6__PATA_DA_2 253
|
||||
MX51_PAD_NANDF_CS6__SD4_DAT3 254
|
||||
MX51_PAD_NANDF_CS7__FEC_TX_EN 255
|
||||
MX51_PAD_NANDF_CS7__GPIO3_23 256
|
||||
MX51_PAD_NANDF_CS7__NANDF_CS7 257
|
||||
MX51_PAD_NANDF_CS7__SD3_CLK 258
|
||||
MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 259
|
||||
MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK 260
|
||||
MX51_PAD_NANDF_RDY_INT__GPIO3_24 261
|
||||
MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT 262
|
||||
MX51_PAD_NANDF_RDY_INT__SD3_CMD 263
|
||||
MX51_PAD_NANDF_D15__ECSPI2_MOSI 264
|
||||
MX51_PAD_NANDF_D15__GPIO3_25 265
|
||||
MX51_PAD_NANDF_D15__NANDF_D15 266
|
||||
MX51_PAD_NANDF_D15__PATA_DATA15 267
|
||||
MX51_PAD_NANDF_D15__SD3_DAT7 268
|
||||
MX51_PAD_NANDF_D14__ECSPI2_SS3 269
|
||||
MX51_PAD_NANDF_D14__GPIO3_26 270
|
||||
MX51_PAD_NANDF_D14__NANDF_D14 271
|
||||
MX51_PAD_NANDF_D14__PATA_DATA14 272
|
||||
MX51_PAD_NANDF_D14__SD3_DAT6 273
|
||||
MX51_PAD_NANDF_D13__ECSPI2_SS2 274
|
||||
MX51_PAD_NANDF_D13__GPIO3_27 275
|
||||
MX51_PAD_NANDF_D13__NANDF_D13 276
|
||||
MX51_PAD_NANDF_D13__PATA_DATA13 277
|
||||
MX51_PAD_NANDF_D13__SD3_DAT5 278
|
||||
MX51_PAD_NANDF_D12__ECSPI2_SS1 279
|
||||
MX51_PAD_NANDF_D12__GPIO3_28 280
|
||||
MX51_PAD_NANDF_D12__NANDF_D12 281
|
||||
MX51_PAD_NANDF_D12__PATA_DATA12 282
|
||||
MX51_PAD_NANDF_D12__SD3_DAT4 283
|
||||
MX51_PAD_NANDF_D11__FEC_RX_DV 284
|
||||
MX51_PAD_NANDF_D11__GPIO3_29 285
|
||||
MX51_PAD_NANDF_D11__NANDF_D11 286
|
||||
MX51_PAD_NANDF_D11__PATA_DATA11 287
|
||||
MX51_PAD_NANDF_D11__SD3_DATA3 288
|
||||
MX51_PAD_NANDF_D10__GPIO3_30 289
|
||||
MX51_PAD_NANDF_D10__NANDF_D10 290
|
||||
MX51_PAD_NANDF_D10__PATA_DATA10 291
|
||||
MX51_PAD_NANDF_D10__SD3_DATA2 292
|
||||
MX51_PAD_NANDF_D9__FEC_RDATA0 293
|
||||
MX51_PAD_NANDF_D9__GPIO3_31 294
|
||||
MX51_PAD_NANDF_D9__NANDF_D9 295
|
||||
MX51_PAD_NANDF_D9__PATA_DATA9 296
|
||||
MX51_PAD_NANDF_D9__SD3_DATA1 297
|
||||
MX51_PAD_NANDF_D8__FEC_TDATA0 298
|
||||
MX51_PAD_NANDF_D8__GPIO4_0 299
|
||||
MX51_PAD_NANDF_D8__NANDF_D8 300
|
||||
MX51_PAD_NANDF_D8__PATA_DATA8 301
|
||||
MX51_PAD_NANDF_D8__SD3_DATA0 302
|
||||
MX51_PAD_NANDF_D7__GPIO4_1 303
|
||||
MX51_PAD_NANDF_D7__NANDF_D7 304
|
||||
MX51_PAD_NANDF_D7__PATA_DATA7 305
|
||||
MX51_PAD_NANDF_D7__USBH3_DATA0 306
|
||||
MX51_PAD_NANDF_D6__GPIO4_2 307
|
||||
MX51_PAD_NANDF_D6__NANDF_D6 308
|
||||
MX51_PAD_NANDF_D6__PATA_DATA6 309
|
||||
MX51_PAD_NANDF_D6__SD4_LCTL 310
|
||||
MX51_PAD_NANDF_D6__USBH3_DATA1 311
|
||||
MX51_PAD_NANDF_D5__GPIO4_3 312
|
||||
MX51_PAD_NANDF_D5__NANDF_D5 313
|
||||
MX51_PAD_NANDF_D5__PATA_DATA5 314
|
||||
MX51_PAD_NANDF_D5__SD4_WP 315
|
||||
MX51_PAD_NANDF_D5__USBH3_DATA2 316
|
||||
MX51_PAD_NANDF_D4__GPIO4_4 317
|
||||
MX51_PAD_NANDF_D4__NANDF_D4 318
|
||||
MX51_PAD_NANDF_D4__PATA_DATA4 319
|
||||
MX51_PAD_NANDF_D4__SD4_CD 320
|
||||
MX51_PAD_NANDF_D4__USBH3_DATA3 321
|
||||
MX51_PAD_NANDF_D3__GPIO4_5 322
|
||||
MX51_PAD_NANDF_D3__NANDF_D3 323
|
||||
MX51_PAD_NANDF_D3__PATA_DATA3 324
|
||||
MX51_PAD_NANDF_D3__SD4_DAT4 325
|
||||
MX51_PAD_NANDF_D3__USBH3_DATA4 326
|
||||
MX51_PAD_NANDF_D2__GPIO4_6 327
|
||||
MX51_PAD_NANDF_D2__NANDF_D2 328
|
||||
MX51_PAD_NANDF_D2__PATA_DATA2 329
|
||||
MX51_PAD_NANDF_D2__SD4_DAT5 330
|
||||
MX51_PAD_NANDF_D2__USBH3_DATA5 331
|
||||
MX51_PAD_NANDF_D1__GPIO4_7 332
|
||||
MX51_PAD_NANDF_D1__NANDF_D1 333
|
||||
MX51_PAD_NANDF_D1__PATA_DATA1 334
|
||||
MX51_PAD_NANDF_D1__SD4_DAT6 335
|
||||
MX51_PAD_NANDF_D1__USBH3_DATA6 336
|
||||
MX51_PAD_NANDF_D0__GPIO4_8 337
|
||||
MX51_PAD_NANDF_D0__NANDF_D0 338
|
||||
MX51_PAD_NANDF_D0__PATA_DATA0 339
|
||||
MX51_PAD_NANDF_D0__SD4_DAT7 340
|
||||
MX51_PAD_NANDF_D0__USBH3_DATA7 341
|
||||
MX51_PAD_CSI1_D8__CSI1_D8 342
|
||||
MX51_PAD_CSI1_D8__GPIO3_12 343
|
||||
MX51_PAD_CSI1_D9__CSI1_D9 344
|
||||
MX51_PAD_CSI1_D9__GPIO3_13 345
|
||||
MX51_PAD_CSI1_D10__CSI1_D10 346
|
||||
MX51_PAD_CSI1_D11__CSI1_D11 347
|
||||
MX51_PAD_CSI1_D12__CSI1_D12 348
|
||||
MX51_PAD_CSI1_D13__CSI1_D13 349
|
||||
MX51_PAD_CSI1_D14__CSI1_D14 350
|
||||
MX51_PAD_CSI1_D15__CSI1_D15 351
|
||||
MX51_PAD_CSI1_D16__CSI1_D16 352
|
||||
MX51_PAD_CSI1_D17__CSI1_D17 353
|
||||
MX51_PAD_CSI1_D18__CSI1_D18 354
|
||||
MX51_PAD_CSI1_D19__CSI1_D19 355
|
||||
MX51_PAD_CSI1_VSYNC__CSI1_VSYNC 356
|
||||
MX51_PAD_CSI1_VSYNC__GPIO3_14 357
|
||||
MX51_PAD_CSI1_HSYNC__CSI1_HSYNC 358
|
||||
MX51_PAD_CSI1_HSYNC__GPIO3_15 359
|
||||
MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK 360
|
||||
MX51_PAD_CSI1_MCLK__CSI1_MCLK 361
|
||||
MX51_PAD_CSI2_D12__CSI2_D12 362
|
||||
MX51_PAD_CSI2_D12__GPIO4_9 363
|
||||
MX51_PAD_CSI2_D13__CSI2_D13 364
|
||||
MX51_PAD_CSI2_D13__GPIO4_10 365
|
||||
MX51_PAD_CSI2_D14__CSI2_D14 366
|
||||
MX51_PAD_CSI2_D15__CSI2_D15 367
|
||||
MX51_PAD_CSI2_D16__CSI2_D16 368
|
||||
MX51_PAD_CSI2_D17__CSI2_D17 369
|
||||
MX51_PAD_CSI2_D18__CSI2_D18 370
|
||||
MX51_PAD_CSI2_D18__GPIO4_11 371
|
||||
MX51_PAD_CSI2_D19__CSI2_D19 372
|
||||
MX51_PAD_CSI2_D19__GPIO4_12 373
|
||||
MX51_PAD_CSI2_VSYNC__CSI2_VSYNC 374
|
||||
MX51_PAD_CSI2_VSYNC__GPIO4_13 375
|
||||
MX51_PAD_CSI2_HSYNC__CSI2_HSYNC 376
|
||||
MX51_PAD_CSI2_HSYNC__GPIO4_14 377
|
||||
MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK 378
|
||||
MX51_PAD_CSI2_PIXCLK__GPIO4_15 379
|
||||
MX51_PAD_I2C1_CLK__GPIO4_16 380
|
||||
MX51_PAD_I2C1_CLK__I2C1_CLK 381
|
||||
MX51_PAD_I2C1_DAT__GPIO4_17 382
|
||||
MX51_PAD_I2C1_DAT__I2C1_DAT 383
|
||||
MX51_PAD_AUD3_BB_TXD__AUD3_TXD 384
|
||||
MX51_PAD_AUD3_BB_TXD__GPIO4_18 385
|
||||
MX51_PAD_AUD3_BB_RXD__AUD3_RXD 386
|
||||
MX51_PAD_AUD3_BB_RXD__GPIO4_19 387
|
||||
MX51_PAD_AUD3_BB_RXD__UART3_RXD 388
|
||||
MX51_PAD_AUD3_BB_CK__AUD3_TXC 389
|
||||
MX51_PAD_AUD3_BB_CK__GPIO4_20 390
|
||||
MX51_PAD_AUD3_BB_FS__AUD3_TXFS 391
|
||||
MX51_PAD_AUD3_BB_FS__GPIO4_21 392
|
||||
MX51_PAD_AUD3_BB_FS__UART3_TXD 393
|
||||
MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 394
|
||||
MX51_PAD_CSPI1_MOSI__GPIO4_22 395
|
||||
MX51_PAD_CSPI1_MOSI__I2C1_SDA 396
|
||||
MX51_PAD_CSPI1_MISO__AUD4_RXD 397
|
||||
MX51_PAD_CSPI1_MISO__ECSPI1_MISO 398
|
||||
MX51_PAD_CSPI1_MISO__GPIO4_23 399
|
||||
MX51_PAD_CSPI1_SS0__AUD4_TXC 400
|
||||
MX51_PAD_CSPI1_SS0__ECSPI1_SS0 401
|
||||
MX51_PAD_CSPI1_SS0__GPIO4_24 402
|
||||
MX51_PAD_CSPI1_SS1__AUD4_TXD 403
|
||||
MX51_PAD_CSPI1_SS1__ECSPI1_SS1 404
|
||||
MX51_PAD_CSPI1_SS1__GPIO4_25 405
|
||||
MX51_PAD_CSPI1_RDY__AUD4_TXFS 406
|
||||
MX51_PAD_CSPI1_RDY__ECSPI1_RDY 407
|
||||
MX51_PAD_CSPI1_RDY__GPIO4_26 408
|
||||
MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 409
|
||||
MX51_PAD_CSPI1_SCLK__GPIO4_27 410
|
||||
MX51_PAD_CSPI1_SCLK__I2C1_SCL 411
|
||||
MX51_PAD_UART1_RXD__GPIO4_28 412
|
||||
MX51_PAD_UART1_RXD__UART1_RXD 413
|
||||
MX51_PAD_UART1_TXD__GPIO4_29 414
|
||||
MX51_PAD_UART1_TXD__PWM2_PWMO 415
|
||||
MX51_PAD_UART1_TXD__UART1_TXD 416
|
||||
MX51_PAD_UART1_RTS__GPIO4_30 417
|
||||
MX51_PAD_UART1_RTS__UART1_RTS 418
|
||||
MX51_PAD_UART1_CTS__GPIO4_31 419
|
||||
MX51_PAD_UART1_CTS__UART1_CTS 420
|
||||
MX51_PAD_UART2_RXD__FIRI_TXD 421
|
||||
MX51_PAD_UART2_RXD__GPIO1_20 422
|
||||
MX51_PAD_UART2_RXD__UART2_RXD 423
|
||||
MX51_PAD_UART2_TXD__FIRI_RXD 424
|
||||
MX51_PAD_UART2_TXD__GPIO1_21 425
|
||||
MX51_PAD_UART2_TXD__UART2_TXD 426
|
||||
MX51_PAD_UART3_RXD__CSI1_D0 427
|
||||
MX51_PAD_UART3_RXD__GPIO1_22 428
|
||||
MX51_PAD_UART3_RXD__UART1_DTR 429
|
||||
MX51_PAD_UART3_RXD__UART3_RXD 430
|
||||
MX51_PAD_UART3_TXD__CSI1_D1 431
|
||||
MX51_PAD_UART3_TXD__GPIO1_23 432
|
||||
MX51_PAD_UART3_TXD__UART1_DSR 433
|
||||
MX51_PAD_UART3_TXD__UART3_TXD 434
|
||||
MX51_PAD_OWIRE_LINE__GPIO1_24 435
|
||||
MX51_PAD_OWIRE_LINE__OWIRE_LINE 436
|
||||
MX51_PAD_OWIRE_LINE__SPDIF_OUT 437
|
||||
MX51_PAD_KEY_ROW0__KEY_ROW0 438
|
||||
MX51_PAD_KEY_ROW1__KEY_ROW1 439
|
||||
MX51_PAD_KEY_ROW2__KEY_ROW2 440
|
||||
MX51_PAD_KEY_ROW3__KEY_ROW3 441
|
||||
MX51_PAD_KEY_COL0__KEY_COL0 442
|
||||
MX51_PAD_KEY_COL0__PLL1_BYP 443
|
||||
MX51_PAD_KEY_COL1__KEY_COL1 444
|
||||
MX51_PAD_KEY_COL1__PLL2_BYP 445
|
||||
MX51_PAD_KEY_COL2__KEY_COL2 446
|
||||
MX51_PAD_KEY_COL2__PLL3_BYP 447
|
||||
MX51_PAD_KEY_COL3__KEY_COL3 448
|
||||
MX51_PAD_KEY_COL4__I2C2_SCL 449
|
||||
MX51_PAD_KEY_COL4__KEY_COL4 450
|
||||
MX51_PAD_KEY_COL4__SPDIF_OUT1 451
|
||||
MX51_PAD_KEY_COL4__UART1_RI 452
|
||||
MX51_PAD_KEY_COL4__UART3_RTS 453
|
||||
MX51_PAD_KEY_COL5__I2C2_SDA 454
|
||||
MX51_PAD_KEY_COL5__KEY_COL5 455
|
||||
MX51_PAD_KEY_COL5__UART1_DCD 456
|
||||
MX51_PAD_KEY_COL5__UART3_CTS 457
|
||||
MX51_PAD_USBH1_CLK__CSPI_SCLK 458
|
||||
MX51_PAD_USBH1_CLK__GPIO1_25 459
|
||||
MX51_PAD_USBH1_CLK__I2C2_SCL 460
|
||||
MX51_PAD_USBH1_CLK__USBH1_CLK 461
|
||||
MX51_PAD_USBH1_DIR__CSPI_MOSI 462
|
||||
MX51_PAD_USBH1_DIR__GPIO1_26 463
|
||||
MX51_PAD_USBH1_DIR__I2C2_SDA 464
|
||||
MX51_PAD_USBH1_DIR__USBH1_DIR 465
|
||||
MX51_PAD_USBH1_STP__CSPI_RDY 466
|
||||
MX51_PAD_USBH1_STP__GPIO1_27 467
|
||||
MX51_PAD_USBH1_STP__UART3_RXD 468
|
||||
MX51_PAD_USBH1_STP__USBH1_STP 469
|
||||
MX51_PAD_USBH1_NXT__CSPI_MISO 470
|
||||
MX51_PAD_USBH1_NXT__GPIO1_28 471
|
||||
MX51_PAD_USBH1_NXT__UART3_TXD 472
|
||||
MX51_PAD_USBH1_NXT__USBH1_NXT 473
|
||||
MX51_PAD_USBH1_DATA0__GPIO1_11 474
|
||||
MX51_PAD_USBH1_DATA0__UART2_CTS 475
|
||||
MX51_PAD_USBH1_DATA0__USBH1_DATA0 476
|
||||
MX51_PAD_USBH1_DATA1__GPIO1_12 477
|
||||
MX51_PAD_USBH1_DATA1__UART2_RXD 478
|
||||
MX51_PAD_USBH1_DATA1__USBH1_DATA1 479
|
||||
MX51_PAD_USBH1_DATA2__GPIO1_13 480
|
||||
MX51_PAD_USBH1_DATA2__UART2_TXD 481
|
||||
MX51_PAD_USBH1_DATA2__USBH1_DATA2 482
|
||||
MX51_PAD_USBH1_DATA3__GPIO1_14 483
|
||||
MX51_PAD_USBH1_DATA3__UART2_RTS 484
|
||||
MX51_PAD_USBH1_DATA3__USBH1_DATA3 485
|
||||
MX51_PAD_USBH1_DATA4__CSPI_SS0 486
|
||||
MX51_PAD_USBH1_DATA4__GPIO1_15 487
|
||||
MX51_PAD_USBH1_DATA4__USBH1_DATA4 488
|
||||
MX51_PAD_USBH1_DATA5__CSPI_SS1 489
|
||||
MX51_PAD_USBH1_DATA5__GPIO1_16 490
|
||||
MX51_PAD_USBH1_DATA5__USBH1_DATA5 491
|
||||
MX51_PAD_USBH1_DATA6__CSPI_SS3 492
|
||||
MX51_PAD_USBH1_DATA6__GPIO1_17 493
|
||||
MX51_PAD_USBH1_DATA6__USBH1_DATA6 494
|
||||
MX51_PAD_USBH1_DATA7__ECSPI1_SS3 495
|
||||
MX51_PAD_USBH1_DATA7__ECSPI2_SS3 496
|
||||
MX51_PAD_USBH1_DATA7__GPIO1_18 497
|
||||
MX51_PAD_USBH1_DATA7__USBH1_DATA7 498
|
||||
MX51_PAD_DI1_PIN11__DI1_PIN11 499
|
||||
MX51_PAD_DI1_PIN11__ECSPI1_SS2 500
|
||||
MX51_PAD_DI1_PIN11__GPIO3_0 501
|
||||
MX51_PAD_DI1_PIN12__DI1_PIN12 502
|
||||
MX51_PAD_DI1_PIN12__GPIO3_1 503
|
||||
MX51_PAD_DI1_PIN13__DI1_PIN13 504
|
||||
MX51_PAD_DI1_PIN13__GPIO3_2 505
|
||||
MX51_PAD_DI1_D0_CS__DI1_D0_CS 506
|
||||
MX51_PAD_DI1_D0_CS__GPIO3_3 507
|
||||
MX51_PAD_DI1_D1_CS__DI1_D1_CS 508
|
||||
MX51_PAD_DI1_D1_CS__DISP1_PIN14 509
|
||||
MX51_PAD_DI1_D1_CS__DISP1_PIN5 510
|
||||
MX51_PAD_DI1_D1_CS__GPIO3_4 511
|
||||
MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 512
|
||||
MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN 513
|
||||
MX51_PAD_DISPB2_SER_DIN__GPIO3_5 514
|
||||
MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 515
|
||||
MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO 516
|
||||
MX51_PAD_DISPB2_SER_DIO__GPIO3_6 517
|
||||
MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 518
|
||||
MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 519
|
||||
MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK 520
|
||||
MX51_PAD_DISPB2_SER_CLK__GPIO3_7 521
|
||||
MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK 522
|
||||
MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 523
|
||||
MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 524
|
||||
MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS 525
|
||||
MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS 526
|
||||
MX51_PAD_DISPB2_SER_RS__GPIO3_8 527
|
||||
MX51_PAD_DISP1_DAT0__DISP1_DAT0 528
|
||||
MX51_PAD_DISP1_DAT1__DISP1_DAT1 529
|
||||
MX51_PAD_DISP1_DAT2__DISP1_DAT2 530
|
||||
MX51_PAD_DISP1_DAT3__DISP1_DAT3 531
|
||||
MX51_PAD_DISP1_DAT4__DISP1_DAT4 532
|
||||
MX51_PAD_DISP1_DAT5__DISP1_DAT5 533
|
||||
MX51_PAD_DISP1_DAT6__BOOT_USB_SRC 534
|
||||
MX51_PAD_DISP1_DAT6__DISP1_DAT6 535
|
||||
MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG 536
|
||||
MX51_PAD_DISP1_DAT7__DISP1_DAT7 537
|
||||
MX51_PAD_DISP1_DAT8__BOOT_SRC0 538
|
||||
MX51_PAD_DISP1_DAT8__DISP1_DAT8 539
|
||||
MX51_PAD_DISP1_DAT9__BOOT_SRC1 540
|
||||
MX51_PAD_DISP1_DAT9__DISP1_DAT9 541
|
||||
MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE 542
|
||||
MX51_PAD_DISP1_DAT10__DISP1_DAT10 543
|
||||
MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 544
|
||||
MX51_PAD_DISP1_DAT11__DISP1_DAT11 545
|
||||
MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL 546
|
||||
MX51_PAD_DISP1_DAT12__DISP1_DAT12 547
|
||||
MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 548
|
||||
MX51_PAD_DISP1_DAT13__DISP1_DAT13 549
|
||||
MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 550
|
||||
MX51_PAD_DISP1_DAT14__DISP1_DAT14 551
|
||||
MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH 552
|
||||
MX51_PAD_DISP1_DAT15__DISP1_DAT15 553
|
||||
MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 554
|
||||
MX51_PAD_DISP1_DAT16__DISP1_DAT16 555
|
||||
MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 556
|
||||
MX51_PAD_DISP1_DAT17__DISP1_DAT17 557
|
||||
MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 558
|
||||
MX51_PAD_DISP1_DAT18__DISP1_DAT18 559
|
||||
MX51_PAD_DISP1_DAT18__DISP2_PIN11 560
|
||||
MX51_PAD_DISP1_DAT18__DISP2_PIN5 561
|
||||
MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 562
|
||||
MX51_PAD_DISP1_DAT19__DISP1_DAT19 563
|
||||
MX51_PAD_DISP1_DAT19__DISP2_PIN12 564
|
||||
MX51_PAD_DISP1_DAT19__DISP2_PIN6 565
|
||||
MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 566
|
||||
MX51_PAD_DISP1_DAT20__DISP1_DAT20 567
|
||||
MX51_PAD_DISP1_DAT20__DISP2_PIN13 568
|
||||
MX51_PAD_DISP1_DAT20__DISP2_PIN7 569
|
||||
MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 570
|
||||
MX51_PAD_DISP1_DAT21__DISP1_DAT21 571
|
||||
MX51_PAD_DISP1_DAT21__DISP2_PIN14 572
|
||||
MX51_PAD_DISP1_DAT21__DISP2_PIN8 573
|
||||
MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 574
|
||||
MX51_PAD_DISP1_DAT22__DISP1_DAT22 575
|
||||
MX51_PAD_DISP1_DAT22__DISP2_D0_CS 576
|
||||
MX51_PAD_DISP1_DAT22__DISP2_DAT16 577
|
||||
MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 578
|
||||
MX51_PAD_DISP1_DAT23__DISP1_DAT23 579
|
||||
MX51_PAD_DISP1_DAT23__DISP2_D1_CS 580
|
||||
MX51_PAD_DISP1_DAT23__DISP2_DAT17 581
|
||||
MX51_PAD_DISP1_DAT23__DISP2_SER_CS 582
|
||||
MX51_PAD_DI1_PIN3__DI1_PIN3 583
|
||||
MX51_PAD_DI1_PIN2__DI1_PIN2 584
|
||||
MX51_PAD_DI_GP2__DISP1_SER_CLK 585
|
||||
MX51_PAD_DI_GP2__DISP2_WAIT 586
|
||||
MX51_PAD_DI_GP3__CSI1_DATA_EN 587
|
||||
MX51_PAD_DI_GP3__DISP1_SER_DIO 588
|
||||
MX51_PAD_DI_GP3__FEC_TX_ER 589
|
||||
MX51_PAD_DI2_PIN4__CSI2_DATA_EN 590
|
||||
MX51_PAD_DI2_PIN4__DI2_PIN4 591
|
||||
MX51_PAD_DI2_PIN4__FEC_CRS 592
|
||||
MX51_PAD_DI2_PIN2__DI2_PIN2 593
|
||||
MX51_PAD_DI2_PIN2__FEC_MDC 594
|
||||
MX51_PAD_DI2_PIN3__DI2_PIN3 595
|
||||
MX51_PAD_DI2_PIN3__FEC_MDIO 596
|
||||
MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 597
|
||||
MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 598
|
||||
MX51_PAD_DI_GP4__DI2_PIN15 599
|
||||
MX51_PAD_DI_GP4__DISP1_SER_DIN 600
|
||||
MX51_PAD_DI_GP4__DISP2_PIN1 601
|
||||
MX51_PAD_DI_GP4__FEC_RDATA2 602
|
||||
MX51_PAD_DISP2_DAT0__DISP2_DAT0 603
|
||||
MX51_PAD_DISP2_DAT0__FEC_RDATA3 604
|
||||
MX51_PAD_DISP2_DAT0__KEY_COL6 605
|
||||
MX51_PAD_DISP2_DAT0__UART3_RXD 606
|
||||
MX51_PAD_DISP2_DAT0__USBH3_CLK 607
|
||||
MX51_PAD_DISP2_DAT1__DISP2_DAT1 608
|
||||
MX51_PAD_DISP2_DAT1__FEC_RX_ER 609
|
||||
MX51_PAD_DISP2_DAT1__KEY_COL7 610
|
||||
MX51_PAD_DISP2_DAT1__UART3_TXD 611
|
||||
MX51_PAD_DISP2_DAT1__USBH3_DIR 612
|
||||
MX51_PAD_DISP2_DAT2__DISP2_DAT2 613
|
||||
MX51_PAD_DISP2_DAT3__DISP2_DAT3 614
|
||||
MX51_PAD_DISP2_DAT4__DISP2_DAT4 615
|
||||
MX51_PAD_DISP2_DAT5__DISP2_DAT5 616
|
||||
MX51_PAD_DISP2_DAT6__DISP2_DAT6 617
|
||||
MX51_PAD_DISP2_DAT6__FEC_TDATA1 618
|
||||
MX51_PAD_DISP2_DAT6__GPIO1_19 619
|
||||
MX51_PAD_DISP2_DAT6__KEY_ROW4 620
|
||||
MX51_PAD_DISP2_DAT6__USBH3_STP 621
|
||||
MX51_PAD_DISP2_DAT7__DISP2_DAT7 622
|
||||
MX51_PAD_DISP2_DAT7__FEC_TDATA2 623
|
||||
MX51_PAD_DISP2_DAT7__GPIO1_29 624
|
||||
MX51_PAD_DISP2_DAT7__KEY_ROW5 625
|
||||
MX51_PAD_DISP2_DAT7__USBH3_NXT 626
|
||||
MX51_PAD_DISP2_DAT8__DISP2_DAT8 627
|
||||
MX51_PAD_DISP2_DAT8__FEC_TDATA3 628
|
||||
MX51_PAD_DISP2_DAT8__GPIO1_30 629
|
||||
MX51_PAD_DISP2_DAT8__KEY_ROW6 630
|
||||
MX51_PAD_DISP2_DAT8__USBH3_DATA0 631
|
||||
MX51_PAD_DISP2_DAT9__AUD6_RXC 632
|
||||
MX51_PAD_DISP2_DAT9__DISP2_DAT9 633
|
||||
MX51_PAD_DISP2_DAT9__FEC_TX_EN 634
|
||||
MX51_PAD_DISP2_DAT9__GPIO1_31 635
|
||||
MX51_PAD_DISP2_DAT9__USBH3_DATA1 636
|
||||
MX51_PAD_DISP2_DAT10__DISP2_DAT10 637
|
||||
MX51_PAD_DISP2_DAT10__DISP2_SER_CS 638
|
||||
MX51_PAD_DISP2_DAT10__FEC_COL 639
|
||||
MX51_PAD_DISP2_DAT10__KEY_ROW7 640
|
||||
MX51_PAD_DISP2_DAT10__USBH3_DATA2 641
|
||||
MX51_PAD_DISP2_DAT11__AUD6_TXD 642
|
||||
MX51_PAD_DISP2_DAT11__DISP2_DAT11 643
|
||||
MX51_PAD_DISP2_DAT11__FEC_RX_CLK 644
|
||||
MX51_PAD_DISP2_DAT11__GPIO1_10 645
|
||||
MX51_PAD_DISP2_DAT11__USBH3_DATA3 646
|
||||
MX51_PAD_DISP2_DAT12__AUD6_RXD 647
|
||||
MX51_PAD_DISP2_DAT12__DISP2_DAT12 648
|
||||
MX51_PAD_DISP2_DAT12__FEC_RX_DV 649
|
||||
MX51_PAD_DISP2_DAT12__USBH3_DATA4 650
|
||||
MX51_PAD_DISP2_DAT13__AUD6_TXC 651
|
||||
MX51_PAD_DISP2_DAT13__DISP2_DAT13 652
|
||||
MX51_PAD_DISP2_DAT13__FEC_TX_CLK 653
|
||||
MX51_PAD_DISP2_DAT13__USBH3_DATA5 654
|
||||
MX51_PAD_DISP2_DAT14__AUD6_TXFS 655
|
||||
MX51_PAD_DISP2_DAT14__DISP2_DAT14 656
|
||||
MX51_PAD_DISP2_DAT14__FEC_RDATA0 657
|
||||
MX51_PAD_DISP2_DAT14__USBH3_DATA6 658
|
||||
MX51_PAD_DISP2_DAT15__AUD6_RXFS 659
|
||||
MX51_PAD_DISP2_DAT15__DISP1_SER_CS 660
|
||||
MX51_PAD_DISP2_DAT15__DISP2_DAT15 661
|
||||
MX51_PAD_DISP2_DAT15__FEC_TDATA0 662
|
||||
MX51_PAD_DISP2_DAT15__USBH3_DATA7 663
|
||||
MX51_PAD_SD1_CMD__AUD5_RXFS 664
|
||||
MX51_PAD_SD1_CMD__CSPI_MOSI 665
|
||||
MX51_PAD_SD1_CMD__SD1_CMD 666
|
||||
MX51_PAD_SD1_CLK__AUD5_RXC 667
|
||||
MX51_PAD_SD1_CLK__CSPI_SCLK 668
|
||||
MX51_PAD_SD1_CLK__SD1_CLK 669
|
||||
MX51_PAD_SD1_DATA0__AUD5_TXD 670
|
||||
MX51_PAD_SD1_DATA0__CSPI_MISO 671
|
||||
MX51_PAD_SD1_DATA0__SD1_DATA0 672
|
||||
MX51_PAD_EIM_DA0__EIM_DA0 673
|
||||
MX51_PAD_EIM_DA1__EIM_DA1 674
|
||||
MX51_PAD_EIM_DA2__EIM_DA2 675
|
||||
MX51_PAD_EIM_DA3__EIM_DA3 676
|
||||
MX51_PAD_SD1_DATA1__AUD5_RXD 677
|
||||
MX51_PAD_SD1_DATA1__SD1_DATA1 678
|
||||
MX51_PAD_EIM_DA4__EIM_DA4 679
|
||||
MX51_PAD_EIM_DA5__EIM_DA5 680
|
||||
MX51_PAD_EIM_DA6__EIM_DA6 681
|
||||
MX51_PAD_EIM_DA7__EIM_DA7 682
|
||||
MX51_PAD_SD1_DATA2__AUD5_TXC 683
|
||||
MX51_PAD_SD1_DATA2__SD1_DATA2 684
|
||||
MX51_PAD_EIM_DA10__EIM_DA10 685
|
||||
MX51_PAD_EIM_DA11__EIM_DA11 686
|
||||
MX51_PAD_EIM_DA8__EIM_DA8 687
|
||||
MX51_PAD_EIM_DA9__EIM_DA9 688
|
||||
MX51_PAD_SD1_DATA3__AUD5_TXFS 689
|
||||
MX51_PAD_SD1_DATA3__CSPI_SS1 690
|
||||
MX51_PAD_SD1_DATA3__SD1_DATA3 691
|
||||
MX51_PAD_GPIO1_0__CSPI_SS2 692
|
||||
MX51_PAD_GPIO1_0__GPIO1_0 693
|
||||
MX51_PAD_GPIO1_0__SD1_CD 694
|
||||
MX51_PAD_GPIO1_1__CSPI_MISO 695
|
||||
MX51_PAD_GPIO1_1__GPIO1_1 696
|
||||
MX51_PAD_GPIO1_1__SD1_WP 697
|
||||
MX51_PAD_EIM_DA12__EIM_DA12 698
|
||||
MX51_PAD_EIM_DA13__EIM_DA13 699
|
||||
MX51_PAD_EIM_DA14__EIM_DA14 700
|
||||
MX51_PAD_EIM_DA15__EIM_DA15 701
|
||||
MX51_PAD_SD2_CMD__CSPI_MOSI 702
|
||||
MX51_PAD_SD2_CMD__I2C1_SCL 703
|
||||
MX51_PAD_SD2_CMD__SD2_CMD 704
|
||||
MX51_PAD_SD2_CLK__CSPI_SCLK 705
|
||||
MX51_PAD_SD2_CLK__I2C1_SDA 706
|
||||
MX51_PAD_SD2_CLK__SD2_CLK 707
|
||||
MX51_PAD_SD2_DATA0__CSPI_MISO 708
|
||||
MX51_PAD_SD2_DATA0__SD1_DAT4 709
|
||||
MX51_PAD_SD2_DATA0__SD2_DATA0 710
|
||||
MX51_PAD_SD2_DATA1__SD1_DAT5 711
|
||||
MX51_PAD_SD2_DATA1__SD2_DATA1 712
|
||||
MX51_PAD_SD2_DATA1__USBH3_H2_DP 713
|
||||
MX51_PAD_SD2_DATA2__SD1_DAT6 714
|
||||
MX51_PAD_SD2_DATA2__SD2_DATA2 715
|
||||
MX51_PAD_SD2_DATA2__USBH3_H2_DM 716
|
||||
MX51_PAD_SD2_DATA3__CSPI_SS2 717
|
||||
MX51_PAD_SD2_DATA3__SD1_DAT7 718
|
||||
MX51_PAD_SD2_DATA3__SD2_DATA3 719
|
||||
MX51_PAD_GPIO1_2__CCM_OUT_2 720
|
||||
MX51_PAD_GPIO1_2__GPIO1_2 721
|
||||
MX51_PAD_GPIO1_2__I2C2_SCL 722
|
||||
MX51_PAD_GPIO1_2__PLL1_BYP 723
|
||||
MX51_PAD_GPIO1_2__PWM1_PWMO 724
|
||||
MX51_PAD_GPIO1_3__GPIO1_3 725
|
||||
MX51_PAD_GPIO1_3__I2C2_SDA 726
|
||||
MX51_PAD_GPIO1_3__PLL2_BYP 727
|
||||
MX51_PAD_GPIO1_3__PWM2_PWMO 728
|
||||
MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ 729
|
||||
MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B 730
|
||||
MX51_PAD_GPIO1_4__DISP2_EXT_CLK 731
|
||||
MX51_PAD_GPIO1_4__EIM_RDY 732
|
||||
MX51_PAD_GPIO1_4__GPIO1_4 733
|
||||
MX51_PAD_GPIO1_4__WDOG1_WDOG_B 734
|
||||
MX51_PAD_GPIO1_5__CSI2_MCLK 735
|
||||
MX51_PAD_GPIO1_5__DISP2_PIN16 736
|
||||
MX51_PAD_GPIO1_5__GPIO1_5 737
|
||||
MX51_PAD_GPIO1_5__WDOG2_WDOG_B 738
|
||||
MX51_PAD_GPIO1_6__DISP2_PIN17 739
|
||||
MX51_PAD_GPIO1_6__GPIO1_6 740
|
||||
MX51_PAD_GPIO1_6__REF_EN_B 741
|
||||
MX51_PAD_GPIO1_7__CCM_OUT_0 742
|
||||
MX51_PAD_GPIO1_7__GPIO1_7 743
|
||||
MX51_PAD_GPIO1_7__SD2_WP 744
|
||||
MX51_PAD_GPIO1_7__SPDIF_OUT1 745
|
||||
MX51_PAD_GPIO1_8__CSI2_DATA_EN 746
|
||||
MX51_PAD_GPIO1_8__GPIO1_8 747
|
||||
MX51_PAD_GPIO1_8__SD2_CD 748
|
||||
MX51_PAD_GPIO1_8__USBH3_PWR 749
|
||||
MX51_PAD_GPIO1_9__CCM_OUT_1 750
|
||||
MX51_PAD_GPIO1_9__DISP2_D1_CS 751
|
||||
MX51_PAD_GPIO1_9__DISP2_SER_CS 752
|
||||
MX51_PAD_GPIO1_9__GPIO1_9 753
|
||||
MX51_PAD_GPIO1_9__SD2_LCTL 754
|
||||
MX51_PAD_GPIO1_9__USBH3_OC 755
|
1202
Documentation/devicetree/bindings/pinctrl/fsl,imx53-pinctrl.txt
Normal file
1202
Documentation/devicetree/bindings/pinctrl/fsl,imx53-pinctrl.txt
Normal file
File diff suppressed because it is too large
Load Diff
1628
Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt
Normal file
1628
Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt
Normal file
File diff suppressed because it is too large
Load Diff
918
Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt
Normal file
918
Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt
Normal file
@ -0,0 +1,918 @@
|
||||
* Freescale MXS Pin Controller
|
||||
|
||||
The pins controlled by mxs pin controller are organized in banks, each bank
|
||||
has 32 pins. Each pin has 4 multiplexing functions, and generally, the 4th
|
||||
function is GPIO. The configuration on the pins includes drive strength,
|
||||
voltage and pull-up.
|
||||
|
||||
Required properties:
|
||||
- compatible: "fsl,imx23-pinctrl" or "fsl,imx28-pinctrl"
|
||||
- reg: Should contain the register physical address and length for the
|
||||
pin controller.
|
||||
|
||||
Please refer to pinctrl-bindings.txt in this directory for details of the
|
||||
common pinctrl bindings used by client devices.
|
||||
|
||||
The node of mxs pin controller acts as a container for an arbitrary number of
|
||||
subnodes. Each of these subnodes represents some desired configuration for
|
||||
a group of pins, and only affects those parameters that are explicitly listed.
|
||||
In other words, a subnode that describes a drive strength parameter implies no
|
||||
information about pull-up. For this reason, even seemingly boolean values are
|
||||
actually tristates in this binding: unspecified, off, or on. Unspecified is
|
||||
represented as an absent property, and off/on are represented as integer
|
||||
values 0 and 1.
|
||||
|
||||
Those subnodes under mxs pin controller node will fall into two categories.
|
||||
One is to set up a group of pins for a function, both mux selection and pin
|
||||
configurations, and it's called group node in the binding document. The other
|
||||
one is to adjust the pin configuration for some particular pins that need a
|
||||
different configuration than what is defined in group node. The binding
|
||||
document calls this type of node config node.
|
||||
|
||||
On mxs, there is no hardware pin group. The pin group in this binding only
|
||||
means a group of pins put together for particular peripheral to work in
|
||||
particular function, like SSP0 functioning as mmc0-8bit. That said, the
|
||||
group node should include all the pins needed for one function rather than
|
||||
having these pins defined in several group nodes. It also means each of
|
||||
"pinctrl-*" phandle in client device node should only have one group node
|
||||
pointed in there, while the phandle can have multiple config node referenced
|
||||
there to adjust configurations for some pins in the group.
|
||||
|
||||
Required subnode-properties:
|
||||
- fsl,pinmux-ids: An integer array. Each integer in the array specify a pin
|
||||
with given mux function, with bank, pin and mux packed as below.
|
||||
|
||||
[15..12] : bank number
|
||||
[11..4] : pin number
|
||||
[3..0] : mux selection
|
||||
|
||||
This integer with mux selection packed is used as an entity by both group
|
||||
and config nodes to identify a pin. The mux selection in the integer takes
|
||||
effects only on group node, and will get ignored by driver with config node,
|
||||
since config node is only meant to set up pin configurations.
|
||||
|
||||
Valid values for these integers are listed below.
|
||||
|
||||
- reg: Should be the index of the group nodes for same function. This property
|
||||
is required only for group nodes, and should not be present in any config
|
||||
nodes.
|
||||
|
||||
Optional subnode-properties:
|
||||
- fsl,drive-strength: Integer.
|
||||
0: 4 mA
|
||||
1: 8 mA
|
||||
2: 12 mA
|
||||
3: 16 mA
|
||||
- fsl,voltage: Integer.
|
||||
0: 1.8 V
|
||||
1: 3.3 V
|
||||
- fsl,pull-up: Integer.
|
||||
0: Disable the internal pull-up
|
||||
1: Enable the internal pull-up
|
||||
|
||||
Examples:
|
||||
|
||||
pinctrl@80018000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,imx28-pinctrl";
|
||||
reg = <0x80018000 2000>;
|
||||
|
||||
mmc0_8bit_pins_a: mmc0-8bit@0 {
|
||||
reg = <0>;
|
||||
fsl,pinmux-ids = <
|
||||
0x2000 0x2010 0x2020 0x2030
|
||||
0x2040 0x2050 0x2060 0x2070
|
||||
0x2080 0x2090 0x20a0>;
|
||||
fsl,drive-strength = <1>;
|
||||
fsl,voltage = <1>;
|
||||
fsl,pull-up = <1>;
|
||||
};
|
||||
|
||||
mmc_cd_cfg: mmc-cd-cfg {
|
||||
fsl,pinmux-ids = <0x2090>;
|
||||
fsl,pull-up = <0>;
|
||||
};
|
||||
|
||||
mmc_sck_cfg: mmc-sck-cfg {
|
||||
fsl,pinmux-ids = <0x20a0>;
|
||||
fsl,drive-strength = <2>;
|
||||
fsl,pull-up = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
In this example, group node mmc0-8bit defines a group of pins for mxs SSP0
|
||||
to function as a 8-bit mmc device, with 8mA, 3.3V and pull-up configurations
|
||||
applied on all these pins. And config nodes mmc-cd-cfg and mmc-sck-cfg are
|
||||
adjusting the configuration for pins card-detection and clock from what group
|
||||
node mmc0-8bit defines. Only the configuration properties to be adjusted need
|
||||
to be listed in the config nodes.
|
||||
|
||||
Valid values for i.MX28 pinmux-id:
|
||||
|
||||
pinmux id
|
||||
------ --
|
||||
MX28_PAD_GPMI_D00__GPMI_D0 0x0000
|
||||
MX28_PAD_GPMI_D01__GPMI_D1 0x0010
|
||||
MX28_PAD_GPMI_D02__GPMI_D2 0x0020
|
||||
MX28_PAD_GPMI_D03__GPMI_D3 0x0030
|
||||
MX28_PAD_GPMI_D04__GPMI_D4 0x0040
|
||||
MX28_PAD_GPMI_D05__GPMI_D5 0x0050
|
||||
MX28_PAD_GPMI_D06__GPMI_D6 0x0060
|
||||
MX28_PAD_GPMI_D07__GPMI_D7 0x0070
|
||||
MX28_PAD_GPMI_CE0N__GPMI_CE0N 0x0100
|
||||
MX28_PAD_GPMI_CE1N__GPMI_CE1N 0x0110
|
||||
MX28_PAD_GPMI_CE2N__GPMI_CE2N 0x0120
|
||||
MX28_PAD_GPMI_CE3N__GPMI_CE3N 0x0130
|
||||
MX28_PAD_GPMI_RDY0__GPMI_READY0 0x0140
|
||||
MX28_PAD_GPMI_RDY1__GPMI_READY1 0x0150
|
||||
MX28_PAD_GPMI_RDY2__GPMI_READY2 0x0160
|
||||
MX28_PAD_GPMI_RDY3__GPMI_READY3 0x0170
|
||||
MX28_PAD_GPMI_RDN__GPMI_RDN 0x0180
|
||||
MX28_PAD_GPMI_WRN__GPMI_WRN 0x0190
|
||||
MX28_PAD_GPMI_ALE__GPMI_ALE 0x01a0
|
||||
MX28_PAD_GPMI_CLE__GPMI_CLE 0x01b0
|
||||
MX28_PAD_GPMI_RESETN__GPMI_RESETN 0x01c0
|
||||
MX28_PAD_LCD_D00__LCD_D0 0x1000
|
||||
MX28_PAD_LCD_D01__LCD_D1 0x1010
|
||||
MX28_PAD_LCD_D02__LCD_D2 0x1020
|
||||
MX28_PAD_LCD_D03__LCD_D3 0x1030
|
||||
MX28_PAD_LCD_D04__LCD_D4 0x1040
|
||||
MX28_PAD_LCD_D05__LCD_D5 0x1050
|
||||
MX28_PAD_LCD_D06__LCD_D6 0x1060
|
||||
MX28_PAD_LCD_D07__LCD_D7 0x1070
|
||||
MX28_PAD_LCD_D08__LCD_D8 0x1080
|
||||
MX28_PAD_LCD_D09__LCD_D9 0x1090
|
||||
MX28_PAD_LCD_D10__LCD_D10 0x10a0
|
||||
MX28_PAD_LCD_D11__LCD_D11 0x10b0
|
||||
MX28_PAD_LCD_D12__LCD_D12 0x10c0
|
||||
MX28_PAD_LCD_D13__LCD_D13 0x10d0
|
||||
MX28_PAD_LCD_D14__LCD_D14 0x10e0
|
||||
MX28_PAD_LCD_D15__LCD_D15 0x10f0
|
||||
MX28_PAD_LCD_D16__LCD_D16 0x1100
|
||||
MX28_PAD_LCD_D17__LCD_D17 0x1110
|
||||
MX28_PAD_LCD_D18__LCD_D18 0x1120
|
||||
MX28_PAD_LCD_D19__LCD_D19 0x1130
|
||||
MX28_PAD_LCD_D20__LCD_D20 0x1140
|
||||
MX28_PAD_LCD_D21__LCD_D21 0x1150
|
||||
MX28_PAD_LCD_D22__LCD_D22 0x1160
|
||||
MX28_PAD_LCD_D23__LCD_D23 0x1170
|
||||
MX28_PAD_LCD_RD_E__LCD_RD_E 0x1180
|
||||
MX28_PAD_LCD_WR_RWN__LCD_WR_RWN 0x1190
|
||||
MX28_PAD_LCD_RS__LCD_RS 0x11a0
|
||||
MX28_PAD_LCD_CS__LCD_CS 0x11b0
|
||||
MX28_PAD_LCD_VSYNC__LCD_VSYNC 0x11c0
|
||||
MX28_PAD_LCD_HSYNC__LCD_HSYNC 0x11d0
|
||||
MX28_PAD_LCD_DOTCLK__LCD_DOTCLK 0x11e0
|
||||
MX28_PAD_LCD_ENABLE__LCD_ENABLE 0x11f0
|
||||
MX28_PAD_SSP0_DATA0__SSP0_D0 0x2000
|
||||
MX28_PAD_SSP0_DATA1__SSP0_D1 0x2010
|
||||
MX28_PAD_SSP0_DATA2__SSP0_D2 0x2020
|
||||
MX28_PAD_SSP0_DATA3__SSP0_D3 0x2030
|
||||
MX28_PAD_SSP0_DATA4__SSP0_D4 0x2040
|
||||
MX28_PAD_SSP0_DATA5__SSP0_D5 0x2050
|
||||
MX28_PAD_SSP0_DATA6__SSP0_D6 0x2060
|
||||
MX28_PAD_SSP0_DATA7__SSP0_D7 0x2070
|
||||
MX28_PAD_SSP0_CMD__SSP0_CMD 0x2080
|
||||
MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT 0x2090
|
||||
MX28_PAD_SSP0_SCK__SSP0_SCK 0x20a0
|
||||
MX28_PAD_SSP1_SCK__SSP1_SCK 0x20c0
|
||||
MX28_PAD_SSP1_CMD__SSP1_CMD 0x20d0
|
||||
MX28_PAD_SSP1_DATA0__SSP1_D0 0x20e0
|
||||
MX28_PAD_SSP1_DATA3__SSP1_D3 0x20f0
|
||||
MX28_PAD_SSP2_SCK__SSP2_SCK 0x2100
|
||||
MX28_PAD_SSP2_MOSI__SSP2_CMD 0x2110
|
||||
MX28_PAD_SSP2_MISO__SSP2_D0 0x2120
|
||||
MX28_PAD_SSP2_SS0__SSP2_D3 0x2130
|
||||
MX28_PAD_SSP2_SS1__SSP2_D4 0x2140
|
||||
MX28_PAD_SSP2_SS2__SSP2_D5 0x2150
|
||||
MX28_PAD_SSP3_SCK__SSP3_SCK 0x2180
|
||||
MX28_PAD_SSP3_MOSI__SSP3_CMD 0x2190
|
||||
MX28_PAD_SSP3_MISO__SSP3_D0 0x21a0
|
||||
MX28_PAD_SSP3_SS0__SSP3_D3 0x21b0
|
||||
MX28_PAD_AUART0_RX__AUART0_RX 0x3000
|
||||
MX28_PAD_AUART0_TX__AUART0_TX 0x3010
|
||||
MX28_PAD_AUART0_CTS__AUART0_CTS 0x3020
|
||||
MX28_PAD_AUART0_RTS__AUART0_RTS 0x3030
|
||||
MX28_PAD_AUART1_RX__AUART1_RX 0x3040
|
||||
MX28_PAD_AUART1_TX__AUART1_TX 0x3050
|
||||
MX28_PAD_AUART1_CTS__AUART1_CTS 0x3060
|
||||
MX28_PAD_AUART1_RTS__AUART1_RTS 0x3070
|
||||
MX28_PAD_AUART2_RX__AUART2_RX 0x3080
|
||||
MX28_PAD_AUART2_TX__AUART2_TX 0x3090
|
||||
MX28_PAD_AUART2_CTS__AUART2_CTS 0x30a0
|
||||
MX28_PAD_AUART2_RTS__AUART2_RTS 0x30b0
|
||||
MX28_PAD_AUART3_RX__AUART3_RX 0x30c0
|
||||
MX28_PAD_AUART3_TX__AUART3_TX 0x30d0
|
||||
MX28_PAD_AUART3_CTS__AUART3_CTS 0x30e0
|
||||
MX28_PAD_AUART3_RTS__AUART3_RTS 0x30f0
|
||||
MX28_PAD_PWM0__PWM_0 0x3100
|
||||
MX28_PAD_PWM1__PWM_1 0x3110
|
||||
MX28_PAD_PWM2__PWM_2 0x3120
|
||||
MX28_PAD_SAIF0_MCLK__SAIF0_MCLK 0x3140
|
||||
MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK 0x3150
|
||||
MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK 0x3160
|
||||
MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 0x3170
|
||||
MX28_PAD_I2C0_SCL__I2C0_SCL 0x3180
|
||||
MX28_PAD_I2C0_SDA__I2C0_SDA 0x3190
|
||||
MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 0x31a0
|
||||
MX28_PAD_SPDIF__SPDIF_TX 0x31b0
|
||||
MX28_PAD_PWM3__PWM_3 0x31c0
|
||||
MX28_PAD_PWM4__PWM_4 0x31d0
|
||||
MX28_PAD_LCD_RESET__LCD_RESET 0x31e0
|
||||
MX28_PAD_ENET0_MDC__ENET0_MDC 0x4000
|
||||
MX28_PAD_ENET0_MDIO__ENET0_MDIO 0x4010
|
||||
MX28_PAD_ENET0_RX_EN__ENET0_RX_EN 0x4020
|
||||
MX28_PAD_ENET0_RXD0__ENET0_RXD0 0x4030
|
||||
MX28_PAD_ENET0_RXD1__ENET0_RXD1 0x4040
|
||||
MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK 0x4050
|
||||
MX28_PAD_ENET0_TX_EN__ENET0_TX_EN 0x4060
|
||||
MX28_PAD_ENET0_TXD0__ENET0_TXD0 0x4070
|
||||
MX28_PAD_ENET0_TXD1__ENET0_TXD1 0x4080
|
||||
MX28_PAD_ENET0_RXD2__ENET0_RXD2 0x4090
|
||||
MX28_PAD_ENET0_RXD3__ENET0_RXD3 0x40a0
|
||||
MX28_PAD_ENET0_TXD2__ENET0_TXD2 0x40b0
|
||||
MX28_PAD_ENET0_TXD3__ENET0_TXD3 0x40c0
|
||||
MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK 0x40d0
|
||||
MX28_PAD_ENET0_COL__ENET0_COL 0x40e0
|
||||
MX28_PAD_ENET0_CRS__ENET0_CRS 0x40f0
|
||||
MX28_PAD_ENET_CLK__CLKCTRL_ENET 0x4100
|
||||
MX28_PAD_JTAG_RTCK__JTAG_RTCK 0x4140
|
||||
MX28_PAD_EMI_D00__EMI_DATA0 0x5000
|
||||
MX28_PAD_EMI_D01__EMI_DATA1 0x5010
|
||||
MX28_PAD_EMI_D02__EMI_DATA2 0x5020
|
||||
MX28_PAD_EMI_D03__EMI_DATA3 0x5030
|
||||
MX28_PAD_EMI_D04__EMI_DATA4 0x5040
|
||||
MX28_PAD_EMI_D05__EMI_DATA5 0x5050
|
||||
MX28_PAD_EMI_D06__EMI_DATA6 0x5060
|
||||
MX28_PAD_EMI_D07__EMI_DATA7 0x5070
|
||||
MX28_PAD_EMI_D08__EMI_DATA8 0x5080
|
||||
MX28_PAD_EMI_D09__EMI_DATA9 0x5090
|
||||
MX28_PAD_EMI_D10__EMI_DATA10 0x50a0
|
||||
MX28_PAD_EMI_D11__EMI_DATA11 0x50b0
|
||||
MX28_PAD_EMI_D12__EMI_DATA12 0x50c0
|
||||
MX28_PAD_EMI_D13__EMI_DATA13 0x50d0
|
||||
MX28_PAD_EMI_D14__EMI_DATA14 0x50e0
|
||||
MX28_PAD_EMI_D15__EMI_DATA15 0x50f0
|
||||
MX28_PAD_EMI_ODT0__EMI_ODT0 0x5100
|
||||
MX28_PAD_EMI_DQM0__EMI_DQM0 0x5110
|
||||
MX28_PAD_EMI_ODT1__EMI_ODT1 0x5120
|
||||
MX28_PAD_EMI_DQM1__EMI_DQM1 0x5130
|
||||
MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK 0x5140
|
||||
MX28_PAD_EMI_CLK__EMI_CLK 0x5150
|
||||
MX28_PAD_EMI_DQS0__EMI_DQS0 0x5160
|
||||
MX28_PAD_EMI_DQS1__EMI_DQS1 0x5170
|
||||
MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN 0x51a0
|
||||
MX28_PAD_EMI_A00__EMI_ADDR0 0x6000
|
||||
MX28_PAD_EMI_A01__EMI_ADDR1 0x6010
|
||||
MX28_PAD_EMI_A02__EMI_ADDR2 0x6020
|
||||
MX28_PAD_EMI_A03__EMI_ADDR3 0x6030
|
||||
MX28_PAD_EMI_A04__EMI_ADDR4 0x6040
|
||||
MX28_PAD_EMI_A05__EMI_ADDR5 0x6050
|
||||
MX28_PAD_EMI_A06__EMI_ADDR6 0x6060
|
||||
MX28_PAD_EMI_A07__EMI_ADDR7 0x6070
|
||||
MX28_PAD_EMI_A08__EMI_ADDR8 0x6080
|
||||
MX28_PAD_EMI_A09__EMI_ADDR9 0x6090
|
||||
MX28_PAD_EMI_A10__EMI_ADDR10 0x60a0
|
||||
MX28_PAD_EMI_A11__EMI_ADDR11 0x60b0
|
||||
MX28_PAD_EMI_A12__EMI_ADDR12 0x60c0
|
||||
MX28_PAD_EMI_A13__EMI_ADDR13 0x60d0
|
||||
MX28_PAD_EMI_A14__EMI_ADDR14 0x60e0
|
||||
MX28_PAD_EMI_BA0__EMI_BA0 0x6100
|
||||
MX28_PAD_EMI_BA1__EMI_BA1 0x6110
|
||||
MX28_PAD_EMI_BA2__EMI_BA2 0x6120
|
||||
MX28_PAD_EMI_CASN__EMI_CASN 0x6130
|
||||
MX28_PAD_EMI_RASN__EMI_RASN 0x6140
|
||||
MX28_PAD_EMI_WEN__EMI_WEN 0x6150
|
||||
MX28_PAD_EMI_CE0N__EMI_CE0N 0x6160
|
||||
MX28_PAD_EMI_CE1N__EMI_CE1N 0x6170
|
||||
MX28_PAD_EMI_CKE__EMI_CKE 0x6180
|
||||
MX28_PAD_GPMI_D00__SSP1_D0 0x0001
|
||||
MX28_PAD_GPMI_D01__SSP1_D1 0x0011
|
||||
MX28_PAD_GPMI_D02__SSP1_D2 0x0021
|
||||
MX28_PAD_GPMI_D03__SSP1_D3 0x0031
|
||||
MX28_PAD_GPMI_D04__SSP1_D4 0x0041
|
||||
MX28_PAD_GPMI_D05__SSP1_D5 0x0051
|
||||
MX28_PAD_GPMI_D06__SSP1_D6 0x0061
|
||||
MX28_PAD_GPMI_D07__SSP1_D7 0x0071
|
||||
MX28_PAD_GPMI_CE0N__SSP3_D0 0x0101
|
||||
MX28_PAD_GPMI_CE1N__SSP3_D3 0x0111
|
||||
MX28_PAD_GPMI_CE2N__CAN1_TX 0x0121
|
||||
MX28_PAD_GPMI_CE3N__CAN1_RX 0x0131
|
||||
MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT 0x0141
|
||||
MX28_PAD_GPMI_RDY1__SSP1_CMD 0x0151
|
||||
MX28_PAD_GPMI_RDY2__CAN0_TX 0x0161
|
||||
MX28_PAD_GPMI_RDY3__CAN0_RX 0x0171
|
||||
MX28_PAD_GPMI_RDN__SSP3_SCK 0x0181
|
||||
MX28_PAD_GPMI_WRN__SSP1_SCK 0x0191
|
||||
MX28_PAD_GPMI_ALE__SSP3_D1 0x01a1
|
||||
MX28_PAD_GPMI_CLE__SSP3_D2 0x01b1
|
||||
MX28_PAD_GPMI_RESETN__SSP3_CMD 0x01c1
|
||||
MX28_PAD_LCD_D03__ETM_DA8 0x1031
|
||||
MX28_PAD_LCD_D04__ETM_DA9 0x1041
|
||||
MX28_PAD_LCD_D08__ETM_DA3 0x1081
|
||||
MX28_PAD_LCD_D09__ETM_DA4 0x1091
|
||||
MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT 0x1141
|
||||
MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN 0x1151
|
||||
MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT 0x1161
|
||||
MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN 0x1171
|
||||
MX28_PAD_LCD_RD_E__LCD_VSYNC 0x1181
|
||||
MX28_PAD_LCD_WR_RWN__LCD_HSYNC 0x1191
|
||||
MX28_PAD_LCD_RS__LCD_DOTCLK 0x11a1
|
||||
MX28_PAD_LCD_CS__LCD_ENABLE 0x11b1
|
||||
MX28_PAD_LCD_VSYNC__SAIF1_SDATA0 0x11c1
|
||||
MX28_PAD_LCD_HSYNC__SAIF1_SDATA1 0x11d1
|
||||
MX28_PAD_LCD_DOTCLK__SAIF1_MCLK 0x11e1
|
||||
MX28_PAD_SSP0_DATA4__SSP2_D0 0x2041
|
||||
MX28_PAD_SSP0_DATA5__SSP2_D3 0x2051
|
||||
MX28_PAD_SSP0_DATA6__SSP2_CMD 0x2061
|
||||
MX28_PAD_SSP0_DATA7__SSP2_SCK 0x2071
|
||||
MX28_PAD_SSP1_SCK__SSP2_D1 0x20c1
|
||||
MX28_PAD_SSP1_CMD__SSP2_D2 0x20d1
|
||||
MX28_PAD_SSP1_DATA0__SSP2_D6 0x20e1
|
||||
MX28_PAD_SSP1_DATA3__SSP2_D7 0x20f1
|
||||
MX28_PAD_SSP2_SCK__AUART2_RX 0x2101
|
||||
MX28_PAD_SSP2_MOSI__AUART2_TX 0x2111
|
||||
MX28_PAD_SSP2_MISO__AUART3_RX 0x2121
|
||||
MX28_PAD_SSP2_SS0__AUART3_TX 0x2131
|
||||
MX28_PAD_SSP2_SS1__SSP2_D1 0x2141
|
||||
MX28_PAD_SSP2_SS2__SSP2_D2 0x2151
|
||||
MX28_PAD_SSP3_SCK__AUART4_TX 0x2181
|
||||
MX28_PAD_SSP3_MOSI__AUART4_RX 0x2191
|
||||
MX28_PAD_SSP3_MISO__AUART4_RTS 0x21a1
|
||||
MX28_PAD_SSP3_SS0__AUART4_CTS 0x21b1
|
||||
MX28_PAD_AUART0_RX__I2C0_SCL 0x3001
|
||||
MX28_PAD_AUART0_TX__I2C0_SDA 0x3011
|
||||
MX28_PAD_AUART0_CTS__AUART4_RX 0x3021
|
||||
MX28_PAD_AUART0_RTS__AUART4_TX 0x3031
|
||||
MX28_PAD_AUART1_RX__SSP2_CARD_DETECT 0x3041
|
||||
MX28_PAD_AUART1_TX__SSP3_CARD_DETECT 0x3051
|
||||
MX28_PAD_AUART1_CTS__USB0_OVERCURRENT 0x3061
|
||||
MX28_PAD_AUART1_RTS__USB0_ID 0x3071
|
||||
MX28_PAD_AUART2_RX__SSP3_D1 0x3081
|
||||
MX28_PAD_AUART2_TX__SSP3_D2 0x3091
|
||||
MX28_PAD_AUART2_CTS__I2C1_SCL 0x30a1
|
||||
MX28_PAD_AUART2_RTS__I2C1_SDA 0x30b1
|
||||
MX28_PAD_AUART3_RX__CAN0_TX 0x30c1
|
||||
MX28_PAD_AUART3_TX__CAN0_RX 0x30d1
|
||||
MX28_PAD_AUART3_CTS__CAN1_TX 0x30e1
|
||||
MX28_PAD_AUART3_RTS__CAN1_RX 0x30f1
|
||||
MX28_PAD_PWM0__I2C1_SCL 0x3101
|
||||
MX28_PAD_PWM1__I2C1_SDA 0x3111
|
||||
MX28_PAD_PWM2__USB0_ID 0x3121
|
||||
MX28_PAD_SAIF0_MCLK__PWM_3 0x3141
|
||||
MX28_PAD_SAIF0_LRCLK__PWM_4 0x3151
|
||||
MX28_PAD_SAIF0_BITCLK__PWM_5 0x3161
|
||||
MX28_PAD_SAIF0_SDATA0__PWM_6 0x3171
|
||||
MX28_PAD_I2C0_SCL__TIMROT_ROTARYA 0x3181
|
||||
MX28_PAD_I2C0_SDA__TIMROT_ROTARYB 0x3191
|
||||
MX28_PAD_SAIF1_SDATA0__PWM_7 0x31a1
|
||||
MX28_PAD_LCD_RESET__LCD_VSYNC 0x31e1
|
||||
MX28_PAD_ENET0_MDC__GPMI_CE4N 0x4001
|
||||
MX28_PAD_ENET0_MDIO__GPMI_CE5N 0x4011
|
||||
MX28_PAD_ENET0_RX_EN__GPMI_CE6N 0x4021
|
||||
MX28_PAD_ENET0_RXD0__GPMI_CE7N 0x4031
|
||||
MX28_PAD_ENET0_RXD1__GPMI_READY4 0x4041
|
||||
MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER 0x4051
|
||||
MX28_PAD_ENET0_TX_EN__GPMI_READY5 0x4061
|
||||
MX28_PAD_ENET0_TXD0__GPMI_READY6 0x4071
|
||||
MX28_PAD_ENET0_TXD1__GPMI_READY7 0x4081
|
||||
MX28_PAD_ENET0_RXD2__ENET1_RXD0 0x4091
|
||||
MX28_PAD_ENET0_RXD3__ENET1_RXD1 0x40a1
|
||||
MX28_PAD_ENET0_TXD2__ENET1_TXD0 0x40b1
|
||||
MX28_PAD_ENET0_TXD3__ENET1_TXD1 0x40c1
|
||||
MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER 0x40d1
|
||||
MX28_PAD_ENET0_COL__ENET1_TX_EN 0x40e1
|
||||
MX28_PAD_ENET0_CRS__ENET1_RX_EN 0x40f1
|
||||
MX28_PAD_GPMI_CE2N__ENET0_RX_ER 0x0122
|
||||
MX28_PAD_GPMI_CE3N__SAIF1_MCLK 0x0132
|
||||
MX28_PAD_GPMI_RDY0__USB0_ID 0x0142
|
||||
MX28_PAD_GPMI_RDY2__ENET0_TX_ER 0x0162
|
||||
MX28_PAD_GPMI_RDY3__HSADC_TRIGGER 0x0172
|
||||
MX28_PAD_GPMI_ALE__SSP3_D4 0x01a2
|
||||
MX28_PAD_GPMI_CLE__SSP3_D5 0x01b2
|
||||
MX28_PAD_LCD_D00__ETM_DA0 0x1002
|
||||
MX28_PAD_LCD_D01__ETM_DA1 0x1012
|
||||
MX28_PAD_LCD_D02__ETM_DA2 0x1022
|
||||
MX28_PAD_LCD_D03__ETM_DA3 0x1032
|
||||
MX28_PAD_LCD_D04__ETM_DA4 0x1042
|
||||
MX28_PAD_LCD_D05__ETM_DA5 0x1052
|
||||
MX28_PAD_LCD_D06__ETM_DA6 0x1062
|
||||
MX28_PAD_LCD_D07__ETM_DA7 0x1072
|
||||
MX28_PAD_LCD_D08__ETM_DA8 0x1082
|
||||
MX28_PAD_LCD_D09__ETM_DA9 0x1092
|
||||
MX28_PAD_LCD_D10__ETM_DA10 0x10a2
|
||||
MX28_PAD_LCD_D11__ETM_DA11 0x10b2
|
||||
MX28_PAD_LCD_D12__ETM_DA12 0x10c2
|
||||
MX28_PAD_LCD_D13__ETM_DA13 0x10d2
|
||||
MX28_PAD_LCD_D14__ETM_DA14 0x10e2
|
||||
MX28_PAD_LCD_D15__ETM_DA15 0x10f2
|
||||
MX28_PAD_LCD_D16__ETM_DA7 0x1102
|
||||
MX28_PAD_LCD_D17__ETM_DA6 0x1112
|
||||
MX28_PAD_LCD_D18__ETM_DA5 0x1122
|
||||
MX28_PAD_LCD_D19__ETM_DA4 0x1132
|
||||
MX28_PAD_LCD_D20__ETM_DA3 0x1142
|
||||
MX28_PAD_LCD_D21__ETM_DA2 0x1152
|
||||
MX28_PAD_LCD_D22__ETM_DA1 0x1162
|
||||
MX28_PAD_LCD_D23__ETM_DA0 0x1172
|
||||
MX28_PAD_LCD_RD_E__ETM_TCTL 0x1182
|
||||
MX28_PAD_LCD_WR_RWN__ETM_TCLK 0x1192
|
||||
MX28_PAD_LCD_HSYNC__ETM_TCTL 0x11d2
|
||||
MX28_PAD_LCD_DOTCLK__ETM_TCLK 0x11e2
|
||||
MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT 0x20c2
|
||||
MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN 0x20d2
|
||||
MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT 0x20e2
|
||||
MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN 0x20f2
|
||||
MX28_PAD_SSP2_SCK__SAIF0_SDATA1 0x2102
|
||||
MX28_PAD_SSP2_MOSI__SAIF0_SDATA2 0x2112
|
||||
MX28_PAD_SSP2_MISO__SAIF1_SDATA1 0x2122
|
||||
MX28_PAD_SSP2_SS0__SAIF1_SDATA2 0x2132
|
||||
MX28_PAD_SSP2_SS1__USB1_OVERCURRENT 0x2142
|
||||
MX28_PAD_SSP2_SS2__USB0_OVERCURRENT 0x2152
|
||||
MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT 0x2182
|
||||
MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN 0x2192
|
||||
MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT 0x21a2
|
||||
MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN 0x21b2
|
||||
MX28_PAD_AUART0_RX__DUART_CTS 0x3002
|
||||
MX28_PAD_AUART0_TX__DUART_RTS 0x3012
|
||||
MX28_PAD_AUART0_CTS__DUART_RX 0x3022
|
||||
MX28_PAD_AUART0_RTS__DUART_TX 0x3032
|
||||
MX28_PAD_AUART1_RX__PWM_0 0x3042
|
||||
MX28_PAD_AUART1_TX__PWM_1 0x3052
|
||||
MX28_PAD_AUART1_CTS__TIMROT_ROTARYA 0x3062
|
||||
MX28_PAD_AUART1_RTS__TIMROT_ROTARYB 0x3072
|
||||
MX28_PAD_AUART2_RX__SSP3_D4 0x3082
|
||||
MX28_PAD_AUART2_TX__SSP3_D5 0x3092
|
||||
MX28_PAD_AUART2_CTS__SAIF1_BITCLK 0x30a2
|
||||
MX28_PAD_AUART2_RTS__SAIF1_LRCLK 0x30b2
|
||||
MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT 0x30c2
|
||||
MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN 0x30d2
|
||||
MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT 0x30e2
|
||||
MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN 0x30f2
|
||||
MX28_PAD_PWM0__DUART_RX 0x3102
|
||||
MX28_PAD_PWM1__DUART_TX 0x3112
|
||||
MX28_PAD_PWM2__USB1_OVERCURRENT 0x3122
|
||||
MX28_PAD_SAIF0_MCLK__AUART4_CTS 0x3142
|
||||
MX28_PAD_SAIF0_LRCLK__AUART4_RTS 0x3152
|
||||
MX28_PAD_SAIF0_BITCLK__AUART4_RX 0x3162
|
||||
MX28_PAD_SAIF0_SDATA0__AUART4_TX 0x3172
|
||||
MX28_PAD_I2C0_SCL__DUART_RX 0x3182
|
||||
MX28_PAD_I2C0_SDA__DUART_TX 0x3192
|
||||
MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1 0x31a2
|
||||
MX28_PAD_SPDIF__ENET1_RX_ER 0x31b2
|
||||
MX28_PAD_ENET0_MDC__SAIF0_SDATA1 0x4002
|
||||
MX28_PAD_ENET0_MDIO__SAIF0_SDATA2 0x4012
|
||||
MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1 0x4022
|
||||
MX28_PAD_ENET0_RXD0__SAIF1_SDATA2 0x4032
|
||||
MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT 0x4052
|
||||
MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT 0x4092
|
||||
MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN 0x40a2
|
||||
MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT 0x40b2
|
||||
MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN 0x40c2
|
||||
MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN 0x40d2
|
||||
MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT 0x40e2
|
||||
MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN 0x40f2
|
||||
MX28_PAD_GPMI_D00__GPIO_0_0 0x0003
|
||||
MX28_PAD_GPMI_D01__GPIO_0_1 0x0013
|
||||
MX28_PAD_GPMI_D02__GPIO_0_2 0x0023
|
||||
MX28_PAD_GPMI_D03__GPIO_0_3 0x0033
|
||||
MX28_PAD_GPMI_D04__GPIO_0_4 0x0043
|
||||
MX28_PAD_GPMI_D05__GPIO_0_5 0x0053
|
||||
MX28_PAD_GPMI_D06__GPIO_0_6 0x0063
|
||||
MX28_PAD_GPMI_D07__GPIO_0_7 0x0073
|
||||
MX28_PAD_GPMI_CE0N__GPIO_0_16 0x0103
|
||||
MX28_PAD_GPMI_CE1N__GPIO_0_17 0x0113
|
||||
MX28_PAD_GPMI_CE2N__GPIO_0_18 0x0123
|
||||
MX28_PAD_GPMI_CE3N__GPIO_0_19 0x0133
|
||||
MX28_PAD_GPMI_RDY0__GPIO_0_20 0x0143
|
||||
MX28_PAD_GPMI_RDY1__GPIO_0_21 0x0153
|
||||
MX28_PAD_GPMI_RDY2__GPIO_0_22 0x0163
|
||||
MX28_PAD_GPMI_RDY3__GPIO_0_23 0x0173
|
||||
MX28_PAD_GPMI_RDN__GPIO_0_24 0x0183
|
||||
MX28_PAD_GPMI_WRN__GPIO_0_25 0x0193
|
||||
MX28_PAD_GPMI_ALE__GPIO_0_26 0x01a3
|
||||
MX28_PAD_GPMI_CLE__GPIO_0_27 0x01b3
|
||||
MX28_PAD_GPMI_RESETN__GPIO_0_28 0x01c3
|
||||
MX28_PAD_LCD_D00__GPIO_1_0 0x1003
|
||||
MX28_PAD_LCD_D01__GPIO_1_1 0x1013
|
||||
MX28_PAD_LCD_D02__GPIO_1_2 0x1023
|
||||
MX28_PAD_LCD_D03__GPIO_1_3 0x1033
|
||||
MX28_PAD_LCD_D04__GPIO_1_4 0x1043
|
||||
MX28_PAD_LCD_D05__GPIO_1_5 0x1053
|
||||
MX28_PAD_LCD_D06__GPIO_1_6 0x1063
|
||||
MX28_PAD_LCD_D07__GPIO_1_7 0x1073
|
||||
MX28_PAD_LCD_D08__GPIO_1_8 0x1083
|
||||
MX28_PAD_LCD_D09__GPIO_1_9 0x1093
|
||||
MX28_PAD_LCD_D10__GPIO_1_10 0x10a3
|
||||
MX28_PAD_LCD_D11__GPIO_1_11 0x10b3
|
||||
MX28_PAD_LCD_D12__GPIO_1_12 0x10c3
|
||||
MX28_PAD_LCD_D13__GPIO_1_13 0x10d3
|
||||
MX28_PAD_LCD_D14__GPIO_1_14 0x10e3
|
||||
MX28_PAD_LCD_D15__GPIO_1_15 0x10f3
|
||||
MX28_PAD_LCD_D16__GPIO_1_16 0x1103
|
||||
MX28_PAD_LCD_D17__GPIO_1_17 0x1113
|
||||
MX28_PAD_LCD_D18__GPIO_1_18 0x1123
|
||||
MX28_PAD_LCD_D19__GPIO_1_19 0x1133
|
||||
MX28_PAD_LCD_D20__GPIO_1_20 0x1143
|
||||
MX28_PAD_LCD_D21__GPIO_1_21 0x1153
|
||||
MX28_PAD_LCD_D22__GPIO_1_22 0x1163
|
||||
MX28_PAD_LCD_D23__GPIO_1_23 0x1173
|
||||
MX28_PAD_LCD_RD_E__GPIO_1_24 0x1183
|
||||
MX28_PAD_LCD_WR_RWN__GPIO_1_25 0x1193
|
||||
MX28_PAD_LCD_RS__GPIO_1_26 0x11a3
|
||||
MX28_PAD_LCD_CS__GPIO_1_27 0x11b3
|
||||
MX28_PAD_LCD_VSYNC__GPIO_1_28 0x11c3
|
||||
MX28_PAD_LCD_HSYNC__GPIO_1_29 0x11d3
|
||||
MX28_PAD_LCD_DOTCLK__GPIO_1_30 0x11e3
|
||||
MX28_PAD_LCD_ENABLE__GPIO_1_31 0x11f3
|
||||
MX28_PAD_SSP0_DATA0__GPIO_2_0 0x2003
|
||||
MX28_PAD_SSP0_DATA1__GPIO_2_1 0x2013
|
||||
MX28_PAD_SSP0_DATA2__GPIO_2_2 0x2023
|
||||
MX28_PAD_SSP0_DATA3__GPIO_2_3 0x2033
|
||||
MX28_PAD_SSP0_DATA4__GPIO_2_4 0x2043
|
||||
MX28_PAD_SSP0_DATA5__GPIO_2_5 0x2053
|
||||
MX28_PAD_SSP0_DATA6__GPIO_2_6 0x2063
|
||||
MX28_PAD_SSP0_DATA7__GPIO_2_7 0x2073
|
||||
MX28_PAD_SSP0_CMD__GPIO_2_8 0x2083
|
||||
MX28_PAD_SSP0_DETECT__GPIO_2_9 0x2093
|
||||
MX28_PAD_SSP0_SCK__GPIO_2_10 0x20a3
|
||||
MX28_PAD_SSP1_SCK__GPIO_2_12 0x20c3
|
||||
MX28_PAD_SSP1_CMD__GPIO_2_13 0x20d3
|
||||
MX28_PAD_SSP1_DATA0__GPIO_2_14 0x20e3
|
||||
MX28_PAD_SSP1_DATA3__GPIO_2_15 0x20f3
|
||||
MX28_PAD_SSP2_SCK__GPIO_2_16 0x2103
|
||||
MX28_PAD_SSP2_MOSI__GPIO_2_17 0x2113
|
||||
MX28_PAD_SSP2_MISO__GPIO_2_18 0x2123
|
||||
MX28_PAD_SSP2_SS0__GPIO_2_19 0x2133
|
||||
MX28_PAD_SSP2_SS1__GPIO_2_20 0x2143
|
||||
MX28_PAD_SSP2_SS2__GPIO_2_21 0x2153
|
||||
MX28_PAD_SSP3_SCK__GPIO_2_24 0x2183
|
||||
MX28_PAD_SSP3_MOSI__GPIO_2_25 0x2193
|
||||
MX28_PAD_SSP3_MISO__GPIO_2_26 0x21a3
|
||||
MX28_PAD_SSP3_SS0__GPIO_2_27 0x21b3
|
||||
MX28_PAD_AUART0_RX__GPIO_3_0 0x3003
|
||||
MX28_PAD_AUART0_TX__GPIO_3_1 0x3013
|
||||
MX28_PAD_AUART0_CTS__GPIO_3_2 0x3023
|
||||
MX28_PAD_AUART0_RTS__GPIO_3_3 0x3033
|
||||
MX28_PAD_AUART1_RX__GPIO_3_4 0x3043
|
||||
MX28_PAD_AUART1_TX__GPIO_3_5 0x3053
|
||||
MX28_PAD_AUART1_CTS__GPIO_3_6 0x3063
|
||||
MX28_PAD_AUART1_RTS__GPIO_3_7 0x3073
|
||||
MX28_PAD_AUART2_RX__GPIO_3_8 0x3083
|
||||
MX28_PAD_AUART2_TX__GPIO_3_9 0x3093
|
||||
MX28_PAD_AUART2_CTS__GPIO_3_10 0x30a3
|
||||
MX28_PAD_AUART2_RTS__GPIO_3_11 0x30b3
|
||||
MX28_PAD_AUART3_RX__GPIO_3_12 0x30c3
|
||||
MX28_PAD_AUART3_TX__GPIO_3_13 0x30d3
|
||||
MX28_PAD_AUART3_CTS__GPIO_3_14 0x30e3
|
||||
MX28_PAD_AUART3_RTS__GPIO_3_15 0x30f3
|
||||
MX28_PAD_PWM0__GPIO_3_16 0x3103
|
||||
MX28_PAD_PWM1__GPIO_3_17 0x3113
|
||||
MX28_PAD_PWM2__GPIO_3_18 0x3123
|
||||
MX28_PAD_SAIF0_MCLK__GPIO_3_20 0x3143
|
||||
MX28_PAD_SAIF0_LRCLK__GPIO_3_21 0x3153
|
||||
MX28_PAD_SAIF0_BITCLK__GPIO_3_22 0x3163
|
||||
MX28_PAD_SAIF0_SDATA0__GPIO_3_23 0x3173
|
||||
MX28_PAD_I2C0_SCL__GPIO_3_24 0x3183
|
||||
MX28_PAD_I2C0_SDA__GPIO_3_25 0x3193
|
||||
MX28_PAD_SAIF1_SDATA0__GPIO_3_26 0x31a3
|
||||
MX28_PAD_SPDIF__GPIO_3_27 0x31b3
|
||||
MX28_PAD_PWM3__GPIO_3_28 0x31c3
|
||||
MX28_PAD_PWM4__GPIO_3_29 0x31d3
|
||||
MX28_PAD_LCD_RESET__GPIO_3_30 0x31e3
|
||||
MX28_PAD_ENET0_MDC__GPIO_4_0 0x4003
|
||||
MX28_PAD_ENET0_MDIO__GPIO_4_1 0x4013
|
||||
MX28_PAD_ENET0_RX_EN__GPIO_4_2 0x4023
|
||||
MX28_PAD_ENET0_RXD0__GPIO_4_3 0x4033
|
||||
MX28_PAD_ENET0_RXD1__GPIO_4_4 0x4043
|
||||
MX28_PAD_ENET0_TX_CLK__GPIO_4_5 0x4053
|
||||
MX28_PAD_ENET0_TX_EN__GPIO_4_6 0x4063
|
||||
MX28_PAD_ENET0_TXD0__GPIO_4_7 0x4073
|
||||
MX28_PAD_ENET0_TXD1__GPIO_4_8 0x4083
|
||||
MX28_PAD_ENET0_RXD2__GPIO_4_9 0x4093
|
||||
MX28_PAD_ENET0_RXD3__GPIO_4_10 0x40a3
|
||||
MX28_PAD_ENET0_TXD2__GPIO_4_11 0x40b3
|
||||
MX28_PAD_ENET0_TXD3__GPIO_4_12 0x40c3
|
||||
MX28_PAD_ENET0_RX_CLK__GPIO_4_13 0x40d3
|
||||
MX28_PAD_ENET0_COL__GPIO_4_14 0x40e3
|
||||
MX28_PAD_ENET0_CRS__GPIO_4_15 0x40f3
|
||||
MX28_PAD_ENET_CLK__GPIO_4_16 0x4103
|
||||
MX28_PAD_JTAG_RTCK__GPIO_4_20 0x4143
|
||||
|
||||
Valid values for i.MX23 pinmux-id:
|
||||
|
||||
pinmux id
|
||||
------ --
|
||||
MX23_PAD_GPMI_D00__GPMI_D00 0x0000
|
||||
MX23_PAD_GPMI_D01__GPMI_D01 0x0010
|
||||
MX23_PAD_GPMI_D02__GPMI_D02 0x0020
|
||||
MX23_PAD_GPMI_D03__GPMI_D03 0x0030
|
||||
MX23_PAD_GPMI_D04__GPMI_D04 0x0040
|
||||
MX23_PAD_GPMI_D05__GPMI_D05 0x0050
|
||||
MX23_PAD_GPMI_D06__GPMI_D06 0x0060
|
||||
MX23_PAD_GPMI_D07__GPMI_D07 0x0070
|
||||
MX23_PAD_GPMI_D08__GPMI_D08 0x0080
|
||||
MX23_PAD_GPMI_D09__GPMI_D09 0x0090
|
||||
MX23_PAD_GPMI_D10__GPMI_D10 0x00a0
|
||||
MX23_PAD_GPMI_D11__GPMI_D11 0x00b0
|
||||
MX23_PAD_GPMI_D12__GPMI_D12 0x00c0
|
||||
MX23_PAD_GPMI_D13__GPMI_D13 0x00d0
|
||||
MX23_PAD_GPMI_D14__GPMI_D14 0x00e0
|
||||
MX23_PAD_GPMI_D15__GPMI_D15 0x00f0
|
||||
MX23_PAD_GPMI_CLE__GPMI_CLE 0x0100
|
||||
MX23_PAD_GPMI_ALE__GPMI_ALE 0x0110
|
||||
MX23_PAD_GPMI_CE2N__GPMI_CE2N 0x0120
|
||||
MX23_PAD_GPMI_RDY0__GPMI_RDY0 0x0130
|
||||
MX23_PAD_GPMI_RDY1__GPMI_RDY1 0x0140
|
||||
MX23_PAD_GPMI_RDY2__GPMI_RDY2 0x0150
|
||||
MX23_PAD_GPMI_RDY3__GPMI_RDY3 0x0160
|
||||
MX23_PAD_GPMI_WPN__GPMI_WPN 0x0170
|
||||
MX23_PAD_GPMI_WRN__GPMI_WRN 0x0180
|
||||
MX23_PAD_GPMI_RDN__GPMI_RDN 0x0190
|
||||
MX23_PAD_AUART1_CTS__AUART1_CTS 0x01a0
|
||||
MX23_PAD_AUART1_RTS__AUART1_RTS 0x01b0
|
||||
MX23_PAD_AUART1_RX__AUART1_RX 0x01c0
|
||||
MX23_PAD_AUART1_TX__AUART1_TX 0x01d0
|
||||
MX23_PAD_I2C_SCL__I2C_SCL 0x01e0
|
||||
MX23_PAD_I2C_SDA__I2C_SDA 0x01f0
|
||||
MX23_PAD_LCD_D00__LCD_D00 0x1000
|
||||
MX23_PAD_LCD_D01__LCD_D01 0x1010
|
||||
MX23_PAD_LCD_D02__LCD_D02 0x1020
|
||||
MX23_PAD_LCD_D03__LCD_D03 0x1030
|
||||
MX23_PAD_LCD_D04__LCD_D04 0x1040
|
||||
MX23_PAD_LCD_D05__LCD_D05 0x1050
|
||||
MX23_PAD_LCD_D06__LCD_D06 0x1060
|
||||
MX23_PAD_LCD_D07__LCD_D07 0x1070
|
||||
MX23_PAD_LCD_D08__LCD_D08 0x1080
|
||||
MX23_PAD_LCD_D09__LCD_D09 0x1090
|
||||
MX23_PAD_LCD_D10__LCD_D10 0x10a0
|
||||
MX23_PAD_LCD_D11__LCD_D11 0x10b0
|
||||
MX23_PAD_LCD_D12__LCD_D12 0x10c0
|
||||
MX23_PAD_LCD_D13__LCD_D13 0x10d0
|
||||
MX23_PAD_LCD_D14__LCD_D14 0x10e0
|
||||
MX23_PAD_LCD_D15__LCD_D15 0x10f0
|
||||
MX23_PAD_LCD_D16__LCD_D16 0x1100
|
||||
MX23_PAD_LCD_D17__LCD_D17 0x1110
|
||||
MX23_PAD_LCD_RESET__LCD_RESET 0x1120
|
||||
MX23_PAD_LCD_RS__LCD_RS 0x1130
|
||||
MX23_PAD_LCD_WR__LCD_WR 0x1140
|
||||
MX23_PAD_LCD_CS__LCD_CS 0x1150
|
||||
MX23_PAD_LCD_DOTCK__LCD_DOTCK 0x1160
|
||||
MX23_PAD_LCD_ENABLE__LCD_ENABLE 0x1170
|
||||
MX23_PAD_LCD_HSYNC__LCD_HSYNC 0x1180
|
||||
MX23_PAD_LCD_VSYNC__LCD_VSYNC 0x1190
|
||||
MX23_PAD_PWM0__PWM0 0x11a0
|
||||
MX23_PAD_PWM1__PWM1 0x11b0
|
||||
MX23_PAD_PWM2__PWM2 0x11c0
|
||||
MX23_PAD_PWM3__PWM3 0x11d0
|
||||
MX23_PAD_PWM4__PWM4 0x11e0
|
||||
MX23_PAD_SSP1_CMD__SSP1_CMD 0x2000
|
||||
MX23_PAD_SSP1_DETECT__SSP1_DETECT 0x2010
|
||||
MX23_PAD_SSP1_DATA0__SSP1_DATA0 0x2020
|
||||
MX23_PAD_SSP1_DATA1__SSP1_DATA1 0x2030
|
||||
MX23_PAD_SSP1_DATA2__SSP1_DATA2 0x2040
|
||||
MX23_PAD_SSP1_DATA3__SSP1_DATA3 0x2050
|
||||
MX23_PAD_SSP1_SCK__SSP1_SCK 0x2060
|
||||
MX23_PAD_ROTARYA__ROTARYA 0x2070
|
||||
MX23_PAD_ROTARYB__ROTARYB 0x2080
|
||||
MX23_PAD_EMI_A00__EMI_A00 0x2090
|
||||
MX23_PAD_EMI_A01__EMI_A01 0x20a0
|
||||
MX23_PAD_EMI_A02__EMI_A02 0x20b0
|
||||
MX23_PAD_EMI_A03__EMI_A03 0x20c0
|
||||
MX23_PAD_EMI_A04__EMI_A04 0x20d0
|
||||
MX23_PAD_EMI_A05__EMI_A05 0x20e0
|
||||
MX23_PAD_EMI_A06__EMI_A06 0x20f0
|
||||
MX23_PAD_EMI_A07__EMI_A07 0x2100
|
||||
MX23_PAD_EMI_A08__EMI_A08 0x2110
|
||||
MX23_PAD_EMI_A09__EMI_A09 0x2120
|
||||
MX23_PAD_EMI_A10__EMI_A10 0x2130
|
||||
MX23_PAD_EMI_A11__EMI_A11 0x2140
|
||||
MX23_PAD_EMI_A12__EMI_A12 0x2150
|
||||
MX23_PAD_EMI_BA0__EMI_BA0 0x2160
|
||||
MX23_PAD_EMI_BA1__EMI_BA1 0x2170
|
||||
MX23_PAD_EMI_CASN__EMI_CASN 0x2180
|
||||
MX23_PAD_EMI_CE0N__EMI_CE0N 0x2190
|
||||
MX23_PAD_EMI_CE1N__EMI_CE1N 0x21a0
|
||||
MX23_PAD_GPMI_CE1N__GPMI_CE1N 0x21b0
|
||||
MX23_PAD_GPMI_CE0N__GPMI_CE0N 0x21c0
|
||||
MX23_PAD_EMI_CKE__EMI_CKE 0x21d0
|
||||
MX23_PAD_EMI_RASN__EMI_RASN 0x21e0
|
||||
MX23_PAD_EMI_WEN__EMI_WEN 0x21f0
|
||||
MX23_PAD_EMI_D00__EMI_D00 0x3000
|
||||
MX23_PAD_EMI_D01__EMI_D01 0x3010
|
||||
MX23_PAD_EMI_D02__EMI_D02 0x3020
|
||||
MX23_PAD_EMI_D03__EMI_D03 0x3030
|
||||
MX23_PAD_EMI_D04__EMI_D04 0x3040
|
||||
MX23_PAD_EMI_D05__EMI_D05 0x3050
|
||||
MX23_PAD_EMI_D06__EMI_D06 0x3060
|
||||
MX23_PAD_EMI_D07__EMI_D07 0x3070
|
||||
MX23_PAD_EMI_D08__EMI_D08 0x3080
|
||||
MX23_PAD_EMI_D09__EMI_D09 0x3090
|
||||
MX23_PAD_EMI_D10__EMI_D10 0x30a0
|
||||
MX23_PAD_EMI_D11__EMI_D11 0x30b0
|
||||
MX23_PAD_EMI_D12__EMI_D12 0x30c0
|
||||
MX23_PAD_EMI_D13__EMI_D13 0x30d0
|
||||
MX23_PAD_EMI_D14__EMI_D14 0x30e0
|
||||
MX23_PAD_EMI_D15__EMI_D15 0x30f0
|
||||
MX23_PAD_EMI_DQM0__EMI_DQM0 0x3100
|
||||
MX23_PAD_EMI_DQM1__EMI_DQM1 0x3110
|
||||
MX23_PAD_EMI_DQS0__EMI_DQS0 0x3120
|
||||
MX23_PAD_EMI_DQS1__EMI_DQS1 0x3130
|
||||
MX23_PAD_EMI_CLK__EMI_CLK 0x3140
|
||||
MX23_PAD_EMI_CLKN__EMI_CLKN 0x3150
|
||||
MX23_PAD_GPMI_D00__LCD_D8 0x0001
|
||||
MX23_PAD_GPMI_D01__LCD_D9 0x0011
|
||||
MX23_PAD_GPMI_D02__LCD_D10 0x0021
|
||||
MX23_PAD_GPMI_D03__LCD_D11 0x0031
|
||||
MX23_PAD_GPMI_D04__LCD_D12 0x0041
|
||||
MX23_PAD_GPMI_D05__LCD_D13 0x0051
|
||||
MX23_PAD_GPMI_D06__LCD_D14 0x0061
|
||||
MX23_PAD_GPMI_D07__LCD_D15 0x0071
|
||||
MX23_PAD_GPMI_D08__LCD_D18 0x0081
|
||||
MX23_PAD_GPMI_D09__LCD_D19 0x0091
|
||||
MX23_PAD_GPMI_D10__LCD_D20 0x00a1
|
||||
MX23_PAD_GPMI_D11__LCD_D21 0x00b1
|
||||
MX23_PAD_GPMI_D12__LCD_D22 0x00c1
|
||||
MX23_PAD_GPMI_D13__LCD_D23 0x00d1
|
||||
MX23_PAD_GPMI_D14__AUART2_RX 0x00e1
|
||||
MX23_PAD_GPMI_D15__AUART2_TX 0x00f1
|
||||
MX23_PAD_GPMI_CLE__LCD_D16 0x0101
|
||||
MX23_PAD_GPMI_ALE__LCD_D17 0x0111
|
||||
MX23_PAD_GPMI_CE2N__ATA_A2 0x0121
|
||||
MX23_PAD_AUART1_RTS__IR_CLK 0x01b1
|
||||
MX23_PAD_AUART1_RX__IR_RX 0x01c1
|
||||
MX23_PAD_AUART1_TX__IR_TX 0x01d1
|
||||
MX23_PAD_I2C_SCL__GPMI_RDY2 0x01e1
|
||||
MX23_PAD_I2C_SDA__GPMI_CE2N 0x01f1
|
||||
MX23_PAD_LCD_D00__ETM_DA8 0x1001
|
||||
MX23_PAD_LCD_D01__ETM_DA9 0x1011
|
||||
MX23_PAD_LCD_D02__ETM_DA10 0x1021
|
||||
MX23_PAD_LCD_D03__ETM_DA11 0x1031
|
||||
MX23_PAD_LCD_D04__ETM_DA12 0x1041
|
||||
MX23_PAD_LCD_D05__ETM_DA13 0x1051
|
||||
MX23_PAD_LCD_D06__ETM_DA14 0x1061
|
||||
MX23_PAD_LCD_D07__ETM_DA15 0x1071
|
||||
MX23_PAD_LCD_D08__ETM_DA0 0x1081
|
||||
MX23_PAD_LCD_D09__ETM_DA1 0x1091
|
||||
MX23_PAD_LCD_D10__ETM_DA2 0x10a1
|
||||
MX23_PAD_LCD_D11__ETM_DA3 0x10b1
|
||||
MX23_PAD_LCD_D12__ETM_DA4 0x10c1
|
||||
MX23_PAD_LCD_D13__ETM_DA5 0x10d1
|
||||
MX23_PAD_LCD_D14__ETM_DA6 0x10e1
|
||||
MX23_PAD_LCD_D15__ETM_DA7 0x10f1
|
||||
MX23_PAD_LCD_RESET__ETM_TCTL 0x1121
|
||||
MX23_PAD_LCD_RS__ETM_TCLK 0x1131
|
||||
MX23_PAD_LCD_DOTCK__GPMI_RDY3 0x1161
|
||||
MX23_PAD_LCD_ENABLE__I2C_SCL 0x1171
|
||||
MX23_PAD_LCD_HSYNC__I2C_SDA 0x1181
|
||||
MX23_PAD_LCD_VSYNC__LCD_BUSY 0x1191
|
||||
MX23_PAD_PWM0__ROTARYA 0x11a1
|
||||
MX23_PAD_PWM1__ROTARYB 0x11b1
|
||||
MX23_PAD_PWM2__GPMI_RDY3 0x11c1
|
||||
MX23_PAD_PWM3__ETM_TCTL 0x11d1
|
||||
MX23_PAD_PWM4__ETM_TCLK 0x11e1
|
||||
MX23_PAD_SSP1_DETECT__GPMI_CE3N 0x2011
|
||||
MX23_PAD_SSP1_DATA1__I2C_SCL 0x2031
|
||||
MX23_PAD_SSP1_DATA2__I2C_SDA 0x2041
|
||||
MX23_PAD_ROTARYA__AUART2_RTS 0x2071
|
||||
MX23_PAD_ROTARYB__AUART2_CTS 0x2081
|
||||
MX23_PAD_GPMI_D00__SSP2_DATA0 0x0002
|
||||
MX23_PAD_GPMI_D01__SSP2_DATA1 0x0012
|
||||
MX23_PAD_GPMI_D02__SSP2_DATA2 0x0022
|
||||
MX23_PAD_GPMI_D03__SSP2_DATA3 0x0032
|
||||
MX23_PAD_GPMI_D04__SSP2_DATA4 0x0042
|
||||
MX23_PAD_GPMI_D05__SSP2_DATA5 0x0052
|
||||
MX23_PAD_GPMI_D06__SSP2_DATA6 0x0062
|
||||
MX23_PAD_GPMI_D07__SSP2_DATA7 0x0072
|
||||
MX23_PAD_GPMI_D08__SSP1_DATA4 0x0082
|
||||
MX23_PAD_GPMI_D09__SSP1_DATA5 0x0092
|
||||
MX23_PAD_GPMI_D10__SSP1_DATA6 0x00a2
|
||||
MX23_PAD_GPMI_D11__SSP1_DATA7 0x00b2
|
||||
MX23_PAD_GPMI_D15__GPMI_CE3N 0x00f2
|
||||
MX23_PAD_GPMI_RDY0__SSP2_DETECT 0x0132
|
||||
MX23_PAD_GPMI_RDY1__SSP2_CMD 0x0142
|
||||
MX23_PAD_GPMI_WRN__SSP2_SCK 0x0182
|
||||
MX23_PAD_AUART1_CTS__SSP1_DATA4 0x01a2
|
||||
MX23_PAD_AUART1_RTS__SSP1_DATA5 0x01b2
|
||||
MX23_PAD_AUART1_RX__SSP1_DATA6 0x01c2
|
||||
MX23_PAD_AUART1_TX__SSP1_DATA7 0x01d2
|
||||
MX23_PAD_I2C_SCL__AUART1_TX 0x01e2
|
||||
MX23_PAD_I2C_SDA__AUART1_RX 0x01f2
|
||||
MX23_PAD_LCD_D08__SAIF2_SDATA0 0x1082
|
||||
MX23_PAD_LCD_D09__SAIF1_SDATA0 0x1092
|
||||
MX23_PAD_LCD_D10__SAIF_MCLK_BITCLK 0x10a2
|
||||
MX23_PAD_LCD_D11__SAIF_LRCLK 0x10b2
|
||||
MX23_PAD_LCD_D12__SAIF2_SDATA1 0x10c2
|
||||
MX23_PAD_LCD_D13__SAIF2_SDATA2 0x10d2
|
||||
MX23_PAD_LCD_D14__SAIF1_SDATA2 0x10e2
|
||||
MX23_PAD_LCD_D15__SAIF1_SDATA1 0x10f2
|
||||
MX23_PAD_LCD_D16__SAIF_ALT_BITCLK 0x1102
|
||||
MX23_PAD_LCD_RESET__GPMI_CE3N 0x1122
|
||||
MX23_PAD_PWM0__DUART_RX 0x11a2
|
||||
MX23_PAD_PWM1__DUART_TX 0x11b2
|
||||
MX23_PAD_PWM3__AUART1_CTS 0x11d2
|
||||
MX23_PAD_PWM4__AUART1_RTS 0x11e2
|
||||
MX23_PAD_SSP1_CMD__JTAG_TDO 0x2002
|
||||
MX23_PAD_SSP1_DETECT__USB_OTG_ID 0x2012
|
||||
MX23_PAD_SSP1_DATA0__JTAG_TDI 0x2022
|
||||
MX23_PAD_SSP1_DATA1__JTAG_TCLK 0x2032
|
||||
MX23_PAD_SSP1_DATA2__JTAG_RTCK 0x2042
|
||||
MX23_PAD_SSP1_DATA3__JTAG_TMS 0x2052
|
||||
MX23_PAD_SSP1_SCK__JTAG_TRST 0x2062
|
||||
MX23_PAD_ROTARYA__SPDIF 0x2072
|
||||
MX23_PAD_ROTARYB__GPMI_CE3N 0x2082
|
||||
MX23_PAD_GPMI_D00__GPIO_0_0 0x0003
|
||||
MX23_PAD_GPMI_D01__GPIO_0_1 0x0013
|
||||
MX23_PAD_GPMI_D02__GPIO_0_2 0x0023
|
||||
MX23_PAD_GPMI_D03__GPIO_0_3 0x0033
|
||||
MX23_PAD_GPMI_D04__GPIO_0_4 0x0043
|
||||
MX23_PAD_GPMI_D05__GPIO_0_5 0x0053
|
||||
MX23_PAD_GPMI_D06__GPIO_0_6 0x0063
|
||||
MX23_PAD_GPMI_D07__GPIO_0_7 0x0073
|
||||
MX23_PAD_GPMI_D08__GPIO_0_8 0x0083
|
||||
MX23_PAD_GPMI_D09__GPIO_0_9 0x0093
|
||||
MX23_PAD_GPMI_D10__GPIO_0_10 0x00a3
|
||||
MX23_PAD_GPMI_D11__GPIO_0_11 0x00b3
|
||||
MX23_PAD_GPMI_D12__GPIO_0_12 0x00c3
|
||||
MX23_PAD_GPMI_D13__GPIO_0_13 0x00d3
|
||||
MX23_PAD_GPMI_D14__GPIO_0_14 0x00e3
|
||||
MX23_PAD_GPMI_D15__GPIO_0_15 0x00f3
|
||||
MX23_PAD_GPMI_CLE__GPIO_0_16 0x0103
|
||||
MX23_PAD_GPMI_ALE__GPIO_0_17 0x0113
|
||||
MX23_PAD_GPMI_CE2N__GPIO_0_18 0x0123
|
||||
MX23_PAD_GPMI_RDY0__GPIO_0_19 0x0133
|
||||
MX23_PAD_GPMI_RDY1__GPIO_0_20 0x0143
|
||||
MX23_PAD_GPMI_RDY2__GPIO_0_21 0x0153
|
||||
MX23_PAD_GPMI_RDY3__GPIO_0_22 0x0163
|
||||
MX23_PAD_GPMI_WPN__GPIO_0_23 0x0173
|
||||
MX23_PAD_GPMI_WRN__GPIO_0_24 0x0183
|
||||
MX23_PAD_GPMI_RDN__GPIO_0_25 0x0193
|
||||
MX23_PAD_AUART1_CTS__GPIO_0_26 0x01a3
|
||||
MX23_PAD_AUART1_RTS__GPIO_0_27 0x01b3
|
||||
MX23_PAD_AUART1_RX__GPIO_0_28 0x01c3
|
||||
MX23_PAD_AUART1_TX__GPIO_0_29 0x01d3
|
||||
MX23_PAD_I2C_SCL__GPIO_0_30 0x01e3
|
||||
MX23_PAD_I2C_SDA__GPIO_0_31 0x01f3
|
||||
MX23_PAD_LCD_D00__GPIO_1_0 0x1003
|
||||
MX23_PAD_LCD_D01__GPIO_1_1 0x1013
|
||||
MX23_PAD_LCD_D02__GPIO_1_2 0x1023
|
||||
MX23_PAD_LCD_D03__GPIO_1_3 0x1033
|
||||
MX23_PAD_LCD_D04__GPIO_1_4 0x1043
|
||||
MX23_PAD_LCD_D05__GPIO_1_5 0x1053
|
||||
MX23_PAD_LCD_D06__GPIO_1_6 0x1063
|
||||
MX23_PAD_LCD_D07__GPIO_1_7 0x1073
|
||||
MX23_PAD_LCD_D08__GPIO_1_8 0x1083
|
||||
MX23_PAD_LCD_D09__GPIO_1_9 0x1093
|
||||
MX23_PAD_LCD_D10__GPIO_1_10 0x10a3
|
||||
MX23_PAD_LCD_D11__GPIO_1_11 0x10b3
|
||||
MX23_PAD_LCD_D12__GPIO_1_12 0x10c3
|
||||
MX23_PAD_LCD_D13__GPIO_1_13 0x10d3
|
||||
MX23_PAD_LCD_D14__GPIO_1_14 0x10e3
|
||||
MX23_PAD_LCD_D15__GPIO_1_15 0x10f3
|
||||
MX23_PAD_LCD_D16__GPIO_1_16 0x1103
|
||||
MX23_PAD_LCD_D17__GPIO_1_17 0x1113
|
||||
MX23_PAD_LCD_RESET__GPIO_1_18 0x1123
|
||||
MX23_PAD_LCD_RS__GPIO_1_19 0x1133
|
||||
MX23_PAD_LCD_WR__GPIO_1_20 0x1143
|
||||
MX23_PAD_LCD_CS__GPIO_1_21 0x1153
|
||||
MX23_PAD_LCD_DOTCK__GPIO_1_22 0x1163
|
||||
MX23_PAD_LCD_ENABLE__GPIO_1_23 0x1173
|
||||
MX23_PAD_LCD_HSYNC__GPIO_1_24 0x1183
|
||||
MX23_PAD_LCD_VSYNC__GPIO_1_25 0x1193
|
||||
MX23_PAD_PWM0__GPIO_1_26 0x11a3
|
||||
MX23_PAD_PWM1__GPIO_1_27 0x11b3
|
||||
MX23_PAD_PWM2__GPIO_1_28 0x11c3
|
||||
MX23_PAD_PWM3__GPIO_1_29 0x11d3
|
||||
MX23_PAD_PWM4__GPIO_1_30 0x11e3
|
||||
MX23_PAD_SSP1_CMD__GPIO_2_0 0x2003
|
||||
MX23_PAD_SSP1_DETECT__GPIO_2_1 0x2013
|
||||
MX23_PAD_SSP1_DATA0__GPIO_2_2 0x2023
|
||||
MX23_PAD_SSP1_DATA1__GPIO_2_3 0x2033
|
||||
MX23_PAD_SSP1_DATA2__GPIO_2_4 0x2043
|
||||
MX23_PAD_SSP1_DATA3__GPIO_2_5 0x2053
|
||||
MX23_PAD_SSP1_SCK__GPIO_2_6 0x2063
|
||||
MX23_PAD_ROTARYA__GPIO_2_7 0x2073
|
||||
MX23_PAD_ROTARYB__GPIO_2_8 0x2083
|
||||
MX23_PAD_EMI_A00__GPIO_2_9 0x2093
|
||||
MX23_PAD_EMI_A01__GPIO_2_10 0x20a3
|
||||
MX23_PAD_EMI_A02__GPIO_2_11 0x20b3
|
||||
MX23_PAD_EMI_A03__GPIO_2_12 0x20c3
|
||||
MX23_PAD_EMI_A04__GPIO_2_13 0x20d3
|
||||
MX23_PAD_EMI_A05__GPIO_2_14 0x20e3
|
||||
MX23_PAD_EMI_A06__GPIO_2_15 0x20f3
|
||||
MX23_PAD_EMI_A07__GPIO_2_16 0x2103
|
||||
MX23_PAD_EMI_A08__GPIO_2_17 0x2113
|
||||
MX23_PAD_EMI_A09__GPIO_2_18 0x2123
|
||||
MX23_PAD_EMI_A10__GPIO_2_19 0x2133
|
||||
MX23_PAD_EMI_A11__GPIO_2_20 0x2143
|
||||
MX23_PAD_EMI_A12__GPIO_2_21 0x2153
|
||||
MX23_PAD_EMI_BA0__GPIO_2_22 0x2163
|
||||
MX23_PAD_EMI_BA1__GPIO_2_23 0x2173
|
||||
MX23_PAD_EMI_CASN__GPIO_2_24 0x2183
|
||||
MX23_PAD_EMI_CE0N__GPIO_2_25 0x2193
|
||||
MX23_PAD_EMI_CE1N__GPIO_2_26 0x21a3
|
||||
MX23_PAD_GPMI_CE1N__GPIO_2_27 0x21b3
|
||||
MX23_PAD_GPMI_CE0N__GPIO_2_28 0x21c3
|
||||
MX23_PAD_EMI_CKE__GPIO_2_29 0x21d3
|
||||
MX23_PAD_EMI_RASN__GPIO_2_30 0x21e3
|
||||
MX23_PAD_EMI_WEN__GPIO_2_31 0x21f3
|
@ -0,0 +1,132 @@
|
||||
NVIDIA Tegra20 pinmux controller
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra20-pinmux"
|
||||
- reg: Should contain the register physical address and length for each of
|
||||
the tri-state, mux, pull-up/down, and pad control register sets.
|
||||
|
||||
Please refer to pinctrl-bindings.txt in this directory for details of the
|
||||
common pinctrl bindings used by client devices, including the meaning of the
|
||||
phrase "pin configuration node".
|
||||
|
||||
Tegra's pin configuration nodes act as a container for an abitrary number of
|
||||
subnodes. Each of these subnodes represents some desired configuration for a
|
||||
pin, a group, or a list of pins or groups. This configuration can include the
|
||||
mux function to select on those pin(s)/group(s), and various pin configuration
|
||||
parameters, such as pull-up, tristate, drive strength, etc.
|
||||
|
||||
The name of each subnode is not important; all subnodes should be enumerated
|
||||
and processed purely based on their content.
|
||||
|
||||
Each subnode only affects those parameters that are explicitly listed. In
|
||||
other words, a subnode that lists a mux function but no pin configuration
|
||||
parameters implies no information about any pin configuration parameters.
|
||||
Similarly, a pin subnode that describes a pullup parameter implies no
|
||||
information about e.g. the mux function or tristate parameter. For this
|
||||
reason, even seemingly boolean values are actually tristates in this binding:
|
||||
unspecified, off, or on. Unspecified is represented as an absent property,
|
||||
and off/on are represented as integer values 0 and 1.
|
||||
|
||||
Required subnode-properties:
|
||||
- nvidia,pins : An array of strings. Each string contains the name of a pin or
|
||||
group. Valid values for these names are listed below.
|
||||
|
||||
Optional subnode-properties:
|
||||
- nvidia,function: A string containing the name of the function to mux to the
|
||||
pin or group. Valid values for function names are listed below. See the Tegra
|
||||
TRM to determine which are valid for each pin or group.
|
||||
- nvidia,pull: Integer, representing the pull-down/up to apply to the pin.
|
||||
0: none, 1: down, 2: up.
|
||||
- nvidia,tristate: Integer.
|
||||
0: drive, 1: tristate.
|
||||
- nvidia,high-speed-mode: Integer. Enable high speed mode the pins.
|
||||
0: no, 1: yes.
|
||||
- nvidia,schmitt: Integer. Enables Schmitt Trigger on the input.
|
||||
0: no, 1: yes.
|
||||
- nvidia,low-power-mode: Integer. Valid values 0-3. 0 is least power, 3 is
|
||||
most power. Controls the drive power or current. See "Low Power Mode"
|
||||
or "LPMD1" and "LPMD0" in the Tegra TRM.
|
||||
- nvidia,pull-down-strength: Integer. Controls drive strength. 0 is weakest.
|
||||
The range of valid values depends on the pingroup. See "CAL_DRVDN" in the
|
||||
Tegra TRM.
|
||||
- nvidia,pull-up-strength: Integer. Controls drive strength. 0 is weakest.
|
||||
The range of valid values depends on the pingroup. See "CAL_DRVUP" in the
|
||||
Tegra TRM.
|
||||
- nvidia,slew-rate-rising: Integer. Controls rising signal slew rate. 0 is
|
||||
fastest. The range of valid values depends on the pingroup. See
|
||||
"DRVDN_SLWR" in the Tegra TRM.
|
||||
- nvidia,slew-rate-falling: Integer. Controls falling signal slew rate. 0 is
|
||||
fastest. The range of valid values depends on the pingroup. See
|
||||
"DRVUP_SLWF" in the Tegra TRM.
|
||||
|
||||
Note that many of these properties are only valid for certain specific pins
|
||||
or groups. See the Tegra TRM and various pinmux spreadsheets for complete
|
||||
details regarding which groups support which functionality. The Linux pinctrl
|
||||
driver may also be a useful reference, since it consolidates, disambiguates,
|
||||
and corrects data from all those sources.
|
||||
|
||||
Valid values for pin and group names are:
|
||||
|
||||
mux groups:
|
||||
|
||||
These all support nvidia,function, nvidia,tristate, and many support
|
||||
nvidia,pull.
|
||||
|
||||
ata, atb, atc, atd, ate, cdev1, cdev2, crtp, csus, dap1, dap2, dap3, dap4,
|
||||
ddc, dta, dtb, dtc, dtd, dte, dtf, gma, gmb, gmc, gmd, gme, gpu, gpu7,
|
||||
gpv, hdint, i2cp, irrx, irtx, kbca, kbcb, kbcc, kbcd, kbce, kbcf, lcsn,
|
||||
ld0, ld1, ld2, ld3, ld4, ld5, ld6, ld7, ld8, ld9, ld10, ld11, ld12, ld13,
|
||||
ld14, ld15, ld16, ld17, ldc, ldi, lhp0, lhp1, lhp2, lhs, lm0, lm1, lpp,
|
||||
lpw0, lpw1, lpw2, lsc0, lsc1, lsck, lsda, lsdi, lspi, lvp0, lvp1, lvs,
|
||||
owc, pmc, pta, rm, sdb, sdc, sdd, sdio1, slxa, slxc, slxd, slxk, spdi,
|
||||
spdo, spia, spib, spic, spid, spie, spif, spig, spih, uaa, uab, uac, uad,
|
||||
uca, ucb, uda.
|
||||
|
||||
tristate groups:
|
||||
|
||||
These only support nvidia,pull.
|
||||
|
||||
ck32, ddrc, pmca, pmcb, pmcc, pmcd, pmce, xm2c, xm2d, ls, lc, ld17_0,
|
||||
ld19_18, ld21_20, ld23_22.
|
||||
|
||||
drive groups:
|
||||
|
||||
With some exceptions, these support nvidia,high-speed-mode,
|
||||
nvidia,schmitt, nvidia,low-power-mode, nvidia,pull-down-strength,
|
||||
nvidia,pull-up-strength, nvidia,slew_rate-rising, nvidia,slew_rate-falling.
|
||||
|
||||
drive_ao1, drive_ao2, drive_at1, drive_at2, drive_cdev1, drive_cdev2,
|
||||
drive_csus, drive_dap1, drive_dap2, drive_dap3, drive_dap4, drive_dbg,
|
||||
drive_lcd1, drive_lcd2, drive_sdmmc2, drive_sdmmc3, drive_spi, drive_uaa,
|
||||
drive_uab, drive_uart2, drive_uart3, drive_vi1, drive_vi2, drive_xm2a,
|
||||
drive_xm2c, drive_xm2d, drive_xm2clk, drive_sdio1, drive_crt, drive_ddc,
|
||||
drive_gma, drive_gmb, drive_gmc, drive_gmd, drive_gme, drive_owr,
|
||||
drive_uda.
|
||||
|
||||
Example:
|
||||
|
||||
pinctrl@70000000 {
|
||||
compatible = "nvidia,tegra20-pinmux";
|
||||
reg = < 0x70000014 0x10 /* Tri-state registers */
|
||||
0x70000080 0x20 /* Mux registers */
|
||||
0x700000a0 0x14 /* Pull-up/down registers */
|
||||
0x70000868 0xa8 >; /* Pad control registers */
|
||||
};
|
||||
|
||||
Example board file extract:
|
||||
|
||||
pinctrl@70000000 {
|
||||
sdio4_default: sdio4_default {
|
||||
atb {
|
||||
nvidia,pins = "atb", "gma", "gme";
|
||||
nvidia,function = "sdio4";
|
||||
nvidia,pull = <0>;
|
||||
nvidia,tristate = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sdhci@c8000600 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sdio4_default>;
|
||||
};
|
@ -0,0 +1,132 @@
|
||||
NVIDIA Tegra30 pinmux controller
|
||||
|
||||
The Tegra30 pinctrl binding is very similar to the Tegra20 pinctrl binding,
|
||||
as described in nvidia,tegra20-pinmux.txt. In fact, this document assumes
|
||||
that binding as a baseline, and only documents the differences between the
|
||||
two bindings.
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra30-pinmux"
|
||||
- reg: Should contain the register physical address and length for each of
|
||||
the pad control and mux registers.
|
||||
|
||||
Tegra30 adds the following optional properties for pin configuration subnodes:
|
||||
- nvidia,enable-input: Integer. Enable the pin's input path. 0: no, 1: yes.
|
||||
- nvidia,open-drain: Integer. Enable open drain mode. 0: no, 1: yes.
|
||||
- nvidia,lock: Integer. Lock the pin configuration against further changes
|
||||
until reset. 0: no, 1: yes.
|
||||
- nvidia,io-reset: Integer. Reset the IO path. 0: no, 1: yes.
|
||||
|
||||
As with Tegra20, see the Tegra TRM for complete details regarding which groups
|
||||
support which functionality.
|
||||
|
||||
Valid values for pin and group names are:
|
||||
|
||||
per-pin mux groups:
|
||||
|
||||
These all support nvidia,function, nvidia,tristate, nvidia,pull,
|
||||
nvidia,enable-input, nvidia,lock. Some support nvidia,open-drain,
|
||||
nvidia,io-reset.
|
||||
|
||||
clk_32k_out_pa0, uart3_cts_n_pa1, dap2_fs_pa2, dap2_sclk_pa3,
|
||||
dap2_din_pa4, dap2_dout_pa5, sdmmc3_clk_pa6, sdmmc3_cmd_pa7, gmi_a17_pb0,
|
||||
gmi_a18_pb1, lcd_pwr0_pb2, lcd_pclk_pb3, sdmmc3_dat3_pb4, sdmmc3_dat2_pb5,
|
||||
sdmmc3_dat1_pb6, sdmmc3_dat0_pb7, uart3_rts_n_pc0, lcd_pwr1_pc1,
|
||||
uart2_txd_pc2, uart2_rxd_pc3, gen1_i2c_scl_pc4, gen1_i2c_sda_pc5,
|
||||
lcd_pwr2_pc6, gmi_wp_n_pc7, sdmmc3_dat5_pd0, sdmmc3_dat4_pd1, lcd_dc1_pd2,
|
||||
sdmmc3_dat6_pd3, sdmmc3_dat7_pd4, vi_d1_pd5, vi_vsync_pd6, vi_hsync_pd7,
|
||||
lcd_d0_pe0, lcd_d1_pe1, lcd_d2_pe2, lcd_d3_pe3, lcd_d4_pe4, lcd_d5_pe5,
|
||||
lcd_d6_pe6, lcd_d7_pe7, lcd_d8_pf0, lcd_d9_pf1, lcd_d10_pf2, lcd_d11_pf3,
|
||||
lcd_d12_pf4, lcd_d13_pf5, lcd_d14_pf6, lcd_d15_pf7, gmi_ad0_pg0,
|
||||
gmi_ad1_pg1, gmi_ad2_pg2, gmi_ad3_pg3, gmi_ad4_pg4, gmi_ad5_pg5,
|
||||
gmi_ad6_pg6, gmi_ad7_pg7, gmi_ad8_ph0, gmi_ad9_ph1, gmi_ad10_ph2,
|
||||
gmi_ad11_ph3, gmi_ad12_ph4, gmi_ad13_ph5, gmi_ad14_ph6, gmi_ad15_ph7,
|
||||
gmi_wr_n_pi0, gmi_oe_n_pi1, gmi_dqs_pi2, gmi_cs6_n_pi3, gmi_rst_n_pi4,
|
||||
gmi_iordy_pi5, gmi_cs7_n_pi6, gmi_wait_pi7, gmi_cs0_n_pj0, lcd_de_pj1,
|
||||
gmi_cs1_n_pj2, lcd_hsync_pj3, lcd_vsync_pj4, uart2_cts_n_pj5,
|
||||
uart2_rts_n_pj6, gmi_a16_pj7, gmi_adv_n_pk0, gmi_clk_pk1, gmi_cs4_n_pk2,
|
||||
gmi_cs2_n_pk3, gmi_cs3_n_pk4, spdif_out_pk5, spdif_in_pk6, gmi_a19_pk7,
|
||||
vi_d2_pl0, vi_d3_pl1, vi_d4_pl2, vi_d5_pl3, vi_d6_pl4, vi_d7_pl5,
|
||||
vi_d8_pl6, vi_d9_pl7, lcd_d16_pm0, lcd_d17_pm1, lcd_d18_pm2, lcd_d19_pm3,
|
||||
lcd_d20_pm4, lcd_d21_pm5, lcd_d22_pm6, lcd_d23_pm7, dap1_fs_pn0,
|
||||
dap1_din_pn1, dap1_dout_pn2, dap1_sclk_pn3, lcd_cs0_n_pn4, lcd_sdout_pn5,
|
||||
lcd_dc0_pn6, hdmi_int_pn7, ulpi_data7_po0, ulpi_data0_po1, ulpi_data1_po2,
|
||||
ulpi_data2_po3, ulpi_data3_po4, ulpi_data4_po5, ulpi_data5_po6,
|
||||
ulpi_data6_po7, dap3_fs_pp0, dap3_din_pp1, dap3_dout_pp2, dap3_sclk_pp3,
|
||||
dap4_fs_pp4, dap4_din_pp5, dap4_dout_pp6, dap4_sclk_pp7, kb_col0_pq0,
|
||||
kb_col1_pq1, kb_col2_pq2, kb_col3_pq3, kb_col4_pq4, kb_col5_pq5,
|
||||
kb_col6_pq6, kb_col7_pq7, kb_row0_pr0, kb_row1_pr1, kb_row2_pr2,
|
||||
kb_row3_pr3, kb_row4_pr4, kb_row5_pr5, kb_row6_pr6, kb_row7_pr7,
|
||||
kb_row8_ps0, kb_row9_ps1, kb_row10_ps2, kb_row11_ps3, kb_row12_ps4,
|
||||
kb_row13_ps5, kb_row14_ps6, kb_row15_ps7, vi_pclk_pt0, vi_mclk_pt1,
|
||||
vi_d10_pt2, vi_d11_pt3, vi_d0_pt4, gen2_i2c_scl_pt5, gen2_i2c_sda_pt6,
|
||||
sdmmc4_cmd_pt7, pu0, pu1, pu2, pu3, pu4, pu5, pu6, jtag_rtck_pu7, pv0,
|
||||
pv1, pv2, pv3, ddc_scl_pv4, ddc_sda_pv5, crt_hsync_pv6, crt_vsync_pv7,
|
||||
lcd_cs1_n_pw0, lcd_m1_pw1, spi2_cs1_n_pw2, spi2_cs2_n_pw3, clk1_out_pw4,
|
||||
clk2_out_pw5, uart3_txd_pw6, uart3_rxd_pw7, spi2_mosi_px0, spi2_miso_px1,
|
||||
spi2_sck_px2, spi2_cs0_n_px3, spi1_mosi_px4, spi1_sck_px5, spi1_cs0_n_px6,
|
||||
spi1_miso_px7, ulpi_clk_py0, ulpi_dir_py1, ulpi_nxt_py2, ulpi_stp_py3,
|
||||
sdmmc1_dat3_py4, sdmmc1_dat2_py5, sdmmc1_dat1_py6, sdmmc1_dat0_py7,
|
||||
sdmmc1_clk_pz0, sdmmc1_cmd_pz1, lcd_sdin_pz2, lcd_wr_n_pz3, lcd_sck_pz4,
|
||||
sys_clk_req_pz5, pwr_i2c_scl_pz6, pwr_i2c_sda_pz7, sdmmc4_dat0_paa0,
|
||||
sdmmc4_dat1_paa1, sdmmc4_dat2_paa2, sdmmc4_dat3_paa3, sdmmc4_dat4_paa4,
|
||||
sdmmc4_dat5_paa5, sdmmc4_dat6_paa6, sdmmc4_dat7_paa7, pbb0,
|
||||
cam_i2c_scl_pbb1, cam_i2c_sda_pbb2, pbb3, pbb4, pbb5, pbb6, pbb7,
|
||||
cam_mclk_pcc0, pcc1, pcc2, sdmmc4_rst_n_pcc3, sdmmc4_clk_pcc4,
|
||||
clk2_req_pcc5, pex_l2_rst_n_pcc6, pex_l2_clkreq_n_pcc7,
|
||||
pex_l0_prsnt_n_pdd0, pex_l0_rst_n_pdd1, pex_l0_clkreq_n_pdd2,
|
||||
pex_wake_n_pdd3, pex_l1_prsnt_n_pdd4, pex_l1_rst_n_pdd5,
|
||||
pex_l1_clkreq_n_pdd6, pex_l2_prsnt_n_pdd7, clk3_out_pee0, clk3_req_pee1,
|
||||
clk1_req_pee2, hdmi_cec_pee3, clk_32k_in, core_pwr_req, cpu_pwr_req, owr,
|
||||
pwr_int_n.
|
||||
|
||||
drive groups:
|
||||
|
||||
These all support nvidia,pull-down-strength, nvidia,pull-up-strength,
|
||||
nvidia,slew_rate-rising, nvidia,slew_rate-falling. Most but not all
|
||||
support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode.
|
||||
|
||||
ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, cec, crt, csus, dap1,
|
||||
dap2, dap3, dap4, dbg, ddc, dev3, gma, gmb, gmc, gmd, gme, gmf, gmg,
|
||||
gmh, gpv, lcd1, lcd2, owr, sdio1, sdio2, sdio3, spi, uaa, uab, uart2,
|
||||
uart3, uda, vi1.
|
||||
|
||||
Example:
|
||||
|
||||
pinctrl@70000000 {
|
||||
compatible = "nvidia,tegra30-pinmux";
|
||||
reg = < 0x70000868 0xd0 /* Pad control registers */
|
||||
0x70003000 0x3e0 >; /* Mux registers */
|
||||
};
|
||||
|
||||
Example board file extract:
|
||||
|
||||
pinctrl@70000000 {
|
||||
sdmmc4_default: pinmux {
|
||||
sdmmc4_clk_pcc4 {
|
||||
nvidia,pins = "sdmmc4_clk_pcc4",
|
||||
"sdmmc4_rst_n_pcc3";
|
||||
nvidia,function = "sdmmc4";
|
||||
nvidia,pull = <0>;
|
||||
nvidia,tristate = <0>;
|
||||
};
|
||||
sdmmc4_dat0_paa0 {
|
||||
nvidia,pins = "sdmmc4_dat0_paa0",
|
||||
"sdmmc4_dat1_paa1",
|
||||
"sdmmc4_dat2_paa2",
|
||||
"sdmmc4_dat3_paa3",
|
||||
"sdmmc4_dat4_paa4",
|
||||
"sdmmc4_dat5_paa5",
|
||||
"sdmmc4_dat6_paa6",
|
||||
"sdmmc4_dat7_paa7";
|
||||
nvidia,function = "sdmmc4";
|
||||
nvidia,pull = <2>;
|
||||
nvidia,tristate = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sdhci@78000400 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sdmmc4_default>;
|
||||
};
|
128
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
Normal file
128
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
Normal file
@ -0,0 +1,128 @@
|
||||
== Introduction ==
|
||||
|
||||
Hardware modules that control pin multiplexing or configuration parameters
|
||||
such as pull-up/down, tri-state, drive-strength etc are designated as pin
|
||||
controllers. Each pin controller must be represented as a node in device tree,
|
||||
just like any other hardware module.
|
||||
|
||||
Hardware modules whose signals are affected by pin configuration are
|
||||
designated client devices. Again, each client device must be represented as a
|
||||
node in device tree, just like any other hardware module.
|
||||
|
||||
For a client device to operate correctly, certain pin controllers must
|
||||
set up certain specific pin configurations. Some client devices need a
|
||||
single static pin configuration, e.g. set up during initialization. Others
|
||||
need to reconfigure pins at run-time, for example to tri-state pins when the
|
||||
device is inactive. Hence, each client device can define a set of named
|
||||
states. The number and names of those states is defined by the client device's
|
||||
own binding.
|
||||
|
||||
The common pinctrl bindings defined in this file provide an infrastructure
|
||||
for client device device tree nodes to map those state names to the pin
|
||||
configuration used by those states.
|
||||
|
||||
Note that pin controllers themselves may also be client devices of themselves.
|
||||
For example, a pin controller may set up its own "active" state when the
|
||||
driver loads. This would allow representing a board's static pin configuration
|
||||
in a single place, rather than splitting it across multiple client device
|
||||
nodes. The decision to do this or not somewhat rests with the author of
|
||||
individual board device tree files, and any requirements imposed by the
|
||||
bindings for the individual client devices in use by that board, i.e. whether
|
||||
they require certain specific named states for dynamic pin configuration.
|
||||
|
||||
== Pinctrl client devices ==
|
||||
|
||||
For each client device individually, every pin state is assigned an integer
|
||||
ID. These numbers start at 0, and are contiguous. For each state ID, a unique
|
||||
property exists to define the pin configuration. Each state may also be
|
||||
assigned a name. When names are used, another property exists to map from
|
||||
those names to the integer IDs.
|
||||
|
||||
Each client device's own binding determines the set of states the must be
|
||||
defined in its device tree node, and whether to define the set of state
|
||||
IDs that must be provided, or whether to define the set of state names that
|
||||
must be provided.
|
||||
|
||||
Required properties:
|
||||
pinctrl-0: List of phandles, each pointing at a pin configuration
|
||||
node. These referenced pin configuration nodes must be child
|
||||
nodes of the pin controller that they configure. Multiple
|
||||
entries may exist in this list so that multiple pin
|
||||
controllers may be configured, or so that a state may be built
|
||||
from multiple nodes for a single pin controller, each
|
||||
contributing part of the overall configuration. See the next
|
||||
section of this document for details of the format of these
|
||||
pin configuration nodes.
|
||||
|
||||
In some cases, it may be useful to define a state, but for it
|
||||
to be empty. This may be required when a common IP block is
|
||||
used in an SoC either without a pin controller, or where the
|
||||
pin controller does not affect the HW module in question. If
|
||||
the binding for that IP block requires certain pin states to
|
||||
exist, they must still be defined, but may be left empty.
|
||||
|
||||
Optional properties:
|
||||
pinctrl-1: List of phandles, each pointing at a pin configuration
|
||||
node within a pin controller.
|
||||
...
|
||||
pinctrl-n: List of phandles, each pointing at a pin configuration
|
||||
node within a pin controller.
|
||||
pinctrl-names: The list of names to assign states. List entry 0 defines the
|
||||
name for integer state ID 0, list entry 1 for state ID 1, and
|
||||
so on.
|
||||
|
||||
For example:
|
||||
|
||||
/* For a client device requiring named states */
|
||||
device {
|
||||
pinctrl-names = "active", "idle";
|
||||
pinctrl-0 = <&state_0_node_a>;
|
||||
pinctrl-1 = <&state_1_node_a &state_1_node_b>;
|
||||
};
|
||||
|
||||
/* For the same device if using state IDs */
|
||||
device {
|
||||
pinctrl-0 = <&state_0_node_a>;
|
||||
pinctrl-1 = <&state_1_node_a &state_1_node_b>;
|
||||
};
|
||||
|
||||
/*
|
||||
* For an IP block whose binding supports pin configuration,
|
||||
* but in use on an SoC that doesn't have any pin control hardware
|
||||
*/
|
||||
device {
|
||||
pinctrl-names = "active", "idle";
|
||||
pinctrl-0 = <>;
|
||||
pinctrl-1 = <>;
|
||||
};
|
||||
|
||||
== Pin controller devices ==
|
||||
|
||||
Pin controller devices should contain the pin configuration nodes that client
|
||||
devices reference.
|
||||
|
||||
For example:
|
||||
|
||||
pincontroller {
|
||||
... /* Standard DT properties for the device itself elided */
|
||||
|
||||
state_0_node_a {
|
||||
...
|
||||
};
|
||||
state_1_node_a {
|
||||
...
|
||||
};
|
||||
state_1_node_b {
|
||||
...
|
||||
};
|
||||
}
|
||||
|
||||
The contents of each of those pin configuration child nodes is defined
|
||||
entirely by the binding for the individual pin controller device. There
|
||||
exists no common standard for this content.
|
||||
|
||||
The pin configuration nodes need not be direct children of the pin controller
|
||||
device; they may be grandchildren, for example. Whether this is legal, and
|
||||
whether there is any interaction between the child and intermediate parent
|
||||
nodes, is again defined entirely by the binding for the individual pin
|
||||
controller device.
|
@ -1,5 +0,0 @@
|
||||
NVIDIA Tegra 2 pinmux controller
|
||||
|
||||
Required properties:
|
||||
- compatible : "nvidia,tegra20-pinmux"
|
||||
|
@ -280,3 +280,7 @@ REGULATOR
|
||||
CLOCK
|
||||
devm_clk_get()
|
||||
devm_clk_put()
|
||||
|
||||
PINCTRL
|
||||
devm_pinctrl_get()
|
||||
devm_pinctrl_put()
|
||||
|
@ -152,11 +152,9 @@ static const struct foo_group foo_groups[] = {
|
||||
};
|
||||
|
||||
|
||||
static int foo_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
|
||||
static int foo_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(foo_groups))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return ARRAY_SIZE(foo_groups);
|
||||
}
|
||||
|
||||
static const char *foo_get_group_name(struct pinctrl_dev *pctldev,
|
||||
@ -175,7 +173,7 @@ static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
}
|
||||
|
||||
static struct pinctrl_ops foo_pctrl_ops = {
|
||||
.list_groups = foo_list_groups,
|
||||
.get_groups_count = foo_get_groups_count,
|
||||
.get_group_name = foo_get_group_name,
|
||||
.get_group_pins = foo_get_group_pins,
|
||||
};
|
||||
@ -186,13 +184,12 @@ static struct pinctrl_desc foo_desc = {
|
||||
.pctlops = &foo_pctrl_ops,
|
||||
};
|
||||
|
||||
The pin control subsystem will call the .list_groups() function repeatedly
|
||||
beginning on 0 until it returns non-zero to determine legal selectors, then
|
||||
it will call the other functions to retrieve the name and pins of the group.
|
||||
Maintaining the data structure of the groups is up to the driver, this is
|
||||
just a simple example - in practice you may need more entries in your group
|
||||
structure, for example specific register ranges associated with each group
|
||||
and so on.
|
||||
The pin control subsystem will call the .get_groups_count() function to
|
||||
determine total number of legal selectors, then it will call the other functions
|
||||
to retrieve the name and pins of the group. Maintaining the data structure of
|
||||
the groups is up to the driver, this is just a simple example - in practice you
|
||||
may need more entries in your group structure, for example specific register
|
||||
ranges associated with each group and so on.
|
||||
|
||||
|
||||
Pin configuration
|
||||
@ -606,11 +603,9 @@ static const struct foo_group foo_groups[] = {
|
||||
};
|
||||
|
||||
|
||||
static int foo_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
|
||||
static int foo_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(foo_groups))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return ARRAY_SIZE(foo_groups);
|
||||
}
|
||||
|
||||
static const char *foo_get_group_name(struct pinctrl_dev *pctldev,
|
||||
@ -629,7 +624,7 @@ static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
}
|
||||
|
||||
static struct pinctrl_ops foo_pctrl_ops = {
|
||||
.list_groups = foo_list_groups,
|
||||
.get_groups_count = foo_get_groups_count,
|
||||
.get_group_name = foo_get_group_name,
|
||||
.get_group_pins = foo_get_group_pins,
|
||||
};
|
||||
@ -640,7 +635,7 @@ struct foo_pmx_func {
|
||||
const unsigned num_groups;
|
||||
};
|
||||
|
||||
static const char * const spi0_groups[] = { "spi0_1_grp" };
|
||||
static const char * const spi0_groups[] = { "spi0_0_grp", "spi0_1_grp" };
|
||||
static const char * const i2c0_groups[] = { "i2c0_grp" };
|
||||
static const char * const mmc0_groups[] = { "mmc0_1_grp", "mmc0_2_grp",
|
||||
"mmc0_3_grp" };
|
||||
@ -663,11 +658,9 @@ static const struct foo_pmx_func foo_functions[] = {
|
||||
},
|
||||
};
|
||||
|
||||
int foo_list_funcs(struct pinctrl_dev *pctldev, unsigned selector)
|
||||
int foo_get_functions_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(foo_functions))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return ARRAY_SIZE(foo_functions);
|
||||
}
|
||||
|
||||
const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector)
|
||||
@ -703,7 +696,7 @@ void foo_disable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
}
|
||||
|
||||
struct pinmux_ops foo_pmxops = {
|
||||
.list_functions = foo_list_funcs,
|
||||
.get_functions_count = foo_get_functions_count,
|
||||
.get_function_name = foo_get_fname,
|
||||
.get_function_groups = foo_get_groups,
|
||||
.enable = foo_enable,
|
||||
@ -786,7 +779,7 @@ and spi on the second function mapping:
|
||||
|
||||
#include <linux/pinctrl/machine.h>
|
||||
|
||||
static const struct pinctrl_map __initdata mapping[] = {
|
||||
static const struct pinctrl_map mapping[] __initconst = {
|
||||
{
|
||||
.dev_name = "foo-spi.0",
|
||||
.name = PINCTRL_STATE_DEFAULT,
|
||||
@ -952,13 +945,13 @@ case), we define a mapping like this:
|
||||
The result of grabbing this mapping from the device with something like
|
||||
this (see next paragraph):
|
||||
|
||||
p = pinctrl_get(dev);
|
||||
p = devm_pinctrl_get(dev);
|
||||
s = pinctrl_lookup_state(p, "8bit");
|
||||
ret = pinctrl_select_state(p, s);
|
||||
|
||||
or more simply:
|
||||
|
||||
p = pinctrl_get_select(dev, "8bit");
|
||||
p = devm_pinctrl_get_select(dev, "8bit");
|
||||
|
||||
Will be that you activate all the three bottom records in the mapping at
|
||||
once. Since they share the same name, pin controller device, function and
|
||||
@ -992,7 +985,7 @@ foo_probe()
|
||||
/* Allocate a state holder named "foo" etc */
|
||||
struct foo_state *foo = ...;
|
||||
|
||||
foo->p = pinctrl_get(&device);
|
||||
foo->p = devm_pinctrl_get(&device);
|
||||
if (IS_ERR(foo->p)) {
|
||||
/* FIXME: clean up "foo" here */
|
||||
return PTR_ERR(foo->p);
|
||||
@ -1000,24 +993,17 @@ foo_probe()
|
||||
|
||||
foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT);
|
||||
if (IS_ERR(foo->s)) {
|
||||
pinctrl_put(foo->p);
|
||||
/* FIXME: clean up "foo" here */
|
||||
return PTR_ERR(s);
|
||||
}
|
||||
|
||||
ret = pinctrl_select_state(foo->s);
|
||||
if (ret < 0) {
|
||||
pinctrl_put(foo->p);
|
||||
/* FIXME: clean up "foo" here */
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
foo_remove()
|
||||
{
|
||||
pinctrl_put(state->p);
|
||||
}
|
||||
|
||||
This get/lookup/select/put sequence can just as well be handled by bus drivers
|
||||
if you don't want each and every driver to handle it and you know the
|
||||
arrangement on your bus.
|
||||
@ -1029,6 +1015,11 @@ The semantics of the pinctrl APIs are:
|
||||
kernel memory to hold the pinmux state. All mapping table parsing or similar
|
||||
slow operations take place within this API.
|
||||
|
||||
- devm_pinctrl_get() is a variant of pinctrl_get() that causes pinctrl_put()
|
||||
to be called automatically on the retrieved pointer when the associated
|
||||
device is removed. It is recommended to use this function over plain
|
||||
pinctrl_get().
|
||||
|
||||
- pinctrl_lookup_state() is called in process context to obtain a handle to a
|
||||
specific state for a the client device. This operation may be slow too.
|
||||
|
||||
@ -1041,14 +1032,30 @@ The semantics of the pinctrl APIs are:
|
||||
|
||||
- pinctrl_put() frees all information associated with a pinctrl handle.
|
||||
|
||||
- devm_pinctrl_put() is a variant of pinctrl_put() that may be used to
|
||||
explicitly destroy a pinctrl object returned by devm_pinctrl_get().
|
||||
However, use of this function will be rare, due to the automatic cleanup
|
||||
that will occur even without calling it.
|
||||
|
||||
pinctrl_get() must be paired with a plain pinctrl_put().
|
||||
pinctrl_get() may not be paired with devm_pinctrl_put().
|
||||
devm_pinctrl_get() can optionally be paired with devm_pinctrl_put().
|
||||
devm_pinctrl_get() may not be paired with plain pinctrl_put().
|
||||
|
||||
Usually the pin control core handled the get/put pair and call out to the
|
||||
device drivers bookkeeping operations, like checking available functions and
|
||||
the associated pins, whereas the enable/disable pass on to the pin controller
|
||||
driver which takes care of activating and/or deactivating the mux setting by
|
||||
quickly poking some registers.
|
||||
|
||||
The pins are allocated for your device when you issue the pinctrl_get() call,
|
||||
after this you should be able to see this in the debugfs listing of all pins.
|
||||
The pins are allocated for your device when you issue the devm_pinctrl_get()
|
||||
call, after this you should be able to see this in the debugfs listing of all
|
||||
pins.
|
||||
|
||||
NOTE: the pinctrl system will return -EPROBE_DEFER if it cannot find the
|
||||
requested pinctrl handles, for example if the pinctrl driver has not yet
|
||||
registered. Thus make sure that the error path in your driver gracefully
|
||||
cleans up and is ready to retry the probing later in the startup process.
|
||||
|
||||
|
||||
System pin control hogging
|
||||
@ -1094,13 +1101,13 @@ it, disables and releases it, and muxes it in on the pins defined by group B:
|
||||
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
foo_switch()
|
||||
{
|
||||
struct pinctrl *p;
|
||||
struct pinctrl_state *s1, *s2;
|
||||
struct pinctrl *p;
|
||||
struct pinctrl_state *s1, *s2;
|
||||
|
||||
foo_probe()
|
||||
{
|
||||
/* Setup */
|
||||
p = pinctrl_get(&device);
|
||||
p = devm_pinctrl_get(&device);
|
||||
if (IS_ERR(p))
|
||||
...
|
||||
|
||||
@ -1111,7 +1118,10 @@ foo_switch()
|
||||
s2 = pinctrl_lookup_state(foo->p, "pos-B");
|
||||
if (IS_ERR(s2))
|
||||
...
|
||||
}
|
||||
|
||||
foo_switch()
|
||||
{
|
||||
/* Enable on position A */
|
||||
ret = pinctrl_select_state(s1);
|
||||
if (ret < 0)
|
||||
@ -1125,8 +1135,6 @@ foo_switch()
|
||||
...
|
||||
|
||||
...
|
||||
|
||||
pinctrl_put(p);
|
||||
}
|
||||
|
||||
The above has to be done from process context.
|
||||
|
@ -1260,3 +1260,44 @@ int of_alias_get_id(struct device_node *np, const char *stem)
|
||||
return id;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_alias_get_id);
|
||||
|
||||
const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
|
||||
u32 *pu)
|
||||
{
|
||||
const void *curv = cur;
|
||||
|
||||
if (!prop)
|
||||
return NULL;
|
||||
|
||||
if (!cur) {
|
||||
curv = prop->value;
|
||||
goto out_val;
|
||||
}
|
||||
|
||||
curv += sizeof(*cur);
|
||||
if (curv >= prop->value + prop->length)
|
||||
return NULL;
|
||||
|
||||
out_val:
|
||||
*pu = be32_to_cpup(curv);
|
||||
return curv;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_prop_next_u32);
|
||||
|
||||
const char *of_prop_next_string(struct property *prop, const char *cur)
|
||||
{
|
||||
const void *curv = cur;
|
||||
|
||||
if (!prop)
|
||||
return NULL;
|
||||
|
||||
if (!cur)
|
||||
return prop->value;
|
||||
|
||||
curv += strlen(cur) + 1;
|
||||
if (curv >= prop->value + prop->length)
|
||||
return NULL;
|
||||
|
||||
return curv;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_prop_next_string);
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
config PINCTRL
|
||||
bool
|
||||
depends on EXPERIMENTAL
|
||||
|
||||
if PINCTRL
|
||||
|
||||
@ -27,6 +26,35 @@ config DEBUG_PINCTRL
|
||||
help
|
||||
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
|
||||
|
||||
config PINCTRL_IMX
|
||||
bool
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
|
||||
config PINCTRL_IMX51
|
||||
bool "IMX51 pinctrl driver"
|
||||
depends on OF
|
||||
depends on SOC_IMX51
|
||||
select PINCTRL_IMX
|
||||
help
|
||||
Say Y here to enable the imx51 pinctrl driver
|
||||
|
||||
config PINCTRL_IMX53
|
||||
bool "IMX53 pinctrl driver"
|
||||
depends on OF
|
||||
depends on SOC_IMX53
|
||||
select PINCTRL_IMX
|
||||
help
|
||||
Say Y here to enable the imx53 pinctrl driver
|
||||
|
||||
config PINCTRL_IMX6Q
|
||||
bool "IMX6Q pinctrl driver"
|
||||
depends on OF
|
||||
depends on SOC_IMX6Q
|
||||
select PINCTRL_IMX
|
||||
help
|
||||
Say Y here to enable the imx6q pinctrl driver
|
||||
|
||||
config PINCTRL_PXA3xx
|
||||
bool
|
||||
select PINMUX
|
||||
@ -37,6 +65,21 @@ config PINCTRL_MMP2
|
||||
select PINCTRL_PXA3xx
|
||||
select PINCONF
|
||||
|
||||
config PINCTRL_MXS
|
||||
bool
|
||||
|
||||
config PINCTRL_IMX23
|
||||
bool
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select PINCTRL_MXS
|
||||
|
||||
config PINCTRL_IMX28
|
||||
bool
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select PINCTRL_MXS
|
||||
|
||||
config PINCTRL_PXA168
|
||||
bool "PXA168 pin controller driver"
|
||||
depends on ARCH_MMP
|
||||
|
@ -5,9 +5,19 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG
|
||||
obj-$(CONFIG_PINCTRL) += core.o
|
||||
obj-$(CONFIG_PINMUX) += pinmux.o
|
||||
obj-$(CONFIG_PINCONF) += pinconf.o
|
||||
ifeq ($(CONFIG_OF),y)
|
||||
obj-$(CONFIG_PINCTRL) += devicetree.o
|
||||
endif
|
||||
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
|
||||
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
|
||||
obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o
|
||||
obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o
|
||||
obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o
|
||||
obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o
|
||||
obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o
|
||||
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
|
||||
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
|
||||
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
|
||||
obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o
|
||||
obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o
|
||||
obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o
|
||||
|
@ -23,9 +23,11 @@
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include "core.h"
|
||||
#include "devicetree.h"
|
||||
#include "pinmux.h"
|
||||
#include "pinconf.h"
|
||||
|
||||
@ -41,11 +43,13 @@ struct pinctrl_maps {
|
||||
unsigned num_maps;
|
||||
};
|
||||
|
||||
static bool pinctrl_dummy_state;
|
||||
|
||||
/* Mutex taken by all entry points */
|
||||
DEFINE_MUTEX(pinctrl_mutex);
|
||||
|
||||
/* Global list of pin control devices (struct pinctrl_dev) */
|
||||
static LIST_HEAD(pinctrldev_list);
|
||||
LIST_HEAD(pinctrldev_list);
|
||||
|
||||
/* List of pin controller handles (struct pinctrl) */
|
||||
static LIST_HEAD(pinctrl_list);
|
||||
@ -59,6 +63,19 @@ static LIST_HEAD(pinctrl_maps);
|
||||
_i_ < _maps_node_->num_maps; \
|
||||
i++, _map_ = &_maps_node_->maps[_i_])
|
||||
|
||||
/**
|
||||
* pinctrl_provide_dummies() - indicate if pinctrl provides dummy state support
|
||||
*
|
||||
* Usually this function is called by platforms without pinctrl driver support
|
||||
* but run with some shared drivers using pinctrl APIs.
|
||||
* After calling this function, the pinctrl core will return successfully
|
||||
* with creating a dummy state for the driver to keep going smoothly.
|
||||
*/
|
||||
void pinctrl_provide_dummies(void)
|
||||
{
|
||||
pinctrl_dummy_state = true;
|
||||
}
|
||||
|
||||
const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
/* We're not allowed to register devices without name */
|
||||
@ -123,6 +140,25 @@ int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pin_get_name_from_id() - look up a pin name from a pin id
|
||||
* @pctldev: the pin control device to lookup the pin on
|
||||
* @name: the name of the pin to look up
|
||||
*/
|
||||
const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin)
|
||||
{
|
||||
const struct pin_desc *desc;
|
||||
|
||||
desc = pin_desc_get(pctldev, pin);
|
||||
if (desc == NULL) {
|
||||
dev_err(pctldev->dev, "failed to get pin(%d) name\n",
|
||||
pin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return desc->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* pin_is_valid() - check if pin exists on controller
|
||||
* @pctldev: the pin control device to check the pin on
|
||||
@ -255,7 +291,8 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio)
|
||||
*
|
||||
* Find the pin controller handling a certain GPIO pin from the pinspace of
|
||||
* the GPIO subsystem, return the device and the matching GPIO range. Returns
|
||||
* negative if the GPIO range could not be found in any device.
|
||||
* -EPROBE_DEFER if the GPIO range could not be found in any device since it
|
||||
* may still have not been registered.
|
||||
*/
|
||||
static int pinctrl_get_device_gpio_range(unsigned gpio,
|
||||
struct pinctrl_dev **outdev,
|
||||
@ -275,7 +312,7 @@ static int pinctrl_get_device_gpio_range(unsigned gpio,
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,9 +355,10 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
|
||||
const char *pin_group)
|
||||
{
|
||||
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
|
||||
unsigned ngroups = pctlops->get_groups_count(pctldev);
|
||||
unsigned group_selector = 0;
|
||||
|
||||
while (pctlops->list_groups(pctldev, group_selector) >= 0) {
|
||||
while (group_selector < ngroups) {
|
||||
const char *gname = pctlops->get_group_name(pctldev,
|
||||
group_selector);
|
||||
if (!strcmp(gname, pin_group)) {
|
||||
@ -360,7 +398,7 @@ int pinctrl_request_gpio(unsigned gpio)
|
||||
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
|
||||
if (ret) {
|
||||
mutex_unlock(&pinctrl_mutex);
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Convert to the pin controllers number space */
|
||||
@ -516,11 +554,14 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
|
||||
|
||||
setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
|
||||
if (setting->pctldev == NULL) {
|
||||
dev_err(p->dev, "unknown pinctrl device %s in map entry",
|
||||
dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe",
|
||||
map->ctrl_dev_name);
|
||||
kfree(setting);
|
||||
/* Eventually, this should trigger deferred probe */
|
||||
return -ENODEV;
|
||||
/*
|
||||
* OK let us guess that the driver is not there yet, and
|
||||
* let's defer obtaining this pinctrl handle to later...
|
||||
*/
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
switch (map->type) {
|
||||
@ -579,6 +620,13 @@ static struct pinctrl *create_pinctrl(struct device *dev)
|
||||
}
|
||||
p->dev = dev;
|
||||
INIT_LIST_HEAD(&p->states);
|
||||
INIT_LIST_HEAD(&p->dt_maps);
|
||||
|
||||
ret = pinctrl_dt_to_map(p);
|
||||
if (ret < 0) {
|
||||
kfree(p);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
devname = dev_name(dev);
|
||||
|
||||
@ -662,6 +710,8 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist)
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
pinctrl_dt_free_maps(p);
|
||||
|
||||
if (inlist)
|
||||
list_del(&p->node);
|
||||
kfree(p);
|
||||
@ -685,8 +735,18 @@ static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p,
|
||||
struct pinctrl_state *state;
|
||||
|
||||
state = find_state(p, name);
|
||||
if (!state)
|
||||
return ERR_PTR(-ENODEV);
|
||||
if (!state) {
|
||||
if (pinctrl_dummy_state) {
|
||||
/* create dummy state */
|
||||
dev_dbg(p->dev, "using pinctrl dummy state (%s)\n",
|
||||
name);
|
||||
state = create_state(p, name);
|
||||
if (IS_ERR(state))
|
||||
return state;
|
||||
} else {
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
@ -787,15 +847,63 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pinctrl_select_state);
|
||||
|
||||
static void devm_pinctrl_release(struct device *dev, void *res)
|
||||
{
|
||||
pinctrl_put(*(struct pinctrl **)res);
|
||||
}
|
||||
|
||||
/**
|
||||
* pinctrl_register_mappings() - register a set of pin controller mappings
|
||||
* @maps: the pincontrol mappings table to register. This should probably be
|
||||
* marked with __initdata so it can be discarded after boot. This
|
||||
* function will perform a shallow copy for the mapping entries.
|
||||
* @num_maps: the number of maps in the mapping table
|
||||
* struct devm_pinctrl_get() - Resource managed pinctrl_get()
|
||||
* @dev: the device to obtain the handle for
|
||||
*
|
||||
* If there is a need to explicitly destroy the returned struct pinctrl,
|
||||
* devm_pinctrl_put() should be used, rather than plain pinctrl_put().
|
||||
*/
|
||||
int pinctrl_register_mappings(struct pinctrl_map const *maps,
|
||||
unsigned num_maps)
|
||||
struct pinctrl *devm_pinctrl_get(struct device *dev)
|
||||
{
|
||||
struct pinctrl **ptr, *p;
|
||||
|
||||
ptr = devres_alloc(devm_pinctrl_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
p = pinctrl_get(dev);
|
||||
if (!IS_ERR(p)) {
|
||||
*ptr = p;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_pinctrl_get);
|
||||
|
||||
static int devm_pinctrl_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct pinctrl **p = res;
|
||||
|
||||
return *p == data;
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_pinctrl_put() - Resource managed pinctrl_put()
|
||||
* @p: the pinctrl handle to release
|
||||
*
|
||||
* Deallocate a struct pinctrl obtained via devm_pinctrl_get(). Normally
|
||||
* this function will not need to be called and the resource management
|
||||
* code will ensure that the resource is freed.
|
||||
*/
|
||||
void devm_pinctrl_put(struct pinctrl *p)
|
||||
{
|
||||
WARN_ON(devres_destroy(p->dev, devm_pinctrl_release,
|
||||
devm_pinctrl_match, p));
|
||||
pinctrl_put(p);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_pinctrl_put);
|
||||
|
||||
int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
|
||||
bool dup, bool locked)
|
||||
{
|
||||
int i, ret;
|
||||
struct pinctrl_maps *maps_node;
|
||||
@ -829,13 +937,13 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps,
|
||||
case PIN_MAP_TYPE_MUX_GROUP:
|
||||
ret = pinmux_validate_map(&maps[i], i);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
return ret;
|
||||
break;
|
||||
case PIN_MAP_TYPE_CONFIGS_PIN:
|
||||
case PIN_MAP_TYPE_CONFIGS_GROUP:
|
||||
ret = pinconf_validate_map(&maps[i], i);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
pr_err("failed to register map %s (%d): invalid type given\n",
|
||||
@ -851,20 +959,52 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps,
|
||||
}
|
||||
|
||||
maps_node->num_maps = num_maps;
|
||||
maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL);
|
||||
if (!maps_node->maps) {
|
||||
pr_err("failed to duplicate mapping table\n");
|
||||
kfree(maps_node);
|
||||
return -ENOMEM;
|
||||
if (dup) {
|
||||
maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps,
|
||||
GFP_KERNEL);
|
||||
if (!maps_node->maps) {
|
||||
pr_err("failed to duplicate mapping table\n");
|
||||
kfree(maps_node);
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
maps_node->maps = maps;
|
||||
}
|
||||
|
||||
mutex_lock(&pinctrl_mutex);
|
||||
if (!locked)
|
||||
mutex_lock(&pinctrl_mutex);
|
||||
list_add_tail(&maps_node->node, &pinctrl_maps);
|
||||
mutex_unlock(&pinctrl_mutex);
|
||||
if (!locked)
|
||||
mutex_unlock(&pinctrl_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinctrl_register_mappings() - register a set of pin controller mappings
|
||||
* @maps: the pincontrol mappings table to register. This should probably be
|
||||
* marked with __initdata so it can be discarded after boot. This
|
||||
* function will perform a shallow copy for the mapping entries.
|
||||
* @num_maps: the number of maps in the mapping table
|
||||
*/
|
||||
int pinctrl_register_mappings(struct pinctrl_map const *maps,
|
||||
unsigned num_maps)
|
||||
{
|
||||
return pinctrl_register_map(maps, num_maps, true, false);
|
||||
}
|
||||
|
||||
void pinctrl_unregister_map(struct pinctrl_map const *map)
|
||||
{
|
||||
struct pinctrl_maps *maps_node;
|
||||
|
||||
list_for_each_entry(maps_node, &pinctrl_maps, node) {
|
||||
if (maps_node->maps == map) {
|
||||
list_del(&maps_node->node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
static int pinctrl_pins_show(struct seq_file *s, void *what)
|
||||
@ -906,15 +1046,17 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
|
||||
{
|
||||
struct pinctrl_dev *pctldev = s->private;
|
||||
const struct pinctrl_ops *ops = pctldev->desc->pctlops;
|
||||
unsigned selector = 0;
|
||||
unsigned ngroups, selector = 0;
|
||||
|
||||
ngroups = ops->get_groups_count(pctldev);
|
||||
mutex_lock(&pinctrl_mutex);
|
||||
|
||||
seq_puts(s, "registered pin groups:\n");
|
||||
while (ops->list_groups(pctldev, selector) >= 0) {
|
||||
while (selector < ngroups) {
|
||||
const unsigned *pins;
|
||||
unsigned num_pins;
|
||||
const char *gname = ops->get_group_name(pctldev, selector);
|
||||
const char *pname;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@ -924,10 +1066,14 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
|
||||
seq_printf(s, "%s [ERROR GETTING PINS]\n",
|
||||
gname);
|
||||
else {
|
||||
seq_printf(s, "group: %s, pins = [ ", gname);
|
||||
for (i = 0; i < num_pins; i++)
|
||||
seq_printf(s, "%d ", pins[i]);
|
||||
seq_puts(s, "]\n");
|
||||
seq_printf(s, "group: %s\n", gname);
|
||||
for (i = 0; i < num_pins; i++) {
|
||||
pname = pin_get_name(pctldev, pins[i]);
|
||||
if (WARN_ON(!pname))
|
||||
return -EINVAL;
|
||||
seq_printf(s, "pin %d (%s)\n", pins[i], pname);
|
||||
}
|
||||
seq_puts(s, "\n");
|
||||
}
|
||||
selector++;
|
||||
}
|
||||
@ -1226,11 +1372,14 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctldev)
|
||||
const struct pinctrl_ops *ops = pctldev->desc->pctlops;
|
||||
|
||||
if (!ops ||
|
||||
!ops->list_groups ||
|
||||
!ops->get_groups_count ||
|
||||
!ops->get_group_name ||
|
||||
!ops->get_group_pins)
|
||||
return -EINVAL;
|
||||
|
||||
if (ops->dt_node_to_map && !ops->dt_free_map)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1268,37 +1417,29 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
|
||||
/* check core ops for sanity */
|
||||
ret = pinctrl_check_ops(pctldev);
|
||||
if (ret) {
|
||||
pr_err("%s pinctrl ops lacks necessary functions\n",
|
||||
pctldesc->name);
|
||||
dev_err(dev, "pinctrl ops lacks necessary functions\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* If we're implementing pinmuxing, check the ops for sanity */
|
||||
if (pctldesc->pmxops) {
|
||||
ret = pinmux_check_ops(pctldev);
|
||||
if (ret) {
|
||||
pr_err("%s pinmux ops lacks necessary functions\n",
|
||||
pctldesc->name);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're implementing pinconfig, check the ops for sanity */
|
||||
if (pctldesc->confops) {
|
||||
ret = pinconf_check_ops(pctldev);
|
||||
if (ret) {
|
||||
pr_err("%s pin config ops lacks necessary functions\n",
|
||||
pctldesc->name);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register all the pins */
|
||||
pr_debug("try to register %d pins on %s...\n",
|
||||
pctldesc->npins, pctldesc->name);
|
||||
dev_dbg(dev, "try to register %d pins ...\n", pctldesc->npins);
|
||||
ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);
|
||||
if (ret) {
|
||||
pr_err("error during pin registration\n");
|
||||
dev_err(dev, "error during pin registration\n");
|
||||
pinctrl_free_pindescs(pctldev, pctldesc->pins,
|
||||
pctldesc->npins);
|
||||
goto out_err;
|
||||
@ -1313,8 +1454,15 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
|
||||
struct pinctrl_state *s =
|
||||
pinctrl_lookup_state_locked(pctldev->p,
|
||||
PINCTRL_STATE_DEFAULT);
|
||||
if (!IS_ERR(s))
|
||||
pinctrl_select_state_locked(pctldev->p, s);
|
||||
if (IS_ERR(s)) {
|
||||
dev_dbg(dev, "failed to lookup the default state\n");
|
||||
} else {
|
||||
ret = pinctrl_select_state_locked(pctldev->p, s);
|
||||
if (ret) {
|
||||
dev_err(dev,
|
||||
"failed to select default state\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&pinctrl_mutex);
|
||||
|
@ -52,12 +52,15 @@ struct pinctrl_dev {
|
||||
* @dev: the device using this pin control handle
|
||||
* @states: a list of states for this device
|
||||
* @state: the current state
|
||||
* @dt_maps: the mapping table chunks dynamically parsed from device tree for
|
||||
* this device, if any
|
||||
*/
|
||||
struct pinctrl {
|
||||
struct list_head node;
|
||||
struct device *dev;
|
||||
struct list_head states;
|
||||
struct pinctrl_state *state;
|
||||
struct list_head dt_maps;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -100,7 +103,8 @@ struct pinctrl_setting_configs {
|
||||
* struct pinctrl_setting - an individual mux or config setting
|
||||
* @node: list node for struct pinctrl_settings's @settings field
|
||||
* @type: the type of setting
|
||||
* @pctldev: pin control device handling to be programmed
|
||||
* @pctldev: pin control device handling to be programmed. Not used for
|
||||
* PIN_MAP_TYPE_DUMMY_STATE.
|
||||
* @data: Data specific to the setting type
|
||||
*/
|
||||
struct pinctrl_setting {
|
||||
@ -144,6 +148,7 @@ struct pin_desc {
|
||||
|
||||
struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
|
||||
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
|
||||
const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin);
|
||||
int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
|
||||
const char *pin_group);
|
||||
|
||||
@ -153,4 +158,9 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev,
|
||||
return radix_tree_lookup(&pctldev->pin_desc_tree, pin);
|
||||
}
|
||||
|
||||
int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
|
||||
bool dup, bool locked);
|
||||
void pinctrl_unregister_map(struct pinctrl_map const *map);
|
||||
|
||||
extern struct mutex pinctrl_mutex;
|
||||
extern struct list_head pinctrldev_list;
|
||||
|
249
drivers/pinctrl/devicetree.c
Normal file
249
drivers/pinctrl/devicetree.c
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Device tree integration for the pin control subsystem
|
||||
*
|
||||
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "devicetree.h"
|
||||
|
||||
/**
|
||||
* struct pinctrl_dt_map - mapping table chunk parsed from device tree
|
||||
* @node: list node for struct pinctrl's @dt_maps field
|
||||
* @pctldev: the pin controller that allocated this struct, and will free it
|
||||
* @maps: the mapping table entries
|
||||
*/
|
||||
struct pinctrl_dt_map {
|
||||
struct list_head node;
|
||||
struct pinctrl_dev *pctldev;
|
||||
struct pinctrl_map *map;
|
||||
unsigned num_maps;
|
||||
};
|
||||
|
||||
static void dt_free_map(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map, unsigned num_maps)
|
||||
{
|
||||
if (pctldev) {
|
||||
struct pinctrl_ops *ops = pctldev->desc->pctlops;
|
||||
ops->dt_free_map(pctldev, map, num_maps);
|
||||
} else {
|
||||
/* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */
|
||||
kfree(map);
|
||||
}
|
||||
}
|
||||
|
||||
void pinctrl_dt_free_maps(struct pinctrl *p)
|
||||
{
|
||||
struct pinctrl_dt_map *dt_map, *n1;
|
||||
|
||||
list_for_each_entry_safe(dt_map, n1, &p->dt_maps, node) {
|
||||
pinctrl_unregister_map(dt_map->map);
|
||||
list_del(&dt_map->node);
|
||||
dt_free_map(dt_map->pctldev, dt_map->map,
|
||||
dt_map->num_maps);
|
||||
kfree(dt_map);
|
||||
}
|
||||
|
||||
of_node_put(p->dev->of_node);
|
||||
}
|
||||
|
||||
static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
|
||||
struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map, unsigned num_maps)
|
||||
{
|
||||
int i;
|
||||
struct pinctrl_dt_map *dt_map;
|
||||
|
||||
/* Initialize common mapping table entry fields */
|
||||
for (i = 0; i < num_maps; i++) {
|
||||
map[i].dev_name = dev_name(p->dev);
|
||||
map[i].name = statename;
|
||||
if (pctldev)
|
||||
map[i].ctrl_dev_name = dev_name(pctldev->dev);
|
||||
}
|
||||
|
||||
/* Remember the converted mapping table entries */
|
||||
dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL);
|
||||
if (!dt_map) {
|
||||
dev_err(p->dev, "failed to alloc struct pinctrl_dt_map\n");
|
||||
dt_free_map(pctldev, map, num_maps);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dt_map->pctldev = pctldev;
|
||||
dt_map->map = map;
|
||||
dt_map->num_maps = num_maps;
|
||||
list_add_tail(&dt_map->node, &p->dt_maps);
|
||||
|
||||
return pinctrl_register_map(map, num_maps, false, true);
|
||||
}
|
||||
|
||||
static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np)
|
||||
{
|
||||
struct pinctrl_dev *pctldev;
|
||||
|
||||
list_for_each_entry(pctldev, &pinctrldev_list, node)
|
||||
if (pctldev->dev->of_node == np)
|
||||
return pctldev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
|
||||
struct device_node *np_config)
|
||||
{
|
||||
struct device_node *np_pctldev;
|
||||
struct pinctrl_dev *pctldev;
|
||||
struct pinctrl_ops *ops;
|
||||
int ret;
|
||||
struct pinctrl_map *map;
|
||||
unsigned num_maps;
|
||||
|
||||
/* Find the pin controller containing np_config */
|
||||
np_pctldev = of_node_get(np_config);
|
||||
for (;;) {
|
||||
np_pctldev = of_get_next_parent(np_pctldev);
|
||||
if (!np_pctldev || of_node_is_root(np_pctldev)) {
|
||||
dev_info(p->dev, "could not find pctldev for node %s, deferring probe\n",
|
||||
np_config->full_name);
|
||||
of_node_put(np_pctldev);
|
||||
/* OK let's just assume this will appear later then */
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
pctldev = find_pinctrl_by_of_node(np_pctldev);
|
||||
if (pctldev)
|
||||
break;
|
||||
}
|
||||
of_node_put(np_pctldev);
|
||||
|
||||
/*
|
||||
* Call pinctrl driver to parse device tree node, and
|
||||
* generate mapping table entries
|
||||
*/
|
||||
ops = pctldev->desc->pctlops;
|
||||
if (!ops->dt_node_to_map) {
|
||||
dev_err(p->dev, "pctldev %s doesn't support DT\n",
|
||||
dev_name(pctldev->dev));
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Stash the mapping table chunk away for later use */
|
||||
return dt_remember_or_free_map(p, statename, pctldev, map, num_maps);
|
||||
}
|
||||
|
||||
static int dt_remember_dummy_state(struct pinctrl *p, const char *statename)
|
||||
{
|
||||
struct pinctrl_map *map;
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map) {
|
||||
dev_err(p->dev, "failed to alloc struct pinctrl_map\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */
|
||||
map->type = PIN_MAP_TYPE_DUMMY_STATE;
|
||||
|
||||
return dt_remember_or_free_map(p, statename, NULL, map, 1);
|
||||
}
|
||||
|
||||
int pinctrl_dt_to_map(struct pinctrl *p)
|
||||
{
|
||||
struct device_node *np = p->dev->of_node;
|
||||
int state, ret;
|
||||
char *propname;
|
||||
struct property *prop;
|
||||
const char *statename;
|
||||
const __be32 *list;
|
||||
int size, config;
|
||||
phandle phandle;
|
||||
struct device_node *np_config;
|
||||
|
||||
/* CONFIG_OF enabled, p->dev not instantiated from DT */
|
||||
if (!np) {
|
||||
dev_dbg(p->dev, "no of_node; not parsing pinctrl DT\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We may store pointers to property names within the node */
|
||||
of_node_get(np);
|
||||
|
||||
/* For each defined state ID */
|
||||
for (state = 0; ; state++) {
|
||||
/* Retrieve the pinctrl-* property */
|
||||
propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
|
||||
prop = of_find_property(np, propname, &size);
|
||||
kfree(propname);
|
||||
if (!prop)
|
||||
break;
|
||||
list = prop->value;
|
||||
size /= sizeof(*list);
|
||||
|
||||
/* Determine whether pinctrl-names property names the state */
|
||||
ret = of_property_read_string_index(np, "pinctrl-names",
|
||||
state, &statename);
|
||||
/*
|
||||
* If not, statename is just the integer state ID. But rather
|
||||
* than dynamically allocate it and have to free it later,
|
||||
* just point part way into the property name for the string.
|
||||
*/
|
||||
if (ret < 0) {
|
||||
/* strlen("pinctrl-") == 8 */
|
||||
statename = prop->name + 8;
|
||||
}
|
||||
|
||||
/* For every referenced pin configuration node in it */
|
||||
for (config = 0; config < size; config++) {
|
||||
phandle = be32_to_cpup(list++);
|
||||
|
||||
/* Look up the pin configuration node */
|
||||
np_config = of_find_node_by_phandle(phandle);
|
||||
if (!np_config) {
|
||||
dev_err(p->dev,
|
||||
"prop %s index %i invalid phandle\n",
|
||||
prop->name, config);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Parse the node */
|
||||
ret = dt_to_map_one_config(p, statename, np_config);
|
||||
of_node_put(np_config);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* No entries in DT? Generate a dummy state table entry */
|
||||
if (!size) {
|
||||
ret = dt_remember_dummy_state(p, statename);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pinctrl_dt_free_maps(p);
|
||||
return ret;
|
||||
}
|
35
drivers/pinctrl/devicetree.h
Normal file
35
drivers/pinctrl/devicetree.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Internal interface to pinctrl device tree integration
|
||||
*
|
||||
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
void pinctrl_dt_free_maps(struct pinctrl *p);
|
||||
int pinctrl_dt_to_map(struct pinctrl *p);
|
||||
|
||||
#else
|
||||
|
||||
static inline int pinctrl_dt_to_map(struct pinctrl *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void pinctrl_dt_free_maps(struct pinctrl *p)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
@ -28,11 +28,17 @@ int pinconf_check_ops(struct pinctrl_dev *pctldev)
|
||||
const struct pinconf_ops *ops = pctldev->desc->confops;
|
||||
|
||||
/* We must be able to read out pin status */
|
||||
if (!ops->pin_config_get && !ops->pin_config_group_get)
|
||||
if (!ops->pin_config_get && !ops->pin_config_group_get) {
|
||||
dev_err(pctldev->dev,
|
||||
"pinconf must be able to read out pin status\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* We have to be able to config the pins in SOME way */
|
||||
if (!ops->pin_config_set && !ops->pin_config_group_set)
|
||||
if (!ops->pin_config_set && !ops->pin_config_group_set) {
|
||||
dev_err(pctldev->dev,
|
||||
"pinconf has to be able to set a pins config\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -44,9 +50,9 @@ int pinconf_validate_map(struct pinctrl_map const *map, int i)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (map->data.configs.num_configs &&
|
||||
if (!map->data.configs.num_configs ||
|
||||
!map->data.configs.configs) {
|
||||
pr_err("failed to register map %s (%d): no configs ptr given\n",
|
||||
pr_err("failed to register map %s (%d): no configs given\n",
|
||||
map->name, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -379,8 +385,16 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting)
|
||||
|
||||
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
|
||||
{
|
||||
struct pinctrl_dev *pctldev;
|
||||
const struct pinconf_ops *confops;
|
||||
int i;
|
||||
|
||||
pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
|
||||
if (pctldev)
|
||||
confops = pctldev->desc->confops;
|
||||
else
|
||||
confops = NULL;
|
||||
|
||||
switch (map->type) {
|
||||
case PIN_MAP_TYPE_CONFIGS_PIN:
|
||||
seq_printf(s, "pin ");
|
||||
@ -394,8 +408,15 @@ void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
|
||||
|
||||
seq_printf(s, "%s\n", map->data.configs.group_or_pin);
|
||||
|
||||
for (i = 0; i < map->data.configs.num_configs; i++)
|
||||
seq_printf(s, "config %08lx\n", map->data.configs.configs[i]);
|
||||
for (i = 0; i < map->data.configs.num_configs; i++) {
|
||||
seq_printf(s, "config ");
|
||||
if (confops && confops->pin_config_config_dbg_show)
|
||||
confops->pin_config_config_dbg_show(pctldev, s,
|
||||
map->data.configs.configs[i]);
|
||||
else
|
||||
seq_printf(s, "%08lx", map->data.configs.configs[i]);
|
||||
seq_printf(s, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void pinconf_show_setting(struct seq_file *s,
|
||||
@ -403,6 +424,7 @@ void pinconf_show_setting(struct seq_file *s,
|
||||
{
|
||||
struct pinctrl_dev *pctldev = setting->pctldev;
|
||||
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
|
||||
const struct pinconf_ops *confops = pctldev->desc->confops;
|
||||
struct pin_desc *desc;
|
||||
int i;
|
||||
|
||||
@ -428,8 +450,15 @@ void pinconf_show_setting(struct seq_file *s,
|
||||
* FIXME: We should really get the pin controler to dump the config
|
||||
* values, so they can be decoded to something meaningful.
|
||||
*/
|
||||
for (i = 0; i < setting->data.configs.num_configs; i++)
|
||||
seq_printf(s, " %08lx", setting->data.configs.configs[i]);
|
||||
for (i = 0; i < setting->data.configs.num_configs; i++) {
|
||||
seq_printf(s, " ");
|
||||
if (confops && confops->pin_config_config_dbg_show)
|
||||
confops->pin_config_config_dbg_show(pctldev, s,
|
||||
setting->data.configs.configs[i]);
|
||||
else
|
||||
seq_printf(s, "%08lx",
|
||||
setting->data.configs.configs[i]);
|
||||
}
|
||||
|
||||
seq_printf(s, "\n");
|
||||
}
|
||||
@ -448,10 +477,14 @@ static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
|
||||
static int pinconf_pins_show(struct seq_file *s, void *what)
|
||||
{
|
||||
struct pinctrl_dev *pctldev = s->private;
|
||||
const struct pinconf_ops *ops = pctldev->desc->confops;
|
||||
unsigned i, pin;
|
||||
|
||||
if (!ops || !ops->pin_config_get)
|
||||
return 0;
|
||||
|
||||
seq_puts(s, "Pin config settings per pin\n");
|
||||
seq_puts(s, "Format: pin (name): pinmux setting array\n");
|
||||
seq_puts(s, "Format: pin (name): configs\n");
|
||||
|
||||
mutex_lock(&pinctrl_mutex);
|
||||
|
||||
@ -495,17 +528,18 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
|
||||
struct pinctrl_dev *pctldev = s->private;
|
||||
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
|
||||
const struct pinconf_ops *ops = pctldev->desc->confops;
|
||||
unsigned ngroups = pctlops->get_groups_count(pctldev);
|
||||
unsigned selector = 0;
|
||||
|
||||
if (!ops || !ops->pin_config_group_get)
|
||||
return 0;
|
||||
|
||||
seq_puts(s, "Pin config settings per pin group\n");
|
||||
seq_puts(s, "Format: group (name): pinmux setting array\n");
|
||||
seq_puts(s, "Format: group (name): configs\n");
|
||||
|
||||
mutex_lock(&pinctrl_mutex);
|
||||
|
||||
while (pctlops->list_groups(pctldev, selector) >= 0) {
|
||||
while (selector < ngroups) {
|
||||
const char *gname = pctlops->get_group_name(pctldev, selector);
|
||||
|
||||
seq_printf(s, "%u (%s):", selector, gname);
|
||||
|
@ -19,11 +19,6 @@ int pinconf_map_to_setting(struct pinctrl_map const *map,
|
||||
struct pinctrl_setting *setting);
|
||||
void pinconf_free_setting(struct pinctrl_setting const *setting);
|
||||
int pinconf_apply_setting(struct pinctrl_setting const *setting);
|
||||
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map);
|
||||
void pinconf_show_setting(struct seq_file *s,
|
||||
struct pinctrl_setting const *setting);
|
||||
void pinconf_init_device_debugfs(struct dentry *devroot,
|
||||
struct pinctrl_dev *pctldev);
|
||||
|
||||
/*
|
||||
* You will only be interested in these if you're using PINCONF
|
||||
@ -61,6 +56,18 @@ static inline int pinconf_apply_setting(struct pinctrl_setting const *setting)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PINCONF) && defined(CONFIG_DEBUG_FS)
|
||||
|
||||
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map);
|
||||
void pinconf_show_setting(struct seq_file *s,
|
||||
struct pinctrl_setting const *setting);
|
||||
void pinconf_init_device_debugfs(struct dentry *devroot,
|
||||
struct pinctrl_dev *pctldev);
|
||||
|
||||
#else
|
||||
|
||||
static inline void pinconf_show_map(struct seq_file *s,
|
||||
struct pinctrl_map const *map)
|
||||
{
|
||||
|
@ -174,7 +174,7 @@ struct u300_gpio_confdata {
|
||||
|
||||
|
||||
/* Initial configuration */
|
||||
static const struct __initdata u300_gpio_confdata
|
||||
static const struct __initconst u300_gpio_confdata
|
||||
bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
|
||||
/* Port 0, pins 0-7 */
|
||||
{
|
||||
@ -255,7 +255,7 @@ bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct __initdata u300_gpio_confdata
|
||||
static const struct __initconst u300_gpio_confdata
|
||||
bs365_gpio_config[BS365_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
|
||||
/* Port 0, pins 0-7 */
|
||||
{
|
||||
|
620
drivers/pinctrl/pinctrl-imx.c
Normal file
620
drivers/pinctrl/pinctrl-imx.c
Normal file
@ -0,0 +1,620 @@
|
||||
/*
|
||||
* Core driver for the imx pin controller
|
||||
*
|
||||
* Copyright (C) 2012 Freescale Semiconductor, Inc.
|
||||
* Copyright (C) 2012 Linaro Ltd.
|
||||
*
|
||||
* Author: Dong Aisheng <dong.aisheng@linaro.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "pinctrl-imx.h"
|
||||
|
||||
#define IMX_PMX_DUMP(info, p, m, c, n) \
|
||||
{ \
|
||||
int i, j; \
|
||||
printk("Format: Pin Mux Config\n"); \
|
||||
for (i = 0; i < n; i++) { \
|
||||
j = p[i]; \
|
||||
printk("%s %d 0x%lx\n", \
|
||||
info->pins[j].name, \
|
||||
m[i], c[i]); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* The bits in CONFIG cell defined in binding doc*/
|
||||
#define IMX_NO_PAD_CTL 0x80000000 /* no pin config need */
|
||||
#define IMX_PAD_SION 0x40000000 /* set SION */
|
||||
|
||||
/**
|
||||
* @dev: a pointer back to containing device
|
||||
* @base: the offset to the controller in virtual memory
|
||||
*/
|
||||
struct imx_pinctrl {
|
||||
struct device *dev;
|
||||
struct pinctrl_dev *pctl;
|
||||
void __iomem *base;
|
||||
const struct imx_pinctrl_soc_info *info;
|
||||
};
|
||||
|
||||
static const struct imx_pin_reg *imx_find_pin_reg(
|
||||
const struct imx_pinctrl_soc_info *info,
|
||||
unsigned pin, bool is_mux, unsigned mux)
|
||||
{
|
||||
const struct imx_pin_reg *pin_reg = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info->npin_regs; i++) {
|
||||
pin_reg = &info->pin_regs[i];
|
||||
if (pin_reg->pid != pin)
|
||||
continue;
|
||||
if (!is_mux)
|
||||
break;
|
||||
else if (pin_reg->mux_mode == (mux & IMX_MUX_MASK))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pin_reg) {
|
||||
dev_err(info->dev, "Pin(%s): unable to find pin reg map\n",
|
||||
info->pins[pin].name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pin_reg;
|
||||
}
|
||||
|
||||
static const inline struct imx_pin_group *imx_pinctrl_find_group_by_name(
|
||||
const struct imx_pinctrl_soc_info *info,
|
||||
const char *name)
|
||||
{
|
||||
const struct imx_pin_group *grp = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info->ngroups; i++) {
|
||||
if (!strcmp(info->groups[i].name, name)) {
|
||||
grp = &info->groups[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
static int imx_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
|
||||
return info->ngroups;
|
||||
}
|
||||
|
||||
static const char *imx_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
|
||||
return info->groups[selector].name;
|
||||
}
|
||||
|
||||
static int imx_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
const unsigned **pins,
|
||||
unsigned *npins)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
|
||||
if (selector >= info->ngroups)
|
||||
return -EINVAL;
|
||||
|
||||
*pins = info->groups[selector].pins;
|
||||
*npins = info->groups[selector].npins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||
unsigned offset)
|
||||
{
|
||||
seq_printf(s, "%s", dev_name(pctldev->dev));
|
||||
}
|
||||
|
||||
static int imx_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **map, unsigned *num_maps)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
const struct imx_pin_group *grp;
|
||||
struct pinctrl_map *new_map;
|
||||
struct device_node *parent;
|
||||
int map_num = 1;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* first find the group of this node and check if we need create
|
||||
* config maps for pins
|
||||
*/
|
||||
grp = imx_pinctrl_find_group_by_name(info, np->name);
|
||||
if (!grp) {
|
||||
dev_err(info->dev, "unable to find group for node %s\n",
|
||||
np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < grp->npins; i++) {
|
||||
if (!(grp->configs[i] & IMX_NO_PAD_CTL))
|
||||
map_num++;
|
||||
}
|
||||
|
||||
new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL);
|
||||
if (!new_map)
|
||||
return -ENOMEM;
|
||||
|
||||
*map = new_map;
|
||||
*num_maps = map_num;
|
||||
|
||||
/* create mux map */
|
||||
parent = of_get_parent(np);
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
|
||||
new_map[0].data.mux.function = parent->name;
|
||||
new_map[0].data.mux.group = np->name;
|
||||
of_node_put(parent);
|
||||
|
||||
/* create config map */
|
||||
new_map++;
|
||||
for (i = 0; i < grp->npins; i++) {
|
||||
if (!(grp->configs[i] & IMX_NO_PAD_CTL)) {
|
||||
new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
|
||||
new_map[i].data.configs.group_or_pin =
|
||||
pin_get_name(pctldev, grp->pins[i]);
|
||||
new_map[i].data.configs.configs = &grp->configs[i];
|
||||
new_map[i].data.configs.num_configs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
|
||||
new_map->data.mux.function, new_map->data.mux.group, map_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imx_dt_free_map(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map, unsigned num_maps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_maps; i++)
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static struct pinctrl_ops imx_pctrl_ops = {
|
||||
.get_groups_count = imx_get_groups_count,
|
||||
.get_group_name = imx_get_group_name,
|
||||
.get_group_pins = imx_get_group_pins,
|
||||
.pin_dbg_show = imx_pin_dbg_show,
|
||||
.dt_node_to_map = imx_dt_node_to_map,
|
||||
.dt_free_map = imx_dt_free_map,
|
||||
|
||||
};
|
||||
|
||||
static int imx_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
const struct imx_pin_reg *pin_reg;
|
||||
const unsigned *pins, *mux;
|
||||
unsigned int npins, pin_id;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Configure the mux mode for each pin in the group for a specific
|
||||
* function.
|
||||
*/
|
||||
pins = info->groups[group].pins;
|
||||
npins = info->groups[group].npins;
|
||||
mux = info->groups[group].mux_mode;
|
||||
|
||||
WARN_ON(!pins || !npins || !mux);
|
||||
|
||||
dev_dbg(ipctl->dev, "enable function %s group %s\n",
|
||||
info->functions[selector].name, info->groups[group].name);
|
||||
|
||||
for (i = 0; i < npins; i++) {
|
||||
pin_id = pins[i];
|
||||
|
||||
pin_reg = imx_find_pin_reg(info, pin_id, 1, mux[i]);
|
||||
if (!pin_reg)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pin_reg->mux_reg) {
|
||||
dev_err(ipctl->dev, "Pin(%s) does not support mux function\n",
|
||||
info->pins[pin_id].name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(mux[i], ipctl->base + pin_reg->mux_reg);
|
||||
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
|
||||
pin_reg->mux_reg, mux[i]);
|
||||
|
||||
/* some pins also need select input setting, set it if found */
|
||||
if (pin_reg->input_reg) {
|
||||
writel(pin_reg->input_val, ipctl->base + pin_reg->input_reg);
|
||||
dev_dbg(ipctl->dev,
|
||||
"==>select_input: offset 0x%x val 0x%x\n",
|
||||
pin_reg->input_reg, pin_reg->input_val);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
|
||||
return info->nfunctions;
|
||||
}
|
||||
|
||||
static const char *imx_pmx_get_func_name(struct pinctrl_dev *pctldev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
|
||||
return info->functions[selector].name;
|
||||
}
|
||||
|
||||
static int imx_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
const char * const **groups,
|
||||
unsigned * const num_groups)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
|
||||
*groups = info->functions[selector].groups;
|
||||
*num_groups = info->functions[selector].num_groups;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pinmux_ops imx_pmx_ops = {
|
||||
.get_functions_count = imx_pmx_get_funcs_count,
|
||||
.get_function_name = imx_pmx_get_func_name,
|
||||
.get_function_groups = imx_pmx_get_groups,
|
||||
.enable = imx_pmx_enable,
|
||||
};
|
||||
|
||||
static int imx_pinconf_get(struct pinctrl_dev *pctldev,
|
||||
unsigned pin_id, unsigned long *config)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
const struct imx_pin_reg *pin_reg;
|
||||
|
||||
pin_reg = imx_find_pin_reg(info, pin_id, 0, 0);
|
||||
if (!pin_reg)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pin_reg->conf_reg) {
|
||||
dev_err(info->dev, "Pin(%s) does not support config function\n",
|
||||
info->pins[pin_id].name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*config = readl(ipctl->base + pin_reg->conf_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_pinconf_set(struct pinctrl_dev *pctldev,
|
||||
unsigned pin_id, unsigned long config)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
const struct imx_pin_reg *pin_reg;
|
||||
|
||||
pin_reg = imx_find_pin_reg(info, pin_id, 0, 0);
|
||||
if (!pin_reg)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pin_reg->conf_reg) {
|
||||
dev_err(info->dev, "Pin(%s) does not support config function\n",
|
||||
info->pins[pin_id].name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(ipctl->dev, "pinconf set pin %s\n",
|
||||
info->pins[pin_id].name);
|
||||
|
||||
writel(config, ipctl->base + pin_reg->conf_reg);
|
||||
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
|
||||
pin_reg->conf_reg, config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s, unsigned pin_id)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
const struct imx_pin_reg *pin_reg;
|
||||
unsigned long config;
|
||||
|
||||
pin_reg = imx_find_pin_reg(info, pin_id, 0, 0);
|
||||
if (!pin_reg || !pin_reg->conf_reg) {
|
||||
seq_printf(s, "N/A");
|
||||
return;
|
||||
}
|
||||
|
||||
config = readl(ipctl->base + pin_reg->conf_reg);
|
||||
seq_printf(s, "0x%lx", config);
|
||||
}
|
||||
|
||||
static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s, unsigned group)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct imx_pinctrl_soc_info *info = ipctl->info;
|
||||
struct imx_pin_group *grp;
|
||||
unsigned long config;
|
||||
const char *name;
|
||||
int i, ret;
|
||||
|
||||
if (group > info->ngroups)
|
||||
return;
|
||||
|
||||
seq_printf(s, "\n");
|
||||
grp = &info->groups[group];
|
||||
for (i = 0; i < grp->npins; i++) {
|
||||
name = pin_get_name(pctldev, grp->pins[i]);
|
||||
ret = imx_pinconf_get(pctldev, grp->pins[i], &config);
|
||||
if (ret)
|
||||
return;
|
||||
seq_printf(s, "%s: 0x%lx", name, config);
|
||||
}
|
||||
}
|
||||
|
||||
struct pinconf_ops imx_pinconf_ops = {
|
||||
.pin_config_get = imx_pinconf_get,
|
||||
.pin_config_set = imx_pinconf_set,
|
||||
.pin_config_dbg_show = imx_pinconf_dbg_show,
|
||||
.pin_config_group_dbg_show = imx_pinconf_group_dbg_show,
|
||||
};
|
||||
|
||||
static struct pinctrl_desc imx_pinctrl_desc = {
|
||||
.pctlops = &imx_pctrl_ops,
|
||||
.pmxops = &imx_pmx_ops,
|
||||
.confops = &imx_pinconf_ops,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
/* decode pin id and mux from pin function id got from device tree*/
|
||||
static int imx_pinctrl_get_pin_id_and_mux(const struct imx_pinctrl_soc_info *info,
|
||||
unsigned int pin_func_id, unsigned int *pin_id,
|
||||
unsigned int *mux)
|
||||
{
|
||||
if (pin_func_id > info->npin_regs)
|
||||
return -EINVAL;
|
||||
|
||||
*pin_id = info->pin_regs[pin_func_id].pid;
|
||||
*mux = info->pin_regs[pin_func_id].mux_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit imx_pinctrl_parse_groups(struct device_node *np,
|
||||
struct imx_pin_group *grp,
|
||||
struct imx_pinctrl_soc_info *info,
|
||||
u32 index)
|
||||
{
|
||||
unsigned int pin_func_id;
|
||||
int ret, size;
|
||||
const const __be32 *list;
|
||||
int i, j;
|
||||
u32 config;
|
||||
|
||||
dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
|
||||
|
||||
/* Initialise group */
|
||||
grp->name = np->name;
|
||||
|
||||
/*
|
||||
* the binding format is fsl,pins = <PIN_FUNC_ID CONFIG ...>,
|
||||
* do sanity check and calculate pins number
|
||||
*/
|
||||
list = of_get_property(np, "fsl,pins", &size);
|
||||
/* we do not check return since it's safe node passed down */
|
||||
size /= sizeof(*list);
|
||||
if (!size || size % 2) {
|
||||
dev_err(info->dev, "wrong pins number or pins and configs should be pairs\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
grp->npins = size / 2;
|
||||
grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
|
||||
GFP_KERNEL);
|
||||
grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
|
||||
GFP_KERNEL);
|
||||
grp->configs = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned long),
|
||||
GFP_KERNEL);
|
||||
for (i = 0, j = 0; i < size; i += 2, j++) {
|
||||
pin_func_id = be32_to_cpu(*list++);
|
||||
ret = imx_pinctrl_get_pin_id_and_mux(info, pin_func_id,
|
||||
&grp->pins[j], &grp->mux_mode[j]);
|
||||
if (ret) {
|
||||
dev_err(info->dev, "get invalid pin function id\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* SION bit is in mux register */
|
||||
config = be32_to_cpu(*list++);
|
||||
if (config & IMX_PAD_SION)
|
||||
grp->mux_mode[j] |= IOMUXC_CONFIG_SION;
|
||||
grp->configs[j] = config & ~IMX_PAD_SION;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
IMX_PMX_DUMP(info, grp->pins, grp->mux_mode, grp->configs, grp->npins);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit imx_pinctrl_parse_functions(struct device_node *np,
|
||||
struct imx_pinctrl_soc_info *info, u32 index)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct imx_pmx_func *func;
|
||||
struct imx_pin_group *grp;
|
||||
int ret;
|
||||
static u32 grp_index;
|
||||
u32 i = 0;
|
||||
|
||||
dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
|
||||
|
||||
func = &info->functions[index];
|
||||
|
||||
/* Initialise function */
|
||||
func->name = np->name;
|
||||
func->num_groups = of_get_child_count(np);
|
||||
if (func->num_groups <= 0) {
|
||||
dev_err(info->dev, "no groups defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
func->groups = devm_kzalloc(info->dev,
|
||||
func->num_groups * sizeof(char *), GFP_KERNEL);
|
||||
|
||||
for_each_child_of_node(np, child) {
|
||||
func->groups[i] = child->name;
|
||||
grp = &info->groups[grp_index++];
|
||||
ret = imx_pinctrl_parse_groups(child, grp, info, i++);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit imx_pinctrl_probe_dt(struct platform_device *pdev,
|
||||
struct imx_pinctrl_soc_info *info)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *child;
|
||||
int ret;
|
||||
u32 nfuncs = 0;
|
||||
u32 i = 0;
|
||||
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
nfuncs = of_get_child_count(np);
|
||||
if (nfuncs <= 0) {
|
||||
dev_err(&pdev->dev, "no functions defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
info->nfunctions = nfuncs;
|
||||
info->functions = devm_kzalloc(&pdev->dev, nfuncs * sizeof(struct imx_pmx_func),
|
||||
GFP_KERNEL);
|
||||
if (!info->functions)
|
||||
return -ENOMEM;
|
||||
|
||||
info->ngroups = 0;
|
||||
for_each_child_of_node(np, child)
|
||||
info->ngroups += of_get_child_count(child);
|
||||
info->groups = devm_kzalloc(&pdev->dev, info->ngroups * sizeof(struct imx_pin_group),
|
||||
GFP_KERNEL);
|
||||
if (!info->groups)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_child_of_node(np, child) {
|
||||
ret = imx_pinctrl_parse_functions(child, info, i++);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to parse function\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __devinit imx_pinctrl_probe(struct platform_device *pdev,
|
||||
struct imx_pinctrl_soc_info *info)
|
||||
{
|
||||
struct imx_pinctrl *ipctl;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
if (!info || !info->pins || !info->npins
|
||||
|| !info->pin_regs || !info->npin_regs) {
|
||||
dev_err(&pdev->dev, "wrong pinctrl info\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
info->dev = &pdev->dev;
|
||||
|
||||
/* Create state holders etc for this driver */
|
||||
ipctl = devm_kzalloc(&pdev->dev, sizeof(*ipctl), GFP_KERNEL);
|
||||
if (!ipctl)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENOENT;
|
||||
|
||||
ipctl->base = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!ipctl->base)
|
||||
return -EBUSY;
|
||||
|
||||
imx_pinctrl_desc.name = dev_name(&pdev->dev);
|
||||
imx_pinctrl_desc.pins = info->pins;
|
||||
imx_pinctrl_desc.npins = info->npins;
|
||||
|
||||
ret = imx_pinctrl_probe_dt(pdev, info);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "fail to probe dt properties\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ipctl->info = info;
|
||||
ipctl->dev = info->dev;
|
||||
platform_set_drvdata(pdev, ipctl);
|
||||
ipctl->pctl = pinctrl_register(&imx_pinctrl_desc, &pdev->dev, ipctl);
|
||||
if (!ipctl->pctl) {
|
||||
dev_err(&pdev->dev, "could not register IMX pinctrl driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "initialized IMX pinctrl driver\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __devexit imx_pinctrl_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct imx_pinctrl *ipctl = platform_get_drvdata(pdev);
|
||||
|
||||
pinctrl_unregister(ipctl->pctl);
|
||||
|
||||
return 0;
|
||||
}
|
106
drivers/pinctrl/pinctrl-imx.h
Normal file
106
drivers/pinctrl/pinctrl-imx.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* IMX pinmux core definitions
|
||||
*
|
||||
* Copyright (C) 2012 Freescale Semiconductor, Inc.
|
||||
* Copyright (C) 2012 Linaro Ltd.
|
||||
*
|
||||
* Author: Dong Aisheng <dong.aisheng@linaro.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_PINCTRL_IMX_H
|
||||
#define __DRIVERS_PINCTRL_IMX_H
|
||||
|
||||
struct platform_device;
|
||||
|
||||
/**
|
||||
* struct imx_pin_group - describes an IMX pin group
|
||||
* @name: the name of this specific pin group
|
||||
* @pins: an array of discrete physical pins used in this group, taken
|
||||
* from the driver-local pin enumeration space
|
||||
* @npins: the number of pins in this group array, i.e. the number of
|
||||
* elements in .pins so we can iterate over that array
|
||||
* @mux_mode: the mux mode for each pin in this group. The size of this
|
||||
* array is the same as pins.
|
||||
* @configs: the config for each pin in this group. The size of this
|
||||
* array is the same as pins.
|
||||
*/
|
||||
struct imx_pin_group {
|
||||
const char *name;
|
||||
unsigned int *pins;
|
||||
unsigned npins;
|
||||
unsigned int *mux_mode;
|
||||
unsigned long *configs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct imx_pmx_func - describes IMX pinmux functions
|
||||
* @name: the name of this specific function
|
||||
* @groups: corresponding pin groups
|
||||
* @num_groups: the number of groups
|
||||
*/
|
||||
struct imx_pmx_func {
|
||||
const char *name;
|
||||
const char **groups;
|
||||
unsigned num_groups;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct imx_pin_reg - describe a pin reg map
|
||||
* The last 3 members are used for select input setting
|
||||
* @pid: pin id
|
||||
* @mux_reg: mux register offset
|
||||
* @conf_reg: config register offset
|
||||
* @mux_mode: mux mode
|
||||
* @input_reg: select input register offset for this mux if any
|
||||
* 0 if no select input setting needed.
|
||||
* @input_val: the value set to select input register
|
||||
*/
|
||||
struct imx_pin_reg {
|
||||
u16 pid;
|
||||
u16 mux_reg;
|
||||
u16 conf_reg;
|
||||
u8 mux_mode;
|
||||
u16 input_reg;
|
||||
u8 input_val;
|
||||
};
|
||||
|
||||
struct imx_pinctrl_soc_info {
|
||||
struct device *dev;
|
||||
const struct pinctrl_pin_desc *pins;
|
||||
unsigned int npins;
|
||||
const struct imx_pin_reg *pin_regs;
|
||||
unsigned int npin_regs;
|
||||
struct imx_pin_group *groups;
|
||||
unsigned int ngroups;
|
||||
struct imx_pmx_func *functions;
|
||||
unsigned int nfunctions;
|
||||
};
|
||||
|
||||
#define NO_MUX 0x0
|
||||
#define NO_PAD 0x0
|
||||
|
||||
#define IMX_PIN_REG(id, conf, mux, mode, input, val) \
|
||||
{ \
|
||||
.pid = id, \
|
||||
.conf_reg = conf, \
|
||||
.mux_reg = mux, \
|
||||
.mux_mode = mode, \
|
||||
.input_reg = input, \
|
||||
.input_val = val, \
|
||||
}
|
||||
|
||||
#define IMX_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)
|
||||
|
||||
#define PAD_CTL_MASK(len) ((1 << len) - 1)
|
||||
#define IMX_MUX_MASK 0x7
|
||||
#define IOMUXC_CONFIG_SION (0x1 << 4)
|
||||
|
||||
int imx_pinctrl_probe(struct platform_device *pdev,
|
||||
struct imx_pinctrl_soc_info *info);
|
||||
int imx_pinctrl_remove(struct platform_device *pdev);
|
||||
#endif /* __DRIVERS_PINCTRL_IMX_H */
|
305
drivers/pinctrl/pinctrl-imx23.c
Normal file
305
drivers/pinctrl/pinctrl-imx23.c
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include "pinctrl-mxs.h"
|
||||
|
||||
enum imx23_pin_enum {
|
||||
GPMI_D00 = PINID(0, 0),
|
||||
GPMI_D01 = PINID(0, 1),
|
||||
GPMI_D02 = PINID(0, 2),
|
||||
GPMI_D03 = PINID(0, 3),
|
||||
GPMI_D04 = PINID(0, 4),
|
||||
GPMI_D05 = PINID(0, 5),
|
||||
GPMI_D06 = PINID(0, 6),
|
||||
GPMI_D07 = PINID(0, 7),
|
||||
GPMI_D08 = PINID(0, 8),
|
||||
GPMI_D09 = PINID(0, 9),
|
||||
GPMI_D10 = PINID(0, 10),
|
||||
GPMI_D11 = PINID(0, 11),
|
||||
GPMI_D12 = PINID(0, 12),
|
||||
GPMI_D13 = PINID(0, 13),
|
||||
GPMI_D14 = PINID(0, 14),
|
||||
GPMI_D15 = PINID(0, 15),
|
||||
GPMI_CLE = PINID(0, 16),
|
||||
GPMI_ALE = PINID(0, 17),
|
||||
GPMI_CE2N = PINID(0, 18),
|
||||
GPMI_RDY0 = PINID(0, 19),
|
||||
GPMI_RDY1 = PINID(0, 20),
|
||||
GPMI_RDY2 = PINID(0, 21),
|
||||
GPMI_RDY3 = PINID(0, 22),
|
||||
GPMI_WPN = PINID(0, 23),
|
||||
GPMI_WRN = PINID(0, 24),
|
||||
GPMI_RDN = PINID(0, 25),
|
||||
AUART1_CTS = PINID(0, 26),
|
||||
AUART1_RTS = PINID(0, 27),
|
||||
AUART1_RX = PINID(0, 28),
|
||||
AUART1_TX = PINID(0, 29),
|
||||
I2C_SCL = PINID(0, 30),
|
||||
I2C_SDA = PINID(0, 31),
|
||||
LCD_D00 = PINID(1, 0),
|
||||
LCD_D01 = PINID(1, 1),
|
||||
LCD_D02 = PINID(1, 2),
|
||||
LCD_D03 = PINID(1, 3),
|
||||
LCD_D04 = PINID(1, 4),
|
||||
LCD_D05 = PINID(1, 5),
|
||||
LCD_D06 = PINID(1, 6),
|
||||
LCD_D07 = PINID(1, 7),
|
||||
LCD_D08 = PINID(1, 8),
|
||||
LCD_D09 = PINID(1, 9),
|
||||
LCD_D10 = PINID(1, 10),
|
||||
LCD_D11 = PINID(1, 11),
|
||||
LCD_D12 = PINID(1, 12),
|
||||
LCD_D13 = PINID(1, 13),
|
||||
LCD_D14 = PINID(1, 14),
|
||||
LCD_D15 = PINID(1, 15),
|
||||
LCD_D16 = PINID(1, 16),
|
||||
LCD_D17 = PINID(1, 17),
|
||||
LCD_RESET = PINID(1, 18),
|
||||
LCD_RS = PINID(1, 19),
|
||||
LCD_WR = PINID(1, 20),
|
||||
LCD_CS = PINID(1, 21),
|
||||
LCD_DOTCK = PINID(1, 22),
|
||||
LCD_ENABLE = PINID(1, 23),
|
||||
LCD_HSYNC = PINID(1, 24),
|
||||
LCD_VSYNC = PINID(1, 25),
|
||||
PWM0 = PINID(1, 26),
|
||||
PWM1 = PINID(1, 27),
|
||||
PWM2 = PINID(1, 28),
|
||||
PWM3 = PINID(1, 29),
|
||||
PWM4 = PINID(1, 30),
|
||||
SSP1_CMD = PINID(2, 0),
|
||||
SSP1_DETECT = PINID(2, 1),
|
||||
SSP1_DATA0 = PINID(2, 2),
|
||||
SSP1_DATA1 = PINID(2, 3),
|
||||
SSP1_DATA2 = PINID(2, 4),
|
||||
SSP1_DATA3 = PINID(2, 5),
|
||||
SSP1_SCK = PINID(2, 6),
|
||||
ROTARYA = PINID(2, 7),
|
||||
ROTARYB = PINID(2, 8),
|
||||
EMI_A00 = PINID(2, 9),
|
||||
EMI_A01 = PINID(2, 10),
|
||||
EMI_A02 = PINID(2, 11),
|
||||
EMI_A03 = PINID(2, 12),
|
||||
EMI_A04 = PINID(2, 13),
|
||||
EMI_A05 = PINID(2, 14),
|
||||
EMI_A06 = PINID(2, 15),
|
||||
EMI_A07 = PINID(2, 16),
|
||||
EMI_A08 = PINID(2, 17),
|
||||
EMI_A09 = PINID(2, 18),
|
||||
EMI_A10 = PINID(2, 19),
|
||||
EMI_A11 = PINID(2, 20),
|
||||
EMI_A12 = PINID(2, 21),
|
||||
EMI_BA0 = PINID(2, 22),
|
||||
EMI_BA1 = PINID(2, 23),
|
||||
EMI_CASN = PINID(2, 24),
|
||||
EMI_CE0N = PINID(2, 25),
|
||||
EMI_CE1N = PINID(2, 26),
|
||||
GPMI_CE1N = PINID(2, 27),
|
||||
GPMI_CE0N = PINID(2, 28),
|
||||
EMI_CKE = PINID(2, 29),
|
||||
EMI_RASN = PINID(2, 30),
|
||||
EMI_WEN = PINID(2, 31),
|
||||
EMI_D00 = PINID(3, 0),
|
||||
EMI_D01 = PINID(3, 1),
|
||||
EMI_D02 = PINID(3, 2),
|
||||
EMI_D03 = PINID(3, 3),
|
||||
EMI_D04 = PINID(3, 4),
|
||||
EMI_D05 = PINID(3, 5),
|
||||
EMI_D06 = PINID(3, 6),
|
||||
EMI_D07 = PINID(3, 7),
|
||||
EMI_D08 = PINID(3, 8),
|
||||
EMI_D09 = PINID(3, 9),
|
||||
EMI_D10 = PINID(3, 10),
|
||||
EMI_D11 = PINID(3, 11),
|
||||
EMI_D12 = PINID(3, 12),
|
||||
EMI_D13 = PINID(3, 13),
|
||||
EMI_D14 = PINID(3, 14),
|
||||
EMI_D15 = PINID(3, 15),
|
||||
EMI_DQM0 = PINID(3, 16),
|
||||
EMI_DQM1 = PINID(3, 17),
|
||||
EMI_DQS0 = PINID(3, 18),
|
||||
EMI_DQS1 = PINID(3, 19),
|
||||
EMI_CLK = PINID(3, 20),
|
||||
EMI_CLKN = PINID(3, 21),
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc imx23_pins[] = {
|
||||
MXS_PINCTRL_PIN(GPMI_D00),
|
||||
MXS_PINCTRL_PIN(GPMI_D01),
|
||||
MXS_PINCTRL_PIN(GPMI_D02),
|
||||
MXS_PINCTRL_PIN(GPMI_D03),
|
||||
MXS_PINCTRL_PIN(GPMI_D04),
|
||||
MXS_PINCTRL_PIN(GPMI_D05),
|
||||
MXS_PINCTRL_PIN(GPMI_D06),
|
||||
MXS_PINCTRL_PIN(GPMI_D07),
|
||||
MXS_PINCTRL_PIN(GPMI_D08),
|
||||
MXS_PINCTRL_PIN(GPMI_D09),
|
||||
MXS_PINCTRL_PIN(GPMI_D10),
|
||||
MXS_PINCTRL_PIN(GPMI_D11),
|
||||
MXS_PINCTRL_PIN(GPMI_D12),
|
||||
MXS_PINCTRL_PIN(GPMI_D13),
|
||||
MXS_PINCTRL_PIN(GPMI_D14),
|
||||
MXS_PINCTRL_PIN(GPMI_D15),
|
||||
MXS_PINCTRL_PIN(GPMI_CLE),
|
||||
MXS_PINCTRL_PIN(GPMI_ALE),
|
||||
MXS_PINCTRL_PIN(GPMI_CE2N),
|
||||
MXS_PINCTRL_PIN(GPMI_RDY0),
|
||||
MXS_PINCTRL_PIN(GPMI_RDY1),
|
||||
MXS_PINCTRL_PIN(GPMI_RDY2),
|
||||
MXS_PINCTRL_PIN(GPMI_RDY3),
|
||||
MXS_PINCTRL_PIN(GPMI_WPN),
|
||||
MXS_PINCTRL_PIN(GPMI_WRN),
|
||||
MXS_PINCTRL_PIN(GPMI_RDN),
|
||||
MXS_PINCTRL_PIN(AUART1_CTS),
|
||||
MXS_PINCTRL_PIN(AUART1_RTS),
|
||||
MXS_PINCTRL_PIN(AUART1_RX),
|
||||
MXS_PINCTRL_PIN(AUART1_TX),
|
||||
MXS_PINCTRL_PIN(I2C_SCL),
|
||||
MXS_PINCTRL_PIN(I2C_SDA),
|
||||
MXS_PINCTRL_PIN(LCD_D00),
|
||||
MXS_PINCTRL_PIN(LCD_D01),
|
||||
MXS_PINCTRL_PIN(LCD_D02),
|
||||
MXS_PINCTRL_PIN(LCD_D03),
|
||||
MXS_PINCTRL_PIN(LCD_D04),
|
||||
MXS_PINCTRL_PIN(LCD_D05),
|
||||
MXS_PINCTRL_PIN(LCD_D06),
|
||||
MXS_PINCTRL_PIN(LCD_D07),
|
||||
MXS_PINCTRL_PIN(LCD_D08),
|
||||
MXS_PINCTRL_PIN(LCD_D09),
|
||||
MXS_PINCTRL_PIN(LCD_D10),
|
||||
MXS_PINCTRL_PIN(LCD_D11),
|
||||
MXS_PINCTRL_PIN(LCD_D12),
|
||||
MXS_PINCTRL_PIN(LCD_D13),
|
||||
MXS_PINCTRL_PIN(LCD_D14),
|
||||
MXS_PINCTRL_PIN(LCD_D15),
|
||||
MXS_PINCTRL_PIN(LCD_D16),
|
||||
MXS_PINCTRL_PIN(LCD_D17),
|
||||
MXS_PINCTRL_PIN(LCD_RESET),
|
||||
MXS_PINCTRL_PIN(LCD_RS),
|
||||
MXS_PINCTRL_PIN(LCD_WR),
|
||||
MXS_PINCTRL_PIN(LCD_CS),
|
||||
MXS_PINCTRL_PIN(LCD_DOTCK),
|
||||
MXS_PINCTRL_PIN(LCD_ENABLE),
|
||||
MXS_PINCTRL_PIN(LCD_HSYNC),
|
||||
MXS_PINCTRL_PIN(LCD_VSYNC),
|
||||
MXS_PINCTRL_PIN(PWM0),
|
||||
MXS_PINCTRL_PIN(PWM1),
|
||||
MXS_PINCTRL_PIN(PWM2),
|
||||
MXS_PINCTRL_PIN(PWM3),
|
||||
MXS_PINCTRL_PIN(PWM4),
|
||||
MXS_PINCTRL_PIN(SSP1_CMD),
|
||||
MXS_PINCTRL_PIN(SSP1_DETECT),
|
||||
MXS_PINCTRL_PIN(SSP1_DATA0),
|
||||
MXS_PINCTRL_PIN(SSP1_DATA1),
|
||||
MXS_PINCTRL_PIN(SSP1_DATA2),
|
||||
MXS_PINCTRL_PIN(SSP1_DATA3),
|
||||
MXS_PINCTRL_PIN(SSP1_SCK),
|
||||
MXS_PINCTRL_PIN(ROTARYA),
|
||||
MXS_PINCTRL_PIN(ROTARYB),
|
||||
MXS_PINCTRL_PIN(EMI_A00),
|
||||
MXS_PINCTRL_PIN(EMI_A01),
|
||||
MXS_PINCTRL_PIN(EMI_A02),
|
||||
MXS_PINCTRL_PIN(EMI_A03),
|
||||
MXS_PINCTRL_PIN(EMI_A04),
|
||||
MXS_PINCTRL_PIN(EMI_A05),
|
||||
MXS_PINCTRL_PIN(EMI_A06),
|
||||
MXS_PINCTRL_PIN(EMI_A07),
|
||||
MXS_PINCTRL_PIN(EMI_A08),
|
||||
MXS_PINCTRL_PIN(EMI_A09),
|
||||
MXS_PINCTRL_PIN(EMI_A10),
|
||||
MXS_PINCTRL_PIN(EMI_A11),
|
||||
MXS_PINCTRL_PIN(EMI_A12),
|
||||
MXS_PINCTRL_PIN(EMI_BA0),
|
||||
MXS_PINCTRL_PIN(EMI_BA1),
|
||||
MXS_PINCTRL_PIN(EMI_CASN),
|
||||
MXS_PINCTRL_PIN(EMI_CE0N),
|
||||
MXS_PINCTRL_PIN(EMI_CE1N),
|
||||
MXS_PINCTRL_PIN(GPMI_CE1N),
|
||||
MXS_PINCTRL_PIN(GPMI_CE0N),
|
||||
MXS_PINCTRL_PIN(EMI_CKE),
|
||||
MXS_PINCTRL_PIN(EMI_RASN),
|
||||
MXS_PINCTRL_PIN(EMI_WEN),
|
||||
MXS_PINCTRL_PIN(EMI_D00),
|
||||
MXS_PINCTRL_PIN(EMI_D01),
|
||||
MXS_PINCTRL_PIN(EMI_D02),
|
||||
MXS_PINCTRL_PIN(EMI_D03),
|
||||
MXS_PINCTRL_PIN(EMI_D04),
|
||||
MXS_PINCTRL_PIN(EMI_D05),
|
||||
MXS_PINCTRL_PIN(EMI_D06),
|
||||
MXS_PINCTRL_PIN(EMI_D07),
|
||||
MXS_PINCTRL_PIN(EMI_D08),
|
||||
MXS_PINCTRL_PIN(EMI_D09),
|
||||
MXS_PINCTRL_PIN(EMI_D10),
|
||||
MXS_PINCTRL_PIN(EMI_D11),
|
||||
MXS_PINCTRL_PIN(EMI_D12),
|
||||
MXS_PINCTRL_PIN(EMI_D13),
|
||||
MXS_PINCTRL_PIN(EMI_D14),
|
||||
MXS_PINCTRL_PIN(EMI_D15),
|
||||
MXS_PINCTRL_PIN(EMI_DQM0),
|
||||
MXS_PINCTRL_PIN(EMI_DQM1),
|
||||
MXS_PINCTRL_PIN(EMI_DQS0),
|
||||
MXS_PINCTRL_PIN(EMI_DQS1),
|
||||
MXS_PINCTRL_PIN(EMI_CLK),
|
||||
MXS_PINCTRL_PIN(EMI_CLKN),
|
||||
};
|
||||
|
||||
static struct mxs_regs imx23_regs = {
|
||||
.muxsel = 0x100,
|
||||
.drive = 0x200,
|
||||
.pull = 0x400,
|
||||
};
|
||||
|
||||
static struct mxs_pinctrl_soc_data imx23_pinctrl_data = {
|
||||
.regs = &imx23_regs,
|
||||
.pins = imx23_pins,
|
||||
.npins = ARRAY_SIZE(imx23_pins),
|
||||
};
|
||||
|
||||
static int __devinit imx23_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
return mxs_pinctrl_probe(pdev, &imx23_pinctrl_data);
|
||||
}
|
||||
|
||||
static struct of_device_id imx23_pinctrl_of_match[] __devinitdata = {
|
||||
{ .compatible = "fsl,imx23-pinctrl", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx23_pinctrl_of_match);
|
||||
|
||||
static struct platform_driver imx23_pinctrl_driver = {
|
||||
.driver = {
|
||||
.name = "imx23-pinctrl",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = imx23_pinctrl_of_match,
|
||||
},
|
||||
.probe = imx23_pinctrl_probe,
|
||||
.remove = __devexit_p(mxs_pinctrl_remove),
|
||||
};
|
||||
|
||||
static int __init imx23_pinctrl_init(void)
|
||||
{
|
||||
return platform_driver_register(&imx23_pinctrl_driver);
|
||||
}
|
||||
arch_initcall(imx23_pinctrl_init);
|
||||
|
||||
static void __exit imx23_pinctrl_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&imx23_pinctrl_driver);
|
||||
}
|
||||
module_exit(imx23_pinctrl_exit);
|
||||
|
||||
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
|
||||
MODULE_DESCRIPTION("Freescale i.MX23 pinctrl driver");
|
||||
MODULE_LICENSE("GPL v2");
|
421
drivers/pinctrl/pinctrl-imx28.c
Normal file
421
drivers/pinctrl/pinctrl-imx28.c
Normal file
@ -0,0 +1,421 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include "pinctrl-mxs.h"
|
||||
|
||||
enum imx28_pin_enum {
|
||||
GPMI_D00 = PINID(0, 0),
|
||||
GPMI_D01 = PINID(0, 1),
|
||||
GPMI_D02 = PINID(0, 2),
|
||||
GPMI_D03 = PINID(0, 3),
|
||||
GPMI_D04 = PINID(0, 4),
|
||||
GPMI_D05 = PINID(0, 5),
|
||||
GPMI_D06 = PINID(0, 6),
|
||||
GPMI_D07 = PINID(0, 7),
|
||||
GPMI_CE0N = PINID(0, 16),
|
||||
GPMI_CE1N = PINID(0, 17),
|
||||
GPMI_CE2N = PINID(0, 18),
|
||||
GPMI_CE3N = PINID(0, 19),
|
||||
GPMI_RDY0 = PINID(0, 20),
|
||||
GPMI_RDY1 = PINID(0, 21),
|
||||
GPMI_RDY2 = PINID(0, 22),
|
||||
GPMI_RDY3 = PINID(0, 23),
|
||||
GPMI_RDN = PINID(0, 24),
|
||||
GPMI_WRN = PINID(0, 25),
|
||||
GPMI_ALE = PINID(0, 26),
|
||||
GPMI_CLE = PINID(0, 27),
|
||||
GPMI_RESETN = PINID(0, 28),
|
||||
LCD_D00 = PINID(1, 0),
|
||||
LCD_D01 = PINID(1, 1),
|
||||
LCD_D02 = PINID(1, 2),
|
||||
LCD_D03 = PINID(1, 3),
|
||||
LCD_D04 = PINID(1, 4),
|
||||
LCD_D05 = PINID(1, 5),
|
||||
LCD_D06 = PINID(1, 6),
|
||||
LCD_D07 = PINID(1, 7),
|
||||
LCD_D08 = PINID(1, 8),
|
||||
LCD_D09 = PINID(1, 9),
|
||||
LCD_D10 = PINID(1, 10),
|
||||
LCD_D11 = PINID(1, 11),
|
||||
LCD_D12 = PINID(1, 12),
|
||||
LCD_D13 = PINID(1, 13),
|
||||
LCD_D14 = PINID(1, 14),
|
||||
LCD_D15 = PINID(1, 15),
|
||||
LCD_D16 = PINID(1, 16),
|
||||
LCD_D17 = PINID(1, 17),
|
||||
LCD_D18 = PINID(1, 18),
|
||||
LCD_D19 = PINID(1, 19),
|
||||
LCD_D20 = PINID(1, 20),
|
||||
LCD_D21 = PINID(1, 21),
|
||||
LCD_D22 = PINID(1, 22),
|
||||
LCD_D23 = PINID(1, 23),
|
||||
LCD_RD_E = PINID(1, 24),
|
||||
LCD_WR_RWN = PINID(1, 25),
|
||||
LCD_RS = PINID(1, 26),
|
||||
LCD_CS = PINID(1, 27),
|
||||
LCD_VSYNC = PINID(1, 28),
|
||||
LCD_HSYNC = PINID(1, 29),
|
||||
LCD_DOTCLK = PINID(1, 30),
|
||||
LCD_ENABLE = PINID(1, 31),
|
||||
SSP0_DATA0 = PINID(2, 0),
|
||||
SSP0_DATA1 = PINID(2, 1),
|
||||
SSP0_DATA2 = PINID(2, 2),
|
||||
SSP0_DATA3 = PINID(2, 3),
|
||||
SSP0_DATA4 = PINID(2, 4),
|
||||
SSP0_DATA5 = PINID(2, 5),
|
||||
SSP0_DATA6 = PINID(2, 6),
|
||||
SSP0_DATA7 = PINID(2, 7),
|
||||
SSP0_CMD = PINID(2, 8),
|
||||
SSP0_DETECT = PINID(2, 9),
|
||||
SSP0_SCK = PINID(2, 10),
|
||||
SSP1_SCK = PINID(2, 12),
|
||||
SSP1_CMD = PINID(2, 13),
|
||||
SSP1_DATA0 = PINID(2, 14),
|
||||
SSP1_DATA3 = PINID(2, 15),
|
||||
SSP2_SCK = PINID(2, 16),
|
||||
SSP2_MOSI = PINID(2, 17),
|
||||
SSP2_MISO = PINID(2, 18),
|
||||
SSP2_SS0 = PINID(2, 19),
|
||||
SSP2_SS1 = PINID(2, 20),
|
||||
SSP2_SS2 = PINID(2, 21),
|
||||
SSP3_SCK = PINID(2, 24),
|
||||
SSP3_MOSI = PINID(2, 25),
|
||||
SSP3_MISO = PINID(2, 26),
|
||||
SSP3_SS0 = PINID(2, 27),
|
||||
AUART0_RX = PINID(3, 0),
|
||||
AUART0_TX = PINID(3, 1),
|
||||
AUART0_CTS = PINID(3, 2),
|
||||
AUART0_RTS = PINID(3, 3),
|
||||
AUART1_RX = PINID(3, 4),
|
||||
AUART1_TX = PINID(3, 5),
|
||||
AUART1_CTS = PINID(3, 6),
|
||||
AUART1_RTS = PINID(3, 7),
|
||||
AUART2_RX = PINID(3, 8),
|
||||
AUART2_TX = PINID(3, 9),
|
||||
AUART2_CTS = PINID(3, 10),
|
||||
AUART2_RTS = PINID(3, 11),
|
||||
AUART3_RX = PINID(3, 12),
|
||||
AUART3_TX = PINID(3, 13),
|
||||
AUART3_CTS = PINID(3, 14),
|
||||
AUART3_RTS = PINID(3, 15),
|
||||
PWM0 = PINID(3, 16),
|
||||
PWM1 = PINID(3, 17),
|
||||
PWM2 = PINID(3, 18),
|
||||
SAIF0_MCLK = PINID(3, 20),
|
||||
SAIF0_LRCLK = PINID(3, 21),
|
||||
SAIF0_BITCLK = PINID(3, 22),
|
||||
SAIF0_SDATA0 = PINID(3, 23),
|
||||
I2C0_SCL = PINID(3, 24),
|
||||
I2C0_SDA = PINID(3, 25),
|
||||
SAIF1_SDATA0 = PINID(3, 26),
|
||||
SPDIF = PINID(3, 27),
|
||||
PWM3 = PINID(3, 28),
|
||||
PWM4 = PINID(3, 29),
|
||||
LCD_RESET = PINID(3, 30),
|
||||
ENET0_MDC = PINID(4, 0),
|
||||
ENET0_MDIO = PINID(4, 1),
|
||||
ENET0_RX_EN = PINID(4, 2),
|
||||
ENET0_RXD0 = PINID(4, 3),
|
||||
ENET0_RXD1 = PINID(4, 4),
|
||||
ENET0_TX_CLK = PINID(4, 5),
|
||||
ENET0_TX_EN = PINID(4, 6),
|
||||
ENET0_TXD0 = PINID(4, 7),
|
||||
ENET0_TXD1 = PINID(4, 8),
|
||||
ENET0_RXD2 = PINID(4, 9),
|
||||
ENET0_RXD3 = PINID(4, 10),
|
||||
ENET0_TXD2 = PINID(4, 11),
|
||||
ENET0_TXD3 = PINID(4, 12),
|
||||
ENET0_RX_CLK = PINID(4, 13),
|
||||
ENET0_COL = PINID(4, 14),
|
||||
ENET0_CRS = PINID(4, 15),
|
||||
ENET_CLK = PINID(4, 16),
|
||||
JTAG_RTCK = PINID(4, 20),
|
||||
EMI_D00 = PINID(5, 0),
|
||||
EMI_D01 = PINID(5, 1),
|
||||
EMI_D02 = PINID(5, 2),
|
||||
EMI_D03 = PINID(5, 3),
|
||||
EMI_D04 = PINID(5, 4),
|
||||
EMI_D05 = PINID(5, 5),
|
||||
EMI_D06 = PINID(5, 6),
|
||||
EMI_D07 = PINID(5, 7),
|
||||
EMI_D08 = PINID(5, 8),
|
||||
EMI_D09 = PINID(5, 9),
|
||||
EMI_D10 = PINID(5, 10),
|
||||
EMI_D11 = PINID(5, 11),
|
||||
EMI_D12 = PINID(5, 12),
|
||||
EMI_D13 = PINID(5, 13),
|
||||
EMI_D14 = PINID(5, 14),
|
||||
EMI_D15 = PINID(5, 15),
|
||||
EMI_ODT0 = PINID(5, 16),
|
||||
EMI_DQM0 = PINID(5, 17),
|
||||
EMI_ODT1 = PINID(5, 18),
|
||||
EMI_DQM1 = PINID(5, 19),
|
||||
EMI_DDR_OPEN_FB = PINID(5, 20),
|
||||
EMI_CLK = PINID(5, 21),
|
||||
EMI_DQS0 = PINID(5, 22),
|
||||
EMI_DQS1 = PINID(5, 23),
|
||||
EMI_DDR_OPEN = PINID(5, 26),
|
||||
EMI_A00 = PINID(6, 0),
|
||||
EMI_A01 = PINID(6, 1),
|
||||
EMI_A02 = PINID(6, 2),
|
||||
EMI_A03 = PINID(6, 3),
|
||||
EMI_A04 = PINID(6, 4),
|
||||
EMI_A05 = PINID(6, 5),
|
||||
EMI_A06 = PINID(6, 6),
|
||||
EMI_A07 = PINID(6, 7),
|
||||
EMI_A08 = PINID(6, 8),
|
||||
EMI_A09 = PINID(6, 9),
|
||||
EMI_A10 = PINID(6, 10),
|
||||
EMI_A11 = PINID(6, 11),
|
||||
EMI_A12 = PINID(6, 12),
|
||||
EMI_A13 = PINID(6, 13),
|
||||
EMI_A14 = PINID(6, 14),
|
||||
EMI_BA0 = PINID(6, 16),
|
||||
EMI_BA1 = PINID(6, 17),
|
||||
EMI_BA2 = PINID(6, 18),
|
||||
EMI_CASN = PINID(6, 19),
|
||||
EMI_RASN = PINID(6, 20),
|
||||
EMI_WEN = PINID(6, 21),
|
||||
EMI_CE0N = PINID(6, 22),
|
||||
EMI_CE1N = PINID(6, 23),
|
||||
EMI_CKE = PINID(6, 24),
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc imx28_pins[] = {
|
||||
MXS_PINCTRL_PIN(GPMI_D00),
|
||||
MXS_PINCTRL_PIN(GPMI_D01),
|
||||
MXS_PINCTRL_PIN(GPMI_D02),
|
||||
MXS_PINCTRL_PIN(GPMI_D03),
|
||||
MXS_PINCTRL_PIN(GPMI_D04),
|
||||
MXS_PINCTRL_PIN(GPMI_D05),
|
||||
MXS_PINCTRL_PIN(GPMI_D06),
|
||||
MXS_PINCTRL_PIN(GPMI_D07),
|
||||
MXS_PINCTRL_PIN(GPMI_CE0N),
|
||||
MXS_PINCTRL_PIN(GPMI_CE1N),
|
||||
MXS_PINCTRL_PIN(GPMI_CE2N),
|
||||
MXS_PINCTRL_PIN(GPMI_CE3N),
|
||||
MXS_PINCTRL_PIN(GPMI_RDY0),
|
||||
MXS_PINCTRL_PIN(GPMI_RDY1),
|
||||
MXS_PINCTRL_PIN(GPMI_RDY2),
|
||||
MXS_PINCTRL_PIN(GPMI_RDY3),
|
||||
MXS_PINCTRL_PIN(GPMI_RDN),
|
||||
MXS_PINCTRL_PIN(GPMI_WRN),
|
||||
MXS_PINCTRL_PIN(GPMI_ALE),
|
||||
MXS_PINCTRL_PIN(GPMI_CLE),
|
||||
MXS_PINCTRL_PIN(GPMI_RESETN),
|
||||
MXS_PINCTRL_PIN(LCD_D00),
|
||||
MXS_PINCTRL_PIN(LCD_D01),
|
||||
MXS_PINCTRL_PIN(LCD_D02),
|
||||
MXS_PINCTRL_PIN(LCD_D03),
|
||||
MXS_PINCTRL_PIN(LCD_D04),
|
||||
MXS_PINCTRL_PIN(LCD_D05),
|
||||
MXS_PINCTRL_PIN(LCD_D06),
|
||||
MXS_PINCTRL_PIN(LCD_D07),
|
||||
MXS_PINCTRL_PIN(LCD_D08),
|
||||
MXS_PINCTRL_PIN(LCD_D09),
|
||||
MXS_PINCTRL_PIN(LCD_D10),
|
||||
MXS_PINCTRL_PIN(LCD_D11),
|
||||
MXS_PINCTRL_PIN(LCD_D12),
|
||||
MXS_PINCTRL_PIN(LCD_D13),
|
||||
MXS_PINCTRL_PIN(LCD_D14),
|
||||
MXS_PINCTRL_PIN(LCD_D15),
|
||||
MXS_PINCTRL_PIN(LCD_D16),
|
||||
MXS_PINCTRL_PIN(LCD_D17),
|
||||
MXS_PINCTRL_PIN(LCD_D18),
|
||||
MXS_PINCTRL_PIN(LCD_D19),
|
||||
MXS_PINCTRL_PIN(LCD_D20),
|
||||
MXS_PINCTRL_PIN(LCD_D21),
|
||||
MXS_PINCTRL_PIN(LCD_D22),
|
||||
MXS_PINCTRL_PIN(LCD_D23),
|
||||
MXS_PINCTRL_PIN(LCD_RD_E),
|
||||
MXS_PINCTRL_PIN(LCD_WR_RWN),
|
||||
MXS_PINCTRL_PIN(LCD_RS),
|
||||
MXS_PINCTRL_PIN(LCD_CS),
|
||||
MXS_PINCTRL_PIN(LCD_VSYNC),
|
||||
MXS_PINCTRL_PIN(LCD_HSYNC),
|
||||
MXS_PINCTRL_PIN(LCD_DOTCLK),
|
||||
MXS_PINCTRL_PIN(LCD_ENABLE),
|
||||
MXS_PINCTRL_PIN(SSP0_DATA0),
|
||||
MXS_PINCTRL_PIN(SSP0_DATA1),
|
||||
MXS_PINCTRL_PIN(SSP0_DATA2),
|
||||
MXS_PINCTRL_PIN(SSP0_DATA3),
|
||||
MXS_PINCTRL_PIN(SSP0_DATA4),
|
||||
MXS_PINCTRL_PIN(SSP0_DATA5),
|
||||
MXS_PINCTRL_PIN(SSP0_DATA6),
|
||||
MXS_PINCTRL_PIN(SSP0_DATA7),
|
||||
MXS_PINCTRL_PIN(SSP0_CMD),
|
||||
MXS_PINCTRL_PIN(SSP0_DETECT),
|
||||
MXS_PINCTRL_PIN(SSP0_SCK),
|
||||
MXS_PINCTRL_PIN(SSP1_SCK),
|
||||
MXS_PINCTRL_PIN(SSP1_CMD),
|
||||
MXS_PINCTRL_PIN(SSP1_DATA0),
|
||||
MXS_PINCTRL_PIN(SSP1_DATA3),
|
||||
MXS_PINCTRL_PIN(SSP2_SCK),
|
||||
MXS_PINCTRL_PIN(SSP2_MOSI),
|
||||
MXS_PINCTRL_PIN(SSP2_MISO),
|
||||
MXS_PINCTRL_PIN(SSP2_SS0),
|
||||
MXS_PINCTRL_PIN(SSP2_SS1),
|
||||
MXS_PINCTRL_PIN(SSP2_SS2),
|
||||
MXS_PINCTRL_PIN(SSP3_SCK),
|
||||
MXS_PINCTRL_PIN(SSP3_MOSI),
|
||||
MXS_PINCTRL_PIN(SSP3_MISO),
|
||||
MXS_PINCTRL_PIN(SSP3_SS0),
|
||||
MXS_PINCTRL_PIN(AUART0_RX),
|
||||
MXS_PINCTRL_PIN(AUART0_TX),
|
||||
MXS_PINCTRL_PIN(AUART0_CTS),
|
||||
MXS_PINCTRL_PIN(AUART0_RTS),
|
||||
MXS_PINCTRL_PIN(AUART1_RX),
|
||||
MXS_PINCTRL_PIN(AUART1_TX),
|
||||
MXS_PINCTRL_PIN(AUART1_CTS),
|
||||
MXS_PINCTRL_PIN(AUART1_RTS),
|
||||
MXS_PINCTRL_PIN(AUART2_RX),
|
||||
MXS_PINCTRL_PIN(AUART2_TX),
|
||||
MXS_PINCTRL_PIN(AUART2_CTS),
|
||||
MXS_PINCTRL_PIN(AUART2_RTS),
|
||||
MXS_PINCTRL_PIN(AUART3_RX),
|
||||
MXS_PINCTRL_PIN(AUART3_TX),
|
||||
MXS_PINCTRL_PIN(AUART3_CTS),
|
||||
MXS_PINCTRL_PIN(AUART3_RTS),
|
||||
MXS_PINCTRL_PIN(PWM0),
|
||||
MXS_PINCTRL_PIN(PWM1),
|
||||
MXS_PINCTRL_PIN(PWM2),
|
||||
MXS_PINCTRL_PIN(SAIF0_MCLK),
|
||||
MXS_PINCTRL_PIN(SAIF0_LRCLK),
|
||||
MXS_PINCTRL_PIN(SAIF0_BITCLK),
|
||||
MXS_PINCTRL_PIN(SAIF0_SDATA0),
|
||||
MXS_PINCTRL_PIN(I2C0_SCL),
|
||||
MXS_PINCTRL_PIN(I2C0_SDA),
|
||||
MXS_PINCTRL_PIN(SAIF1_SDATA0),
|
||||
MXS_PINCTRL_PIN(SPDIF),
|
||||
MXS_PINCTRL_PIN(PWM3),
|
||||
MXS_PINCTRL_PIN(PWM4),
|
||||
MXS_PINCTRL_PIN(LCD_RESET),
|
||||
MXS_PINCTRL_PIN(ENET0_MDC),
|
||||
MXS_PINCTRL_PIN(ENET0_MDIO),
|
||||
MXS_PINCTRL_PIN(ENET0_RX_EN),
|
||||
MXS_PINCTRL_PIN(ENET0_RXD0),
|
||||
MXS_PINCTRL_PIN(ENET0_RXD1),
|
||||
MXS_PINCTRL_PIN(ENET0_TX_CLK),
|
||||
MXS_PINCTRL_PIN(ENET0_TX_EN),
|
||||
MXS_PINCTRL_PIN(ENET0_TXD0),
|
||||
MXS_PINCTRL_PIN(ENET0_TXD1),
|
||||
MXS_PINCTRL_PIN(ENET0_RXD2),
|
||||
MXS_PINCTRL_PIN(ENET0_RXD3),
|
||||
MXS_PINCTRL_PIN(ENET0_TXD2),
|
||||
MXS_PINCTRL_PIN(ENET0_TXD3),
|
||||
MXS_PINCTRL_PIN(ENET0_RX_CLK),
|
||||
MXS_PINCTRL_PIN(ENET0_COL),
|
||||
MXS_PINCTRL_PIN(ENET0_CRS),
|
||||
MXS_PINCTRL_PIN(ENET_CLK),
|
||||
MXS_PINCTRL_PIN(JTAG_RTCK),
|
||||
MXS_PINCTRL_PIN(EMI_D00),
|
||||
MXS_PINCTRL_PIN(EMI_D01),
|
||||
MXS_PINCTRL_PIN(EMI_D02),
|
||||
MXS_PINCTRL_PIN(EMI_D03),
|
||||
MXS_PINCTRL_PIN(EMI_D04),
|
||||
MXS_PINCTRL_PIN(EMI_D05),
|
||||
MXS_PINCTRL_PIN(EMI_D06),
|
||||
MXS_PINCTRL_PIN(EMI_D07),
|
||||
MXS_PINCTRL_PIN(EMI_D08),
|
||||
MXS_PINCTRL_PIN(EMI_D09),
|
||||
MXS_PINCTRL_PIN(EMI_D10),
|
||||
MXS_PINCTRL_PIN(EMI_D11),
|
||||
MXS_PINCTRL_PIN(EMI_D12),
|
||||
MXS_PINCTRL_PIN(EMI_D13),
|
||||
MXS_PINCTRL_PIN(EMI_D14),
|
||||
MXS_PINCTRL_PIN(EMI_D15),
|
||||
MXS_PINCTRL_PIN(EMI_ODT0),
|
||||
MXS_PINCTRL_PIN(EMI_DQM0),
|
||||
MXS_PINCTRL_PIN(EMI_ODT1),
|
||||
MXS_PINCTRL_PIN(EMI_DQM1),
|
||||
MXS_PINCTRL_PIN(EMI_DDR_OPEN_FB),
|
||||
MXS_PINCTRL_PIN(EMI_CLK),
|
||||
MXS_PINCTRL_PIN(EMI_DQS0),
|
||||
MXS_PINCTRL_PIN(EMI_DQS1),
|
||||
MXS_PINCTRL_PIN(EMI_DDR_OPEN),
|
||||
MXS_PINCTRL_PIN(EMI_A00),
|
||||
MXS_PINCTRL_PIN(EMI_A01),
|
||||
MXS_PINCTRL_PIN(EMI_A02),
|
||||
MXS_PINCTRL_PIN(EMI_A03),
|
||||
MXS_PINCTRL_PIN(EMI_A04),
|
||||
MXS_PINCTRL_PIN(EMI_A05),
|
||||
MXS_PINCTRL_PIN(EMI_A06),
|
||||
MXS_PINCTRL_PIN(EMI_A07),
|
||||
MXS_PINCTRL_PIN(EMI_A08),
|
||||
MXS_PINCTRL_PIN(EMI_A09),
|
||||
MXS_PINCTRL_PIN(EMI_A10),
|
||||
MXS_PINCTRL_PIN(EMI_A11),
|
||||
MXS_PINCTRL_PIN(EMI_A12),
|
||||
MXS_PINCTRL_PIN(EMI_A13),
|
||||
MXS_PINCTRL_PIN(EMI_A14),
|
||||
MXS_PINCTRL_PIN(EMI_BA0),
|
||||
MXS_PINCTRL_PIN(EMI_BA1),
|
||||
MXS_PINCTRL_PIN(EMI_BA2),
|
||||
MXS_PINCTRL_PIN(EMI_CASN),
|
||||
MXS_PINCTRL_PIN(EMI_RASN),
|
||||
MXS_PINCTRL_PIN(EMI_WEN),
|
||||
MXS_PINCTRL_PIN(EMI_CE0N),
|
||||
MXS_PINCTRL_PIN(EMI_CE1N),
|
||||
MXS_PINCTRL_PIN(EMI_CKE),
|
||||
};
|
||||
|
||||
static struct mxs_regs imx28_regs = {
|
||||
.muxsel = 0x100,
|
||||
.drive = 0x300,
|
||||
.pull = 0x600,
|
||||
};
|
||||
|
||||
static struct mxs_pinctrl_soc_data imx28_pinctrl_data = {
|
||||
.regs = &imx28_regs,
|
||||
.pins = imx28_pins,
|
||||
.npins = ARRAY_SIZE(imx28_pins),
|
||||
};
|
||||
|
||||
static int __devinit imx28_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
return mxs_pinctrl_probe(pdev, &imx28_pinctrl_data);
|
||||
}
|
||||
|
||||
static struct of_device_id imx28_pinctrl_of_match[] __devinitdata = {
|
||||
{ .compatible = "fsl,imx28-pinctrl", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx28_pinctrl_of_match);
|
||||
|
||||
static struct platform_driver imx28_pinctrl_driver = {
|
||||
.driver = {
|
||||
.name = "imx28-pinctrl",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = imx28_pinctrl_of_match,
|
||||
},
|
||||
.probe = imx28_pinctrl_probe,
|
||||
.remove = __devexit_p(mxs_pinctrl_remove),
|
||||
};
|
||||
|
||||
static int __init imx28_pinctrl_init(void)
|
||||
{
|
||||
return platform_driver_register(&imx28_pinctrl_driver);
|
||||
}
|
||||
arch_initcall(imx28_pinctrl_init);
|
||||
|
||||
static void __exit imx28_pinctrl_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&imx28_pinctrl_driver);
|
||||
}
|
||||
module_exit(imx28_pinctrl_exit);
|
||||
|
||||
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
|
||||
MODULE_DESCRIPTION("Freescale i.MX28 pinctrl driver");
|
||||
MODULE_LICENSE("GPL v2");
|
1322
drivers/pinctrl/pinctrl-imx51.c
Normal file
1322
drivers/pinctrl/pinctrl-imx51.c
Normal file
File diff suppressed because it is too large
Load Diff
1649
drivers/pinctrl/pinctrl-imx53.c
Normal file
1649
drivers/pinctrl/pinctrl-imx53.c
Normal file
File diff suppressed because it is too large
Load Diff
2331
drivers/pinctrl/pinctrl-imx6q.c
Normal file
2331
drivers/pinctrl/pinctrl-imx6q.c
Normal file
File diff suppressed because it is too large
Load Diff
528
drivers/pinctrl/pinctrl-mxs.c
Normal file
528
drivers/pinctrl/pinctrl-mxs.c
Normal file
@ -0,0 +1,528 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include "core.h"
|
||||
#include "pinctrl-mxs.h"
|
||||
|
||||
#define SUFFIX_LEN 4
|
||||
|
||||
struct mxs_pinctrl_data {
|
||||
struct device *dev;
|
||||
struct pinctrl_dev *pctl;
|
||||
void __iomem *base;
|
||||
struct mxs_pinctrl_soc_data *soc;
|
||||
};
|
||||
|
||||
static int mxs_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return d->soc->ngroups;
|
||||
}
|
||||
|
||||
static const char *mxs_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned group)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return d->soc->groups[group].name;
|
||||
}
|
||||
|
||||
static int mxs_get_group_pins(struct pinctrl_dev *pctldev, unsigned group,
|
||||
const unsigned **pins, unsigned *num_pins)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*pins = d->soc->groups[group].pins;
|
||||
*num_pins = d->soc->groups[group].npins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mxs_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||
unsigned offset)
|
||||
{
|
||||
seq_printf(s, " %s", dev_name(pctldev->dev));
|
||||
}
|
||||
|
||||
static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np,
|
||||
struct pinctrl_map **map, unsigned *num_maps)
|
||||
{
|
||||
struct pinctrl_map *new_map;
|
||||
char *group = NULL;
|
||||
unsigned new_num = 1;
|
||||
unsigned long config = 0;
|
||||
unsigned long *pconfig;
|
||||
int length = strlen(np->name) + SUFFIX_LEN;
|
||||
bool purecfg = false;
|
||||
u32 val, reg;
|
||||
int ret, i = 0;
|
||||
|
||||
/* Check for pin config node which has no 'reg' property */
|
||||
if (of_property_read_u32(np, "reg", ®))
|
||||
purecfg = true;
|
||||
|
||||
ret = of_property_read_u32(np, "fsl,drive-strength", &val);
|
||||
if (!ret)
|
||||
config = val | MA_PRESENT;
|
||||
ret = of_property_read_u32(np, "fsl,voltage", &val);
|
||||
if (!ret)
|
||||
config |= val << VOL_SHIFT | VOL_PRESENT;
|
||||
ret = of_property_read_u32(np, "fsl,pull-up", &val);
|
||||
if (!ret)
|
||||
config |= val << PULL_SHIFT | PULL_PRESENT;
|
||||
|
||||
/* Check for group node which has both mux and config settings */
|
||||
if (!purecfg && config)
|
||||
new_num = 2;
|
||||
|
||||
new_map = kzalloc(sizeof(*new_map) * new_num, GFP_KERNEL);
|
||||
if (!new_map)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!purecfg) {
|
||||
new_map[i].type = PIN_MAP_TYPE_MUX_GROUP;
|
||||
new_map[i].data.mux.function = np->name;
|
||||
|
||||
/* Compose group name */
|
||||
group = kzalloc(length, GFP_KERNEL);
|
||||
if (!group)
|
||||
return -ENOMEM;
|
||||
snprintf(group, length, "%s.%d", np->name, reg);
|
||||
new_map[i].data.mux.group = group;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (config) {
|
||||
pconfig = kmemdup(&config, sizeof(config), GFP_KERNEL);
|
||||
if (!pconfig) {
|
||||
ret = -ENOMEM;
|
||||
goto free;
|
||||
}
|
||||
|
||||
new_map[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
|
||||
new_map[i].data.configs.group_or_pin = purecfg ? np->name :
|
||||
group;
|
||||
new_map[i].data.configs.configs = pconfig;
|
||||
new_map[i].data.configs.num_configs = 1;
|
||||
}
|
||||
|
||||
*map = new_map;
|
||||
*num_maps = new_num;
|
||||
|
||||
return 0;
|
||||
|
||||
free:
|
||||
kfree(new_map);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mxs_dt_free_map(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map, unsigned num_maps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_maps; i++) {
|
||||
if (map[i].type == PIN_MAP_TYPE_MUX_GROUP)
|
||||
kfree(map[i].data.mux.group);
|
||||
if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
|
||||
kfree(map[i].data.configs.configs);
|
||||
}
|
||||
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static struct pinctrl_ops mxs_pinctrl_ops = {
|
||||
.get_groups_count = mxs_get_groups_count,
|
||||
.get_group_name = mxs_get_group_name,
|
||||
.get_group_pins = mxs_get_group_pins,
|
||||
.pin_dbg_show = mxs_pin_dbg_show,
|
||||
.dt_node_to_map = mxs_dt_node_to_map,
|
||||
.dt_free_map = mxs_dt_free_map,
|
||||
};
|
||||
|
||||
static int mxs_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return d->soc->nfunctions;
|
||||
}
|
||||
|
||||
static const char *mxs_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
|
||||
unsigned function)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return d->soc->functions[function].name;
|
||||
}
|
||||
|
||||
static int mxs_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
|
||||
unsigned group,
|
||||
const char * const **groups,
|
||||
unsigned * const num_groups)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*groups = d->soc->functions[group].groups;
|
||||
*num_groups = d->soc->functions[group].ngroups;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxs_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
unsigned group)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct mxs_group *g = &d->soc->groups[group];
|
||||
void __iomem *reg;
|
||||
u8 bank, shift;
|
||||
u16 pin;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g->npins; i++) {
|
||||
bank = PINID_TO_BANK(g->pins[i]);
|
||||
pin = PINID_TO_PIN(g->pins[i]);
|
||||
reg = d->base + d->soc->regs->muxsel;
|
||||
reg += bank * 0x20 + pin / 16 * 0x10;
|
||||
shift = pin % 16 * 2;
|
||||
|
||||
writel(0x3 << shift, reg + CLR);
|
||||
writel(g->muxsel[i] << shift, reg + SET);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pinmux_ops mxs_pinmux_ops = {
|
||||
.get_functions_count = mxs_pinctrl_get_funcs_count,
|
||||
.get_function_name = mxs_pinctrl_get_func_name,
|
||||
.get_function_groups = mxs_pinctrl_get_func_groups,
|
||||
.enable = mxs_pinctrl_enable,
|
||||
};
|
||||
|
||||
static int mxs_pinconf_get(struct pinctrl_dev *pctldev,
|
||||
unsigned pin, unsigned long *config)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static int mxs_pinconf_set(struct pinctrl_dev *pctldev,
|
||||
unsigned pin, unsigned long config)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static int mxs_pinconf_group_get(struct pinctrl_dev *pctldev,
|
||||
unsigned group, unsigned long *config)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*config = d->soc->groups[group].config;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev,
|
||||
unsigned group, unsigned long config)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct mxs_group *g = &d->soc->groups[group];
|
||||
void __iomem *reg;
|
||||
u8 ma, vol, pull, bank, shift;
|
||||
u16 pin;
|
||||
int i;
|
||||
|
||||
ma = CONFIG_TO_MA(config);
|
||||
vol = CONFIG_TO_VOL(config);
|
||||
pull = CONFIG_TO_PULL(config);
|
||||
|
||||
for (i = 0; i < g->npins; i++) {
|
||||
bank = PINID_TO_BANK(g->pins[i]);
|
||||
pin = PINID_TO_PIN(g->pins[i]);
|
||||
|
||||
/* drive */
|
||||
reg = d->base + d->soc->regs->drive;
|
||||
reg += bank * 0x40 + pin / 8 * 0x10;
|
||||
|
||||
/* mA */
|
||||
if (config & MA_PRESENT) {
|
||||
shift = pin % 8 * 4;
|
||||
writel(0x3 << shift, reg + CLR);
|
||||
writel(ma << shift, reg + SET);
|
||||
}
|
||||
|
||||
/* vol */
|
||||
if (config & VOL_PRESENT) {
|
||||
shift = pin % 8 * 4 + 2;
|
||||
if (vol)
|
||||
writel(1 << shift, reg + SET);
|
||||
else
|
||||
writel(1 << shift, reg + CLR);
|
||||
}
|
||||
|
||||
/* pull */
|
||||
if (config & PULL_PRESENT) {
|
||||
reg = d->base + d->soc->regs->pull;
|
||||
reg += bank * 0x10;
|
||||
shift = pin;
|
||||
if (pull)
|
||||
writel(1 << shift, reg + SET);
|
||||
else
|
||||
writel(1 << shift, reg + CLR);
|
||||
}
|
||||
}
|
||||
|
||||
/* cache the config value for mxs_pinconf_group_get() */
|
||||
g->config = config;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mxs_pinconf_dbg_show(struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s, unsigned pin)
|
||||
{
|
||||
/* Not support */
|
||||
}
|
||||
|
||||
static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s, unsigned group)
|
||||
{
|
||||
unsigned long config;
|
||||
|
||||
if (!mxs_pinconf_group_get(pctldev, group, &config))
|
||||
seq_printf(s, "0x%lx", config);
|
||||
}
|
||||
|
||||
struct pinconf_ops mxs_pinconf_ops = {
|
||||
.pin_config_get = mxs_pinconf_get,
|
||||
.pin_config_set = mxs_pinconf_set,
|
||||
.pin_config_group_get = mxs_pinconf_group_get,
|
||||
.pin_config_group_set = mxs_pinconf_group_set,
|
||||
.pin_config_dbg_show = mxs_pinconf_dbg_show,
|
||||
.pin_config_group_dbg_show = mxs_pinconf_group_dbg_show,
|
||||
};
|
||||
|
||||
static struct pinctrl_desc mxs_pinctrl_desc = {
|
||||
.pctlops = &mxs_pinctrl_ops,
|
||||
.pmxops = &mxs_pinmux_ops,
|
||||
.confops = &mxs_pinconf_ops,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __devinit mxs_pinctrl_parse_group(struct platform_device *pdev,
|
||||
struct device_node *np, int idx,
|
||||
const char **out_name)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = platform_get_drvdata(pdev);
|
||||
struct mxs_group *g = &d->soc->groups[idx];
|
||||
struct property *prop;
|
||||
const char *propname = "fsl,pinmux-ids";
|
||||
char *group;
|
||||
int length = strlen(np->name) + SUFFIX_LEN;
|
||||
int i;
|
||||
u32 val;
|
||||
|
||||
group = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
|
||||
if (!group)
|
||||
return -ENOMEM;
|
||||
if (of_property_read_u32(np, "reg", &val))
|
||||
snprintf(group, length, "%s", np->name);
|
||||
else
|
||||
snprintf(group, length, "%s.%d", np->name, val);
|
||||
g->name = group;
|
||||
|
||||
prop = of_find_property(np, propname, &length);
|
||||
if (!prop)
|
||||
return -EINVAL;
|
||||
g->npins = length / sizeof(u32);
|
||||
|
||||
g->pins = devm_kzalloc(&pdev->dev, g->npins * sizeof(*g->pins),
|
||||
GFP_KERNEL);
|
||||
if (!g->pins)
|
||||
return -ENOMEM;
|
||||
|
||||
g->muxsel = devm_kzalloc(&pdev->dev, g->npins * sizeof(*g->muxsel),
|
||||
GFP_KERNEL);
|
||||
if (!g->muxsel)
|
||||
return -ENOMEM;
|
||||
|
||||
of_property_read_u32_array(np, propname, g->pins, g->npins);
|
||||
for (i = 0; i < g->npins; i++) {
|
||||
g->muxsel[i] = MUXID_TO_MUXSEL(g->pins[i]);
|
||||
g->pins[i] = MUXID_TO_PINID(g->pins[i]);
|
||||
}
|
||||
|
||||
if (out_name)
|
||||
*out_name = g->name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit mxs_pinctrl_probe_dt(struct platform_device *pdev,
|
||||
struct mxs_pinctrl_data *d)
|
||||
{
|
||||
struct mxs_pinctrl_soc_data *soc = d->soc;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *child;
|
||||
struct mxs_function *f;
|
||||
const char *gpio_compat = "fsl,mxs-gpio";
|
||||
const char *fn, *fnull = "";
|
||||
int i = 0, idxf = 0, idxg = 0;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
child = of_get_next_child(np, NULL);
|
||||
if (!child) {
|
||||
dev_err(&pdev->dev, "no group is defined\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Count total functions and groups */
|
||||
fn = fnull;
|
||||
for_each_child_of_node(np, child) {
|
||||
if (of_device_is_compatible(child, gpio_compat))
|
||||
continue;
|
||||
soc->ngroups++;
|
||||
/* Skip pure pinconf node */
|
||||
if (of_property_read_u32(child, "reg", &val))
|
||||
continue;
|
||||
if (strcmp(fn, child->name)) {
|
||||
fn = child->name;
|
||||
soc->nfunctions++;
|
||||
}
|
||||
}
|
||||
|
||||
soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions *
|
||||
sizeof(*soc->functions), GFP_KERNEL);
|
||||
if (!soc->functions)
|
||||
return -ENOMEM;
|
||||
|
||||
soc->groups = devm_kzalloc(&pdev->dev, soc->ngroups *
|
||||
sizeof(*soc->groups), GFP_KERNEL);
|
||||
if (!soc->groups)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Count groups for each function */
|
||||
fn = fnull;
|
||||
f = &soc->functions[idxf];
|
||||
for_each_child_of_node(np, child) {
|
||||
if (of_device_is_compatible(child, gpio_compat))
|
||||
continue;
|
||||
if (of_property_read_u32(child, "reg", &val))
|
||||
continue;
|
||||
if (strcmp(fn, child->name)) {
|
||||
f = &soc->functions[idxf++];
|
||||
f->name = fn = child->name;
|
||||
}
|
||||
f->ngroups++;
|
||||
};
|
||||
|
||||
/* Get groups for each function */
|
||||
idxf = 0;
|
||||
fn = fnull;
|
||||
for_each_child_of_node(np, child) {
|
||||
if (of_device_is_compatible(child, gpio_compat))
|
||||
continue;
|
||||
if (of_property_read_u32(child, "reg", &val)) {
|
||||
ret = mxs_pinctrl_parse_group(pdev, child,
|
||||
idxg++, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(fn, child->name)) {
|
||||
f = &soc->functions[idxf++];
|
||||
f->groups = devm_kzalloc(&pdev->dev, f->ngroups *
|
||||
sizeof(*f->groups),
|
||||
GFP_KERNEL);
|
||||
if (!f->groups)
|
||||
return -ENOMEM;
|
||||
fn = child->name;
|
||||
i = 0;
|
||||
}
|
||||
ret = mxs_pinctrl_parse_group(pdev, child, idxg++,
|
||||
&f->groups[i++]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __devinit mxs_pinctrl_probe(struct platform_device *pdev,
|
||||
struct mxs_pinctrl_soc_data *soc)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct mxs_pinctrl_data *d;
|
||||
int ret;
|
||||
|
||||
d = devm_kzalloc(&pdev->dev, sizeof(*d), GFP_KERNEL);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
||||
d->dev = &pdev->dev;
|
||||
d->soc = soc;
|
||||
|
||||
d->base = of_iomap(np, 0);
|
||||
if (!d->base)
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
mxs_pinctrl_desc.pins = d->soc->pins;
|
||||
mxs_pinctrl_desc.npins = d->soc->npins;
|
||||
mxs_pinctrl_desc.name = dev_name(&pdev->dev);
|
||||
|
||||
platform_set_drvdata(pdev, d);
|
||||
|
||||
ret = mxs_pinctrl_probe_dt(pdev, d);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
d->pctl = pinctrl_register(&mxs_pinctrl_desc, &pdev->dev, d);
|
||||
if (!d->pctl) {
|
||||
dev_err(&pdev->dev, "Couldn't register MXS pinctrl driver\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
iounmap(d->base);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mxs_pinctrl_probe);
|
||||
|
||||
int __devexit mxs_pinctrl_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mxs_pinctrl_data *d = platform_get_drvdata(pdev);
|
||||
|
||||
pinctrl_unregister(d->pctl);
|
||||
iounmap(d->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mxs_pinctrl_remove);
|
91
drivers/pinctrl/pinctrl-mxs.h
Normal file
91
drivers/pinctrl/pinctrl-mxs.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#ifndef __PINCTRL_MXS_H
|
||||
#define __PINCTRL_MXS_H
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
|
||||
#define SET 0x4
|
||||
#define CLR 0x8
|
||||
#define TOG 0xc
|
||||
|
||||
#define MXS_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)
|
||||
#define PINID(bank, pin) ((bank) * 32 + (pin))
|
||||
|
||||
/*
|
||||
* pinmux-id bit field definitions
|
||||
*
|
||||
* bank: 15..12 (4)
|
||||
* pin: 11..4 (8)
|
||||
* muxsel: 3..0 (4)
|
||||
*/
|
||||
#define MUXID_TO_PINID(m) PINID((m) >> 12 & 0xf, (m) >> 4 & 0xff)
|
||||
#define MUXID_TO_MUXSEL(m) ((m) & 0xf)
|
||||
|
||||
#define PINID_TO_BANK(p) ((p) >> 5)
|
||||
#define PINID_TO_PIN(p) ((p) % 32)
|
||||
|
||||
/*
|
||||
* pin config bit field definitions
|
||||
*
|
||||
* pull-up: 6..5 (2)
|
||||
* voltage: 4..3 (2)
|
||||
* mA: 2..0 (3)
|
||||
*
|
||||
* MSB of each field is presence bit for the config.
|
||||
*/
|
||||
#define PULL_PRESENT (1 << 6)
|
||||
#define PULL_SHIFT 5
|
||||
#define VOL_PRESENT (1 << 4)
|
||||
#define VOL_SHIFT 3
|
||||
#define MA_PRESENT (1 << 2)
|
||||
#define MA_SHIFT 0
|
||||
#define CONFIG_TO_PULL(c) ((c) >> PULL_SHIFT & 0x1)
|
||||
#define CONFIG_TO_VOL(c) ((c) >> VOL_SHIFT & 0x1)
|
||||
#define CONFIG_TO_MA(c) ((c) >> MA_SHIFT & 0x3)
|
||||
|
||||
struct mxs_function {
|
||||
const char *name;
|
||||
const char **groups;
|
||||
unsigned ngroups;
|
||||
};
|
||||
|
||||
struct mxs_group {
|
||||
const char *name;
|
||||
unsigned int *pins;
|
||||
unsigned npins;
|
||||
u8 *muxsel;
|
||||
u8 config;
|
||||
};
|
||||
|
||||
struct mxs_regs {
|
||||
u16 muxsel;
|
||||
u16 drive;
|
||||
u16 pull;
|
||||
};
|
||||
|
||||
struct mxs_pinctrl_soc_data {
|
||||
const struct mxs_regs *regs;
|
||||
const struct pinctrl_pin_desc *pins;
|
||||
unsigned npins;
|
||||
struct mxs_function *functions;
|
||||
unsigned nfunctions;
|
||||
struct mxs_group *groups;
|
||||
unsigned ngroups;
|
||||
};
|
||||
|
||||
int mxs_pinctrl_probe(struct platform_device *pdev,
|
||||
struct mxs_pinctrl_soc_data *soc);
|
||||
int mxs_pinctrl_remove(struct platform_device *pdev);
|
||||
|
||||
#endif /* __PINCTRL_MXS_H */
|
@ -25,20 +25,18 @@ static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = {
|
||||
.pin_base = 0,
|
||||
};
|
||||
|
||||
static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
|
||||
static int pxa3xx_get_groups_count(struct pinctrl_dev *pctrldev)
|
||||
{
|
||||
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||
if (selector >= info->num_grps)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
return info->num_grps;
|
||||
}
|
||||
|
||||
static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
|
||||
unsigned selector)
|
||||
{
|
||||
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||
if (selector >= info->num_grps)
|
||||
return NULL;
|
||||
|
||||
return info->grps[selector].name;
|
||||
}
|
||||
|
||||
@ -48,25 +46,23 @@ static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
|
||||
unsigned *num_pins)
|
||||
{
|
||||
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||
if (selector >= info->num_grps)
|
||||
return -EINVAL;
|
||||
|
||||
*pins = info->grps[selector].pins;
|
||||
*num_pins = info->grps[selector].npins;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pinctrl_ops pxa3xx_pctrl_ops = {
|
||||
.list_groups = pxa3xx_list_groups,
|
||||
.get_groups_count = pxa3xx_get_groups_count,
|
||||
.get_group_name = pxa3xx_get_group_name,
|
||||
.get_group_pins = pxa3xx_get_group_pins,
|
||||
};
|
||||
|
||||
static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
|
||||
static int pxa3xx_pmx_get_funcs_count(struct pinctrl_dev *pctrldev)
|
||||
{
|
||||
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||
if (func >= info->num_funcs)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
return info->num_funcs;
|
||||
}
|
||||
|
||||
static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
|
||||
@ -142,11 +138,6 @@ static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
|
||||
unsigned group)
|
||||
{
|
||||
}
|
||||
|
||||
static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned pin)
|
||||
@ -170,11 +161,10 @@ static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
|
||||
}
|
||||
|
||||
static struct pinmux_ops pxa3xx_pmx_ops = {
|
||||
.list_functions = pxa3xx_pmx_list_func,
|
||||
.get_functions_count = pxa3xx_pmx_get_funcs_count,
|
||||
.get_function_name = pxa3xx_pmx_get_func_name,
|
||||
.get_function_groups = pxa3xx_pmx_get_groups,
|
||||
.enable = pxa3xx_pmx_enable,
|
||||
.disable = pxa3xx_pmx_disable,
|
||||
.gpio_request_enable = pxa3xx_pmx_request_gpio,
|
||||
};
|
||||
|
||||
|
@ -853,18 +853,14 @@ static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
|
||||
SIRFSOC_PIN_GROUP("gpsgrp", gps_pins),
|
||||
};
|
||||
|
||||
static int sirfsoc_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
|
||||
static int sirfsoc_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(sirfsoc_pin_groups))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return ARRAY_SIZE(sirfsoc_pin_groups);
|
||||
}
|
||||
|
||||
static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned selector)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(sirfsoc_pin_groups))
|
||||
return NULL;
|
||||
return sirfsoc_pin_groups[selector].name;
|
||||
}
|
||||
|
||||
@ -872,8 +868,6 @@ static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector
|
||||
const unsigned **pins,
|
||||
unsigned *num_pins)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(sirfsoc_pin_groups))
|
||||
return -EINVAL;
|
||||
*pins = sirfsoc_pin_groups[selector].pins;
|
||||
*num_pins = sirfsoc_pin_groups[selector].num_pins;
|
||||
return 0;
|
||||
@ -886,7 +880,7 @@ static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s
|
||||
}
|
||||
|
||||
static struct pinctrl_ops sirfsoc_pctrl_ops = {
|
||||
.list_groups = sirfsoc_list_groups,
|
||||
.get_groups_count = sirfsoc_get_groups_count,
|
||||
.get_group_name = sirfsoc_get_group_name,
|
||||
.get_group_pins = sirfsoc_get_group_pins,
|
||||
.pin_dbg_show = sirfsoc_pin_dbg_show,
|
||||
@ -1033,11 +1027,9 @@ static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector
|
||||
sirfsoc_pinmux_endisable(spmx, selector, false);
|
||||
}
|
||||
|
||||
static int sirfsoc_pinmux_list_funcs(struct pinctrl_dev *pmxdev, unsigned selector)
|
||||
static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(sirfsoc_pmx_functions))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return ARRAY_SIZE(sirfsoc_pmx_functions);
|
||||
}
|
||||
|
||||
static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev,
|
||||
@ -1074,9 +1066,9 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
|
||||
}
|
||||
|
||||
static struct pinmux_ops sirfsoc_pinmux_ops = {
|
||||
.list_functions = sirfsoc_pinmux_list_funcs,
|
||||
.enable = sirfsoc_pinmux_enable,
|
||||
.disable = sirfsoc_pinmux_disable,
|
||||
.get_functions_count = sirfsoc_pinmux_get_funcs_count,
|
||||
.get_function_name = sirfsoc_pinmux_get_func_name,
|
||||
.get_function_groups = sirfsoc_pinmux_get_groups,
|
||||
.gpio_request_enable = sirfsoc_pinmux_request_gpio,
|
||||
|
@ -23,9 +23,11 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <mach/pinconf-tegra.h>
|
||||
|
||||
@ -53,15 +55,11 @@ static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
|
||||
writel(val, pmx->regs[bank] + reg);
|
||||
}
|
||||
|
||||
static int tegra_pinctrl_list_groups(struct pinctrl_dev *pctldev,
|
||||
unsigned group)
|
||||
static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
if (group >= pmx->soc->ngroups)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
return pmx->soc->ngroups;
|
||||
}
|
||||
|
||||
static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
|
||||
@ -69,9 +67,6 @@ static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
|
||||
{
|
||||
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
if (group >= pmx->soc->ngroups)
|
||||
return NULL;
|
||||
|
||||
return pmx->soc->groups[group].name;
|
||||
}
|
||||
|
||||
@ -82,9 +77,6 @@ static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
|
||||
{
|
||||
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
if (group >= pmx->soc->ngroups)
|
||||
return -EINVAL;
|
||||
|
||||
*pins = pmx->soc->groups[group].pins;
|
||||
*num_pins = pmx->soc->groups[group].npins;
|
||||
|
||||
@ -98,22 +90,221 @@ static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
|
||||
seq_printf(s, " " DRIVER_NAME);
|
||||
}
|
||||
|
||||
static int reserve_map(struct pinctrl_map **map, unsigned *reserved_maps,
|
||||
unsigned *num_maps, unsigned reserve)
|
||||
{
|
||||
unsigned old_num = *reserved_maps;
|
||||
unsigned new_num = *num_maps + reserve;
|
||||
struct pinctrl_map *new_map;
|
||||
|
||||
if (old_num >= new_num)
|
||||
return 0;
|
||||
|
||||
new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
|
||||
if (!new_map)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
|
||||
|
||||
*map = new_map;
|
||||
*reserved_maps = new_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
|
||||
unsigned *num_maps, const char *group,
|
||||
const char *function)
|
||||
{
|
||||
if (*num_maps == *reserved_maps)
|
||||
return -ENOSPC;
|
||||
|
||||
(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
|
||||
(*map)[*num_maps].data.mux.group = group;
|
||||
(*map)[*num_maps].data.mux.function = function;
|
||||
(*num_maps)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_map_configs(struct pinctrl_map **map, unsigned *reserved_maps,
|
||||
unsigned *num_maps, const char *group,
|
||||
unsigned long *configs, unsigned num_configs)
|
||||
{
|
||||
unsigned long *dup_configs;
|
||||
|
||||
if (*num_maps == *reserved_maps)
|
||||
return -ENOSPC;
|
||||
|
||||
dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
|
||||
GFP_KERNEL);
|
||||
if (!dup_configs)
|
||||
return -ENOMEM;
|
||||
|
||||
(*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
|
||||
(*map)[*num_maps].data.configs.group_or_pin = group;
|
||||
(*map)[*num_maps].data.configs.configs = dup_configs;
|
||||
(*map)[*num_maps].data.configs.num_configs = num_configs;
|
||||
(*num_maps)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_config(unsigned long **configs, unsigned *num_configs,
|
||||
unsigned long config)
|
||||
{
|
||||
unsigned old_num = *num_configs;
|
||||
unsigned new_num = old_num + 1;
|
||||
unsigned long *new_configs;
|
||||
|
||||
new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
|
||||
GFP_KERNEL);
|
||||
if (!new_configs)
|
||||
return -ENOMEM;
|
||||
|
||||
new_configs[old_num] = config;
|
||||
|
||||
*configs = new_configs;
|
||||
*num_configs = new_num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map, unsigned num_maps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_maps; i++)
|
||||
if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
|
||||
kfree(map[i].data.configs.configs);
|
||||
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static const struct cfg_param {
|
||||
const char *property;
|
||||
enum tegra_pinconf_param param;
|
||||
} cfg_params[] = {
|
||||
{"nvidia,pull", TEGRA_PINCONF_PARAM_PULL},
|
||||
{"nvidia,tristate", TEGRA_PINCONF_PARAM_TRISTATE},
|
||||
{"nvidia,enable-input", TEGRA_PINCONF_PARAM_ENABLE_INPUT},
|
||||
{"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN},
|
||||
{"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK},
|
||||
{"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET},
|
||||
{"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
|
||||
{"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT},
|
||||
{"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
|
||||
{"nvidia,pull-down-strength", TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH},
|
||||
{"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
|
||||
{"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
|
||||
{"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
|
||||
};
|
||||
|
||||
int tegra_pinctrl_dt_subnode_to_map(struct device_node *np,
|
||||
struct pinctrl_map **map,
|
||||
unsigned *reserved_maps,
|
||||
unsigned *num_maps)
|
||||
{
|
||||
int ret, i;
|
||||
const char *function;
|
||||
u32 val;
|
||||
unsigned long config;
|
||||
unsigned long *configs = NULL;
|
||||
unsigned num_configs = 0;
|
||||
unsigned reserve;
|
||||
struct property *prop;
|
||||
const char *group;
|
||||
|
||||
ret = of_property_read_string(np, "nvidia,function", &function);
|
||||
if (ret < 0)
|
||||
function = NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
|
||||
ret = of_property_read_u32(np, cfg_params[i].property, &val);
|
||||
if (!ret) {
|
||||
config = TEGRA_PINCONF_PACK(cfg_params[i].param, val);
|
||||
ret = add_config(&configs, &num_configs, config);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
reserve = 0;
|
||||
if (function != NULL)
|
||||
reserve++;
|
||||
if (num_configs)
|
||||
reserve++;
|
||||
ret = of_property_count_strings(np, "nvidia,pins");
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
reserve *= ret;
|
||||
|
||||
ret = reserve_map(map, reserved_maps, num_maps, reserve);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
of_property_for_each_string(np, "nvidia,pins", prop, group) {
|
||||
if (function) {
|
||||
ret = add_map_mux(map, reserved_maps, num_maps,
|
||||
group, function);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (num_configs) {
|
||||
ret = add_map_configs(map, reserved_maps, num_maps,
|
||||
group, configs, num_configs);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
kfree(configs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
struct device_node *np_config,
|
||||
struct pinctrl_map **map, unsigned *num_maps)
|
||||
{
|
||||
unsigned reserved_maps;
|
||||
struct device_node *np;
|
||||
int ret;
|
||||
|
||||
reserved_maps = 0;
|
||||
*map = NULL;
|
||||
*num_maps = 0;
|
||||
|
||||
for_each_child_of_node(np_config, np) {
|
||||
ret = tegra_pinctrl_dt_subnode_to_map(np, map, &reserved_maps,
|
||||
num_maps);
|
||||
if (ret < 0) {
|
||||
tegra_pinctrl_dt_free_map(pctldev, *map, *num_maps);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pinctrl_ops tegra_pinctrl_ops = {
|
||||
.list_groups = tegra_pinctrl_list_groups,
|
||||
.get_groups_count = tegra_pinctrl_get_groups_count,
|
||||
.get_group_name = tegra_pinctrl_get_group_name,
|
||||
.get_group_pins = tegra_pinctrl_get_group_pins,
|
||||
.pin_dbg_show = tegra_pinctrl_pin_dbg_show,
|
||||
.dt_node_to_map = tegra_pinctrl_dt_node_to_map,
|
||||
.dt_free_map = tegra_pinctrl_dt_free_map,
|
||||
};
|
||||
|
||||
static int tegra_pinctrl_list_funcs(struct pinctrl_dev *pctldev,
|
||||
unsigned function)
|
||||
static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
if (function >= pmx->soc->nfunctions)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
return pmx->soc->nfunctions;
|
||||
}
|
||||
|
||||
static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
|
||||
@ -121,9 +312,6 @@ static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
|
||||
{
|
||||
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
if (function >= pmx->soc->nfunctions)
|
||||
return NULL;
|
||||
|
||||
return pmx->soc->functions[function].name;
|
||||
}
|
||||
|
||||
@ -134,9 +322,6 @@ static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
|
||||
{
|
||||
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
if (function >= pmx->soc->nfunctions)
|
||||
return -EINVAL;
|
||||
|
||||
*groups = pmx->soc->functions[function].groups;
|
||||
*num_groups = pmx->soc->functions[function].ngroups;
|
||||
|
||||
@ -151,8 +336,6 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
|
||||
int i;
|
||||
u32 val;
|
||||
|
||||
if (group >= pmx->soc->ngroups)
|
||||
return -EINVAL;
|
||||
g = &pmx->soc->groups[group];
|
||||
|
||||
if (g->mux_reg < 0)
|
||||
@ -180,8 +363,6 @@ static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
|
||||
const struct tegra_pingroup *g;
|
||||
u32 val;
|
||||
|
||||
if (group >= pmx->soc->ngroups)
|
||||
return;
|
||||
g = &pmx->soc->groups[group];
|
||||
|
||||
if (g->mux_reg < 0)
|
||||
@ -194,7 +375,7 @@ static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
|
||||
}
|
||||
|
||||
static struct pinmux_ops tegra_pinmux_ops = {
|
||||
.list_functions = tegra_pinctrl_list_funcs,
|
||||
.get_functions_count = tegra_pinctrl_get_funcs_count,
|
||||
.get_function_name = tegra_pinctrl_get_func_name,
|
||||
.get_function_groups = tegra_pinctrl_get_func_groups,
|
||||
.enable = tegra_pinctrl_enable,
|
||||
@ -324,8 +505,6 @@ static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev,
|
||||
s16 reg;
|
||||
u32 val, mask;
|
||||
|
||||
if (group >= pmx->soc->ngroups)
|
||||
return -EINVAL;
|
||||
g = &pmx->soc->groups[group];
|
||||
|
||||
ret = tegra_pinconf_reg(pmx, g, param, &bank, ®, &bit, &width);
|
||||
@ -353,8 +532,6 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
|
||||
s16 reg;
|
||||
u32 val, mask;
|
||||
|
||||
if (group >= pmx->soc->ngroups)
|
||||
return -EINVAL;
|
||||
g = &pmx->soc->groups[group];
|
||||
|
||||
ret = tegra_pinconf_reg(pmx, g, param, &bank, ®, &bit, &width);
|
||||
|
@ -836,18 +836,14 @@ static const struct u300_pin_group u300_pin_groups[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int u300_list_groups(struct pinctrl_dev *pctldev, unsigned selector)
|
||||
static int u300_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(u300_pin_groups))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return ARRAY_SIZE(u300_pin_groups);
|
||||
}
|
||||
|
||||
static const char *u300_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned selector)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(u300_pin_groups))
|
||||
return NULL;
|
||||
return u300_pin_groups[selector].name;
|
||||
}
|
||||
|
||||
@ -855,8 +851,6 @@ static int u300_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
const unsigned **pins,
|
||||
unsigned *num_pins)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(u300_pin_groups))
|
||||
return -EINVAL;
|
||||
*pins = u300_pin_groups[selector].pins;
|
||||
*num_pins = u300_pin_groups[selector].num_pins;
|
||||
return 0;
|
||||
@ -869,7 +863,7 @@ static void u300_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||
}
|
||||
|
||||
static struct pinctrl_ops u300_pctrl_ops = {
|
||||
.list_groups = u300_list_groups,
|
||||
.get_groups_count = u300_get_groups_count,
|
||||
.get_group_name = u300_get_group_name,
|
||||
.get_group_pins = u300_get_group_pins,
|
||||
.pin_dbg_show = u300_pin_dbg_show,
|
||||
@ -991,11 +985,9 @@ static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
u300_pmx_endisable(upmx, selector, false);
|
||||
}
|
||||
|
||||
static int u300_pmx_list_funcs(struct pinctrl_dev *pctldev, unsigned selector)
|
||||
static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
if (selector >= ARRAY_SIZE(u300_pmx_functions))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return ARRAY_SIZE(u300_pmx_functions);
|
||||
}
|
||||
|
||||
static const char *u300_pmx_get_func_name(struct pinctrl_dev *pctldev,
|
||||
@ -1014,7 +1006,7 @@ static int u300_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
|
||||
}
|
||||
|
||||
static struct pinmux_ops u300_pmx_ops = {
|
||||
.list_functions = u300_pmx_list_funcs,
|
||||
.get_functions_count = u300_pmx_get_funcs_count,
|
||||
.get_function_name = u300_pmx_get_func_name,
|
||||
.get_function_groups = u300_pmx_get_groups,
|
||||
.enable = u300_pmx_enable,
|
||||
|
@ -33,22 +33,25 @@
|
||||
int pinmux_check_ops(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
const struct pinmux_ops *ops = pctldev->desc->pmxops;
|
||||
unsigned nfuncs;
|
||||
unsigned selector = 0;
|
||||
|
||||
/* Check that we implement required operations */
|
||||
if (!ops->list_functions ||
|
||||
if (!ops ||
|
||||
!ops->get_functions_count ||
|
||||
!ops->get_function_name ||
|
||||
!ops->get_function_groups ||
|
||||
!ops->enable ||
|
||||
!ops->disable)
|
||||
!ops->enable) {
|
||||
dev_err(pctldev->dev, "pinmux ops lacks necessary functions\n");
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
/* Check that all functions registered have names */
|
||||
while (ops->list_functions(pctldev, selector) >= 0) {
|
||||
nfuncs = ops->get_functions_count(pctldev);
|
||||
while (selector < nfuncs) {
|
||||
const char *fname = ops->get_function_name(pctldev,
|
||||
selector);
|
||||
if (!fname) {
|
||||
pr_err("pinmux ops has no name for function%u\n",
|
||||
dev_err(pctldev->dev, "pinmux ops has no name for function%u\n",
|
||||
selector);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -85,20 +88,23 @@ static int pin_request(struct pinctrl_dev *pctldev,
|
||||
const struct pinmux_ops *ops = pctldev->desc->pmxops;
|
||||
int status = -EINVAL;
|
||||
|
||||
dev_dbg(pctldev->dev, "request pin %d for %s\n", pin, owner);
|
||||
|
||||
desc = pin_desc_get(pctldev, pin);
|
||||
if (desc == NULL) {
|
||||
dev_err(pctldev->dev,
|
||||
"pin is not registered so it cannot be requested\n");
|
||||
"pin %d is not registered so it cannot be requested\n",
|
||||
pin);
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev_dbg(pctldev->dev, "request pin %d (%s) for %s\n",
|
||||
pin, desc->name, owner);
|
||||
|
||||
if (gpio_range) {
|
||||
/* There's no need to support multiple GPIO requests */
|
||||
if (desc->gpio_owner) {
|
||||
dev_err(pctldev->dev,
|
||||
"pin already requested\n");
|
||||
"pin %s already requested by %s; cannot claim for %s\n",
|
||||
desc->name, desc->gpio_owner, owner);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -106,7 +112,8 @@ static int pin_request(struct pinctrl_dev *pctldev,
|
||||
} else {
|
||||
if (desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
|
||||
dev_err(pctldev->dev,
|
||||
"pin already requested\n");
|
||||
"pin %s already requested by %s; cannot claim for %s\n",
|
||||
desc->name, desc->mux_owner, owner);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -139,8 +146,7 @@ static int pin_request(struct pinctrl_dev *pctldev,
|
||||
status = 0;
|
||||
|
||||
if (status) {
|
||||
dev_err(pctldev->dev, "->request on device %s failed for pin %d\n",
|
||||
pctldev->desc->name, pin);
|
||||
dev_err(pctldev->dev, "request() failed for pin %d\n", pin);
|
||||
module_put(pctldev->owner);
|
||||
}
|
||||
|
||||
@ -157,7 +163,7 @@ out_free_pin:
|
||||
out:
|
||||
if (status)
|
||||
dev_err(pctldev->dev, "pin-%d (%s) status %d\n",
|
||||
pin, owner, status);
|
||||
pin, owner, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -287,10 +293,11 @@ static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev,
|
||||
const char *function)
|
||||
{
|
||||
const struct pinmux_ops *ops = pctldev->desc->pmxops;
|
||||
unsigned nfuncs = ops->get_functions_count(pctldev);
|
||||
unsigned selector = 0;
|
||||
|
||||
/* See if this pctldev has this function */
|
||||
while (ops->list_functions(pctldev, selector) >= 0) {
|
||||
while (selector < nfuncs) {
|
||||
const char *fname = ops->get_function_name(pctldev,
|
||||
selector);
|
||||
|
||||
@ -319,18 +326,32 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
|
||||
const unsigned *pins;
|
||||
unsigned num_pins;
|
||||
|
||||
setting->data.mux.func =
|
||||
pinmux_func_name_to_selector(pctldev, map->data.mux.function);
|
||||
if (setting->data.mux.func < 0)
|
||||
return setting->data.mux.func;
|
||||
if (!pmxops) {
|
||||
dev_err(pctldev->dev, "does not support mux function\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = pinmux_func_name_to_selector(pctldev, map->data.mux.function);
|
||||
if (ret < 0) {
|
||||
dev_err(pctldev->dev, "invalid function %s in map table\n",
|
||||
map->data.mux.function);
|
||||
return ret;
|
||||
}
|
||||
setting->data.mux.func = ret;
|
||||
|
||||
ret = pmxops->get_function_groups(pctldev, setting->data.mux.func,
|
||||
&groups, &num_groups);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
dev_err(pctldev->dev, "can't query groups for function %s\n",
|
||||
map->data.mux.function);
|
||||
return ret;
|
||||
if (!num_groups)
|
||||
}
|
||||
if (!num_groups) {
|
||||
dev_err(pctldev->dev,
|
||||
"function %s can't be selected on any group\n",
|
||||
map->data.mux.function);
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
if (map->data.mux.group) {
|
||||
bool found = false;
|
||||
group = map->data.mux.group;
|
||||
@ -340,15 +361,23 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
if (!found) {
|
||||
dev_err(pctldev->dev,
|
||||
"invalid group \"%s\" for function \"%s\"\n",
|
||||
group, map->data.mux.function);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
group = groups[0];
|
||||
}
|
||||
|
||||
setting->data.mux.group = pinctrl_get_group_selector(pctldev, group);
|
||||
if (setting->data.mux.group < 0)
|
||||
return setting->data.mux.group;
|
||||
ret = pinctrl_get_group_selector(pctldev, group);
|
||||
if (ret < 0) {
|
||||
dev_err(pctldev->dev, "invalid group %s in map table\n",
|
||||
map->data.mux.group);
|
||||
return ret;
|
||||
}
|
||||
setting->data.mux.group = ret;
|
||||
|
||||
ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins,
|
||||
&num_pins);
|
||||
@ -364,7 +393,7 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
|
||||
ret = pin_request(pctldev, pins[i], map->dev_name, NULL);
|
||||
if (ret) {
|
||||
dev_err(pctldev->dev,
|
||||
"could not get request pin %d on device %s\n",
|
||||
"could not request pin %d on device %s\n",
|
||||
pins[i], pinctrl_dev_get_name(pctldev));
|
||||
/* On error release all taken pins */
|
||||
i--; /* this pin just failed */
|
||||
@ -467,7 +496,8 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
|
||||
desc->mux_setting = NULL;
|
||||
}
|
||||
|
||||
ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
|
||||
if (ops->disable)
|
||||
ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
@ -477,11 +507,15 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
|
||||
{
|
||||
struct pinctrl_dev *pctldev = s->private;
|
||||
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
|
||||
unsigned nfuncs;
|
||||
unsigned func_selector = 0;
|
||||
|
||||
mutex_lock(&pinctrl_mutex);
|
||||
if (!pmxops)
|
||||
return 0;
|
||||
|
||||
while (pmxops->list_functions(pctldev, func_selector) >= 0) {
|
||||
mutex_lock(&pinctrl_mutex);
|
||||
nfuncs = pmxops->get_functions_count(pctldev);
|
||||
while (func_selector < nfuncs) {
|
||||
const char *func = pmxops->get_function_name(pctldev,
|
||||
func_selector);
|
||||
const char * const *groups;
|
||||
@ -515,6 +549,9 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
|
||||
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
|
||||
unsigned i, pin;
|
||||
|
||||
if (!pmxops)
|
||||
return 0;
|
||||
|
||||
seq_puts(s, "Pinmux settings per pin\n");
|
||||
seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n");
|
||||
|
||||
|
@ -31,12 +31,6 @@ void pinmux_free_setting(struct pinctrl_setting const *setting);
|
||||
int pinmux_enable_setting(struct pinctrl_setting const *setting);
|
||||
void pinmux_disable_setting(struct pinctrl_setting const *setting);
|
||||
|
||||
void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map);
|
||||
void pinmux_show_setting(struct seq_file *s,
|
||||
struct pinctrl_setting const *setting);
|
||||
void pinmux_init_device_debugfs(struct dentry *devroot,
|
||||
struct pinctrl_dev *pctldev);
|
||||
|
||||
#else
|
||||
|
||||
static inline int pinmux_check_ops(struct pinctrl_dev *pctldev)
|
||||
@ -89,6 +83,18 @@ static inline void pinmux_disable_setting(
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PINMUX) && defined(CONFIG_DEBUG_FS)
|
||||
|
||||
void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map);
|
||||
void pinmux_show_setting(struct seq_file *s,
|
||||
struct pinctrl_setting const *setting);
|
||||
void pinmux_init_device_debugfs(struct dentry *devroot,
|
||||
struct pinctrl_dev *pctldev);
|
||||
|
||||
#else
|
||||
|
||||
static inline void pinmux_show_map(struct seq_file *s,
|
||||
struct pinctrl_map const *map)
|
||||
{
|
||||
|
@ -193,6 +193,17 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
|
||||
for (child = of_get_next_child(parent, NULL); child != NULL; \
|
||||
child = of_get_next_child(parent, child))
|
||||
|
||||
static inline int of_get_child_count(const struct device_node *np)
|
||||
{
|
||||
struct device_node *child;
|
||||
int num = 0;
|
||||
|
||||
for_each_child_of_node(np, child)
|
||||
num++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
extern struct device_node *of_find_node_with_property(
|
||||
struct device_node *from, const char *prop_name);
|
||||
#define for_each_node_with_property(dn, prop_name) \
|
||||
@ -259,6 +270,37 @@ extern void of_detach_node(struct device_node *);
|
||||
#endif
|
||||
|
||||
#define of_match_ptr(_ptr) (_ptr)
|
||||
|
||||
/*
|
||||
* struct property *prop;
|
||||
* const __be32 *p;
|
||||
* u32 u;
|
||||
*
|
||||
* of_property_for_each_u32(np, "propname", prop, p, u)
|
||||
* printk("U32 value: %x\n", u);
|
||||
*/
|
||||
const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
|
||||
u32 *pu);
|
||||
#define of_property_for_each_u32(np, propname, prop, p, u) \
|
||||
for (prop = of_find_property(np, propname, NULL), \
|
||||
p = of_prop_next_u32(prop, NULL, &u); \
|
||||
p; \
|
||||
p = of_prop_next_u32(prop, p, &u))
|
||||
|
||||
/*
|
||||
* struct property *prop;
|
||||
* const char *s;
|
||||
*
|
||||
* of_property_for_each_string(np, "propname", prop, s)
|
||||
* printk("String value: %s\n", s);
|
||||
*/
|
||||
const char *of_prop_next_string(struct property *prop, const char *cur);
|
||||
#define of_property_for_each_string(np, propname, prop, s) \
|
||||
for (prop = of_find_property(np, propname, NULL), \
|
||||
s = of_prop_next_string(prop, NULL); \
|
||||
s; \
|
||||
s = of_prop_next_string(prop, s))
|
||||
|
||||
#else /* CONFIG_OF */
|
||||
|
||||
static inline bool of_have_populated_dt(void)
|
||||
@ -269,6 +311,11 @@ static inline bool of_have_populated_dt(void)
|
||||
#define for_each_child_of_node(parent, child) \
|
||||
while (0)
|
||||
|
||||
static inline int of_get_child_count(const struct device_node *np)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int of_device_is_compatible(const struct device_node *device,
|
||||
const char *name)
|
||||
{
|
||||
@ -349,6 +396,10 @@ static inline int of_machine_is_compatible(const char *compat)
|
||||
|
||||
#define of_match_ptr(_ptr) NULL
|
||||
#define of_match_node(_matches, _node) NULL
|
||||
#define of_property_for_each_u32(np, propname, prop, p, u) \
|
||||
while (0)
|
||||
#define of_property_for_each_string(np, propname, prop, s) \
|
||||
while (0)
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
/**
|
||||
|
@ -36,6 +36,9 @@ extern struct pinctrl_state * __must_check pinctrl_lookup_state(
|
||||
const char *name);
|
||||
extern int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s);
|
||||
|
||||
extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev);
|
||||
extern void devm_pinctrl_put(struct pinctrl *p);
|
||||
|
||||
#else /* !CONFIG_PINCTRL */
|
||||
|
||||
static inline int pinctrl_request_gpio(unsigned gpio)
|
||||
@ -79,6 +82,15 @@ static inline int pinctrl_select_state(struct pinctrl *p,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct pinctrl * __must_check devm_pinctrl_get(struct device *dev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void devm_pinctrl_put(struct pinctrl *p)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PINCTRL */
|
||||
|
||||
static inline struct pinctrl * __must_check pinctrl_get_select(
|
||||
@ -113,6 +125,38 @@ static inline struct pinctrl * __must_check pinctrl_get_select_default(
|
||||
return pinctrl_get_select(dev, PINCTRL_STATE_DEFAULT);
|
||||
}
|
||||
|
||||
static inline struct pinctrl * __must_check devm_pinctrl_get_select(
|
||||
struct device *dev, const char *name)
|
||||
{
|
||||
struct pinctrl *p;
|
||||
struct pinctrl_state *s;
|
||||
int ret;
|
||||
|
||||
p = devm_pinctrl_get(dev);
|
||||
if (IS_ERR(p))
|
||||
return p;
|
||||
|
||||
s = pinctrl_lookup_state(p, name);
|
||||
if (IS_ERR(s)) {
|
||||
devm_pinctrl_put(p);
|
||||
return ERR_PTR(PTR_ERR(s));
|
||||
}
|
||||
|
||||
ret = pinctrl_select_state(p, s);
|
||||
if (ret < 0) {
|
||||
devm_pinctrl_put(p);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline struct pinctrl * __must_check devm_pinctrl_get_select_default(
|
||||
struct device *dev)
|
||||
{
|
||||
return devm_pinctrl_get_select(dev, PINCTRL_STATE_DEFAULT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PINCONF
|
||||
|
||||
extern int pin_config_get(const char *dev_name, const char *name,
|
||||
|
@ -154,7 +154,7 @@ struct pinctrl_map {
|
||||
|
||||
extern int pinctrl_register_mappings(struct pinctrl_map const *map,
|
||||
unsigned num_maps);
|
||||
|
||||
extern void pinctrl_provide_dummies(void);
|
||||
#else
|
||||
|
||||
static inline int pinctrl_register_mappings(struct pinctrl_map const *map,
|
||||
@ -163,5 +163,8 @@ static inline int pinctrl_register_mappings(struct pinctrl_map const *map,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_PINMUX */
|
||||
static inline void pinctrl_provide_dummies(void)
|
||||
{
|
||||
}
|
||||
#endif /* !CONFIG_PINCTRL */
|
||||
#endif
|
||||
|
@ -25,7 +25,6 @@ struct seq_file;
|
||||
* @pin_config_get: get the config of a certain pin, if the requested config
|
||||
* is not available on this controller this should return -ENOTSUPP
|
||||
* and if it is available but disabled it should return -EINVAL
|
||||
* @pin_config_get: get the config of a certain pin
|
||||
* @pin_config_set: configure an individual pin
|
||||
* @pin_config_group_get: get configurations for an entire pin group
|
||||
* @pin_config_group_set: configure all pins in a group
|
||||
@ -33,6 +32,8 @@ struct seq_file;
|
||||
* per-device info for a certain pin in debugfs
|
||||
* @pin_config_group_dbg_show: optional debugfs display hook that will provide
|
||||
* per-device info for a certain group in debugfs
|
||||
* @pin_config_config_dbg_show: optional debugfs display hook that will decode
|
||||
* and display a driver's pin configuration parameter
|
||||
*/
|
||||
struct pinconf_ops {
|
||||
#ifdef CONFIG_GENERIC_PINCONF
|
||||
@ -56,6 +57,9 @@ struct pinconf_ops {
|
||||
void (*pin_config_group_dbg_show) (struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s,
|
||||
unsigned selector);
|
||||
void (*pin_config_config_dbg_show) (struct pinctrl_dev *pctldev,
|
||||
struct seq_file *s,
|
||||
unsigned long config);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -21,9 +21,11 @@
|
||||
|
||||
struct device;
|
||||
struct pinctrl_dev;
|
||||
struct pinctrl_map;
|
||||
struct pinmux_ops;
|
||||
struct pinconf_ops;
|
||||
struct gpio_chip;
|
||||
struct device_node;
|
||||
|
||||
/**
|
||||
* struct pinctrl_pin_desc - boards/machines provide information on their
|
||||
@ -64,17 +66,24 @@ struct pinctrl_gpio_range {
|
||||
/**
|
||||
* struct pinctrl_ops - global pin control operations, to be implemented by
|
||||
* pin controller drivers.
|
||||
* @list_groups: list the number of selectable named groups available
|
||||
* in this pinmux driver, the core will begin on 0 and call this
|
||||
* repeatedly as long as it returns >= 0 to enumerate the groups
|
||||
* @get_groups_count: Returns the count of total number of groups registered.
|
||||
* @get_group_name: return the group name of the pin group
|
||||
* @get_group_pins: return an array of pins corresponding to a certain
|
||||
* group selector @pins, and the size of the array in @num_pins
|
||||
* @pin_dbg_show: optional debugfs display hook that will provide per-device
|
||||
* info for a certain pin in debugfs
|
||||
* @dt_node_to_map: parse a device tree "pin configuration node", and create
|
||||
* mapping table entries for it. These are returned through the @map and
|
||||
* @num_maps output parameters. This function is optional, and may be
|
||||
* omitted for pinctrl drivers that do not support device tree.
|
||||
* @dt_free_map: free mapping table entries created via @dt_node_to_map. The
|
||||
* top-level @map pointer must be freed, along with any dynamically
|
||||
* allocated members of the mapping table entries themselves. This
|
||||
* function is optional, and may be omitted for pinctrl drivers that do
|
||||
* not support device tree.
|
||||
*/
|
||||
struct pinctrl_ops {
|
||||
int (*list_groups) (struct pinctrl_dev *pctldev, unsigned selector);
|
||||
int (*get_groups_count) (struct pinctrl_dev *pctldev);
|
||||
const char *(*get_group_name) (struct pinctrl_dev *pctldev,
|
||||
unsigned selector);
|
||||
int (*get_group_pins) (struct pinctrl_dev *pctldev,
|
||||
@ -83,6 +92,11 @@ struct pinctrl_ops {
|
||||
unsigned *num_pins);
|
||||
void (*pin_dbg_show) (struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||
unsigned offset);
|
||||
int (*dt_node_to_map) (struct pinctrl_dev *pctldev,
|
||||
struct device_node *np_config,
|
||||
struct pinctrl_map **map, unsigned *num_maps);
|
||||
void (*dt_free_map) (struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_map *map, unsigned num_maps);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -23,15 +23,14 @@ struct pinctrl_dev;
|
||||
/**
|
||||
* struct pinmux_ops - pinmux operations, to be implemented by pin controller
|
||||
* drivers that support pinmuxing
|
||||
* @request: called by the core to see if a certain pin can be made available
|
||||
* @request: called by the core to see if a certain pin can be made
|
||||
* available for muxing. This is called by the core to acquire the pins
|
||||
* before selecting any actual mux setting across a function. The driver
|
||||
* is allowed to answer "no" by returning a negative error code
|
||||
* @free: the reverse function of the request() callback, frees a pin after
|
||||
* being requested
|
||||
* @list_functions: list the number of selectable named functions available
|
||||
* in this pinmux driver, the core will begin on 0 and call this
|
||||
* repeatedly as long as it returns >= 0 to enumerate mux settings
|
||||
* @get_functions_count: returns number of selectable named functions available
|
||||
* in this pinmux driver
|
||||
* @get_function_name: return the function name of the muxing selector,
|
||||
* called by the core to figure out which mux setting it shall map a
|
||||
* certain device to
|
||||
@ -62,7 +61,7 @@ struct pinctrl_dev;
|
||||
struct pinmux_ops {
|
||||
int (*request) (struct pinctrl_dev *pctldev, unsigned offset);
|
||||
int (*free) (struct pinctrl_dev *pctldev, unsigned offset);
|
||||
int (*list_functions) (struct pinctrl_dev *pctldev, unsigned selector);
|
||||
int (*get_functions_count) (struct pinctrl_dev *pctldev);
|
||||
const char *(*get_function_name) (struct pinctrl_dev *pctldev,
|
||||
unsigned selector);
|
||||
int (*get_function_groups) (struct pinctrl_dev *pctldev,
|
||||
|
Loading…
Reference in New Issue
Block a user